From 3706314c938b87a4f0fc8ad57cec3caf3e98885b Mon Sep 17 00:00:00 2001 From: nmemmert <67961292+nmemmert@users.noreply.github.com> Date: Thu, 6 Nov 2025 09:27:57 -0500 Subject: [PATCH] Add PDF renamer web app with ZIP support, styling, and logo --- README.md | 105 ++++++------------------- pdf_renamer.py | 157 ++++++++++++++++++++++++++++++++++++++ requirements.txt | 2 + static/trbc-logo-full.png | Bin 0 -> 71976 bytes 4 files changed, 182 insertions(+), 82 deletions(-) create mode 100644 pdf_renamer.py create mode 100644 requirements.txt create mode 100644 static/trbc-logo-full.png diff --git a/README.md b/README.md index 119d9ae..96cdb6e 100644 --- a/README.md +++ b/README.md @@ -1,93 +1,34 @@ -# pdf-rename-sort +# PDF Rename Sort +A Python web app to rename PDF files based on form field data (last name and first name) using Flask. +## Features -## Getting started +- Upload multiple PDF files or ZIP archives containing PDFs +- Extracts "Last Name" and "First Name" from PDF form fields +- Renames files to "LastName_FirstName.pdf" format +- Handles duplicate names by appending a counter +- Downloads renamed PDFs as a ZIP file -To make it easy for you to get started with GitLab, here's a list of recommended next steps. +## Requirements -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! - -## Add your files - -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/topics/git/add_files/#add-files-to-a-git-repository) or push an existing Git repository with the following command: - -``` -cd existing_repo -git remote add origin https://gitlab.com/trbc-dev/pdf-rename-sort.git -git branch -M main -git push -uf origin main -``` - -## Integrate with your tools - -- [ ] [Set up project integrations](https://gitlab.com/trbc-dev/pdf-rename-sort/-/settings/integrations) - -## Collaborate with your team - -- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -- [ ] [Set auto-merge](https://docs.gitlab.com/user/project/merge_requests/auto_merge/) - -## Test and Deploy - -Use the built-in continuous integration in GitLab. - -- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/) -- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) - -*** - -# Editing this README - -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template. - -## Suggestions for a good README - -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. - -## Name -Choose a self-explaining name for your project. - -## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. - -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. - -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. +- Python 3.6+ +- Flask +- PyPDF2 ## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. + +1. Clone or download the repository +2. Install dependencies: `pip install -r requirements.txt` +3. Run the app: `python pdf_renamer.py` (ensure you're using the virtual environment Python) ## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. +1. Activate the virtual environment: `& .venv/Scripts/Activate.ps1` (on Windows) +2. Run: `python pdf_renamer.py` +3. Open your browser to `http://127.0.0.1:3000/` +4. Upload PDF files or ZIP archives +5. Click "Process PDFs" +6. Download the ZIP of renamed files from the results page -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. - -## Contributing -State if you are open to contributions and what your requirements are for accepting them. - -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. - -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. - -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. - -## License -For open source projects, say how it is licensed. - -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. +Note: The PDFs must have form fields named "Last Name" and "First Name" for extraction to work. diff --git a/pdf_renamer.py b/pdf_renamer.py new file mode 100644 index 0000000..f60540e --- /dev/null +++ b/pdf_renamer.py @@ -0,0 +1,157 @@ +import os +import tempfile +import zipfile +from flask import Flask, request, render_template_string, send_from_directory +from werkzeug.utils import secure_filename +from PyPDF2 import PdfReader + +app = Flask(__name__) +app.config['UPLOAD_FOLDER'] = tempfile.mkdtemp() +app.config['MAX_CONTENT_LENGTH'] = 100 * 1024 * 1024 # 100MB limit + +ALLOWED_EXTENSIONS = {'pdf', 'zip'} + +def allowed_file(filename): + return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS + +def extract_names_from_pdf(pdf_path): + try: + reader = PdfReader(pdf_path) + fields = reader.get_fields() + last_name = fields.get('Last Name', {}).get('/V', '') + first_name = fields.get('First Name', {}).get('/V', '') + if last_name and first_name: + return f"{last_name}_{first_name}.pdf" + else: + return None + except Exception as e: + return None + +@app.route('/', methods=['GET', 'POST']) +def upload_files(): + if request.method == 'POST': + files = request.files.getlist('files') + processed_files = [] + temp_extract_dirs = [] + for file in files: + if file and allowed_file(file.filename): + filename = secure_filename(file.filename) + filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) + file.save(filepath) + if filename.lower().endswith('.zip'): + # Extract ZIP + extract_dir = os.path.join(app.config['UPLOAD_FOLDER'], 'extract_' + os.path.splitext(filename)[0]) + os.makedirs(extract_dir, exist_ok=True) + temp_extract_dirs.append(extract_dir) + with zipfile.ZipFile(filepath, 'r') as zip_ref: + zip_ref.extractall(extract_dir) + # Process PDFs in extract_dir + for root, dirs, files_in_zip in os.walk(extract_dir): + for f in files_in_zip: + if f.lower().endswith('.pdf'): + pdf_path = os.path.join(root, f) + new_name = extract_names_from_pdf(pdf_path) + if new_name: + new_path = os.path.join(root, new_name) + counter = 1 + while os.path.exists(new_path): + base, ext = os.path.splitext(new_name) + new_path = os.path.join(root, f"{base}_{counter}{ext}") + counter += 1 + os.rename(pdf_path, new_path) + processed_files.append(('success', os.path.relpath(new_path, extract_dir), new_path)) + else: + processed_files.append(('skipped', f, None)) + else: + # Single PDF + new_name = extract_names_from_pdf(filepath) + if new_name: + new_filepath = os.path.join(app.config['UPLOAD_FOLDER'], new_name) + counter = 1 + while os.path.exists(new_filepath): + base, ext = os.path.splitext(new_name) + new_filepath = os.path.join(app.config['UPLOAD_FOLDER'], f"{base}_{counter}{ext}") + counter += 1 + os.rename(filepath, new_filepath) + processed_files.append(('success', os.path.basename(new_filepath), new_filepath)) + else: + processed_files.append(('skipped', filename, None)) + + # Create ZIP of all successful renames + successful_files = [p for p in processed_files if p[0] == 'success'] + if successful_files: + zip_output = os.path.join(app.config['UPLOAD_FOLDER'], 'renamed_files.zip') + with zipfile.ZipFile(zip_output, 'w') as zip_out: + for _, rel_name, full_path in successful_files: + zip_out.write(full_path, rel_name) + zip_name = 'renamed_files.zip' + else: + zip_name = None + + skipped = [p[1] for p in processed_files if p[0] == 'skipped'] + + return render_template_string(''' + + +
+
+
+ Pou%eTHHWau+X-n3 zWnVG^Ca%E2w0YUAf1D2DKxDvo0s&MlAA!Kdrb|X}5L55daDFfyFmuW128FqQj$rG* zeF3+W%dYsv^a_srZy@;%*P#>euGYWhSN)5be29_%orA7Ve17N~Tf_l^fIx5%+3VH& zn%z9c>%>TaI>2DL%|{~;OYb2i&^ZL%13_&(IU7K=EDNe2;73Zp?~~e(7ki~aVgJ}P z>i&7j2;d$Bx{SQX!gCW8h@SwqRh}k*$Or^3w%h=<9f-B2{kNrQj+h8_y@>2Tm5A0R zIe^YZI{{{Zhcg>P`iwTTl%})0PRv){QG`yiQj*7 zB+cypKL!QNzA1nY-^3FAQvmWy4l@Z-tVsI5^RyAC+6kRI|D#`6VG6G7y36|Cd0Vlj z;CM6n|KvSg?7d|4-`Q6~uD~x20(K{#m0^~7DF0)Fg ^$P)eHe}=ELv{wi~>pNCdK3eB{7piJz zF{MGx_(AroLO2yA6AXdq{#~6H`}>ZGS$~rpBjVb>!%rvr3!!J^dvQk%^H*Cle?_%u zHjA3@{yTj2Kt!JW m3yWVevT)=Kfc{fPGHu;uk$X2NuKqQ?3PSm^*gair==* vQ(J&{-IeS=UnHR+s>QUe9J~rTEz7w`ClCYU$_Eq&^CI_ z`7M>h>$!csAm!zHU=Z-Px1SVdDHrvICcYP4GQ9AaYoaMvph|VzD$2eQ5esVO7lY!Y zWX;Y6bgMS{5iF`(g#UPeW@qLRy&<)aROQfL*>4oP z6C=r^IYi<@Y*$^AotYVp|570Hg{ip_IABL%Fy=ehHS&WFr-O3md$S$>oeI!bewv># zQ@k7H2u }z^|1-p#gsLS>~2c8O _TMWcUU DMhN*73B>eu>!lyRv_FlQU5ZTHobN&B2uI~CKwkbSgC zM)IC*QGVDMsLMr(8YN-}@0w`P|8y!+LFkLKY4@9JsZO zF35tbJsMp^-7cYS5jfC{MlUdtBRgW&krG9A6UlM*%d1_a;IWCySfOed&gCJ54Xl-B zN{qY#;=t5 #1wBSAJoAVgx|e#(8Hn{1 JZ4@o6f53Whh`hC{m$>dQ$kddp6*NRuz+6cCGw+S3VG*1WgMBTg?Zi2@m z_Wu+FuVFu{?6~(Sg*ncn 6^5FR^Kns2W;O3j0MWo|XG zdRRs(%;>~sqY1ao94#`A>ozmbY>!@??-CkxKfhexHosH<0hBi#eaYxgi*6(#%D*i& zhc&RavGi&2fe480TKpS=!n1cCCE1SSgME9vZsH(!>Un?7C0+W7tJAyzDIC!hsH*+| zM? Hdeolz` *l99fq5f$&qiE?b*@HDx7;QX`Bo7*X5_Ug8mjMO##ufjiR8@lp S3tmqt>JzbboLLZo?3R@WEDA_0&WTuq zwc6@Nh$Jh|IvYi&_HBETfE$BuH@jr?dYFJH?b39XuPo647Qmml*H_p<=4>Fe1?Sma z2Sxd@lbC1{ uRRe%Hm& zOY;dq;obHk4zEP5)S9;BY>cQ!FQUz-Hs3D~W{LFjR_p8AzP9RvS>!~&C}MD93mb ks$*LH=@?}J9%QSs@Q z2nuDEIquS|g>U_M*mIc@KFACo9oo{akSgE(w&2Z(u;&6%C?Bq;<;Ja?2`stPT01g| zjt+SF{xqG82SVtAEUl3&!h-enq^LrZ^ak~g5GM4<6IWc>t$h!ae@G6dd!!1Q;V# pfiT0A4;LUlcGS(iXcYDKvDo)xDEEW4d^}|WHW>i?oyR|3O?++v 2AT&9IzSH#$n9`Yj?!9}UxEBYr?n?{OS`LXC;_gl zY yLytUp47QZOT&K^h-nBL5BfTLPv%gsS*sDd`=L9`-_BZi zS!GR~l_+k)Iv;^pC{aRo?l#^DBes YpuBZ-U%8W6H+t)Y zi= foo>;z?4PV&v~-MR{onQpP;^^wgm zQ$2*qvJgh3Ij6jvxI;DIzSI{C%JUJOEAgmCOxBIp<)fREMP1FBb%{d|()P{+SK!!U z30XY-YXCM10E!SN1dko4y!CSE&z!%Ht52SNPr>7NZY9_XsCs>ko<6m;z7|nRA1DL! zc{7%CbTE84&c7@S;@H0;t64s`rVC;@sF+*xJ2z*B`CeZ(O4_9%VrBHI=|83X^6}NO zI1SwU8a|mIMyBH6?2)mQaOLo2Q;CUf$=q%&n >xA=Re?1_Ai}J++>gnGXY+Tz z=&~NcmeYuxC=So53jjeBcup0;;+-(HQ8V33s4cJs1uSh>$?=Q$L?N5VG;NIm`C1nn zh~xOdajk8Wt(@_(Douq1#wvaWxLSs(vv%jiPi}xFi&y~%PHqGxXFaUSToPmjP2%$B z@~I-9_F2k)*h+d2$~&DbDw+-_k}2x`{TL)GvLa6T
SSphgbE4SE3-7=aSJPQDUoSGy#!N9aFGjFT$pR`}X8(+FDw( r1js6IkL=V?M72&Au4RI)_OoZ}YNveb$V3RHT6vE*p;gH0|mY zD^!Vc_F +0YOw7oW5~v((UT)*!=zgADv}0_nT3x+?+6^~YAEgAtp)Hi>ZF Oaw#j%SQ7eSmhoo+?y9xL^_mjCT@vT~{SQj2 zF?~`V+V*N-j{}p@*ufrhIi-e?>iS%drasB+`px{oK9}oVqUMB?;w mfK_t5woHbT5)0-Rp;X zmQg `W%*Jt;RFTzK_S>M$L0FYbymGgs-dlFud3N-SMbnlXE-0Y& zs#UEw5-ee^2h=-$u`v~ZeY9^d9BW4xZsKZvuk(L7=nX+!TxCFj;d7cPcwN^?qB2 z5iW?Ql$eT@Jsf{(h#;w#ncOg=bQ5Qg=?CFme+kKcN426J1utK9M}_6_k7R2Vs@!%= zpLI+&cx&m1(N4ULSdMg8MrhTLUeF6#55MvcYrxfgmt1PV7|Wb=O6r$GRP;EM$0Yv{ zVdzvX*enldzK tXlc37haNLe_=F4HrV5M)k{Oe?7OJAz;?bn zMk-v>aoLGtCdXE+b !%ODRsGq5tsfMoTCr`Uc9(ZTiwY_8JQig# z!ePH$kPrwcqQDatifG>7tqe@uEIhMfFU?RWpIm{+SEtEit~yHg!`IX$;5Xj2l |6D?2%NcS#mRVuUOAH;* zEKzP*_w~T1-LIBCsNYW+tJyujHF0{ohP7ZIH>{RDK+;(35-29m{Ksl8u;8MCtC$In zJx=kj4@-^@C(jwsKkTQTs2*vRT$VLH(`{l ww&IDv`pn1yA|f~ z j5-hK8@0 zVT7sZn-o>NMDkQ(4UeUoh=U!yVRsa|M)|eVA``l9(M+aCc1a_@yu$J{=AJJ!Pd+4) z-Y7Y0WVp|>6~TGz;8Ubs<_RN2;;w|disos*EY5{11D5uhS7;|7hd zG3}=eT21+H-Tux4^L<|U*6q&eOC?^Hi*7>!&+Od{TVEPXRtw3H z_wjUBW}@8G>Do6&{4{day2pI41(>0!b>|@#^X+}bdvDCPYXmH7ul`JkOcCz^Gd_j? zsq}?C19fa((=wam?2f`e_`dgb{Z|Dp=g6qYE+Ju64U(ZjL*jj8?JVO>*~3p4-P$@D z!#~eC%xm(qNi89x_+l2HRgM+9WF3UYb*veLYHbPXl=GK_Oec-V6oxYL?=#H{MVw~z zZ4VR~+y1;A?fL1knb;Vf_`=H aJX_H>8gtRg_dg1L6^4(DXFj2)jS?%=bmKR~MY}$IbCS9*{!TT> zqH5TmrPG)>jQve?zx)N5BQnY&HeWfyeJaKs&;L#O9E|Vyyp&c_Qz_it*|#eSRTW2D zf3Z%1RB+iqN))~PWw;Y-c|is+>uu#`%%+{@VkEL(-nXgP z6`}k9qp6mtx*^SaZYR?(Y?Bxsjkl```?8krlDh$K^Ybk-2+s&{+Z2kayCB=)ql5Tq zK!4AF9JWg>n^Za#Qxwz$X7|IV?T#8|sx^1IZYDixI}_0%uDSEpL-X>JjT3kSYJ{Zb zoeak}Gsg7?MTe#n9ieG!@7{Nua1oVWNW8fFURk8bPwe|(t$~GEz0}=|Y=uAt#p3U# z$z>`AJvxt}&N9hlLzzp4D#;~r`EO;QO$Mhi-pF0=9ZjQ_dp+xIApyq+iYLomZ-^AT zad_CKNf=+qyKGULarTC8*R4Cci(!{b@ed3zx3{IQL;IZ1uq8{{7O_9;ca ;$Ond#yc{kc|1sLr6v{mAVIj6k`4KJe74b&u4+T`Dxc;>=$>yt24lU?%< zCO@6We+uTmv!3gBG~L_nq-Oo|;4m>U*P&B0W2lEAJX1a&rT2yy5W2|}a?R FIoGda6eG2TgK6-hRT3N?5bMRO@NMlH5-(@>r&ho zNAKJgHh!`$JVr=sXOUp9dY&S=%!T2Of1cJ7XEwN7M2A?$Vw#q};i^-D^umLxA1Mo6 zGQhJev3X|iGz91z7>tU=aXa6;epyPbCB|#hSq&}`wnPrD!^94dc$y0K`R5BNV=^X0 z0TDzU-v*v3W`RN1-V=6w#@8n;Q0bqkZOnF;$Kgn3mbm$?&K#B^`RiBt+WgtmXN;K< zB8rZTO>4K4BbIV!3p+RZT{+BSzx#4($EQr~dgyGiMl`g&DGz2vhZs&NAcptRZ@;25 zKIWH1si1pS^ ;# zb*}@ J z!(R^Nr#y%R7GJ~fs{&+WsbY@%77a;jo8k))lfWz>y%q>DOgn!!xiXGDw54%!1=8vp z-ZDonobdgTWI$u%ZGFrLXTwj4xn(xp=fMiskADF8n^j VJ$`{z;M@VU#O8C=9r+`~1q&90|Ql!F^vxaI3Xa5i5?{ {pCo`9JE@Zj(qI6%X5gqat*qJ)>#EG~W622j<@?BSbG=uA+VIz&kk zl5$8*CASTvnQtrS$x_ndxHcY}>7$d&XHn=F>#oM2n}C8b!Tp-WbqBU^dBJdFTQFmj zo((LH)G5B+`v;(=A-arFFVYT`>EZRt3p;mP_=*rTHo-<51O{Y7$Ynq;6mavc{TU4% z(onLNVjyaQZdXe>Cm;T7o9FvvsKAXtAnd|~?@BeF#e;87M>u8^YelenN#$Wg<$;>M zd&?%Q!Sx}O-1-eTIP}^S<{eu;Va>gM&u^C#VzMIomCS9&+rND7Wg-JMp9Nc3%~M1E zj|I!T(d+e&es>z8u!)09vE#T|eH#Nkb*UL*Z*Q+M^$2yh6n=X1(Cwu4mm8t0Y*OHg zQi0Ls!b=0?s cfDI` caghn^EyM`fp-wsm4guCW!Ex8v!n15r|J%$8*>U>cW>&lZX+|bI_#Z0N zr8vMTK;imbBy#_J;r~ %RH3Y5T&RMj5hx7+pqpRHUwPf-#1?Yqgns2 z$#U64ZpY7l_b=IJe8e_rJ?m2>WjGjH{F~v;ZIh;Dd7}ptx>3&rqqBBbD!jwx5t}Pz z^+?MD{jr{#llw=`M;6-xHO~$C)jIKA!I#!C3JYicWectVu}dB^EBZm-K;~qPCPZU) z#@P`s1`o0dZFap^ZDPe+yeIiJJ{H_IbR(tCemu(;ar*DFCDzb__mlR>heFvxn|V#! z*ncvOn^~Jb*>QjCTT@m~Q>F(O56)C!FYn2$$@mucb6G;n^l0>6GvT1{Skgskr>Y^} zH=9GkovxE`&L?!q-zs7$HB7JzNBL_^LRcQW7E#B&iMgb*?@rIa=x)j)uK2vWMVY3# zYcEXK1`TaqaNAs|Qh>S=v~5(yo)#@644 YYY4uUhx>$jpVt&=6;d-{31hp0;!jfR=o zctumaJBJ@ I*nxzgG;toej5E z+1B|(dLP6jqqx4jC9X_Dv*&Ea(oh7C$u_z0xt> ;0NKqt{i>bA zUEj`G?xP<6yxlZ=YQ1fzBY6CJ 2CG5y+6l#PCp-lg$u;qU5&fw@KO8Ebo+K}mpCi8Wv6 x^YWcaEu84` zT?%cR$HY6TlYDbDR(S75gNhD>zk?w6Uyl*KFIhC0mVl_26Gy2iE2c9qoy?z&b@Z=z zmypM2mveQ=B{Q%pSe&&BDa^f^Ay=OF;82m;!tRil(KzNH(HBA~)0PW{8-BISXasIg zv5> 5aD})x7RcKdoKa?N;)4 zReT3fKgp;j4Bw#u`R>8B_3wuQE4vz!`+a3OLwYV mo*T0)TE)r{I8({JU+uZIt9*c_0VCAg=_a!vi(oQe?M>w zCBt&xB&+4=s-?J^lLda{$H@L`M1kI)24u{<)z2#YLGj)>iOtL9nU|8C<)8i?^UIUO zj{Ycj>8%yThWxH3 b`)2SpT}r7StHEOw~0i=*JT zNn-+_A3l==!sHxOe=9WvsI8*22etbbfBtAX GpwZjShaBN3%SMwwI2F3`pskt#zZlM6<#*8T>wX{Xwh&Ev z%7E!8h~fY96nnL)MRYR%rDhFJ>l=_#%H+hD;7d;|e>sw0b#_xSOzz<5(W)q=v=1)l z 9VrJ8KLx%HIv1I $#9K>N!e9^DD z9;Y#2e*pu))#HvRf#&Z)9}_OC-%tPdmnkczV}-~0-?a`jA-uS!exngU*B7*7C?-Gi z3y%PflBRG|=-^!N`K><>9!X{GE^V2%X8xHH^g3Nb{}NNQt4fI|e$n!hK8pP>kSUNP z^#2;jqJKeL0RY$EhRZ ri2I8&13hz_+`ofS{QW 3~rbHVyuK%S^m4=HKM}*YZ#~C zH^522$l-rEF)(xQFC2}653&0DD_q-LnLQlSUH)sI!AVnmsze|u`+xWPTK#_jI*LGo zZ5|Ym-k%Mjs3phmw|)aket}ECmz3;P{vSzP|9{sm{OyfB#QcTf0T2^ZyotcS8^d7) z)`!Wj|Ki!?Y|&sLN8vA04f{BapApMlaSOCTzeHT@V6Y58Yji&TD?{R!{mcJ02QpxJ z%l`hV+niDPuN-;M{H5q6JuAn58%QVqHejhs|EmR5r6LrSLNmK33i(YV5}9a{xT^gC z5cvCcOhIgmq_9?hR`Vr0jWRBKlW%hm0f*f`lV5vG ` z R*(o`kM)ud-fmDx3pUZ}a_=vrjMeo#O*sIP-+; z9{mj~*UN_ox~orDT+0j&Zif8a3CP=AYO_lkGAz>jJ#PvrdXa{B6t)A;T79@cetz#D zQu@zE-*fS$`X5+dt?}#2)Q{IM{ EG|=n`!57Eg@0g>y(|U)W|ly` z9}IrX_3LGDQU)whN{*ObUTwC>H <5 z_FxOQz42U#`mtZdfbwEr#py8psiWU0K_t`Zhs#>44FUR6#UH}9UbXIr>JM7NGY*4- z!LJDXb3pa0b35y?J90m-+r1w$J=rqb;`BY^_Jse;KbZ%=Ou^Hu^~W4biD6}|n?~L< z$t1>KqMNKK!kzRi*4xxQ6hq{6u+-k6r7THAIG*jxOCevx^2XxeupHu^8fkv9uy&T4 zqW>{8o5GJ9h4rHk%ele=N8~}$A*U?pm@B=bPQ6{Gx7z$e(8SAJ2D2NG&8lmI&%5t# zVhc?}`cM3NSw@1r 5bFx0OZx-@zn9uXyEQfuT{Y48YRFhA- 5;$fmzGq0Uzr8#@{lh447rA~OaScRn+CVxew zrfw$wp^9Vj<-5)1vl^ELC2?GeFRnMcAF>_lM>v_2Ib~mnH}_8(lx4v^?4$?e$(e-I zKb%R)u>WYy`mK#M1djVM-GX7W-j Cg+za$a?uoRA!W zgP)@K8Gs1*?r3GZ2I3a?ru%PZ4kLd@9hA(=B|6rP7j2pCPf!0E0!%Qhl7c@oDfEIr zLFXcI9IHA9-FVOwiJp93F?9J)xFQ80KCcnGC|d$53glF06k#g2!uB_GTL^$1l+W7d zmfiXLTkT-25@f=WM({SjxVGsm1PN$fzJ2HRN$~qqpO-go^~f;3PAUqg(SDt9<26wS zmwNT`ODWAa_s#>EkeGlRl_s8^dtEPHyl0q)ynsxM*P!U04yR^j&do0u%+JQpR+Osr zSxyv_iV6D-v<%qW8vwfUaDpO$4A`$AlI`fB!S1CAP6|73ja;DefONfmwIS%6lK=*K zRC1Lzq7bDvx&m$A`8OZQy4+_HuSRD)hJZVkO ztlzY6A#r4fob6=3l*apcG2*_>RCmIo;_91pexs5+L+dX;!U-Q i6?^`yyCf?+DTdK)c@8(<5cqfMKU0%R$VLEbEt zUd4f6K^hxMQ#QXJWeih_gMgeGnINXq5--vIX^QIrn~eW7+1>$r(NUsYP!w2Ze@FrD zB7X+-@C2LU{%uMI=US2Zw8q8u%L^%|U&0t6|33M8YREj*qQ>4MDkLyE#6JNGHX zg7Eezc&90#{_FYzg`#>WBX;mOmZC&jDrgPx#n69;^9N^w|MKvVQ$fN2T%r$9wO{(U zvdEi`rdau>jq#K>)GB;=(~}JphtB4wZy1S#x(0e2QVF=y6 ub&(uBpAYfEdw_C zsscC&=v=tyuXh)^r7AAfVKetmR!J499AHf @{ zv2IOAB;It(_pENb%M)^4T(9e@Nvne^`zVKM|N9mC{b`r6j`H|&ldK1e@g+(M0i{o- z=3!9P60<4;dIYp{^YZOythx<}jnISWMk7(Y!d3NIDSS(C)ijOGm+@e4uJ9};-we9y zQJH)`!rBhOTOJucJ+|I9On2|XPMltPN_1&Vtc#%Pz)WbU9?L+*&wWRvqjX8 Ek|qp&n^*`IwK1_3xuz&-(8wZ}bqWZ6c}Mn>bWTGpvkBetu!m3* @Z?1xEAvBIt WdOJoT`AnL?AF;5#84B1ZLW2^BefwDzav5@FAZryDom>DPH%cA?EO(1GMZ1 z6J-GR!?zx#4OhW&*8N1_cUkaQ?&DnH i4cqcr@3)#9ag4#&r- iYM zYhi#98)(w1cKo}5`ifXycD)Xmz{?zUZ)5jGEcUaZy&wq7j8XNPlMhjRX-!+cPOS^b zTwpZA{<_V37aT`8tqlYzy*yvVcppsFyV4@;d?bNn=^tv=CJXHVU-8f**Y!avx8#-W z%RNjG -d7c1kxTZ_G-6ZZkjn#Qcx$9$9eS**9{;e3LCVATFt|+G}iPfIZxM z0n7x{FJJz(4f2~cRx9TW%XP5PBc-EbAhJK`?7HYg%~#=o2ebLTPYCGBT0*5`eS-|( z-w?}i>rJ<_4tMw }FmrL_s_odLO&c=XY0uOH;}=-h*Y`v?u;<=*bwD)@n2(PLQS%Gy|$ z!ae+(R4Na1wDAsqU! Cr_)0N &)Fm_c5Wkh`N03eGGA6!OJPy-j!j zz+IVbd02l25>WhlEXJXJRPgu~^8hQI 87pV6_v;o|xCb$iDI&)MctPKO!xH_m@C6`{$r-wV-+^UsVr4rG=mHtL= zuhO*ClT<)_rgIqDL_UXQHb5mWO;Y(17VZNweau^Ahte2Khh}_uJuR^s>BYW4PG*tD z!y-RKF7?tw)96%a-C2$#Svl2b`5?$|3Kafv&&mO^gkI(D%tQmd+JD@qiZYF{1t30b zjPdYJf=MQG#7d=SYTWXp^R`)1cYubEO^SMqj2`x59oq!M&*w-TmKMnzs1TNv@fn$6 zysll^qOs#j;f9fucW@oDX*T_kkv$xq{LKq36Dl;m>YR`L&v4PpCg5OlV8GGp?wHL7 zDXS-MK7l$1E*&xAGm)C~&2QI^)lWX8sKvF~B`V2V^HWG-iXPv3u?#*+-sI^DtTMys zWO$aJb@GU{$_TkfeneK5>1Z^v?V;6*ycshV{;=r+|F>3GWosaZ`-e1u$(!~y^Uq)l zC!7Oy@#=9OSdA?nUCG=TXo_=>8IZ D%`!x~=Ui zIBVevdCdE;Sp})tx2{e%3;pKOD-7c4h<+GuOW+zH^ZgVt`yA=B>+6oyWCkpihf31w zc#Q1D!s {?krHBKyucY}iB92QW$Bye_JAF2zTTd2 2Vs3JBC~0|p{rP`XWy%V^#y3N_ul=- z ujAm_R14S^s?LEgitkkH>iKvzPRjRrRA#x~$cBs?i}%Xl2qRz`vj)%aGUX z1LMB)div9CqogVQIoN?n+cxjj<5<(`Rl#Fe2JBTP?D~v&e?!B^m2?nY4^eX0EHQUI zU+8a RyGavy@(Vf-4qG`rwtL(=Fx&t&06qv)QJXUCkvGRLyf_D4O#!-l-C0=OCF(q=!-B#=id&0Sig(b_SVMk)^|n31AQ-8dI7e3Y+qRDgvg z$pK`UrltOl*^m }B87gf%q9rUbwA6Vp5Y9I(Iv=`FKx zY5M)8TxcDaT4Dll@CF!7+6s%JjAg3Pu1aHkZmfW2+X;wEcq`R+?Ix#ObG?GNVuNW> z=Nl>-V%a#y?gBd $Fkc+~!lQZz7H=G=FU_82yB$h~v=zNMbi z>OL#~Y9RNIjXksPz(HEk$n(<2fW`M!>=-}CXdwj2@M7 y_%7RVgeQv49_yBe|zZ&U!C^?rcE zwf)&q1$|&=f^P|hcu=ZNUrjm$QO>ojSW~sLfn^}AqfodDURi@b!X0#dM7_AQP-C21 zm`d%T*=}5L1m^{_0c!cZbTlo|2vxTPZJo^|OwNWCyt99l=7|Q<(>y=w6Y>;y;>g{^ zb;Yi44fsouo3#~BR>+>wgnII+tYD+)tbOnRwO)JEj{_7Dm02}c%avSMRD&s~JZYY; zbcCu@KvlvT_i%Jslc&UeoXR7!O*iTAzz2Nni1#Oj9Bs3265Hp84xW4K%~5-Bv97qY zC7u0%nZ5`Je%tazJRw3e@@N>bEv#7o2P8|$W7veX`gDV%BavLl&Kg(p?7pj;cv?;V zq1&qp?{-hM)8XP5h9}As_nZw&+?uxF$fy~QFHRXpm)cicH#6$tPU}HS{{R}UI&}E; ziqGs1HazsGNsDnsa9Hc_Su|uOy8AwWQh@0y4Ym-l8Y~lnDK^Tt?H=%Zk8TZiPC%yv z)j)$|R{+Y3uhXUqEPj30eAdO96AHk}Fb(2Tcdlu4IRaKW_V{;)!X|)B7!daHv7)|) z> -Kne~bB-H=UIP$RBj&TlM_ZtlxeB4m_ee*OtXFvyZqivjml|nS{g& z?@kdak2V)kz~3dqOpSZ=+mG!7sp}l1%^;w`+T?wV`Z+*Dg~nJ9WkxY_ET;p}fqM@$ zsYv%+gM_{nah@A)@Or2j=jM{+ycRqlb9 4J9l_gzQOAw5j`-xBfe69)97E1j&jc&Syij?%Mb19 z(FQ>pV{vbZ+hdkrfmLl`WF;g3^vJI < #&C_E?vP7U7&{` z` ?xWLJ839YA~r$8~)>OU&!W?d7Zwq5cMR3*MVF4J$`nm<4xB<=K#` zHfmDxg`ua>k3~CvV)^KZ?i7a!9-TT8y?nD#N}zcW7uR3Kf0J>zxYJ+>!ne&WF@XsO z<9+9*=dbO3X7T;hv#`f~9?;*~fr>@099@gsvgG2BU+!)6#^oef^l*54bWz09v#a|g zs9eQfr@}RaD2qVzNcVNS=c0tTCit_o1o&rBR)lFF 1>9T-6h1$NGGWCTv7bOUq*Uv_cg4&1xm%`D$G5OO z2YSI5QuAJbTi}%hE({qVn!)CTbd7*-Ugkueg#=9TWo+ln*kHOPhuD%3RmcX+(%O0B z??6Zmz+`VO8wCl_03&dmEpXKHdh{SHJG_5gZ)`N|9ku0}*)eRNyh&SdWL6E4Ta7I| zN-D9$d*G3q1W2f>X!P{1v9^GX0?M@_FP)5R@y3C!sH7@k }JR33c- z-9O*2rO7Pz(ORNk{rtXNkEAA)A;FtRy Xzl50u8jrA>WE$^~;BP-SU}Ij$)aEz_?ftWJ{C z*AF+M6yn<#jcAdBFk3;d8+$;$`D}Jg;=_N65>+Y%OkEJt@@BK-FQtcibHoO-lnF2E zne=-jK>Bp`$Tc8m5ez&`fMp!*42jC> %Kde@1Tf0xF#C_Q@ z3CaglCpM8%FuYW!!og>j#avTMrDY?@IVfzHot{{okwq)|YcQ^GMCZ;w-nzUsJ@e4O zi1E1 `SW znzvH4gJOfC-m@w#>VyooPkoRb^lL(l+i)ZAD%wZ>;2}8XPiyE%e0)v5T2@M9xn*z8 zgZ&2y1h`*&4>UMQ2p|l%E_oM$5slO@2~f;@Nj@`VPu0mzU=DOnOLo-J+`c!U%paaL z4~ZRsx5Z$b@myPnEj-dqZlL=!?s~ZIn%;Llp=pf2D+^oRd@QQrbwURWk>y>^g2gzO zWwcH?tPmr|Mie60f1l2 pE?#U3z~#yvn0aSm#rN% zfPP%qHbMtd=&^rz6BJZNuA+{xJL!^uzcipRO;_)OpS%J=PWwB~?pEEn3J;%4?@NR1 zAY!W@y#vFZuy~5@G)DBV>xA4ns9|5qeNRj53tn{ai4v%Vf~Mfs_5&{bgdD4!v)*!< zH?D-r!@KR(@17Lf3yJK eh$_{^t!Kcp9Y$7edXs)PJJ-Z5}I&B%Tp(K?}{56%1e4B#=E zsd|`$e_SS`jwjS$v*sj3seQul(DpfQLNJq9hj|z7Y5^>NJ)(%0?<0zmUMu;gdk??~ z0pxR$u3Pgg?#VR|O1rYot}3 eiW2*D2&F!cxYU^Gmwa1;p*l|PUy7+0igBf8!eC~EMx@y~ 8z&Rb}>#GysRc$D7{10&JZ=19o?76{AI;4f{yHeNTXz1m$r-Saa_<_}I2zA%#Mj zF@a$8ym*}7(gN$f)0ki}XfMCBOz_WV*7){l{KA9dSo&KIDvUaRR4{opksZIe6V?GP z%?@7j?USqbW$uVunem0>Zl8Sta#A@RvFK@>OX}*DY3}7&(kE0%#@i9_99Ye-H2X#v zAZI5oNu8x+l0Z3Dy`wn0^M1#8U&0tw~?so*&-Z^DcCI=DtS;k2YDjEg1^9C$6s!FnXVI8Nk`pFL&EO8@^71UPs;} zDp==KxP021TObd?y#%u{oaQsc_d7{c>e(xa;H9;am!>KB=@-3&bpbB*vUpeM$uL-d ziT)wI>^W}$7t9&(WfiIvg^_{bLuzHRyp7zwQQ#NUk96cj7hL}?KmExgVm6EQsrYjq z+*MW#SnfCPB<+$E`w=dlJYioO?H4`_yEnCH6KWMj`+Xh6`Wtt(eQn->R#b=fSmQT! zeswrmbVzB+SE&g)Yg#S)5Qxk6kMwi1);tD5Za|Q-a~d SdGtdJWG~);*Q)1Ifq6hg-dOM4_y)gFk+xd;9bDKyzoM7Omd4 zAg#dCKGAkY6g=LNejLuA8>%C`@E4KNJF{nG {qWvBLe<9;=!J&yW}Dqq4u--Hc0zsU(&Axb%&Y%AtlX#8@QRNthUde0}ILAQvcZ zaSqHY_(dRI*9;tXwa0%ucQF)3cxk}pyCLSY>0_6{eD`oJrm+(*{?)4n zpW2A74Bp#otZOV-Ivj7QTE9^=Z^Vthz?0tKSKNUojhv)jT{NxoY}_)>Za!a*xKZe* zHA@OmhnuprE;bG61)5(V6=cxb&=6Tt37f9$S3G=iK~={3O2_VcuW?rCbYsCBN@LaF z4LUy+xjB`ok>037Fr}iZr4l~SOb?r=yHJYP+&t$_#x|Ge3e&JYWh-K5s#H9%N@a3E z*$2oObApyw<$k<{OY*6R*{3qF+0mc>8S2!lzmU%t9CkMYBa~l)(yLE9xXpWPY+4eA zQOifqy?;$hVDr<*i17>s?VBZcy^U35T^L#I@TYquvY6Iaa(oOalTW`lG*;P$sxSo0 zL6nkMm3HD=KWtf*!X5lm9AkoWRJQRqYzh6Den;mgLMrZSgE=P0Sf(QPagvuAtPBu7 zZ3@QD!GY%0Bq3Xy{jtx~xXuh-o985R_+@cWsr_5O)eb9Ev8fu1B8?;6k;90pNRrU~ z4c>2o?Ziss@9vpgi9$4Oyx80Q0z)BqAErq(tk~JN_4`M5_qu5Ih$(gG3V%ECyTrsq z%i`BipN#u9C`;$Dx}XxZtN=$>f|24dTD`&}puiec>u7Z8;GoNKBKwQ;>kd=*K@ppO z^iaxkaIK&7d^k>NTEeSDVyU40KF*aPj+L%SD R(ub*+4e0ocPcL0c!ZE!Xa+= zy7h*VDiZH_cHP$79;>Xc(>}z0)P^2|dbU+Jf|g*~XU=L<#{8IGxc{r *XvSFgf?2|LDj>BC<*y7|lnykRk!>5k9^$Crp@~tIa z@kW8ig^^xI(z}*}Y++Mp{5}wV Kl-M9^Rin3VgUQbX zCLjh&6Ml=?11{74_>5~AG5Vk#Uycd(uFaV2+tLyBd7u(_ujcBZ8Z`+bhVa7vAhR6|~oy&o~x3Sw3*CA>mj<&+$fir~W4vdJdfKVz|17 z>SFrI*t?5s+=jEdCHoJMwMz>o3|1D1uD0cbZicBX`nCl(Wx3nIy_O?veBv&_-I-P1 zM&>=yWzvreOsz9flYV;#ypqckXqDw69M5v(ND5IEU2Aive)di=%3t19+^2Bm%VR68 zi5fqgvt63e-sd5rW%M^u<@6ONZ-a|wS*IRr=~s_z=5q;g&noW>Y#9cy-C0o1D%eyt zg dmAMU6B*YlSx=`O5aK(Z>XPVyYIn%k^SD z#dcaOYz5m6sV~$BghVm!*OR|;%(Grr=JA-~AOv_u>xbGKisH-;TPqSCsaa<+xm1PL zf97=;DxZG=H8_SVQ1L0|w=`z0Yr@|}LY7z;?xaa8j |W@I44V#y0n}1PUw{BrqHEq z=TKxE#;b2{cf+)e{Ge(&R@l{M@UTg%C8#v-&|*|(VrSvT_VUOXE5&}4YEK$rRQU 87gB#p^Hc zYZ;f#cjfn3B?m w7v@h&eGwz5W+01{&`Dn&W_$P-dbBA3= zXXf@s3oB(Joa{p-$Lhzwi?zP(H}n6Q3k!$q9`Zp4HqXT+j%|NoJHiFzi1(bI?MH>o z<}Wo*Nk6U!zmYKPdiwL#=|x`W!NH??)|&;qZWgS&TKg(T&;vBDq?>KJHyZa{Afjq2 z1)=7GR9>390H0jo>@ltK9*WuXY9q&W3Jkc~wADMQjqOb;!!EUAzBQ4Rv`6p2L?g=v zoA1YGBh}9zFlUX*9$Bhtux1oC@o{@jR_qW_D@6;aK7O= sz0*Ns+Mn+&9Gp(5(dB1I^j>)x`n*>DD^qxd2KU?3TI4}kuI;x zX8$!)|ESD|$s4D9u3RmsYbjiKl$S4XvR^cK?FY!zj+OJ$j|mg@NmH 3H@cJz`pQwl1HI@!1QRy2b~dWMrz1u6Rg?j2UDN zJ!l _*xtkB6LRZ#@d&fY!V+4x_}q`| +3{XG-B*g0hmA2gRTpM2pMGz5)-`w~^A$&u z^k~kww10%Al2wgU;&8h`zRFiE+001i`YN2OHCu@#%74`PAW-7;a-?HbrcPu #y z>b+~74A}b95$@?WB(?Vy6OvDf9Ad-#L1*P!iTJMjQcDf_jQt~f%wtzM1f#gKPDdG= zGx-Ipy$v!OBXVkMCA@DTs?^g*u9)DZs$;#~--f8f8*Utqn`8-z=`U~ 5Jx&Y zsG7fO{(8zl9Di7OZ+7=9Ge%+gd>7;Sf}OgWQ#lTL-PbpR0&JMpFEp2tIRq5sd~Pkm zH=5fHs?GUwc}6 3x5W$y-tAh!Y2i+N7GrztJfW!0_f}DZJUemfvA;%Mn1Fz? zx>-i^#qr3+((8u}68df6$4f7DGGf(EN3`*Bs2b!)kGZ0Jz4^6BUjuTF8R`(&k^;>d zsss7t{lBCwaD2SDs@|rgP@oWKh_e3Bo3#9OB@dz1J-tcfy<%2>T4YDY)1C)^E&WFB zaKYf$GM>7PK{56A^}UwmAzOjRN;#z@O(p(dYZaNc)Qe(@u99(&VubHs^z3?&*&}_P zq0M-QiFV@JBhTmd|Fq4fo_gGrb^iWlY>icwG2fHtz_wb!ZpqvdOSC7H%gs{5x&^9Y zcbiXmIa(>fZ@FoOee6S@y-34xNnCnJ?{q>6?92w!a9GV= 5x*)6@b_g_+_MhAo#PNp)3QYV%B= z1G&%n9Y$ptVe+L%bVI*=;^1rHiAc_4VCCn~f|T7@;0&^3ZrwaC&mFJKbxD1Pd9W(` zd~IzolD%d-$M&C`SVil*=`j0JVw-l#r9hju!Asl`QBVKV{9@%kN|_P+^^WYx@L(01 z!2* B~nHJeYufep;f@8Hx(%tT< zoo+axN60o~{Os9_vgle4x#y~MwH0w1uZFy|b7e$No!^3|XysHyk~EVW!;#3&oxNG+ zIRb1u{2zlrdaLcHFtMD)SM>I$Pd&J(3%I2j4UlUZt7**!8BZ5=a*B>#-=?MiVY4gf zy6(9%mcEpLu1url7 ;L%Jec<~V? C-tK4p(pN*$V_y-5y!ERp0%eT!XGz=|yeA%t@YLQFY1iM7XzL z_=im|bf&B{X^p$S`#846N!FhMJLSK-tU(;=f_aqa%AGta(pBar#O}{*@Z)WntPktI z*Q(@>N>geh$PzUT*x(}Oex=nmm|>EuFMitxVoL#wlqf3Ji)D-O%6J-L1U<2+dXARL zV`}-y>e!Si9kD?U@8kOUquc;;YcG#kQ4fSxX7eWu-mkY5q$G>C1zgP$xnOELWxOg3 zEIoRI_= *cKEtK8%vyQWH3t-~ ; 1uR~qTE7E&hApxBlp!z(AVIHtA)smny~|8E*8qWJ6X*QJzjelfY2S30u^AcvDt39 zKs_LFfmpB7?YeVRMK*Mx!W3Eb*&Da^l1XBhCRJ?e; w%(ZB^ybrXlwT8O&% zwgt(qFM&I^LMHre*ie`z*xI0AYry=nCO6Y&m2F6^n<}RPBw+>d;@4E >g4z7<33onB;u^I7!aX?gGDolPuGXyhmR1;V7?f44Lm%2}LwdCMdQybG_ zaV1D0Z@4a`cIAgXYBBfp>FlIb$3X265A(JkwkIqhUZOcEUQpF$St?MjdUEcIwE_oN zX`>w2TvQk|GEp(+!+A*(N&m5f1Cuv<5@@i8RCt1%8%;Q@#ZYiNu{q l0AP?IFPyqfO2&a{;I%Q}OzeLmXJzXD)FJ z>lxd5!3QcfyZ^Wk-tFRLtid>ulu9P-hxF|85_0Jb?McKQ@=Er73ex%da*Sy+#!s3W zOQ6CwYx4%N!AhqnNE!;Jk@4WKRra71zq1+fvcf))#D-r`yh+P3lo6s5+G2r~W>Sz; zqU0@G*@Lv (-5Kl- U^~9<_EwGqo!qEEXLCt zZYc`Xy-jZl=mSv%lDzSdg62b|Rn0e7bs@;B<${0%AJ~)_?6-~&xC#_U8yt75VyXZu z>?aF5`Tz_4=xWN8XXJdXUD3j7NY@t80TW{KHWjv=7JGEp@a+LHNPqAlV{so5sDJ5s z*xD0`tlDCL{C>Q<3m6JGz(+5wkAv!#@k#rUaf|U&jbcVgk~d9?`}EoKK#A|{fm;dj z*dNNrAud&j&sc`0^c~E5W_ElMd9XQ`+rRs&Kxs}DN*hNaJD8!KrU@O8zi}faA{FD; zD37WzjP0JPV~m-JWDF$AF$Ov}zo5ci5V#jcLHdF}u=TM~wxAL+pN1-RB5AR>j?J+7 zgyar 1Gv zB<4NCpf`@)?tQhxgGd^=w9VTyymtU<(vvjcyS|gU%m!CbU>}Arh>zEfFZUF>RY_*M zDwkGi67((Va?#% ~WX4~!Y2b531RS9tO zhwIoq6m7%$w%QazI0PD8cN^P0ytPw4rhMy=YZU0Z=tFi@$!3TGZ>r*ReAQizE|TZE zEn7o $?bO&Khx?@*zwk;_?23MV6B_!yYFqq71 z#mtUfBWK+a${_Q!yEEJHUJQzS27)INCNZW24lT}^cT6shfx{PObA1`xMFz0e^=E-o zaT2+$pJn;1D)xZ^K!LF2k%S^=?WmbAUwG9^-ZKlUI6XGD=0<^dPk~q(lTBP)ox52f z><3BUYO@=~29(^Y^^6MdSXE_)gG~Jpu;ms)jWsuapf_y|1y+zZu}?#qR-$*7ji8nm zBWYC(v3tVv2Pj|sJ|@?$;Z|(!590PQTAas?`pwzb61kD&vrMcjTtUebd *XVtH_+WSg_)0Zp$5`tq~gOek1NFYYTGP zR%~7(v{h(PUby8@JoBZ0TH1~**a%9*X}=c@^A{AHz~Ppa9k& >g+LStS}Tb8TKBr|K& z-{ms6 h-;^yne)$Iiet!SI_VExT6}r+ggb)E^|y9 z94#ayl&vscJ~FQoElHnbXGT}U_$8 =$%`dYs&*Yq zcEeYLuu9|eAen*Nk@XiI{i$&91!gu+k(+nfP`k@mBb%*(N$P!tQ5>RU$cqhB$sCo( zz3-U9yDfosk) Jn0D zXV9wS3 !2H1*_JP^KEw@FQY2!mX#i5hx5bwoDIt&)iJlsYGN~g zKY@f$mRuuRPiXPdHW}gAyjA8B$XRc6H52&(5tQO}^L>RX*~25mXG0mzTDyM3kC1-2 zM>+HS13OQ#*rk+~ugJ)P5a* j=@u8i%HXNLt*jTl33TVO%5($cpJeEfCUCD0U8OoVZ%wQN8 zm1a}Uu<`IIjsltNK#{8s2E`s)!GIG@ZOXFWFe)eCZgfp=m$=-<#L_xYHyPrjFEs2M znK&elK^i8jz`8dz)?bnJ>s7=U&yKS`=gC{c=GiFy(jkuSx~@juGqPL66@Ag1)a|W0 z{`$FM2NkA^17}KBdicVM&_9Z=C~K$=S}O%8s{|(G!N@j8805v=`@%@VDEim(3RRV# zu!!k-wm@`|9p2RwZEZ?dD={>kfa4c=wHhwhOS}tjZ{^)6`Pi;Td?&H4*IUuBR>_=> ztX9U~JzR^GKqoBihLxA?I2oTbQ$FUMkhHVgAkFl`i)lcxc6VnMyCE2ee8@6pm&-j* z%+=;QE@lw0a&I8>_8?8DTF`n4jhbAip2WLuA>EH@HbJN#Sg#$sXj!!iT}L0>(qgXT z*!)7`lG07HKtECjjoM}br^ryO;tfi&LApE+Rcaw_l3q%QWaB*@OrOECpUB-hOIpX$ zqLKT#2NbRqDcMJ39v_{yt=&PsEWE35y06WCV3ZAwPZg`}s@);9(=;jEdM~xJ6Fx)S zz8j6KIGughO1|E+Tn#S0O*|`8Dz#SoC|N;e+iiyBdbJVbfZ^(OO{7YPXos2?qoEEm zuwUNMZjJJRb{O?mQ3Kr)pK}}2C}m7k*!FO1!&=L1Uh?{a@b1ow8=I>kHvT bnh*WY)&T6_|`okID~C~ zkI@xdB{?2wc&*xx-3%3J&o@;nLfa8KzO3@fq4C^&p<7j^$rk?8MDRu9D-TR6(sorA zZhTv9S2H?jv-xZ?da1RS8|%m)NUY!w^n5Fwq$bspzl^0)#aVQ1JTOUAtOf=M>gNm^ zW8BVEVn^)0Fto>9$<|-$u*;nMOyJ*9YvEDO)x{K9E%)W}nTp_FRBs70vo0KXt>G8s zQkOTo?R%#vAZvCft8n#;A)52fviG#z3NJWfc33uP=RFH-1F1nZuVJW#Ty2yJo>~y6 z=`n1DMP}AQql)mvmP2{fHV44$V6O=!#d<#8?va;!pQ>BTE~?>@F}RurTba5;?J%`e z5GLroVcUPblSwoJ-!6ex-`%Ze@}Gj$){pbH-Kwj&*Uil$qPerW7`naM&`x_@D duW^cyqid?53Jd!!=}&3mupi3t5B0%B6M-9>=#Ge6(wxt^eO*BerTL z?#oL@_x^kDd98NK`0M)`jDi!@=7@&c4Y!ze|0|jmZXiDAS6xiG@|ifsA1LI>jCAR@ zt@u$kQa3|nCcfQ{U|K%7ennBwua3oL9WJ+LGJERXt1C9<=s(
LSh;?dY|5(YP26bM;?ri_(ZM^IhevoikutTi@lLcWX!=`V`Mtu$s0=aqn8T ze(_4?mB2}^F1y %^-A)`r>Z^~L zg+8p4`LJx{Q1#I?8RQqwz95$I?n9~P`fSub%4vHRBi?d&C+hB)k+gWcVMLhadk-g5 z-3T`(F`fzOFjT*TJ!^JqyIRj7sSG%PGkssG=8Uu7*&@})T_huZnav8j>&dUu?p@@G z+?=#-=8U;h=WfEwJ%N$s9`m{#vEYTuQuXs(Z#aDIV;F^N-NBoCz7 HgMbK*|V zM9P2VEeF*~OccNK?|gTh!B|K)O4T~h*X(hd(!IYb^_nNw(*-w4?iGw^`p9ae4b>oR zNAjVa&8DZPI2Br+?v`Lzmh7BL)b{2Tn(640wCf`yNUjE9{X>~b%eJ+_`0N>s)zxfN zvU2Fu&fS3EoD`RDF2!5w^=p-D7Q`aSUz2>0vY9UhlCR-Z!z$nEv$f4N)AWjt91MzK zvNz|KS9Rw3mmU%Emxjnyo(aqpO|I7NrWgN?V`|}R9?@EdwCht-Odpj8s(-g8$Se}Z zsAn+SN49sLeOxv=3%B09|I-VDE^uJvD(?c}k2=P$t |4 zb+T7gzTXoBz<@b#vMhNj3r&*|qC2}f15|tNT974+P>X4SDbgq(Pfp_nKR+3NSumcq zf?BkXb8nWHr8pyLtjbusNn_T}yLSg#dXggbS+w`(b7;x*Ai3TPfb&xd&`&YHNwp|L zaVX0~B-518a$Uo*1?%SH-#nXa(fY6m(#OXnE{X_QJ)fzC$RBGh-b)mhIag(_Y&mvM zIqF}AXvnvLXEz;TCM~w3u{n_OX0IX!1oDO34oU7~Vk9(|f-_3xj{C_O#1KS&995!` z7ntXeC+uxUYR0ZQiY!D-*sM?sgS2E&i2)G!)X5X!N=m{GpfO73ZHez{=cNCF@~$^U z^D9U$Mc8_5GP8sHWe7S0sG4mNvmcQwuic>p=ztG+A*fu2!F=nPULo^YGT9IWTEB5> z3g!yh#H;`9@ZDw!1s9T!!Laz>c8aBU(3-n}4XRXs` @Rd=c;W&%H@;72~adQ*k#j|G<@1n?X~Mw$be?D*vGP$s|&5ck9F^?_U}}DO71P z)DVk_{}31-xoi(x%l@BNPo-;yqkhb v?9bAS=h+f8Yx8O^<+l`TuE_f0vmH znd(sp`v>WptGp6Bsw|b}++;-tAMosrm=hknoQhs7`nM_82R)`@4(*i5lJy&W0Nc)( z+#4Dr?ru9flGO{`1IifmN&aI4Lrrow4Ouh62RsoD_w%cS{A2%p_0V_R{HU{gnCCy; z9pcG_l)W?m=hjvv1qtg{Nck7*Cr&w|&dr;J)c@QfP}N~xJKHn-l_mQS{0T}wK3#=8 zsKAG;2G=AFmI7k53+exPbN2EDjGfOB?+8!WU%FVfE8Y@Wi@PQMq2cw3CsnECh6Dd_ z%AWJYO2n+JBjsP}->#?KB)%KYcKiqIaZzgIl{t9VvwqsYV!Pn_=o~RlqD%E35HBQ! zmm+5Vx0#fH_tg|H9c~Bye`u?ddQ!>Q+@|r*yH9qnjKe$B(XRb;{{SKFyD%I|=>DIE z2JAlIiz8$y{*rse-{g5oN=G5fKYX#yp&*vZcIo{CBKRY_cY}<&66}wz93jRq1!mU_ zv=Kw5>_z_~I6icade~(sJ@FqdP;m*9B5;a$s=v%Sw)PSL(fb$3*9r>`ulP@~#s8o; zJd{&95Djyr{`;n~nZR1bD4~>>E~eY^FN$9aY}mcx7j*w^TDh4r>SW;5W%zG1g?$ye zN``*_P}1sjx!18jr=Q^u_fEc^qN<=K?h8D;<-l6^PACLJW2GDJtx2my `SyE znrY@8DIi2Wm_PUe`VLwFJ&JvT#iPa1j_5>mLx^ASu3q>iik_FAmpSQjY4i8kie9G} zJv&C@46XU8SZ$>wF}2TbAyesamC#CI$4Cb%N#@%bj&6pR8D(`MLDF1txktZc3A3l( zfTMEvsun!1ctnm$lSY%;`O<*f9K!VyLZd&YRd>MC-ABYzr_9ONEOMBwQVtZFNWn&6 zQ}1l<8vF8=3oR$3<$`n5kUJ+;WC^<4B8e&^J2wL1%Kz~y{YdWE-L)kRVcpO}GpD{B z;*z-3Bakzthqm?&bQ?1GJ-G^}Ote!xcxy5h-mbr26nlEXc%xun+G*S;nue{rGjtnk z5!kU{T!>`G!-g 20>R8Sw=Zg#@o7C~?)ZRV%zg0DqXXDW^+UWKoG&Q=!kwI}f z#oc}JA$tGM=Rh?S?Vg;YhTwT0f0_%R%ZV%){04I!J=8x3vUABc1ZcB+{V6mbhY(~R zwb}0Q>`z DI6_8cz6ExXj;H zNj+jH!ya~q#?$b3v!i^f?+~yvp-FVr+=Hw fd{W^AEwjH!pA$q{?+IunW%d+j{RC zaoEQUx%U+gS_<_fCSJ2DGXceD#I+{AGz|v*a#6;IUC|hJK4|)d*Z9g|1$jyG`RG%5 zQ%AKh3UcM^G-L))TMIv3<~RaP2d_@9^vhq?rRhm}v41WQ(eC9bydz;cH_1(I26%Eg z=jtQqje0e_@_0$lmy@$4<%syb+BXxO);}&dRsNb*_RVBIVTB4C?LwLteYWF`Hr)^# zrdl3j4^yW7Y_BS8AAV>>?(i}c`q@nVK80{Tk}8slnQE2BiWzL9>ma-kMr7SwYGtM( z(mOFYF*?yZ?ayJzVUl2$pqJR+La)ad!NA14!sy9p3BPyf9%tpLIKFEk)z+RTMdLWL z5|ctwyMnJ9v@#nyS-)JGvOJviDo}6h`*JYpLI^hvLr8XrO0aqeTl<7XLQbs=x*4t1 zvAlhze24E+N#js$ackntiVw0}*J)qQehE4~EfjwaPH{$Q(k*c4BUj)@gUsVyx+OXy zcIMm~+m_knGGSyTx-23j%nGAkI#05iQMmWoO+okBT4MR_t3&rbrnycoFSDSWuaZlL z?eRM^S40pdu-Jg@n4ue@Zdt5yMD&ZE8}V}Z! Jx`2;B{gspemOhUV!Bqlj2bl#;0&lhaxDpMALx zMFtAShzh=9pBluda(IxfQo;COWm^%y=IA4gZVBB(Oi335Dx95M5sd5?_zvjQ!GmJ_ zCB6OfH1jfWmnxdIG4mCMSBGwe`~Fxh{K)aU<-tjFYM!8C?_+DX^W=L4j2mS#i#|Jp zs!qNmtKV^dI<&{CK0F*0QK42U(A(%?&y!E8=rdgYoa^ %*h{`}`O*V%zT7z)S5 zrWxov^YXyWc`GHwkMEisr4xRS$xOVRqovd%hESm!z1EsfQaU~A_52USs#`_YAKhPf zb_6p6-37+-eGQfSnYnihQH34fve8;IS@iK#qDuOac9sEOh@B_?rMTvJ7P}7PBy}#6 z9^LQ@J)7+mU|w5;HA95hOW%Mbq^+ZCh6sHU5nU1N5W>(NjCVqFo|TE?s66eR % PhUJbY18gvdU}#dBC}U&|$iRwAP+oBxS5Pf`fB8k>TZ zqE_BVm@gD>(Br@`RKMW7X;WdvlfYXkB`@F0?|nV*N}i!&u&2pX)Qdw2M#-~21=)Yt z6hv>TXe{M@ z00A97LToX}gB$S3RH-Xc_)WO`A{;{(^cR(ZdCPprg5s9cVL;vZFm>T4KroEXuzWY1 zhIjA 3Q{he@jAl!by)sYzIoNU}vfvcf702?ZxcYa?~shw*VzW2`Feb zEHtC$edTBQuocD|U!27@Bs|&ntO-zN_Fg{@KaQYAlMy*i2fN&;CDh1xnk%}3oG78c z(Nd{86OPn7zm@m~$lt?7aVjbo1i)1?>;aN41)xsgo(~<}=EqL%Lu*7XqBF6;vK^d| z)S5_$AJidR4ze$=)0+q!WnW?Avzu@5lj&dqGb?_H&-0S-*6_3-E4dLM^bAbiW|g+d zp0BV9BtQHZKu$jf2~8S%Lzmo1A;GE6lG<9)VlDCI{+8D)!}ESuuYxR)nP(k0 -C{_MF zJ41flKm8G4x&dZ!6ZXKdcbFaZ+H0*-!&yJgFJM@kr`k2(x3?BDnu=`YC{-A);r+^g zJ_WY#jGs7s>s-FqHMJhqxHY9fJHe157L<_SOE)K1X*x2F^k?A1uWlmipwZdbnwmo&rEbW zbamNK^yP;Aux{~18p|TLQ>51_Q9A(<7e&I7Utfz*m3z;#8 k zP~Fbz%C6rZ^$+4P=J!6AZv-oKxX_pKd2UeQtl~FWPMfjmevjK}{7#udA<`LwAqBI$ zR-(i8$&b~PoVU};t!vZD=RaRA9a267l6!7hf5gAIpSY?= S6iUJ-R$(lF4HWmJN(!??5dz z)|AEbjp~NX6aHIa`|{PPd*rXmKH|5vIa<83I*& <3T zz!R!h3N-6mUPW=*b|m*%r{1z|G75V;x3YY5ZY4#yqN%#E#$i=^V^s}gDs9ti?cT^d zzO9)Mb8Xn$v+4kM_`A$7mi$c1>ym{UDbS|-QO{}O=)1m@bB@^u{pzGI^o|U&lV{mI zee=YLfEcpc`n@s{g`RN`p!BOc`pT~l2$cjZ<=wH73w=?a>H5Ybul%>?IRLZvW_*Lg zx4|8mr<21_bK}yae6}kdUhJeu?vgxMr+paMeSf-$ UR?ddpqTwlnK2T||Np-P>9+KpO291guL0`0lZ zWXWFP$^AOeru@^fC1W7`qyPl1{pSC^ Tw&&k&Ds{n~s(&yS z&bd17IKBKY-aR4 _I@Dr4#$j+V_1`-LPAW?0dG8U2BbO5E^5?7vV z_#s=%uFUVbK4k019wdZiMlblB*kP(4B_`#98KA=C@8cNK4FH{&!ScVzQKD&M4UUPi z4&x>Kr~jIFd*tw;XDyOfe0+s>2%nrcTCC)_Aoxmxbt?8NwjAq#&J9LV>D$h=qM3vB zsWNH(XbkX_kf8lT>jCR4r2AN8h?=c`v+v0@4N?R)&$`W%_SDLPbr1Fn7863GVJ;cr z-AYDN&M4qxu)WqFm(1^~k#(HC9SCIXb$?gDX$Or{dCd{z3Z4sy8%Q_OE`G?P(!6ea zcV3`Wo8IvF(Q|VILK!{hX?qGPFRv2l{_%?s9=xHKpuf;hA ex;i!be5mh!q?@Cb-vav^u{&K zOIaE#ik( 9pOCML zG46-UllYT7NrCAhuL*^e@5&8~^h~~1a~+>inKA&?hAk?OC$TX1wjna`F(_N^Z3 zzpvE)<+uxKEpn`N#QBjK-osH~w&m4XisUcuLqBlM$|oduw+(u8Gq!K=_2SUsD~IM( zT|!DbEnACOeDc|0C!r&HJqJjJr;l_inx^XuqR@|YJm-8~&E?zG2iWk9tu-AK=?Lq3 z$bFAijcb=opDv*90idrhx;ib#I@fMj2dfYm4?iMhw+~lj_1$)t6^; 0B@iP`0or#+UM_( g$ktBCAamZNx0;I-cp4Y A*rsL0L=M92z}7+tExC= z&E|=cbWx(X1~hnzq5Y7YcIKcQQ>WHzN^7H>05%1_Sy?^*S0ul#s++pAuc6)>$mURO z3dwT=@B4(6v?ZS5Cr7BV%_lx^!{6iF=z>_D$Kv;oo~5dRf`q>x!DidTDXf2A#M>7w z(Ce12h4V+LYII8u!Ci0rxEjs!XTwPB4LNE`2+M1>sxH@`5Dm(+M)e9QDXf{N#ky4s z)BElvGOqGuKKo8!N 4qV=@&-xFuM$A)YE}gTbS6jrrvlZJ^4i)E=Id`{Itut7#HS z%3*D?bU`XU4T?wV@H15XXDmWay@C&d`o3H^j|&vmg*7Fk<5~Qh`fNE+&_K&k0CUwC zXWv$%bMjV^&dR&SS9A0o^x(9b4!E|WEJs;da9?! YEN< z&hYTe(%owl?)?m~JRx_?vWfxghQDTj=BPma(Vp}V;wJ*#3nkR_+pwk-)~Mq4M~*c- zBm1CI$5TLpsdRrNn0V^BTiN?zPHr|xbCRJV&7oZhS>Bg!W|0+ANL|CH5ctgJQ46jk zwmHK~|GUP}xy_@{%GYdqKbq;fCrY|r*>SNB*Gz~?mSL?2Abt(~N6J9E-&peiAW^@S zgg(e7vnf=yUSZHRiY|!1z%y7Wa3LZ#;5CJ{RZi5{)j=0sZ`Nn=bY}tU7H)PE1xQ{g zOg1J`HZnQaEwfHXeR=tkE+}eb;T}WGV?lEmR07wjG5gU+RrCAG5B249CDaoRQ(!MX z)w0fPh4DuFnJQjxCC!zeI%b>LZBrI|x=xGg7*!4LdXydh!75VjUb9S7Q&oo75h#?u znia YTdWM+t9*wR%Y9!!2bl(5LI zRZ zGyc@F5H@=n_IsRDU^B{|E}oL=7J_mH9C^)i11DV81!bV5m^_ECc~o7`!qNT6xl7#3 zIfHLD4@R&eSJG5w3T7#&s(^g^3hNxLrRL!iNp!6OONufAH
mEw0SaqxYqCAL7?ED*^`O$W z>geR7?1+VRowi(O!IGZmujU>cdNud%y^CtExC7r8Be%8#`Kgr5mq4Ym(VK^|Pta)Q z9p{CegdtK5Nm~yu+G$TGy=>?| v&oOtw>@7Z zzwo|wrkePnTR3n4H+ir0L1pViffYrL{t(+%!s5%ga7g}Y^5deq58~4XqFWJ+U%GEv zN$HtOCUIee-evQi1HM;d-n+FY|CMCzKDux-_oJoCsj?yF=0e@LLtb=qp90-al~9o> z;g?;UtDB;&V85EcKU?DBAA0?Ly4(~$kgOh)d2*=GJLM>M=OiU=iHZ1e6Iw4{bG1zQ z%Yjw{XZTxOy?gUzJvfP4dNeh-FWy_J@M;>pJEJaYvwhpx3oiEiTcfF)`mVRBE@Tbn zENpEo-T9pC2KJjHIyI#%`9*%HK9H{4Oe*dg08>{DQn6rJ_uTNO>H_KXvFwjv46eL1 z`Zn%07<(WNjKMglw+Hg3)wgsnbQ7CGRP-76k7${IqLt<)n7ZD22|Z&I!I@!yyGt=i zN<$qRWsUbgDb+v!WITBPled<+z1?&kA0YO nvqJEo!H=_QDLtu`@am0UaMf|KPm}BRLQ!}ZOFBxE}q=ib1Sv)YWhpV1?z`N zIAzg}D1()R0xlRrgc5rb_Za2VW{5co(Lg8_ov&uy#+kFC@l8~ew6|Tu65<+@ypJYw z{j|NRR5cC?Tc;LFEv|O07N>2p1kBhU+ReNmIkC+;c(${OdO|Levd5FqoQ{wCr1v8@ zUHPMsQH+rVI^T6&owDKWX29@0TIC5J0L y7nqt@2{ zt&pv}SbD2M6AP572ua9x&lhiafl)^4;iLCyIy`Nj$jEa<`y4a99Tce$%e4Qe9f_sH zK7 ?rcY$wbY(WBxaSswrdZpl}Zaxsp>nGi_z-tP3?2Hz!x)y zNJ==QW0e! ^*m_8bXor3~=w*yiXH0$MNu$9`3)&RYQbEpA_k)%mD|X`@&$nkn}x0$9aaz?%Tvo_AU#?w=do^I_GV-s@&y=O-NL2 zt%<|gX_B=>-*DA8j4ZHI&;BbBF Fc)n&UH ^yc8^Q@v?Nh(I3)N=z}`gAlwUG z=l%$5tE!nZ4Q2%t)}A3%50)GUhWOR>=+?(4B=|6dW*3?)wI>%u z{i~a8a$5aV-ZzM{1zO$_TDHA;aMg$cOGRB{Cl69v1UR$C7F%y9O<2f>F3Pvwc8TR* zUdW&%YUVbW(`a8?^LLa&R%?>|*QSH`wgT)AvO