From c3297a137131ae07c6af3af60ecdf258e585e04c Mon Sep 17 00:00:00 2001 From: "github-classroom[bot]" <66690702+github-classroom[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 13:53:27 +0000 Subject: [PATCH 1/7] Update GitHub Classroom Autograding Workflow --- .github/workflows/classroom.yml | 223 ++++++++++++++++++++++++++++++-- 1 file changed, 212 insertions(+), 11 deletions(-) diff --git a/.github/workflows/classroom.yml b/.github/workflows/classroom.yml index dca83b024..8c4fa1b7e 100644 --- a/.github/workflows/classroom.yml +++ b/.github/workflows/classroom.yml @@ -1,19 +1,220 @@ -name: GitHub Classroom Workflow - -on: - - push - - workflow_dispatch - +name: Autograding Tests +'on': +- push +- workflow_dispatch +- repository_dispatch permissions: checks: write actions: read contents: read - jobs: - build: - name: Autograding + run-autograding-tests: runs-on: ubuntu-latest if: github.actor != 'github-classroom[bot]' steps: - - uses: actions/checkout@v4 - - uses: education/autograding@v1 + - name: Checkout code + uses: actions/checkout@v4 + - name: Step-1 Test + id: step-1-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-1 Test + setup-command: npm install + command: npm run test:1 + timeout: 10 + max-score: 10 + - name: Step-2 Test + id: step-2-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-2 Test + setup-command: npm install + command: npm run test:2 + timeout: 10 + max-score: 10 + - name: Step-3 Test + id: step-3-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-3 Test + setup-command: npm install + command: npm run test:3 + timeout: 10 + max-score: 10 + - name: Step-4 Test + id: step-4-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-4 Test + setup-command: npm install + command: npm run test:4 + timeout: 10 + - name: Step-5 Test + id: step-5-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-5 Test + setup-command: npm install + command: npm run test:5 + timeout: 10 + max-score: 10 + - name: Step-6 Test + id: step-6-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-6 Test + setup-command: npm install + command: npm run test:6 + timeout: 10 + max-score: 10 + - name: Step-7 Test + id: step-7-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-7 Test + setup-command: npm install + command: npm run test:7 + timeout: 10 + max-score: 10 + - name: Step-8 Test + id: step-8-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-8 Test + setup-command: npm install + command: npm run test:8 + timeout: 10 + max-score: 10 + - name: Step-9 Test + id: step-9-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-9 Test + setup-command: npm install + command: npm run test:9 + timeout: 10 + max-score: 10 + - name: Step-10 Test + id: step-10-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-10 Test + setup-command: npm install + command: npm run test:10 + timeout: 10 + max-score: 10 + - name: Step-11 Test + id: step-11-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-11 Test + setup-command: npm install + command: npm run test:11 + timeout: 10 + max-score: 10 + - name: Step-12 Test + id: step-12-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-12 Test + setup-command: npm install + command: npm run test:12 + timeout: 10 + max-score: 10 + - name: Step-13 Test + id: step-13-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-13 Test + setup-command: npm install + command: npm run test:13 + timeout: 10 + max-score: 10 + - name: Step-14 Test + id: step-14-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-14 Test + setup-command: npm install + command: npm run test:14 + timeout: 10 + max-score: 10 + - name: Step-15 Test + id: step-15-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-15 Test + setup-command: npm install + command: npm run test:15 + timeout: 10 + max-score: 10 + - name: Step-16 Test + id: step-16-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-16 Test + setup-command: npm install + command: npm run test:16 + timeout: 10 + max-score: 10 + - name: Step-17 Test + id: step-17-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-17 Test + setup-command: npm install + command: npm run test:17 + timeout: 10 + max-score: 10 + - name: Step-18 Test + id: step-18-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-18 Test + setup-command: npm install + command: npm run test:18 + timeout: 10 + max-score: 10 + - name: Step-19 Test + id: step-19-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-19 Test + setup-command: npm install + command: npm run test:19 + timeout: 10 + max-score: 10 + - name: Step-20 Test + id: step-20-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-20 Test + setup-command: npm install + command: npm run test:20 + timeout: 10 + max-score: 10 + - name: Autograding Reporter + uses: education/autograding-grading-reporter@v1 + env: + STEP-1-TEST_RESULTS: "${{steps.step-1-test.outputs.result}}" + STEP-2-TEST_RESULTS: "${{steps.step-2-test.outputs.result}}" + STEP-3-TEST_RESULTS: "${{steps.step-3-test.outputs.result}}" + STEP-4-TEST_RESULTS: "${{steps.step-4-test.outputs.result}}" + STEP-5-TEST_RESULTS: "${{steps.step-5-test.outputs.result}}" + STEP-6-TEST_RESULTS: "${{steps.step-6-test.outputs.result}}" + STEP-7-TEST_RESULTS: "${{steps.step-7-test.outputs.result}}" + STEP-8-TEST_RESULTS: "${{steps.step-8-test.outputs.result}}" + STEP-9-TEST_RESULTS: "${{steps.step-9-test.outputs.result}}" + STEP-10-TEST_RESULTS: "${{steps.step-10-test.outputs.result}}" + STEP-11-TEST_RESULTS: "${{steps.step-11-test.outputs.result}}" + STEP-12-TEST_RESULTS: "${{steps.step-12-test.outputs.result}}" + STEP-13-TEST_RESULTS: "${{steps.step-13-test.outputs.result}}" + STEP-14-TEST_RESULTS: "${{steps.step-14-test.outputs.result}}" + STEP-15-TEST_RESULTS: "${{steps.step-15-test.outputs.result}}" + STEP-16-TEST_RESULTS: "${{steps.step-16-test.outputs.result}}" + STEP-17-TEST_RESULTS: "${{steps.step-17-test.outputs.result}}" + STEP-18-TEST_RESULTS: "${{steps.step-18-test.outputs.result}}" + STEP-19-TEST_RESULTS: "${{steps.step-19-test.outputs.result}}" + STEP-20-TEST_RESULTS: "${{steps.step-20-test.outputs.result}}" + with: + runners: step-1-test,step-2-test,step-3-test,step-4-test,step-5-test,step-6-test,step-7-test,step-8-test,step-9-test,step-10-test,step-11-test,step-12-test,step-13-test,step-14-test,step-15-test,step-16-test,step-17-test,step-18-test,step-19-test,step-20-test From c2d2dd6b010b9f1035c10791ffb0e1a47295df9c Mon Sep 17 00:00:00 2001 From: "github-classroom[bot]" <66690702+github-classroom[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 13:53:28 +0000 Subject: [PATCH 2/7] GitHub Classroom Feedback --- .github/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .github/.keep diff --git a/.github/.keep b/.github/.keep new file mode 100644 index 000000000..e69de29bb From 79a8d08a2a9524eaba82a9e04bbca131289383aa Mon Sep 17 00:00:00 2001 From: "github-classroom[bot]" <66690702+github-classroom[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 13:53:28 +0000 Subject: [PATCH 3/7] Setting up GitHub Classroom Feedback From 15a883b765202c87aa2137d11666f36213ff804c Mon Sep 17 00:00:00 2001 From: "github-classroom[bot]" <66690702+github-classroom[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 13:53:30 +0000 Subject: [PATCH 4/7] add online IDE url --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index eadfc715a..818e40bb0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[![Open in Visual Studio Code](https://classroom.github.com/assets/open-in-vscode-718a45dd9cf7e7f842a935f5ebbe5719a5e09af4491e668f4dbf3b35d5cca122.svg)](https://classroom.github.com/online_ide?assignment_repo_id=14920935&assignment_repo_type=AssignmentRepo)

StylusDB SQL

A SQL database engine written in JavaScript From 920904a788fddb4c230ee95a268a203dcf53acf7 Mon Sep 17 00:00:00 2001 From: DS-ALGO Date: Mon, 29 Apr 2024 19:27:04 +0530 Subject: [PATCH 5/7] implementing --- .github/classroom/autograding.json | 203 ------------- .github/workflows/classroom.yml | 220 -------------- .github/workflows/tests.yml | 44 --- .vscode/settings.json | 5 + README.md | 1 - docs/design/HLD/HLD.jpg | Bin 80046 -> 0 bytes docs/design/specs/dbMigration/.gitkeep | 0 docs/design/specs/dbSchema/.gitkeep | 0 docs/design/specs/sqlParser/delete.json | 22 -- docs/design/specs/sqlParser/insert.json | 28 -- docs/design/specs/sqlParser/select.json | 158 ---------- docs/design/specs/sqlParser/update.json | 37 --- docs/readme.md | 81 ------ docs/tutorials/01.md | 54 ---- docs/tutorials/02.md | 67 ----- docs/tutorials/03.md | 54 ---- docs/tutorials/04.md | 57 ---- docs/tutorials/05.md | 100 ------- docs/tutorials/06.md | 114 -------- docs/tutorials/07.md | 76 ----- docs/tutorials/08.md | 210 -------------- docs/tutorials/09.md | 131 --------- docs/tutorials/10.md | 76 ----- docs/tutorials/11.md | 81 ------ docs/tutorials/12.md | 71 ----- docs/tutorials/13.md | 74 ----- docs/tutorials/14.md | 189 ------------ docs/tutorials/15.md | 141 --------- docs/tutorials/16.md | 52 ---- docs/tutorials/17.md | 60 ---- docs/tutorials/18.md | 81 ------ docs/tutorials/19.md | 105 ------- docs/tutorials/20.md | 13 - docs/tutorials/assets/tutorial-19.gif | Bin 1135294 -> 0 bytes enrollment.csv | 6 + package-lock.json | 4 +- package.json | 7 +- sample.csv | 4 + src/cli.js | 89 ++++++ src/csvReader.js | 42 +++ src/index.js | 14 + src/queryExecutor.js | 370 ++++++++++++++++++++++++ src/queryParser.js | 177 ++++++++++++ student.csv | 5 + tests/step-02/index.test.js | 6 +- tests/step-03/index.test.js | 24 +- tests/step-04/index.test.js | 27 +- tests/step-05/index.test.js | 52 ++-- tests/step-06/index.test.js | 72 +++-- tests/step-07/index.test.js | 81 ++++-- tests/step-08/index.test.js | 65 +++-- tests/step-09/index.test.js | 54 +++- tests/step-10/index.test.js | 114 ++++++-- tests/step-11/index.test.js | 126 +++++--- tests/step-12/index.test.js | 104 ++++--- tests/step-13/index.test.js | 104 ++++--- tests/step-14/index.test.js | 46 +-- tests/step-15/index.test.js | 46 +-- tests/step-16/index.test.js | 46 +-- tests/step-17/index.test.js | 2 +- tests/step-17/insertExecuter.test.js | 3 +- tests/step-18/deleteExecutor.test.js | 2 +- tests/step-18/index.test.js | 2 +- tests/step-18/insertExecuter.test.js | 40 +-- tests/step-19/deleteExecutor.test.js | 2 +- tests/step-19/index.test.js | 2 +- tests/step-19/insertExecuter.test.js | 89 ++++-- 67 files changed, 1431 insertions(+), 3001 deletions(-) delete mode 100644 .github/classroom/autograding.json delete mode 100644 .github/workflows/classroom.yml delete mode 100644 .github/workflows/tests.yml create mode 100644 .vscode/settings.json delete mode 100644 docs/design/HLD/HLD.jpg delete mode 100644 docs/design/specs/dbMigration/.gitkeep delete mode 100644 docs/design/specs/dbSchema/.gitkeep delete mode 100644 docs/design/specs/sqlParser/delete.json delete mode 100644 docs/design/specs/sqlParser/insert.json delete mode 100644 docs/design/specs/sqlParser/select.json delete mode 100644 docs/design/specs/sqlParser/update.json delete mode 100644 docs/readme.md delete mode 100644 docs/tutorials/01.md delete mode 100644 docs/tutorials/02.md delete mode 100644 docs/tutorials/03.md delete mode 100644 docs/tutorials/04.md delete mode 100644 docs/tutorials/05.md delete mode 100644 docs/tutorials/06.md delete mode 100644 docs/tutorials/07.md delete mode 100644 docs/tutorials/08.md delete mode 100644 docs/tutorials/09.md delete mode 100644 docs/tutorials/10.md delete mode 100644 docs/tutorials/11.md delete mode 100644 docs/tutorials/12.md delete mode 100644 docs/tutorials/13.md delete mode 100644 docs/tutorials/14.md delete mode 100644 docs/tutorials/15.md delete mode 100644 docs/tutorials/16.md delete mode 100644 docs/tutorials/17.md delete mode 100644 docs/tutorials/18.md delete mode 100644 docs/tutorials/19.md delete mode 100644 docs/tutorials/20.md delete mode 100644 docs/tutorials/assets/tutorial-19.gif create mode 100644 enrollment.csv create mode 100644 sample.csv create mode 100644 src/cli.js create mode 100644 src/index.js create mode 100644 src/queryExecutor.js create mode 100644 src/queryParser.js create mode 100644 student.csv diff --git a/.github/classroom/autograding.json b/.github/classroom/autograding.json deleted file mode 100644 index d045c04a9..000000000 --- a/.github/classroom/autograding.json +++ /dev/null @@ -1,203 +0,0 @@ -{ - "tests": [ - { - "name": "STEP-1 Test", - "setup": "npm install", - "run": "npm run test:1", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - }, - { - "name": "STEP-2 Test", - "setup": "npm install", - "run": "npm run test:2", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - }, - { - "name": "STEP-3 Test", - "setup": "npm install", - "run": "npm run test:3", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - }, - { - "name": "STEP-4 Test", - "setup": "npm install", - "run": "npm run test:4", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - }, - { - "name": "STEP-5 Test", - "setup": "npm install", - "run": "npm run test:5", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - }, - { - "name": "STEP-6 Test", - "setup": "npm install", - "run": "npm run test:6", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - }, - { - "name": "STEP-7 Test", - "setup": "npm install", - "run": "npm run test:7", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - }, - { - "name": "STEP-8 Test", - "setup": "npm install", - "run": "npm run test:8", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - }, - { - "name": "STEP-9 Test", - "setup": "npm install", - "run": "npm run test:9", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - }, - { - "name": "STEP-10 Test", - "setup": "npm install", - "run": "npm run test:10", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - }, - { - "name": "STEP-11 Test", - "setup": "npm install", - "run": "npm run test:11", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - }, - { - "name": "STEP-12 Test", - "setup": "npm install", - "run": "npm run test:12", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - }, - { - "name": "STEP-13 Test", - "setup": "npm install", - "run": "npm run test:13", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - }, - { - "name": "STEP-14 Test", - "setup": "npm install", - "run": "npm run test:14", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - }, - { - "name": "STEP-15 Test", - "setup": "npm install", - "run": "npm run test:15", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - }, - { - "name": "STEP-16 Test", - "setup": "npm install", - "run": "npm run test:16", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - }, - { - "name": "STEP-17 Test", - "setup": "npm install", - "run": "npm run test:17", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - }, - { - "name": "STEP-18 Test", - "setup": "npm install", - "run": "npm run test:18", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - }, - { - "name": "STEP-19 Test", - "setup": "npm install", - "run": "npm run test:19", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - },{ - "name": "STEP-20 Test", - "setup": "npm install", - "run": "npm run test:20", - "input": "", - "output": "", - "comparison": "exact", - "timeout": 10, - "points": 10 - } - ] -} \ No newline at end of file diff --git a/.github/workflows/classroom.yml b/.github/workflows/classroom.yml deleted file mode 100644 index 8c4fa1b7e..000000000 --- a/.github/workflows/classroom.yml +++ /dev/null @@ -1,220 +0,0 @@ -name: Autograding Tests -'on': -- push -- workflow_dispatch -- repository_dispatch -permissions: - checks: write - actions: read - contents: read -jobs: - run-autograding-tests: - runs-on: ubuntu-latest - if: github.actor != 'github-classroom[bot]' - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Step-1 Test - id: step-1-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-1 Test - setup-command: npm install - command: npm run test:1 - timeout: 10 - max-score: 10 - - name: Step-2 Test - id: step-2-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-2 Test - setup-command: npm install - command: npm run test:2 - timeout: 10 - max-score: 10 - - name: Step-3 Test - id: step-3-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-3 Test - setup-command: npm install - command: npm run test:3 - timeout: 10 - max-score: 10 - - name: Step-4 Test - id: step-4-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-4 Test - setup-command: npm install - command: npm run test:4 - timeout: 10 - - name: Step-5 Test - id: step-5-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-5 Test - setup-command: npm install - command: npm run test:5 - timeout: 10 - max-score: 10 - - name: Step-6 Test - id: step-6-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-6 Test - setup-command: npm install - command: npm run test:6 - timeout: 10 - max-score: 10 - - name: Step-7 Test - id: step-7-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-7 Test - setup-command: npm install - command: npm run test:7 - timeout: 10 - max-score: 10 - - name: Step-8 Test - id: step-8-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-8 Test - setup-command: npm install - command: npm run test:8 - timeout: 10 - max-score: 10 - - name: Step-9 Test - id: step-9-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-9 Test - setup-command: npm install - command: npm run test:9 - timeout: 10 - max-score: 10 - - name: Step-10 Test - id: step-10-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-10 Test - setup-command: npm install - command: npm run test:10 - timeout: 10 - max-score: 10 - - name: Step-11 Test - id: step-11-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-11 Test - setup-command: npm install - command: npm run test:11 - timeout: 10 - max-score: 10 - - name: Step-12 Test - id: step-12-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-12 Test - setup-command: npm install - command: npm run test:12 - timeout: 10 - max-score: 10 - - name: Step-13 Test - id: step-13-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-13 Test - setup-command: npm install - command: npm run test:13 - timeout: 10 - max-score: 10 - - name: Step-14 Test - id: step-14-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-14 Test - setup-command: npm install - command: npm run test:14 - timeout: 10 - max-score: 10 - - name: Step-15 Test - id: step-15-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-15 Test - setup-command: npm install - command: npm run test:15 - timeout: 10 - max-score: 10 - - name: Step-16 Test - id: step-16-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-16 Test - setup-command: npm install - command: npm run test:16 - timeout: 10 - max-score: 10 - - name: Step-17 Test - id: step-17-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-17 Test - setup-command: npm install - command: npm run test:17 - timeout: 10 - max-score: 10 - - name: Step-18 Test - id: step-18-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-18 Test - setup-command: npm install - command: npm run test:18 - timeout: 10 - max-score: 10 - - name: Step-19 Test - id: step-19-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-19 Test - setup-command: npm install - command: npm run test:19 - timeout: 10 - max-score: 10 - - name: Step-20 Test - id: step-20-test - uses: education/autograding-command-grader@v1 - with: - test-name: Step-20 Test - setup-command: npm install - command: npm run test:20 - timeout: 10 - max-score: 10 - - name: Autograding Reporter - uses: education/autograding-grading-reporter@v1 - env: - STEP-1-TEST_RESULTS: "${{steps.step-1-test.outputs.result}}" - STEP-2-TEST_RESULTS: "${{steps.step-2-test.outputs.result}}" - STEP-3-TEST_RESULTS: "${{steps.step-3-test.outputs.result}}" - STEP-4-TEST_RESULTS: "${{steps.step-4-test.outputs.result}}" - STEP-5-TEST_RESULTS: "${{steps.step-5-test.outputs.result}}" - STEP-6-TEST_RESULTS: "${{steps.step-6-test.outputs.result}}" - STEP-7-TEST_RESULTS: "${{steps.step-7-test.outputs.result}}" - STEP-8-TEST_RESULTS: "${{steps.step-8-test.outputs.result}}" - STEP-9-TEST_RESULTS: "${{steps.step-9-test.outputs.result}}" - STEP-10-TEST_RESULTS: "${{steps.step-10-test.outputs.result}}" - STEP-11-TEST_RESULTS: "${{steps.step-11-test.outputs.result}}" - STEP-12-TEST_RESULTS: "${{steps.step-12-test.outputs.result}}" - STEP-13-TEST_RESULTS: "${{steps.step-13-test.outputs.result}}" - STEP-14-TEST_RESULTS: "${{steps.step-14-test.outputs.result}}" - STEP-15-TEST_RESULTS: "${{steps.step-15-test.outputs.result}}" - STEP-16-TEST_RESULTS: "${{steps.step-16-test.outputs.result}}" - STEP-17-TEST_RESULTS: "${{steps.step-17-test.outputs.result}}" - STEP-18-TEST_RESULTS: "${{steps.step-18-test.outputs.result}}" - STEP-19-TEST_RESULTS: "${{steps.step-19-test.outputs.result}}" - STEP-20-TEST_RESULTS: "${{steps.step-20-test.outputs.result}}" - with: - runners: step-1-test,step-2-test,step-3-test,step-4-test,step-5-test,step-6-test,step-7-test,step-8-test,step-9-test,step-10-test,step-11-test,step-12-test,step-13-test,step-14-test,step-15-test,step-16-test,step-17-test,step-18-test,step-19-test,step-20-test diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml deleted file mode 100644 index d1ea222e0..000000000 --- a/.github/workflows/tests.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Run Tests - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - build: - - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [16.x, 18.x] - - steps: - - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - - run: npm i - - run: npm run test:1 - - run: npm run test:2 - - run: npm run test:3 - - run: npm run test:4 - - run: npm run test:5 - - run: npm run test:6 - - run: npm run test:7 - - run: npm run test:8 - - run: npm run test:9 - - run: npm run test:10 - - run: npm run test:11 - - run: npm run test:12 - - run: npm run test:13 - - run: npm run test:14 - - run: npm run test:15 - - run: npm run test:16 - - run: npm run test:17 - - run: npm run test:18 - - run: npm run test:19 - - run: npm run test:20 \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..b242572ef --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "githubPullRequests.ignoredPullRequestBranches": [ + "main" + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 818e40bb0..eadfc715a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -[![Open in Visual Studio Code](https://classroom.github.com/assets/open-in-vscode-718a45dd9cf7e7f842a935f5ebbe5719a5e09af4491e668f4dbf3b35d5cca122.svg)](https://classroom.github.com/online_ide?assignment_repo_id=14920935&assignment_repo_type=AssignmentRepo)

StylusDB SQL

A SQL database engine written in JavaScript diff --git a/docs/design/HLD/HLD.jpg b/docs/design/HLD/HLD.jpg deleted file mode 100644 index 72b064b60556c6776e57a9bb3b7d62b64a963f36..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 80046 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 z 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 Pmh=Doe)GVYAH)9#Lc^Va diff --git a/docs/design/specs/dbMigration/.gitkeep b/docs/design/specs/dbMigration/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/docs/design/specs/dbSchema/.gitkeep b/docs/design/specs/dbSchema/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/docs/design/specs/sqlParser/delete.json b/docs/design/specs/sqlParser/delete.json deleted file mode 100644 index a7731b472..000000000 --- a/docs/design/specs/sqlParser/delete.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "dialect": "PostgreSQL", - "queryType": "DELETE", - "delete": { - "from": "student", - "where": [ - { - "field": "age", - "operator": ">", - "placeholder": ":age", - "valueType": "integer" - } - ] - }, - "returning": [ - "id", - "name" - ], - "parameters": { - ":age": 25 - } -} \ No newline at end of file diff --git a/docs/design/specs/sqlParser/insert.json b/docs/design/specs/sqlParser/insert.json deleted file mode 100644 index 51ba1b62c..000000000 --- a/docs/design/specs/sqlParser/insert.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "dialect": "PostgreSQL", - "queryType": "INSERT", - "insert": { - "into": "student", - "columns": [ - "name", - "age", - "department" - ], - "values": [ - [ - "John Doe", - 22, - "Science" - ], - [ - "Jane Smith", - 20, - "Mathematics" - ] - ] - }, - "returning": [ - "id", - "name" - ] -} \ No newline at end of file diff --git a/docs/design/specs/sqlParser/select.json b/docs/design/specs/sqlParser/select.json deleted file mode 100644 index d1492488a..000000000 --- a/docs/design/specs/sqlParser/select.json +++ /dev/null @@ -1,158 +0,0 @@ -{ - "dialect": "PostgreSQL", - "with": [ - { - "name": "recursiveCTE", - "as": { - "baseQuery": { - "select": [ - "id", - "parent_id", - "name" - ], - "from": [ - { - "table": "categories", - "alias": "c" - } - ], - "where": [ - { - "field": "c.parent_id", - "operator": "IS", - "value": "NULL", - "valueType": "raw" - } - ] - }, - "recursiveQuery": { - "select": [ - "c.id", - "c.parent_id", - "c.name" - ], - "from": [ - { - "table": "categories", - "alias": "c" - } - ], - "join": { - "table": "recursiveCTE", - "alias": "r", - "on": [ - { - "left": "c.parent_id", - "right": "r.id", - "operator": "=" - } - ] - } - } - } - } - ], - "select": [ - { - "field": "student.name", - "alias": "studentName" - }, - { - "field": "enrollment.course", - "alias": "course" - }, - { - "subquery": { - "select": [ - "COUNT(*)" - ], - "from": [ - { - "table": "exam_results", - "alias": "er" - } - ], - "where": [ - { - "field": "er.student_id", - "operator": "=", - "fieldFromOuterQuery": "s.id" - } - ] - }, - "alias": "examCount" - } - ], - "from": [ - { - "table": "student", - "alias": "s", - "indexHint": "USE INDEX (idx_student_name)" - }, - { - "table": "recursiveCTE", - "alias": "r" - } - ], - "joins": [ - { - "type": "INNER", - "table": "enrollment", - "alias": "e", - "on": [ - { - "left": "s.id", - "right": "e.student_id", - "operator": "=" - }, - { - "left": "s.department", - "right": "e.department", - "operator": "=", - "logic": "AND" - } - ], - "indexHint": "FORCE INDEX (idx_enrollment_date)" - } - ], - "where": [ - { - "field": "s.age", - "operator": ">", - "placeholder": ":age", - "valueType": "integer" - } - ], - "groupBy": [ - "e.department" - ], - "having": [ - { - "field": "COUNT(*)", - "operator": ">", - "placeholder": ":count", - "valueType": "integer" - } - ], - "orderBy": [ - { - "field": "studentName", - "direction": "ASC" - } - ], - "limit": ":limit", - "offset": ":offset", - "parameters": { - ":age": 20, - ":count": 5, - ":limit": 10, - ":offset": 0 - }, - "performanceHints": { - "useIndex": [ - "student (idx_student_age)" - ], - "optimizeFor": "speed", - "avoidFullTableScans": true - } -} \ No newline at end of file diff --git a/docs/design/specs/sqlParser/update.json b/docs/design/specs/sqlParser/update.json deleted file mode 100644 index 0a11f83c4..000000000 --- a/docs/design/specs/sqlParser/update.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "dialect": "PostgreSQL", - "queryType": "UPDATE", - "update": { - "table": "student", - "set": [ - { - "field": "name", - "value": ":newName", - "valueType": "string" - }, - { - "field": "age", - "value": ":newAge", - "valueType": "integer" - } - ], - "where": [ - { - "field": "id", - "operator": "=", - "placeholder": ":id", - "valueType": "integer" - } - ] - }, - "returning": [ - "id", - "name", - "age" - ], - "parameters": { - ":newName": "Jane Doe", - ":newAge": 23, - ":id": 1 - } -} \ No newline at end of file diff --git a/docs/readme.md b/docs/readme.md deleted file mode 100644 index ed966d64b..000000000 --- a/docs/readme.md +++ /dev/null @@ -1,81 +0,0 @@ -## SQL Query Engine over CSV in JavaScript - -Let's start building a SQL query engine over CSV in JavaScript. We'll use Node.js for this project. - -This project will be complete in 20 steps and will take about 2-20 hours to complete depending on your level of expertise. - -- [x] Step 1: Setting up the Project -- [x] Step 2: Create a CSV Reading Function -- [x] Step 3: Building a Basic SQL Query Parser -- [x] Step 4: Integrating CSV Reading with Query Parsing -- [x] Step 5: Adding Support for WHERE Clauses -- [x] Step 6: Handling multiple conditions in WHERE clause -- [x] Step 7: Handling Different Comparison Operators -- [x] Step 8: Adding INNER JOIN support -- [x] Step 9: Adding LEFT and RIGHT JOIN support -- [x] Step 10: Group By and Aggregate Functions -- [x] Step 11: Implementing ORDER BY Clause -- [x] Step 12: Adding LIMIT Clause -- [x] Step 13: Error Handling and Validation -- [x] Step 14: Implementing DISTINCT Keyword -- [x] Step 15: Adding Support for LIKE Operator -- [x] Step 16: Adding CI Support -- [x] Step 17: Basic INSERT Statement Support -- [x] Step 18: Basic DELETE Statement Support -- [x] Step 19: CLI Integration -- [x] Step 20: Packaging and Publishing - - -## Refactoring and Code Cleanup -This will be done post Step 20 to ensure that the code is clean and readable. This will also be a good time to add tests and documentation. - - -## Next Steps -There is a laundry list of features and improvements that can be added to this project. Here are some ideas for further development. The objective is to always add more features in a similar format - A tutorial-style guide with step-by-step instructions. A lot of these are challenging and should be broken down into smaller steps. - -- [ ] Implementing SET Operations (UNION, INTERSECT, EXCEPT) -- [ ] INSERT Statement Support: Implement the capability to insert new data into existing CSV files. This includes parsing INSERT SQL statements and updating the CSV file while ensuring data integrity. -- [ ] Enhancing the Parser for Subqueries -- [ ] Data Update and Delete Operations: Along with INSERT, support UPDATE and DELETE operations. This allows for full data manipulation capabilities, similar to a traditional database. -- [ ] Schema Definition and Evolution: Provide functionality for defining a schema for CSV files (column names, data types, etc.) and mechanisms to evolve the schema over time (adding/removing columns, changing data types). -- [ ] Schema Validation: Include features to validate data against the defined schema during insertions and updates, ensuring data quality and consistency. -Data Integrity Constraints: Implement constraints like primary keys, unique constraints, and foreign keys. This would require additional logic for constraint enforcement during data modifications. -- [ ] ACID Properties Compliance: Aim to bring the system closer to compliance with ACID (Atomicity, Consistency, Isolation, Durability) properties, enhancing its reliability and robustness. -- [ ] Data Compression and Storage Optimization: Introduce data compression techniques to reduce the storage footprint of CSV files, especially important for large datasets. -- [ ] Bulk Data Insertion and Modification: Develop functionality for handling bulk data operations efficiently, which is crucial for large-scale data processing. -- [ ] Data Partitioning and Sharding: Implement data partitioning and sharding for handling very large CSV files, improving performance and manageability. -- [ ] Row-level Security: Add features for row-level security to restrict data access at a granular level, based on user roles or other criteria. -- [ ] High Availability and Fault Tolerance: Build mechanisms for ensuring high availability and fault tolerance, such as replicating data across multiple locations. -- [ ] Data Auditing Features: Introduce data auditing capabilities to track who made what changes and when, which is important for compliance and security. -- [ ] Disaster Recovery Mechanisms: Develop a system for backing up data and schemas, along with recovery procedures in case of data loss or corruption. This could involve regular snapshots of the CSV files and schema definitions. -- [ ] Transaction Log for Data Recovery: Maintain a transaction log to record all data manipulation operations. This can be used for point-in-time recovery and auditing purposes. -- [ ] Support for Indexing: Develop advanced indexing mechanisms like B-trees or hash indexes for faster query processing. This can significantly improve the performance of SELECT queries, especially on large CSV files. -- [ ] Query Optimization Engine: Implement a query optimizer that rewrites queries for optimal execution. This could include optimizing join orders, using indexes effectively, or simplifying complex queries. -- [ ] Custom Function Support: Allow users to define custom functions in JavaScript that can be used within SQL queries. This would add a layer of flexibility and power to the query engine. -- [ ] Data Type Casting and Conversion: Implement features for automatic or manual data type casting and conversion. This is crucial for handling different data types present in CSV files. -- [ ] Parallel Query Processing: Introduce multi-threading or parallel processing capabilities to handle large datasets more efficiently. This would enable the engine to execute multiple parts of a query in parallel, reducing overall query time. -- [ ] Custom Function Support: Allow users to define custom functions in JavaScript that can be used within SQL queries. This would add a layer of flexibility and power to the query engine. -- [ ] Regular Expression Support in Queries: Add support for using regular expressions in WHERE clauses, providing more powerful data filtering capabilities. -- [ ] Full-text Search Capability: Incorporate a full-text search feature, which is essential for efficiently searching through large text data. -- [ ] Data Import/Export Features: Allow importing data from and exporting data to different formats like JSON, XML, or even other databases. -- [ ] Performance Monitoring: Develop a system for monitoring query performance and logging slow queries. This could help in identifying bottlenecks and areas for improvement. -- [ ] Automatic Query Caching: Implement a caching mechanism that automatically caches frequent queries or query results for faster retrieval. -- [ ] Support for Transactions: Add basic transaction support with features like commit, rollback, and transaction logs. This would be particularly challenging but also a unique feature for a CSV-based query engine. -- [ ] Advanced Analytics: Incorporate more complex statistical functions and operations, making the engine useful for data analysis tasks. -- [ ] Security Features: Implement security features like query validation, SQL injection prevention, and access control mechanisms. -- [ ] Optimized Storage Formats: Add support for optimized storage formats for CSV files, like columnar storage, to enhance read performance. - -### Process to a new step -This project is built to be understood by someone with basic knowledge of JavaScript and SQL and then following the steps. Ensure that the documentation is updated with each step and uses the same style, format, and structure as the previous steps. Best if it can use some of the older _gyan_ as well. - -Checklist -- Find a feature that you would want to implement. -- Break it down into steps such that each step can be completed in at most 20 mins. -- Create a new GitHub issue for the feature. -- Get the issue reviewed and approved by a maintainer and get it assigned. -- Create a new branch for the step. -- Implement the step. -- Create a PR for the step. -- Get the implementation, tests and documentation approved. -- Get the PR merged. - diff --git a/docs/tutorials/01.md b/docs/tutorials/01.md deleted file mode 100644 index 5faf47779..000000000 --- a/docs/tutorials/01.md +++ /dev/null @@ -1,54 +0,0 @@ -## Step 1: Project Setup and Basic Test - -In this step, we setup the basic structure and testing for our project. - -### 1.1 Create a New Node.js Project -- Open your terminal. -- Navigate to the directory where you want to create your project. -- Run the following command to create a `package.json` file with default values: -```bash -npm init -y -``` - -### 1.2 Install Necessary Packages -- We will use `csv-parser` for CSV parsing and `jest` for testing. Install both packages using: -```bash -npm install csv-parser jest --save-dev -``` - -### 1.3 Create a Basic Project Structure -- Create a directory named `src`. -- Inside `src`, create a file named `index.js`. This will be your main file. - -### 1.4 Configure Jest -- Add a Jest configuration to your `package.json` file. Add the following under the `scripts` section: -```json -"scripts": { - "test": "jest" -} -``` - -- Create a directory named `tests` at the root of your project. -- Inside `tests`, create a file named `index.test.js` for your Jest tests. - -### 1.5 Write a Basic Jest Test -- In `index.test.js`, write a simple test to check your Jest setup. Here's a basic test example: - -```javascript -// tests/index.test.js - -test('Basic Jest Test', () => { - expect(1).toBe(1); -}); -``` - -### 1.6 Run Your Jest Test -- To run the test, navigate to your project root in the terminal. -- Execute the test using the following command: - -```bash -npm test -``` - -You should see the test passing in the console. -This completes the initial setup with Jest testing. Make sure everything works up to this point before moving to the next step. \ No newline at end of file diff --git a/docs/tutorials/02.md b/docs/tutorials/02.md deleted file mode 100644 index c4bc3c742..000000000 --- a/docs/tutorials/02.md +++ /dev/null @@ -1,67 +0,0 @@ -## Step 2: Reading a CSV File - -In this step we add the functionality to read from CSV files, since our DB would read from and write to CSV files, considering them as tables. - -### 2.1 Create a Sample CSV File -Create a new CSV file in your project directory. Let's call it `sample.csv` and add some sample data to it: - -```csv -id,name,age -1,John,30 -2,Jane,25 -3,Bob,22 -``` - -### 2.2 Create a CSV Reading Function -- In the `src` directory, create a new file named `csvReader.js`. -- Implement a function to read the CSV file using `csv-parser`. - -```javascript -// src/csvReader.js - -const fs = require('fs'); -const csv = require('csv-parser'); - -function readCSV(filePath) { - const results = []; - - return new Promise((resolve, reject) => { - fs.createReadStream(filePath) - .pipe(csv()) - .on('data', (data) => results.push(data)) - .on('end', () => { - resolve(results); - }) - .on('error', (error) => { - reject(error); - }); - }); -} - -module.exports = readCSV; -``` - -### 2.3 Update Test to Check CSV Reading -Modify the test in `tests/index.test.js` to include a test for reading the CSV file. - -Example test: - -```javascript -// tests/index.test.js - -const readCSV = require('../src/csvReader'); - -test('Read CSV File', async () => { - const data = await readCSV('./sample.csv'); - expect(data.length).toBeGreaterThan(0); - expect(data.length).toBe(3); - expect(data[0].name).toBe('John'); - expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later -}); -``` - -### 2.4 Run the Updated Test -Run the test using `npm test`. Ensure the test passes and correctly reads the CSV file. - - - diff --git a/docs/tutorials/03.md b/docs/tutorials/03.md deleted file mode 100644 index c6e1dc18b..000000000 --- a/docs/tutorials/03.md +++ /dev/null @@ -1,54 +0,0 @@ -## Step 3: Building a Basic SQL Query Parser - -In this section we will implement the basic functionality for our DB to make our DB understand SQL so that we can query data from it using SQL. - -### 3.1 Create the Parser Function -In the `src` directory, create a new file named `queryParser.js` - -Write a function that takes a SQL query string and parses it using regex to identify the `SELECT` fields and the `FROM` table name. - -Example implementation: -```javascript -// src/queryParser.js - -function parseQuery(query) { - const selectRegex = /SELECT (.+) FROM (.+)/i; - const match = query.match(selectRegex); - - if (match) { - const [, fields, table] = match; - return { - fields: fields.split(',').map(field => field.trim()), - table: table.trim() - }; - } else { - throw new Error('Invalid query format'); - } -} - -module.exports = parseQuery; -``` - -### 3.2 Update Test to Check Query Parsing -Modify the test in `tests/index.test.js` to include a test for the SQL query parsing. -Example test: - -```javascript -// tests/index.test.js - -const parseQuery = require('../src/queryParser'); - -test('Parse SQL Query', () => { - const query = 'SELECT id, name FROM sample'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'sample' - }); -}); -``` -> **💡Do it yourself:** Try writing a test for the case the above function would throw an error. - - -### 3.3 Run the Updated Test -Run the test using `npm test`. Ensure the test passes and correctly parses the SQL query. diff --git a/docs/tutorials/04.md b/docs/tutorials/04.md deleted file mode 100644 index 0339f1812..000000000 --- a/docs/tutorials/04.md +++ /dev/null @@ -1,57 +0,0 @@ -## Step 4: Integrating CSV Reading with Query Parsing - -In this step we integrate the functionalities implemented in the previous two steps together to get a basic `SELECT` query working in our DB. - -### 4.1 Create the Query Execution Function -- In `src/index.js`, rename the function to `executeSELECTQuery` to indicate its specific purpose. -- Ensure the function handles only SELECT queries. -Here's a basic implementation: - -```javascript -// src/index.js - -const parseQuery = require('./queryParser'); -const readCSV = require('./csvReader'); - -async function executeSELECTQuery(query) { - const { fields, table } = parseQuery(query); - const data = await readCSV(`${table}.csv`); - - // Filter the fields based on the query - return data.map(row => { - const filteredRow = {}; - fields.forEach(field => { - filteredRow[field] = row[field]; - }); - return filteredRow; - }); -} - -module.exports = executeSELECTQuery; -``` - -> **💡Do it yourself:** Find and list out conditions where this function can error out and handle them. - -### 4.2 Update Test to Check Query Execution -Modify the test in `tests/index.test.js` to include a test for executing the SQL query. -Example test: - -```javascript -// tests/index.test.js - -const executeSELECTQuery = require('../src/index'); - -test('Execute SQL Query', async () => { - const query = 'SELECT id, name FROM sample'; - const result = await executeSELECTQuery(query); - expect(result.length).toBeGreaterThan(0); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0]).not.toHaveProperty('age'); - expect(result[0]).toEqual({ id: '1', name: 'John' }); -}); -``` - -### 4.3 Run the Updated Test -Run the test using `npm test`. -Ensure the test passes and correctly executes the SQL query, returning the filtered data. diff --git a/docs/tutorials/05.md b/docs/tutorials/05.md deleted file mode 100644 index 291552cba..000000000 --- a/docs/tutorials/05.md +++ /dev/null @@ -1,100 +0,0 @@ -## Step 5: Adding WHERE Clause Handling to the Parser - -In this step we add filtering capabilities by adding `WHERE` clause parsing to our DB. - -### 5.1 Update the Parser to Handle WHERE Clauses -- In the `src` directory, update `queryParser.js` to parse the `WHERE` clause from the SQL query. -The parser should be able to extract the condition in a simple format, like `field = value`. - -Here's an updated implementation: - -```javascript -// src/queryParser.js - -function parseQuery(query) { - const selectRegex = /SELECT (.+?) FROM (.+?)(?: WHERE (.*))?$/i; - const match = query.match(selectRegex); - - if (match) { - const [, fields, table, whereClause] = match; - return { - fields: fields.split(',').map(field => field.trim()), - table: table.trim(), - whereClause: whereClause ? whereClause.trim() : null - }; - } else { - throw new Error('Invalid query format'); - } -} - -module.exports = parseQuery; -``` - -### 5.2 Run the Updated Tests -- Run the tests using `npm test`. Ensure all tests pass, particularly the new test for WHERE clause parsing. -- If you see your older test fail, update that to include `"whereClause": null` in the expected output. - -### 5.3 Update the Execute Function to apply `WHERE` clauses -Modify `executeSELECTQuery` in `src/index.js` to filter results based on the `WHERE` clause. - -Example implementation: - -```javascript -// src/index.js - -const parseQuery = require('./queryParser'); -const readCSV = require('./csvReader'); - -async function executeSELECTQuery(query) { - const { fields, table, whereClause } = parseQuery(query); - const data = await readCSV(`${table}.csv`); - - // Filtering based on WHERE clause - const filteredData = whereClause - ? data.filter(row => { - const [field, value] = whereClause.split('=').map(s => s.trim()); - return row[field] === value; - }) - : data; - - // Selecting the specified fields - return filteredData.map(row => { - const selectedRow = {}; - fields.forEach(field => { - selectedRow[field] = row[field]; - }); - return selectedRow; - }); -} - -module.exports = executeSELECTQuery; -``` - -> **💡Ask yourself:** Is the above implementation case-insensitive? - -### 5.3 Update Tests for `WHERE` Clause -Modify the tests in `tests/index.test.js` to include tests for queries with `WHERE` clauses. - -Example test: -```javascript -// tests/index.test.js - -const executeSELECTQuery = require('../src/index'); - -test('Execute SQL Query with WHERE Clause', async () => { - const query = 'SELECT id, name FROM sample WHERE age = 25'; - const result = await executeSELECTQuery(query); - expect(result.length).toBe(1); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0].id).toBe('2'); -}); -``` - -> **💡Do it yourself:** Add tests where the above -implementation would fail and to check for its case sensitivity/insensitivity. - -### 5.4 Run the Updated Tests -- Run the tests using `npm test` - - diff --git a/docs/tutorials/06.md b/docs/tutorials/06.md deleted file mode 100644 index 69405e509..000000000 --- a/docs/tutorials/06.md +++ /dev/null @@ -1,114 +0,0 @@ -## Step 6: Handling multiple conditions in WHERE clause - -In this step we add the functionality to add multiple filters in our SQL query. - -### 6.1 Update the Parser for Complex WHERE Clauses -- Modify `queryParser.js` to handle multiple conditions in the `WHERE` clause. -- The parser should split the conditions and identify the logical operators. - -Here's an example implementation: - -```javascript -// src/queryParser.js - -function parseQuery(query) { - const selectRegex = /SELECT (.+?) FROM (.+?)(?: WHERE (.*))?$/i; - const match = query.match(selectRegex); - - if (match) { - const [, fields, table, whereString] = match; - const whereClauses = whereString ? parseWhereClause(whereString) : []; - return { - fields: fields.split(',').map(field => field.trim()), - table: table.trim(), - whereClauses - }; - } else { - throw new Error('Invalid query format'); - } -} - -function parseWhereClause(whereString) { - const conditions = whereString.split(/ AND | OR /i); - return conditions.map(condition => { - const [field, operator, value] = condition.split(/\s+/); - return { field, operator, value }; - }); -} - -module.exports = parseQuery; -``` - -> **💡Do it yourself:** Add error handling to the newly added function. - -### 6.2 Update the Execute Function for Complex WHERE Clauses -- Modify `executeSELECTQuery` in `src/index.js` to evaluate multiple conditions in the `WHERE` clause. - -Here's an example implementation: - -```javascript -// src/index.js - -const parseQuery = require('./queryParser'); -const readCSV = require('./csvReader'); - -async function executeSELECTQuery(query) { - const { fields, table, whereClauses } = parseQuery(query); - const data = await readCSV(`${table}.csv`); - - // Apply WHERE clause filtering - const filteredData = whereClauses.length > 0 - ? data.filter(row => whereClauses.every(clause => { - // You can expand this to handle different operators - return row[clause.field] === clause.value; - })) - : data; - - // Select the specified fields - return filteredData.map(row => { - const selectedRow = {}; - fields.forEach(field => { - selectedRow[field] = row[field]; - }); - return selectedRow; - }); -} - -module.exports = executeSELECTQuery; -``` - -### 6.3 Update Tests for Complex WHERE Clauses -- Modify the tests in `tests/index.test.js` to include queries with complex WHERE clauses. - -Example test: - -```javascript -test('Parse SQL Query with Multiple WHERE Clauses', () => { - const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'sample', - whereClauses: [{ - "field": "age", - "operator": "=", - "value": "30", - }, { - "field": "name", - "operator": "=", - "value": "John", - }] - }); -}); - -test('Execute SQL Query with Multiple WHERE Clause', async () => { - const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John'; - const result = await executeSELECTQuery(query); - expect(result.length).toBe(1); - expect(result[0]).toEqual({ id: '1', name: 'John' }); -}); -``` - -> **💡Do it yourself:** Add test cases where the implementation might throw errors and make sure they are handled. - -- Verify if all 7 of the tests are working fine by running `npm test`. If not update the older tests to work with the new parser. diff --git a/docs/tutorials/07.md b/docs/tutorials/07.md deleted file mode 100644 index 54fe8687d..000000000 --- a/docs/tutorials/07.md +++ /dev/null @@ -1,76 +0,0 @@ -## Step 7: Handling Different Comparison Operators - -In this step we move further ahead from the realm on equalities to the realm of inequalities by implementing support for different comparison operators in our query parser. - -### 7.1 Update the Parser to Recognize Comparison Operators -- Modify `parseWhereClause` function to handle a variety of comparison operators (`=`, `!=`, `>`, `<`, `>=`, `<=`). -- The parser should identify the operator and split the condition accordingly. - -Example implementation: - -```javascript -// src/queryParser.js -function parseWhereClause(whereString) { - const conditionRegex = /(.*?)(=|!=|>|<|>=|<=)(.*)/; - return whereString.split(/ AND | OR /i).map(conditionString => { - const match = conditionString.match(conditionRegex); - if (match) { - const [, field, operator, value] = match; - return { field: field.trim(), operator, value: value.trim() }; - } - throw new Error('Invalid WHERE clause format'); - }); -} -``` - -### 7.2 Update the Execute Function to Apply Different Operators -- Modify `executeSELECTQuery` in `src/index.js` to evaluate conditions using the identified operators. - -Example implementation: - -```javascript -// src/index.js -function evaluateCondition(row, clause) { - const { field, operator, value } = clause; - switch (operator) { - case '=': return row[field] === value; - case '!=': return row[field] !== value; - case '>': return row[field] > value; - case '<': return row[field] < value; - case '>=': return row[field] >= value; - case '<=': return row[field] <= value; - default: throw new Error(`Unsupported operator: ${operator}`); - } -} -``` -- Update the filteredData assignment to use the new `evaluateCondition` function. -```javascript - const filteredData = whereClauses.length > 0 - ? data.filter(row => whereClauses.every(clause => evaluateCondition(row, clause))) - : data; -``` - - -### 7.3 Update Tests for Different Comparison Operators -Modify the tests in `tests/index.test.js` to include queries with different comparison operators and run the tests using `npm test`. - -Example test: - -```javascript -// tests/index.test.js -test('Execute SQL Query with Greater Than', async () => { - const queryWithGT = 'SELECT id FROM sample WHERE age > 22'; - const result = await executeSELECTQuery(queryWithGT); - expect(result.length).toEqual(2); - expect(result[0]).toHaveProperty('id'); -}); - -test('Execute SQL Query with Not Equal to', async () => { - const queryWithGT = 'SELECT name FROM sample WHERE age != 25'; - const result = await executeSELECTQuery(queryWithGT); - expect(result.length).toEqual(2); - expect(result[0]).toHaveProperty('name'); -}); -``` - -> **💡Do it yourself:** Add negative test cases for the above implementation. \ No newline at end of file diff --git a/docs/tutorials/08.md b/docs/tutorials/08.md deleted file mode 100644 index 123aac444..000000000 --- a/docs/tutorials/08.md +++ /dev/null @@ -1,210 +0,0 @@ -## Step 8: Inner Join - -In this step we implement the `JOIN` functionality from SQL. - -### 8.1 Preparing CSV Files for INNER JOIN -- Rename `sample.csv` to `student.csv` -- Update the tests in `tests/index.test.js` to use `student.csv` instead of `sample.csv` and update the expected results accordingly. - -### 8.2 Create a new Enrollment CSV File -This setup gives us two CSV files: one for student information and another for their course enrollments. We can now use these files to demonstrate the INNER JOIN functionality in the next step. -Create a new file named `enrollment.csv` in the root of your project and add the following contents to it. - -```csv -student_id,course -1,Mathematics -1,Physics -2,Chemistry -3,Mathematics -``` - -### 8.3 Update the Parser to Handle JOIN Clauses -- Define what the parser should output for a `JOIN` query. -Assuming the following `JOIN` query: -```sql -SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id -``` -```json -{ - "fields": ["student.name", "enrollment.course"], - "table": "student", - "whereClauses": [], - "joinTable": "enrollment", - "joinCondition": { - "left": "student.id", - "right": "enrollment.student_id" - } -} -``` - -- When there is a `WHERE` clause it would be like this: -```sql -SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id WHERE student.name = John -``` - -```json -{ - "fields": ["student.name", "enrollment.course"], - "table": "student", - "whereClauses": [{ - "field": "student.name", - "operator": "=", - "value": "John" - }], - "joinTable": "enrollment", - "joinCondition": { - "left": "student.id", - "right": "enrollment.student_id" - } -} -``` - -Now, modify `queryParser.js` to parse `JOIN` clauses in the SQL query. -The parser should identify the tables and the join condition. - -Example implementation: - -```javascript -// src/queryParser.js - -function parseQuery(query) { - // First, let's trim the query to remove any leading/trailing whitespaces - query = query.trim(); - - // Initialize variables for different parts of the query - let selectPart, fromPart; - - // Split the query at the WHERE clause if it exists - const whereSplit = query.split(/\sWHERE\s/i); - query = whereSplit[0]; // Everything before WHERE clause - - // WHERE clause is the second part after splitting, if it exists - const whereClause = whereSplit.length > 1 ? whereSplit[1].trim() : null; - - // Split the remaining query at the JOIN clause if it exists - const joinSplit = query.split(/\sINNER JOIN\s/i); - selectPart = joinSplit[0].trim(); // Everything before JOIN clause - - // JOIN clause is the second part after splitting, if it exists - const joinPart = joinSplit.length > 1 ? joinSplit[1].trim() : null; - - // Parse the SELECT part - const selectRegex = /^SELECT\s(.+?)\sFROM\s(.+)/i; - const selectMatch = selectPart.match(selectRegex); - if (!selectMatch) { - throw new Error('Invalid SELECT format'); - } - - const [, fields, table] = selectMatch; - - // Parse the JOIN part if it exists - let joinTable = null, joinCondition = null; - if (joinPart) { - const joinRegex = /^(.+?)\sON\s([\w.]+)\s*=\s*([\w.]+)/i; - const joinMatch = joinPart.match(joinRegex); - if (!joinMatch) { - throw new Error('Invalid JOIN format'); - } - - joinTable = joinMatch[1].trim(); - joinCondition = { - left: joinMatch[2].trim(), - right: joinMatch[3].trim() - }; - } - - // Parse the WHERE part if it exists - let whereClauses = []; - if (whereClause) { - whereClauses = parseWhereClause(whereClause); - } - - return { - fields: fields.split(',').map(field => field.trim()), - table: table.trim(), - whereClauses, - joinTable, - joinCondition - }; -} -``` - -### 8.4 Update the Execute Function for INNER JOIN -Modify `executeSELECTQuery` in `src/index.js` to perform an `INNER JOIN` operation. Given that JOIN are generally performed before the where clause, we can apply the WHERE clause filtering after the JOIN operation. - -Example implementation: -```javascript -// src/index.js at executeSELECTQuery - -// Now we will have joinTable, joinCondition in the parsed query -const { fields, table, whereClauses, joinTable, joinCondition } = parseQuery(query); -let data = await readCSV(`${table}.csv`); - -// Perform INNER JOIN if specified -if (joinTable && joinCondition) { - const joinData = await readCSV(`${joinTable}.csv`); - data = data.flatMap(mainRow => { - return joinData - .filter(joinRow => { - const mainValue = mainRow[joinCondition.left.split('.')[1]]; - const joinValue = joinRow[joinCondition.right.split('.')[1]]; - return mainValue === joinValue; - }) - .map(joinRow => { - return fields.reduce((acc, field) => { - const [tableName, fieldName] = field.split('.'); - acc[field] = tableName === table ? mainRow[fieldName] : joinRow[fieldName]; - return acc; - }, {}); - }); - }); -} - -// Apply WHERE clause filtering after JOIN (or on the original data if no join) -const filteredData = whereClauses.length > 0 - ? data.filter(row => whereClauses.every(clause => evaluateCondition(row, clause))) - : data; -``` - -This would also require us to update the `SELECT` logic to handle the new `fields` format which should now work for both `SELECT` (`id`) and `SELECT JOIN` (`student.id`) queries. - -Sample implementation: -```javascript -// src/index.js at executeSELECTQuery - -filteredData.map(row => { - const selectedRow = {}; - fields.forEach(field => { - // Assuming 'field' is just the column name without table prefix - selectedRow[field] = row[field]; - }); - return selectedRow; -``` - -Verify if the results are as expected manually. - -```json -/* - result = [ - { 'student.name': 'John', 'enrollment.course': 'Mathematics' }, - { 'student.name': 'John', 'enrollment.course': 'Physics' }, - { 'student.name': 'Jane', 'enrollment.course': 'Chemistry' }, - { 'student.name': 'Bob', 'enrollment.course': 'Mathematics' } - ] -*/ -``` - -### 8.5 Update Tests for INNER JOIN - -Modify the tests in `tests/index.test.js` to include tests for `INNER JOIN` queries. Add these 4 tests: - -```javascript -test('Parse SQL Query with INNER JOIN', async () => {/*implement*/}); -test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {/*implement*/}); -test('Execute SQL Query with INNER JOIN', async () => {/*implement*/}); -test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {/*implement*/}); -``` - -Make sure the tests pass. If you are unsure take a peek at the tests in the `08` commit. - -> **💡Do it yourself:** Implement the tests mentioned in the code block above and also figure out negative test cases. diff --git a/docs/tutorials/09.md b/docs/tutorials/09.md deleted file mode 100644 index 86ca209ed..000000000 --- a/docs/tutorials/09.md +++ /dev/null @@ -1,131 +0,0 @@ -## Step 9: Implementing LEFT and RIGHT JOINs - -In this step we extend the `JOIN` functionality of our database to add support for `LEFT` and `RIGHT` joins as well. - -### 9.0 Update the CSV Files -- Update the CSV Files to include the following data: - -> `enrollment.csv` would become -```csv -student_id,course -1,Mathematics -1,Physics -2,Chemistry -3,Mathematics -5,Biology -``` - -and -> `student.csv` would become -```csv -id,name,age -1,John,30 -2,Jane,25 -3,Bob,22 -4,Alice,24 -``` - -This will ensure that that the `JOIN` queries can now have data that is not present in both tables. - -> 💡**Ask yourself**: Why was this update necessary? - - -### 9.1 Update the Parser to Recognize Different JOIN Types -- Modify `queryParser.js` to differentiate between `INNER JOIN`, `LEFT JOIN`, and `RIGHT JOIN`. Adjust the regex and logic to capture the type of JOIN. - -Updated `queryParser.js`: - -```javascript -// src/queryParser.js - -// ...existing code... - -function parseJoinClause(query) { - const joinRegex = /\s(INNER|LEFT|RIGHT) JOIN\s(.+?)\sON\s([\w.]+)\s*=\s*([\w.]+)/i; - const joinMatch = query.match(joinRegex); - - if (joinMatch) { - return { - joinType: joinMatch[1].trim(), - joinTable: joinMatch[2].trim(), - joinCondition: { - left: joinMatch[3].trim(), - right: joinMatch[4].trim() - } - }; - } - - return { - joinType: null, - joinTable: null, - joinCondition: null - }; -} - -// Update the parseQuery function to use parseJoinClause -// ...existing code... - -module.exports = { parseQuery, parseJoinClause }; -``` - -> 💡**Do it yourself**: Remember to update the `parseQuery` function to use the `parseJoinClause` function implemented above - -### 9.2 Updating the Execute Function for Different JOIN Types -- Modify `executeSELECTQuery` in `src/index.js` to handle `LEFT JOIN` and `RIGHT JOIN` alongside `INNER JOIN`. Implement `performLeftJoin` and `performRightJoin` functions to encapsulate the specific logic for these JOIN types. - -```javascript -// src/index.js - -// ...existing imports... - -// Helper functions for different JOIN types -function performInnerJoin(/* parameters */) { - // Logic for INNER JOIN - // ... -} - -function performLeftJoin(/* parameters */) { - // Logic for LEFT JOIN - // ... -} - -function performRightJoin(/* parameters */) { - // Logic for RIGHT JOIN - // ... -} - -async function executeSELECTQuery(query) { - const { fields, table, whereClauses, joinType, joinTable, joinCondition } = parseQuery(query); - let data = await readCSV(`${table}.csv`); - - // Logic for applying JOINs - if (joinTable && joinCondition) { - const joinData = await readCSV(`${joinTable}.csv`); - switch (joinType.toUpperCase()) { - case 'INNER': - data = performInnerJoin(data, joinData, joinCondition, fields, table); - break; - case 'LEFT': - data = performLeftJoin(data, joinData, joinCondition, fields, table); - break; - case 'RIGHT': - data = performRightJoin(data, joinData, joinCondition, fields, table); - break; - // Handle default case or unsupported JOIN types - } - } - - // ...existing code for WHERE clause and field selection... -} - -module.exports = executeSELECTQuery; -``` - -> 💡**Do it yourself**: Implement the `performInnerJoin`, `performLeftJoin`, `performRightJoin` and update the `executeSELECTQuery` function. - -### 9.3 Adding Tests for LEFT and RIGHT JOINs -- Given the number of tests that we will have, would be good to refactor them in separate files. Consider creating `csvReader.test.js`, `queryExecutor.test.js`, and `queryParser.test.js` files in the `tests` folder and segrate the tests accordingly. - -> 💡**Do it yourself**: Refactor tests - -The following tests should pass now - [Link to the Commit](https://github.com/ChakshuGautam/stylusdb-sql/commit/7d4877d09055da7ef63ee6f2321db2e3fa87ad24) \ No newline at end of file diff --git a/docs/tutorials/10.md b/docs/tutorials/10.md deleted file mode 100644 index 75f093b0a..000000000 --- a/docs/tutorials/10.md +++ /dev/null @@ -1,76 +0,0 @@ -## Step 10: Implementing GROUP BY and Aggregate Functions - -In this step we provide the much needed aggregation capabilities to our SQL engine by implementing support for `GROUP BY` and other aggregation functions. - -### 10.1 Update the Parser to Handle GROUP BY Clauses -- Modify `queryParser.js` to parse `GROUP BY` clauses in the SQL query. The parser should identify the fields to group by. - -Example snippet for updating `queryParser.js`: - -```javascript -// src/queryParser.js - -// ...existing code... - -function parseQuery(query) { - // ...existing parsing logic... - - // Updated regex to capture GROUP BY clause - const groupByRegex = /\sGROUP BY\s(.+)/i; - const groupByMatch = query.match(groupByRegex); - - let groupByFields = null; - if (groupByMatch) { - groupByFields = groupByMatch[1].split(',').map(field => field.trim()); - } - - return { - // ...existing parsed parts, - groupByFields - }; -} - -// ...remaining code... - -module.exports = { parseQuery, parseJoinClause }; -``` - -> 💡**Do it yourself**: Update the `parseQuery` function based on the hints in the above code snippet. - -### 10.2 Update the Execute Function to Apply GROUP BY and Aggregate Functions -- Modify `executeSELECTQuery` in `src/index.js` to perform grouping based on the `GROUP BY` clause and apply aggregate functions like `COUNT`, `SUM`, `AVG`, `MIN`, and `MAX`. - -Example snippet for updating `executeSELECTQuery`: -```javascript -// src/index.js - -// ...existing imports... - -// Helper function to apply GROUP BY and aggregate functions -function applyGroupBy(data, groupByFields, aggregateFunctions) { - // Implement logic to group data and calculate aggregates - // ... -} - -async function executeSELECTQuery(query) { - const { fields, table, whereClauses, joinType, joinTable, joinCondition, groupByFields } = parseQuery(query); - let data = await readCSV(`${table}.csv`); - - // ...existing logic for JOINs and WHERE clause... - - if (groupByFields) { - data = applyGroupBy(data, groupByFields, fields); - } - - // ...existing logic for field selection... -} - -module.exports = executeSELECTQuery; -``` - -> 💡**Do it yourself**: Implement the `applyGroupBy` function and update the `executeSELECTQuery` function based on the hints in the above code snippet. - -### 10.3 Add Tests for GROUP BY and Aggregate Functions -Update the test suite to include tests for queries using the `GROUP BY` clause and aggregate functions. [Commit for reference](https://github.com/ChakshuGautam/stylusdb-sql/commit/2df5a81650ce1f3846ec8e0b605aa2e7371dcf79) - -> 💡 **Do it yourself**: Think of both negative and positive scenarios and make sure to cover all cases. \ No newline at end of file diff --git a/docs/tutorials/11.md b/docs/tutorials/11.md deleted file mode 100644 index 02938ab60..000000000 --- a/docs/tutorials/11.md +++ /dev/null @@ -1,81 +0,0 @@ -## Step 11: Implementing ORDER BY Clause - -In this step we implement the functionality of ordering our records in a particular sequence by adding support for the `ORDER BY` SQL clause. - -### 11.1 Update the Parser to Handle ORDER BY Clauses -- Modify `queryParser.js` to parse `ORDER BY` clauses in the SQL query. The parser should identify the columns to order by and the sort direction (`ASC` or `DESC`). - -Example snippet for updating `queryParser.js`: -```javascript -// src/queryParser.js - -// ...existing code... - -function parseQuery(query) { - // ...existing parsing logic... - - // Updated regex to capture ORDER BY clause - const orderByRegex = /\sORDER BY\s(.+)/i; - const orderByMatch = query.match(orderByRegex); - - let orderByFields = null; - if (orderByMatch) { - orderByFields = orderByMatch[1].split(',').map(field => { - const [fieldName, order] = field.trim().split(/\s+/); - return { fieldName, order: order ? order.toUpperCase() : 'ASC' }; - }); - } - - return { - // ...existing parsed parts, - orderByFields - }; -} - -// ...remaining code... - -module.exports = { parseQuery, parseJoinClause }; -``` - -> 💡 **Do it yourself**: Update the `parseQuery` function to add support for `ORDER BY` clause with the help of hints in the above code snippet. - -> 💡 **Ask yourself**: Is there some scope of refactoring in the above code snippet? - - -### 11.2 Update the Execute Function to Apply ORDER BY Clause -- Modify `executeSELECTQuery` in `src/index.js` to sort the results based on the `ORDER BY` clause. - -```javascript -// src/index.js - -// ...existing imports and functions... - -async function executeSELECTQuery(query) { - const { fields, table, whereClauses, joinType, joinTable, joinCondition, groupByFields, orderByFields } = parseQuery(query); - let data = await readCSV(`${table}.csv`); - - // ...existing logic for JOINs, WHERE clause, and GROUP BY... - - if (orderByFields) { - data.sort((a, b) => { - for (let { fieldName, order } of orderByFields) { - if (a[fieldName] < b[fieldName]) return order === 'ASC' ? -1 : 1; - if (a[fieldName] > b[fieldName]) return order === 'ASC' ? 1 : -1; - } - return 0; - }); - } - - // ...existing logic for field selection... -} - -module.exports = executeSELECTQuery; -``` - -> 💡 **Do it yourself**: Update the `executeSELECTQuery` function to add support for `ORDER BY` clause with the help of hints in the above code snippet. - -### 11.3 Add Tests for ORDER BY Clause - -- Add tests for the `ORDER BY` clause. You can see the existing tests [here](https://github.com/ChakshuGautam/stylusdb-sql/commit/39efbc7d7a81296c58a31e5fe84224938f64bcf7) to do TDD. - -> 💡 **Ask yourself**: What is Test Drive Development? \ No newline at end of file diff --git a/docs/tutorials/12.md b/docs/tutorials/12.md deleted file mode 100644 index a3263ee6c..000000000 --- a/docs/tutorials/12.md +++ /dev/null @@ -1,71 +0,0 @@ -## Step 12: Implementing LIMIT Clause - -In this step we add support to fetch only a specific number of records as a result of the SQL Query by implementing the `LIMIT` clause. - -### 12.1 Update the Parser to Handle LIMIT Clauses -- Modify `queryParser.js` to parse `LIMIT` clauses in the SQL query. -The parser should identify the limit value. - -Example snippet for updating `queryParser.js`: - -```javascript -// src/queryParser.js - -// ...existing code... - -function parseQuery(query) { - // ...existing parsing logic... - - // Updated regex to capture LIMIT clause - const limitRegex = /\sLIMIT\s(\d+)/i; - const limitMatch = query.match(limitRegex); - - let limit = null; - if (limitMatch) { - limit = parseInt(limitMatch[1]); - } - - return { - // ...existing parsed parts, - limit - }; -} - -// ...remaining code... - -module.exports = { parseQuery, parseJoinClause }; -``` - -> 💡 **Do it yourself**: Update the `parseQuery` function to add support for `LIMIT` clause with the help of hints in the above code snippet. - -> 💡 **Ask yourself**: Is there some scope of refactoring in the above code snippet? - -### 12.2 Update the Execute Function to Apply LIMIT -Modify `executeSELECTQuery` in `src/index.js` to apply the `LIMIT` clause on the result set. -Example snippet for updating `executeSELECTQuery`: - -```javascript -// src/index.js - -// ...existing imports and functions... - -async function executeSELECTQuery(query) { - const { fields, table, whereClauses, joinType, joinTable, joinCondition, groupByFields, orderByFields, limit } = parseQuery(query); - let data = await readCSV(`${table}.csv`); - - // ...existing logic for JOINs, WHERE clause, GROUP BY, and ORDER BY... - - if (limit !== null) { - data = data.slice(0, limit); - } - - // ...existing logic for field selection... -} - -module.exports = executeSELECTQuery; -``` - -> 💡 **Do it yourself**: Update the `executeSELECTQuery` function to add support for `LIMIT` clause with the help of hints in the above code snippet. - -### 2.3 Add Tests for LIMIT Clause -- Update the test suite to include tests for queries using the `LIMIT` clause. [Commit for reference](https://github.com/ChakshuGautam/stylusdb-sql/commit/fd5ce77fd91e80655072fc6348d19d426fd12673) diff --git a/docs/tutorials/13.md b/docs/tutorials/13.md deleted file mode 100644 index 39ec2c803..000000000 --- a/docs/tutorials/13.md +++ /dev/null @@ -1,74 +0,0 @@ -## Step 13: Error Handling and Validation - -Every piece of software can error out and hence making it extremely crucial to handle errors and validate the data. We'll add support or error handling and validation in this step. - -### 3.1 Enhance Error Handling in Parser -- Update `parseQuery` function in `queryParser.js` to include more comprehensive error messages and checks. Ensure that it validates the structure of the SQL query and catches common syntax errors. - -Example updates for `queryParser.js`: - -```javascript -// src/queryParser.js - -// ...existing code... - -function parseQuery(query) { - try { - // ...existing parsing logic... - - // Include validation checks and throw errors with descriptive messages - if (!selectMatch) { - throw new Error("Invalid SELECT clause. Ensure it follows 'SELECT field1, field2 FROM table' format."); - } - // Add more checks as needed for JOIN, WHERE, GROUP BY, ORDER BY, and LIMIT - - return { - // ...existing parsed parts - }; - } catch (error) { - // Customize error message or log details if needed - throw new Error(`Query parsing error: ${error.message}`); - } -} - -// ...remaining code... - -module.exports = { parseQuery, parseJoinClause }; -``` - -> 💡 **Do it yourself**: Update the `parseQuery` function to add some level of error handling. - -### 13.2 Enhance Error Handling in Execute Function -- Update `executeSELECTQuery` function in `src/index.js` to handle errors gracefully. Catch errors during the execution process and provide informative messages. - -Example updates for `executeSELECTQuery`: - -```javascript -// src/index.js - -// ...existing imports and functions... - -async function executeSELECTQuery(query) { - try { - const { fields, table, whereClauses, joinType, joinTable, joinCondition, groupByFields, orderByFields, limit } = parseQuery(query); - - // ...existing logic for reading data and applying JOINs, WHERE, GROUP BY, ORDER BY, and LIMIT... - - // Return the final data or handle specific error cases - return data; - } catch (error) { - // Log error and provide user-friendly message - console.error("Error executing query:", error); - throw new Error(`Failed to execute query: ${error.message}`); - } -} - -module.exports = executeSELECTQuery; -``` - -> 💡 **Do it yourself**: Update the `executeSELECTQuery` to add some level of error handling. - -### 13.3 Update Tests to Cover Error Scenarios -- Add tests to cover error scenarios in the parser and execute function. Ensure that the error messages are as expected. [Commit for reference](https://github.com/ChakshuGautam/stylusdb-sql/commit/c2214a1a75de155786a54b353964235d8d17864a) - -Note that above is just an introduction and more detailed exceptions will be added later. \ No newline at end of file diff --git a/docs/tutorials/14.md b/docs/tutorials/14.md deleted file mode 100644 index d1422661e..000000000 --- a/docs/tutorials/14.md +++ /dev/null @@ -1,189 +0,0 @@ -## Step 14: Implementing DISTINCT Keyword -### 14.1 Update the Parser to Handle DISTINCT -- Modify parseQuery in `queryParser.js` to recognize the `DISTINCT` keyword in the SQL query. The parser should identify when `DISTINCT` is used and modify the parsed query accordingly. - -Example updates for queryParser.js: -```javascript -// src/queryParser.js - -// Find were to add this code -if (query.toUpperCase().includes('SELECT DISTINCT')) { - isDistinct = true; - query = query.replace('SELECT DISTINCT', 'SELECT'); -} -``` - -### 14.2 Update the Execute Function to Apply DISTINCT -Modify `executeSELECTQuery` in `src/index.js` to apply the DISTINCT keyword, removing duplicates from the result set. -Example updates for `executeSELECTQuery`: - -```javascript -// src/index.js - -// Find were to add this code -if (isDistinct) { - data = [...new Map(data.map(item => [fields.map(field => item[field]).join('|'), item])).values()]; -} - -module.exports = executeSELECTQuery; -``` - -### 14.3 Add Tests for DISTINCT Keyword -Update the `enrollment.csv` to include `5,Physics,` and `student.csv` to include `5,Jane,22`. This will ensure the following tests pass now. - -```javascript -test('Parse SQL Query with Basic DISTINCT', () => { - const query = 'SELECT DISTINCT age FROM student'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['age'], - table: 'student', - isDistinct: true, - whereClauses: [], - groupByFields: null, - joinType: null, - joinTable: null, - joinCondition: null, - orderByFields: null, - limit: null, - hasAggregateWithoutGroupBy: false - }); -}); - -test('Parse SQL Query with DISTINCT and Multiple Columns', () => { - const query = 'SELECT DISTINCT student_id, course FROM enrollment'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['student_id', 'course'], - table: 'enrollment', - isDistinct: true, - whereClauses: [], - groupByFields: null, - joinType: null, - joinTable: null, - joinCondition: null, - orderByFields: null, - limit: null, - hasAggregateWithoutGroupBy: false - }); -}); - -test('Parse SQL Query with DISTINCT and WHERE Clause', () => { - const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['course'], - table: 'enrollment', - isDistinct: true, - whereClauses: [{ field: 'student_id', operator: '=', value: '"1"' }], - groupByFields: null, - joinType: null, - joinTable: null, - joinCondition: null, - orderByFields: null, - limit: null, - hasAggregateWithoutGroupBy: false - }); -}); - -test('Parse SQL Query with DISTINCT and JOIN Operations', () => { - const query = 'SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['student.name'], - table: 'student', - isDistinct: true, - whereClauses: [], - groupByFields: null, - joinType: 'INNER', - joinTable: 'enrollment', - joinCondition: { - left: 'student.id', - right: 'enrollment.student_id' - }, - orderByFields: null, - limit: null, - hasAggregateWithoutGroupBy: false - }); -}); - -test('Parse SQL Query with DISTINCT, ORDER BY, and LIMIT', () => { - const query = 'SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['age'], - table: 'student', - isDistinct: true, - whereClauses: [], - groupByFields: null, - joinType: null, - joinTable: null, - joinCondition: null, - orderByFields: [{ fieldName: 'age', order: 'DESC' }], - limit: 2, - hasAggregateWithoutGroupBy: false - }); -}); - -test('Parse SQL Query with DISTINCT on All Columns', () => { - const query = 'SELECT DISTINCT * FROM student'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['*'], - table: 'student', - isDistinct: true, - whereClauses: [], - groupByFields: null, - joinType: null, - joinTable: null, - joinCondition: null, - orderByFields: null, - limit: null, - hasAggregateWithoutGroupBy: false - }); -}); - -test('Basic DISTINCT Usage', async () => { - const query = 'SELECT DISTINCT age FROM student'; - const result = await executeSELECTQuery(query); - expect(result).toEqual([{ age: '30' }, { age: '25' }, { age: '22' }, { age: '24' }]); -}); - -test('DISTINCT with Multiple Columns', async () => { - const query = 'SELECT DISTINCT student_id, course FROM enrollment'; - const result = await executeSELECTQuery(query); - // Expecting unique combinations of student_id and course - expect(result).toEqual([ - { student_id: '1', course: 'Mathematics' }, - { student_id: '1', course: 'Physics' }, - { student_id: '2', course: 'Chemistry' }, - { student_id: '3', course: 'Mathematics' }, - { student_id: '5', course: 'Biology' }, - { student_id: '5', course: 'Physics' } - ]); -}); - -// Not a good test right now -test('DISTINCT with WHERE Clause', async () => { - const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"'; - const result = await executeSELECTQuery(query); - // Expecting courses taken by student with ID 1 - expect(result).toEqual([{ course: 'Mathematics' }, { course: 'Physics' }]); -}); - -test('DISTINCT with JOIN Operations', async () => { - const query = 'SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id'; - const result = await executeSELECTQuery(query); - // Expecting names of students who are enrolled in any course - expect(result).toEqual([{ "student.name": 'John' }, { "student.name": 'Jane' }, { "student.name": 'Bob' }]); -}); - -test('DISTINCT with ORDER BY and LIMIT', async () => { - const query = 'SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2'; - const result = await executeSELECTQuery(query); - // Expecting the two highest unique ages - expect(result).toEqual([{ age: '30' }, { age: '25' }]); -}); -``` - -Update all the others to ensure they pass as well. \ No newline at end of file diff --git a/docs/tutorials/15.md b/docs/tutorials/15.md deleted file mode 100644 index 8a5831cc1..000000000 --- a/docs/tutorials/15.md +++ /dev/null @@ -1,141 +0,0 @@ -## Step 15: Adding Support for LIKE Operator -### 15.1 Update the Parser to Handle LIKE Clauses -Modify `parseQuery` in `queryParser.js` to recognize `LIKE`` conditions in the `WHERE`` clause. - -The parser should be capable of identifying LIKE patterns within the query. -Example updates for queryParser.js: - -```javascript -if (conditionString.includes(' LIKE ')) { - const [field, , pattern] = conditionString.split(/\sLIKE\s/i); - return { field: field.trim(), operator: 'LIKE', value: pattern.trim() }; -} -``` - -### 15.2 Update the Execute Function to Apply LIKE Conditions -Modify `executeSELECTQuery` in `src/index.js` to filter data using the LIKE operator. -Example updates for `executeSELECTQuery`: - -```javascript -// Inside operator matching logic -if (clause.operator === 'LIKE') { - // Transform SQL LIKE pattern to JavaScript RegExp pattern - const regexPattern = '^' + clause.value.replace(/%/g, '.*') + '$'; - return new RegExp(regexPattern, 'i').test(row[clause.field]); -} -``` - -### 15.3 Add Tests for LIKE Operator -Make sure the following test passes now. - -```javascript -test('Parse SQL Query with LIKE Clause', () => { - const query = "SELECT name FROM student WHERE name LIKE '%Jane%'"; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['name'], - table: 'student', - whereClauses: [{ field: 'name', operator: 'LIKE', value: '%Jane%' }], - isDistinct: false, - groupByFields: null, - joinType: null, - joinTable: null, - joinCondition: null, - orderByFields: null, - limit: null, - hasAggregateWithoutGroupBy: false - }); -}); - -test('Parse SQL Query with LIKE Clause and Wildcards', () => { - const query = "SELECT name FROM student WHERE name LIKE 'J%'"; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['name'], - table: 'student', - whereClauses: [{ field: 'name', operator: 'LIKE', value: 'J%' }], - isDistinct: false, - groupByFields: null, - joinType: null, - joinTable: null, - joinCondition: null, - orderByFields: null, - limit: null, - hasAggregateWithoutGroupBy: false - }); -}); - -test('Parse SQL Query with Multiple LIKE Clauses', () => { - const query = "SELECT name FROM student WHERE name LIKE 'J%' AND age LIKE '2%'"; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['name'], - table: 'student', - whereClauses: [ - { field: 'name', operator: 'LIKE', value: 'J%' }, - { field: 'age', operator: 'LIKE', value: '2%' } - ], - isDistinct: false, - groupByFields: null, - joinType: null, - joinTable: null, - joinCondition: null, - orderByFields: null, - limit: null, - hasAggregateWithoutGroupBy: false - }); -}); - -test('Parse SQL Query with LIKE and ORDER BY Clauses', () => { - const query = "SELECT name FROM student WHERE name LIKE '%e%' ORDER BY age DESC"; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['name'], - table: 'student', - whereClauses: [{ field: 'name', operator: 'LIKE', value: '%e%' }], - orderByFields: [{ fieldName: 'age', order: 'DESC' }], - isDistinct: false, - groupByFields: null, - joinType: null, - joinTable: null, - joinCondition: null, - limit: null, - hasAggregateWithoutGroupBy: false - }); -}); - -test('Execute SQL Query with LIKE Operator for Name', async () => { - const query = "SELECT name FROM student WHERE name LIKE '%Jane%'"; - const result = await executeSELECTQuery(query); - // Expecting names containing 'Jane' - expect(result).toEqual([{ name: 'Jane' }, { name: 'Jane' }]); -}); - -test('Execute SQL Query with LIKE Operator and Wildcards', async () => { - const query = "SELECT name FROM student WHERE name LIKE 'J%'"; - const result = await executeSELECTQuery(query); - // Expecting names starting with 'J' - expect(result).toEqual([{ name: 'John' }, { name: 'Jane' }, { name: 'Jane' }]); -}); - -test('Execute SQL Query with LIKE Operator Case Insensitive', async () => { - const query = "SELECT name FROM student WHERE name LIKE '%bob%'"; - const result = await executeSELECTQuery(query); - // Expecting names 'Bob' (case insensitive) - expect(result).toEqual([{ name: 'Bob' }]); -}); - -test('Execute SQL Query with LIKE Operator and DISTINCT', async () => { - const query = "SELECT DISTINCT name FROM student WHERE name LIKE '%e%'"; - const result = await executeSELECTQuery(query); - // Expecting unique names containing 'e' - expect(result).toEqual([{ name: 'Jane' }, { name: 'Alice' }]); -}); - -test('LIKE with ORDER BY and LIMIT', async () => { - const query = "SELECT name FROM student WHERE name LIKE '%a%' ORDER BY name ASC LIMIT 2"; - const result = await executeSELECTQuery(query); - // Expecting the first two names alphabetically that contain 'a' - expect(result).toEqual([{ name: 'Alice' }, { name: 'Jane' }]); -}); -``` diff --git a/docs/tutorials/16.md b/docs/tutorials/16.md deleted file mode 100644 index bca0cf6d2..000000000 --- a/docs/tutorials/16.md +++ /dev/null @@ -1,52 +0,0 @@ -## Step 16: Adding CI Support - -Let's add continuous integration (CI) support in our application using `GitHub actions` so that it auto runs the test on each commit to github and let's us know if something is off or is failing. -> **💡Do it yourself**: Read more about CI/CD. - -### 16.1 Setup directory -The code for Github Actions CI/CD resides inside the `.github/workflows` folder at the root of your project (github repository). - -Create the folder either using the GUI of your editor/file manager or you can follow the steps below to create it using the command line. - -```bash -cd /path/to/your/project/root -mkdir .github/workflows -``` - -### 16.2 Create a `tests.yml` file - -Create a file named `tests.yml` in the `.github/workflows` directory and paste the below configuration. - -```yaml -name: Run Tests - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - build: - - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [14.x, 16.x, 18.x] - - steps: - - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - - run: npm i - - run: npm test -``` - -### 16.3 Commit to github and see the tests passing - -Commit this folder to your github repository which you must have created to submit your assignment and you will see the tests passing. - -> **💡Do it yourself**: Look into toolings like `husky`. \ No newline at end of file diff --git a/docs/tutorials/17.md b/docs/tutorials/17.md deleted file mode 100644 index f88a18871..000000000 --- a/docs/tutorials/17.md +++ /dev/null @@ -1,60 +0,0 @@ -## Basic INSERT Statement Support -In this exercise we will just support staments of the following format `INSERT INTO grades (student_id, course, grade) VALUES ('4', 'Physics', 'A')`. - -### 17.1 Update the Query Parser -Add a function called `parseINSERTQuery` to the `queryParser.js` file. This function should take a query string as input and return an object with the following structure: - -```javascript -{ - type: 'INSERT', - table: 'grades', - columns: [ 'student_id', 'course', 'grade' ], - values: [ "'4'", "'Physics'", "'A'" ] -} -``` - -### 17.2 Update the Query Executer -Add a function called `executeINSERTQuery` to the `queryExecutor.js` file. This function should take a query object as input and insert the data into the CSV file. The function should return a promise that resolves to the number of rows inserted. - - -### 17.3. Make sure the following test passes - -Create this test in a file called `tests/insertExecuter.test.js` - -```javascript -const { executeINSERTQuery } = require('../src/queryExecutor'); -const { readCSV, writeCSV } = require('../src/csvReader'); -const fs = require('fs'); - -// Helper function to create grades.csv with initial data -async function createGradesCSV() { - const initialData = [ - { student_id: '1', course: 'Mathematics', grade: 'A' }, - { student_id: '2', course: 'Chemistry', grade: 'B' }, - { student_id: '3', course: 'Mathematics', grade: 'C' } - ]; - await writeCSV('grades.csv', initialData); -} - -// Test to INSERT a new grade and verify -test('Execute INSERT INTO Query for grades.csv', async () => { - // Create grades.csv with initial data - await createGradesCSV(); - - // Execute INSERT statement - const insertQuery = "INSERT INTO grades (student_id, course, grade) VALUES ('4', 'Physics', 'A')"; - await executeINSERTQuery(insertQuery); - - // Verify the new entry - const updatedData = await readCSV('grades.csv'); - const newEntry = updatedData.find(row => row.student_id === '4' && row.course === 'Physics'); - console.log(updatedData) - expect(newEntry).toBeDefined(); - expect(newEntry.grade).toEqual('A'); - - // Cleanup: Delete grades.csv - fs.unlinkSync('grades.csv'); -}); -``` - -Note that there is some refactoring also done in this step which is reflected in the above test case. Make sure you make relevant changes to your code as well. \ No newline at end of file diff --git a/docs/tutorials/18.md b/docs/tutorials/18.md deleted file mode 100644 index 75151ca75..000000000 --- a/docs/tutorials/18.md +++ /dev/null @@ -1,81 +0,0 @@ -## Step 18: Implementing DELETE Statement Support - -### 18.1 Update the Parser to Handle DELETE Statements -Modify `queryParser.js` to recognize `DELETE FROM` statements. -The parser should identify the table name and conditions for deletion. - -It should return an object with the following structure: -```javascript -{ - type: 'DELETE', - table: 'grades', - whereClauses: [ - { column: 'student_id', operator: '=', value: "'4'" }, - { column: 'course', operator: '=', value: "'Physics'" } - ] -} -``` - -### 18.2 Update the Executer to Handle DELETE Statements - -```javascript -// src/queryExecutor.js - -async function executeDELETEQuery(query) { - const { table, whereClauses } = parseDeleteQuery(query); - let data = await readCSV(`${table}.csv`); - - if (whereClauses.length > 0) { - // Filter out the rows that meet the where clause conditions - // Implement this. - } else { - // If no where clause, clear the entire table - data = []; - } - - // Save the updated data back to the CSV file - await writeCSV(`${table}.csv`, data); - - return { message: "Rows deleted successfully." }; -} - -module.exports = { executeSELECTQuery, executeINSERTQuery, executeDELETEQuery }; -``` - -### 18.3 Make sure the following test passes - -Create this test in a file called `tests/deleteExecuter.test.js` - -```javascript -const { executeDELETEQuery } = require('../src/queryExecutor'); -const { readCSV, writeCSV } = require('../src/csvReader'); -const fs = require('fs'); - -// Helper function to create courses.csv with initial data -async function createCoursesCSV() { - const initialData = [ - { course_id: '1', course_name: 'Mathematics', instructor: 'Dr. Smith' }, - { course_id: '2', course_name: 'Chemistry', instructor: 'Dr. Jones' }, - { course_id: '3', course_name: 'Physics', instructor: 'Dr. Taylor' } - ]; - await writeCSV('courses.csv', initialData); -} - -// Test to DELETE a course and verify -test('Execute DELETE FROM Query for courses.csv', async () => { - // Create courses.csv with initial data - await createCoursesCSV(); - - // Execute DELETE statement - const deleteQuery = "DELETE FROM courses WHERE course_id = '2'"; - await executeDELETEQuery(deleteQuery); - - // Verify the course was removed - const updatedData = await readCSV('courses.csv'); - const deletedCourse = updatedData.find(course => course.course_id === '2'); - expect(deletedCourse).toBeUndefined(); - - // Cleanup: Delete courses.csv - fs.unlinkSync('courses.csv'); -}); -``` diff --git a/docs/tutorials/19.md b/docs/tutorials/19.md deleted file mode 100644 index 12aee546e..000000000 --- a/docs/tutorials/19.md +++ /dev/null @@ -1,105 +0,0 @@ -## Step 19: CLI Integration -### 19.1 Create a Basic CLI for the SQL Engine -We'll use Node.js to create a simple CLI that takes SQL commands as input and displays the results. Node's `readline` module can be used for input, and console logging can display the results. - -- *Setup a New CLI File*: Create a new file `cli.js` in your project. -- *Implement Basic Command Line Interface*: - -Example implementation in cli.js: - -```javascript -const readline = require('readline'); -const { executeSELECTQuery, executeINSERTQuery, executeDELETEQuery } = require('./queryExecutor'); - -const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout -}); - -rl.setPrompt('SQL> '); -console.log('SQL Query Engine CLI. Enter your SQL commands, or type "exit" to quit.'); - -rl.prompt(); - -rl.on('line', async (line) => { - if (line.toLowerCase() === 'exit') { - rl.close(); - return; - } - - try { - // Execute the query - do your own implementation - }catch (error) { - console.error('Error:', error.message); - } - - rl.prompt(); -}).on('close', () => { - console.log('Exiting SQL CLI'); - process.exit(0); -}); -``` - -- *Running the CLI*: Users can run this CLI by executing node cli.js in their command line `node src/cli.js`. -It should look something like this: - - - -- *Interacting with the CLI*: Users can type SQL commands directly into the CLI. The CLI will then use the appropriate function (`SELECT`, `INSERT`, or `DELETE`) to execute the command and display the results. - -### 19.2 Make sure the following test passes - -Create this test in a file called `tests/cli.test.js` - -```javascript -const child_process = require('child_process'); -const path = require('path'); - -test('DISTINCT with Multiple Columns via CLI', (done) => { - const cliPath = path.join(__dirname, '..', 'src', 'cli.js'); - const cliProcess = child_process.spawn('node', [cliPath]); - - let outputData = ""; - cliProcess.stdout.on('data', (data) => { - outputData += data.toString(); - }); - - cliProcess.on('exit', () => { - // Define a regex pattern to extract the JSON result - const cleanedOutput = outputData.replace(/\s+/g, ' '); - - const resultRegex = /Result: (\[.+\])/s; - const match = cleanedOutput.match(resultRegex); - // Fix JSON outputput - match[1] = match[1].replace(/'/g, '"').replace(/(\w+):/g, '"$1":'); - - if (match && match[1]) { - // Parse the captured JSON string - const results = JSON.parse(match[1]); - - // Validation logic - expect(results).toEqual([ - { student_id: '1', course: 'Mathematics' }, - { student_id: '1', course: 'Physics' }, - { student_id: '2', course: 'Chemistry' }, - { student_id: '3', course: 'Mathematics' }, - { student_id: '5', course: 'Biology' }, - { student_id: '5', course: 'Physics' } - ]); - console.log("Test passed successfully"); - } else { - throw new Error('Failed to parse CLI output'); - } - - done(); - }); - - // Introduce a delay before sending the query - setTimeout(() => { - cliProcess.stdin.write("SELECT DISTINCT student_id, course FROM enrollment\n"); - setTimeout(() => { - cliProcess.stdin.write("exit\n"); - }, 1000); // 1 second delay - }, 1000); // 1 second delay -}); -``` diff --git a/docs/tutorials/20.md b/docs/tutorials/20.md deleted file mode 100644 index db85de5bd..000000000 --- a/docs/tutorials/20.md +++ /dev/null @@ -1,13 +0,0 @@ -## Step 20: Publish Your Package to NPM -- Add a Shebang Line: Ensure the first line of your cli.js file starts with a shebang line that specifies the path to the Node.js interpreter. This line is crucial for letting the system know that the script should be run with Node.js. -- Make sure everything is perfect on the package.json. See the additional commands added for CLI to work. Test this locally with `npm link` and running the command. -- *Update the Version*: Update the version in package.json. -- *Create an npm Account*: If you don't have an npm account, create one at npmjs.com. -- *Update the Readme*: Update the Readme to include the commands that you would want to show up on npmjs.com. -- *Login to npm*: In your terminal, log in to npm using npm login and enter your credentials. -- *Publish the Package*: - - Run `npm publish` in your project directory. - - Ensure there are no errors in the output, and your package should now be live on npm. -- *Verify Publication*: - - Check your package on the npm website - https://www.npmjs.com/package/stylusdb-sql. - - Try installing it in a separate project using `npm install stylusdb-sql` \ No newline at end of file diff --git a/docs/tutorials/assets/tutorial-19.gif b/docs/tutorials/assets/tutorial-19.gif deleted file mode 100644 index 67405f195c168ab3103f963e41bf01c127fc6670..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1135294 zcmW(*cQoA3*ZyFMB}9*!D698g5~5pOuzHIgRtZ4}!s;cmYV=-LXZ7BDjj&pXk|3f> zL^k&QzP~y1$DDg+=H7GW&fI&Sc{DWDWn^DS5qjhOehmEAAOHXb05||30RRmE7y!Wj zPYQtmPzV5r07wXch5#4{fc@W82o!)q0XP&uLIE@sz(4`)|JFm`02B_u;Q$g2py2=p z4q*ScDFg{XkpLVCAdvtX31E-__J5inXaI@^;AjAe2GD2#g9fnwQxCxaPz(Ua07wjg z#sC-$fc>9M5G(-20&pyV!~$q6fWZRT|2Gr{0bo!71_xkB0EPx&7yyO^U;qRLfxw^; z7#spaLSSeJ3#cd!;o+o8VFPxi-7@H7z7K0VqtJB42gxIu`mo4hQ-1F00jY1Pyhu7P)GoU22dCP zg#}Om1OfugWb6aYs-;3y~@ z1&5=Ma1JmOq5uE~0dP#fe5`#lya2N~@i@^a{90ZGlVsUUR4vEE~u{aDC zhsEO9aHM)_#zrbi25MqLA_REcS^fq${PlXdGJ6dF_YC{+32pnK3+q4%q_ov(&Dw$Z+kkc zi)}mmGT?P-WApTn_wHoQV;Ay&9lm>?$~5YeLjL+4ZM9h9=4M%*{yEzp33z<^ulw(> zv(+hE{jFf^?a|M>?->cwR)(=()a#qPMAh z5zXv*@FIpal*c|6lH_V1$CF=aA1_dMV4on;%j1wJG3)B^Ugk@sL(RV;87uy<7>AUBQ znPn;Jla=Kk^p1EdGCeI0D@qVrM`abx7DuSc>?6KvR4b08y0U4R@kcFsXYH`M_1n>p zx@LTLid4KWV_S`cbWaMs%!)O58t<{Y7dB3)TQcWQ{#veS`6QH6i{3KP_GtSTr7hIH zkzMWCd7RW$*Yz`q$*beCnDn&gVn@5a_t&={r@gpemV5o`RB-PB;>R`KgZG7xy@x2C z3A`Gn(TBepp|`DhHOlODEIK+z$9OT${!!;*f~z9&Vv?_I`eI6G?EdAn*ow~OjMVqU z%UQX5Brhrlj~GF!Dwin!d1%F&(E?a>2Kfo3B#&GI8+b@An7O}hS=PEI@3-RMvH5y= zfUB1F^9yM{|9YD?5C2uWF^{WyuV(At3qC{gZR>&SxJ~IVZ?|-RZ!w(nd-fOWmcQu( zq-Sq-V}$eDJyT3g{_Ll@DE#@B;U0SOwHkKP{wCAcMsBCTl)E#uI`!mFSLKjG&{30$ z-rJtSb(^;*-CLgRr;WSh*yFAT^<8HpCBM%vSfuB$m$MoV{#`Aa>i@f5cKPt{*IK~b zzu#Zn$1iW>Q$L8g?UmTx-F|D!^ygWp&FMI0tKx{%~?MGSn)9DR~sCmq}E0HLJTVC`;vAE>iy|Ai-9 zUd|`!A>O{y{j5ku_QlurDv2Pe#wbB#czS|k89(KYmWdXgsAId6eQ5*OirkSjPj#A( zC=1|)D~TGmmpxt}fZFRdA;YXV*vkT^W=CSOqnk>(SKG%&bPYe?YYr;!#MZm0N9MjU zhKg`1Lk+VRMa%aflCo`&d=)RZKH-a4wL&kaQHIM)lm8iPL-xkXcN-MaQbfm(M+CFHI9B+l#kj zOil~kD}%WcE2kM4OhzQ`Jv5k6=#~ToVkDm^d;zFE&vFs*gVNnx?S$-R1*>flg?x>R)u$4mqZfonE$$6 zPAOaR2&WEwQ853@!Wt#?R-C}nApWLop|M{M3DCpdsw8+z!~`54z%M%4Wq;(Fks_$M|O0s=8? z4ig-{nRzZW75F9|&~fG~s}bW3=2TKWRvx^hq$}@u`IrI%4aneM$2vc1603-y_J&C^ z&P3e3IiKHCP4`UdY0|bWO@d&(4r);0x8N{24M%E=5MGAi4nnP+mF$a-igvKY=@5o) zG>&F|l(c#j*({EX$H@lN5&p4G<(9TOQ9p4i-F91F%x**cvu*twWEmiAmVWnW1^zQH zlE=<6_gbL?ZX0^a$$zsT%oX@9U1(R`)3~JPEssY1$wG~O+7G+mx630*e!Iy%Kb-Zu zE=(kTAi8~+*M%B+kbMDZ zjPXm(PK`^JyVvw_0^U3{rlsPLk^b?>sabRDZ*doU=wzxOIzuVQs7<)FDnE2G=E^PE zyu`S{?W&@jOl+r!u_gA=e;Eps>xJ?Y+6ybsr`x0#Di+*!D<8`Kx>ang9U0+nm**6I zMP04U9JCGa?6u*<8F)Qu3D(XJ9V@b|HYjL{vHP1WY<&@=_I#A4$%n%y@#iu>Lz_2J zR6f~#c4lPfGT>9^N+|?&T^Yp;cpDbFD9*#kABK}bDN^QPn)5CX%((BF1?&5VMh^QB zw}#$Ih6&JxDQYn6KJ)`JxVAoqjygH_NE?zAzF?;}!2P!V70tC9^Nyh1@!J30Llc7) zN$b;Aje7%LQUQ_bGOsl&5OWI-Po<&^&7zFoM44npdF=37I#bwZc#7=%xJtNBlN^$HLyeaeS9)NbuckMIhvgk9rZUL}0XENP=XX=a($i6*Kl zQtKl2RmhdsIS{{XHbT8%cA3v9e{%#s6+_L_>3@JRkDO}(bUi@IvG`5Gv zs!RT&k~j#v*dKP~Qe}&9$|qo2@KChmm7+YanNml{)5TOOu|xtD3wc!wT8{MlgK4gG zZe%H`Yi;RTtLavM(rp+r?06~IB9QCJknMeiBNcAcb9*?T1 zAan6R2Ck5fk70392!_l^+01D3OmClb8_GB9m`okI7^J3}QnF(1poAKs+5kO`zZtIu zSc0%LD4z%RaYFHsINNL@v&=l}fG5fDRs8oiQtvOaXw#HxILG4JAe9%n}$e^%}daWZRF z-X<9SuIM$-AZKmN}e7SiyoD{IZwJTo2S}|H091; zip$@vLh=XZ>c!_d|H(Lgng4^gz__#243%##SEhw3vzaV|krdbmmD#$LS(B817A?f@ zEO%Qghu@ZaGFEuYRrpv`ybh`$e_lk>SrN2W5qw(_%2*jDSBbEwj0~#Gc|j#KtjdGy zEK15QvRf)fF=Q)tmZYOfGP6sv*Gfc!O0p)ao~>17@SzHVs&d>=g-2BtTBvG9l$p82 zWMH{7V>vXw+)1vyDZcuJR(b1Mb#rG~Ur=>7V@)rry5Fs4FuQsvzGkGehFCfM4P&jp zTWa{X&|v|z@KWU&2AVWO4w#Bn?3*N$H4vf z;6w86#~D=3qps@5Z);{5ny6x&O*~yqeCtgjQ%z!jn<^;*NnECGjRvJ2 zFFUb_Np=|9d_21e16pv{nPs_lBO49vLTjy~b^fCDm|DoFK`;YCQ$?V@1zew|?bD<+ z2H~{ueicj=o})-|??(Sw3`7;m`15n!@olRoQ=9jbHXqBj*KgY-jR7)Xi*E% zZ)bi8m71{|!D_2!L-U*lMX4eYW25`i()Je-CMnzP26!fBno6=TTWv=Qc1ImD(#B%< zhEk@^vcC-#ObwOpoi$yZb=92>2@O^JUA0VIr0e`9c7zYZS}xcL>(Q32swDR{OzI^x zC|R`~&zb=Wyc9)}+BDGEU#&rYjj$+B4%VIS+Y_`Lwvz+2 z47X&Iw)}|Fp_OhD(yqCfs<|ZX6V-0MvFzim?mO4+yL0aopX&R~-;amw>wHewvEHVd zL-Cpa6_Ex}N*F*SO_Vbp8${IZnhvU0?M{XcII6igk(y9V$2t+(x|Xq1w`oyKv)+4X zGW2?otLCMHpG`)Yv%%XT!<-?R?jgC2p{Lj(j2j-Tq06qVLI`>$O& z!`}XuV{hJ$`R9(k=^hK(7&}I_1^=zv8Hr`w(0=%4z>%}t1$U*TKRP}tLBgQZQFPCw z@SzDj81lSfpa;}JqfFazHR!FQA~a3GdB0ba0(dx1k?!sdQw#ba+u5SsRnI@w`lF%c z{#0{tS9A4L@jf=1Hts6O-8!54vowyV9${-4a9(4`7d`d%2DSEs!7@ zE1kZn-pBBXdoJ1>c`hPwc2~|Za1*rdzKM^?(1Y_pdmJsGW!IsY`$?hulicQ~r~f`F zuq?@d>l_WojS`1VrehUZdwRQU*q-+MuTNE3Z$nAdn3TCHp z$m1?fll5n^A^{Xn3X0Fc&`V4Y-k(mfUQG*GZP%IZNnGukUd_o{O(k2)5M0xZ004?= z2F=gXnvIJcjpI7Vt&TaJ$+hW@`McctrjYekviUBL`Hq?OzMt!zEF1XN8-yMk%^Ycp z_;HGx8_NGSW?44pYb{J!GY+ZQQ6 zN`mTGqaD9#iV#x7y5xYV!*h6;yIm4xBrK-D?!CQMKzQL;+zA5qtZ)~|g zT?B1r-|lkS%#{^=cMb`RJZ8FQYD4>XVDflS<mr&1>S35)l?c0mPf zQ@z!FJ((VCLMY$ZI7IEp>g{gd?MNn_$=schKR&K4vko@V01sMAeN}Eqtp~|Jrs42MTtK3LwJ=`1`j>2d=5KILKcJCW*?HfP4HnF`ndmv9&*kzy3MPbdbdf(PD477k9 z(64Qgitf;{*ZJ^jf@3S}JVv?f%g3nhmd_Hu-CG&p1;43RE-1)`_VRy{C4LGHmG#Vp zP_Xz$_1;9!-Xv|^AaOU+(f#4aeCah5i2@fcx!Qd>o?4$V@jv6(mN^@ z9M9Ar&yfEkJ;5&Ej_17oeSY_E?QsbejtQtBTSwB&y8F)<7J^Nzevv+$=^plK4gL1W zraJr`h1C>&_`7fd=`5#Do9a=l+6^YNJD5s4^=aLot29i;)vwk z&8wWFk1ZfUAMmFiTe*Yd%5O;FYyp;3&#P?%cB+6I4`>ohS2T-$gUuHXY2A z3VwW)XTmdxs5S5NXR+MLSa!rorK7D4ONT#DN$n>M`uM{!BXN(V^O*xZ3|l+USGty8 zPqz&5A?AnKooTE7@o0@@H2fsuUVDjjB}o5~6A} zrpAqGbhfWW)#+W*8r2!S(4rd50ZWYze>n4%Tg5OJW%@R5C%|6W%&2{Cw{&rS1l6FNm#dOh+|S9Z75SMSM>;Y&UF%ROKH zXMaIg`bq?xuMJd4)vj;`YSd1zpKCBhT|L+2D0^+F&0mX_$zt4Sl3|P6rP1C|2zhV3 zqU`5otS{+AyJTXk^4U1j@#lomsWR#_%=$&hXGsgAJnv6>0rD*?=I>`(mS8Yi$#C1} zQFP{Z37r0BHr2WrYwm5ITP@vtW`0?|8sZFCdo?2{Z2@0!GPU-c^Lx1AU-tf?P0*=z z+n3kpApu*#f6`620&$$}Tj6AMGB3h@3d(Fp{ZqU78o}b3`8Ae5I&&vMdb!;pp@s9m z?;(kZgo%_!u|Jca44ktZKkjNV@DAAjnwCiaS=_O|XNoaaCkwExlli}}HH5*MRn z*?Yb0!~BnrZeLb-s9WHUDyuwikBVEOJKbt(e+B($=$Z{Wt{M?~;?eN=uG0g(5^X8r zA5xm5(e-2WuV)WTRnn{PHxbrrfPg#Ldx%s6>pep468vh6DF*xBoquOAenO*mX*eUg z+3h>~EI{11Y8=$_dQM+j-fzj&w8wARHbCAV9qx_VGDLh0zlVQI8YL)w8;tixLF#+BX}cy?hrPE{+;)BVPh8QxeB*E@!e{^X zQlU2TcK|)FV_etw8;5`5U!J|W!~M1e&cBNS)B;;%#AbHe)i=Y^0y~isvNb%(X^n@X6jyRQ)Hw*$M88^=hDh9-^Be^rd*^^Xf zt!c+dS2e1gI{T>C@~K+kVJVSOkg`}=?ZF#QDZ0zA)2xeG_U{me!@N!JV{9Ro z8~txuMLKH}9rhR*K4+>+W!Jv9dFsHta-c3Z_$tXixP*Q`Q$zgA^ADlN9FG^wGI`-I zSosmL$Q$au4&AxniwhV>2)CxH$)fU9_2-NDHhvu+h+;3P0k^(d!6BO})#5|#dC@V=m5mbT4_m=COSkdT;yht<0=R;Zf|$X!teKb?rukhK@> zSyFcU1_86;MB_gTNB z$_kZYG}U`-xi;Hs+_R!cmZR;xcw!XPliYAVoF=X?`YD(}uZlYKqP(cHhRGRerQDKLN2qN=Zklb_HKPrX)=(Rc*)yBqd!$xesqow2)Ov`N`*M;K zqBnzP#lBibKU%Hg*?A3<3UO|Vz0J;+BL%cXY$IG_DR?vI*hWBZHAyl2`u?94G}JiH zMhS9m4$C<^JK~U@1hC{_F+`P%?gt?w86h>q+HcH;gq9m) zodj^iY=1GMddp4eBQ=iVmS!{l8O;T-V<&m0wV4!ubex*tXpI3O>HSaduhZC-(&kgR zk5UC$1Gyz;G-)?TuH(eNvQPa7POp`hR)G&|jRsJIg6Dfk$!_P%rk9ox(1qLyc}G$A zYl^)05N--5DsxeMn~X*=wlAAxfL8I`sZAQ6#LI)AaD>gx-F;-lumcN@XI%bB8hJNz z8j82Eg{3p=C%O|x5aezXNM{Z_u?GCtUU@mEDCA7nx#>rO}kDI_Je3Gf1Jg&aO)7s^et_^ zCj<&-_@|$o^@cn68&}TFOXMF_!a~*XgH$;m8((MfCsoeWf&5g|hEt_IRhqn7etGUT zr)w)cM8E2zSm5>#)-eN*00Lsgu)i8Dvro97l63ak zxTI?{RNxh{NZ#>9b*BM$CRyrxRitykuq%tH8^Tte?v$}{k2;>yC@RV({)3;t?M9J(|5DWV|Ujr1tBM1TYoq2{Rde(@+A```+nQv zxgEh*m1cRkfc%wG_@?!))hx2t46F=5jNo^V*Kz;u_2a1f0Z2cdL_fZ2|0nZ|Qn}b1 z4(VmPQpl@}y{|pmImnnWg<=w5YN2nP<5{pulFNXsi)>LcUKsTtFGvybUndKGPY0*F zX=L^#Ku{~=)8x{Upy_s*QodNWF~c)x)A$k?ntUk*9NEg~CE7gJl^99an0bs zwgwty@WBV2t7NltWHWb_d5#AKuLebFhQ#gmSLBtfOI5sP$cp!|eWI>ik4Dw?;fy%M2R`0r$~zzbFA(`@y`VQoiw zE%dPJk}9)U&%BDffwBDj)UbiT$aCzl5k&sEl^RT^#{@EBrlV#qp;lZ}%77kXgufSL zjpEH5*i{^`gOf2w#xgCbF{_gE79u#!05&L})m|*v44?2u4TEeu{5m4Gjqu0~%Q|AB z4OZWkDdLD!H+rQ+Rz&MqliQ0=MQg0Vwp8Xu^K8GQcdTmcY-lWSX)JheEaYk|6g2*B zDH#c-;pHK`!wAYJBRU-zP6LU>wj+fK@d*{X7Q)AIVg~qxl?khbeVVBVQC31rZ$eWZ zLXSN}T}obj>2R4H`|lK*>t^buSei_9UdBdjnxZg6QzCCiALwd=05n-ZGg%0kERvWk z-rzAw*4P$Rcge!{IUA{fM5)FWTxrJY?eaQN5$k2AQ$nJIyw%yV@P*Gn!j&Mmjegz( z5DD>=;MYg7@iJBTRA5#@k7I-oPek(TC^1$-Aq>LX_W|btLa$K$0f>rl8`M;T&*nW) zejk7M>OUcZ4WsBMQBM@E@RN;@n>r(HJ5tIuN-PrrGE=3isY?+cly)VgQtVpXQz}5{ z7P<9)v?ts9L{W3wN+Kba%&*LK%OBX>X z=ySzRa~fzCnHliK>Tr$s@l$r|UV%ALB)qPKVyqD<#+s)55mGz^(%bm&k5zRxhX3rU z<|enW$b#gdarv%ejN8B@oICrv__AA@n+U2OwcPd_0jch={i3PuSn{nGO0!0@WxH z7I1g*`$%yl+4K}xvCHad(bpFSU}6Bg4U)!a6SgbAQ6YzjlwJ>3uhJ89_BR>H>HVO5 z4C1A@Y3SpXkug*HaKXBaqcBOP_#k-jgsHJlpRYX{^Pww##TvVES7{2I8`s4@C|x5D zzds)Bgo*LP#71G_(#>$T%81WR%{<8no%u)|VnQf!6c7DC1awZ5l~9xCp67O?hZ&XR zYNW|_v`ok+2y{soYR>5$_j@lILX6K#vGf}fqZ^wA;fc_r2NVTjfo;S;8UU*k#>o@G zNdYLP#S{DiBUq8o#p{d(BgERH#0tZ}+X&@s1lgNsZ1iD#H~4H6VXsqk*tYeB3oVL~ zVOo_4PLZgl-1WTJu626dYXBL}Q|Zw1zW;4sB5@c4Sz|H%0Fa4TQtcwLo)^mmczHM4 zFp;7_+y$N$O*J?!lZ?x!a>I<6b-N-xlRwU`v+O@RfAG&=$3>9{&{Wq!QqyvPI2w+K zmaYkut2NFwCyB0et)ti)5YapI<(f;k&XJq^rl$2h>dW`^F9&5`4ryD{-FSDQk2FO- z>5PK}WImOH5WEL!NLE6_@jk1LPauqrk}l}$HpuYc$z{~s4@Ki-9>Uaqtq6m#dK!Fl z*pv`GJ{9v;Ti#4Qj}>AwQV}b%vmKeRp-r5=4HMMix{nyJ0;rg%ctr@b%mkb6hq>tT z@gCrlMSa$4H@0^CkMIz-)I-Ke@gNCV*_i@b_iiQPirrfU5w$F^HfkAqM}!jt(maGz z^UGVZe4-SD&xxZ%42<5Wn%*gH{-Tc)tOkcQXLR!wx7eFvp`|-!)em-e#PL=Hvk<&f zbU5{#75k>xw_QD9KX~7<&~2W5bp-EjBKhg53Un9VUy*4T;R&BN4$5BXDHF||F6pW0 zIexQpJTcxoQ+0%f?m^4;v`)jOOtM)aMU92&%;7b!@@^yc|vaa3T_1%h9!3|r~5_793HAE8|gql@w6+kl@>(> zfBHqtU>>cd#}o5XamidLs`ssqArB#&lCuvqOmlq8dzi}b41Y3rAaVK`n-acO8UAQm z`d2mr!$Q7ainIpr$LsR!z`djS^g8I^Y0XTaIDVRMex8pa4Ci-@-G%8F;&a{LYxC#` z3{)SRjR#4U4qmsdSH94_PN!bOXa7?EAmZ!7^j!B|7)z6im#(hRjYFi_08V!v|J>=l zJ_&`8kp6XSam1$UPx=BOsmRa@({#kT2`j7^{8Qv=o^()D=RVT z9!u&ZnfN3I2rv>s+(N=@ply_i;8pAz+Xpe#8jxK_auEY~^RJvvKr_D(K6K}&YY+0r z-``1KT-Z8yFpGgo4;z(DrWg^j?-J0ji~5HbarJji)n3B(TooN%LCF4HQmoozM* zT;Mvf*-y^R7Lj%2nn}D8Wr)umE_rQ7{8B63$g)K}%QFyl@HnI*SIE#<1$xr?MAb{E zTO~eDxyYzQ^GEF$ov|z3l`FmPSNbbgcxF=01pmc+KJloq>PH&2`5=;G#VNKZA1L4h zd@zJY{ugl!G0{2uk%r!%{);$j2cICZ`*H0*dXH=yi~$!AJ|F9J6$!peL0IcFExx8{ zmQcFuW*FhW$)SwV>fH1JEaDCwIhhY=Z1&S7P50*55!qRm z1MUDUKu{ofHVT~YauL8vc19G`Kk!!49@%Z*#k~)q=IJN-)9?3y=d!7d zz2*t9^0nVLvrF#L_IK2&b1c)iRd&9u(7&w=2&#IvS6&}fS#Vp^7c_U_kj$W;sE8HH-aPERaTuFfSUFkt?qKWz zJ|kCx5DHM8tFR!X0Gt$JMG7p@q?eeLiJXZ;oc*hECQqpQzyi~?O1~m{RXN`M;t{*N zoi2^=W7?x~b+-dkx8jVu@3uz=eRqd0N5^fUN8j&CPeQxR$iN*Pv=ZtK-`p_BN9UXU zx@uOBAtVoL)YW{j&bj^Xq-UAhaIP=Ghj_89;IR7w&@;P8UF&ikWHD>p00RF35d}R6 z@4p~P!5a4l>40Emq*jcCdfP)k5a4AR2a4=#BUl_#92uwpAcako3tHG%tQQV_)2kYn z!Znb=0QO8#rrueIef}UR5=C7#Rl`k|l#9ClF_l79pE82F;@2v}%SWX(Ii-SXdHR9rMXk7b~tpNRsp^dOY{W zF zgY{0DIqo6GHt1*LZfMuf$Dd}qPI{*D z|DN_zzk7N%@}S`9#i%&0`*J~8_}|GAsqMe3RfoQR*Z)=PJr^4hTi7eb9ASyu@6`ng ze}8msDPT{h9zXkcxo-RHKdAIa!86?Vn1477K5;)DNkbUuX(1kUY(F7iL-_sRLIMur z0kBpBg4`#8CP?g|1eqI8$q%bTg&Wz$D51#WCq-Z*vq4%!T@>Us8?pJ#Aj2p{G)D~^ znOCI>-LyDN(qrzc(BoOc}T!nA9y5in`= z;i#Ki{ySJdWV!jn%|?a%C4)iOt&w>_8`kP9do>plZ#V@9#&}9N4RoV_DpRy*?5d2hWrfI`UvacE{-ib{K zitm>);DuLGPH0*b4s%M6jArRcavA3^z~Dj6sLk#pqcRi>W$%aDnC3GbxP{fbHCJ1* z{4k&5Gf|nuO%@Vy5EHq#5w>gD1$l2O6Mb;f^V#S33)RiA#8nv#h`lb1AQP~s)G`~Q z`&AeNgWEsmUmX=nYs~NyaC(@qI%SgaKJk!pO^OFkb2?olho0C*qbU=T*ovlD1u@t? z0YB>5=g-;3w~CLa#e9?E*NWA)g&>uZqtWfd@^!CL6E^nw+B&8~grL<%Mb|gqW#5cE zNaRtCUeRJxS)G}ntIPq3IU0~OZsPlHq(rV!jdd$ldbHOuiMB1JmH(<04n3{j!d?XQ z-Tf2}vt(FG%QU6(M@?F`vVz}3-cXmxdr$$27O_0xojQ0YFSAm%At1XR@@NqT=z3Zy zg&zd>*ye#YqZLKlaOn`(?p0Wmd&V_ryVWEP97qkUe?=V%ewT+L0)ux}Qo?CkW~$7G zv`nh&(kHa_#4OTtO}OQTuGfM-c*+*hi{Wc%&JNA&v zj{ApDxd6cdtX3jmURLEbR^k=z7M4@@)B7dus`OH+g`PIF0)&@x6|;)oq<+#xVO^f2 zgJ0FWLZpg74+4H$c=l?&(NvDlmC0-g)a@^lu0EP=vS_YNf;+#MF*p5Wv0Pmz>F6uJ zYQBE^xijgyK9J?uGQyd}Dic9O>5!uItZbA{XuQaB(4NroW~8h~#K>UXGQ3oFXe9*a z75JYIduSJOa@2`>o7Yf+B}N7mV|}R{txA8^eP7os{$0_?4z8dnU4Ip*-J#@RcR;n# zK_o0Q_@M4AQat!8xrQeN${^~MTkOJqGJf_SGT;w61YF^CuDJKlGqwM(VClFW)x}ea zbZJiR(hvzE!QSEH>-9QNns-5C%b zB5Cttv4HIZne88f6YZN+kurUiYY;t>{w+)A#%|Na({JagisZi=+T{n|b5p0_MiTdD zVzMr+i7vmlVVxEtLa!_odcHlWznw4na#^k~|Kr7n3h$uBK(9k|t6bhigpSfdZ8+MU zIb<`<2*WKBFY?gfkxRf3bhlwuB2Sv~>nnn_o5eYB$obJZ?Z?&`ZsFL*h1n8jhj&X! z>T~U%ci(PWK9;zGZPvxf!)?b3?)vMV)tztsz;5;72A6Tz^DW$;0xVu39#!GL=LxLl zN~&x`drpL2N-Ub&8E+0TEvwd5$-{x>j9%wCF$1O%gwW(0v+R(GM@3XzI5z6Z5$ezR z5y!AVxc2oqZ3|}7%IvGsQm%#oV&IpEWAh&?J1quLcaDG(>x7JpPID#jtH?tl&+o!v`& zgwo__N=(SgKR z_{H(;uH+dJM3LN)P)(x=k2XbdCp+`&daY_%*fQ%VZ93G>qS6GO#;_@1zxsKc72zNq z&(57x%o`8kOLBzfL!jl3d?}8+8Kv5-5S@H`ou*QqNyydwPSqj%%i$gR!Q#Lcjj%IX z{UeyK%vS3ey#kk$xH5;4mV=mygAsX&q~5Nvf)h-r%*ejXSe+B*Qw9riQWlL?QQXVG zg49?irWmMplR;f-U~>!0{CRM&)5!b4;U{$*HmxN#-#Beg%4~me+TE2o>O5RzNFbs6 zHr=rmm}~)0e(ZOHp#xUlY>q$3xc6xwA@+TKtG_w_CfJVTwC2QD9tT;M-c(hi- zvTg-F!nAYkoT=&p#b({R`}SHaT`POfzt>TB5%Q*ZPb;1~Aju_Q77`fb@+SX#Ksk3% z6F2P5{SY(ej_!iFmW`if_r_!sB3j1Y;Bl5`CG-TA`)*`8@332)uq$0XvYIj1zhKAu zO+O8FGEsJlvMG!5+>b&yMf>kZhgL>MSH{HiM5R=kB=NMUj#^C;UQ3oo6m3{SwxFf^ ziSn!zXeXUSCX-muq9~y!>|4w^)0e}jq~f)oU}rln9B+zHRf-gEszOyNn?{eK6R@_^8;hns>y;ZrRym_-PL*h0| zGC$J5cOQo`1;?>Yeywa#!&vA=CcZf2GLC9xu>Z~J>eFjBeqJ8s^l|^?H-b<`_vaY( zTVwyaioj5}z-UxZr_0+x?y4YEWiNMS5~`~82!(P(WgNktKG0v|sQQ}!p=fl}+PTDr z%UhBZyu$}ScZM@$-IL>bGh+9$aFy=tMPt4NzJzlLt+UcLtrC2od6GNYlRw6XKepI4 z4)G%{n!h8dy2IbKqxeThP<0%t+OFq*Bb~i^4Q{`ikECZ7Rb;kjzQn0qH|~Gb9cAf5U`ZX}HkA|i$K-S}<@lx^fB#!?lou=X;~Utlb>W-MA@JgH_} zVVng4et*RUse@~fu(Rfa3X0+7jyB15FFoqwy2(jqiutO0Q8lA{bAxVk_&=-YYOAS! zE|AwQk_djf6F@~S2=h5DDIYAY9ntXdEK@nPdH!rG=kJQI?h374@$u-2|Jj)$h{^WA z6#vBVElpv@2l;9?Mg=!#Yd4n#zkK=m%I`f5KJs&lz;*_Fo4jtDPU!2Sy04G+#Ch%K zPT=f9wV$Ls=GBGv_3HK+Yv*h{7qx`GvEw|x`3vp2d45aD(yy@)vMC#BEnce=TF>`b z>GWJ}Jz48LIUW`I*>v)AQs`t&=rsTNm%F+z`1NN*!sq1m=X9s)YRojr)H_mMJ95HT z3iVg&!q<9U{2|tuS0~?0gbv(JzkAjn1l8R{d;azjzRB>qNjd#fclx{4tJF1;)>!%H zwdeYx@Ns$V$v3Z)llp(lLU$LZxL>CyL?U=AUU*xlZUTjZY^Uc^A_UJG2sA`M`VAoN zQEF?vOAD`S&jz9Zk$dkN?!|}@KN(*!AHe@qcH8Mi@}d5BQ^OyWH)(yt{V@@;z6R0? zFS6YRGE4K|+j=~l2>!js2c+i!!8yfa+$&1z#ygTTs>dQ!(v6g+I)p|dwEB&-rlNGV zjdTx>i4z(g28hzXYow16We7MXsm>@a2kXzAk$)Gt?G^p|MTB|Cn`xzyeCwQf>J@Xd z=%Y3Y8V&s;_4CKiL;+GCHvV%qYB6eVA1eMPYH2aZ10MX z-$fsjHZz^R61~?fx-Kfp?<+>o%`|Ywf>{pF~O<{f)?$MyQp54;?ccs zQcv8BmE@>o6K;}w)&yx2=ji$`;lhbO=@XY96K7v<=6IViNrBobQ`P+M9l!g=b4l+W zrPdiTQr6^@o>s*zEy42)t)d~Js*hF`)ve_MRBY7*oad!Z9ZNQ$uH)MVboUk-opKnq znrfT0+QhW$(b{biIzuTGnmHN7FQ3&rb)VBKT|yPVUy+5zY1TyD&#;WS_7&m~H~iaV z_`p|OxLI7>&rs#s@bRUwxUX>^x3YY8Sndld9=yET;^%H?qVqk5#Z}w)mzovVQlwDU zt;?sozL1qm%ej`PD=n7mehOPHHs2*}e=~M7UaRm(m><7ZB9%(mZhCQfWe&OG5zklC zl5jLaJ8DQd>9;yn=zLNY@9V)qB}&leE#`@@u8Xb3T@zX*B3d=5tz9Fcoj>~N^!?Hv zlY-B+!dF@syT!g-RV$Z&e_?uUWYl7OPulxI8|-hZ(c=Ik?%%M7ZQe$c)X$l#^Ms7z z?OcY$txx@|hFbh~{rqhMY`vuYBYp==Ne0X%;B!}**F?adMetibSmp023;VuB$Do`fAEp3=^lvY5=~vP+ksQB$G;R>j+C?Hh zT_Bvc9*v8TY_@eWoGhqYwJ@xg9lmjw4vYziFK7=42neiiPpFoOpS!_H4zNnH-rmr2 zhjG~?HqA5JV-r8pV9`q2IK=D>^zmR@%GmD|Y1!0gvXc}ecrW4cH|8(x$|N1`whCq40SQRI##g=5o=xGH(gI(ZJ;1zE1n~~F|1-e@f zj+?XgmI*fEp5rD|Oe$}2pAI(Ov+*k875a^q8o$LzjS-lEo9r3A- zg3V$DEztm)@$j!?<|IIE%kHje~oO zcRRUrySazEjJJ#Y^cLR1`D;D@+q>IE^4S?duR6Q?=1ExC@?qGZ(56Pr`^Z^fj=nlm z5PRcECIHx&+%bE<@jIm%gve1U!$Ud6JGsSIJjP$VM@;z{UglzIW|eMfZ*<#SH5eJF z$BwO-vg%mVZNhLeJc0g-dEMuur-p+TymgS^_rW>So#D)@_Gwkeq~F{j9{c!h+?AVo znJ>N4H$Btqck7v(K`0%>lS02;=az^Uby+>yDJr0;7LLxl)Dr|J5Ta_Wx^Z$BRlL`1 zI;i{oruhUs(P7Cuvn95=Q9QH-n@tL&-HfWH1->)mnu|h<6p`BA4X{TYFSnTR&zgV$n z*q(~oSXUd;A87lXN4BFDwwk!N|9-in`?sgNxEDY1AOG+tKk&cqx&w!aQ6P~ySgvDW zL*f{3HERIe`R(z1f-%K;z54av{fBX*_utmQk=?LrTWs~)c>x|LtbgOhAPmCRt5?`d zC;XuMvomqeiRv! zBIX)R~j#PM{pVeCn0#S)^={Zk-#I?_R%s z0sj>onDAi3g%KZCoS5-q$BiLBmK>S#WXqK?U)G$N^JdSTL4OtTYU8L)5)g~uiiU*@a@;fhd=*){qgecn|FVoKL7ma@$*kW{Q@MgKLh_e zPr>~V91y?*A54(J2pwFoKnfeo5W@{Egs?*iFZ{5=2}RVfL=H(zF+>$TWD&#`SBw$H z8DFe%L>X=WG%*0Qpc2cf9)aXhNV|M|i!LG)kV1hYt7`Jcx15CXNv5Ji(#R=~%yP;q zxx7mXDTmbZ$}#N{vrH_}B(umf)eMqKH_cpAPB_zK)6O}=tP{^S^K7%vJL&Y3&q3o1 z6wp8SEEG{g6V;Q^M;DEhP)8+IbW%Yr&6Lth59PE`OgGgO)KNPXwbW2iCH2!&RfW`3 zS4~}2R#;PIHG!aTUCFszc@+vafdKGT*j|Yp*4Sc^JyzLdnO)Y|W}$sn+Gwer*4k>Z zy;fV4g0P~B3kYznwQ-L@g^N2F$Aoi4F+S-WrV-+cO++~3hc~vkTO~yFo zk5vx2<&j-xS>}~#j=5%-aYotZopUakXPtXK+2^2N<`{?ofUv?63&OQ^)=F#Lvr90o zbeh&yp~m{vtgYty>8-(z_3Ey}j(Y5`#rFE_wbgFBY^~FNo9wvhHrwsG;kH|DwDrb& z?!E!fTkyXJ=euyW_eR|BRhzKFih{R|Jln}7ublGBEzcbD%{A|w^UpmG9rV#fFP-$$ zPwMvDru}Ul;MZM`9roE}ubuYWZO@WP1#ekFS5pN9t8`R1Yj z7h3wF4?+R~hOxswzwDP+{^sYW?;d>W!~Z^d^3fOneD%v`zJ2fAPv89a$7f&u`0dYs z{`=wYzyAFTa<{+{j(~~e*=6dnr9(>LSo;33B ze_(8580jZQH_8!?Y^38G@pwl)#*vS9?4$nX_{TBkQILW3;~`mwLKZ6Wg^N`GVIv{Q z$i=MbDI0X8B_sJrNotalnB1f%J4r$qit>`A%p@pLY06KkGL$Y{r7K%GN(vrjh_x)@ zEjhAATkaBls z4D_AuK0zP$F&hkjKj)1J_Aoqw!j27~uhO{U*Kbp~yaulQ+)u=~J zI?|JNl%*vtj<>)C%MDJgYLs-91NBBznlfoiFSMzkbUL<5_LORW`C3r_C56*h%95$2 zlqoAy`BbSk^^{Px>QtRd)um>Yt5wCSSG5|;tP0Eu$TQ|yOM=gv1R*R53BazN6Ibg% z1Va}Ys6Yy;Fp9wSdI;#}L*RN$v<_CVg(d7^4VzfRF7}t*vO-L+nHUMI2`^=lz*F#2 zI|*bqGg6q%Q3AjjN|J&UP)PzAwzCvca0fD>HIrZ>z=|)u4hXZ&=4~U3TixcCx4ZRi zZ-HyB;t>p`4kM>^0+0kLNMW-{nrn5WkelWvVYAJ3h*}Ry*R_OmInOoEZI%2Fxxj;xL0*FG+ zb_VOc|8%fHg0+QymiIolS#ESKt6U6+N5c|`3jnBlT;=Ljq$xFVaa&qq6uUIVBvo;X zSIS};zj($jwsDMUoZ}mt2LO(PY*d-rB+m}2EL^e5kZG!1Da8iKNG57cZ`#ulKe;NE zWeR73K#EP2k!lAa$|y+j)4Y_zz*mX_E6Q9DF0%=>2%eOWHZclBmG@O_Y4T^;G}-9r zS-DEKiJR}HJ85zS~xL%Pvltu&_uM%*4!R|(dYz;c7r z5bF{|2?^-5S=16@{DgSOp{DL``fMKNN~gL9ne|$nJdj)ePo&h(q3(u5JZjk(*}zF) z1v}=kj!{?-3H)6}B+5t%TC779)?)`P*s%(6M4J`VX7=@10f{nhqT8zwHxjhaUwWcD z+uNpR_Kv*{Z(q;Z&;~*TNU;iUCm`GM-nK#7iGVY&V-=b3Z@!hyYz^^Qy9?QHs>{Pz zi7S@k6SsK9F@AB4+b{@7^bvKbGUUB*mcXbsa)Om`lqo0J$aZE+b4#v-SGRh$L1=YR zrrUCc*A~xmnr)HCL-UdU2nnkQ2NaNigeza4~;*&1atToA-PbLpzZZs|eW8c{PD% z^YHJg(bKMW?m#*X>v0lj!@X8O=~Z2!Py?a$tG^Ac?>P`sjA0=3Yz2T5&;WYZ#wu_D z9WVhWPy>4gpVI5m5QpbH%eI`1M|!Twvf}jrLM{c9V+0+~C`$0;TJ5rqObJ{tI}~s7 zlAx`Y?Bw|G1*c2TOpr=QA^Hp~`N*Lalu#4mi@#)xAg-<|ijEy>A-ae{3R(dG%7`7b zKnt@X3R=NQqOhleK+DJu2yB5BS|JIeujtm{35h}zM!~>nDhmCI`jn5#_-_SksstzR zE&PnqCe6_nO%M%{5F_mnEo~4NQ4v9~5fSmy3NaEH@ewVNmU<|<)B^V+LfB}pAUv@) zkc>$*S4u6E)?CJje%bn;+7yT;S{0j(H z0sjE5w)*QBd6AxWFQ3j&;f@c#a1j{)n+^Y@QO%SC`uwV|B!L#zO`eQn)HYGOz)NN} z?i@2N9noj>qf~1~aS4ifk-IZuW#M z1u3t#RL;n(&<`=IDYk(7rh>HGPYXiJ3a4Nlpdb!e;V7ga0tl@7fIth@0r7~!>C7U! z=m`wH;_9+O3T&aYsA3DouFP6t6p{c4SPR3XfE~b26VS}f2uulmWEAGmxd@CS2O@8Z;NXuQ^sU#BtQz64!3+p-xY(C@=#f z5IZmMI?r-DIS>Q8Q#-{oJjv4n$J0E^^M4YmC?qkb^svj`vubz>KIs$6>JzEX!XAr6 zKLsM`%FC~mE6Sw34wRw(b3g->Dt7XE=nM$vu0Z{h4mb1+ z;|nD}bS$=jDJ?WXy>ChX>@!7!iXP=N5h>9TClL~5^b%ckMq`vl+cQTi@kV*HMsajU zee|`EqOmq7u$DzQbWPUwsv#gM00Q88oYX+#$sxA!xSj*QumjcF3rP?P7mpEGszaa- zY8y2{-_Q$6og@-f6rNcDxfpb|4eF9BQ& zF{I`z%BD{lqe!*@5+>BmR^>1vbu1}$Pb>9OEj3dybyKTpxFDzDz*BiX;+z^rW4sBw z4BJ(KlWnbkZ0o7GsMby^F;TbRa1!3saQ)jjVsJ{N7MW>l%jhFp&-KF#$-)m2+{ z6h?#eUE6hCf7D&$m0f|fUguR_dlX+Sg{(f+PU{qPY87A!Hed_(U=2255q4n}wj(S+ zPdPPWHFaVowqhyvVl6gfF?M4)&r_W>T2qQtVT58vMplbOR>kX`WOZeO@A~knWfj6? zSE4zBHM^=+T5cwbov}mTbkgZ1dG@)mCmWv0)kZZQV9*;dXB2wr=V6 zZtd2HG4_HX?*Z~=F41-Eb)^;Sf$XcZS}gSK&rmT@0Xk_IG_Zc!76#g|~Q#_jqN98G(gxnb&Zgw|SxWd8IdcsdsvjND8(fxF-s#TR_d_j}Pdbk&!8*|&Vtw|&Vsere`<^7O}AcXw@9c2zfb`B#7MS9bxp zfAe>M_t$@Gw}1)we+3wU8Q4%V&8&X&t@_k*n$ghe=n zNqB_+O}KEhUGzrXQ798*oS9f7`K#W z*U37wOI1s; zAX^h>6=*>fX2FePn2p_-jbk{6-I#{mIFDz+hE+ip=J<^P*^RxhQ?hny_>(A24DaPfQ3uKhhsPt z;w$mAfEA|gz7T*FU^ojDZWCyMHT`M~*g=MYn23E1CD>FU2&^F@8MRn3IJXxVHFS{@uVOCwgCSC zAPb@(0ivK5Y*?Jzc_~zoF#zozcd}|WffP0jQ&7tXcParkfegfKAyW9EPdK6>dZHz| zqA7YXPUMAyI28Pf7L0Kg@UNbwz@s~Q9#&x<)(?<_c!!Djp?FT%K5Z@QGBIP#vZAXt zVo?gnV6}oHl8G&nrP-xvBbm3Orx#ih7;HO=S^*Y%wKgF`uve+`QmGetjLq1KulkC+ zSgXYttG61At@^9WSgf-eti2kgZk1L4Mvej5j}agO*14TmAqxP242WW#tp@@B#K4A) zF$%JP7V3D90r~Bcq6Bl!vMNjn|B(N*4li_Csf}z4$N(=EdZD=ldr?cv1VYOqnH0=o zpdmY&2YL&(z~`o*vx#D~Bbgs5nUohelUuu#VSBbc`L$~slx^F!aeKE#S+@VAZB>Gm zXMv;9jTyZW0oWk|fItlBK@1d*6o&hqe3_Mnc`X=@WId5TvfH`hLYZr03pjxllMA(Y z6oM(ZY+d1)CL7o>G z3TQ!=txy7Nm=(r=ylUZ&0ePRBA|PE*LWH}v8J8uw4Pczd|Eo*8=p3T;TD?7(wo*6S`&ihz1O0dix0%q zT)B?gthqX@yL!&gn$Ge3&h^~R`CQKZe5~vI&sP;`)P}9$SQP*Ou4#dWttXagQo^zT z3orl(q5umZ01CnY3Iqt-4}EFEufo*s{|$ zteOX+vSHmkDw`{adJEvIwi-E~M4Jqd`ryM{;TM^@R9)Ak`5+`g;F(#~>6^bXUcWUy z<2iogJsyYr8^C8l4cWNC@p;ilz7|@c7Dzz}(~uQlUJYr17T6e%XJL?egg8j0lCm;C zKQ2*`L^$eV)a~N2i49SCe8-hO>6w1%oxbUx$U?3o$X6Peg&T-}*y^i(rML0OQ#HGc zxKzbnSdqBwhoe^i3L9T`?TvZgy<VeXN((d;1*F^Sti=%i8YuT+qq7@8dr20pIWM zK8}JVZ`hiT1>23q*@pAEtsP&F6@M0Tn1(?eT`j+A9T})DpP8}j$*`Tb#Wk!#|MQi7 z+Hbq`QD53q-`cZX^v%c!FzTH2*_dEXgeLwhtfB1#JCN5*Z zApilAfBBWa`IEn$nLqlSfBKgn37+3iN#js=-cb1T>7i&Uw$l5dUi`^_{LNp4ef)`O zbs^*nJn*X-t^7WMV8N7wS0`#MaJ4{KRZFKlIshU7kOV*w3@kV>3Bd$N79LEXFrq^M z4-W!RSdrqwBoUGrB&ZRiLx>woCM+p(V33gq1(Hnvs1bh)W9?_ach1qTM)m+;`chZQ$woEWm<$b}J4zHB+OW6Fyw zZ^rytvt-epM~5c-aU}o%30Sip=(_d7*so>BhHZN`!7Ze8!Hv*ReKtgaS z#{nDeVu~!jNMnpJuE=4IC)SALjyCc*Pn^l#f1ri7})X+%{ zMX^vr5;gTwcq#>;ghLYG1VngA7%J#wJEx%CshE4N>!6lovKQxs=NN`Yp}o$D{QgE9&2o} z$S$jFv&=s0Y_!l$D{ZyZUTbZ(*lw%;ZMWQh>utE;jw^1tvf?RD5-k1clDWS?zz+Gww>cH3;f z?RMO7&ncZ^c13$9;6(iy*5Sb zP9{;z>ZQUd9{5I+0>`g%21z0RXLO;5$`DC)PVDHVttN#Ltcyo96RaYEI;o+~g{Qb( zuR3)epPR{4d`^$=BoKP1PCiydqb^^2?2XZ)&=vbq4-prHvmxXX2L+nrZ5j ze}4Pszn?z)@PF@q{OHp^|7q*rufP2E*N?yd>vLKI6(geaDfIapkx9N1S?dc zU1+MHZ(5;+1dL)706;*7aOODiluRiC;!~*BQy}f6FgPhw5W)`BFr4XTWl5-Ef?oI@ zq=DyOHKfkV&XdBV#AjzQ#LdX05CHn7h4)p zT1B##)o^)RydHF{Xv7Qum9a|}G*g+h1V=WKsf}^uk{!=9$2_``j&j_i9_xrlKME3% zZ|ox>`FO`dCK8c>Jmen@3CTr1Qj&v=WFsx9$V=u%Z+tV?NH(zwB+LQ|bJ862Qlgwx z^{P-bS*603x5`Ah2~oy_6zh5w%c?w1IUSi5TNJfDK}kmmwv**UE+@K{h$K)+Pyj0v z0IHjaj&)mMrsi5%IW`5sRmuEGG5eQI-KmM2UXh#vh*=bJdJ(j$RYWI+`W=peq9Ml|<$EM`qiG?(_3L^mi=n^(pa7A|w2L8Z>3l>A z)TeQjWGEXLu6zbEjlN_(Lw%4=4{EolLUpQAttwToYSpY_b*ozKDp$Yi)v$tftYR%I zS-ma#4{Hj2em4@tC7waGy^37W(t}q$e2o>l8u+W#XC+CH|m{`Ey!r) zb=VB=dYtv1FgXRgofY|WsEc=G#A`m1dVJ#AS_OOIm%%9obbX-RoWyq3F1tO zn2{s?aEU8PNk^hM#3XL9iCw(n6RUW}*L|^#V+>;&r?|#AzOjy3>|-APxWx8k;y{HJ zI%+XCT6obFlUFrPCvPiNQhpz_WL0H!WjR$q&b0p}uBSYG+*liT*3LaOt)naJ zT0>XWxyJRadHri!>l)U<-nFoOJ?vfsJK4o1HnX3NzNc6>$UCMHkhc^?6zgY4@anO* znbhqeyVz>l9uc|0EpBRGJKf(Fvb(Fj?svx<-ZGYVz3H7}d*>V9>c029|LyO9?;GF) z7kIy)H0OlVS>X&{xWgL`@rO%1;uN2_#Vd~Si)%dN9N+k~Dh={Ui#+5cAGyg(j`EYM zJmoB3xyxG)^Ows!<{^i&vaL*IVz=7ZVqP|~f9~_Ty!z%mcQ(+E9dx8Cz34RF#U*SC)B)J&V;2QPaR$=+^$rycF=Zo9tC?sm1uo$YU5 zyTR>V@Vvvl?sLC;-}R37y~~~Ngde=&>3(>>%dz8(_juzU@A$|=e)5v9JmoKM`OIT} z^P2B`DS1NknTtO3q#wQMOON`~t3LItU%l&F5Bt}vTnbyjiPrHqbgBa-)U397)ytRr zuixJ5M+f`WiGTdxCtvu;@4E7x&-~{bANs`~zVxjh{p?r2`P1({MXXQ-3%E=0SOT=* zv;BAera$oPPj|QrkNEg2KJkEGzy0AqfBDxR|NEyu`STBe{ilEbCx8J+fCm`=c$`!K zoX3Ej*MJY`fDs6R6DWZdNP!nOGtf8*nLIV zgi-i}L`a26c!WwQg-|$!R_KJ^0{~WF3F60p)P{Z(vTX*4ZEDmcXIOx3h=BL!f9*Gh zau|njIDm9`hjxgDdgz9DxQBDdhi?dogII@zxNb=_00Te(3#fsOh-8iki5nP+lPHOm zNQswdiJ6Frn>bIO2NJSpeohmLEl7$kSc<1;im8Z-tEh^t$cnG%itv*EM64lOT;_YD z_GJTQi#RA6JGW_D(SrklIPznIVv&pFH9)>tg;=jaRWNm^gY(jgRAUxf2jPn!$n!qm; z8GIDEDv{zTTObJv!-*-Wi7Tm+Ey5?%ClN1;@X0r)oaFaPXXezQC)&@;DiIZKF z8=G)3v^R=@1~8jI3Qwg~Q7{Tx;6ZryAe*oS^O8I#;xYWeN?U;ck+BGiU+I-$36^6i zmSstnXL*9Yw-#K9lUzWR)?+CU@eyyi6d#cUT*;P_P$@GA1UP9GnxZR#GZR`M3WW&) zaw1nNabJ)E6p2}r!U#c-0*nE`8bLsqaiVE-ftMJ`7PLn^+v5_G@JcmNT}rS8-?)v? zn3~|InyBfT-58GE2%D`ro2+S@tBIShDUP+7o4kn-N46T(rUazGnGnI1q<|C7u?09e z1_>}IK-rbPAqAT-21ZnS#)%V?fR_m|21-el32~gs`J8m=9N&2%q96vLAPV;qmEb{@ z%h{FCsRh*0oy3V85dfcL5D{)k2FW=EH>nAukO?025ft+ODW|C-IoY2J0iW5Sl*^f% z(@6$ffHKqRj~5z{|Co>sxuFNSkRHmR8Y-d~ijX6kp(OgD9jc-xTB1y1Ez^mhK(Lwm znE*M-mBwkKbz+wnftS7VoiHk+IXO@gK%G>%2?jBv$YG%63D|9&! zZ)v9qpq(akqtOwgGbxjUDyW4@sE2B(iHfL;>MW^YHqqgi<$0Pwij!L)5=elPN$?Qy zAqB)~pGn}Cok}RvNeU04l)v$#R0#l;x{eW`s_Ga2p!bp<5g-bqfCN|&3aWq*Q9!0q zfB?0c2~dCp!%7P1nL1HWn73M(PALiq012Xy1rSgWQbT)9bDamVl&wLdGMbz-L<$WO zon|SnXi2W)YOdvquIH+*>H0MbB&mSvoqj0^$61`DV5tmoI2xfRFuDmzkg5m@s>Rut z#W}A^NebNwP2KsVa|N0$0R&Qdn5Co=5K)*MBc)qfnCUsE$Xb|TASY5FrK$j?92*Ae z846iotSF0_yAlK;VW%WHPysNnU6!W{L6mtqno>}y7}>J4cZ0pTn?Wm^LK~Y!OPfS{ zv_q@3MthsOxwJ{kv_Si`O)Fe>`H4N21ole*A4+K;2SKWYLYz_XA3<}IS&NaPy0v70 z8%o&_<++sebskEIOBgjDWGYuVRG7|zo>4#s!I}xGKuSP>1W@p$VNeiAkOhCs9O?-L zjSB@>pbD8VxM-Rwt;3Fh8X(vC8rcd2oO`VhL8G9Gsv(M^qz!2z5uOSv91I*De5zB)!tfHHxvHKH z1u%t~39Aqahgq1bfC*>{1!Nka!I}hPP^-y`0EBC@SU@e-5L;Tq^P#gjDU`LL z#f759vEiKt!kN=X9Wc{ewtMOhB@-euB?V>c)1D^3aijTudK_mp&C-4!PU0QwM@IP z%eu9TySHo1$xO_$Tg=Nm%(IKk&K%9qe9YB+Z)s%(jOaDOX4^$inEzj4aX}jmRU>5Gzs6(iLi{ z646Ii$EBRgs0`CHP0BSb(>A@yqkPjlozteQ(>)#2KwX6`TaM)>%0EzQ>a)m`1pUQO0xZPv_;*3W#_YMs{8Jk}3+ zEo^y{oUpA>W|X^_a3DLSjv~I*#SSuhH7`puofqXKIc&NPFE!d4P6v-d37 z^-S55ZP}HL*_Ta|@qkegpHtG?}{invMmqOd7UMdcUDbfXz z1o&IBafJZh`=%e^rO>*+gc-S|#HHeGrRa&?mE2hVyA<>ausu3ZZn>SYeXkLrwx)#B zr!3U_{nPvn;QuZE;66>@K^@=)PSZSn;07+>L0}M(WVSZjpF!EV!KrRDvbR1Hla ztYIdpsk>2oovISGrvR#vQ%RtmqwC{g4drFs)?h8=Y;EOkJ>_DZioX%du?P?a z_=~J@rLu^r&ZgqtTM^lLIx3qG>47R0dzu6Ztl62Z>6y;yo9^kI4(j5{kyAiK9 z2>@E4pbSF)oJr}y;@fBg(ZjMz8%n_994q5WxvWjB3Zk$Inh*tgo3T+W3ISS}k+2Gx z00D%n301tQG*Yen^|_+k8eEW^TOGF={;g99+}$4B-VW~HF7Dw@?pnn_y_>}p1F1Kg z0QQOzA90bVc@gNrj4q)k5Su!yQ?VS2vS9!PC~Me2aKGUTO@)~SguA9t5CutazKAOd zE6cDIF%uTL(gke2HXG@qDd{zv5c$pC{jJ~w&fo~{-y|RMCJ*u{zu*b3@*>ajD_`<{ z(;6<;shsJr{iy{M+PTajx29g?tIG2W3IHFjqO3uCg{cWz;2tF|3Q};U2al#$0IW!` z3FAEf3i>+=%t5A500FsbzQ7IzPw(pk3II{?s{c{IEpnr;ah+L9wzEN_I_sWK?d5e3 z=38FncCY1MzV~|1<#-?FeSi0S|Mvk&dt0zxylb9$I>suzu*iU6Y!r=sAommdoL4(L2QClPR_-|gMl?}8$&+s@n7!qFaPyV|M&0Pb3EL2G0Ca|5J(XJ z07*d5;J|_j1sYU{kYSR94OCgisfn*>{+s5wVF+fcJ0`=W#M*pOSkRaxN7a@t;?1#-o1hS3Z6UIaACx973)2` zxNl;{kRLk++&D7jznKXy1z@F$1p)vPh!#zd^yq}AOQSZO+I4H#s87dUt=jc$*{pNd z&fOZfZQ7|7WXb{nA@AVHbt6Z868P@h%X>rjE&ccO=h?Auzuw*Yci!H^gO5J{-h6rV z)z7O>Pu;zC@$KQ0XJ7w4cl!6^+n>K)fBydD!_U6}`5REc{r)5HKm!vjP(cI%WDvpz zC3JAY2Q$QQ!wWmK@WTZ?3=zZ#M>MfS6e~PY#S|%YQNt>{u!4Y_RI;%~9B?d zu}2_xBq>NDcXX*pB!5&gNhX(cvPmePlrl;xr?j$4EU(luOD?zcvP&?(6f;aR$27A{ zG|yBsO*YqbvrRbPlrv5?gYfKv(4ezzPdy>z^Upp36*N#n2j!DJLrFxmP(~AVv{6VO zl{8XHC$+RvOfS_mQ%*Pav{O(&6*W{+M>VxnR8LhkRaRGZwN+SOl{HrXT4%MjR$Old zbN~W+-OMhVk^lfLAP`Ez*ex`v$svT07#2v3G&AT~VQn-P0Fi=t_9c{}5;ln~Hj%=l zs8~93vdhv%ciqY)YZtR$*_GDadEvE8-gw_tS6_VZ<@euu_YJsTdh;C^V1pC(_h5z< zE_h*w?R|J+i7OU3;)@~HnBt7-4ZtJ>09bLia7o#O42YQ1E;!LnUbHkRq~K6doWe!9 zPavd7Svu2nCKTK)UgMc&4Ml9RXrgBx8R?~!KH6y(qka+Usg0JJ>8Gu(I%%!3zM5*U zw{E&?u*)XB&0Z*^TPpY;C*?@z@Az;G$}+`@1!WEO3G^Ap&c4EJsJzUS(5)nC{B`{)0E{{;|$0~BBZ z33xyQCJ=!ORA2)c_&^6n5P}n=6p!+YCjkwjFnHaooZ%cIFqBDvZ!-Id;znXU=t&PKJ`5KBB%GtCliSeMIyNq9_~!wLgFWH#J9vHL|g>XT;sz3C(p?F&2|IDT|o(YP=h8Ep$k=L zLmB!|hei~l6P0L1DLSPfSfC1cI#m)(COuLxa)&01-XPZ*(nXGM6fxVxC`8IZQYg!# z@+9eMkN{Hm;bdH(DkMbWryf#{MwIk3UQP?QxXz76h!kY11fAMcs6JJyQKjlsty)#A zURA4E%tc4cs&sth{#U^H1#mSDeBS~0x4;M{aDoHeUtWs0&po>m@^g#aWW8NO=L(1sYtWL0=UKz3rdvpiQ^zLVxTZi#TT_`jcI&i8|N6u zJJxZJdHiD^2N}pi?r{*Ru+coNN+rPgqiqmCswG2tXo-5+gsKeIuVxv`Th?-yx%_1> zhZ)Rc7IT@&eC9642*ZPA3ripi1Zp+^i*Q>gUJ}K!VJ+V1FPF9ROojwwC5DC1ccC2R zeqw0CCR!zK?$)C1g6P}ocDAsUv~4Lp>DrPO)4APrr8RBoOh>xYqXspnOYLba<&0uFM zd&1CuHnXd}Y-~^4+R{EYx1&vMZ$k)8iz`S-99yg($ymraRyUE|z3z9%8{YGlcfIL- zZ+qt(-}_e6seHppUB`#Z#y*t(_6e!0i4Ra$CJ&k&Zf1x-T;dU@_{1$|p=;s=Y3D z$1MCm)H7L4cfHE%5IfwF+`<&T%Spc-Qa9QILJ|Nv>s}Xpm68K|;R9-TNn)fnOMQFe zw+(K{KVI_L?snuU|Lw_Z`|{V;eCI2l`Oj}Y+@rU==P@t(1Z3%w2I<=-5TL=;wItD`bdtKCK!|w%=H;azm9NxpCn}Kb@oSqjz8Q!l*oGblx zkALXkyXZlW-3x+@PNH2|d%}JYg)x(;G(8yF_9_{5D;~lIDAeNdhNvnVxSHi=v|_?s5w1LWn8sLf!MZ?HdX( zoH5@sIiQF~m$Qg_6rvFNKcr&4Nw`8Kn26}RJ_!h(AM}%9ZKK=BDB9_m2VaLJ?6lbTB^7<@sgj7qAUN~^3& zth`FC%t|F|xYW}aDc}TwvLE8v0#3-mAdG@=xZN+R0420E52F9?c0RIl!DqL1@t-z@k%g0Oh5)=CbPk-@MdeUDpir5SGzj3yk?QO_>dYB~Py+4zos00zVEYd2 ze8z15Bu{B9&ue5x^)%0DY)@)DPxy3CY>dzMl+X1{Pxh=&-q0{4Aqm1cw>G@7VfoK# zxd>|6mH;ghBU}=VNKlC&x3nX-c8dtgN`gbI2?VW3iri2Q?NAQ=P!A1J5FOFjK>$h6 z0!_G~X+af+Ta@Gsvla!F>e!hWWsd4#I4UEQD#OvO>`|`tQ6T+MAq`R@9a1Cxsx62F zO<)fhqzoXSN1)RYlWRkDi$X~49KrPKdRn0#YR6tEsL|s&NITr-~ z(1a|=1aq^AMXWXb^tJGWI|&iC@6yEM9JWlQngsZsP~}up4OPJ#&P%;d^lVl7oKO4A zPgq@5S!LB%wbfX~PhEA@T;7i%!%qPC{W$2BKFI z`IIZ8*4%JcQt=)>0jH&e&Y6_SNbwm%A=vZS!21)}B5l|seOQN$ScsiiiLF>&0ai^g z4q}BE3B^-+WV&E^RtP1EEoHHuvokPVSEGQTl4H;!>A5P!iDz+B%sJD$=%<j;)AiMX{g%l-ugX5gwA; zrSRT6v%+$WG4hQuw3S|q*uoj0B+5=2- zU0`!JES(;>CG~NlKBRcrCQy+n$ZGoXR z#)z2N(yRcV1*|}zO^P*^f@iJcM1zQcJY&SoUN-FBJ?>aUeu}*Rv|cvFi2$&`m{bX$ zJU;a`h?s$75we-$fxYvcgmJ0RlLd-?^5lB_-!GJjDMeYX{aRO^+O4HpS&n5|?%Gy{ zWm}%*T(0F;&RS7pF%Uzy=yav{4K(ZdO7KkKp7CI1z7KhQiqTbD=&X+pMg0K-x8Meqo!`sKvF z)#t$TUE$&=!dSazv2@t$zwz&WIDc!JT7CMXkR^x z(`QZ7Bv62u#prsBh>&*Q9t_Bwt=TfpAZyKuK~4ykjvSQ#-qM=Bqa0b#0KlH_O)7?1 zLyDLrOb($il-#_Or)>hv)e}g+N$P@VEN(eR#GPOXzG|z^YOLOBt?ug2*@Sep5q2fv zLiS;$T9nPrTX)slK*3<^p-0tH;_=rIkv zeQTwv>kaN1!qr#Xh#!_T#hoFiQMyG9=B_GEMH@sf)6GQrnZQ^fjh;%4QsHEu!^3XvUZ zBk^sMfYTcx+BZG!noz=S*;|<)&~QGqUiMmC?(SRv_GR(*?(q(9@;-0#PH$ZX@AY1o zpS3ecmDC|&!?Hav9=()P{nP{T)W*y2{w~#CE8J=xk9F2>|32_|)gBQJum840h&E`4 zhVY0!=!G`k2S;cL&u|Ri@Cv8!3%?L2&ICmLTfmuR{}gi{&~nU$dQoA@(@ z2q@{pRmR(~x^DpR*(c?$!59B z4H_JcJ(8~gXiiS(0yqx<1rQA}R)R9*71yGcIzdpV!A?>nssDN|{h%~s1#FD~FgGecefPhG;xOBtPNOyO)bc2+V zN=TQKwDMcf$0vQx^PcxT=YRgg3^UBmz})xTT;J<+#pj0Yu%dRTnl}02S9_Y2cH26< zuM9T4;))lCac#-{TA{n(MOPF_VFLlL-PLe%wY;(5j#~UqxCFdzg(+Zl2%iS96-q>& zDkD(4mTxNq=#UPLDgdQTAZm}U-)oL4)VB5|cOH`5&rve&eQaqYnUHo|T|)0J1#6%%52(nr9ES{lyc#>Ilp#^MHV z*yBYlz7?E7t;M~~jgH!^L>TqD9*c+nQ3rcb2%5?7-A?}y9C!)W|>g~kK;>N4& zYC1In?|6Pa$_dlz1*M04WR?xvW9NmJ&Wl0LO9@{)O$bBoe_WLEVWquLH*#!qs(irQ zdR2)QQ;F7Vdl7?{q8K^YsxjiNIgc3X9lWW}VToGX>L?S%{6v-Nk z0agG=8USc@_{CJQX*-*}p(ISOWMv>LZ){iCO1}qsWC(FO3jk?F7s3@+>!8i8e6<@O zTdOSB&?%n=Aa^_HS!xY&jZ<*t8irY`N~MveF+f59vrMdbbiiQv4OWB)UJ?_}9Wx0; zF$T3E#&lb_D}ZLAl&u7CRnb!;g-vq$hD(^QDv#b|49Uk2)gCxQQlgqx(yalM)Jphc z)^n}i>^JKb9CzmWqQ$OYaUNb@?oX46Q3`M>yZ<&%%f#*yHUGkR?Csa5ePTKl76Y}9 zyEg)!30TiGx(rEwov^o_?|nsmoAABk?tF93&DTmVj(0c4>#kh5_C@4ybG|+1_HFXK zHovD2v;7kw&hM%LsitAqvW6Mpp>o#EoeZ)7=(H-JTtbO;j-io&H72atM=jOr79lH! zTw|~6JhDW}Wjl*Rl2whP5GhCU)X)xI?l#kSU!}idnUGRF)jARLV#_UNtz4oZN-Qh2f$lovgI; zy5L*4i?jQQF?$0Y#=x}7B#4~Ytfm|#Tks$*^1cFqJ|Wdy#YEfr)VipX$&N}mB}r8- zn_fR$kyrc2-H3_M_Yi-{_p|!j-O- zoY#ZCtN9J%259UfPSta8-o%kw9Sv2Ku(a5`o~aW>MHsII=0>Hf|W) z_Zc2mp)6|MF`rIQ*ixaH(WB-84 z0gGG~nhTZJ6Pl0Ii5FUkdGtYOG2z)|;iVKmJ>lhyn0VopoSYBBs|7WeMb=8X^+eVy zCgMdlLLVhdF*%em6J>18Xqaprg(pjbPc0<$dnl|2<-jK@nUcE%H#POac~+qq4OGBF zOrhA8Xbjdcj)r-OJ7GL60NreqAugZ#IwL6tDN)N#6_M{1;vFFU$0V|B!Pe?w&suW>>bnP z+7<=)&!Q33UDH@_7%d!(kRU6ht>l1ti1XWobsLgqkzVHUf$1iLV>()xg?W6HW0Og8 zV6E)hJbs#!$z(Mht=F7*{Pk&4D7sObOQU%LOm$PJCOX;#s(AvfVpC{VVeKO0JaC;3 zccwkVjCMwYdjY|~9+KulOj!ecJ~}BOFoH#C)9aSp!5fC>Hr#OCIfc2*sFw&VjMQLP zBS?zu004ks)qO~djwhk7f3$28=s-9eSlTb|} zvdDB`TIqL(?bSI4hR^pxm|5A1 z0K8lC5@Omwe?%6mRtOaLKsHBx&?y^Wjs~+ygM^T9qcO5Pyz{~lhcvUWp4Tc_K8#z6 zm%R}qHiW*A(~y?bvk5`F)~RQrbIPvPLF>aX{YgQMGASmpSdFnXnbZORRs{gS0;B8V z=~n2GmBU0&B3$vZff6Kq9#_G_UAoobsX^{+}*_Gs`+q#^8Hu!%Jy|mYp)#L zIez=9PEIb{gl^qcrID)Px(&M$_V-Kb6*bfI`F7pMch>?(YG!VHa+)e@ekz`7O6vhU!R(YI$t9VfZRHQqPqGQ4ml&EbeyQg}(XnAHbu&qVxn2&LOo>6K zh2GSqUXFQUnXGbOUI$#c85}UPosV-!3DN};XAtz#(mWe&6NP%9+H6M5?6?Yi3a@-K zmt!8nz17o%VAGnUWnx4uVU|qLLa&V3iCtA#6qyiu}$e4(;Ps@3>cl;qe=+@ zBksSGi$RM(tpp#*Q)|fUZerZ`&}P&v{+#bs2rw*Ae&&voEy`%viffl8wtkIT}$Lk?YALOK2W`^p|7bH{32sq?x~IP}xYG|0Gr(qr#iLQqgZ? zAo}wAB~~>j`OuBsw3~Iy$_drOIfO%*_u^KxDvso9#P6g(M&)K@s^7H}+LahxTEBnl zgtC6s3mJ_2WmL;@IPAv8;=A;smG~1(ZG)9BKmm5e)6YHm&8mm$)M(+55bYYas}a;& zjyEIc$}|t_(G!~wny)yCT+@3~5?QO)Yfs-eeTbR*x?lh1i`}O?1$UB^aKTNL9~&m=+YmxVSG%tX)zsE7C|o(B ztDu>bAgn;_QQDxj9yI2>p-2)DJXu-1emwH&>t6Hem+hdNUlt#q9(_Fhdi3VzDdWB! z^rk1JtahHD$_-hSS)%T`I-(h(cwpaq8mQiLT0kfT3}bu(Q4p7 zFKic@Fzf-^R#$SI2Q-x``t86g?7lRz#i^YhSMDf@;;1loM{*l=#mbhX_r?f5S()rC z$#|0hal^eNSDHDH0t;ok+f|x1l%bp=7bjPi{WeFl#O!@nSAuFwi`kf`gc9;FD#H&?&rO!N6hcxuT>PzG-AJ_X-6{BT@ULSuvY52 ztg+oHRbCQl}}dd$H@)vHq|^{2p^5n z2c)*Z_~S|1?c>dP;cvhS1^8(ooL5E7UczJ{w~i z{sl#uj)w<3t5a`Yzdk($V6jXiFvv`&U9g!lr(N;+1=XJtO0&$klc<{}Ded0PobjZw zTbgkPIkU`qGenrq`mm&D&iZncFU|UKx3PTmFS`%>7$CTi`7!VYTKmT!2o@`Ye=Nbn zxnLMm)?A1J|MFa@vNY>_n5z22`Ebn#S@-QxOS;A)^gUS@qKqRRF1#{L&svB!FJE4W zv1(&ojJ19Da52tdA!{-I`QGwk0s@O|DbbzGY$?f`DSIi|pMPa31u4z8oEoNXwwxCA zAbUAI)^24vBhiy>B{Ma`Y$Yo*J$ofPw|r$Kr?Bl5MW{;OnXTqkeDGS$uiaZ&Eoi`E zUn^`Od$d;6!IZOB+{3@RR?;uczFs=4{%E~y^g+&g`J~rSzPQ z>b3IKjhf9i_D{9D?;d@sJ6Op1RDZI!`sp>`0>@?p2D$lWBQ|rcm1;HD+GexT81_~R ziH7-BD}_n!mLtLAwXOE6viRE_43XyBoh%u-+g%(LYv~o2fz z@DVA)bvPHMVR<+oWs-lm5Np42xR~h0b+nWkX?e7qnS%FZCAVUux@NqN>v*j+l=|6v zr2tG0O?GkP_*27$Yp6Z>T>G*+tnv8E=TVb_FME^rpT6u* zdtLi_Fc)}#H!Pld;icepUH`}kBp6rf1KK*jASaACFWd9TD3B*qXT!1wIsWuVV z3W-4Sjs`5@O&5@VA_g<85m$TDm7*sROQ55X&}q|+7C#AF2G#_Q-gIYCNW#_VXdAaDhJr7VyaKC>#UxsY2nf6ZfXiqwSMQ5+2(@xAZeuiMXY@bc^PVDRvz3@n9 zUouQOZrwja)E@20XSX31%E4MtS&rf~;kDVWF&MUU^M z3-%HaKIs~YKibWJ5M(QR$qgqnUBr=A%!WtGB}rTk%Tgv_1%Q=rCt?q>iUeeInBaMBh}^B#4^j-clYHaYPUZZJlbW~ zufQB=w3ILOoL843*5Pd7-7C_z;CU`cvc+l7fqCJXSXVML78{4l{|3xgE@c02!2D(tz5oj5K{6b_ zf%!HXdlbymdU5;#=C`}K{|4rF2Vl(SFu%S#r2Jc$e_HEf`Ojfqz~M0|sAbB1s72}@ zz&5sqg;;%#Uw+3jQAEEl@B&LR;`Bm|qIM3g6P}uQ`YLb;TsV1382$f>xUQZ()AF zqg@;Y^9cM@+6%HB5;2F_8M<7}NAz%XS=ARJgoM`?Df!uM${}O@z zZK63*@hbxDti128_;(QK2hse2Kv$G%E4MzLBhWXZ`EMf-3-JY9{&NKKo&tc?O=mpV z&|JO|&Hpw6b&*T{o@o9Z0{zE{X3;N1^M4hAN zj{fo#SAiO!38HSeUu13n>A1uQR78zSKc3>zK=iF~wd@hdR2@PrpWv5sG@r#~dfFw3 zd_;tOf|7q{j^k1H%6>=}W zoue{!1AAY6q4*dr5HwuA>6ho@lF-}s-=Cwfg!6I9i`LLVA9~gEY+RyR)b|CdmD7J4 zm;T}$RbwRl%{iK?DJA}!ap`~cDgH4o{p2a;C}gBB{5~#)NH0@-AD04UwNT?ycl68I zh)4Mb*W!O2mnPE5!B3gLk4s&_-KcS?+1Nr4joiF268%c9RRGR4)H&M3*uSZZDe-+= z`hJeaU=Fv?osUbOCggBfE7pF0j@I5a65j8zxFG(0T>9xb`adx)O{_g$Oq`0e{5~#a zYz!`DSA5ldky3LuE{#}xX|E+Q9&*$h*#w7wEfKg$~ zH%0a`YFujNatc;aKA7DvrEObyScDpvKDO1TeH)iZLhG=3+XXiQ10r1fFa7Ks{cns* zX&ff9|DkbdiG~amD@AXYz7x0U&%Dsbayzu@2^}nxIe96omr`{54r*M=guKOa=b>py zM1M;8=6T3%bcV#FrwS}Rd@4v!x#9adkdB+zx&|PYeAg-0P2aGv!DC*O{&ZZ*QnLRx zF4bmJoR3SumDKZbX@!lI`*W6ZoE#uoPVH_;ZuX)Ci~5Z=pFF4V=sRE7Mv!dpiiLx7 zAN+1y(p{7rsUH8F@6elrSHMPGzw%kb^h=KZ1^Lk?s=Y#Q#au)3nnWaT`E@k3UwH}` zAO+w;TLqj6VlE^UELOi2#C}Ei|6)@5hVX&-iN6YBEX}miC_#)0%=%9Ru^$MJnw0*3 z!Bfr!vA>y=9?CLsD}%3|31SMQEwg@?Uzs9FxKWdmhSGbKAolN1N`J*uz@D=bEQH#S z!0VWFAECZjC_#+1%0bx&hZ1)vnNSNCC5V}kxIhi~QhksqAG|Tr#VmP|WLQ1}Moc%0 ziJkf>_?m>3S#DN4A@gs_nQ4C)PJsX*fFmBz07wQ{p`MeE0L)*Rz&GI(bQP??3-WIH z$wZAakPPwV_>Tyu|Krbzs32na`~L^p*>xiU9e_fB3F^9+|LVHs@OhERf4J_4+-RLY zlmve!%(my>1><+IS-<{&{8I+>O)&l+yzU{l`3;vf&bjIyEg<+)s*g6482m;Vhq z{H0v}7yR$Pt)u)EI{atk@}Ka(|Fm5GKdPfd`eFdpewE9QJ)S~g?q_oOBO$y0QZ5%r z*Z&7P$}jvc|L9CEKUytp|Hl8m>nOGR|KG{w(6R8m?{c}s!HYuob{oR)a=9F~;0&Gz znTyM?m8b9!knkzLr^k}jxm;fBl^Iq>M5II}_;a}&#s9YcnOy!)`Coi69ZD{jjY7TX z+3UI?bHRN-mB2^h>7tR&a7Ql8OMxi4{5~ud3D82xj(e{Rmcai&8k8Ykn$eyBfJ8%7jXCMwmYo4!P}JccVX zQ{6jaJm;d=WVW*wM6sOfB<^u;=c;|@I%()jHB5~LCNN+`$%H}Tfe>a1Q|_L(^=9K{}u?nHgAHcT2SgwRU?(^uG0=4^>{+fAn~TW-odvNP2l@4@Xj z`w-qcB5$N~x7ujhpPI0z!azpx&+X34**oDF5dirj4{g>n)&6#!Ht(4^`$Va8{8m|II+`UjG7R9b#=uQJ*J75X||e%HCXO z36XQk8;z!q+E}aL<&JhU8}n+QB$<{jP?kY|7Rp&}dX^A*MHM9KoSp*JkUImR!1TFD zd8#?%NK`^3-9VM8;VM)s{wyJ~7tR3Er+?TGWz=?-5b>1CKoiT(nuAz?#}`ov5ht}c zTYe{IPe(RXLc|dVcL`z!MjNwFZPt;u85gm(LO+gVFcWwM>(0Fi*2kAY|jA znW#lD&XN)&t&K{ET#jN&RMloQEqb&;fdV1nrR98tu&`PjP*w+7P;4={RzCSvHLbW+ zkL_(Fu*hs4T4;ABdAc|*Ccaf-u~DT#M?X)lUyEqra|@%lyJW`Tlm$kwV(rbh{e;zk>ar$ndm%e^T=D4 zXQ%i67cJgK#V!9c5L(FZfucYNaRh#WN{F0lu+=I?E<71lJvO#XXVyR^L}sdLR)=+o z+akdRk(^;UnitGb2@#!kmJsENx>vn6BXui@!k+B&NXo5Ki~XsuS(hFU>EGPbnn5tf ztGvU4FR)HIYs^i|p-T}CbpdhWgLB=r@(&iN=#*#|n55XMZPQ)zj{@SakrXaO&K?~u z=ZsvAWVke7SDA$Ul=sSd`Gtb%gi9Wt~<_~4u`)=i2PH^8+C$B{T4>V z`Cw4O_&|oew9H5S#Ek@6Cq@BY+IC(HY&B{xj+M}2hj)Z`< z4K8XsXGeDAQiD>bQ3=>LWK;_2(z)KC+paBiF<}dCU(paRX(YqPjd2!$f*}l^L(-GG z4_fk{D)}zKnF~uEh^U118Bt-x?!swg^!UfV-L*x9wg?l$hxG!jdQ?b;k00GMpnx%)&5)zLl5+a zYDpgzagfQRsr~ae3vpq2dTY#MlV;YjW($?UpBu2 zHaT{bZYt?+b3msU<~i0;Y_`|pbtJs zKIWF8tiZC|#e+&0J_V1GzOsD#-c`NhqmhOWvY%bWrf4w|Ut$@QX~7iDg{lpCdp)fp zQV4YT@6~~cA9+Pe->x2v?AuMBc)FxCwcea^Srwb6Wu>Zy@$E!giOz)6iWueoJBtgS{V8nM zkOUBdfxf+R=5$3^d)VZY8Q7$I>0WQBb2W6Sua|6y2zVtGCtWAzzgYM2Xmo z=JJ*+hv-~|oIne*WQ_>zcy24hAz9yf=Vs`0i9J>jZ_A~4ARV=!1{tExt==M;9JWRt zV&P)@^>Y|L#Yf6*VHb$PX0$O}!Up(!@{NN1>TcI!z!ZmX$!@&1hR-Ud;fjxO)j`jj z`aQ4LU!FTx9J}g@pB{XIJ=sEUJ^8pev^kC!&)3s&yeyL=Z;y&&BqK9VFdH+}~<%>jh2G^otWrOC?;1L#_* zPAs8GIur?#q5xxHyKg4Bl@r;^T0K)>p}jdwnGxzvyLC%m&|}{Kkz_;;*S~w?DpO~> z2gbIuNTY!15?Set2lkBm0|(msi|(S0FRft=mK2mY{ccQ+s28$av0WlxB?niKQ^_27 zt+{ycq6v9Zh<-j*yT`BM1|Rkg)AW(0^Lc0Fvl#4!&f|T-MVuKbeq~Ft)EZtV^MV?+ zHFJt?=c+9LdAo902L#~dO+*% zGyGlVsQsx^#i^*Ab0il}J`IR;n@eGYr(NEZ`s%{Q{;Gw@ zmm^|@gWblMEc7ADcsTt^FGZ!Msq*AegZW;Yl;qyR z>f_=$1tM$-F(tkh4K)(lme=?K3gKWvnVv`0=%k{-fOkG2J}orpI)`{cRk?{W^33$N@>%7=z2Dbz;I$%cSn)>j5DM zJqS3_&r*5O``(6QtQZ;+v5FU$hKkc&&~{p?^b2%azwx$H#J`Yyy82ehPW|C0r&;Iz z4VRm$@NODt4`{a|N3$9-3;%HA&V)um@;3b0smd09a4_=IY=&U%&W9_XRJ1NUeHnac zl<~%JIn}Ga^b0@q;>}YIZEt{LyU1>myEBIM6~GJInhCWaN9^D!NJm8jg_!#bK+h`} zgC-Pf&sbgzXJ(0ev=N-Y{B(radxut25I4F|zRGU~ugXSG;I7QPSNPJ{ zUf;rcR%%EL9+hNYgJPlOZ%2$4c|l+Uf$HYV4=VA~pO!=9T^I}^bZFDKBPnAw%aZ{G z3QeT1WEJOO4VM827Xam{J!Vcj{Nl$lXf21mHn4na-?;WMC5$oL5+Ug7@0Mi3nLTNLCqCBiyDf!SA^EVx z(WNpZSqeB^&4k@3@vs9VMmFgz!8C9w;3v(7T<WNFxa+1J$uPB^@6ay)VLN)ic1g_m{`-);-Rk{wPP`~Tbu>!heku>xOL({+ttUdr#yTYe*$tQx=4U#jJ@rzz@4L z`-&qfbZOb299rvrEskmz4Ore(o+lA?X`w8pU_i&tA-vI**BvIZl5Q+P7=USQi=oP}^$oxHMBH zfJ`Y=TPj`rX?>G!Na#c5w~ly-G=obyT0_yM{P9ojnZH;iZPcP)KY3c<;UId=%kwQK zbPpo#w(Lxn>btfxQeJlif?=|G>7!kwlE)X?y7 zPVGa@ou9}M)hHrEBeMm8q$XAW%c1;& z#y{k4G*HbL-tLp|#5&gDrctOk7Li}UoDf^Wu}_GD zeO{FArU!g{2Cv^^%;C}&)KKI;tjM9`O4fQrWA(f&MiFC}r*_(CZ4B-e@HK{3g8QR@ z9Mrxql2?Z8x%RTtP{W3IBNxUbD_*p-T_lS4OP5g_dEsiq^<3rc7uNa=*tXxx7{oW? zbDrY82;c@VVM2bJ;&qV)UH&EY@DF;MPKsBEN#Rd* zu^+_eSO5EWVqhjz8msbKT}%deiu0{U;Pc@2x&OV;-hAF87+n2yRu?-ps{4xho4Qz{ z{5I#g|805)xM~rc;C}8%7|1rwoTYdT-KZ>>LFAYWw7=HHjNEbZB7#X6?+Tu!V=807 zw=8BpqWo_kDj%LK2T%x%3RM?dy1`0^KqYJ9!;~Lnr9EbfXG{oTrn5!{UT|?l24KEg zMn>x<34vbeocZ6k3}nyhVq?e{bGkx!xDyr|OAx?t7#D6#qTH=+M~F(t@OGifI#$uG z3o_wk*!iW1Sip<;dAc5GAmNt3W8zkj9Tt zZv-+84rju_TP^BXXnTlO2QO7bn|p4XCD$96$}SC?tyFPyQtUP@M&%!q0S^gF&CtLU z46Rkbv}0t2362&dZT8)x$M^E`RhQ~eb+N}j9GxO0NDQ?>MoFA8Ib``MKgyBd;baHZ z5Qh(9wNRLt)6}A8b!Y)#=6F@_TE8NiF&iKg9L(A3;X9qPLBkj-Exu#A zO=)(ASBK2DSMq`&AC&E~dH);wfJpa2Ua`2400le@_XLJ7{!b;(^u4}-LwVP! z!^g0!Yj+e)uMO{o*goalo1~G$an}>5ki4ON@A~QRzVzW()V=WacZI9C-SW>Ru_8cOY-G2sxC&p@WJbvvr?9syWt@P zsrdK0ScJ=CqN6KSRbnUK>S7t;@4w)6Ql?>`*3PCY(gN2KzSYIJ*=6MQp-h-WpT$sh zF&ceos?v%82$vh}WI|ECVFT#AE;fTRpK(?fa|9X8;F+-0mN~Y#^8LO?@RR)G@9JXz z)R8a>63=WG_gs~8#y4)RR0D|PZX?}_L+D)!JAfUaU?d;B0)RvmQ1FICg@w}Rz3WhL zf-8sbQe5Rc?1V2o3~q5sW!30RwoLO5SFS=57*Nuvh6F@ZG7K`Ayy}jdE{tqI`QJ&~ zP&L9QJlVMnXsnJs55U-ufoKgHW~#wJyTMnZyB87IonaJZ}g{n zv)ozku&E{%SGwvZX6}-rINE%9EXKQC@9?zGxvBj!CQRatXR!jNue>#8xO&G};ia&u zP%3Sv9#(X*w{nP1*Yiy2=39#JQXn9YMN1McJLqA#oBA&JBA^Xj8KLeT!c8#Gs3Lb~ zet78${KyAw%!D)x8kw~tJMKBta>!HEljizK)=z)D9l)aw->qTiv;JQ(n8D zo3vn&BhSp@W2s&KURg;|f`Nhj#K@_Cd3j|V{*9gJb1|@Emh-1#;QJMA6!GcJx2x!W zzu~lBGkqooJ|deDm$jNxEN~j>{;>C3;k5s?M=h-4>7Rn6*(6t7q25};@kn2(nC?pVkfm0W7eGgT=d|?@K!-j z&Szt+YG=ep0VM_=_LwS_M33|=@YfvvK@2R3-|zVs#K7KVrDsP&iG*dDGKwqk7?c>O zRF|NW(fTZ>YmX~&i zetdYbWc;0-QAo)bY11bnUZW3iG+wXQuvaoq&e;vVE6pIj@7MZ%xs9UwW8SpmkO+Lg zZ{sc7?0O1~(3Bf)cwGSfS|^&W_jPfHD|q>vo+2l#IV=0kiwEUgw`&92>m9C?C0euQ z>(ElRWBVl(uLs_{_(AH_hxcZy?OMofjCqA;3?atv(yU{2?a)oUd+&Dd#N==-QbL>B zwScyPs<>uLak2w1zE;I$7%wZ>Cy^NPr)MTui{cy64d-n%(WX909owo_(Czz79#Xe9 zWF!ca;O8wJvR<_;(2J5C6bNg7;kA2bt(?Jdzh+`}jSHu#?`to(;rP-^tAy#9l&FJN z5$7Sd7!8iH!F@lzuUjLH{PXX4hX(X6@9a>HbFgZL72>7J%XM9(C3j6v5^#U$o`F4S zbn$4%c2=8^)h*&>aq*j=yuHs!by8F}_Fs)2Tvd7ZOx}r+d-`VAvZzq~4t3`9kc$}0 zn1zyxTzjC&cB`Y5l?l6AAw-A;v+mXY3#UE!r{M7GE&D6&$u+Z6keP&3?cIwS%!R;Q zl5hp7^l4(;Y3D;3w!I4C3<(On{F2VTIqC){EJHGBgxEPn)@$GtX*0$&4<2I zF|`sdZqffhq3Y8z*6*A9KaC;^zGa|4Ywk18dj3kqzWcHXS(QkHCZh{VgZiqet0fwE z!x;Iax$i2oz~67BB7UYp=`DPOD3d-6Q;p&&y&r+{W%a{rRfK}0fk_X~n)^5dWWWGc z6cr2cLB?oou_ngd+IqE^=-%Z8(Y5uJl1}pHH@hm~voYGw1h>LWPlogpXGq0Lj*ua#- zk(9{0xC}w#KsERM>E+Lw`^)!H&He7wvJal@T+b%n4V%Y(OwX}=7Mza?hcJ;bKav)1 zLiw`LJzrFF-$vk*{NmnOIOMFkuSH;QCOu7$qGAKqMO3KfK21zL|8iSa7@7SVj|s&~ zRHc(5{8+o;(v1^k!_Oh8DoVmD|AE)sBQ%Dkm<(v)K>;)PD&3@X`Z`896nsn|@z=)v z{n)h7M`)!~rJ4gcXj`Qa4RVstkVrjY<#z-{3)e?6890M`1kf%G_oIu&lqj)Ha8%s2 zHe%oau;i5T+{%qRmEV)M9$Al`enNg(ryC0Kpq|Beh1&arslel*gu}p;=$m-isZ3Q= zJg(xF-q$$YU_NTgBXgBxPI#CceyMvfdzK#QgrY}}N|<{>e$9Q^97W_OAZB6#09{1| zK$@p9=g=8&jig~1ssNEAk7Fr)jwZn(nZrj2r&%fS|Rf@DuO04I3N*b+AnJRZ`k(e^>u29T^A2&PY@t^)d(t+I zKwF3*(U!#LQ`|zt8f)s)utIM%OnB-hr<7L+3|0W!4VEmsMrY(pPmF29#@W{52bOgu zB!-KVMsIQRp2QwvH3hiigWPc`0TQ;@LO1jBwv9FTSdt8(bVaOeGt=+vq)DeCgw^JTK@dnn_Txf-mg}HuWVg=p6 zMYBQE4Gl`&v?YUarV01_VyiUcQi}ys(eOX1~QKm^q56GEzW)m2d!dTdN z)74&C(U+Qcyk=uWdvBfukF4!5jL0Nn^~VvISkYn~S&rQKvPK_x2Ld7i<&7v3V&}GW ztg=a*ielQh#}aC3Qi{<-!!=6)v9++8J$@p}qa9WH6K`Jj5K$M@wm72u8Pczl5jNPV zB&wy@Z*h}*gBQ&G4@)~}(+)tlNvvr@ug^+FBg!}l-Ies8F!NrpQS|5!7KC+l%Hf1` zL>cce021R`fYTjBHVO8dw{jI#0#G z{Y?jBPSIpz8$F69$Or6TeP;_f452BOu`Z%2CtfC;ycH{sZjgT`2S9ulgEHBa`N?Uq zapLWHbIHwisc~>ixd~pb)lf(!Z6;VimUbLJ@|kP`(QSddqb5?k;~-#5uzVwN4&>++ z5={`}u@y%H!xa{UDJz)C$ZRyYNlVR>MPG02J+?SyD7+j8=KkqYzOxB=ErTRpc_J^X zsdWXPm%_Atuo`wZ3tY>aMAKvxvoJ{2m~&uW!IY78Q}AY5tT zE1Mj;{mx?RH6CF>RwF67k ze0S%ga>p3$^JU}cC`5$*u`l~)DrVUilLyY@@)CMmXgQdTS}Laf@!=bLe($fE>_n5} zM*Wm9jMo#;k#!=gzb4iNHL++Vs<-f<{ z$rw|O{p3m9p%iMoBo!DN%*h}(N)CmYUFzF9?!X5er4YBNtknnG-k}Abw!`KrLN)?x zbj7ftCbHSO!B0($->LHNblY!S7QU8x|Kw_wA02zB%g)IX4CTvCNPJ2Y5tH7zfzz8~ z^C?58PN?b@C4g#yKT#wf#))2}X6>^%Nuj);ar@azV}Z{e+$Sw&LB}4(C;YCJo1Ihx zn^GrUt-u5RtM?;orqN0>!=_3Bl~Ouk<+kE6`wpAP_MjjMTwyQslP!YI7;2VQ>Nt>K}I(;Tzi3LMNO+#=Fbx&7=|a(Nq^#T#w@B)@#*>pr@6f%kj{ zvd%hN>oadH{}c6F^$DPZ{shHUJivfVQyKld&VH@ZydrQAXK&!*>(l4ed^93Q91pwd z>Z8bPO8F1HKS>k6KAHaro5ZE0cpOOOz{Hr7Op%E7yT5 zH-#Iopc|j&nJ+6C<%ZtqC_L&We&9CS_RHR z!MqP5DTtA<8)lV0Ficia(DZ#xLA*Z8Xm-Q@ih-9)rFRF5Y%jLjEUEwOXa8$kVroWy!!SkD1Mh^W z08pdXFwEz|T)><+sfvl$d{m%nk=KehSl=iBV@A?riE%%IZSY+nJkt2U+xU1ih<+d- zT*mvWAd=wo#dYq-I{mn((`p!FNZ~C!Sz5Hze%!@S3=peR&l2)A4EIzy*!yiT6=jG( zFotnIA)ud7XVaO!Dui$ABIf2rKxYWA5Rv%yMZk23`l(&e^{P<1nUGV6hbUzj+$2&Z@7%N$D^paRRlgP;4ZW=P;bTlS*<- z&-hh@oe3VMJ|5wGxS4E#@#e+6P3JuQi(Z(K)?@zsvLWjbTyevT&wL`(C2mssFh5z2 zz`l=ns?6r*V{+N>WsnxPS7%TtWmtqMZDR8C$f|qS_O2MQa)wiSBnh#EjJ@(mj?Aoz zc4~^IQj30(0kYk{w8I;nzs!}P<#Z%?xymu7{xGJ2GWI&wy*X&?zF`auJBD*0rZgRt z%}P_l8apTyH>?%+&M|KERor-0+~io?hr_sO%J|t+q4+ti_yx!KrC0GQRq<^L+ zsFDZ;l1Ppa7IsNg)k(ajwlpg?!}pU0gg_+wNlZ@33gD;t!3iwm$y`Ut+}W4gC{r{d zU%}{-`Jz*Vt5ZbBQ^d7N1dmcAgi|H8Q^#kXOS8Gvlc&m#rz#z#DtD1@j`ELEq^Ucl zX-21YHl}J**_YA>-5qz`qfDp8PB(T+H;qm=8>fUNs+Uxxvw6o_$vp!!yn5p6l4qD= zU!C!MJj3}YgJbLlLO9c1`04}gOz-GS-|9@!)5bLYnM{AGtdOHCNa3u*^w@|Mu1a#s z@aU}gqpXc0M51tZsu?*v5i?~VE3G;^7xz`(5dwCLT)kOR|9Vb=Q%+@cPIYz8UQ@E+ z4F7yGCTdgIyY%dq6&}SBq8axrM@CSlc3S%iZ*x)Bz|pgI7NR^?9WPufyX(29>Uo;; zl06vY;`H9ra&jZu)>=vG^$z*gc8YB)`N(oMo#{Ls9^5Uqg4YsxN4PK8#vBF43$B$= zkb|;;I!xt4H?Q$np&A0?h~QCT9h1NBi$1Q zmy{X9r5wdXj37vsX+Dt9L@tm=PM(!1wv>%ogZ0U9sT*&Co^@#skj1GYk6k*dl^z5~ zTIO!0d*9E{W2fJeptgkGKVOzod_JNDthyp${xO==Zd);TM%m6a`_c@* zu?`@xMzebUPBG~-U0ZwcA)8cc`u>%qn?%8K2F6or_BE9H#_yPff-zp~IQNX#d=3_= z7bXeABw{Us^z@eR^j3`xZIWr#ZL z_A8i%OkX->*Hbnz59JWOp(a8@H(ZOc|3EFxADwjjeiVN2Ym?)bMOm-aw@V;N8bDX8 z>V0AepaN8@k~)-ir>yb5;bVs)Hr#5&EOt};;gc!98ivN}%`VPDq4g}2S8|gYEqQPt z7)js;Szgg*Y~BWg0byXWln*<}>1s2jVY7X(NW*ae%%2;75(a{n5DmQcJ#HcLC-Z#v z8c0!Wf>p1Xdq2F`8{LbCo2E?(+H+(Itv4!>NgE$UlnQABWV8XY+9;0+RFH;7GweYn-wQj`Z1 z*;$Z#rQN0#?8gMbze787;}W+jxQK0%(J)AgraVdKo;?_yubMiTI7YXJ#PFqFarba6 z=&n8v9*>YCRxj9^ZS0m3KIk#4(Q7xJ9$vT=EWG0 zr83b2q-0P91-Ruda8pia&JVw(TU1>*wv)=Q2(8!VMu++}GygYhJT$RS#bc#3hcy6~ zZ-8{)5)#eay;yV`x1Sq+T8No_3ypLON4^kHe-#?9maMBRCK_QmBFU^5hOpocc*;14 zSIl^0PG=GQR+%K|76W{?^{TQpv;aXQr7DDkf!1iaRh2PuB#Fx8Epdu?WF`cI-KiUU zh6##sY|21rc~1zepU|RLk z0+1AFFT}-4ak%P0a#m2BhEk<6qDqGLmgmJl6|tHY5UDcYUIVDpsFSRbH6;&{HwrSR zA&M#Ff!;6-&ZD)EBxJwTpQk+H-Tr{wz{B$k=uUTyn0p^)B0!rFgmhDf)PTjphuKCz zMRgO~jhNw_AdCJMg3BJ)IV1^n6S0eRTX|bSYKq`8YNDLFyANXkG1FS=Cm^IG2y9h7 zWAp}O@ZKa{s66{Ux*?yDp-f(=T=0F}mPV{tjvv|K*zr{ifpNpR_P z;^!0#B1D5aT$jF!T<7a4&%SYEKKdbY{Zc;ou{B5#wL-;@TE1g{(3vl}gLraqOAw8QEzgdu4^TB9xI8 zD&_Y%=h#IWclUjNfBg#{&h>e{U$5(WUe_vH)>t*M;iy69xF@X{L0NkJYNvIb>Q`AcOmKY|gIJZ}`>}qYRJQeOdUVenFlrd>vb9I@j@I<5RcyJmBI&=00~8 zB|qV7$Cy!|+sx6g-Yy+{d!my|>2qjDpjk%Ht9?T%m~KJXi+t^9!IJTI^3zdAXgs`1 z)^$?_?SsDwZyliRyEf(W(OS?j%I|G{>&-KGJmoehM0&U;e1e?Z-IQ=R&}-7$IV6cFEdiqPgRz>>Kmx~X=GvZ4^F z?nZ9-BBGB)QKkg-RxBcVPpd$Mj3}DZd^JT(FdbhpjT9P6E*V31Qqlzy<&9vMt|i{B zxQ!ES=(x6q1EZLHkL|Of?fTIe_*8>U5yuRkk}qZof?5w5y!dJlFC4)Dzd-26U7-C!{AB{Y!_3R1cR9?bCx~@yR5w96<1r<_p!{~>q8(cNcRKV&}MyY@Mo6w95V57 z2=WoxNC3D<2nm-V+fX5Il;|#5v~Hj1w{@Qso1z^d;4OsWTgAz|!)Q3r z4&v8HXjJ7^Sjs7l)RWcqsM2lWww{WsyC83dN!`4C9&{y zlqF&Jym=0Y$;vsL%0}GUUO`71n)47n65)__(aPLI&e=WSV!N{0KBx}ehSZTu_fEf( ztsuQ`_h=+a#h-V}IP(l^HxG%e!PnES_>Xqm`;5@7M8^-!@vMciu0Z zHd^uScvz)7_DhXc&@`GH0&6;aE) zv?cG2t+@k}SFz!PpEX+H!Uw1iw}u|JrFEE`UdIjX7te$Wf#CyYZZryzDNZuBwubmA zw1j*<73ad&yTcDgay5uFzs3zCOQta~6x{ltQ+$_5m}x#!coTSUBqyA@NyCvH(OvUc zf>^%#cwLSad7H6{kX&_?lh-8$4UNs~RBK#))S(zmj|=R2L-$M0*OI5`fp+Fbexv8R z+aotCv!ltp?~sX+LhTh=ohj7Da=oRpOr23p0syA7623Wbt940p>K*_4OlTs0G2+%$ z{Kqpq9`r^Wv1_~M5BSRX6Y@Jt2qW|+j%y&VmW$~mE^`w6~5 z_2w3o*vU_YjW>2&)@yhgjDGFB*RQGMCfB%+`;F(f*{X}UpHEUUq^Hxoi4@wzMNC!T zK!m$DzDRzuu7r2Mz;4%E_~6WB2jVdE8yYs7Qpl}N#7tcRzVtX3=2ca3dyc6NI)818Z==wDK3xRAxPRe=7_3! zTpoNp7SM04Xgy))~3K?IkHUUvwAO z(QS|}>v0COkioWsJQ*>X{(6%V8foI;X!8AWN)*vtRes0}VTm-+O+t$MVLEBhI(P%}=ab&3+;CDyOSx$tHVMr4N<+IVz7| zMy@ft8#8e7-1`uI#5|7{1kAFF!;F@mnG~~(WDpE%*aD-MVZBa!v@A&tlFFjC$Qe<5 ziS+i|RfS5^gc;Q?MtYMGhHGm;xDTyhW}0P`e1lOpgY^EEN9)(KUNf@R)~m5DGc)}% z*6Z(Jlw3Q#9+O$faFfNo3_J{Kma&dq_?dD>dLLL$BH*r%^?8`<~oY-lt`zf>~)_!VCyGZ%jGv{Lq(e zbpl>M@o;D3T@r}PrvAbyDYV9|YiyH4w<>)mhld@=t&2P5S2w?|+5P-ciAKA~4W%l* zx1SD`Xs`!pp$rmkqMly3y2b1f?dV74R9Zs&k=|C{N4KvqVo;N!9(^C&fZWT#rZt%k zR)@KXS+PiO)b50+av=cHW4{8fQ7|hK~Ezuu8E(&ZWS7ndoDZDe=B|@$T zvsk49BtA5=O6bt_#dsqM)?WOJthntd)SX6!|Cz3LT0$~^J3ko-6pE>*uasD~_5SUF zBzw%>q*3jg8|`>c9Z1wW?x0B0(N9P3{^04Toj}1rUNb-hf3AM++MS7uUB{_7pG{J} zzVrE#I%?kchY+9wM5Y<3v*D;&V+u9YV@0fS?DvN=p&hK0=q@JQ@|8*nvPiyVDU{O)NA40{eju=~+%f2gJo%>PBSr9Dm?q@o&M~n)1P3BC zt}`q29W`dW${?Z1bzxqmghU8%Yw1dfX==%f6E&kvdfF8J%|@&BQ8lom6!RIW7;bU# zhvwuuHZzQ@RXq<0)P)yRO6(6?HPOzJp@OTFIE8i<9XNGH+xOLI2ewiowL$9q`>yAe zJH)%Ad&ez%;_tbgc%9r)E(h^T8rXP>$^ta^=C*zok7rXI zzGX>6cVVtl;@qhs)diIje`!e_0-sUxQWp2)&F2)sk5yT8+p4MXUc=_qlwD2nT!q89P(h#&d;<;w4SzG(t_x7%(nO`VbQUfRtYa& z&8uvSwzJdaL0gbf){uGSL37(#km~~&C;_Ety;Q5j z&%HDRZ1(yrRUY(>?JTxDsESf?t~@9`J>k4yMtTdSWN87uJjj#*B?DEIZbnK7&M$9ET=tpIST;*~!H($*i zy05%d-bHg;gu-Bh%5Gug13SaLm=^7mwR`0Cj|JtLY`*%W;m(0G>G@|3ul7p?9lVPx z587<;*tYwV%@e!1mj=b~w9*HFN{=lMvPM4hpI;ty+K``?&u*LP1#EfHyfjFidPnwb ztHdH2VqPQo(!iGoeSE#Qnn^wVY!6qzw%zEHHE!!(J$1Wkc;Das@EtecKEpdyeB|3Z zF1?JXPaj8?~OlYwTq@*w4E#p+4oA~KEc zeZ3FEVe8u132g?kG{g#{oXynXYFqoz?WBv!gI1>WeI&3rY+Ro0rG}h{VwLIvXFO4~+ zpNqk&K2eb?(#;d{*E+mQdR}=@uSqai9)zc1&&FW2_TH(HXmO%w;XJqsq+!p+V0A*; zD(7!!r9|33THX*4d{iwQDAFQed2kULX74N-Mvs0hUpn=Z)iXsw{k_zT9B#rmG>p)O zE7$MXIBnB~JbiOsvY@4QU~^X5(>>{;=bzrDuOyLpHfVPrRlfFZ)Xr+^!PN2Fq;k-+ z7wG8*>aI!5H@$O$_du$p?}2QD66!1HG5W6jVURIqVg8Ujfb;*y+v2~*-&H&h>&uM3 zA&0N43ojGt6-q#}BKvZh^B-B}wS}YQ^PiBhSY2y3{R>slSzJJ>tr3`J?cD^L-Xosh z5fqIaV!#aCn&3uG+y9geoFdkbY4NW7?5b!j#sj z4KJJ5@nv0Ibd$~Z*VU!msChrX zu5R8J=WpTfs&1?p`y1-&R`$hNTvxZu7bnkn>+oum@YG4k)W%G7#lZOeX;R%~vd^i*;8?MDe&{wFrfmudtc4$#1) z7d#G#Ac(&;D!vevj%ybE|0&f*$!ZW3tLAJzsq(oW;ZY8Fpfc=5C$?D>?X;Q&h7bqK=a=J75dy&s}P?_{9I#Mh#+-gBzlAc19qQVQ-D{h`fNyG2-@#P)b6{Rh=Q&RYzbm)l1+%EH|J5tb*0f{=P zlm;4T=2c}|T;#)&T?&Z=`z&WzSL1I@%s?`Z?)`%bKZ=2hs=L-yWIj?~YFUfRsA;zBQ< z#@pR+p_jv--}fY4ordfUmWxhJj<$lE6HK1#g|hkUPHtcq_@k{`$&dCZ0`qVD(GsN^ zr#m_)DYym2;&DuFl$_HwIXoYa;(oN`>>?X0*G ze*ce_m4o;t_AA4w28qP}X!DmG$gy2r|Kw7@pWp3G>Xm#D$29Y!^-MUr;&o?Nuo3<% zWA~Em@A}I8z8`JOzwt*)q9i-@X@XqP=rf!c|Eb0CZ27@^auRgmDsNt&D|G$LZ1|+& z+gSJ?*nFv(wztwBuPVOWYW-Kds>Kk8PJd-7kY{TNgS-mV)W$;8 za7PN;SqGC(AWGki6Nz#>7@V>z;xEouU6EYck`Hv0HU^uiYUpyCLC!VuWAmkldScx7 zT{DaImip>!c<}rYmfY@Ga@Yr4xz(ay?RPw*Tf;oRIUDNQnf<_Q$n3vSEg2CqnOwnh zp9lpNyjEjVmFs8Z1y%)S$!(g#6iZZ!T^*wWG%StC`Dyq_0f28jl7;_nPvmx}M1TgW zQ7I{ykUt$jRWWF_5;+S4lOx>?u=w|8t;wGzsqUNS1Uo-MKY46xF$NgiuReB@sE`Nd zJaQYIY}vg!ybVCe<+UgH#pXA==MatFKUw|s)Iqb)1kP={s?UveMxoWlAGsa-tOJ!L z5IYVonvhqqh)fsc+15l8ty{^FBHZ=t8j5)$Eu? zpoMPuQ5{&i)mqDZv9BcOkFO+US_jmA)f=&ADIIv76zvLft>c4#!pYc-ZQ5)zo%co* zQB*2PK*@Hu1eFx@ZE>?Vvd+W45&d=5q2}p&AWU)I8<9c;Ao|uD(WV^2HyVWET}St} z;`fZ)Q@`Qs-JO1TX5@a0gp(TVM~yvX%*=jwpd$hRI=t>~E^ZIG_-T9J$;(?Fb(U}a z{L$jr+u*U$w5?k|JnQy-H$tMrK0Zl&_dRu{1-hMGrXYlH{6!i7NE| z49Ee^qlk%Kj+cXc8=doFy=BiDPq7dyHWaD*xIbax*>-xZLhRwda7}l1^z}6WAme;7 zx0Gj3sFF5Mx-Yf`uLTC^wZ+lr<(f2Bg%V0k+U&KX<7xIhNTsJ314ImRGi#^R#Ba_4 zT8|sAjc6(VOZEt&=m}4Qy;}7V&tvA+F{ZN3r|Z7zS-1Ye$vB-eCrS>WoX(m1U-V}% zq2Im+pEGAQwt$Q|6i*PqSpqM27#V+)gnG+Go_~R8P9rEQ`CoC3E@vEYHk}Z z1=4^ya~S2F`D?nh;F|6eVJ7YYl|aX&xM1s{L`QZCzx7~-R($6uwm^a{tiKq=SXOc7 zUwN3bT&L19YdSY*WzDRa{KjBOg$IEqdxXuO8xFmrLS#0K%OlhZtL++ zJfNzWPkVlS6#IK5_*Xoj*vrk!SWosHy@^5&4pod<}w?N zORuR}e}-|mjuhEo0~P5O%01raa@Gd2hIsR6W7AO0nkKbfCnajtcdJ~wA7NtkuB9GQ zE75AOCg}tOmyUbrz~x* zS)O|4#Jf|sc3)EZL`TBur`MV=ySF@Qmg2H{-{tmRA7Gx!%|=5a+J>o^VW)S(U!fK2 z-uF7F!0b1}6lIhI<0q6q%800z+Eio`vokS|k7nNv@)8sayk}-rH~wsX}@!d_I44cX+;~YOs|m^h4j{t5XKiZqLb{ zjh=b-nTUz;kyQyBjoMy-v;uW)^zCspVE=|iv8dq6)pPVU26}3?MbHTf0AcwMx>m6` z1KI9KD-=Uk?N2C?OK>{*uNP!y?(`ayj&!>?T!a;6?y;Gc9%~P_*rKAxbTqYjxYlfu25May9Pe~zL$*Up>*O5NDpJ>I2GgMg*~Hw zKG5qO?e)oY**!zP_P4m$3D6a?EW2`2ZRpL68E=qE($V{&6$2&h_kJqXaoK^)b z)+#bO`LlSfV&tj(DXoHfEPgh!T@v^St#W}@{Bo_L;>2s!fmPA}eXV-)Q2sxsRc6>? z_LF@><%oqgzOh`UBj0kzt-vJoc2WBWC!B;Pe3NK#>H z)#9x`(RQdj{auq*wbl6ky^Lz(4^ECxU2J_w@SuOZ{rD^4^)KA3<<_>Vv6q;?#JJ@> z)I3aEac$5C#dAH3LQg*?#=lN9;zMvIwpU2mq|3EPKm<<^^a9d6zG zzW)~2E6Ha2-t-&K2sS_aIJAE6rH{=w8INojuJ0{b_ohhU@TZ+u88KiD%E;&~nX;3j zpLaa>UA&<^_I?<|#n`K_pNm3m8h%l#8@ikj1*@S=*L{ zdYDD-5WTlLKmA8tCH@Z_*;IbX4CXZx=xa*DFR^XT@zCwHzq2i7@CPqX|L6>s`kSA@ z-#vppxpaX~!*d!11&w-}qx4j1medusF{dGpP25ss{P!$g$|pI@MjsU|0SbC747$JVMopB$q7 zyyb24y~}r>)$DjSMPqjB$*PhI1SJt8grTUC{`;q1TC_i}bKEkC&OF>m&i+nh{rYam zRiQT>(a**dFvOnqhaVkali4|OjhH9;9EmZ@AdNSN@%tlS3KEUxu@7ZAA%zOt{bPJWq;+Ye485RWnWZV|tHwZZ z-`Tb;NR7aeYl>t0o-&F+(}M|{0kO?`Ea^d0e2T*7m~*sy{3)PC+~ViPlpG|Fg>B~| z5c7MlXijMr?2_A64@6fVIz(%p!`ih@N8Z(zE_$^mEAM^9Au0`ulF;-$@f&xyQ0oCG zvUsEmVL=LG&FMPtOYv>8(0l{slOF<1Z})b~=+VFdj`xHx-01+Tl>m%ldSxgSZM;w` z=WHdCGq#fDv@(naa{n@i!-}->HeW8vF>BSP*q_l#Z;1WhrIkhmViXdXEhX81v=Sdh z%dU|EF-!H>@bi}|!|&G0zEItt)=I|5#M4@-$eaGNSNd;j&v~oul4_a=RiSd$I%qS?DNR)DGkCk!S!A5OxX< z;@yeCZ>d*)6qG>U&xaDM zh_29mQ|&ed6mC8HKGWclQz#{QmzZCQ*a3+q0|4x?3qn_$G1M>+=p?Qsm8yhJ#)Us7 z+#^YDKn1X_iG=J(K)GI5)?$ed=|P6jY|^N^a9kqlJxe!_E<_Q~C~mwoafOk;uffv? zi52(K%>)}okICn(N)M4Ns$=%5mTsZ(%J^f0lu%{~piYvV$m!Soj|m*IBZ}R4K?=Dz_f#U6L&E z%f~?omLQV!@ zG+LD#0$e^GyILo^bZ4EXv~i}JFkv<+_yVU8)rsfdl^1q#G7dm1atlF@><9=w>b@(| zBu&xKSKB?CzLYL8FIv%48z^LmSL3-BZ{Q2n%mJW&UAb)pReGNf_&=)Q;_5Hjq2qc? z7o7MJua&-a7=5kq(0j34)d?)KO|aBFEn=(Z6fb{5~;!5lIt` zEnRjI^Nyh~o6dSDQle8P)rRir5A#q9zOGtwk z^)vL}_gYCm!@r+3%xc?%>x2LINYje56~9QDHkm+=W_e)%+oFVlTiw^a_P|HG(%#;A zx(_L;gBqMEA)U@vP-K29Tak3d=JXgFT_#F&o%7o&$we`=f6JWqV==V5rQR#Ds?U1_ z_eG9De~EwY%NW`cA%8*1LVn#L&pkC?BY?es&&bkRvG8a+p=*r7MMKKKLr6$vO*Ii&iw#X6qG5e1r@IUSd zOiQIX%8$WZKf%p0aHF0hI#jQ(40Hr0Y6k+kZyG^mo976;PmU`3c4|y^+7U?jzvKwK z7CGw(TtKm1CWLceuj==Zrg(5e7q#%jrlkV5VWIZ+cmOu;iu%XNR(Jd6_}lh-f1GUd z@_YXu-)r(eVJ4nlUadJjKV>)nr}f8ph1(1NF<$+@+zbEAPm92HJGd8)S`#<_r-i>~ zrdw=L>y+6O;o~`};U#*Pg z@7W)nfcXpkML)Ga){&kWo82Gl$jSf@KloGo*I7q?;HUOY>j>%ePi>x&;7_XP&s*#l zEvSDn{O9)>34Uf^{PPwI5L}vgqA>L*1cL=U_olC){pA-JAXmuM`fvQS7Qe-&a~R7X zAAT51vLFk);H>)2%zt6c#h>GY;w;_sKZ+wrI|M!IhdriV=N`CG8wMUzamR-g?RXI# zRQ5lC!4a(V_;B^{$nQKpGzcwydV9 zUJ}re!4EsMq$A@jN$0P3Wb6)-x#PKd$Gm9jA4kT&k7Ocv!tj$oU*?S>Ik zNCjhGHZGP>z>Vt9OOV1+z18)&(i zB*=Nx;_aO$9(uq{w}TRJ8uBnb06NKYb~P_o3i(?zKv3xD5vpUk7w`I6iDPb&qTAu+ zOmfmg6_Fmd)M7qb#pXq>$C*8|-leN5Zt${k~>=rieKGwqwWPByCr z?VJBjc;Gxo#xElpO*=AFZ1Puscl+jOJ72M4nS?x_m8o*v?{j1X7u1ll99yy>C*Q-O z&O1>u30-?gcO<;6CQ<5IWv#W{NJKkD()#iR?a#KR+xHn91KT$%X?g`-FvGu=x@Vm%zmYY@Zg7>Pp%2~sNLS2u18usuZ1 zy;lb!-PJflGP#cQ5Et4`zKNTj*^wp9hYbl4DOYOA z4$sptvUsi2s$0ch@0A|lD4^f1gzIFx9w@l4c3t!B5AX2p&%HtCX@a+NZ@v;mlSX}8 zU@QxB@rrSJQcLBVl&itDS4`L4q>p1EJh1(=1th%cA*Hwhhd!V1)r`bPE&J+qhZ}WF zPC_3!QJB}{6=+2tIMy36eVv~EK&XM1J;b~Zgp8962@g}jVDvq=+4c%X2LwDh3juhq z#7)eH&8^YBDvwp1Mc&QMmV!iLe1QjAu2QdaT=0RwW_-z{1+Ha0y*Wph&1rmfN|Vpt zl}<0Kk7cgCBD=yFPOR60HqGh2KkX)dqC$)g)2<9n?s||p(_Z0UF5M@sHlqEc&_>i~xkAEOK*2ST9hy9l($4_a;x>+6$%JeqL5kSKws)kQ^hf%p9I3bRw z$`KSmDcmHRyXj zGZ>WO1F^3E6GkEW;%?3s{geIgS`FNU$J)MZvs?)J{(%VbY|8Dsr1;py?W4`RMYA(N z`snw%r}4A86i2i@dJ|%K`lxa^8;OEqG0)m0XFlZ^vYGzm$tnhHiO0qsXIcl}Rr93S z;G4mY<@=L!t6E+vmT!FYg?oCcz(Xc@0lSI~*a^_W*yltCftgo_!KD;A*Dmlas z9p^CAE+HV?h#WuvCBJaRMK;LaX-4Z&u@UQfAimAnV~bJj^!rcl7QI+J79)?%x-b1# zE@JE!2043;sxD{a=X3V-UKXoBt$d>>68IF*RT|;Lfyv4V0=p}#v~LW9^WRFE zgDPuG!TB#H2O$~upz`32E8#6mEeL8d*3)&Q(8|v@y9t36j#)3 zxwYAf6)$KV=abkaKv!4E;=PcWFTSW)F^NA&4yciLX3su?r$z8lGTcc(wQ8^G!nS-6L8iZa&XKuJ?&0#dA=9UbPGig;i}kR${GAC zKv!xPli>D%R6HWYIQU>!n0aCfSWcV&x+~&H8Gkpvoc2^#N_W)Rua(pO*I=VR3-D83 z*FOuoO3$&^HcS7Ra@uDGp`QO##fn$SM3_b{zG9{GBdq=K-PZ>OW&nN#X`iX_-1mpD zM3{B$R&jOJDTfLpDAa zor1B6P=JqMp-PcWIUdFz$U|^j((74!HAZBoHEueFq6Pw$8Dr?{t>AUZyQ=uo4*a4|BS8W+JLr8y<6c#VuCb6$K^-ox-OoJ@s6sJDV_%oO zt(gaCRc0D#_NCj+40>a0aIee#bx#uL+{*q64|CQ+Z-bmVCWY0wlaE#J9-9gg#6n6R zyU-PG(fz18-h+ExS_2LZRsl)Z@80=#jnpaK^DIA?%|%+XZs7;JEd)sSf6;C6uhlr= zaP{+lTkqNL^Jo0F*X3eB)n(g)XSf*$Ao2LgoVjNHzJLt^< zsupV;ntCiNKzV+$b}cx2eIlfv(`p6)e}MX2Lq#cH&&KJ}rReK9s<5aP<4ms5_{zpRY8ONfym+}_>vjGE z4>lg>H8mBEGQbSc-H!WaQS^Zs?d zv42RH?sFA^ojcoVEGIhuf%@#tEpe+q?A*MCA{MT*gf1z{IeTCA+!OecKBuBo#BK?uzrl2=Z=c&z7Q_$SH>u*9DgX^vz?B)Ac!IOR=p~M1O z1Y$bv^5h_-+i}f4dL4Q&@1y>Il{h5y7r1Eez_q_-IMcxCN^T6630}Pnsj)a5(3Kx_ zRR-Et+J76c$bYLwz&K`IND?r1xR@f%yrCHG@i;JtP2WBH_+_`1Ek{mpDu33M6lK0>=!3p{X?}8G+icDqn zQWtN+%#PE*JG(ABGrWmJy7Hv<95p66{))j1ua7r+B6jPhzD|s^eUpOGIJ=_eGm9Nz zpFzK134_H9#+azpJg1)FFBBeQ?7Y(pcMh=1EusuOSg`H34(9sv#E+eN-Ko9SISd?w zbP=IQ8u z6-$4E#f|k6jkyX`i;*))|1xw(*f3qSK)KLJjpRK!8wlN*wS+QaRL#fkuRkhOe}64w zt$rPi`cS|vC_7PBgIc+1))5s2s}lwc4*Kv$<5D!HRn(!Mw$;P$+`EV7NppU|RTd9y zTEFcVd=_5oS9*Mtz<_MnmR0Y&>JHY;Am2k~_3>mbS}q-X4tQd>^J9NOcg9B$E{8h@ z;NWuXX)UWc4o?oJJ*@kpY?$fxE9q~P4X;!mzo!9l1^Ot?Wpw7pHet6sJBR1a0lz^X zr}E3Oc95^@BdG@4V!z;wK8B&UH>@#^FEDGqlQgy14ni{Bdeak>GuH>_Wm>h@?xRg@(lr?$l^|lEIt1K{oC1I;eh_iYidZw=^I4j{Y zSCknrDUzo?(33B}httjZHeZLgKUL;}eNp9JRdYVM>2!K4YV)~VAIy$Wjz^431Ye@X+>nH(Z(;u(_^;z|~C znTR8|bK8D4Et4RBPi*IP>eTT=U;<2OciI88r=Zf!M_(rcim^^#XCKkpZV-7sD> zO;EVykcvAcfA_b;-}|gIcuEcn)6AYeC7;d^Ya9l>=6L$whvASyibNd!kELmosT~QU z&xSQh5B+i9js*FXgP_-3L#In3YlFDP(PJinUDrC$YaZpE6WODjw6V4F>#dm&@1K8Z zqwu-eU-0$ITKlTkkwl+%%f!7T6{Q2z9*JwoMs&C+kr+du4>eCn+F_taj>l?q5GzJX z0ts-_=voe!&6a*C!fnND9#DSm^$ra7TO>7_A%JY(iw12FHjM@VRTCvK=Uiwa8iS(I z9rD$N2W>c%YI@vJ0Hd-#k6wJOyXIwqNEeYLML;oiv-6tdc8^M=?)U4WL5FtNc9NL9kVsAU$l|HBT^D)$Tw<4M5QaAHu3OX0L6=#h@ z*n3iS)R)Ggowo|6?@70=kIWc{K;yV!_9}lI*36H0ibNG(dN*ATHMdDABC5E5_wLlx zwWoyb_?tPX_6F9_ftGg1xtn>jiX+}Qq>Mg0qxO7>ZE#)~MGV%hsK^RPw3v5Xyw>m5 z;Uhi96b|*=+|z;C&dFqiH4YgYT3&~Bx^)PH_ax!hd#K?gi1O9gmx76|?0Hb_ldQs8 z{EUCi&3xY>(_h_@JWy~$3XR*O4BY6;?;W@aZc@OG1mw_h8S@ z-OPUiL%sN=aCma)H!=A=WT0SIx{RUK6(|YX9|n(xOd@LSsYnQmj{JBRDPgW-f6k&aShBlfUwuaJK*Ij|iT{H}fwx zDId#XbENq^SCu05iW5JH%e5SjZP?4Ke4NDFzlJUy)` zY|axM^-iC6YtC9W`||g|6gf=GCurn8@s1vvVQ^g0yLXRMo(;T!HzAdjzl!w1sb&71~S#$lp3ve<`%7 zKhrF=Jnz4Y%y{~6KP|L3`_mT+Z4SKX{p*4@cSXm1MqGp8_ zG$-veekMm{$6)9Lnv)Fo(hdi{aKSk=wXI07Q0?SqXM*tLm!3k7${TUrVW2W%Ti(p_Fv{lZj3oOuE*SxU56-E$Q|G z2sl>ni7Q5y%D{xqf(acry29(!yDi0c1!e>em4fY}@KUz9cF}FuUO4@g)R%pm@Gf>G z^IwN*->17?w}O@RHEcqs9B)p-wTn)Do*X~SIr^DA8X*3gpxWOST2*MF@G=Lo1L?Xv zU$cczkJSuMXqG(OFSD{{+XfXPP$<`VG#s3j!Y$GypR`v)1hTm?K@l%|ng;8@+{Sa)LMs>p#(-Ax^p z*H1T&L`|Iayo73*f}=ZkS&U64HSm@3I54D}Opf}=TxM9~bo?l8CBw~F?*UyE#gM*N z4qHZ_9j^d|q$nup*6b6o5#%*tLhrV#zLLjul;5>GWl3OyPkyDUw% ztV&g*c4~^bkr;9g3IH$TG!w=WljP6sP`6?Ui@jljQo1Ohj&33Y>)2f2 za!`AUbg+X@$Ia7)#Q@QHodxf+dQ-G`` zt$|L9sz!2}iv!ys3ya5g+!TNftZ*ymW4+u#ZKbh_H!>Q!PqJ7;6yrEcMU8iO5~A|1 zQ#tKB>mTu`-sswax2GFKogHMU*pAGeMcrVWzj}3ZXDu*)m|yUXQQflP+58khj!JC(>6Q_g zQ(O7{z`-*ghhco}_8#vQuql8ET`0-W$si{(yaCoUS`J_hG{k;mV$P6}II}wo?_E#r z!H!J<9BwFw+Y6OpS2xxrq*{AfU7TePG=nKnlyzPVWE~N9bz`UaoGvnuM%R~uLk$y% z);{CrU@Mz3BtaeZbjDhZ z0im`;0zJ{t4d@U?alayXw6oM3K7T%zcoSJ~S(oQ{E-(<5LI*N8=fA7APAjS_ghaqpUC4w<4|mIgXzW``Tb`>Ou+Rta}DqtbA^IG2gC&U)P_Hs#st_|M#MpqHaym{KQXiR zN8h)51b$;`lEAa*Pptg|je4Y09&4m(_=Ke-T-(K~+*{gszLw5P;x_-AL#a(^uX2-g zI{4Mxl$v8%-X$kPWTCf`G!u9rz*aed2E`#?TfRf&{S(CeG;pny58h(v2?ZHT8L~~E z<5KorVsWBDJxIUN!yd86LN_MZInObOq93r=fa-4>TMIaq*l81t=A~Wu^l&SX zxhI!r?BFRS;J~WPJ(VnDSt|E*WJm;e6LeDNp#P%L;=lQz&`~NUsV$R%*}Gi1 zztXi|eb8+a{9J?b`sB9P%0w@2wSVTh+IkH9@#BzJEqO}91C1m(qzfx5jSLjz>=PSZ`{@^^OxHmad@VK9asP2W3rK7E`Raf{z? zKea98O8P7I9qC1q(dTii|GL!`(*cUC4apBr0vaUL+kVnqj9vX>&BfU72e|rw75v57 z7z|MC)UCh;D3Z2UuI=oK{1c$C8g2LmwBVJS_%>vnJTLO0Cw}g1JTFCN{gt!v?^^~j zDXaHLR1{I#4KA|`n&~84m?E3~ek?~3SYWI9DT)9ux>8AEr!+CzksG@Vs#6J2NeSQu zQ)J-!t$IqEn|3-Ry9Lu+++!iI zvDVwjJD7fTlEPL`7Cqz6aIQ}~rp=1riU$zFsw(5Os;(koRm4u^gaHWsnWjfDn~QMt z{Bg5lswA)iYjpYwfB-{f;yzqErmfLt{+08A086ac@30u+H$P^n&ITA~6E7+}QWNF7 zjh+A84Lq9#pUu_TIMu&r^|AMZsq~W796@^3_2Y=C2KE9MS`WvydPfhu2Zwy_0 zrh{NTm>0HzMVZWYUY(jHBOJpE-$0bT7u3W}6@a~PF1XK7wCA7-%eX+{PnR!-g8C17 z$!O5{P1VQC(p)D+pZDJjC_r5^l&I1XLM}{j(`TWIsbT>vj3>&28=! zeMpbo_n8ZFhn43B&4zfzml|O&paA^ThIlm^n(%I;L`bAZtxcA1NbD`sb(L#t9o&ya zc0ze28qhllEQ=Yo3A|eK&?97)Q-#}5z`zX!-k3O}g(P!u6rR7sxNT9l$hggr^vAfp z0+1n`#xya7=iC9l(H3wEjx#2rTOtT(6bw<7t}z#1@3)J2=7y3ev1)apy+sK(dnUWj6*j!nWrUA^)PgJ=7J^L8L?? z=>VA$K|0?de5~WTOP%hDm=9#z@&01?)q{si=$!a6P_*n12DcGt_8qln-a0y{Reavk z#)Zq5ez;QTs@q!`10CarQrfHfVYR~DHF{Ow%c;sg$#_{yLUz6HoG}rrh1C_uo}TJX zAAfdsd}@{c!}G*cAc0k{pt45uJKxMebNDP!W#Z7A4Cp^B%SEB%O4<2O;K zps~h8s4Kb1#T4e}+)amLaue5Yj#WDLC?;Zf)C>T~Ygyj!T9a4Imft1|l`Ju;#tWfClV6VxL1 zA|-XqU3+)008h+k0+I_Cd-uH;NKE~_?W(gdE!=dB93Yg^sWVnIrcFa;LJL!f+F> zZeDEEg4B~~L`xN{p6^c)0iEmwOFG$^p&QnV$Cm!uq!0bUMU9<;Ie!{E7dqLOT}k|H zOb5Xeq%}CO;TvP%#@LJ-(fo!BCaZ+Ui$D8|Tw(7X{ztZFOlh9ElJfyCgEyI_cO~|k z^1i|OQv?zTW%m1lhuogBw6|wT`g*U1)O;2c^QYBv&d_To(>xqWPBnR`kWxWtsDy5} zc6eT&*O2pcPR?l#RD-q&(`e*3PsUW)Kda&P86@5nYLdBT`QB@E?aNtmX8~4 z@MUO^;o?qFc*oxuD9e9o3@B7^z}OEQY);q~P9kmMse10EWGov!3H-B6Q^eJYI5RgvhN#M+3jM!=W8KC%&V z{vh}e9|8aMq0DZyEw08X*+V?DRU$CPZgyO zLVg%K!osaIVv5^M$vp>(Vi{H+6dosR^xqdBpN~i>lR6}!=RnuNvGt%ZqE9>^K9>RU z^j?LgwwF*urpuYO_2}I;JcxN&a#3(SOE7!%0@t&@l-Fvi9R2Hgtt*$U#599-+KG4Y z=K6&lYZLJV>h1oe(q zqoD!2<2zpp?mu0#_ja~_A}h(72%R()|7@S8_{5A(5=9NVT@h{zU({Pcy%V1q({Sgg zc`I0@$R0Qf;zjp&Q4+s>D~Fm_VZ0*Ul@^zK$94b zlK2=O#W7em=2J1(j1hSwDHM4R)*f3~BTu2!Q;0p9>gHh-V)%3#)?Ip%8rHlGQ6|$@T^$-KyhVmxb1o5+pS? zCkA96a_yJzWe1WI#1mYUjYR^&Dy2KucxY9cj@g7)e=wF%^-wY4F5;{sbd|jAqeMAQyW=j z)f^T+Us=)FOFUnzwnyhA-TxAyousx6>Y`^vJ9I{C&D^lmkIA&IM zvXYgMgd{5~$qG?I_RJnFtL#EDN`+*vgrwyAKF2zQ=<0szd;1H{FX#PyJ)e)s=QVrD zg0#2oW1vGjnf@;C+g@K@FL~d$Q|^=r9&k${1;}aB=-g)AYoe(qAr5}g*|E-#S)4!k zhPIM}9HHg%#QXds8iyBxLfB&%#YBZIgWhB?LM#$?=Kv(TeDp3BTbw0j zP~QP@!19TCopModgq;rAWX=Rga7dLvv<33&`)2%5#`$kevS%}5EUS2Wf99h7JIOZg z>0Or%;P>QAv`B1ISH5V!j+9dT=95fL9||vo27*RPOqVWNA{@HeK)C_BZ!!5X>Eb=k zERT(M?!AJ+-@z2oENYAfK`dHC6~5^E++w^NqB>x%*kvZuySy}$-;rVoiwiv=0s)pL znrX_EUBn+e?8~!h7dMS%c&!fH2@+*q^6{R3W?HAUPEVa!XJdV z2q*H3nlSG5!T>>uD2XI-^yfQ2^1^~I4 zHa*(7%i==C7QWAoAJazKz(o$Rqg^6}Lw0(W9uQ9V4s>m#-PKYqz0V}Tc_5nkTDHV4 z9|biKM3htmhASOj&y7lNF24^UIIt!6A*nFe`tL*ZRqw-5@9*xz$A;#8N-kg`p9hK7 zDH@Td-!5d%THZ`ttXTTDwyI6$3I1+XYiw0qg%&&iy?{zB>#<{kTsknl4am(mq zM8(pdb020bxerBN15?7#s3TupXPbs;5q-{Gadwb45vyB2tsKJ&V04AgcE^yWf(5yfNU8w4cj&yD+rV8u!xEJt`-Gab{>7 zC500^?7hw@_QCI^`YuowrMR>u9!R^h;_z5cg_%52poWq@Yc>WP;%j-mMHriMupO?d zTjlF0UCe&kcK6;vcRWHC%4cp34BVsrBhlOo7j{O~DTzeEGB(`1Jj8Xei-~fd4~I5N|~(NrIEQZX=6uJ&Hye=;#K(T=aHb zw-7lbRAoBIdP)aYOOZ-M4#_UFH^`v=S-Nxkv8$9AM7n4~R0#NA(oKK4$L}C3t6Tut z18hV|Qg6MLF`^_%_-dZ-jqQFo-M4JIY>Bp0$s}~&cKpW5L}A^sy(e-G<|+WP*5*|j zrj}YjG_2A^e!^%q0+=t@u1>tukn%3dsb))(HdRn3v}BBxG6{SDJmRy_ zu$C!$%E+d;6@&VFO3@cmCy-YhKQK}Fzb6z&+5+8vMeQ07w)T?1(C04$qc=2B)GQnq zUBhc98_m0hk=^4<1Qb$DxcaC9idQj?r~-;ZAKy=)Oq4tJX^03pkk^Z2vxMSd3_l`b zY{;s$Yl{(ba4HQZMr4Fs^DA;>gdCPKGC~e1pionDami;{@VBXv`2opBCr@_}MBjl* zdLMfq2mt4dCMt*sIb`kH0q*M2|7p+ zZ;)Qi%TAW@RE&KPs!96zZPp*^Z`(ZJ{C9K>qXOr2x^TvoBIJH4q4<5_?S=zGfe1MU zIj|LXgp%wM?OBr5$*d(bqttOpyr4WQA`U)3ke=i$&8XiSr7ZAVZ3YD0o93BfY7h|i zx*?XQNFv#QSTU@N;Z&w}f{bQjfT~1KC7;vXn)Ae0ZskhH3Aw-DDRXg1QS}XV_hF|O zM~SzRs=R1%-3`*lGoaz-L_H<<09kNbFdDz#!OS7Pn=mm6@{QJ0mb4y6@O;j~Tv^f^ ze15d$MU}H9Zm6M~U*e+Q6s{mSle#U7q#BQ6!V84%&Fx^{NzUA9(H);dK7PN0tv6yB z2;EdT&z95k!;0`ezyUBx5Ll{;%YZC#Yt*05Sx9I;qUA8AKRYr1QBft+xsyOVzgK%m zxEouaUiekxzJ%|}lE9xdgf$ux`%@)kiu=GPm)z&P%_T=f2))&8~pUv z@n>9i!^(;7Zc|Fu3v^DN47z8hXfBj9|`_S52D^`&atQDx6cpOh* ziDBt&U-in>MA`Z@^KSq743(eWhUUKQr5Rk`k#ECi_aHJ<=H#S>Fjsjn2vI_d?W}+M zA~jJDu?r63zWNG-w_m0-m^=Z(FrN%0rUK-o9%X89Ku#JPqD8m`htgkz4IwA3w}|xf zl_C>1D8`?Oq+As&Tik_H|m--1-*s4mWVk6uV6M#Tn$taNvgBZJ_6Vh>S zC&fOQ!EKEN?yLTkye{C|zQ15tLaE;Pu?qf+Z4V0&sEgNFFti3tgs9#~HZQu3a$f<4 zrEkSvAO8G6U7CpRt2a>Yt6%zUuieC5OkVJP6L&NB)ej@?P@o8H`%3o}JpmdaA&BlX zItCJr!2-}2HVo+Zw-YjP$pyOpX|X}i%sS8*Jxd~%y^El-p7Ukeg=vu#7?nSV#?+{S z=d(e^s~J+4#c!X<4|7=Ib^@lw6dcruoE8_(HA8k?n7f^%ogz@PK^%^bPavknVS#U~ zTuv&EHq&H?Y0-H31R5R_@^%W@=|qfDS=~%|Y8OUZI}%iughVy8c>-e0jw_g~dwsnb z8MS>KF`BUv;&W9xpB*WP_-%4ly2}(e9?^c%yuA$WMT{a(0)WJ&lTI!~(eIE&JvQ8& z3=A$O5UH@+J@d$HG-R{%;jpZH-%yN-8!cgmz_ie8mTx*`s7FlN6Yff08GMTh$ATnW zohn*O-z93yAo|u`V_;fXizY}(=>v&<5nV<`GEirwKCw7A;CAvkU5QNWdr9tyVZOgM zUbRTM;>gW5{asNOGQ^5r8RRCW8dl$w9$S>+s{1FEiLs|h=ManFiWYLZIx5u)bBn=< zNTFhZ;OWG0$0l4-Xok6HP${`#zTn{fME?M}M2u!Zc?vl-U8OMjLJ@ZHPCHTqB}L0X z&IkA|c3gKb_B3*cR2cMX<`Mu@J@f@&+l5_{J%$UrN8TnXEU<5{LMgcp-{=#rGU?Z4 zXLg$?ggvlyO_ISOu`}r0GHOxJTGPU@ z@;V=o*mvpWr;gw=52eEI*ngWExWt4gGP|TaMOODriEv9*+NG~IN-)k4^lK5CNy5|sUvzit&;SXB24uW`{1x<3?P2{hIikoE$OO9rkaX~LkV}`(bF9v zFD*`F8FA%O3h!p1ETLK~>iL>=*Bv^b1D?T*DTd7X;mL$c7zHdmsq6tX2HT%S;lmPp zW2-h%$;!2f@HJ9l*Q#@!PwZm>5|c zQns+J#6GLwJ@@0qw(Waz)vm#b7PY9S_liJbeULzvJm80yJ|+1)^yOIWX(MXc^OeuT zr^e!-Kq~B9Vjo;4Q6adpAy!~KLGEgzQk>+AMD_7R)tW@*+{zcJc0BH)dc7*I^Pi?; zlDbk7MXEJbDj&CgdRn8Ns0Fj3vEb!+Dx#>Tin;0O;PuFp(@Da0Y|X_~$^o`JZu%BDatr)!bdGwS($YUO7*-SwK~5m%yj|+N-HnaZ<1Q z)ISw8*Q8qKR=pmw`*g33AkC&s>dj~)vBWK&VWxA5Zzc*pJs5dRE>Y)I|NKhm$qK zXM*v9A5!V3P7&O7#FB0U-`PpO2Joj%%Ay1zd|ZMIkW@RH zc=FVVfI_=Qvp}9yL62yS;i;y=rwPzeYE#%$L9-f1mV~2-ss2ZQ zlZXlH@NPZ|fC{y1Yqul0bX=d^s zY~u30zxfJ&w1*4F;gnp?_;{_Ede=$N)N?%^ez!*eTu1`1mQe6T1QeUUgSd=)myMQWMXjk-q)3NA$w( zi&J^RnvYWx_`=0ay3eOVzz51Nw?cv*9h^*bAgRCdP4b4~{&Lp()Bedj8Lu4{y2gEi z^m)}oIaHJb4B`fHVH{j#x52~ogs1<*=mxs&PS8-v=q~5q|_<<>gf*v|9Fiix^ z@anvIl;cK>|3-1){WA1()gr^J)=R2I7A~P@#53DaQH~3l`bU^>MrP9_*>A=pap7>W z6SKH5hUBc#1fo&HSo#=|c#pV*kj6T=A36=<5?Ugt)-@!0h%nZrlD<0zhj7*Eft@_%75#T58~O&>L+|?Yw3IGgLatvONSCU;b#>wGGdy+k zCXWFc$&KC?QgwsQ_e?+E&!A!9U5?G% zwwJo$-X}4RbkPKQs~aIZ(LzaxFmSYMPvYAo*Ai|CQQDi*%0?y7Ui-%@aUdz@0%Gf9>kNl)Uj_;L{i`(@{ zN>2{O$+3s_sFxNr2MlGvBX^D(@yR4#Ao%2}nGVk5Nc&s&h@*o3b=UZAkT?Fh+!TBOXt? zpI7kcwE;gMHi^yxz+#FcKeZdqhqB!?qn#AP^^0iEo%U)koaU zCw#2wGSaYMbkpLBCtO&&^#_@D99CE@&g(uQyPQp`EGOp|=ghk^i(pCj%BG zP1u*(S+P}~TWUl)7}4+rJ2GZ##Y`q1_M~34G0Q?Mn;e()@$=(og*IHLjUdx%4LtQ{ z!}X#dl1Ev0>$hh_p2jzMV|qoSh>_r#+^s(JtO8Kv(74&;k?sgC0XoKjt5?onH8?5g z(ahrF5qedOHQP}@5-Vro8@+xnBcDbqIor#8LCfq62Aqa=vGb=BZ&9W<3vz-Wm#+eH zIJ>GZ^L;i*9aYNJ-L3o7BRo@!bcSnNTaIbK1d?4$=5<@1x6u}<{tIx{luL3mA=+^F-M0C8ZnGCz46y*Esa zzt&&MLHWI(s=;V&K~ z7R7a7BhDCT;ucnUH_0ganXyxnVc*bQiT$fZnBwnGu#q!IAF}F&-GYdS9`)Ti_E-+* zZb4w?c9;>f;&s^@ewVYS5(jf=vnh!|6-+z>;v6z_`clpc9PEq>BM zEWi}~?$PTJ`fV&YpTEeJDh;A%ABl&}Sn?-r=TAEWswfM{J^xTLku0`JVqR zO$SrodJL|bfaqProtDqFUYm};pm-e&4LGALovpNwrgIP+xcEbA0e-6`o69C%d<8 zzc$_v*hpKp;B|xG&@l`rT|x%G%WSbFVuBxu{7oI}aciOnY)3q97MCsg}XB$i?e}^oz&^rxpkzG6*0S1-A4y zCC#rtjDF1Ol1a0}c>Z8K_U?VL8~En0HDWdMnLw{GNbGxo*S-EE9{0!Lo&okSY${iS zeI$2ly2ir>i6rjh%F;XSaxTO^i(ee7bK?k`4H2eBo)0xS+;N*i`!@D7k7V}V^}KLd z>vroY`rXPE?+keMu|BqW{3HziQdc!_q9f$u$LVxmcWM2sAzZqHoR&K-ChNoYt zuksUwBc%Kl8+q{GsvU(L+AlRh&3ALMWf$GIkJnoDeGf8UHW9bD9EI~f$Nzvnj<>}Y z;jKbOW<*m=>g45d2Rhm>7v6pTfGS;7_;|okIg#4<#+`TYxcqeKOm?AZpA+E@>Txv` zXl(6pI})Df2yQ*fWTbnY5ff~pP3xm$dm|ghA>&7QR!8xHHE%qzvfqxQqAxjZujk-l zn|a5pL(b87#EJ`<5#pw|4AQ*0{!V7t?ue`S$DH$6?N|LEA2i;+M@@+UgNQ+UFtk=V z-dB=|9%Rv3#SPszOJfqFfp$t}#n;_|2YlZG{jb*5{rvO(1DWXhB?<_cC{m&zK!y%O z!&lNn$V3-Yar8Ze2@q96vOJ@7YEVB$I-suZo}Yz(l&`XJZ%l|mVy`gN6hTY?5`~3c(37_kbNc$M{2$J+ z^(XV5lboY5&&r3^hJexJJ41xgb~GHtCggqx#px_H7LnlAa7?)_e}$B|Vl;8LcB8?u zJ81`s9p=wUKhg%?!VQ-g>CgS9ZE zFeJTVxcJV4Fy9mvg9cA%{X~`{;kFj_4^r4??0t6}ec!Kie+OM_Z2>s4+N=^k*YtYD z6=H4!VtPUDba`-DVlC5tiI;B1xYy7#t3;}fNuqtQ+*g|s!$J^VVkCM~u~t+?i2Rx4 zvz{!dqPZT?3(W2KWMu8+B3>GDCFm2PMn|GOUzqEivo4CJz9{#~Fk1sk!6!7M;rNCh zFDqHY;Y74$fn!;Ujgre9rAaAC?b7qIJhyqW6wgXAjCb5T!e|YX9O1A5cakbS6?6ZT zrTV%1h_X1Qlc83ZMfwNEk5q;?kyT-|xMV?)w4#qL2SmBDBJ<(hP4o zryWvA&9i#I5|-Qp+5|)j!$jB9VQ6GkLjj*9gr510&?IPn9vi75wMBEPew576Xqnak z;@-*tf|0#@EAhsi=-Tefj`%t|CE45yuSat_5Tbj@5kgZSqzQ^p=v!E0%;8E4Nruvr zdKh;I38=bU{jI+wmWo0;p4iCcLqxdQ0*suZJcMkx)Lv*<#KJckMj%3(aKafKxJV6t zl@>g(lHj6$UN}b`-2r|017#axHrYzZQI06`mVKqSt>nEl@b9eN0xhtnsO!RWR(9)B zzboFIE*T!acJdke{?!b=)CRl9jYb0^@MBm?GE3w`GlZ|IdyzKB`Paw~1m10xC3UY) zkrF7qj^U}raXvqMk6WpFUZ=+p=t+sihtZH0Si~sDs0fY-JC4TP_q+TgWI*W|bi)M- ztZKR$CzU^jwa}@GWq81Xqls_!L|==tw2^=~riHM5))DA#*$KBS4RcQN6zT=4gt{l| zS!V{~pzV4UPE-w|qXQmMFqi1+g;7=be<^-K68FyI0hC;_>)aA~qy3 zVH~L5TpXpioS0bu^ZsyZe9hy1<>y_@$A397F?+mYHfH6_J?{u&;?_24mpNi$@p)gH zmu4MVS3ZD+Lqm?t^7#4WPA0+66>?8x;C{6o?sU_nBCKIMB;FYfweCkN>FslA$N%zK)hdcLM#>kB|kY@Kj4-aVkZ<4ZFO6K_Uv&47X6 zmzG+eoUAyRL1T>_43!Uaa&l`1%`SX-)wVS^uS{mh5~~Y!GU8h$;{v4 zFm#g9(H&9e^i65kERnAJTqnwi5pklkjPeFLtTf+Bz%HZjf*pA_ul&b5ay#kp55t?& z55+J9qQ3aI0%~#WI<&-g;ekvYz z{eXhK2Rhn#^{H*6`#Y**Tt}X(?6aSlP$QLoA;|db740LP`e!!^U1YxYJ@bjWRxI?9 zmSN~%g2Pvp5;+{O1sj*R&KEvMW+q4LcAWun$HY2#MgWNEjubkY!ej$URfi3U#U9-W z(QaY|mo1lYv1zQ25OS5A*%n9fS;3jMhqj9NA`L$Yd5AN-p5Ipl2e*(dJc5uUk6com zP(_^Z@D`VE?L4^Y1mH+3!FW;$t^+JY3e8(w$%S1ph@8RlLIf83W%IZc_~g<3F5{)6 zQ;N&ea1*hF5RqltV>*FE!TVG^XqDiHFy#e=oJ(8PA(B!11KT6_6?wbhICqD-I+U11>-aqc|7z!t$ zWAJ`xNUe(Lp{Yc8*T%am()+0@(*kh>ltiF|h(P-=P9S&B6-pxJYb>#tD$3LElwE@y z@mf8JXKwd|y5MeX_uN71ftG9fZoz4}P-BTlBb_&LEYEELT3RT~`IjVgM;{?;$WWmr zWJ1|b?4FB>jQcLDA`%(zC~L4}y}Kp?KugF@`jba+T~!05eq2Mgu_T@Xa%gnm{O$?J zV^MZbV>z6gvxWj=b@P~+P(4EI3cKgg7>qjoNlPSj9AP_f0+XQ`oEPSTWKAt#gW1h5 zvm}6$h%5e?TQJg-ay!FuV$>7^fvRMBKb^w70i=X(t7v6hRlWM~!(+}S{*P#TcMunT zC8wsj&vYv(G#R{OfJ+)=A3st;N`ZOiVIbXo!lDB_)B$DuGSo!n#K$#1R2=s-4Xk9z z9T=_RD%)sPvZ!7%dZT18Ja>KEzKy((kId_Z{l)cxsON536<3OGnQql&xB0xl|M*=>e(Mrz^TX zqHcTWMIG@OYj1cWn9EaRYBX4vp1NIHSIW%@J>+2(<7|y3$sUkY@qna4p3$NGrqKbO z;M5l0OKSTWioP)My$Y(acw?p_$zPFSWBAm%V82LX>#+lGD+H~*^uxxemGD1)Ut@Xn z6|*o!Wv!dQ7*LhWa*dR&&P)A!;%G%^>F|-d5U7N9<;~t_Iq^$HF+A)%Ld!%k$GVQC zC#oMT-;s_G#autv@zuE2h7BN&$k?KrgEVr^HHPI^9ale{q}i=bdZGS>_9x56fFZAa z68Iv-FnYN5U}Y0P95KK^AYDs4fH-Po@xC}vki)iQ_slpG9{!p_;|M|&6QqdaVOm&h z_fiB6f(C^N`<;*@SiurE$3`)!?Xx`azF0<;j zznKb4{$OgL{S_cvGgvI*POI&SW1eV~t{3{pNtvgF-%JJ>XHC@Xq0ZNF9PU$5>|pZ% z5j#81m=Qe03@1wY8rFunpOllt{H`mrbUVr3ykZ_yg*O)v7z{!U3iQU5Y5$?XXDMjMonwDaPFd&OPI0L{bO%Zs`@%kCU~1~_Q5y9l1_5u!Dm z&Z~Qic%BXykAFk7EdTT82^AVyIWYLtYw=|Y?>WEQ&$u@dcR6C9n+L`ay=U&7d!BUl zPacJ7C)OHA#wM~E1g7@&B^@!I!JSJju{Yc6n~*or$8NnPd#ZoVz3~eiw0}ZS+}4qJ zAMtrz!|&8#Wa2Bh$pM;8D=EBZ9kl98HJc4O;8iu7*Lo5`#fd=6atPJX2!i?0Z_#Hg z7p58oT9(&%o~9?$1Bkvbuxvj@D=l*>kgQ)A?Y^U=i;+7d%9OE0`ZAjul{DLN%3|mf zLn&vcxM16NU@rIk$Ew7c+OFJJ_Fmf_ub7H~Q+<$>kQf4TQraKdT-_x;8ee0Mfj*~C z2Uc-+$60~ zl1c=abr*<1#Bd#;uT3l(x-=~yMZCnUf482eNRU4GVS;3R5{BQG!2(rlykPW!C-)c% zMjLm8-0N%)3wX#iZ9M$Q;WOU9(_I;N^+I5Q(y5g3##^DU8W=FKtH+x|JY^9m06ntv6PxK&`w2Ho`HxodxSwNrKb4mqT3~tMMYbtx&pKJVSr~Xz^y!*38NjTI z<;?{eeJWIaEU&1nEGhn^feBOC0Xk%Yl5amr!wkIEaxK7V0pqOUW8dv z{+&%^l#9BdDwS8AkKNcE2tuDOuoK;PESgV==#d;%^j!8GGH#d)LE zr)&KTxO_#QpaMwY=6CAYC0k_BY2O_4l|c@E6W?1H`{?a87Syq*`WZj3!&hiz3bN*% zKiRWg>oWIp24CeZ=x2_)G4UVFn@vr4NMr%)uD&zx0bWqYZg%a&Qg!SPJ-|$xG+7Oe zY6*;cBA+ul0dd2UDu#D_=W|$)1lv-O1Jwhp&5GC}kMGNgO4e*que*~q@sc@Bg{*t& z7MZm3E+RD{tHGy_I`xIYjqt4Y;!0ozN#xC-O6_#%p8+{k5tDTTAjjZ&cWiC$fGUFRUq1m&m~U9X@G*4s zb}w;Gby9zot=jJni=O=46(j%jbN8U1JhTmb8f^-Q8-B{s1@=n?*6lKy#QuyXKplJA z%?*8!{N2z!N8cIF|9MDfJzSqjIuciKLd&h7rbN+BLUw?=n%jGUntxL70^XK!yI*acnYm(<)-;@BY``|9YZi#2t z$}_{qjhPQ&k8~lQ)qT3C9X|8)?O@t@8_I|1N6kJf4Gw9L$>Fb zhn#vvEiNd_1>g8_pT=26I*`XWg_lmBR?|Mv<(}+AGlT=$?eypvO4!Hwk0-0ZVK``p z<;Jr6a z5(PRoGBxHHsevrE`d6f)`&jwact;5bXtpIL@TZ*Pw6Wm}En}@r!Z5t75pyM|q$`eW zBHlz*1JN@Q%rXa{Bej`qAX!iln11EA1hEya%+z*Pav(#yRyrjg9CV5LWPU%hy*9KeIIG^9Y?$^uWPn2`4_i% zRvszaCP)Fqh)Z>^a9Lm0 zm7(`Cl#}8O8jF%S@B~QYVH(fUg;kC>=%5L5s&pO^a&mv}4PnIDsVfdP0uTzf2E8*1 z2EFftwcX|ud42|=VC!8CKu3LBfUO-6Z)C0PK~KIW$8;XqvYdPphyU|H)@ezp!E9^w zD}y=OT~7vcPrtz=rDzK>0a}*B8Nxh!5v7^k8F<6M+oHi~?nGoX{P62U|L`Nw|E6*N z@k@vG0O<2uyNikhvSoQAxvKwzdaZ8 zL%5au$;WJWc11!@3M_h2cC+X$oy4Bj==7ymdm5TSp}OSz~x54BtuF1=e^)8$e#PR)Sd=2z3R{GTe^t5Ml5qCariL z48Qqa@Buy1QD@L8_z^T8eiBNGi(B_XP>SCWQ!*57wJ8~}(v)l=!d})_d1D{;Twmq> zxQcKj%}5$k8uh)zO%6@_wWJ~#n38iFc$DVT#N!Lt#uqEe?FBX;`(7v26TE#yPlASN z8yL}a1s9ir(8h*KItBldGRHwVuXj};k6u={?u8yLKLtA*%i5yb>lF7sHayR6>}^fz zi5#D08~7S2JR9A>BTTLkAiVcX@u&)RRDar11$*p*#BGsg{4tITc<=uKj;r2i>h=?b zAI+;z$$IZz-P?aC{`l8`=C2+k5t9Sol@XXVDx zU!|PYAvs~T<#2+O9@%cgEL$hbHSbhh8Zt|hIq=UuuxtrX3HW}WxWm+`d1srP2q*4#WRuyyA-?zPX&fA(kp z5i&;Uu?w0oX0OD8{y4DfS*+ZOF-mv}XtOIUayZMQ72cA{<$Si=8W_%1d{J>= z@Dwhf0lC|L=cr$Y(4u+xb4TrR^DuW&mEIPUW4pPWdOakxs-94N$$tD2c50Vs%Dvn( zX_lApD0UvS9&z$K%S@ws&(bWVD7dVXAm{T)|D9{@K~Gf#Cx+YpH}HsB+gXIY$PfOq z^tiwDx31#>a^B`B)?}sxwg()&dY03X}$#5=% zxO1!&Q~R-+8?YDE@OLMFe0uQHz{h7$tleX^A{3{`>fp>NWA)N}gJaL-#CMN3D5)%K zsat7rjVc-Ed@VK-O}FccY-n5z|Kf(@Yy7}!!bIE9E&y5Mtcz~Q-~^dzUf z&Lx5q0VWr)=Gh(~$(0+ZK$}LtJC{qyL1?%lvrQQTuswU}9NnRun7#1TD$x2`4{)IY z6=)a1D+;fSt9<3swHl0(cjE#kc>x!{BD)ZtjrTV8B5OlLYXTbjn-o^Q3e8;VkKcA8 zKDt@9hf=@t+EoH!pX$52-&civ&uq_TL$8QQ{M6M2JV?yN@nI*x~B(Z0L=CbXV@HYyguy_mdypsugHM_nI`;#3U)1=5oOn z)-^E3gYOeUk-1=t_8S3wXD+8FKPiFS9RS?~jmf(*-;MIF)BJUM2^fs`$5ko#VXXH9 z*Z~A*K09M)p-4YCT@fg0y?5RZO5--e$N%l#<5B7zBzy>s$tS1mlH0#T0tu9~s=h}_ zX`huqb|UOIn^n^4!Q>@x=e4|yP=J&o6jcJbZUkrUHc6Q%pOZi~D4PHhNQ0z7Kmyr6 znA_&YK9tvqL~vpO3FN@W*R}7y#DC%W+x@B43g!88-SjVU-DMNkpE~UMHc5Dm0wu5y zA^uv=hiTlp{EkZ0oWG-PO3c?Ms1brzY6%r|+R%rY7`S;YFy~vKexHe@+g?RKb1uCy z`(ZX0-$v4Q=X{FqoIre-pRT|VA7;;oFMXh{=Sir6eVeRJwrR29{UxA*S={m4j+ktS zJE}n0_B+r(fOLD1L86h_B{LLl@`gUlFq){!AIE$4{J9^d^Z)3>l=2h-0{aeI*rJ|` z`+(1K2EF5l@8v#pXD&xEXV{@1Sq6>Y=i=gf`GBQm=HTF+_fB#nTwr6S)E@;mVu#nDX2L| z1cZk!K6o^P@n|F$_ED`u1^GhzwUBMG`9-VqqH}#^dGleBK{ch_ zzJG!o38rYxNfvVlCtjJCEslbePjBo$&HTbqaR25hq-2qAc*Owj+Z`8I83jLb5B=OI zfTKq0&bx=^1GtZQZX*sZ7kS~D1{56W8kCZt?DPB}1<(}ww;xUmN$IFx<~96&aaa&I zFG5}`%J7~o#`P01t5>H-pcg^0neM&}jRU=d0h_TW&@`)F5BuWRSMTem; z(znDgp zU%+ANxtMXPsJ#@4&3*1~dpfJ!ebQE&Vgf(_f{!8FigwHl^jy3%IogAO01lm+KKHW%p~8Xq?}AWX$%RW&4T$Cq{VqWfXBe1%#2b7ls;3yjTxk-3q=wC&7uT9e#HM!lt7TL3|Ya) zS-Wd#X{m}KH5{!U{Sw7n>}Gz=LDB%z8H~dZ?gKT*61qq6A)B9X_wR}S{@kCalZR=m@H1B&`B&fehn{=eMdt_?gIB!S?iR=8Q& ziN#$g4HIA9eeI9$XipxQjgodm(?)V?ze4LJJE;j&=KY)6#5qpw|J}F9vEjTQ{9Ewx z7aO#~8UBiI5o^y9E8Mnx&AE>cxj+Axui5eb=1h}k+dFm6yX+)zn0d=-aS(V2fot{} ziNNLpU<*Ff_?x!BhR~kq?VcyJ|9*VSg_afV*gp>2+I-E|kCZ06+)t0F!A6&Af zLiE>m+s|vh5UtRh)8udk=$FC>@bz6Yom#42HAhIp&N5y@Ua}f?=e_@4vcDA+-QOtw z&m_;=TfBj+jTJB1Uo9;;5%;ok72*oPVY7fxr6ueBEdNYCdHzzAUCJl#wBrD|+7-P8 z$L%V8qw+;#hy-yd(jqTKab=aim*USBI{y;I*B^W-X0CZDb}w9tbIU4%t^KcDij_v9DxLv0Lx z<)s*yO#{SHP4l8|r+@Fn**h`!%*vRh{qi=qch$WVt7JXxrv~ ziGP@6>9=D%?f3r^fup$0iM0fd4!`gbJa}s@f#byp5IRb_!n!}nKl?`f%O?IH%B-+38b1WErhJR%>`HbVGAp*qbUcq1Mrh+c(9Bm%Q?2}PEQSudg1yL&02fUGsPv3RxW;)8v{_Ew;ta>xYFkOQm<(Y53MS+ z5ej`JgQ(ItH7`_O)uR3{3e`oBLiIY?*Eo()yYrnK}9E_U=b}Q-He6`-NGkp}Ol9uA~3%=5Z{*Jg)8Bz~e$` zPq313{X<&DH7uDq?-`caZiHg*mwb87)fZVh{xGQNoW%V#a`yidP?O%T`SR`u!tntU z$@CNTC5Dk%y5+~KG}80=v+0Qcvxt`{K|V*Md25*@kM!A?&^n|NW_7p+)%1fO7m)D;;x})=v~f&lyI9I4@|q?{2Kp4L+?7M)iEY zwzjownkH)ox1U~&cnObxV~1z9;eLy)OvI^avgZe~ntTMnm~>7TVEV7-S83znt))Zg zMY3PJEB7EHUT*V@Vn^--G{jV;pnD#WgN+)UBeEa%orGn^9jCeUa z@A;ID0wP|JtF)Z=iVd9jcPPt%g6Pl>-iC;R=yG6{{(vlq7R`Ee;N=G&FFz2?d@G%I z1SwdeT)6V2HJEi9J%L23z`jvGUwyA#yKv$i|C&gp{+dXGj5ibpnS|`w`Jbe;{s(B^ z|DZIO=`ZcOS}^Nh+V|J&;(&?tFYUW54r#$a`j_@yDR1#F?d#1qH2Ka~obz*Mpo-b& z_aU2`XEB%it6wdsbuWm`e7vC8Y;-}(!gdRRb)hZx3Q?zw7%B?>qH*gbja+5Z*AxC>L zC%0;8PVV*Zb8;75qa1%-qlK94zf;hC=Hs!Nf0C1XdP1J(cFJn$Lch3CZcmu?X!UHm z&}|cNJs#(Y+Dhu?`2Bl;4M%KVj{@Y1L@deaq(mW$EggRgbL^{sNzpjlvH7 zqo(6!^1bhL!8TC_oIj7B)<;#WstZQM$!~%#ScxibMKQx9?^}xz7YKeNwm7_)ICR97 zMLH4}rMgOnId=QY5jXzo$gStgOXmA(+W)zjp&MQ%0EiiEs_!g_8StYaSb&&;YSh<5 zI+~uMqFhV>5Hom3GcZe3NUD$ehg3&1@l{mF+KmQ8;K#6tOH?X^jt0g{$FQkXR4NyY zUcc)d!*NQYO8w<%P+oNm=Xp~LX}SNgNT46r>|>e{?b22C*S|mQ!gvwdE8G) zxE_GM&Gx&`R!#q?cW31ijm4>#w={oyHuLwFNGIJPZoiv!GS#)t0j30)1x3(`dgCJ8 z0!8AZ=cE(HzQGw3&50-`C4O5r-_*Q`g6qT&G1-%0ngh+oXm_?I4J4Ft_H&#Li!Q6k zY{&`3mWc5tLxWWiGZdZ2Rhloj^&749Eig*2QpxRkBGr>L+PIN^cfA3#C)DQ$KKx7l z?mwD(lO4Z?HA28*n=4c}SRXy-dlxLdN__}dv zw8N}CfT>q2eDEt>ji?z*DLs{+@D9O_D(85SFvdtVnTG8oci@lN>bo_ROVx-o%K;ken`{ERgrYr8=Bj}})nb*v1j_BluZEB-C05?H)Z!I7to)y3s6poyuYsMz;Y}|)4KP4 zu(lg(SBQR4g)%WtNJ3ZW=hGEkVY3&I52NV1E+A)*QfnxL)DaF-0;F3GCvp20c7epB zxXD0cr+C2(PCp{C!^B3)>P1D${fUKwq&b>+zcmUcD8? zka*<$5H>Uv-RZ($p3-Sa|9p%HsiA_RO5@aIwW6w_`!r?^0b#FVlYFn!BnV!Ago}o+ z@{r`@E3!vpOs&L(*fvbVI_T^iA4*9V%I^DG$<^7+8MdAFZR0&Xl@rE#-igw zC`b+j2AoL!+;ww@ktjkzV&{XVDp!bcCoXlWk2xyrK>yt`&M$zR+f1;v=aBuEq5Gfa z<=m@xacsmHDV$Ob+~D{TAS`$xm}AHyfB;|_hQka*@W z_3<`{ARdY(S?f$S7J)4jFHBKc>n6}3?Qh=`&Jf}2AvqRBSraeDS6Sy{m*q}A-4oJA zrr;M!>Xs&$a5FYS!6PS70yUNe3xo~g#5lS3biG1}dTAN$Er$g#C?;xFWW-bjbLmyy zl*o*&3FAN8*IJQ@oUVQ7mcH?|ci;hR$168-X(f>{zP@MkvG4V4U12U2!TK9cm+eD? zua-8PF3qo=tt&+0OTWY(`fp!a7hK4omEp_VRb)k#ZeJB+>x~Xvwhwg#K^LZLU*b7% zAxa-IyNLpRU_UTjy#h&nr{-c=bc<+aMe4~46^Gadvm`L~8q3saol=1{DfI8wcRBfG zFt4*dYfy^GQ)8$=O*j<&-iY0WAvHA8PSN|5#y1A;A4?1yegwionq{P09$+%tzq{vP z8#PjLe;*ohx?1?W)=K_x1)fC;SJb?(H2j3&l1HHuaZk^g3XXSy>9VPIS(a7Yf@Npm z+m93sR$;t8==bcz2YiZJg1xO|bvz^{gJ<_ske{uW6W=`!6g=!cNi3|9G9IROW^lYo z+kLj_h_?v72>hzJo@=#gI{oRjO*f(sIddk=`mJMCvsIfb#e!Mp5|hNNK9BaY)aUo_ zr*{T)g`7`qYYTVxX)BKk9-{8yV7yY$n>Xf+IO_H_NVW*K{r zx*2CUaA|!28csK8mf`nrN}n~$YzDq02_Z-ie543Q;7jZuOwEK$=J2HqrzUlEn5?Z- zAF226-NZE6qv5^SxMkL3*>a=o2)ikb-GeR}-X9Nj?vKITp)blOTJ( z@_G2wSR9lfQO;emA&P1|9xjup5M0?1D=?lQcQsKdPVz;f`go#hO`>vc<%?9i@g!}6 zB-Jv>#*EPMWJ8%G^`^?koPzNb^Q%dk-I7fOFUM1DuAk!hXuRtM4#o|8f&mgVc2$@R zJ#+U<6P^6I_G;v<%K;JvVPd>r4Mk%@r%#W1ymYopWJFg4uzWY$u~|FjXFKjr$*lOg z`PqJiRrbzCs%RHx`~0ozLBhUx>q_Tm%-_11-6-wVbF)1NN2@Aa2E~AU=03JVt~CAn zXFHv;1PZbKt#N$fBTz+4yC>k=0(anq9Tix99HuX#2_t4$e(Ta13y_gUouKn+ZgQbT za0e4;g$w09e=|ikkSSt1TEX&9GDSAFIk#{Atvg(}tT_uH^_n;jtpi0n8t*w&w&zmT z$TQ&9o$OAVS!#q#tr4x;zuwJx#5Kf|0QdMD!i5yE?E$F#Ef_Q_Z*Nc$tG#l6lC`|-PN=6LjCIJ8AHUqjDgv=1F8+aqJ($osO(B2Hv5)qnD1zm z)83e0_=uF#+%_DWnnZl{OBh3^jds@m{p!C?^e=35rXxkz%*i9g_Q_YHB{hIf(C*MN?yAhY;xFt~HS{UI=d@$2e#&G3(`OK!? z%k%c<*?YN!CBpY@=vE|S_$0}}hx-_6XD2-f1GEi8Z{-<8xJwdc2Fsqszosofob~u39ndbC%g_&FrWLlqUAykzZOFmJJ5DlK#8+w+!wl_9nA?y>%#O0e9 zpVP;ta?4?6sxLVU^CYX0Mnj^B@9m6&MM+<>Ka6_O`WzONR(=tqk3i?Ivmb51G&PT( zp-JZQ7$t`|!XJjaipWZcurluznU0!Ajvam!Lp52xX-`EmvhP@mjf(WE%MW z7M|A>jhb^;<-}Sc^r)C!o{|!6>ZFU-o;6hqO|~cB#l*=T??}w$eBGNmhuHxKc6aLL zV|JT;Rr(&%zPCiRuzt*rLvm}$iV+N(a8)K0TVC}Gbh@*hjlwc_?!*{c|k%z_#mQ{=lBs97|jZEydgw? z#S3zkIZhhq>LK&p1aPAX4icrW zhO^&mu?HWgejOHEL`wH{xMXTvqvavt0{8Nt+a+6(Q9AB>zD-&PNPqj>6PNaFY9M#` z+n15DJu_c_oJ!f}uCvuU0-YINgsVQ{Oj#X)$+uL8@xA(N~uLq=IEdo>5EzJWyBK$+h!mZ$-S^0)$Lk?dx0ILBulCZ;zHMX1HSa-2kN%{MLFR|uF%L7Wc5CeKPemNJA0v5gW{R_fkApY^*jTn=?R-f%$K z(9{B>{fBJF-)VZ+KUJ5j+ZF=KP`2Z1;u#1=+rM|$CTn_EoT{jdwr$pXxu0RQ_slZd z?*k!QBx}D~+#$ulP&!XsDL0J~8A%xP7P?EaPKh%sic;pS$bNxPRE01-h!8}Gabm?8 z>W+di7)VDT5QZHvuR!{hxeZ`5<-kU&f=v9YZ!j!!8$YQKe)I#B^Y3Q5K7?Tf-g*IH zi1%+&Oia!JR6!^T;k>Rz<2;@YVKKQ05Uy&Vu9Q)&Oa<4*hyNdY=lw|K|G)9$bdH^l zLsrtUw@_KFV|I=e5)Fw$vO>EkBrE0EqGZpKy(>vJA#EuoBV~o6;d`HBbkwowU7zpy z<@^Qb^}L_sx*k`$fGq1eb79vaeOza{-X!yc@C#V>Iq!~-IhWKgbmo4@?C6|P4JB?l zzYqNEOq&A_&7m`u>2`!INN4(Pbjukn2L>RI3XN`w?z4qF;?>ZJTh1B#BHn4;(45*A zF;WpWh>!KbOFI0ZA%J#OVJysC0MvLW}UVuv`BPtZdy_Dml9at{=W=(vGj`9}1R z*R9e=6+6FUB?TCY_P(N7i_B^^aYO321|)WdW;z{toZDSaR+QJpfDzLFysth9ncPkvg!M-3>cJ*OFl0^i zMhuu5m`udm&cE_a>j+yfai73$^57_^&MUA0$1MRKXeib#&Gi&bW`3Xzjzd&yc zr?#7dh&wXu~?iVKfvF{;H)Tk<^+W+X0W{fBv$ED0tZN}%P|6;&y*YTQl zbC@lVCbm$`VZ}^N;J2icf47f~4%lz?VLXd(nw{7jwy46ZBi zJbry+2QqzVq2DJH_WeA|*aaB@!|!wwpPAG*0w%Vx1!7hbzG$03eNzdYT-fIlY-&^D z1lJ*WUT=`ZxRx~Wy!x7(jXSRgQX4E*vIx<{_D>GKKNeBgS7!@k`h2@rI+AcO17Y9H z&oc8Kej)2_x(-m1gV+Zl&{1Ej7T}oAo30Sep%PvP(Ymtg6PL>y~C+ z`l}T;|KX*U&{X*UB5X*1!AnA3J?b0aYaQfa*T6sHfq@nD>Pf%C%*t-RpYi59Wh~ZL zcuZ(Z@GCrXdHw%-WGDX#z@l0ZI|iwkJkfgMltHBpE01=@XS}Ib(5v2CO)9V7&)fCk(*xw9qInh+ zQUShq;oBH9YsO#U&HKv<%j>5U+RjlN!Hb(RY;^k9Pimbql?Fi|xX(3Cq>q&V&`u%& zz&~I81l)WhZzc+4dH!n*#bq@37p&KTtFqtt+rpd~%-X!Ru_m-dgkCLbi^TkDyJXoP z7V099u+9AvkPWok(F3R*l(o=Guo5Y#k{lxtOxm!-x zdmTXZqJm&D`_sYsf=@hGfQ8o-->llOIncSXuuk=(tXwO1+HS?oewGhZ4`dzQD=mq$ zU0U`(8qFxfvt1J2P_T2~s?9w0cKD;@iLJxJQg&OGS!H|KtE{zr?JCK(r|Hs`>J^Mj zW!WC`_#9{qfdn7F-T2UbFSO`BRIGEbeXpZ(j)tD|rJ;`YGK#MsqVBH8bfmXly4t={ zx;$^ooeq%=2HD%Rzjc>(6z6r7NgitKsowHRuUkZHHKxDrz$>O#&#}U)M3FrXUta&W z=c_RZ0N8sa{4DAgHxT!$;mJX@9lDV}33gfsx5QPXK6QO$L%~j$ffC6sFYsZpA=OO)^E~zbjwQF zL=SLj`kt!4(04T1IaqMtd3pz{l>_{lyM<2Euq?l?vo&?w(9V2HLAvr>Pn~rsLMCX= zU3q>I>=r9OUc`VHy~?&_Y?BeTIFN^aW?wgu`Q)2`RY~#o2b}|11xu5xYh#_8SOTxg zsl2seHh%F==D2^AeUfu1!^P| z{>KMbbbhCke)BcXrY`HCYWAUXQjalDI23OUZO0s6(jbxt&qglUB$@(#w-;*8ix^3( z!wrypAY~9GlpB9%4u;bR=#?gi-y{4*n%`Nm7ZNeCn{~JSDfJx%BTcb0$L*AibI~H^ zjf)_t(2s*Ts*+QR#yK0cI8jtoT>C|oCZ6%wV98Lwz5~uSwwI(}QNT#tdME?}28SA+ z^gg!@i&=r#P~b2tn*Pv>hFHtS<#&qETmUpFQ7nxKI?@s!>t>W3bsqo$oZ?_yxlT)dc+L)A}KK`XoO^9+2`N6 zk(hvZ8fU>VsqgOX*OxF000X40(si{29zg0FajRS_t!Bisaat(j`J_AZd3Upcf7UGe zzbZ=eaNCWwjU9F=T%Ox~Ueq(3dgf=vS*B*jO1qJf zj0H^wio^q;Nv*YZ&CR^-F%Fs{%9OfI`(?o(dd*<*y$MBV{-(b2v$rV8Q;OWvDU(%# z`%(kahB(!oDJmsWQm4nPY_{c=Dmf`{;{#YWEXr0(`cxcIz7Frydj@;X3}99sa+l<{ zmXd}sKk%}-uQ~W37Qn1%#M7pQeGAr3f<3>9zkwG3se{O&2>fb^Af;QpYDoYiXG~!< z&kekZ57?55gKyMiJ3jlrPzc&Jj^&*IrQ)Z8p&SfA=O|DEY(X1yKX<(zW!7UehDQu; z0p!qyPL>=TdLKePj5ZrtpRp@)NMf|je)MM++P81q!TE7LTi_OTin zMV5JE4Q_%2_aHC0|Ju;jmvu)vH>8NhDG_MTGt}73pQUHSqwH zO4*pAv4~ON9?-v28n46l?}vL!*{}QVe__{}7sHQHD)-$h=T<7!MX}^MeqCe-_8Ks# zDSll%M?PK`>A+G_VlzaJOkx-#gp(@dBD;GEr@Xjn_yCL7#MVV&9U&=6>}AsO@ycw; zo3Eyp<$4GwUp8p143qErCWNy#V3ij`hOZt^I76tNcwpMJKa#am$ZK(dxp8ABQQ7_^}Ql24#vHmME zJ*2NUH;?hGUS~1yUS`lfwAeS*2ZF0_?Wy>obW)*|G5tedgCwK-b&HFmP7y#*0TtjjYUG zgLzN*_oJOxGp%)l@?#BS)(RBg!Y09$FK!o!hbyP$VE-05c^5eauDpKdWVrHQ>f&^; zK6us98*AL&=L2;SjB*mEh>`|ieV@bVxL)h++3@ID^(d_GE`)rT?(uR6#fo~~nnr#N zdv3>TtDo&eQk_cY6J2Z8qj2>A8-SByiQ{;iZu&@E8FtDHFpOnf*dh-Y#t826q&fbdyM4PN=5Qh%f(4QH9k>_ z5+!GZ`|Jp=@5)_ii8?*JJM{CQE;ky3glERWU-@wzSdIqe)07(wZTQ0T%v^ZO2N&8x zS}Tq~MbupY`UyS$<%H(Rs$-hHO^oZ~ia+!VYoaXPvVHwhg4B<>a89+EW5r-8Nra~^mJq+K4QZbN?0sqySBlqbK~Cch`A))4=e&khiL zU{KacKB9Q^3|1zHq0_}F0pWg?>! z#=I?w#$*gf;!dw#9#j*T2Dq+Wa(@6!#x`!`Glsi$MFJ_nM>P0Mt`GPjL$!{%rAx(# zw*}|A7PLC=hhE>A)276$s9GHjcw2n9%`iFLBmThC2OY}-v=eWG$nteEMQDWpg3s|s ztCgvEM+iPCmxk3Xda(2itUvHCrQhp^=LgI$GdX`7>3=Qnfvu}LJ@qO^%r0MM(!=6J zg?Dg|r|H}j-bWIcu*BPSnu*v|43PPOe(fD$cooR}aEFv@>WH|TKAn zbL>F~h$Iw+d9Z2Ku?MGVj+ozLEt6P=CEiYY95}yS4*L=9y&tA<`JJ5FDG}~u?Gu9b z0F#k2FsKe-GJf<}4(~0$qW+O?Z(ICUfXV2bF37%3%1kq`T>Bt z`@!WwYeu)?oOE;$4i>Cc8#~WDzY#ETp25P$U9`@Ol;X&>S26_kN&~_k*1gtga9eV|^89LwHWk6E=hMvrW zQ<+GXC#65F+Chk}p!=7O6zydBR9doWD8+PzCV| z3^vL+X^Kj=3f(jc`ktj`e1cldvOd~sBuFkAe1>#&0d_x4NeP2dWEeQTs=+puR}XxO zd6GENRE}<}**+<{qTh!u%fFrf^)rBEV+^*xjonxiv5=)aKap(MO7?RzL%i<+D7&mV zLMJw}!2!j|#=>@c0Od2SZE#L83f3fHzXr+SZDy#tuQ)j$aeqa*g7MSk>2=4Y(h{aa1rB+Pgk_I z1;>M&JOsH`Ii6e2bJpA@q?9kjs(h?$MorAgDQFVF;&kf zs1gNNofxbnpnU)c5>Pe`iHS)tyVAUL?R)&lw(OQ&yU*p0qQWf9mMKa7Zwk;?Cb`)D z3=;S}2mQb%(U&pUn3g%$mzxBD46FC*z0W!eO8{Wg!`~<~w!q*6%baDtk0Kvme|o;e z`5T3^J(z11m~JGp?bezwSxN|i3adGxS@Q~tQ^Q*C|N3>x&2RGQo4FH^k3Z&9UkC*W zBsM2|*+d%1{~#X;s?_r^g#Qexw2yX2j|NrdxkBV9i*|(cUFDUZGN=;rhVSsyn_nK7 zJRcC#LMNP;Z&E=Y_G?Vbx@|NvnmnaPftVK5P6VK6+ZuSpIkXpHjhd=P8fihR2>5Hm{N4u@&uz#FfMODHi4friIlvQ>UEYGMG9z*LNy@#L!ixaCT{xbe2or^>ZY<{GMC(hQUcbyV;oADmYa}2UEXF^GI zoTMaX3l3;_Z<8%;>d8#K?``VpqO0e-{Em3BD6q%lbAPs_oQYu|nf9W&)?3|NJ|EV? z6t%m|6)VYVVUG9GhEuI|!G6Nhlv+0odGM=#H@cb=kWAd{yeL5G|QkRT_9|6gYKN zN}i8XkjBRbU~`|2Nq%6p==8xak!ToZ7yh(0@`y>NZY`XVfA=GHK$1e1Fli&j_uqv~ z@`$BSd*6;c;*;B-EaoGA>T5=P#Q!4x?!&wuF&qv&;=CAi<>EhLrYJSoY(g<7?4^|* zX{ej%@ltU|W{auTxg+Zq5r~th!@o9LsKbi{9nVvY%@*XNhpAR&lF``$8MUnblIRJ? zM%RtS!|zOKzx87U$h?&+#RmHqakhASNievCI9tpr>rO zXIKOX;o0K&1Jl!uSTg(KtaIVNk=eKVa00W1sO;;B2^%{nnJwJ7JDV{cG%8>m1&*b9 zy?jmtBe2d5L4|qt*Kv#;riL{+S+RBvaWzjYnVs%j$;KF!OJ^Fk{l3Y#HTBE@Bnc8X z8NlkExXG9WP>ryxw|j0$f`4F>VK<+4W6I;vG@FcI@wueXn`zHxtigSOE)XXJ-&VI}LQ}~~{nZ2yPda@SQn0~T8 zBRM`<=WJWd$@+HeF5=7jCtsG*JYE+2UEpP@1Un-~msWW9uo-lb#F=&Bx=7;8I{ReW zMW0#i=l-;&lL$;Rv+{xP*T^GVq#3+O;)QzQUL^5CJ=+)g|6;DgeIjSpeG=!onQ|qF zbKMxZenA&4f8aPvoa=rwRTAgA)<2L5@jtJBU&y%*w~U-|7fGD!7OsmV&ULfxB6}Qj|`m%`k zx_|X$E#zD`yDpMA*DYKZNu29u+eH%Ry5AuEL>=bL+Q?&VP1B20h;!X+U*!LbxsIsA z?07ngY9zpcpQFW_IM@BF-6!#0N4(c%wzq@;Jegk-(iSxeo`;#~Ld zd?FVel0%&9h;toruKQFyyM!oL;py>H3wf`bT^C8b*DYKZNxaw1wu}7#G1rY>(818# z|C8L57dmi!0&Ltk0ak640Q-O-0akEI0<6i&EejDJ0^gxeB*03JBst;Y5T{RaYIx`+ zK4$_f_G4G|=!8k^SRA5tiSXx!BY043@5OVx9{SevE#e}M(v<(8d>Q@sPY!8Y#^*Y- z(Ky7r5gRuSinvPBoql!J^>#JBFI^IVsZ1U6Gs03+SB*%CEcuH$&D<(zzi~9G4}eCE zKm04Yz7$JDwG+bJ&J4k!>yO?AB~6INz~-%ug*nghi1+JN9i?$hAhYew1<_)@x1MVs zo4&m$)e`si(uM&dr+Fl_6t+cZhOcyyiKufx*UymC%y?*n^MjQDOYH~GgKwW|wygf% zSFbz1eL3Fs{ZDe5Jtxas3z~$bhPp4XtH)yp!~hNlK}1g3T-a&B0D^0PR$sF5G(4ii zcWv_>~QFXnn(ljBhrZmPjR}isM`MiF()S zTX}?%=jT|gh%@@vo;7VjlZyXT7 z+2iFv9fcr6kHktfTshrE%LhGnVu9l1zk zRuz&nL%|L!Iz`tfaqa_y5L>u7Y^aQ$7Rffm!8TFactHo*<-VaXYdwmjw4TawP;s1B zqIAY^(i(AOfyyNHW8G{aa`2DY=N&inAPnnEndz7z@&ZNcF0PG6MIqdUF;3nds-=9< z*2SKFwTL)BIeB=ziry~x`oon*;15!yYOFn8UaTl?@3P9r6wPkw7Ab_y+o z{OaK#?`J1JT@HELB9D1mb-tlD@F{;R7bF6zwr>rm=2JPr-3Kd=a+FA+rA#>b-G+<6 zD8v;g<^a5csmRVYH2~evvMCD#p-8X0MB!L19ex7iDoziQmEy3V#Av$hs|`a7fk4QF z8pj`pea-da*uGy@vyGq=y-8i}dIm*maV8}&#UfgHeSD>(s<_wg(l(j2XQgV^>>;}` zpjF%s+9KE2gdM+r5Sfv4UcH6R>w;&StTw;a8UY__pSE{gQ34nRWhW|9o0Z$j97_DH zv=UBO7;CLVS6$Dg4asi+A95cj-K!w|E+?P03Z_bi7KnO{s<~O&=qEeoL`3j+xN#5Ea0Hgr__d&<{=o9sGe-Eyn4B;a00-nC!2yHnrCO5$dd0@wD6%R0!+ox=zp zgxIkj3N-~bZ~BW0T>M8^YZ4^tDxEBakivN;;;*cIiqXPrud-g&%I9)B7ro|Cq$sJa z)`={zA%_{6)~;QhI-$3?Q$#*rE_rC>li9WI#ug`2&F1v_`YU#3C~28G=f}@4g>Gs? zZBwh*9Vx~s^D;4sxhm+jZP8PXr93OWMJtsU4pZ$yI;`sI*k>i~`<(0fJK8tO- zTuCHO%MS~xEqm(|kX+ln&RhPKQ`C+!$s!(8_bOJ|eLF5YS8>S;+bP@=?`ed7$qHGq zui4SL?seE&&cfxk-TXpYNooR!p{bohG*Ta{RSY{-!Y#ESA)meLQNbbiWA`~K0& zYkkAbTLVS|`JIOY^BO-@f6n`Q^^Gy3^6$iI<|#)cMMt6op6G!8kXk9x@n3~A{N)|V zs8d4WpXo?go_D)Qc`|}d^|D8N5Osa(M5D;;OkTvn(&L6wjerN17V*gRxT70D^k;t$ zj$)m%THMDjRQ|ywC)I={XHU%dl9L!5^&ZISCYnDcND}5TzswWD{fC32s1Klk;3%M4 z0Q1Z7(tB(}-L6RL2-sx;3l+~d)jkMCd&ir=LM4J>Sn0lSU5AH0btDrI93>8f(wa8= z9Iq=amT-c4T2V9fz5#-x%#1EBA#pnK99(j>ul5qt5GNwTpYR7darC~JXRlwJYV>`cFy(y|ss7TGDtv?pEvA_-Ni2>RGjX$DZOvP#F+zvI6gdj?`q{PV|`wsAOjfMn&~414F$0 zIv$A3af`RE4ty{nks=@Z%SJ23q)WO%J+7O%-oU6FP=d!GeiTg2JmB~eaJC3Z2;Vzd z@zfG7>pJ#p=@HB5oRl?kZP{-giITOGu2erpCUdK=iOEgM1#BT31kH(FLFWSk38jLr z6zvzH&??!alNP+hkxSwpx*BY^jU$9LRxawGYG*gC`$<2rP_%Us7s9~5nm&Ra^mB2JZzsx5+0hMN!(pMv?C{KTUwC4}0lo)c6hLvdeqe71qcf^v=NY)05u{yc z&!Fbv0r3l~Hgbrm#oyl(y!MiaCGRl?N|3n4r^`yJ?>0f<55(wuT|*!TkcW4n(Bu%z zh4glYOFK$rt!U%@S>LGd`CPrv#};#8Z8bw_Sh+JBSKQ|7TvGR+SD6;l#_iAGl;UKr zN9l+Mzsl#7c+0ZwvJRP7O9Mo;KbHc8DvTi)71+X!C^D*656!$1v4(7ygBs@UI?GBo zO=z&b^{y%;Qil(7uz3c05S9e4n6UpmO;k4ib{4 z4G{u|-&Yn%1l-XT0vYc4+L*)9RM5Nj5`2){fU_>VjedyyrNY30zu(#H@HBl%Su|_Yik0T?GeAa6H|W=jsUtvH0bIi7prrCG+)=41U!7w& z4Vr8FUs@MT#(jPRTDnH7#XIEwyLK&0feNL%<(J!xJ9Zt9M`t)ax@Dx+ajHp5FQYDd zSf+I4feqd}P(i&?*R<^8IeDAv*qt7`owRFnF|OR^Xv825eJSjZF4J>FIZ~<7^l6Eq zpZl{&WcqQXm`U2VtEZ*ZT@(2j67B1a`T?WZT?1jauh`;Y>w6`r4wh_akqZ1$!E5!{%^X8`&)h9ZC5E?>lZ5kP3cC zE@CkMkW%`eYb+K$P+}ep`v1g^a?2d1{vjXmSh&6Q29_^x;;uP>etx#sfS{ls5VL7( zi&;Y{*6g*)k(HhzHLA>)Z(D+1S!#4epy>YcE9kVCst~Ee?;Fa}Vjo;Xo}*l;oE}#j ziSiZLQ=T6GFjgZ{`Koe8!lT3;X=X3WGZLTNG}ucjEhTaNS(@p?ggq6RH(q2}r}+p; zNhZC_JMroL%ZjXB>M(wSdNtwOZ8-Yj22#oyg|>#Nv>uG=rGi@WaJqX!XEMjc|ESaUefZ3~3vWtMod)dS4M%UFpzBC6O`Z3rR zd-KQ8hpet2U%N|I4}a@>a%lMbm)4uZKfZnL0wBKBVIVTBehVf=y?#FWEduwC;i+p2 z8bNTQ7|HTvhvNB^o{QFiptKdZe?0HGbfPkn?Q`jGf>PBe4#u)lC7E7tjAs-VFS<;5 zSFcY{WfYHOS(*B&Uf(e4Xud7za;;$8{X;;vtXwCz*FV`aTIc|}V%PKDfb7a>k>h0* z`a`{e1=KO3uIS2rET4i(Rb#{h%PLJ|K3%Tyj9D9tt}@&8Dfnq+j6_yhmDQm|}Ic+hCz@qe+iDh2*q-m6SJG$@A_WH6=%98rq7Y3eN zWPKcXF~PnrdEcyyV66<*e|2e#$Y8UduGJtOgHuhOW~ePH@E2pOepFj30j;ZOt@@O; z5^Ic&WY`1L%C5dIEi1RevKz;dN>m9Z!- zwUz9}5+usH{y6%9;gt`kLj28c0^)a0soaf*nf1w9d_S6DZ zD>F4)%=M>fv{ek+7jSdsXtfIDAZxjG`q&|oJ9dQT%8At~!D93Jt4zB_=SusW2*_hJ z$-S{^l}M`PkkvWXD{aT5UIZW_#JO_OpvqrE50OF*W^+`o+y|F+Q!J39kh19UB-gv% zQw-rQ=_&a{!meezoDtSz@}9v(M2Yv@hu$-6+cJAA*3Js`bMv|FW4+@a`=1!hglqTb zt5s>SCxCFB9Yo}HhzSp2Ul9DGX15blWf-Ys>0O#r-RBV0;pAIT(o{Zp)k<_7#BKsa zB*&z1<*2R>f3D;60Omm zvbb|4y4p7Q)0H;WSeYlIbERkOhF0{0Q_nwzeyNPz^to*K!I>fKTp5QXQ?7Ah=?f!Q zi<4t4uW^y-3x{2dQ{Yvu_1M)H!BiEeGzi8vd?c%&g$xp6bv{)+LGoT-kkbQY+)>HwjSi z3;Amr@gc$clmo&@9|?&FyJ_9bjrCj(qA;>HgV*Ik5h%x~+hT${skYMwCTY{5pF&W+ zVUMG#{WVOM$M4F*JmezpkF)%q7#{q-uIPP#A{3)QVwA8$frK5b#C;H69QMSkWo?rG z(s~8$1g#JsZFr<;!gi?mCjqA_|p+En@>mVgiptwoCtdS zPX``92QSu4dTxd}T zR+488ulLxawS_P?BzBdTOU`*yX~I{;+Fi5pCkdP7n0+xqwg1tM12_6-{OLgL8m{{M z%7IMe%WG#wt1nG%yh&f)cuE3|F89#V-^T0(Xmq^<%O2zC-?RC29QI)ySxL@z%x+Rs zjhWEsvMoI=F;S9z3Oi(u;8;xRP{IMvnT)aM#z7tzX`>&`Prg;?@sD%J`mMQ*Y72M! zb?!E6j}H1dciWno{&NnIMQ5L%SX2zouNRU;mOVfi!Ro$#{N8|wdt2BQJQ4Rco3V0M z1ljR(W$X379hW|ed&4RLCTqJnm9L;iu&-lE0Fs4L0`SaD2{3VE^P3XjQEn1(zdY@C z&Sf@jcLRx|2B>J}DkH04G^A-c2^Dv8XZ~k)WY?|dg)UvUZTrA^R)i_#^&jPVR+H=*|gnQCBVshw@Btqav^ZtlA7eY z<>n98!lI=Jd5bh56Po4`qv8zMkwl{+(Wp3cSrPuRitr47y?Ztc=|8}!vs<*Lc^Xa~ zF~JK|y?8o5qRH=HZJdb-Ucc!wgf$$Hq>v>{+DP&JcOg*(`{px}sJ(BCuyG0bIoqBr z;>#kAr2p#6S|sDk47x}noM+*>NMeH5>;;#LZhWy{v@ViyRl>94$;Igp_(1skR|H5D zL<`+O;5N%%h#+I9^lM8Vm-S4S4O9oQ#l%+6%r0{8R6qYj5n=|Z+gwG6Yb(^4CDCG4 zxg#P(k(^Uwc9GMFXN@Bg=o7jg#UmfP!(n%>O|Xl6H4d#^>N5OUeS{UUTGa=6>+3Xe z8*Q%`z!zg*pMxp!vG3DUHElZ2WD>UnK9UKr?|wLv)5Y|SJ73JCnE*R{&i$4N;LcjI7!PcuM zTH;$n?FQOguc729+QOVqF(0@Brw2rctCYRnc2WyPfg=5M60Z8KHhj(&6M)T1Urs^+ z+-7Nt*<>TCw>!ikY)%Cv9;X;SrRg61*i6vyx&Udxjrm#8LfCI~PAY-^Ul$=NbvGt` z1r}tTU%Lv(R)6a*Vw~D8GM)`|XtnuF?IN?i&5nu?lTBg;3I_E7T$YuE3-&gK23DHkbHHsDfa|fbaE!tACdzt7>>{-S$ZrwjvYv^z+5gfmV#%L^vx~?MR36;5 zCO9L!I5UyOeg#vk8K1 zcXhr{e>m(szWh-bsFP4A^7lF^N^#E>_S-UjGO@Oa5=df(wz^&Pynw9^Ppqx@-WqGG z8y9O+oT{4KRyXxBeeuNFtBzrQ%=KtIo}I#zp-3o0Z97DXC%)N7RieGwWq2e1J3no( z?C*85m)9Ao3gdE+RmK>-MZ*0i)JdJ4=%*oeqylkvrH|Se=LLt+;DXl4C=D;LI`QSg=~~;d3PB%hpI_#vLs!IK+P?Up%1rNGlKOuBJwRuOIiiNBXw@b*1<| z7=Dlfhyq$RxgLjHjC@R4K6MK!xcoIi$8x)(xcaY-z&)*zkd1DK`?P*B?SVu1Ohd{sB?1bYJjOt;+kAoaW1^uCWdZY0YD2X zxsxl%gAZF;UtT0%*mz2H9>ZT-PzO>0pao@^UupeYX$Xs6T0<6ZD4fuOl2(wokKfN?IMlO(6gW#cuePq`Eakj*pXbsF&W%@6@f(6oi4_TOl_=sZl40d9lY*zzK3{8*Z#w_tlizmXTj)Ijr)mIO{2##P@CbPr+HV^*in3c(j;3#H=D6U%YrlkQ( zSQ!;pxmcvtC<%T{U&-O%n^KQM2aqx&vtEOTEVG+W@fB%n(Ho(2J~R%NA(Jx%yYl-U zn|Iy%a*V!f`%{K`^li{XUPTUlv1AN*$x>K%;n$5XR_|E0Mo7%%0X%)RHsjXoJ=SP# zJ!CQ3GbBZUHuhc09`4P4Ma4oD{f|rCNosm4XJv;Azu`G^Ps7}b;81&9>|BfBcR)lu znM<%7(6gE| zfbghTM(04|R4k=$#v@d$P}Q9uVTl)^JaJ=Gtj90P>f1)CSmQmbgvvPbXsY;Ui{tr&pV}TK?tO53+A~MoYbR=nHr$z`$(defnE^=`sev`Nw zs5(oalYsb19q}e*Q%#P!R2{$l4l%#7_;ekwOx$dJL_@*+Ig=4ylzkE7EIzhf#y?qn zEr`%D7T=jXdQ;J4>i46BmjU%h)|R8j*R>mc{P$^nDS#B5oRmk$28E3}%@TA@`qEp+ZQX6b5g!RS z%^ISDvB%Z0St;-*o0O;EOZ~r@l;>D=rrm5^b5j6Ve0$f#_D;g$n?;j2)2ib>i2{G} zbPsQ7XPH?{%0*4|@G%yj(L-khz~Zapx^QIKcaiq+25W%D7v*+DuKhYbDHH+H0Hhzk zRwo(-1dKxdJO%xTKWHphaf{coH7xY;wc)b9tAu@om=IHwLZwI$kK&FHCWS^j{KlVB z=H4dyrXa?4!XA$)>7_r^_sDk7>~0M%MtK@%ySkKdQs`^QiL%T-)p1hj^ABxV$98Y= zcTNf8c{WB04Gkw#k4G_@U3N@a$~L@FiPzYX_ROgCBhPgkwNIMZfEO2f)9_~zu|Z|w zSED^qwDww`vs-tFjqcqy=h!=!8D>DvLe^~=^}#+}s^PFl3sZ>LHLNz$6B+J`&X2mP zdo`O;Pxiq^vPPE?=?9x1a_V@3|S{#8>E-n-V$P6Tt*v|AJ303{aD1k zJ9)T*hC3_&R}GS7{$D;AJ$yqC2_`+SZApT(xbR_&e)rXq{?O%v<2uK$Q76EbceUk6 z8=*Q`y;%MfnW6#j)^rjqe@Z1f=GF>m&}v1+ecU>Q^rNIuG0nE7bju>B14XLF3!40% zGCs19u6z7hA9^e3Pj=9O+%DVEUlj%XK~WMa^`EMdWWrr(;*!mECAC_4FzqIPp}vP2 zTZH@TwTFiekJ<8tO}BxpV?}hNPFoHR+DcP09|33jwx#H&RpB8_X#E?xdVbz^%d7u&q+Z0Qy~0L~G0+8(}AqLg!JP*v*o7 z2qmS>VT83($;$~7|~^PgheckM{QBA^9cqp&h_tEn6*M#bl#m@Ct+bJ_@r9k$$^B7 zBy(R@{WYaf$NU?hm67UtbmA$u_Nj@XHJt3}>B4H68JsLAtM=G`5_)h^=%SYzv&ov> zcdKj%(!!SBFx{f^ye@bkJx=Y0nQq1N$GHO;$ro=}98h`j{K#{i3z7UnD5W>sp=tw} zIfYcbMun;T7mbq(F8Um}qwVm9=ZT$P9EI(*-M6EzMrGB%WV^%{;qal@YyH{tXd9}Q zJ>L~$^V=UL%0-;#>WjHaN!{k=f2O0ct@bkqHRmDwyH9inJ9Qn(6E2=l{`$&BEvw)% z6dW_U2k< z?-u9V&4@9;qQ#c4OdJr_B)R))cbIwWF5~rkxEt@i8WwUDclZ)l`XDhd&tRi=cjwy* z-9wuU&EM6wb_DWs*UEn5B8h`9q1vhI0HdbOegzEYrB4hgt}rOrGkkA(eV+5ai?55W zja!pzBZV7m|B{m^4SSy89rQ-rY(^1o^eJrt=iMAl-^!(x#c~)+H@3a?LShd}3JeFE zy;0)_B@HF4wq|M#B1=Z3t|*OPuqPBEdmsd-K~yO$0S-!}0;YDyXmAJMp$2*n90;*d zk@upv4i?DZqG&h*LX<^I^5X#+^nC(AN{5Dqqjp^9(ky>}Be2$^BWZX!7n&rudadH2 zyS--DRVYlgVR|J$y=4+;mb6DErvp--AIsCZ0yXIP2w+%O7xDDhHTjedw`a8SBgW%Z{bI|&|?X1h!M9M0RPxo?ev@G0-rZK)KD zyNxg+lvY}t^$#c*-A$UXoIo>-ChL>DtRaG*I&de zJ!oO>4D{z+tS@l*)zu)D40;Pk*@!`rm$E67p-4&vMRu+RHYkVUAeR=q?e$V7dMD?i zXSK4f+9+x&jI$=3iy}oK3JL#|o?(>2N8V=K?ks)nnX@g|>B{IA*~oJCDjy&D%T-*Q zh2aM!ti0>*Y6xuf;Y2jY`ID0Ht}Q{U_wkF50I}pMvZrkq{JUeXvLLb#f?n&bd$}t@_K@>GXM%LS5bvasx zFQv^7Mi!Kbl#OSTxXy~i4*?>Wt}9&R@`yF=&OR`(m@EcF#jg!=f-#$Fo`O(hzjCHG zBQsP)b9L98HzJYpc6GAZ5w72IkT*xO)hi< zaEt>`{Q94^MmRW;(+N!WpZ@*3&gEM$mne$A<3C;INL_#Fs@Uhw*Y}!agHdt957&T)f1Q_oi{Jcp?aks@Smn^MkvTKJq-E|PfDa+VMT)Iz=S6{Cz#Sf$4@&=V6EmGXe_*$h*!Jy;~w&2}icD+0o ze7@P1t%;=O;#bRP5HA&Oyu_>=1m4{DWe{BRgz18t*-qr8FRP4sc_VMgbziQfas$<8Hy7VbKOvy<` zYZ>j)r84f6#Q}UNLcu@36v<(-PDq+*U)2Sa`uqZ3{*G7mbabiQ^?GLMt|#`w!3p!o5)hR=WoQ9_4YzbWrhjUZ(1Jx@Djzlv>HP5N0kF2|t5IOI?5job-sr1SmHari zw!wAFhZ+vgn5Jm=d0=|EWZ;d&q|1TPmaSNtV%{|`AhbYepiKJxc^W_Aj^vVs#D<@- zi@x*olr^mLt=TeZv%<}<*Fakf?~o`P9UXiDmVa(kKx!4`K*Qxm&oO?=(ns*YXiS!o zu-JK!$p_`r(pXb-sj?5K#>oXcB%2CZ;6S{$ijrN<KK(8{AOvuNz$aQqW`Q z16ht`a@!cfoSD|oF+srI-N@ik{Lic>!lhtsbAi|qybZ34`Egv4GG#)UW7tS5<` zCxH9Xu4pcqAZOzPm#G;9V0_Morj^*H@q4B?kRZ?mrd^+B@$qT)VY+Wux(5`UvX+s; znCuK}&abl1-K6gzedtnBYp+RlcTQ)=E)s)Q)SjdP&sSLs5cK>sMEUOd16R}^ALQe3 zsXQwAyLm5_4?TKcl4v&cLRO=Sk@5`5Xbk?~{4CU63pY3`AA1q7ldyRYyTM)Prg3;) zO{1yXo1gh5)0Kkc?6Q@Aof0#bKq=VEH9+*Wwvx`tw?PLQo8JWs1{8T;InKtI z6T!(N+wQ&GJy(DC^)ovWALf#ur(k+Zyu{xx; za@C4cpK4xxw(G0c1+Lm>7_nFFbHS%SzXr0NZa?(udbE88`6W9tIBB~ba>Wo}Mm}a} zi{Qi=Py?6&hbK2eplaDM9wUf-f+7|23H|cJxA(#1X9ie*jc$|k(-8Hj2cp|L8zOMg zZ4;jJfQ1i&?0iy`jFuac2LfgCNKj+Tl*N_h+08Qb9K#&`e4>)9D;8y|WNoU`LCMLOW_IBjYS#r=vBe&zR z`Jp3>7YmoC$13gSzeQ?XydR&6i`6O^k}!=gAdX5e>-#HoLX5)pI3+JTbK4?0^InzoVXD487%AD;OdEf^wD`u}^{gf` zc6l{pjzUM>EJv8%3CtAh0v{iS%~*~17ys8L>sye9TV|1e>tbw?`(e7i<-bloTE=Ji z;;bgw=LrjcX`pY>zqJ$#gcr$Za2W@}UsOcu?c9%`Wp37ccYd&?_nApSbK6(Wp{$QoamShN93Hh&f_U zf{#yOO+PoJKWXCY+;toq$_Mt9uK7{Z?IJZXUV-^{l^J~+JH71aw->iQlmYs@FOcce z59Ag{36GZ#{rj&Zt^^emSc8GAFPzz=p9bT(wAeA`Ik1 z|IlH?`&!TV{XrJRiL!w2kJRR}Llnr7nw(TL4jBe>N#V2=8h?Lzr+#^Vhpsdm_WbGh zmsdr6e}8T2r{!Y5Kf45!5b*v;bals2=A*d?8bB_>4Ep7{PoIB;U-0Xufmuc!p`{hoSg0X&i4eSH>?y6yWeFXXT9@^Mwg zSN~PNd~eEr`B3@ZMd+7>%I)^Gr4823sb3~e*Tm^M^Zon8!VP7r00yAX5xrV9I<~o zx^&Dx{w3f8;)v}C^9+OVj%!p&B}?zp0Ej>YbvXGJ)Ni!pxsKSgTgVX)*o$8+hzIOq z*5e;~X19}F={oD?t2+*}5_}S_7DRdY z|9rI|PS<~Ax}IHkPds4Hzq=a!ens~te88wPWbr{bonBIxo|1T)Si3jYzcfkHn z4%o9hNf8g&i+_?LYQ*Pok|JuvXVo;%^?;3QnrAF`As(<7zgiFv*mI~B#1VT|)q;4y zPH%r0M|5Cgap%Om>yg}z8Q{)KgeTHZ{`diVb^;RO0ek){E}{ebFJ5u|2M6rg^~=QR zdhz>Z;&eTSewjF3&#GUZ>vTQ4T^w<`Ui@l-esvmbAFBmG&H&)~4wLwI0eX0pV`-+7 zCNc3X!P;ttILfiMz3txveSsw?0oVs87<;k*p1KcSGoBc*} z>IPe`9Pb2j>Hy$5kW&W$&lfXleK@;$suWE`j(9XK9%xq8!V?EPXL+Gc&j|Y1$x}3YJWYjO&^>&bh#!18V}~g5#y$T5fOzBniwA)J;>JBYnF(@C3LFV^mHHI{(D?`|uGQ7pxPi;^seU59 z1%(hWRFoA2q|*aILi>lKMa~@90y*r+x*A7(_k42Jf7zYe05|w-A}{I{VgM{_`e-l7 zZDwr)+2);Vwe;Cnl508)Dq^|85fTP_DCGPM&$AwDn(9k*{t_fKP6FL*MLzew8b>xd;I20KF6cngAMLAg zK|&8w-wm|h9RBg`m)K2m)i5w)X#uH3haAmpOxlz7)oJ5>bp$-Hw1`KbSXRB61rj-B zU#$w{KkvYhkg#)FG(V$%iz<z>g<2hbI} za>)ZSD}(H0E?4LeX$dgCdAHh|9*?L>yuK3&ZU6LsfXF|eogHSb*Z0{?9>n2){*wpM zKK>U^9>nYW)fr43ljcnQ6Y6%Nef;lLxBmy%_u1Xkh}ZYUzo!we@5JkS?9CrTAF{fB zeC;Ok&(q9amj50~nt5X+t8YHvYodMp|EF4&I9>ml>3VkBTH4PMbFd!vV0%r+}@=w!cqYS&m0dd zkNHSBUbALI+!m#nCE3%c>P1jDHkx*;P% zwgM_fSHA(1hI~LFtHNLpb5N~`iVT*>&NVQ1x=B{tDfI&R@x?N8F9pk{TJlo|y@9ig zG3tEBBVK+b6?lGs14G)`bQZ%FMmcm;YopolBj`2DkL>lU>|~itbqq@HHg0Kj zBE9sE-5Iiz4}RvTJD&zT!*B;2hG2uNg0+5xu5vfJ_>|e1=P_T+uKSh@1-jo(Y6p0L zX_;$}C-F-)?78LN+U%>Lgx&^5sXH4wk)!X{*pdAod+*`aWVr5YCXj@LX6PLfYN*ni zsPqzwp?9P=5drBU(h0qV-g`&7fPjE>Q0YxXx`3c`8<=sez1N!AXPq@?_SyTK+1EAm zFMLn1=-#6d5^s9>Z%PkOY~ED96n)I32M@ z(@@M0A4hm$*ca(!&TD)NEbg;qyh83)bWJxqwwSJe@@uOV&&hzBvfb7tvpf}?j!=xlO5(K~A} zMgZGHM%_4lAy`xcU#|%tBIfEhO-j5R{rXn!+ZAUA!va?+aL+Yr!JEx1^L}HVoZCo|0DApSXm#Bhq#?Y!0C6FBj@ESI-cYe3sc21k$V5F9&xBO>D}V>6 zmN~32;*&j8H3XJ;mHa={Z!JggP`gt?zaM_zN)E4d=?13=rn=PYvg%F?awUrwk@d(W z&(l3Ci_FNmVc*^ZN@!{uGKuweYAY0LMeUNh$T&@DD0^P04F@uo0yBQ`PaCT*G&m`m zsU`<51aq`{u0op@J=03n8m=!_{kVogj%Apog6#DRc`u2;ao(983K12SIM>VT7AoFH zLf6wb@Tfh+JRSENRFhUuj{PfK>t{6MPhu;`UPG0q>`cMpKXQgZT16g87Ja_&*0OA{q(7#@f3nwZsQnF zyxi-)gi&I}nNUZj-E#v2Z+oWiM7>WE>LBON=Y(R_CrHNfxWn2^$ zn13Nq&Q%(f<`GF6mZSxhpBS5pl0DBR)ZQHZDZ@Y&t1n$_r{QL0q|G(}Ds>CmlSo0$ zq~@HL@w=wlQr2i_a^j4P*Eca>e!!NS$(~t1IAGJ?&bv#qovqu8Vq) zgj$PF=*6y;iw6HU{K`x#2G!bScSXRi+K$y!fd?0jSnWF1w$yp4z&ViwL4J{!V{b-R z$m^W->l~#fmfr?mwiJ=oJF97~%;a3QR%r`a=QuUxiwyr~a3 zwNpzpS&)7;U+)pExw^?d*D(|WQD%jbRE^pmDh()lzkO>yzrOpVK4NXQ~T4_KIA}(;#GcA;qSB z81;%~R^ql2^rAJ)Z9p^Vhdu$fXPctZ&-ung2}5N!hI28I#^Oa?0f6Yj|djufc3bCg5~mT}##Co?68=sEPt{k6(+ zlBX^p`Fw%;(JY8}t&J@#0&4!Uovz7G@>Lz{tasqMf-tErBAw%~!m<$gMvi!CH*O&& zN_~-2+El-N{T%n&*RClV>o^dl7t_@iBKm=f7NPCOVdKbly!)=HrRGrD7E|v!Y3HQV zThlk3SxEZI&bNMVA8&VON{e;}ybHUvP{4G(C-LdKN@zUrd_h5fPo5=yJ~*5Muvy}?_Qd{`jTb$ zxEjkleM60U6z)T~G81^Ods7S=!F+$6!|(TtCnDz5To0nC**Us)KaYJIdh+{h>qp+s zpIVey@h@n$%P~E&KG&BBEy)y{O9ubof)Vfj*Cy>9c87=1?IQpplOOfk{bcV&2x%6LQL^0v z2=oZ(7(48s-x_S@;K$S^;PcJ<^Nw}Wycad?)3o^zZvU_kp`3hr54qZ(Cbim7ztEfg zMEj&g@MeW$?j~|RjmQ4mqwj=lsYM>qGv*Z(N;bRCB&0PMjMYTMMu>2Xc&%^y7SS_KmuW@unBuZxYn-X`dBRmiG^51AucQn(mr(ZG5j4@1k1}NK z7vpNb$5opk@{LW=p;4~>etp!BF_}!0-xZaK;-|2Fulx8_zZ*PrGz!< zXqFiU-`RL}dh?|1SfPvi#UdO{{!iYD^6!7A+p6-R=0VVTI)Yj zk)G1I-Z0^#fAVe=2TCn*X3Oj4LS%3#XNm*k`!-({V_C07PKNzwWy+X`o5tq;T2PtP zSSc_|F_%kt=t-HH#|vZXPodm4Nid+l7c@#j26=$rpbPf8M+gR)%SRDkgjN)XaGK(5 z)q?nRgSA9d(Va42E^Jj!PQEoism=($i4Pn%EL`yO~OU0@(WXO$hji1q`5C{eV z?~yB{X)eLFm-QJvl@}fK3E6o!?a+p8!t#U?H2tnby0%T9B$m10k&?7~s0?g?dxZ@+ zX@sJ)w1UZ_&|8@_VQ!z2?~QroW@Z(cdKeW2OYu^W5O5cqW-RPv(d!Bb z$WWvY(mV6`AE0iUd&TbV-9*7C%#GmIj;UlKu&%R64;O$uL(XV`yL<@F`ZXmbBKX;E zs<4wExo9l1GaI5zEa4-TVj4E~Bfn7<0Kt1WL_w?~4B6(I1z=)6!and(MSl@1GhzPbO$J6@~T8>56YZZoGa}qa+)=GrqR5HWB5&v2(B zm0vat+2y6CP(BnJ|4zF0?N7cJIGsY9)B@1}w7+y>SvW)lOoae-W_b`QfFX?lW(KV| z_EJzkj9C~COlFnS%kx>$IcTbk3jG3nuxv@qC$>A_cHJ3nM@R7GV_ajrF|6I!?0cOeST<2l-2;iT%XXZ*r8Z zXOzf(HSZLcVw8BwFvQyU7aYJ0Hkn)x34^N9krr7J^!jiEXah!|Agd6QzmAr((uY_~ zftAB;)vXZ)2+csf=uKJp^G_y9?{8uWIE5Cx)#29G13ZT*te#yhPj(>?YsjXV+AUkP z`gMqdHJ|}QfN5zXuHcCY6d~c^b7-dZ-|!}u%2H-(JrDOG^05qmOs~<*=81~Con9$y z-noRd%YFtKkyY^^TXyMKgn^S(L2;fe3))2PvC z{1t7kqi(2Z_fsum>i4PlG$296Tz-((h3w9&evc&1V&ZnCG#c$}*zI9(fkeJKrecuz zYlb7ml;LcU0}_l52^h|1LwoSzwj2~4`|n;&j41#f9NhdZ3D33$WQBmiC)W2B$n)UP z{3glmb+;!cLdTv?_lrTCZh-fB5@)tAfwUuDhd1@}+EO*?{2U_`vqnjZ0bgp`2o+wb zC<;OaMo;D1!Tlrmtzi#JU*yX7llOzy)!=Ezj5)G!@0Un`G)If)izr256gQ*<0Wmgc zpwnVI#$hR~ReQGrPp8=_F%l5ZJm#^9aW%E){b|xUgUe`mpD7|B_4)l!*=4+n6n2yD zCGn)}HPxhsURJ1V-6HXwsv%DFz|MN6lkO1d2@O3zpPd}&%f?&6CQx~<@-Z?+LH~uj zJcO!|Qkj>p)*ci= ztX=9UVu*l!m?v-}ez7us(2Uvq89$tKlJ)gWJxBp;X8}8R?z!Twfo^zIc*Y#33d{1m;ME)TzT2YC-97Ca84=0=&A)I~#R%qC$T>j)0;Hj1cM!s!# zfr zwMPhYr*482fntk50+h7vOrSTXouCUhj$3ej%y9E>hJ_bq%mQ#~VK8&Z`k**Kxp9CH zQQ%egXDad`Nj`!ik@2+B>LGM@E9tz#xFM$tqNU$IuxIK?D()g;Nbze-)!w@w8UayIo2a0S7! zH2?uxf&I{iJW&mKc3bna!0B=JXjksb1Dm#ab5*=zhYdkUC?)OXPxhNPirV>HRc6+n zftG}t+oCdG@h5iFy{(uKYRd9LYtXZ4JUZ64YBY{$Dz5t~{#M}2L*n_2Pf^v0Xiwe_h9QHT>*~ z3COmca5eey>Mj0iitT#l?)8#FK?nMJ34cYS3r@giU$5b>$!)IJ@BZGtCwFDmxKsFh z;KthbC$Bcu)hxmp0)IUViKr(5+Gd=2U~}m_(RTqUgMIR05D+ah76eozBxbl1L9e^1 z97`i;HJGKlrJBfcI~c^Ex2>MarCp$$t+#{D5VY)#V9?*y%8_`u#tbV$Y9M4_2lh*| z>{I!ak?eA2$yGCj+8W%#jdQ$;)r7UGL)nI(jT$U_g27BihbGMqZwgd$jgHK6)gfpY zY<^ws1tAv$fIV|PBf;K-)t<@Z*m@w6j7>Gqesb*)AisF> zW(!iHT%FtztMGxhfJ3>72RFlnnABwm*8@kz09PE&Q~(CADFCrp4m&%PA6+6uDEZ^K zeeVn9UKQ}OU6Tsk{Rk0N2B)$Vc3#md=OGYVS8Wk1M<4bUA@#aW6&cfNt#TCgp2jFy zDM_PZnQS~%YBewdss@X2bsu7U1rpN|8R2Zv67wV&ASM(_uI`&Gu|~_))!A0biv|+( zX;%<$>WuCX+fJ2iNwTAF^Xm6A0LzGdBv5r@1+bBKm_*`m(LlMio!*;8s-C~c025n z?n1IfB$QIA#DM&aNgv-J+|gokxAdls2?-q9?cY{)p&V8W7NqS9pFw1ui=%t@b)&4G zsta*$+e+Cw-g87@^>_(N@N+fAkVgk$t+dGx3SLYcx)5Hi{y;u|mFv$>uZZpjos2l`8N?O^29>HA zld=P-4Ivrt-qRN(1pWFta`)Nw?WEDWhZ&m#egJsSJCK{B?m+GbO0Ja6gog-H(L5mT zan-fqR2bc0(T=lzI>hlS9vOUq=wn8~wXqLvH~B_WP9;)k+R;V~5jLa_(nkPfK2( zwiMtPP;*9?WdrfjcD1f9TJFBHxoh#JeD`2O9*%>VAC;YC=L0&U>u2-7MmWjY>AihC zK3ni@uu?YVTe^`>MC|pXlRQ{<>H_hG`@_p@;~;1BJjGn`jYwx@E?M1JBX4dDL$-=U zmu{jJ2E}mXtga%fw>wr&%&FpnHgxSwTYFG`GtxyX+~{8R!d!(^xnxZ8{(JJMFAt$8rT49)E8QQL zm6pXC>euh$#p-2JZoszFu|sZ-k=dZ$usyNxmu@rSx6Ed^X%l;AU^l{(d-Yf!Bg*U0 zk37^SO4AqGU$pHguvSx*h$o|7`mEanV$C;cU&Kzw6r|X9YNdnbJKjZpA@yl4;Y3+; zsKvYcwrRd5NfFGMye6@Kam(sdua?KiI?W_Vec`lyv4@Q#mdZOYYom9u_Zv7HtP^|x z_oXq;@Hh+zol@=dbY=H#Q-5kB+MUk(xZ!uCM}!1rNP$5=!TtSJUaoE%@>dUD5z^j& z^nG)cJacI<`87$n6*t9Yg(EMzPdo0O+}0txH2>0%bY=1=3b}SnwyO#j>kFo+Pv5h6 z*I5k2;?D%D9`?Tk<>=eE$T{$ZE2lMs!o1uBbV9M1uw1~5vhNlW%dBjnx69xgB!}aB zvHa$&j*?)Fj)F(j{yzU9EJAsYs|xEe+Ni9aRf6)BEv{a4djV{RR4M(1$g9>k~%?^sZNB+w+B^G?YTo+74ZpX@)<&z+noD55joq4 zTHG$jlkh#1>igACYpGU=%+fc{R3>1;bPAGXJg>eFJpj&7CBvGx;yoyvSEqHlktIC% zko{k)M3tu>4K5qE>;2jFitX3}CirKjUAo>4#~KJ(naAZGZ(J&jqvNjsw9!CN^m5U!P~?*X$u~z9 z!_Nwqf#^l-YUwyevW31m#T(CMNTBs~u~0&&e)aAB2D**s#1Z6I9Lw?{+|xM|1Ysx1 zS#MCRs|@l0Z~4not}owP-nYCW#@#?nJzt#4TPV4~@UkF{0h~1kP1u5pGx3us_qSEo zeqg$t^19eQxASg*XnHaCm)DF#D|h+=;l$0*r;(zd!Gs@VsFNFJ0Z>nhvI{W)c^)?w@dBAG1H(|N z3W(|dN{BUq_7o98#Q|~x(0le!-@V)}6R`eFj#fuPb#{&(CzPT;A}WL!V*!=Ri+mdn zHCrE?6|I!tR%w&IUHl{`?@T_zMz(edt{k2$eI;%7xgDo_H{KfTiNfky5AlVj3AhbO zu@f6;u@GkEz*{8~JBH&sUhKuub15K~0=Y*%5BXlbHbs*#1@#>Ph|y*Jh`AxrxI{hT z5IuG&=thFXdF2a?sH3vt;IAH>0>Fq~tpi2F2?y(Tka>U#01P8|!({bGb&QB90^K?F zbcHa!!r7%DZN#zjt0rV=r^boG|@2wE;8y>MJyM9n-0 zj8XHR42A3L(QDXDHyT`x_IcK(wG6T5r>v&vHmeQw z`Yz5i3N?wFdL=PI!CPc*OZ~pvC$~L4vRWGv6%vA)3j3gpZ8<6+x_x)t%)qKCfqELd z=YK008QEHE($lsossWCYHYdyiyStf-&|@hg4K;9eGiCS47#1B5#C&;KZ?4Kb3WYvv znV2ZIq-QXTuNumf$m7~xWt9Nn&9ck}uMI=HhD(DluBoPv@_mIvpii-| z?#@1$l4V`z0|QSo9IHtQagw>S1k^}e=Rp-lMFHQSTPE*Ba;9a7TL^Xbue7dZ(L!fuDHBrVMkf7 zlX5M^xVH}kjl+(uU`D3dmfNp>>TXjl>c26Pw>30kiOFP;bGKpBHcdL@-*zxGifXi} zN#Dv89I8pT(_@7i1e-EFQ7w&I1>4bb#jF;4CylqMSp43WY!Q(RhN?K)TP9FgLUI(= zc4qWdgtcdO4R-ZRq4lYA-$~S5tnx4!@pd}>Yel_P%L7qdV|zuDk{8zg207J0;+&__ z*x6-KJxiqACtO;(bwGO1D!E?(a_fO4Xn-Y8uyT9s#& z$)4CE_~xM6@jlvt9!!hnldmFeB5f_?B z*qzeOgsJ`XWZ7KbkvkW$WhfhvB#iMX@g%(vA72VbHmjGu5TX}L2@G?qA?0qlmnj4V z!|y7Pjik35*Hy^nc-ab*ZG;Ldr4{!o%MDbY=6n>Gp$1FGpeT??N+Zi=s_uz`ln~B%g-M;cFmP= zZT3Ja#48B)97Ytj|_)NPNJJ#_v2H<}6<(5RXdq&@S#Hn7T zi921{y+N_Dm}C3=4v!;&TlR4?XvGm0L*c>7K{;=DDzIyD{+0U(l+v;opi1x};QTIx=ia&B-;kon}le zFiU*FCk``?kUh@zpnK6QVms`GCi8sW=y>)d-Z=3r`uaG0cR@GMgR@*z%^@BB zLQZOdlu1I`PY!Uyh_g3FX7QxT>?Y5fAq_R}?(nmL0$Rko^Ls=WnEQMOVTRJP#P^<4 z7|{9T8|28|zc3y_XhdI_(iIAoUzqb$1?u@|v3ViwT6T=S{AC(TCUs_cxSS1sNpRDaiT_M=1Zy7Pl8O4_?6gj-xzg`H%y0bs=*MHP z5sxC2`H-iNACKP$s~e_HG4_>yy7#~2*XHtgFS+mdoQz*`@-&ymI9qbfCDDI-`rMM+ z%Lm^$%qSP7t@hEm5##NX>6Y&M-EQr?9W5+2k{I=z?I|0Ua$&vO=ttYZ_Y5A`j4k0(`y@Q9)+Nqypng*@BEYQntyx-c{WFGeT!SUh|^Dbz%9=i!>= zNh?zTHiipZJ*4pSPEnqwxX};z+7LwtVm%3yI9T~wMF!Cl9ptzzqON}v=?^ukgXE9*jP82juI#0pSq zC59;iBN|0iEh$2{vArHx1$*vTW}dQV5vT8Wdi43*&Go)8A}S%b@4}n-!B{#m_d{u< z6)%iScXd-3s?ZG^p>MR%WmkNcdLvL(nvr8!n3T-=4hmfhTxxK5avMtLHXx8?pfqj9 zv_Y>;Pv;IwxDYwr9?uke^yNzCd~c>w|9QcbG`cw3bj30-sKhbaLX}YkYs8NWcb@LL zgSE#UCme3M+nY7LwA?hJh?25?_0k7OER6^SGx{UKV0<0cAw^u%Y5Ek3{!`)PV?M}8 z>U6ba3kLAiN)!Y!ou)_2NMjpwCkDlCL8dXf5drb=)qOy^;?I#NbI`$&bo=Lb4r@aI zqzI_Y7%-KhRgm4%lwwTaX$y3MeuqLtyI zOEBD)h2e(TNPbd~STW@(AOc1@WXIWHa3 z-~1l8s3v;Kr(20~LB`TT=lALj3f#rVI)! zB5-YF{H7@;H*R!`jIcbp5*d~9d7#(DW2!~vXcj}+UxPnkEn`$TtKY-K+DqVs+-)r! z^`8CtB`_*HOzAhA%702HI-|kgBR+eFU4C(lO(X1BWnWJ<%Tx3oCpr%jVVlXP-s-?+ z3Tu+Wa5p2%Xej0T+8SRX%SjA#b1A*eTD3p-NPT?zE8k)+QFiXEl9yH-$Bo>qr)mU+ zUbHJb+`lqhEnpXpUFongICiB^7XUY;np{>W=>o2$4ytQ=Wk284W=c)*mjcQA52tJx ztUn7?Ip+gRW+kt{5(wtah*WfG2$JcOhtymtVKi3v65C-L_2$oRUoJm*PMK2agsZXf zuyM>&;Osq0rjO!*4{n0AgW(fm9D`RszW-c(u!BE1b@i@&{|kQ?Kv>m7&JaPJO0P{B z$jy0E1mpwss|IMAg)u*E zU{(1|!IeEN znRO(Iw=PE%^%$?%X&2PHUY){?we1`_jyIiY&S;l|XA2CCN_=R}?7iX=W|&R37~o7t ziByc*@|HV5TC(2;af`ErYnZi78v7fh-va;`gTWgH3S}#jqoB8kE0osM) z4UdDmb$+YTz6qFVDY&eI#vIV5rHsv5>c@7;E=L?M-w5H5g?x-`?xh;e_`nwj)w@vLJ;lp<%}&52_YWNvc2 zMU@c)p@lZF@#7tZW`~eV6>m;r{b>?jb_P8}Q@PGlK7(7!DEqYsa=dN43RT=OT&dj1 za+w4tUzd;^vs3nr{`WoOThyvg@!LG$1U`!`KI8fHR_-Uj8vw_u*$8MP%2q<#cP)mJ z_mBqt__ly8m8QxBjvJVB&gcI{6*qgKOjVv8>qz`kBPHTfC1l;m9jf(`RcFt+Un7DO}#D<Pm}OU(bLhNk3bBSya7b&cQD> z+tl!mSWYKN#CKovL<<_voGpP*GQW=a5aqPNw6pJ=H(pEz%(9842iRUNL{53%5idE~ zHzR2)*M_i`#8TEVYwM2jJc=t&8-IPTYjCf}kEx}X^Qc9KXM?Z2{pcA?k-;)Fb}S}X zqRyCpnvd5wotsrl$x#|t;Y-62yelezuSvEe+FMu_JQ{3IL z1)(0!@~4PIok7<-DR@#{S~ZAO?N9e=?-Z4Wu0x*|^W^-5T+Fy87vX@6NWl>H&y&>W z*2sQtn%-m`&3Np^_7@8_nfd&ICD%-!m^-bBa6t>P@ro zFn=~kkrJV#!8jzQXv*$P{KTL?s!ElGp!-wW^B@6OCs$EvGRRi|95br&Em8qZS#sCs zwjviyL-_4-6EjVMca_0QP?&wZ*BPFm|ChYwDm{hQfpzCc_IGzzPS2j>SwgL@zVk!7 zfCx5)HEn6rDIXmIL?|$aQWcK4B{=RpM%CIHH?)y99x%s$R0wfj5993Pyuy5JGlbNb zM9Zia2pYr&FcQMdWI6{~JQ1YB>zVe7w5=0p>8#o;C~l|VmJjZhsRbOwpn*%eLb9-r z&7?UDj`ZO5lRlW-*u7VW(o?v&SKB{2PGdpUtM{S0z=Hnc`$&VH$Rg6j;zbu7g5wog=IGCpo!LXV%F4RwgKy7=CljLqQ>(L^*I9-EcNw| zq0iUF9Cu385GBYj>l$t!SwlgrqI&qAjomiTYx`{Uaq*3UHEzWc-ramMGZ3;N>MhW) z5yLcdWU9ugfXC>w3#IDz5o1sQTHhRX8_LHqRMF5<>aYdM@koL$efanX!J0KxPK;Fj zhQzY1v}IH^%u;-l`Id~`On!;ffu*<2ET8Y-<;I-(vJsX(LZDegO)HL&8zj<8$vvin zbimIj4}O%=h~SbW{*thsJXG*OIKAG6#`?ngF7bOQZqDhWg(~`xw>GN$in+ju!u7cg zfKCKKp83wPZO=aO#L3eBQz|vRKeyBMG`dEf?XP}zW>lzRa=eOH$Cx;3+2VN1w0|S% zXY3VzZ*c)v)G^!Y^wC@upj;ZQ!nSpJatrtB3GE$5o&yfcpiONZ2ht37)fpRYVrI4W zDC))!s2XBM!?HZ-BIBQ=YsyeeaE<`Wn~`Zdm9lcmE)tR06<(GfS9OSO%~R$B8nb zK&!q4apR;Z+c5};Z;p;$x$Uko)d8#K7yTLsV*4md&sJqQ?g*|#y9Z?s&*DEo8}K_$ zeC0YOJGL3zQS}@e@pcPiG0w5~`}4MGX*tXZa!eBJ)Ftig&C1NYKoXJZR_r^g2_S37 zL2a8|g)%m0ZjeO|_hU&XJ=sF_yls^~&JrxU=6Y<7b(AIZHrHhiHEY?rWdxNCQ3q-H zO<~$CAwe3v>2k-C?$3 zR^_aS=&cG?;Zkr`;46q=CHRC7C`t6KayLRp81TeHc=OxPdef9m9~hZS@QBocswg2` z95FAhfu4cEG|mku!$}i1G!!8ovE)(x{m@Be{*9tmKL{Gio}ezZ5zFy`j$@fs!P*#r zv!{cD)D%bS2NO8*Q}oMRN*PQ)7*M_`D)SK;Gz_^H%h?}Vj?SF|`?}2Lw(7EjL%#>P zcu^K!V{()U@~)hTvDD18fx7+HM5-#h)uMB0tRQywvUKLbIcZ)!2yg%jxbi0A$r=!m ziQt!xpl-GB14QPmlNS|N^q!-#Hz0s>P;h4^k zx?O_Nl($Z!$qL5bcL1x9pbp9iUR=nlgNl|OyTlyj52m$DcdXj24waU<)smI0#I?dH zvQ?o+DP^IeqSsA3b9GOYxP zZs9-=C3codAm>e~aWsvvd_P#;g%qIJc-UW)>$3W`lRJXIqtA+#S5Y{GD~Mnf5CZZi z@DBj0oIki&d9;%^9B-kr<5^kzTToT5{<$tz-YDX`5#RmmS;M?2YPSJ5pJ8sd(0swS zwC6;0ZXXpf0wH8KiNa^nj}96D38%s8`6w+)-0S^T_Q{hXVE4nWBJ==#A7$P+$eZAL zQ-kNK0?cS}RmQ|56p}3&o4o3w5HjjKiRazOplWT{%;%f@Sn%#;-n~B`CxAHMO)JM6 zLs8@`WRyYa%Il@p+F*)16be7Nck^Seit|p$9}vB0LOdk6E^AW5IQ45poLMb;cGr8N zfWBBaF8{A80zie zqY*_@yRO`wJS`i6iXfmpENXslsaqw+or}CCKMQi2bMGr)!0`*1<^YnioOMEeuy8XhI;s<18Mxz&Rj_@ z1Ljcn3aK%odRmdyHfCSmkpGfEWcoaovH2wGH|*in;uhw1^VvCm$wV!8aJgBPKMW#; z`a0iH4-~%1+gN`t8_D|7i_1O&(IT+uD5^S#?OGO;c8GAKALM~Ht85ET2NFzeqBN!= zy%$sh0F5e$zEBE&)pL&`mWZc&El&0e{qCZeXCwRm-0Dd_05H3Z4w#mxo+HM9y|wY8 zUDzTs9D`F5^eTNSe>%AWq1;oG<2L3di8SE>@ybgmh)XE=D^ePB&@3Ipr9pB`krE?Y zDkntqCQ)tyPMQs-UF!Hj+SMjt76B2ckD=?&`vbsOXk!HgZ;sE>zkXxp8Ks-tKfgNf zK!*ysU^06Oq1DVaJrXv>O9CGD-{>Fw)<3H$V+Y4^!a)k^yb4lpG(0(!0m6|yD6J{V zh&o1jMSxb|6l`ihm3Mr$jK_{FzegNyI3^2WXW)tl=y1 z9+NUM%Bj)Sj`pc-n4izlD36VquO@gA_ALGs@L22Zcn!ubz?<*sVBJsQQcf+PF8|Da zaL!LrXGH;uinaV;x56@8wU>aFA9F2ndsO|h8$JTMrURp{%fp8BONIzbX5G=!{bO~y zH@5=nZP=VA8(MuJ3G7!62dpW{9WlKkc=WEl*6 z;+b{sa5llL*3M*?e?c&3vuN|Jh8QDvoNeTW)clt+AZ=U(`(gdF{>17ys%n z?C$vQ?{7c&`1W7?g@4)KW_3tC-J7kw|5tzE@zzA)y}$Yk&pv;A_v#h?KU&1H75`U% zVJgsbTH({i-d2+QfQnJFGObIQDS$rNUO`QAe>+VlWtszLVB}Jcv9S2N7u>PUKFdDC zr9x37QD!&Wt^L387s}jERXW)J^xxK|kynrHl_nqX7?$CT_&y}EUbyU6uApCm@F4!kQ%q-<463BU|@g% z6W}(00W9!O46JMfG3revL;sH&D2P+mSI1f^-xbP-6SJUOtENlU)A%gMTdQX)F{S8# zAXqGm=6^YY^>+U_`_Chozb=5gqG~f%pnY#MPIwr#75|b;WJJvRZ>MVggDWWJlU;8=UqzUuq==*4;z|Nk}vYl{iY`pMa!28zS8ck)Dn z=Tpjb56`F7dFsz+wEky`AHRL@|5X2NE$G{Sd4hfY^B+q3pGL6bDCx<6L$J)h6YO6M ztg#Q=mPE5WCBEn^JWa{@2vU^7D*#;EE&7$X#-#Y7+u0lGPj&x4tNz1j>mOJZ^bf33+zc$CuKXvg8WzntiPsCG zW$dIGlIS`~@Q5#E{`41H^gmBq|AtjO8e`}`th&_W;Qsb^?em}U4+#JRsKNGs8~^^H zzAI1t1Q`-e$NwJ~|Nb#N8Ha0-M_r@;O?X0x(c(z{$NKsL0db&76He^G+GJ&`=jG?GuK;#Z89@0fNsm5gt*^@fsnp@|Yq*-g$so0{ z+sP2UQ{Bn`!QNNLMcJgTMeogA7A=cMaW0cQ;5VA*iUdfONNXcek{(bax4g zN{JvUKYVNVocEmF^X{JA{hi(O|IFukp8NjZ*ZsZXdtLuV7r;jbcmJS4a(z{)%VYQc z)0}x>v*)~ZuB_aGePQ|8qEqAhv!%PQ*gh|N%sKx#d1_j_f$MUvgCox?q)_$nf5#x%{}^9C(9i#e43egf$)h~lUkuWZ@$~|OgK7_t zY=_fRko4P0$@#SNtDwG{w@a|7(W${V`kl zg6j5PvXzhDI)D7ThROtYi>@8bvp+)Ka8gjegg1X7+$MllfcIbBGavBvp8ZL1AU@d| z5go&*Rbp(QX+9XnVl|Y$k4OJw&;Ef4H_7cxi~|bTFJa$nEF-V6{04CJ*Vp9-mj7g3 zezfgW43@+!5FM<^SALGt?w}=cFSuS8yxEa|=F{)JSw+MZL8dzDkbgIUpS{(i*Zd)p@=q;6|s*Roy0v6Mers|(Ntg1BE>FZjEG>y%@Eo@^%;MmXo3@_S0LN1$kdHJGfm-R#yl&?;hbKy zG(JPuQ&}QJpRX)B?B|2@qaW_|rC9OzV+6po_0F{J|LLf8_^22#OO7`|St6dvL(74~~NY zEn$E^eK0Hdw+H`(CR2bJ8tf;+?+5?+egAd8-rwH$S2X?HuNMK-NHxAb_}7=1l`fpI z_Q%2h6;1!SXlbhAhqo)kjg@OJeKD~9T{LA$KmU87={n!@moBmY!Gr(b7%eTW>ZVg9 zh_8(-)=V|(En)F!RGTRctXCpDsOTjc)~x8KFLg5MQ6l`4E5rOZWHz47?lC8|VFobh;Xze(WGBp6AuKd0Vu2>x;)yxizt-DEA6$-p5)(WcIGSz?AvI1>Y$2ay> zR>#Lz&;&F96z~tEQP*{#Wsq$0_d&C|M$TveS z*7SUH*>sg!9C~{=saB{mUXCT;@vfuFB_?o?Ft;^y^6eP~pd5@w?S~JsP{wS+q7!x%gp7cje~R3Wco(!^oabNSKR-z8&7bh~Pty8#Ee`qrD8KRV6^D>0;B*nbeOp$y zNyj47IQw(LmE|Gemq9i^O@#d6k^kx#V_lcL{#)dQM(&^F#rJ<7dAS~B^8+blKO^PN zkJLN~pylT>qUV$f{{k1_uZ#x#Goyk1lhOPgtIqy$42v+8>Wwa}A8?svE-V9sfIr3W ze)5HWX1wS>6Pv%C@&4;LoABQ;&h}x9_MeRRzn$19QK@30q2v7;L_`1CMK<~ozrD^O zf@tyn?I4=$|K=dt<^Rp_D|7z8TqA#u2O!?R%{u;9hfMy@;sN#BIK|%rB|l#q{|uD; zAN5y$&x`f4>3$#KS*ER{x)P__ZrOE&#tj z^FFU*=W;#@_p&>~{_0d_)MRmT!5dhWM>)>Cd;~kK3AGK7tLP@zY2AITyOl z3<;*s!vMdpQ5%f=QM>n}R3#AK?2mth;-7rPAFuBDy&3(pZ~wg^{=bUTYxk!czzMhq zME&dz|Ams;zfz6#+ZHE*0y_UFPD|%1&3pd0Yd6yeWv=y5x4<(0O1t@2=md~PXug!8(*918KHYW8eJEXZzBD})(3^rC!-Pr&H;3Y-V@NjR zWnd1H`byr1PTR@4iO1V!nG=z1zIcj^-;;m-aC%Q8itKOFZvI|=kXUH_SG1ddllpn|ig!>bYF(B->S7?52BtxOkKGjQz`AUXsg~ z{i4E(FK^2lKYV#t^@{!Spl;6PS{nAI;_^e==MR@3J8y7&J?tfR{dzROQ2F(EMBop| z4;tiguD+hm{fqkizgT_{`=5~?RJ+GN`VZ-$l8ucicz%{2WLpya&~9p`x@l@JZZlQl z{~EQs&Qjk1AOLJ2^`Fet?<)Tlp>jZkI(kJ1fZQG{|0|W0S=GHbz#){!Ww;Uxn`S#K*=4KZDUEXGFD1Bh z+N_87hML^ngKr56qfJhbYY?lKH`l+LtFju-R3&Ex^l3IYp+jiV-lU_6Qu&0(@O7;Y zSh>V>#|lYr)aNR{P-}1b^v=f}mzGXe5{)TsfZ|HxJPiSux=BDH5qfXfHD|r?=CrCU z0aLhQ-tuklj<$iXm_mhkzBn-(q>s-m3V$tZ8H*3}!N&#y(Q)YfOkuza-E2uRW;u$7 zlxTe$E|~Z90YRz|hP~S`%>SeP+bR@=66EY0@LSdXJ?z9QUB!?eQ4wHh^ zM@QrRDls>ELnk>D4oc?lr?*n49YlTMdM1O`DwKr6w^qnrO>4ggDs*r?V^Ghyb^n2> z!Xs|^Em;VwgGCnHWh3*U^yos0k8|vsBKRjE0Sj*{BK5UIxKs-yD6XOT#gnwVeiQj= z`1wmu(4Ft?`=K-Ey)DrDO(ms?(%)WHhu??DRBndOz4K}_d`Ruq@gU@&W^gmPEaJhF zZF0cKHzGWkR+e{~YYtSVKRJ!_89;sTTT=mioG{+#3FF(@guD-O9=m}F{?7`C79|^) zo)Hi&n5J%KH-lQENofa(Vzbi53-Ib6zWYTbMebn=-y9`1bv>(2A&)+>StzRX&XkWC zES-74Fyxl=6;IvCkugcK;8RJaOUV73rue9g@LPEX7kbfttNbc;v8_n#=~&D~<%+2_ zx`+ZeD(KFBQKn*cJ*@&VFU?&_kM(TcI?4I|9pWdAOy>emAWaExnHUgOlI&D>}v0S4PYAuUG5`Y3vqBoN)* z4g2JR-bs(AQpErGBxrTNU<3`47merV6zyUR2JbBVY^LJ!^Opt}y;farJzZI7_3c-* zdm7S0@%R}#!}ZjkN3r~SVHhcLN^Tpvs(d*D1uEt5F-aS!?9SZ8%TO03tEbx|^=6%2 zz#xg}#JL>DY)N_L>rUImZND_hQ1hY5ZB>-SkI|$IPo^m&0cyqq(>qyrRiCxj`GlkY4P<=!FcEorR-<*__NlS|t6PmM>?!aE(n!NpP;H73iaz zO94c9$&2`IUAIa~k$YNMKg%{XsNeX-XO71qdhznb70n4!YLdC)#44>r7IR4F>^mf! zW#mjSVqXows|Z&VAdHX5y~aXnn1Cay8Kedgw2gG!fE}G>KZ_;t`g}HrQL&RtoPyIE zfjUP+;*99Gsd3@AhA6kSt6Fk?GE?ZUIcXPR4`We+xF*AjB1)52&>U9z$J>USK)iLF z!gl{X`vhDxO>@@XWCMO6xX2nF6hvPCisN)w^S*e;>ZH@+_?S2XDp(4kRAk`K!de_*?vL=M?kd_9P_ zp`ev18Am4_7*7)iev?Z$TCC>f*!QW;!ItRVjw3D7FDoeKUcZl>G+7IYRU{^tduWL| z9{xlDQlprd&~e@gUcZ$rhu(ZIIX|9r+Ix)7$<72UYss(UNyp}!wNY&R=6aqGmk#wE z^g9|N=Pzj4ZpRv%uM8!7bh{J45>AfwfzidXXR?;eCe3w!%B2du8!WM-AMop7re@xk7X)lQnfsT zA_WX9W}dKGu?97fy*9f@qyh7kdlV|KR6B$ukO(D>%*F%gvRJCyn=58#rxUt-J|J7; zLuT!VD@XBrTdiZIGzitFzB2mddd0fxGMBFP?#x&uU>nvfK9U^RW?=b}?`(%ohxTNL zuNAFh%JcJLK7irKbuNb>k};$%TZ5g29ZL8)eOht%rkp^Z?6@1YW;brGpa(kIWLGyK zP=BbdMR2S-vUrPOy5MHe+!uBz(`MU25OFcf`w{m9AH2L{Skg-yCL6l}X+pnpmdw%H zXUxi)GdN)bBU^&7HDid)x zxS2uh-U&$oWsBe4h_b5LLYHWO5Pux&o(J}yuQiB z=%bc6K`BQkZD0{TitBUs_yhgxK9)5x7u|Vq)@!t{olH}1Wc%dpzAuP}#f%z}#k)Hj zIQg$aGzs*g)0hP!=y{E*2R>f@CkEOSORkBoM&Ad*GE+L;#h z=zQxP8{EjR54~ftk#Kk1!1jJ%+0J*bT-uU0oo$_%36>fa+~xs`C_3FD<#zKdEinx~ zIj7QX6$Z7m6_H{OJQjfsgAX?FCoGXi*|&1-i6Ws@j54d=fiShkz&y?DtQ?F&i$$GX&Iln@deKoJ+4Ib%FWzT_u1HSch2N4Tw8gO z&F>vE!<$M&(I&-K?72(U`P|hMa8CX?4fO0gK4nY z7$7I5cqNT$!;|nHatkWkH$Db zHz+^}2TvoL5TS7zB<>w-pBxOq^X}k<V z!zWho6$Aj3Vn)tLNTk}xfqjbOyI0>Ah%%GJ(_8c$QXQN`6OG?y_9XCqXfA4HDQ zosN%`>!wymkEHD)JKl^$r;Z9rM#`ZX=;%azX^M&?B92vuqHj{Y_J&Elfko9h_8cih zajCQ^&>M|I^H7*Z(IS}h1eW0Nx&i$9B7E`(@C!i#s=+9vP^^|@WXC*>779n}Fm$gd z!qpCzq|dWG&ga^%v}%upUu6T**Fl-%*JGst%FolOq_o`WGYJ8}#U@B+_6Fpq+7@hM>NMWJ(r1Q{guDbPqAhp|p@F3ZFGd9|4Qq-hOO z5(kMKf?!vSkP8iHdX*z7>21UA6t@_;JUli@b*K&sfX)e!sG*}G0YE!}nN>ja_1L@e zKH~*s7`-5TMNFG@Xtx2>Mm>Q*GWdJX^>Ac}&AO3OHzbb}1kDN(L<-1Qq{_|n%L^*! zp`hjJP%7^r#jC@N3Uz2jCnQuVqsd@_Ipzvlwb#EkTkO@c1BZ{{X z$@+l2b&%A0Li#vJ`w)~_1(1psBp8QiALfYqEBj5Tu*yMgQ0Y1bP>p@ed`>hiUk{84 zP)27Q^e_iunWud>PXz&x+y`+#%u@!$PiTtVr4xqSqtC|Idc}p-Yk-MjMymqmK(lhi z9Wg1!X~XrCa%ZV`{Bp-@U{BE_&8pdG9Iq#$i_7oxMF$h=+lo-zc*iEgqC(Y-A7q8K z6lq<>kf&sUVzNMCM^W4A&}DU;?Qxv+P9C9Jy8J3gIj0b80Xim$xe}VGPzOl|l%!QT z61}2N-~`kd0H6o}mO11_6%extXj28mLcnc-5^MNwee!M?&lsJ$K{o1`ww)l8b$J~j z5d5xLmmwfy9F%z%Q_9@8s{}B|3=lN{)ilfDAC}88S4>@KHA^x}n@bFc6)h+UK5^L zD{KVUtjbD>h8XxlupL8SLy%=aHtR5i83|8U$H`MKP9Os(4nY!1uIs}xG#>d8eW}Y= zrwxk}G?s*#RFxlqX*5&wwzxsuO1X_wieIGMTDd~Tp2-Lgfn4rl*>HlShR`0eWI#GY zh;jguzUBT{YIZq5Q*{W|-MobL1io4F5M|Kww5FhUK5_n*I?@4w@>F?Mpj8mdCoXB? zNvgwdMj4qQKa2A_8KD%m5I#?QrG{)De%8I>Nhtq;w z#sj9Q<0!qmp4?LhLS2t3ei@3Yha2Kdt()bkL$BvJE174bab~l{Dkp2@Gz?NJjOPU{ z(J64ErE}(zCU}B4{iBb#6q%$Lq%cPm(^;1rgD#a(sHTW{@+2Bi=p{(z5R|Ci?B(B- zunwAYf|xReP>HI4p{80tV(WA2WllEPmO_%R=dNlrP^7Z-LXylKTWr;1cH)20f$p*Ys_XRrCIuIE`W3zzw zW?pU$@-1JF)#-$+a9-(t2t#(Y6kdWk=8|E?XF8bFGEj9LqPsprAf;Qg0LfgR^A)S` z#Fq056pe$stye>w38?ZRZii(6H6&WPInQcy<%=SK);gxGI_8SIZipaM-B)OVhfG(R z7cfo_=85XxM4{0M$$d@DpMO7Xxrji>gH!nx5$vCu{n$5zz~8Z zfv9epOii1t+}Q9k1k^3QPc&(U7+o1L4bKkl91dnL*C(gOCK>|b#_LR2KX%ZB;s!V>*BFh8%-NZ0ig^HTMcbC^^KSO>Whh4qPzwdx7y^b)<(YB< z)raEX;}Ek>AZidqCJt0&&WD@kn~?(@7kcfv%hIwyNv%v)Qc&zxA$x;F!B=q44pdB8* zFL0=|%@bp#)p9c%=ut;kg?hu=G?;MHpF|tZhxDO*8_Yr0!V$UQ@UH6XI{4h07l=M z+2Mp}c4Frrvf$n%m6##SQwI@>!n6@RWXp8Q>d+2Hxt-dYn>@7%lwt&$>3u2d(8JlH zB{?|WyC&w|nr5JF)eMvqD7p_)K>>zMp}HslzW_kg0ji8B<&r^aAZqOWnVw`S^z^*- z2;kNnhgz0YmR5trg{eNJ1JDp?d4N0@b^mG8&(bHB}_U8aWr#?4&+6H@=qU z3R-pqLpX|^R8{_c>Q}KFZ$fmcGg-K4LC8oBKQD?0$ z%WR&l^O8v+;kP4b5~<)uoj{$=uA3b+TAe^`^9{{qW0gi2^qS{z9;kNXl}6pcrtT~8 zdtT;x3nFq^mJjO;dr|gjnP_W~Vr@s6kd> zG*7eHqJl=HMqzMlJ(R#^)}L;0Vmp>0_Ec_2Kr;H7T^jSLeGFUlvwTme(y4_|uT?Q~nOX?^hd{HgNwZHc=s6UVDuQE)>V?@ zre72VW=)koAhwhYU8J@chxT*B44*SLLO#WfvQ8<8R(C^%CfRz4yn57S2(;X)WinCW zqdn4^jJ6j1LROHmYoxLh+fY+a)`F_?dT94pCxwT zny|210qphSq$J;*b*-wvS|E?wAd%b0-nwne2=QYgqi|H8Fa>M&m&3Z(*`LpWr&q5J zPn}d>!(R`(D+KHf*WOl2l8NF}ofx*SJYi&u)M)Qlf!E0J$xgTR>$X3iQq-axnJGEN zuX?Fs;mlY3eS5oJ&+I9PU*AHKKtpPZcG~%sWl|sZ0)EU_bvXxjc)5(t@WEXJJ9ibu ze)@VH>_%HXp4lZ^uXOvDxKnJJFYly)a5|P(DfL9T3qjNRFJdY6#yKy)MH)FZv$>e! z5A)71KQ0&Z(tk!3ENB_ZP(VU2hnDU!F2ymMy!D)o?yi-D2=>ARK&(PbEZku$*(O5q z{;5^`(Q}6#T@8Mn*)*Q_=UN$7-@HX%IILcbNlNI9?3qM`k?x~#opB{n-T{TL+Rs%g z1n-nL?zY^i46U!4M}*cj(#>fLKawGRU8kWQ>f>h;1R_uV(!C^TMzy2_SL+@lQpjI zg*u$4`wkxTo0&})>-qZ3%YHGh6|Xn#Ua9Oh@V!sWE6Q66MxAnN}iS@ThW(CLnS8?K(C@)&!&TWX;)uT(`S7PnsuEJE6HbFL3pYsnA z-`7Q6$0}ts2r6(7Ei?{hnT&P;v%!>D_^=7oz?C-5ZF^O& zWh`oP*75?veheHuT}1eHg)%KnN6NEdIc>=ylI-^Xi_MlJfQD=*r0%L1?bzEEaIGb_H4`RJWoSvUo24^cYYf8ai` z0eOmJUNfWA*gdwKY%F&SK}+PFq_vuz#c-R3?)I@{WFRFcRbiq|2~bw%%5mNbSTI6A zrtrvQXnfyQh|6fPQ}b-m%6zNF_ZHnkS}zW%2#LFYnuFb{Rs<(V zy(6fQli?8`nC=IHG0Cn(!{zsqnT7j8Ums0)bUY+OoK2V6$=)$!n(fc?iFF7(up4zU zjN>(Al~BEBZuCJoD}VG;en(uYAxK2Oo9MnOzmvV{04Xqvvw=R64RB>0fQlU;1J;l> zm)YI4hVR-@Ik z25!y>sJY8!Zz7QZXD=7~)A_)XmuEpNkDYNm9*dZ~)tzfeRqTe-a>eI4St2xx*i>P$ zKqjX-x(DS4THR^!pG@c4KL)w_>W@BrZ5B9Q^F0X=Uj@1622tmqYsslGl(<<8Bb=nr zLG$SGy6L77*1AxpTMB+REG@qhdG|{)9?~}f;?UOw8)E0XqsXt6W7!leYpH_W;`2pq zn1}OTg^CRm!PNgW3J#VPZ8TjcSt8F}( zd~o?axaf2GyMTE^S~SFA5|5a(qu$b@7$3LNp^^O*%!t}({W#Da{SJ>iZTG?$gvq?{ zgSPu40xf`l@{S2ifWdkKWi9|azlrx9f9a(pSAF)9Sm>2+qu`99{awd46BqyV*6whe z(|S7bdtrL%UMvQmd>u-6Z>ObJ6VO+t<4R!;w0I-Z_nMwwijc&;5`3k$>QbE1w&ncs zdL`Aw&3jLliH;wKfg`C>ki{pTNfZk9CK#&4(Ry@hR+jk zH=X&UK%8L3G(uoPdat)$Ce~s+^E=h6wV6pSZv~>RKDTZKiB*wG_-qodoyRrbRlzwp z(i^x zCNf$!<{C*>nhMIcE@F5$HElPtjx%C79GAD7&bpi4qkFlzoCMg-kk`#z*G=3j=xA7; z1m>VigH9^I2Wr3^d0d3m*C)6q0tVwOtG;6K=n)8%zOdw^qaYByz)FPi#0NQV36*p15VU`Ra*7r7dv47p{PbCmy@swoJqE zu|!t!oW~`A%la}mCeFWF3&LF`ebs#4$B`}WgcruD#YsmJc9T3yA5T^bLjZxORCvo^ zqMeJ$%m{2r@QWWz$r}`i!7e5cRu8OBz>2Zsjd{vM&3s%zkIzFfiA$?oM%=>@7A~MT zkZ!?SmC{q0Uy@YFonr-&aW5Mz-yW(sz?lU!eqG`Y_Yn5iZ;Fw^y~3w5&U+C~TXcmc z+dBX9^HvRyvacC0T&)Hxk5{?bo#nuSHnEsd`Z%xWWT;1Gq<0(I8Pbvxz}pD+uk!{= zCx`RVnvMI1{2fmt5QCeaY0ue-A36l)_ggCR}O-ADs4@Zzc$E(%HnaiQOxu0nC zki4&Vba{Go5Ow{+SZln`ucS&9W(h`=xN15zAev1Bt;_z>LM?%ed}>Tp(crMbX_c7P zxOprbEiLp6>eO+I3cs!*wVZ?%-q$BGx7meMMW)&@mpT{~tI6?OGH65U#>KL?0zcP^ zk!{p0l`2mNSD`2Sd*BI|(_lw3%EC#*Ovu$^5y@)C)Fh6`N2EEYb>molnF(b2NM|i${*!GvRN0L zP?W`7jq9OQCep16>U?kl2MUPraCycagg!x&B7c&(PyMk`ep*!$Dm*-g8G5)W+v>LZ;D5DidSdqiqB@s!h(Hpuas=1ls|t;`27%}Ox&msz7m{*dIdbXP}URLU&Smf zVN$-tg*PJ_LwYG+Xs<02G_BBH2i7i61%w|0nM%22zfRG{lrW~J(z3>BNySfV^37~o zk>qBn*UwK=sm#=84Q)>jA&mR9>Sv6crJBNWV=r<`i(g10QxB?B;+RI{l~Q)9smvZD zjBRFZ%e(C#Xuw-W`_W`LbSR-S^1=7YTSzHcQ<36?#0?H~c64)Y&fPZeOQg|m?>1#_ zGG)EAR_tsm7Skp*#(SYsuH!y4_qe`ECjlSgnTRo&gFx!j88AH2$Tncp589Xu_MG34 zo>SkXwF+0fA}c3+oT^WEFDoo4j{sC5{vh?;gZUV`g)s6MZ^<#`UM1reBtj^8X*umN zT;CTj+vQVq*)*b@c_CwG!GXXa+8J?`a;wSh)@RZzVa*i(uq>kmhT|ChhPMkv35Ibx z`tDy#N;A5ptjn_vlZ!tsR=%I>)MQdm2-Dap#5c(j04>$qEL|+>Qi=8=co~`_W|<!>_Ff0 zNP7eC&6boVW6@7ygm+jAytPO9R;K9aD7U-HuqP{9hN-@4Nyw}$PGdYUi|BJ)$#vw8=hoV)`Im^d2ij`?<;rW#qV++1h0jKkM3MpBV?zlt2-kuCw83;7}5G!*X!|Oj@ zdn?P2h6&xnHs5X!A+-&S{K_6-RJF>ceXC)U1&3%Re<{V+yd%q)6?2R8dn#UV`SU|_ zF1f8M-ipFyoh|p0CBYN_CLWw^1-X@q)>@@RT!lpaB5%Qw zgy6XL^O2I5Wf40B%Js{e#zeU`_`^1XrCe}h{)iCKe%c)i+ogo;)Mt#(w|r~U)%`{9 z$iLHSQOXt&Bo8xV8J0JyJ;SQKlvZS8d08GC$TrO7wbZgqP}9655oyjNpSyc>hj(>} z-#yN*&I-b<4+f3%SP&>{=Ngk$_E4N6~t~xb# z6~0#oitwkv5Ra*nOQ_`-4&<}T6$*?V`o_Z-S88L5VQbFPvb6Ljk=-D{IQRBOWiZLm z{pWle9#~w;=)xMQ_wR^&Xiu13tYUU@l^^Cd{_S2 zLA3&nLkwfB40~uh|M2s~R_*6~pC7$DDQ!NH=4;s9dGUb*l*~#u&o`#R;lmE-=-sK_ zJ+QT*X$-~k~M;&{T((udlAW-+7zOB@=3)zx$SwJ~@xpaK~56 zJ--SU@=KG$#6Ua`!HZE2?RUJyL}Is<#Y}NTYHCH%mI7hR8oRTuZgeX7DGrBzJcslS zVTm2tog`kyb^0_IZ2BTsOU>21%HSpYcQl3GTA=+3IrBA!0&{wi0(l2Lae|CXOa5%%a#8LcnH8ncvxm5u zl2pf{x}l2<<}=C;9PnUfD!^vSQ8+x)mhvNoVXVrT`|aDNFAMx0==fvHq9@GWb0seI ziEvSxX+|3=4FBv38cGQoa_MvTAoi|g)eQ*CB;lKFq)2Vz&J77q4KzEyiuTNPzcnN=Q6f&cD1MzI-G+-)}(@OjuBWq^M`eCJ7tYe=+`o`||G4=UbE6k0dUMq36|a zF7=iPqCgWbu*k>br64E5-(LkInimb zN`dt-oVb;IA!by3KDb#1IK-MRtVT55i9q?!&F#!4eGB(~ti$pzhB%o8IPWt1mUvh=it$Ys@w=cN56s3YF`D2 z4uBGKJK1xF_JrUwXqMR@A^XG01l$hxj%Ws=k@B&u4#%`Z@yvQPPW#7nBgxzl%mwg- zISc~3L$86VE|ALt1>sXF@cN=cU<68VrCQYMG;}<$j3qB>GzS0$W)IEWK`S$hBbt|i zLgvdg_#-9)0nRfzDXU~479#MxpF*@7pD^Kv?g~YF$zw7Zr@5<=8yR2vn$M5M`gs_% zDx5C3cSlkM+&>&#@a&D}$n#hWb4p51VR$MjBC}EN0yN{4G`ws1TtZ83d|-ck*9)Ji zofzjfNjf5$t-g`WI`ZziE|U=)x{{igIJ2Tq=j5o+mVUnG3dpn?cL5Scf^AHv+UE>+8>O{I;;y_+0>(MPWnRHM2L zH-p>QlS>N=J?mu5^|?W8f^H)_u1mKodrMzCf-B5IdqLlq=%7t7UXnJ_pC}BqdafIm z8zMy;vi&JP&yuu7E>T)w-`XM&q&kR5G;nODOEP(QL6>}G;ZOSFi8Z|<%;mNeA-UwS z!QP^?CNrJ!oyzk4tQ0T&z%}>N1k7xdL*igTFfc|FOXT3|`3hrwbj>a8{JO~@`nCFQ zHI}j}%jNudaR!)(#?3kqQ+YJf5ly2?Dw@7LT5Dfw+juC9Q8&S}m?*ub2O5DgR(hU; z$we1bRu&$kU6{a4*LC+EQR?E8J4lA|0#ky^Sa;mv0ZMn_OkPh#Wh#sl=pRa{rHpDPTM2hniM$ zsCiG>oGF&ydp&su%Q7N=DtbJ~@>29f|D?{fn;_CCTHE*g((Y;1=!3f-tAti6;rM}O zRDcRXTsvuu%KMz3Yevb>qfG02hJ;VbF!mX*%BtMCbXduiu3k0d(lm`*ve(6-kA1-h z5^FF3@@2>`E1iww6f8{vC-4Vqlv#;3 zE@8u5h=KwSqP(_XppT+&GW_kkWghv1&44!&4N*vY4H@u`I$cW@YYf7jHG}9|ZLh`t zgzA?E17Hir0ZIIt=wQ+9qbE)B1E(OQW`O$PxJUnGU6cg4XYQk|m6YfVJ;0HC72?Sft*9Q+8Qa-mm9$*67xi^O$2>7r9AHvwCu2Zh9_(#= zh!2D47SrnolUh8AS-8O+1)N_wm7%C&BOjN|hA*@z^~GG%j228maZ&~WFG~Um&+|H} z-B9tqY$BiIxfb;BfLmoGR=J!ry-E9(gfP;+d`CawnS~OM($4tJ zk5nr?;we9of~ss6B%?~Ebrl$yN?=XUfHI6iN)K%oxwj3HT?|=Y$P#6#ggL2aYfDYP zG3)m*&tf}U%YyEX*$JN}lW|{d$6-VBwDH}eVVOGI3L$D-w@-Ft%^yG7R5B(}5K@{}4Z?bEwvWGH4Fd(e;JsOpPwW1A`^ z0SoSOa_E;)Iw`+Oo601zu%Ojp$+|l{d2hUyT4U2TfMt0Dzp)9!QmvB=DTY8K2{@`k z9fOaTnKkC5p(*TVV^-07wvCbR$ecZbbm5bcpId>U73xy+)E~Na?Tb`V`#E<8SF;=0 zON?=K-j*i2Xntn=nxBhG#^C$@cA^PWoYSA6Y&{k}FW$YV5Mbf2`<}?UJI^yD=v_$+ zX4D4+sjfmGlV~}B;LW|Oj&FAzB=9#uwM~8OPq@P06q8-xs5aD?g!n8x+Irt{qxS$r z9>F1shv*dOmlNlXjVs$8=43!4y^jM(|7wM2*FT7;<_;4>w_y>GA2OjoQf_lfVdQ8Y zu@&b@H5r(}?P?s25#6Ypr!Yejn-5_GvpK|>zd>l}HF$mafcI@=Wv^d{+fxm!F>Yjr zd`CK<leaz?Dtz$1?Sa-d z-aC;s{(|b4%HK?NFfP{gmj&)=1{^-1G1i}E_ipDacMR5Q8-*3})PJKqdZ?GqBy^qE zS6w*@xeDGwZxqZ_c5Zzxp1j5$B`{*eev(qzySVKV66D2pkg?P+)1&dCSGbrN>}LeWNyDb>s!|&7++MJYyZ??EDo{%hadh0&8ge=h+&DGs?w{ znWQ)?9Sn%$04mpnC8{qUUUal>i&Y*EJ#9Pw^1ZEq!}%>A)-p%PS^3UA6{+T_ zjfq1o&aCQE;H1+cP*==q|=gaqVruv6G zXH60NR4>u80uqdebqvw&o4)x(dGGwiK=$&G0R?bZzi-8;Kr-u`Egh3RYu$tbvtLj0 zkP<|Hs{xM!J<;6hV)k1(0;|E?ADePqjIyb3y-Mf>_Lw<#jz8b2EZ8 zF`G1U1{|CP!I^l=b*m)QEZ@fXy|r z^qsyrYL{DsY?iyEoBec1s$k<>$yG2rGF|~ee@04mw$xLn$ueKde_7tj#*FUFu|W>QWO# zn#M`K822M(t4YH{Ps1)j^4sR}yXby5>HV708@BK&(m)0vCv#miA=p7B2Y(jXWdW93 zC(B$!o89D}y~-6^r9ob#9wW^7R&yk5*B($<$nR~*Z5w}HK#J4nNwIGy0fN2vgUn@# zWN>7xWoe%#=sge%veFM^iqthAO?6uUJ{0T~C;=8L%E(t3${bLxSjZ@G)2j66sVK>? z%uBIMcdPE^seYhkS+{08-Oj7SP+LS-|FW%0l&|`UR<_DmF3-x7ZaKJXRUVd?sGfgm z5~wqlr|Uwe7Yt+@>0$NF*AJ#Mh@{i6=wTg@HmpE5%-Ing@MkXbHz=^tZ@6jDmZxwl z5U9{iq#z}!fJWS@q~e553bxg|MQ=%O+ggs!R@Tj0)NNIQhJRf^iUJUg__L0n!_{}K z#?Xn>uXc?>x|jncZFFrJJ#1~I=;LVDqcwmwU2+z&-JMR|aNa=pH0Cqva1WBq>q+a_ z`RSIJg?Dl6{73zbVr`h)WP!^w=Hmf+PUvh!{%-7%^ktHQifH)OXkzg;hKn}cj4`K0 z%5q;oQz5D_CqGwyePa;7f{08l?>Qxg5IW{n2S8)Bw)WD5yn z9PbW%as$2BhC~H~F6!uee>b3Q)R`B4S79{uwBNOXpt7~plXX^7`Q5R>eqUdBe^>^qZ0UaV7x z;WZ{TOxyJ=BC5S?P)HH%qY~=i%lxoFE}bZ_6#2}(ih)!=Bx;t?sqP&ro#meQ)nxOT zt+|`uBlOaa4=gW(A;I`1%r}dwzgx3eOPV5l)%Xg?)@A*3@{ItJY@GCl!nPzcE0SXK zN&LgeBgXFNlJ|F6qsQbdDu}d`izK^tqZ0dyQ-jOgbX{-lxsTfq9Xr09EgM~Rvh$(y zQYsxA!vH$HV%BFsSLhmlq5?O!gWGqz$pJ*1nBM!aG{iD_c41{bzN5+Lt98I+w%Q-| zh0aMq%AyAHyu?0YQhQ!k3IBBG`RuDq7ypcN#s@8qi(hu>@A}Pcvaaryuli$J70`F$ zGX`@**{Y;~$z!SqDlFmMo9eRg>*^-C!r(JqSs}Ri5vB_-JY?4-x?j~i_Da(EyeM?B zXvDC>;OpLS!<+IC_AmY)b$9*MR=_QMK0pE_SO~$P4Ix0#;?~ka@Zhe+ixr2KmeLm2 z6t`l<-Q9}2yOkC#4n+%9hUdBV&fK|k*IhGfX3d|FAM#!Mth3Ml^s>9Oqdg8eBa&P` z9P=K{R~&@|Rk3p#*|HmA*bPg*J}C0H{_A3Qr_iWjbf$*d?KsvL&mh!r(MOc*+uE2K zzv7t!#iknGphEBKFBMmB?p-SYLon<=Fi%4y3#@Iqeqt(C3%>nua;U`9{X0i z)ETg>#>M ztG5r1LNrrCY*>1ufTv3HH%3=hTZ)8z#-~a;!qp0r)$qo-GnXxRAPQSjMdK=vWO{dz zKKIA#)01}s;8IphOHN~#6-^Qo;5YliXGNF!O6j(dr+@QX=!4Y#998t?bT94&6=!`O z-TZS_NzBW}V&MMMtr~gn%r7WCKhZdED3SddMidpT(V2X0QP`A3TNh@bz}N^H}h zAhAqNG-(6YP*jX@Q{4>LfQXDiLef}PG`QvnsEFA*Is9&@d?Lin{Vgzy49z@{80Ogp zoWApE`_UsIImJ4q-V+i##kF!BOr0z~0*^Ulncekbb5|}6Z&;tl^o=~;>c^11&%KO) zX$=sjD5_K?^JRe^*x5kxG6Dr6tnaU~U&dayOlI+sS zmY9;wL8zwL|QkQpKmfZ3^@Gy31w*ZOkP5J z1`*#m3hsLpvh=sWls1Z%IpxuspBn-g#v{SF>+vf3yY(b)Hq zCf;qTn>Cz7^*<7Fu6>_g*HMpLozYW{j&lcVI2{zujBx(?&Hv3eYc>*w_h*b%Y9vzg za&|;QK+4IfE!aZJg#OPghgff@lL`I%hIPfFS~*@-WE6z%(=u409MZ0r~hTi*yGx4txP)7AW$8Oxzm zU)`Q~9eVdnG81@AqI6W*eo9fb&T-?(aT9X&=k(E|>z4M5+&`wCFUVydeW&6lzn{MP zan)(3Vef-=r0W90hxUeZ^!LjZS*5fP)zmG5>h7if%T3WgN$rZ$H_mD8TT~anKOm&x zQ1KXxE_^T$pFRa>DH8&wWw?cp{4wFQ0=BbFvDS*wcV$B05^*-l@f=zOy3KJ zpaKZ;*cj?Gjc=g{`?GvrBA17pB7b(@8)48wSgOEwAnYPjX<6<in&(yLZ|qyBHz!&s_mHqVSg5vJXwP`%{cW`?ly)^K%PL=1 z=1MA(_Rui*?I*k6X+L><+bstwp541>ty?-9rc?MbGepuHAi>xeI&cRCE zOfo`05?mRp$m0HTYgC>;sB@DA-&1vwI@MIw>Z3Mtn(Cvq#Kqp91p1(P$^vdmrue2( zbM9sDNb3wLl+$&W`=O$&-wmSngx(=hueb$USk+X?l(>^^#(OzTRJiKGVoE71%i4d( zO7N$_rbT9A$}0H2;$EFMvo7G2>Ty|K#0^v1a8EJDKicKZ;Ux)Eld_a*x>NG>&a+eL zE4>pUOVa5=)rA(3Ppd8qy5U{D4QG{#$_F_o<3F$~b&cd&AopqDnBcRI;HB16e(etU zoFWnB?-EtOkfc^lcM3eo(ERe?URN&0nc8rNpXXr8p}2g0`Dyi-{-=W+lHpp*D^d@U zonxMcAx^e^p&?hTw2HlxJ9)1bR$LA)^*@WfOmh+cwEMYs(N*ZiapB8E3sUH_ zQskzmnP(%cVq|lc+2vEDz_{V&JBj1#DWcc76kSWQw))u~hBhTBilMZLuUG6rZu2Ha zMsP&!)DP;qjn|33N_aIoK&5Bka?-8!v^C)zCn2+C~V`2X&{0R=&>{Gg=ytFBOM+xcQ6B zCZ0Ov^Iy_;=1L^I|Gsb#IIkc4wPydTgtZ-Zwh^l~v9v|K`A4zP`bJ9Yst7pxM`~SO zPsFf*&{xf#97I)B^vU|ttK!Q3rm|;l$#wP5)q3>m@{nD`MP8?W%?H#Ue<83J)}i}R zB_;L^NO%p8GDRB1$Ip7dHJsqHA+OR)Y{YW2h2Xt4T~?qxu~_y`>DK`3|R2chEcG8)BMo?7>=LNPM<3t5tkW zG1N)5Yt#cW4ibLMM=gQioY8J{o!d}km@`S*?iLrDpL{!;3_gPqEA4KI%H!j>w+1I4y;CHMkQ6^>~jdMmmJEVPeHP(WD#Zb5pN zIv7n3Q5Oiphxp1nuy02I>}@wH1=-{k&KcAZVL~`5YIPRgX>3)Tj8bqqn;~zhPC-;s zUA{;;=s*HG7Dx5L#KI=CA3X^t_n@+thGE1gr%=9gNONi>IC^+l%}oZTOq?zc&Jn}4 z2x}l!yUi(~pxt@mTtQ|hIxH7d`vn}rR#%G7DUHxnG9XnN3{aCVjx9yTBb>HAu{(xO z_$SOD4&`9{(Jzeu94B}D`K%AibiC0o^GIr#nst%sL93SD5h@dDVU@{RV#njABesIG zb6gN5wN2LpVAtHxJZ?z4z9+SoGyvXP8li^D?w+6RMPKi2Xayk)ayx;rDnx`EjSkYu zEB>jD5(I6jpK%#fphW_ayWx93r1tzQQoD6&Wm{MSDF4*tE_j&rT~}hgJSO2r89GKz z9j%psNqldVD`ajH#7*6&@J>)=7b^ze;r;gV307Wt|3y%oJrBH_-wZ9+)m9{Y&qoTm z9Jxi)T~FGXKvFeIB{f@=^!hAcAj3iJRcJkaxFdIbm5H*Uc+O}7Mvn4_4hAWcVjRY0 zpS!H*8)x;tku4ZrP_^;-CiCaqo-e<`;;z-B`GwTgQ8e5(9mHUV4@sNs7CXQN3E+&W zN_Q(vg z8&i!{$KIc(Un^?EMWP+p2{^CEl&bK(R;!(l__>dUJD=3J(*5C9P;M3jJ`l^L|ComE zhw4O!W^b|tOAipK$e-Q$l~1d95B8HcR{xA~4g~Ie)a;j+mE*Ic?eaDC_2b!>6dAkn zVn6?O$}@uDp@Bv)L&|uY=2bL8%pwm?O&N1JL?efv3gDTqkGgDSvCK6ZV5AR1j9pK|2*=(`L(2|f0T59f(4}gm@kaubi=S3e@|AS zA^Hn+1Aw7XgM-t4e(`QS{&iL^4`r29QJxHnHsZvZd>qXX3pm6t?o03nzebSDM2x9M zkoLq8+$~5{`RJx53!v|I6(H{-Y~}LhiOTP2#Gs#RN+sZ#8_`S62Xfzp2c6qVG5GB3 zWpwxe1}r3MKqM;Ehg8=7jvQCX07BT3RP+QXJ+vZ-p+W+BL(~YCMi4Owq7Pscykgsj zpKQ*J>~0?R)!~DfX#O(6p#blX~ zZ?N24#4v=*nImG{LV^(F4k}I62wi_xcr}3Q6q2uk?2iS>x`tWsKc0jxs5fkCoSw36kcca(#rh1$Xjbzu^uA!S(K(xV{G4*1i5N^=3DD05QN=NdK*8;MY%!F8 zZLQWxO%}*k=9fHoWdu?3HK+%$?&aMbGzPX!Y3>1JJg*{Ok~e>oXW6u|0j14%cx zQvorQQY9b|rWeUF3G9ZlT2>;~AOgdL9G0xuIMz%-Rt8s8aSd0w$6r-sk*FnA&h2MJ zex#}b@Z6KscF;~HiTw2vpyqZ+^W*-zDN4vWGz_=+P01=)BC)h02* zdq^;xpI=KzM1J~xCIu?&+r`QmZ}g@>Pn9J+n$#6vOwUv7B^A|7GzUcIH~)!Sud=}E z6WA*ui9}BcZ;Tj+HC24HM82nF@p&d@P|jvg_z4A_H-#9uHeoHF@IDntmH>2b^82Wc z+p&Wugoq6pe7{)e;aATYH}svCI8l$1_d&Z4kEq!4Kn`BEL5M*#-0$6_8(0=!(xKpy zJc@MZT!tlK2$r>-RKff!Kt-Q(+s~PcD2GtPs%ecI4=+m8VTkgsXV6W8#a+F73HF@C zJ)w_nb16WD77vIlkrxW?bweR#T}~Y0Hg(xP!)n69?2E(zW3bCOI5eiTJ+4fSJnjj~ z{v{@u*P{+weo=S!j>T)dp8TW%7(kK-NZ{d?$k{Dr;@d@8eqbM7cdN*{2Gc7evtSlY zf<&%OJYx)@?{g3ucwB7n!DDwc%^L(PZQxFr9!&y0EHS$x-wBraQtPEdqbX-jLg!2` z4i^?q-ABsfb+AyN+J#hwM7ZHn&$yQy2ct$&qB3}Y!)3Fp-+AOE<^Vc;yX!qrv)gbu zHwG7xV_?GJkeR@9N}y9m^vak(J66Q#B{)U(*7w7C0?v&AWxn1L%*^=Lk7D@8T2FT^n=i051y*(hqME+wdu z-)T}-g0!F}R;OXX@uWV#v<6TAz4dhiZ4v&#FQ)_T0HSu!L_@XAu6TJq1SB&DCpj4`0|z2I)U4Rz*Rmo~%cHzzCrg#)ROdrPBH=j^&U2Ppmn+2QK>X z=&2(g?3#sII~#;qbrMVPKn1-UT#n}b;P@#~kmwt(#9DU!73BQ86_M#}*O)TVtnrcs zRp*iy??|z{dbu;Vr>U^dpOHjtD0y@9qt-ctoG?buJ%TyBj`&0K68;8R@gK6jLVYsh$dw^A*-n@$FX#zscbdRFGtl%eJ;Wc!)a_C zsWD(-lac&6{d83I`%409idM|4PLyf+T{Yb|OotO}A!Xdo~Ssl!n z`Njg0YxbT75^pj|b#(f#T(WTHhS!bvTaqU-FHSMG3i>v|M(|l*`X+y&f@U1PkOu2j zRNiX)+z*CC7on8PnlpSdz3+YiUcUIi^DUyA9uy(7c(C4!@H`EqLb-ngh4kvAj9Ry? z>Z!r7uIk70c_T<#%*)h#6dFh@>HP%SJ?#;>6ENffCrF7iMpQXj z&$S?uIK>8?U4wm`J|vd0ay8y`GGIl&i_H!f6B}11`&5BjKhn@R8H4dqlIhIecYcxi z8r6`WKVu&dLzx9SH7ie%;_G`KI1_VxAnh(HH9!Q>%*~dM&5{*19+pgxmeVP_UaMt( zEpR;fHtifKjbCL=;Ux8ZtSBg)o(e!av&T_DU52pnT|Sz}^tj(d zBkBOrVd3!~P3tq0(utEQmcrxT^0C03RI-Z;A*%b^2W1TX9|GY6mk%N|JO^r#SE778 z;y!LZDBK6~_g?WyvL+#TL*FlYk$iBgwWqAozP92U0Y`G_IKx2Mb0svnhN%zpg3pBV z$7eU5lG6FSC7a=!v2*51SNu(nXJspHQl#(-L>In}fVSt&KZdqlFQ`Z@GSU%o+hOzb znj@GOWd`FzsNUUV(+SFo*EJ)rkk=mA#pTvU*;UaCE)L<&fOw}Z$*Y2g5*TMGt62%d z@2RgpKh|9Q{88*xZ0LjcA+&+|0Cb0;=a0o|k@IU-^^Dc4Kc7LFTw>p_-5jXN&jItP z_o=?HF}zu0`2r)OU-ys7zVqb~y;tDt9|FdbsJd=>y&h?@oK}K%wgA5^2j7Hy4>yc5 ze=^v;%L$8=4|zzKh{aSUm3-cR*z$RfIk;~jh_RM)T)}->AIUWtG)QO8m}3|D7jcL3 zemucj?|Z}%C5~4Pu?()5`pTeOVpj6#qzHnylT{JF3ii8(mrNcWfuViTlRnw5vYOuz z`&YTFT&q+$8#hNFTdxqS(Oh>&J|6QEQAB}UPtoR)%RH+cNkNuA4WFpnXZfQy%B_3a z?vIanI{^78c?zVwx2cM?nOT$7JHuxz>3V^(CivnXE;w}|Eq7MckBC%eoezO5E$s?9 zMF$^%myA@~3-dho%2Qn>-=l%sEIIP|Z*1P0Pd@E%hxwfcXI@>!D3W8`3n0PQ;jYAv zW2rBic;@;zJ{Q_17xLpPedQ~P@oBJBYrOaNPw~Cx`c;m3+|hamPjP6R$RhVn)XALc zl)t(TUXEW73It(zV2B7$zy}l4#Ng*4!Ol}|~Q9`6*rTKPoLE#WvBCKFFg29eBJ4n!Of@{7mp3@yr_ z=gZZqa^(Wu)ON@<8LpT8!2!KAiws3FD-=}N#XY970YqiA=XYjAW50hT-+fYnD$Qg(x)$LlldI>Oan;#cTucVul>ol~TU zZ!Cjg>PnWuG-hFzAq*~qmZ5jvpqD(^wQQ!tq}RMQ>?O*>OvB5bum`Jql`F(yl+jhO z%82)L23Uf3Mbj>DDMdZc;f#bBO;O3jSVvg;^|CS>Ol~G#f^8{JuBGcT@dX%N82@e_ z1e#Yfzze>sCn)-4%4B$~K0z}r2D9b^o08DNGfR}v!@hbL#NlenamBwG*C#?N^sYV7GmCZYG#oduj$Omz9&z(FntZYBfq(`B&Z zXyDW=&mjsh)!8#-)F;G47IO zcvhv}7T`3S$QWy>YmkO^Pr$*dUQz2xvR-Bu%0F)YGN!#&peLgP&4AJaD(ZK_l;u8( ze0VJ7o7-U(t@eD$_QSj9%Z`fs%+ESqO5PV{KeIKnyHFd5hfl{{R4s_iU6sO3|EBc% z_uw1(wdI2=@;n7!V#NU!0k&BfA6MZ?_b<+`#1uswU0&9_FFi1+383P*S(asZX_p(9 zvG-#y+otL%jsL~tG+kK7cvN}j;k+{M$w%kvJ8^2P3A)bD3c#-hx5gi~*3FAFJ-?hc zkAD4q*>&ReN5NzG)Rp^Qdg*l_vm^AU8Dr|3$J=QXHS*6dor=bvCz_)$5_c~iCOwY2 zh*2Yc^7bc*vJ&B9F8BLN4Jk*&(?P_&AYA0V{ew)N}gSHTh+Ls+4;$M!ie6 zFhwui8s@r(8S5UQTb4szX)g~_!hk93-nBpifIvDRo@6X7j1;EOc9Twtvr=VZ*hJo& zNq|IoImO@?RDmYj3L?$Z*BOh628)??<^2aF5MSst?8R4ZW~HPiruerQ)dG>FflggV&$N}p0ZLxtUfQE*q46#c(R=>!Wmeb9j>WN!0qp2k! zAKHr`3v2}iB7h*x(CBazKPb>`ycj5hNBKmZ=`Hox=~Ceh;_LLTOw9}rQ8=Y4q2pe% z;B=uJAuPf>n?`;?krwU}srgz(sqrTbFB?*hd**k6R&>N{9@jIoICL;7Zc8-l5bY+b z%6xPnCb0+_z=fw+h?M1M;RoSKsc=7K48IQJid4wNk$ll;)kVRbfmQ( zQn;27_byTe;6yJUfM${L%0|l1FiaV@ZEAqlCFDiEIb>^dmvdPnMIg%ssbuC?;I+Te z65?I&lucj4(wl7D#kHcgj3uCXYlIvzX~fF$_|5)<>K?Ra5z0+dIM5`Y_fyY)V-d;WY?9g;FWcT zLH3T>^$&mg_bxAZ?|GXbK&NdtRva7I_PmE=nAb9wLIs3!pV5W=M`x^HV7hVS}*UHkhpgzXm_ES>#j3?9%nmN9_moGYX zY1_O@@$#^~CUMKLPls9y;*yT?jpLJtE(?SQdkTQV4X;stF+nIMu@UVx1&IK^Z*LCx z49v=V)7Z2_usmxs6z*jJL(&c)l$eLT<4HwBhymY9ce{?o?(4gM;^QG}t+XG9OC;4m zT!TX6^N%3K#ht-Nj5=>i)QK}jKO_{e@Xn*`qABjG5>}tz@soJ@4d{hD1iP85J)Y{N z6BdA^A_z@_y+JaBT3I)gdD2j2O3FtBKrI~rbnva@=^aijL>kOr%ktsgG_?Vh%Y$dM zax9b*G%wlg131D0es!~T)ZAVZQrD;jUnwx#Xfx$$l2bQ=Ztvp(4ai9h$m0P_SU=OI z*q2}nQ&Ry?dVTlDZf24Kpmc;*I04fZwV8`B!|J*7cAT@RmUVWV_lr3LzAN8rJ%z;p zVEVj!xDFF23n;$>Qdt8fSy(utK`z9hiJe+-TS~eRVKODc({*0TCa`kV18#R~J2=o} z(jbN!&NGjIXwIS z#8OO)oQyg*?t`^ZK^SknV8CoV9{{TOM?eVxy^9r&uvn*VWHot{5HM7P8yUpW!1zn8 zxC*j?dIiKS*3!4uoX`+*JMC;jxhMPcP9PceZsG%}D1evq3j!dut;vPjQf45B%y zU?fPbj0eyPq}~^xY%KBv1$mhDG7`x^imjotdmOKYWXxwC@?JmzInX!n{b&^mG=aTV+b{6||FY0ZbAn=nLx0wpi^0 zKI6RCxfyX9d!JnqG1dS!jS1UBGCkC`dOZjFnGDFYu;NVwUV`G4q2}F$51TzKic%C- zH{}2L1Mu-_KcB%vj3n!{G1D-rCm1+!6V${X)3y7+wu=cRpZIkL`YM#kci@GIa^_cu z%$+@c6+!Bm7p_ILKxtX$^hrnwhrR6(*^!$o9xZTS4lsb-po)Q=8bNL^cmCc5i4{ERiElpBkd;6%DL?SS_m|!DXG)>ooY&dq zEcC<{auOSkSh}u?yFXt-1llk*Sz1ih7f!Hw5XNepCnWFH0)D_f;Q7iE2{!w2)XUVK zfo#<7LAM7JwX|Qb{tu(n&2EMSR6Kl8O^F^19SAB&d6fG{w)b<#UeZLyLau ziBII3X*P${+d_;_1wpEsAm_eUCVe5B#-LXPW%rZJ5A=khy~y_Ux_~wh5t)w(#vEokRQkpUx`=oWV(Xv;9Xk*g{lBY zl}9-XcMU6}>$Z)nd<*TUyqa$;qadMDg=0d9KcgmPumU^wP+p3QL{Tr9PC%62eu2(x zmsWJ1E?KrlF|tm%)Fz++_-VhwL#vwk7YqG*SRB$Ip^xQI^rm`ASI?NcK1fR!%iUnD z(y+p+=ra4JZ^lYy-m2ofPT^&lvz-8itynL({;45X_!-TOp49|F%h2{#x@$lORE?KF!J-tAmaLGmQ6zSOsT(=&2(fudK)858VVy@ zid&_g)qqiAnRO^;%U9BcwiqL}>`m4f?x)h=Kmn3gopnc{xggpLPui-Hw;rcb9o#Ln zwe@eO9?2!p4!2TC?!k?@V}@F*YD!x^jePvviWcZs)L3|f7@_qYsTY`g?#r0t5ed!8 zq1`9xFiYX)+Nhm7XunkHI39V(l|wttE!beySee*y8F@o%_UaKK4;{wj(QqWD>}$u# z!ADA-E~-&kIumx()!TBC7B3lT`9!C?52R^$+E$kBmeM|+v{Vhg>i%Zk-PB5(m)|Y= z6U+O6UaGFEFRhwpO0GPy2i4Zft=c8S(<@8L;);xbv$Si3Mm#iOI(fyJuacB+*=XZm z_Ty<7nJTsRAx#=pv8Gd>0**V|gVVoN;#j4{N;N4dt)o@DuX2-lOQ2ccd#{Hn=1CcH z+@aaERX|-e-8jAP4vV&JS^Ha_rqJ#_vF|d!87nUCH@Z9+kW%Q4l9WaKaRBWI(1Kz3`4lHKmIC@ea=1``EiKwX1MCIr|1E7d+D&_Mr(zx{g%#f zp>3`>m3&Hwv@gt|@^@YQT>b~A5z|DcQk=I%j&w8AuvB0ar*B*Brye7DKk@USB-NqM zhhwXzo#(9$1aZCAqy0GC_!VQHj?;6S^zlQLK9jP}Q>KoerPkkhCaxHp0HcGuzXsgW z+igSp!kxI&Ph~7eCqhRiDuqUl+IWSV+6l`icTAhLm?jcG)rSjD97THIwe_!&PT#H% z7>gLC{eHWwpoS=$X8+ywQ+8~GG;j36SnzibH(8GeuMW?<5ky=Z+r)QS0;RacWkdT1~~Nz)-8CL%pctEduh^P zXNrP4_4ajF^DFefIDC+9J-P84$(Yfk^LtQxbS~p)iE4C&O^Wbf{cT`aB>}_O?Ruz! zR4eK0nYJ|P3Z8D=pTliDYKOUq@gX?|&o~hSmRBTIc;z{A+3kHqWa&@h$z!VfrKiQwLf3 zcna_2F*D{sYV|;MRr1-wwc21N>Ey|u@#Djr@$W0N?=mIokF$z`$;2m2n3)gnTvzP+NZ1IA6u`!t;G`EfHm6x-2r~B z3&byN{h-m&{-;r=LA80JqvPgA4`g{ev(nhF`Ad_9{hK(XfL;$0KDkq|%*X=z^l0=bI9B8cRKj&1h*t&aD_Z8i%b| zCHCU2I91WTt$59U6NeHFZHvDqnLfXT(JVqZw^MAA9Jb%v7Zh)&IyLNVr@8fW?xcIo zJM3h<*e>45^!>iK^TCfWf(AyY%CVar=3{4{gARAcv2K^5d==WG^+S z25c1_)=rMs+tFIIvZb9jB%VER8aqCGx_qVo- z`Trh9BSObiQ5vWo)X~@-IyNzQ`|elY3FUDB;OT0~7a|J}?E!?hYnsJe1L^1i!3EOY zx`O30p%2W*he99B>VBS2dcvOaOeyt9FxQT=A9Tn=y)fKeiJ7--ppo2JZbUjHctxEH`_7)d8LVOOhos%-;DAafr~50zalx z1Sompe;pWIP(&c}Tg?t)x~KsX8|)(Yf%*b}Tl@}U@4j*`f}wcUe;Tp_sEYaDu=ra3 zEMo7uWXpak5_A{f8P>jc7!xW@iafcwSP*7Or3hpY&VeNl_OeT!hHK(BTEumODU?rN zu?;U#*Dgr^bv})>=rtwnK}#{jo#O0Oa~T!}`$bz$-?`!bXE0jmLMNfR_Ol$jXGR^jq_?3720m(P-#M)Uc+hephPo+WpZ7Vw8E zk6JODrwpnV2qq7W+De|kpTrdi7b=fA8lV4D9BLdIbMZM(TO%zLA5b3mNIg&ARV|cU z7#e@xa-MO5D}1n{JmIr^o_Rf5xYJ+MH1X!=`3C@5ku(wZpW+a)S`mhJcrrxtA{+Xy z=pW)xM8JM1%~+9w*zi=8&qXfc9r%$fRy$5#@FAO8G1g#sItdx%kAAk-)_@4+wa_g% zM#9y162pPV7lqPfj*WF$;Ous8Jn58Ftr_Zy0=_v@K-->9AKP59@nwmjS^|CT@LYw@ zWvK;Oso?;2z9#ju%wDb3cwuqIBOx<5^GhvR+ymG#Gsx!J~GTXv{=H4EPt7 z_BQ5>03HA%NajDq9L*2@pTvAy1t99VzcN%?`2UNT{~I6oA2IKVyxF0%`S+NA{B`9< z)%nku|GGXuSp8?r0fgwae~CFUd(rVl|cRlnUF%Lr}+21Oc1w|YG zm2%0V{_r0$e}Jd_zmK_5qO7*Q!`FBPv;QLIUMyYzRm{0|vw~81RsYV%l{ekSyrS*oaxHs%Wdm2x=^lmmP%_;ojN|9=#7MV`}MxPjAYADvy;^mF#pjgf1*Q8|G;|JR9L3;5i=^UT``e6W=L2AAfLlcs?Ob#CtI*N9%ksrNmKw zF|8_gbTOl;$a^`fYv6o2XJ}V`IdAHH^v{_8laKpDwnU+eg0eJ zGCD2Ii0i*sE*tZFejYY{`}^xZVt&oh^5(BW?a0jyfHVt0r1a026RT$7(++kL-o_k? z%K~yJbwP|z0_aAw2>%)LlRyM%HnE~oH!Sre2(6k8F&ONoX*mhz$7Pe+DfKWcpM;2y zW|Mml_T2e-avSp;XyJdOTv|b<^85IFZevcGOLx0eEtvX$E9M-^Ls;XpxRlX6_J4~x zY5u<`muCq@s`*?7|0(7|OCRv?@&BV;_<*|rVUX5;YS&;@c26k8pEQBEI_LiiVg3*L zl8BRLHk^uGg8=3a;E$2En9RIA+^Jg<$2nc7nTyT9)|brv#~?})3WJk8-_nS;Qz_sb zX(<2H=(ahW@lX2l={J2INL}TZ4nG2tJE~1p>pfvq+-5v+JX-xR|3P0q1;wrHDh!C8 zbE$gpgUzP|lmmfk(0U!5gZWz^tTW4LtjY7>%UElp>tGpGP6$1d^=bGZ8M&0Y=XLjo zybQ(!v)G@DLG?5HHh)|HF^Jx_>+Xj**Mo6pJqlELJF9o#E+bZ2Y07u#dp;$5XNP-a zUIrm*{R5oP8Hwkp+$I(i0CKK@>X?Y5C)t56_26#eTUY7Ty43>AS;qs;eXjlKr(R1|4CpOf9bZo41OmY0sFw3R2F#U@=~H~5Dh zkpa9#8nb~@d+=8-G%a^?@IUu!`UXN!;6(hX;&^xp0{~zLhJDqA+BnN(Wk(d_wQtIX%4{qBvJQWQnN(llw`w-_i$hsG>CQX$$A`^&%uMea<1@Air&$K8} zR^dT_UmIQ_e_5sjN;u^D;j##>pmomb3wO4v2hf}5K!|3kv!~nG|RyZ~Diu9`nS_=Nz zE?l-ly58c_88eR67mwm!+5MB8xga`E8wSBp zTD~Xw>`oTYhVs?sUgr1v_mX^m1|M0swU5t)$}5w&d~5bRb~v(eSIAy49d!DcsJf9p zIhI2HBoA*yG3A=teA65h=e(y9B9^P5| z9^CE#nD&TBf?q7~1&hmTXvf@1BJAcV1Opv>!QH;FFy4H4jDyhmN^wj`B%deuQ_d6*KCfP+SXP#J(Ari84J-6)E3$+<@$ zWl)pZ`g&0MhheWZaXGj2rF`)3T?5&0^05aOB9voJa%P{B>!N^?fk1APawCo4pgGn6 zgtCeJ`i75OVfmu-`14;v5glfYolexw%0Czv78a@7=F0_w25Q%qhx<4*q{@6%U?dy; zR$SQp)384+U)YBDp(piPJejjJ^yo7ssgO#XLs`y0+f~8iK#fl`H<%~ScFk$GTg?Xf zF(^#w% zO43D%0$K&5?7({X1lHsxO<-E`j4o~P6AE7r+{c-O^+47UCf|rVzgES>%dvh}crIgb zOJ5SJ?cQD?=YB?3D%aMX-YhIuNkZfG7z~cxgY5E1(#*b_Lk_l-h_pQy(Z%lKFUVcl zNj!R^BE|8Qs^tOo6ptiHj>P`R`W>tUy%w>e*rv@rkYIQ)+bAG!(y+_%T7*jqMof}M zr^(c>(PoJ=wn+()=~SF+XW_w6aldDv{+B`2pVKPuL^!v8{G{mnX#poeZ>koHG@=W| z4m&o6D)+HVs0P9YqX2Qz7c3!*tiwZr@1!as!79{r?{ zeze5n9QLCGWe;J2SuCF7&vI6`g(#-R!j0`zJ}uvPaPmHYM7fAzn2#O+8#-Q(i!#oX zB%g6af|i_FlRqhJJ_ynw6y&k|X!mK~_^M^Ge5i=L#>iSus0;lp z2FgkJ?qcjUd2ja^b6Lp3EbY$k$VO*s@H4*y#sjA7UbMP^e#56lEj53*4xMX(6Kf#@ zMUXl%!B`Q1AI_<20il8h@Q*N7bE?YV31+&~@V~Nb<9eErhwdS7=J&T-ZmKk(`Bp|+ zwLn8;(MHEdZ2q#_;5ViT@i?r$4I=4;o6lt#X6 zV0ruDJm!1J^<3lD=9<_8`rJS#Gy7Hr7F zs>SiR5i`v&oj7?NPV!grtaV}4ii%X+KR>OJdn@mftp0%5K(@jJTKe|kp0$ez7^07c z+%VzZRUFdyYY=S+0>GluMUruXVe_F60(%8OFiFm64b+zxDn|4F+<}-1VOBTfd;s=? zw@iXT#7m-($wm(7@t4*RrZwW5#w(2!d-zv;mily5!c!tlglIxHnJF2(EtM{n9R!p|7VEd0K9n0GSxYuxzd4Qi28#ZjRrma;Z%=9BmU0Oxcfcp2E zz(upt?kW_P1*{&E3wM1qt8v^A{~i8R=DRY6p6hlqf(JotvnxmYU>(dhI08`N?|}g| zpV zG;;%te)zeJTC4qsAS->AU`#gY6Sp23L)XLfQG3s6h1etIvX~88n{|y3r4Mzw1#~%j z<7eML3>_Q)bNp%*89o+p!(I~uK1)tU?DEM=%$i4e#9%ZD*MMS5GUSb(_{FXq11R!7 z@Xro&1l8vA!vYa615YU#8&<>)Ed zm4XLktRQPY9;b5|5-Pa?Dmi^oFj7{W>RL`XDbx@@bU6nVDl2f4ZC57ZpMeb34-haG z(M+?@En*eays_d>iwXPk{dIz2IL9{2tpWJHD%=r2D zO;LIXU_R8XC&i&yM1U?#z*3$eMqJ=7QZEgmZzjtrOX=I1?4YU*v90ncr+N8=A8*7C zs;w6rM5UDHFK~PN-!)!fx{2ykSUegCh_>NJSUL35V3(-`X@p#P@c9=Co(eB1D97j` zZgLss7A%iZ{1RPpaG2n-wm?RY2RIgp(3UlkW~;CcSO1Z)#tz;}2Bq*PzDhJOiE#x z1rnb6EY8S&F5tLl0a+@|32qpU!1#jxvHzW)~fFJd!M67;HwtqTB4(%k52oV z9vk-71S6M$3(9cNk7<2!!hp+NA`%8t17(KM&z`l-ym*=l;_8aH{5aWVRBNqh_hmi{ z#4)7sV`?J~v`sFwqbcfkgd(p|4slo!YG{!vuE{o$=;MaMEu%6JH|hsk=D(NXxDHTm z30e*gdQMZUd`f7RCc0t@urwzw7ym;g4zR*MUU3kutNML``2RR@`w%yjS4Ho`Y?j}< z31A&Pj?ybI$^p2~0Vt^>&&4?Xg%bUq6bBjP2`satg(TW6g7|-0;qO}==nGk;0<;$c z5~77S5tFk9fyK8V#!YrIV)w#9;O%o+pmo~E8rF(iYCeUSKFt)0^m6}d8m&e2N}R~i zQxdcipyWi=D;PJVht6zWuATx?2P2oJfI2#j@gjvPQfR8mK>X4Wp#U6@aA^)WjV`vO z$RDk82Yy^iD-N=692cd*$f@F0T%e0#MvG{^KP$wso5Xp)g48_=5duC|GN!lt;WTsU z2%?v?8P=`Qg0u|Y=i-1Iq9USOv(9&UGEi3QQflvp6B|H z+94=0*05!HiCa5tc?2|iBH_?bOAp5P=?wUY9$EAi@uZO~-WK9Gxsr6a;!z=rDPh{~ zxq{X8_~LX=(@EI@ZU~-wXzF>40eM+*oD#={A^ez0lnKD^he^aGYi%y3FuF z*_l1~Q0V$e;B1=sP;2^xWnub-z)pZ_UkB&}p@^_d`(;#n6|R#GeUg{qu2GRzXGrhT z4wF8K6>{B(t`g*u_E*R`?9+KS@cd346$g|zS%)Qrqt*2OWXfwto8Zw7aO7SeEB>J} zBz`+&@bwnR2+(i@Zm2AQb$l$5_sRY{&ZE8P5j{+RJsBdv9RnT7%e-K}^UyQK2}GXE z5wDVVrojo%4nzEDgWcuk@X_tVM#wuxzzBn9+DFeU0%%#B~bGlh7ZQ99A_(&nih(y?i0s?oaMfO03@zlkG zojL%BMrKydkJg?8q$VOLnH8h11%{>o<8G(KUnkTTr|U7N#Svz1as5rjLB+O!_rw6D z!1RI+V6k10aI^e6CkXm%MS;_eJ{b6#aX6L-%=QMppP0=(^a!pFlTPp+9;*n$)tS+fSkQEt=!C`b^n)wt&o;^>0qR=WM9Nylpq{t+c?_B^LR$zSftO z#p@8?(@eu%{)*NB26tI{Q7LExl76EmcQrhe&Y#Hk&63S0v@S%SR=ss9z>ftY5kps7 z*gm?xBci7DrR>r~i^N~3lEjicrK$c`%k8&Ci|4JFeP4{{xbko9TY4=hLyhEPtfNuL zI>)OpQOK8(t)F-orfCJWu1Tq+`$CrE!npSO^PH=+vlW03bO51yLHI129iXS%O*ckA^# zn~f?I*Pa9urOqo-mduejdH8FACcXGJZ1O`v-Y#n?BSB4nH^+mwcO(`oQ|UPhH|b3D zc?uQ9uvQFn7Sy$dfmkj(ng+*~k!o-j$&eO$InEV3yxq#Xyg57BwbWeZ!on>qHX6G-nPO|UfT05?$j6xAs&q*WUy*~+zZ>sZw>eDHdvt=xiez#7 zU4&|b=Inakyswb*6vimpmlQop;~ZCWRn+#S_I24twaY#R@5tBFV=q3& z8jE%5f2SdhBox?W;qMQ^lY|%G$l4V1`vhOM2;U#bO{a7R2StjWPcLm%o1Dp&o#%9D z#wVSLj8)_&o%@=cW1DUXd2Z!gpQ)Lg_u8FjB*`(ko>x%eRTKp<&7Y+Sp7)x5CwVPq zq&gcGz4T7yQJdY{Z8%yjyqpj{9{(qs;Jx$BWWolzsi=A^9DcMgf4SH={IDZtAi5`% zbHrVEdE9bk6Q;Cvr6SuelL1vhcz;zxbMtQ0+ob<$V|Q2c-_@PR+d!(Vzu0@jiu?aq zl~+aOi?~mYDEAVyRdN$g-%;Lf2$+wW-Vv!0=5ZgSvK}}xh z{C>lwfyW-RUZdpS{`BjD@b~9yq2H&47S`2hgp>Y$Kwq2Sb7t-Tb-DMC68HFA^!g_@ z?0Wa|_x0sj;-!7W&hrNtAQgs?5{it94zm|8MF>SlqoN?WE0Ku9pe2&_=lnJTB&TsT zUSBkqjwZ%31`cx!O+_#%Ne1zAp~)ms(N`Hyx?9W?5ZSd*pz$0`hl%(#YR9x#4dsY2 z_fTwb*=SXfq>}lNc+%?@P^SC(Ts)kOrV&~B2ERNpE*7Ac*N&0tT^slKT)n|4 z2mk#CqR_uJACAPLmMze~vm8&P6pQ+gzKjFl>30NaLI6lvXqNpwIFF|@l?ushScYB; zD{|bQu?z9vo~_Bk)$&z?16)pH+TNY^UkP;DEeUwFD$o7qcAK9OuzT8R_w_ueEf&3r zHQ`+@t@SbLETj;y-OcwQKW5qfLX=oipIFR|m#NTS0712A7T9nua zfZWQQ6R=ig?l($mV?PcR)f%5St#5iSlfJnL{caj&TM*o#a9!wiWNu^=UmD?F6hUDj zfG>3u_^haRAHjH*r6?;i<}R^Uy;>#T9@h*xY3yaufVae_(DV4o`EQ_K)5*NbqIMu<+fUQrpU0hMAK)PVZT}mx z=TA-6Hual9KRqw@L;fFq*<~5ej!iPpc%Ej7!T4{}l8#aI>mpkL>@4SqUJaJh7{(bT zV4G`K)oq*a*7&mTNW5tPVT3hZt-;i(!Z#uld?yW%csUuYv))~FSC>|Tk>IhXybvU( zDvuq@w6ypyWcElYljnL3I^#@ejAgc4cA4el0^cTqN%XqMoK`Rv5t~@y&V&YmP71!`$hwE#C3qq~4=mH8~NVFM4); zPaL!msWgXUMau_P>ra%PlZ0f(cxl`pj4y}yNUi*$ocG8A7%AQhe_!^37d&>=@S49c zB2Qen1Dj-pszsL3>-nM4I=UV3<0h0_y&UJV4hJY*!9v)QU;h2lrnkLD|lqxYdo6!=)TA`q@bLjh8$ zE1orxmYq+&?MO7MwR(cP8k`A`1LemMetAiv<&* zG=J)^`+eVNB`oxd(#9^wR0`6+ija4}d;0IQovq9mfa zbj#TTKwFMTf!QK?K!lG#CE1hTgqcieG9cu5Ij}|E;T}6$4Box-sf-T92EO*d@HnAi zB<{W~Y%xOKCSxCI5dh6;`r*zt%V5=QWVQEXv;GrRH6UVJ3Y*S1MFI|I@ErtC` zz+m69Q??P*%KMt31ISUpS=EuQS3nfXkN@_qh;%#!GMIZsb8#%c(T{w=7AaQ;{aqx7 ztSQZ&0;V{;hWhmvF^%THfP3hzp31uiZ(JvYY_D5%$L3Td4D-#4f%A@9Jzu{x`i(J% z6VVH9NpoaHKBVX>`qEqie<<`GElp-s%?$8%WEzpK!%f?v8@;+;Te8QTZLuE5ic(x4 ziunm7Z-oq(v%a=fyAaxB+x0Ao$h2^noUFL=7!3~+wReuWxcV3wRL|--hJA_E2%0H3 zI*&AJ4L>sp%1`egJ?@$?xpuAmkG|}*Wp8bmGBnCr6ZPfTiA?hu6EeNeBDP!_BV_k@ zTLKT3W~Z?NCtL_**QkI1tOBkv6&-vu5W3GNAomcEu(@9Fr9jH?iX){{erjr{a8|0F zDgj0IPkmXJieC#n$KmE@y(r8S9Wy1U!j^d1>!av~Q%ELR9rqr!7VjQi@KQ*OGw1*Y zGE5Na?>tsWzz}+*0Ek9j*vfvb3{37)qd5dVO8AMN&qWgXI`%*MQg4G3z+t!20|I0i zBti9!Xr|`N$<=hzGe%2yiAdVfG#OyYucj#lY5v>Ow{pVc-c)PrEFhdW$MWR!T2V&a zR5(T(i_x;)Wv6K=TQ8R|%J8g}Wj*VUBtUzQjz_w<<OQ3mE%3eEdxd6hj5mi($O zcY|HsN%EzNbi>Q>hTcRFJNc!~ai2!HZCiAFYjj5{E3C@FTvbz0TDhVkIMk)+ttdYN z<-=U~sS+|R$$X`1D949_9majuG!wV7H~IbP&L{_gUo=E(4Bk>*Of|J*VGT#cLSw1DT%SLJ$j2 zhD}L#u6hw?!F_!B{P7mjRh+-FqM(&_6hVuW#KCbAFT?nn=5~5evT1 zD|Q8LBU*~FS^`*+wQYx#sw%_-lZ-Cdgfg{%HVnM~(MfFu#osFXv|3XBx#7?C#D{-R zA1pWVuho8|3<3xSdxsjoS{5M%anWlH?imht02)sf^HH6}d&CD3+6FO32emA+`^5*a zq~5&U$iTrEqC&{P)*isGz`&m!Bz&bW6EH9H22N?ZWZvHX zpWGlWyM`ad8JByOpV4{*&g(5TNzx|i5W6Jb0ReKB&}32|2-5bxiEm1Jd&i-;!3(S# z;NuyUl9q<$V)WsopNvSv8^x0(43P@QwXBPGxs%E&kE$GvstONCuJFR2M=+H{JbsG< zEF{H%JQ@^yKjeqXFr?Ko#te8ySzb%J22=`E#*K_oeH^4X=p*ySKxq^D=)iCI zN?-mNf&`823N?ua;rc+hfAWu&YRTM6bs&YOue*=)91y5mk9)u-01=D^4{baYxU33N ziQ(-^1?}Du?LHK#RLufLj1xhtatO289_bl3;mLH{7>P?6yayw0j|0KllaclPr#+)` z3T$8V;#pV6w7-kMQ)5J#4O+~tCzBp0`^#nBmBi?^B}8EbX~I(~FTA0DCbPV!vLmK) z{)fKIYg6Fu9q6%dG-7EnO(mjF{oE`5sajx=s&}efT5;!MAi=pmO(VbHF#}^HUQ&9h zqHVfPxu-OA8m&OS{&D)#BY(RF;!s^tHBZcOE(apnOjIt%nN>{3QCu|?+@6|M9ih}T zI@8<6Mfe*nBS6V`i07kF4on@88jw`#5d+|uDJU!4$0OI;5-D1mnW~sY$XELK65Br- z%TJ^9$|xdAO36KtvZhY&b63vI4oz#%eVJuV<&1m&Hd8l3Na)p8Vjc5bM}R_20$Y>&G znn7!wkxW=Xl2Py3R2=bd2Kp?b$gm>K#UBThTtxgwUrN`qN0dq&JI-p8PGb@-;bP&V zy`4h8W7Ff*z_VE*Dog?GWU-=Y5LYgdRpP8qOZB?T4(&6beJrHd6v+HosL-+meXBXj zFW#8OM2gQgMWI$m(NF54=~TvEzpil7vdl6^_3XL4RZ&Fxon+}^nTA$tx`2O*Lt-Fr z8vb%Pb;TgwpU03?UQbZC664HxGu_e=zQT39BHAv2O9ee6{*l4k#?%N{N)lkGR;8u`MKQ#T87k*gvYd-(sKbDt2RUK<>Hx{L537XK z7J>vR#?Z@;58l>8N!bPqmq}|DIiUlRACsnIRmo`dWY%=AB;VYD1susnIianbP=kCT zcbR;|xT4U(*IF#{YJ)E-F#sl+H#mVw$arA?zx85FdPDeib3 zcCop3q-bu4k;}i_8?=Ed(

V}QjxgVr8eoBr|(%R(#03@Pk8BbBKWQvglebm-T5 ziH$fe)VD4aGZyQ1K5w4{^=>SSPvamquf_ zDUidsQaoE(Z&|R=3L_6U8yI6^bv_@x0tOP#`Z^ZBe_(j9?s?j%$H~ zhE~>-ugHf1zejhmpt>YudvJ8^1D;;kX7PF^S)R(~$k+}r6R+hqi`}Ra-f{@6UMgHi zi`5W}CI1a(+Xtql0zW#g-zgy4Pm{5cFrU86DJEtWEt0W;Nrjb|8y$;wh8S z(yjcmTFK&M3C0zAooqzwr|moI<&7kUL-*l?ln90UZ{DkuWcI)DQTyGz$*Dpz97DE^ zbU;L;L4PiGt2lM*n2{>HgzuaE$LE0Zz1ksOI-w3G6DFR2fixBG;Xy)2FV4iI{vpzN z`WwtPZQ(=4BIWC65kf}AMsGzl>p`}TNj6?t4l0WzOf;5V6E{o~IOlG5a^)efEYF8a ztY0}&D>%}3CF%SWZTv-v>9Da9q|rZTR;PoBPwQ<+TVK5LaT$HT$y7~I*QK`QG(hKt zAWK3Yo7!t}_hCVs5cOXlmy8(rBx zPOS{|@G*+Foh$fbf~85YBO6!YjAEL&O6_AS-ATjHSX_aYy?0zaBm9|7)}1x6QR!M8 zD?$m%amHvPY4*0eBBF*fF&$k;7Tz;n7FO1}c7XEZOisZMy%}F7-w&?G#X$^<|3f$-+9w{98;GoA4=14ouZ%~D?{DMNebM~n;>7MQeskF7#48``uBCj2Rl&qZIPe!WMJp>d2e>#06RwQx}}ibi}clE^j*gYp`t2PaI%*P#0a`#+IuY+Z^& zTen}K)1?MV2MHKk1y#yqx%=8UYZM7h;(#&e_i+4d~rZ64k%(~Adme_1~5ohKU$XF zNjC&hdM`ppKU!y<5C*ofZ!ZDRWFV7vi%jJT@l6TSGmB>RBNr$9lkRYL^kl0s(&_dEs`I;qLJTq!Cku7VtrDy2ybaR!-#9Nr?rC^%t4KPRZ zRfa;ST2f1FQz20VOFMM&aRsJbCV@lIrpQ638llpc_jj@hJRX57h8*j_VId#kjelKu z@soXjFboBs&H0(*5I!15%IgNf@8vP z{277uyFL_r^A;^E6jI)%Na?x45ZiG7u+8OKhfr^gBCU%o@0k*~?=z+-qr|D7%J4#3 zgA+Iu9ASt@;2>{=*Kzk_$rFQBZ`+&(Y8`aI7cvlt1Tfaux1#6KFOeePSsn?TsVlZ? zWhyu{a=*!wJ^rYw;lJEMuTj7F(L@$eF)~Hn6`ibFRgr-sE%gmycV)Vwyg-GNz%*H9 zV)sQ4^QXRFznGhb(1lo<$KtZ`%qQupSj=ayzdD=G3)Yde5FkJ(yw``3L3r{hC=s2z z9cwOKkkmESuA?ZWy-q?10;ubRi1xbkC=JEv-RC~?o368tPR(xVmzhi-u)`2`FTCu# zOB+mdJg*s7Ntknt&?ty=oYblJ&YEU;T+1v11YVBBdKuF)_P~3GPI|)otAE8}il#{Ym{S0r{a8vX(r33$ zJs|RP=N(++`M~OHi2Nsx3Oni?UjY*>UFxiF(JgQ*_A-#a>r})pN{q$wjo$O{wuoC4 z-{rx#n&@nDt~b0rpY!n&pSg)GQy{_)7KE9y(%BB|k+#A#WGgk}ZyW6cG%*g$_VrW$ z%4m2@DehQg>B*(4yZa$kfRX&d>$iPgPq2QIBExHXL~WCjiGi=RlK~Q9T%I1c%;p{y zK2t(auJj~p8U`uGX^pg&jMt6#MnhplU=znf{RqNb%Af>4XI+Y^Ri4ZG0@_R6CiqV&cwOd9=hzB%NjI$ICYoF2gL8RdW8Z zoN*#dFSzn?ejk^M!*yeyfSf@-PeDC=`r;7r_i4*J#Kq*=4eFTZ=m}|Lv?K(=QbN7- z1rQTXD8#`Yk>Hs-rYa!?qpd`YRxu@h+{-RGp%8>Xx-4huZ4;JIBO?(wb=Jk=DCD(| zv(r7FyWCdA+xKzwI%>!$sX2C%)Q*kQppOo{IZuqxkuTF>tQ46ms&CZ+i&G#I_Aeuc zRoV73MPX1kZl(6Cw+#^*%4oe{Yo2mN6<=vJ51T1m%g?~ZRN0qoyiJt5fWME~^r3dG zFAO=@J%fgtRBu8Yo2W|hcipk-#DW4ettt9#f%Z=n{qwH&Wa`L0NphtP1=Eh^aF{); zG<{=)?Xf&LnBwMMVNDm0 zWSv{QkzVm;OaA_MS_c#^cM|b7A4yb6o#6+%@O=p1WYDYJy)hK8~f#QklGaf`gtnI1-a1WNSlV z(KjPRm!fTk=zK8ZS7huD3K!^=ajw8b_i|Q0Pt~dJcz4!MPx>?ub6p0h3lrRIz9J@* z)clLXtn{gJI;OPjjSC%B+m+n@w~by6-#2MTSwz3LPvzJWZN)~cx33hw7Km^V5YLB? zRZ$n+)m$=cUKhody8TuZ7W+%(IU0}-uU1efI3tMn7`oo_66x->R?s2QC;oAE zQ4d3o!y6J6@$PKJ+`NhT74JZE9qlWrRgyHP{Otn6rl5=Phf8Z zLjeP!QW{6pYYB$-K~Y>YrDv-78a6;G?*|dDM3jpBf#aLlZKVKKP{m5{Cf>&A%p?w7 zoegq-lH1R&&ceOyDb#-50pSxkx7%;V{~!|U{j6G6EWYo^uVxwmN%w>*Y_DI?O|>J8D-gm6ytUF>B0t$IAxyDO>KRFE%H66jmrBc5;zsw0ZmK^%W~!jc38`lO9u# zMWDardd*-GyBHian+v zDqz#_Ib@K@IuzkGU753cMyogjkpWtV&H0$lf=bejl`=ENB}XIO?9r4+L(=7kcCU6M z=C~d zwtu`R;01x0?41oJ{5Fe4*vve_IRk>hedAzmR*Ge=Y zYcnDMNTUrNo;NGW0G9qWH$vVKE~Hto6&!0^lT19E05l)X(mzx>E_Bw8m7E89uQkLa_XjO4HH7wgXT2j>H$UZ^~ z(ISea5bta+n4i{Bx-!`ONZDCJkF8Lls?xCWI55*<)TLOcc381~NN_exHAxZ(ka%5k z=37gRlrfQAh&Uo@h(6kl&6JyT#I{Q1?{oPX7Mo0d=$=V5V%iWaApv%XLFg)h?;4Fr z2AAH|D3jy?A0Qmioh88BE#xBT42LO=`stj=y;|OGS4QS;$PIR}K0Pw1#+txFL_`nwxszs0Z#mb`4W>e!kUy%X4Cm#^Z_A z<7id>$kt~J`?Epx?>egAmEovQ7hq1)2RA~4{~ZQ>wH+EoEs@CbMV6)SuMWXx2qk+J zI*d)ys>9-{7ZVlNW1vTUgCt_Qo}HdnJdo_heT7XXg4f6QMP+WK?m1 zhtZzPF+H}iL<|Yz_LUF-aFHPqDv|j0?Cfo1;z^Cl<5}W~eexkg;qGNi^zZ@(jCi7&J^R2QYr-&9JSb|v}ga}Oc>{ajXNqL!Fl$^~80L_WBVBH+&lw@XC)#lde z16#&xWmAAz5~)?g7gd(I1SA^GqQHzM)hPSgFBHcuOwqSf7c%1s()?K1l2hUdwb9yF z?+vO=ontg4G5_Y!h=`bO&azyyx=7&CdZ}N9BwoyteEY^yJ9*8zH@-L1&d{IA~Z*3sHBRsmvOA9!iP60xg0nt@ZB^(XT3{-R}C8{l}Ep3*RZ zXZ=Tpt{L5JPn7*J4tt7g1EXECD`}X-oe(p2GIFS%GeCO2MRVr8My9?3WXRe4ZfrTG z_Az2=rsHB(Q>UIPqI;~qdkiRjiKT%UQg!$VIOr_pDIf8bne$>i&cH=>dmL+*?TD8- zLa`ofNj?F+8Ao)vi(5pLG9AJ@mX|(h$Gic_eL_ucI%P>w$axmyEIJpBd>IB&$n+jv-iIrTnM6?g>Yqv~NNuV~-!gyW zypdICY&1+EUXJ?RrVifrx#W#Hc!>^;@xpgJRIah> zIo6*(EJl^uUdkZWKBRGgQSQg}SEyAC@S4Ji>W8N{*D(@rW_&;KdNfgUTJ^IvcqO_l zQXDNRzR6O&a^m4iV;m)pP5C*DyzSd`nZeA+z8+;wf2RnPRlj#2L3wz8B`Y6|cNE1% z7tJ+ZC$6wNoIltoD}#+IlbC$f9@zczia>TdeDtPOlUUUZ%zi5NECDS`||L7;E^ZB zn99mTyEsa8`6TCDOTZAiie2Zigq+%^I>nF6KF0({#!(1j!m0F@Wmr_XS;z6xS-BqN zO1t4Cqp1mOSuBczncXegUTqaMdisxcfRctvC-j!4=w7*biHwDQ>)`PjnGQDkHV2Hx67|A^Nnt;F+OO8b$aaiObm z&S+8QL~U$H`_T%v!5T_I#2Vi}N2+b`Fx0jid zml&U72UgtMR!_Z7AFaI#TR#W4PG6)qf~I`_(R@!HuI8r>`yQ?lo~v1!e3tgU98x$y zAKv?ARV#Mncl5Qb`ybzZ_bFqd_Tj3vnsIQ8=L;q7if6#x`;)Kz)-dfvJ&AJZJ4bx( zknaPJj?H5JpZ>h42lC;<>^Gq8D8A&-Wd2yGadL$RF-~2Fv4_3!*0`&ca!%cTR=ZVN zB7Q@1H}3hzhA#8`$zt>*$7Z7B_^e|A2xL;-<9;^zV6ABq86 zvE+tjf0HFW@_YYuiizyTiV($s^5V)33mbB20vb#6^^r4k5`In^2&gMGH2(Jfs!+I| zY}6Ag@T>IgULlo0=qqdbZLLy^;RC%kc*?(KO`txR|B+CK05@0cDI@JF${nI7PhgPk z)}@KNrh!13rMG5?_0x^;GnJ984Dy8f1@YkMtw+tSj}MGmFC?r7O%Pr zF%RpPg7UNsmCv0MJw5TA746SGAb3x)9Ujt^vjr%i{9~fo)k^>QI~tkg-ZlTCzd{G7 z!o}yNspLV0pkFP`Tg9=u$?z5JCG4by&vuZBBB5UEzx=HYLKDgU28=xcG7HRCf*KAR zZroZ%SlQFeLb zkhN;gT>9xD=_Yi{ zsw&ZcKCzRk7zG_!br;9tKTN{E^qf;QuYEbpH>9w5PtW*IgOH2wJnPIWZ`w&O(c{Il zQZzbTpgj6_Zf15Q`)>yN&jF;OH)frwomp}DSq_}PZi~6gIRi(5kLnefuMt`XMm&b70&A|AXJJRQ7>{@`0Cc*=EhbHv?k+dV*69 zn0ZQ~O{*X5XANU#1^)aL6DRqPzLW?@!KKsgO0kfNegl!s;7_%bi6`d71Kzur55v%4 zzAOxQ(5X;rRyqkV&Xgh&D<};U%rQBbhpa)zLHckcm4PlnCeP(w9a=^j?%3=9SfWq` zj6Q_*v^mJWRt(vG>B)pU>3uRAiXs%sayDqSTdLCeoaJKFsaH%#KuXNA)8JKy4s`eV zG*lMMjd)_XdTlfkjZ3fF`@iVR<8g#Cs$NES+pSp>6Q*6~TyKY!YK>~$zC0hNwNDlk zzDD{r&Jk@cr(gT>{oM8jLQ#lC3;c(cfI?DNES_EuMLa@wSuHkNE|C)sj;=j;uh9iw zq*ctr<##DZY;&#BZYy-ZQ1ik$OVd@s%rctWjW95QvrVGWFTBdp~7&-7~)r-s~yA>Fo2Wh|@=EEBg#geV?|O`Ik! zS%eHvI~zS5U} z9m_Fpcoe7Lm?@bIPuDoSs62Fu0S|XIpSzW5MV?To68CrNW#HmU-G6WCFNyRj16$ixdz9BwjI6F4Sh@mbfly_Qt;c6{i(OgBk;g0tMEp=F4>XC0Kx;> zj_GHxOn>(rS9){7!CmM^R3mj)|DXY8>>5nmDNj{3Jg>}k-7GiBx8b;84e?J=2=mp6 zS;9!45Tl8WG02zz9{=ZhpHQpE?Q6P{-6qi&NJQMMTh$9RkK> zh2*qb$Cj6DU8|Ro(BcD2aE?7F=qn6MS$`46WYqBb5$G1NQLLRWDX{-XUlMcemwp`e z?1_4a(i94|gXN5WVIKDc?}%NsTgV0sB$aSXShKsu%SeFlj`+HtE%Wfltf>eOOBD@ImCUXFOxA73Ca!e ziV31dSTEJI9WG{J9DGd|f1EUn4_E2}C)vqq9RxLCoBz6W3YQ`#7z`IjcSdnoV_lj*lJ)PkqQ3sI(ge4XoPX<-|4t9wfyEY__$d! zgugH8`K`m6vv}?uf3%&+aOPiJEa4DRyu`mQrS zAumqp6(FUC*?uW@X?Bzu+|(Om%W6(kQCIv9)!~2ft!RC3(_ofQu;u7Lk8ZWE5SVbU_j@v07%Wk%G5oNG6I)gXVMWD? z9><}rdEyUhsk1L7H#t}BxaZwU~55OnBMwiB~bkTed&HoxzZ)u5z zYpIK;Wb!hf-Tx#qqj8&=u?z+3peTtad!oXDDK%f)hfNyXy_olN>a!S7f6S27TZf=N zw}aVYo5cBfapaGFs9NNF6VFp@{Q4SB{mnY*i82iO-Iz1R>f3CfJUcKKm8|#Yf?^m` zJg(1KFKzG2!{+JU1cDOq8Hvr)EXp~RfyA5u2`yay)^_$Mw)He7>Bv}Dnm{dj8x8uT zagZ5>EoZVon_MiX1T17@{m#`;ByH4;@XuZeYK|77#H}3flb*29`Vev{k;46oH72z* z1{)zyRC-BVD2^UDAuG;ovqy*Z)F0~8$Ye29;Gp6r*keaE$pHKM6%f}jlu3A-6nv=% z&i*yAN!apwo`{pywAKX@Xd6I9LkixXII zOh$7a8i&v3f)zsTJ||u{hrTJ;w=4w4LE6pmtLMaKemVIh{khP6c%H=n&_1doVi|62 z2}zx7FQ2MQq3d+mMU3_Ivm!_>-1ZMzk8~Qcpz_LXjR(ZIC~9i6;Cv?p~9{(%aAeFYL3kJ}gP8Ypw zEEV~BM;3z7QD4IypTC7A5W|lHH~9R&C*i>MKZ6sJep39zcE9g>+~t%IH#0nZd`**F zI{rsriq(vNlG)CNHqC@{`~f^SP%9>x>>$#s^656DdAFmu z(Er%p`S&V3Vr!6SEiPlLR=qW2BUihKHu|mFk{I{%A@zjN^R@Dlfu~Dl7$uv@@ZYEA z;=dz*ilE+lZY?qdYZlZ%j$^wz!@gp_&z*^Xf(~MS98iCF(L(O-BCPKtSti~;+wT@pep{g_NU&6|e zl(@=K1V(~x89{tB&H8bIcp*mo$HKjpYN9Oj!1{zVEB4U_c0go%mkS`-axmrkL&iJ` zAtq|2<=LYQ%0?5`&LV___DkR>AfZw%LKYnWDEeiM*AWTM2$4vr49c^?Fm+h{MX%|o zUA{AYRyr;_T#J{r{h~!+1DcJ}>4=xv-EwqeUaqpS!2^{cOi7ddbI2xGQ*<|2 z2F-+@)ST7b6>BkJ!qNwrB}DWpW~L6NWEDU?1#L%5d`0zO^9iUwgSltwNKV8cgAG2i zvfa@ojl4`dyez~KJ7H@T2RYVptBG|;JC59hlVYqH>s^(XCni!WYY6|j`RsU<@v9WO znA#up=0(ofvA*oGI+JOb)J&$}5)-L1WYAxpo>z|E{fvxNBgWfOHUg7?W*(x81!1_R zW?V+rV1wGZQ@r)0X;;ILio{40e@)qA2p_8gY|Va@Nidys1x2Vm12c8)f5k2p z-5^;UI3aVjO>5D*vDLh#6`w%qAD!dyNq)bl9Rc)<>t3y%-S0`Yzo znac$(iU^Lb2Y()4CBY-WO5eL@r+H}EOTqjyy)eO%_SvFx9yrp- z)k9G<@(t1ATHIbHs(Q8_NZK1uxf=q5Oo&jvLT~ z3pq#JmbI*{ZyIt(r(pFG$Zg%1)O61Cz;{mw?w7^mw;o74?CX`8NIN1@vf;g&aQszQ zHfzh6am0QzPtOemlmR4fQy93VS*Om~gIgpBz=u>^kb5m?^yT4E<0RKS6roK3txcRy zMF~4>52ncAe+q9bXTNYxgaJ#q;-RA{DEOG%Rbf}xdtJ*qE*8 z8=ED;%M zk@Eu%(?3iBH>QV@M-;Sg3wYBEHI*-$Dr(g{#fblhy|ZwLdfmSMFfd3e3`2ts-Hntr zgVa#c4N`)nG>V{fgLFtpcSx5?NVf=rSb&6}C?P4zJA>GsW1f4@eSiKBGwZw8+WT1_ zVwxL)`OPmC2py%M1nb7Ej0{UMRgl8LeN&~7*ZP;_m5Un~mj#-*OrL;P*rV-mCd>zl zbHFPqibF6~Rk!sS6<20f_NRr`y_~1*AC;ydDKncd^A*#w;GUj(4&HtA1hgA{xt8=} z3f#1z6&h>k9D8V$_4rh`Gaa?!Tlt)Qvc#IUviLi$o#1g^2-nNC+?%y89h12sa2aeU z!i}qP%Te(qGIj;}>znE1R_M*E!UZa5NWfOClk#{=<@*WgEuS6(*bsp%#p>{B*4X>5 z@>XdL(!G(^eOj(5G~1&x!Gz5u>0ro+{Y<^h53x6he(wv0cC57LEu2rMEV)g&408{v zIuX$}XvcW(v!D%m({pI3?ak5E0pN4`rYSuSfzy5&rI6O%O>aC_8KU+MQ%|5$K?ny| zFAe3uG5msdjUY(|;E;eJu7qr()KkaA7{AICR~0MBu}a3MmjYU4;@zf-7_>lowOqiI zMOMbRH!b#kyhx{vq-_y1+)DjOjUuSh6#MN}l5L~CJ_5GH>Z;pDg4v23Z8OIVpP{?) zUM!LWa-GpA<+e9GLtFMz z9KiO1@MC8bpW{ua8q+70I`3U;qv7_3H;B90PwEc0>3RS(t+N=}=&jrQ5*x7ghcr=1 z8Z!2+ou~z!1D$oZIxdsN*eex@6pNE%ESkqM5riZj^&zv>^J1=pn@#g13zfd-^KEhZu?(vdKBgD|4MA^Z24|gW#fd2oipVam69&7(E24RH=*@RGl@ zcZh`YN*eHcA1|=tlArfz6J(u>k=&}ZjCg99mWF%J`Lww$bz7Sj#gtZS_UQtn*mY9L zN`3Hxnw}(3sTPx-b;X}XIHJ*z=1lmqtG9$e_(f*+5kt{^%g-Vc2JgW(*d9MsffT87 zldG;XS)FgS^Hkb2#^&%mG2`W#p{|Z z6%k((Pl?{K%?OcVsgdV9&f5~#Udu+e98D8PdoA>7RvJvSTs4zSWz};QF++Qia|J_n&x#S@G4h~4Q=uO)0P=OyGtd#Xg*%WRWXq(h}!tFXnEm^?MlzO{pXbGHIr3~ zBrN8Y?hdlS0%gQ2WMo{jY3{OGl-<~`CRIqAcCI!j=xhSR5O>&U(CxHLTbHaAVTCiJ zIk^<7!Vp%!6(${A@!OLLg6LO*73hL5<$GS%ylzc+LLBWul;q)2p}|@)kQT**P30Ug zlS;W3vzX+zFvxx>n@c0sPM$11z_6e#tNOAL&f%8Bo^dJpwI$dNZ3|4;1Kns|hKb6x zqQEhGvo@9E(aCq`K&k|l!O9c*R=j)_G}Tvw?mf*=UEsOfhw&<2wTlsrzi2esg^7wR z`+;D#W)bfXC4nOom7I(1@Zlk4Ip36cUbF%vip{CP zJj|VKuu@@eBogZ7#bP$wKj-6h0{Rla;y~^-pI6sUs7k!yC3%gmv=kOee~-tMyXt(U zrY~!$0qCNThU6Rk`i*-CL)+87amt``LuGw~wb|vm4mzjpRRkzKnkodo@6N2kS^=r)Mg%dR(r@H z|22+M=YqxwkdPn(HyYa2rE*eD2us((HK-bamo3>dmfM^F-e#K&Ju}%L=n$fQHI!}3B)WI7 zT8L%6E@b>LKlTvNlw}tM-+Kxo` zkb2&oh%1iAjdol#%V=nSc;c+u4F7A#135{-Y0i=dpNSux*R^dA@f-_ry{F3N=|Qj| za0GDs(3R~l-1%1_$~Za|4Z5>A_m|k?l&c9&cyL06S+M%Ay;!*kwtw1bLB}*wR9&pV zWSk_>b#)%J89)SR@opNof6Ba=?0lyL??u1X^P8%152;@hS^>vwRF5fLb#x0gV{TWO zx824ZChMU~h#-v!$rc!eoW9+a)KS5BbCv?c;ro2JM|>xCrU zK1Y}65(<4UZoJSKx*)!J%25sc7Nge!__BMG4xiuL!sdU{i$Tsqf!tWqD5i@C;ec}c&29!GviBC$ z-eOS;hgCW~Gl%A?U(zr1y^ch~-to$3hR+EKPMM99pCFPH(89x;-sU?q=kK-gw-atM-Ts0NrJe^{_v2Ba9yZZi4z5 zK!6Lz((t8WvcpnC3;6YGZM6rq@0+Q_Si|m{0$leLWj+vJsFBEn6Wa8v@?;aEOX*3Cv-|R`Lo^NtVY4 zD2mZQ<120laR=*!DPc0{*zmx?Xu)l#Tqnc#9I)}afIZ`Qi$gkHhDzG$WU2&$@nOnI zw~Q41;}bLCL8=#U%yZI0rOk7*7?}_(HxN9rI{Oi~aP-0%8psQugf}8s5}ErIFvM9r zELdci-JxDemQA3zSjG}Y(#(;8K(@@N5)i5I1&BK^A#~4ns%Q%ZL%);#1qbqzM7K`4 zhiY0KOg>eaCOA`F2VZ#}bQ+C0Uger&Go=rH`1p%6_*USBT+9Q(HcdEO-B<0BR|P>a za4{We+JGffy^AeCD2T;PE*f^uOG%8JMGue0od6SwD_}aQ(!`di;vnh+IAEoCHDhnc zur0ZcLnDH`2v1jn#n=+gE)j(tB}SSQB|PSW&e9M-%3t4+b55m7)~E9p3k2g-ge4C( z@C*y{UEKqw%mH@I=nYgBAV0I5HmraJvxczG8{R!#&M9hST zt+m5$1+etoexOjKqH(>s3LVtr&2&Oi^0GumyNjywz=L{iwzJQvsRpWBPg^m2QC33} zTvT%oQrW7naF#+meZ-s%$kpLa!(m1s7E!uX{ijETRW^cPS65%RnsvEXbbE${|RMWiyFPAH> zpKSyKpLkQ{KN0VOW6;Rnr1cTt!NjHjXyU;AkNX=|Mu%tPWyQfVw1|ZSqeOvdVE`t6 zO-#LWJOFvPJ0r$aOZAu~6iu5!qg@}sn*$0OJ5Hy;S>}VloAks8$8aWV>hjQ?)M&gv z?0z=AJ=D@R8l4AA6sX#CTH5~dU_sVFZCZ~p033%?dWcb)C&13eizre`RGt22fLg|F zr%5Rwem!FELO5;GeeP^Xb!z^-ac)<9Bz2ON$K4WHM3VHxlK?E_!^;i_Tuhf$&9EWR zF!aX7^2mYB?cwCrFUG54MhDS1c(7>XZ=cwr@+TnC58%RTG{K1i_CzV*95cyJEe!W$ z%1iO)ZRhtOr#e8&!z;xrW)Qx12upCE=wOfKV7M+q?*a|1; zq{bepC3J+#oeqVd3p13_k5KySiMf+14s$M+78}_{S{~_vHfl9XZ{auVKoOomsv4)#+6OK>_pQJEOOGdTW;AF&k4ih+&X9y@)oi-mjxkk_bLe2nqvxhKq^*AK^AR!$M zoeJbygEy>WaePussL>FMdOSr%hw5K`IXT`Qu7n z6>j#IbSL&b;PyFoy%3$pDCL3%3#KB523~y12{WvLuuFsm;b0i>ZUk+Y_#76O>~#iD z79wio(G|2$wsU~?zHF&M+#y=Mu95w#)Fvciz}oXVh9~hJlXabKZM$pYT$)SB5+zEA zKms}i4CL9;%BV0;x6n&9hV;dFK?o{V5ug+N`UTR@*Jxh!0>>mVx2yo)$c=t z2gSnno&{qvzyRdUMdGTR!ZqoNS87smo0Hs={PG8bwhF=1L9E*9(*c}kJ<(Wt?r56N z1;n)U;TpH*9KTk}%e!96p(ESAO?ygnkaHkUPuV?zp;#%OzB~|<|s_s zuMJzL$6h}5bZCf6ag7yi@F@c8q=dDDSR#vNq6(LQj67)9={+oD){T7cX)py|NyX^` zQQG6Dkr;-On${j#e!8c+67;@m~-)xmO*!Rq+|Ng16vgZ?)L2l2Cx$5p7 z1J_wfH?qMN#^*~X>$Xy>h(!HxtM3Kpuz&DW*Fw~h$&XVGe?X8y^J1)o64Fj=ygVO4hu&$IHIz7OC zLH%*AH&aYMNQN7pqK)QGQ**A~Q)*HJjC}#Tu70RzSOz=Y8hw?~@Q|RfWLuFGOa%e= zWvNcZqgIeE1Q39r4SUkb7eh4stN^8$P6@E*424@OGqqwq@h}FB8CqQuPxd&`PA7l1 z_aEoVI1y-b z=+TN1-EAH8TUyNNyqGWrf76q2Zax)n2~#-c@MGE7Rb`@TOZaWAmV;{FWAGQy?vR6SQS?MgB*9<)#!r4TyPC}NYyfZ{H?E%Jmk zYrCdGa18{z)V#2L*?}H*n2p#XrQ*2dpt1Ce*Hhh-o&;RM3ZzwmB=cZPn8u46H9R>;0XMN2V3dS_4cbU>ph`D~4g(iC?!pheMmsP*K=^Vo z0vjkI!!MK-3AV|wi?$Pc_ACQR6CyF*OAyWn@ATSZ5t48Z^kBhPCk={*kR<--S|tlmn}pq z%^Xg1k$HpnVbGt~B!7GtK3S9eB!K=of}Wnoirs*2ApX)~F8QCmM`7hXV%Utb0gR6r3`}*I2um8OMlVd0nht9uI4KG4FcxmSL;L(D z5r7Zc#gZb^nIUIRM)g>BU!}NI=Y_d=#~^x;EOG2;yoqinOqW8%yu_>`-UvJf8xP1@ zWD4!YkS#R!vaV1&op+ItAuG9&eKIZf5N)K23_}LOIPytaj7Zsmk{qz-fuy;NRMxz75h8}UOEl8l!{U&9Z}nCT zB%yhmSjmsnzVULsV*Ea7X-ab$86E*Cn$Z0e+!2i_XQJ{QmnFuhFD5jkC^A|a-lE;t zsY7m_g2N*KZzhpxyxgdgFVRd5uuEhXDac$*t(BIRrMcMUE9$@icjh5bPALc)DWpWp zx1@`!Cvnz+L$0b&+AN-g3MV+2K|}m6goq}r3mKBrk!RSDvYUuN=LiEcNUnOP4!|#- zS3UBeg#VnaPlN)cv~(WwM?!NiQyWb{nhAzjD8ftuVK)+pw(3j>Q&-=~%1D(W$dqEP zlC`px7gA0#+PsL~s3%21QtFu@@QUY#X}QB$cvV&=9)C_krJNS&VO-3L6pt(+AUuM8 z8(|fG0V9=wfsb1IDhLe4p4%hrx>(VVX$Lzpu}ipF7(C`L;{4}yB4((6y_>Jw6* zZRi4w#IM2Kr=tldwW6F2#Eq1zHdq5f)8Qdviuo#zk6NzIS3p|x#no+v>m0Hz!)3J9 z2|Go2Iy))PwUdMz3Es0XBhPb~V=K%xzQ#vE@+jZ`X06op6bU*lo02y1@S%KA<92;d zGwY*M;_bZH#83UloYd9~u7y)rpKB*DXYxNXL=pj2KW^bqQ_DBzL#o|ePqnHKiMS~1 zQRr1CKuQlEClQl5M4%H^M6W|QCs^%60rt+YJZo$CCg1VMmILFtfUq24p=bW#tp-Aj zYFynV=UXf~DQ=}tqC^|uB91-AXx$q7r^*Is7 z<7MYrG?YL}8VS3z*>jbV=u5ol2e;C#B_Pf`G);`42={AkT4`!3H!v^XFg6k(MBa-# zblaqs%~BN`k|C}KGDhNF55j2i%a_4#G{m}3l1QL9$KExTUw@9O3=Yj4>4db5Uh@+o z0ML<_4*Dnb-=K1;u~@s-X(nvlnCH-Fa2!}dp_&F6Bs*vu&C$!8CNv;oP( znrYTFWio>0CR({~mN?an$e1TkC<61;S3w;Go`bPo*Y@XaUn5lM%FpXn zY`8V%$cZbEb~5J?>z-zqW4+I4{Qg!_O`&@U{bCrdg2%yK)8Z*gfoaW@#O6e06e8|* z^aEf=wVR`)VuW#Ejse5Pj^@eKB-y@#rlQwwP@Yj*Gr18UM?3Lel1!d_o6e$FX+;zn zp;By)kA=8b*M(P_ zge04U-y*#VnJ=M7;J0^PW_m(y)nL+HzW2!xNux~8;m*BNnf1>p2~vB{-h&Xp-Tjy= z0qPfTOtW@5)l6Aj@Fi<&9GAV@MeKlMdZ|dZkn$ATiTPaX{g}t>{5cni&RB8WNym57 ztH9YG z8hS=Rt(_=-Dbe5nvpfPk6F!s6QVi)^wL0UZLqP+up2>b)VSKAaA+UOkg$rB%ocF6( zJdBY`=Zn(t=MG*Ub;swuFGqCkkexFdx7@3WVK;jDTNe)vz^u<*aor${<^ppDMX!4d zMk(gnmp;6$xfx#%PMBZGIg?}kVzc;)24P^1gn7}bFx-&_Bto0InJe2Z(SbL}dGgU? zy1Aoogh_ZdiRtr+YKn+EKnq|}MP@tUnO#1R<4wkzx2NS2 zh4K3b?-H4YVI1|@%ODbE+LeZg<~%hzIIEnam?@vBH8iJMpjlx(H9GWE8h}aUO`T(7 z+*XDOzKoBJLDwpm(4O)7a`f|#I?G#krt+&^oNPF{+={0&vS830K+I)we`L|9J!F|N zEG;Y;%?oqVI$}bhGsgcQ-;D>5yD!ZKb5)B?9*nM7jFg<}%c4F+L%^$qXC0n{UG6Oh z&OCjYIkU7q)Of<0Q}^D6{gYdnC$jY(Y&t%>Tk%LXmpf;qG=Ju$!@PMHaoBqfhYc!8fiaI8?n~cm6lE(xVNt#)L1iCoo^my!9ltTW z+v^rrl@KnXX3t{^SxLqOhb07adX!yf8xBQIil6j-(FkD6al^tsX^Vc^0euYG7Qct- zc5(vu9G2yT9(VI#Kg8BbY@{?Hx}v6IKjf&c zCtMCb>~%*;s=M-z^wTbbV@XnSYc7tfny1sFoknk}=|*QZQgt(nn%AwYYTMi-R%h1l zlAaS+Xj668b-L$RHRwH|Dx+i>?sb~p)kyTE?uAz?YbV_+cA1Gg0NgVGD4-4F#13~X zl8j91YD%LQ77?q?4tMOI2H-yH#xS{^r~4^)?CkQ~gRZLLN1t-Xx~oebw|&eVd)Qr5 zHq)1KJZQgMZTal&9OZnyp4y71!&i;ElI7|u=kM)u$6h>Y@WMSqZd|?ixIL2XWbd__ z<(dAkG7}Gc1i(cy6BizL)#Do9c)iO^ym;2*4d^pwVjP+KUK9Yg01fsLGf|%8C}hG9 z#Y|K?orGj2o+1`hu%#<~3&4FGA~gLTfNMwwBT!W_L_>q40JvlzeHgK-kOzIFikcaN zC|tt^$sJQ7Pb0>Zy*m|Wyp(ea3Bc7%CpOGO0&pp4-Nk@#dIGw{v(tB>K(vwgv}7az z7fOJIg=8k8-SI;*6CbXb{#It9J&hvsr_97cV{YrG^HsPHu%B0tfi+u*ts?TRD^<^q zi=jPjt(%Wu+5zCMQiy?6`x9Q&x49q@ZWy@Q%t=lp1y_q#(8gw(2wq5^b_?6GEmIKoa`bbGqLLV<~Ny%#jc)G zTo>(^dnK<#1`Vj6dA%}XTKszTzVnOMYh!*~Z`MaK6$Lk*oZ)XF(aLynL*mU1u6nWl zzB3m^`)Dt0zu8)QvAs=GLWMR4`XOdwKP>0_n2FopU?!%KRJH$8%tS;v!?W<^!@> z1i*a|FLqpdAmZ}N4CY+`ZtcrV?vPwrQ|a56M_*42lz#s`@YR=j)$JN^IK9D~^a(CXse$L~?V{ z{g(@}wAge`4Be^8VkL6IkJemf&8uBHsG<}mN)Ovmm$#z9(HgNZAU)K=!Ck2wi2o55 z_WqBNr;l36)Vr=v8p>jPR+Xa|dH9OiZGd@>&E zR~YB4EuoktTK@{h`FBeEKZ?cujf`{C3tIC#jPswu;_|O_{1z4$`b_bz#Fw%GK45X7V|%lI zBNq3;*Cc-83K?_DMM9sz8^V{x!T|0Wr%Rw31!<1uSrvs*ib%$}ky81cmI9%fU~^+a zs*B1%Pj8-3&dYTBt6Bn{#Tj0rpO9by2p3~uWn2m%lR7|ZC?z`Diw~snp&PI8K^RJ5 z?_=5HsAb?TqQxsdX(La5^eznp04)+zh(Zy}62?`j1kFhdV53O~#0pu(WIXGmHZ?k^ zGd&<`MX$(x(JW6F{0+wW;FDXhN8Tndz%EP|1Ykdagy|B4kN`NWZ2&G7)yG4vC}1z0 zbfVPv!gSv%-v2NN{L7*CmlZD+EnJ0Q4+BqFAh6~vff%UWe*!tw#t{dDZjGde!cZV^ zF%q*+LEtP?QOKcoDq6$jFF@dym9wNl)~zhr9*29)W|GcM=guU%uKv8@{T&EAhzi{F zy&!O;;u$+8=RdD~_Fn^mTiMmh{~`#y+EQR|GT$I_s9k>x)5UGV-k21kk>8lg)(qX4 zrXb$$E-Jt{{x}F1Q6xO`14HfBQn%nc5V(?zJaVWFa&tirwI?c89-@ZY$=EY*-okW0 z2Z6s=ynhk|{#Qe7P8q#xXrM;-FAueY2iCzI?GhqO;bFlU^dEu1Z&e++2N(||f&&x? z)T`x6%^VbGjm1^Wq&XWAQH2h~tk}F=z(FO}s^C+u)!ear3B03uG&4AdqGbHs!ErbF ziJ9?%;f68L_$M@b_!lL7!>SD~&#-{t86DVGBF4A{EQ|tO%AMX}X$PCAW=dl2LR12k zlVa~mSaybm$4 z^w1t!rMNK%frc#>QSZyjH2{McF%X_?2YF;BNi_G7BpD@j-l1%*l{}4}JhiIMp(2-+ ze0}_UjW!fa*U??|pu9@oTuOQAic*uqoc8gGJ2j&#MQ7!(S<&AT(a``qBF+sU0>M5N zaa=|z4QNLb5Ki`cM4ZS2_8Adf|7IYyOl85{veR#q3GKXnk9LXZsAQr}9qprJ!s9Wm z-uq;NeSmAKD~`_sl}wnX#vJ=fGNHo0n@s5SSXJ#L69?qu1ZMq}{dbcIsc0;A^y{@N zPe;mz@t_LkXpb>{bhaNVHH54#Ke?TM@(MTYPBL+&p8T*|+H+i&?M?3O*V_P0WHMnm zFFEFc#h5eZi6`)6%!>e(OhD95f0Ru4L4BDg{87n70CN^HnP9JcG7-ex`juqjt%%1f zfhADM1Oc#NGEzZeSHw^6C68iI)&>twMeF;rOvf3=m`x*-iQMVSND-e-Xe3|DguP+$ znS`x2z8CR8@m3}2N%AMD{)~CZWI|vxJQZVzWiSQ%!R(XFI53M@R-)6~tXL|X;X!sr zj5(|5WK!N-9yKErq@GZ^&HA)phloA|4}4m5ZFTNxaRVmXv#ZTth`80&76i z`O5oF$Yf&7m+g7=UG9VJ;Xsb9q*gC)N&Q4J!LfGVVc2Tz!P%L@wTG^2+w*IW z-1l&!CKH+Lrid=B(WRK`?o3YSjxN2;C1f&@#qB5DiT)R3tG((*NfeJ@1O^6~SOgxL zr{D@-ZzS{u&8u9Jr>AM09JIpyJNdcbV`67mMfV0S@LvfD?^Lt}lk!SUWX}e$ zFu5w-DhU(ieA?Zvl&W>v*(Bov1Nm`Dy%OS*%MQrG;!aV_ivGgs=0cq#GQysQDOL|b z={7?h`C@6es`s}+ZR0IO11X|CqMql`=FaH>M8bT`8Hz7hh3LkbsuXhzu$-7z$!f0bqpr%N~KIl>Oq#%bNP3V3lWqx8vL^=$~9~zj$z|U2dKPkvN1M5m%SA zwO=ClN{EfKYw3Y2ff;rDC0D&G(#9hlMjF$xn?#AW2*KONNoaaK*6_ru`^w@DGCs%h zE(2naR{1w_^>#p*eaIe7R~wVP;b~K1pQNQcM=Nl&G$J;bkd|+wLtLIWDqD7nRmP@8 zt=De@;t}MmPHf*2}})(*lpX_H|f?mL<-}&cIfydSBtZi*}IT zNGO0Cd1%J_={Is8BjTS+?=KSphKoP{M&7Hkd5ro-T8qm&eLKAmgK_SBBR@{>aWPrk zt6=Vf@6!7QZR@8Gd+OeOBd-a)7>@2C`)YcB{)LYT-}&twqw`P?KkHcEjkoFjFB_fj z`bPeQ(V0%LX=Ry7bhz_R8=bFyBj?Kp)&6DQNNg{^mjkkb^E=VbL1S!LtCb;*bQZlk zI?nSe!}>wY@Dbx!tJS-wvkO;8EwisDYZ_H?IG;SzXXSh{pFHE`9p|-eUBDyrq4~A9 z-$*Uiko5^;?B4aqVUnC1lTqr{pM4{d>Aka>BPzXj(Ok}{M5Xr+qYjt8{YDnOdVUS{ zjcnM%wYAVpitHI{XDa^K=zQNda(nCL@WCg(P0w8=2&Fb zkIax|0H08g<$}0J13fZXRYBFEc=}KbSUZC-?S9Q(B~>XY1jj|;LIYrHcyko~BUjB> zUB=rk?XJ_xl`-T-(#o3B)mdeU8>ANI%L!w6*+NFu2$j&~#3!=ZBAGP@?TeO^7J^L+ z(rTz(I&U9(cx|S*H3g$j354+>0TM(C;|9h@!l>T}#r%D1O^mei+}qg->C)dY5ATGr z=t13A*P3`KAFVZ|05NaP!v|r!i6j5{T2qib`=KSydtvuVboTX`=Pbw ze_t5YOl&xVQ}IltZc>ac_zHEW?saazxqnv})4rB@r$MrRKo}hztA$4wLydFk_OG?K z9mVW+xPX@d-GdZHils1rlrX+afF?r{84;GVB|GLpH?m6ZYvw^3Pq#GsrUwnXOofl8 z3oG<(aJ`dx5Fusj07&4|d5&nWY?=a%r^i0ZAIv=Bi2!|9U|u-X(x0sAi{@sk(r12lat>LuK$5~&S|?@?``H$ zJ)QUWna96Gwth?I5fWqR^hxF+bP{*3b+sK@3jf%6@QIEO^IVOnoF3{L4uz9U=ac>!-_OA4L1=&fwkL>}iw2G?5= zbacqf1I)r7^Mjd3CRu~-yUYX8ZAkHcRktKt8o#PYD+=fc-+V208KZ=eUv8z_%H{1m z*EiT>dl@;;@$a`A5N7ARN@VGK&h(}z`muAOvWHf?vyZNw(=4}Jiaas0l?~e?-S0{9 zl0FYN=d`r50$+G5bloxsd5xhMD2G5J-o3_fYCa|h%$1asRbI>m5%t3d57t%I)V`D)B4wdGE%e*8)*we2W)(GR7zsz87U7%R+6 z1;3x*E(y)UY2N@@LOQwt1_0Cp3W&?lh9VGFR%wy?U<#eA1%4kJaFix5oz77+0=2zj zkvYL&0s;aV>yT7r!hFiMc1C(fZ3jnKypU=uBIdu}))+0!O!iD;X}lICBfrl|w;3bT z?m!7dEz$PxNZi}oug@+aZu)(E`*pwF78(``{ieiyZJ_+`N!*8k@T)#}q|D;;ffBVu z`{RTEyFQp$8h|?Qm1PAmW*01VvR4&wb(#e{TS7|QmMQYGWIVj*Fx^VHHuoCp_KVc2 zyjkQxp@TVcf3bV}rSjGX7yjJs*H@NkU-Q8~aNg^xDR8kV~`#L2nM1#h_}09*N{l5O=R1(cJi$Sd@P2oUF%@ zV;1RDC$c4QT5Lnl;^_jHkUn^G@sj&TKA5Uw4^c-x4{D%v?br|E?T}hE508;00`ijQ zyMN?y*^!b2+C4}8dr2bW!D_qoN0NTq)b$(BQUAH)tpEJZ;v%zn8`O`THxm|Yxzxd& zUBG*d;mpcnCu-_SKu}GF!vy;Z_>>QN4K4M)-RnP1u)igBan=6)&SGWoUnNP(oN~Xq zv)G=#wTXIh@Qs~CKVqv+zcD!br}p}m?<7e!4IKMHl5$&oSj;8S)R4znx0Eo^Y;A&C z;IQ+RfYz7#gh#NerTRLBQt+~-gDiv7sXp_#?UA$)aZHzQ|wq{MVPJ%WmgC92R{`fd2ZhXk6`i_Ium+_1(Y?zxJf``6*{H zF>>6*u}_S8gk}oL>RN;cmwRDdCcL8Tdw5>L1nDrEVeET;)#hn%;G=FO<+TQO4&EdG z{to1qldQ72vmd?U{HY|X>0sga-b#vY9l5%bWPM%IY`;EJeS6*M-#lNk7-I9)nJUkg z4z=!##VUO#X^B*&;SI;B=&$Um(9ZVK9jQVk7<<2!r;`FZ+Dp>^IJ+_TKhBQr_iQh@ zFM!!mDs&qQ)(la%Tx=n`En*ADH+{C)20cdB3`gLVE4DMYIogR*X1`UTvdav8mi9Uv zj|xzE`m^7%z5LFL?QexmHw=4=+CE%t|M)f9i8DPD-|_55cC-^H^+RvTzkRVSii3SL zN*?)WefP{yxfV={(DQr0 z_l4Iqm+fC4X}bKZYiVz#r7hfbEscT$$ZIF>KXSJ$}k=SP^|&jpSA{kyelVUBp{>z-?1;}O(I5js<0@z-QS)A zUHh+xC~<>UymwB2Qib)?tpWc(odX@HP()CRTQ2GnpWLa!LfIF;VB!$kSma`g=FN0i zCv(-c;byE;R2bdp;lTt1=%=17{epcFuofzwU%hAZ%Ge(D;M7^h>e0@F)9Sx_aQZF# z^3~%@3C_RpnC93Mkxw3+evu1HC1PN_djJA_`)4k}nBMs_gZ}!@{3na}?YDjZ z*Jq1=TNaV~D}UzyL>5uZwDHF1PAl+j_X7~{1OMJXnZfVA%>DE4{dZ*s|N4LLCFH+X z`Tf5a4e$elG>{8z+&A!lpL29|sh{aU!&ezisyT2Wz>vca2 z(uqS>JA*W>$$iuyT`=5?tttxxQxZ2X!Rd)?%DR4K4^TeUjU1%gdT#gHp_*IRYC=%W zEw#V$?ft7kde4Ev?xtUOm7Yp;;-lu4F9zv$*aQaj{SEo<$G8+@=3Arm|Cld+WxVT) zUvd3wd@=LwKfZX+mw)FyXH=9V3DgrwTS!db|DB!1jgU9wmZkpn!cj{d?8^*1qGWp( zmtb_L8v?SbUs>zvKIk#8Li%FZ5FVJjrt9psue=phxd;INx?;m^o#~%Og zfA1fA`~lkVo&Vm$qwoH`@58O{nWz7^?C~q(U3>hB>tAD!nTh_`?fvJbAZEBH^{zxf%JMcO0cFmrgK6 z6@0-_y3T!Yx2>3JIqI`63Af7ob2|^Mbq}>XAA8^2^Y)?jk(=3|qPpLI%aSwZEP&!D z-A8NqkXUCJEMZ4YhRX`fP8wVxhD@P2N;{SFr#zIcXQyJn)>ix-O^m8eEMe)v60EZs zQEKM1nQW&BK)d|9JRjT2N&tI?qG)E}`*9=)Xzi(@* zSCZ@c^R5$La+H4VmgOsL#ZOY_Y(Hx&Hb_fL5iJZz^HIpxp2AEMCfjf2E1)xq#}tby z98);Fm5OX)Jk4AyR^%&&eAW2E`zETn$HZkEW>byBOlyUUdeu1G+=O~)tu6{AYm;i_ zId>HW**F)rP9!Bh8*EOmIXxl8&(I%kuwd|*8dW%keAUQfF#(CjK;5#4DhYik97_y= zqMCbl+lo){`vRr(BcZo3n2!r|C?ea6JK+s*SFcV#v(&$6E1nym<6fC+H9$7^czDq9 z#&&d@Scl;D1~VRzVX2{3vS&C4X+Ky|Dre@x=hbiI&uuZ#bH-#YlFY+Ifx@&`)5<=P z4ck;>@@}svPik_rVWxtJq8mWoRXl#3K0;)TTtVUbDQIR&lW02u#Es--YL~-lG)x>t z2ZRbUX(4lNsW3qxW(zKb?l1wwPGKU7FQYep0O+ki=+Y$S%UlRKWE2QHJ5YWEa6MPv zxpSAJG^fxWrktwRl_l{pN6EZ6kX2Q6w*qqKH3CYJ$1zxU6PwD$hepX!T$PrJ{~J9AX^#rro= zsCFOJb>X+qc^oUiI;iT4?KZ7p{hbO(zx5S4%~(`7t`TXoC<5Z3chA9;-}!{;@Vowa z58G{yb)|FrzU+_x*>j#>@5X)PGQRrD5RfhHv5(q)zWyd^)K5yRuHdTwa?=6iJ99B; zcxu4PD8^0&q@6q%rN~vMg#Z~LLHc;QMoleD z{lQuM*@zxKSGsoDj?9j)r+7*#F3Cp zwcgvt+a%f%0W(zNZB=2CEhtId{l4{Z65;(rsaEfB8G8qiPe3JS<-WjW{P*PU%&|@1 zNADB92n^*1A7~gu;-i$h?e(vKV5vBg-^QNEgtO5_OY|ep(v)Y7HKAdiEBY9YI zsb!N68Z;FEM>gKl*anJ1%!nJY!QuEzO)9mpm?NS}qIId043W|9a$1()zLd&vFO1F?izJ8}=+O8Sm$6Fc!{C7|Gdr3U+A2oO9%+`R$V>Ezu%Q?S zM4-=|^cylZJ3D}XUnf62aEQ8R$(@iimOxq541EszI5;*2vygCfLiWwfKbjlQX!`LB$}pNfN|8< zU~VL8OauhxN&)ZBvdQmD7>%GfK&%H(U2(_!2w$0_uFg64B;8LMh;-JRtm5g>pF3;w zxxaAM6GMvs-3l{gU(k;bihtHwe}e;5-H%rOa%Lio&fDxgk7OwF_ui~dp{_XSO~ zHA9h%10DkqiUTxK$Zisjoa2m2Fh^>+0^iPYgcv>t2RMM3Jn59kx(<`Zl2AKb^!@vo ze2!39;%Xyc>7wIpQQ}wMzHPrt(b!B`LxlW~tG9o!+Cj31W#GLGuF zumB<)$pO;QxX>OZeb%ECPz;eu)6vUV_w2zt7RmcoMlg>uII= zA-tyQ27TwJGxMK8f^bX40g$8R;QcBiW}eG2kiT*pfr2X=cvYIf%`m%;i>KUXtQMBRj5?KLlh^&%jaJBOb-U z$04m&?GkmTMG2a~{M2Lh_U(*2;sqdRp3a8jogr@e!ialMJ&I~$d2vXz&kpU=@49*C zW-D_}=z~N_I+?rf0+pq4J^Or)y=N;b#5!@n z{^;?|L`|#u#@9Jo$(A%9fD5W_9Q^Qn2U&H=0uTaVgDBn)z+WfXV|wX-hu_!3Xi^C1 z{YrQGyYEE4M%mwgC*JyfYuU7_j|Sj(-RY0p1kQ=ROJFT}6JaT>?-ST}--*8<*?;Nx z-*%^e=J#)Wfqb}l^wH+}^3z8L$N)dE6qRPuM5FWlDlg8+B;o#hlD)6`gc#jk^7qhB zL_)ayJ6>G0BJoCln1bQoC9uyPNdCjn&;PXqmcJ}1TAMx3G6!Q zbHy;j);j1my%8MWDHL~qxeh?|9WTznO)T|&ty4H()85|q$cI}}#eVW#gar3qv^K>; z_5Hnx(7}o(HyMhG{N<6|=|q{>F=7UvuyBHJ?YsHb@3T|TpxS(4h*acjLZkRWAqnBt zf>5VxcTFK-$OJb0m@=Cp(RN%Z9{3aF!>LBP54(~EqrI8%psyG9Op9(wqWBG%y6k_ginA-Ml@KIXoB$ix9Tw~a%4Jdkto zZE1VtTwFi&xrYCIQF?cWv9q#;0(bym5Z5=P zh6L?HI{cQ~hr3Uv_wozv;&_7C1$xU@JUWYlM7tja|K zF@n?WM@4-*7H(5OBKlp_m#K^39h{6sBEPdFjgnEwZ;>e2JDlkT15j}%>RX+ixw79E z`$>v7P}uk#@*5fTg?)BJ)8sAo?uh0uqrU$W_^Sh$uz_Hk;X;MWW(b3w9fmIb!wV>> zX>ioIlj_ZMH2z_rU=i6EHvIYeq%#AJGu)T-|FL)7k5u+;{NUK5W6R3ko5u(__Q*~u zqf}O+Y(iy|QC5-1#!6Wkla`a~| z!B(1r@#Uw!`O0qw`m2oJ8ppO;e>K&Vx#FqmqwbxXsppcK5sBq!QUNnp1d_>kK!CeA)|Wc{M(pW#BPwk>2V0luGx+Y=46Y-xw@JcOiwQ zi#!PTUZP3J2*N}(T19vouhFXAPq&>?au$n7GW;geOjG>x~S+lhWC zcrLRq;0pN_hEpW9h!QcdWL|?*v>F+BGOwcol=bKtcJ<~Q=iJ*1mEV*y=y&0j-%AkA zraBAR;2Q|%Vwnm%^)1w2Rmm&sTIRy)Oc~E~r#!GNg4dZQiwwv=grEA}!|ShVY#yFl zJoPQqU&Wv)rAQFhHhS)U6AST&*IzaHXuXLeS**WucoXmD7~Bt4Xbz&R2xUmTA`^bK z*(RGH5z*zu-m;2j*H#Uxk;pG18Yao2S1Mi#t#J~H3nH4L>ybP*dzaW`n1%NoZ0WlR z{a>k`&+R{tBC}(^bs$=`3W7_{sv2?$g2A&pyQ6zCCs(cJQ3&$zJeBQ## z+bsuzFcpkkt>UPfC8@z~Vw-AkMn1|d&XQZ-^Z+Te?4bw1ic`>AQz8Xt#X1*G0>}wI>x5d)mJEpDs5{pXu{G6OotK1kxF$VDm zMTDv%(2p@_vR{sA>yj=n?hrx_LTE4+Nf#zEzny^>QkTw9Fn2KgrN~`BXoqYIp}*l| zmsoUbzunnxrhmVJel3~Zzp=9|R+g@NcK^jM1(2Hct=WI!4CTZLA~G5wsU%$xKI@!N zpMNP}buL?!*=_QraGDO^l$!yEq$+O9F9rPUK5mNl*yyVliSzS3Jv%d)45w!ocD5S~ z?m>!#?7=xKcuzy)99seeee4!BV?Bi*LCh)qP5{N zcBA`pr1)5$ZY@=U-~0}(eV)~U>XnC$7weG+w{J~#iZ51zKhn7IYi}Z+42`BO3xXfMr8HmhUp+;kQ7 zFd4hm)qlp}q51+lqo5+lW_hLpum;ByqGGLYnpHVN%j+<)m7w(ph;>z^G{q?1ww*eI z{qBkW6|;Bk;adLhI=n8xXl?T<_I2b>@RHguo493o9_H`SJkn%D zN+V@5**(I4PNpr|V<5X{4X-go zCI3sN?Jl~q3Ua%V?0}N9@XvjT94&-CIitOjrQr6#YV0yt|Em)+H@7$+hBJ?>z>W}J z31Q3t?gpt~dRW;aV1S zz~Sp=f@}qc$IAr+I6UQr&xZGed71Q*{Ot>OvSkCZAO9NMiS5vBmoqF4$zbxQW7NC^Q+0gfm&?nMqu8Jo!pVw_ z^(e2ftQ(}f{;^)%pr59~Ht3d3Z_v-C7dB`+wSDs&bltzWL5qxv{L}`mrx?e$;SKsr z==^+a^#bR;ZvV?R!^(~)7O}GSpM#a{+W@S*)}&u5_=1&b7qBvS-~v{@FGq_24at~< zPdd+WY61A9PZO4xgQFsOWCeFv^GFEe2Us*nUHRt=R-S@m<;_nzCkcGgAB+m9FJR@~ ze{s@hr?4n+egZ4UfY^ER5MV|_wC{7?XwfTLVg5z38UV=`n34dHeCK_C`uN@1cf;c) zptVMPp8Wzq@;79)vDS`~T(TwNYY8N;+u%e7fMft9|Jsn-75*k|FaVNQCF&Vz?Kr<}6)fu!@s0fQ!*a3^- zp+(-awl@bGi3E(e;ecB!jD(c6bts#RSK#P76mX-v#Cb7J@!!;WR=}0+OZj5o#w%=5 z=b568M-vK*S9pZryo_HuCU1H`)gQ-304^Lu3qP`FsT~y?@j_paB7b{`Klu5+~=~ZWfvx_l2#%{)xX@hY;;Fmh6 zFT{oZ-QFDYs1PGh<|V*v=jgiF9ullaun%G>rqvzxRNaUr`7)yGI!h zb|sLTz|?pgWN-xxWkzVk;Cby4T2k*zr*zr0Ri^_^Rrt#=m%RUk;527d1dBs@pN0FJ}S10 zR_s&_M$p60XM(bV_NxX3QitT4R)}>pss`Q)CK!E<2YP)-EkLyOGBVVdsj9unClKv4 z9s7w&<+SEY7An`+qe%AdBW(%CIDHir-Bk($N*`q@tNbE9Rfz&=-)=&il=DI+67D`4 zXSi>s;z%0Fm}5Lj(|Vg$63?QEFXIC>B|QH0ecHjQ-6WnI`gr^k9%^ZaZ-P@mjs8(?(qU3hsXgdS%P8^#Opbk$W-%I@ z+!g7Z$i~RZ1sdVW2~z|yo2ubFK&ijxPcJDT}}Ar3C$-ZpIOl{V!TE9 zO|)I3TCbJ_NU%Dva^ZFH-YD-nAZ&`@Tul^{pRjlAwrgpVnZooD5QrXPI-yW{_=+w< zz&$a<*OzL}wjFt#$6$%Hw=JsiGN*;v_?f7@r$cx)ceODh1+))=4p_Hw3nSlCMxRul zokTmEnI+2_1WEz#nC2e-hbwr{^C6u`-p$9C&5J`q^u`p9;^Upo^nCQF1@~EcDT8vh z&jB``iHXY<&+*v&j1-UiRu@)2bKt&M;PHZ@j($lUHUCY6!oF!7Yk$)qv++R#KrDS^u^L0xB_d zyn=2@j(g`Q2*P#yxu(u!oj}pay$Ew75uEjcyN=#{_3k|2u3f=T)TYQQ$XC*zKddXhzxhEf^s8Bd67wFs< z$tmY4nlFc#!+z1LbLJJQ0+q)r{T&*DLnbI?%*F5T;S3DN;hlm<2Az99T=skRZ;yzet`@-6Ktp3QF-i1A#5o>8H3&3Z8f!`FPo)YV8w49lK%96Hnv)?p=&o^M9 z?eXx)pl>5IC>KN9ov{+u_@)K;C47wxN?;JEfkg&Q2FG9}GRex4FtQxp?fz7rXA zfuC}6@=C;v93GzP^>?G#VRwHqa(jC!o8(o52f@+GkjlH=}4uc{=P7 zmJwo)jnZk$>){O|@j_<@>MgJ1+tiyr6ZR#3V0+Uly2>|Mcw%Nw*oZ&)TKUud{v!0o z=Ur1_$o`%D$uke#@l+x|S`R)A6;icPXf^*F$*`LfL&ZgvFN$2cOO%?l+4OUU4gJk7 zS(@}Q`UNE5Y$7X>EnM~qgYM{S8ZEMvO|J53etHzj?W(jsmwk>RP~e)$Cr zhH;ukG7Dvr`eiLhG0R9u+Wz~9@4)5h~)C+q|?%h+HK*9 zE=2n>tzQyJjbA&*!6ju7nG~T6dw*6J{9ufF6)h;;Ureo z;;H_3C=peX7WLFrV@5m3n3Uf&a)ge60N#t1oe8|#4L@q5TdA^`>OwMHg< zC&DpbL*Jb`5Gc5NibhlaLuqK+>)C99IREyL=p+p{VhOM&h$GW zJeV1X@q)W>1};mzN=aS-Qy+%2s+KZMPy0e)AD%H-cGL1~dZ)TNf$>#fYCRXuo3E9c z_#f52es}`-=7fJ}uU*v^vdmul{I&?=ebSDlthz6v{>^@PevnNM2U81eAx7^8>F@dN3@_iya=zxr+lq!)4mT3xW3)!73Q|1KArk@D|slu}9 zO)0VGGflq)9XzlMpMnJ)z%os1=7SDcX5|o77z57WxJSQ+1sxm;+HsxgeX}t#!r-3c zHyci)d@(-3mUB{Ao+k-1X!06 z1xMZQdE+ky+AlXg<(lEG4z&NC@oDQ31bd!Py@N*(h;ave2K{vI6i>eNQUpP~vl$_z z?-DEwW+8&$lqAPe1i|%3`oa4RQ@=-W0u;vyTk@hRW=eN?9H1>GB??@W$!5==j}J{~I7ikzrh z`pEJ4oRD2N(kI>N9w&6=#X$R}p@#RpL7UF=#1g(Zznov`Tb}31N%*W*fD8=-s}4>ZFg`KMLrakbR^?8abL2-{K@m@x9Ck~DS zcOLBEpoQFL z!rY2~y0I>t@{1>jSC&A*W%$KeO3npo(UJkLWp{5(0w&7C&7oCgI4Iwjsa z#$2b>q0XDP7zXnJPbvZaMy7^=AyZ-1;Jrdgf%RVK4+0w$uTaOs`aAAog+GS(cffO> z*LWk99nYdTy?06GLPDHh77;-(2dMLW!os?`v~AYE?r6BEOC$SpbZKF&fG%w;aUbZZ*McTNR_RMXxNVkov0vzJHF4Dl*6-^;PVda zhy53wTzeg`Ryw{fuX1uJCsp{Y>DlZi>y4fVhg)@gm-Lh^1a5vmQAKRm+cC^Kd+5R$ zXQ|0Kd)-MTAqFIBfJE(AO4Rnzdx+!Fjbs^Nim^?U6FfwNNz~@E8Co1H#BuG|EDd&D zGUYiePo5VDWzNl*tl^4yWGO+GtW`I=;9=~Pz5PILns!@vg*HqIKubNc2yBc-c zsyATij1y*beeuh@aK^cEs;EG6krQ9_Wft~K9bbLMnT3_UZupFIuJKaIx)6n)umqW7 z`1tbF!;Nm*+f2r0xF};I`*UP$VFZATZLLk4mJlk32WeF+CwcZ(d(lG;|MDK{l7WAD z*K~}Iws_`@UvAX{)3_|}(AztQee0>4$|-o(it=RVeAddBdEP`g5;6Um&CK&R`Lhsu z1m3S_*)<&?mW-g~(bDkI&H+=eeNFsI^=~r}{ZW4rM1SOT?k;u1-1;@~7Y3TP03dpe z(MD`xYLp>6qroi;G0Hd~i?R@C%GP&!KBkac!EdrQ>`eV+oo`@gKs{Gm{Q(H^4mxfK z(sR>*TGR=@>;|a_=`ZH40d(sY)w)e9R6jDp6{>Ti(~ChUZ3_xjL3wh{F?$Iwu`i6v z;-|XXt~YuI<(Z$1QBr9gTrZ~Z$DitQj6uBWjYUh})}~swMGm67CHdNVRKKEb4`O@t zBF8%q4hj&UAP1y{kOvnu61lbe$bO=b7YIiEKM7=EivY0=kK{JW2q#0EHBXM-d}5eB zn%`+VJX+A>$vRfp7kYB+)?iZlSkXxS@L2KdO4jk)Zyui<-;merfaxNPUkGGb1ID}Z zV@}oct?K7F&AK&kkZFu}YISfM{z`Db$)fr#h+a1g1pv_{0Eqto2GK<;=VT)hWn)c^ zNo#2#22N286@8-D7+i&{2bhHObP!aN=c zdSWiCI>9PJs|O-m#n9NA4JHLJ485mo{(3!%_tbU(hM|cM&DBpoLmtI~B@Qmf(Dtq8 z#K!V_f)31M=+!r|4PxkB4tA7Xiyc9%zjJgUemX z#?L*<5uBg@ZoPiK^wB8$es~o;ydP>s75oo9Xe>i13ESR-##?8Hk3qIU&$;gi86$dklO)OCK0nte8} z-MU!Hw#y#=wm31)q1ruj9~737%<y4)^t{cZiwCL?)7S+fV>hjL(855j6WFbXo&`aMHd z42u6wBUz!<@IoWmpK`!ow+CUndi8$AIgKrh07YJJqB7uUJzNzdLJe8$8De9qK|Yf) zS;tj1au^RabH8%~&%i8U16Fp%A~z@aLh()0;h8TgIM}!U?Ix4V=fC~arJEn*c@^CC z-B}7Z)>Oe2AJ3dy=GEIgt~hTf^YHZCryraNUVn~qAM0=J)aMi&?)e{r;HrJwN!4x-|o@e z|1d_92I z9bO(bngG_ayK@+{%R&^=diaWH^994?%*C%Wmlqmb>efKlf%V*My4%2IE(+2re~>+( z8>L1`@Y&Yu35riyK7)r!Xj|LEeNeZdw|1PKoyZOLcN%qFz0g0*n(T;xF@il_YlfE3 z&8{PD{ldx-Ow-7fVQ76VH`&6mfbpb28TF65rRA=z2&AEdG5R>j>oWSVVkBd3mr^S7 zZDro~jMOg}e+F9!O0e|`Cwi-cf5m3spD*u%#*otEip4+J;|5^?mqYPozHatm+8&f& zL)1NylGuZ-=Ro_2huG0gO&nm{*sE)b^Sp(Hk1|wQ?i_GiiC3f^WwYtL*v6R zeYjYM?{0-q$eSj`I{qnfL1IXG3nI2Z#9K`u^X+3DJGei{i+!;e$$07Q_-3<*G5WBI zQdn8^*F)oxo7M1R08aR$`9ou{5X?gvY1e(=akN)-aQ`>OgV$*XbJ~<~U*&I97XLk& ztX(fGkmmJ9c!M7>`sMKyKPpCA;i04_poUz49Ru)h-SC!EJmx7E3oDDBxS;BHtokC; z4+Ck|WAry;-WQ>IDX}wZk^P^CEAp_{X%M_)J-rdHi4)ondKMRI+g8IBppFGdn%x-t zkI#5i6_LPbHUd0fi)xDqS`_j3_>ACJ!3vZo>(o#z0xA$~z*7y{?Q9{nf(tZA7h8h_ zF~!b@i<`~p{HbzlaAl3xX~V@!lHS(K9o}DGC&y0?ugi&Ho6RQf4l9e7p6zLR_s!j5 z?J#Ld1tX&Rn61zt=kD!-a4w!IUzU;JU8$aboyyCo2)q)@nPG8RDu+Ns=jn6VVeZAT zKpGNkf@SCkPNimpan^f70A&QAjL7-_Rz_^$4fzw45oI^NSKjvH>cO5W#Uc)Rh^@a82YE@mmQvYxQ6MrS2`5Vbs1)mDO0iO@?y;OnN*t_{1P zWWKFXJU#l>LQ42eH&mC{+6KYkd?vri@p;q2YMtSRUy1I<_IbNtTA~tMaB*(u;JiK9 ziyHgm$ex=@-vo1>s#Tty*x7z@^M}z@HZg8ygQ&jyO0bfY?)*WPOhVLT z(88v1xE+tcEq{K~fbw)f)4UgQ60qV)s^ls+lO^-AN7lzcT;Ic4Zx=feEKBCLA1&?7 zjV!ew4V~KwWpc5h7zXOW!Ocxt5NA162OliUrhCwQJq1^#K`1hl0qcZ;ysMLCs1F{! zmW&j?&MAz`cL~Umi7aEdjcFJS&=|77s?IF6>Q|>o11}aO?G4Yu39l-m=SQ~5mp@k- z@f0gruu6#4EC`k*)9KTMLxaqbV0AcyPfp}n`}JwRhNw5NESdC4^0>1frmlf9J9v?X zG8MyvW6+dRBrxq8Jc1aP6ly@8!oP5I{$8Utkf*SA3CKd8LSJA7xpW5iVG0VmvPzi0 znkS%SUZGYj2vevXe`it0#j0s3$y;SQby!?aq_G@|6_P8?x~tWyQh-=jvtbdMnHe=I z%Tf?G&#Oq_59Y=WM^W944%1Iyha+imZ1~}55B@VxxZsq=rv7~|8a2*h_|_NK=9#XG z=l2x$eRDWk3g7w)&6bC6t$Hv;_a>~J`nVFBeV<9{QI$wu=fQj#?7Vn~S?0o6Xb}Ni z7`JDp23yjPJiL47<1~CbQrTi`IhNHMs-f`tR_Ot;?+4c{n5 zVI9dTCptNjUCod_@_)|NZ#(=9Z**9eVt@$R#G<{u@H3ENux%D?AjM$)MSDA@7y$e; zz&{VAW#kVHrDs*nu?%PAJvM>$G4-bnU;npP1;&go#r6RIyfqN7xGDa59v3X600R6o zfD6_ec7T5dqV&gmfH_%jP5}J;MU?fW5%J1@t94(+KX0nDYJ1^lfPdaL_!$E5&+G5F zo8g}qLwJA`{o?80@|6Zs^g(NcdjkCP`e(5? z``<}Afj;?d^R_?${(1e|-0Dc|`Dm(5@y~$&dHBh16q_(@^Vsaa2tTj%KQGg7FX%Lo z7prCFlc=*|mnTsJS!+uvN<_vz%TttO0Q?N#=l=vh1N`%^2#4P4I0H@YYiIlb{PX%d z?q>MsMO%g-ti_%AJBg^MC>P|i<0^dD?^Kqc;@=Q-m8eL)ncj9o@4gSk-u#UAT;t{b z=k#FKu44PCp{}}u8_!CdzxtoW^3uPa#U?Akh>Ti4Jd1s=FJi-EE!spk22b-j!tDIv z{nYUCti!F2_2#!(c@ifr+gC5I=y@{thv|o&=)Y>5l-eI|n*XXl!n~4sAkzBpXmd)k zWQG`qSrAwmvbC9BHbj=!gSR=c^_<;<%KoNt;ufp~#{Lzo1m*-nS3rxRtp9!p?~cA4 zT@5n*H{u8Pj=oh@J-?9oZtJ0aEi-@L(M@I@ekMH*%Y47pcj5>v*5Jav2QZb`w7=D$ zx1;i^a!JRG_=nL2KbiUdkYH@6V0D|*6&84`!PWg6&N_q~zWFg`W0~(c%YT*c8j z*t7UEpB5}J)FSxi6<=5Jg9cCUdH<>|W_bOQ$ou9y4ZpIB8FnypLKcS?tCEmG7GlT0 z)-NTcyzpVmU$1^CP>x}X^-DAOc(#9Q7xPpGf)gErc;hG2H;UwxnQxjE=VQl*PaK8! zG2S$hKa%;+K5=2|g9wLc`TlvLeMPjT?Q3=0M(UTo&h)*DN;5CRgeh!c^-E*9FJZCc z4)xNPy7@a+7pwLja2QpIzX+>tn;!cJuWp;&e8Guw!Hw0c_}u6EQxE3mKv*lgn7<~B zF|Md?tG{`}?fbFgMsoK_7h}gy4wg_X_PksF&Q-kc4wO-T3Jjj_kVF6hcIw~AZ~<}N zYoGdd-Nco{w<4IRu(xras3f-=ffvKFS!(iKG@Yzr@_HX3$(lSed6;ll0ylzqIh$$? z8UlA?J?BEx66_`b>w$aIB)8BZ`L+K5Rto?9IPcyhD|o|mfr{Wmv*|ATf;YCX9>B-R;?%fDKe{u|5nYT={mg(R`G@X*StZhuT!X-+Dp)VT^Ba%@6IuL|g25Mg*~K zbc#`cDV_tNF!eZtf8WhM_2vI>Khd8D{Vj z?McBLj~xjcSv!S%J}@vMh8ml^>$y8&nS52*0f zgxO!vY`si;4kU{M;&VWJKK;xYl>=U5ztY*gDHRF8KmROYwRz9j|MS8P@XtRKpYIxf zI9A0uH~Z!X;`3GfGmtF)Tk$i%KLh;pR^^_XadrdA;=gsQnSf+*AX)sYid&_1@bNkp zu^)e>fn;$YSsdV>|1bIHW%wCrwg&D@>)n}vX0C7iRhu<$Z`@zC5&XQW*?Lop_V&_m z1Igmsh9d&_XMlf(kkD-(!zRE#Z=1ITNEToJZCO)9zPV;=AX)tPUhIHm@wF~?5Lvi8 z`+(`hqC0yrcLCr(NY0q7Wh)q&taIhZoT}$*Go5M>9LRuYF~Z&1r&+DGlDkll zX^eNOiha7%x(%MYFpxP7%U!_#>ds!tKLg3)z?=Z#XG?Rk-Tlu1|NL9W8Q`A*{`q(C z&zrJkFl;O6`cXfqqtI%&yWu0Jb9bp5<}T&ig%iEi@HoT&E}|6RpV!)E0sr$Bq3br} zpO@*kf$(sES6h!)1H!|z!2tgZ%*lFl0`Sj&Hvhb-MH}Fsf7*@#_@CEWv;qEk{Y88G z`JXqHO}M>4JitE#{4?NxjzxPJ?CcEsnk!s@00lW90sdzI7p#X1{v!Oml7C*N-(EjO zAMii_^uoQ(bs7ME{=@L|D*yAQcHHfSpB)VY7Kkb`u7E#$BfPen2{Btgt`a5-c zvQ&7;ARl-`VcmhiN;cCiaL5o_p z>%E2~okiY;ERtgNPS=ILIk~uL_F)QLcxCN^DRP9+p9XG< zr1{(*P|H+MPh5d&zy^hIVM_5xK(Xj@>lRFrs9P$de)O{b9juHRyS2d*Zi?i*!wtb%|zVcTXzm+E@Ui;$gPn1!MDeOf3QX#*Iidvv(`ezpd zAR>7A@ogVaH2wC;8sURL(R4%6&EdAJ<8{$WKwbQw{_O>VzJGnt_u@x+BdhfGLhC?K z*`GenOK5#_LUBwkt2)6dLaW7mku9v!*qRL{a7JuT7ZyBUWEAhIEj(X@_|Ucb>1W8J zFtqNze3iCuJtsDn-xIW)5!>`Cz00AmlJUmYSLtMZi$(amsc^yV#bN{SciYS?;G*6l zi@gn9)XP%H00tXi=GJ58{vs9lN(OtG3LIdtfjL=kPJSyuDliQ`SB0s@%x zr)L(xoNLYOAA>nz){Je2IS28oOHp>ec7gcCfEne=FtlE~lGMkb2vnEhIIOT{+}5VT zI8eQgHADB;STi~%F51_}Q%+Y`?fEcq$yrgi2eCbRF+L24-~O#V9@|~>{TG2_fH?jy zi!p%suw`FnKvn%irfCcH&zoAb0dV}&i#7m`myPolRn^4*o~nB84^~yXJAIy=9*6w{ zv0^}|@FauR&S;8o9mwiM`$90;8jCiQV(j{hw(L(X+5|hhUkt8TsR8rzgFD63<2}FO zjt+qMwceIL2E+rzac!i0Zc;;ppw&=kO>XkTYfv`~3WdCsrg*tv7Twys)Rtt`c!em1 zn`w{I59XS5)!s~RyPJ z0c>2)KRlA#D8o9M*Q$AP^yU-8^wIoI+u_lI9#7V>!oJXxW48vA(#MKM@`uNYUstk@ z-+uG>9SIx}0J6#06EqID%xk3Kp#ipM&*rLk_0U-XT-xdJGul2V4 zF(7{X635F#)qvv|z{UVJUh0zqh+{xhJ@hI$#*<|zB_Y&gC^aQ1Z73}xe`qK@t8%?L z0UXDG(1wuuPRI7^MHo|@Zl~O-_(gN78WzP#xDYZ8H zwSh`0xX&tJS!3){F&vPZ4cxN;oW69=T3P2PyDAEE><>u>Tg72-YUc+y?4SN91043U zkMb6AI>2EA9QJ?gnFOk@w#^L?;IP+E9UOp{%dZYrD8~R&vm4|0UQ@nP^!E222DdqK z|BLk9D>>|C`fkAd3}9mb8*ejgyvqE%DGerojR9;7n4hoD^her#J$0S>@G2$w`iG&6 zg0T<7Sydb#NAlWEeH<+uxc+hM_Vn1t@lsUI+1KU7zpie1Q=SY!H~rHy3vk$L-Lw7} z%n6vE|8?{8GJ!W>eg>BQ^_Kp>2pq38KQC?58`YFy*-?x$WR{FDg%_7v6NC#xE`~C8fOZVap$U;mcLI-P7fN zts)dKKd&wS7)-wL`NK#7kea`yOeJiPV`m>vjVBvKx%e}X~F2br{-1c)1B6BX475v1DVs^PSZuBOLMY4(zpP} z@qaqb0CBw5{t6Js>yuE)`WDcISX%@T2*mae@@WJF5bP%!7=!=@gQ#b~$cP{m5F7m3 z#fN+n0faUO!bT&P%Ze#;L&Im$sm_YM?**Y%h?L8Yt8jth7~cM+hNsZ&Wa@vOud36oN>Fzfk!Z+zCn^@Z8JRROenqZJQX zfZX&k4X@YV${lzZBk4~Ksfs8`)ru<9_$=T<>u@-JImN)est z3zSoL@Aeo{I|#X;93&MFtrU`v^LVpgpwX6_#~6xeB~R^Q14aC?l?GHEIV@+#| zf9LAq2Hw;g8BZmA^TkgGoS&zS5>nxX!Juifcp(R<5hT<__vHsOU&9DsoCaBM8yA$g;1LD1XhS~5b!0TO(;$^$xYjqNps+^2e-sx`)4!|$-87m zLKOqwJl2UH!raO4J6d9Ys0-_o(Li`kk-l8|eMvXjI+=O*DOKRrroTzFk zRIrQxa@|gW19)Nz$6~ErINPXtF@lu>o`(o6^zSJfZ zzX##9i2fXq_$SRNdgAYx5%BCzpDN=j*XJW}c~KNRkc*IDOo7XMgE7I;BT`^|*4&uP z-9h|1zW#)PvK@(DCyKYh$9w2PLiWQrA4%>&pB=xT`j*guu3|DG?V;{Cp_!qGxR0-> zDo98S7N=cswYwGNUeU>$DsoIGy(6pf;}MDcoDpM>$dKFbvhHF(qk$BIB2azRU(V$$ zMxZMqRDjFf9MuRtn?ka_Qq)7|fy0h{Mw#SyFwx^XZo;W#tv_RX3_r;QF3HVa7uaPz<7)iDyJQ z6evU#h;Qbn$KmK9-(1ESh;o!x+Tl>`G13-RuizI~EW_9(!&T3VH(#`f33f;EPZ2%s zi1vbON`Tzz?csxxdbKDDf!@3IU98=EqZBsj`VM*XU< zO1L&{uk@?atMWaD4 z9(<6>#Z`tE^FhR4*^yM*FrO<*;VrYorwYotb2TE0k8q?|4pH13RpQNvx>y1>2??5$ z7%{?nWs*ly^thWSEuFwazk@;Rv5WORtPm#eK7}UqebxkiW&5l53k~H|6=fAMxQ*FZ z?R*qW*cLB~%xT{sS2yW;AcGi8?I2bw|E!33|E11qbR=Tx3xqj$BRlY*RG?knQx4M=| z(>}ZGf0S4ucM`tT*@{7i$Yeb{8pW*+gkiz^G_Tkg8|2!%DH^Lu?<_;SAi=;x4N(+KAc!VJkg!(#|?j*~Ehe}xc(RUgu zjCXJAi|uf?K;n**2yv@H-3dmxg@OyI@9C6#ir4B(=Exj=NBFSRSHWEVOMM#J8;xTzVEFs`C4)jkGYAnRY-aDNC_@V776#Ik1u_dxQEK&m~;q0%^glKi`DAupjg;#LYg<#stXc8wvD`jW^gnyL|j zr)iQY{Bo)ExlT~@Fj$H6GYyC$mVvDx-D=NIcaUI=lmCWNGhMNqAe) z7NN>%JL@AI)kiOtz7e{!Ive-!J4%H_jgcnT4-Br&@$_{^1=7mMwV5ChQ0n>#26d>| zh~aVC>SL|<^`8>Czv`o;kTGlHK31*fS(>DlAugrb=Irjx5Ryy%{wV0s6GI|79E>?T zh>{@Wr7BLaxkXkvcBHuiML(rLoPCTDXy0oK3~>~i9M?O2>WJb9wgR|ja*)f7rmRLF zT0Yr63mrsU-;Op2l>|yqmNTIQwV64j8D%d5mq$IZTSwx4@-lMa0*D*m?jWc}L$yA& zfi-Hj)!t<4_?Dx66Aq?C#vUXWr4a=VQMq(vQ>p8@OurR~)UyTSq7e^VM9oIO02M^Z z!j_~ZD&zxSX*$;FPI1RgL?^)ics7-;xf6C1Is(65KdK#7rP(_{$bK#`Cbv6MtnkGu zO8qPcq*&61LIm(p6!O>fd-kEIqA4((F#;dO;P%{yf0PC#(A~lwziuD#v>h(h+!I64 z69^vo0PihT$lC|vHFC`(cZPZ|mC-zTrPPaJaj{BdF37t{zn`q8E6;#RIf z3=qT^6XBQgBa9GyD8gxQC?Yp#hrJO-qXmK4A+GN$NZ3wo!gvmbzzCMI2)Fl|PPEcJ zyjMdHMIs;b47a4c6sAv&Ypk=A5uMKs`5g)J6Q1V-c#qEDwcj#)bd#y+QB#Iy4H0xoHkaQR?|N1rSxT_Gnc5Zz1bO)0A|qC zL(XF~Kn#z;=wKOoE`&yxgRQ|L$}B8}}x^?OMi|4g2seSesWUD)BG zq}TEZOb9&GxU@FUV@IWvOdXPicRRB;u~zm+p)@Ary0AUnss0!}+WSJXcWsjWKS{^t ztZ8|!?!}~`5E7u6W=J(qu+x3(ZHyLq=}-y_3A?AXW~;cs1+BE_#)nYC@mzK$ePm3U zs){iBnE9o;mqmr38HHL$5FDgw)IDlwjr?c*UCM z(ebcYZBR-T>Y6fM52YO+O3Lb>w+sq~;$`DI=DZjbVvEhzL%M+&VW(gdd_C6-$wgjd z&P}Qp19zHK{=QGn9_^6O#AJnI$sIP?9KD_t7xrrra%APEp;uB)AJ1XUJ>6CrO!YDM zV7gF`pf)X&VD#l1XT!D7A>6tz=;YGvz)hLsyKx21P^(iBMXLvk{c~C#%3rrH;!s3E zI8st(N1CKWK388pN8MG+B8Yqd7z#b-H7wPX5P}m=+49OUs)p1Do%^T(B>#SnL-DN! zHy=?o0W25tc=;3x?V__}xTOXHly$cF?rE2LhF+}Tn8aL`kXc;pK)~fp z>lI^jiqzv^>l+68zH6_2LhBSFh_i3s{&+i_mO_jLpBmpr6C>Kq$Js+mtqt=|cZ6p6 zT+ZnT8-cV|X-~2Yh){A68Cdk=ov}LS>32z8b=)M5=}%_vz8AhB)|aDdK#ss09#P@J z#&jFSLhQVa;6PnT78vZ%qLuAaFhf>0$6Iv10*{LB=5uCbIx^f*?c7mm>Y1T3Db_MN zCq;gwq>}PNmHqeF>TPlv_n~lQbjd~1N|(4L=7CDH*>B&Mx)s_WoJ2|!@HR=Xm0Hp4 z(f%P}3SLw4nQXJ&`j8+!5#3`V!7;)n#-P2#>|?=stmXF)`^nOq;8q9w7R_iqb;Lt+ zk`cOJaHO+R{bt!g35hb3=%>9w(ZgZj30tGSN+;8M$fT7l;*{d0G6|rn9nXDbo(4$H zy>L3%c`mRumAkVlsQ$FjhX|2`o$Pg~Z;{jbp4Oo93J!w9BP0Q6bapm$>%@Y?)1HYuxYZHU=k(x~3Bus*2j06IMrI$p zCVx2T#Hab%X3FWIh}KtQ1a-w3Nme1~HlmzuL{nlFiz`O&YE-|RbVo>N z&iDupK3E?MS8JpsX{3?7L7XP{;oIQ{6r#$L30G_4SPwx^0z{ zoHS;dWu|RTqAXWl+!kZIg|jm~@K%#ZQ_IN3A_L zs@)T}-6WRu^rT-nMMvZW+nspI{dre$ke-MMrNTCrjKE#`p=Zz^YgV3ol60pj`W__< ziKV=`SeoPGIEqf;*nJ^;@fC-&vwb^TU*_FZD9TsB znES`(Lc36;U2Ey@=_81NM-^M6y44WC$fN`Z26l1Ou!j-Q=l0Pt*UKnSA!F51MmImB zJwSY}O}G<}qtLf~=xmR&MZPx!|E-#E2rekdTyIbu1Ci%Mm?AY|qQpm{2zIbK&4HR4 zokQ}a$hSnFqMdv34{iy6V0Gh6W?#!)62)|GWsF=tf3{3RtM|1`cYE1l;{+_2FW(D% zOMA|nCqItw%$`s;<4-4Pj1O_gRfX2Ki|lzxgitLPORDhtAqK)rLqE@q+>}7_aIZ8b z!(v8JA=fv(G&dDrns#%GhSzX#+`DwJJCowRr%o_>jJY6bWUd7gI*IaJ@53Dj`oLkayDT{s*eqZpCb;kqNVchE=zmyNHg8P=vC5n z;zz~7SqXReGkQBeb`}V~O5QW9jJq!cU3u;eZrW&2UPndXyK;`1V%<-#@(z#OM84k~ z)!KQcDwVQf>>=@{AZno78F^y3opMY(*679IvHo*ogVAF{ z=U7jWj|_hv6S5dhL`XDXA%1;s+~a7^`@7?_-Qz*7^;YS9qiF;ugG-6x6cNUcf=xZp zcMX2185Wogw!!JHu1kG7HvU*7Wpb?ZLg1_Z%YIckosWGd5HiPQ)t(4yYGBdiv1hl@ zogSi8A*7j$e~C9Y$-hgsuI_pHt(_&K!xNN~2rnVAohl5W6u3~D^RME2k(hRH9~d|! z^p61Xt5=zX;}N5$rV2$k;_oxXw~QF+;GK@T6LdX^F-ncKa!605x0W)xHfsMXpSQiU zk8!D|nJp%U(v*c!B>uVCs3d@asG=(F21?_8``qn0rrIDjwKuLsuer*DCj2ShiTx)y zaPz{T_uU?)jZyDcn9+N}GyY1`e>{<4*OM+@`r_+T=*W}0UDi3qxRGppPwp{~yF(he zZOiZD40Az7vM`1NJ|brCN-tFkppws^g52kXWTEQtE5*3WHxocg*n#2PXAH;WmIG&hCezf_WTEu{4hf?Qpo5F9Koa{_U%9TYy=Z&i<%xn*D=azXTum(igl z_(@$=f2k14u6x&g=e~Z$@PEv@%dhSmP>vQo`x#8CF{m0R?N2EkuJKAe2@MI0P2Q3Y z!c4fMSwu+n-u)mNT}?h!Jhmq(3I%vrLCzsEROlT$p~v)eYjaTWq(l#1j&-p>>F9W5 zZxh!=<(NrIq60xkv_%VaW~=6MZmY(|$BV?gd}`l=DADsM6k2bLn-i6;$wX(#T5ZAC=${}>6AG9cxQ3B!3ewO1- zOesV%+bQ??Q-9B$_Us)RF_X6|d#-ntci?lMK6R1gmE)?TEDR%*hGOi3l%q zaT4EZxpE|OcznoV9Dx*$#;D&zl<;*;u}rOJ!i-G;$|K~be)rSX9+n`$Fj?VPhFldF;9Ijy-mnXx@N1!T2gfNxI6wic>mA|?(H&5 zSat0upc2K4^6S;V=AxrPTpz<{4blR1V2D#eYCgDpg`B|nTNpPGZ7-E*<6Rrm|I2; zBKqb}z3DPfDoJv?AXn(uI>-;!q_>ZM8sJ^mV4sJa*3##4n_%=4;vryD*Qa2MirZ1C*#FGL&%=ZjOg%+wkA!;6iMho zyFu}IrSR!H)7SG#K_ryede6NPb@Z+o)oPf#&NT=;4<|VY*5_sCAQk#4+nx(%Wz9z^*R$3`+`@}oEd z$Hge#HF}AGk3l@D`GWGW-6f@t;ax72V#uL0WD1X|v40}PqS@qgfIJ#AyHJ|Lw#oNM zeU11jK54GdCO;#oyJ@7 zsQdC(s0Jw2<573b@qqXTWN_2a*+ZV{JeH4>CF6LX>fl`86HdNA6wxIi@{DOCuD_6q z!{dGDnQ|lu&5eTn63jS#5KB2Zry&Lkld6)3E)h87C4KZy2w`S!XBibz^U-|cNVOA$ z;H<9NAa|4~w$zWM=q1sK6S;u~fei(FJetwu#dSVPpqa{Cz~hMlqiHi6iJO?HMZarJ z{v6DtVCb^G2>7?o%j(WGrc-|5J{PwJ}VUZr#%@zzhxpx2RP zl7<-aP+K#qhrB1}wCRNp)z)It?XE@V5EY65OO??=s`po7L4Da{y!TNu@0IcHXp9H- z*dL{TL5WRM7;T2mGfI8Hz@}Kc`xpij{UOxrts1rDqJ6PG?RCdgo1^mf&>hpJAQU{| z0}-dt53v(9RX8V<)ot5W{H#GmRUoHh&;*RpMv6xCAtmU5i$RQRIJtFJT3c%84)mj$ zV@EJ)E_jvZ-|j&+cSa^p)xgpxqVi3z%%SN3N9uD>Ny=H$La$E^GK(YG(B41CA`ek0fK^v%m9dxb6*x$5Lp*eIZID=NX0WPkP&jr|nHmqf3bgt3vqE zB)qtCppy9~RLbXyk1+_GiB{(tQPdN`OTcjt)|5eGyuo&@sL$e#RfeKv$!tImT1$p2_`f{2)#%Ny+{WUHT2$5sz~oB2m&G~orEU6_uhLG1nIp?6C1sW z3RXar7aYgq%$vDq=AOCtp8MYX{reF1-fQi(zI*NU{qEk!h}vP)xh5%z>Z`2Ov93%3 zkMeG~re0Py88`P&zj#kS(!K88nbYUifI-ER~=Vfm-s=HO(XcZj)Kr@UF zC_ik{jXVFAz1UFVgVwx<_k=5S$cTaCL)Dv?GOqNHgmoB^cn%aNL zf2dOP-lB>4W5bA|Vn!E(u*~vjHS=4pEGNPTVj5eo-CjNcy;Ri+iOb-6(TKZHn?#sQJj|IB8 z?R z@>ZkQgOfeyB4VB_m5xJU>d1VLsK*RxcR8h^#_~(A*gvG@53_pd05BrkEC0L>iS}(P zZu4kMWSgYLvzkbjrw(_p6ze!M6u*$cH#MUBa@EUr(hB5J)t9GBmI>?SZi_9wlm9yN zL~D)OTiW45+L>tvs~|+-eTPc>n`GJ^siu)m4Izlz=^^1AT|IFGprfn)cGI^uf=<6* z7#a}}^C}a89rYDg6gv&+iJ&Tj&rOr(p`B<|ri>9cPilXWA~#OGXF@-nl+n$tOYf@e zuH$)gR_x$}Iku?tRKjz~X9rzH%SQ`$SPq1P4ss@4V(_+*8{#@unBbIa)*b#Xmhnrj4ITgJ-{A zCZ>>WddE`xd8nOs>H)I~!O`2eG{utxkD+*FsiR?e@o?!>@k}6RN0N4Xl4eKr__>S8 zl5}~UT(TJU`&f2_$o2$H>Y_AF9Aidx{klUl@4L>Au0`2OB2>CvMh`eV`TH2kP40E;#q|tsHD!3#ckZ_v zTb@r*l$!>0j_>s-zQNy~!u3{v#7aLaXPRGK zw*qiLC9X44cp&x=wqnr`2qw!m9mrEuh>IIY4ixvKR!Zp}NR#YCAKZP@6zbH`=1a|? z?r^G091YyOdjXMK&2e%{iHSIexC@iAPEEzwUv8ax&%2BP2vhz%NZ>v>P{kwv>VP(7 zFTaYpDMB;0M@lxeSy{zce8xXKmOrwIjvAi_LrF@|a$lzU-H;v+eXe3Z-(n>+0DI|$ zXaXEhOA`}i)=8x$@jySRn=UC;iHVmgDBlq4!L53JJNd<@p>a3G{-nx;g+Q<*Y?}rn z&>z|oT7!nkYC(fcVifT9Sfz?p{5PW2`a{)`(5C1aO)HltXcWdd+4IRM!e=}JUB0^ z9c=7%`V$?DXSnfbWt@;sE`vjDZocmW3-qXjXhRy4#tbFr9k?K@?4MK+5H|6S4)Ta7 zzz^e3MUNS^RQ1tQ(UJb`H|p+7M4JXN5Y~bzbp!* ztv_bc8SBrV@DYXS4G-+7icEbnK*2jH9MOApSID=2eze~0;hGRT-a=*2VDUq5>{IAu z?3{o9U@`hr7r*{kD<(d|bBwA7?B7qN)(@JHhECM*<3R)7-5>w7e0r8p=Dtj6+CWQl zw4w-Px|pT2W**CTb7Xr8^L%AA+EmLfR!z$^NfYq!UFgIKh$z)G^aMRrWRn#I@CQIj z--V5GIO)U_On^~a*3uZ)KkmrVagHnymSn|NGiH!{-N^i_xkL&P@fFWHNC5Ch*NPd z$A;R?-sl;6Ch%zGa4xByUC1XUgkE0(AymjI=Xxm8u!&8qlS(Ex9LK}vICbL-6K4d8 zeO&J5Mk$TS%(KwV7q2!>f(J=Asi1K(J1d5|Z|50-u+}o_Vn?XqLlS@~rU(Y;Zz912 zg=Mp}M@RW4s8DXX3Q#~Ul}tYlRgQ~BY1-k<7GCadLsokDh{_K8V~a*i<%-&#JnkF8 z9ZLvb&0}5~V;L_KgfPauqtiBW(((5V#QJF|v=SZV#)c&6CRIH_s?8zt`TBz{x8cFH zJtfNwpHBHk#`I$h=&|cf;YV>vnEiLyI6+?}&6XIz{M^N7^^@Z?`xm-G)sNsY87^}x z`HbSs0s+x|u*qRR^hJIV4f@YojrID(^B4e}-M?KYu3vxoZSQK(6rwP$e;ObJS(ONqPkejPY$t|h~-(hoCsBo+v7Te=(s!;xmLbFug)r3 zifu$egSLTA-F<}Nw z_cQj~@MGTFP|C20BekUI9y-j2yx7ZvR9eu>63J7qSmW>pIfv`p6FkogzFWG$z}D|9 zm+2d+4FqWIo{9d9{p>RpR0LJ9B7M_M9PA6iMC%7^CbO!5^7F-$AS)V|nE8VlvxK^5 z7U+Y=wW1AD>vlpbR@fpKm#EyZA0exT_$<)?m`0?E5FT+Z`KYS6S<=#K%m`gdE6k!{ z)l!sAv~^ybrl>3%s#7X*d-(oJv*HF7%Z0MBs5#+}>6aKeXPurck7Zd|iLNtp5ivjM z?qW5_W2N$ew2$ryb+)$1yR^IZ+E~=k^tIZ|+>!xagh@NmJiyRKn?97?jKtnJukXI@ z?Y_YkxE|0{dSrI>(G16ONU!ZPbDfm-l4~CblWPr{+RtZ(pF44{Ow#d60u{%rW&*W- z0><%62ZYUhjy34*@DCeyaqOeip8NYFJ%TL6X?k~Cu%20D*o!)9k&9U{+gg%`jX-??& z`~vCj@(9n}$3dHn3^3lkFirsBxexQZGTRR`ih_XRezofw*oDl3?aRb7_4i|D`6%Vi z4<}JYd88{IO?_~Z_9x=r(@fbQJtyiQF|F?JYcj@weaNd?;NJ1cr!0;`2+`VkonZ0# z%vIe3v9t}+GUoA4VG3!#Q4|NcC^dAb^>i?z^5WzRb{@6I&tC0QRJk}}{HLXY=M{$X z(2?{~Puo~P)VV>e`fGS106pS{g4Yla`Z=l<8OL)%SEXT@-LOjAO@Et?R=p=yJ0!EG z7K7#Q<<6$&Z{6RuJgMMvQ zJL)(?-W&;OP+P1y&bcBA* zv|nBG<#cR7M#?ts2%X!N3~^J&4y;oLt!7+ZQgj&G5Y*eXyYtk4^F`=}RoH%M7%et5 zrE@EU|LUr>t@Wcy=_~F29O;tb?+mX|R}Z))^%H0VU`kPXJo`^t9I>;95u69F!Dp@p zGdsO*&_iCnIM?vrR--p9srX~e)fw>%3`_o4A)c&kVn|hHGXNICA{b8rW*)nU6PJy!7^BclDMq z%7L1(N4$)Qg;USRINoQmOnYifKLCxCIbIIG?;z^I^GX{DTuUhxH+2;*jlA|i;mTg3 z2Jy7Kc5+oFgA_=ckrHU)j=m78TfAQ*FG@T7YOUomM=TaE;jK{6etzFwp6YZsJ9Xkt z<=JZke)`XEsa#DD#a?>vfVh#npgE1k5>!0L^f$ZTxg+Usb5Q?0+j|m*{w(2d&Ea$R zB)W8#_?oTSlQTp;)R$H7(ZhA03@#V_6I=WTpP${?CqHp}uCH|#>*5<}v}R*4ui?4$`tu8_gR;QGTltUQ z>U&S#b>{1HCbGvaD#R#-h3dh2c^4|(X=Ey(>xE4jscl0R3YkP8|Cjbsn|*hR(CNmN zHjhA106sneoj5z>SMv5ZD>U9(1=(Nva>J`;lAwSUJknWvm6=(P2YbE-(YP`ljzJ=aW` zVdM3eTkpB&s?7V;$xDzN`gM9*CgIpPUhPII)|J50C{~pgs(}7FLfs1E5O3FBy0nMv zW=A!lltNdx_XJk@W7u^n9QOs+hEv37WsBWQ4e&7OktUwHPIiSv^po^SUbYTFnejC0 zY5czOf_I3=-MFeelp>79$xdHA6o0cam?(7Z)!~_UExG{U3|#qu!0n-)Lf}Fdj1~L{8|e+d;J|JQ!;Jo#YFfOKr#xAtdI`MW(zA87gJmRda)qhmkxzLy)E|WxV1PRz*ZNQ<^mtqZNu66laMLnfGLg zJhRnLr($1S7^gyRj)H`#Ru_S_a!Ku?K$lv@r(%~sgVUs1$RSTCVyH}K*>o%1CQwH@ z!#&B>7&xCOjOo1v7PSEw#qe1a+tFIpN-eWiet zJvTz)fFmzjS%Om=T^+KLLtP!B8I2cz6Rw`*FBWCyMnI4we;(__=}A6u(^M{DiS1O; zvwEBH0^(JhaW-2!sz6Oo*1&eh`TQdFYJn(j&{jDCX5)>`Gg@;1pQiSJ(CwQeVrdBr zrOTEH8>`ADQ%m`!ZEv@`J2E6TT0ea`yVD`YR!}2|g(9Z3EX$u&!_*i9Z@{uHlPc;` zRRP|GO&aPVV5kXNPI{uiy#6>15^Yepg=6{+O`U6vQquEW`t!h@)yesz{@bw3F1dkB zoq6-VxFAjl(<&JQh^(j`A_!-Rp;8;NwiXG9>+srjfW}B@1+zjIbQm_(Lbq;k=uu@6 z;Zu#qNJ!VGs-i?dH<{GEt(!4f6~R%DE*CgrVpCm4Yzgie;017WGa;%it%eADCc%Nh zZhb5u17=0sDGwFHg{`gcRn~3_c|V4GUt-~Gp5uTtDh#FMG-{V9@UlWRo4TrPuvtbV(#ko27}8W; zh7w{QDOr6vt~7F~rZ)YRcVU3OZlpFxAkt3}N||8?_ldM*tR(_pRm`rCU5JqIUbIn` zH0$u&xPH5$S|4sGqk$JyZHkYz7Jdy9%hX&HBE3=#j3wtGReD6$=ZUlZuZbJWgbgh>SUGh%N|zbPPC09+Fm z3xr~#0u9C9oWAnNe(A&LYMLICp@ zdGQuy9CJfU*)~BtyJUX4rlH<=@sx-kfQ~gTfb6k=u6~z9lx%oqCIO85qMVLgkT6!C z%(kddHJ&CxSS7+*qDZK5pf$zR<@!@R0&+pa%l=KPgq<&m%=^);VTwTUE`wRr`Cwmm zP!@A8z~JwULC4h1ML* z{A^WX)XqVNOMzr#p4hdii@^BmvtB#(t29~UN4ie^Y&=F6z4v2FxEL^36A4Px`5B=P zjiu!-hNjk=++}6h#TsmD)9NK@>Pm`|f}jonAk=~B@q1Z$Gkwy_TxY~ORh^vi4IU;! zWeM@L0CoX*$XW(SyS}CkCt1Ga%)lsDd2EEXVzy+lSJS9_n=76TO9dyLeW^Pg>I_^u z7908gx?-pRyK+~LAG9MkRAottOfdL9{v6}wCe9bW{g;>=1(=jKK-U${04K7#3FDL4 z`oJM%by3|#0wRgBGhuxOwIQdOwK5X}Qs5|k9pmWRW%~zt=}VhE><)Yx%^TtCRzfY0 zO16WeOM9T`>g`4YW1OqB27pa>cDFdQkmNhjLb}Q#?WS7!w_92+2 z7-mq~BHj+CwVV`py)r-Q0Ju*ht17LBp*?5iyX<8Ky&()Gzh9(MN^6-)M3vU-iwEE= zI$QBU8FPP6P+BYrSZP&4;{8BHV>6|)qw;*SOy0Qt2^ommx{p>)`^G~X;zLzltr$-* zjd`3<+iqlHoa}d@tws`NKa?WyG^xJGz^T(;c4P0TfzK1X7rpg(*Pn~c3q?B#Tj?v%$hwLBR=|SwJR*aSN5l9N-Pajt1?mk5y7n?GvYbO+sqt-@%`Zmq&bVk zZR(sfOq`)}aQh&5j0sn77NR89*pq@}aBe5Lhuhr<@y49{AcyzBJeEG2>s9yuXYt`LDaNEzRX-YBnHgo6C>GY*ibs=JAIC7YcS5Rn3~VU@~$7EG=pTaBTxq`W|?e?@NC)W$kcVFo-BPB5V6cSdD!`tq`rQ`c!1tDcY*pVil8QE1WK!X=Q(z1&Oi6uu(x| z=X!z)be{nSw1JAeIp&-<*EEfxogzIe=?X4eEE)ig$TiylV-p=z$44avAA4r1gkI+b zR-LN@6gx)>CgHuG^`B_C%iplIk#kcDo*P*@e0nOQsFhfOoj8y!P*1;PF~O}5dA~r0 zQTN4RKbFzFAdbF_D8nXFezafZx$LUetCKzbay6tw*5+WZNE_&Up|olz>jX)OFs0R1 zY-us!6tNgh|<4VoSbBo=9Fv*LEe{BmG~dun`Iu{lXBacf^|eUDzz{z5k{Ukl+$`Ay zA`<`yu(;FaGDU)C=w+yTsF7o)gDD1DP*TpH^v*AE(u|Xm4cuH$dHGeQv?{QiZ*ev0 zsmSP&QEGOn^x=lEf4cL_r)a9nP?A7@iaDw_#RWQ>p$!EA_aOD4OHOI|ZkL!t1WUWs zx5K-M0I2qk8|$G1+*?R6r#RRBHE;|nRD_6wxax$US9bDEb`pzT&@kZpxdj{%ovLvH*u*vJ&sW5PSb zCdan0d@b0H%{o*k*s1180y~YVP6m^Fx3&~!eY!jQplO(IYy18s1j@ipJMN^)yA`8L zxk-rdXI{h$Cf&~oUV*N&_C%FaHe1Ft5o)()&k~ruZI2`OS6f-iH0=+6=#3D$Xg}kA zRI$F+ZQ6els%)wLgh(r4i=-f>lEz{ju^6BX+3YQ`=&sNvx>z9l{OWDFCw$pXY>w5p z`F8NH$sxG)+{!I2OQu+TJ>~P2HZeQzIZzEsZO@>$2ng9svZe_tKbZ4gQ3a7pSXLJ3 zycjLgg%^#ESMUdo@5#$05$Aq7&#~WoN#F8y^Ovh`NHeRem0w=HwrEd~9v=ZVGc|$v zGzc=NB%~3ZoUNE<0qc2BF2mOSe9jGcB*|TM^klv$D0(%Z6-6FwUK+9{M|7RZols=ERK-Qe@gI~$g3 zz2tY1doNVmSg8A|>Be0AWedaEGDunpwZQ`PAFEFtRfj`|`juWTVvC8^BY@m|jHd-z z#NJ%jWYAp1YHaI{H&?S<5oEJ@b7_U7KnHXJQTKS%{{vi_Z4diB)py zzzxp68lJH?QIh4^Z9((_vk%%h$R5_5KDy3!rJ9EVa!)^&wpNgzy;ks~0Q>1)rqe>g z3U8TfdxW~Ss@Qa}%C(}`gcwi!OnZd@c<2GT05S;4SK2G#ciJnBY}Svo*Dxv}`zL=X z?bWm^lwReRwAbaqbd|>6p}n4hS-m6(1N)mE-Hhhm|*-vSXnHq|6TYp%j^W(!{ zEgyQu8h)g`{&z`II4sIXh0y(1yz@7~ie5|piT2vCxt8kO%ekKR6YX`acs;}W!{&OX z?^oI@h5bf0hV9?@VX)k}Q1mvkY^Re*Ygx zk4kiWGr&<;_GXZ$ar?~>e;c0_!=?Cq%J$L+Uc=o7r}#$_p;-c2a7m%p1- z6?^&ap{4@w`zc*Lr}xwPHs$YUj6GhypEV8P{V->l==9-{ZDIL`pCu`t(g3diAW4CH zf%m!Z3BJ9BK*~QVN%2Qt&AxWH+s|Hk_+}VKdwn~uaQgGRDZOj|;X8k?zkJ&1JAHKc zZuZ*I=e^$&Qnp#90{P+RKt4DMlZ0o1KU${140rsghL35lQdE%a0AUA4sDffAB4wPD zSu&eIufLO`c_)ZJJe$ad>P+zXPO$iJHi<`5J;9ru5HwK^+&M&Cgb%)pQB=)AB=&c+ z4Wa;|OulN`RHVQ?R$#u1c_dOF0Oey9*7Xh}u2<}R#R(4;e`7{H+tkAUN;X0hMojle zu}@+?+T-f|T!xSRediBIRc{{VGM-TCm!^3Wg;C98ro={{6r8;5=WUq}0)6G)197x_ zo>RCWgn&SQ6@*A+bN;P@(0A_rYgU;kCgUOE07YC7I_BO};$hEvy=w= z<-dOrx}(&;pZOailj1Vy=ZuOS1mA;D2Z^$}2m?_zE(l2%f~x{KRDT(S6uW3@wgN?u zgHV5s|L#vgNIT^C8E_Ym^OCqAG{>sWA8kkk$5?~2;vfq_VnFaBS$=LZuh(wa+~$%7 zn>d-E|8BUgYA(%ef3IlsZiF)!PO^L)gmxo6k&|?9ISPD#(*F3WWy^{SGorvFoc6~N z;5*hKW>flw#K*seb#y`j8OrI(^(7YrwJPnO4%WZu0Gs?dtn)q0;3Pi&fpxw~e5f_o zZT=eT{95AUKaX{MUYfps@qFyTgMV4e_Ai#EHbBC!f0g+7ZLGr)>Bh%pntOh=ktHwk zlKp0Wk{1WsO^OJqsG2?~EDOv6PJcgKra6( z1O2G}vdahvBmYZbuuV+Bm6l(?;Fo=2_>0ZI4}-tE#%onmen+XHn6EJS*fm53S;Zy( zD_!IBr@goTmag$X4ukRHgI_j0aewi$aUq!dRntm>!>fB61*NZ=w*^a_T6WrCviIN3 zIJ|CEYYltdcKG2%<+TF}(bo^al>fCEh>{ll$6)Y}83?D$_V1s8aKVWv>;K9?&bJb< zrtJiRRUq9RKO78>Vit!FBijRLa2d!|R|Jz``8NsG@3J*HV!Qozv=f_%3iv~m zRH?qiFvcyeBEoLckqOr7lDVDa&xDoOYS-$BqA;k6fsw0TZ&N?ZED3igjb2ZAn+B=1 zR;n=opeWig8{vhL>q=vN#bj(^bT;Q$ZuE`$9JpdE_z9`M3^2P>fHS~q8_@XTaZN~F zwhlp{Q~?DU%hhZEWsq%L-cGzM5elxX*^Ne!g8jfuFoqjTM(xay_<}%~*e1IiRmsGv zcYYoOfL4k{Q+wk3C0@8VKzwr^=`%AWC4bI7(^7&vpaGt(98scMsC*F#^eYzf-;$~` zoUV8iT53X^A=Fh;7*4T}4OQYY(DR?JZzCxO4HOyy$%F14z{=c5l#J|-H?5VtsJQ>(AIe@1+tvMSr98G$JhaRpLDpzr^f_YT zm!=~Ur7s&)O^lps(9SJ9)a@V_C#m(&(pOb0d?^^I%{DhaN=RL*En>vl2o0A43u?lr zK^>K7Wel=iYK;PZTA9c*AFaDcvGdYtL_Q7Ogr-a5g99`P%av!ZZ`<_&8b13njsE6+o`NP(hnMxZCS9-; z0qT}c{p_y}Ovf&_#-^2f-$9Mr;(LI@1K`ByOaUU_0$eN+)o+Wl{(s?ZkN%$waD+h8 zp8z`uC(X-qA7|}fYxLq2dw=JD9E@}p_V_WkpJmK2T_(c zh5P#vfVKU1HZ;S*U#}`k$UIJ(u8kw~{O`fnw-5 zkxrO$3^Iy~UlAUJe}W50ZMqf(x`O5RRBl+B_P2rHHxcAH_}4hgwMB$Qap6SQvDPC) zjjy|Xf4Dc|0ibcCB*l%g@8@YBOT)|hqZtwY#N>Yv>&CMBrjW6m@BVtQK6MTBy?}J% zjCJwDLQOJ3Nh*Po=~DgL<9nmh*$i}z=x61I7X|Sb8n&G{)xGfu|)l2ZZtp4jaBLE++ZNAew6*x z_qkQ_2B4h?aQ#2gy7!Qbw-WM`8<2R!L^V2DbFn}YbzakWR=irmg?V~tR{K;7BuW;n zExxwY>wob)lI9Wf%3zYvCt0Gp3hTlQ*pC$u9-KQNfhTd3iTPnNKi=Y0=g0-1`TlG( zlkj3*4jCRJ?}jyJ9||u3ES2Pvg@^)J6L9eRasvxZS){Fs>HzS3SZ4{u!2MXmfB8~` zN+VxSwfozx>9Zb{SCYSNqp!#HW3Q+D>h+$#JItOysXsl;cV;;`im_a3F~Y{ zku!d05&vGRzt`$-u!Vcs<#+bS?|%3n-Z(f+#E*l3b%0|CX!c`vko@xy5CY__$I_g9)MfIZ-7l9QfaWR_@N)sNqKKvqtDNP z&7nWvq>F&q)O9NXWYg0iob8^I6Noiejvhd52R7jQAr)i5W}sx9-3B6UK#^&f*GX;@ z9{wLJ@YA4=kyzP}gZ`69?8iYf{xIm6p9YO)rieSJ`#$JWy(pCjq2$UJ3v~G)osm{{ z)-Su!uz)NgXMTIX8g6RL<%JnWUy%DrW`1sX|MNEPQ=l8EwM%B*Q7k9ox$nIh{stw# z*;y91>c{Bo&JPp#CHj(Or1-NvG+RP|iGZt-To8U8v>#9d#*r>DX$xdjEw+DYd*dst z!S&Ekn8(!EKIG~tYA7H1aZCa@baV16)N=pbG4+7{G}JP@j`+Hnl(wRL+X0X)LGpGt z3wW_2Lig$5dp7@yukG!Z9HYJso_&@)N?NhbA5HnYUTm^Z|?QG!R~iI{0~RL-wE1(kLqtw^EasZ-v?^`J-72WsAc^X zYN`A(B>&TDn-@_Y*bE-ee-eRFie-*T`PMPfhdTEShkPrp9D^z_F62vn{r&$msPg}@ zeDL3or}%Mris);RDF26bqLKY`1+ZG{!EbnK{YN~d@e`i%{}rAp)vh!R!>>AXLj_oC zW|X36q@~pIGLS z{{=7OYeoM*peKLlW&Bl?omzZT3Mj~LrkFd9TBJl50P{t;0nqp_-|uXYd!44KIqL;5 z8f2ErqCXb}Aetq7S{EhZxeIVMi*i3fnxyMZ@F>w&>cB|^-*?f;%v5idSQhQGgk{%+ zi!eKsMrW#}n#xS0eKmIN_-&pBOW0-l~^hl8lqJ;y^df)tmRtb!4=hxOI(GTxnH?#KbN?EF1Gw} z-u}-UV;NuDpC5Ax6#X+{$u-)S;h%BYykY^T{ytRCiTp84_q^BC-8HxQ)a14)G z?7*bq-Z1|irzmD${`Q8s0e%(CO9i-mM=cpTdjH;;e7Pf2iCsaSB~wF=7+$?az0_j zDOGnI_Mv{QjmCw zObJx{bN|kF5E%mmp~@i*Zrc6ykuRxnqcg{xteHt91@w8I9YKzLrRu1;D3() z@sCev5P&Ge;VTh@_`87AFK_*N{Lv)V_y1A>DRclGlJJ*6)ZuD3RpUS3TxHIDivauq zim5d6c9}7JadvppiltpZA@T64>b?3GvsD&D?#U9>tA33w$_7QIAEaQquAdliK-8tZ z^Dc{(TGamV{9x|4&BcD}6d2ITYK!-@I_xX==w^EECV|`S3|p_9G=UbMJ3`)DQ&JnT z=aW#Mjae5&rZUk9Oyke|pltecSD|)=3l?cWj#(K+CI{0XA4J1MNMb>jVFUoM(yQ37ec^=U_ z&$Eg}MT#E>LQPgi)&yg7+?yUMe49*)^h-0E@>Y?edLal3Sylxr_hTZ+2jSTSp-V-v zF=F+P=ww}%kk2AE_s`@@T?lo{1qLycXd+MA$uql|W37F`W!U$pLa)tiZWd+*6VPUO zL`!I95hdG~6qPk>m0UL0K5DdAOZPG?m1*?ahr_c*4z?=W4MXg!4E7J=s+oyjMAhK) z50Tc;Adb05C2^(U9-XYGWM*GY@m6p@5{q$OIgezhoBqn2S6_4dk$bdO`jt8V`T^hs z&rbU>bN!>_els?DDF#_gKXUO5(!`uM&=jYa6v_5L3Oq?T`7KNgUx)%-|2U9Af< zs(U+v6OaG@ARgIC7v_CW#NckONMqxcMsW zWFEa+riRrciXzHu-Yq3UR^qGV`D>0lu%|P1aYLtY0#YZ}B`02`yLL0#6SQJ(HPv&+ zbvHalkSzFKzk8A_Bd=X)oQ*oP2lioa{eqE~BI+m>Jnf)3Aenp08luVg`VGxC0t670 z?Y_fb{TTROp@V=1-wR?#hHs%qI(=hEKSfY+S@1e9!exwc*&^Z-RgH8Ge9RvwAmz#P zuoH5=f+d&mxwLve;+2n0z;G%C?=YqL>$)=RD;*uKE>YT%!!*ea>pb3s=^3Yrc3o`ec5bT3E z<~)xosY6^Z8Ydu?odQyO)=zqlE%1!tVAP{$WPmZ%2>?Db^ymXy^t`y%EyS)x_#g%+ z&nL*c$;7IHZyP0uQDmXm1f9qgi;kHPU~WVyF=-48nKT4O6I16Ys^%-lZuFB8X7w-R z<*^4aW+ijN01i(UhU^W=RL;@ns5}$#(;>GcwA=}##3>G3plSEZpjwmjk{@wsew*II zDJL~-0GC6^X7Ex+$!>HV!Gx%?@E*YEZ0d58-@@_`NxLA{hJGc#9W6Zq7nA}@DoVA} z%GpaMTP6@T7HNK(4BD}N$dRMQ$hDFU^~Tx+n*zAKrJ%%{fjqRG8GF>GWCz&ijhgX2 zjOt*hXzLISEJrN``7l?}i4w?Tu0^_LbJN`Hv6M9pMIaBLfRK9q3Cc1^nLn=x-%nQo z;X4@|$b|ICURU5qnQAcPMKU_2${K1>V|?oqI3+N6uL%%I%GVe-9dm#Z0&tZ&f!t`v zeh#=GPqajL2I-@G6*{V^I1VSht0UW_Lp0F^UMP!k9z05LCoqIaxJ2ybnlzgkpzM6$ zZEDtjsx~`c=n+OXk0rKDr7nwXh7To=-r1I$D|xg8Qf(r{zL4U2p_WM+n0rC19DRvn zrrjD`<9lucja1V2!??nTe4wsU(zA?Q?Xq@f2^_CX)`@M+H0=Z>$r3N=hpucTxGwtJ zvI>s6EIC0_S)k->F#~F7y{2(*3@0L|KbeLvF@W01o84H7wbg?ik4jMxQgaVzDi5Gl zFGdT}Jr<;&Mp3R2267HBQK%#_y>+S%w^3cDdA!%VYbX%uF}%$1X|E4WQWF)Ty24Dm z->;}%6O%Z+!gh9lfCnoOSEy>Gwb?YNKU$N}IK0YtYk$a;q&BHfbxkmJf7n*NHf45r zO|)hIh?V_zZJJM-dE3;@QO|()*`-!Gg_MMz2GQ;sZ~Q zHnvC1Ip&Rjip10KB+7JR3iT~6ytnlnP1TmXUXY3ws4>DUO*sYKdSZr-8e4FqMPI?= za-%q+K5ao*V-k?IyUd?Ce+zFkFBBz?I&t^jX#R{#lBayx3pz4*-TqcOEj<Gz+#;%)%ey6H+7^R~z6 z%bTPz$!Uhl{ZT#Dm-c?C>k1mx-7#O@6=}3?>5U!Cw0wDAbp-3N(D=m2-uj{GwE(;< z>eI7NUp}@c>a7N794^rw?X^|2yh$88TswQ}Y}cK(cZC|Cw*ss_%#5{BGm$4ad)pK$smRK6f_ zU$DL}zNarV$(NwXmuSwHWX~5)<%baWL+blc*!nDb_|Y`^(arfW?D+`-Js8FPuSWYZ zRtwxz@aJms=b^H8nepfE7ZMN;pvd(W_6!hD3Xo_DkemxRzeiRE^tvD(D61bR?-|&{ z7O2=1s5%#@z89!T6$C8`)YcEW6_`z$)zeYfN0v->}n# zlFgejX88FekR!^95VbL+IXj`#lp&4oA$X)AY5HVg(vC_U1gL6~wmt7h<~$a&@}lB= zlll>t*C`t2!Z#AR6h2ryyYHZ+ z)%th$lI|Wf-94PU`-Ow+-rijhXDFUQ6#mU9XmV7<1UJE>D3bjsICV7QOf=FUn&M_O zRdV!H$1R#i(J$7b8L4BK&%~f^G6D@^@I3Bv+>7CP6vOu@;30-3D;sut^CoR}Owf@_ zjEGWX!z!CYQ>>jW8f_3YDi8_F)_5X#RR(LFH^;iBcvFQsUK?UJTjL3yzr8f=nlud5xOy@0&y(Eg|MHb}*wAs{>6KoT1sM#2{tdZXXdN^?ES#y#b zawaAu%CHEbe3h(Sis4SuiTJ)!x9&0D!CpPHEA#|P{`^wXmyf(YcFE$wmxZHmWEhC; zHk=ZkOiJOj5I@6vS}%oOF{R{DO2rwAMg?x_KF!Q~43*S=DekFz;&#oOks*&#--;{O zok?pjNNd08%XB@Zuh{>=y|gn_38U2MlV{SW4AN(Arq3m(&nqzu-b;VBpT0ny0X#|q zWKE@DYo-ACR4UofXS7VBGvaRYbS zEz)=;?ltBdxwUL*(un3JGL6j~QLo&Ky*DLEbHtU+Dij%$k;ZGitf6zcnhlvEfr-6Zy8z8=0V8c+jMbq3 zeR5U&_5zbf1(6Lo&e7b{_}TTl(wxeLyK)8U6S2%Q*ETl_LxQtcU6}aoi!zQrCSB+$ zvJWnzOr$hfDT<=83~Q!ra4SxmFU~k9o<_uKfJ+3Diu1fmic(5SLa9ch<4cvT3k)fT z{o^YQOB=jOo3?0jQcCa7m$n_0w$G*g>7zHA~aNmqYtkye#y_oTz+lQ~1uS za&I2_ED4dTlgE->ktXW|-_>k16O&7>tXNWbx7iK9QxI3RUtn2={7zM9xCPtcaUR{NZP z$~~Y(VR172im5(C3Q}QZ*w_o9M?-+YNZVWFomiLc=IbRLV(}d=CMwNye)j~7NC_$E zY@`}_K9a%-@9!^V?mlb=PQvhd5fv*=X`gr)q$E#$A~!-`NRg^pJZe(F=QlbjP&=%` zUe%>{$OfM!BxS-Kx=3|1xFrvFrDLkvn*A|%;^DQo+F+g3D045O?7YeqRiRKV65ZDL zW!W#aLTNz{AOiQrSv;{PI($kS@O#?8K-Jh653swrCrLv+wMm#Jgu9l|X$GX)<1oYg zW_~T*JGZV~vAVLgSL9{Y#;{GB%|RM<7XF?*dnC7kIlFz4oAipaN96<)?c(`f!Slk8 z@=v;Col#|fIu0u{<2WnH1dmQ8ngCS0a1%{dX>yW^OZL=~2EwJ<*>8}=_h~~W9vnS_ zzgZ!Ob^ve=BQ-v@fT|(gt0HALP%Y8q(5AZVwj*srx}CORGPG0`SSHHM z`49or92nH;#?Iyd1yO3+Vv>2(GIITEi*%Eha)iswG{a?*9NWoA8OU=2qcL*5pNy`6 zlI2tedC9t>wVF;Dv^RS*B%2E}%hI%VM&T{WM%s(r&uN@hJfj`h6f2y!X?5N^FyDfy zgLzS||8Y}R9L-1|=0xd$)Z>m09&wBN$}(o1D!V30MqP;N;xWfA_>ED!-GYK$F~~(Z zVw?M4sOh;K#-`0WE=-hXW%o{{QFL|;1#*qw1@d;U7RB|O9I84X*SSyX^#yrRmXM8l zJ;|?c83=nZev>JeMXMLa1c82rgVji1-48LFZ!)SDLL8xu$)+Z6%1usmTzhLZ${g+C z=SV7`BHo2ZC4L!^@1i6@PhUgfoWZ1e!cu2^G8mxA#?}baHimPQlYKHG4SB@$wq@#F zOFefsHN)rH;c!}Qw3d%@j^|@I?(O6G7Py?7XQi;A!#VPW)ae_yvJk6M=A2@R?c+qz zk_x;t0fR_OfNHhkoY+Ogg+z+;5p$E#fTmdaPvPX}bY_vU4pDRfddKwFRf^ngN@;?!LT3`E8ewfvpRI54couta#WueFjRx7;n z^^w!m)v&!ZroNfEZoe{YE4eQ3na!uqx?fU%_)L1RXpqI^RE%mTXR?YNdCpL;)L%aO zfJlW_i^hm?Y$9hN8lS!qF;Br@?b?ci}v zFE>1j(40T5Ui{%OEakZ9m+R#}SKk?6ot70v?SHhysEM=zi*B-`5&r5aU~08Fbqcs* z^y<5(0Pd;P=C@7(pRYE5=GybmmQbIs9Vr-?fGBuye^x@Bq+U#b=JyrTvQbP+sHg6y zy!QW-Q2$IjQuqw9V)&&LJz`2iebTSVi8FEJmHU?Nkrsk1|A*JU8s;C~_!}mEXuWo_ z`$JoZGyiCNgx}vOp^i`pfvzmcCl~3pMUo`cIX_n~w(hk@(de0tue;~QnmDaq%zNq{ z{hWk4NxisnRze-I(rZ?|n0ZFMSY2o9jD)%fNjuV%_0U;_%**-rC=5x5xDPh|DPf?z z|H?h;*UrN~nlQ{tk=qe-I>a;#B|24PD=cPjA=lZAs8KU3^PnZPgD>mSr*9!A4W8by z|AAYGy&G}qze%WV;pMuB-<9jC5bpRW*G1A!sy84B5`I-|_78Gh`{^-LVzcvB=6|Q$ zx$u37_^zR+7R8?>jDM%tEF!m0a3*1FunYX;xo~&sbi$aDJ12QA^nOL|e8@6PC_K73 zSK0?aZ&fCFF0dJr^KePGeVH0YKcxoUe{gCbd^%Mh*uGWSwYBPVm~C4EH$iL8ZwRGxj%DF``2hV{^L_a8#^$kV1*f z&b06V@+l$D>CPZ9D82Ec4E+u(`8gT->CPYrErV+~A zqXY$e@BRlIpSv;fmLDl%9>}&>BsZo%g#RMS(BD3=de^VIG5u-yH|ub0T+54jAN%Ak z$&E>NEwfA7suLtPCc@6gxe7ECv{H8T043SoX6lnA_gO}JolT_dmJlh~r05@2yFgi4 zkyCC=q)|d*wf<61E&`jnmn&SCmG1ABq0g?k!GDr;Odsv{%b%8^uh3sL;9sH;DReld z@Q@vk!vpuoO;NZ?W37RJ`ie;5tQi^lruElo@6X84w?}X=Jt}>0f^^Nt2_US>HFR``Aa@|p1keKel?e5BMOC0OI|uXMf69_~G(7a>xb@wco<$b^ej!9~5dA7a-K0<0{O@y2#mV z&SX+|b&vJrQxFN=_YP7^|CrC~uKK>#nw4{k0wgw(IG{snZU;WC{X*u6a8i=}Xmk6m zi@-S--GyXxep>sPuu$SZIuow5SpYT>SP1{zqNp?V2QC6Tk2`heY>qAe%)n#*+V7v+ z+)ge)batjcAw}m*Asn8LPJ!{>f|cKNVHSAJ(0H;(EGTNKxjm92Kl!0Oj_Ld;XHwO7 zU6@JD?W@{1JK$9Dwo94)KTvJDi=f3)!fis}9dF>gj1Ev}eF#GK)LJTnpx&zO%{Nt} z@7bj!JN60%OY6>_5Nqja5n%wyJYEBw=dfvs8Qo_qmz482%@MEZgAewLW#uU(L zIlzS@c+X1-bE`nGH~zX=X?vKv@VoYK!cLyI5x&!Ar3SHYBY)8od5jHsu(RV3?W37h z;13=N{~ame+TV~8k|u_po$Q$yZgQTUcaM-#!XM_{V653h?<_-ZS`I=Gj{oRE@|iiw z{J$Xkcd-e)DVcw656v()-<-JiR9q2Y$Wn25a(vC&a;;ytrWA`89c3 zb$%*f2Vm5H0-5=)xXZWaWNL6u{&OLof87nqR07z}o8X62_!%(mzhh2bM99pPJtY1INk@SKn-5*pYxD6g{B898C&ZjWD3wMD2{O~`NYbC6q0aJU znnT~uKxQ!b6-em()3N|*8m9ngNNHg&07oM+^MpfZk#yfp3!mvGa}ewSD)P-EHE)z5 zvXl%lNg8@?%AW;Ag`{{p8{vs9${pgED64jYXYQwOp|2+}-rl`)J z`{I53FunrZ4E%0M&3BU+ubKZtB`~Qi7Nsa}&*K*hkkqn#^QI_8_Bbew;mkc?#EW$) z2?uyHJ=wW%lod(mcH=%PNmK``5Jr1=g#$Znoa3z0BorVeiVdVh0f+xmq9|i##DC*( zNCgW6SBQTiL-?=jex|5I)T@C<>Tw3Nbw5fa0=u8_A3N)R zpJc;Y>*j2IuKSi7Za8hN2%Sn4OE$c55|h>-^25AsP$F(lJL4IaIQvT*K`dGEMz7M0 z*^nHMq+K7mvN4bV!^zuI+$tr*ARi4tNy^?owIi9eSHlC7FvPEnTxE2KZzP?IV0ZGH zbtj!^1$D5lbOSm0pWrWoN#_@nPL1y`k6bV>K_o+LvUZ(yD2-wL)eY51?G4+pOOG(d z1HIKc!kZA#mFKYqY*XFIu_{$>5=)^>h6=}s{m5tnPbTxUcR^&+_mNHD$pk!^q(xN) zV?MgAf-r{fNTL7RW{@#9@MQ9Lo=m`+4A$g#u_VdvcX7!@KcYVZ*5rR=P5uIN2to_1 z=T!OUTV8-|_m8yQU`+;V@;}6*1`OCA30M&BzqkQAA6ocD>HRLWa8|(rgceS@^MTr4 zKh}1GHFcYm}c1Qlo&kYx+j zi58aQ}Q-{5Naz7Xvi7y9RgH@1i5F7{7~& zj*R`u^AuQZ65@5z7XJ^72$3+}EvUR360^}Gb< zWN=RA8>+|qnGH1`(>#b z_Ut@py2Z3qP2Wx@CjB@Ls=J{}NM!BXwbdxfcGmPyQZ?ToV1F^Df7+0fX#A;`db9-OCSOJw@W0|R_eRcYXi2K{kVZFNWlI@0(RPkUr!_&jNT|3{Dt)-&8sPS z7(0ZMaA%#Wl|LVUZ?7|knTD1di9({04lWWTd6=hm_t}L^oDod+D?A;gQK*M5oC7N4urLl^MI=X<-ckp4X*3Mv7p<_Z>OOEuIs^dJt&jnjB?_7<$}Iq^y(tlZx`Yq ztZi{a{PT4^D3b!pr2Hff6|BjN8?ZlgLjRLR`T~VG==Sp8S%rZ$d2vG=tjV`-4zz*X zkiX0g0c-N&2JHNr{6*;nq2?geeBq6c!J53dAwIt*gHUr2YW~xFO|T{}Zotm3$={@8 zfAJS{fU^Y)ad1us=VTBv^8bO1%&*CyObS?&!J0h${8U@Q@Qbs<|4abL57p!^2I#q( zykH>?)?~0IgEe_EYVty{Hoiswx&+d{enZvIQlL=t9!KL z{}Zs&UY)rM!P@xbR6c9!t0FH6g{6wyb|RfIG+|nd#%u*gyh2@yM)e@)>!kuvUVCNF zzDiyQSI%E#mwt;B2D)-`JINvTOLI4F&&5lfz2$k!Bap#F1C-Te?SD2(tVi zUi)g8e|Y0>nD}9_>EP4pWg%QSZEb)l&v3!Pr;Pd~d}!tZtxY5=;PGj_k5x~tnxS0o0&d4O81F4udE~EC!NJWuh+vBf zapD0HY!=0Q!_SUAF#|XA*RUyJg>H-+jh~gIgcp0Fq+FSCsS%|gu?`w1Ql z0yp#jowgf9uq|%e4c26^CWAFOt83`#zpy5MaTEtp6AkXJ7q^N2Ap{$UDz~Rzt8^>7ucgF?_rL?N?f#{<8=R9DH^jj?84TE83Rtiv zFK)p8P)+_~fCf?JpuoakK2L!)d2vG=tjS$3_M^ zURLGh5s3gfSCb8l!Kld=!4chLM)!$6 z1@5lF-L<;$+Z+A{v2P=5;SfWq}L^Kor}5XLSc&%ole|n13<2>J&V!qP zpWFnDv4J)D@2kmQl-}>w@?(qn3(l*4&0p)z70$7!Y+KQGIOdy=Gk-*t_AW_&}M zQBCZ=^2~&%Sr#p2*X6SkpXZ($c=xFV$oioWbGPpOFHCgEKS9DIiedDL=#NFzTzjC7-@kYXe66_0?cCv> zru%D&aKg1)BLnRTYxHAD= zc~Jmh8tZYy^=)Gs0(7g|GJ&L92aeNYL;zrX-NYcVzJIj8zUBB8zKE5&6NAO_!4o6a z6Z%!df#YeV0zq*~lVfHLH{tK^dGe3H?``X0;I28tf2%F9Iv9BVD(3?72z9JUF|g8w z0fpHGjTk8$%;to=+|X;M3(0R+9S(YigV>`gbRp>8yL^4?9k>)isSc;HUt443D5z6L zc@TSlRb#KyR+9b8$&&jlqrFq^Qb?jRwt#I_p9@wYjMlHDfJ3D3qOyA!T@<#EN2||O zvm%TktE7y$J3RXii+IoL0ZLe?wcdQnj2iQ zxH8p%e&1+?8$24NW$HQomy_LZtT)7!Yc=*?$*#D;f3mcE|7gEoK24;cGp<5^)qsDA zLZpyiX@!Bvz}0H^$W2kWN@J~ofclC^;jGe1bL)Y?CYq?N#kdDn0Rz|C6{19*ls-6- zGjP4vJ!*R!uFAS`AZVl_YR7QtxvKM{1Hr(OXbgp1wcV=05QJj1sbIQ zfDx`SospOPP)26nD@gg74EX06`BR0Tmyvy-fS{lY1VxrYr2x%GOZaf4SZ{8+%+nB0 zVS8*1qp(DM8hHhSPVQwhT$)z+A1b_~Y9`ke?}FEnd>3yBI??QP#cc+Ru7)do}ZDKcORIfVM?^ck=tRtj$I9*gOiKMW7%$p zyl#fN$r9He+HFd9C22LWI&t5)p{;}n*@3D%x5tKiTgroXT|n6k;3EACbS$XfO$3*+ zvq)Y!d>K#+R@|bDx4gPV{b<@{xZb&Wv~Ajmx>FAlG9A%z8^~?Y<@+cK4Ez#=Wo%8v zPQB3bzkU2VzIxOC$^7hl$Pc&UT_2Ser^ShVb z4~kK+T$N0%Uw5>Lz44hAHhLI!eU2i=jT=8?_}C`m?Y8}=wA(2i&PU+1TGj7)5sldo zH(MGS8QQ-%{5)#5!jExys4A;9TE*Z{r7kDf$=|9q^x;rxvD@U8O@Ya+VWHRd<~F5r zad@%W-@9VceX~6>j$iN6X)YDo(<*p+H9v31#{uv{x4NA1p^lzBfFj;|FRiMh4TOT) zH#ygGv%?X99HT?)yN_M>z-<`cdcOkb$tsbCq0vNLv2aK$?@SHl5hY`2ta|&hpy_iK`4YkSC-_Hi}cze-9uoU*t=9(y>^Th zA>><1?k=_NwMWr}B4n}mXajnuGqT1PNbz6J$bIfc3gN4sl>9Lx_umU=c^GwD?C;LV zmd^AjP1C@p+FIK?Ob@KexFP2@MTuO30al3v*O~iUG3%Wk#AU;;zjuh*u@OzIvdpXj zx}Qa1o)0JAE`2eMLx@d%F~q+{2-!jg*MnMlxGsSD(eDUw`4tB`ez) z=wPrX6s^duyTdxfDQ577)7@y?p@3cfjmHF8&A72-)-^%>jzQ1q5WCJzW#r@gUOsD3 z@pGl~6`Ib-d!pnX$7;Qg)vSzF&nkPIX#GA;cS)RPv0Pnh!25V3#W<}eWp$Z3?-ML8 z#p$%kJ;`Z&pLnV=ZvSxElRKmDlWdl(@Alx(Oqq;Nc2SJiUs+yXBr=pjxD=1)ly4~0 z8cOxAj5pX)-tfSBC@o}3f|0Cz<*_8?A zC(EC{7#+&WUy^9yEdT7)s^RPs#Y8K=@@K6g!#ArhB_4~CfBsHuIH$fc@kCbn^KR?m z+@>W-r;6oY^al*zYFA9Mep3EoC};R~@1>-(ZSpTi8;9?VR3@DtE`K>WI-Ca>bcX8e ztOvwX>4%aX4`KDF&k(8(k)Mdz+xd`QDBYfhBgNU0jRptHg05$2O=iDQO$DS&YAFZ! zyR5)9UqBbc@V;o-qcgtDnyD>$0|(l1^Q}~7QQGyJGvS)T3i!1vXz!9+B;w7Q^ zg&TL26N>FxI9__uh?*Cc$3IKw2~^_4MfVBt-`K-XmRiJbkb0Gpsg-lrHe#WPN29Wg zp97z7Ha))G@*2E>9w5A0`}#f=_xV0u`krk@VS*(*nuc!egnM_PmKz+HP8f+U%~=!E zASnv$d#$7~deAH6x+wMdVKMI<{u?jWx$mxgr=C0dIN2j3-cYea>*;7+_JfSXla(F& z$3~yzFU?GLR_xSYJyu_$l$q*R*=Zm;)==${nI5IsWvo5cSpOh1Gpn-8{LI+Xrlncg z#fsflfn(3wm9lc4RCb@p9edvEk#+0#%3H7ZyxGkthJdPz^_-{3jJ&fdRpM6Xk$b(l zO=8-eRP2dl>3UFk75Ykxb?}w9)qPU=i+^zP`!AeX0bAR=(SeVFp*`~om(HKN5HB( zBF5YYLRS+cwaOmX9rdBx<$w8@cjght%l?)p6V$5rQQVWce7I}#C!H7<`n@IlwjMBf z5c-Dopp~URy_WiN{3;E!5P8^%ioHXZPnKsq)`F3-=D#}3&>G$1v3;n$#S`O=Zo)*w z7y*|Ug-&RmB{NgsYih6@mVYc_+v%$ZM^uEb(oWd==}Yv(KduyBWHy{5hov+S6s)tt zPVv*?gLQ6DX6u~9aoIGSJiT)plZLkK<<_|oFjn^S!kKU|+zsG18-&e%U zyQ)uS?QnTdKGN}7Uny5qe1F-qfQtTd!I_4`bf9u;Tl~O-?LRmI(y3JZpvL*aHyjJ$ z1vc#f`nNV5*#&|sUmpR#)o}bfM?m7=GXnl{!x67bAzy!Q)zD1CvDzyEC~4v0Y_&S7V_NHpN{96_ z)`a7z*q?en6wXqPh}XGQr`06lrF^?9Ufn&gu-YjmyTXy}qOhotnv9=o{O$FIiGeaT z-6t}iWh5Nkw|YO1IfG1*gxTrv>}yY#x@UKog&ihCYuk?t-@!<)#P?Abj=k{9lXBp< zp-^aot{%xpC?(sitY{(^9l4A2NOs^yZ^hj|xRA^cCbfoA4ncW3IIl;JD(=K8}mKUoB2&La=ksjKx@BDcF z1-v7j)Y40Q{uOr>QF~=1IIIpw$4jgu3!%p|KDwRFd>1`_A5h}hNb$s~^+K;Ev2yjM zjR6_dhE%H%mB7|C@5?%daB`-~h!TSJSUiR$xS{$i$1yU+{VHhTFU; zWI1h69mKjM1!z6};2Ot^3vPCY#hk6#pph>bBA>bP3AWeLpzX!9B(9=-Ab{yxx_C;X zWl5Nu^d@gNOYXdFGFqBL9|+`gm~QCUvvTYL!r09txRLudXb@<*v*9@=@YfmdKzY`+}(2eB~&y$V=p(?I0F-iTqP5 zi=XKr^7Lsb5in^ehR*lS2s;_UW(*!eJP!ew_lS?Nh9AiP@HW_!Sk@gE479DxBi>Lr z-zI+#Qx~;^%&y`B?3ixZNS62nPVi7K?|~2ennFZ+o3j(52(oSUDKyr-=iw5plmZ-i zBPte->sITI??Fga)WT#DAyh0rbQMnY5`1Q)`#urMKnINCbik^WgI z^h|q!>yqkoZPc$Y>6(R(ti5h>oot25T$s^5Wp~#U-Kcvmvnz|1m-Sq-Zk8$2OXS_h zi^N8kZ#cFIiy~@nfG_nXEs^o|HWpGce_SHJJ|CH#x7te8XBY}_cj~z*(&mb0OJEAo$sC-p+@vFl-2rYg)+HV};#rc8?){6Fb>aZluA|75fs? z-)tOy@2U0Z(bXCSc__gq+PHCD;3@9bfNQvN=r|eT5t?&r;c;1A^?|kbbV8OrxtM4S z4Y@LS){T3~V?34iy^X=$`jO(5C&iCL({&zhZ_kY!DLbjZJJj&BQIHK%9!S@}j8t=@ zdwrVI(EHU&Mm~Uha=EG62;2Zq{Eu+ z9Rd#T%A=jr3HX?JNv`cbe7*ZJ@uq)ERm5i}EM(>y3?|+pt`_%Abw<n(lwZLy(3+N4PxFb<~8`Iu6M$Fc4yR=oi@vS_M0Z&bDRVR3?c{| z{twcZRu|O1_BTwtDTOdyd{vRJjcz;T^WPvzyW*vkl<@j1WL0VTl#k-=7)ZO~s~nC? zlxXZ(ZXvlPXLiLBUNE~7-EDLt@%H>Qd*A4v3MqWp>%>QgKu{-3G55>bc{S)Q(=A+K zW2>{&Wk&@8*|xC&O}gG~bI|`_2Y55dO^t4Br2)~i*SnTfO|Bv*iDdT=T5P0U@lH>R zluM)5>zF%a3b&E2cjepG&A;BMsQauTXGP74A5BXcDFXnUZC^7~1#)5R`e{9vK|Imp0!g)C}#z==OX238#6{e%CGb8Q77 zd+;X#-nZb88C~H680P<`uJB@Xd#2m~i}S6}<7|GW{WJTb^;w;Nd0+Hz>GlLBM_zyR zKy`#TG4i#f^D74`7gldl()q)IO8=)J1E24U=u~K*NeX2ZkRSu5E;ju}d_uh&G*3jV zlNuT+*8h+~xI=}Q9Wnu6y&xP9KuCW81Pu5Am^vv@36aLqNf_CuMD<;4)0f>5-M6}< zi%{$=Ru1frewXg3pbplRZXhQ=hn4$nx}(V-!8ZNh#?n7cR5iZ8d`XAd+5q%9B<;q* zr;Pd~d}!tZtxY6s)B99M`*aKEs*gzo6jn|)Fs=(oPW$h0U4CD3TJqvn{axC$6naO*O5~YpCx)7wU$zdv ziiVeP*Y#2{hqA6Tcq zV3*I;=>-dMuulJXLj3ow)7KWaPLpu%^@d4vICtl7P3QAT#*;!GUd(jS{~pl#z67T+YJ|5jH)T zagVEb8;dt=jxb)N7N=z2@< z3ON!)PQ^wYp+fLStMhi=EoApdr4QZ2km2eNQ?0kB*%OcFaoa4Xjb(*sC&Rf7aq%|* zhzAlD$#Qzz6`MKIGieLx4Z#D!WHWfRDH8qnNzWe-1GoHjZ6M99rYeE19F)XM;be;%5I!Xnngm~{Lw!;H$P(seSlSiNNs$z|3w@hEFm3I~|4 zGQhE^`R(MxZNU0nsH7Fmr?tE#foc*C8h?NnU&2BgTkRYpFWFY2St40gNN|3W5=t9b zobzUa>|!@gk1}fH=9rkuDTG7VX}MDp5Q4sQf=v)cGP}lb72dO5mV{GIbUQ@1 zi<$x|0l|h|ia<53XsN%xo~pnZr`+6LYvjpyt>;8bOZbU#EMaw6%CUP=;cTTxi&iiY z>>})2(0LnW?MxGo((1nENU_JP(o%JiWq!l3BBa3HMfGw+!vS_UvY@Vk_R0%A_9cEU z1dUgZw(W)KL!o=i5AYB?a!mE8E?o@XBeYR8;B4e^DD;zeOb98td6CVuX+N3V6d1we z_8+r-UJQ7~41c)41pRlyGqNJaYaTEFrVk&82O{_? zf9|bM`7)w4fUYJI+ja-Tte$MMjXrYW-L_yLp2A_kY?tkQc{{#4ez!_k31aC!lEh4l z+b|0y)Xmjch(LA_`dIf_+Ij~HcE5Y-fbB6hG^;g$aYAz`qb@y_UV_u}RIf(@2_*3A za~q5(Q&6#;&WJA58_o)nmXOi1%aES|IT3g`)-oH z*Uo)-Lqfs+KXD#X{O|%*D1;ylsr4pW@Dl4&age}z{bfwu^6PEI;OK{PqIk`h;?;iQ z&g`~yLq>4L@soMb9j3ObC>dTrms)jevi^9QGaWxR1u}W?9J8;#7?7Wb6rlmy$Kb%E zo}>#Tl%B~{hFbpdj+Bri4qW(Vn$_g@q2p3cqSEyrh%j#${X0PyD(y0ar;D^hjHhFs zQ5f>EtkVequu*-s5=om}$j4#p*2zmk-9Pl0qz_q>=YL>H8e5+m{F*Rwc$w6d9!{qH*%|7vm04M z6MxEMxl6i_JVUP)2zF$^DG_*TJd$IAHmu@MDlg=~vjT?b&EocSH34rM+16zNrIvO_ z_h&1R25)6RP<`N9Z`f7G=PraPk?_05ySdd|)srS)BfLBAq2XyBgRvP?5^_;?w@c}`YSYo|f}6Bdx~0+Z zy7P`x5^|nq?B-Osp(LqG`qbn*v$HuKW|6H9Ua!++E-{K>`vl)&kD@^%?)C+3uofUEB7tkBP~;;f!Dqo=0BA#MH?gP50*2)36EUG zB05>T#ZG%YRN_^bI5;kgBj_z-(q(^GCSEJlLA7Q&pT&B4y zJc%%R`sS|lkdE@TD(Ys@J+~*8u>&?l0D$fZfda4ll2|EwU4WI@c^5i+Y^Xm3!*2A7 zqqg>}?K--4jF#X4v#LJZ$_vN}afy433sCm*0+ert??Snj0bTWW`%xtXq8Ie+X|E}= z(T-ItXj>>G40FsJOGOz{?M&sR+sm8{M-lX##iZFJ){_<7LqmX#zOU#M5lr;P4^eA6 zT_|iZR|QrTtdpa|GF384Ll{EbOgFi}CS;4Za!A{B?q)@%F&0DAEo@F~Z(*chD&b=g z;-=UeI#iZjgkh8Ma!z08gMgM!epI?5^=&hWNc($xl9ce`uO*^+Yq(=f5qNKZ z@ijxwaOp;p@SQW-gS*2pB0CGWy^opFvV6fDn_;5D&3;#D{9-{IDG`Ypd+pt9Cd)2w zpK5BNlK7OQWoaN2GOJ~25M%jC%kp2khC6gNVOo1|n!QxQiUjIE3Qv$X=y*teVlU-5 z9{ehMiF^lTtG~c<+!tDwy%%w9*J-X^To5hGpJ6YZZncw)WDd&}~=8#Gf&SN~|*Xs+e-fJ;h0W#SPP9<)f}>#2#>=Dlam z9l!Ka@j$xX-CdQO7gTBS>ANwa_;}t4Y%wu>Vu+=be!TCcy{A{ubH5{ZWLuIhsCL17 z_X}yj9tP_`F-@NQKz`4K@e(EI3B|Xr{?PqAD9nfh_6a5qbrRhBec(TkORfwd=x$3Q~Xh$)vJ|A=^ z{~7AnE<01$+HbvsJal+R{Yt`HnQ@5|fre-#Ga%e2#jYM9DBXxEM_aBzxLWMPrN5F$ z-YV^KaXFirEy|;vwrJx!YCGtL@YSmyVK%?>G}uh{0P^qStGnOZ&3o5Ns{igWp$B4X zBOwX>sMp7HMH;$?Ric`p7*M}wmV+5~rH*5t)7xqW{VPn%FUwF#M_x6}{Lt*9hkM)V zr19V|r#hna^rC06d5XMWZ>PF*dy77Ar)Kr~l(nE!@;Ugs7cHz{GwoEx{`<63?bKR{ zi+xAvj{L=a+Zt6BxwYi%ch_uDWUNuum{|LmOwTMsSNTZS`zLnBOHSyic#@6@hg>fS z?^E%+J@oVogPOlKecpj!%EX5VxSgVT1UqXS5s`k8w1`v57eD^s&T{UQmB6ESsc~Jo zGC0CRIY`3#3%77YK>18v)tNnGgO7daCd7*jiAaFb<^X1d(zItnW*0vk24K+1w+6ee z9a%mie@G3ZUSBS*GWIU_!tH_4I4m@1koF8#z-Fvm3tDTqBa2lTb=*#MBtlvAjLRF_ zWz7d5!YSLeZ7A)RhaMnN#i>wOR?2l~nPCjqc1n+)waRSvVkIHD<0;ClT?bhxOA91u zUm%_3_J$}C3|{50&gpeVmNo+`8Ku#}4rg0dhpn*8#&Gm|Ufj)GKT%?s$CjGxIzk`1#IvuI4Iy^WAZ*e#veBsD$r z2>^mX3}nYwlawuvMeZ6lC9KeGCP_`VTE;L7LPUuV*X}>chR>V%W@VnYD6-AThLfmJ zkJ}i8)V?hnPRW`79og`IX{+VBKJ!zn_3tK%FRgVI%Opi0M`nEuRUApL7|B#87snU( z%v;q42H!4Ej*Q};9hM^he+9|K$MIJ^V~&E+ZFcKu+1 zYk|ZG&m9~O$ZZov0(q+x2v3vzmLfKBo*EZCjN|YjPX*<; z&m{WK2t#aOGH__JjBCO?iT=~gR1Umvf_LW6O7xRrEj&jNg_6(%hnX zmum5tlT?>FudNwv&@d;de%V4m-~4@Uc3(@04{uMrWfTBB@ROgBRL9z{o|I*tmQ*Kk zjKrDJs{5uS)vNYzIuvBV9Y|r7eS4Z?loXrO{}e5?M6KcI7`;)GElE9DciT==ElvKC1Vx=Sr_&)VER^g!w&gm`6^}5#oX}>bl5RmpOGkSWQ z(__ute&zf_`M$y_J-y2e^BaQH9KE1;tEe?eo&6D6q(aI10S1SXShee`A@mR=z(jhr zl>ixnuD&dYj~gOPZ@M|TSscKX)UR{wJ#gPPqSK2K#fpNQ!gH-kmmwd&Id1j zhBw(QlevzJ5SGK9f2DN2ed2TG-F#00oc@0L_T7=n-X|}`dc-#xy$eh@m^CCSh?*r3 zlfJMPLJOe-R+7H(3F!-&xd^^u+JR7l@gYyTyUx%qI94)pA1^m#QsOMOh=s`(r!}$8 z2d@hSILQDU0c}gC4KdwDhj1{kyS!D+02Z=50_O`+qN?;y!7JKsQR6^ZA2ZzL!V7^B zc$8g>F0ikCb?Yjf3pOZ0m|O<8*`^@IkTtV{si`9`dG+qZh|_BEN|9v5zI0x?_JW*~ zl;-fg%Q3lpurw-koN}u)WyBxhfIc)ziQ#oHRZPpjGry~`^c_6-UN=)CQ z7#(|8v7C&|=TDQmgz1?_^e~@(n@=IjN#9CO`qqb2-^yrHo2RZ#l{qTws%rzopvZxK zfma;b5oq*>HYBM}pv0JuW^rS@?a-V{9sDu61!(O?xRGp8D8>`D7P{fXviv+B*vX~t zT$?bvJcKD)X-aFjlCw+LR8wUZ~qW;5oiO9t*|^-g`lbI}1v=zKiRdy*4-#-ucT-Er?D z@@f36-rF>-YVN78k~mA|)cJvUalj zquCz1?>ue221^T+I^fPvGM5Na%7<;O8GR-~h$*`+WUrbLo5Fj*R#$#>JP?LyH~}ZaCTbC>;CzFa!A6F6yIrZFT@2^ZFer7> ze8W~asvV-^bjyubuBa^@uZ(Y2kB=(573c*22*j%?2pDs*kZ_e_8>4Q z?lYO0uzGws3%4UB85&64ke>&GcX?4ZSm;Rsl&cy|;21d@b%vFzo@J+m!c^CrnbB%m zu_|8TfzK zbvX({(D%8*u2tP$bpUr2`Zk7OBIjxPl&!NpC0X~9_6mYt!@E~|J>a+r6T{v&;;O(P zIp#ENjJ$S)&g9r=ow?0{F0{F=%T?}b-}5RQuXAVPb~-clLJ*|P#7O$W^6B5QAV47f zmU&y(>i55W>+rY-| zn6y7IuhEP$x$s5O6)t-gU$z^1w2v+q#wIcy50SG?q9;ep{067LZ;14L%K-+`_Z5=9 zkIo;jd)F2q=V8XaJHRW1$xI)U<$(}@l@yb?*fIug+dNX{6%+zWoz_x^(I_KbWZc%5 zrju2hm*4fGly*fkHLbO|K)vBkMg0J0xg&aoaVKumK|Ay|_~fQlo4BPy=GtvT& zZMU8#H>w|4cQ;f}U=$Whh>(wyX%IP%(`b2;$qqM9rO&V9NKhtAx7unU$Q^}SQBOvY z=7>Q9os_q+S1ZKxAVZDo!Z(^eh=vL!3x=2`{>BKrR^xZrd4hu(JM%&zmK@gd8Y^)gGGk5?EpjcS}`!!@REFfJb z4iI5b<(sOmW&WGgGHHN~QF89vEg#{zmq$tmupM}i?zcie&X1_|hAxKIK;|;NA^H2g z1Ce#HxDwLO!$Uzym55Eb=6~glfOmv4`N(6WnGGM1nQrnlS^vHhL{;g{+Z71K`#fax zuv0Tgf|sOU#f-bs{MOAGx$es`>5J3YK@j3T&wF9Y4F~1K^=hhhBe~&3M!))v#w6k2 znI8U?T~0Fl)S|`|Qot}YE=kp5Le{$ssY=kN=2kWGxY_8T9fYCvARhhDemGcZCof4M zo;)MoC#XOmpl1J>MgZOG*^`@eZdCjx#V(OPB4cnS%+usfPX8f!ukApX)GlFU3|VN- zdxNp1He$~X1ltTfrj9r>qQl90?nC<-u{$lvS^a0nbc)TFbwUg7h)rmp5r8ud`L7up zIk_1i++)eCmxK!Ixs5FsG>sO0NtTvLXS>JZSG*T^e?Zzsh69)EHcmO0%1NUik%YYz zBFp~i{K38=WDbc00?Yq1`D0iI5PEj z@d8-Dp%{5ofg}!U3bo=5L<0_`>`+2}(F!sktpExM^#*Xym|vAc>$elCci1D+0oj#n z^m)lPB&0iItg&cuK8vtSm^U;eKbnmjtEq(}~ zNc4b?W!1WO6&oMQa4H-v#a`e_t;UQ$+T;S*+#0N9UB$PlZtWw5v`U?${zt3H?lKQK zsvXgz1~N^pGMzB!XRa7bdjB$}BL||>N+QzPq~vI2+ol3+yygUS3Pkt9?kJa43q#oU zRE&Ytr0&NfBq?kbqHzTwupk6>v1}awe^82$FZcTiD&=2dx;(E+w}m+KkG4nnnUB7W zj!GPT7oXKV+L2t$Kh~N4#C)tPyDf37`_^#x&nR$zi%dP`;einK$UF0KeYHSA3lggT zJ3;&V5~{xvv`JqJTECln7CC4sL_NgMer!=3s69?}Yj9OHcVqnEwN7 z^E6;)D@p8R1olgoHaXv{&Gb+ls2%(}ZGt;Gqk-+bUH&))liyA|_$!;>uaYD#WG{AY z&d_lCMeShU>NZuQL`5VT0nu&FxFU3s539c-5M@u3mEov3Xh98kXG#WAZC|bezM8pC z`Y-k>AoG_qmqWFxYJDPoYVTffqYyp|J*)@i&ELhw&sq6)#HZI8cO+!D#&#s$8hY1} zluypvnOwkN(h16&|0K0@!PbCN5^cR7QJ3E+@1Sg|J@r~pyKF(U%f{G#-)+LbK{j=P z)_>pJBv62xgx{+l|D7>q|IC1$Uz5Kmz2Jtw<3(j|R?o|PuqLY;zXfaZcl1R6nIS%3 z%6xi91_hJ>{`nTBGtPi}7}2(Oov42Z=l#n#%|KyF31`!mvY(;DrY+GW__S7qNV%~n z=A<9wkK7$ML(x-dmZWo8mD%-lj-odmu;%rA(-ge}4{qHYXsag8$t+g}BwA{Jc23sS zm!O%Z=y9z=Qh_M5u7&eW-VjSOqdY?5>=#2JKnZ%?Rm&L*Q{pBM16ay85*A)gT zx3);3I`CU4u2svV8Ar_h^{Cf2?Vk@V*YTFbyC{ znJa`+X^^DMr*6_x?K0o1d6v1u0v0Kfnn;DU2X09=BQyY?hDmCmBM zH@k6c@Xt(m`pLbS-nQxal=@qq4H-3yLiSfhmn<6eKeCgjQs10=b4JILn*vU7%vyQG=(WNUU-8akooVs&nM3<)JN+gd*V4l}aslUy!lT(J5lH^KA>Tgq`OPzuN zaPc|yHxfH}gUvhh`En(PAT)G+rSsgI{e1f+B;s{Qsc*P*pbA65H%Ll-6RUxpbE(gG zjX2+NYwWI1sn6`-c2a#S|q+HS)pCGh67pIV%=dli7G6{C9+*Q9l1`d}Q zZQrQiV^(MxEJsl0ztI{DOGKm52r>yM6bW^R{h*4~(B91nN9aqimP5NJEjF=AUUJbR?p3+wB|!;= zU}!T@a3N-&R3JKjpV_;|ibjxY0h>(@aMM0Ct3fHW_b~@+ylS$+sfKqCd(7>qW7QB?N0FBVyA)$`FDU;FLOJQ2ejP|O zRW{4nov1Yw94;ofN3Trxst`U^kq=-p4R9cnr$?x4HKE0_)=?3MSQE@FjAh3Nef$nd zt4|~zfQ&zRe4-;M>hTd52#pt9^i-JEadxCbte>I+Bre*Fk8ha{P!`0H9Xt5eYm1k| zLE6(d5)|(-5=?3shE^+HDW9yiT-?tQ%1i21e6hhpB&gproE4NLOoXxW_M@>pmckWU&@^|SftQco$2VY z2w;R)wZ^)!jvR6e`gRj`OynJuh5?ZyBl#GArj05vr^N6%jGNH(SYsu|e*m9k(pG+0 zcd{-~r}vGASgeDuN@m@8c6%%0Q^kX#!wFg$>mLc4=$~ajK^+icuDdMotxPYaB3nRsldoA;=_*a`e7`%zjy-hVOn~~9!K{5Z-X9{4bz~); zD7fFrPY&6y74UF>*?)*H=UnUp$D_9ommB2e0I%;RY@bC?i4N+G_@*Fa6OfJwB0$LB-2 zY)zGjAJQZICDq_z03X@u7UL*O zDISG3Q@`;CaKxYo+1mP7BNL?*SCe6|TT10DV$r6-Q37$RTZUpM;x4ntKFhd0^pIaH zHE>5Nr}$b&&$8Qn0m2iz_KCcBU=D53+y2(*D1%n5@jg`YlHnfFMvD)^I&FLRrxH!< zk@{Jl^bxy$W&(Ul_n!=Sr4b*$-mtSzUMht2Dyg$hmrA(P^ zP+eqll|!=yzTZ~u0B4;#5w3tgZndgjW0&yp%9Hz#`l&zPqHgP~0lLy{jeG`+jpXO845#Eo8|9l$}pR?meGruD<02Z{5LjoF=KQI_HN@_c_bab5KH08Hy1z z52>;nos^-%5MZKL%$9`e8kXoGqMcF9G9?cB?_#oDeFS=fBwTK2v}hs*+Q zSgm;PwAJqnRN^9cw9|zXrcNsjShs4ubJ`Q2Zgo8quEuVdpsr@7=@JlS>#n)?VeMgw z5M6;A#|2sqRkJLQkDMN%HR5B}tH{*o%%D_%FP-bFTAyY1id+~G;`D42Ijl})bh9SB z+U!v4KB;z%%M@mJqL4Z7^^M-!<{28n{>R=~$3>m4{eKt+n4uiHae$#iT2i{ZyE_G> zR6uHANa>J}PD$yK4nd?r1O%i-1q@ISez@!Iv*+2fzY}}TdE7nx{rzv|b>G*0UDxOH z{`eT{@aezNb5r%w?XcAsku}4y^LT}RgZ#+IecH5%&trMZ6}2c}8+j#U-AQvSPUfSJ z)ZF!BCW|j%HBxYB-&(lqhU*jF#DooX`4CgDGlVs6ae!d6-$9?g>x`l7oNZ=3M29Y6 z&Bq5EbVm(rkS`s;u&tCX=c`_7bO#X}sH00nqAg1n%|8&Y=xY$BZ_$)uMTW4ZNe?!7 zW59J8D!3OhM%FqS0 z(K~m@Cv~i+dWYE_2$)(k*a~{<0vUp_+`W`AtnAS2^}WNcAKi()sUMVLiH)JtC-h&qgO!b3c^NE2G3xwYsJn$xW5Dbnz2PZH#@L5CbVIlT$Bm(O}% z#z#KA*YpN0MG2LKs^0V{*fw{j$gC|L%nNk`EOq?1o0DGHrBmzVctO zKRM`u^#Mw0QLgpL^bKebM%`zJ8s#J*wuq3!Ufn(&W3P2x>f(Gfh(1P*ql=7XN?$=h zQ)(&XN|*+JMVbWs~dt`W}qU5dV(afM>d**AxfAi z%KTx9Xv7*%nCydFw6Sv)!yaoR&gL~E=e3PfBC&EyZgJ&W9Nh~QDv81@jV-p#3Dvd> zE3F#Ry6Q^tepql)9U3ds;ANq8f+^jLo2FUDqi&#GRf&fG;W+)Kfq$F z7=^1{>e5(qtX%6;!zsark2@d`dXb(-b`vw1alOA5;@UW-DN`PPa3pu z`3eW1)8C^g%fp8KFJSmLc%1x?oZiXeuY^m*`m(Q_UdP49_2siwe*v@_{)?8;_ubCl zY#IN2!0lV03S^2MF8~mAtC#T=#E%0^8^-tUa zx6b1~&u;-adC3xZPUx&bq?9%(2{G+v0FyNy5F02}1G1n~U=qi=X|Fn0DS zCx(N;ajVI{jHtW>v|q8-%#1b^^v|Iv0(f2M{4qrw0haG&@` zdNc~)TrSFael}20PySH=QVfdf-zK$RG~0h91mXMNNsnIpx}V)DD*uc9?B7X`{vn;~ zD?R!@)@(P4x0x9Hj5PW-b=v=Z4(yA5^S|hE`R6q{e4mfY-`j6?*AY;`>!h*FI*Q} z`Ejx=+XYD%u8SX(j31xb7gv0ocW(S^O2+T=i2urU@ncQ?T}-8maq)lAi~i4BlYjF? ze-1cY^HEc6UXVA&ZD6`rRq>xDlN8d&2TDw>zCAl*%+oysG;uiN}mL5+h65975a z!MvQ-L;ZO#TpZi7PLqwXmzI1VDX*OObzJ-l>9P0gs>pfTRdGpVpR+=4lsWdf>*8E` zjISPL``(hg717Vfj}`7}txNIp+;tIV6FXT$N&VV4{byv-`O_bK4&i48{kWC-N2bd^ zW*yoLfH-~;EB$jIE0tnh$*=O)F61h_Gk@%?L;imaLi`sFhhOH~|3@cizYb*0`!_DC z+u}K?s!k4ofUc8wV{%u%yr0s${^f%ZF!0OAn#8Uzhs)ttIu_=!v`>$=imOgP?>4?Y zJ>DC*a(43mD+~F2QB4H=taUCk`!RqH1YpZNCoU#~&hzfivv(lpVP5}m_6{3rXQsl1 z%It#t|Hm49|N7YW{2Pz$$^IbY`LP|j`u3N{cFwNq%f|(uw?7=))1$T2>!+W#iq)>; zQ=sJr6o?xWo*loReLHjVakJ_xaq$ra^C?yi07JeLNWK>cRz80n40hh7$@ywbQjCLj zDSSg5{X#eP`(FLO$s@$L;1T}W_$PnbIsU^lR@oPU7#v5M!6dFtOJK^%qt(C8Bm9qw zMCh=jSAi>+Kr0^(--^XgeZCLC0K>lEouBKGI0j5{b_MvJnIRJxpIU(PMB|&`u!Iwf z10G2EgKq46j(_g8E-(gY{#CCv9&Z=b53l|_=vi_iAn|=%5UQXh3fq=M5K|4)Apy8P z4=J54G9HoEbsryxsgLFso`Zq_HuxsKY*-Rkl-bCoGjOeJrZg;uKW_$)uLdmyo*RQk z)@PBY4p5Okk8Y=YLb}3~&Z;Vd2_!pr2{sc*;}#%8+s4VNY7r8TYZ$^nPly^j2jopR zBC?V&=|ssG?c3vNe4QU_!W`n1O)(((@Iq@`4wwnG^}jbL?y4CNdprU;1IzU>cZX&?QeKrW zAqowuPGnn>-joZDQ*oJ}bYE!OJlaV|?fkh-`FX#&`+HRN7t@f7X$b2dKeFY?ckCLQmwXxuNRjKTJcAFf`5|jo4rELLvPQ0mSb~RJaE# ze|f?c&O4ed(9Z8U;kT48d@~nWW=((ej;7*!JK?_=M4UO|e?EWtWMmxOZ#`lZ=lQvJ zIiE?$pP%4u(Dpw+li;)pxNyGxx2OpI%%jAP@8krF=|RzIs?JA=QfYw_lD%JJ)h0q8 zbz<(GZ!7?yoMRxeN)fteD)n_^F_`^{tmqE5v6lE>m|4{U`yi@so)tC#sH-yw?b1*D zqst81$X@f_C{iBBg~6Kqfx9rNUq^iZZuHx5!)tvw2D@tVtA@(O*1y}#YQPwX$fye- zmT!FcO*J6&GG*o`{!u0|BeAdl|7JC+VWzUgAqrE!A<}6G%wLSQw;sNAmAi80T&XQ` z^lodi-0W#b`|;u4%i;TKk2<~_AH93^;_0JD=RfFQ;UA@mVyuLoKf5g~HcT!8M*mIv zS|v7%Vb0Vej}hM4e_vAKZ!RI_I6kc<{a+!{zikJ89qckb@kE>@xD)*c&x-kR9^E(o z(eeSeG&IOw;;W453P-+Z4({Fgq13-8}|fjGbD zllOc7^A`GFD+#~P1N(Q?AQ&?xv0q( zHTm3>^Rv4DXSLf8T9{wfYA*Y|I= zj9gRp7|WUepUCXLZ5gqtKq2;M8EJmF`Sct#$uVs6Q)KqN!snqtrN*Bkvws?FIo0C) zFHt6)t*wB_KN^|cDRIL1Rd=mV0!9B9MrQw!X4n627Z_Iqz8 zjIf_#(f(0A84&O@_yOy8r6yhU?jgX9c zunTud7V~SIqB|W*sIprqlQNC7YDu>veJ*0-UJka!`E{ZghTz{N#)k$2f)?J=iEmj* z+zDpNqT1L)mi5r!H)3?to5~?UpH}>7VNg0DccCl1kop1vDh^Y30aMQ*(&&=jE5xjr z;Ah>Qb>{sWFqBBnpnT8nIoTC`E(WWT{Gx*+d<8;4%pM{8J{+?ro&RIu=2CU_2)YY^LO1z7ps6j`kmw$$J>6!@~TMbiQ}t^ zrj4>!m2Dq)UR8CXv+h>+5*G&bdOV`iYmj9U&nZD0E>8mSN z-7Mq&|Si8?It97(}`bXXLP+6uQ-1Ofg zv=a!H&X0RT@>4e1&s75SyQ;*+%k_^}C8Ffnq$f-MayZQ@Q9SBcUZ}KKR$d6+{jDk? z%lf)*N;gBNV#fBEzG2?`)$7LPus;E^?E9?}-(Id&B#pmDwEp8&Vx`)H{=5-}a`CoV zG%6PU&@4qkQYm1}yoPl4YG5#0PN-vgH-__FUFFG?R6mjam zdujC;$$w+#&yj+1h@1BV=WKR0`fqd2zUR)2f9GGV#{SnVtuo00=!_4{@G-CMen%-N zqu&X-@GlJ)zsWiKt%(jSinOR}^XH-MZ%$?Y*N6X+p8U|jf8AtL|J4Q_2>9>36wog& zh5yf(_s0g_>GeN9=FKF(jn0^Px%>ON6#g$8_*vATKneNiOJ6fq&M$@bjHlnCk#e41 zg?1Z`ooB4by2hVJAz|l4kA#DQ=hOlTCqY1>{%W)z;D>+bn0KNqh~qam*_OWnKa}rd zG5iJm(4FIqK%VqbS~+UMezbj31li;u3#58K#w|L(amHSpd$13YP`_~c)#0O9B!<7@hA`#i(0v*C ztM^}i4tpChtM05cZbtxB9IQ*1TmG=Q90HZyO7qtyW6}yiPh&vwm!C>axSkOxJLN+1 zg)zZ19U?#kL^lw?kD_-$epFh5{JK59Eegy$0XMq`wIhDNtx7Tg2bed1?v zxNp0&`*7^@REcGBna*qF*=rE}22}T9b(baCuXDqXd@gbY5LPC|PGV4JvshO~Y8&79 z@PZ;drTlHj3Ab&PtP&=1r8a7!-d^Juh6j7y45i1ZJp?tM#~w*aw8d4h<676GFu0EF z4ZyC_wpaS)=+;Ri_Sdk2kg;uI8n^k7J6yu8D6NTQ7^9F-X z&OTB7SI&+PuuN{BNNP?nn7#uBmD@I&5xjRTTsrpFu;^$=~fPD7w((NNV5~eMgBrD zdIc7JY#Q}T#hZ=J5N0|G4M3*QMx~JKxcssL4F7O&AfQyi?uqhmh3^1L_L2^7BP`y=aJnNAMFC`_{2p9_=8IL8)N(8hmKyMLd zlID4Y%L0OH;>Nb4Z!G(CzF3y=Td{h%i(Vq~=!>j~CO8k4t|h$-htU;~uAYWkE3w8- zMA}6Zy)X`mTkt!`SQf#J4vedcEO7`Qm!f-sImD-mI~m*Sr)uJ8ARl2~o9!+vAJT+& z7D_(DmEesXOD_YWYVx|2I{bcBq-SU>Yy%k;Bw`_g!94hgp3tpd8kr6CBIaWD%+si| z@um(2@kxYBcN1=t5II0qL*2vPYG)sNW2n=(jKehdicw0Mg`-99!h}B18UQ-A1b`E{ z@+v#NxU=$z=*LMxo;HdF#cfVcc3g=pwwd_mxdoXjI1uQ8Ayfqyi*|kFt-?_R6hc8?pAhjT@G7OiTgef}LDE>rL>zzse8+*E5%W(Iz=1!J#Wl_k2grL?K3ZD4gV2KmZ65?zuVg>LK1e zA1r3MoT*_`+ReKLw`KQly%dI`fN21UdyW~ldVvIaTZNb(|cIX>rnBTFUktx8$M6{z>I_HBG+Q_h|tYZz4s<)Mqv^t1)NgM zBj)HewZ5?9iaia?fex7`pXtE-gTx}UuVOJ`2WT8IZYYW_gnP;^_Mfe)l3*_*g46QG z$g23tQ{}?Aoi{hooBD=}IZ;CGg9x+qn*n7yJtq8a-vgLWfE*YzRX=NCPRYD}M>$Z%2mCf$CF2Ep>tN`yw5y)A9uJ;vILxAMpeH zVEtDlT4jc9PWm?j^m*}3Io?nSxL9Ik#NCIBK3d;bsex@!BhRw7vo~z+Ckz6|Kh{&4 z77e%VMMEN9=X+reJ;U>OeH2ax#NE&c%E1&8tcMiBAh2RCPdsf!b?Ik#6e0|g=$$xg z;3h(wjfaQzn8)I|P+3uk;PZ?>6qr1SMB4G|OaA~YADp_twUI?_Dh;3okRud*c5k#Xf zW>5doejwD_nA8w0i0Tvp#otp@<%8O8`h$X~{A`TL@DvVH@3`snpt%_f!J+zr5Pfx< ztZ}KeWlirCXZHi2c^$e&_uHslKC2{V1rn)` za8D6?xT4-gb6#(WC1hR6;q3SP|(ylev%Y#^& z1Il5T#2R#%d#; zR6{-#9d-+2oJ^Kfn@odwfeVE)4yIL&g1Hi`7ff<615q}Iq;F7e+XAwy>BtO}3p#Zh z26WJaSRV33p~u6l;{fCn=pwq9qTyQJXG}f@fq;fuvNT(`xb;=sBMOpDV{oq4NrSL8 zl*RZ4mDWb6!xXfl(ETYA;p_{wvrl@}l&ruLrI3Sm4~mKI7XGDC;ij&Xmbhwv!gWN- zUFks_MW`?NR(Pa2G?I}b+9!H}?p6#~sdbqyfF$6kvQt;zyZ zrxO%0XHyjKstill;ndejv7@k)SJ;zE=#+es3OKffuYQQs<$JUF60?k0r z0bPY;u)k+g>8CXqqe)2io=any03kuzbjhS31&7Sxpqm9Wki=RY@m`5qo68Bys*?1y zm}w!_Bx)iFv{>7Y?}Lnt$+DTwdQ6@)Izpgm9(Dj<`&3bMw?{=HYh#!a>X<=#P(Mau z9$TMCH--s9@=gmtQAsMW2GAJ9WUZ6r$N)8^r!opOpWpY;2_#2z036JKXvr80mo+WN zAw{rsIx;|k2J^fG6I%h*hi#}HpKe)%U$GQI4GvL+d(gyBtFwrs)GaATv#!H zoX;ucod7Twgb@)*;GQMyCFrhgELg{E6qjPRiC7gZyq1U;4@mJwRk%|e*xPUyQyn+7 z2wbq7@*D~X_VqzmPc>4+G%hna?G-!ep$aSFx|*IhCxJfBizr*y_N_tT(7}``Gbvn$ zn3)3*JI=syG=D*;&KW1@)y$0oCIE_C;z2{nEk4aD_`T|n7AH0Uf=;UyU3Af6z{0*q z^CY@8AP*%D1|V@wp5)+XpfypHP=M+MkvrY;D96gxx?hV%bXE5T8lEj9F|UB8QI1wH z#LN+-Jzb3G_$-r|6Eta2Fe+a-qsS9!dAA72mf`02h)fNldAAQvTu4kWE>6GIW5qs8 z-C=o?i>aa*Bo!aRrWgr*YY-2aAWNP|mDD75(PS=gmD*096Z%*q6-(MlEzabwwF1Wvwlo;~5W*TdIvHYl52NHJWN}w>D*v zxTLnWJ#V#>YV4qB>lSY7HEQcuBE7^2<*{rXc-}U8+%`thJ|WybWz=rn(?-~(N8PWK zQ*Tc85cc+Ly`41ZAp&HHEx{)Ov>GD9+qQ3iQ{K|4M36!!$b{weUgFUc1peG{$I0_Y z2uWL-6^6W5k3hzqS7|x~yC}4ecn@b9a`Oq4Z94Hqx&S~iyD0UH^nm#x*Fyr^0We$5 zc)Q-JGO7d|Z4J&toVDssAq6+8JT4bVM-Yni6bX02;vLglJ6vWEB^1V!iap}Htv3eo z4APpOOQ{D`|`Oxo3f-$HMoR=!rd2 zMel{SE(}kMv@q-3T#TR*>6W-&m|WxTPqv#6u^0-|hLT_fpzoV*Lq9rduYIe7eOJ3ZBGw--=oY!O3rWMmZci5$cP4_7PVvyC>E zL!-NNQ|eDF*H>7N;kLr_G-eD7~JxrV3|NnbwvjdGp{}Fr}eWmMDLFdUpX^_|QylJsG9f zj7|HjR!i8rG9J2SlHO~hIU2|r7rU%wsPUrAX;PNeli9dM^%A2y_9h{h_GeWevT0I0 z%k*z8XyPLXdW6emDd^|a`tm0A+_SQ*)|_L!NNHG6m!$J_0bp-L?F$9lD&_F=Yqyfg z=HqYPzBNo;4t>BiSMI;S?gF?ULjX$1>_eL=!kHTsU2Jz+P-?}0J8c5>CZAede0ny_ zCtf{=6Eu=IqRBt^7|mjsYj<%s>kck&FO38Z;vJc!3QgW{qt-j_EaP5NOuC}3;(4D?W! zVF7c0!xU8qNxf}O(6nJJIm?dsalDhzMn7R``wHDgKF-sE)$Iamk!cw<&heLp9Xlpu zoGd6i52#;>=Fc2#I{FP~X^6OIWNg+hy^4^SfIq?4sATUj-IeHh#T>NT-?3}Jy~~I9 zWQ6+l(RjC>DSOO;A*rzFt>Nb{{J0!ssqAJNR#DV7ZJ$1q$jo4Wy<^KT;{aIts{)YB0EG9Dw+TW_%1>!G*smCD9NJ(Rjys~L9}6s<&?Ac%n(k9 zWirS(4tC!ndJvm&o@VJ?C>!deA?pLfv-GYvqX&v=WVf{GC_#G)RQSv~6G~87ji*h^s*4n)TbI=``WO49RK~;*=m>P7^k)R;)cI>mnqYzDj>j(0|q3Y~}Vx&CxRqPH_|r_*nG^Ou|U)UGt0>`cr5qrzC{2pt?I; zTq{y=1HG0Fy!$xPGIxR-nAi0boUqyzM93M~vV>WNlMk@u1>*;yry0?6cG<)nCCRC_p52CKNBR*|);*F!j{jX+)oae_5Ij3dRn+!@4w0#=FE z&WIrl?Z+#Tpu@1#%$LVEgw>3L%q-_fjg5$oUN3+#*_{I&CdA89tp#UK@FNQN9E2Tq%gh!(0_Vav9x-nPzR+ z*nu{mzC}2F!<7o1`7iQ6Lj@Fqb z%>+vuL`>hl(l1~YgQp#=9Xj&z#@sc`Y8iReo9; zBH=k0fO5$&FJt<4i%a8+Fe8D{fMY}Yr<|0ZxI?UO#Jp1Z!Y^M%GJEQqFGEo#?Ak|S z*XBO(u@16a54ntK9?EtHd}HA1X4^XplaC^v<8qAco|9EmC!W)KcI{q8g5~_B{yizk zk4gAqHLwn>yalfpcQCH`B5qw$)LM=4;BZ+pv4BsT#g77x-wue~`EvNS?Msv9rWpWDKpaRs z7KkBj4kT(4N9R{prx3yk&trss*6-H|r$c^Pu&G!)+Bky+w=SdrF!C>@aJu12pEqM* znn9uh1e`20&$>yHd}b_6mdj9TttRfKG#sop4wKU-x{|*9CQMG+68|bUmJVr7gfs<` z4Skg-nD>14M~EaW9mFqO7!fmeg8-5RWV!jru*ipU#V68)bwM$(y16`*1z$eYv3!{R z2o~OO9ZgyDuoHk_7X4213WxY8%bK;FyuqC z7B|*)@0n+^h^pj7QnB>9xUX#-A3hxO2JbwJt^xBBJruAhPX5#(OWbRx%nL{$)+|mZGgk$jDOf$x_lByi$0R+cM8f6Qpxh_BGON6S zy^n{AZ5k%C(4+I;9B9QE09}-n4e6Qu;xHddnLU9TtSq2BcPsEpTP<)Y!2qvy|imtO^Bm+v4 zLwK+A$PAKtA_A949~uZHXDcFvwD(05lR@d}S0sSh(mEcQImSp;_I#}{d1Y7(w+dfG zi%z9bY#ts2O&U1|8-5SXcYdA#;+}d+fP2M|gc*zRz>+q@dl-H}(n<-OxIP$?T=PQ3T7DIH8lw5b>2jN@E46Eu#JNafpl3u{KMHSkv7hF3R3(PWLla0DNkt!` z3O~aD54_8MLu|#qlZD$X7JQYy_uUmK&CTbU{j;6u4Ou4JYb-diVL~taW^Sp_)_d2` z2jd1kFuK%cfm6Tcs`TC@PyXv<(2452e8Nuy`;_QE86Mhb7FU& zjX^7L((;4zL27#0mm-pqj6ZHH=-kVCT&he@UdE!eNb??60Dy1eRM+;&OuByj(dBJh~d z>X}KvkY;x9Q6iV6dytIusyDyyhB{Sq@$tly146InS>audCgtM?^|Fq!hUD3B8v-dp;N-bVFvCSPFc z;*Q;AGv{&FruxRk*C$q=p09I=1&=Pi@v*x{#1ZJzak%*Q4u;?I^hA;`*3w@1AvFl^ zk#E1!;5;niwjAaQ-^Y4O2dM*o8+?y$jvmrq&BE~Ck`cQ#k-GH0Sk8Y(=h3Z6ug}8| z!u@xx4vun_O+Pjc_`mUbbiDuUEc@`$Wq$(}fi5{U5x#rM{4yn0!Y^s0@5vp5Tihm> zgrX)7I|oib?VRH2)_?YRdgsERKntC5mGR(Iu*5g6hcOIngab zNnSu;4h2$S57~_$f?({;wl#_A4%W4r^y_Lx!yBoIwv!Aufk;PN2z(p4Ua`vDZz+l`ED3nT5^h~o)GN@@fK zhczX>TkYb>N8Y1Aw$FE;v3d5O9Ymuy6DjQ7_1ck?Y)uXV7knfj!H&jLMtO(;qlVf` zhBYzB4@m`(7wq5ek%ixX^&DxaAf1YgJk~1gi32q^?9!*R6e`w?^JqIi7f@neEPi4svtLq zoYYH7f`I$lJgfj60(9U-=D`Y%P%mxfU5jPnF2BiP4I0>{kr{FlkTtHnCMhTP5TdkE{3Nyo|S5hF#Roy=>xS2A#uP=4!EOV*YQ1(q0qbs%<2NX{^J z{U|z|au5<7!^6{ZhJCxA@mOR&4JWd+${z*5z*QTP6YZN@`Lr{~$CKHIEWVW)%x&L? z63pC3IuJqGZs;K2ODn)T(wtQgbLm*xd{-expr^t}9z9{OBu+lVS}{Q$m_;rf30C}k zLrhf}qNpWBPMc6+++Q@(Aq{%)xH&d&j0HIcs=JBITL804HwQ*vMk)i6-z)aAMj7WS zpr4_ek@O3~0h8*CP7EhzyiI^$iY3@K1*{5S-f z_qdC&r)3xq1?R*bK@rk$LMHp}NGfTaF@FsaadKhi)_h3r9bb6hX_SF*e%D9mt7Plcanas;&|e$ND^wCk-|DNGfNX zG;K~qtu9|BraGwx5d7Xys6r_sZY^49h+x+q3eKULE~)yQmvh_;o+9KJ9=X2`!+*!7 z{+Jwq$^;l1mYYaus8JuzWFpEB>M0$`bYn6gQ3qhAz8@#}?lA{7j|c^)vy<1QlM zfN_fxNqTN}{0|xyx5v|rDp7}IV2)6){aVH@4ZVdphXpxTnm*SBB|A@ezvmbu6^|@1 z@T}X2qS9#Mbaf~*nsT3lw^(SDDEJ9dS}T{L>6Y^V9${{&n@~GUgdI_S2fG2KPyzqB zRtTy(hjOv6=Y(=8cNjrKjqhMn^suasAaVqp!CmE3`lvQ-YypxGG?=VEHE=k5mubCH z0bF3n6R0xCiU23Wq^24l%cp@SPHGBm*3LH=O{@!G75|}WI1bJE2=B7df>lgZEyZ4!>X{z!VZLddvY-N~-cv(C_4LyO@3Gr-_!v)n z((}&t)OM*caU(`I6)ual2wI|re)bep8OWHM{y^aZIjuGUDsQFA!sB&g;Afgg3j_GV z1;h0bPi4yUjw&%&`ShF&#w7WZe5Xc}O`g(KMWkhx?Nw-s4k%VEx=fFsJwsbUanP$I zElN|4r7c)o)>#5b=;wJo$xfTk4Ta<+Pwbd1y+VuoQb&Y9HrT$>jg&92z{Z0O>R;BB zi?F}DvZx-KX6PPavWqaQKGH&}KM(%Go{5b7tb(+anS1`_p^GK~m*#A^Tjvp<`GI|P za(YuT>j;hKc`wFf+}OO!W{ zupdDp#phP?%d<3rALvZ7u9Uj03*fE_@oO5qv9{LjeD~TaYS}!lVIf$2JGyA0G|eDMU~9l__)^1FmJnNsp3Eo?-= z0&j<)_rO6S2#FM?nxJ+3OKY42JB~=6UN}v%8<&Ec6_?H>m||>Jxom4$3c!9l2X_IT zW@iw_Et66mrN1TW3cea(6(>L)g7)gM3lOy$s6h?6M4g+S(%44Gdbea<)lg=y&z8Pt zyCl|WH%7Uk#G&?O!SxN3umm8Vfn8R??!NK5$T(KcHRlWwy4H^}trLV3{t1rxJO!`} zeG%lMd&-#~$Fx^@jde+GC5j+ik?ktTy>o}_pmoxIk9Tm;jdy%+$WO%Cz?6Z4} z#KhcAT^S8tB$pg8*`7P+6Rq6ZP_XhI$S=?;?`&aJwdrejdb--_4II|Ycy#dC=#F8rP z2XTX0I7wbg1lGg>nZ+?Xh)5S8$(nAc0vuqik}1^Ybyl4>31!Zc$?h+7-bi+=%!n!< zCb<>$5{9`yNY&^_+W{f;12dMudTt08Pz3jp+}Wm^-5!60op%}WLDf`^eZ!OH>f3uP z;i4WTHJUku6zxbCUnJ>WVzr!o^vhrYSFI_^{V>wSOndo`g@UHR$Yb_r@%m=J{1?*ujgI-N+{rP~LsL8|9DHxD1 zakv(q;~Bc;fs@!9MZXdv|ITdI3Y7_!N8P5kmXO_^Mg21JK@trfVWvf-+kI?$M=`IA zg1wN=8;awa?Im1=OyNWlV6HbY6nF7)uOlsLvAH-rImzFNhPaqixCDU#@ytV;0%P=2 zvmfSq+7m)I$6`>F0j?6Mxb{eVW68~XglC+JxbUli&|LFSWU2~NG1K+26$F(O4YJBK z)%CtSvpFeVk`E$H+7)n!0DmNSUdeIGImq6f=W5^s9fGmJ-Jm@X>efLvNnv&)2=xdQ z$pJo5#}2A3BZ){ldbJf|pU3P>6x?(aH3xJ(O9(%5q>I%~xG&E;)Zl;;V^rf7s`Abd zA4yO860=qFz8#o*Y>7|AAneG?_03+0dLZ+WhtUBrr%D_(E}=-h$Csv!e`q{V2K+$^ z%wt#ZOkG7$E)|EfxLoxUd+Dvvska{w66WxHL-tq!)>c(dyU{F2qiWn(t!@UHe=3sq zN6xXtn!Ti*kCZdST-qn)wj1Ydr8P_q~MDAg;d`etVpi1un=t{O7Bq9%(E zz&-bD)y@oYkI&W&3~|$niNQP(IA)>f9FN1Ny!ts}?$-F>V~3{WQ29`DtiZ`)qQk=& z-=HtJcU^;W07t5fj}k~_>ygzcU{!Q%5ZE$ss*?p3Bc-<1EhiNLq1L2Cy3wX^Xk-PDYMJooQ;^<;~a2LvFqW7zV$P#VTV$qv=clG0=lETGF zfcvG1B`CS5jmj*J?y$Ht>I#q7J0Do*sx1c+*quJI&DS~3*1Ej<$iC3zu{lxUbjY#P zcI)uqiIUd(i|`0SGIh(qJ*hJVDuSB}k9Bs$QLw1480zwZmJMZz-3f69mvOn& z@5##md8BH!Mb*0`hn4LpDo9r>W-1gg7~G8U_;-WE!zs3uxqS6r=GQamSJt{GrC}x< zE$tlF&Vl-MIB?S8%wDL&G1uQZor-*Zzcc&r`rA{{lcR&p$*L=}g0Ji1^s0Kz2!c?+ zY$PCggBU`5AciKWSJOa60)c`BrZF`NVt=2Cz(;5=OVW`EJhLYF1cC*kCX>P<`?E+B zf|)p)EbZ7nF(&AYR_G`CTyk&9Rx>lP3j~SHUxmlZkl%zSD6llc6IFyhtr@+{(pfSZ zjF4T4R_AD3PjY&~RA_W&wh^A8qpi86lVT;=%#h*I@`)kS{jnfp)_cL!Ap=R>q~{3# zdx8W?Alx;hyD~N(HiH%Ybu6P;h#Wi36po~`^%8I~6S5tN5uxsAOW^H%bP<+<96~{U z^ZWW)9B{N%Au5(_K71(NN4ZTDREPHr09zC#P?FJEXMS4w!arBjn5c>6uH zB5xbV=^2k$`WWtM9V36f83WWW8is^op<2Ujk}RwbiZtz=@I<9LG z6%VL1ifuAp-HmOL2o_t0B>g@Ji ziwciu3G$G{v(LHK!S$_UHI7zNE4$lT0;{1o{uBB7n#`I)@pDqA2|Y8V(nvui2$jFU zKv^dz!=w>ZNyHM$+;rt`N1nm_sw6>HU5uDGwhot?PZ0^77R+V3G*rmeeE>F-Y zK$j%cxzrr4#&TReUUi8p+2PN-uk10N&H(16pQXfvsYuuSF7 z4{;0vp=zFl3GDC@b?sZltmVzQvKpX54~H^ezvl6>SOnInLg#P+AoRYwTe+#i zJTbnmjj5X3h9;xEe{ARH00XZ_grMR*NSStmg<^+-@U1Nl}dp^Fb z_aXZ_i+)2K4->jm{yq0?Cmq^>kx>nLqrqKo;*z;_?#AX(6|8LIq~aRVOUR0D7MF|! znZ6G^ne85S5oJ*n!(Hr6x9=@P2g3w(UOPzd@{KFHy>GFec<5}woM+lxE}*}2)!;c= ziXeveXde}u)N=>Nkt0^KSEr3^AgAOxOHKVDP3z95?VMpeZ400@VzzAU?Ji5BwB2Ce zxHFh8wXqfJ>ZeEt7cY%bLvu>v`hGrkF%!*aOrJHcMAY_@pK`^8_~}zsA<8VeIQ)9J z^|rpm4Z7WaV%S+lHCZ+-M#)<*)%_b3=l1H~V*M-D5J=t>;Eb*la6H zYpac|qHGF%(1&UoGi~9%?Si9hU$}En+3gQ~2ic%KuDREA%HB9Wl^NE6;-lL&DLLHL ziW$8dkHW(+Qfd!N*-*h+VOWArOUtg9RQU?=CF%*5b!p5HZx#sCj=(Imb={RKL>F@# z@aJUoVm&k7DH$#FjtDl=?WJgEIfi|Bji_pis4+{6eYBAqpdl=h+!t z-m=*lX1QUUPR-jgS@EX9{-KUEa46CuYs2SBp=no2BmC*EC4pJX3!8|;HrAUP2i46> z1KT$?mzCAXFcvIChvLWPRZ@gs+)hd}x!TWD>0YP(DM3nONM7A9r_{ol247rqSP>36 zeBGbR;a`5GFIbv|#g;cuW&3u8$Ghd#@Nn%JJGD^XI#=Sm?0DW zQ?`q4qKT{pb8IC90m*MhKd`qdblWxn(hcyPoQ;?d?RlHxn2+RMkJ3q1L5F5Z_kV))mX(oZ89Qls$g9g`ceXm7lF6c@aSg394Q%iDE(QL6NaB>0&#l&$|Cb9epJX230YJU~K&6n6~}T#7@XP@qU~ z4*`O^yHkq0ySqzqcM24@0tE`iT?!N^RABqw_uiemerIQQcK?C=^2|JQ=E?bf4z&(| z^6D)F{D?5DlIhqY+UZn^5JS?dOA|r0&$ZWWw1;8HuM&H6_wFFTc)pDB?C0CGWwB7K z_l49WK&e>udi7Ae>2#F!r%_C}24;Th0#Hs?JK<&k$7LgC#{c=wG*Mqw>IzDRg7fh6 z;K?_MLvY9lNRQCSW>TXR2-_-{>DhKX8=aR&IA|B>L8ND5hg3ofX&;LcJ@Syxfg54K z<*<=ama%OM3_{Nlhg>kZc^Fg)NQjD}1zEL@gYSin0Iuawe{b4>OkmOg+$0d`6p5-m z%1!Ao9Ss40+GpxzSq({C7El4@a^V^su4S%qeeCE@C`e6fm31TlU(uCl&nMu4h)s6P&*&im48pc#0&xTeVEQnd7_CahNj1#QxfHFd zP?m+of<)ASjwd9nv_t{9Em62aFp)ETOGY}K;ZkZWixHN{uZ;5+3($eP%nAK7H)(H= z`n(t@u8>T`iid*p6|%gwoT{&Dj#*5`Ftd{HJg9b?DL=V|15XT=>zX-J&m?jV63C80 zXN@LO;g&{;}wo^aS6l||X~_BIkH9fyc(44@#n4VK2< z9!)=gic<+Mx6Z~NSsL-MPcvI7F+qh|N(aeL?;&b&0e^^xrR99~REsi~5OLw;%jPnB z3ECsXR__<3@b>3g*3kBGjahRo=#gz_>50Y~1Y5u@Vi`0~8m}w$bU>o256GT7iD-c7 zmHM#dV*JgtfmMs$>Fj70QHSQ@h(Z(?~dggxvt3@pwWIZdGmKhve zlBQ-3oR**K0nOmplblp3bLMZguJm^?ta5Wkk=G4i+81Q&e1J+;OmHk)o~Qh4T8;XT zVv!O+2cQJ0{?CiW7(x`|_5Y*AqVb1lYQ?tN)#iU!EKcMpw!h!#{$G>d`;(b`c3=OE z{H9Uv`Zw~stM&AAgW2SNO@4=9(f+eoOkp>g`M-09V}+D}#IkZb{G$z#Iw}o1F})sRJr^a3f}at~c2LRSD@d`p3**0F*-MoE|A+jx)8(E#Cnd(3TbwbE zE9hM(XHJze35}1d_+F=cFoCeh$xmoxU#C_om9goJPr&m-li$adaahSu>aAU;cTDYL z%h&`00fQOO2IrNwJ}MdzRA*vJ9>}HIDDmH7rjx7&qm;hHx271*o-Wl&C=FDOm{X+R zoccTE9MeI#7Xb2+#xFok7-+wFWufX7qNLXhl=4!!F7z^zrD{)jwj`n0=j+lyp?UTI znmxJmP%sBE;I%z^AU4p1NxYK?aJRu%43a#OkY=3<$t5i5-K&tsrJs$OsmcdO6-o;b zsL)~z7vcn2$|FGIyo z2VxIsg$yiKx;7O^GB<)CfPs8U?PIwvc|5L$6v(;azS-1EpsK`ABzp~%)EAO`yd?>9)}0V) zuy+V$5YUZFrn4=>7BU$(vF@IC)wG=c6xhXHGn7FJ5+(HbtKSLTY1V#Q;} z3LQeX;dOt$bIhfxIS~-x?#54#5l9g_90!jy3fi)yeSSA~M$9cE1+^!8<~gR!c_RV# zKMTQbgP&-Ft1bReLXPgo{@kkny7!s+E!)+$y~N*4Nbn^#TXY5(_Vk4>B0T9eqyMZSNNWkBEvv24==?&HP6KlxoT z(Vp24Qm1k<9QONA=NDh_?xV2tn4Z1+>)~$sA7075H7eO2{tM#{4PFA`#H@2VxamX*abxS?G)8*NT%;a zXU6=?PK(MR+uDGAF5cFMSoL8wjOE%jy(fXW;9*8*<9pn*-UHEh4|5p-Hx&`rM|oub zL|gym+`uyc1i%4O`}gKckOU4Ja;!ljIUMi5xL%^Z^(KT?G@44jsdPMrMY9??-c&Z3 z!EH8?E8ko`og@68At+WQjYUi9()2YxPnMqS3Qo*!~S)I9(K7G~Y)}jUj>i=^7sf6^POH z^mLjZ&4W}5(x?7)lo9O8Hnm9#Bm8=oW&C3=B=D{N+4CN+t)Nkl7ewz9UrI#{gHZF8 zd;fX8L?};0(jgAeL-=&VmESgh4eB@2+7RRS4clIdk>xVl`W2S3>$ExB-~ab^L>KY8 z+XQ|p87zoVaLZswxk4>?zyw$%_t6AiWJD@ru7>Ki3ZHv3!MLd74z!I#zQK?cDtbfC zTbdJ%9?wi2gY%Vm*J#+onl_B@`raf^0-g0Aql~XYzu#5E|HN4nzuQ>J}5LC=b8f7SmSK2ggwzGrT^~DUrCM0K#xhkw69J4Ykkf2>Z zlK7y_DiU1v#AaKG7VuE)G-`lx8eD&%w{ARM)^S<}YV>7~s>qLKE&V6$tsr~ot&iiu z;(zqk^W0i7INVy&yxfZ}`GIrw+&T(NlB&&&RoOopzM8#yaiL4#9ZwwhUII*iH3m(2)_?JWJuEFhpT76T*weSJiC(``Fq&oFCRLr{v2b>h5+HO@5<&I5%2%wQ{EJethTX#55@2;bHzPKOAZrL#=O zF)?b8;QR5iF}Z-_%oBG{GD`K>Al4QnmToAd4C9~IOWK<#9az~It?e>opNPolqJ*D? zd=NE7typSZ113SELSO}IgfdRg9U~A^#U$c9^~SMhRFsNY7CEAE{B`LhVur`a}b^S3{2P2YsdNl%TJ zMq^7JDFVma_hH=ho~Px~%nI|H$hbf&^AcGX!P;Y3VD5Vcwei?D(O*;f(&b-e89^aY zoDexe{S_cNRI)j9^g@w$BNX_mqiVuF7)xZI+%9#KvF7@6)n2B)+*bHm!ILIpUNCIjPxgOmG7=* z4bva!6sCU6)<;8&Jy0DiHyDSP<8NCV;?89jd`5v!mqgqV8=)@Tz8|5(M2*?f_DTlX zfQ=o&1`IV+a&A2&1{nB$miody+-{w-#hp+OfIsEAr!j>YN|;GJFY?YZcQjucGaCjV zP$3EBTu;MZYbExNQCu-x+i#ERbuz`mB0IW}FVEc?g8FLn;g7^;@&o-3K8*P~C&HS}oqU0(avyDyrzT1R|&L1GA-|>1fvLciD!?BIp9c5{`j@=8d0Of`A)6W^DK<;TS zUiD0_(m0*z6LA`>>SFpCCL#%aEXMRf3}@Hb+}c21p=Dw3CASP8j??1!q0-;27fE$? z20_CudBB%;F3$)+-$Z`Y1$or7wW=K$BozTJwA(JqsT{M5xjv7b*SC0JUi1YV(;d(p z*W}2tMzpGXwze*5)=yOF;&bZQ0Y7*8lshe1@H@14xP-*|I?s+!n5FBxPpV{gZyG4c zxY@Uk3UQ75imS>;$eb<$3Io?ib;lf@7C2u{hwkyQl7kh{e=xz+5zs`_UXNb8TtYu{ z*85it29~v4=g}P8A)*c9Uf*4C9q@V_2d8@!YaOFFohKX#8cP$aUQ+7=vb_#JD_!3& zzM5p5T}vpsL2}%TdL5tpobI03v7~|9``bQI4wB0$%1-@;zWq7@3*-9!OPx*K$ zf^=>G5&)GIwwAqfsps_a1LaFaJN9xXkvNk`Pg03?x3%B?+b83NkC}C~910jRZs-_zagd=3qoT#q#X@iVr zJfr9rJ!V?HJ@!ODGe>+Am%+ z7mPITtc;i;C+@41LJd-1^333unF4TIvB9*#(sY1)X6$Na{IQ&Z1)0LAY8stsn!0k@ zxZv9nxS)m+XH|01w)~rLOcT7YoyuwAwc5*}HC=By0+o z_?TKbQOBHmf;mhG{OIHCQJ>r~AL^zmDLRJaXM>vQhf+m1@{HE_5Mq4jcveMP?)qxp z*Kyj^BZI`JG|jKXnn-Tdj&aL^2n0t5o|6nZ7bAV=I3kgZ?&U}@hKcLKmHt7C*(GcK zRjTIq7R&P})lHv5aCV`KWHJg~l;Jp@n`iXfTL*x%-P>CuTs=IR8@T*!q3jPlJ9rAn zqzH9hLl50RpWAqMG0mA#L25ip)VqkHx{zP5M9`K*deIl#C2#P~=KyFWR-9K>lpnxT zzyvNVAA*P8<13Vx__^jaw`9c)31rYbzSYCT-5s(W zobjZswx$cX&tlbIL!ftM`8Sq<_bRfxs&e%RG3YQrw&m|`t$05oUJI)-X8sjJ5UnVd zq5^o29!8~@HRLCexPz7`m-zMBKCvL3S84k2;jBroY)iK4Jm1=}?AlP1>i!4hcj>4| zk7!-yd_K9#B8|Y8w~@TsL5K_^o=80NaKv}5y3S4z!pnkN$c;A0AxvH6!RNhvY3;R0 z{f#aD6p@00Wi7-ub;?E}qOrdJraosmKt>+#5tC0#uO73z0h^tS;3~iRSdC;}6<)<> z>7$w_}K=q{&Tc2E`!Qa=UHnyF9+?}3Q!?R0EV)6#2zE5g)k|ZyXj;B{v_T? zOMD9f0$Ud zT+Dv82a3u^rc}Ny$# zto4o4p{6q}yo*rKjB43=$V~7xt8V()nPR1Bq5Dl8Pb{yOg*`v*csVC`|HT(Re#ju=WyLP$0UR>CC^i5Kv9CS-;A#IJ zGw}Uw>+-v)XU=#`W+y+`C-@!p2pbng`){x~1KeJi?)11WIh6~BS$VU$F?Ytw3i*Zb zgcY||hYk3AQcKtNijN7!M)v>37v@d7^=}0X7`u#`P3l5iJf-_uh8UX`W3m*6$~8=4 zMqwuALqzLCTvIHUK(0SEoY%!dE+4}_#Ds%w#D$O_5O27V2(MfZPgz*_HlJ5WxZaDN zVWl40nx=O*LMD44uI$ zb?l+77r_ zW_b9rlLe!ZQlvB9%UN zs%gD_zi0OMZ<4+p*ltU4xv#}x8W3}fTz)?XMT`cyu7kxAc4ZE+x~<;mske{tY?OT+ z@7MBYeV%56_>d}h2dj9Jvb=sNZ?yq;PvK5zOEERS=0$ox z85DWqY^Yg}(94Cx(by_(3H)Lib>5n&^lsw)MTzO>Xszi@HeLrYt0mbDhit6oKPNgo!>|8= zPna_0=4t^X%58&|P&GvdP%H5LVl<7Ws}@sY@z{51D_wP)kY3-uN5?<+X!bLA)0 zGSqW@P>}Sk;{tr%XNg)*(CctS6_mFwaUgzyriya*sc&QB>(g^WOZE|L7k&EZ3EEfq z&)DfF<&=CCmH6P3o79`vy@~!Bos2G1a_;ch^F>FSFbUC30L>Oh(kEGyHAUzaIDgBw zv2nd<3+Hi*nJ&eQBCA*r20d*+#|QFIDplof&pvF^h&M>+R!p-NzromMc^p-cmQKQM z^(Qv$q1x@ID(l;K%VSXG)>M(m*m*@Web0y_N}3jOsgXbdJc?-Y<|_nNi9PNO z)55xQ}Kcov>#~Rc3Ms! zBuRM8;qV}R4z^wUJPduZ-=@_uR!3BHfLwa>Pvi@8p16rLjEiCCK94dgP~E)F>>L4_ zgY>VX+@u6_&n%67Efj1EE=T?*tSjae27*l?eF9~>p~WJ^q0`uoY|)Fk)2bpRfQa4%V0w7AoSO4P)uEBPNdE>62)-`j@LM?7zi<+-Br*Rd( zenwb7hB$ZOk%&}$2cFZU)~H+@&9wT(k^&qQ3h1_vN2gVCdN)sQcuQW9LD8-e(w5`t>7&&2Y6CfgDTFPtZ)$9i`eTxo!ju=q{| z?*k5fzzC_V2x1HU@;?8%9V?me2>!TqVfG3S`J@(o05nL@$s(jEoM~HbuswX#uC4l6 z$d^#@)wROrAcunH=&PN(+Qh|MLA%#~m$%h}UkTVrTI{eD+y?$~jixYx#aWpw?}rWk zRVK_O$7;n{NW+8`=5TlCIBP>B~bpi@C9iIpMywk6!)R>zv2r=YQ-{f zG&0#*#~S6z0!*wOglvOVplX6za%eHU7G!Ja;hS_i*oZzE{$Jn=$S(P3^gX}0>m?x= zcUXdFS(j%3sZE@XI?BTDg4WgX_U`-s=~6#_mBtM2%l>zGl}_ z<(HZ}PL{X7bOuVR^uJ}({Pev$-{_B^HG1@4>%-UV_xmICh&mYcqe5A9H?mu$;g>Ue zqBw}uyg~9A?O%K$jfma3=U2lQdy%ty0#%+_>}qa4EJkRfG@+_Aj|{QFhx7iRYrjUB zM@xH`7vw>Tmm`li-7Ye;?|{58x(MiX>9;m4)#3NDq8iM28B_86m*RU^Z`fmoc@;U^ z_nIb&oUjtwG0o2Ggs!lu?3uYSh-O~@*5hcFdvRFWtRnhtxS1DMEca4M{QF;gLGl@6 zi&_~v)%cU(%jXs?>TOg1(Yv}6 zwH{S87>h#i%n3Z&y{v-^9E?S#$X+4&ouu;z;0&JeT~=Jg_BPm4I_4>0ukSC3DrJPEQbqS?&_v z^>k2x>#2(=U&#f=$i)H!0(pAGJM4mM+g=()W08>_1mmSkY=`s+RDOB)ZB*0==CF7L zk1r`xh#q)^!>U_P@1ie1;I1vnhsO(eoUdLN&vj7AuZCLQJ`!0FMGBgP6~PdL*g@H; z;$XL8ELH0i^<0qYZDrrVoke9JM`srDQpto2PJT9t`qcEON^DnE$LN3g%XJjAZ1%Em`e8S-(~bkXMgn%$ zwc8Y&L*Tm4#Fno_vf_fNYX(B6k|l89wQq>{%;bPNbn)3q!Ng}|VV^C-fpCezCkp^z z1BEV0z%%zbhMayF%N)E773oZKiU>o0-Vu#IGZlR1ZH%%qKY+0iuc5JJ!h~rm`OG#^ z)VYLc>?>1W6KkWlYN#oZ4v^t*H}*=yTm8n>f|dKvb8pdLg@Eh*0{@^{&wwJbkHY13 z>x}ruT2(kCMwX*{Hmd3=-LxbanxoKAbtAJ{Rjrn^JSfB@SWRMRO13eY#oUxeLSldg z76fE5N5znc3>M}EgMt%_iBnskP^^ZqXHrduS&_j^!cl>~9u`(RcwsDrrZ5-Cb#e)r z9D@zYxJS@+vOJy)cF`rX!cY?v$&JNU9~#e4>vIlyHL3EO+q97|)#%Sp!m3H#~U*6LwyxrB}@Dy z0RC)DG&@q10^E-e^N~YQbzO8(VUh!d%5l`{5<@J@LF#_-gKp-05IGbrKoPY)QAr^+ zL8;nMNUT)Yvq4<~`Yg%Z);E}j-PW=~Y@!*c&r!TkC?tLL0uw3bHC>ty?-6pu4<-|q ze-FvWBdcto)f7SK`G~68W){DPd3A%IgvlBZ?YG@$OK3 zXkXpW*+HFLu1&6Tf=}YvS}c=NL?E;!n7Y+ihMhkNhPJ$Gi1zaMNrkryQ%_Bapf1o{ zd8H_fO{R!g`vi&NFRY;f7G#dB3u6Y=e3~GEw(R4doMI-<4|CzrDQqq7pnHk>sWi81 zfgGK~x+&7=svtj36vc_R7CReb^H%hkshTwahx@~R$EI2JO<3BVO`P)M-Kk#w8GyR6 zMp03dOpmIN*X=)}->Ksafl&o6tmff9l26449Km+c8#AQbHMCIaxD8~bsyB_ zsdx2KIw&d=9^}8;1ANxG37Ehd!dURVd+|%@gx5~b33of52uo;B$t2o;>FZnFl!nBb zd6XHGUKDnLJh7Vr*1QQg6dW^HsIS(5oIl~M@4Qv3V z9+VR2>r+Sy>mRTT<4iRT8<^q~=rXAcP9>UKXqThzz7Qey$~`f<)atQO@e<+OP|EUN z@*KX%0!iC`crQ{z*nb!F!hk@3_W^z4)dS;M!B&WF&|3Ov2QkcN=I!RhIvnphi_hea z;mA7ouptT3=+&Cp@|kU^SRtf=V~Xj~J;vDVD-vM5+rZO88K$P?_=kzJ z;O4+P5sITG?c85M0uB&aVg;;J%Z{*M0U^LQvF0Z~3$Mjt$IU_8Kc_7`xmEe$-ouPs zHBnm~aMvc)9NC|E;$lt+B6yRDJMqpIzqTwldN8L<)|g`3tE4P}4SR!`>s1m@)epJ4 zQ-r!k=^s^6&)hCsu-p!T_F7EyWDy~XoXR6 z+VCebBHiXB%KJAL$g22ag1$GHCC(V=raPSv=WBq~=DH+&lh|=QsUCCuhG|HzWI-C( znc+ZqOH#Ee8{btY^z|yi32X27C-yeLY31J!o(>Z!Df5n_E*hv}jV!@@v%lE*OKu7| zB(HDl-+aBTj}UX3#s{y7&T^51;jnx~dir}`y8povBL zVKjmJTBo84T+cOhCjce@6LBeeRWbl38pMYVjugI1w99Qb?lEN*1G@K5M@6D?43d`)Qn;s{+JSdI z4Nw7JQ{D{H0*88R2C8BPA^bxO(nC@!8A=c6%ww59G;USJiscp7? z&YPhZzz^I+A9$c2ZhnbhVfD>ZV4Z&GetLi0S2#D=VJt?_jdxZ>8RElmKJ+FklZ24{ z!)u^45#`YS5ivOx#u&!1wAS$M7DZ@err_C7Fro+}HE|vFh#Y>(ySpLCmtw z)*Zqq`O`NC)m^ii#TxT14~=j9hCVb-e)v8h7Lh4CPevX!CYz)wdoMcTOe7aqSnFB} z(n}4~RRejHhIy3A=(&IN)cWXyl=I33dG~zO9q5Z6>-Z_b!l)R`nHbD@kHhMnAz2Ex zLJ8#b&WPiFpE}U7CLGHj6ctWC@)Xn1^W>J|vNslA3)brx(Z&WDDxq>3gWy!zj%ec; zH4W~&GEh7;&qx_W?lZiU$k_%w>nc9y)n;W#2uCw>kbPuOtaKPz+qD`hZ$n+^O>B5H zxB@xKZZp9;kMnrd6%h(v+YG|y zH4qR|>qp0!F&``x6Raok(Pv#QDwAsM=)+(G6DB)t8Fogfb4K*#c=0+cVvKmwN2zyC zx~Ed9!!&oe_IY&X)XIudFSwLdA51eIH{JtlmY(K(H608a(W8=wW`c;NQ1#S`1Y=P3 z5Or?IFdsa$zk9G*$d6Bn<}z8wiSyYl@R*XY9hz@V%nszxS{NxLlHDsS17ZvttilO5 zhg}m)yFAcT<`}DMcY_0JnoKV-CmHx!vS%L;4{4+MSDxrCrsPqm<@@XpR@K_0(aZv*( z|2Z|Qs#7_aB0G}^4Y!F-k4!#K7cC20er-Iedj-OT87Lpav;)DtUU`3@i0VaNn%kjr z&JsAXnCNpoUJX#a2_-%M9Y5j^4u^tIdf1gpX928g)$ViQL*r_q`QHN-PT{zOf#>1Oix;6=3r_3Aj`V#@hM4I54mFQK~Dsc`N={&#tq`TQpds=&HP&*}t7dLnopS0)h5 zEmuDu3^&eDXA9&QK;?kZ;0^_IUuF*tA^V53BrS3pztr3gsVLAX+3b=<-3q+h3D3FAFm)}Ll$@h=Pr zQ83{A__)-oV`RtAhwwJJAC#`jKGi@a7C1JyAx1HxM!@kgR*ZqAmi5QDp*OuFpY5kR z`Aa=ALAXCzf+GQN1R6{^U%PNbQ6?B)9UPZbV7<0<^{}`vqJ5G)aigWM08@n!&fX~H zhEEv~_Gx%U1rpzFWXaF^WUZLIT5oOhTAa0X#(==OKIttOie&L^yqNt zqdpBzZ@*Z5L@m5N)%2;%lsEUY&y);YSkA{B)VIFFbkC-C|FMBLQrw$Z?3=OjO5_T~jsiVZ|_Dp20a%A+-(Dzl}%Va~>vQiJTQ>j;) zC)`J^Cd(9ofq;NJtFE)Z+^AI$ll40;>)^-9W$xjJLdqQLBmZz~Xs!6uYkN^;9*b(a z-tNfEUb0BBPAppv9wE~_bj7h=?{X)Ttc12Mz1>kOdv2@siG-@u(4$@bqN5mxnUqJ_ zb%w*3>G?=>TL!8jPQb*$1oiJ#wi9&*3q9LTy?n=q>fCsNPQ6?+a`xRop1cM<*^`+$6(Bo|avoJk zrd6~%u7Y7r?ofu==og*snS2Hv;(84nRX#plvy>XD4pYr4FA>CjdP=gnTt~rfrQi`F-d`MZCv5OXGehRV^G_BtaCSP!z8Nj&M zo=J^p+i%f~yk^aPtyk0az;K&hetAKA-gf>QXJ}50qHFRjcAMvjd}+l(6(!j#hblX>*m|S{0p= z)o)w;t<3z&frq)AVo8;_0L5vBme2+)WbxG+~buv>EMSD=*=!ta_4sb_Ai`YPT@gm#-f53sv!*Gcb(H}}YlE3g5^nFmet+z2dF6HfLDvy7 zP*-|Fy>{tJitT2Sah-d4AtF~(g>Z!9=YH6}HYv!T?X#&%XL@Ms9&jPJ4(EOF^fLJD zwGv`nQkQjqZG2#RR1I?Y)N+JE@jpSc$a(-CoD z2m1|#e-@u{A#t!1_`22V6YT^szVM|vV0+M{dQ2LfK1CPG3NcBA&+X5A#@OAmj04*( z$vqPAzs)&1ZhS<{wb;a42fSB&Jb4;s7!82V1YjBlB!cTNgaS@UpRQhD$P2!clYJ6> ziy`rzp8P>+^GDrxfNo?Am!=L*XyR1iQ zDw+rUe0g)UP@!4x_($aKY^~i5_c^JfZj*~*fDwD&tNT><7Z>M>kKg>7Kt%NgPWi7k zdar3WKRbOD_kH3CrwMfN@PY(muysH}o{QW=Lh%)>wGh;G@N@|hy~yo1#E#}gw#==I zdU705Ffzv>^;xt7Mj&kvut)>1{2~aaelvDOO}mh7vR{qyu-1iNozUBe%J*=ItjYL|^pYuKB&_ zD;MxFO8xVG|3z|X`A>DV^yi38)8MZ56@QA(3B#Hz15vvgwz6k6Ll3q+JRhn3eqW7x zMPt{Ec^j^M(h^<1(?ofa6sBTOAFIpc925BB&o}e(6nn3#=jVE}ca|>t;v56<#{Rr0 zdoTYdWzj$UmQ^U+Ibo8*lWU7#ZK-!U`FN@crvkgC5+`9C=AM$05aXmZn*!ANnjV*nQ?$LUQ<( z*+dVRkCa?y3J-bXaC8+zoytV^>bf6A&Rl4oJI#mE0$)sMBsO9wlV^x)d;u*@6H0O= zaNb>FFFD*@xeA2>@YJmdP&U|0La)Eceo7rCNrnv)whEsk$x(2D*%uIYdD%sJ~5 zWzB(cYa;di>uZdjy1M(ve+D9X*r^5cu?cSdehNytv~$kDGh&Iu*TdbNityI{v3zC zjJNC;z^eZ#B5~XAoqK`gR>WlRO=2pR%qCFJdy7C6TC@Ooj;$0B{*i6i3U|72Nddx4W)~VA&u1Y0;fF%AYg!#fIw} zMm0?ETWLAcjg5>lmtPgJni(yqTF~2w{F0WJ$22QtVqlw(>br2~Ts6MxaGumdHGU_y z2PS-i^+ar`6ZrgM;CNX%?dvF2;^TiHTQ)cUcby;$--R5n@=yk>h3jOi7)%<+im3#V zAT%8dCB+W}zOY28Qj-{98ZC_Cjts6aEVU)e7s2GQmLhU3rCh@iq5@qr(bIE|)20+k zq?JA`nTWMu(dvd%;Y{Ch7_n9)yP7zvac~Rt&tjXjjNQ(+KHUhXB&S_}u{K%t%xzb-DRZmqbw1 zVg!hw0S{AsfCQj67Rpu}2-vbj#dQD68nysHVCmT!SfCWkkeZ}21VB(d7EJlT!2X;7 z?{!R8nZcMd!PSgaI^K59ITtiKr;OSe< zp?~t2Ajid`eHV{DK~J?7xmRnZQCzT&3_g07%uq}*7=%i{t!-8<6)z$yMb!#eMh(49 zN~CAsB5Ml+6NZ-k`NS=Bg_!Ly#C<7(O4M!`%s`BWX&4o)j%Og%5EN(aPdOBs^@~D; zj~uRM$i$uhz1FIX5v8e|_}jBz&lEN2flXQacs)cchGUL*0rD&k`0_l0GS3L#Y#=L$ zYB9)z%%$2sP{smtYe4mmZ5^3vAZVh55X*02>>}xFo|3>_ZHc1gR&-{9;)ZBv8ih#1 z9Y>TW)33qY4Rq#eQg1A)@cwR@G)>DB)`9i&jIm~-LZ1fUfC13GdkEiq(3!(_iZN>_2N~ZpbL*)a=#U)zwJYpoH(R9k6*?Hn zJ(EK;gqEA%d#L)f<(KRkeb$ai^jCdQs6lQ)xv{1lE)tq(f;RuC{FXFum87Fgjbf5@ zQK}~i%r$GQ``T-Z+_OXyjckYt+lhrck+?0rhRZNDs0FImOYLrB@6$egGH3row{H4k zZSx19L%KVJ2E69)C30%R{x~7@dU?4mz~%Pm!?J=z^C5FxU>f_=w3_ylz}!&VUwnbE zK-t2bW^)vQA4xXj{E=|}>IyxH*)ZY3*AC=E=ME7OK>ahwF8PX`HjtA zW(4P%{h8Gl<>CTD6@suwZJtZzGb6$`B>hj1Pfwmu0!iHs7)HF(7VQTr$lq5T(0YjN zCJ#_NqqH6;b3=7eMc($Xgc_Zr27QhS$M%4t1L7eV>5vM4h)u4MG&G1rT57lsUyW>5 z*+lK@SmA9Z1m~a-=b})9YI%~i&>au>Hw(F)E5v<#u86&@R`>+L6)YkYH(8chxt)SP zv`Qm-H!(@#NiLMtGUN1-bmR|O#CKYVu%)Y;Me=aE-{YYa)6zG+Cch<%sAlM>4`P4Q z%>Yn~`Z$b%(ZtW%fIn)DG`0!=ICCOACe%#D^j!3PwM49mL%8$O8_rqQR0%}h__uQq zsyk|CTchiiZ3?E<}ijUPpQ zOGvD+MN1$9GRaUb)Hr6*Kf=~`s3oSKDdrPr;2#~|z)y-AR~0;;4c}HL00d&J68*^3 zV(2Uo4lhwoEYkX$NXa1Al-AV^h&QZLYnjO|1$RJ- zZ)2MZ&y&0737D-*(5seTxC}DMGDypoO4Gym#6ydS)j8u(o-*?Xc+`Y2a=B>MsX6hu zuT5ya0yhAp#B8As&sQgi2guBa60@dJ>9n;`P`1aR8;ek#=_DaBL#9Gy#=I1z4y2U5 zq<{mwyUqy1g;XqWPg=H2OJzU!?~h%@KN>@$P4?ucQkhZ{4S>a#9NJ_-MUosesM0}N zGE{0&!7e;Yn)7?=WoG*2WjrHEWDs4~Tk7v~p`dbLI`RB(_f&!29ZWq4qehu27n7N% z9DHao%4JUO5eYMeoA)N9SfERqqdJlo5%@o8y2YX3SwmUJ_FN?;lcIu|AVIAAc`UIg z1hH!@H>S=}s3a1BN|vZ@^IJiZ2nFmMt2mukLAw^o=5Kymm@!qja#h$M%7W!3i1waK zZ{>(aeO^|T4=&PK^9+!+#Q*x;vqLANLxh~Q#I$OIHLdl4VBV;&y(Tfu%j#t1@s&ytD``{z-%@wWeVMQu*Wad-{O$t z@vM7m*#SS9#7I?Sm?1NnaJv4M%bq5QTqP@7Q49C(^SUZft!C2#XsAJpg9=oiSEzM& zZ8aDSHE}X>DK#aR9Qk`V3}|-U0uMQJBZM=GZulI9Wx?+at@~2+Gli>)rJOW=M{w$< z##6|1f*9=j^vHazWI6g>C8-#Yy5dazuBn`)4P{z1%dSvxB@?PLlk-x-sNmYNWX~!? zma}f}sF>FQo6VY*7*T(H#E`oElK_WyP2v1jN6T=?rP9JcbLfI-=5sy*ga*2l4YgDu z;6)f&cy(LZ+q$Ug4kO1$xZ8`74)4MWFe8&H-5llfoSjFJwF7s@Y9+_Duef^e%NL?> zaS!)}pF}{VO4di=L?CXzK!vu`>H%JET}De?gLHkJ9W)1GP_Jg#jQb=7Y)PL8Gm4-L zdI;TFh71@kugK^67*ar@7g^*#|Au#%#ZQ#P5*U7@FdKc>G&KIj#lvK%M?5a(;L!+f z?JV>Wfav4c(TUXGk>Z}nqm`N9?~mG8H{5cok%#8m*a8AmQ`DS#M4E= z#0#mlTfDrXhchU?M|zY1(JL)k30l0A{1Mn4nuI|*D_BEd;x=LPve~1?YlyxVi(jiC1Ch!0JBHKzjKbrjQn;GFIWSjT# zkG-75e9CM7Az{h1=+KI2&Brv^3t{}=?2*?upE%@Mb_8N0ewsy`!fCtswB8S||Lo61 zmFTvjm)M5fY!%`OB8SBsi91P;oe{hnC1;kB*eHMdACwKi{bbp0okm;o=O$}Lz!1=P z5;-eIjAlI!6J!@b6*v7#3@E6}TJ(#aD0^@kL`sUlGu{#AuBsGN(g9E0n*pas9P?h{Sb#!CY zn;m%`)tryKA0DNsB)Zsu1gX(G`I*R+F~EHhd&X-9UJsMTk!wEs58tmNw4#0+HVv=a zzIGGohuT(AM4dKbUnF7r*MmYT3dVG=;T@P+a8Y4ru zVd*%$&qAT{jaQu!+msIz1sU*P==_s?^e>aa5tMcW)8;%R8S3aQ?uW8=RqkG&U5SUOHV;^jl}&)7#o zTGEL{Vl@^>oS`L!g@NRYk!P0qEF@ml2R1HRZbJHB3C&j&J}71r{5VtTc6mhRZg``% zFs9I&(A-{G(@!ZxYHE66`gNwr=Vz#@DEYBjeY3frkOkgV(#r7^wq{gT$o6-^_-qcC z^Qzkk&X{Rqb9{nps!Ny#pl_w{8KUoxpFN{lQyS2VRtv2n18h_28t7Pcw~~P!Av-_r-|VNLzD`0 zB2_euFI;{0t}-R&;|=2ClFf59BEaZ=(p<(i%@fN=znTRe+z?U1Z4(RxpEA!z<1k2CG$L;Vp2!gQtl#-I zbtFtn!=CeBkvk1ghTz4*co>u{Ao~;qglxy^$$Gt&kC5#>!!`e<{37WiZs@@~a*kSZ zBai-rS9L`fvwB;nzxrwmJnukMr1lZ)?^3lRV`v0ozHF`8G@`=wZad8I-Eh)e`dK!X zCsS~cKa*8Lm#9Cvh1`k+|C(eA{bNlw^pZ;k=|T0i=2SK?(~%fYt7-_QLn-oCW5#C& zkLSD~S!+LWh}&Z(^^tgyhyq*Ez`_R4UCE;TShLcnr1;OehTA{ea8GZcrXVoTus`o_ z-#L$?f3rJ_i{Qjhjw1qFFS)+N)Hd9isrp;$PX4#NDz7!6=c2-cc|wcYKfHA+@Wir& z{fel%8VMEev$k?x%f-@Sn7uSNFS@QyZNJ)8f%m4YNn$;_9SU+cyChzH31BYEgCZtl zo*Oo(eGY3qMVP69q2Qf?*#^{B2-z4)n0~ZX!)xRE=;`}kPvi8!F19>MuNtD~{@j{8 zdqxpgYK(&&!)GFvXVPxI?LNa>te+U0bUK*+rlZ`o;mY|2?7(03b|3kH3=ND1bv1E!mV>mR49UZdRT=eC_Wn6eMz2 zo!RI==yzMxl#XS+>;Ie(C_;%MN0NRDfvHf)lUtIRrzgt`M1&zLy_z3eIFWmhRDYV0 za{qzHLN+%!L=Dy%T*ntQ(QWAIbu^LdNwZm;``&OED z%J=&0Wvcxn6pYjWK8gy*fznH44_OR=h$v|9jjs*)SQx(^J^m0PIYvfY7gz$ zbJF?azA+SwqYnY|x$nuR(dc&$jk&WW=YWa-3F4>iqVttfK%{XkeX3>Zg^C&C8BV&@ z`i*vrof&t|`t|1h_xbBg7sF=zxia0Z%xA{!7O#yG*J0%vX>8vV^PgYVndPcyZGGzE zFPiOpa%U%KBI*%39HV@lC_%GrSqH^^zu2AQWk2&)CYn+**W2-9xn{XuVyneoC5nYl zaBOzVXqldHhy0W1yq1f4VId67`Z9=~>R1={hKQR-r{|qUvZtG2O zB4s{iQnn(*KLlA37I7FQiGWkq!jKTc>@hB2iEfz(*d_^KQ-A)HKsaV=kO&)#JoPX6eZ@>JW%ZI9&7Kb}>Zl;)A{rAZ zlAnAAhi|VRh(x`)X&qhjw~IxvT5*MJ#&bdf4+?zjR3OLhui6a>9*a{k6XXOt43Lg- zj2h=RuWv~u3KzN^gVKvLWurnAiB=!bGa*r|OKt>Ol9gp6e|de2_c_ePM6yOzJHL~f#t9FZ zC2@Q4CJiXIubS0%RZc&6&ja`UjC{*?nc^zqP`~lw%-L^sTg~jxZjRfRKl_q*giMOt zf>-=)ScM&q8*p;PybVDK;OofHQ@!8YOQC#q@8@0M3%MLt|qjIhQe7i zie9X;jJ$~x9kTiPakXCOLn?eyUedtdsYI%fWl|Jd*%7#Nk zf$btOqGOEiiy}@_Cx+YWW$~*jgZX#5iQwSSex{^!^rPdyV0}H7`456Z$v{lJt(3Ng zvJp--uE&9&r^IXO#bUrFQr;XlrLa4*EP0){EDBf5EV3a=Vw@w@$nbv7_=pZB5%AYJ zCZlDCl|Kig`U=-(ZT;aqOF=P*zf*dTW=;&MN%A6KD6N;Dl}kG+Z)K-G1VlqiC!i&e z3bgg@yj&QS*SlXPnY2TCFoPT)lsusUM^3mD(|LulGpK!Zfu0mAyEr5ZTMC$bhM`*y ziUAOc3%KJ1$qP38!cv|{L}c#FvM`N$z;xQ1pDiUgMPcn)NK2ajk@m?HPQ9@B z{4Y;*YkI%U=tH(<8?kuOu|r3%3kTBy-`E~45S$xiHyf&>mc<IZlOfgn^26Jo&`2_R#5;T9jsAXEz74T{9@5g%M_njEdF4Ojt1kvk2w z=*>-C89Jl6SD7t4IcfR-w2LK;^mx3)coZ%`v=at)x&$#(JOo~Em#^(x(E*=5*-HBF zi+kFKOKlue@=SJlv)(z$q$VF=Q{o!gIC*MZbVt`#PP9Je$gDW)5I5ixM$_QGU0kIA$q2IH(Uu#JBhn__>#nr9nrAToK;= zq=7ek!u0AQi*V1VDMJ=&qRitFK2MEok!|+>gO3!~#Kj(@ncSsW31+PTsL00n-Nbh4Nt#Poa!RG`YBMSrvE&l3U? z?LYONp{NyA8L;jN?5*qBX)1AefSl}$1RNj%0*5|y*v+UX$tV>otJLuU5T*%GP%&gU z!`87OT2}F)r{U`N2N}kT@)AL&RJZ{9sAgQc+gkgL0v0;1K>!5ziIy}(P)K|yVCCpz zR^}Uq!cbm^*B{&kG{fReKjHAE7s8@=A5d^;a4Mx0lG~An0nD(tZ2pDhL(L$d( z0hxnTMsz!V_%KnSB(pQy1Df%TC^Cl1J0cqgxli{=S*hoB+j90iXWavEX|F4`P}rYM zvbX-jZVExt7y6_ns5q^aT>9MxA#_uOr&e+}`R;~1DO!^x!<++{zj9j}xu-ML%-4O! zHr$Y<>JjQ)NX|fsZeIUePGDNg)KyPw@_Y)1H@grvK-C-1&WAHudQxvzG1NGxO3K0> zdJK#ap#Z~|Lpl2Yocs2sh!yEqB+4*rSkoj0Wzne#Du|nrw}&(@N9n0pY?R#|2e&a? znhEp}5xT3$E-1s<`qd?dYmRJwp{;%u6*#}CLbBNq+1WRDm%7y9ZhNvdue@S~M}+d7 zx;#Vap$Dh~1V* zI`4A43^@L12%Qdzz1Azb@lbl<{wdBd7^fv5EM%IyguHv>$fXh%@`{P2zj8E$1*@?& z8AFs=2XieX;y@8}SU^NAAZ!-y;`aEseNZ(SeAotmNdbA)#(_jX;kX*xh5JM0!iSEp zVp$5xW=RM(N`cYim83T0PzyXD`dbytDQts8vh?7-(S8!8f-a=ksJr{8D9tiZDN(N2 z#?}lT@aw?w?Pg2nW^qXkff*b-#jpagvvQe=lGirj4$)MO_RZsVse)nVdYX}MVsSD& zXmZF}{1wC73g{VCAa}eo=&NYBusQ)f_YBDLWjcHY_dYsP0K>`zrlWQt7Er7uos!C680OzAO>W55>0M|Ah1e?b!^fp zZ<3E$LhoLcP;>zC=xXT0LdZKp$@f5eMGYsJ1&nwh{1bqK-dBI^#%H492+s!)?jDCN zJR>U_1gU4lK$`++0i;IljAfL(rVmQp2fcMalP!5DStw+#UBGyVkO(twgG=Q@fLV&h z`QtE(eRn%6LX$#RSRM8#O2-H&Hf#fexw4g73$Dun3*dwWaAc!}Xd{P|#zdZn=TEcrU$19&%%Pr907sr( zJDyK)mmd%dI%P|8ED)c;8`{mk3zBhQ)bXQjshK@uuyhM8D+c5~1H~jpyL?~hE)}}F zvajcRMc9ctBx-__!vS?{<`l5PmA4pnm}HE~)VM+z1Of6on&(SO|pSo1G|Wjh0cc6|4zWKk4*h z1gEwL3he$7xxmb+pMp?C7%@%hj%rgjhqLS3EeU2w`a0Op#*>JcV&J4W`@J6`i>8{FPygN zLtS~D4ove0WkzA45bx0&dAn12+$N$X1fxq$Sm zhtzr>k!W8W$9KdW1f`+r^5(%)PBlLr2gkK~7ItfW_*jJ%nK$|z&K6;LwU@`S!`?9H zlFa`x`McP;9l8JXE=#M8>XnW9(DyI$Ve;y-rFcKSJf<77B)s4zV{>D8ynxbuMedSG zKR*XUT75ntW2-12pZzvy1^%U&o+O@ZLe*%g!$u&ATImdd%Y7uK!L>t#UG)N1xh+?7 zrwF5#ZX^)D27Fz%Yh9FJTO8AJqbM=n1L-$oe+{6*!si)n@J*wB_B%0)jfxi7Rdm#+ z5JIaCW=Vil}?nioXF^$@ZY|f!U~**NY^zTUIY53%+mt z>rMq$hO1w3X;MKCH8ih$EJb{~iu($faU;VMJZBTb;P_Dua194Pk2GPU2Y6ZGN8JEp z99e*x%bwQbnaq%Y=gNI{BS;W4fDK@fmh>PKHFBlK0k#0(h5!b#_8drp#@Ycp=g-IV zfeZR)Q6YeZ_PLWmc+v3vysyuR6&0a!Hhv1VFWOA~@$#_;5DYi|p|2cfl}KOm80^A_ zB4)mp)nA*$&}Q?Mh{%M^ar7zsigkob{uV?p_fL{&mPLHHyB&)7V6#lBFk9Al#S}JF zVKGDdtBL++(-$0P1^b4QFs1G|U!|?%kiJl1P|W+&jp)`YWve&_q zc;eTFC78B3+;D@k-${QCEN&(Vh?(-#_VY839%rx3&08a0i5K=v%I1oIUJnI9A%zNiE|%t-8~NTmR_Z*HpB|IsTds`pU`R!LsSUm zTG@Ca?lTK>BU*6q)CIOlAgqQmBBVktA}}icCXhmitKu=}O;IuTgU;pw8y9p##dW}% zr@yHD-nf>3RWwExKG^(;WMYa9u7{Ji1aI z94`TuZ0rCxju=Bp%i9a|<`oLX*J}J2SC~Xa$C#S^edW2_J#dZ|D_VyqTwgNR;s|`kBorYecWmz8$ zAk9-Ga-0CQsR)PfJ&k3m_RQM=mHOStDmsH~Xo;#__&1~ZW(sgOAyP5uv73f>s4u&? z6+duAp^`K5(HQR2S1ikv^i4pxh|hOxO8vgy(YA~p6XZxSUowQ1Qsl^#Y4_e}{oZt( zi%X|bbX}D3)v&ReH~6e8$3BdRdaqK4pK>nWmk^m8Y}4|Yg`1dQc7tF^nZX&oAdWWm zD~i;u-E%x$k9#Sxn(x!*#R2k{O4oN#2 zto|!jhn)T~IBqDp=zkA?m%p28<<~g>ti2Z^spLJC|L8|qG5}i8!VEl8V5T0TEdKnp z^g-%CGhi~m((PJAhP}%p(sAHZhU|dc7kZ`^1xUIaB_48nQG6^fKzhJyhKA`c__|cf z#LwtLHy6``T}_19>7bCATbl;tj6CgU%w z=4}MmvRtM_v!Il10bBAHg-TCWXfr*Njg%Ljpy;KoPyAmFkZ~oc-T_(L;Gi0WO@K*5 zJe3PH(TY?vLvwpDH5BIVdzh{0J~9=|sKlZV6YqX&TMPbSl^R1f@f26I+=$gl`nKR; zPt*AZ_CAwu`*sR=cmJ5ljSOwd`&|F!X;0O=03{FC8S&XiWk;qj8#|9*TF?Aq_&CwC z#>DS7^7L`jTMHlv6{@NQfuXek0GbFKO4=X;I4}fEN{n4gjhGyQ8$+;jzcmW_V?iRU z+<>8i!6-}#jO8v{bDT1gM->W&53@{wQD_89c4|R?x)vHo#*p7p1F1|5QjJ?Em@MQ> zvk*Mc-kk{3=ptb)20LQm#$}=^h6UC-tvWq=>9M|W?RTb;^QP~b`WB*}f4=@pDB7^m zA3;bbl_1)! z?HL}A*H{a*$3$7TgMyjFcya(O}w0(fSC z1CThIcNS_87JhU8jl)(PB^Z=t429>BLMEGKAdyN&^Pv8 zd8=_2Dy$H#e#A=aZZouEnCIF{V4v?fjj@02`z6-?P2gz`jZtR`^ow&|^1vd>85(#$ zoT$aH7Uv1tFXo!C5I6+lvdSEIlBJ|4yGFYT&9Pa&+d=w9Ll$Y(4O3d_LU1wiW_E66xJnDmMWDC%^w$K;J4Syc~M$sKj(cfV=ut{s|R&9dQ zxQ7+foV1@3{+i%5Eq*rXH6wLLbSbBM(YhzM_m=|fuXD=5tW*AaztDVN=JTcIJMoOd zA`M`2gtta05!qsJsA&p%zmrv~gXxgJ=0{YBSgn!V-OS*pggr#C;MsK&J}=E;3~t~PGINc7=ky$ZfQs-FqIIemZjFC*{~l5|g&yu$GdS|S1* zaHGAL8bf3&@mCoe4hH8hBESS@#Sl``^8x{eM8|q4=>xn2@p@A}H)_F{EnINM?buYv zf(#Zk{D78>O#;h=CxCL{z9dRq^;Q63|WH%RFh zL-R=s8flq8+rma4Mn~inBuM>6b>o!9%7t1|rD?q`1OlB*O5m9d-tzzMWNc$dF~vak zUn8OeZm+y+iW$ygK1kq}>F)?6{2u?+GidVgSpybA?6V-p<4MXNO+N|0sTh^#y?8wN zV3L`foT^#qiGQ5nIxE@O7-pU)wHUVhODYz-lky}v(4~~ioM6IWJoUvoD5q@H0aKr^ zCebaw%0^A0b>W(or`p$%`8)Egv2(&NJozhiI8Y+F)5&q(cO@)5NCx6H3jASv zRren&L0489iv@f@k%(zmv_}TnGb^I=@z}cp|TmCjx_|pVSd5s4u z-}(5eVswl&@CH6U?%}LZ!Sub)*O>rZUT8I1F{}#WFm>qu$gRJgb{}cdYjBz1Oi+$j zIvM6PDJ<7*pIiGP?>S;~(Gbdef=vS8)_mHD)8+YiESUmI3on^8LaM|=J$TPJMY7?F@Mi zlVQzCjUA0h!i2`Uchdrc#Y*8~M&pB?IKy@Dbp0hk!&50x)AowOAVV+(v3^(z+i)T` zZzI8R=YGZ@KM99G@nhd6(8uNcJ$I}JS~D1GRA=HgRCycYFw0dDb}3||?Rait!LrKE z^^Ws9w}z2J)Mvi{27nX~VIee@-juQ-V9P_xZOyjm&OE`@y^QY|u(VN8`O`<8(1@uWRDU3X$q zo_YT28saADl{%U_5Zz4F_F#si?X|d3aQSNEMs2IIs;Q33vJ7D(L%^?#9wPvyYZvg#_dlif&~Vc8%_wMsU7sRi*m@(# z)(oU`Mq-TvNk(DwjdJ!WUWQgoak_UD^WUAUQ;e4obS;}49AV`A*3i*K8kA>_S~}E1}vfySQZ;2p-GNRDEGV5>iu$D-K14!u7E`m|e#0_X? z(@!eU>{E+i5P?FI1~hQfse1OK-0-74ve}=0P)iZe&#;He%g{+>m`{3=3xPcy1}yCc zNQ<*9+?Tj$!g)`=KR>?oX!p}4ZzGlR;Scc?a=`~7fOT446Rfh2U^P z@!?J`E4PxR?f_w*+Z-7J$dFc+g-gnpRtYkFIBOG|xIG6d*S*y%TIM+MH@2Wj3CS=?5bFqx2iQx~f$TQ* zGD)Vgj|g{!91d9>w~~u7xuuS|#vj!=7t;ARb!&l)Tw%ebD{#0H6nbv9k;3IfM#Z70 zOhaJ$%r}-ND>s{+Y#6~o9Tp(v^Afko%TC)bz&E@(B^JC1-6)Ec%gUW>N_iC><0nFo zYWE$-^~DpWI`x0?u*{UWkUs7HLEVmtuGvVnQQ|Wtbig2=J1qQfQ4oh^{zhr~$q>?~ zT;xeWs@26E%veLy$Kb8qN3#C@KpmymE&Q)u7FrK)lF3@aeugnLdS&DB7vhT9L|*Xc z>c3I3wCTlH$Row!$4iL8z&;^4t0@=*qq9*qlHyiW?weV3dUSX>&IkUvGMpuHLIphN)&L|EWfmB|7F(`Z$dn6;o*9hUz?NW774)c;r6jO;1m$>7ZWgDns4Dgn`#u4E_@-l z=Y2*H7#wK72~3ihW3&OXT|LR9%r12y^UIVt!G-*78ISMY*j{Gs-UsS|DVplWl3!t>=azTa zD+LjyPF3Aw3Nqz-YvnduXVd02aqk@1%|~;)SQL-0aQ6z(xJ8W?oFuv2yNE{&1sCFx;8}7LFFQvWRb4Xz3a;e)m$RtM7SFaJt0Sc2ArpW~ij6Ub%PI zx%XT^e|4xm>G&P^LgwzEPOVxd!Urk1quQP!s}ZW8F(~r9xEBScH6sUug6PYt zqkKHsZSfraIEYchWvG;ez<7y5A*;tYO<>k}(2{$^+GX&Uhu-7v>grPJ(rAr5A?l1M zYT_stLl7+u8*Xkx2QGr4I++0SN$_Pib3Q4M*@e|ei<*$~gO}WpDFRm`S)Ry*EZ~!D z8j zx>SWio&OzR_KjYUL`+I<-aMp&1E+=$x2FiFs1E|TCC%9w1>sK^TNBFC2c$j~$qCZ< z1dW*$P_3D*1bl?lS`c!YQ1>U~KGY0pBFv2_#E6+tlRQlbDQtp>d*l-~r2-{>PLBVn znYmFB7ivY|c-T`B$Oh%Tvq~W!i$=Vs>YLrG6Pp)e7(y|PN`trL3-h&(l+&?f<-dT4 zehK-!21s>72dEI|1l6asDFJ|!l7kU<0*v4I9wi*NO_HgFOnO#z@oA)q#Xiv+OMhot zDV(*X&_arH+eQD4uc_GwCe$kPoU4vea_*#yK$h^msNxiJ`kmc^qUwBcE-gWO?`0p0 z&NKTT;;fVlag#>tE$ts0J8w^x+=!R`n(`b2{Fs}0qkidP%DCc>_|racKVOgTWiONkxXIXj$-R^2l>~O={RXVi zSrU8{#JUfKF2JdQGl=)#7Qq?jWe9Tsz#^2qbsq_7GC?)prqpM>ewcPFVOBkq>7OzM z{dXPs1(P6?!s{}6?3VUxUBR?Gm-VoPEixR^URb{Tb ze%Qjcap^LyR7T+I7bim%^ddOThkiGLzQJ=|WP5AFe<(h9lAb8i{b+J8PT$26O1xF2 zq;w_KOrGRpfxL(V;P*jj8IMpyQ-Baabuvx`iT(KD#CmAL+vb5)6FXrJl0fJ-AFfJL?O{1 z?Tl;eF`mK|%%b8~V&}-@h($#!w?>qc;|8a(OdwSE-v~l<3R+`t zZ+f53w4)QjR(&K0NkXEbDWU}ut&lq~k2K*AKEf9+8VU3XmCTtHnafKLN~}vNNBRqxCcv2#(m+zv04aHldw<)Mxg;&JxR6_a^={_;~Eve5;AVRk1bX&0rD_DRu*b?mILL0T>oQWQHJe zB!Jdgcr__5n(u~A?VEcgGRXlA7$p7l^;DRyX&V3YTG-%(^1ta(jcuNpPyhaYHNUyZ z==e0%5-jph%;5LU%-tmkDHL)?1T(PE2Ew5sEF8)3&3=$^2`ssZl|U8;FO*0{!(($K zGOxtN<+q1LC>$r9Ph!>60v$n*5ohV}NQ+>xN%dxtYuxN-F*fP^WTUxRWRnB9dwKC|Z$J(r0Gw&CPKRzd` zt#12YKHvDAZw@E1o8Nu84Y)j9thfLAIR6bgJg+S()^owntKfsw#7OtR=9Gn6 z&vXr}Gko;!jGSA4>X~>g`skZIk8GX)pt6P(JNBlVZpDwrV(LO8o>YYZQhlbzKkz!a zt~jjAF3GMp?ednUSDZK%z)9iDCUwbjW5&ywi^BL_2G}jWEYCP)GbQGtYF58LFKWIX z!auc%`4KAm8CJ|P_`xI9Ie(P^`lhnDyhHoy8AGp3>{6JYb%Ci zrx44m$;jtF(>C^AeeO>38RLEUlHpqiKX?0+SzkKv_jcCH;Opb| zyMJd9A`Ym355tzNGjAWVR=#^R2C3i$))9pes*sK!QS_xzH`uwRD0g#a3lRB!@KxEi zm=LAvkNwMQ2WQE`q2rKo-Bo*r95PhNE|sP3fbqRMb>E1-2%ddab~Ipm8*wKtwe zvA9^?MQFqn;nT*mDGiyEzy2-Hp{N-rllLX0LnEEfqdxG7cm8%Ap45=7{c}&}nT5U; zg{wk-G3(1knvVzhB4Ip1A>`Ye3oE^RU*_ERo2}`;b9|5jX(ff;5+@i5Daf;FrNrCV zFb@t27Ku8;X*HRi`Tj^z)=TwPW$Q1)G=Az`ui>(SP7;K{QgiI9jL)13Zb zS93zlt-6X*S+a|2nAAFOz=)ge*$L+nQSxm^j+6On`PN_V>~mCLG%s*-hbC9}!Vl3d zcG`LCJ9aQ~ayG6x8@B}6g=-xg*2~p>ZQ~}GxPGMC>8+~A(G&Xl-+EPgwiWrbMj4s& zcZNy>Q)ybe2@6tp{`ZaLaUOpXsD2yls%iA6y@e)fKjjgcQzM%f-j+8n{)G9!6^V7@ z7AqISj8DI`5-hqnu~Rm^*2*4P(0@H>bw~UAJsAI7Hn4KTh*Ahk$G9)+^Nxy5+HQe% z;H07sRwhXCd#vclu3YhUXWs6KZXu_S4J)0YT*KPOV)~323{92h@xbCy2(OuUaw4dLeYEp`5ouvw5&7SI3TRflprpDR()1^Stt$ID(NU-OVq@(#wnYvD_Uf%;Y z_t2+#*@YG<(z+DW&QW5W1Z?&DPKx>U$u9qjGa%c z2!3QVy7lJAve z^ssHqwZyn%eCKXLFs@LR>I)~G@?6ilyb{&F_A;#`4Yl)R&Q`h{*v*4sBPgY_jWxHy z1XQV6L&#F|4`k;xgliCaS=$i3qFv@HwB%w~RiC)M4LQCZ3Rleur^;J&dAS(+n2U?o zTtMg8HdahF{fLMw=)^k5C3f;#V&e-HJ@{$rdV3?cb8vPO>3(bN@*80Su44>amC+`l zz5k#&t1zGGcX-+BwdV>wd+}CTUpRErrM})6Nh~iFea&zS=D+^_z7gAf_u=!i7l;WX z-y(YHQbB9!hr~)ReNA$AhJP%(-W1gh1QlOQy(?1g_K2j^-@|W(J%8-_HP9$Fz5QbMZ}3#{ zjOco7`x7et_&*eKsh3_#jqxvHH@oXiubRvMo`@*na&HBr4+pK4rv5xn`&$0%#LIf? zR4i!wj?v{#qW3K8VbBxuN7qwtdoPYhgA%ciZhH57XUnVqN^rhPUWmSHW^jA=;XF(F zH(f^Xp9jk?(2u0M7;ri(onF4Y-G4bj@pNp!smkIdBCC-WHQmJUeY2*#Gqc1BPCs4% zmguvIL$N@L2yPP@t@^B;`?{(!ae@knwE7-a3nQ3{@Ki`LG^s|s3XcDXeDvxAT@)tY zZ?rzmfi6%!C@E-&>t~{UQfVaIF)s}#l0{tB%&&pf3MkJ|?`2Xc`8+%MWZ9&wWb1MU zs6Ay*G-RbYdu5Ff+^`aE`uBs41CR6HpD@b_s7PlY4+w$>hdg9Ck#>J;x%$v zMhSOxq)&C;(0!6KF_e%dl9!<$I`AlFoS@(t%8+Mamc5i!;^w<1Y<{npFORK}zre=_ zApU^wPb?q+Hy;QNz4qKIl7s)|t1ca0tVH`=H}QMgPw}C@C4f4dj1O=Y${2Ly*R04gXD@ci}cNZODFk zAM${ZQKf_BD=3nj>)r?bZrc8eS^161yQcr5&P_zn6w?KA@r=ZQeE?92cD315=MPj< z?SH6qx+>$*RVe z006)vsO=8!pMK@>dd_j)u_ro&b&M_I*I9CzEnRy^Mb$996?lEZeQ=w8M4D~YRv z?WF(qK^=Ee&}@}EsVc&UJ82q<$lY`uJ;&V)1G~!IOcUS3-7E`60^@9(Ovk;Pf3d@b zScf*GHCEdl5t--R+ffF%T&&!WKmB&N|271d^PnK&6ox8{5qB_p8~Yz0G+B}JFbAsU zbXb~gH~uj)*Z1hKydY5Cs-h&*>8P@ztm>$$rtRpcx?$vw^SGvE$?2Xt->W*V>%O|D z&iin={ugyV0vo#5YL8Evr&&7+005M8t&YcZz_&K+=N$I-4bEYQjvZVdg?9%KAA`=5 zw&OaB_+GBZs>Rd)q0Wt3P5wij*K6MV<8oJ8B>8`#&cAbzOhZn0?q$^Ku|`85*)U~Vx;>%Lmc`#Ze&aL_5ke6vtOV6 z_iKNB3HtT_gF63ru~=4K7pQ=#IlVq6Do}H{803> zFzU$yT#?a!lECwDI8hAMBm^L(KUf$3HV> zYGz7J)2JjhP17+QBq2mIoijDvsZ>a!BuBBXbxik3(ji%cfdTo(;mqJ-fn4~NTLib|%_&cvfut)pZJt|S;!Zg3O02Gr@}`&3 z5|kn;t2fAM?#$kvpqxm(>SWau*#HZfopUT=J<^`v%2)kHUb4`AM>5wvLbF|6^0n-= z>tStyiK>Sr#j~#F%tP#cx@-ix=KB6;UMGf`0n4W8)(CFKa~%_MAVWft3W(@~TgHG21V$2e( z#JyxRV{lP>KViv8zk6=mld1{k_O$$VOrd zmUqnMY29hte07w$`WJFv+(;T@?wOajGe?j^7VZq0k<8cf_|W;6F< ze@A0Uz=)XP<$N}CZ=|lde)-ZHHgm6>G8|>@K+nsGo6H;&%ymOZB{jNpFJvdv^0myBN^Q*^zsamE*OpsvzNzg@!-mwhv-fwtY&+NJE!UpcbYxTe`R56#?W4?X zzt~wWm+=d^dX%}(E@Cl*eJ?u-08aVNLYUxRGdD+hBa0B>++8V?nATk-f3CIrieiO) zPqp%G=bo!7&1pT?RQp?du9G+wdTTTVH}}?35?eNo-()t@QD8IIV)Lt;mJaE!#+hsD zqp(w(D!;7nj$>ka-(BZ(n@s@W^|D9rY>`lP{bJ_2>{@gB^|Pp5?XR1oedY{4XGUxp ze36uRdaxz!9GkhB6?5LS=Cbu`TVC_&H|_cT?Qc2?Ip+>_j@@KtNoNdoS1;-q>Z#G0 z`?j~*t9X!-K8X$M?MHtl+i3)O~yF$lHPD zjFI7?{_&g404JpoD%?p&(4wJ&tU`_@ony?ErWB#9IzP$WPEQ$H49bF4EO4RIOEEBp z+ksLNSDEguQXRvyi&Y{z*y%&!jzw?up_JlgRhR$RO=ecvoV{HEw%l<- z6_j$N$gV&~TAc80R{6pUU56k!P?2Uz#ge;Shj&-UiT01*WS-1i5!72ur8E=_-NNyz@Ai|~I&pWk1Emxe^Ix^g!C-e1xuFY8GKW3u9_ zKA+Qk{a;L=?fY&%LO%vjnXp-&KmWaPBG-a!Bhc7unVN z6^gGQTyugx(&@c*(bKQ?-Z0WRK`1mCr4MDj`>R`#>BXqqwhrE!4fcB4T&tL2>1XXs z(%KfTJD#u5e}BglPR+lf&*D`0>!vV^Ew7&*b@(iOE)V>6`m^+@FeoQg2pV1}G?2?! z(t0i6!A>@P#8i53eU?7wI)>TwnL9Gn`ziX6?%HNdkv_tA$1lQ9qR+?}eO$a?OUD%7 z1L|o%+)^BNMqep$ls@-kpfJ}(#0_lv&Hwe(WOr$BM5&*P14P ztTKtjC@@teS?J^{^9$YKT_FT*`}1N}#U_iBoe{m64w+fpu1e>zdYG-$WLr$n(fS-o zrSt{fP-lpExlKZLf;3z4g)Xc#4O7Y>20Ngb5%XdM7p%(B_f(#%(%AG&=i0^)=a%y0 z95byJyUjQJMV4^rp$+m^oOD{q!~;J)4xyvw7wrFxQBCmyar0 ztc-;Pxt`i|a_xg77jiKQJI`HN6+cJk;%_qyNx+1Q@cy47GqryTVhaD1O|gIDKShsY z8{>R;b4{GysUNLqgOatrn~U&W|0#c;qV34Pe2g-xXvh93V~VyqWjpi>6z$iz2;+)& z^q)do#C8#kMl>_cOf)zDVz{m*uI#3bPPzXI%npUV2K$K3Y(?wgyp^qJ+xqTps~G*K z+@9njynR@IfRlZ$&r@*Az$0Jj(*utK7qt&OVd%{H>wn6}iuPA+-S%U*!`L^JuxQne z5Kbdf0~|(HeM+DEg^G6UpVA|s`{{qm2SvL({tU9zjhpQvj44`08MJ33+~rn2bjP-F z7h$&u|3(H|(TbmxDuU0r)w&Dr7Q5#;G|Q$tY@sC*D@iFVJLu$#!nQ{roXQy!}xUg}xob zpgnq3hbwP2Q8w+qxMq%Pq+GGoy4*XJ+TK3LdBmj*=tdguySFPg@1soLGf*wKGUr4m z+eK)mUf+9n{?5ky=0qs;gU%LV>+BhD@hLH}bP76q*59hLec-Nt7Za!c%KzZ3{+vwI zGsaBT*=!~rTf+Heul#Rd;%{kIx?@Znf90odhnkPR@_Aj2>9=is4n-8&jWKcjl|PAz zyY|~Z{8nf6hrROuTxU-((bfkV{S~i#naKRC_pkg<=6#40y?0hc2>ihkZkia+!-d6n zbwhA&1d5wq1a}jD_DsPvYDj1__j;3siv=l4Qil=2OrnPn`U9r;*_aZAOHTy~N#a-Ubri29Rtpok zb%yMUpo`_Z%5d54V|IYciXN+>E*93w293ssrn!0(Gg`Z?Am_Y0uZ)?I(CMlSE8@Ap zp6dgPsC%bajb@>({`%P#A5oX8=BUW%*c1r?GKpx{Qzk9E=%4~ z=~hC~{;YJPdL8^WGjiGt&A&1u1v7UKww@Cks&3yTx_zkE$AE1{E*j1!MYo?CY43Y; zYRrt>%Z*&R6fwm8u^DM1vwj^z6EfsLz9EUD&yKo3q|P1y?KQ+&DT?QzeUI)j*7v$) zB3xyQScp0ZD{$`9 zW~5LGJiF`ABl(I1D8UK_aK4Eq#aaQ(;+&AwT501FWuru?id3G(MC)PV zt@I6AiLDU#6tKae}-@N4T6z5D|q(J|2 z&LqyRwX8Aw87HjDLDL8aK1r9zm!U8RWA*_Z| z)Uhw@1w1TWK9hghR?R=-2_lX@X%gwi7A2Wedh;lJt0?)^<-a3JenhtJCle*+kt^uu z$+&1fbjwM-_KOt|MMgen@LIl0oR7FVE~_6)wUB8~sGm~+6I-NPgc$Lm7Ys_ZD(;@H zChxKtvO~GEROp`h6%ul{CQ5FmkNm8q9O>D7Ea)ov?y5Ac>h3E=@Og{^#oNxS%N8~d z&AbZj8mgf!e<`2qFz2FbZ*4}hh)E4)lI#BaY~4q1o<9*K-(wQFsVeY`-aKMbZlB54 z{kbS1U2^;Z>6R@<54d8S+2Es*bs;>@@?4tpew>R^ZRxf2w9kXUnex`j27XI|2Ctj77s zytrfU_%`gvCNQP49M0)S#(XE%^gxb#Er}x^2dpwaHz8n;bRb($=Pa8|`jjVsu*PKysZlJ?(;p<_p=<)1u z%^X10wuKNgK2`KIhD!M6B2A1OZ{{?@f8W>m!bjI1k`{ax*W;=?PO`JZk@3Hpv+epW zjcl1M?DU><5GKLsD6o58;8s};X;damx#bGx5YcN^bJ!6m%NU2|qRo89&JOQo_ZtHR zanma2K+vwM_GlvDJmY7Lz-EnoZRNETMdcTF+o2uQm6(5J)vEtyYyBh2aJ#kl9T2=6s zfw6wj(VlvLBA3z2>rff;p6b9#rM0Cb4gos%^g9mAPq<%S@H!jUW|L&hLP&e+Diio- zP*Y|6r5=mN#0XwO2?Xyk+E%3rg&~^{YYW$T+G7{aJ!C+$PDvd=mL?#PGWu|(8zB_a zdCSi5G`n9gy^o$DCH1tj;E1rm<)b-^{(6a=0`!(ON6~=J{Jmr}rS;)!Y12FLnR2$n~vUvT}oAk#Jw8 z?{srp{+GlyVo(<2soV+)y*pJ_ec4B^w#G=MuGDZjn-e`lvTOM)D>e9}^fryn|EI8d zQ{lf84F4^j{%pOoX_Uwfpr`-WeZ3#Sf0{n|Yx;WM$bY-znjala?3SjY=g}6avd6WK zM-4O`d}-{y-g|xf7#oxHhwg}~h~SO!?#QHZ?Gp`PENM6F=yQPG*Mnzk7i`sh`Z0Tk@I7$G{p~mdK%5EuGdR=V zJc=`nrsHf^lltI8aQJ)UEIpKmP!{AE!^ot8nX%CKPRZs)u`)%1vA{T0fqU zv%BZ9jgNur@j(1U-X@a52(W#aAYkYe>F(t~;vY zO-8G5kE=uefV1L__;*#f_c-G_;CTLh6|T5SVl*UIk>n!pBhS=kY!i`_9SsgQ#bSt5 z{r#CC5wR0;mYqHstsgJO>WtNo<7GP>s#YX?H1EW*r57K3Dr1XvRm>@r9C-hUq@3JM z0S3=_ZMOmz{rTFi!{G(L~-^{9yOAcSgDu-97ZdQ&l;^q>< zSZ%ji()EgB>VWHbZFfdYV9z!6y5gSea@V+fYo6BX_SUL8$tc&+cKK-DFp{1qt{Gqn{6|6cXP8xW`^ef^SP0H3S7&?r>T$FJuhi}mFa6QCyF`Y<9AZTWo%W#d+GHd zDF?&ymAtF%J_!y>V%K(!Z6kkuUvl`^T6`bq9Z$+>Pm~;_sg=6y;@pwFc=pqqD)UM= z^n{48jK+A$L0p4fa@d$)oQ*MX-nV|nD&iI5qb<0ss6eJc5*pWPAfB5RU+7+mwnMS4 z#cJMNfyZczisnZ6CI{83LSfb9oMWh8@5~j$D{ruyzh+$+f)kZ_b@l;vQjUGg4pDsQ zMyHZQr=CN&Rgv)4Dt;C zp1LuNo!trCoW@BS%CfbuTjxhtp5LJ3fi(_Jkvb*uG=y54Qx`V2Dj}KnX5F=8hiUu^ zFRc{WUUlQ-$>tLs)%-mBtCEjkUL{d3VRSiS2fD}%%O z@X8{aBbadl6)AmZGWT>U;jBivGC!qE7w0dDYND5{PgjK4?jav<~K?7&M#WB z!-IQp-#TwsT0VstS6CG52g*Z*}7r17TZHFGu8eRBsxm$Dsi&Zex|9&v^`82bT{LH9)K5oeOXy4TX|yR%vch5FI&2vgG~iMOTTq0e#I4> ziZ?Md|Dk90S8n?j(%*D`;< zac0FBfcT8aD){UzNu>hE;+0#SMqNX#0>vzUQ}tqMtZ&)kRapU)I=oP`r`NpEjWhB_ z0(AokD@gQ1wvX+|7@%T_c88y#JTRLxL}#hL)MTmS!X{1Olt`ohty1Use<<4r=5HqL zw&J~3I=0&iB+a+(w))$o4tu-I<>1({O#rkBsWS~qg3=j44%XHWxf_p3v|NHS;!|%& zQ8A~->tvZ%@IoE-Wn-jyx7*4%a7$oZe>OtLz25lnapd^KU@QRhD;qFprxfs8{H;>v zI4EU^|2-*V9lP=;k}?I@zg%B6zG~#+5zRkaU-h}S)TRS_zGZpd4+hL`5~1c@U-kX+ zJhjPhsoiq{#bEUkITAK*Ky%UJTAW4N2N#Yz4wEcXzF>XUSgFa&gTCPIJJB+!C^?lT z6Ihh|K?^y5GJggvO1@jj`EMyoerc1*Xf^R6s{H)*{5HbOh~!Gjz5y zoV?d(yj4Awy*_T=+Nze>4z{ZQLjoj2iu|**s(*09VCvg@f3N_dOhgvg+k1D*1D!@z z>nm;9A^Z<(bf!)PP(pwbVsxkXPb48gD!eO0M|jX@4{{=whnZtIIG~zb9OIGg@ASF= z1p|nNQ8Z*6(fU~gL&?l9T*D$=^et;xw){)huzca`V!71ln73VIA0h!JQtGQo;|D@y zqQ#d4`>nBxB{LCP(UUjyk826gj`$be2LbJfuecBLRUME2lf6w}2#h5h?4x4pQ2ag_ zsc~S0wucOeZJ$x-XOLTkIi?a#M3wrRHBm|5^$7y%3{Yo`=?u`A_-=pqBVA_zrLXKguQJ=ZxP|Vl)uJAih6v{{HX;=sAD`j1k$FX}RN@ z5>j5C&hPu$O$k4dZun#v;{THfj`Fxq5@9MMO;96%8Ugeh{j`MO?10H>o-iAT}f6Ux`oz{RWT{px-c=5@(4{-tyD`=0%{Yj+C0HJans?%M82ja|E|g}5;4p~ll+-JI&RJCz#q zx$R%H2}XCpwaJwD@;OC8_{+Py#*a4-4>V02Zyp|O{mL$8ZfHFdU9=A#?LHif`>H!2 z@B0+7=;xDn*Ro2b-d($6A8*FUB9Mj1{xr)}1=p?svtGQAUU(T)W-X3-6n(jzrJbFg zb!hb3-An26#RlG7JELwAyiF=p6MQ#9gFW>-Ss3_$%aX0FR57`ba*a7uCqEhjO2beK z!)k*^$XsRu$FK(GnZ-u@ zm3mOgqVP*mymNb$s%;nghjT#^<}F(QSDzDVk}K~!{}eH08ILD-eRaaZbFan7u06*M z0;N#D-0a6S+DPn^#KhqOPyMrk^-=}*>R zy^<{IC;&LW?0g>XYc3a0z%RYGj<%?+_lD7j%k}>cmy0=;WU3%{N5iBk?90WS?n2ek z-wHp+kKuO)5=}C6o^-i*Y;kuSBPPI>J5H#AeLhcp6F!(N_sM)%?Nwsm5P}x;gxyd&YjpB4q=$=WrnQEEi^jp=L)Y}=hCH|vl)9>W) zLZVk)Ih%g(+_ooGC-lyp{_W!Ko|fOPoXdDvK%d4XO3TZ9RN~7ox4Jqn>q!MeLhmH) zeD>2TN9S*PP<=k9`FgZQfT;e3+!r^JOjB21y>RB`?aXyoPU>Gg+jcK+`^yJcFP`go zSO|K!=1wo-k8VhLF>$-o`$u@Ve-5AATcsd;suy((_0;IhecM}avGwh%28WEdefPhE z@(TPO@Nt_Ap8*LRmgV=+*>pC1o-4q%@mV4VV#nZ<9l))Cq|YpZ(G>*n^Z@_5ODrn>jKI0lI3ZGA<#Fnn{zRxRF z@}ykP`&5~$k#)9i9AeDkCQprsrw1qF4LXEVEPs7a2H$Dxw z{O*hX?#@C3+@5q&l+!qsQdV0G*KbJK>g&M)8l0)*HUZ&?gOW8!@V@jrGT;z~z z%`6pIipFFMr?zIpnN_Vhr=b_&x%DTPY&z3mzBipj*a_qV_4 z`14~)>QZjsNTqhYUpZ*eP{B`KKmS%qG{TpYCobIOOQFSLB0hc(T8&;mpM1+?j7pKc0wj^2g5+jV%-MPWtR#}x+I>08TCHgwO3CJZ%+tW>8PAWtKR?UBmlmmrY5Xy$GXEa1D{@6euptnGX}_YrpyV?(Vg#I zN3@Y)&9P8YI1<=xi6cspLljdj&tnkRFf4^lPiGrUHx0y4+_6$7y2p2f5^mr3UwCG5 zFl-;ccypjZBESG}ghJ~!8ymj$Gmii`$rCUaNlkSvH^Vkh{zW6L4i{Z_p?}p*2t(-m zXLJ&cf?;O!d8g9|5_fC-g&DB|SCfeIQfdz$3E~#re>d?!GGj9j)Au-HV-_VcSWDD2 zes7&9IxLwH!P9hP(37Ql8!)BR<^uBR6otJP5;wTF;8K(+CR`!ZSaaVvgF`81@k+H3 zq+e3PCN4~kJygF7mA_dluFL?gfmCk#o2cAkjfQZCO{TK-M^t{9I^JGxA&|+)`ml*R z?{GzEa_bG2q?4#Stenr>-}$obT;r&hKUFGwU0$8mRW7ot zwd)_C@`HW-AE+$2W#Eyo^yz`oJMVw)(p@kkMV%gONjvws3sanPhsG~V!4eJ+b$^Ri zyq?(I*PJmjJk;MYG6HZ%1DuqP?z}JQbVGlQRwNjg+f6#~@UDdviyoP*6+fnO>{f5{ zUjE^1_6fT!8v<7Eh&YSDq$s|l@=-Oaj3&yN?b6+WmM>;gd3~~kXg{kWiOCbVw^hO) zdLFCpU(Rsn7R2*cQXq4>=LR`531fHOl@x>XnTHyaDh>8_hlX7t$ehveP7Djdt;?+x zN^#Y7$BE<1@0QB=OryhqM^==g_;pTu^!!!3!|V8-%2&i*Ic8gnE2Q}DJ4ZKht| zd$;HKt^CC0{go&~i5J09Z@CR7ubBmXyla;(_IEUb%N?e=+~Lph2>N&#--gGnBX0-( z5|52p0B)*2-mZ`FINvza@5Wv{`<8H-?0eCw1*c{O{zSaVV^PM#x3o=-x2vsTfP;j-WW7!qG_rrev` z#B=hZneW1)ZZgT_;uDY$&ZBF$__ zjGs~9M>BCLj});xuCld;26MERHk z00BTC8BfGG7wd#rqNV6IH$=HAnM;(i39Cc|g&c&?W4FJ?9*oj#8xIAaJC#^RmGd{- zcy}^E8&BZ>fI@ROZEX8O8}DE9V7#^g?f+K~#=#d!iKj38LQVV22O~@R6N;$6VedaR zTo6D3@WPnsqp^-_>1&pA$D(6DqR@v}#{hn|N$_G){-}+om9sMI{bcjqgVAy!l6wQU zvwWT4IwhSGxJTseGrAJn;IO*$0USjv!IG| zf=?!|+p3&QrR`PPabk#&3?o*VM0STI(c)z-Dyz&d)CDs4#mk2yDpziJclG!?Wmdry zJD6Gh$x`g#ww?DW_IEzlm$cuelAHjO?I0z_lI`GCp`Y}sP>sbiSMaJ3*oplSc`9(@ z&QHH_=R3V7K%D^UgfX1}UOAr73I9j~?l}%HVq39TKlpshB$yBZDcTf`(4iD#B0D|9 zL)_H~^kM<+Z60$1#o=pZN`wV!+?C}?Je%LWCSuXV&zK;NLch%@^fzZdj@X%`p&%eR zISD!Sdt{&&0n!8XA|^NE{*{|}$R2>(a~^~Omcnf@nz>P=u0Ox_WO?-1=HGeh#pf-b$&g={ZE5xzbU zI#KwTw4wvFEx?q@R8uNH`_i6o3Gt21WWFfG_sN;eKV0|_u~~_-J1sKUxdj*y&w^v3 zKdOR_OAT;&4@icolHq5!F8-@zkeUmTqQ#&rSj7StI=vJppDPm|rn99+%ORiT&fr00 z(9rx5hGqt6U;LBy#kaT9pTU9A42Pf(Wft40@YUYof8I9_hZ8RKqYY6f67ZAW7E@XF z1)3G0Spk|A|9Z1xr3Zb+?-fK0&uHGu&WUTeGe1DU0G=>dm+ze$voQ+xr=iMOe!A3R zQi#zJ$t4uOX+^O!_G89_qLXGMpeX@9J*N8f08NRXZE7kKMGL{X5h!Hbv#J<0s)K_r zj*)}NawEoadx8xLIqrQ$rP z^27-|e5Ypzn6Lox046LZKRf=BgvDQ36xN}idv*+tUMq=3&-6izW+{BN&HT^PYt->d z2!PWqmf!7!YwM(|0mjHwU- zG$BAD{1;4!|4$--w~fI2hc6PNf5`4^FdFf0YVoi19X=J98XtF#`wsqmJ1hV^#@N>y zT1XD_)r^M0em}eb{RYr)0R4vkhjh+41C5^Vx2D<`T>bN{shd;^$o0PlXr_)4Wbj}2Vd@;r{AE&GBQ_IKR< z{Mj29|DUf5&~E^znLlcp`4iZultQ@SR=~px*$#BtXC6KkGM4awTU^;m8l@ zH-MA?{f5bu_!s6I#9u&h=WQ*0`;Kra<7`L4;l-+zpMj(?|9^)qo5!_C6c*;dUFy=i-@X zQ9F&q9j?N7c6FQg{aL=~Q@iEFsyg@ehlY$}vyUdw|YvqngGlWd$`Zx^T1X887 zT8_;P>RK*0#$&-& zy<(|E2W_i_6nV=XV#Hp~g6Uhtk@kg>Vuy&S%HEj$eVJNF2O`5xAT%;D1S&pVrNG#g zKPu+}0pmw4>50j)u-@lzx?v-EPkB`o%+Eo!?HEt$*6yBDz@`N#BL{2qo2i-yiO%A{Rz#_ZTZfo(K4oQsW6{%9HU2L*#U`C>CgD_T z@Upo$%$0MR3Xv$cHDN65NQDO1V8@|p;?aZE4aw%*!Pv)fEYy{x66}_YgFA-m1^HBT zL<~CJA8D)=pN5nL3Jrn&R0PH_PmO=D%bR9TNQfRF5sf_EpHF)z{3eNNG&4&+s+1*) z%&Ss6g7H?y+KI@86uEWQgl9B`4J>?AWFA=K%L8ddzDZJ7E1nk-l^w^K?w~WYKr`$t z%yyQBUlFQ`?^uL;ES6;(WUhQ&w8nZp5-wCYFNF7agp<~ya}1KTX1BPdYLfzaPnlTk zcJp5e&q(xR3oB_4_*V!;J)Osu%{q7)MQ6&#s81hEbyvb#G%Ne6iKV3YZ3vFWPCueG zzpD1I-G(^PtM4`tey7JMs5U{Af|k|f$LJ>`GQ4TOb~i^}8Oo&s==~4?Frq)XArVIJ znFh&v+fyJVUepbPtlh8v?BvL@fy=sv-pkH9pg>gR&`f@mrhL@{AmW12fxeT<%NgK~x6{#oKkI zsET-u7)DdN&!1Z!e3|=hlAtWp4@Fxiv^g9mFOcQFf#y5BC9m8@ z($;5$p^lnetnL<_bvQ@Xj?c8AOp*=FgD^sREK9>TH`5L37l&W5;*#W+m>Ga0=S)~g z>Ci8o0kfm*Q*HA64l?ZanK*h8XJ!{lDb;w#I^X2oEUs?SU>86g@FH;46|64LUZEsj zrlx#Hd&Nmt@pNuGxr3F}82kB9i?(L1MzYnFrCH;c?s7xs>zm~I8nUU7klb!wVvC^X+u_^&1()9BXZv7LHU2vp_`OhCv3gbUWe$H{`X#)_GOKxL zlZJI%9L9~Lfqu1N@-~Y{_dFF4c}Sv6=RS_}qHl5+UE=N2g^tLOxEC}q+TULHx>(n! z7LuvKfr5E)AlD3zuzX5v!k>x(zA*z;>Ls4LJ2&gg^=jd-iZ!CpN-=eF70tHvEORPu8m5ixEh$hMc>mrSOy4dY z>#iDqR~llrwI#(00vx97i`F>Fx};s#B1URhtNGlKs=6g+Hmr3W1UOHYaW%p*Tbq&> zx)eY#od+<5c9IA4F88`*9Zqo$SBRA^#t1YD+Ka45-xw&J^~_`ib3jKBiC@Q+2}_RZqA`exPcSx?oj} z_ZU@^G^KTG{jGXqg{~%PFB+#RZhA6BN4G8{vX?2NpR8+9Rd?h-uPV2{d z1I%f`bQ+aFAIb%=Mz=_{{AO=^s^%2r_ue%O+MoO&2uANg25vp@`eB6A77PYaIy_jn zo%xp3BZxgP7!|TMNZ~k;>9?%U(Mu^n^kqymrh8`Q zUS)XzHL^7?SwzXm`?u6nBqd5IO}|sD?F|A_$yqApExWhCGMW;0TlMM9ngizd&Ex`Q z3K>`+pnG@j6Ou`xH&HM^b$Yb+*(QvvImqSjNq)oFN&h z`ZOk_lNXoCIH=khC;zLK{~D4a(mJz3P2I6-Rb7=0sb<|!ATq;JDb%8DpVa9n;;5ii zs?YyO(5|0()n&4v-F`xKUt$tk#?TaAh$AO8Cub*9{wQd_6ur5}5h}^L_bRW4FZslA z#i^_v2aQ+IEdY(z$!@{tOSe~6nfKH~jR7gd?QC$z zV&|=aSi?QDhvEPeoR`AFtU@jWdpiG)aE^PA)ByIFiZA&jOrs$MzQqj-IKpQ_5y2hC zL0&1)Mm3<5x2={T{xnC7XT*9vujn;H{6qeS=oN4P7{Vi$YR2}WqKhRHoc!SpG0PJA z84^;#baT~k1dSfegNNJ~k-({+x z-wF~G^jjwr^pk$8bjDD3^`efUo*JFGZ+q)4w!VGU;Basy6uwQ3asI+4wX}ZdF)sQ* zSrywdczN#n^1)(g;oG6^+lI@BiY`3d|7IX)Yr)X7mQxwkPnW+!GA#R+HYNevE<=Gr z7m}mx0KWJ#io?h)24AM;Ebaw$j+wzu0%!_b(qEkj@)UxFFGDe4N(~;|JVTsX@&lK# z{{GlLM=cBifT4@G;k##1pd;>%8U}C@j*OsVt&9O{XDC2YvD2)NpcBk8eNQQ|B`{7S zAZnYhWWJcd(pS85VvX=U)(?erBujqX$Lq@z_yl>oA(;@C74YcS;~Hs6<--2Kha;eC zA;V-2%xWX?zECO@l1!Y#!wldjHooDhWa*w~1kj?^z7#;Fg5)SoS(6X)^gHFRL3s+o^(T|3|Ag)ONx1%gC(PxwNR^WZ zAXEa5(cb(p5&(JxNowf!ilCSG2A-@b92^W4d&{9xFa%d*yNy~)DaLe#+$Um8)|xj% z5tm`P9rQ#f3FB-GAQ{D?+^|A5n8}g;o4g*WcrOJ?44r_bW6{bK_#>ZUQ^}Ya=>SRY zES-@ZR&!v1^38iA>=!oQg&N$zMO(;@U8T6gDZUb_l(+4R7-CEK%wBlJVt>&ok@H6# zln9LFMm{goUQmly#EMV5D#<_%cWic+mk^`YZz!G_p`ta7$JJC4=FTw!@m!N<oUK9)Sgy~eY}?}XqBCND44*hebGFTf13T%jeI z?%EsoC$_8ZjmW#b2`X2U4R%%CI62sxNSdBvn(q=P%)?;H&oGp%HpA*?$ zy(B>@Tzf{mqqdZ8vHi|hsTQyJW>xHEsJJVMo9iQ1POqx;vsX@=iAu7W8)EKWKjSnO z`7Znle;0n8%HRx?#~{JSpJ)efe0^q(pidgCzzz$g|%IBLuWlbf=Cr2fz$sDfo5UpPe*+C)6dCLNl@^ly%8iudR2wdH3 zhIaQ=<1IEsSyLMMZ!{!hphcbl00lxw-uUHRzB{V19BnQd{Y88SIJlb<5^&nM`%oWb z0}Rz8L) z!k&>_cb+Xk&L|cUfH9WZ_|B_%ktmLb9pXR&OXr1O`yh`k{>otZ!{AKrq9nQT1s{Q~ zZ174o+2__BMi@`&2~M{c8coO0$5L_)=bUf^Lki%eEQxuycQ}V5U@-)*E=^DcIXrdL%Tu^~tH!Dz@|; zGNfntpBjsaQt*)DnPqA$_T^YW`~ZRw{D8`c?k44P1w**FNjZEJx^@WYNKQDp~O#? zAUNlb(XTJIA{=WQl8qOh$ce+5*lRwEU<3)5GI@+07L%9Age_5Ke?0Nmu*t_SKp_jp z5T*)OaMk_yTXlaNMJI(|ar|f`x7oorSx}O9yETFUAI^prk8l*L0mZsf$Jr@^2M#1l zwlmusU<)ua;e$v5qJLBL8P@1>qZ>m91kr@7rUk$ zpyzV}LMkOt+sq*6-Y4eTdgAlg_H)D#Psa35E30_$>HyG`?QFl*nd8DZ3(HH_kcb47h z6Q^C`k&qUeB&;rWHIvCnZZVSkzOy#a4hGEx&<>tFYx_rv_Lj-nmZk34>S&HdtRkMh zogO&u7=#X`7&GY#@^b2~IjTY&>nJ7f7xb`7L?_OiF7(NhB?u9aiiB89TSTd(H_HZ2 z$77L7WnM6GfFn6plTO!?KAGeP2jYZym9zuswE@%q=u1u|_yqcrAWA@AaxzM$ll91SuuBHsQ32Pk+%cQ86(3({T(AC0CzONNhyR1chV8GXs95oki$xWopvgb z5=n|zplst3x)0+x7hS|{$KaaX)X1sPKt^xL^bqWA6rd%kD^VVMN?^s|G4`j0c}i`d zMUQlMsFa9GDI%78ny$1*LFsPTT5+8;7TSYVDz&7`&nPe!n@A~>wd(S>bY6|gkx5c; z-U%^-DmErwnba zWmRmkz=cjP#lRSDhshd7V?h=JhqPS_6-BtiJP40Gg~)ci5lJeNN_<9C72or!7`n7D zVZwU)PUS;TtANND(<(=_+Rr~vNNvB+diG`e#m;iMj{M$Rn>sEHJWK7kJktr}sbD z*Z&D$-(I@tTkfZQdBpG&Gt}>lj1SKqnK|3DK7kDOv&YC3P^3VW-3LnW4}yHPMS|N= znWd7LQa>)LI+Po#K<^!&pvuJ?(psa#zH)dmO& z&>8usoRLx>`cEGyAJhix(+`vqQH~dG%WZT??4>rN>+-ItRaME`^XNXLrx?_T$C(n{1c>}D+ zJc}t>CR9ET_9UDL0O}}#Qkzw2^;|jwyfZ@{`EKkD8)D(gB!@LHJ#v7^likEOR}E1> z1C+C^OJljzJmhR=INI5mq~Y4)OLFvDMxzv%`(^>AI|y+#mJ9#^3+_X+1X>|vpdrp9 z(z#xAx`~c8J4YYo7`;qM22M_>Gda%og;|txg{E$gbFJ&%R$=Jb1I7o7MvJ0TS}V17 zrR4H>3As7 zHFo5+4_rBQ8Y)w`^2L?|7#RR)v?w$WE*40~X<*LQ96so*j+(w>1(cpiw%*q1#w?6h z7>+1f0kQQ!Hk7K}+NEwXJXrRJGS!-`SIS%uOGP6ui7kKd#vmBLgreVI6%AXQ6a2twK~$6Y9tVF@4$ zGucU?GGSxMP@H^?-w1+!o~2Zw5AXD(IzCooH0YR!8>5&F?zo$Y%aN^FjHtU%G;C0|Od+p3LFt1Z;8~6S(q((Z zKM4iJtUIMCephN;A0yUaVg^6f?t}saU@m;l#N7-m!v3olfK^rk#k=wrAI)H3CHSFDS3e<5+fl_0SP@U^cx?p7B(AzG{b&et|stoFgz-k&?k*FL1B z|IXKDYf84HdGBk_-@NnFzP5Gy)qyAL%cj3>3bWYq`sq=J)32XJ?P`DBY`BzX@VO?{ zVDLp!;_1Pbv~%rW_|g=c<8*COb^f!yw&9ZA_Ai^ke_|AtgdTADWSr+u?WhqSN-18r z%a=ln#Y7~P67rw=(KJ^=W0RDq6uQ4ms5^g_r4rCYK$>DH20$Zu&T8j?WWEzK-$s6*XrDh?`VhYCrQNwF9(V#72bK{LKgb0x!_I~&;V87qH> z&FUcu$Oxl&j>GFCYImWC5uDcx@AHak{x1F_BnjbT$%=~pN=Qha1o}WNYTgo;$a>AA z3*bnarLZRS3b%Bj<1xBbU#$S#$R4Osng5Hh^WtkX`Z8$eh~8QO+=)I|gKRp*f6Lj} z*{0ki(ySvei-x!v=`?k@kn=TOo5^8q0G-_vU|5=)MIpE8$zfLl)~faRsG+0_38X7_ zTh!yHn*uf=g|z_#{0SW?&3c9_>Bsk$9#PT1Ed$3_?_3CrCNB_N#;J6}jj|p0N}jIH zi&^1CAR)Kx!`q}p)~|crmDtBWaVRxOx0 z#2HAH7lWtsyMM9ywG62>w4?#55}bK3UciRoecKneBEs+H47=&YH$9TFB-{=;=RQt= zdDx$o2*25SSyb+BU1VQwlK$op_0+q!E(j=``i&yAMlQXR!dOT+7q5_#Flcy9o^X~I zxp~VkSJEpn{dp|?)2=^crBzqMHPUud|xC1OMBDwpZ!F5XH>++AdS z-%}_e9{~ouz%tbLFGGQA1K;KKzdGPm`|QBn;enH0YZ&LBafK~^%{&s0MgwU3({Et4 z*M}32%V@IKVpGJ6q}UsuW2eHr76!T8;h9ktWPtIu&BDZ=PV8dbaR7%}(e10%{Jb#W#GR)bIYaWe+ zv9$zD%!0A@W;6J13Y9`-ibSCh5>JItg@Gi*1D<3Hsc9|;*pGsJtxpo@GNIy_ZHzUo zG5Axy#at+3-=);HIX;#t3aalv2=}O%gLvXu7_Ch)Gc3L%7%rZ4*k7 zO+0%yE63|91CEfe)O;-nfxQT^0fV4uuA4jW6-(9J2<6yRswRS9uTyx;xYAlL1#B!Q zFASBxQ(Z6My_@W4r4$vTt1h>7pvW}#hN*SbddS&3Wq$j5PK@rs&In(_3i3n;yve<> zOrq{O-6`epG?#etf(13>d$7N9W9#_p01XYmU{?yuy*uoG>|KW=mHi)m+%6$>lbv+! ztwLyD`(7(l5|ULmX`oUeWagR~4SSPKT0*u$C20v+A)8A1J@=vzO}%g4-}6tL?>Xml zzUOcg5X`nipllmthy1P`0)0UJCCv4QVV$T5ZP$vA9MiGf9eVrC z_7{FN6!aJ>ogJh7Z%Egl^4(?DxiJ@T*NRTGOfaLljU^$u>V6#Ua;I8=8 zMX>D?3EOEZ1<)B;S3v2z&Vg`LmXrV}KxCIY5~A%1g>1z?5}=#~JOfCUp$d?x%E;Tf z%!u*wa|Mhk2~O)ThNIBpx6ja3yQXb=MZDd}o2-EqU~YY>h`9&89JPXo3`gl+B8?|0XD*m_1XMz`N#i%a!_-HBk@!7k}gnu^8LI}$ui zyCohY=f0H>SV_*cQgy7r{@oFScr=|PRqYPaC|BgDS$LUh)e7IP4Cl?gIbc;&Y{S?_G!FoA{_h$JoWt)2C#!(2|wN|A)uoBg%LrVSCSD^ z6)JY*m%WngkD$eR~c*K^*! z%s;zqjna+WzUERt-u(joA_HyJ5S?9kI=hfw$(mNJKbZl<-`{BcrC?T%$?Hn3zsdkA z^*?jrq@a4?F52^x89-Me@ekcUKxZ+W;<%c@dA*YP{ww%j8iLLIuQ1yy(Xk+k1HV3{ z$^|f^DFH-*!y#phHGK5Vs>FhVW0BOMT=^Uty2}OC-@5RT1#cyiaJSAZII)?rlyv+^ zZW{l?btIH%30|-na3xENlT>C9{GdA6I4D7?%7r36CsxEIp#a0tU{c_&lYfoJ@>Pv= zC9cKi*a70BC-oVxqh%b&Bt4H&MG#-9mpN0Wf&|bgWCv((Q0aJSXc04ia9u05so#q* zSCN(gtUb(x0o};E68B2crw9eHgor4vRg^OPL}`A@-NpdL=IAR&GZE zKfjdzNvUsY@d^q958}NB{I562=52s`Z}yL-KlkM7j!jZt=lIx!mSvYal&-KMy~a#$ z9fYCi@%4Ui;{um>83O0C@AbFexFHy!>oTzKFd4gmmmBts=b@EqjIR8LTt^FRdQ2}4 z?sDDuG>s6c-hc5EnL6Vh`W=EqgDjZ}TsMf`Rijm%JSe>`tZ(bM=zfqbf?n~0P#Jyg zDTiG?*c*xnRSng1AJ<=IGUqN(=a#i8r_#xJ7lm9&UmiNE2}`k4&p-ZQ%%4L=EQMby*?hi56aoT5WQV^BRUy zY^xHrM>IC(IyxoVt)^*CVNf@`n~5}+mOxWz))#LYPQ!X78F0!!Dc2ZI52{K!C|dF4 z-ihIiu$wxXk`;Ufz9M@W6}pXsrRyGP%m{=p1=ayPgi~inKH%4k^Na)7kY9ZaP7nfc z`-bU{!TF+(ajvuf#n$ryXfTvTTFIqf~n!9p3XN{^ND!7Qj2Jo znI;r-BzC1&ioEH{sFvaF&P;2P>&~hdd}Nya%=%4tP9x4Z&tR6HX`IUkX7$%;zRe!~ z90;!pSvDgOz64`gh*;ub`8g22-T`JgBM`oAt7m_?hf?M2KzNF1_iqHke=3Zjl|c5c zCGMKSbmKhioWT3`sH?okJK~lfJpL2L`RC5r!e>@L`WPI2{PG*0*JeKkU;TqU&3}eN zA)Iv2+z~C1p69ZY5CSZx$L&iCi_Hs|l95XgXkG99*a%mLmFkpW{VX>&f_jHS!FE?- z=^|<;s_{}if_yY7$x#){tuP5#tq~Tt2RjTJ=V~^^*N(|~0QGvShq8+|P)2zZlCVki zqtR;)TX|bkp}|qIQW&yC4mB!E@X0|!Dux_;N#()ZnRAsEWPPHPpb;>I+^`Un6#a#9tL_$@OA+i|dP zAzuQwMgz_#*vN62!~KE*;(RDUKb&O*a~&>?-B#6FqDSEyHjd^5D&2~l-FNy_Ka7!J zLogrI7&LKEut$6}s&uf8^<6`_inZiPiPCZ5XstpvLxvLw|AIkN-mS0YEc3)d`>D*m z8B68QxQkq&1Zxo$6I3shgO9;bys}rqu2{K82^vEQ>QxD9IpvR9hmsQYg?Q9Ug@9#X9Um(iV>WuUm`@4_pi9Asq^Yk(gLmZq__} zYAA=q%^aX>+S$lbv^mX-Sns4}veG76RxZyZy(O@Pv}vG(FLZZ>627zVt{woOlY&A4 zsn>H3kl#+}T@w7^df!tEJ@2gsK$EVfj$4@Bl6|jqo{OxMqkse z`ILph)=&V|oXmILH+=fEgJ9&rb~BjZkmYGuz9zcYX=FLjvg1r4h}=MGK2gFB=9|}F zevCpQT9~nWNcn*A(LDg+wq9f@Z{x>68*yzCZwF3rFo%FEALhCIOdW4{sz|#yjewMG zHXU-5kE>97y|Tj=Ei~mg&@0hDv`$?(N>>sL36e0aS0{U@gP`|?b8cIqPO9}{=}Nuj zOVoPZIpB@3&Fu&hGngF?j?u)$nr`dQ8fX#Ich$Hvb2yxcLhG(Fr@p&>QV!p-+;y-^bYSi<*6qr{0<{(q3TB2 zVZg1zz6B|g8sGsA`tCWNz*dJipUD@vhLEyCi&Wm@7Fo>H=!1p|`!8krqRtC8Z;X|w zot%i|RtngQ8zd)hPjf_8%fHJ2CnD!x)KNh(qgddCB&#-Wia+a1B{d-Bijmbo1d6Z$ zq*fi6Ws^-c(~8R>CmeFZAt(H+V4&wu+cjw%>y`Hs0`{A`TN<>hdv5r7oZOrDVH>vZ zj?FSS_i#OnH0WLH?cgotyv>Io0j%s`WKVX|(05~XuWzjrS~ez`n^QZ6>dc8a^{(ph zcI@!mwV4=RAXCB}j=8w}b{gn@086>@o$0*oS}LB82L{}Pu`!=S97R)pBCtQhm%4Y! zF66Ll36_*5|0Jye&9DsJ9Tx>Kv=^sM?BTq*r_7uABiNS9HM(3i39)y1)cz%_95<5= z-*<$?za$@brWU6qvSLOV5t3`JFVZiwbRtCPNtlU>17i_xB`lYheY8PzTY0-^6-8Xt z3X)`HsCLNiMfU9ClG(Q+71(@~nBJ_ORFIg>)4YvC+?rk=r(j5(@vAGmx^f)g z3a|ETCwv;jlAYrC&R%3z`?57GH6B5{(Sau13R?$jUEwHZ{s3+XH50_8ds79C_#Y}W zO%cXla>&g{41U=m*D{URSMd`L`R6p@Hy!fNrpQ+g`PZfhv=g~7?YBSTkn6{({Ug8R zl{tKXN9yt-ho+?or+&$YJu=B5e_Utr1Ha^FL#`x~)I^$a!W6k+F<+Xn$BHs+?S}vbKBvtDu)dO662)lS^Yi{;G{SqHy@WUz?SdS zB>9Sj_Au%s_K*<+A8K5LSd@?k#lLjy9F;|BK5c{N84ku$lJPxp2!N^DW!qpd(FHL{ z8d&2RFj#o6`a%JbfD_e5#&D`L#Zu?Md|%6vS2U-x3y^|Q)G|qpbjN85$wi7>+cfp> zIf_XM3Bv95{8{fY8fCFlu(>x2?WZ7!mko(u=R(H3gjiFYD3@CGAiY@=^_d!q0cyZQ z!!D{aAx^>xyOw0BKaAT<+)fqjsz7w)LC=J7-Qh8;(FdLOvsc-K}Si*=rwE8h94U~KcY}`12=pg z{|(3mhtG{{xhE%j+i!6t)Y!ZR+i%Iak8I=ldZL#*PmJeVTM?isQi9p(gb-w=-~$v* zDeuM#?B2=tT1O`7c%ehr{lq=|0puko5NtA8Nh|5;n9YNB?{EoFzTx>sI;5dIoM_^{ z2?K}#K3V_;fJ7gE-y|oViQWz5R-bhJzMofBCnIG5A1g*04 z=!y&Le*eCCJ%DA#eUk^K+?(WFi4EN1_6+t#sN1bPI7{2KE3I^|B{ZAS(f&aGFsjxgyTNb2s1jHDP^?D(=W)j87nJr{H*s5i)-4> z+7nsuuPE&_Yz z%W1ZD9g54xRSHDq?(r)-g;9~C?w-l?@g|CkT+KgnSC9d4F(+$6o{W`Yf;IYBXhrpS zs>@InD7(7*M|A_K5=**je0&~8bte$ZF!`$Z`)P%1j@3(YMI5%4eO3h?WWgJ2Q$YGt zUCwA?NsazAYA^tfv@#Y`<;Z8UV*@9T(j*NiR~}0sV_Q?!yIhk&XJz*2QratJ*VH@v zT(7spyork}mT}KGR`_Lz(lX&Z{j2Hqx{cpN?_Y}R&9n4_v$RdvsfWFs_vazSqsku! z?dH6+`y-iJM)~dlt*pfSS7f9C>kxYmyCuNHdDZs~Kgwc~O~&0fYnC|eOD0Jr1If}dc|(i1g`^o8OiCN`0Z|UbW1iXrAvI`IX%=e zLD{!VegK*Y`sWa=au?BQ-vxa$`rn}J1Y!RoWoL5GnPb{rcK;Fl2cXD0fv-OR`DDpX z{{W<-$h?9Rp=R{T`MtTSz4f4O`>S)v(?*SK2tq^?c*j)VcaA6f^Bwa z@LYGyjut;<+#Pe5n(@p#CUZ@Jteci+)9IMDw|m*l#( z=sk-c3boiiR{DWZ%XSk?<(ZAo-Jagh8LE48-{upH`R;a&G-oz&8WT71+oHDJne7!V zfCYDg!t-Hc`VJ?SpkTtpPHqzS#{$f-89k#G)CZIH&VqEmWZ6jxdGb&$q#ko=uCW@9d;8Bk(SUra|;q}>ZBs2A! z)*?1oqX#X#k>)}19ddWXISoeEr@KmJ98fB*CT5yTmxW1)Y9O4g*jAD1t8Zs2==M4; zwF>a&!h*jwf$VB!Y!S0)$8Pq2-Vn0@75d&PP^ z-^+ZV?zMO2&-x$3hgu#_-Z5u|TBh!pT^1JL9y7yms;i=z6jl60 zs70Djm$f3!ep-8oI2c&zg@c76#N)uSS?vA?fj$t<@{8$3GnJ5oxSyVj$(!*tXC|5U z)3cC}0Q%{P53I}y^djffCK?Pkvfuf88VqN#`>)cA7Nf6RIe!7@=UIW{B+C~sp}12l8f2Oix&0n=qB-zfvm#6_Ha z@u6g7+}bsr;xZN-{c(nq_AX<|Tjxp$rp`fMgn3hqL4(JY+nIavc>_Hiv@brnd6e$! zw&h61Hgw6RhQ9N*m61#%r6t?m_j%isMIo1BN+lTjv91bHEVN~%GMoB+u%1zDoR~5> zjeg&t$|w%evNEL;{eEF&(Oj~aa@CN2|2Tzc9vhLXGUP#U@-Flyp>!q3q>M|Yn@P6Z?_d+O zkdh!GfUR4pr@!OGu<>PTZo`cqG1ZO?gY#S*3yTa1h}>(=pBRkP@zs_9NNds0J-D2V&$?pXM{Rvhd7N;oT4G%F#a66uv(qbRE!(h{r9-1KT*1@NOg1>Jq$K!Pn|qc%GzxEKhwWrpzczpXj;AI9D9 zc;ed=f?k{hKS8!kv^M=@%l&tQg3|^wrheGRabv1`UBoJxEt#SuN7%#8p)!N1lpJwC z?9(*1Yyp4Rf8BCl89|eio3-X}%}&Dx@=+p|nDr9uZu=GVyQ;+~MM8?aOc;0GQiYX> z1;(GZwwuvs|NnV*Gv=hHGYD&dJ)&0fo;bVhgN+l13SHGCaf z56mL-BrNFYfa^362sr<|;JF5#+5g zd12iMHxqYnA9R0=SV0U5TyRyMhn{etI$7 z1SWcn}%KofG)U$U(^;oy*)kc$*{rl;xpW9X(n5Ww4JI>~rOuZkgHoDT^QT&T5 zA4i<+zCADWBdEwV{|}8XsAx33+GrtBk=ri{A8%J)P0 zekkAnE0pXP{tAD+ZT1`Blf*zt%Ho&a(t8d?#&U|h(wUlt)Jhx>i@;3!Lil*P9*7Y4 ze+wb>DSy=$%H~?czR*9{yl9QGTVT;P`GNG$9$s%r@BCXAg?>`B34GPO_(in+Wb@+Z z52Sl6f8g-?BkPC1fe@85L>td6dXoN{j}QY;UBa&)q6hNif>PQe_z$mVncnlXAnFE+ zT7$U_x`TMn2bbG$;c9Ya!+Sp9|MTgd&*cB}UsgAb@y^r#pDzYmdG;Wgq6x)6F-Z2& zfRaQ#Im>|1^6Nn|61}S7r-zP_e|M1VYjtzHMcfQ5Zv6rHKyu#s@u>9-&*#>jTUX~R zBUw;_F%v$tXTis;@l>3x{4<_U`znC3$lI=KH;`Jpjr?;y7+fV<5Sw|?M#cWDp@NHw zEiB~Bs=QcqkYlL6^B?)$p#lr1d896DeeCPs9XEgDcZV#+kN)oHYyGL;9n&Dk=I+U# z+G}1g#&TdmA*W0v6*idWO^pH6>T*ihR~!a+Eu$o+YbD4{f&P^(%)c_INcfjZEq~;| z^{u7&-$Wi;KA=}wrL{l~L2@P+xrQ>0ZMqcteRP0!(IBrC=e0tWw~G-SjQEf^bjWjG zPI9I+jG5AB20AQ=YJrTBf5<3V?5YL&lRh?3{q2RDlm89XQjvWNuUbd|HQ<^oJ3%8( zwMb4^EenD?kY55J&kt>DL4L`1k>~%xFPXL!{X2gSp!5l(h@kYzVoaaljzf@NGJVGa zYU%n@U;ZJ#bd~&&vtIm>Cq`mR%*UN>vXHj;4s$zPvHzzIS z>;3h<*Cb;b!N+C;Rbp*P1NXL!bPe1`E%dCIHq3#s(Mf27?N_ShB#-UupsPo1TQA!D zSjF_@teE#n*8*BgyC=kqSI7D*MZeKdpHSp&`RQGI?6l>=?e{|OTaJGmmECjtlg<+5 zGatt?8a@#T<^xLRM{et43F5O!PS&3#!_-UgeoAvAB;_YqdM8Z6%z;rg(~(LQu;-6b z1_(8JjiW}Fa?7dPQ~653IQcYS_Uj5^)mRrI42-^kz5CdDT~f1!hx04>iL}gU9Q4oS5Vl(qBDTKlQv%iIjvqXe~gL? zAv!`_!oPq+t=CH`QWvq*kx`Q>|4eo+Bh&NRy9ac!?s9O{>fK_c%hXn!lQWB8BdAAT zTD|_fKNXs?T)ix;s@HELBYKs5P?=J8l6{y0ddV^!4^pBu{}_WO49n0iXRxol3FFx5 zUFqcCulDsF=3=Jr5_f+I&$u8M+JxE`uds^JASjv7o{9raB+Rn&pl%U69j$7qX-twG zHc5|BG8jeEQxnR!xryB;2*Yi^^3wV@9Fq4)?)#MqG4H!!xOI2kxHRGWBUb=&qtJVp z`woa*VcQ>YN|>uv1>T=N4Gu2GBFW>?vU0V)A%js|_{G@Tz`Vieb*Cv?tB^gX zUu9jjCr{E@DnB_5o}@=xF)wOO;vaE8jM{+NN|C zw7RR5c=O%}6YSL>uVgdBWen<1YejT(S|kiP3rNlfWy@o#6U4PoYDT(d<&uBs5;x1^ zc-vzC1}iPn0b;bzSN~)n~!(2|;pYiMm9DEKRgeM~ej=*v{Kj zHZy$~EkRMFV}%Nvm{+|kB`;g+d!e$$>tb$Me)&3o&Xov&`5l}P|K70xYyg6A>+dY2 zm-`19#8icf9qD{lmJxgZ3hFHBYPrm~nn<*t2s|t^{z0sAq}(OBtb|92>KP`_%d-+6 zU)3peUoD@V^dw{Ed-sp%@FTAku1x6gDYH&7}3JMZ0XntcR@Yv58(%(fpJZZI!dO${KI!SkOVt4PjK39TQm zrJ%={)!f@2icTAOCH;{V!JTZzB2JJ^43}!~Wwm&x7&Rs-N3h|*t&QUT`vp!Y9QCUq z1^tMi;JblP$dZcAL!Ar+z1o+Afa* zcU;$GVtBE%6#b*`mW828b-dN=J;}zAg+1_6lw+d+i2-^aL6>eWk;WnW?$o;+q)0-| zG5uw#Kz<9^;oHl6@7pvl2_q@nlM|AA$a!6h7J(dH;n>Z4$YYVZLr=wb~wu@;Ffx&QmE71lszM;V)2VC?&`BA6=X63RF3Z063Otmv{)ps&+Cxqd^4I) zoQuQ-$cdjYqglwWWl{;M8hcy}XIpbz7+}ly4Z6X`?h|OA1vZ#s+FRH}xrOCZytsqe zqHDH2DN~D42@vy8vSuNv2zL|ozsy+LWfCluTa^wZx4h<&ekZ3}M;4I57q#AUxI)e4 zaPW4a1A^i7nOd#BAvI&{A}3onYu&>JKJ|Rfw_`6>&*g!^9Y)Ue_l<=N^aM|J8MJcV z?x?cuQ3xJ33*NwPJbuqELcwp@py67=2Bp3g!Uu23w~N!3D{o(s7QViaQ))*Y{=G9y z;F1w)E%loJy~8b}%RLBb7>p6CidWhhRdY#@?BX`^1mywNnsD&F>mzaeNJj}oZ35pr zuY_H(a*q-;h7#1POf(yi*cg-Dy4oKT)Jx>*(nE%lj1&_!9+%f;=M5zv!o7ELkMkOa zQf#XdwMWVyA5=++JLRRe<0Py;pC>uhMe)mfM_$#*BLAdZL*z2*X3{~?ioFz%;69hA zk;?Z2pPcirTTe`!Y%;z-`Q^F1Ph@Q8o&5h<=b z`b{%84fBmh5lu%9EbRohm`yt4gI0(s zTPMk(uyJw4<2;E9sWdH};{8<#Z&EmX`gd&BWMh`zoQ+il5)=Cqy3&yZeLDzLv9;wK zu&tV?l*)sN{4$hgs$FS>Sk)vd;zxPi*V=jf;oQa95^~lF+Mzu+1_k_`_<^yrNvPJk zH&<^DQ}yy?kJD_qnt&SfwY)|odc*97!pDqM6ujb1@7?R~c@AwR8S>~WiG*Q`GT<7^ z`pYr|2~jzu-CpqY1ZrQsHeHYZxi0PZP)NK z+qUE{r=FC@&mC#E8P>UQ-s5=XF4{BNjFtV#S+8@hFH<%<9-~b~iUWhUKJ*sRt~F9T zzuw|IqUqP?-ZMU2daFZphcrccTR}z`(F0$5tz)TYSCKJm09b%BB-M$MDx9>i|2mu9 zA;%Iq=G$s$$;6;k01lHNS>}74;e9Iinup2E{}*pyXhzfWgp%6Pq2 zCAdVFVIZhf;ow^5cyNn(Ah_ByMmQEzWuh?c=j0wnfR6}TF+uf0`NNo5 zkH~8+feel7z@ec;9r8r=lK0#P1%1Is#Pm>Q*tADvPt!GVq-Jtrdw;^7yNco85KWx8 zM`SoXh>$wly<_#QgCa7OV@Xf8oD{DK8P1H`N=>O+(NLE+oRx|bP4Z70lp2P!xfEfB zRv#`sQsvBy-NRAY zy^;K?ZHfGgev6tL?Yon#9y|@2zAd{H!1;3Gzok>me&ZrAQ>WPI`Yx<5r)i0u^5yP? z%<0S7kRjciuEQLF@p`3OH{K1j%fjgPV^6)u`Es&na!wO`7#Mi-^8QO(MQ(#JeGe)^ zGd=mu27|G<<;b9rQ^U_5yKg0d^?IMhPrvyQ)Rb>erds#n9P?o#yiTEY2+f3n4oMtW zv!`&K7!86_i%ypS-q7CcjUqDMb!r^wTYg%CBfiB~A;ljK46EmA`|VOQejPx=-skPy zsN3=Sf{q@>{d}_RIjtb@i8<)rB+aeo1i({UFCMKcTXT4ghI+&$yWx&l>qak|S3YNG zOxnY1%#Vk=x{7qRM_xN-6V8v8!2LLNwC3=}n61#`B{|3gJ~0|~`v~-X51VWrFH-MJ zOf4Qa2?``cqulvJ5xH?mH-t0)0L_=g=-j(@KZSx~P zPtumlSPOdgVdOJR^DzR!|>xSox`$Nq`Ym3_dYJ$~K8Pnijj$6$vu43E_xYD>TY^+3j)OAFnlp#rC{^aP zTT4VOGrKZ3uiaW(VfZGGL!V$jF#O<1g-BzD{0r-5ePopM9u+!ayOGLbrduDDu3vua z9Xa)x-Gg0gSH1gmWzB{0aS@N_{cxk3kDqvR-@G0&2GH@2t#7d>^9+NJFHLqbi*Q_7 z8Ac>pDn5wRMWWG-EfFjQSpf*g)m_x2J4+>e`BOoiQctRnE@WuvbrG96{WkuCJ4}3Q z$0F!Vg$o^Bdp!>@;&h74m1q^dr0PKFZJ;UC(0AUJjd=AyX~|mWG;e#dC}e2vEpdig z87l>1K+39AW>dcp)-#IDd7uQNad`XTyeJOQvNEL;{eEF&(Oj~aa@CN2|2Tzco;_vd zYI*$ush-h%hL{SChW^0Z%E>3D|3W@l%(`=!Nn0Hm+k0L_XjpT>oxhi<3&0+ zAD+0}>m)t(#OyY^zFCRn3PWa?>QI7NFppYJ`6HS0x+~!|CVMj8?R1dRNouCzonNQi zQgVttJ+Ch}^~6-+bjp)^Cx$b^$dip^@>4N5tE9T>$;n%E}{w-$WBJxVWi=(k@O4?xsfP;QlW2Dk5b|)NmSCB zvV9(ezSrZl?`}0Y)hMA;*>tutsDw?V#x-_H6LJ;(Wyw~Ik9U&Ls@qX#5Dxva_uws! z7u{|vsI44H9}|hV$5y5#6U3(DcxUA`!wOv&FZGHWe!Uj(am!0QsPlV;+Jtj@?W`~F zxMZ%UTgXSxs&g;HPU65maYL7?Pbb&Q4{IR=UFBh?K9%mU6m>z3M3qx9BSMa|5X!GQ zp|%1I3$!`h^x>H_%pT)N)fKt*?X#uCiA-7VDPT-{&xCBsZgsQXx>_yXHrJl;T|+z% zrHqW9RB>@n*_AzZrX1_fKduQWOTWE^)@Wq-vE-dh?cQ_dP8W}`&|hAsmnUW6>AIQc znuWDwfrxo}=5?ViHPP#bGPj9VJXLyoE9cfo_ezO@4=;h`x%o?#4(Z4+Y-mtJ?_H^V zsG0rxt5tF~hIw9CN{&~r5chM7=_!HbSK@8!Uf7;^=J&SzqGn4VQHE%__;d>s2CC1s zglm6`8u#Hb{O*b56zg)o=rK9+= z6o0aNcc+oaL2M#Q6c%l|Hg)yn$?m=f0}3|q`abQN`?qd>80n3+7-3{Q0ejzvqXxHc z%MacqG`f6d;$$Zhwfay2JN{%>&vb$?OfCNeC4LpQAscB`dklZF8>P2zbvBwvht>-OMdPW#u_eXFUte*eF^RKy zLqgAb`W%iLM8%J?iCf~Sf!@KFD7u54V6`uYnz3^@PJNz?M>FDrhCKUD-Wun5layI! z@+LXA6;z)$^5{&j<`eODr54eccBPf#s6nO3o34y%8QyM?8klxx)gMgk&VFWnvi<6d zANUfkL}+mv_|D0W@4;;bo36eRa2R7A3-fKU)i+OeMoCl-|7#GE8~*`D8b06>-7heaDZCO0zyU z?knY-<7Bu0q}}kpJd{>i$b`2rBM?7I4Lo$nBI!!d#eyMyo<<7aurSMq`ta0XDW+6{ zp&#q25XC}U_L&-RV#?$+`h9~c=b#3@ftzPg1Mi54UH87G1{*87osE&%Y?IXB$bsT5 z#2uICRi91K=y!VqHa;#>s#M6h)Z1ks+-#h!Se;>^S$co-+p^;O(kF_M<6W_!`b;`S zNo85KrQH*jw?>KUp**E++|w5w^k?Nj^=U4rNZE;S@oiBgMi9#mIfetaMUnKllO02X ziui#jzA6p0K4@W5IFpHh7UosG+DoANTpPlzJTB!P-nlGR`H3SXDW!8kzA*E!aOX+v zAr1{1gUCbgE4KUeMiVnWV7YxFVOO;9jvK_sn6>yZdrRJnqLPcE%@k`jmPqF1$*p8L zvfEYMp?ar#m~aYHr=t3mBffWF*|KN0b{S4zlfgl|0O6M3gZAM0jK!3H>pErqASC;n zDbWiTbtY1xHswd>N@JY#$$dFr8be3+(dsyy>a*QxLm|WUYSy27Oy8+F(-@I1B=?M( zy~Iuv>7K_!JBoULNmHq|VhdbX~&3D;g0z&&!>V)Di&@O;BodNA{_>UBx2HQRm%%|j78IN4x5+ub3yz5k2Wp-dn{%_`}_8&vzk8!?SFHI z{0~C=w)d0J-m&5OikZ;vq`FFD#Y|`y+^qZ|>ieqi(gAdo)8Pw5AK3A#&sx!}SmCqk ztFEkViNI8?kaIw;Kpi}gxmU4~ScvO+aEw-$jM7;)Vt}$eT1uJvp2cOf>8W@M7~Ijx zDel1~)({W zD5stJ;UJju5eiI#sRB!C*qyV)D|xg^f1*0+B4*$K!U<*a^{Jm{UwI~X*+r%Ao%*|# z0K%1IM}IPMKY+S+8PAi!$bCR~#GE`Cf2EOi;=PgE*9`LHH3=uK4YXB9eigZYPB~6C z5pBCEvSWfL&xp3YWbOL|5OFoyUr&|=uQVKZF#Qs3v#qzK!SiH+13KrBF0;Y3_KZL= z-a^BHX=_~b7ciBiqX5Aa-7u^>8%(wCxZ-#+&O&p+@#G0GePZBalHJi7%EC`F159h< z4_vV);%N^9dGcp4-NX=jUWO;${jk!E(l(NhB$HQ~xX)m!FFsBR@?@qx#*;i552o(y zI53^TlO4-QL7tp_%yfz;zv<3dNwI8Zb&}?l%${Q2tFn*pnZCU_+M4+G*4Xd|pWIJG z)1qzbQhEitdb5YNO@irNI!=;9#f;N=vPL0CteHs>&*xLWtGUATXxq~Wvcc+O=?a52 zXwGENLbEYD@<91Bn5sYJJX)u<%J}GGopYdt27;+bxo9vBOxIqretM{cKPL@iFERzD zvp?i`=N)VEoa;)X|H-;7?3@4yrn7kR&e7vtnU5_#bmz9EeCU~swyhlluQZlpbMs`w zs~`U!o;>=47TOQ<%p{@`jcza+@mNC1}y)UmDbFOW&5Mw1)`(CHI5_L;laE0sNQ2(ANo=2MoWTd*T%l zzjKk0IQ=L8AH72&axYDRq378~sVUPyfX61gd*=V6o_c;f7=E4eeL1nNe(mu%#RM1@ zIx5WphF4-H!EiF?I};3LHfTHJ?+Fs@D*%Z%R@)@Ly%dV$i|7pw;mwQUy>e*i&t5o?p_f)A~A~G%KyE>&@g4R5?LIw|pqTRw}VlzyG z(^8h*$9&LdCctotS^7Och6BTqXGb5K&j*H_DWJK47ZsVB9Jr!|m z>icHy=^Lg&=n}>H-qMmez;J(d$>pSTWF88d4_T&}2FAAp56!wKuv0~cm9M**93T`L zWur|ZziLBzAYl|cc(Rr+D^0&3>d0p6L{h2e=%bV)%mM6;S6I!S5zOib96w5;Nagb? z_|d~FH0i;SvL_5fpLO{N7w*lla%|sR&lc;BwYP7{+&Oi!cJ~YiG?j@rYN^7r8dy_*mAU<}Ty#c|L>UkUm)90!e4 z)1v@6C{2Xhl%SX40bzHRpm*U(z&M`=VfQ+>`!_#@pI5_i&<_FA1^q0qR%Ejo2)n#1 z(r3Z$mou*KX^*$JZu)|Peon8pIRS*-&7GDw*zKFiLBY7`l`U4~d^X3e=8l_+W*@GW zDjYpL$w6^vT#$oqxFe!Cr&l`#yK{TB|K(5Ny2IyV3TX0ro!5DWlNtWj8Tb1f^nu_K zrjePjn{7$z@*`d?wQ-0l4;ew^#2Gh?&_QU#SCJQY#_cztY?C18HZw-3GdV50K^7yc z&V@hYE{oS7aB-z|2k^yA=eh5eRRb(eW&G|VT6@tFc&o)N!I670yBqlFCs2xJ7$G6HftW}CrX}tuT7e$ky?gMX(65KQBO}$jG zcwG$Jg!0uso_nH6xGBa_kee=oTvNKy&=&R?$^`rY~k$jAAnAI>>Nk{BOy_@bj6 z*7vy`lq99MLqss0cNf$W-zFOiU4GnwbY2`mUZzFU$w zy{haV5?HwEmI%aW>`;j4!$wGnF^9X2>atM16;8!r2ga8L#E!d8li2ZRdB>j;Fsr@@ z7-C4kObga85&>iQe=J}G`TueO!xBM8Fg^anwgw;)yvwB&cbqVvg@%_BxQO8MPU36)b0k|6}A1k9I1v~tm& z0XPUGa;`dfAn^q*?kaZw6wd2m~WP3L}t~SsYr1D5gl10Ms(#pbt_s zmk+W)T4o*!0{I}25Aszt6oegrFLtnfp&+0SQp9oD%T4LVgM3nuf^d+y!|y~;ubloN z_K$^VArk}wj<0}Ysa8B>g8YTrWrY-g*!TrF!0ziJ4##^!7%Yl13W;sq*e8$9Wx)dL z5CSGX5^7|uGO*setB$9Ec{f)1>3O%`N0WJI$e%(JC=;?M)3cL#H^>S3Yn_lyv(V)9 zJs|)MASiKYvO+=aMuc~IkTgHe6aiT2cqOFQHpF=>5s#$b{g03n=!XwPPQD^1kgEB6 zRn7V@aMDK6PMi50@r%+^pl4kQrF@emNW6d~3f8->Q09;TpbGl~wU`W3)LX z05wK0l2+Ae1C?KoTCCC9`ByeZZ_@{S@oT@P=F*>s+`k^ETu35v27&1L#~Pz23e6%u z$ISGOaK%cQ-nlxt$tGQjjc`}5j8MF+j*Gl|=qR|+7Pj+pV^^q0(KXXQE|u}J?Q=JO z7C_%znz*qx&FHql}$g(8Iw@% z9hkWrDdZNfz#mc+91EV4}5(ZtW|6$_7IF#GmAO4ewD17Waha(e|9xB_V&<^#Df z5cBzp`9ME){$A!YT|YrCjDE#WE+gK&KJs>A8S&PQcLP7Qj0l~Bo>~9cq8HQzeRb?F z9^U~o_R~@1CvqtS01?0^1WKqSlM;%Y_}3(qF!rC9P)o=^OQ?O&=+5QEGEDJJ3FTq( z?~m?K=qNhU-a-H_6SLMzE1J&B3cPFa$4e-~lz0D-gaSu*NLNz)qn*&FKTD{Hsh>K^ zo=xBiGy;z910_^haeC=pfovytB7#WTl8MnBsTHgYN2nb(^q6?S!dV!fqf0h5^qse@ zjGVo%%FvH>#Yw2++e_*5eLQdYj&Zp808+j?u#9Mqwb!OT4=#`~JkNRQPZ`6|&!5E| zm4kl%ES{*`cXKWa1R;>a0$r$~3-y2NLj4mC%L1k4<{=``&mYLAg?!pYnwI+shvm<5 zkv}D8pr1dBTh2f~e-@9Nfqwo#KY!XIu`)azQT}Qs9nnDt6FOopT6cEDhPm)`#zh61 zbjHWUBy=VuWp{QarWTL$yh+NeGkKGo+nVqu<;HO5o2&Umyj`h9G^Sl?r5uS}>6IdH zx-zO|c)K$ns+o3Y)gMgk&i=Vm4;Yn$9FfHXA>VaG7D&rLjtJz4K#s`&ts}BPS_X1N zAQXX6nz zh%6om`K}|fKw1WJL?A5#X_^0)midW{$O56rJVXS_h(H+;C?oRU&xkCLoSBD<{3$sD zWkeRYoPivX#Up3F>xleWBJ!so1ad?cH-tcr$l`$z$Ps~JW`EmV2I?jG&-Iclkd}cQ z5y)4CeAWM!uL@;Epo|EV5!toJeCUz7Ve(L&mQDB2W1VyS!}SIi%!i*C#U>9onB{a2 zKRr~!Kl1G8WAl;cwr$BHFYHFfyGLHyFBKSVbfUEwedRjQOVTsij9sW+61x;Z{!%4#c})jQ{V+)nCdIr=Xj^QNZ;O?nciyElOzQh9x5fThti1Z^eb>K%l_!4@ zD>H1;oPclugGEtBA+aJUednt*Ntw(KlsF7pc{|tYi^EAuC8mn;XJMtPrPGa;%P`o& z;t|>Wc!YuQ$ek~{y~$%;F;}yvaGg=Jmso3D^Z6~q?akgOBJLKf6pe9<51J#s#aBV3 zqs32IhWoYuE;ZxV0qO_iUk7Sgcf7u!%tRx^o)Ae6sV4^QJx5+G7%X^18C$Sma(L@s~=2 z2Yl$cIog`|_SVF1;?ntu)E=|GZwWhv*qZ_+d;^ujkIe?E#M+Vu?rj)k_mmdUDqN^ty;u zhEv#-7Ban`7>$noUEso*U?rPgNUOsff>)1}mTY_9=Y3bT0M#^9BGI7Y?Sfl8D=Xzc z9PX180%y~VvcI|Iuy2sm{%eR}%xVf{Wmw9dHgl5J~z z+aJQNg)ai1!mffUr>_U^Ayew#6oCq}u%RPt* zBnW(w4s1GBo`O`Yw6YicH%O3rE^&xlb^Bql<3p?Sgp=e5uj-D00CWAf07jZP~&D)P7jpx?>>n_vISpc(XJu9W{#D%blABgjD zlqlAb7G#%Z#u(kBT?w;?0Z0NA+8$NxTCmRA%HY5*vQ;nZxtyts&L1Uv!1y?*!~qWf zBEq;poFOLst?OF3LC`-xJ01CDb~+iFo&G~aW;Ki;A4N>e#+Qm;G|@G=gI_e^_q$8F zt2-0FXtGg883Bv2;_b<830%cYSr?L+a_L^mo1W{v#V228_1BrQ--I!*HxqAfc=Pr) z@T(%MtG{9$UWA=xwD`XkVPs*z(g_h(oJg{;B5XmD2-9Y#Wx01J?l;2Nr!_5s+fj#M z&vr%PL|AfHqL1|TV7tL%SQ8ATZ%`8Jt!!m1Ki4|H=)-|IqzFRgPeeWg1X0|39|<^W z9mcswj3vEP0#q$N2J{DRp$f`8jUq&RgN&t!<{F(Sc z9jz3wgdJI(dIvxG6md;@V)AJx11~n~A%5}+#w{*R^6+6d2#}@%E*I(TyRUV8XF93;msfg*2>lVtT`Za*m&t!}P zqgpk5W_FS3@1+q2Wqs#uDI{ldQ3>v0OvA*H=kYLrgr-L0af#WF~oZpa735ujl9VOJvu z53kQ_VVCA{!@`4N{Bq$`f_@!|V%mp;Z(DH)RYhf(XiFJB5Pm4M7FK0;Vj#4UELN-p zbMJ7-PL4BMVmD0#Nb!uS;|)RfR4jhel$$kwxrRQF8|*h{#n?$kPiRZ*&?>jjmaN25p%V&BFWVoqX|SH>5wFp zXh*8sbcINx_12h;`q8;)gh)b~f-xVO@g?Z+H+;rUoWpNV7KL1jnK(_7dC}sqbCar& zhuvh%)z{hQMihr=879l17SJY}c6nR?_kJF8O$9R7+#p;sog0@R_ulg3UuLe!&BCQy z0>Gquud1w~v?7-!#FvFjfCCN?0wA@*0uHu)&X{VJj(c&%GTcc>OEdkTdLx;Qlx&l< z2Zp0P+d{e=|MI_($nyA-$fAG}S%1-SkV8WQ7i_?JYM^8steXd3h&hwKIt~sc zdq9cxb|KlF|4w54cY+PAJ75-`&18=a0k1NZvj82M=`9`mruTg;)-C#G!(xmQlttK; z;!#N2C&JQ#lqyH3Xb?A@ zuO?Gt2b9;Fo=g;$U@S$g5!h!0)D=2 zMFOs_30K$jPZJQXXywN!TEW#d;p&=jbxr?k1LEHhAOC6=Irtp~)_;aY6qY4FUlK zQ@?QD^goo*#<3EdviuHZ!M*hLpH!CLalrPg`2@#Gs&Os{=W=i^=l7q%{z^p-eg`Z0 zlU&YMW)a-;=Q!euBd$MaLH_SxCBNF+{E;pp94o;&n&07QaIEAzbu|B?Yw_=@t=Yd& z5j94G8rX%xFWX;apLoVW^gs2|{u0>DTw`Z_H`_S4e-P(Wkk1X!M7CC7uJ3n`eB~d4x?j>L`q-@3K=EE)!%|yNCp#@)t(w4e zX(SMDO%=P<`*l6KF38I8`Y#nhKOYci)ICBl`gnvY{8AB=c)j?So@_PzkpIcE{LNkc zF&+BKT;!?&Q2%xvi@3U5ae zlIVSu@>d=Dn?L(wI`ox!$W;S|(;?j9(mz}l;B@G_P3QiD4i)nL-xH;ub*O%xrVh=6 zqWPjj*5kCN{=E(rY!82n=z$FH|0DlRyv zWfZCO*76;QI`0Z@XZ2fmR=8WE@0St(N=1H8e&%mv<(teRxcm$*KZDE9{O`}t{7H@m z$3<|n$ZwrRaJNQ3#4PfAxX7<&ksm1ag5x4MF7jhOjP;#!5#N7Kz5E+4^6yf3Nk6CX zeonm@7~nzrxj!S3ExKP)c$chTztm>_<#qVvgrGaWejMWG_+1WA=MTJc^|f&Z7kgR7 z^<@5Ik)3t=e=nf@&SNjve=S7sh5j-2()K0x()5?ui}C+6_VP>jxeKBu?kqpYU;29u z^-+I`->J+0EJW*fF|Ywzu37-#*DqrIEJhiBNQ}O=EmFs2UvOgd4`LL^W7G+x`>)Lc z56isze!Z37uf*sI>ep|na|<6t8rHGXzLcy+`Fclbj<3S8;D2+Q@IMbRD1D%mGX7Wq z+h~YD9BxH~>8#K7m-f^Be47ycbD6kiD;^B?5A}9Af9NdXYje?90rDHffn%BfdX^x_ z0LGmq{BUOp)rC3#y=Mu-nVd%7Z4B>UylbEzy*mHp8FhZG8s#SfaN0U#Jj&)k-Bb`s z&nMm|^3^!745Ay}hSp$DuKDF%g91Z_VB@g3JJ_+)zZkS}Ui6n3-h_07rX}?9U*0ts z(9;@__`7!vaD_CuRd~bBPDOR!3IA?o{j}R|Rnunq?!C6RJG=M){8x!_<-OmnF8yj1 z{#X3`Z@|&t%6q@<5(`(}i(7@`R^dPBD*Sg8()?MG05uA$rpepkJ zS4i_mROCNPTJ&&-MnCo{9Cv7hJ2Zl+L^5mE77irx8kJiQ)D{h;ihgAl!5tdmW|4oI zMZU!H{(JY>-(R3+hm+<*6lOMi*ccDcNFDnr6b8WcbB#>2{S!_&W)OK0 zX+E6akii2Hc8gb5B3)C9eBaCH9}jcMLNX4?{`GS4Pck=O8B1`81Scr}Bq+F>qwjYY z{VULlyE(!&f4kwDzj4jqf2{fYcOa5)yRP|G<_3pIaERnby%rD``o3~;b_YR0fMAHu zFXl!i9NoZ5o9hpP<5Q-B+fR%CY;N+Y;~PTx5;UQv9}Q{h`g?@~#H_wNCQbj)m5npw zfL)KXAg0e8B5jC`ajQha{~_e|O)jFpm9F5fkbZ1k!9kNB2fhB5FbR&7;M!S=%Xi8v z|8tQv94Yx5+r|;qxs4#@~s>Vj*I-*jt0j?ejG>hTet`w zfDj<~bNR?!pw=%3zhq!$WOZ)W9WWKYb$@lZ#566iv>N-Rf%HN zZK>a$C^f1$KhpAGcLtYc{f^VDrv&#qV+U0KTifwaFRcJe2w$X8Z9I4**7 zG&o1|gF2eu5j**l!fRidMQ~gMry@8N`9W3WcW{w!JB#3ACpZ=PCl$eQ5gZr!*GGL{ znMJ;pir}~ij*I-L^+#~Q@2mbOkNjGH59^1&bi4klit(>>^|x@5KgrSHxJU@Ksq0E8 zy>sbG7_;BjN;oWxcNNW8902(Hi-7lHkbBd|CX`7u-k$3<{?5nNv6 zyFBWA~-IB<06yarK9}U>t2N(I1 z9L-mDG~a5|i>oR5u{XWAnvx$U0smXL2>#DCB>(^jAPsW=yP6V0JZ59`Kh%^c0evt9 z>R}*+J+&OBurMTic0{f$s?z&nLXX(OWOj@w<%Bd!~OAU z&a3XxZ0bV^?iDR-g7qYqFB9P7opuI5k6<>uYOwb7t-E&y{Bg

EgkL^s4xyk`SP%iHougNgEiPG4(2-_H^rXg-%WZU)h*n|r$5h86JmK;CsjJhqm>XoZ;qn%dtu(! z|EBanYcQTvs9Zv-bS#9QLLDw<%Rv1cbULr;v z!&&!woo-B)tLyR$NjB#AvcX8Gmaz)+z8vsICto&R#iLF_`F)<=9(0f+CkA-w96Mzp zO$9G|@a90Jt5@C_B8P_OIh*6T3i+f{GF&aKUYx>#mP0#!wFP->oUVsa!`gfKKm?7B z-nt5s`efJ%L)062jgZJbT;V|~sj#PPuMs<9nDBH|1O{bPh#7Q5(t#@XgKbF*=&fqu zWf)a^Bfhm`>?x{)s+btcU=C(V@kf!R20CY(9hlwoABlZ9hzoiVO_k}>Rq~(^6PPtH z=BrL$Z8vrX*-3JTkeh03C0gYAjq@Oi$w%;j!$gX8XhW=_MrKl3;wIC;P5hJrW_wWb zn*xr(dxnE)lL=gxfkndC28Jrxpz7vqxs{F=VY=NHx%@e-gp!-7%HFt`4KOWe9{Qz= zB$TGk4i`(8T^p+EG(;@`X9+FXHP(DNv$k|fz#-m*OkKD?SzEZ#v(0`^65uP)nx|9Vgrr} zU}R-T4K2fJI3XUFZkd+Z;CM>QQITj&nGO#DFzNA8vFu2h-nGGroDWAOOj8v4;aZdV zj8ZXmkxva$2Pcc=uU;~_UT$2XHC3LEB_V_bnKTYg-3xeAVM|tFe$5S375k>rRks2e zY>Ovg4zKcxsjwDun{J+ebMJbLO9Wv8AawK1{UEYSJ*s@O-HdOm(YlrPbVKGx&5`U= zj-z>5ew2f?F0~Ucvc;H&<{rO2iuz2oC>H~@RLl|A$E_#(SrZpP zkS$2SdYQ9@O%NH`IuM4Q5p6Ij($>nXe$n!-eW4zOM~s0=5AvxVO(6FeBlC3YHT5sA zrG>Iz43cI6cYyV(6(43MG_S0;5i#`OQKX2j+HiJ~i+QQ;C7lNazVD$J*1pwi(ad=% zm}>eZ{q3YWX}&@ted($)mA9F|q=Xe&##ko*h_cmS>~$D0Cp(N1+V~0ez90FRk!fnn z_Oqma!opNQFc4C!@X^0A#a^P;UYEmTSFW>jm$&R~Q9UE!K~br}y#&61WOC&DR? zTzN^hw%S?(3C&DBkYo8(R8#2{!fGEMGR!kci^ptGX*N~Az=n(mPKqq&>k4@kv)2Zs zMsuJMtr9{qc8<}>39b2=U^l0`1MyQ@g@WHRWa6Pkkv zE_P_bhL5j#DQp~%OsrpA`g8&i8q7#XPsA251iaaM33ka&sHkC^d%BK0lbx*(oO>Ed z4tmLBSUSC>_wMQ~(9;oTOI5%uD!yX3DK|P=I%^7%QcGS=l4X6HPd$X1psp zw`oN*PA(wGib==&{i3zfoKi&+Pzd}%U0%b3{|fz*>EOpLNM3m zW<4cC{0<7+gGxf*sp4=|WGPUVey|Q_g$<3F!5CZd1v2g_g zd<^O0r*A{(gU?+FNSE~R#R?MnsHNG7e=t(26}P96V8+XZ1lb3ZBH2iM=s@{&M08gT zZEv6A4i=Za16Y;u=9Yak#z^1C&Pt#Nw7W@&2`V{oyx$1fGlTqeH6&C0j?QdI1GO*L ztg9@YKG!NGpqduHUtfrwA>iE&ne`A``Y?$a>0_Qy<^=6d>YKI+{-s_120US2^x-1G z7NXt0iAM<3bIO(m2^*g9TctOL`Yu!@U7MUbi=FYi^e#LSjE6~L%^^CnTb*0u)v3f~=XEZT}U=EW=2pngZ&fkD)ZD45U%$r@QcCP7$Uttme z^1iwr&(3FhsCGeqOybqF;HI(v8j|jIu}X|sf;gYKxhsHyfyV0ONZ&;!QK8K9egS`T zIO35bAZa2|o#=`i$4%bG*mN3wjpHO#sL4ZKUA^NlxWUyVDhvJQXaAH}g~6`PDH8n{Wq&5x+3cn<2Ev1Yzxr}mT;v7LCwPOQcVi_t`F2jyGqHrYz z^P2yxOEQmGib9H?&Yb2?JxPTYnU)+ND_97ElK#LRp=)}YUBfk!8?vS@%Fa%7kzGh~ z`s$GplD}J(5Od}gJD2q`@52P3HJn*b#jn&Q^QnbUUO#o!iI_}+LHsE~-eVdO_e0u{ z>|@4=Y4vtTGX5I3zlq@tNbNa^xV| z7rt(BK0Lg@(v4L{(~{u*V`RhOhrXbWFQB}?3WK69pPsY_@cEEtN{IM zel2BrUFl&>VMTfBC7T&jp_qB1RBWn;Og=Q=V+#|jsmQ$YI|K5D-!@Y?WWlOv&MZ0^F8JPWy`%modf0)1j`NMqx zQ#JmXYM@m$VPG{lvzoZodAFsSyuy)!sRnwchT5uzmL%-fRP|C54U9miOPz{kfr-w& z`shPOp)XBIU#wVpt(SbQaD~*z54GYIqMLlwj3-PbatOjWHx{uobq8oIPU`D7z1h6S z3cREt-hM?YhpEqG)6dKV)1p$PQ2^!x58nL3;|HvG5KdZZ0Eu!IsW;sx?&<+AIVtj*+1~!K(QBgcN;TnvQ07^s%Z)2te zCAxPI!aD~Mogf4SnO$=xlg7JJ*^)B_uLDyk4%t4ld)#r?5wSp&3sgQaDl$nBdBe`b zPTfQ23I$hp<{J=m&xmQAAAAepgHPEJ9oF%=m=Q_Z!u_$S@+5&fKE$vgsH0M!1lUC$WZmRO)lFC0w+Lo-lA?)y zl;QT1^);jb*T>V{tI=l@7<^VMfWd~mYJRo~kkx87qg{uh23Jx1URfg}e5hBvV{eO! zr$k~SVeln>9!SNq16J!%26ObK(EHq6Uw#{e3+KqXBP3|^ArwJKr~oMxB@WzV3e1OK ztsoAA9c-$~58%)m1xQtpeOl%)VYSseXJ=o2h&~2gq(9I~e3RIF=v4ej=oc5aFdWMZ zH6o&^sX#Ru4$^4Y)O520Bq79Jv7-#9na$ZW_a(yCSXCS?9tuGE-2pooV0=CKfFL1| z(hJ)~Z0R*rxZFVqAWA$LCYK)f8LWV;d~7H5>LL)M*x84yj}GD=biTGX+R%Y43F_>8 z81>=vAk>XW%cMO?ZL<52<`O=2W6FQo7XnaxQckH!8x4s+npzv{w~aA8)}gdhX(#e# z+pV4^3Ldb5W*T^uTp)T#J$dfaQNz>*llxlg?J?gCldQ?s8%727nM1;84>lt|wmEkr zdx1uRo_6sDtNd2h*)#0Vo>ThX^kVR>yY?ykVkPATjkHGBg8PIigIU542J1`47^Bsh z_wzXNGgXN3e4~T=@hORb(kTuWwFNe5FQh|t`E2e%VJFn06221k`SLXQI_~blBgATh zVxGhXWe-Rk8C_?kPI@6=%+l%n;0ZrNS%-!5ZNVp9LU4QbyDIrA$6@)3i>{jIFZI{D zZpDt?P$~%Yi=T)+B8Ez;1klimdN0;KlnV22dv>(6tY)C_Nr7Fh5&7YoXJ*w5<2#2@ zsfGKfSjL1wa@N%rpq;7Es=}N?YFGPEd}UT%Dus7kNOtO(^%z0V)w{FZ<70Iec~e)j zr|MkShRo;TO6&GV>8iKZ`IE&id}5G_UDtc85xK}I|9Rc`9*xoY4fCfAW;q+yo&xhP%y6hGNfbo^Ddx;l0)7Q{LP3d|Jdy)h#?ZJ9uNo;7pe9=jV^@ zGJ=%0W>r()A#Ddw+yRF$NL?=RshX{R1xOV6_9@D7!l2Gu4i#s@nUk+r^hG|BZ{7$| zs@`Y2;28}q7bU61YyrhcB7{jg-2nqxJLD@{)sN>zDZQ^K?Wo3<@O15yB6H;!rvA!f&*}-4gsuv@ys3w+YY0OFi)pQVx+pJWNK(*x|30^^F zi{j%-TWow2a8Z&xeS{(4Ma`{Qa>Oe)VUg@D_Vep8WC^8)XjST&>09SpGk==fWqsMe zx=R{AOki)cTSMF_MhpQk4=_&-3}cGwh(sgps>wnw$Di@W+jL9d#?v4k%Gu|S16Go| zvc7OAz--N(EcnRfvmwh7!}b*pw4)VPTtd&CD7{0TsoM&jddYw8d8IH(tkRP&KeTZL zXv9PUBL1>5wriPw>7xzh0Y^MMm5F+W+aTAjXofK*@W}ZBq)Zg@V)x}nFL}lOVYD!$ zU+-0i&z&Q@6}ANkD+QfEn-%!kWi@%m`M2*}o(&ThwM9K;RC?(K0RU8hc;swPCQV{= z{bZCO62#a|FAF;0NkGH~t`U8sqDOiX9}##>|@#CBY{+>`KZJ~MWHJGM$yQ*$zl z@nE%CtpY$>V$LKCg-+O^tOF319ne;%8;xQ+AcV!NXg&97IHfFvx(AE zzY__W&j364G8_dWV^vMlUr`PtV^IpBH&|7Tq!BugO*2^Qi-v=_XG`5u_z5`45;&U& zgDMk*3>u6t*5+y40kFyxF1*H`3^tl!`qHw&W2qyQ$!yQMxUa7cQ1g)Q8Xlo<{9op%x-6nmXdUms8NlvL&q39;SHMZa|59#}P_k1gl0AfYC{ngij8E`& zrZ-HKXw^{rPL8jbuGEZUovzHY8|CfAaGwo9paKUNiG^%=pQ98~*6-nL&I0RhDFnow zi~`6ab$L~uguG-|6UvxG%8K+#8tKYx)EgDq8xL~$l@1%gV1YpVbDNS;XjpQ@$fI$i z!Rqou8-cmIpEISzE|u*_%re{t<6!58BB zpI*G&hY?}h`OJl%S-s15A~8IMg;JpA*i=uKPZpzlqx;tqQk`2amfZF8o*Ql=&Ofm@ zUE`3ncE?ZH=V5sjN58|pi)0!7J8(lrxSdsj-}#V>(m`g~&AViScVZu>zyjJAF3&@Q zXYSnhs$g$lV~!f#bYYwEHY&Y0u3 zT~g8!up3HVSKS)2yM0jk=1_@knT_)%$Jl+1vp3(&lnBn|?jH#TEY*llzkl*z+Hh?8 z%A=gJ+lo(E(<99|b6>>WJf&)jPt#97O%K=8VY*<_-3TW(9YxV$Z3(5C5afQNCwER` zkESIlwf6Q6(DV5u*84W)Rw1;GmS9ZWR z6uH`np+u-UI!{kFDr;kp{3caE%VQp8tUc|6CbbCCAS?ZKd-`5kb@8VpSDjQH7^j-l zrN#R~&j2atnSA;p7URM_unw$mO4SxF>c<8G9bq6jq%!R|CS0`;|3WfSU3xq|&T;WH z$6;R?R#aOpk7L@mY2b|Vc;a1PQR6HX4VQXxQrlcVWeL5OX~TGOI?AAbxUk%8dOW4E z5C&mIYoC8Rp89Z@q%?(Hw!y$a8jO!0(Z(V5>>@b;00y8i`opjhH?gRbbqXODm0p;u zL?TPGeqY#Y1>2N~tmnSkG+FGL0tpncF^Oh+>wLXug-EmCVO^9Erfql~b$syL5h)r+ zdId^N$vgx+guI0aPi#Fiai>IyOWq)oKh)!eV`S?(GXFjLG9SGYcySOk9+@&(xK%&E zN1;q;2zDd^)oj8WFzHKeE+h%`%-yrh6&!xbXgri)}3gA#$`xmLs$~FiX;_XZX$1 z8ACdi2qN4A*U~-5pUdTgd*SMAkk<`Z*wYdG0%Iv_lw?#EFdelm&jjG3r{l37xg72E z0(ptG=nDB&^vzNMy{JNC7(W6DBo!roap>CfAQ-?2Jb~JKw9EirZd8Ze@ugi{q9~A_ z8;QM8FwSsoZph)tTV2u$GQkMz4dm({gO6K<7N(Sht!iCfYExMZ!=rj5-s!0pyZ~W> zx7~Yig%+BL5e;F-*0R*ni^kibqU}bzr2s0|?l23*zaL8N^JR!ii!X?176 zSJ&00`HVU^lc;-B{B+0|#!}5=MF69pRoO}i5QnPg5#?o=mEOO1RkOCbK#Y`2Nu*#E zzLR;;S*A7RY0Y{xL{gRjX$x1;k}<{3sXwnU`r2{B=s-%)%SgETBDQ6?>H(A2 zBMDcUY{km~b(o>zJ6X|^4C4+4M?ctDy(X}NGxE^^%ad`tkV5ive*I2LuSsZOS1C3r zt^uF#g*pXR_PK*Y6?-N-dqwgPK2w8!?9;}eSY(rfuCte!!)#WQ=1^9wGa=X^X96;E*$@C z?(-3VrEKlI@lxBhHIwkY%)oW7CrX4GDG~m1=_VWkUL!r+`TQ}XdbUdb$MW285m? zlHL}AlZ`Hf&5a$+JnAU<{0WoFzB#F&U3IZ$@G@E6jn{|xD4?6w!Iysna1)6dFSY_Q z!;QGV+5YiZDm7%utEhksiarR;f5Fj-zn(O91)Zsk=Hshc!*m3vNtEP@MlqoeTNDoi zq=Mm!1dv)FKqRyuzrzU4DJzj$M%gyRPXHjV7Vo6>?dqAUNpa)TpCH=FCt{$ctZ7AS ztnphX)*86-+DKU@$@wn|&ze^Q+?pjNiMg%O27vp5=r58hY5)nv)(Yh16WxP=_Msp?Ymq!R z@z*^mP)@9|aj!H(JLy1Ns{~j)jbc=}u1u6vtf`%NxHA}BBN&7~*Im6t#ji?$0wddq zNjr45>Nx4|e9A|khz9`#+E}f7-RjkKiO#%4q69gqc3kORM-i`8M1Ub67!$aohl&>f zh4GOA;3QW=pqyZpu!V>QnTU<;*eEs+~M}q>4|>Pbfdm1Sf7Sq6&$-TQ0%MK?zLUdp3A4lPaZtX9b%o}o(P;4>mL(W zftM9jVTall!7Qr6ZF14_g&M|-jY7fdCT?I!JVmdNR@RB3KHuRANZ0f}>0-J@C>ZO@ z!N+Ib2IM2F$TrTQpP;8ruw)LPHLBr-t3QgYR^0CR%Upq`XN5m?0CgTFrd=% zUbs9$_%?DhRRL|c{-vw+ME$h`)&gX?o)fzoH z0qPgfvu#$Q!J1X?g46C_|Bfh=0=#r$jI&q}fN%wx&WnkZ){0t^q|m zf>z80;QMF+Dl_VneHDiC+H0v~cU6%5*=zz;V}jWVf^+zvCn%P-o`BxOQuyBe9MVVF zmRCoDJVC*wG+}x|p%bzuB(F+`XM)<<9f$5<>sl(c3gOwC%MgI5o*dVtvd2KUd33-3 zK)fKaP_W^I*b^nGNzEeT7?{jsUS1=M=$NdgH}l3GsD@^Ro`~EQMlHirMzIk_Q+U|C zvo+&pS2fM6CM{mJJgYZJiIVG?Jga_{#72?y_3No*qsdHP!^*-bhxYqNJy0^WY3Hk^ z@m=F#SI*g+P&wS3b{{Em@>W!MAf#tQJ}CHDmu2dTgMx-{tfCtF*ciON(x~LtJhM#v zayimDPY*xROxKAz3)v=B7$MQa=NKuIf}IZTEplnrk<`JeshRU+kGIYWA5KPsUl@e8 zpF2T4FpuDG5;Fpu5Rl0f5Ov-l@m%Mxv>c(T9Q9^E>+%YRbn?Y0qGj4E>|aOETTdx? zw1s%}MNL^)Gv?{`fUPf9zBeb;4C+N(ZC#_vI7b4{Y6tTLsU<9_FTv(s2c{p<*?gAoL6|FF<`zRKl?ki6@y7MeMtQ(Z62~YtYGeIiQ1;Z8ra&7-+D6`B;jC_?@yP_} zsZ|2%GiT@*qp;|8@13=N*i>YGcE{@kgXsP_u`Xn)AevOpLV#H67(KrH=BcvfLaceU zgw4}02rDDHgtJ!&|o8hNq5Qmo(Yt>l{VJomrb{`{oBdOIJPPTkg z>Gmtu51YpU`GwJoM7IrM-VAyYV6X{X8HlMT%F z#UjNeZMxE{XzKir#)1kg2_$PDmrEu* zS48_lCXeWDwkbjJlJDDd(Y!ki?_m+ACD;WYXpRr4R z%HW5_dv6Hopor|)^=7BMg=UE6EHyywyJLBmve{Y}Kg*0pe z9mVf)BuTciZ|vTo9WMm+#3rP%t~G?n5S_H%#n1#xMt^a2QxaNCce!EHXk(KDZnMOU z6!4m~+Bt5U?x#bLYlnjGa(8&UymA^kZyku-qRE8E5J7ZK@+A)Wa`CkQFE)PSyR(HK z%$vq2&#OmM`V<_bJ{D7u*~AH1`D{uf;>i%qFYlsNQ6tIv< zRR^XIwQon=bLQc54aGjr8=tMoQ$mv&cWnS78Xhon&EuCy1?kBI8IEQe#`>mA+sWBG zKuum*n-0r0jGa0qPji!x>(PRy7;HjR?f1{2MWMPaVl&%7%P zYTMA#2@Wx*nY^%TU9A;0$H7ilcx=6AYe1qjR3VJ5=M70Vs)=;`^m{x zW{hIY=h`PJb~hZ%z&~BO_^9z#R;6cX|3_;vt-hGdJ;BtiXqDZ46q~G{lF*y=6?{z$ zAg^-HRWeB4&ea@`tn~TYU|SS_DbT^QrxG8nbzXsi*L4(tK{=9Y$(oA}bcK@haFZH} zc5>e#BDEx~6$9|a5Ndg6HF@Xbaq<>XGdp0o@CkUFxK%Gs*o~m9RoQhg6EHv~Erq2H z?>4s~0dWww$IcPoWT|0^VU^n({^?4~MxU2EZvhuXmfN^{6l<*3M** z7|fDAvaN{U5P#gJ?Nbt*PsPQWHSSy1bCOGlJ-}vXCFz;l+bSFK6DG}Ga?MS^ zLtQoSYdOBcT~0%NlGfx>144*+OlOa-d1PW+2|c10 zg^sqyON{P&ev*ItV!rXptG!QW-iMR3O%HoOkk$m=RP1sVo;6(;Ur~5kYq`1d`J5t< zU6h@;?To+gLS+jF>@zF3K5)^e%StjJKBY;P26X(0a7=@M((M2sLXfDfEuNR3K8>uD zIw5KYuQ3!Ms0BAev@*cfG>dp4aQtgDz)l^)CEhFC6ZQgz&sa4Xd@MTSg&R@VrOrq^oZs$ssIyvmTwM<~XY zNX>cdigBV-blUJB6q;F6-6kViRhQ!eU>doXpkAk{?K zHw$|8SG^(H+n*#y5%|nWc}Dm>E_50^G4?^+1{MQ_DopDS^3)l|2-!>C5&BW7azNh} za#oXXLt2qBi}`81Q<6TqC(zzxv7~}L$BlZag&Pu&<#yX7o+#c0T{1~b3xK#Iy!^&( zf_d$HZ8#zsu=*-^F_XpQb^%5A``P^`!dMPDlK~`?SEb?z(J?Oz`A;7)2OwD(jFtTd zt+Ehi74r+al^fg4NnUqL{1$JYPNG89j>Wv0?7-iXSc^IHS#~{MTgksp&f?anCp@d( zc9@Ve{L9`wdU*BY3JvR=V89l*A(vBO z#=?n1Qa<-MVEQbnPxT$vk1((bx}D4?JjCAM*@=(z*({rTx&qW}qz=424CDGPn3@zL zy&ftLClWk<1EO<5Xw06)W6SySfrcCJFo}zv5flbG%K^{hBZp(0QQok?1a!#KDEYZ1 zqo=C8NA2PaVAp<4u>0dQE^hHL8D=VLG`28}yPMkzOTxjt+oqZt@cw) zv7@Usvz8ZFLu@tV#^b;Nn67d>^XfWh%7QYTd+C6#Pi>-9TNI?R79&(2jakh^0xyks zKTgNElCS9Kt;!6XSU6Y1ss=e8Mu$Tqu;P3o!&W8TGectR8`AK8M6wZBmAzUW`+2~ zKk4BBavUoL7>e^bdRZEi`X~Aa=*33}8r?P|q?G?K!S<1@Xz7E+ql127uXnqPh`acJ zC@o{?m3ktolVUwf{Ba!xT1 zN4NNA{nYNFC{htBI9&v9u=A)wy0M$G;AL78_P0LZsLFNYOZY}QR-;yCfEN1lc@aLW z&yJ7&5j7w4$wczG;}KH|Q$w3bNx@I~Gw*VIYx6CQc=Qa$`3v+RLb)%B!xRPWsfLQ< z^HtR`mE4=i42=j$ity7?K|sc>{xsR-vzKUWTxRE*p97qAI5{pTk|bCXl-6f7N^Z>P z4EDHaIR)1#8a}|#CA0Y#8-z#Dcswt!=^9xtsLC!)(cgi**3nNTEZUNBDq%c)bGahF zipQV1V)ms^W9!pT#8suMy4~F2_q%%Cjlv|eBCv0`MR)mp@!o4St6ufzp}D8K%03^# zJi{jF@1e~}67(@|hV9ixxpl>)0)VO)Ao@YK4-JyM+VPUFnJv~_#_oKX?*RX9Yosy7 zTkT}=x2-4KN@9^lH_b%P_f%-jmWRvcArtW8`R&&0-P3?o>st2|kzOkOp(L1ermVZB6(eUG}trdXR+JCY2tAV)05$KEAMv^pwq!YzG-!8nsGJ=~@$a{W@l{2|AL^_&hT$F%x zZjxf`M9QmWdpVguelaNNqG$bJn+?;!)w~K_&&EC>`v#BkcxK`&iixs9Hp!!)2Vu{etD`Dy5ps|bU+cZg^{04nuOyhx^UCXwtStwmL zo!%Z@8rY~H&kc_U2u`+mkIX6A0dM|fm}1=>bIoG?tLOkTL%SvZcg>Dm^Cs3llfnU+0{Bd>o{YN1($j*sfLW*tnTKamHyo(&1)_JCR#k#D}=zoSQ=a^HV)t z){EmnxXLZ6ixz|LCMJ|#?JWf~h4f3lP1)3nxOp+q%~||I?n9-wb!X-H58Au1f)?+d z^e_^Q8lV@$rL{iXd>8Tg%jdG)#ny}de8}*#`fGU{XUk&rU0dtJ1LGq6MJE}PHIMl& zBubjnTd?-T+h}#t@2l$Xhv*R;lZ%hAxaz{%ZA`Vy4L9Ki&+wkGctpEdXutOWEvuOl zj9WdEQsb?myw%(PZZ5lhB=_x9E?JH_QStJTP?TiNe1*k@!;9x9@mBU<=2G5LqeRVC zRGnDf)CE!TUl1RlFy*v6Py-zx*vyWel6kVx`K{<4J+qX|N;e2S?Qcir*}HsvnoMbE zBR!9)gN<2hDE#2*AWL4e+WGtkPgt}K)brGx9?`H~*wti&Wq?ZN@=hjM4-XhP zR`WP~l4<+cxJ>h}#SAEaWHyteh}uuk^|eAFyLij`5*21^DVc?64AQHIVwO^a+hHs; zIkO(N5X4yGqA61zHfReo(449gw94sCt}~*?fX{3QnN(dI*D{6yH74)(gvE(VH2 z(Ho~~rX!KTsShUZY*0o;BQR1d&T6R=l#lWBsKfKHdOCO__hOZ-{Jh)dmxyeDg_ z=;_^-Cyo z4zaDr!z?+v4I~i2iJN(e4E9E<6F11LcW4ULYE!`EefNV3+0`F;`xlbhuV@?==V zfPC_x(2jLew@P1s-vmul_)vlN#zELV+59t!HSP0kyg021Xxjk!o|KD`C#CWG^*x zAai5~Aqgx_3%|@2YDlymB(GW>Kwh(jPAJUs|B$U>&h(&cn-p5oi@VSGftl_Wu}90vvsN3T`yaP-3#};ffsgQl zXxq4N9vemSB32d3K6wqs!^&Gc!-V934nXIft9sVl&&^1ePC_U$l{Fvc6unwB*`EvX z3ysUH>Ax&$s^KRvSX>EUI~6@!e7kE-t8gt{-emI(!GM%Up4up`{T`D!o zO(z$6dTWt`*_(f!hWFN>%e&$12aA1yLfEi3i=~v>P#YYa#DP3FNUqe zGZ$MkeTvXh&8}Q2F% zCcJ4twl|*e40u_soYYFw{DO0@gpcu|l99fk@fB#L6~5X5>fU;e$cG$|yCaIe-o-p* z;B9%KQLKi;aH)m*mRR?g+nA9Ucdr}G&cYlvh!iyJv_MRjiI=eM5A<5i00J(6RHVuQ zIfI6t7hRNDCM{y={kUK4KYQA)FA$%L_k3Wj!9|BN{&Su~d8F0b;`<~IMWa@BGq%o~ zF&mnQ+O3uf(=@nW$gX@7h;Sr{~+(=LXQH%5BfY5UzRWGLoOehuV5`()oZux2q}R zz+pehk1dFe(HHPTUkST5?*TIxBkeWStSuOz-lRMBSxuh*r@b@(hjQ=#_%+NhBuDlv zHR6admL$rO!C-7rgd>rYBE*S8C-*_72xW2#m1RiCl08zE7>qS7Cq*42*@v-Zm+x5W zbk3dbM2`B-UvT|&Js;24d;19O3BSl1!DW*1<3u%`0+~~%+~#O$grj;)Ov}(4eFhUU z-{GXp!_Ctk=6=Vp%$CxK@`2hcvMIvo1X27dmd3-ZyVV*cJi1QIT7`cHr?efZ|5ECv zkY7wplftA-jLJebuxZ1$nOpHBBP_SdddBDA6HH(cYHb2NN)REEZO`24WdGdVIRv>Ib=js&-C&ES?Y7+#Oo`e->=uz= z5Rc6oef2c9%e<&8HC4GjTfW_Q7|Plco@%`5B2t7& zGL)+06SzrmJsj#3x){L?WbqWiQC^&rC-jl!`VKFN1tcpqb#sj(a4OA#2Y%Y<+aT`Y zn}j$u()9B+k=Zt$uEXBUdTQwnPhK0#m?fQe*-l%PmRy6&YzZVfUQ zLhoF03cWq*Cg)PdsJBI=_6M)^$1F>Oq!pq@rR-Iz-4z6pBd;OyzlVz82G8>14da77 zU4P*IQ?^k;!{1=DM*>Hm9)uN3BU+s)#aq-W4?g;Xzjb}F2p$}^mwY8i{-&65oIOOl zz5S$l!ql!UY;v;Ik#1Qk4DFbXlTA$-kX9WHUT)5d7e?#aU~3tD`wbBgzoLYf7eTi! z3y?%$h;b+W=3SaheL8li{e|qIO;#+Et~cH8=D5_^x}>?m@&-gTf)tz248r&CPUkeC z;9(lFmn$m4*YU1PXHJtsK~Np4E~CaaX`g|F-{#Z{lbV_cUcE-yHZ#o<{&UDXb_L3c z_^#3GuVxC%~nCu zHXelfdo?=DO6fK~<;n{>doy(A=DN|>old*+|$a1TSSkJi2uQuZrCLjGB*Qe#fOZ;B$rNw%6~d!a!M zQ;Gb>_WVBu|D$+!IE<`Bq%R=uqc{B>5>L1!-#kT>+}Tp^!6^e5Y&3rg7vX1HLnEhN zB6q5w&FMFS(~H_uZ))#^pU4b-y0s1vDsC!@70Z0oyye6@fLdU;u$j}r`&ENb$yyX*gd+y?SM z-V<#PKmPPcdxU%2&Gtx-;m-CbFFJS!4#WBGHV`e{{f_I{nSK1xQmxJ#VR?s+#D%+d zb;je)!n+b;L+rY4Cd4InB_`kQ>PkwBoNl#E&U(tj3fyi>?7nqxxT`z0h)#@@hUc^= zr4xjcNEy|#-K5Mq4Y8h?ef*y6XNQw|ZohEt?#Us3&YeQu-sHD*h`u5)mqXuu=;ma~ zKE52OuY^St(T`_0ap*7Qwn^?U<8veRm&1G!0|cQ^hk*)__~Zc}D0fz8rBsxOVYN)X z!(h$!_J95T2J|b&@s8L~$MMdD_*>&$$vM5_-D%|#6Qrzq$BCZY!Exu_dn3IQh#;m5%Tmjz=Q+n(M2>oeO^#q z91Ry?W*^_1B@hSRjHc|C^quCe#?i?U?lb?|=L2JkhH9dVS+DkCM0BGWO$f!Dd3|T3 zn4VNagE8yN`VIhhqswS;CFitozD$|X$m!ECJdF^@53L(Rxl@Qbylyv4lMlV_8oCrN zt;xuMJ2s^Pt%R0tN`} z5S2M-Rw8mp165Mxh{3N4&B>mTCNFx4Q6h%RakSZQ^R3ZWfpWd0Em%#7vDcSO9LHKI zM@+`r!rgku+Ht-TpMqxlt%;97)5ASNoN`c&e3glE#3V@J=QpMSfm6dT+{j9y3?7ni zM~}$qzlY|7<3R5`G?kw;G|fWO$>QzXHSeK$JeWp>oqL@GOiH<}8_H7bhJ{wzoNl;| zQ$uuctThG$8z!|_fl*`_Rtg!R;-#VMn$J4WjgdeFGaf{j@HF(D-Co^nh~iY`Zxe-m zU{QR4Ilu`SUlI`T-2Va)=C2y9N+7J<`!(k*Xt!WN~P?O-KnEmF%M8eGgOE5g9)wGqW^i+!ukA}5VNv&N>W zodY+Yz1SJGMtm%$uu}+N;ASXd;TJ;j{HE#0bnF#t{a(DNS--z&bqr^ZP^oxZQh>$r zJs;*U5lRkQ3)!)x92V$D&0(wT1*|=nP%*23ATW>$Ie)Y*iCi!_ycmLT0Z4*SK#uKf z4qF64dWIewtX6_-Jjqfyd!tom11gy=u1(GmC0d&(M&e)l;Ur% zPTcWD<2Uj2&*w0_uzdeHgTNT}cywv)vm^>ZHti0JFO~SUUl^HCF_Xijul5I;FaRIs zFrDM2JK~Zqxc)PT5mb2wuzncM^~IS4)LY6Cf}(@!aXGwNjNo7-+6#qv&aEv!uqoVw znMRdio&Il+WG)H)=&H-Wvo|tB$WD=&OKFpaNx>uI6 zS$IJmK}tHO3w%^Z;PZhdhcKff0W)V>=XGSREUa;ZAT>DUx-dB2;nz*QvWNf?2rdfm&J66Lq%l~X2%_J_W zBz>bW`MV_jx5CUx678HM{iQJfZBx`r()_j*Rg$QZL>hd6q!%BmLvbA)dWhbfGW1AS zZYgsu)8E8g%hzj*QzdD2ZV|2A(!i%yFTa(tG*yzm14)`~gRhQC(z1m=Y9)yp{(5s? zhuHVt>4;0}%_H4jOh=yDZd)Cz3`>(FYP+rbS*CqcZT{U6GO;9JdZT{9y|KZL$4QnC z3i2mL`dX@@^a~57CPoLln;sMvQmzBgi4eWOoVG-7sBi-DG?Q!x(T7Dtq#46bg~<|N kLY1WNK$2*H&#WZT004m4263YF#z2&=85jV8!GOa50Uh6XU;qFB diff --git a/enrollment.csv b/enrollment.csv new file mode 100644 index 000000000..e80af8d93 --- /dev/null +++ b/enrollment.csv @@ -0,0 +1,6 @@ +student_id,course +1,Mathematics +1,Physics +2,Chemistry +3,Mathematics +5,Biology \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 3afaec37f..a6ba782df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,6 @@ "version": "0.1.6", "license": "ISC", "dependencies": { - "csv-parser": "^3.0.0", "json2csv": "^6.0.0-alpha.2", "xterm": "^5.3.0" }, @@ -17,6 +16,7 @@ "stylusdb-cli": "node ./src/cli.js" }, "devDependencies": { + "csv-parser": "^3.0.0", "jest": "^29.7.0" } }, @@ -1573,6 +1573,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/csv-parser/-/csv-parser-3.0.0.tgz", "integrity": "sha512-s6OYSXAK3IdKqYO33y09jhypG/bSDHPuyCme/IdEHfWpLf/jKcpitVFyOC6UemgGk8v7Q5u2XE0vvwmanxhGlQ==", + "dev": true, "dependencies": { "minimist": "^1.2.0" }, @@ -2943,6 +2944,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } diff --git a/package.json b/package.json index f52103d5c..d2b9c2349 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "A minimal SQL based DB based on CSV files. For educational purposes only.", "main": "./src/index.js", "directories": { - "doc": "docs" + "doc": "docs", + "test": "tests" }, "scripts": { "test": "jest", @@ -38,11 +39,11 @@ "author": "Chakshu Gautam", "license": "ISC", "devDependencies": { + "csv-parser": "^3.0.0", "jest": "^29.7.0" }, "dependencies": { - "csv-parser": "^3.0.0", "json2csv": "^6.0.0-alpha.2", "xterm": "^5.3.0" } -} \ No newline at end of file +} diff --git a/sample.csv b/sample.csv new file mode 100644 index 000000000..9e7a9fa25 --- /dev/null +++ b/sample.csv @@ -0,0 +1,4 @@ +id,name,age +1,John,30 +2,Jane,25 +3,Bob,22 \ No newline at end of file diff --git a/src/cli.js b/src/cli.js new file mode 100644 index 000000000..6d281e6ea --- /dev/null +++ b/src/cli.js @@ -0,0 +1,89 @@ +#!/usr/bin/env node + +const readline = require('readline'); + +const { executeSELECTQuery, executeINSERTQuery, executeDELETEQuery } = require('./index'); + + + + +const rl = readline.createInterface({ + + input: process.stdin, + + output: process.stdout + +}); + + + + +rl.setPrompt('SQL> '); + +console.log('SQL Query Engine CLI. Enter your SQL commands, or type "exit" to quit.'); + + + + +rl.prompt(); + + + + +rl.on('line', async (line) => { + + if (line.toLowerCase() === 'exit') { + + rl.close(); + + return; + + } + + + + + try { + + if (line.toLowerCase().startsWith('select')) { + + const result = await executeSELECTQuery(line); + + console.log('Result:', result); + + } else if (line.toLowerCase().startsWith('insert into')) { + + const result = await executeINSERTQuery(line); + + console.log(result.message); + + } else if (line.toLowerCase().startsWith('delete from')) { + + const result = await executeDELETEQuery(line); + + console.log(result.message); + + } else { + + console.log('Unsupported command'); + + } + + } catch (error) { + + console.error('Error:', error.message); + + } + + + + + rl.prompt(); + +}).on('close', () => { + + console.log('Exiting SQL CLI'); + + process.exit(0); + +}); \ No newline at end of file diff --git a/src/csvReader.js b/src/csvReader.js index e69de29bb..1296d8a25 100644 --- a/src/csvReader.js +++ b/src/csvReader.js @@ -0,0 +1,42 @@ +const fs = require('fs'); +const csv = require('csv-parser'); +const { parse } = require('json2csv'); + +// function readCSV(filePath) { +// const results = []; + +// return new Promise((resolve, reject) => { +// fs.createReadStream(filePath) +// .pipe(csv()) +// .on('data', (data) => results.push(data)) +// .on('end', () => { +// resolve(results); +// }) +// .on('error', (error) => { +// reject(error); +// }); +// }); +// } +function readCSV(filePath) { + const results = []; + return new Promise((resolve, reject) => { + fs.createReadStream(filePath) + .pipe(csv()) + .on('data', (data) => { + results.push(data) + }) + .on('end', () => { + resolve(results); + }) + .on('error', (error) => { + reject(error); + }); + }); +} + +async function writeCSV(filename, data) { + const csv = parse(data); + fs.writeFileSync(filename, csv); +} + +module.exports = { readCSV, writeCSV }; \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100644 index 000000000..37946433b --- /dev/null +++ b/src/index.js @@ -0,0 +1,14 @@ +const { readCSV, writeCSV } = require('./csvReader'); +const { parseSelectQuery, parseInsertQuery, parseDeleteQuery } = require('./queryParser'); +const { executeSELECTQuery, executeINSERTQuery, executeDELETEQuery } = require('./queryExecuter'); + +module.exports = { + readCSV, + writeCSV, + executeSELECTQuery, + executeINSERTQuery, + executeDELETEQuery, + parseSelectQuery, + parseInsertQuery, + parseDeleteQuery +} \ No newline at end of file diff --git a/src/queryExecutor.js b/src/queryExecutor.js new file mode 100644 index 000000000..85681f54b --- /dev/null +++ b/src/queryExecutor.js @@ -0,0 +1,370 @@ +const { parseSelectQuery, parseInsertQuery, parseDeleteQuery } = require('./queryParser'); +const { readCSV, writeCSV } = require('./csvReader'); + +function performInnerJoin(data, joinData, joinCondition, fields, table) { + return data.flatMap(mainRow => { + return joinData + .filter(joinRow => { + const mainValue = mainRow[joinCondition.left.split('.')[1]]; + const joinValue = joinRow[joinCondition.right.split('.')[1]]; + return mainValue === joinValue; + }) + .map(joinRow => { + return fields.reduce((acc, field) => { + const [tableName, fieldName] = field.split('.'); + acc[field] = tableName === table ? mainRow[fieldName] : joinRow[fieldName]; + return acc; + }, {}); + }); + }); +} + +function performLeftJoin(data, joinData, joinCondition, fields, table) { + return data.flatMap(mainRow => { + const matchingJoinRows = joinData.filter(joinRow => { + const mainValue = getValueFromRow(mainRow, joinCondition.left); + const joinValue = getValueFromRow(joinRow, joinCondition.right); + return mainValue === joinValue; + }); + + if (matchingJoinRows.length === 0) { + return [createResultRow(mainRow, null, fields, table, true)]; + } + + return matchingJoinRows.map(joinRow => createResultRow(mainRow, joinRow, fields, table, true)); + }); +} + +function getValueFromRow(row, compoundFieldName) { + const [tableName, fieldName] = compoundFieldName.split('.'); + return row[`${tableName}.${fieldName}`] || row[fieldName]; +} + +function performRightJoin(data, joinData, joinCondition, fields, table) { + // Cache the structure of a main table row (keys only) + const mainTableRowStructure = data.length > 0 ? Object.keys(data[0]).reduce((acc, key) => { + acc[key] = null; // Set all values to null initially + return acc; + }, {}) : {}; + + return joinData.map(joinRow => { + const mainRowMatch = data.find(mainRow => { + const mainValue = getValueFromRow(mainRow, joinCondition.left); + const joinValue = getValueFromRow(joinRow, joinCondition.right); + return mainValue === joinValue; + }); + + // Use the cached structure if no match is found + const mainRowToUse = mainRowMatch || mainTableRowStructure; + + // Include all necessary fields from the 'student' table + return createResultRow(mainRowToUse, joinRow, fields, table, true); + }); +} + +function createResultRow(mainRow, joinRow, fields, table, includeAllMainFields) { + const resultRow = {}; + + if (includeAllMainFields) { + // Include all fields from the main table + Object.keys(mainRow || {}).forEach(key => { + const prefixedKey = `${table}.${key}`; + resultRow[prefixedKey] = mainRow ? mainRow[key] : null; + }); + } + + // Now, add or overwrite with the fields specified in the query + fields.forEach(field => { + const [tableName, fieldName] = field.includes('.') ? field.split('.') : [table, field]; + resultRow[field] = tableName === table && mainRow ? mainRow[fieldName] : joinRow ? joinRow[fieldName] : null; + }); + + return resultRow; +} + +function evaluateCondition(row, clause) { + let { field, operator, value } = clause; + + // Check if the field exists in the row + if (row[field] === undefined) { + throw new Error(`Invalid field: ${field}`); + } + + // Parse row value and condition value based on their actual types + const rowValue = parseValue(row[field]); + let conditionValue = parseValue(value); + + if (operator === 'LIKE') { + // Transform SQL LIKE pattern to JavaScript RegExp pattern + const regexPattern = '^' + value.replace(/%/g, '.*').replace(/_/g, '.') + '$'; + const regex = new RegExp(regexPattern, 'i'); // 'i' for case-insensitive matching + return regex.test(row[field]); + } + + switch (operator) { + case '=': return rowValue === conditionValue; + case '!=': return rowValue !== conditionValue; + case '>': return rowValue > conditionValue; + case '<': return rowValue < conditionValue; + case '>=': return rowValue >= conditionValue; + case '<=': return rowValue <= conditionValue; + default: throw new Error(`Unsupported operator: ${operator}`); + } +} + +// Helper function to parse value based on its apparent type +function parseValue(value) { + + // Return null or undefined as is + if (value === null || value === undefined) { + return value; + } + + // If the value is a string enclosed in single or double quotes, remove them + if (typeof value === 'string' && ((value.startsWith("'") && value.endsWith("'")) || (value.startsWith('"') && value.endsWith('"')))) { + value = value.substring(1, value.length - 1); + } + + // Check if value is a number + if (!isNaN(value) && value.trim() !== '') { + return Number(value); + } + // Assume value is a string if not a number + return value; +} + +function applyGroupBy(data, groupByFields, aggregateFunctions) { + const groupResults = {}; + + data.forEach(row => { + // Generate a key for the group + const groupKey = groupByFields.map(field => row[field]).join('-'); + + // Initialize group in results if it doesn't exist + if (!groupResults[groupKey]) { + groupResults[groupKey] = { count: 0, sums: {}, mins: {}, maxes: {} }; + groupByFields.forEach(field => groupResults[groupKey][field] = row[field]); + } + + // Aggregate calculations + groupResults[groupKey].count += 1; + aggregateFunctions.forEach(func => { + const match = /(\w+)\((\w+)\)/.exec(func); + if (match) { + const [, aggFunc, aggField] = match; + const value = parseFloat(row[aggField]); + + switch (aggFunc.toUpperCase()) { + case 'SUM': + groupResults[groupKey].sums[aggField] = (groupResults[groupKey].sums[aggField] || 0) + value; + break; + case 'MIN': + groupResults[groupKey].mins[aggField] = Math.min(groupResults[groupKey].mins[aggField] || value, value); + break; + case 'MAX': + groupResults[groupKey].maxes[aggField] = Math.max(groupResults[groupKey].maxes[aggField] || value, value); + break; + // Additional aggregate functions can be added here + } + } + }); + }); + + // Convert grouped results into an array format + return Object.values(groupResults).map(group => { + // Construct the final grouped object based on required fields + const finalGroup = {}; + groupByFields.forEach(field => finalGroup[field] = group[field]); + aggregateFunctions.forEach(func => { + const match = /(\w+)\((\*|\w+)\)/.exec(func); + if (match) { + const [, aggFunc, aggField] = match; + switch (aggFunc.toUpperCase()) { + case 'SUM': + finalGroup[func] = group.sums[aggField]; + break; + case 'MIN': + finalGroup[func] = group.mins[aggField]; + break; + case 'MAX': + finalGroup[func] = group.maxes[aggField]; + break; + case 'COUNT': + finalGroup[func] = group.count; + break; + // Additional aggregate functions can be handled here + } + } + }); + + return finalGroup; + }); +} + +async function executeSELECTQuery(query) { + try { + + const { fields, table, whereClauses, joinType, joinTable, joinCondition, groupByFields, hasAggregateWithoutGroupBy, orderByFields, limit, isDistinct } = parseSelectQuery(query); + let data = await readCSV(`${table}.csv`); + + // Perform INNER JOIN if specified + if (joinTable && joinCondition) { + const joinData = await readCSV(`${joinTable}.csv`); + switch (joinType.toUpperCase()) { + case 'INNER': + data = performInnerJoin(data, joinData, joinCondition, fields, table); + break; + case 'LEFT': + data = performLeftJoin(data, joinData, joinCondition, fields, table); + break; + case 'RIGHT': + data = performRightJoin(data, joinData, joinCondition, fields, table); + break; + default: + throw new Error(`Unsupported JOIN type: ${joinType}`); + } + } + // Apply WHERE clause filtering after JOIN (or on the original data if no join) + let filteredData = whereClauses.length > 0 + ? data.filter(row => whereClauses.every(clause => evaluateCondition(row, clause))) + : data; + + let groupResults = filteredData; + if (hasAggregateWithoutGroupBy) { + // Special handling for queries like 'SELECT COUNT(*) FROM table' + const result = {}; + + fields.forEach(field => { + const match = /(\w+)\((\*|\w+)\)/.exec(field); + if (match) { + const [, aggFunc, aggField] = match; + switch (aggFunc.toUpperCase()) { + case 'COUNT': + result[field] = filteredData.length; + break; + case 'SUM': + result[field] = filteredData.reduce((acc, row) => acc + parseFloat(row[aggField]), 0); + break; + case 'AVG': + result[field] = filteredData.reduce((acc, row) => acc + parseFloat(row[aggField]), 0) / filteredData.length; + break; + case 'MIN': + result[field] = Math.min(...filteredData.map(row => parseFloat(row[aggField]))); + break; + case 'MAX': + result[field] = Math.max(...filteredData.map(row => parseFloat(row[aggField]))); + break; + // Additional aggregate functions can be handled here + } + } + }); + + return [result]; + // Add more cases here if needed for other aggregates + } else if (groupByFields) { + groupResults = applyGroupBy(filteredData, groupByFields, fields); + + // Order them by the specified fields + let orderedResults = groupResults; + if (orderByFields) { + orderedResults = groupResults.sort((a, b) => { + for (let { fieldName, order } of orderByFields) { + if (a[fieldName] < b[fieldName]) return order === 'ASC' ? -1 : 1; + if (a[fieldName] > b[fieldName]) return order === 'ASC' ? 1 : -1; + } + return 0; + }); + } + if (limit !== null) { + groupResults = groupResults.slice(0, limit); + } + return groupResults; + } else { + + // Order them by the specified fields + let orderedResults = groupResults; + if (orderByFields) { + orderedResults = groupResults.sort((a, b) => { + for (let { fieldName, order } of orderByFields) { + if (a[fieldName] < b[fieldName]) return order === 'ASC' ? -1 : 1; + if (a[fieldName] > b[fieldName]) return order === 'ASC' ? 1 : -1; + } + return 0; + }); + } + + // Select the specified fields + let finalResults = orderedResults.map(row => { + const selectedRow = {}; + fields.forEach(field => { + // Assuming 'field' is just the column name without table prefix + selectedRow[field] = row[field]; + }); + return selectedRow; + }); + + // Remove duplicates if specified + let distinctResults = finalResults; + if (isDistinct) { + distinctResults = [...new Map(finalResults.map(item => [fields.map(field => item[field]).join('|'), item])).values()]; + } + + let limitResults = distinctResults; + if (limit !== null) { + limitResults = distinctResults.slice(0, limit); + } + + return limitResults; + + + } + } catch (error) { + throw new Error(`Error executing query: ${error.message}`); + } +} + +async function executeINSERTQuery(query) { + console.log(parseInsertQuery(query)); + const { table, columns, values } = parseInsertQuery(query); + const data = await readCSV(`${table}.csv`); + + // Create a new row object + const newRow = {}; + columns.forEach((column, index) => { + // Remove single quotes from the values + let value = values[index]; + if (value.startsWith("'") && value.endsWith("'")) { + value = value.substring(1, value.length - 1); + } + newRow[column] = value; + }); + + // Add the new row to the data + data.push(newRow); + + // Save the updated data back to the CSV file + await writeCSV(`${table}.csv`, data); // Implement writeCSV function + + return { message: "Row inserted successfully." }; +} + +async function executeDELETEQuery(query) { + const { table, whereClauses } = parseDeleteQuery(query); + let data = await readCSV(`${table}.csv`); + + if (whereClauses.length > 0) { + // Filter out the rows that meet the where clause conditions + data = data.filter(row => !whereClauses.every(clause => evaluateCondition(row, clause))); + } else { + // If no where clause, clear the entire table + data = []; + } + + // Save the updated data back to the CSV file + await writeCSV(`${table}.csv`, data); + + return { message: "Rows deleted successfully." }; +} + + +module.exports = { executeSELECTQuery, executeINSERTQuery, executeDELETEQuery }; \ No newline at end of file diff --git a/src/queryParser.js b/src/queryParser.js new file mode 100644 index 000000000..67b94f5d0 --- /dev/null +++ b/src/queryParser.js @@ -0,0 +1,177 @@ +function parseSelectQuery(query) { + try { + + // Trim the query to remove any leading/trailing whitespaces + query = query.trim(); + + // Initialize distinct flag + let isDistinct = false; + + // Check for DISTINCT keyword and update the query + if (query.toUpperCase().includes('SELECT DISTINCT')) { + isDistinct = true; + query = query.replace('SELECT DISTINCT', 'SELECT'); + } + + // Updated regex to capture LIMIT clause and remove it for further processing + const limitRegex = /\sLIMIT\s(\d+)/i; + const limitMatch = query.match(limitRegex); + + let limit = null; + if (limitMatch) { + limit = parseInt(limitMatch[1], 10); + query = query.replace(limitRegex, ''); // Remove LIMIT clause + } + + // Process ORDER BY clause and remove it for further processing + const orderByRegex = /\sORDER BY\s(.+)/i; + const orderByMatch = query.match(orderByRegex); + let orderByFields = null; + if (orderByMatch) { + orderByFields = orderByMatch[1].split(',').map(field => { + const [fieldName, order] = field.trim().split(/\s+/); + return { fieldName, order: order ? order.toUpperCase() : 'ASC' }; + }); + query = query.replace(orderByRegex, ''); + } + + // Process GROUP BY clause and remove it for further processing + const groupByRegex = /\sGROUP BY\s(.+)/i; + const groupByMatch = query.match(groupByRegex); + let groupByFields = null; + if (groupByMatch) { + groupByFields = groupByMatch[1].split(',').map(field => field.trim()); + query = query.replace(groupByRegex, ''); + } + + // Process WHERE clause + const whereSplit = query.split(/\sWHERE\s/i); + const queryWithoutWhere = whereSplit[0]; // Everything before WHERE clause + const whereClause = whereSplit.length > 1 ? whereSplit[1].trim() : null; + + // Process JOIN clause + const joinSplit = queryWithoutWhere.split(/\s(INNER|LEFT|RIGHT) JOIN\s/i); + const selectPart = joinSplit[0].trim(); // Everything before JOIN clause + + // Extract JOIN information + const { joinType, joinTable, joinCondition } = parseJoinClause(queryWithoutWhere); + + // Parse SELECT part + const selectRegex = /^SELECT\s(.+?)\sFROM\s(.+)/i; + const selectMatch = selectPart.match(selectRegex); + if (!selectMatch) { + throw new Error('Invalid SELECT format'); + } + const [, fields, table] = selectMatch; + + // Parse WHERE part if it exists + let whereClauses = []; + if (whereClause) { + whereClauses = parseWhereClause(whereClause); + } + + // Check for aggregate functions without GROUP BY + const hasAggregateWithoutGroupBy = checkAggregateWithoutGroupBy(query, groupByFields); + + return { + fields: fields.split(',').map(field => field.trim()), + table: table.trim(), + whereClauses, + joinType, + joinTable, + joinCondition, + groupByFields, + orderByFields, + hasAggregateWithoutGroupBy, + limit, + isDistinct + }; + } catch (error) { + throw new Error(`Query parsing error: ${error.message}`); + } +} + +function checkAggregateWithoutGroupBy(query, groupByFields) { + const aggregateFunctionRegex = /(\bCOUNT\b|\bAVG\b|\bSUM\b|\bMIN\b|\bMAX\b)\s*\(\s*(\*|\w+)\s*\)/i; + return aggregateFunctionRegex.test(query) && !groupByFields; +} + +function parseWhereClause(whereString) { + const conditionRegex = /(.*?)(=|!=|>=|<=|>|<)(.*)/; + return whereString.split(/ AND | OR /i).map(conditionString => { + if (conditionString.includes(' LIKE ')) { + const [field, pattern] = conditionString.split(/\sLIKE\s/i); + return { field: field.trim(), operator: 'LIKE', value: pattern.trim().replace(/^'(.*)'$/, '$1') }; + } else { + const match = conditionString.match(conditionRegex); + if (match) { + const [, field, operator, value] = match; + return { field: field.trim(), operator, value: value.trim() }; + } + throw new Error('Invalid WHERE clause format'); + } + }); +} + +function parseJoinClause(query) { + const joinRegex = /\s(INNER|LEFT|RIGHT) JOIN\s(.+?)\sON\s([\w.]+)\s*=\s*([\w.]+)/i; + const joinMatch = query.match(joinRegex); + + if (joinMatch) { + return { + joinType: joinMatch[1].trim(), + joinTable: joinMatch[2].trim(), + joinCondition: { + left: joinMatch[3].trim(), + right: joinMatch[4].trim() + } + }; + } + + return { + joinType: null, + joinTable: null, + joinCondition: null + }; +} + +function parseInsertQuery(query) { + const insertRegex = /INSERT INTO (\w+)\s\((.+)\)\sVALUES\s\((.+)\)/i; + const match = query.match(insertRegex); + + if (!match) { + throw new Error("Invalid INSERT INTO syntax."); + } + + const [, table, columns, values] = match; + return { + type: 'INSERT', + table: table.trim(), + columns: columns.split(',').map(column => column.trim()), + values: values.split(',').map(value => value.trim()) + }; +} + +function parseDeleteQuery(query) { + const deleteRegex = /DELETE FROM (\w+)( WHERE (.*))?/i; + const match = query.match(deleteRegex); + + if (!match) { + throw new Error("Invalid DELETE syntax."); + } + + const [, table, , whereString] = match; + let whereClauses = []; + if (whereString) { + whereClauses = parseWhereClause(whereString); + } + + return { + type: 'DELETE', + table: table.trim(), + whereClauses + }; +} + + +module.exports = { parseSelectQuery, parseJoinClause, parseInsertQuery, parseDeleteQuery }; \ No newline at end of file diff --git a/student.csv b/student.csv new file mode 100644 index 000000000..e9c960121 --- /dev/null +++ b/student.csv @@ -0,0 +1,5 @@ +id,name,age +1,John,30 +2,Jane,25 +3,Bob,22 +4,Alice,24 \ No newline at end of file diff --git a/tests/step-02/index.test.js b/tests/step-02/index.test.js index a5467ee48..59a3322e8 100644 --- a/tests/step-02/index.test.js +++ b/tests/step-02/index.test.js @@ -1,9 +1,9 @@ -const readCSV = require('../../src/csvReader'); +const {readCSV} = require('../../src/csvReader'); test('Read CSV File', async () => { - const data = await readCSV('./sample.csv'); + const data = await readCSV('./student.csv'); expect(data.length).toBeGreaterThan(0); - expect(data.length).toBe(3); + expect(data.length).toBe(4); expect(data[0].name).toBe('John'); expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later }); \ No newline at end of file diff --git a/tests/step-03/index.test.js b/tests/step-03/index.test.js index 9145ad3e4..924e2e3c1 100644 --- a/tests/step-03/index.test.js +++ b/tests/step-03/index.test.js @@ -1,19 +1,29 @@ -const readCSV = require('../../src/csvReader'); -const parseQuery = require('../../src/queryParser'); + +const {readCSV} = require('../../src/csvReader'); +const {parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); test('Read CSV File', async () => { - const data = await readCSV('./sample.csv'); + const data = await readCSV('./student.csv'); expect(data.length).toBeGreaterThan(0); - expect(data.length).toBe(3); + expect(data.length).toBe(4); expect(data[0].name).toBe('John'); expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later }); test('Parse SQL Query', () => { - const query = 'SELECT id, name FROM sample'; - const parsed = parseQuery(query); + const query = 'SELECT id, name FROM student'; + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], - table: 'sample' + table: 'student', + whereClauses: [], + joinCondition: null, + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); \ No newline at end of file diff --git a/tests/step-04/index.test.js b/tests/step-04/index.test.js index bc353dd3d..51e8cfd7d 100644 --- a/tests/step-04/index.test.js +++ b/tests/step-04/index.test.js @@ -1,26 +1,35 @@ -const readCSV = require('../../src/csvReader'); -const parseQuery = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require('../../src/csvReader'); +const {executeSELECTQuery } = require('../../src/queryExecutor'); +const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); test('Read CSV File', async () => { - const data = await readCSV('./sample.csv'); + const data = await readCSV('./student.csv'); expect(data.length).toBeGreaterThan(0); - expect(data.length).toBe(3); + expect(data.length).toBe(4); expect(data[0].name).toBe('John'); expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later }); test('Parse SQL Query', () => { - const query = 'SELECT id, name FROM sample'; - const parsed = parseQuery(query); + const query = 'SELECT id, name FROM student'; + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], - table: 'sample' + table: 'student', + whereClauses: [], + joinCondition: null, + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Execute SQL Query', async () => { - const query = 'SELECT id, name FROM sample'; + const query = 'SELECT id, name FROM student'; const result = await executeSELECTQuery(query); expect(result.length).toBeGreaterThan(0); expect(result[0]).toHaveProperty('id'); diff --git a/tests/step-05/index.test.js b/tests/step-05/index.test.js index 66a77c061..8522a0db7 100644 --- a/tests/step-05/index.test.js +++ b/tests/step-05/index.test.js @@ -1,27 +1,35 @@ -const readCSV = require('../../src/csvReader'); -const parseQuery = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require('../../src/csvReader'); +const {executeSELECTQuery } = require('../../src/queryExecutor'); +const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); test('Read CSV File', async () => { - const data = await readCSV('./sample.csv'); + const data = await readCSV('./student.csv'); expect(data.length).toBeGreaterThan(0); - expect(data.length).toBe(3); + expect(data.length).toBe(4); expect(data[0].name).toBe('John'); expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later }); test('Parse SQL Query', () => { - const query = 'SELECT id, name FROM sample'; - const parsed = parseQuery(query); + const query = 'SELECT id, name FROM student'; + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], - table: 'sample', - whereClause: null + table: 'student', + whereClauses: [], + joinCondition: null, + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Execute SQL Query', async () => { - const query = 'SELECT id, name FROM sample'; + const query = 'SELECT id, name FROM student'; const result = await executeSELECTQuery(query); expect(result.length).toBeGreaterThan(0); expect(result[0]).toHaveProperty('id'); @@ -29,19 +37,29 @@ test('Execute SQL Query', async () => { expect(result[0]).not.toHaveProperty('age'); expect(result[0]).toEqual({ id: '1', name: 'John' }); }); - test('Parse SQL Query with WHERE Clause', () => { - const query = 'SELECT id, name FROM sample WHERE age = 25'; - const parsed = parseQuery(query); + const query = 'SELECT id, name FROM student WHERE age = 25'; + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], - table: 'sample', - whereClause: 'age = 25' + table: 'student', + whereClauses: [{ + "field": "age", + "operator": "=", + "value": "25", + }], + joinCondition: null, + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); - test('Execute SQL Query with WHERE Clause', async () => { - const query = 'SELECT id, name FROM sample WHERE age = 25'; + const query = 'SELECT id, name FROM student WHERE age = 25'; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); expect(result[0]).toHaveProperty('id'); diff --git a/tests/step-06/index.test.js b/tests/step-06/index.test.js index 2e2ef6416..fe79fabba 100644 --- a/tests/step-06/index.test.js +++ b/tests/step-06/index.test.js @@ -1,27 +1,35 @@ -const readCSV = require('../../src/csvReader'); -const parseQuery = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require('../../src/csvReader'); +const {executeSELECTQuery } = require('../../src/queryExecutor'); +const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); test('Read CSV File', async () => { - const data = await readCSV('./sample.csv'); + const data = await readCSV('./student.csv'); expect(data.length).toBeGreaterThan(0); - expect(data.length).toBe(3); + expect(data.length).toBe(4); expect(data[0].name).toBe('John'); expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later }); test('Parse SQL Query', () => { - const query = 'SELECT id, name FROM sample'; - const parsed = parseQuery(query); + const query = 'SELECT id, name FROM student'; + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], - table: 'sample', - whereClauses: [] + table: 'student', + whereClauses: [], + joinCondition: null, + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Execute SQL Query', async () => { - const query = 'SELECT id, name FROM sample'; + const query = 'SELECT id, name FROM student'; const result = await executeSELECTQuery(query); expect(result.length).toBeGreaterThan(0); expect(result[0]).toHaveProperty('id'); @@ -29,23 +37,29 @@ test('Execute SQL Query', async () => { expect(result[0]).not.toHaveProperty('age'); expect(result[0]).toEqual({ id: '1', name: 'John' }); }); - test('Parse SQL Query with WHERE Clause', () => { - const query = 'SELECT id, name FROM sample WHERE age = 25'; - const parsed = parseQuery(query); + const query = 'SELECT id, name FROM student WHERE age = 25'; + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], - table: 'sample', + table: 'student', whereClauses: [{ - field: "age", - operator: "=", - value: "25", + "field": "age", + "operator": "=", + "value": "25", }], + joinCondition: null, + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); - test('Execute SQL Query with WHERE Clause', async () => { - const query = 'SELECT id, name FROM sample WHERE age = 25'; + const query = 'SELECT id, name FROM student WHERE age = 25'; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); expect(result[0]).toHaveProperty('id'); @@ -54,11 +68,11 @@ test('Execute SQL Query with WHERE Clause', async () => { }); test('Parse SQL Query with Multiple WHERE Clauses', () => { - const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); + const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], - table: 'sample', + table: 'student', whereClauses: [{ "field": "age", "operator": "=", @@ -67,12 +81,20 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { "field": "name", "operator": "=", "value": "John", - }] + }], + joinCondition: null, + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Execute SQL Query with Multiple WHERE Clause', async () => { - const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John'; +test('Execute SQL Query with Complex WHERE Clause', async () => { + const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); expect(result[0]).toEqual({ id: '1', name: 'John' }); diff --git a/tests/step-07/index.test.js b/tests/step-07/index.test.js index ee0ebed5e..5faa49133 100644 --- a/tests/step-07/index.test.js +++ b/tests/step-07/index.test.js @@ -1,27 +1,35 @@ -const readCSV = require('../../src/csvReader'); -const parseQuery = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require('../../src/csvReader'); +const {executeSELECTQuery } = require('../../src/queryExecutor'); +const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); test('Read CSV File', async () => { - const data = await readCSV('./sample.csv'); + const data = await readCSV('./student.csv'); expect(data.length).toBeGreaterThan(0); - expect(data.length).toBe(3); + expect(data.length).toBe(4); expect(data[0].name).toBe('John'); expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later }); test('Parse SQL Query', () => { - const query = 'SELECT id, name FROM sample'; - const parsed = parseQuery(query); + const query = 'SELECT id, name FROM student'; + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], - table: 'sample', - whereClauses: [] + table: 'student', + whereClauses: [], + joinCondition: null, + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Execute SQL Query', async () => { - const query = 'SELECT id, name FROM sample'; + const query = 'SELECT id, name FROM student'; const result = await executeSELECTQuery(query); expect(result.length).toBeGreaterThan(0); expect(result[0]).toHaveProperty('id'); @@ -29,23 +37,29 @@ test('Execute SQL Query', async () => { expect(result[0]).not.toHaveProperty('age'); expect(result[0]).toEqual({ id: '1', name: 'John' }); }); - test('Parse SQL Query with WHERE Clause', () => { - const query = 'SELECT id, name FROM sample WHERE age = 25'; - const parsed = parseQuery(query); + const query = 'SELECT id, name FROM student WHERE age = 25'; + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], - table: 'sample', + table: 'student', whereClauses: [{ - field: "age", - operator: "=", - value: "25", + "field": "age", + "operator": "=", + "value": "25", }], + joinCondition: null, + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); - test('Execute SQL Query with WHERE Clause', async () => { - const query = 'SELECT id, name FROM sample WHERE age = 25'; + const query = 'SELECT id, name FROM student WHERE age = 25'; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); expect(result[0]).toHaveProperty('id'); @@ -54,11 +68,11 @@ test('Execute SQL Query with WHERE Clause', async () => { }); test('Parse SQL Query with Multiple WHERE Clauses', () => { - const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); + const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], - table: 'sample', + table: 'student', whereClauses: [{ "field": "age", "operator": "=", @@ -67,27 +81,34 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { "field": "name", "operator": "=", "value": "John", - }] + }], + joinCondition: null, + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Execute SQL Query with Multiple WHERE Clause', async () => { - const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John'; +test('Execute SQL Query with Complex WHERE Clause', async () => { + const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); expect(result[0]).toEqual({ id: '1', name: 'John' }); }); - test('Execute SQL Query with Greater Than', async () => { - const queryWithGT = 'SELECT id FROM sample WHERE age > 22'; + const queryWithGT = 'SELECT id FROM student WHERE age > 22'; const result = await executeSELECTQuery(queryWithGT); - expect(result.length).toEqual(2); + expect(result.length).toEqual(3); expect(result[0]).toHaveProperty('id'); }); test('Execute SQL Query with Not Equal to', async () => { - const queryWithGT = 'SELECT name FROM sample WHERE age != 25'; + const queryWithGT = 'SELECT name FROM student WHERE age != 25'; const result = await executeSELECTQuery(queryWithGT); - expect(result.length).toEqual(2); + expect(result.length).toEqual(3); expect(result[0]).toHaveProperty('name'); }); \ No newline at end of file diff --git a/tests/step-08/index.test.js b/tests/step-08/index.test.js index aab1467e6..93e1799b0 100644 --- a/tests/step-08/index.test.js +++ b/tests/step-08/index.test.js @@ -1,24 +1,30 @@ -const readCSV = require('../../src/csvReader'); -const parseQuery = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require('../../src/csvReader'); +const {executeSELECTQuery } = require('../../src/queryExecutor'); +const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); test('Read CSV File', async () => { const data = await readCSV('./student.csv'); expect(data.length).toBeGreaterThan(0); - expect(data.length).toBe(3); + expect(data.length).toBe(4); expect(data[0].name).toBe('John'); expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later }); test('Parse SQL Query', () => { const query = 'SELECT id, name FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', whereClauses: [], joinCondition: null, - joinTable: null + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); @@ -31,10 +37,9 @@ test('Execute SQL Query', async () => { expect(result[0]).not.toHaveProperty('age'); expect(result[0]).toEqual({ id: '1', name: 'John' }); }); - test('Parse SQL Query with WHERE Clause', () => { const query = 'SELECT id, name FROM student WHERE age = 25'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -44,10 +49,15 @@ test('Parse SQL Query with WHERE Clause', () => { "value": "25", }], joinCondition: null, - joinTable: null + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); - test('Execute SQL Query with WHERE Clause', async () => { const query = 'SELECT id, name FROM student WHERE age = 25'; const result = await executeSELECTQuery(query); @@ -59,7 +69,7 @@ test('Execute SQL Query with WHERE Clause', async () => { test('Parse SQL Query with Multiple WHERE Clauses', () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -73,7 +83,13 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { "value": "John", }], joinCondition: null, - joinTable: null + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); @@ -83,42 +99,53 @@ test('Execute SQL Query with Complex WHERE Clause', async () => { expect(result.length).toBe(1); expect(result[0]).toEqual({ id: '1', name: 'John' }); }); - test('Execute SQL Query with Greater Than', async () => { const queryWithGT = 'SELECT id FROM student WHERE age > 22'; const result = await executeSELECTQuery(queryWithGT); - expect(result.length).toEqual(2); + expect(result.length).toEqual(3); expect(result[0]).toHaveProperty('id'); }); test('Execute SQL Query with Not Equal to', async () => { const queryWithGT = 'SELECT name FROM student WHERE age != 25'; const result = await executeSELECTQuery(queryWithGT); - expect(result.length).toEqual(2); + expect(result.length).toEqual(3); expect(result[0]).toHaveProperty('name'); }); test('Parse SQL Query with INNER JOIN', async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', whereClauses: [], joinTable: 'enrollment', - joinCondition: { left: 'student.id', right: 'enrollment.student_id' } + joinType: "INNER", + joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }) }); test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', whereClauses: [{ field: 'student.age', operator: '>', value: '20' }], joinTable: 'enrollment', - joinCondition: { left: 'student.id', right: 'enrollment.student_id' } + joinType: "INNER", + joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }) }); diff --git a/tests/step-09/index.test.js b/tests/step-09/index.test.js index aaf711f5a..02e6cdb86 100644 --- a/tests/step-09/index.test.js +++ b/tests/step-09/index.test.js @@ -1,6 +1,6 @@ -const readCSV = require('../../src/csvReader'); -const {parseQuery} = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require('../../src/csvReader'); +const {executeSELECTQuery } = require('../../src/queryExecutor'); +const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); test('Read CSV File', async () => { const data = await readCSV('./student.csv'); @@ -12,14 +12,19 @@ test('Read CSV File', async () => { test('Parse SQL Query', () => { const query = 'SELECT id, name FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', whereClauses: [], joinCondition: null, joinTable: null, - joinType: null + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); @@ -32,10 +37,9 @@ test('Execute SQL Query', async () => { expect(result[0]).not.toHaveProperty('age'); expect(result[0]).toEqual({ id: '1', name: 'John' }); }); - test('Parse SQL Query with WHERE Clause', () => { const query = 'SELECT id, name FROM student WHERE age = 25'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -46,10 +50,14 @@ test('Parse SQL Query with WHERE Clause', () => { }], joinCondition: null, joinTable: null, - joinType: null + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); - test('Execute SQL Query with WHERE Clause', async () => { const query = 'SELECT id, name FROM student WHERE age = 25'; const result = await executeSELECTQuery(query); @@ -61,7 +69,7 @@ test('Execute SQL Query with WHERE Clause', async () => { test('Parse SQL Query with Multiple WHERE Clauses', () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -76,7 +84,12 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { }], joinCondition: null, joinTable: null, - joinType: null + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); @@ -86,7 +99,6 @@ test('Execute SQL Query with Complex WHERE Clause', async () => { expect(result.length).toBe(1); expect(result[0]).toEqual({ id: '1', name: 'John' }); }); - test('Execute SQL Query with Greater Than', async () => { const queryWithGT = 'SELECT id FROM student WHERE age > 22'; const result = await executeSELECTQuery(queryWithGT); @@ -103,27 +115,37 @@ test('Execute SQL Query with Not Equal to', async () => { test('Parse SQL Query with INNER JOIN', async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', whereClauses: [], joinTable: 'enrollment', + joinType: "INNER", joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, - joinType: 'INNER' + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }) }); test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', whereClauses: [{ field: 'student.age', operator: '>', value: '20' }], joinTable: 'enrollment', + joinType: "INNER", joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, - joinType: 'INNER' + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }) }); diff --git a/tests/step-10/index.test.js b/tests/step-10/index.test.js index 5e118eda5..2b9ef2e73 100644 --- a/tests/step-10/index.test.js +++ b/tests/step-10/index.test.js @@ -1,6 +1,6 @@ -const readCSV = require('../../src/csvReader'); -const {parseQuery, parseJoinClause} = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require('../../src/csvReader'); +const {executeSELECTQuery } = require('../../src/queryExecutor'); +const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); test('Read CSV File', async () => { const data = await readCSV('./student.csv'); @@ -258,7 +258,7 @@ test('Average age of students above a certain age', async () => { test('Parse SQL Query', () => { const query = 'SELECT id, name FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -268,12 +268,15 @@ test('Parse SQL Query', () => { joinType: null, groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with WHERE Clause', () => { const query = 'SELECT id, name FROM student WHERE age = 25'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -287,12 +290,15 @@ test('Parse SQL Query with WHERE Clause', () => { joinType: null, groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with Multiple WHERE Clauses', () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -310,12 +316,15 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { joinType: null, groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with INNER JOIN', async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -325,12 +334,15 @@ test('Parse SQL Query with INNER JOIN', async () => { joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }) }); test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -340,6 +352,9 @@ test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }) }); @@ -387,7 +402,7 @@ test('Returns null for queries without JOIN', () => { test('Parse LEFT Join Query Completely', () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -397,12 +412,15 @@ test('Parse LEFT Join Query Completely', () => { joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }) }) test('Parse LEFT Join Query Completely', () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -412,12 +430,15 @@ test('Parse LEFT Join Query Completely', () => { joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }) }) test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -427,12 +448,15 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl "whereClauses": [{ "field": "student.age", "operator": ">", "value": "22" }], groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -442,12 +466,15 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Physics'" }], groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -457,12 +484,15 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab "whereClauses": [{ "field": "student.age", "operator": "<", "value": "25" }], groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -472,13 +502,16 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Chemistry'" }], groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse COUNT Aggregate Query', () => { const query = 'SELECT COUNT(*) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['COUNT(*)'], table: 'student', @@ -488,13 +521,16 @@ test('Parse COUNT Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse SUM Aggregate Query', () => { const query = 'SELECT SUM(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['SUM(age)'], table: 'student', @@ -504,12 +540,15 @@ test('Parse SUM Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse AVG Aggregate Query', () => { const query = 'SELECT AVG(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['AVG(age)'], table: 'student', @@ -519,12 +558,15 @@ test('Parse AVG Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse MIN Aggregate Query', () => { const query = 'SELECT MIN(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MIN(age)'], table: 'student', @@ -534,12 +576,15 @@ test('Parse MIN Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse MAX Aggregate Query', () => { const query = 'SELECT MAX(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MAX(age)'], table: 'student', @@ -549,12 +594,15 @@ test('Parse MAX Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse basic GROUP BY query', () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -563,13 +611,16 @@ test('Parse basic GROUP BY query', () => { joinType: null, joinTable: null, joinCondition: null, - hasAggregateWithoutGroupBy: false + hasAggregateWithoutGroupBy: false, + orderByFields: null, + "limit": null, + isDistinct: false }); }); test('Parse GROUP BY query with WHERE clause', () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -578,13 +629,16 @@ test('Parse GROUP BY query with WHERE clause', () => { joinType: null, joinTable: null, joinCondition: null, - hasAggregateWithoutGroupBy: false + hasAggregateWithoutGroupBy: false, + orderByFields: null, + "limit": null, + isDistinct: false }); }); test('Parse GROUP BY query with multiple fields', () => { const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student_id', 'course', 'COUNT(*)'], table: 'enrollment', @@ -593,13 +647,16 @@ test('Parse GROUP BY query with multiple fields', () => { joinType: null, joinTable: null, joinCondition: null, - hasAggregateWithoutGroupBy: false + hasAggregateWithoutGroupBy: false, + orderByFields: null, + "limit": null, + isDistinct: false }); }); test('Parse GROUP BY query with JOIN and WHERE clauses', () => { const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student.name', 'COUNT(*)'], table: 'student', @@ -611,6 +668,9 @@ test('Parse GROUP BY query with JOIN and WHERE clauses', () => { left: 'student.id', right: 'enrollment.student_id' }, - hasAggregateWithoutGroupBy: false + hasAggregateWithoutGroupBy: false, + orderByFields: null, + "limit": null, + isDistinct: false, }); }); \ No newline at end of file diff --git a/tests/step-11/index.test.js b/tests/step-11/index.test.js index 1cf5f2def..68f672e72 100644 --- a/tests/step-11/index.test.js +++ b/tests/step-11/index.test.js @@ -1,6 +1,6 @@ -const readCSV = require('../../src/csvReader'); -const {parseQuery, parseJoinClause} = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require('../../src/csvReader'); +const {executeSELECTQuery } = require('../../src/queryExecutor'); +const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); test('Read CSV File', async () => { const data = await readCSV('./student.csv'); @@ -258,7 +258,7 @@ test('Average age of students above a certain age', async () => { test('Parse SQL Query', () => { const query = 'SELECT id, name FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -268,13 +268,15 @@ test('Parse SQL Query', () => { joinType: null, groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with WHERE Clause', () => { const query = 'SELECT id, name FROM student WHERE age = 25'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -288,13 +290,15 @@ test('Parse SQL Query with WHERE Clause', () => { joinType: null, groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with Multiple WHERE Clauses', () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -312,13 +316,15 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { joinType: null, groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with INNER JOIN', async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -328,13 +334,15 @@ test('Parse SQL Query with INNER JOIN', async () => { joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }) }); test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -344,7 +352,9 @@ test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }) }); @@ -392,7 +402,7 @@ test('Returns null for queries without JOIN', () => { test('Parse LEFT Join Query Completely', () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -402,13 +412,15 @@ test('Parse LEFT Join Query Completely', () => { joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }) }) test('Parse LEFT Join Query Completely', () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -418,13 +430,15 @@ test('Parse LEFT Join Query Completely', () => { joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }) }) test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -434,13 +448,15 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl "whereClauses": [{ "field": "student.age", "operator": ">", "value": "22" }], groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -450,13 +466,15 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Physics'" }], groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -466,13 +484,15 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab "whereClauses": [{ "field": "student.age", "operator": "<", "value": "25" }], groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -482,14 +502,16 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Chemistry'" }], groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse COUNT Aggregate Query', () => { const query = 'SELECT COUNT(*) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['COUNT(*)'], table: 'student', @@ -499,14 +521,16 @@ test('Parse COUNT Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse SUM Aggregate Query', () => { const query = 'SELECT SUM(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['SUM(age)'], table: 'student', @@ -516,13 +540,15 @@ test('Parse SUM Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse AVG Aggregate Query', () => { const query = 'SELECT AVG(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['AVG(age)'], table: 'student', @@ -532,13 +558,15 @@ test('Parse AVG Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse MIN Aggregate Query', () => { const query = 'SELECT MIN(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MIN(age)'], table: 'student', @@ -548,13 +576,15 @@ test('Parse MIN Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse MAX Aggregate Query', () => { const query = 'SELECT MAX(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MAX(age)'], table: 'student', @@ -564,13 +594,15 @@ test('Parse MAX Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); test('Parse basic GROUP BY query', () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -580,13 +612,15 @@ test('Parse basic GROUP BY query', () => { joinTable: null, joinCondition: null, hasAggregateWithoutGroupBy: false, - orderByFields: null + orderByFields: null, + "limit": null, + isDistinct: false }); }); test('Parse GROUP BY query with WHERE clause', () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -596,13 +630,15 @@ test('Parse GROUP BY query with WHERE clause', () => { joinTable: null, joinCondition: null, hasAggregateWithoutGroupBy: false, - orderByFields: null + orderByFields: null, + "limit": null, + isDistinct: false }); }); test('Parse GROUP BY query with multiple fields', () => { const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student_id', 'course', 'COUNT(*)'], table: 'enrollment', @@ -612,13 +648,15 @@ test('Parse GROUP BY query with multiple fields', () => { joinTable: null, joinCondition: null, hasAggregateWithoutGroupBy: false, - orderByFields: null + orderByFields: null, + "limit": null, + isDistinct: false }); }); test('Parse GROUP BY query with JOIN and WHERE clauses', () => { const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student.name', 'COUNT(*)'], table: 'student', @@ -631,7 +669,9 @@ test('Parse GROUP BY query with JOIN and WHERE clauses', () => { right: 'enrollment.student_id' }, hasAggregateWithoutGroupBy: false, - orderByFields: null + orderByFields: null, + "limit": null, + isDistinct: false, }); }); diff --git a/tests/step-12/index.test.js b/tests/step-12/index.test.js index d15c77ef5..d6a7a6913 100644 --- a/tests/step-12/index.test.js +++ b/tests/step-12/index.test.js @@ -1,6 +1,6 @@ -const readCSV = require('../../src/csvReader'); -const {parseQuery, parseJoinClause} = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require('../../src/csvReader'); +const {executeSELECTQuery } = require('../../src/queryExecutor'); +const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); test('Read CSV File', async () => { const data = await readCSV('./student.csv'); @@ -258,7 +258,7 @@ test('Average age of students above a certain age', async () => { test('Parse SQL Query', () => { const query = 'SELECT id, name FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -269,13 +269,14 @@ test('Parse SQL Query', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with WHERE Clause', () => { const query = 'SELECT id, name FROM student WHERE age = 25'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -290,13 +291,14 @@ test('Parse SQL Query with WHERE Clause', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with Multiple WHERE Clauses', () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -315,13 +317,14 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with INNER JOIN', async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -332,13 +335,14 @@ test('Parse SQL Query with INNER JOIN', async () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }) }); test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -349,7 +353,8 @@ test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }) }); @@ -397,7 +402,7 @@ test('Returns null for queries without JOIN', () => { test('Parse LEFT Join Query Completely', () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -408,13 +413,14 @@ test('Parse LEFT Join Query Completely', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }) }) test('Parse LEFT Join Query Completely', () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -425,13 +431,14 @@ test('Parse LEFT Join Query Completely', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }) }) test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -442,13 +449,14 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -459,13 +467,14 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -476,13 +485,14 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -493,14 +503,15 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse COUNT Aggregate Query', () => { const query = 'SELECT COUNT(*) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['COUNT(*)'], table: 'student', @@ -511,14 +522,15 @@ test('Parse COUNT Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse SUM Aggregate Query', () => { const query = 'SELECT SUM(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['SUM(age)'], table: 'student', @@ -529,13 +541,14 @@ test('Parse SUM Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse AVG Aggregate Query', () => { const query = 'SELECT AVG(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['AVG(age)'], table: 'student', @@ -546,13 +559,14 @@ test('Parse AVG Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse MIN Aggregate Query', () => { const query = 'SELECT MIN(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MIN(age)'], table: 'student', @@ -563,13 +577,14 @@ test('Parse MIN Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse MAX Aggregate Query', () => { const query = 'SELECT MAX(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MAX(age)'], table: 'student', @@ -580,13 +595,14 @@ test('Parse MAX Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse basic GROUP BY query', () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -597,13 +613,14 @@ test('Parse basic GROUP BY query', () => { joinCondition: null, hasAggregateWithoutGroupBy: false, orderByFields: null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse GROUP BY query with WHERE clause', () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -614,13 +631,14 @@ test('Parse GROUP BY query with WHERE clause', () => { joinCondition: null, hasAggregateWithoutGroupBy: false, orderByFields: null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse GROUP BY query with multiple fields', () => { const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student_id', 'course', 'COUNT(*)'], table: 'enrollment', @@ -631,13 +649,14 @@ test('Parse GROUP BY query with multiple fields', () => { joinCondition: null, hasAggregateWithoutGroupBy: false, orderByFields: null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse GROUP BY query with JOIN and WHERE clauses', () => { const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student.name', 'COUNT(*)'], table: 'student', @@ -652,6 +671,7 @@ test('Parse GROUP BY query with JOIN and WHERE clauses', () => { hasAggregateWithoutGroupBy: false, orderByFields: null, "limit": null, + isDistinct: false, }); }); diff --git a/tests/step-13/index.test.js b/tests/step-13/index.test.js index 0797faaba..5fe667f4c 100644 --- a/tests/step-13/index.test.js +++ b/tests/step-13/index.test.js @@ -1,6 +1,6 @@ -const readCSV = require('../../src/csvReader'); -const {parseQuery, parseJoinClause} = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require('../../src/csvReader'); +const {executeSELECTQuery } = require('../../src/queryExecutor'); +const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); test('Read CSV File', async () => { const data = await readCSV('./student.csv'); @@ -258,7 +258,7 @@ test('Average age of students above a certain age', async () => { test('Parse SQL Query', () => { const query = 'SELECT id, name FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -269,13 +269,14 @@ test('Parse SQL Query', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with WHERE Clause', () => { const query = 'SELECT id, name FROM student WHERE age = 25'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -290,13 +291,14 @@ test('Parse SQL Query with WHERE Clause', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with Multiple WHERE Clauses', () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -315,13 +317,14 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with INNER JOIN', async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -332,13 +335,14 @@ test('Parse SQL Query with INNER JOIN', async () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }) }); test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -349,7 +353,8 @@ test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }) }); @@ -397,7 +402,7 @@ test('Returns null for queries without JOIN', () => { test('Parse LEFT Join Query Completely', () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -408,13 +413,14 @@ test('Parse LEFT Join Query Completely', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }) }) test('Parse LEFT Join Query Completely', () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -425,13 +431,14 @@ test('Parse LEFT Join Query Completely', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }) }) test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -442,13 +449,14 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -459,13 +467,14 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -476,13 +485,14 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -493,14 +503,15 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse COUNT Aggregate Query', () => { const query = 'SELECT COUNT(*) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['COUNT(*)'], table: 'student', @@ -511,14 +522,15 @@ test('Parse COUNT Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse SUM Aggregate Query', () => { const query = 'SELECT SUM(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['SUM(age)'], table: 'student', @@ -529,13 +541,14 @@ test('Parse SUM Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse AVG Aggregate Query', () => { const query = 'SELECT AVG(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['AVG(age)'], table: 'student', @@ -546,13 +559,14 @@ test('Parse AVG Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse MIN Aggregate Query', () => { const query = 'SELECT MIN(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MIN(age)'], table: 'student', @@ -563,13 +577,14 @@ test('Parse MIN Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse MAX Aggregate Query', () => { const query = 'SELECT MAX(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MAX(age)'], table: 'student', @@ -580,13 +595,14 @@ test('Parse MAX Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse basic GROUP BY query', () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -597,13 +613,14 @@ test('Parse basic GROUP BY query', () => { joinCondition: null, hasAggregateWithoutGroupBy: false, orderByFields: null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse GROUP BY query with WHERE clause', () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -614,13 +631,14 @@ test('Parse GROUP BY query with WHERE clause', () => { joinCondition: null, hasAggregateWithoutGroupBy: false, orderByFields: null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse GROUP BY query with multiple fields', () => { const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student_id', 'course', 'COUNT(*)'], table: 'enrollment', @@ -631,13 +649,14 @@ test('Parse GROUP BY query with multiple fields', () => { joinCondition: null, hasAggregateWithoutGroupBy: false, orderByFields: null, - "limit": null + "limit": null, + isDistinct: false }); }); test('Parse GROUP BY query with JOIN and WHERE clauses', () => { const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student.name', 'COUNT(*)'], table: 'student', @@ -652,6 +671,7 @@ test('Parse GROUP BY query with JOIN and WHERE clauses', () => { hasAggregateWithoutGroupBy: false, orderByFields: null, "limit": null, + isDistinct: false, }); }); diff --git a/tests/step-14/index.test.js b/tests/step-14/index.test.js index 502411fa7..0bc0e0607 100644 --- a/tests/step-14/index.test.js +++ b/tests/step-14/index.test.js @@ -1,6 +1,6 @@ -const readCSV = require('../../src/csvReader'); -const {parseQuery, parseJoinClause} = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require('../../src/csvReader'); +const {executeSELECTQuery } = require('../../src/queryExecutor'); +const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); test('Read CSV File', async () => { const data = await readCSV('./student.csv'); @@ -258,7 +258,7 @@ test('Average age of students above a certain age', async () => { test('Parse SQL Query', () => { const query = 'SELECT id, name FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -276,7 +276,7 @@ test('Parse SQL Query', () => { test('Parse SQL Query with WHERE Clause', () => { const query = 'SELECT id, name FROM student WHERE age = 25'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -298,7 +298,7 @@ test('Parse SQL Query with WHERE Clause', () => { test('Parse SQL Query with Multiple WHERE Clauses', () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -324,7 +324,7 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { test('Parse SQL Query with INNER JOIN', async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -342,7 +342,7 @@ test('Parse SQL Query with INNER JOIN', async () => { test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -402,7 +402,7 @@ test('Returns null for queries without JOIN', () => { test('Parse LEFT Join Query Completely', () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -420,7 +420,7 @@ test('Parse LEFT Join Query Completely', () => { test('Parse LEFT Join Query Completely', () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -438,7 +438,7 @@ test('Parse LEFT Join Query Completely', () => { test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -456,7 +456,7 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -474,7 +474,7 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -492,7 +492,7 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -511,7 +511,7 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab test('Parse COUNT Aggregate Query', () => { const query = 'SELECT COUNT(*) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['COUNT(*)'], table: 'student', @@ -530,7 +530,7 @@ test('Parse COUNT Aggregate Query', () => { test('Parse SUM Aggregate Query', () => { const query = 'SELECT SUM(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['SUM(age)'], table: 'student', @@ -548,7 +548,7 @@ test('Parse SUM Aggregate Query', () => { test('Parse AVG Aggregate Query', () => { const query = 'SELECT AVG(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['AVG(age)'], table: 'student', @@ -566,7 +566,7 @@ test('Parse AVG Aggregate Query', () => { test('Parse MIN Aggregate Query', () => { const query = 'SELECT MIN(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MIN(age)'], table: 'student', @@ -584,7 +584,7 @@ test('Parse MIN Aggregate Query', () => { test('Parse MAX Aggregate Query', () => { const query = 'SELECT MAX(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MAX(age)'], table: 'student', @@ -602,7 +602,7 @@ test('Parse MAX Aggregate Query', () => { test('Parse basic GROUP BY query', () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -620,7 +620,7 @@ test('Parse basic GROUP BY query', () => { test('Parse GROUP BY query with WHERE clause', () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -638,7 +638,7 @@ test('Parse GROUP BY query with WHERE clause', () => { test('Parse GROUP BY query with multiple fields', () => { const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student_id', 'course', 'COUNT(*)'], table: 'enrollment', @@ -656,7 +656,7 @@ test('Parse GROUP BY query with multiple fields', () => { test('Parse GROUP BY query with JOIN and WHERE clauses', () => { const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student.name', 'COUNT(*)'], table: 'student', diff --git a/tests/step-15/index.test.js b/tests/step-15/index.test.js index a2aa4daee..dc1fa19ae 100644 --- a/tests/step-15/index.test.js +++ b/tests/step-15/index.test.js @@ -1,6 +1,6 @@ -const readCSV = require('../../src/csvReader'); -const {parseQuery, parseJoinClause} = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require('../../src/csvReader'); +const {executeSELECTQuery } = require('../../src/queryExecutor'); +const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); test('Read CSV File', async () => { const data = await readCSV('./student.csv'); @@ -258,7 +258,7 @@ test('Average age of students above a certain age', async () => { test('Parse SQL Query', () => { const query = 'SELECT id, name FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -276,7 +276,7 @@ test('Parse SQL Query', () => { test('Parse SQL Query with WHERE Clause', () => { const query = 'SELECT id, name FROM student WHERE age = 25'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -298,7 +298,7 @@ test('Parse SQL Query with WHERE Clause', () => { test('Parse SQL Query with Multiple WHERE Clauses', () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -324,7 +324,7 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { test('Parse SQL Query with INNER JOIN', async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -342,7 +342,7 @@ test('Parse SQL Query with INNER JOIN', async () => { test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -402,7 +402,7 @@ test('Returns null for queries without JOIN', () => { test('Parse LEFT Join Query Completely', () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -420,7 +420,7 @@ test('Parse LEFT Join Query Completely', () => { test('Parse LEFT Join Query Completely', () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -438,7 +438,7 @@ test('Parse LEFT Join Query Completely', () => { test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -456,7 +456,7 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -474,7 +474,7 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -492,7 +492,7 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -511,7 +511,7 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab test('Parse COUNT Aggregate Query', () => { const query = 'SELECT COUNT(*) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['COUNT(*)'], table: 'student', @@ -530,7 +530,7 @@ test('Parse COUNT Aggregate Query', () => { test('Parse SUM Aggregate Query', () => { const query = 'SELECT SUM(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['SUM(age)'], table: 'student', @@ -548,7 +548,7 @@ test('Parse SUM Aggregate Query', () => { test('Parse AVG Aggregate Query', () => { const query = 'SELECT AVG(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['AVG(age)'], table: 'student', @@ -566,7 +566,7 @@ test('Parse AVG Aggregate Query', () => { test('Parse MIN Aggregate Query', () => { const query = 'SELECT MIN(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MIN(age)'], table: 'student', @@ -584,7 +584,7 @@ test('Parse MIN Aggregate Query', () => { test('Parse MAX Aggregate Query', () => { const query = 'SELECT MAX(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MAX(age)'], table: 'student', @@ -602,7 +602,7 @@ test('Parse MAX Aggregate Query', () => { test('Parse basic GROUP BY query', () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -620,7 +620,7 @@ test('Parse basic GROUP BY query', () => { test('Parse GROUP BY query with WHERE clause', () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -638,7 +638,7 @@ test('Parse GROUP BY query with WHERE clause', () => { test('Parse GROUP BY query with multiple fields', () => { const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student_id', 'course', 'COUNT(*)'], table: 'enrollment', @@ -656,7 +656,7 @@ test('Parse GROUP BY query with multiple fields', () => { test('Parse GROUP BY query with JOIN and WHERE clauses', () => { const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student.name', 'COUNT(*)'], table: 'student', diff --git a/tests/step-16/index.test.js b/tests/step-16/index.test.js index a2aa4daee..dc1fa19ae 100644 --- a/tests/step-16/index.test.js +++ b/tests/step-16/index.test.js @@ -1,6 +1,6 @@ -const readCSV = require('../../src/csvReader'); -const {parseQuery, parseJoinClause} = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require('../../src/csvReader'); +const {executeSELECTQuery } = require('../../src/queryExecutor'); +const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); test('Read CSV File', async () => { const data = await readCSV('./student.csv'); @@ -258,7 +258,7 @@ test('Average age of students above a certain age', async () => { test('Parse SQL Query', () => { const query = 'SELECT id, name FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -276,7 +276,7 @@ test('Parse SQL Query', () => { test('Parse SQL Query with WHERE Clause', () => { const query = 'SELECT id, name FROM student WHERE age = 25'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -298,7 +298,7 @@ test('Parse SQL Query with WHERE Clause', () => { test('Parse SQL Query with Multiple WHERE Clauses', () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -324,7 +324,7 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { test('Parse SQL Query with INNER JOIN', async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -342,7 +342,7 @@ test('Parse SQL Query with INNER JOIN', async () => { test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -402,7 +402,7 @@ test('Returns null for queries without JOIN', () => { test('Parse LEFT Join Query Completely', () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -420,7 +420,7 @@ test('Parse LEFT Join Query Completely', () => { test('Parse LEFT Join Query Completely', () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -438,7 +438,7 @@ test('Parse LEFT Join Query Completely', () => { test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -456,7 +456,7 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -474,7 +474,7 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -492,7 +492,7 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -511,7 +511,7 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab test('Parse COUNT Aggregate Query', () => { const query = 'SELECT COUNT(*) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['COUNT(*)'], table: 'student', @@ -530,7 +530,7 @@ test('Parse COUNT Aggregate Query', () => { test('Parse SUM Aggregate Query', () => { const query = 'SELECT SUM(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['SUM(age)'], table: 'student', @@ -548,7 +548,7 @@ test('Parse SUM Aggregate Query', () => { test('Parse AVG Aggregate Query', () => { const query = 'SELECT AVG(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['AVG(age)'], table: 'student', @@ -566,7 +566,7 @@ test('Parse AVG Aggregate Query', () => { test('Parse MIN Aggregate Query', () => { const query = 'SELECT MIN(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MIN(age)'], table: 'student', @@ -584,7 +584,7 @@ test('Parse MIN Aggregate Query', () => { test('Parse MAX Aggregate Query', () => { const query = 'SELECT MAX(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MAX(age)'], table: 'student', @@ -602,7 +602,7 @@ test('Parse MAX Aggregate Query', () => { test('Parse basic GROUP BY query', () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -620,7 +620,7 @@ test('Parse basic GROUP BY query', () => { test('Parse GROUP BY query with WHERE clause', () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -638,7 +638,7 @@ test('Parse GROUP BY query with WHERE clause', () => { test('Parse GROUP BY query with multiple fields', () => { const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student_id', 'course', 'COUNT(*)'], table: 'enrollment', @@ -656,7 +656,7 @@ test('Parse GROUP BY query with multiple fields', () => { test('Parse GROUP BY query with JOIN and WHERE clauses', () => { const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student.name', 'COUNT(*)'], table: 'student', diff --git a/tests/step-17/index.test.js b/tests/step-17/index.test.js index c99d01fbb..dc1fa19ae 100644 --- a/tests/step-17/index.test.js +++ b/tests/step-17/index.test.js @@ -1,5 +1,5 @@ const {readCSV} = require('../../src/csvReader'); -const {executeSELECTQuery } = require('../../src/index'); +const {executeSELECTQuery } = require('../../src/queryExecutor'); const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); test('Read CSV File', async () => { diff --git a/tests/step-17/insertExecuter.test.js b/tests/step-17/insertExecuter.test.js index 8c405f727..9154b0e2e 100644 --- a/tests/step-17/insertExecuter.test.js +++ b/tests/step-17/insertExecuter.test.js @@ -1,4 +1,4 @@ -const { executeINSERTQuery } = require('../../src/index'); +const { executeINSERTQuery } = require('../../src/queryExecutor'); const { readCSV, writeCSV } = require('../../src/csvReader'); const fs = require('fs'); @@ -9,6 +9,7 @@ async function createGradesCSV() { { student_id: '2', course: 'Chemistry', grade: 'B' }, { student_id: '3', course: 'Mathematics', grade: 'C' } ]; + fs.writeFileSync('grades.csv', ''); await writeCSV('grades.csv', initialData); } diff --git a/tests/step-18/deleteExecutor.test.js b/tests/step-18/deleteExecutor.test.js index 11ae617b7..636403858 100644 --- a/tests/step-18/deleteExecutor.test.js +++ b/tests/step-18/deleteExecutor.test.js @@ -1,4 +1,4 @@ -const { executeDELETEQuery } = require('../../src/index'); +const { executeDELETEQuery } = require('../../src/queryExecutor'); const { readCSV, writeCSV } = require('../../src/csvReader'); const fs = require('fs'); diff --git a/tests/step-18/index.test.js b/tests/step-18/index.test.js index c99d01fbb..dc1fa19ae 100644 --- a/tests/step-18/index.test.js +++ b/tests/step-18/index.test.js @@ -1,5 +1,5 @@ const {readCSV} = require('../../src/csvReader'); -const {executeSELECTQuery } = require('../../src/index'); +const {executeSELECTQuery } = require('../../src/queryExecutor'); const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); test('Read CSV File', async () => { diff --git a/tests/step-18/insertExecuter.test.js b/tests/step-18/insertExecuter.test.js index 8c405f727..f9ff4fdf9 100644 --- a/tests/step-18/insertExecuter.test.js +++ b/tests/step-18/insertExecuter.test.js @@ -1,4 +1,4 @@ -const { executeINSERTQuery } = require('../../src/index'); +const { executeINSERTQuery } = require('../../src/queryExecutor'); const { readCSV, writeCSV } = require('../../src/csvReader'); const fs = require('fs'); @@ -12,22 +12,28 @@ async function createGradesCSV() { await writeCSV('grades.csv', initialData); } -// Test to INSERT a new grade and verify -test('Execute INSERT INTO Query for grades.csv', async () => { - // Create grades.csv with initial data - await createGradesCSV(); +// Define the test suite +describe('Insert Executer Tests', () => { + // This is the beforeEach hook + beforeEach(async () => { + // Create grades.csv with initial data before each test + await createGradesCSV(); + }); - // Execute INSERT statement - const insertQuery = "INSERT INTO grades (student_id, course, grade) VALUES ('4', 'Physics', 'A')"; - await executeINSERTQuery(insertQuery); + // Test to INSERT a new grade and verify + test('Execute INSERT INTO Query for grades.csv', async () => { + // Execute INSERT statement + const insertQuery = "INSERT INTO grades (student_id, course, grade) VALUES ('4', 'Physics', 'A')"; + await executeINSERTQuery(insertQuery); - // Verify the new entry - const updatedData = await readCSV('grades.csv'); - const newEntry = updatedData.find(row => row.student_id === '4' && row.course === 'Physics'); - console.log(updatedData) - expect(newEntry).toBeDefined(); - expect(newEntry.grade).toEqual('A'); + // Verify the new entry + const updatedData = await readCSV('grades.csv'); + const newEntry = updatedData.find(row => row.student_id === '4' && row.course === 'Physics'); + console.log(updatedData) + expect(newEntry).toBeDefined(); + expect(newEntry.grade).toEqual('A'); - // Cleanup: Delete grades.csv - fs.unlinkSync('grades.csv'); -}); \ No newline at end of file + // Cleanup: Delete grades.csv + fs.unlinkSync('grades.csv'); + }); +}); diff --git a/tests/step-19/deleteExecutor.test.js b/tests/step-19/deleteExecutor.test.js index 11ae617b7..636403858 100644 --- a/tests/step-19/deleteExecutor.test.js +++ b/tests/step-19/deleteExecutor.test.js @@ -1,4 +1,4 @@ -const { executeDELETEQuery } = require('../../src/index'); +const { executeDELETEQuery } = require('../../src/queryExecutor'); const { readCSV, writeCSV } = require('../../src/csvReader'); const fs = require('fs'); diff --git a/tests/step-19/index.test.js b/tests/step-19/index.test.js index c99d01fbb..dc1fa19ae 100644 --- a/tests/step-19/index.test.js +++ b/tests/step-19/index.test.js @@ -1,5 +1,5 @@ const {readCSV} = require('../../src/csvReader'); -const {executeSELECTQuery } = require('../../src/index'); +const {executeSELECTQuery } = require('../../src/queryExecutor'); const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); test('Read CSV File', async () => { diff --git a/tests/step-19/insertExecuter.test.js b/tests/step-19/insertExecuter.test.js index 8c405f727..95453731b 100644 --- a/tests/step-19/insertExecuter.test.js +++ b/tests/step-19/insertExecuter.test.js @@ -1,33 +1,72 @@ -const { executeINSERTQuery } = require('../../src/index'); +const { executeINSERTQuery } = require('../../src/queryExecutor'); const { readCSV, writeCSV } = require('../../src/csvReader'); const fs = require('fs'); -// Helper function to create grades.csv with initial data + async function createGradesCSV() { - const initialData = [ - { student_id: '1', course: 'Mathematics', grade: 'A' }, - { student_id: '2', course: 'Chemistry', grade: 'B' }, - { student_id: '3', course: 'Mathematics', grade: 'C' } - ]; - await writeCSV('grades.csv', initialData); + + const initialData = [ + + { student_id: "1", course: "Mathematics", grade: "A" }, + + { student_id: "2", course: "Chemistry", grade: "B" }, + + { student_id: "3", course: "Mathematics", grade: "C" }, + + ]; + + await writeCSV("grades.csv", initialData); + } + + + // Test to INSERT a new grade and verify -test('Execute INSERT INTO Query for grades.csv', async () => { - // Create grades.csv with initial data - await createGradesCSV(); - - // Execute INSERT statement - const insertQuery = "INSERT INTO grades (student_id, course, grade) VALUES ('4', 'Physics', 'A')"; - await executeINSERTQuery(insertQuery); - - // Verify the new entry - const updatedData = await readCSV('grades.csv'); - const newEntry = updatedData.find(row => row.student_id === '4' && row.course === 'Physics'); - console.log(updatedData) - expect(newEntry).toBeDefined(); - expect(newEntry.grade).toEqual('A'); - - // Cleanup: Delete grades.csv - fs.unlinkSync('grades.csv'); + +test("Execute INSERT INTO Query for grades.csv", async () => { + + // Create grades.csv with initial data + + await createGradesCSV(); + + + + + // Execute INSERT statement + + const insertQuery = + + "INSERT INTO grades (student_id, course, grade) VALUES ('4', 'Physics', 'A')"; + + await executeINSERTQuery(insertQuery); + + + + + // Verify the new entry + + const updatedData = await readCSV("grades.csv"); + + const newEntry = updatedData.find( + + (row) => row.student_id === "4" && row.course === "Physics" + + ); + + + + + + expect(newEntry).toBeDefined(); + + expect(newEntry.grade).toEqual("A"); + + + + + // Cleanup: Delete grades.csv + + fs.unlinkSync("grades.csv"); + }); \ No newline at end of file From 1cdb514d6a571bca4cd1be637f3457826c8f91d1 Mon Sep 17 00:00:00 2001 From: VersionMaruti <156605831+VersionMaruti@users.noreply.github.com> Date: Mon, 29 Apr 2024 19:38:41 +0530 Subject: [PATCH 6/7] Create classroom.yml --- .github/workflows/classroom.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/workflows/classroom.yml diff --git a/.github/workflows/classroom.yml b/.github/workflows/classroom.yml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/.github/workflows/classroom.yml @@ -0,0 +1 @@ + From 5f44f626e9d82ac7b97864a396a3a0a8223466d3 Mon Sep 17 00:00:00 2001 From: VersionMaruti <156605831+VersionMaruti@users.noreply.github.com> Date: Mon, 29 Apr 2024 19:40:16 +0530 Subject: [PATCH 7/7] Update classroom.yml --- .github/workflows/classroom.yml | 221 +++++++++++++++++++++++++++++++- 1 file changed, 220 insertions(+), 1 deletion(-) diff --git a/.github/workflows/classroom.yml b/.github/workflows/classroom.yml index 8b1378917..8c4fa1b7e 100644 --- a/.github/workflows/classroom.yml +++ b/.github/workflows/classroom.yml @@ -1 +1,220 @@ - +name: Autograding Tests +'on': +- push +- workflow_dispatch +- repository_dispatch +permissions: + checks: write + actions: read + contents: read +jobs: + run-autograding-tests: + runs-on: ubuntu-latest + if: github.actor != 'github-classroom[bot]' + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Step-1 Test + id: step-1-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-1 Test + setup-command: npm install + command: npm run test:1 + timeout: 10 + max-score: 10 + - name: Step-2 Test + id: step-2-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-2 Test + setup-command: npm install + command: npm run test:2 + timeout: 10 + max-score: 10 + - name: Step-3 Test + id: step-3-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-3 Test + setup-command: npm install + command: npm run test:3 + timeout: 10 + max-score: 10 + - name: Step-4 Test + id: step-4-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-4 Test + setup-command: npm install + command: npm run test:4 + timeout: 10 + - name: Step-5 Test + id: step-5-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-5 Test + setup-command: npm install + command: npm run test:5 + timeout: 10 + max-score: 10 + - name: Step-6 Test + id: step-6-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-6 Test + setup-command: npm install + command: npm run test:6 + timeout: 10 + max-score: 10 + - name: Step-7 Test + id: step-7-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-7 Test + setup-command: npm install + command: npm run test:7 + timeout: 10 + max-score: 10 + - name: Step-8 Test + id: step-8-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-8 Test + setup-command: npm install + command: npm run test:8 + timeout: 10 + max-score: 10 + - name: Step-9 Test + id: step-9-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-9 Test + setup-command: npm install + command: npm run test:9 + timeout: 10 + max-score: 10 + - name: Step-10 Test + id: step-10-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-10 Test + setup-command: npm install + command: npm run test:10 + timeout: 10 + max-score: 10 + - name: Step-11 Test + id: step-11-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-11 Test + setup-command: npm install + command: npm run test:11 + timeout: 10 + max-score: 10 + - name: Step-12 Test + id: step-12-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-12 Test + setup-command: npm install + command: npm run test:12 + timeout: 10 + max-score: 10 + - name: Step-13 Test + id: step-13-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-13 Test + setup-command: npm install + command: npm run test:13 + timeout: 10 + max-score: 10 + - name: Step-14 Test + id: step-14-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-14 Test + setup-command: npm install + command: npm run test:14 + timeout: 10 + max-score: 10 + - name: Step-15 Test + id: step-15-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-15 Test + setup-command: npm install + command: npm run test:15 + timeout: 10 + max-score: 10 + - name: Step-16 Test + id: step-16-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-16 Test + setup-command: npm install + command: npm run test:16 + timeout: 10 + max-score: 10 + - name: Step-17 Test + id: step-17-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-17 Test + setup-command: npm install + command: npm run test:17 + timeout: 10 + max-score: 10 + - name: Step-18 Test + id: step-18-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-18 Test + setup-command: npm install + command: npm run test:18 + timeout: 10 + max-score: 10 + - name: Step-19 Test + id: step-19-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-19 Test + setup-command: npm install + command: npm run test:19 + timeout: 10 + max-score: 10 + - name: Step-20 Test + id: step-20-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-20 Test + setup-command: npm install + command: npm run test:20 + timeout: 10 + max-score: 10 + - name: Autograding Reporter + uses: education/autograding-grading-reporter@v1 + env: + STEP-1-TEST_RESULTS: "${{steps.step-1-test.outputs.result}}" + STEP-2-TEST_RESULTS: "${{steps.step-2-test.outputs.result}}" + STEP-3-TEST_RESULTS: "${{steps.step-3-test.outputs.result}}" + STEP-4-TEST_RESULTS: "${{steps.step-4-test.outputs.result}}" + STEP-5-TEST_RESULTS: "${{steps.step-5-test.outputs.result}}" + STEP-6-TEST_RESULTS: "${{steps.step-6-test.outputs.result}}" + STEP-7-TEST_RESULTS: "${{steps.step-7-test.outputs.result}}" + STEP-8-TEST_RESULTS: "${{steps.step-8-test.outputs.result}}" + STEP-9-TEST_RESULTS: "${{steps.step-9-test.outputs.result}}" + STEP-10-TEST_RESULTS: "${{steps.step-10-test.outputs.result}}" + STEP-11-TEST_RESULTS: "${{steps.step-11-test.outputs.result}}" + STEP-12-TEST_RESULTS: "${{steps.step-12-test.outputs.result}}" + STEP-13-TEST_RESULTS: "${{steps.step-13-test.outputs.result}}" + STEP-14-TEST_RESULTS: "${{steps.step-14-test.outputs.result}}" + STEP-15-TEST_RESULTS: "${{steps.step-15-test.outputs.result}}" + STEP-16-TEST_RESULTS: "${{steps.step-16-test.outputs.result}}" + STEP-17-TEST_RESULTS: "${{steps.step-17-test.outputs.result}}" + STEP-18-TEST_RESULTS: "${{steps.step-18-test.outputs.result}}" + STEP-19-TEST_RESULTS: "${{steps.step-19-test.outputs.result}}" + STEP-20-TEST_RESULTS: "${{steps.step-20-test.outputs.result}}" + with: + runners: step-1-test,step-2-test,step-3-test,step-4-test,step-5-test,step-6-test,step-7-test,step-8-test,step-9-test,step-10-test,step-11-test,step-12-test,step-13-test,step-14-test,step-15-test,step-16-test,step-17-test,step-18-test,step-19-test,step-20-test