From afec7799e8a361a43f7ade5fa82486dfad237918 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lo=C3=AFc=20Knuchel?=
- Azimutt explorer has several ways to import your schema. The suggested one being the database connection
- as it's more reliable and offer more features (see below) but you have many other options if you prefer.
+ Azimutt explorer has several ways to import your database schema. The suggested one is the database connection
+ as it's more reliable and offers more features (see below) but you have many other options if you prefer.
- For more details, you can have a look at the connectors to see exactly what and how its being done, here are the scripts for + For more details, you can have a look at the connectors to see exactly what and how its being done, here are the scripts for PostgreSQL, MySQL and MongoDB. @@ -36,7 +36,7 @@
If you just want to explore your database schema, you can upload it as SQL statements (CREATE TABLE, CREATE INDEX, COMMENTS and others). You can do it safely as nothing will be sent to Azimutt servers, - the parsing is made on the frontend and your schema is shown with no business data being sent to Azimutt server. + the parsing is made on the frontend and your schema is shown with no business data sent to Azimutt.
@@ -45,7 +45,7 @@ <%= render "docs/_h2.html", title: "From Prisma" %>
- Prisma is a Node.jS and TypeScript ORM + Prisma is a Node.js and TypeScript ORM that use its own schema syntax. Same as SQL, you can import the file in Azimutt, local or remote.
@@ -53,7 +53,7 @@ <%= render "docs/_h2.html", title: "From JSON" %>If you have a database that is not supported yet by Azimutt, - you can create an issue (or vote on the existing one), + you can create an issue (or vote on the existing ones), send a Pull Request (look at other connectors) or extract its schema on your own and import it as JSON in Azimutt. You just have to format it according to the JSON Schema below the import section. diff --git a/backend/lib/azimutt_web/templates/website/docs/getting-started.html.heex b/backend/lib/azimutt_web/templates/website/docs/getting-started.html.heex index 4afaf92c6..569b23016 100644 --- a/backend/lib/azimutt_web/templates/website/docs/getting-started.html.heex +++ b/backend/lib/azimutt_web/templates/website/docs/getting-started.html.heex @@ -1,2 +1,9 @@ <%= render "docs/_header.html", conn: @conn, page: @page %> + +<%= doc_prose do %> +
+ Now let's dig into the main Azimutt topics. +
+<% end %> + <%= render "docs/_footer.html", conn: @conn, page: @page, prev: @prev, next: @next %> diff --git a/backend/lib/azimutt_web/templates/website/docs/what-is-azimutt.html.heex b/backend/lib/azimutt_web/templates/website/docs/what-is-azimutt.html.heex index 1bc1913ee..3340d90a1 100644 --- a/backend/lib/azimutt_web/templates/website/docs/what-is-azimutt.html.heex +++ b/backend/lib/azimutt_web/templates/website/docs/what-is-azimutt.html.heex @@ -2,8 +2,8 @@ <%= doc_prose do %>- Azimutt goal is to make databases way more accessible for everyone who want or need to understand them. - For that we have built several tools, the biggest one being the explorer, + Azimutt goal is to make databases way more accessible for everyone who need or want to understand them. + For that we have built several tools, the main one being the explorer, but there is also other interesting ones like the CLI and converters.
@@ -17,6 +17,7 @@ The Gateway is the central piece allowing Azimutt to connect to any database. It's a simple Node.js server with all the databases connector allowing Azimutt editor frontend to access databases. It can be launched locally usingnpx azimutt@latest gateway
, hosted in your infrastructure or using the Azimutt one if your database is accessible over internet.
+ Learn more about it.
<%= render "docs/_h2.html", title: "Azimutt CLI" %>
@@ -30,11 +31,13 @@
Azimutt is doing a lot of work around database schemas. We took this opportunity to build these standalone converters to be easily accessible:
+Learn more about them.
<% end %> <%= render "docs/_footer.html", conn: @conn, page: @page, prev: @prev, next: @next %> diff --git a/browser-extension/.gitignore b/extensions/browser-extension/.gitignore similarity index 100% rename from browser-extension/.gitignore rename to extensions/browser-extension/.gitignore diff --git a/browser-extension/README.md b/extensions/browser-extension/README.md similarity index 100% rename from browser-extension/README.md rename to extensions/browser-extension/README.md diff --git a/browser-extension/build.js b/extensions/browser-extension/build.js similarity index 100% rename from browser-extension/build.js rename to extensions/browser-extension/build.js diff --git a/browser-extension/build.watch.js b/extensions/browser-extension/build.watch.js similarity index 100% rename from browser-extension/build.watch.js rename to extensions/browser-extension/build.watch.js diff --git a/browser-extension/package.json b/extensions/browser-extension/package.json similarity index 93% rename from browser-extension/package.json rename to extensions/browser-extension/package.json index 0c82274dc..4f1d755f9 100644 --- a/browser-extension/package.json +++ b/extensions/browser-extension/package.json @@ -13,7 +13,7 @@ "repository": { "type": "git", "url": "git+https://github.com/azimuttapp/azimutt.git", - "directory": "browser-extension" + "directory": "extensions/browser-extension" }, "scripts": { "start": "./build.watch.js", diff --git a/browser-extension/public/assets/azimutt_128.png b/extensions/browser-extension/public/assets/azimutt_128.png similarity index 100% rename from browser-extension/public/assets/azimutt_128.png rename to extensions/browser-extension/public/assets/azimutt_128.png diff --git a/browser-extension/public/assets/azimutt_16.png b/extensions/browser-extension/public/assets/azimutt_16.png similarity index 100% rename from browser-extension/public/assets/azimutt_16.png rename to extensions/browser-extension/public/assets/azimutt_16.png diff --git a/browser-extension/public/assets/azimutt_32.png b/extensions/browser-extension/public/assets/azimutt_32.png similarity index 100% rename from browser-extension/public/assets/azimutt_32.png rename to extensions/browser-extension/public/assets/azimutt_32.png diff --git a/browser-extension/public/assets/azimutt_48.png b/extensions/browser-extension/public/assets/azimutt_48.png similarity index 100% rename from browser-extension/public/assets/azimutt_48.png rename to extensions/browser-extension/public/assets/azimutt_48.png diff --git a/browser-extension/public/manifest.json b/extensions/browser-extension/public/manifest.json similarity index 100% rename from browser-extension/public/manifest.json rename to extensions/browser-extension/public/manifest.json diff --git a/browser-extension/public/manifest2.json b/extensions/browser-extension/public/manifest2.json similarity index 100% rename from browser-extension/public/manifest2.json rename to extensions/browser-extension/public/manifest2.json diff --git a/browser-extension/src/appendButton.ts b/extensions/browser-extension/src/appendButton.ts similarity index 100% rename from browser-extension/src/appendButton.ts rename to extensions/browser-extension/src/appendButton.ts diff --git a/browser-extension/src/background.ts b/extensions/browser-extension/src/background.ts similarity index 100% rename from browser-extension/src/background.ts rename to extensions/browser-extension/src/background.ts diff --git a/browser-extension/tsconfig.json b/extensions/browser-extension/tsconfig.json similarity index 100% rename from browser-extension/tsconfig.json rename to extensions/browser-extension/tsconfig.json diff --git a/desktop/.eslintrc.json b/extensions/desktop/.eslintrc.json similarity index 100% rename from desktop/.eslintrc.json rename to extensions/desktop/.eslintrc.json diff --git a/desktop/.gitignore b/extensions/desktop/.gitignore similarity index 100% rename from desktop/.gitignore rename to extensions/desktop/.gitignore diff --git a/desktop/README.md b/extensions/desktop/README.md similarity index 100% rename from desktop/README.md rename to extensions/desktop/README.md diff --git a/desktop/forge.config.ts b/extensions/desktop/forge.config.ts similarity index 100% rename from desktop/forge.config.ts rename to extensions/desktop/forge.config.ts diff --git a/desktop/images/icon.icns b/extensions/desktop/images/icon.icns similarity index 100% rename from desktop/images/icon.icns rename to extensions/desktop/images/icon.icns diff --git a/desktop/images/icon.ico b/extensions/desktop/images/icon.ico similarity index 100% rename from desktop/images/icon.ico rename to extensions/desktop/images/icon.ico diff --git a/desktop/images/icon.png b/extensions/desktop/images/icon.png similarity index 100% rename from desktop/images/icon.png rename to extensions/desktop/images/icon.png diff --git a/desktop/package.json b/extensions/desktop/package.json similarity index 98% rename from desktop/package.json rename to extensions/desktop/package.json index c0d88922e..08d946d30 100644 --- a/desktop/package.json +++ b/extensions/desktop/package.json @@ -17,7 +17,7 @@ "repository": { "type": "git", "url": "git+https://github.com/azimuttapp/azimutt.git", - "directory": "desktop" + "directory": "extensions/desktop" }, "main": ".webpack/main", "scripts": { diff --git a/desktop/src/main/bridge.ts b/extensions/desktop/src/main/bridge.ts similarity index 100% rename from desktop/src/main/bridge.ts rename to extensions/desktop/src/main/bridge.ts diff --git a/desktop/src/main/index.ts b/extensions/desktop/src/main/index.ts similarity index 100% rename from desktop/src/main/index.ts rename to extensions/desktop/src/main/index.ts diff --git a/desktop/src/main/logger.ts b/extensions/desktop/src/main/logger.ts similarity index 100% rename from desktop/src/main/logger.ts rename to extensions/desktop/src/main/logger.ts diff --git a/desktop/src/preload.ts b/extensions/desktop/src/preload.ts similarity index 100% rename from desktop/src/preload.ts rename to extensions/desktop/src/preload.ts diff --git a/desktop/src/renderer/index.css b/extensions/desktop/src/renderer/index.css similarity index 100% rename from desktop/src/renderer/index.css rename to extensions/desktop/src/renderer/index.css diff --git a/desktop/src/renderer/index.html b/extensions/desktop/src/renderer/index.html similarity index 100% rename from desktop/src/renderer/index.html rename to extensions/desktop/src/renderer/index.html diff --git a/desktop/src/renderer/index.ts b/extensions/desktop/src/renderer/index.ts similarity index 100% rename from desktop/src/renderer/index.ts rename to extensions/desktop/src/renderer/index.ts diff --git a/desktop/tsconfig.json b/extensions/desktop/tsconfig.json similarity index 100% rename from desktop/tsconfig.json rename to extensions/desktop/tsconfig.json diff --git a/desktop/webpack.main.config.ts b/extensions/desktop/webpack.main.config.ts similarity index 100% rename from desktop/webpack.main.config.ts rename to extensions/desktop/webpack.main.config.ts diff --git a/desktop/webpack.plugins.ts b/extensions/desktop/webpack.plugins.ts similarity index 100% rename from desktop/webpack.plugins.ts rename to extensions/desktop/webpack.plugins.ts diff --git a/desktop/webpack.renderer.config.ts b/extensions/desktop/webpack.renderer.config.ts similarity index 100% rename from desktop/webpack.renderer.config.ts rename to extensions/desktop/webpack.renderer.config.ts diff --git a/desktop/webpack.rules.ts b/extensions/desktop/webpack.rules.ts similarity index 100% rename from desktop/webpack.rules.ts rename to extensions/desktop/webpack.rules.ts diff --git a/extensions/vscode-aml/.gitignore b/extensions/vscode-aml/.gitignore new file mode 100644 index 000000000..eaf5a2953 --- /dev/null +++ b/extensions/vscode-aml/.gitignore @@ -0,0 +1,3 @@ +dist +node_modules +*.vsix diff --git a/extensions/vscode-aml/.npmrc b/extensions/vscode-aml/.npmrc new file mode 100644 index 000000000..8e012302a --- /dev/null +++ b/extensions/vscode-aml/.npmrc @@ -0,0 +1 @@ +enable-pre-post-scripts = true diff --git a/extensions/vscode-aml/.vscode/extensions.json b/extensions/vscode-aml/.vscode/extensions.json new file mode 100644 index 000000000..5be3c32fb --- /dev/null +++ b/extensions/vscode-aml/.vscode/extensions.json @@ -0,0 +1,9 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "dbaeumer.vscode-eslint", + "connor4312.esbuild-problem-matchers", + "ms-vscode.extension-test-runner" + ] +} diff --git a/extensions/vscode-aml/.vscode/launch.json b/extensions/vscode-aml/.vscode/launch.json new file mode 100644 index 000000000..a6abe6204 --- /dev/null +++ b/extensions/vscode-aml/.vscode/launch.json @@ -0,0 +1,38 @@ +// A launch configuration that compiles the extension and then opens it inside a new window +// Use IntelliSense to learn about possible attributes. +// Hover to view descriptions of existing attributes. +// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Run Web Extension ", + "type": "extensionHost", + "debugWebWorkerHost": true, + "request": "launch", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}", + "--extensionDevelopmentKind=web" + ], + "outFiles": [ + "${workspaceFolder}/dist/web/**/*.js" + ], + "preLaunchTask": "${defaultBuildTask}" + }, + { + "name": "Extension Tests", + "type": "extensionHost", + "debugWebWorkerHost": true, + "request": "launch", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}", + "--extensionDevelopmentKind=web", + "--extensionTestsPath=${workspaceFolder}/dist/web/test/suite/extensionTests" + ], + "outFiles": [ + "${workspaceFolder}/dist/web/**/*.js" + ], + "preLaunchTask": "${defaultBuildTask}" + } + ] +} diff --git a/extensions/vscode-aml/.vscode/settings.json b/extensions/vscode-aml/.vscode/settings.json new file mode 100644 index 000000000..e6109eee3 --- /dev/null +++ b/extensions/vscode-aml/.vscode/settings.json @@ -0,0 +1,11 @@ +// Place your settings in this file to overwrite default and user settings. +{ + "files.exclude": { + "dist": false // set this to true to hide the "dist" folder with the compiled JS files + }, + "search.exclude": { + "dist": true // set this to false to include "dist" folder in search results + }, + // Turn off tsc task auto detection since we have the necessary tasks as npm scripts + "typescript.tsc.autoDetect": "off" +} diff --git a/extensions/vscode-aml/.vscode/tasks.json b/extensions/vscode-aml/.vscode/tasks.json new file mode 100644 index 000000000..fc326ca3f --- /dev/null +++ b/extensions/vscode-aml/.vscode/tasks.json @@ -0,0 +1,54 @@ +// See https://go.microsoft.com/fwlink/?LinkId=733558 +// for the documentation about the tasks.json format +{ + "version": "2.0.0", + "tasks": [ + { + "label": "watch-web", + "dependsOn": [ + "npm: watch-web:tsc", + "npm: watch-web:esbuild" + ], + "presentation": { + "reveal": "never" + }, + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "type": "npm", + "script": "watch-web:esbuild", + "group": "build", + "problemMatcher": "$esbuild-watch", + "isBackground": true, + "label": "npm: watch-web:esbuild", + "presentation": { + "group": "watch", + "reveal": "never" + } + }, + { + "type": "npm", + "script": "watch-web:tsc", + "group": "build", + "problemMatcher": "$tsc-watch", + "isBackground": true, + "label": "npm: watch-web:tsc", + "presentation": { + "group": "watch", + "reveal": "never" + } + }, + { + "label": "compile", + "type": "npm", + "script": "compile-web", + "problemMatcher": [ + "$tsc", + "$esbuild" + ] + } + ] +} diff --git a/extensions/vscode-aml/.vscodeignore b/extensions/vscode-aml/.vscodeignore new file mode 100644 index 000000000..742a07ebb --- /dev/null +++ b/extensions/vscode-aml/.vscodeignore @@ -0,0 +1,17 @@ +.vscode/** +.vscode-test-web/** +resources/** +src/** +out/** +node_modules/** +dist/test/** +.gitignore +vsc-extension-quickstart.md +webpack.config.js +esbuild.js +.yarnrc +**/tsconfig.json +**/eslint.config.mjs +**/*.map +**/*.ts +**/.vscode-test.* diff --git a/extensions/vscode-aml/CHANGELOG.md b/extensions/vscode-aml/CHANGELOG.md new file mode 100644 index 000000000..474406779 --- /dev/null +++ b/extensions/vscode-aml/CHANGELOG.md @@ -0,0 +1,17 @@ +# Change Log + +All notable changes to the "vscode-aml" extension will be documented in this file. + +Check [Keep a Changelog](http://keepachangelog.com) for recommendations on how to structure this file. + +## [Unreleased] + + +## 0.1.0 + +### Added + +- AML syntax highlighting +- AML suggestions via snippets +- AML symbol navigation +- Create AML file with sample content diff --git a/extensions/vscode-aml/README.md b/extensions/vscode-aml/README.md new file mode 100644 index 000000000..e631a84a8 --- /dev/null +++ b/extensions/vscode-aml/README.md @@ -0,0 +1,90 @@ +# AML Support for VS Code + +[![VS Code Marketplace](https://img.shields.io/vscode-marketplace/v/azimutt.vscode-aml.svg?label=vscode%20marketplace&style=flat-square&color=007ec6)](https://marketplace.visualstudio.com/items?itemName=azimutt.vscode-aml) +[![Star Azimutt on GitHub](https://img.shields.io/github/stars/azimuttapp/azimutt)](https://github.com/azimuttapp/azimutt) +[![Follow @azimuttapp on Twitter](https://img.shields.io/twitter/follow/azimuttapp.svg?style=social)](https://twitter.com/intent/follow?screen_name=azimuttapp) + +A VS Code extension to design database schemas with [AML](https://azimutt.app/aml), a simple DSL that speed your design by 2x ✨ + +![AML in VS Code](https://raw.githubusercontent.com/azimuttapp/azimutt/refs/heads/main/extensions/vscode-aml/assets/screenshot.png) + +## Features + +- Syntax highlight and suggestions for AML code (`.aml` files) +- Symbol navigation in AML + + +## Usage + +1. Create an empty `.aml` file or use `AML: New database schema (ERD)` command +2. Write your schema using AML, check [documentation](https://azimutt.app/docs/aml) is needed + +Here is how AML looks like: + +```aml +users + id uuid pk + name varchar index + email varchar unique + role user_role(admin, guest)=guest + +posts | store all posts + id uuid pk + title varchar + content text | allow markdown formatting + author uuid -> users(id) # inline relation + created_at timestamp=`now()` +``` + +## Roadmap + +- diagram preview + open in Azimutt +- convert AML to PostgreSQL, JSON, DOT, Mermaid, Markdown (Command Palette) +- convert SQL and JSON to AML (Command Palette) +- Add parsing errors ([createDiagnosticCollection](https://code.visualstudio.com/api/references/vscode-api#languages.createDiagnosticCollection)?) +- auto-complete (cf [registerCompletionItemProvider](https://microsoft.github.io/monaco-editor/typedoc/functions/languages.registerCompletionItemProvider.html)) +- rename (cf [registerRenameProvider](https://microsoft.github.io/monaco-editor/typedoc/functions/languages.registerRenameProvider.html)) +- hover infos (cf [registerHoverProvider](https://microsoft.github.io/monaco-editor/typedoc/functions/languages.registerHoverProvider.html)) +- go-to-definition (cf [registerDefinitionProvider](https://microsoft.github.io/monaco-editor/typedoc/functions/languages.registerDefinitionProvider.html) and [registerImplementationProvider](https://microsoft.github.io/monaco-editor/typedoc/functions/languages.registerImplementationProvider.html)) +- quick-fixes (cf [registerCodeActionProvider](https://microsoft.github.io/monaco-editor/typedoc/functions/languages.registerCodeActionProvider.html)) +- hints with actions (cf [registerCodeLensProvider](https://microsoft.github.io/monaco-editor/typedoc/functions/languages.registerCodeLensProvider.html)) +- AML support in Markdown +- Connect to a database + + +## Issues & Contributing + +If you have any issue or bug, please [create an issue](https://github.com/azimuttapp/azimutt/issues). + +If you want to improve this extension, feel free to reach out or submit a pull request. + + +## Development + +VS Code language extensions are made of several and quite independent part. +For general knowledge, look at the [extension documentation](https://code.visualstudio.com/api) and more specifically the [language extension overview](https://code.visualstudio.com/api/language-extensions/overview). + +Here are the different parts of this extension: + +- [language-configuration.json](language-configuration.json) for language behavior like brackets, comments and folding (cf [doc](https://code.visualstudio.com/api/language-extensions/language-configuration-guide)) +- [syntaxes/aml.tmLanguage.json](syntaxes/aml.tmLanguage.json) for basic syntax highlighting (cf [doc](https://code.visualstudio.com/api/language-extensions/syntax-highlight-guide)) and, later, [Semantic Highlighting](https://code.visualstudio.com/api/language-extensions/semantic-highlight-guide) in [src/web/extension.ts](src/web/extension.ts) +- [snippets.json](snippets.json) for basic language suggestions (cf [extension doc](https://code.visualstudio.com/api/language-extensions/snippet-guide) and [snippet doc](https://code.visualstudio.com/docs/editor/userdefinedsnippets)) +- [package.json](package.json) and [src/web/extension.ts](src/web/extension.ts) for defining commands and more advanced behaviors + - [AmlDocumentSymbolProvider](src/web/extension.ts) for symbol detection + - [previewAml](src/web/extension.ts) for AML preview + +Tips: + +- Debug extension via F5 (Run Web Extension) +- Relaunch the extension from the debug toolbar after changing code in `src/web/extension.ts` +- Reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes + +## Publication + +[Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VS Code extension marketplace. + +- Get Personal Access Token from [azimutt](https://dev.azure.com/azimutt) +- Manage extension from the [marketplace](https://marketplace.visualstudio.com/manage/publishers/azimutt) +- package the extension: `vsce package` +- publish the extension: `vsce publish` +- if needed, install vsce: `npm install -g @vscode/vsce` diff --git a/extensions/vscode-aml/assets/icon-white.png b/extensions/vscode-aml/assets/icon-white.png new file mode 100644 index 0000000000000000000000000000000000000000..952ade234fe5f89cf98b06634eddbb7615f54954 GIT binary patch literal 9405 zcmc&)_dnJD7k}S-aj(5M+56fnBOxPOHlb^my$Nxzi$rEwA=k>txKzmMUa})Adt9^ z&iAzla;yKq$3RI5<{KattJdT)J(Pt2DLXld^9MrNakN0rWs)EX{#H*L_DVv|OJ;-) zzk0>SJA$DuC0NeaHgzKKgG0^TcL2mDthtD$Br%et;PucNl<^kTGB51Y^*aEQBb|PmYq317Uio)X;;)f)Lb%E3zOC z*bXPqjdI(uq~UQ$kh&g`EXoW(lYCC!CbP^iU!ZHm_Lr&Um9%7)!M_I`?j2yKUk_K| zL7X5OiBpi}tq5$DjLsnK-TlUSZ-~wk;2$goLhsxTIGXh{#Yr?0nqFX>Jf3fqjZ$7v z22)U!K12|d7))zxb!xLB{uX{xEd@kDikg2~4a(*;vqP7ZL#bK_Kp{z_g@YxRwevvc zq`z?w8ZlVUHCwD{aln~bT|Rq82z=t6s*T5>Ih%A3P7>Y6>E{a7@Y ^D8~f6UZjPuud6cXz@A%IOdez_opv5_La@koKiyKvRL; zEM!p^$Ar~~^fG}Xg3wYL(WD;|XW1_~6x1Z;2Z|j1c8caSq0C?~|Mzw{3)W;D)2g83 zofm(p{w2%bvB(d<>)`9;FUZiWRH+VpEqc!Ww*& cBrF#C zIOvE%JJa_igxzNzetW9R22SintA;x{^T`bau(9Whh{3y|G>flNT?LPpl`K%_cPIyv z2Kya4MBs59k1ZA1)o*xNPeE)LEXVy3>2R~!L`<++6-V(xz~Ma6={0dlOG06pSEUZz zPj(7F@vWx3JA_?b-b@kx#qW}iLW2wP-0sKqwNPTA#{vz%{4;+fFYzz~Zkeqk$@9op zwn;ieQ+Nu0J1Ltsy-O4gC{20i(*^Nf B9w)sf z`R;`8mjLgtJgiRWl53;!jS{>Xe-hjs9vH!?Q9*&c|4_re^sR@S9LRrFjonopaqj8N zRqz(vajF-n1!ZJCMj!S)zWbBl?`|8N4fuQ*KM?7sKiLmneDOe73@%N<(T!rUzf>h) zB|4Eer(2H_1#SX&$kY4uZ!aa8#F~LdmZ4m93nEs#BANxO`Y8*-f{DGIgW)(c?Aw4b zvz%X3xA|fZq zlR-frAG@#Yl0a;6LkeOs3QE46Fojn^6OfGZYtG6U=ieeD`5aIfG86uLDEz{9 z4?ULapT2qQQ9?sRt 1`cSYK1t=oIFy!@AJR7}9-Sl!)aeQ>joSG_=ur z57A-0bP_3ZO4NS8rJO)K%4g2i3n}|9Cc}=XOe0aEBZA1Hf?S0zKi}9eu)|<-P00ef z+?JmDSWE;~td?e^94wYM>=GzmOGnAgB?Mp&{$+bJ55@@{<^}#k^3G+UZrS#bdA{Nc zqVKPw2n5Jf3KCJ8*FKn4+wj+EVak=7e8O29Czv88uH4I=DBo~*kpyY6>;dfd*e#k2 z;Al+kXF|v)KB5No7Q>ufOG)@KO951MW47@ZVHL>(u6wXZ>0A{-+j2;mMk_iB6G5Jw zOFC7?7Yl(s2*?uWAp*6lFlf&S-rcmGydh}#vSfrfTP1mMDbO`7Ap!v!3bc5%q>MLd z6io5*tE)vtG|}_|s4@o$d%|zFYKs5sW~9O_oFD!<*BRY@04J|GOS_UJbJzX4-2|LN zznD19IM3?S5=R}?JiLoYyEp<_VeLh?_-O+I;N%62;xouZN-c=Qbwq`HRl9M9a_wpq z6z&l49i}a!YF8rrrc`EgHjbvGz27DtX3*eJ{=zy08d1|t&62?~JVM@{DGv1r|GFI4 z*pj)-F9&5nw0DV1m1qDg8;@SS9JkBnWVK w|74h479 zQb)5#-`VhNa`E#2^4X8WoR8%5e-HH_d=0tgwj>vQcfizz0joOZKWJDiv=?F5jSp-L zhy^MqgFyS2EF1a!?P7?MA~+mw^Ff0}VJK#{E3Qyu*5Exv#lN-UHFx>WTK{g+5fTq4 zs8u+hoCqvTW14vqL9iF@h4AmhpkWkwZ7hc7?_Ku3NeVSqqt1#s&V8jk_hG?M^|L`Q ze6e5Xlo4@x>{6)-M|c<#NoTKWvV`}WR)3ejsY^pEiXi~&H5tD~R354)O zlpSl{<*Awk%YJ`ee1LctJJj%tKa`Cs8wS#W6De7+7eo=>R*XcAaP`315 r<_KXK_r)Q)l=zH1-rqakhY-$Qz95SyacRQlo(0>Ek8&p2!B?x=!A;i!#i`wUWg zc~qk}OqODN6&f#oM)^LLm;8dZWp{+P%t-N-p|w@p=qjcTJQe?c%HkcbtO-fv0 g>9%z2$!+T_u stU!lVE7V!2A z>s`mARSzD0cmCpZuX(ov0Uo+v!dNz$H+ygVFf<_O=>zY@p>$v2=z0!1zb>U+GuSfy z#;R-#NoWUHMoH0w82>jmYTM9sR+8}zFHq!PXC?}2HCC|-T)}Y`q7v+KNEm-XX$wP% z_6+|(af(uu5sIdrwHbiH0*XY7&sr6d$kq_Xl{2yVXxH>eij29GflE{(O|xJBhj!B% zq75h5gupk *_>D4+_1L(;LAm60=3gpLr z-2l0jPgp3~5c4I=7P3{M*K#TosdySaUOU@Yb8cT*5M_@(x`xgB>%oEHU(ddG?F4=^ z38km7t5bIsp*4UHF&~^>btPNqKO5>l1eLNtFQx4ME=Hr(kxbc5qk@70_56b+v?0)p zWy9=hE6IaCdA|>1;J)5Zz-G>+@lPU`Doq1xzo%;B-Ngi5Z6I@YNhxt$Y22$!s=L$l ze2qvt@QwH!x~|BhBXJcjNWystAz+PEL_-@xSp)7zq`60~W#($J%OmM%stu>^6GKPM zM)$`l|2Z@f0|>_V!dg*;`O#zO% $A}FQd`^Z;H$Dv6;-43mnd$as|BWBN# z$ttgX@?oq+7PHpkR6ajqkZqco c%dKHr>7N~C| zO6-M}Z5Yj7v{Wq7rZ_^AGLgbfxkw8B$$ka6_eBt?Su+gYE>j$677t+vx@JA#Wz`e^ zd{VFTsmURTbNr1mk9_;DS%Z~hQ9cq_RT}dnIYn|Q0If9jJe&WlL(@6p6JhOT7gnj2 z!VxD)^oUjDUv%X-MQh&$VT4O$rM!Kq=7Ec%21Mmx!7iX*vJ8XF7x#O1lYO%Avdi%6 z0kpt@YRNQlh|Zg=;f#;qtq THHF(t-y@efrsC4mQF(1`NE)mRh zgrH22hsP!3F%<^VlZy@ME-$L+5`ea=KhfIX+@2M-hAW01@!E0+%L%On(aVd`flBy- z<-C`w<${k`k1_s{%-eA>MhAT)8#w=#=s2%9Z>MDEgl@+ghdj=CdGz9wf8*UNc2wr= zM3&&_E?;uR`dZWDxU}} 4wW12kJ3sUy!kiNS#-=pz zCs{PglSz2O?c^RWGzEjA;<(mj$?&SiBGTl;z1d@4_9}cJyh00`=6lOt`6`}94pt~D z6pIo1@azf4;5$_r(3ryu$`z=av;Wbe1AlJvJ(Jed^`LrwX6D)S_Qm!YV6@QeCjf72 z*#a+Pyvm&Iv87)wCdQ7 8kPLe2W*Q jyXWx`uFn zG$O6`v^>ndn1a(YLuJD!MmmhEgKcwUt9T|)O96}wAf;=4_;BT|l$$JB$x{$4ecsMp zHiq942(+fi_e?~V3u+pIAi`R)rxlEqkYe4*WXZaCTHPQzErEU)GS)Yr%LAWVNlHdG z@=13V<0fJPFB`dFvpKI`V4UC-#3efqUP0RSOCM+~dH5n>HU@;-Jjrzvr9i1=G=e z_FR0$TPa%qmVPhq=~B@~8<@vRhE{K1Dc*_*UZPiUKbiJG7N!W6)FBL=1x}M>{-7Gf zD-` ;f#ryu$l7>*4UJ&A2Wk?R^yUpbz|4B*OBn~^sJCVff5NJp{7@Z z3&WH-%PC*WC7*!0aCib?jlN)ac;TXGLA`@^Iv`pP{tE`4RR`4^_91Z{9h}LI9U5{T zslng4eh~hQ3G+h{UzNFk<;c3J2G2|MfI?~*5TsG4&=(qDe*LN{p~C>Qn{LuA!R=2S ztxDYkX~3u)8AbT8vuzsL#MqmX0PjdA&&75kJ4!7DxC|SjAk!oiR#mJU PomB* zoUu{}=#w|!8_mE|Vfon^f(^h%SXJx!Kx8p^C~e~)8S@R7>O__Wzz>WG6-&Q=v{&+g z;sk{zn{6%Y(g6O?T6&YKa;}(5A);2TN!adZ5qYvg8IYmUd@^#hK_+N}He6K*+WHAF zXO%0FBEbcU3$Km<*fkKih4laoVLwrZ4CKr(muhF4-}opSN((t5;DH5#JA!+?K6(Uc zfan$o)%mw?8R?Y6H-Yv+cA#H@R1_E;J3~$z!q7R5E)BTVwgh2G{@+;x0&t)*K?#>_ zD=~QcCo94$kDkFMSEDdN6aMQnx68D`;}gb=Xq#Keg=DuYJqXWV#ygZ$+04I1DtP-K z39`s=M(aio^;}qruOCo>8xXrTlY&3znd3StO>W2s^K($ogh#x|I@vsAY@Jbn5NZE| zfe-_Kn6iIT;~UDdYy)8|ayRJ!%nnAKPp&LO>WPgySC?=*1Jip8(MM@WMn0gj?ndhN z%=VPmyx?;Kz^RAaUk?J$klnb=&C0iJ3Px9JQ#)@6wjF4FFUR@XjrP^_Ti@21Ava@I zex3OL=3@jkyXK-9L)jrjZVC_^WcZ?l%oyj(0uR~+T_o@(Yv2UvqyxTp3^(jF4yVx^ zjs7|PDZ~<%!r!b^rB{$R*Q^0G7vQliwR*a)swla9;p>#2i7E=2dOIU?&uEN9d08z- zV@gk@sAM>en-Ln}PJ})yk a!co5C@HD@Z9( z4!frUFs;b?3mFu%4TZez8AQj_)F5Rj+oMSU{#d6E^2<*^ye*9&R)F&yEq=3l2=4nm zChEt2H1|k4@9znCBr9*!p&VVP@0$!92}%z37P|^UvO0i_%AkL@#B|7rBm!C8cQaH{ z|L&uYugov;vmyb1ty&lmbI~Qp?$%pxeG;gl5HFzsW< a?>kiaTjw# zviD4oqvT*gc|R`dP6!4F@**aG4PiojKOqx^%l>q~)`A;9itrV6FW=nE=e-K6KF qU!dTKP+SIqVOd8^|!EqHlD_UH!gp|B=GRt#Z#oLH0>Qgx(?PPMp00lT?>y7V#l zxA`th3 }~ zY+mU7ZTrc(G_4{|Sn@&PQ5br?rO0`cN}}d{`7NN2w|>B{^vHfr)ht5#?0$=UHbBUL z2pmvz +7W}JvNU4AFzJ(rgj zq~>3oY$~Q7k{zzaI53P^U8vpEHZLF7INN2iMxim#%Fbx%#sd {j#^eIY5e2;z#RI!^JW<=OKAZs76sRxg)EH$}} zQXf&^(1bt#+g+;%+;M>dEdP$qfLJ;5$n9luhFymPZ)L1if5j!|mBQ^gQO~nht8m$+ z*N|uQ53oHnt^ju@wQ+?WXOzR~7tS!2D(xJ4otZ%~81xLV#~Y7yh?%YdS7Q8ENCy(Z zQ=2t@_lFU>^rJG<0Av*32y~V@|Nh(Z?`!AzPXfu-f}O-A`?KdG({aEZQtJ*R5oNv| zxlh-A+hRXo_d-rG0med7_wqkfkzN34z|O1INFgTl;&B>Ho*P qFkl2jqK _WO3cZoL4Qc4BxPf^e-BiJ zD8gs;{$%s~v1qvIa$`Ot#gc->DH4E | A47i(IhiC^G!J4r%$3W&06Z#4$qQ- zH!RR6K`~v%%QS$c)=g)r Xssp-%=RF-!JwJr;Ww-o3{LMVSUkFsp**tzuE; zL_yQTx(Ba*CIc+TkIT*5jc^kUA16lxKe;rLQ~oy7Uddy1rB0J&X`L~U9b30!9Um@f zn!+RKb8FVGTZmwRK2pE@8M27ae>t!(J_2soiA>gKQXLn70_@2Up`OF7>Sk96x8B!s zKi3
yW$*xB2OMcnfxkZg2W4|!5ekib# zhrHZWmQ?^IA;)USr2rmPr=wq;Z-2SH_9Wg;z(kIq1C0Y;s)J43O&gq&aKla )yJ24BthN(JE~(88sr(T6bk0wI$qg8AAvL<@91T}|yWHrC3kW|2TjF%*fUJLnlm-AC98w5Zw zN>r9yR)xI)jMN3i1*$;2IS`E7^q?dxIVfD)Y$LJQ?dmIbu$0n=BlQEi GP5Xx^H{4zTA&-DN1HzJ|WIfDS8U0O-`Ew957Y9xrV7QQ>=5u?xwK5>g zEy(UyJeIcZ@iUR=r}N2gw(Gy-aLOPy8;Ru~XRok}ae4usCZ_qN3h)=Qb>ID*>x2|b zQ&Hg80LrBt?~3!h-{-PO?Tp|meb>Yz!Z^-H;84O(LdFH?z6~M4$UG4{-i$9?%Ym5S zayS0=b-8**0rg1H1J&iUy`S5Fi(T$7f0Z=Z<3_B{&s=4zgj!G~t=Zzhx1C?T%E?y$ z?H8 V642V5K zOJ~>X%~{;w8o<`!Gtm# px7(JKUx(bh2ehhNrDSCM=__vMfWaNZ6+BPX!(x zZ{q9JE_ O`C zVcCt7BFAK>=~CTtK3-mjuP;i;sq49OpHv#hqUkptkZj|JxB0&NuHK@&6F%0ocyiPE zC*k$E`_9bw9iY4Wmd}uHQoBtv`xp4V_F*afko~RA885K1nU(2xqy?>v*MrkO9`9lc zWl`U*tWE}jKZgPzYFvPc$p*d%fj?}dOYd0UrrtPzS{VomXC{*!y}M |qw$k_!ps>$>7pZ-3m*ZukHA9tzg_xCrgTa(I zA?z`uC@`TNdJDEmEJ`#%1B)B~AbC5Z=;_J9S3K+cx2)e5c!UYYdl 9POLoNR0F2#x^(RBd;&5P4m;W;A2|eO>)u%Gw&PMiK zt@mP$!ThA(eIK#%k8@=4e*Wd$UpfzkR4 psvtWo{mcQYZh$9Ysh}_u|E^S zq59+a*Yuf>gJ0#FEKkEvZdMgB5MUc_YsmkhCbNLT!A}NT*TTcN X4dCs zJ9@lVJoaCSFc&EUB7ON^{cyYBRdh2YrlardPwMc=TcnvnY6xLpglh^Z5QaugO!r0J zn2z6y5@ZGGpUymq5FTx+f-lJe5K5-b2*{Jvv{*94UXHoEV#7XqIs^UEM3ZFRw13g~ zPM-#AffF#B{Dw;TL!#xv9p42YGOdtaQhkzx4?_EF34-0f+lk89L^B{HUaC`pwS`94 zH^4f!-w;IK)YnF_N7a%fmyrYfJgYjF2Bn76mWfJnH((&-$%^1gAb5;0rX=wfE@FZ4 zD*zJ>A$K9wJr_S)crRBYZc+PqwOcZ&%N~eh%M?$1BMQ~(Ic&$ND-7)zS;yx#Uz^A3 zF%`fLH#O(Mp=7=fs>kL`pVb4z^k%)^R8XJ*5zzuF#LC>#OZS|!9Lb3gN*KQ{pjRVp z4&i 9fQh#Y&KP4{EBC~#XKYwLiJzxJQ@{`aF z?8vBE@{b#AunT_aZdTCu<*TLfz7*tCIONIG+bp}!ay}sdr4nz&B8?Rz#qKLa&w)GL z-OPf>#2Gf~s7JA3yF>Y3kJQ*fPiZIao6sHT6HXGCm^LHq(@{TrBkNnP1LqgoQ_q8G zi|->N6LCD}p?f5$1c<1E5Jv8J2xt6s9tC#S_R4 FCCU7X~0wAG*n z=I<^H@{rSjOZ3fp?fsN}`Y`Youf>63v^ $P|L zPsBMiVsLt1?`DMypw^i;@)IJ#q?;Y*j~mXXw{ghrG1fmE{x1kfza;NvS#Ju9<<30@ z8j#(4=k%FEWLb{ARhMO`D(q9{?9FfXy&%L-ZqP?#pm*?a{WdtP;=4!#dy0$Pyb&=g z-X)v~1II{kGW@?^zY{_NHop}#_XCk8T;Sk?G&}@pjV*wAfdE7_>;cTt|9w5nhQwUf zQ^t$;nIoPQTSP02Q-`d^US7dpRi0*`ki2szvyN)Q8Y%#0dH9yK?(@tl=~r!{nDpRs zq;a~MnBhrA>=(n9-*^}#h7s`@4}tze3j1WbmrmdNy;xgP=)et8qyR!{3~?w76JqRL z;2BLhQ0!#JevJ%E(k&{Pk3q}Wyff!x-(f*0zJ*Hxd%SEF&&ETE=91);qbF0~u8PS^ zr=N)_T^BhP;?L>aLBCr+yQll0A-nYn&d*g)`^Ts1YP&pN1zw;n>q=qNBvw^H{jio1 ziXB_XBmu{vkg$dxfGHUEL8UgoMxQay*!~`>(jB%N-1P6VwPba*Ffjt3gfd`7( XTvagbe%Wo*%c&pLXaKzq$|q2uSCARMQ8RV^} $shg=<; CLS5HSv7VK3Sg;2JhY*+-Fi70Ukg-Pq0(f*q)y+DX5pC+Vm{YB!}orVoa zm?RDO_ 2YrgDwBDUk|qgHJ;|3MY~Q-m(cWv4Q3vX`tpYooEHVu z*dFW~%FfgL=8wJw+x !1_i z(>$3DVKRoB*b1M|SVC~H%(9A)&3bB#+p@|NN?M~IdIOPA@6A@+j37cdkO2{`$>1$_ zyP}wngHE%7Q~h80$7aKXM>BGoRgr)I!TcM3`&F0Rir#d_&)
+KsP}3u3DEC!2 zqzuj7D2%$eGR0OmG< GaLeE!4)}C8DGQR7`<)-=6jMPeaH>K-Lk4|_|KK{V-xUkNE&w+?)+&YYtsUZ zHGKY(8rJuswhW5@8NEw0$_*8je |f{5l+G;_oHbgPfEOAf+hGD$WzOH>A|`Kp?Y+ArPSrC$@-1CL z(C9z~%fkXS>T1^eNsA8`n{w)vX`tBFGHAGT(Hrto1S3 $5)YR6A^HD(T z=nE6**p#|7zSeL{-H`=7b=v%y#7{||kov>>Dlao==8J>>_*W*zW(U>!dVH5NnD0IO zu~nmJYNNG9(!$O^UKe!EO9eZBrJdpXbanF)FE)3}`W>g%eluL3S-OSq{=q}WGzo8e zZlo^snOTKpTWpN>F6*w)N*AzrGkW)f4#DDFJenLOWp>@%qtV4AICfJR)FV$EFQ@xT z{n@SeMJrEw6GNk`r&Qp}JJ3g5?AwRP< I3j!*)<6E3iv|q8CXlR;He>L~DPB z!{+0^zM#ZthkD 7HhXzuFfetp+^is&PvLc`=hWnRvenZ|l}0C8h< z(dGmWT7Yo{aI-v2r$4PVWqd;R`&&HEsp6zFW8544mRED*qrY%s#ll&`;&g2s6rtoJ zdkpg6*ak%zunNKFL_B^;2gRy9;D`}E(Bl;f<0x06fw`pYs*oFcl*mN`@3Li+ klbb2<$fGdI` zdWF5%1KyuM!io-Yr=4FSo|Ic-Uo%vJ5I%t3qH8Va;=x3X35t;GfS>dgs9>A%Q^cZX zPDZjw2RHY0-wOsCfC?7vHaU~=+%HoJTr>I(T@jwrNYUHC#IPUQ#{4-uEF=>R8_Z zZPkvt!v%?aKEx1TxBHNB-0;H%yE-o-=_e2O$-DxgBHlkS%K+%O*qhzhm7p-bQ8zl+ zeF42UCVkSl-dN)tC9A6`(}4L?jiIjD6A>uRCVp?#;A~$Em3ks8 DpChy)paZf`EbJEx&mnR-@uD^oM^ll;cg(^KE6eD zopAH2F?ae#27d^C^;a7ZfN^8z*c_0mbsF$zs pURF8siU*azLZn`;|)s(8{%Y8 zMJuJ0IK2B+NAzw@r$RiHU(NItXYOrWL@zS&bq_0_zB3j4)?kEIN)7LbwP-t5Bi@6-zuYb*VIh4tWVL?A}{^8n$p-TRQtu#;<74CG&pOTprg!% z_tNH)vWuP*Y3Mv1g;H>Tmj&)&A3%G7kGOCHi`2?!Je#pwIr`T_WXwo (X33w2*iqKn7ZUh5{)neY>jq-L4 ;p=VFRyWj zDMwngeZ2}H9@)m{eAfTywOX>y<)Ww;m{1zmc=7X(#M^Rj5we1u4*G`_V$H6O<)s_2 z*CHYaCno9d`}y1QWn_OZy~*18Cl^p)3S~xeZ<+NnXX%guSbU$8&pYueQbaw;f$A^} zs`p$|43U=Y>?F|$wKhp0798(#8k23TmMS& kr$MI_tHWT4Z(sDPpM~3$oci|yNKzKI+H70IX4b+a&_9I3Ei&VN}Bf6JWo;wkY z&lo3S5~JN;nEduL-=g-v&tE}+9IwatT~g3&7_VK`JL%PwPQ*Zv<5t9K0%5*Y5>WZc zvUG}H&lzv`W_>y3M3j`6w!{K@-_@z@KHr@&1Pduq5^J&bVkf-&8AlcHK0$5n{SNPk z^y)e}_U0%i-m%|pY__jInS3(@f2N62PkdHBoxoJ4zDEHpYf`<#rYHt++tyKf^Jn*N z+n^pl+ XOI~kKFL}B zwXsR@`RMi5eX4n0Ohj}gwbx&?-VY%z+fN_iVojRyHN{c;m^b!N1Yz0AmsbxR-ozx{ z?EFf8QY=DIuNY+yr)D!p0aV2E&3=n_Z@5vLezg**?z7F8R8;9mkJ-mVakB+cSzlsm zWp8j`$M?h&Z|`uFbfsS%ThzmwRV^EtUi*G<0PjUsdFF95Y|4{*pJW@TqsEnRDtWTp zT=1*a{5DIFX1w<^lrhzs;=Pq7#?9SOqx|v^+F0 zFKSO)7^6kL=TOsfjiah4ksi=SO3Goyj%LCs1=?CGJ~^HQYn53~*Cp}3baQ*3AECld zH81n7JaT=k(cpazpuWtCD4o1~O1xAUkTI7_5}@(a2s&K4K!*0<*X2cw4b=cO |ad4%%jN9zeZoF)|u!Y zi1A;ViI7~Do4yXXf^xZJAOopj)BI}pcQipO;``ZdPvF#JZtj+?E-4S#zahDwrTk1; z=Wy b8@2etE%%e^$J>0tAIFQL z!qG$1duc&$YHu_yb>1|VA0{88KHp1QA*aUt2U`Yt=f1i(3|=*UMUHokJtFl%MJLed zmnErWtR2o@RE`6nEBV|>broz%iX>`Y8*G>AFvL4c{#rwp@NYzRME}(!s|dXw$sWLs zM63se-ty-`8gId|&x3N1k^jan2uXkPs#{N-fmxR%Tp#T2{-+d6YzRXC&;KM+F$U5S z#fqC)@c((B;c!xUZP4db$MK66`Bo zL(7Ab>aCnWIGkzkRKFx!OUr~`4@$n81f>Nn$0N|ABoJzA$h_VWgH?JqoI0DN^+O?L zlRm@f6VBI*&hJTf58`#Gce8H)P_K8PWR|Y@+=*O6v-?JLlYS$s?7ff{5&7xa`}bsn z`O{d(LgK6f-%1F6T(T%%A-=p4-fkG1X!g&Jo3uRxp|`{@oTn?!t{Q!;nKe=xmnI`d zsd})B`oDHxat=5WLS|XJNucw6AYfGJqzEpSOi6%bqSM zhsvMBB(GFMu3j-*T-6`GPMd#QhUCPOSh|aT)MV}DVBv~-biX3f%eXJHn2n1Pe>5SL zl1)eztm^;+e zpCDkgj-j@`S6-6f+pSo@TA%tYQac? z<9?I gQB4Tx~J)vGWurcV+G0J$sne*8QbzA+?!L%Q^`%pG%zIB16l`P(7Cmmr>#= z&VsB2w(~yEHDptGig&>RU2jt8utg8%!rzxgu)9b1FLq`SM5O5BwFzQ3G@au4J-r)= z-gQkrWP{7C@XW4RR>?`}@TFfa)3tt7kWvNbBdNTsqgr)2AD47o{VDK}r@QORx+rnj zoO;)>l`6lVHG1$v^sX=xU_}tUCV{T-!S!!JM}?3@H*sMuU#)v`k_(Zlj%B?2y}o>F zx(~tqmkBBkDyf199YzWcgumYOn9A>8d$JK5Ym_PzA_RC)nMkI$UF;(BvN$LYZ8Xz@ zby&=4;M9C0sPSEU=>EI0KX0>)D`E%pT5D`8fmwC2*M^K6@So~7brl;=wrK50=<`cV zU~#y8LAV!XWbT 4OV79X!_3e9GrQ3oJKNBQJpg>pww{Zk;9fK z-H&Ts#?WiA*OT^ ^B_`=wn8X54$AQ=1YzCA6oYC bNcK6p6d;o#y|vP{If zZ;q<>8VBV347~Hd9!(4r3$8qmkfdR8ElXiVpc7#wEaUNUC@HNV(r%hS^WUoBc6a5` zgA(u{Dl*m*maxqy4Pr7uL7r j?Yx&Np z!yXXed1i3*t4Dm5ytd0PbS^8Lq9zv~d2}PO99Z@d(h<1XGAe)NomP(u2Rz{jt@DXK zq_O*J#HpL!@nK2xAI%}W+%x>{02O1=EGl<_g8-X@`pE7mhoT?xz)MeBTTaB;;^&e3 z`7(c>i-i@1;8oLLa`M-OKUdPaRegUAsPplfJcYBj^aKwC%VE+(6>%i_WqueH=0xmU ziF`+ZA3*>*N`Z%T5GRdJlrwg&NJw;=qTSEZW&9 Ai)?MhOCJ1BAW^0nQ^AoC-gd(te&ihZ}?Dn2}|ltxEB+yh}qK@z}={$Ck>EM z3guf6OhjcCfKSix0Hh^=6SlKMFb81(zA!OzO%7N5O@ja`lQ2(>>9#hgq1mP#ahNW; znoX5}XweRFpL8u|Qc`uhW@^Bo2?`nC@WKGsgsP&e5(w%@-6T3uf$JN}VZP`}j7FXV z%FC-kg;B=!0KrfRQ;)J_$wsOiJ=OsUk$?*^(g7C9Q)0<}@Llhi`cudo5U3?CMIC*2 zHMb;6nl^j(x9_@E&>Xz-;Z0%r`!?Cbln1%?XplzEm4FrT`w1>uIzCVnt<8RLvKc$d z?qfs(b)uq;UT0y)+Sb4KldyJxzPi-?&EjvO!nc@k7Wf8*0HbYvLl^$I+` WuiszmY?EoCQvzr)X(a>*>p dHTns@XfjE6Zt7}Tl#kWEcncg6$Nt0Kwy8Lj3e)7m%ADZ)_w?bu#Roxz zjOB_KJe}kLDDgE1h<3Hlk3$+?Zdj{1Vc|NLoJiH1m0tp`*%A6*@o+1DP9*(78gKkY z?Qp7#%37DYrZIbof;sq0?OF3KP57H)X2a4a`z+CkSD$Ep)eh4eh~P#b9w$dR!}2yO zEnNZk6gH#}1%#d}6w N!8&Ox2`P;F$eP%q@f@62!BaGGD%e3zRMvZqxPDFNEN)O zT(YiK)mbjkd2@QCekr~+PD_9ute}rs7b?$*bkd9BfTv|Q+NE!YXtT@MNglQ5bC%JL ze#FHQyR-gPnqH(K|B}5tvgQ{1ZAVyZr+tLQQVq-vjy&o2D)FUwqp-_Jg$JEXetlLZ z5^kc{^#J^F Q|vx576aqIO9zv}^5r82O* z_g>!f=#K#c_yl02LSW4v*Mu-a3EY1R7}I_EkGMvPz}LOo^DjR@VT5(K=kl;Px2&q| zWe_6#uNAKDEPyLJ{ss*pxCNvB=B(e=F-AWQ2N(R}*SWwjC181;&*y;_sLhN3aHn0% zF!2Am$$Egl76Iv10$yYR7EK77ghY&4E1H$Pd=2T?u7Wl0!(bTI8J#gj9;sQI0wa z$(l*@nrv^#$VzLLR>hEvG&mM}+X=d_n0&f}m52Z#3s5Zn9^+`}@!0nscC 8g{-FEumUH$9sSFhXE{&QBw|3Ko=i)ur!l57VV?T=1X0QEaxTX 7(w_`_>zta7c3l6T&J=(@ Sm$9nPor>&rc6p2g=`3f&_7hlzN}^qjVLr{wJGDs uiAT#nirr1weJ z1T^i&s%JK3aMa~mJ8Y!hd}ESFK5G*3CVYSxMgn7keAK!8;Fi|Z<$uD14SJiUeP{bY zEs1rr>TkV!kId@6*~c_Crmk$C#%bnM mTy@A(D?SfXb?TTf^z89E^}3!Tl&lCVqPolGPX#T`q!Ch-I8Yd{AM@ZoBpg zhY-w8H2q2}#7ezd+_|RrQL 4>P4rT2Y_5CqPf(UzM;_yv;={porQ!0@05Ze~r`R5fopcO8roM#zc)zUJ|O zRkfYMY=mndB! w*YI zI7kemra%BWR5-X{u(zu#UGE@6)qc-DM_ }0P`EE5Jb^Ge7hiw6Gp+Xe4PV% zQzKuBc{L8u7G3J>UC0CTqL^zX1_4kQ?LcZhhGomQb1VZBWlh=ls@yZ|9p$uZ#h#A; zA~gc)sTLXV0Aj!zLd=A%v~i`;kytiVo6F$HleyOd6Z6p^|DGQ5BGoo9i4Uwb`08Jh z!Ljl&Sx1`7zJVP3qf%|@?tj1CoKPu{Wli?!rz@v&=P`p8K&Dbt-XuBk6V`0$>g$^A z_~f^}yqaxR+qlJJD>$b;-EaBD|9LmhqC*KCh{Xe}-4Ou(|1K9F2Jrqj`53UgZEZ<_ z2kwSO{2y{N&_;rp|Dzv0^~A@5BRO?CEg!Y8MZLcLZ91jqXVXmmr}s%fI|+>XRbk#4 z51(X+b%EMyoUo7dUkc3fW1eEWDq$zG`DwkY>o{pXcHQWBt4*~-l_y3h-?4f-dVFpO zV#q TjiF`?Xm*%DIw+?(&vRXlR7UB)m%teh?PO`a(eu#V*@B;mdGg zKki&Qu3*U`6I5I|wZxFK)U^}!{wAkH@zU6#63{^bYV)TfQWKk^_+69lH!7dvl98rz zRTX{#M2} c07iU=QD=4ndg4Qed%Lc|3_!^19%+2N%Aia#rgmk 07m35zUIXSQYviylw8Ce!{Obl~o{b>Dy z7gVdr;n7*-vK4*F^4Vyl+9r}CA!<;Rm7`{~lEbZl7i?}5I4Ax$tSCKzOF(ij3crOG zQ7j7fyF_e?vMtf@Rq9-2M 1}J =!HBHa5{r8u{?9WN3omm#$&ifY9 zsmO+G(=3e-MrsQ+{fx&y2X|T2Of+FkiD4YO_9bs2`_uPuRyROtjX^tN(C-hVZXnDO zz*vRvwsc)Q?QuKWzkJ+WLl^`D7yiy7&?k&9xp5|OzbyjtfEs6${(i-!{C&|u;m+RG z)ZVMvM}Jo*IIJo&jTj6k;jPW5t)xX}@S@$6bd1b&v=iZmnkc?}!P~R~3*j*zxlNt7 zOzrOMrNt=QIO)x%*GaT)u O7SSe!)8{{0e1Ckw01PWd zVJLc)N`RpY&W||nfZNi?Rsvf@v5D6FSokLvek^9j3vJJ2exrRHN^8xuhda ht DV$pGU6o{z&D-=K72}KbsDHb!IlCcSs{O_+G>@4WOZOatq&DH(Bm-X1_eYClQXL zCY5(|r*}JR+4N71AR@DYdj7=iY1kY~v^EBY0K-+Gx4mUxw6OtNI;b^rbI}kx4?+6V zgArS+%^R`8uY`?)3)QP}```!q3tn8)Ud?~~m0m*T!_O_oFT82j98jj}0WvvDAAbC3 zxr?XmJ+>ax=O$ZO3$OWLf`A_T&TOdIk)_xjpZ?h(wV1YyOs=p_8n!%fyKu%soz7py z+xS(z-8z?SeM5A5>rU% $OY<^qVLW79@wW^`HZ^V2GP4{QaX*fSHXyrAD4UjkP$rFaHGoEt%64 z`^W#7%a5*{aTJGBdxEc_Fvk6j2@XC%I_9EWEXi+NM9ApWkl3jbZJq6QixSU3c+#V5 z?U4@twH=pd>)(dO)rh{6JnUsu1vC4JZ!Rw|dCHHEw(N8w{8&iFn-j$EFu664wCt4n z?*HkJ3?6M^$5s-}w~InF!2*o@z-F|(oXdcopkl)3aNq66^qZncu!E|LuFk$_-n OiqZ1+zt; 3Sm_g{8%aMTU>Fxi3yU@gfd**y
$`dfEHd%5@|idZOoHJ!>1bdsQx6v z^V{Z|Q&PlL9k`K~q9Q8j^%3Nn7ze^g+m5>19jeYOfH_{`hP#+p(!&sfS5|Dspa;kR z9d;%d-B758%iSqN%&=7z=!^Nbzc+@Ltrr{IbwGgD*9^!8=b6WO@S!+3wz5bAoyfW0 z7oA9+C)C3on?k7In5 &pF9KX(*n^92ziGoh!U5KZ&(uS5>n^H7bziQu4UHFj02$&_Bdb7c;G2HI zl;&^e_M3$Nw8@~v(!{Gzdy#|L86LEsQb7nq3_Z9#CConmq{qI-{5OklI81UIcEDkc zw eJuVcmk2ZX?5!6hk>EE` zHT&B!=^NkPd#&aJj#cdOwCdgVc}ci^UP5$NZxRR`WvS|T%=1Uns+*2H4Sf$a%+KLw zBE9`~FLy4>!~WBj=&Wb3@qbiBBYEAZq^9QMVVF2n#-}Z;$!=-7_{&7n%mbZ?V4?ih zl4sc_O$` dn=lE1@wA59<*oh?zkeID2(H5(F$KTYAjJv6w^I<);Wu;iqC?q^P2FsG`e zQej6G_if6&CrY(*Dp~MPG`K-paA^HC9&YULRg&?U8F^j!5q?)+YCUxFHqIh@h{aYe zuG$K}sJ4DkEchd;h@Y2G{nO@)(B3pI_XiGqIGOn}#E*D07@2M!(JpLl3?9Ekbqmv4 z<4)yhVV%Yx%0a;xB(;IkVlJ(q_u^3hdxIvlwj=WkZtAj t6}SzL{!v%jADt++Ld+M3>i+VN3fxx$ zj95NQ+ibSWzA~Ti=SR@O@^Ev^ohZ%t>4fDMBzD|F_4*|&OP?ieI6}C%xn|y;snWGy zG`(u^-(r(bt$`=wwi@)?g8q1(ln0lq3u*gFujT98Qq~sbD%Se6HM@QU%O6`k=B(m~ z1V}DQc_rhKRMs6Sy Zd zXO{@^f?i)(gmS#HrKg=I{rVOtrpAm0fR+`Pu654N_gcs5H)p0|;Bo`+y#C nW|Djzpn_|Eau&>-lCe9xEj>Sty9xnl z3eoW17ANsyL*cDr$2WTD!Dtw>#DHc>fb{E^07_ z-){BvMk*8&t|m}HrGkdIau!Rt+|K_+DCcT1sK_Nz9P%?t*Gca4z8r!p2Q$86ES_sV zpb)N@dt)FWemvIGCK4s3mu8232^X&u#O4>l#ZuNKVTcxf7-vsfKW U3+uFa?S^*z5gV{w(n|G{Ii>siuvp(++3-#fn` zvxr7@R|57@B1lz&%}46$-zk6FmkFeNYRDR Pp$FC)*ETANKQZNp4wq$WklZO5p`;YM89@2v3Gq+;1$Il;`}g2K zqZm=DGb2-6wCdHuVpB^lon>kN)o&G&TWEk&0!=nLRyUBp{@b3`_XPxIy0fCMR2=dW zShXPwm4h_!9&U;1m(0e?+CR{F7eB3V_u07y>zn}_V)8H?!{kr);SARx?BM}km;dYk zbXMd Xe>s1M$SNRqFk~DBJ{Q=r zfBKa6--ICuw@ppEg|qGdkG1$8bMi_V$~=zGNb-me dlVi| z589GNC}Ibn;@m+YI)Re91b{-$lU}+nnAmP#2&Ky8554^)cK2NJ>ygHVAuYzv7?kML zk8sNWQUa`wWPV}Gz1OyA!aseTrXpq~U|3FT)Vp0<{Bbn)wI{9CX7lE}T;s35S$3T* zln?%>P>kMhB+}j1LZ)O2b5uQ+kh`@{75#-Q$EEGVGfjsFhZ?3q;m2BnZf*7x=|_J` z*q`HhSQ<+P@%LC?`P;CJmVc%y@mWBb;y==0Pr;fU9W~mfzIwjjDJyhmd-PEGR*DvR zuznO7*0r94Q`f1?k|ywKU)3Ca`;pblNzcFcy)g%DsG@6vm{E%hyVYtH&svy`-|M-t zsL0U5FH$0Vw?|#1$1@Kb0#>W%`F5WRZeGhq4{`@O;}}E|J7{rXgp1yk3- mL z1))%0E${gH_gdt`0k@%oQf@AmuT4#TrZX6R9z?&BpcV+pT-rT!cMEqWObMNuu1;Ra z8`q)ivDf? v7BPF9Y{?vQ9!JxjyzxN#gh2;0hujO$qY+S(E2zjZ|gpzG+~v^Qqte z)23JaBNVfoYX7vm@;W0%_5)G6tH}GVKb|kutJ|-VOGVvop-xv)ZU~t?EWGk6lVgix zrp2@jMz1F*gWL0L@yWu41N5j<$h~tYr8R~0tjG2(mIhC&EJ>FVwxEv3@}DcJ#2%%N z|KP@&y-is N*RCX0ucy%F7Mk0&37>ViEv_+kvbn6w8Mzv_RM+}t06% c(UOw9-kMtZtc$pyn&Y7s*TuT;kmo=|=Sm1{$ zTweuu23Z d=6n3aiggbC1hv 1S4xm oT=WaYUxeRu(5L)KcWV=GzSg!+Z-%~+%{{R z$f@9m%&t1OwFGE+(^#4%Sz@eW)}y-D;Z+}SA&x;_@rSkUnTbf_I%~s6-A|$eS1$st zj^^;aAWK_RX_7zs83`VB7@#Lc@3OxCfwjC>g_)!hm{%WoK~^kj_>Ng%gF8&!ey{A7 z!PpVGEb4jDi1%AI9