From ee6414e2cf19e39d1c1801a5e67278ebbd0b04f6 Mon Sep 17 00:00:00 2001 From: Neon <10284121+neonspectra@users.noreply.github.com> Date: Thu, 16 Nov 2023 16:10:18 -0800 Subject: [PATCH] Version 1.1.0 (#1) # Arise v1.1.0 --- ## Changelog - Bumped `actions/checkout@v2` to `actions/checkout@v4`. No impact from this change. - Removed `sed` from the metadata tag evaluation in `build_header`. Replaced with Bash native pattern matching so that this evaluation is safer. - Added checks to automatically rewrite any XML reserved characters (&<>'") as their escape codes when present in page metadata (title, author, etc). - Rewrote the way a majority of the page metadata values are parsed in `get_page_metadata` to make the parsing more robust. This was necessary because previously unescaped double quotes (`"`) would break the parser. The workaround was to use escape codes, but if we're automatically parsing escape codes then we need a way to put these characters in unescaped now. - Added a CI test suite to build the default site and test to make sure that the XML reserved characters are getting properly escaped. This is helpful because it allows me to more continuously ensure that commits I make in dev don't break the site. - Added a Smart Deploy step in the deployment workflow to check whether the triggering branch is `main` or not so that CICD can intelligently deploy the site to either production or staging depending on what branch triggered the deployment. --- .github/workflows/arise-deploy.yml | 25 ++++-- .../workflows/ci-xml-reserved-characters.yml | 39 ++++++++++ README.md | 27 ++++--- arise | 4 +- arise-source/config/footer.html | 2 +- arise-source/index.md | 14 ++-- .../posts/ci-xml-reserved-characters/index.md | 17 ++++ .../ci-xml-reserved-characters/kanagawa.jpg | Bin 0 -> 604467 bytes ci/xml-reserved-characters.sh | 73 ++++++++++++++++++ docs/guides/creating-arise-pages/README.md | 3 +- lib/functions/inline/build_header.sh | 42 ++++------ lib/functions/inline/clean_xml_string.sh | 25 ++++++ lib/functions/inline/get_page_metadata.sh | 50 ++++++++++-- 13 files changed, 260 insertions(+), 61 deletions(-) create mode 100644 .github/workflows/ci-xml-reserved-characters.yml create mode 100644 arise-source/posts/ci-xml-reserved-characters/index.md create mode 100644 arise-source/posts/ci-xml-reserved-characters/kanagawa.jpg create mode 100644 ci/xml-reserved-characters.sh create mode 100644 lib/functions/inline/clean_xml_string.sh diff --git a/.github/workflows/arise-deploy.yml b/.github/workflows/arise-deploy.yml index bb3e791..4828e1d 100644 --- a/.github/workflows/arise-deploy.yml +++ b/.github/workflows/arise-deploy.yml @@ -11,11 +11,6 @@ on: # Allows you to run this workflow manually from the Actions tab workflow_dispatch: -# Allow one concurrent deployment -concurrency: - group: "pages" - cancel-in-progress: true - # Default to bash defaults: run: @@ -26,8 +21,24 @@ jobs: runs-on: ubuntu-latest name: Deploy Arise steps: + - name: Check if we should deploy to prod or staging + run: | + echo "SMART DEPLOY" + echo "============" + echo "We only want to deploy to prod if the branch that triggered this workflow is 'main'. Otherwise, we want the site to be deployed to staging..." + echo "" + if [[ $GITHUB_REF == 'refs/heads/main' ]]; then + # Feel free to change the value of OUTPUT_BRANCH. This is where Arise artefacts will be deployed for production. + echo "OUTPUT_BRANCH=html" >> "$GITHUB_ENV" + echo "Workflow running from main branch. Pushing results to production deployment branch (html)." + else + # Feel free to change the value of OUTPUT_BRANCH. This is where Arise artefacts will be deployed for staging. + echo "OUTPUT_BRANCH=html-staging" >> "$GITHUB_ENV" + echo "Workflow running from a development branch. Pushing results to staging deployment branch (html-staging)." + fi + - name: git-checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Install pandoc run: sudo apt-get install -y pandoc @@ -39,7 +50,7 @@ jobs: uses: s0/git-publish-subdir-action@develop env: REPO: self - BRANCH: html # Feel free to change this. This is where Arise artefacts will be pushed. + BRANCH: ${{ env.OUTPUT_BRANCH }} # If you want to change this, change it in the step above. This allows us to intelligently deploy to production from main or staging if we're on a dev branch. FOLDER: arise-out # The Arise build output location. Don't change this. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Handled automatically -- Don't change this unless you're pushing to a different repo MESSAGE: "Commit: ({sha}) {msg}" # Copies commit msg from main to the deploy version branch diff --git a/.github/workflows/ci-xml-reserved-characters.yml b/.github/workflows/ci-xml-reserved-characters.yml new file mode 100644 index 0000000..d0784c0 --- /dev/null +++ b/.github/workflows/ci-xml-reserved-characters.yml @@ -0,0 +1,39 @@ +# .github/workflows/ci-xml-reserved-characters.yml +name: CI Test - XML Reserved Character Metadata Sanitisation + +on: + # Runs on everything except the main branch since this is only a concern for dev. + push: + branches: + - '**' + - '!main' + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Allow one concurrent deployment +concurrency: + group: "xml-reserved-characters" + cancel-in-progress: true + +# Default to bash +defaults: + run: + shell: bash + +jobs: + build: + runs-on: ubuntu-latest + name: Check XML Sanitisation + steps: + - name: git-checkout + uses: actions/checkout@v4 + + - name: Install pandoc + run: sudo apt-get install -y pandoc + + - name: Build Arise + run: bash arise build + + - name: Run test suite + run: bash ci/xml-reserved-characters.sh diff --git a/README.md b/README.md index f8b844a..4ac2611 100644 --- a/README.md +++ b/README.md @@ -7,22 +7,22 @@ ## Overview -There was a time before React, before Wordpress, and before even javascript and php. And the webmasters who ran the 'net back then made do with what they had. They wrangled their webservers to the fullest and they hacked together sites that could do what they need-- somehow. +There was a time before React, before Wordpress, and before even javascript and php. And the webmasters who ran the 'net back then made do with what they had. They wrangled their webservers to the fullest and they hacked together sites that could do what they need. -The web has grown up a lot since then, but unfortunately many of the modern tools we've built on top of are just way too complicated to maintain on the day-to-day without a fully staffed corporate webdev team. +The web has grown up a lot since then, but the mentality of "move fast and break things" has created a landscape of flaky tools never meant to last more than a few years without constant laborious maintenance. You should be able to run a functional and pleasant website without needing to be a fully staffed corporate webdev team. -The goal of Arise is to take the lessons of yesteryear and make something novel. Arise is a cloud-native static site generator written in Bash, designed to be a fusion of ultra-stable timeless 90s technology and modern DevOps paradigms. Arise is designed around use cases like individual blogs and personal websites. +The goal of Arise is to take the lessons of yesteryear and make something novel. Arise is a cloud-native static site generator written in Bash, designed to be a fusion of ultra-stable 90s technology and modern DevOps paradigms. Arise is designed around use cases like individual blogs and personal websites. ## Why Use Arise -Arise is written in Bash with very few dependencies outside of the standard GNU toolchain. Arise is designed with longterm simplicity and maintainability in mind. It is unlikely that the core code Arise runs on will break in the near future due to language or dependency updates. +Arise is written in Bash with very few dependencies outside of the standard GNU toolchain. Arise is designed with long term simplicity and maintainability in mind. Beyond just being a static site generator that doesn't suck, the core development philosphy behind Arise is to minimise the risk of breaking in the near future due to language or dependency updates. Arise supports modern SEO features that are built into your pages out of the box without any extra effort necessary: - [OpenGraph](https://ogp.me/) and [TwitterCard](https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/abouts-cards) support for rich embed details - Dynamically generated RSS feed - Dynamically generated search engine sitemap -Arise is built to be practical and let you build a website that actually has real content on it and isn't just a single-page placeholder. Arise uses a modular page architecture with support for dynamically generated metadata-rich index pages to keep your site hierarchy traversable by end users. +Arise is built to be practical and let you build a multi-page website that actually has real content on it. Arise uses a modular page architecture with support for dynamically generated metadata-rich index pages to keep your site hierarchy traversable by end users. ## Live Example @@ -57,10 +57,19 @@ All of the documentation for getting started with Arise can be found within this - GNU `awk` - **Used for:** `evaluate_inline` - Function that performs inline bash snippet evaluations. This is disabled by default because this functionality is still WIP. - **Why:** Using `awk` in any capacity is the equivalent of staring into a horrific eldrich abyss not meant for mere mortals. Making those commands portable is another story entirely. -- GNU `sed` - - **Used for:** `build_header` - Function that populates headers with metadata from page source files - Dependency for the header metadata tag population. - - **Why:** This script makes use of the GNU version of the '-i' flag. BSD sed will not let you run inline sed replacements without forcing you to do an extra file write to create a backup of the original file, which you then have to run ANOTHER command to delete (literally why). +- `sed` + - **Used for:** + - `get_page_metadata` - Used to pull out the metadata header in Arise markdown files for further processing. Also used for cleaning up relative URLs generated from folder hierarchy. + - `build_page` - Used to pull out the metadata header in Arise markdown files for further processing. + - `build_sitemap` - Used to clean up URLs into the tags RSS wants them in. + - `evaluate_inline` - Yeah, I don't even want to think about the horrors I wrote in this function. It's not currently in use, and I'm pretty sure it will get a full rewrite before it becomes active, IF it becomes active... + - **Why:** `sed` is useful for parsing data out of blocks of text quickly and easily. However, much dogfooding has revealed that `sed` tends to be pretty unsuited for this application. As such, it is largely on the chopping block for replacement with native Bash pattern matching where possible. + +## CI Testing + +For development purposes, we use CI testing to ensure that new code changes don't break Arise while in development. CI-related scripts are bundled in `/ci` and CI-related workflows are named with the convention of `/.github/workflows/ci-*`. **As a non-maintainer who is not making modifications to the Arise source code, you can simply delete (or just ignore) the CI tests if you don't need them.** + +In order to maximise the amount of [dogfooding](https://en.wikipedia.org/wiki/Eating_your_own_dog_food) we do in testing, CI tests are run against actual pages bundled as part of the default website (https://ari.se.net). This means that once you replace the default site with your own custom website, the CI tests will break because the dummy pages they rely on no longer exist. ## Wishlist / To-Do / Feature Ideas - Refactor inline bash evaluation function and enable its usage. Right now it only works on very tiny/simple snippets. The main reason I wrote the logic was because I thought it would be funny to implement (it was). Some refactoring is absolutely necessary to make this feature practical/useful and not just a good meme. diff --git a/arise b/arise index 4eb863a..5217277 100644 --- a/arise +++ b/arise @@ -1,8 +1,8 @@ #!/bin/bash ###################################### # ARISE -# https://github.com/neonspectra/arise -arise_version="1.0.0" +# https://github.com/spectrasecure/arise +arise_version="1.1.0" ###################################### ############################################################## diff --git a/arise-source/config/footer.html b/arise-source/config/footer.html index 9fe5c3e..7934749 100644 --- a/arise-source/config/footer.html +++ b/arise-source/config/footer.html @@ -1,7 +1,7 @@
diff --git a/arise-source/index.md b/arise-source/index.md index e922431..801c42d 100644 --- a/arise-source/index.md +++ b/arise-source/index.md @@ -14,17 +14,17 @@ rss_hide:: "true" # Retro doesn't have to be regressive -Arise is a static site generator written in Bash, designed to be a fusion of ultra-stable timeless 90s technology and modern DevOps paradigms. Arise is designed around use cases like individual blogs and personal websites. +Arise is a static site generator written in Bash, designed to be a fusion of ultra-stable 90s technology and modern DevOps paradigms. Arise is designed around use cases like individual blogs and personal websites. -You ever see one of those nineties zombie websites that hasn't been updated in like thirty years but is still somehow running today? [Stuff like this](http://home.mcom.com/home/welcome.html). Can you imagine a modern website lasting that long without becoming a completely broken mess? +Let me tell you why Arise exists. You ever seen one of those nineties zombie websites that hasn't been updated in like thirty years but is still somehow running today? [Stuff like this](http://home.mcom.com/home/welcome.html). Can you imagine a modern website lasting that long without becoming a completely broken mess? -We live in a world where the mindset of "move fast, break things" has trained web developers to keep stacking more and more overdesigned trash, one node framework or polyfill at a time, onto our websites. Over time, we've lost sight of the fact that at the end of the day a website is just a tool to share information with other people. +We live in a world where the mindset of "move fast, break things" has trained web developers to keep stacking more and more overdesigned trash onto their websites, one node framework or polyfill at a time. Over time, we've collectively lost the plot and forgotten that websites are ultimately a tool to share information with other people. Arise was built to show that you can take simple technology like Bash that is so set in stone as to be basically indestructible and use it to create modern web tools. ## Simplify deployment -90s websites may have lasted forever, but no one likes setting up a janky webserver on a computer in their closet. Arise is a modern cloud-native application that supports easy deployment to your cloud static site host of choice. +90s websites may have been robust in their simplicity, but no one likes setting up a janky webserver on a computer in their closet. Arise is a modern cloud-native application that supports easy deployment to your cloud static site host of choice. Simply fork [Arise on Github](https://github.com/spectrasecure/arise), edit your site, and point your cloud vendor to your repository. The included CI workflow does all the hard work of building and deploying your site straight from the cloud. @@ -38,11 +38,11 @@ Arise websites may be spartan on the surface, but they are designed to take adva ## Practical pages for real-world use -Real websites don't have just one page, but rather are built on top of hierarchies of linked pages filled with content. Arise builds websites that are designed to be modular and traversable. +Most projects like this are one-off tech demos. While many of them "work", they often lack critical CMS-style features that are important for actually organising stuff on your website. Real websites don't have just one page, but rather are built on top of hierarchies of linked pages. -Arise supports the creation of dynamic index pages based on individual page metadata. Just tell Arise where you need an index, and it will build it for you all on its own. +Arise solves this problem by building websites that are designed to be modular, hierarchical, and traversable. Arise supports the creation of dynamic index pages based on individual page metadata— just tell Arise where you need an index, and it will build it for you all on its own. -For an example of what the index pages created by Arise look like, check out the [Sample Posts](posts) on this website. +For an example of what index pages created by Arise look like, check out the [Sample Posts](posts) on this website. ## Get started with Arise diff --git a/arise-source/posts/ci-xml-reserved-characters/index.md b/arise-source/posts/ci-xml-reserved-characters/index.md new file mode 100644 index 0000000..9c92c99 --- /dev/null +++ b/arise-source/posts/ci-xml-reserved-characters/index.md @@ -0,0 +1,17 @@ + + +# CI Test Suite - XML Reserved Characters + +This page is part of a test suite to ensure that when a user tries to stick XML reserved characters into page metadata, such characters are properly converted to escape characters. This way we ensure that such characters don't break the monolithic sitemap or RSS feed. + +The way we do this is by having a test page in our template site which contains a post whose title, author, and destripction all contain the XML reserved characters (&<>'"). This test suite verifies that this output page has all of the reserved characters properly sanitised to the escape code versions, so that they're safe to handle within the site's XML sitemap and RSS feed. diff --git a/arise-source/posts/ci-xml-reserved-characters/kanagawa.jpg b/arise-source/posts/ci-xml-reserved-characters/kanagawa.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c7ecb7edcb7d7e67ffe01e8340df2911cac895ff GIT binary patch literal 604467 zcmb5VcRU>L7Y4e^>b-YXFVVviB|3}fC2DlvuzHQG&Whd%5ecGq!mbj%CWJ%;u~>qL zvU-Vr_jm98+E%vK%b83=d~6Gf239;?aqU+T{}cYG*io5dM5W;EkGI#uy9A>?9359H-5ao z%`N!v!Ukn7#k&^l7aRh6uc-$AZ7LWskCw)QX>s)x=;NDpslODo!Fg(+xODgHy~7QoqQ=wTr(85y>N2d z5I@`2`tjpSlX`~yIl&bS-a0Xr;G3AdxmEN}bkuJA8zq9^VPnnIa=IuVv0h61a>vk_ z$)F3aE7WH6U#s=Goe`HMwpgO`-Uah)=^Y^w+w2J5rz3q_n+e&UGoWX+J5LoT(q3JL zlhoSPR?iTd`u6QaRWkfh=wxzaX0k`(yc#*)2i@F!_bhWjxt+w1t5xFi=V*7BCg7R1 zs^H%U Ccgd{wt^5NEnRHC3&pHlX5ekhg|K_>! z#z~*1M?p5k`qW>n0xKVO-DDJFQ^8W6^Hr(_=j$7eWe{?HZPiCVeY?G{adzkKR&1;Q zH-nc^=PC&xFrU!4QY&;$>%fcgDAQ8gjDHHlWk>VjsX8A-|DehH7P&>N-FjutW|woL zYKu7<6f#)kb2Jso#})o>Log(j n7JAL_fdWyC#)S3m4 zu{B{9%6rMK@aK(QG0m^GsfzTn?rlZvffpZ;_t!T@Hn|T6IDz{*!BTsH&1wn&+IK$c z%9`h;T^gwsjf$Ek&4#AUUb-qWXb~>8C?^e=xCCqhH$1a{V~pO4{@PIQQb&;OEYa-y zLGt2~Xx-8XUeA6yZ*MmB5F=$Uk|7k0+_uf}x%N)TV637Lda=x8y7=e!J-{| u&D(}ClL`n{|Ni@x hDA*m;Sc*MJEwx%A@`gI-RpW5VjFq*8t1(G+{4bNw>o<1=w%Wff zJw(69mTh+ME!f^%jHNV0BfbxMAvI8)i )NH8nY{^#tZX4y+-qd-kqU8h !mOy%I9^cyy#4m2oACXNT8rpg zyLt)V-00`5vX`U@S?-aD&GZQJUOfW$hj^UG+e*sNSPH;p!h27z z_A}IbkG-u$hy@9K`~;Bwq5hkku%}h?u2O#ZhcCh4vgtX|w2$?RAk1-ZxhD&yHHrNR zk3LbO-cC(468R*qQ1Z;@L(>}kIwBy(k!1p5CVYzji-cA7u}%gX$P2 T}Y7`aK_iv?`@ureU4`IDE zR1Xlol7m)v=D0GgU&jE5gHZ{W&Mb7z`-wRsL_PWe76j4D`MGeB;tklliD+Z?@{5Mf zFkn#4SWsx!K2|c2Qt|0j! ISx=Gq{<$2jb_6S9BO$pkHe4Dj2a z=g3fzgc*}r-iuGMOFAPv>UXoT4-)Y*Id?W0UB=PG>BQz9)6-J>J=>MRk?Xl;GtIjO z$9XKLpIN2oxJFlc)swUdJzjIhAM{?e^|}42H4kw_xDkB$CX<7?qTjgeC~~TXE8!0N zv_b5)$9bu*rE!RnjcA(JRHAv>Ym0?X!8e>Y&&Tetk(0~I2|NoG**F>)nHO?@U`tKn zI=?}k`$JK#bWX;TlMEjbrtHXSJQgW=KY97yPjJ`prNf`I(bTuWpN(lK8X;|GnDZ$< zrlHpN3GS+KIvpz>Ay_%9H-$BSeqr`vG7Cp&5=G9R &w;;lbocPhF;*_DK(P|HLlk;@V{SVjC{$KqHP$OF#!|yLQ$SRJickWr`nvGmQflA zhu`F#^pj7n=h|qF2Kzz@(WK)Y#;H=bc9%ZFMwB5fHxLdhmsIy}i*Lw7HRj3Um{ m`sty{VohTY=~B~WFi9O8LhIhoR?)Ox-OOlLoe zPGcge;WIm4xWOxf1f3`k?< g)sNzAUjs(&bIh6z zwe`8wxV8P@LYV(pSh|ehV#=FQD3!B*P$X{fA>u#42AVb-@V#d@X7h$c-RLHQ3xMng zrwu;64;;TLxprxWZXqOl*&ogBK0gzv;(?^xhw6Wn`WEf^vtDzLxHl_ h+}&Ht3E<1 z0n)ljwha~GObcl&o%bif9StOh9#NOrXTCD|r8kQ}e4HmcG6WoQOe-A&!yiPL%>!q@ z4GV^`q1rsmNd(MBVU|*Y`)VjxG%xnj{^VTw@Z17`jM2;SL2)cx5A7?yeOs 8QTLtyd9c9hVQ$;{E@#P|0=FH8yWUDeb6H;#=L z!jIyj0BJFoh0#-N6l=kEeZ;9%pbpuRkzd~lmFn c5O+WrXyMN{vIyahh(prP!P z5gv%Vb`g5nUqePcU?-yEQt|SJ3tV?Fr7-$6bb6_0GBa%Bc-Xx_xuLG~?~lLcXps%l zr-6STf#K5G)W6~~&M%ffXuM&fUE>F!0QkiSE|#ULe)FBQ{!OJ5qWI{X;?h9&*X3UI zn?R^WaHxQi@;$@vZimH1*>a-E_#fywVs!So_Is(Tny>kKSgE1tB`hR)(x!|oPbmFz z=Yd8MYU3@KLTqkG8;5itT5-k-*|50Jqt;{8dS4Q%2KR#SXaUH8akBO%r=a5rMxB5L z9JD0z >TX zLPY`s5ven^&z$rMLse7A(D-<)R^fQKH`+)J95@j{wHhngY$ZDM^EEOo3gobR(*}J% zY>38ulE<69K}O?x=HH3CL*mM48=07cA`E!(IPR)ASMtYSY8DfgF2XyH;!)ov`@mry z$0M$Z%1Vo51RN=JxrWw;x$H-{efA|TP-*$yi(<$CCbvdx(Q)x$w1; VQv*bC(b;q=@&>>@< zoSD)TDtN)^6RxF3wz!-<1QN^EWP8ff`U~m@xWPLLYw>zBsb(up3z%C<(}*09o~_?Y ze7kHS&llmh<_#9`VgA==BwsVFX>++FP=qG<83e^=iU{%txZ5d_GljJiyZM8gOcG>2 z(^5z!E8DR|58fRLrz|3kGx5PkECa8OVk;hYDlORk82j;LF{Nm1VUh4k%P{4S5smFs zTC@YuAs{mHC36-X-I#1wi<9LQaVk+=$?2y%=#2kF0dOpJs6A~*Z;;fIio0^#INKhl zH9|LtqGayRRcnLr=ypLzvE^(3IlW5>z))qP{eVT2(*GUvIOWaU=NExlKlud&ThnqV zEw3{CBH9*cb5gySX3<5BLaI0Uvup7>Su=N%%5C&{RGlrZrsju7jYQ+$WTr0_5+7x4 z6E^aR+SF{TZ=zaW?4L)Zum`OphXZ#E6;j=3*#g`G+|n{EA^eRo^B&U+npaB0^-V@% zOM}>&jX%E*zWoejUXEXQXK RHo(d6T-EuboMPM#91yTi?HZSj0DWGyDjLsQa|DZ6KP2^R5PHrq-mrJ6RdD& zG9oR&j2tGzb3W9jv+obiC1 iV!gUhl!WS(|bLWI;j%Gpg zM#7a62aFKee`YL6+cC^bY2niv)g!`?4au99PjdGnWi;;|zOo;o$^9t)v!w=*6&}C1 zLam>vE) J7-Ku1P znc@3q8JTqKNW(q(qBioK>35WaZ(T#=Ot-p_J}uYyMZu1rWG|B87iQ2) a!i<8*g{z)ZU>@{>H7h_x&2*4 ==7an!DIRs6n#&7H-|Tei4u}s=sD*qnrpBlhs_GbDIIo>>!#}ydEoNM zhe=sUB*m?09)eN`rIjX qj&35LvH?s!Tt%^ z(wVT8#OUA$`k0^jFOWo&HTJ29uHaCwlep0f=tbna<;p~qcz0Fn0J}i-N<3=zV~zfp z=$B(0a%o^Q`nuf0BiK`YL?dxPI|SU&6j+cxuGK{tR_CoRr2tF6ZYT-5-XGH`AD8Ct zJI*$EaMD*EZk~7RrZAHeiCZ{>=-SzojY0td;VoE(fauNKVlm3sC>LJ@`ij^R{E*NV z?6ZUBf%NNeeS2%2WwL9ySk(Stm4eOQBJcSUY22$U)Q(=a>|3>Y8#-bI;;~^0R-hP( zNYz?T;_jV8OE&s3a$aeyl82ITL8x8Lq}n+Me(J<8cz4r7zCG*#VMk^^;BTq(eWsDh z7(SKs;l*pkewe>CyNJJ}pF`e%fTvV=;E#t50C5plKhujyhBM|qN!^nl92Yt4ifv@8 zhXcWHPJ3%D2aCowmfx|E!x@D?mngP2VARv)J qv Am;gv z?NmE8^Lz38f_dgL0e;8@{8usuHBXu !V4E=wAq)uEn?N?D*fj%xlWpk58CH%&P+i+2_yiSx72;`@@ zdf2bs%WofN;G&6I`qh;7po;X*7&@yPHFdXIx7gusR;he5CertLFUoX? b=m$dba~ykhoe1uYuZWSuoHeVl8Y6`0%Egm=5btNENvX($-tUfxgNb0v^8xVg>7i8 zzESF5HH@GB;dcuz2^Ask^?58%VfPeAZ?-$LT8ebai =pmQ%;l*3`wBJ?B|*L DmVvfxdXhiNC6jo7b`qz3Nhh|CU5^vp+4&CnFQH a7m>u5RY7>d z0BkT3Ec)g8mI>B5Fs$ELa(WasT$Ywg?Zb~RCaoCbYy9)%SK= cto @ Ji(XYPw} zw38x2RQv`OqX}^xURni^ANA|`-lQw&oBRp=aoQFw*IQdu+X1N(pZw;9^uENQiQ>x? ztvytvyII61jc5koyPAAsWo|9#dbIrmNLqm$HjlZ?lPyhh{Cx+3jBc@{?0Yrf)I#3~ z#-5{L_jj+j^=@1Kge;~HGM}$hG>;zu+jxfm{Q3{jfJzP$_i3{Ue~{PnA;M3+2Q4T1 zFLM_R3)oVr|Gc9?k~;iNv$B#|zF`mfs;&F-C??Cx2%K%$eBaDMC79_R2%d`IDOJzR zmZtjZN3_-da01E&!9_L*!a-_%TFod8Pu}3;<&uF^YU a~w zw)o0K{?%s{1cG6&AxeTDR~C `K;}fO9UItnse*0O{56y`%GGY9oCiduY}( zMW5`@Q}uYPDiB&j?un_Mf$yQ0uuLt{cKRO{8QmgIPy2_oIjDQ@&{>VEkB~>^;b>I# zY{K47moa%MxvTn7ovu=cRUquy0k(egdlxW3$0uecxb|Q-QPCE_(>{?b(}kH9BVLN@ zl_?yl+U1}dy6V+?&rbR)Iw&NUKPuiDgn2^x8 Ok5w_M756iGe6k$DC75QEO=47-z8>C7IA1P? zJT>>WT3lqnJAWnNWuo Y@<$u!fZQe8hsiE3Gws#M(hwd)EhB z4(y&u_TOX5Tla6}7{1}K7B`a+-3^bYo;}#&oc d1; &xMGmc@7vI0$RYk=yKur!guxw;vL(momoP5$6Tf|#x{;XUVs zC=N1{#H^mQHK(Dkpm13)yO{jstp5NhWZhTcvMB3k(|NXx`*k>s2+;l8uNJG3z`1r& zZ7dTdkuLebKPgYMuZ7h9a<7RK`|2xiDtMCcJn`4ZI)cxY^Zu|6;7EURY9WVEL+IHg zCTF*%D=MDM7F+sQZ_Kz2bJCkEhP}}8shz_pEdy~~sKhmkQl^#iAC(_{QV1|SZBnD} zBdE>N4plb`v!!a!Tj^+zX2DsE(%F^&TUNVg>3Y^az8EaCt41+9IC<#pP=DH~q_i1= z5I+tOZLuGjUG{_Ty;RTY7#|VV4elsx{g)0WoWm?jgmwqtSOnG7?&0 4m*U6=JA7U8NWSU_)o%X~4|rQ3UPIHa2Q=m5u!kb;V{PZWJY-=>wPaiytIzFexr zx%sK`O8pcyy59jHkvPWx8-Ob15AkHEb##E7%xZwdoVAd^+d9iHADv#wc8$RP4P@vT za5?GA`G=Cj+fWZS$VBO6#3Vp3x@?vgZHe6%!Fv6*Qc1wi^lU0$ZdW2%EGDd}>k{V8 zq=Jr1H>z!-IwGp@Ao2JX_e=;$+IPQ51}sy|_d&$^B6?#tg38x@W>MCQc1MyTx{XVY z!zNYMztlDwQ8VmbZSld*)i5(ot818C@VZ!gC*yXWBKgyHOu$Rn=6V>XV;rvo6znS# zp+U!;Eu)-ym?njy@}u$#*xY~=$R_V`bAFBjon9PV%T8;>@ac}G>S_vf0Ir%gy?(jC zS=xG g5Kd6ouo{7H?b_~nVF!b+eAAUBTYH7Jw@5f z4WO?H*gRRdWXzUr8)v7~9ONS)rUpY-sXbG@Jq*BpdW0q%je=sbRp1jh7cEbT|CfIH zXWz3J=OI}`cEXd+`zk_nbG*!fj`UB=u2w$(wKu9TG)^4M#@r@laVfH}ha@7I4B6Um zqp$a2!dt?kSwANzz{O!}moTO~pVP -7^ z^JQ(n4DnBOKEz;I@%*)1+!0&KmZWL6{$(-!d7p=DOVWou;n(iG;o*C}Fm`@VtBwSo zF$=iP+KS~ M9wkv99ih2&`ujTm%(`!ZRdBKF!3h3%*qZmLibY~jy%MqF=g2ZGAx )ExaBhwkfFe$n|6V ztlFDFQ7K4*pBb8W80sXeUs~Jg?HBroXtkJFFupSmWP7beccG=>sK!{uXUbm55fIW2 z0%Bc^1xCN~=!<|sd7P`^H*G`OztXE2H}UYifhGa7MlKprjwB-D1dIj={$o8`ot8_N zkxS0Cgn)v2HQp%SN!|}Lw%TfK7{_nCqhNuEleLFgEy{XuDlSHV7=1&a{OdV|r+{G^ z&*{1jg?Qn$v>y6{T-%BV7L>QlHPgb;w>B_nb;&K?@iZZe3gI24n>LC!W1Yh+Hd5{6 zI8=KN@3a2z3QvNVvM1RM`C1*F+cdtxSQq83oHB2Xxsqlg{{v`c2$$>b!TxvwYDA9k z-2>Dmr>V*Fn!Wei+XaIV@WkGzrsfvdc)4PA8#w+1^JN6BHZ}V3qdj0=s&(|V{mNiH zI)!B~gq9`%vl8jE9H^E-qYKx(clM()VBBjmu$OPnAO{lV_#dF 9S{2nHfOxRbh=8i?EX($_k zz!IfhBVq!ayoi7O5z{fAlKs2XZR-*0UHhWBqx$+LkEZz^uPzN-o%Igh zqJQyQ!e=|6lLZM-?2TQ2;!>sbV?Dk@sqa+4IP6bgGka?kZHL}J=B`m Bt9vw zoB25ZjWlL6mUOHBS+SD17VU;SiXOZBzSPD rUp0_Gz=lhVqx}=t<6*Ex> z%Mkut$M}{96#fGxIk0i*a_7dKgGVRIik?v2jU5+rGK|$H#ZowIUKB5eKkJQ4fc=H6 zNmI_NUw=hRaHS>WkMAZtTI2~8Z~*cuXWw^!43u-x&!v67K|iC*`N*w?75=1M^*RjA z!@Qar)|+V+ha&Oq{ttiyiU|}phzhmrXe>gAtqhvn@?h%H8bI#itDttWO ?UpSGEgnP_5c)0EMd9FX4}Ka^K=H6)#m6K^F9Mfdou%*xGB>%_|3 z9o9+fHD??-^PjuV?H(@V{E(e)AOP={VX1F ompXN*JH8`O3O_&9gLvyN67dGp9Y3`st5!nW$udd? zK+q~N&|SOl(yQ8s5oXh?JnaHsX4XEGx~i+@b?rda&wHaPyVQ16Uc@RNSrZjtyvs<& z>#rM0!ZQy$;%%~C0b>|On3oDFwcb38%_2fc?3-LT262%iFCq4ShwN?W=+kq3BKV8t zxOpmAA5=r8V7jj2RwIIfjK3G~#$K`F-CoxI(h9XVH`v90oO@N};Sx0xhf1m`yk1?# zG%yc92~?>EGpqsvD?;RAX=#o+Q>5ZXul>V4W$tL-^Hwdijov$ml74?`x$wqqY2=(v znW0ZuAZ+T?1|W8Jr3$Nx-{j^D74PpA`{jq|J~KSe>uyC}==H>2t$tY_oTlOC&UgAe z;9?bYwjwkGVPMy8#a3->?#0Kw^^~&%#@zGz2PFQ12)q;d!mvQ2O)(}a6PdC+y_Nka zjpO%%b~I-G-Cd#gK^s|>CSPmdXD&3i#S7fRC0qxi3hoO`VYP>DS6jg>@|BeE3)sWi zBrZAWHG0a+(>@+O+g#ml7bPmwwG2cm>9?#k??g5p`dx0chtC!AH~a56rkeeux|J~d zL-&7RucbL70%7>p2g@uS#(c=b@SlDLQzF;)Hhu+L6s`-A(;sLkAmA`5G&prOO?^9I zYvlQzJhz$aM?W428srA+BW8+j=Y2bFbg&bCphcl$dbBk=|J~oOJRFV2{ ~{7xQ%|5^kZ7*5WEPg3>^>(dlO_jZf31?sKh%i#1bU19rK|WPbC3pa)8ItkoRxeP zq3oo$*y4#VR9e0Gy(GePR+3v978S8oVUd9T`pZUQWiL_op#jhH4AYsg!On?k^ZVjR z2lLiWhIwVAhR(m1+3&Q)-AQ2A1?QXWswOZN=-ob|?#XtZp#N{g$^1u%Vq}iTu`Kj0 zq~+fCfrl1AND6!E7f;1EYeit-JH3mKH8oy=ZQIM`TS@vJl`e(%w)PbDr3MO~$K*_h zwYR2Azf@h+V({wF5P5zf9^*pcp>gr9<86n|hq}$xcm#7kQ$bSI=7NH%FGJz$e*#?3 zhz7z B@9&_H`>nM`?zUufb}3I3JJY z{J)$gz4eM;Mz&j!MaSDG*8%qq(jfZ-wa!{HbQTbIa0*4PG#r0`V=jJ^g}b{g82yeY zf`p+%TK~-qLost#uvaDY`DwoUWLIGf#|%> ;OyyFV5H?jKo-jpU=h(ZuUnRxSia>3fgy|au)j>P&MUzRnJbL0&dQx}DT z=$d8O$5V$#ejC{3o=#1++8H;@5`M8{f-75@MvS*CyB7#_*ud~(k6}!p2cM9@j{+L1 zdr@WdRrBj{K_IEoH`xaMk@SQNiX->7P8MH=;hQx9H(znfUI LTlxBf`eQzx}h#cTh}ME->g8e)cRf0#KJ0}JJtmFhbad40YA(~eJ5Gem-{R IrxGP3Ef?I~i zjf%KllzX<*S}mr8tKM+Y>a%FblhvKlvDro#APLb5w(k#HHZvWAw(tk1edVe05~KYD zoJm~L=_!uXVfVCozoQ%ON`>(i6n~NA#l}Lj2rAj^9e}d`nVYJ7wMjKGt;C6Y>CwPK zN!y*(tG<`IDbJ@FwY>jash6A)9B} MU1ah=hs3!(_&<*76ocAR)k=4nswvr zIl!kgLze;(XO<|i8h>6Bp!@P==xM*zcr)eGHF2)^zz*}=6Ahw O{=L>5$kl` zMhx0$%hlMmY9`y!zG?>np7WjKxQ>9{hu;^*!qp02I$z=F?d#E1{sru>I7A?-M crS>gqTqdx7E4Nq0^F)~n}N73 z4r=+RXx9KO>*^iAqw-p!RtfaWARvNb-!k+S@58#c;CXKFPpd7kb72H{8Fimherk&3 zXG>uU67Lqx{^040By5_EdDTEh )$)|peQf`s^ zD}V`J@dlMjEI9?kiE1I)*OUI3umYRgPgJvm;}HYI9xuu)u!fBT@sNf-ZA1~@&GM9; z*6~vw9e4XI+~=myO@8L)fR7#<1CJm%yE#*6aJ96SK _gKe(vk@S9BoWmMUJbyF&K>l(ua(={GHX!Bu# zxO)^>>wjW*2apiW)i00AbiG3;d;ssF4>i 1;}IG<{cQQ@Ji?Z&PB3X=yZPJ~BbaT{NL)gnwlJG9^xkLiV<<-qq@47b%Y8%H z7V~@|M5sD&TT=XT%&N(AxZw@$EeL^U3-{Wp0w1rUPKbq&5bKZQ-zFV?Obzvz`YUEe zv1mOVYdgl4>^swmerf*Kb{RqoG5L1So>aN(+HpDOpO+P+vVbRv#O>*mM }^vsY4*LZ$khp>T8IW&w(Hg7KV)3YBe zZ-U7d1rD)_X2B*;jK!1Z$um`1Bj;(|YW@~+SBhA)HX!_!1rFlZE2zn%HrotbD-pvu z9KYpM>XuC1+;m?GV|sX7AB?)ux_^S_&5TE $uR>>|i+aSuuX_Is!Sm)E@u=z=9O8Pp zJ2=q$`KdG1qqUVEI~mkA+ZQ8IVveC&UOCYA{$7sGv?XtAUkjIg>e`e8v54z!-Ql>t z-mgoH{Uj#@p+OhYKf>bv`nMce#~MN%c1C>m2n39;Lbf4UnX&hf@>-n0MYo(0HBh)E z-WvHLX#-ivI6(;=wVWzTRGdciXdGR@K97I@tm~AO-~99W6>>$02&R`rB}p?@ci>7! z-_d_=HY{&VOY8UMKe?8*YMb%@TDM(0)DX}+%uM=0%u2fM87HUGB5pfAHjCRn zpx89&tJxulTPs{0 ^*?{O)h2r}BIm8tD4KyUs^B}$^cZ$u1!g%Rr6$th=* z+D KEtkN5$bE3F+AeZ{JI6gK#nBsGF{IkW4OHqH&$o*2B>5-l7}j zem>~59UCs#VUcVvf~aYr {fH1`)B`JfdNy z3wZ sAEGxC{A#mngv(Yuxp7V3bRr<&EGu@ziz08^KN#m?HiO|}9%7pKGugM6 zG2dK }FH9iQFxOJUv@gHaiD-1Xxz!*d5!*4t_3Yz0X;XVaUEQDE1gUlX z`0|y6Z!*L8@T4pin$mGxX)OTdZl*0}_e_bqIJnLpb4)EApjbNt;rxCcf3eajFQQ6% zk)LUpHcIfNe(c%^On&xE(aa3fb~PnG_%UA>Cd>=ki wigb^P7Mo$7}V2I2#x8x;oCl3Wf;uSwGnX z4GF2#A|DPyd7aJ!g_?o|I-JBA2*an#h$+_fSSuB%5lgtu?bUZ;-U>|L6%gQx7)3?U zUiZj$Y$2pB#&(o)IUb+Z1Wwkn?M>ze%C1|^aqe}qia^2QUmA&Wyj&0Fcw>V`ezdzX zaPot@%Lx%Am@0S2>Mn;kjkNvz?ek~71)x45j=E=Zkcur4DCH%?^O5xY-j2*UlqV%V zZZB2;#=G>#^H!&PC5$jWsXrR3K&&S;d0;L($$V*U_3IiXCgT02O^JVm>zvkK3+@$4 zB`7TsfA}$G9omk%X5Wz4;RGMtem{BE+tk43X1H5-FC6!;w_sm9QCrA`zyFl%3Rf&! zG{CPsOqysvB<-iIz6()r5(>*&vy!RIFB5c*Y-FWS zWt4;r*)Nra{|7jYlZe@vxLhXH>%C&2&Xd>J?Gx|CV#rdi{Q KL_c#iasyrGgi7%&t37`Gi4UX<%wGI&q6?MhZJS#uI*Sz6cxY$cYD*kZ90w+pyk zzs=87o{D$vVPRhsJQV{S3sXj1!yTWgIuLW yLYS&lg+jeEWNwM7#5Q<+b~Yg6kT7C1Y8`8}<@z;@sXVn%GD}6mPdH zPmVWUylj2s!WEA@pu)^kCfXkek4nzVGd9lOjyzhWN_u4awU$)CqD^EKyE+wH)5b~q z=Zcu3U8T0;7mz>nvT&=rWGwB2=(xnimpCN?nA ^_CUy$ zKV73+PaCQ?YuoWRd|~4r`AZ`YO>4jCe0~tEpq*Xue#oqRn#;G7h#K(qgdDeEOm-*- zcSpL}1|{qvS91U+-}}TMvKq6k^x&2|GV1qoxJDi=)I)4Ax}^rvN0DEGNQJqAeQf)y zJ_UrQ;{+xcj3dmgIW0u{ER}555K$bI`l G@o1n8wi53!)`BKqnhhNrrGLb9ij#TA*ULSf>K|;^X7&Bi}6(?5MHtsxKdQ` z=LJ&cE$&i%LmWg?8o09Vj$S||!**mZOuSPs%gFP{4`t9;@A{cHw^*`e6;S}b9=SM3 z3s%zRyDY!M<7K(krQXny+y%%F^X?do+s}rP^SxJGYLzUv8WdOUcp^+e 1-HGu?0#wl0^r%3)b3Cqb;r MH(t;E8`M zH@oo^^=zG_q=qUy=7SuE HOeNt_Pn!&`yyy-@W2M_#Az%BNztIY!ox+^6? zvhW?mS7MZUa<_*3ndOx-ejE0+n^Q8|sl_W&_9AK-xT|#&>8Oxxq{n5gKV63i41w=m zEH{8%?=i|E#n46Q9$(Rk^DKFhm)ja@4p*zBUZ5%3KeB_^n0byH=Xky{)uhI>^-L{G zKQq8lWGVx9p0z9Vj!FI}CYsjcjF${|@4YP#rST(kl<7GfNzzg=+&qoK%2EzA$Ede= zb3v*bzxSff(<;q>Wn~OCU`963vi}0w`5`WB&L;I{zhwnlyb~EE>_NYxP%cPVyL7+e z>umTxfrQnVZ>0X&a^%ACvw8z^N)NCS<8 ?7|6eP=c=h<1LDx zjlSxaFJVF+ty0l0Um{cX_Iw#0TKK!ox DiSj3(GC2wIOOA>5b)AoYlY#vzk4Vs|}aLITqRyrz|xI?K~4j z^9s9$AOaD**`arso*VMWv$+_47+DN75#3zauy?FX#x4-yPlta31bOJ*Y?yS0;`!53 zzhgTvf^CAVN4}nSkumq0)|k5z&Zk(s6n;M~Wr!U<;gk#o1o`X-#OH`lf2M6N6Q1WS z`f}Zfi2eNHwWcUU=<~?sXXnTPU#99ef|tA}B+(QyJ-p5-!~|-EQ~5nrFY)=qpT5lF z*$=8Og5q=C`)3b^580C-?Ih`!_Dfjg26=+jZagkaaArhl$G__Hemv%l2)0aB8n-C$ zSGG@!ro!Fp*sP}PScYPca6EvrsBL-Uk`84mTfEFu{|~^A^%9#-9#0+o#9Zr3?1>`~ z1HSi?yghPlUkhE1#L$SObzUw5i(a>j*<0IDEh#p+`udp?&8^}*mJj^sWUjZqrT+mq z$|6iKr+uQehb`Xe3;M&SA_v_Ak&XBK+}%Qxm~G7cCQ!U9()|U&v*K@GN|9xgXVjzG ze@@M-1|>1qy1+LCG4R`nd1lF&U~VapG5_?ZEYGg7AU6VH0(78e2%zUi !HH35+a#Uv zJ)8HMIDa|pESPE9#wK%=P3e~dU&i^hY=wNB&GcbqlJNDxsyKS9aQgEzzOLwJ}NmZMq+acJ5ZPKxHCem{9CKsK>8@3VpGmi`Iz7H@cg2TnJYr{C@%-% zzHUlaOIBp6!khY0w%3hocJ+~tVeBElv}?h&N?@`GMC^803<@q}RvV2)uCkbvEkS-_ zRpPBraYbk}QHqR`41MBc)bWAxa_}+UtdaMvu+uHqM#L7XXZ7EJRjNt#H_24LljTcb zXn*os(Vv$0fC%T?KCdEY_?R*cz}WoY%|L1fMcftF>_%VpSkTkeJCBXKYqc<(ahJ%K zu-OLTpA{~Z5aOeHbqQ-V%}dwjx}RO_bI} 89| zw(t0-CL5xB-WW)_i|vo*@36)e?K +-acq3vkbP#*NQlfD^WHaFX^<_-OmCM%dtBP0mHXEBO3##QBCX$CU-3h9Ey7_R? zPKY$1=fJJtaHrMhZ^`ZPmC1^&@f!Vi&4txA7uL~qPeK_mYt2Ar*su!O$kLm}sSJa8 z_uKL>hfCxRxetl#fl&ySqXUGM{p1CX4r=GB9=6N>XJ8+89&a>XWJFbW-^5Xd9!A^q zjKJXzfJdBwN&1F+4B8uFJwh+f!vYTMu%*WF!{dMVF^$dL=^3JbAD4~=`Mvp~R_XIc zPCEH*1)|$7OnOnSt$QBFnLP#$WEDbVR4GtY0q4I{{vxP>|MaLV|NOKzGkdshmBe9} zGxw(o?e1?IpA|jL#OmK!m^FlY{vM)R>>?>iJ>zqq_nJXouIQ12ucGOVhO@fi_kky4 z3%G=s#IsJug)5n@V+N>Wv%wP>l0q;O89Jy_r8e+`4-OQr_iT=PCBs;kem5X##96F% z|MEjwlyT4X$cIZ*T5sx!NY7^SWku0&(5$%u_w#X&%5cpn6XBx74Osg7{{ZVndnu7d zZz7LG@aJNM{ohg2-IbtI-2UFbe(Tw=C}q*Ow7ssbcyjR1>;)|&6`>|2wN=TjIJc%B zE~ON0oO{W2Tm8C~xj?z^Ta=4<{3ed-5zk(bKQ)-uQy`u+cGJV^NMN@x!g*tc-}S`G zLkO9&!+0i}`R;>Lq8^?3&U_Cqp5jNPL1xGuik-SJWzt%yXV@&)Ui&|*=P Y=V&F-ptKk?RQ%{hX*$9}XnoIZ^)Wkv~2>|4?Z_g%Y{Z$m1ypP?Hbqc>JaL z^=TXty*9#S=
vpKwbM>O*~kpvI{>#I;G~TjaAQ#vnp~9L@MSv~D+oSBgkP?Hr;mV%bLea_ zY`5WQ=Njm;#T>jqSwTpWQ9L!P2o@a0q=zqj$+!RQ9Sa5w$|M0+2ZrB-4OrVIimCic ze; NSxCMnUDv4br<6jHHS@HjCy%LoBBwY| zs?y~l6q>UGcp{kg2fy;yoJY1I7S@<$s`Xe2)lPC7GwY(lKt$UW;#Dv`hqbk(O|X;? z2{v1{W^C>YOC6glz(wjjRcc%^g*Qt1p}%j~N!v+pa;zS>EWiiw`}&l~c%U_Tj=E#% zu9x9pEAAM*7e~G7nfjMEUZ=Nbl*-rj(QB;^E $N$Gx5Ky?7Sg z604*?@|)&L&AS>8@W#|S8wwd*wv7rt;55e_{~Qy^(qRP*=mK&gV1!)xGSM7&{kx`# z?sJ4Pi)M~$g`78iA8e>z=Ifb%{ #B)%g5$Pdxr3_XK?NKd7H+Mt%& zhFUU`h>M`VpE%rS(UW{gEY#pgeknY?{bo{^p7~P@lw(%CyX|;dqezAHP}N~Kg+e6m zbm`1%{Vj(+9inDa3>Nf{_(r*8b|<=}Pwi~jRHEn9N?sFU hWGLx`tBc9?V+Uu+E5lbK4y~oWrdv0`Uq D*`I?WruTlw_(pr%EeGs P&l{rG1f+k@YpCyQC*Lw>D*Ybp!_h_5>3l_V z9CTwjb>MWEAAVBN_tHc?1Ut!vCjw=VK|!N^{FW1SmJ4z9RL9pEYA&NyLX}QTpfYpX zI8K3$87{l>R6n2uD25^~LzyXa*-$fw4~cS0^4P-x8P|vHn7jousfqiiq+pJVTJG#9 zjYQo_M9+q=!QDM(6}M{8PJ8z=6ABB&&A$|@PjYJZ3hmc&Gxi$=Pn+AN>1PWpZ-=<7 zQ@&Aq(RQ^@=|x__!uPBVBcP6At=hh*pCS`53BLW%vs9UR>UbN<3O`MOXaN^auH-(w z>=`Ubcs(&D&s!x3n6YrUXXJn^6uyJo?gq BTpgl*ueS6o4m*G$L|R7SF!yR3k)UR(v_VVwiknm3x8ss zeDpl+k#4Eij9K=K*pIz7wREhV!_eyXg?`Y@?afOEyqch7Fw=O*3yk6h;6H!`zdfXq zArJdL5cxlf&cdOow++LiJ4Lz~ATUx&kd#KcOIi^aqZMh8l1>Tf?vM=-VRVPmGGH`< zbocK&-@mXp=Y5~&zOTzw8Wyj2oL@~FwgPy_#O=#@O5% HO6Dh5Y zEQf`8hojE>Jbn^qlod|cuS=L{BNhdls~AXH^# md-ExUL0}7 z@(FbmmBK7|&hkU^mBrAF}@+Y(Eb*+lU=2= zf48>Z@Y7?n@Z8O3WWRsXfA1crv7+K3 oNl)CK>O+jYU%KCI%&N~;Ts;E;1eE4h7ida+R9UR_xz;UA4{ zM$$`;F!$r2i9cde1kO^4)m3`NhvlNIV!)8$5{=%Wc}bYs{AH|+?HOk8;awOWOTH^f z0ZEmlCd9TCcmDF$w?`5HcMP+T(Og&M{0ExdDAY(q=+4c`)XC0f>u^2(2Lhm|0nB8e z09iZy-Cy4ywvtS=#jmX2EH}RMORN+VhA_`F-lI`o5kt`l1439#=2l1jSD-+lPOjiH z*;3gu!4u|CgV{&CnkRnC46_}|(`Qkw25&B?_CL}j=)>9u5=!so|3=r&_-P3mY&G7R zw?kf$Xw-iY%GbR6^P&HiTV2k#By5h8dNbUAkNdP|&wHjO%n5!>Rvlk|&SHs0zERxu zA>pyTpbxiJ?DG7NK^u+brr*8rVEWs(K*K1YuRw?G#e?{_1&_bmaOZR&a6bu=yJKYy zh!fhA`*T$+l_MN5pvEimXImmkU#%i#IJi@{@_QhDM@yfvHP)xEW!c8Z8+FbF%6H9v zDS<^a98m6tjRx9G1m1mp-MSpdc`I2K@;R*Qk?>nqazciuf*n~!-pWIRQyPiBP-7eX zM%qpA%VJLbchamXOJsjQ`j0ohKVD_^`gz`5FEzBqolKx#Yp*BMKgAnOBbg146#;l? z3#TL}Pd2=La$w~txrr_Vu`U$!iWLeR)(Q-+WG<(; KVab}RS%SbZ3$$H2bNoqldkUV+Jwpw*WbBBc50hM3-;3??2g8!x(s^^2X5jA zk&OppJ(C3sVj<`j1mnmTendf4siB9m3milnI{8$vvFl4XcBt7Gbi)6OFByb&R8KENI!81C|Lb-BR)k*)74|3cJ?cyG zqY2bmsCQU$C=m(tFLM(8!_^JT$!7(8ss2$`Fg1z0t8h$KdW;1du?(+(;9+2GqV&XX z9`0YJ2jdTs*pT9eGkrZL`0dx@YgFgUvlxLbvoHMJHfmUi 8zHqB0hNcxOib!Gs>+ 4 2CIrX2!10V9~lzP8AtNdX66 zSbwMj{01FdMoB68tDwzePmaI)G1F3XXsnwkOwFR<;9R!P*4(>6lSvn&0>f9Lt#KO- zKwJy}G@mHhTI($;xR;i^A3RQz38T+F#6dDX*^dVj_8yIMXnlScSF+v66!vFCehYLU z#0eT!(8Uq+G| S%TzEcc1V-N9?EAn1;}x-kX!p8aDji z6`_V|{R&IMTzyyAK}-|mf=_U%_3=s?r5UayeP^=&G%L8r&862VNOaUbJT!2cxR03V z&U$#Y`vPIdd642j;&b%|Z_GU?Q2jyR0wDZXxbWGDvIe;WnRZ)6nIQLgtqZq;C9>E! z0gFmrd`Ndl3pnAj+v!yX0lmu$-3Y~o8SzULn$TN#=;ffHN1NgtF;ZugDE>c?XPNGg zv AT3R`ak*3aK?!Jn3V$K+!|JLQgW^BJ;rAvkQIAg+pr8Bp3d16P0p3#`AXP9% zDXLHy?&`~WcD?qqsk6k{n^)5`Wa%z3PLzFY&yhWk9W#kGNrC1F;G|3H n^Z ziAnPbKm2>*>zIQ24+N{jwKBDI;Z!LCfiq~;v{Nizn8fkut5mysBy(hb3F)-OA>ir@ zKRTP-2~qyw(B?@eM$rXFENqM +%4R+{ z8X<^(s;7Ws3Qx=b=2EOb&gd0**$5(Hc#yy8rlb~m=F8JDBVw(6AISeXd(=ezZv6L1 zhy;r_*1^P6(P$#kDXaK;kHCYLuG_WmDoHQSAdK+YGzyPSq3; )@``1eRyElX1ggP_pPED4A_oY_KmSbVS XQ8j>4pPzZ$E_^1Vt33{sbAMa~DjeIYtpN%69GIZ*s+=Ns7=@$1lp0+KY~%oX=; ze7e{$uSkAbQvA`X;ar)js7V8}eW3CCe;`6k{{z&0Ck2G`Hj@rhh})6K!yo8d__$B{ zOx<>4nQmUu>Lut8)s)(~EXRl=J0|GKu@#jF3RTnGVBA4&@{iY&Z1W09IiNtfxqIKP z-L!P!Ry}u>|3H1v#>b%RQH^A9cKX*%QV{b7ks;^zfw14oHp<9*xA9w>?Ri-{*+v^e zc Z(M|V@rm@FlGqZ*u}pgut8{p GnulN;+~e${|;9xfoFX=g8AF(n}v-GDFiDYw9v>Y#5Kp2 zDruEqug%T9JQR*`*5qr(N#etBNi;&pMN)BpaOvwVlAvb4+VQ{Y)tE1e@~XSNYLs>n zU$s8zDUQz|*)Pn2UUeV_SS)^&!t>-Y2jj0cm=jnHER(~GSHtdef+1j24a%^Tn;KhN zmoyM?_R#kDnjF`d(lXs7!MK{{WUp^z?_U~O`bYidC`|p*pU*F*5+Vo D*V2 9tcNF_cN;zBREZGi`wM;5Vkgr$7n_zDP?o!Cum$nO zfqC5oM=}4V`gHMLf1kFw>lXUp5g9-1c?)ctRxw~l2jOb#-81j4atuHu(MJKE*$OeP z0F#=ucM0}zl5z*qb0D6BUt*yjg=2WxoerdFwB*q$SDo9-4JjO1X#z>+eHQOnSbc#L z1Vy1~kFz7Lj^2+w_%$}mSpfD=r}e*Ldkrv;C5xN2*BpGMAx_;L2hdJj8Acw*pRcUK zDmM@1ATqx))reS4qH*CNxOazv$5Vc9r{=A-bEp|U90BZTU7oUp?Ro4xSIJJXZLpbJ zwrd|eMq>5>&(%HepUIYJ+|$%oL}61F9{`kzl81=1ItS?4Qf|bx+}*&~)X+YYod`yt z31Xv_VX+sK_FO#1K8_@Wt*!Iw(bT~ycJ}#4-GXGLPz7-0&Z$h}5u}vYj8Nb<(72(K zS!3H5s)sC%K5w9}doh@uiQOn=nHvQX>Xa; 3zI;IIi>cuF;V4ix_2!_fVS^Z~ zXeR4~r%9sfVUGZgD--zHAvWEvmn3!&;MNx>A;#%oG)2eXQ@OaYv>}4bA;bZNUo9k& z4Q#YbgJv1Hy_$;NgSlc&Kc6RGwER1X9A>lY{|5PB0V+cU4^VFYW%dj)zM=v9qfQZc z6s>Q$-9g_;hJc*l>T7O=Xa~0CtkCl?oR-T&cioX1+Rib>N_fZ>`m|S0G|CQhY4 |CrhR3j9S=D)&kp*+uJG;!4r2 z>lSFzvhBVuVf6JXftH9U@ZfH>S>ICDK}5~^kirH7)gtLx!=Mnz8J^A>Uwd>eX_vBx z_1d-uA!k*O6yG3QPa5=1HWj7@1%F%noH8ZOzjad+htEpF?e?*!@;A;s+A?a!?IR7a zBF265>KS35*g&n!v2hG9n|^2Yr&%|cjsMk6uR66l&Qc#8X|;teeH3zng#KyFqI!my zgH&)#^i3yr-mBrl!>-#HhCIPX#*Y#Y<2*Zjltwx>I0M!D0`6R?dQ{5k=1>P5$C){X z4`|ZOk48r9M#`A$qm%2>tI%NWS`7l`4Au~7uNzxC9x7ph-&a-~HvX|TJUBaCn%JCf zI#u)N-BY3EG8|K92szff)`pu)*#-8gMiZ#gXX37}Ko>HOXq1nLPrQ69*BE&42G`-t z){9p~S{z2+(X0lrOk$~J_+h>9^=ZH}qi&H7Vql3A$V*c8b A_hjaWZOJ!Z*jcY I@K9kCx4mHh{ `C5w2 z`=dsqk_+HEfYW)k&QtJhP)` iI D&=P*DNR$X0E(}gEMg Ut0LW0f zCi>M2-Syt-pu6A+dUdZ6(R@k43;`O&!(ik*@#g1OJKBZh_*UUh(CR1z;dre;7mtE_ zx#x%fK>VLo%gi$9lxHJikgQh^+LWXtGHcmCgCBS?iZdPvOapo#>dy^wk)*I|Mhh`L zzu(SQQeWb~S%zOQZ&3XQkU{9){{-t6DN5-`#5GvB^4ek!#@?y`D1TGhe7!g};*Z-s zgS)Y&Cl3ZYfa7bVjOtQGwp&4JvWn*uH^g !5bg$ TDU}<&pixS+oKfxC$; B4xb-6CN zU7fsrN$R89HvE}6bec+I``Vf!!{Gw6$47lHk$oDFo_fBKy}v053Qy>B1ss7HWD8A0 zYiD1aw!OMtg1FjP%CpY-yLL~4LAh&%^<`PB%<*X%n_T|iH-WU~&V&J-uc!=WhDPR0 zW=7OW378UFX#alZ1^cAIW78SjVX!#I^|d`mRzf^CIip}QZqsqCJU-RgBS;7LjN0Eo zGpO!Qe~ORR>R9O2^}N5gUjg20ec}kd#j|0w^*gz@@CQUA?!u4nRj_7 )%bjU9T_0&QHfK9?IkqyYwb9i7)t#ZP;K zPS%zaOR7Ebko~~@6I11n)hP5{2>?Tf9TvReP9f-+xNI3b? Y|?kvLNXc>Gw zF|tyJsT29U ~-a+3ki_)u4&7tW+Lsw{YStEYy~@EM7m8A71|*Jmq{`Yq%Y zCV$!5l|EUpt7t9p^e~_E>5+XSUh2Mk45XfOp@RM1I(P>`JXN8;_PPl^BYY4f7&1y( z+|C+L@xj2}9Zzl^)1q9s;;sK5 o&5+Rr8S8kTqfftgzXwT_b(Ly^djkwal1& zi~PhC!@q|$Re%wI&my3^-#omFFKSC+notU2kPd*MJC5m!lHYyl(Ue7z zgfJ2T3tI=%GC@AEh4-yiU5%I9S3Of77nP^fLGFF~+Uu( W@3iFq?3?%} zhT9*7*Q(7dLT(vzBfdU*{3~>vDpRrbmED8|KdeT|L7p4LwzW?6;cRcjfqyL}^3RF; z;S0=-&rVPBZHs$C#_VB0|lq!Gh3lpovP5!`QN?Neg?nlU^r)YDAR%#jo+|BjF3{ z_`xj{9#sm#yYN@iB+!2p%N85=*8_ImDU?$<`mPhC13Tw00c%<66^G$#dw7g5RMlg0 z?ph~(+gc+MqPikJeSX!I%@&i5wId~)!70Fh68I?I!^~Rh+W)h6SbPdP9z| 0kV^nhpmAJUkOqu05skK@*aE6+{l!41vQ6OolMlw z25lu&20rZe>_WFt6uPe`91gYbC{f9w(_PQ3@ff#H|Vm9m?Q z`HN?jY0*ft1dXWqJL#ia>VvU3_~V =hdB=DQ7EzsHb|Xx^I&H{DmBAm60jS0M3ECk0Ti zHyfiIVO1{+jMQcWbNm@a*(P;s3q-z3aC_JWp?qluo@Vapdc)yj9Y;ew&Uprfx-{N2 z4bp&F=%pQ9wut3Gpc2EAmZ>EhEr;CKrp^tGpnd-SD7X0@2N6(-Qch~wKU=Ts`!$4Z z-q!L9Ov86C;-eGn!cyH_Z?dv|NCvIXz3&c$8H z;s35c07j4JAF^KU91ko;_3RJIvEA!W1_Su80iD$E`oFn0|13P7S{Jf h0C*y7H0@CIR&Wf@E?XADbm86HHv3P8zZ5#K~G#bN`JBT}lwc NP{+s@;5L|QX6=%@YA1S>E>{tcg3TT3V7oYo zI`5hB3pJbg%-^;^77G~QY<-?5eWwl*Fz#8d^N2Bn^HBQ5xQQ;2rJ@lFTEcv_R8nE4 zm~&HdWJh64@1GgcQ*n;hkcqe60(3G(jYg@ksu-8Z1xujBDT1kK_m4VdHIyT81GY2N zwLSH^%6_WemquI~Fvwh+E4Dn*l#a2t;`JtpLN*?`iV7N*c+ydu2-+BTnG#*L1dvJv z4lcX!= Yy6=TN4R5kbQfG|nd~E`c845o*UF3>`L9Ri;>kDei)0>qn9t);Kmi2>@ zV<*)dG^q-Ffwt{L{x;S>Gr{dDYEscO9e1&3=RN2^O{O$B0_zA0Z|#vTq*61LOY6=Q zm`7Y)F2)1)6N-|3q?}3%{NQy{P{R`KXV={ra azzE{BOY$%;EH+Goo zPJlhr?rzgc+@8j27v0-*oANKuQF`yB1L7Oyx+j8L_T-$A{atcx<|1uVrc6ZNLzG+g zbp|jPb;`s;9WpbBL7Xuw+aux){f@sog%xHyR1K#6@{CN9-fGaBd)N5n9N)jJpoKt+swKvwzMmptP=fkJ`mH*FUw_e}|_Q?|l@|N>d zpv>z%Z#AyTB=c6wO#EHOkc^%)q)xC+KWG=5!F>K`LOj1&j9*aq`juJE*7^(m`Krk_ni+Y*uKQKwk5Sv>PQ zd3c+$rBCyBx9`&w?9xzoooR%)P!Z+NScbM4<*WNfYE-2{$JcMTx_ZRXgi*j1(V96t zSlB9aK;RYA1xvY`{~EM}`$&5=u%8i*paw<{y>y;pxgv)SIDW{kmk;jO9AA#p!YXc; zUeME0baXuC&y$+y24aYb9oVS?x0>^=6f$1+-$PF?prwMg4=ue>W{~;Qgb<4Op&7gh z3VAJdW~(A!n<=b`$9mY!^#H93;ffXwIAxv{WedB$>8`ZwtBGU(6+gn~CVljvLc`wl zgW7oJX9P92zd!VIHk9b4lwLMRutvIGptUqQIbvK-Ai7Hm)7REc@Zj2BxO(p?`K}3; zuWjI~P10)(h(i{qMH~3+sw4hUo01&-b?jnSurM;U1XH;kkXG;=5btSVLkMe!h`k?P zFr6H6(wi<+7*99+2l^maf7zP~c1t)eQX6{V$QtW!TZl0y-$n8|dMj_&1?tN4rKomm zVbD`eyahV&q(bUYhC#3-C-o2(CmM&5oK?aJ;&@X;MuW9|w_3vf Qx(Y$nWJQw49@ce?S$o-;a6=y$e*G#-vzxfIM|bR%@8G!>yB$%M&?af1$q> z4f~ 2GY*6eAt+Ob~;ov>NKX6@>b4$y&Mk-GV+Ih2k4z5gmO5)=<=}zBj#Q zspCl_uj5O7+ose&{
lh0WQ)MjYPc!$$94Kw(_GR;7%2Zx7PDTQFLKG}!0Y(=PiF?&^3Scd+zbb |N>hOwI(L>5CrL${Q=Y{wrC+$>TZagJNVN1#psZ%YC#eh4YT#iN9u)ja z`{R&K0Oqr^KK~$eEub$-9rw@3v%CS`5#6<}WufXwtnNm36YNT_93Kv|t8BcRcM}6B zXFNrI927alJb<)eWlsFQAypG*z?VM#_K!w*FwpK|hRA#WS`7K4a-TmBI(ylgW#>V+ z%I7(M5L!umXq1`cinBNX?CwzrT6Kr-BZpk^B^|Mnx*Dj|b5xuFPgwGvF)%TaeiDR! z&CV$z8)8-lu8 !g7{i iHGa`nc--@NTVSvOR+kwBOX6AXguQw}6CNWOt zfSl)ms=Xse`bGdm*=v^ ec7wXomM0r@gZRhqR@bQ zPjtV^{xnui?I(Q7t$pcW^6~iKnM0tI2>?$6#{Mj?-|hd6^|fQ(@sCFUJ)wEF3$-m( zYEXjgi~D2RjkivJ7C`tGPwZe5EW_BUqco5`>aGLZ2W?#K{5xW6T~43)%d4YMBH>re z`Dzc#0B91ua@FIIK1{4B6@~ZEGbe#X7irCFrtY=PgXb=R7a~+|puDFXjW{HrAv!sW zOgUEwIm7&_>n1}ZckFNDgFoma8@pr%3--6@qzWy9@(>7D&M;^pSf&G*#s);hcuaGy zeUV#>*XooxJz;tBzxi_V _O-wvBWa{$HA5*XbQ8>8~RTFnyoza<_ zl+lXnT(V`>oeK15GpJ1T50qoXmlw{^ZTge3 z0od4mO_FBAUA$T4onK{PK#&hQ05&QNN^`*gz_N lmf^m)`UT6 zKxlvdJpE|!qU$ZUBYkf*14(^w8FuQ>s0e WR-^L zY;J&D^_u((F#dAK7m*e(+I$0O@39EK#Y0kVl3P1-D3I`m*)0$H+pHK4chKTJ%P1a2 zsP-H`_=_uJ{Gm*z5H^@j9Fe5e#^)~U9{x}H>)Q)ZNrD9OtotdKzMZlo=)GOf+$D84 zQ`Vp8Y%Pr+7}G(%aO8y0E?C+x&(gnVd=KPCAk&ckg$(kffmkf%=QpYzw$qgZo03Kv z8rjSHhAeK3DOO9Mp6MA}hN+7==3YHC2FAPo*ty&`pqC65;ov1v)%EG@JqEbL8B*Q_ z;D_yl3XezsZzRT>@y0HZ-}z$$ 4(b!+>r0Y{$AS6n*p z5=ClSm_(zGb!hQs6Xp{15j%R6A;c*EO^Ws$D84=v-$Em?RKYQj+g&l1G c3|9qH`gDM1DQbp0S_N%9mcWy-CmJG6nj?Pg!HhfT=1W&c#wbL-7M zgx}u(Lkmj+xt-t+*rC{s_B*u%FpiL1WZ@4XVoxFoVL%bnm#8cj3W7iXX|6+g!G`R! zOQuaiqVNA;R_giZMBI`E$#vpXNT+A8YAjKl`dg53f)-W%sKPMT`#&56UAx(;Lc(Xr zu@+3jZ#UAW&6o Dh`1w#A$EzWX*SK-8sVWz(kjNvas_pV6l2|$WWdJF3u@Vk+$&I{%@?K!amT>MI{qMc7Ilihb9(-~ z{V#o~E)`Sz8bx2>%Rx^|%nS}s|JbY5AXD$yXWFrp$h5va3|EXcITUTvKm4(m1!a8< zD=3@qJ->&*0*1*pa~+YOCz`m9?avT*5lkU~;&e;&1t&gjRbl6<1S^nCl=WB>Rob(m zlvi%9J-7*?9V=)s`f0~>#R0tOc1Sm(zY@_&nZy! 4KKUgZ6nF^i`< z5su4%SzVAaVC~En)55i4-7_eygB~4qGS;} ^p562sr z5VW4j(d&*Be`*A}KZsv3HB`vQ4L`F8_k1O=f&PaAKKLbqrw-3<>vuU$?p37ev16L0 z+*#hy>+Z_{fs(cE?k|#IFYxR7Kx9FK+w0d#^)Svk*1rEhWHuk=rU^5ffA<;b3ys?Q z&>&C9g3Bll<$qJV```&>g)9iPFIe2#)}-@N3+ZLHTZT8~UfrusJTENy{yb@l FXp&g=6X zfaTHVLgXoSnl!ZbgZOG u0rf~~Q9=obqeR_jN>&k?M +;G%Y}?TWnbm1P-(GS7UD{E>|rW>~T0KUpx05s{6L}Y5z)#EcCCi zB+SHgdupMHWhX&{{^m4Rk(~C63S)2OHb{JjA)z=)RqyrF=pSO4m?%r8#tOqZtF+E) zkA%o!Y_7N-g(Mu3c2j0)bM!o!hSK`xo`J2)t!g7Gj=23jj8{C)dbZ<&vrP8}gdx wZ} YB zfALMpUcg9XOaB;L>N)$DlrqbB9@DoVBR~7s&zpmNRm2-*V@X2UuPedDlx23G5}cjY zE7!`B^yiGCvt|l-hpGyO5Eq|vT3Zm(|0+(UNJ~emn*t8M8E?U3w YeKemsIkrw$Bo`c ^+jN{6EmrtUU)uzJenl zMS!6fR#U-1#f(BU*#ov4uHcJtE~Hy*U~$@=@dRp4(cH9`bXy1gvSz{4#H&tE>0JTS z cXr|mKo|U4`mwGO;qV$2ifR(_N*q_@S_5} zKQ9e4_T3C=$TU~#`> }8_pF*ZCyB%od6qkJG<20jAV|f+6yr6N zBU*r#4rjOHV1+uz?pyjSD@g540I}UST-XY^A)EAxi!1afurZYWFVMaKwy{4KV!f_y z;`KagdxjR}ze8cr_Bff}P1w$j8evc06Y+rafJV#hWp8Bqyk>idy#y-^+ImBK?!=Z< zQ}Qoi9$&EWT5_18CN7RRL&93CMHcvbzGl}=StODgT2yWk5Ma1Np|Qxvs}w0df9lXe ztgixb78tE@w9=lLLSqY7%e6;Te2KB2S+UC}SOYt{_5irCvi=&HnA$b)owbK~oOe=2 zJKGZfP?)x{$hb$6P2+lye-pv^RYCAe90`9oIfC4L(skW&SFVxOnZ~3HC^>sd fyX#Zz$L?1lcc(WY@>y|zx?>;TXA~>A_qW2OVS>P+|;bz*uXqns1amT5GTW# z17D9Jk6p+|Fv}<%%s}Z!F`I70=>mw1>uM1_v2c==Ui$6_doEYc=2gpt@U!z`O`6K? zM&|1OK-WJ>U-V*dM&)wZ0G|-*DkvxSKT!E;mu=d(@Gk +H%*oZJql0%JJ`d* J_2qm$K`1QddffhWOL8MJ1?obIAryLc{Kgv z)ZU@&&kiEG2vs^AS{$v|V8H9>2GE4_f^o~9zx5UDiH}0=-Zv0_NmtuS-cnnS*A#7H zdRFiOyf1x*CO#Yc55%_%>2w{HN#hivx0hcmO`jx;T|OE_h??O=wGGCs7{k`BbCS-7 zIV(OvSzf1dvukARyZK@TmvK4xE=`KA1c#2@@zM;d@+s$8H_z4g6Y`GyPCJ)jGBJ6F z{l~t