From 306b99bd3df7cc504ad36f137326755cecb3422a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Schl=C3=BCschen=2C=20Timo?= <timo.schlueschen@uni-hamburg.de> Date: Thu, 28 May 2020 11:58:49 +0200 Subject: [PATCH] fiona toolkit --- __pycache__/downloader.cpython-38.pyc | Bin 0 -> 8579 bytes __pycache__/errorStack.cpython-38.pyc | Bin 0 -> 983 bytes __pycache__/fileLink.cpython-38.pyc | Bin 0 -> 1548 bytes __pycache__/renamer.cpython-38.pyc | Bin 0 -> 4123 bytes download.py | 155 ++++++++++++++ downloader.py | 288 ++++++++++++++++++++++++++ errorStack.py | 17 ++ fileLink.py | 44 ++++ fiona-toolkit.py | 40 ++++ icon.ico | Bin 0 -> 82027 bytes icon.png | Bin 0 -> 5499 bytes main.py | 16 +- renamer.py | 142 +++++++++++++ uni-hh.png | Bin 0 -> 12454 bytes 14 files changed, 692 insertions(+), 10 deletions(-) create mode 100644 __pycache__/downloader.cpython-38.pyc create mode 100644 __pycache__/errorStack.cpython-38.pyc create mode 100644 __pycache__/fileLink.cpython-38.pyc create mode 100644 __pycache__/renamer.cpython-38.pyc create mode 100644 download.py create mode 100644 downloader.py create mode 100644 errorStack.py create mode 100644 fileLink.py create mode 100644 fiona-toolkit.py create mode 100644 icon.ico create mode 100644 icon.png create mode 100644 renamer.py create mode 100644 uni-hh.png diff --git a/__pycache__/downloader.cpython-38.pyc b/__pycache__/downloader.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b7ee572be15028dce2bf9a1f345e451e9e096957 GIT binary patch literal 8579 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 Ang9R* literal 0 HcmV?d00001 diff --git a/__pycache__/errorStack.cpython-38.pyc b/__pycache__/errorStack.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8e72ef1e319f60881c145cf582caf02222681e89 GIT binary patch literal 983 zcmWIL<>g{vU|_J{b2=`ak%8ech=Yuo85kHG7#J9e6&M&8+!<0BQW#qpQW%?=qCh;R z6y_F&6y|28D8>|)U<OUrWMsV{HWN(03IhW}Dnk@w3PTiA3S$aW3qurh3Udle3qur3 z3Tp~m3qurZ3VSevCdVx<*P^2QqTrIm<m_ZdkRebEVuQ?c2Du01>~w}2hIob)hG2%3 zjD9N_Z?P7G^sHpO#ZsJ_leUtfh@F9f;g`LBMt*Lpeo1C-zP?L-c4=;EUP-FHo2S2@ zqkc+inSNSkeqN$(T4qkFZc%DpVs2`Yek$AndIgoYIO5|o^D;}~<5@u#gIvJCSS5^b zq#jJ3Sl1ST%qRi{Z4t;wurnb92Ll7cE!O0m)WjkXvlyh1fw4*e$uh8HGDtHtSQtQT zkU8LR5o2IrsA0%rSio4qRKr-q)XcPykr5n5U|Thri&#K*uq750q~@jE;&3b|02{uN zxrhxU!3y^KEf#P<fWi;SVa$msDcne5zz5a|jwrpvloUTrHc(iBbjHWu;);*Y%}*)K zNsW)c#S<T2SelpvktyP2U|=W$#b1#Ch=s5O%mVql2o%*IcNT-(#KFkH%)ty6!=1iF zu%@qI22GYC9tH*mi~s|LEI7bGZm3}dC8Qdr8isgAP;!C<6;lx($bI}Ef)_-9-3KPX zjs*DwBv}k{DFY)LW0fE*G~r3YPm`rc5TsWKL<oZjkTyu5f{g+bVDmuk1lb6Vbq+?b byZtnoz#a#4u<5$RVFL+fJCG~DTKTvDFQc%j literal 0 HcmV?d00001 diff --git a/__pycache__/fileLink.cpython-38.pyc b/__pycache__/fileLink.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1f621cb2483d5945fc0bf744735e158db6f620d3 GIT binary patch literal 1548 zcmWIL<>g{vU|{h5c{c7OGXuk85C<7EGcYhXFfcF_D={!Iq%fo~<}gG-XvQcecZL+E z6y_F&6y|28DCQK#U<OT=mmuAK$siIL!_CQJU|>jPh+<4(h+;}%Okrwah+<A<NnuW5 zX<=w)jABh?&0<Soh4WZa*izWRGVH1BS!^jBa2`tvX9^csh9i|Di!Fs4#!KNz;ca1v z;!NQSX3*rn#o?Bjlj@V1mz@l91I$ezHWLE_gEPo)G7Jn1HH<Y3@eq=+hN*@jo(U|% zoWc;yu#(YFljRmiT4qjaNo7ImEtb5*+|*mlrA0ZnSaLG+vNf4+u@tA~q!qC<FfbIc zF)%Q!WGLcfU|{%VtDljdo2p-unVYZglAm3go0?aWs_*9M@8_tWl3J#pmYJWIs0%V! zw<r~4YLPyO19GljLFFxu`1s7c%#!$c4v;fJ1Op=*7*+|wyrl<IlgtS790LObhz-JE z|AAao!;r-g%uodKw<hB){&<-7_;`>HRx%cWOb0s}LV%J5*gt$At3g4<z*NNx)1?Q} zlnfSyS_)#bzyef^fq|ifA&YSVQw>8Fa}DD{P=K<4f)e5Y)>~|)ML9W{Nw-)F5{rsc zZ?Tsa<z(e&=79sRhzAscOb{1=gOn2#u3!T0EFrkFn921xIJ|k`MkCB;Wnf?shntV= zZIBlH-mYO>zyM0u3z<@wB^hcM;u%5S)@1Sf#i;)h6eBPH|NsAAlj#;)QE@>|W=Rpq zBSnHZTp^8c1u4E1Mv7igdIF`|B5Xbd#h5(84y05C(?+ImZ!zi>iGVyM%D}*&$y5YN z5k;Ud#p+d%Gn5g|z_1gPxWFkHWDF=J*Dz)?74d;eoD`;D25<;7`-Qk^G8Tc1(uAa) zD6Zs;)a2}Vu<yaK3noBG=oT+n3g$_5klmnM!obMI$ih@522bZG%KS9BKv@!$2;$>! zamB~y=BJeAq{heJ;)#zhEKSUT$P{riFfiQWC@9J=NG&R<1m~h#Y{jW1C8<S4ptJ>c zWRWB&c)%_~5Fob|fqV-}_QjxbiGz`Yjfs(qnT3&y1xho+Xs}96mRn3kske9_8A=bF fpNc@47Ay<N%%~RJ;;?}@+zu32#UO%%k%I{UNzful literal 0 HcmV?d00001 diff --git a/__pycache__/renamer.cpython-38.pyc b/__pycache__/renamer.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7861889baba157474f84a68ca5ef2047018eb113 GIT binary patch literal 4123 zcmWIL<>g{vU|_g*cX!+;AqIxWAPzESVPIfzU|?V<c41&(NMT4}%wdQE(M&mvxlB<^ zj37314s!^IX31gBWr<>eim`?;xHF`%rm(dzq_Cy3H8V%Cr!WRHXtKWqneV5`c#9<< zu_Qy2@fM?&CgUxxw9K5;l+47O{Pbjy0%Xh#bA%rQ14Al96k`fQ6jO>&3R4Pm3u6>> z3QG!W3qur33R?<$3qurZ3P%cO3qurJ3Renu3qurp3Qr1e3quq~3SSC;3qurVia?5B z3quqa*g3+t*n?8@5_40F{F0fFECsPao_7X$UXFo*p@d-pV+}(M<3c7zh8o5ihIpnL zh6T(E89?3*W?0GSr^#}Q)vYKoH}w`re0*kJW=VYfEw<dm;*!*&TijrNd1hWpez_*o zEtcZcoU|fN1_p+e3`IN)3=F?)^fU5vQ}s(SbMy6G^0P~GQ}aqv_1!%E{T%gEQp@zy zGV}8ibwOdITLf{gK9trgs4U`OU|`?{Ig}0L14bT3HpVIesJHZBj!9+&NkTCwNI{Ch z-m3$9uZAIuu^H;IET$~x5|$Fy6vh<B6sBGlMurl$8ip*U6y_9`UZz^c8b*+O3TrPT zBSQ%TNCvEvy@nx+J&U=70~8g#OpFXAoFI`Djv9t6t`yE*=31s2rY!Cht`x2m#uV-p z9+1f?48aVVynZiP85kHeS#GhUW#;7EVkyo{Nxj8VkeE^dCM&DbLo!koic@n^lS@)l z6hI-N0E)I^g~Xy%h2)IHy!6x*g_3-Ql8jUZaJVTX=jWBB=9OgT=jkY9>ZR%_<m8v9 z7AYhr7N_bcWK<Spq~;YXB<7_k<dx<or4|({<mcs7>aAqF#Zr=5QKHFM#LvLM@DfC5 zGJ)AeLJSNHRXo99M}VDBtjSa)!oa|Ai#<6%H#adar3e(rw-{43S#B{G<(J=LOU}<J z&CLVryv0^rl9`-csmW8s&cMI`j{jR+xrv#1@oC_6!%~o#oPCQi;udp=f50tPpTwlp zoLd}8C3%o!#p2{2;&F@3skEddKkpU~BrM`VAyIsbCA}y!MU%ORn}LBLia94KCyFP( zAT`e|Gbgp!sU#1a$RGqLofLsGJ;*b~0-*H3$ipbY$j8XT#KS1SB*auD3`;slsTL*m zfIJD$9BK><3^fc37(iK}gfWW=lwwktdzoq&vY6vpY8V!<f@Hw4%;Hxij+D@YlQW7^ zGm}a(i<2{|xRHWYlPQV|WOrs_PD*CcE!L9ElAKgcwp(1uIjM<7@nxB*<wYR-qXZI* zvqAm@1p+uV6iI_(gA>lbC76;~T#%Dk2@WT)l9i0$P=bU8DDxG8gG8Bufk7UThd7vo z7^_5J0f8LWC?NsLc_0kVM~@gm#RMoHWid4~rZ8r+Okga!m(Ebb5YG%ISxQ(zvf#V| z%1>-r>?ItaVho&DKyqx&jNsgbEY4X2$(LLyEZ}^^Y6Hq~Tv^<pTm~xaQn*0*2qc%q zox+{Ml)?it56b67<MXAkqv_#EVN2mp5rFIAN#RZrMB($M2%+%#QiPHCyx>woBt^8B znUSG{uZA&23~V=lia0dKgH%YQNJ3PA<pgS&vIJA4z~zS!xCCJYg;_JB3qx!{Ei)*T zvY2X^B^hc#er8@ETq07#(#*IJRNjDDS)wV7k_@%15b-RrTDBU71>!Yq3mI!cr4Uz^ zM2d8ZObv4lTMc`PbQ*JtEHsQ*z-F=5us1V-Oq;-1=u{$E!;mGFB9|gx!;mGNqR`7y z!w@f1!;mGD1#!7zic*R)NIy6gtN4L)c?h&rxW$%QQIMFIqRD)VIX@@m7IR)|IVh_q zmXsEQ$^}sVFRo%zHh7r=Do>0U7#Q3%nQyU{XQq^7L~-P1=7Cwa*o#YwQcIFEinKum zA!89pVUZ4~pwI=SX*NG_DODs4DuX!ub5g*?UloU6YB`t{#THxwwvr{UIJI1pxkv(} zRT4x<f%J2fr52TBCMV`-GDWfF7iFgAl@y7A90bbDx0v#ZH5sG$DvOhg@^f;ah1o5J zTg<6>DX=n*tt>I8G_^R24U#KvvE}6#<tFB6GDC_$*5Z=Hl2ovnMWP^U`9S_)L2`#6 zNEB4;Xv*GV&PmM!XVxNhkn6beb5i095=$~ti*Iq|rIth4;DYiNS4m=0PAa$%ERq44 zp$O8#5mJ<z3MvY2v6K|0rWS#`dW$_HH8CYKFTF?wq=YjV?46{<qFbz$V5Mxy`FUxX z>9?4RQ%i2K7J+JwTWpC11*v%{MW8DG7JETrQEFaE@huimVR4HST=C{)R;Auz%gifI zEh;He0=Yl|WIPX~3I-P~#kV*im5@_Oo+bylgo)zFNrIN_oRDw@IfOA2WN1!mJlK5p zl*}R!qsSX%AbVbFxgV%40xp)o1h{O{U|?WS1(i*9;Nn_{iH(sBTv&54@-cBSaxsZ8 z3NQ*ViZFpl0dOHM1QKBqVdP;FV1lTTViaQ%W2};d#9omeM!|?uuz`wKPy+>Au(g4U z_$-D6j0+iR8B3T-KpB*!nGu{_qiUII7;Bg$8EToU^gzXZ4MP?Sh+o5y#Rj6mEhdI6 zhAj3PW@zQW%*YVVP$<F30D?6LIhGV=P$3e@P$&_>P$*Hukj0V332H=w3JP%MWA`fp zWrrvhm;Ag`O(saJvw~CREmqf}qWq#;94VQ_pahem$yj6qN`qWQPN2}`Nlz__PtM59 zNhwOrEAjwEqb-O41?nwsq_`}y2MN1_2!9aa1~P;N9H+NfGfPr)i;Dt52C{(I==BJw zjT!=qD^NmbVB}&HV&q_AVw7MMV`O8LVnWm@NEQ|+gW6-DxCLPl8-&3@56VO}j0+fQ zz@-%^2#P@MHciG`>_w>sIf==suv(u3mW6I{z%mfJ+aehl7!pBl10{6^MnpxA<Q9}v z04f{c)td{b<k14f7APGsf+`_~1x%pI9aPn4v4BOGAtK=nc_J(fC9K(8MRuS#W@LzD z$YY9NKzM+y2-L5*#SLon#HZyKrKgtMVoymeE-A{dECL1lEpAYo1}4SlSW;4ynN(Vm z3XbF=O;E&ua|oCKXA@9M1XRWrg943#k%^Iuk&BUok&ls&u}TP*>=8`}l=eO-P(dwF zaG-wyb#@qQnNk>QnNyf*SxP`{e-=>NKZPNiv&aU)U%-^YypXY$xrAW>a|%-mV-4d% zW>5w0!VtTvmKCHfg{6jdAyZL84O0#40+xjg<_xt=g${)dU^!N>Tm?uDMVt*R-T_y~ z4(2bYVM^gZQO5}u-%-Pq!i6Hv4Hmyp!<52<BF+mIcc@`X;e&~T?5JU?VHO89!}<M+ zEI_f$7o!)Qs9WWz8x@lhtEB?2@2Xg%9d)B(t2jV1F)6ySRV>jl#b7c%_7|gWDX7SZ zKD;FM7E@v>l(Q{1iYXt)*%KSZRGO;EdW)$j^%h%kYGP4x#x2(LqWsc=Tg=6!Nw-+R z4RlR5NKRubE-3<)<e<zH#g>`}D%PVoi&E2F!OUBXIq1pThk=117nHoMK-q|qg^`7c zg-L)>h>?$pgOP`khmnPmhmiwJB3KYUoMd8QtP+H!6?oyV$>^ua4eHl{%If&|TU_z+ zx%nxjIjQmSw|L^?3riDoATr>t7`S;|1Zq$gflBToP?1ms%6mni6j}swCX&+;=@*p# zKs<1(oP&{zm4laqjYFS<mxGyuvj`-s$x#GK;GkNnBqJv?30h~BWM}4;q!vNi#N1Gx gUP(zdxc&s|#Ae|w4jYIs>_BE0gE|GEZ~|jy02wLYHvj+t literal 0 HcmV?d00001 diff --git a/download.py b/download.py new file mode 100644 index 0000000..00d6da4 --- /dev/null +++ b/download.py @@ -0,0 +1,155 @@ + +from tkinter import filedialog +from tkinter import * +from tkinter.ttk import * +import re +from pathlib import Path +from bs4 import BeautifulSoup +import requests +from pathlib import Path + + +class Window(Frame): + def __init__(self, master=None): + Frame.__init__(self, master) + self.master = master + + self.download_dir_str = StringVar() + self.download_url_str = StringVar() + self.download_links = [] + + self.init_window() + + + def init_window(self): + self.master.title('FIONA PDF downloader') + + self.main_frame = Frame(self.master) + self.main_frame.pack() + + self.url_lbl = Label(self.main_frame, text="URL: ") + self.url_lbl.grid(row=0, column=0, sticky="w", padx=10) + + self.url_field = Entry(self.main_frame, textvariable=self.download_url_str) + self.url_field.grid(row=0, column=1, pady=10, padx=10) + + self.download_btn = Button(self.main_frame, text="Download Files", command=self.download_files) + self.download_btn.grid(row=0, column=2, pady=10, padx=10) + + self.path_lbl= Label(self.main_frame, text="Download directory: ") + self.path_lbl.grid(row=1, column=0, pady=10, padx=10) + + self.path_show = Label(self.main_frame, textvariable=self.download_dir_str) + self.path_show.grid(row=1, column=1, pady=10, padx=10) + + self.path_btn = Button(self.main_frame, text="Set Directory", command=self.set_download_dir) + self.path_btn.grid(row=1, column=2, pady=10, padx=10) + + self.link_frame = Frame(self.main_frame) + self.link_frame.grid(row=2, columnspan=3, padx=10, pady=10) + + def set_download_dir(self): + self.download_dir = filedialog.askdirectory() + self.download_dir_str.set(self.download_dir) + + def clear_view(self): + try: + for widget in self.link_frame.winfo_children(): + widget.destroy() + except AttributeError: + pass + + def download_files(self): + self.clear_view() + + if self.download_url_str: + if hasattr(self, 'download_dir'): + self.download_links = [] + try: + print(self.download_url_str) + r = requests.get(self.download_url_str.get()) + data = r.text + soup = BeautifulSoup(data) + current_link = "" + i = 1 + link_header_lbl = Label(self.link_frame, text="PDF name") + link_header_lbl.grid(row=0, column=0, padx=10, pady=10) + link_header_status_lbl = Label(self.link_frame, text="Downloaded?") + link_header_status_lbl.grid(row=0, column=1, padx=10, pady=10) + + for link in soup.find_all('a'): + + current_link = link.get('href') + print(current_link) + + try: + if current_link != None and current_link.endswith('pdf'): + self.download_links.append(current_link) + file_name = self.fionalize(current_link.rsplit('/', 1)[-1]) + link_lbl = Label(self.link_frame, text=file_name) + link_lbl.grid(row=i, column=0, padx=10, pady=5) + + try: + pdf_file = requests.get(current_link) + path = Path(self.download_dir, file_name) + open(path, 'wb').write(pdf_file.content) + status_lbl = Label(self.link_frame, text="Yes") + status_lbl.grid(row=i, column=1, padx=10, pady=5) + + except Exception as e: + print(e) + status_lbl = Label(self.link_frame, text="No (Error)") + status_lbl.grid(row=i, column=1, padx=10, pady=5) + + i += 1 + except: + continue + + except Exception as e: + print(e) + else: + return + else: + return + + def fionalize(self, string): + newName="" + ending="" + + regEnding = r"\.[a-zA-Z\d]*$" + + if re.search(regEnding, string) is not None: + ending=re.search(regEnding, string).group(0) + string=re.sub("\.[a-zA-Z\d]*$", "", string) + + for l in string: + if re.search("[A-Z]", l): + newName += l.lower() + continue + elif re.search("[a-z\d-]", l): + newName += l + continue + elif re.search("[\s]", l): + continue + elif re.search("[\_]", l): + newName += "-" + continue + elif re.search("[ä]", l): + newName += "ae" + continue + elif re.search("[ö]", l): + newName += "oe" + continue + elif re.search("[ü]", l): + newName += "ue" + continue + else: + continue + return(newName + ending) + +root = Tk() +root.minsize(800, 600) +root.geometry("800x600") +app = Window(root) + +root.mainloop() \ No newline at end of file diff --git a/downloader.py b/downloader.py new file mode 100644 index 0000000..3d68e42 --- /dev/null +++ b/downloader.py @@ -0,0 +1,288 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import re +from pathlib import Path +from tkinter import * +from tkinter import filedialog +from tkinter.ttk import * + +import requests +from bs4 import BeautifulSoup + +from errorStack import AppError, ErrorStack +from fileLink import FileLink + + +class Downloader(Frame): + def __init__(self, master=None): + Frame.__init__(self, master) + self.master = master + + self.download_dir_str = StringVar() + self.download_dir_str.trace("w", self.entry_update) + self.download_url_str = StringVar() + self.download_links = [] + self.download_info = StringVar() + + file_types_a = ['png', 'jpg', 'pdf', 'gif', 'docx', 'xlsx', 'doc', 'xls'] + string_vars = [IntVar() for i in range(len(file_types_a))] + self.file_types = dict(zip(file_types_a, string_vars)) + + self.error_stack = ErrorStack() + + self.init_window() + + + def init_window(self): + self.main_frame = Frame(self.master) + self.main_frame.pack(fill="x", expand=True) + + self.info_frame = Frame(self.main_frame) + self.info_frame.pack() + + self.dic_frame = LabelFrame(self.main_frame, text="1. set download directory") + self.dic_frame.pack(fill="x", expand=False, pady="10") + + self.item_frame = LabelFrame(self.main_frame, text="2. which file types should be downloaded?") + self.item_frame.pack(fill="x", expand=False, pady="10") + + i = 0 + for file_type in self.file_types: + check_btn = Checkbutton(self.item_frame, text=file_type, variable=self.file_types[file_type]) + check_btn.grid(row=0, column=i, sticky="w") + i += 1 + + self.download_frame = LabelFrame(self.main_frame, text="3. Enter a URL and download the files") + self.download_frame.pack(fill="x", expand=False, pady="10") + + info_lbl = Label(self.info_frame, text="Download all files that are linked on a website.") + info_lbl.pack(padx=10, pady=10, side="left") + + error_btn = Button(self.info_frame, text="Show Error log", command= lambda: self.show_err_win(ErrorWin)) + error_btn.pack(padx=10, pady=10, side="right") + + self.download_frame.columnconfigure(0, weight=0) + self.download_frame.columnconfigure(1, weight=1) + + self.url_lbl = Label(self.download_frame, text="URL ") + self.url_lbl.grid(row=0, column=0, sticky="w", padx=10) + + self.url_field = Entry(self.download_frame, textvariable=self.download_url_str) + self.url_field.grid(row=0, column=1, pady=10, padx=10, sticky="we") + + self.download_btn = Button(self.download_frame, state="disabled", text="Search for files on...", command=self.download_files) + self.download_btn.grid(row=0, column=0, pady=10, padx=10) + + self.path_lbl= Label(self.dic_frame, text="Download directory: ") + self.path_lbl.grid(row=1, column=0, pady=10, padx=10) + + self.path_show = Label(self.dic_frame, textvariable=self.download_dir_str) + self.path_show.grid(row=1, column=1, pady=10, padx=10) + + self.path_btn = Button(self.dic_frame, text="Set Directory", command=self.set_download_dir) + self.path_btn.grid(row=0, column=0, padx=10, pady=10, sticky="we") + + self.status_frame = Frame(self.main_frame) + self.status_frame.pack(fill="both", expand=True, pady="10") + + def set_download_dir(self): + self.download_dir = filedialog.askdirectory() + self.download_dir_str.set(self.download_dir) + self.download_btn.config(state="normal") + + def entry_update(self, *args): + if self.url_field.get(): + self.download_btn.config(state="normal") + else: + self.download_btn.config(state="disabled") + + def clear_view(self): + try: + for widget in self.status_frame.winfo_children(): + widget.destroy() + + self.start_download_btn.destroy() + self.progress.destroy() + except AttributeError: + pass + + def show_err_win(self, _class): + self.error_win = Toplevel(self.master) + _class(self.error_win, self.error_stack) + + def download_files(self): + self.error_stack.clear() + self.clear_view() + + if self.download_url_str: + if hasattr(self, 'download_dir'): + self.download_links = [] + try: + r = requests.get(self.download_url_str.get()) + data = r.text + soup = BeautifulSoup(data, features="lxml") + current_link = "" + i = 1 + + self.init_treeview() + + for link in soup.find_all('a'): + current_link = link.get('href') + # here happens everything with the links + try: + for file_type in self.file_types: + if self.file_types[file_type].get() == 1: + if current_link.endswith(file_type) or current_link.endswith(file_type.upper()): + filelink = FileLink(current_link, self.download_url_str.get()) + file_name = self.fionalize(filelink.name) + + self.download_links.append(filelink) + self.tree.insert("", "end", text=i-1, values=(file_name, file_type, filelink.link, "")) + + i += 1 + except Exception as e: + self.error_stack.add(e, f"Error while trying to build the file link for the link {link}") + continue + + for img in soup.find_all('img'): + current_img = img.get('src') + try: + for file_type in self.file_types: + if self.file_types[file_type].get() == 1: + if current_img.endswith(file_type) or current_img.endswith(file_type.upper()): + filelink = FileLink(current_img, self.download_url_str.get()) + file_name = self.fionalize(filelink.name) + + self.download_links.append(filelink) + self.tree.insert("", "end", text=i-1, values=(file_name, file_type, filelink.link, "")) + + i += 1 + except Exception as e: + self.error_stack.add(e, f"Error while trying to build the file link for the img {link}") + continue + + + except Exception as e: + self.error_stack.add(e, f"Error while trying to get a request from {self.download_url_str.get()}") + finally: + if len(self.download_links) > 0: + self.start_download_btn = Button(self.download_frame, state="normal", text="Download files now", command=self.start_download) + self.start_download_btn.grid(row=1, column=0, pady=10, padx=10) + + else: + return + else: + return + + def start_download(self): + self.progress = Progressbar(self.master, orient = HORIZONTAL, length = 700, mode = 'determinate') + self.progress.pack(expand=True, fill="y", pady=10, padx=10) + i = 0 + len_downloads = len(self.download_links) + for link in self.download_links: + try: + pdf_file = requests.get(link.link) + path = Path(self.download_dir, self.fionalize(link.name)) + with open(path, 'wb') as file: + file.write(pdf_file.content) + item = self.tree.get_children()[i] + self.tree.set(item, column="status", value="Done") + self.tree.update() + + except Exception as e: + self.error_stack.add(e, f"Error while trying to save the file with the URL {link}") + self.tree.set(item, column="status", value="Error") + self.tree.update() + + i += 1 + self.progress['value'] = (i / len_downloads)*100 + self.master.update_idletasks() + self.clear_view() + + def init_treeview(self): + self.tree = Treeview(self.status_frame) + self.tree["columns"] = ("file", "file_type", "url", "status") + self.tree.column("#0", minwidth=0, width=80, stretch=NO) + self.tree.column("file", minwidth=0, width=100) + self.tree.column("file_type", minwidth=0, width=80, stretch=NO) + self.tree.column("url") + self.tree.column("status", minwidth=0, width=100, stretch=NO) + + self.tree.heading("#0", text="Number") + self.tree.heading("file", text="File name") + self.tree.heading("file_type", text="type") + self.tree.heading("url", text="URL") + self.tree.heading("status", text="Status") + + + scrollbar = Scrollbar(self.status_frame, orient="vertical", command=self.tree.yview) + self.tree.config(yscrollcommand=scrollbar.set) + self.tree.grid(row=0, column=0, sticky="nsew") + scrollbar.grid(row=0, column=1, sticky="ns") + + self.status_frame.grid_columnconfigure(0, weight=1) + self.status_frame.grid_columnconfigure(1, weight=0) + + def fionalize(self, string): + newName="" + ending="" + + regEnding = r"\.[a-zA-Z\d]*$" + + if re.search(regEnding, string) is not None: + ending=re.search(regEnding, string).group(0) + string=re.sub("\.[a-zA-Z\d]*$", "", string) + + for l in string: + if re.search("[A-Z]", l): + newName += l.lower() + continue + elif re.search("[a-z\d-]", l): + newName += l + continue + elif re.search("[\s]", l): + continue + elif re.search("[\_]", l): + newName += "-" + continue + elif re.search("[ä]", l): + newName += "ae" + continue + elif re.search("[ö]", l): + newName += "oe" + continue + elif re.search("[ü]", l): + newName += "ue" + continue + else: + continue + return(newName + ending) + +class ErrorWin(): + def __init__(self, master, errorStack): + self.master = master + self.master.minsize(400, 300) + self.init_window() + self.show_log(errorStack) + + def init_window(self): + self.master.title("Errors") + + def show_log(self, errorStack): + if len(errorStack.stack) > 0: + text_w = Text(self.master) + text_w.pack(fill="both", expand=True) + for error in errorStack.stack: + text_w.insert(END, f"{error.error}\n{error.name}\n------\n") + + # error_frame = Frame(self.master) + # error_frame.pack() + # lbl_e = Label(error_frame, text=error.error) + # lbl_txt = Label(error_frame, text=error.name) + # lbl_e.pack() + # lbl_txt.pack() + + else: + lbl = Label(self.master, text="No errors") + lbl.pack() diff --git a/errorStack.py b/errorStack.py new file mode 100644 index 0000000..6da4435 --- /dev/null +++ b/errorStack.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +class ErrorStack(): + def __init__(self): + self.stack = [] + + def clear(self): + self.stack = [] + + def add(self, error, name): + self.stack.append(AppError(error, name)) + +class AppError(): + def __init__(self, error, name): + self.error = error + self.name = name \ No newline at end of file diff --git a/fileLink.py b/fileLink.py new file mode 100644 index 0000000..3f841c2 --- /dev/null +++ b/fileLink.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import re +import urllib.parse + +class FileLink(): + def __init__(self, link, url): + self.filetype = link + self.name = link + self.url = url + self.link = link + + @property + def link(self): + return self.__link + + @link.setter + def link(self, link): + # urljoin from urllib.parse should do everything to build the right link from base + self.__link = urllib.parse.urljoin(self.url, link) + + @property + def name(self): + return self.__name + + @name.setter + def name(self, link): + self.__name = link.rsplit('/', 1)[-1] + + @property + def filetype(self): + return self.__filetype + + @filetype.setter + def filetype(self, link): + self.__filetype = link.rsplit('.', 1)[-1] + + def checkfiletype(self, check_type): + if self.filetype == check_type: + return True + else: + return False + diff --git a/fiona-toolkit.py b/fiona-toolkit.py new file mode 100644 index 0000000..8f411ad --- /dev/null +++ b/fiona-toolkit.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from tkinter import * +from tkinter import ttk +from ttkthemes import ThemedTk + +from renamer import Renamer +from downloader import Downloader + +# TODO +# Fehler bei: https://www.desy.de/~gudrid/source/Prototypes-und.html + +class Window(Frame): + def __init__(self, master=None): + Frame.__init__(self, master) + self.master = master + self.init_window() + + def init_window(self): + self.main_window() + + self.master.title("FIONA Migration Toolkit") + + def main_window(self): + welcomeLbl = ttk.Label(text="FIONA Tookit") + welcomeLbl.pack() + nb = ttk.Notebook(self.master, padding="10 30 10 10", width="800") + nb.pack(fill="both", expand=True) + renamer = Renamer(self.master).main_frame + downloader = Downloader(self.master).main_frame + nb.add(renamer, text="Rename Files", padding="10 10 10 10") + nb.add(downloader, text="Download PDFs", padding="10 10 10 10") + +root = ThemedTk(theme="arc", toplevel=False, themebg=True) +root.minsize(800, 800) + +app = Window(root) + +root.mainloop() diff --git a/icon.ico b/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7e6c1d28db62be12ee11c9a136987a6340b83287 GIT binary patch literal 82027 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 literal 0 HcmV?d00001 diff --git a/icon.png b/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..14676218238a5997c2a1a398fcdea52e0e9d2d16 GIT binary patch literal 5499 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�&C8al znJ~SuXGl9guQ%v=^UKT2vlr#gtNWE%BF1!J`=|Qn=jOgp<-c|7mPz59`}O~At+*K( z{)L5xsy?Y~*bS<s=e9C@kURJ9wR3p5_%A`m2em)fm;Bbgb27z<(|#wPyj@Q=qX5G_ z>*{YhRT&axyJLUkI=H#9F)=VcnEUhd^Tjz=I!{hkpM8OggJJ!t|KIOb^Y2|e=~D6~ zmsL!Ca<*O9+m#uv%r?msvYUHh;+;D&A;laFUswNsadGj+^e;g{L6bI2UbAP9%->Fi zfb~n3u-HCU-F|zmR*ZAv(^FGlD6ll_x@vD^B=mF<zn8ans|BCUX+}l^rKwY=z7UPK z4xZFvC&}?B(QNkHd4D4f@?IYCwr5hdx1Yat`}Wg|zPvorDIBS>dUE9Ew7{}5Gs9yV zT3V-`&oBP-<KxD^fB#<Z(9mgM+-GWQ`?q(-42kvox36B^9it~c*Q&HjN?JO!e*Vp1 zcebJf387qbZrq5tckiB_%S-uHYfnBqJA386efREMzh1sy=QRHuyIQMOLosLN>g+-Z zLDnx-Z0CMXDt>;>wfDjAY8|oDOXtj)Q{_47)uP3Vf1f&ix_upkMDmoWQ<qjuGZRpJ zkhvh?>-YKm_J1a9%fBzT<<z<0`P;T^+0fV5x8U#H^?N>X$y%4`_)U9S|9H;&=X3lO zlka^{Gd{M?@R*lG@_XI*eSaQZTN^!<xuGND<D;WbO01aWnC7vaGCpr}IIi|<=$RP% zpj)?CH~TO5nR%$}{XN+&`^)d`sT6v?XGZZqwdXc+$`8Ja?wf7+ZQ9M8dubaZe(}p# z6y!7Tm?!)(%&_4VnST0c!P)u`&IwCut*)5my}Gh8=lZ%>$KTe)MMZ~FBmZ^loR)Tr zc=p<o<CKbL)w1>L&;RV#XG*)rBazSEH*2q**Z&J`4f}r^o0(1H-TwZ|@;7gCgrEP( zpYu8W;_bt22lywctle<??cFX$2bU?J{^Q04F*{pN>icp0IQ;VR@<@Mw{|o=tU5~Gy ztEHv&?}+99{55}8IVZ3uzlqPv%Cg|Sn$aj@;<tSA!-dm+aW(bz@m;%gN$AY}Ru#`p zr#8j-x-7o9d)3KFDo>9eIWi?QB&5R5`Bi~MghHI-)G1S1PRc9swKx0DHaok%)~fbb z$+H5BCaa&F9q)F(w{vs(-+A)AX=m}it-E*McDXmj*SR*xV9t>vF5Bw=*O}~fcy@li z|K7cO?Y^eR#mQBFzgzBH_2=fzo1U9==BqC%__FMKXv4{rsEqBmwQJ*e!`4Q*_88vU zoPJ*R|NJ>~d?F(wx8&cqGuhlGA|@7;o2whUujc2x|Ig=KzPGo!)$-b+MM}FWK0eyN z>+U=L3&nQxxo?C;NB@@co73=YP3-Pz=jPe&o?N_7ZtcTjhClJSxw(3Bdl+XGzfPJK zvZdv{#q-IXAL1A;EO_!H<(Or^n|F_g2@`|K%Ju8}g)cHhCAqK(Ff8!oxBVjEIq6E< zG>MCr4f8>xB!B<@Jz}}u-Mi;RKL^8wCFkva_o#SUdAL;ESn*!;Ksg7)g*6*CY|uIu zp&WH+`N{WFR9<ScFl1aiaNqz#a*p&WhWR=3EsN9G1>Y@T;+<`tA2&nibi2iK{>7#t z>;H+XdY;;J`|aEn3=WsylvVFn@jTkIadif7XkBuTt+=%G?aJTw0t^c>Sy@?oC#i_u z`xn7&<6k%V<d$nsi$bSOo%%OWa6zmCe^F79(Ve{S>2p5oY-vlnxqsdE?cY6W|IVF1 zZxIti?1>X6ERxM;|M#4<<oX8HAGMFly(WFxuQpjzTT}Dpyp#Q03?=D*e|^1j<Az0A zL4iU1w5Lz!6iW-LUb-(Yv*`K9bDb;NJFFy<OM5ovOD6xmboui7`d=@XOGw}uMV$5Z Y|E}5P=Bu|G@qko$y85}Sb4q9e0I0A8#{d8T literal 0 HcmV?d00001 diff --git a/main.py b/main.py index 590bd87..1ddc7f9 100644 --- a/main.py +++ b/main.py @@ -28,14 +28,8 @@ class Window(Frame): self.btnFrame.grid_columnconfigure(1, weight=0) openFilesBtn = Button(self.btnFrame, text="Select files", command=self.select_files) - quitBtn = Button(self.btnFrame, text="Quit", command=self.client_exit) openFilesBtn.grid(row=0, column=0, padx=5, sticky="ew") - quitBtn.grid(row=1, column=0, padx=5, pady=5, sticky="ew") - - - def client_exit(self): - exit() def select_files(self): self.clear_view() @@ -61,11 +55,11 @@ class Window(Frame): self.statusFrame = Frame(self.tableFrame) lbl2 = Label(self.tableFrame, text="old names") - lbl2.grid(row=0, column=0, sticky="w") + lbl2.grid(row=0, column=0, sticky="n") lbl3 = Label(self.tableFrame, text="new names") - lbl3.grid(row=0, column=1, sticky="w") + lbl3.grid(row=0, column=1, sticky="n") lbl4 = Label(self.tableFrame, text="status") - lbl4.grid(row=0, column=2, sticky="w") + lbl4.grid(row=0, column=2, sticky="n") self.oldNameFrame.grid(row=1, column=0, sticky="nswe", padx=5) self.newNameFrame.grid(row=1, column=1, sticky="nswe", padx=5) @@ -104,7 +98,7 @@ class Window(Frame): self.new_pathes.append(Path(dirname, newName)) - self.changeBtn = Button(self.btnFrame, text="Rename", command=self.rename_files) + self.changeBtn = Button(self.btnFrame, text="Rename", state="normal", command=self.rename_files) self.changeBtn.grid(row=2, column=0, padx=5, pady=10, sticky="ew") def rename_files(self): @@ -114,6 +108,8 @@ class Window(Frame): self.listbox_status.insert(END, "Done") except: self.listbox_status.insert(END, "ERROR") + + self.changeBtn.config(state="disabled") def rename_file(self, old_path, new_path): old_path.replace(new_path) diff --git a/renamer.py b/renamer.py new file mode 100644 index 0000000..5bfb72b --- /dev/null +++ b/renamer.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + + +import re +from pathlib import Path +from tkinter import * +from tkinter import filedialog +from tkinter.ttk import * + + +class Renamer(Frame): + def __init__(self, master=None): + Frame.__init__(self, master) + self.master = master + self.init_window() + + def init_window(self): + self.main_frame = Frame(self.master) + self.main_frame.pack(fill=X, side=TOP, padx=5, pady=5) + lbl = Label(self.main_frame, text="The selected file names are changed to the FIONA convention, i.e. lower case, hyphens and numbers only.") + lbl.pack(fill=X) + + self.btnFrame = Frame(self.main_frame) + self.btnFrame.pack(fill=BOTH, pady=15) + + openFilesBtn = Button(self.btnFrame, text="Select files", command=self.select_files) + + openFilesBtn.grid(row=0, column=0, pady=5, sticky="e") + + def select_files(self): + self.clear_view() + # returns a list of filenames + self.main_frame.filenames = filedialog.askopenfilenames(initialdir = "/home/timo/Schreibtisch", title="Select file") + self.display_filenames() + + def display_filenames(self): + if len(self.main_frame.filenames) > 0: + + self.old_pathes = [] + self.new_pathes = [] + + self.tableFrame = Frame(self.main_frame) + self.tableFrame.pack(fill=BOTH, expand=True) + + lb_frame = Frame(self.tableFrame) + lb_frame.pack(fill=BOTH, expand=True) + + self.tree = Treeview(lb_frame) + self.tree["columns"] = ("old", "new", "status") + + self.tree.column("#0", width=100, minwidth=50, stretch=False) + self.tree.column("old", stretch=True) + self.tree.column("new", stretch=True) + self.tree.column("status", width=100, minwidth=50, stretch=False) + + self.tree.heading("#0", text="Number") + self.tree.heading("old", text="Old name") + self.tree.heading("new", text="New name") + self.tree.heading("status", text="Status") + + self.tree.grid(row=0, column=0, sticky="nsew") + + scrollbar = Scrollbar(lb_frame, orient="vertical", command=self.tree.yview) + scrollbar.grid(row=0, column=1, sticky="ns") + self.tree.config(yscrollcommand=scrollbar.set) + + for i in range(len(self.main_frame.filenames)): + file_name = self.main_frame.filenames[i] + + self.old_pathes.append(Path(file_name)) + + dirname = Path(file_name).parents[0] + + name = Path(file_name).name + newName = self.fionalize(name) + + self.tree.insert("", "end", text=i, values=(name, newName, "")) + self.new_pathes.append(Path(dirname, newName)) + + self.changeBtn = Button(self.btnFrame, text="Rename", state="normal", command=self.rename_files) + self.changeBtn.grid(row=0, column=1, padx=15, pady=5) + + def rename_files(self): + items = self.tree.get_children() + for i in range(len(self.old_pathes)): + item = items[i] + + try: + self.rename_file(self.old_pathes[i], self.new_pathes[i]) + self.tree.set(item, column="status", value="Done") + except: + self.tree.set(item, column="status", value="Error") + + self.changeBtn.config(state="disabled") + + def rename_file(self, old_path, new_path): + old_path.replace(new_path) + + def clear_view(self): + try: + self.tableFrame.pack_forget() + self.tableFrame.destroy() + self.changeBtn.grid_forget + self.changeBtn.destroy() + except AttributeError: + pass + + def fionalize(self, string): + newName="" + ending="" + + regEnding = r"\.[a-zA-Z\d]*$" + + if re.search(regEnding, string) is not None: + ending=re.search(regEnding, string).group(0) + string=re.sub(r"\.[a-zA-Z\d]*$", "", string) + + for l in string: + if re.search(r"[A-Z]", l): + newName += l.lower() + continue + elif re.search(r"[a-z\d-]", l): + newName += l + continue + elif re.search(r"[\s]", l): + continue + elif re.search(r"[\_]", l): + newName += "-" + continue + elif re.search(r"[ä]", l): + newName += "ae" + continue + elif re.search(r"[ö]", l): + newName += "oe" + continue + elif re.search(r"[ü]", l): + newName += "ue" + continue + else: + continue + return(newName + ending) diff --git a/uni-hh.png b/uni-hh.png new file mode 100644 index 0000000000000000000000000000000000000000..db1d30c9564365cd9eb0bae9ad2228171fc6cc58 GIT binary patch literal 12454 zcmeAS@N?(olHy`uVBq!ia0y~yV7SV_z~IWk#=yXES8eeD1_lPs0*}aI1_o|n5N2eU zHAjMhfy+PB**PE}BfliSI3vG6!PD7Up`a)~Ei)&TfuZ8o+~D+(;Fn^y-|u~K^6qGu z;+-EP%ApYC)ZHL5QB6ycQ^2c3ap6tTz=MLWt}N0g7IZN8^)>W}2I}y1aou2lqPVE9 zd2vVAsoxK)7iVAF^ZnV`e_OBHJzw*A?&kCC2RL}9c^C(pHt?);k`sK;eEi6<hfnkz z8o5*o7z8*rrzjTxRc2)PQD<YLt#p8W9|L2>Wo{0J1HQ8l7|68$=YQoiGlsFDh4Dbi zL<?_@1`!5_sy?S>3=VFL4RdFx1v4yQVMsWgob;F>K$jswz5dx{hK9L6W>zyYL{Cu^ zWn3_kK|wgR!-XNknqkfPur61I2m=O@H18vp3^#Nc3_QcrJQy}?XE<<9fO``I2M>cm zU`MMa14}hS!U<*N3Wk=M3?goy!fifkuM>E##lTQ8bCb<Z6-(E~Xb#;%_V92$IgN9k z;@To+iA;&J9P|!V&XhE2G~s{n`3wWYf{CJn51K#!tvJWG?%X-EzHNN*y07-L{Z~p# zdi?L{`PBsu3=9uT>Ms7%(cdi9V9nN$`)`rzJC=+%?ggdayVExDJ8WfG@bXsp=K@gJ zxGtQq^XAQ`PoCWHI^q<acq+X1U;3f=1L1#je%9Ii`Tq66zDFvJMzM|VEI%F`I`hS6 zsm%FFoGnRrp7p!`+0Om{kL+coBc4e+BeX;w2MQJTxy<VMY_wFV(`l0CQPoTTQy$&d z`OR#1-;`lPmK|gDMBNp!$;{up)deC-4m|qK!0>5z{=q969Lx<F%@5C)|9@})*L{I1 zLqnS9q(TOUI2RSYkW-uOk8?0ExGZSY+TbYt<)DPl0XCU~talD_|4A@waZ)*Q$VtG7 zE2TlEC_!^glaof<*$uK<3HnzYWK9kPX0%N%;L|%4x`WTQfd5w_$Gn3Ydm1@e98Yiv zCo10RU`*<YQ10UppV|6D@t_BbP`8T0$qtb~CGUx*9)>|(Aqt@$vY%{=m@M04+;&a0 zKEYtr^rvl)yWy0^O@X#oc(yw4TwyNN;<kwULQ09@tbVZtvo92Fk+SVETloCK>J0u{ z{dUgB4Gz4JU^hOJW1x5Ju+v5h9nQ(gr#C9C;aPo5YD3r>=G~oNlh1D~XAx?2J-}(k zQtqUXDCg)A;S=F^!()YljEafiElzVz=9a)i>PnMWcyCeLCHV7*M3RwVdxVFM@-?A; zVSRz>4(B80DngykM(R5!FnMlV5^_oClG~-cAmx`jD`%T{NGVS~c`GG*6T9UU9R=+Z ztxx7YIsC-<iS!f2Ptja+lN<_{{0M%e5p*icOY*6}Q<JA`sWXfmLl@5qy1Qawh@feI zl+)UU+k(~ywyzL2DV=3`wpq;6d+FLmQ!h(ph-ZAyT>qkEm*Cy0a(>e<gkL)S(*4Es z7tCMEd3f7In~!&-Ye>$PV3$ajESFe6!)KY~<!;I2AqM7#uV*};$v-ncG(u~eR*mSy zQ(RNMrm9Vq*3u7IxoX*}d#kuZKZl+U>0cQaT)WOK)HwL@O3o|OR)?;d8}K?<Iyil$ z^@{dY=_~R>?3dI<{_SLoJnVDW-+4*kf{pQy_Z(B;PL|wUp`)11ySlBk(e#Mg#<MqT z%CvUR_$#}++jiB;g_h37UdG{@gFa75vuA%iqwvR^5<kx88q24DuIsud@?P_irt~rs zpPh!OG1;r8O`jIA+GBO#YWLTB&DOnLK6lw(*WHo78~GfMd#T5$yQlY`W1agv_-63k z<y_0fd~L11uG3qUy;OSPZkO`?dCT9;n71#kVV+O^@_UtgpZ}7n)&CpvH}}`_ukJh% zY@2yh*lzQjldw5zT9|JmtAG6V$3W-U!w$|%6Q?Flf7mi{=S7>vSKWHu_<J&s#XMGd zoO>+y*kUy{HAOXV-&elxW(E1~T&B6q+Q-`G_}MdO7oEK}({#42;dP_uv!BntKKuUm zgs6%rooy?&?MU_9^dxFo<hyNq@>-)TBbP>mM#XM+TRV5H>b2c#cP|%QzSD2A-|BhS z(hqO=xb5V&mD?pZJiWnod)>C&ZMBK%N#g0-kFGoXZt~vAwYzG2|Jt(iw%_DiEgL0U zSG=W2#460{-mG(T-r3h4{W9&PetN`tf%7+vA8!*rt$8GKZt(2O?&;#`JByn?cXW4p zH=Wj-Zl^a}`q<qQd!Klfd@YQ9Sas>^+}WFFA9}mu_WE~b?=s)D-<f~LWWMISNaNxQ zhfg>^2z+|co_qdOgY5fj>inJk8`HNwSJqF~pBTRO`iAXG%U69*d@pYI&8}$vW4p&T z=J$;5MaG{oKd}A8_S61{^XJ94-gmB7{-5%{>i<QC<qfKg>CBytj*ZbwzkgKKDDLmG zx4NDBZPU%Sjy(%@I*K~>H?3`YdT^~`#)&r*)+&B~KI7cPbD4at0d+5~U0_dqme_r` zjz_(<y*0eezOSGoLh7R7bkp*ScbtpwyZmyQ=5lX#x}m@2dR;G5ExT2ESvI%KcbV+6 zKc<%!dFE=w+z8JcZy8HHt#xL3Is5MadHcEj(cDMekE_LJ=%0u!s9bpN(3jTbVk`B8 zbgZU1_;mPLO!?p_ptVA*NA;6%xoRI*<ssQa=}P(+%`SG_aE{TE^ZVqX<y$rB&BQ&X zl`2P#m+Cy-*`mI3!X6)9pS!cI=84TJQ^+;4wc2agJZa*DLZ?-VzLU45ze<0WR(5(# zYU`$dNAtS3>&s1LKbgIG!Wz~{U9N3T%U*;;X<XN0-;|yjp0@vN=PAo+tLJH-eS2o} zsoN9G=e(c)|E<s=p@);UEp77-*OiTUws%dI<tCfL%G+FzMOn4m!r0c>?C9F2m3!5H z_1p02>+1HZRrzK&#vMG>bZ{$U_G|7?uBWZFukT!c8|xpTA9;Uk;;**3(srVqUF$?{ zi%%D=zoBub;;D3d{;B;l?@ZaUa`lm&Dd*EJrM-N1Pj_B4-?UZJpH1h><Gp!n3-A4~ zEpNYmbG@xU{jA3A-ObyacP`#<vtv){@{{MzTHA*#3HcK8E5z*GrMp`bum8xq_)fZd z&o`4dS8qq}`Tp1L<i6XXjG?|))2^oe_WZs1yZyS(RWE-``<)xR)-Sj4?Q!Ny%zxRH z`L<o(dF86?CEJjo{%hK=-T98o@B26ReYq~L8E<IsoMVra3tTFny!_62|GONo)vdCg z>NOA9FUyz7rpxMQInDYs%WZb>tl!Z|(YyT5*j>E#>R#0!_uKOPb4+X^E4@C4oXouS zvgz{V^iSt|=1!ekTc`K)PQvX)+p3=@pSz#MpZ|WBK*_^PuK&BATko+x7xQUH$)`=X zp9+WX2%ojyDn9pB$t#<GlP~)p-#usdtaUqMvUk3#+Pk$n?fXmVdFJQte%V|3QSAS< ztMe>v@9zCvmH++d_pkTG?$#Bl|2=nl_sw$kcWd|f?}`87@YeCB^WFBV_R;_D+<1Sd zKI=gFg3lN4xPNDBZ9e~R;@5tDXV(6i{ioY_+g{JJu(Py$WMB06<)7uw=TpwB%@hB( z=-=se;$r%BKd!#Me(vIoiwmcJnm&1dZq3rauMWJHTz~u6p<{CUPF5Hj#(fF<{q|t_ zopRati|_OMKdDiu*Z80DbK}?G3(J2`mYh8KKMV7W&wrAQb#F5;FeoH@1o<*BRH-sB zG&D0X{QS?r(D0Ihq11qZ;Z*_ygVhWM2J!q!@kiYl7*sEMx;TbZ+<FsR86k3foBdr| z>%$5PrxcnN352M0XslonRei+7V%XvB!g@z|@x_du!o%Xd92eOOJKYXS2(q+FhcLa< z=HhVd<>Kf%q4oNWv2E;o{)~49O%tBh-JAa9{qG+$R<2rSRr+hrs^V3CR})eb8W|Wk zybb@<w{P1c#K54FdbDjugFY)8&poDyUrax@GdNj%&XU}tYjEgz1LNWl9*IBp!CH&r z<u`=bGkgEM%qRasYyRT|_Ghe;31w#69<%xK9(a?ZGebOu;rPM6N@kva`|Lz{d(N`; zoMlVcY+bWpb<MQ~#shLzEH|9nOV)%W2|w`tn5DhCF5tu-R<`=$&-@F&{kJ}yexSke zdzuyl!-cHINhhuAy;lD{%&RoB=b=?|{SBY1Q-da`95!X+sr&BZD$vl)WBqkyg8~CX zgZV+(2}}OUX_w#nvF*I<)8adGCD$4MVAr}jJ58&1+1t%GTUi{kco~*0FPZyPnW5)! z+KzJ#fvc{kX+^m&3A!L+mpT2soDqwG-ullq)zt@B*m#~x{y9A5l`prb)#~P_ZSVI? z%iU3C_~ph{P6mdod*9i=zP*3z>E~rVESoo{OPn+Qk*+y)+q#8Uqm&t$_vG3#H;P0s zueq%~{om%+)ZF<e@6X#mZGC0PnS!|o?@O&;`!BO=K7*bS%c5|9gBiBWTRw0Jcr-Sp zIV@mY+%YZE<M*n4uW#+V!*|AA?{F#G{|z&{4m4JU^0zFN@aaF^aBvR4L*+-Q2e#Es z3Mb?v{;p+USde-6dhG9b9kneJ7#D{yL^WtF-+00LH`9h+(Tw?B;n5L-3=EehDBS!j z>rwxM(LkVVY3Tapg%Ld0CI4)m!o|!NP-?VdgCv`bdb$9MAM>3x>I@7kHWxWgoWd3| zc};Mu(tJDC+)CAeue=RYCSAX7`AT%bzRBzr`oR~nq-K~Oc#zNDWB2oSdDGG@Cpe4+ zOpMo0KUja%iItg+=bzEiMGImxSU}7*K@S-Y$h=NC&|vsq!XRNv7bCOVN(qC659NVc zEGk=c78oQP(6}1EARtS@r#EW9Vb{@yz*YNM#Fl=KO4nxNky!dmb^$}9kid%4G)>hn zm4OU177F~@qrt#3<y_9ypm{U*N*H)u?R0wR)|T*Xy|BX<qx|I>`oFChf>u39jc0Gz zcJtN!ryt{NC66W@&<J&}n|!kW;(_loS=8FgnVC!#COGx4H*XaE%4HxYz9vBS%a1DI zfD0@fPu`viKJaG)d-H$0Jy(k*BsMHaJo%h~;ld6z83qpppX%m^#}_i(*zdfI$DWV% z=Sr1;=b~G*`x)7zoL0~95Mb*GVq{>IXy<?9`0c`;*VYHBXEI3VG(I+bwRQ0?iGJ=k z5B(PCu4emo;UGvh;p<!GkYwQi)AbEE^O6r}h;Dh~xRKqu>1J!owk@j?ColN<p?twf zO_tAl;{VOHOVZN#WZd}v32WNRk8e+9XP??-r*pF5pnc}TMUUUFU!Lr+XQ2%<TThT- z!T}9YQ24K&%EipUHQ`?C+%MnzE(vB>dtPTK-Z6=BamWJ3MblYl%(J?pcU9-DL`PT+ zk8N<@7H{+Or&%s`^;_$lFO_5F2stx5<wJb)_M(s6Or~F~Dn)i&-pg20_kp26W{Z9t z)5Y!l46dbf&!siLDzUo4ayD~2(}|crhaSi;57F&f%EI%!`C!ul`<V7O8A=LXj1nIl z%b8~cYO&=D=bJ8SGQK70!{`3DQ2CRm;flOFE%&7Z7hcV}IdkUBe>HaTc4cpFnB3j7 zI()rfu!abezW#b+7RQWT(aW6{3VizcXS<YntH2@8NhzCezRA0Jc<R)t*PcClrf<Nr zSW8=bZT0tef0>SdwBO@j`0x;GJyUw%W833PUp<fAS98;U_0>o7=FMAKzpPh}J!+=U zm(%+D&qx>~99Ud_zxMmL=t{xVgvNWv?iULv{^aL;ao*vdGgB4cqU*1gEin>w;;{NX z`SepKX=&*v4<CLEvOj<L@Z+Vuy}Xl7KRslAb>VMuY3bd!Zr+TXG;NyM^4;hET&<Vt zZL`h4x94<TUf%k+eKncB%frLNqn9jS&TeLED*1Za{*srI<}Y2U>gDOldG6GySqYh$ zosS+ro_^`4i0i}e@9&rIEP8rs%ezY-)-_MAYWeKZS!d-MxTCw<d-CGN%0a8I-ubU0 z@8#vi)_F8(OWN64kMm#0?%AqZ$|54*oO3^BS@(T*wYD4E<hXzS72sew@ceW9@4X6k z^Yz6!SoW{hTN#oS5+AQW#cS!J?UvrAW@fXlUB5m%%VgHJ_{JN%%kzIUv2qK|nl;Pk zw(h?fv-eBbR(+Ap&VKE*G2&0nl@)=O*REa5wLiHiXk~?Q`nf%ulaKf1@AhV%e?I)f z&l*?tKhyrj?fbWIs=3T{CWa3cHb?C*{ZU@?yF^DpN+`=_dGo7dz7KZwH^xo(V?LHv z`upd9l_y0z0~7?d7=NCo8@=u8VSam?8>_?Db4496<ar%%TeIs>=~?-$QD>KGbUpZ3 z@yUGVY8B5-J7e;qC6@+iI&eI+k@N3MlsKBUIaJ+$p3K@1t)It^9ouT<<i^O*;j*Z# zJcnP(<VBp5Q<L=ChR)7T<&w{tRXjXA|F-1clGML-=0}*+y_9W}R8FdSPFj0fz12za zNrA<xzB47e?t3i_I*_!{L`Tf~bNcUv0U9kP`%7O2tqiG&wcERNW)~ArMT7MB7dQ0! zycv%6er{l77coEAtfRN^ap1`v><I^&|EKJ@WPZQqb8bPwho{-s*ZF?@_DxU9EN6y_ zf`Y>K9Xl#GVxK)a+Fh5JnD`PD>A9hst{gaUAm{GP*H2DP_TIa9Z}+=<d#&Xd7Hr&j z@k_V<z7AQtnjI-WK0KWC^z`)QSFT)%xbU=J&UV+e`}ghjO-)U2+`YT^({cIwKN1WJ zHf$(((ZtHF$0Kd#^X$nJ70bd$N4S2?yt}*nJr^&pZ@7ktQ>&9=%+8|JORe1Ef1)$J zB6pR%JYQN``iz0W(9kg2*4Fm4jEu|_KR>@u6DCaPxpe80BLjnZ-kljDGBP!hT2mjj zwzfJuJ2@FCDJz$k1~+cG`}FPXj0G<{IyyRRs=mC43J<?t6&`;5*WT*y|NLuf_ujm; z)Vsc{sAy6}Rh8Z8GiP`%EM}bIrCR^`+FJH@UTL-J_j|u<f&3G;{Y?7&S}}PUnVOj@ zo@NXV&d$v@udEENzx+16ws!B#{{HjLPo6xvur>R--1l$a>K28quH5ooOipg!`KwpA z-n)5o=gGTw_ojV%a?=0L-@l*lo$_gIU<s37?N|SQdd(M!0s#gFJ`0Y9nlC#Zi=Rkj zUfnM`LH~4Af8(F88k(9LPoFs>Gkx;p#}8k>{{47E;^DkwM~||)yScr)v%h{nKZ8SQ zY3cnpZ{95Y`t@rX14CF?nCi-vD=)8$-*1=t>B&iT&8|cH|Nr}~@8#|Nn@`F_W4?;# zw?(eqmo{(S9J?+5J|6>vw0Yi_)oa(j6_%H`pQXUzTUlB8-@5#r#ouqY^EbZV_dBm| z?%cbztxk$LqGcDK&#(Vy*?siVp3mp3f10fQ{{Fsv;qPy`>627$etF>|z{1LKAZeoq zU;E-kt^1ZNIdbpn)vuHG?yYt7^gL<Z&L<nCGW~SDMd70sYexZ*_QQb>D^AZi{jeb9 zuH;KgnZ8wf_T0I1|GvGy{rWw7?i{*wDQN!o^%pN}PCu_-_U?|Q{9%JvS5^imN=iyH zwzajLb#!#RAHS#KV)^xTvC@9??e;EAKR@rgle6<;J{gM*RbO9S{kT2v?yKC4j2joc z*i}?jYg4kbqh+L|q$W<8vgN~R{rz`Rv$LZgynFYLo58`+u`xR|G_<}&;9i#DhfkkA zu|-BjO?x%tK+~T;e-x$7^K6bhEC?}9J7aMuX`=~;V$IoEruIvhE%Up*A@T4wyV_qi z_GNEw94~)&r?9KLyE^*Wd?}XAe{ap5`K!5%l_Tx9W3h|MfqIXX8MkdrOiYrlt_pq4 z$Y5k-#5B*gI_-K|+qPNqU;ZCBaNzyo#f$ANYkz(Db8@o!{F+ZsIxjyy-v678o&C6^ zq~z7RJB!l~^-7z^gsqKYWn|QCe$&j(ub`)QZt0peISK#&{guD?mW_=~j*p+8KU?&W z<N5ja=3hU3+O;X+U=v4e)Xtc7b51{Hat*YYe}1}~o7=ftdn!L4oHS{YYxTD`oL5Y_ z7cW|r_R6mM`@6e^`~QBstuaaE=3=+rQ!=JmA<r%>biT^W&R65XFL!t5QjbY3t5&Vr zCp#m5{nYmzZJRc2>i3w$v)K3GvSn%(rLV5Au(P+zgoj`6c64-1|5;O47!-7ggXi#y zPoIij2QT+yy>j*H%!^*GlT>ERn6W}gSlGSGWf7aW`1I_}X=i`^d~<X2=8UC}K2{XT z^<VER<2l@L_~D9@vteT0tRk)lZ*ES%EwXOas#W<}S+BM{c<^9{sCHNm8-s*l(vhbV zmEEU_h>0DFp0!fLV21tX&oxV*_1-T{G^kfIadlx}ds2VIRmF2sYoY`TE9=|qr6)4m zcPR5n7(7_GdUf`{rQXxkR)%OD{Q3DgGb2OVnHhykO5F+>89I7<Ta%CXUEC)sz{2>e zTlVsD|Nh1H(Gd|g@`g!A{+>B=rtsdqd#=UL&ivFfF!)d%8~=LiL+`cEE_G|}@^a0W zpJQFFw_(SQ3J*`u&bc#ZMq2-0c$Hmc*J<skUaBvyuaCbv_4V|lzbccD_tmZpTdn)$ z^4H8C51RSoKEIZcktvF*)$`Ss=f7OX8_TBX^5Vw=gS<OCOm6kdSQI>PW@rdsA2)M< zqQi@x`Uejm7P^+REl%Hl?3i2d-M5|B8o%ahh;r&E8*a#9FL_sJ>UHnO-n(AiZy6FK zI~{L_+<jXdYS9;L(YIQJt91c$dPu|L9bV;zjK>QXh^q@Y?Fd`__L4X+7uT<U=jK}f z4hjlNd47IAdvx^euEfJ_cQ1&3G0nbK^X}23qTWRsa}+pu9R;TJ_MT0Sn#st};*>af z-2_?dvYeWlnm?C*{P?l-^|iIX&9t?%V@gWCd|CIcuB29WZP@9!{dIpYE?Kg~Qdr&Z zPwJl^A2UToMbAaO&3?@C+qc<Wef5O9L5I#|EGSV*)95<%^%WZfgR}GDXXj2`xDY!d zaAk;16>Ctx`q?c-Ste3uP8?r;b_g`d*;ZY7xqc2CE32xSiVDlMt5;KJ&zcn$yQ?H~ z*4nkXt^4=yza1T*C9^_}bI*egYjK8zt(qKcP7~&PFy8DuqIasie&@8)Pfz{+`Z~Pg z{k^>lzrVX%TwYeTkCCC^{XN_7lO_pqr>8&v{cEv(R=w0s5r(XLSC0LDzkhy8O3Ie} z^Yd&!{P|gYV^8Jhx?im~Z{4!XDed!Z=aa2k&aIgH{qBhqEAmcGQoTK0CvsEmn;RST zFJHd=H$-ddg4Mn0V%=BM>YqM)*7x(}^7+qlZg0!2&B%CR9<_E_?S}^keVrBt)Grmv zaQ}B+@B8cJrEbpKr|q-~RI&Z<x7b>miDAd?-RUpRu8Fx7Zd3j)Cg8Qt<);cwi4vxj zpPn3f^5ltwzP`RV&*6k?Ya$Jbo_Ivd^{dxwdtF_`vHv{#uh^%7*9FD6#r1m5oIBU| z_rqcS^}m1qRApjVvTPY!*4C(q9R-O?&V4z5Icw`%7U#8L%zL?9`gi?WHfiI=!nYv5 z*Sxy2l0k1ex1F7x{iRA!xv^#I*0neGR)4pe>7%x3`}Xte*R6XO937p#FZJ}ar4ns{ zvYeZPR*D=sejL;qy!7eQr+==lu3~X<ap5l*9oB{whiZjdyP6mpu4HDou`&7hc0NA7 z?`daei8{}=64#IWBFxo#mXnjSTS{8G@$kbfwx`oJhbm26p=WPj?-3Gm<=nr&zr}z3 z{w-g*_~-Jl!uttrQ5sWET|c8+D|IESRGN2}&AXoSC6d1+t=?Z-8!cS->*aF)Q>RX` zxwyO68zmj-_-$urcl_n^HEY&%6&Dw`x3ssvPu>_Y>+$ja^#=@iO4f?cb?v$SYisuP zbsRFs84nv67#cG2wKFeWy7b%oJ)iyl-T%y9QR?>e+=J)O#oZ^V{65ggEPZZ{rSOfc z>gjrso1SFb+wZrKeK!5Z?c4hmI2Nt-tFHbntu%2(pnE}fPHwKFhRC+tmuK2mfBX06 z&!51&ygYGT9i4fXUpg(^@bksR#lnXVA70!qZ@({OZCG=F#+5z)|NTD6p?JW6=Sb4W z;^^qxWqrn;lh!D^_r1~5*JqdOXP2-0k@)G^+1b-C87J(o`^)wE_3P@3+I4H~ZcgkL z*Z;L_=~C91-DSE5jvs%1{NdsDcy3Nk%Q-V<NJIq$JlIw6@Q_D(`t#eCmX`0f{5+Pl z(L_6J&5dp8=jVNR@!~}(DDN)SURw2hZuzIo{qFM2?0kFNCaKIe+rG=WdFj%pAP04s z{l9r&!Od&e#Cm#rZ?9>&W^~|b(bO$F-@JM?D?TX5DC6=n-)dH-Ml}lyi@d+TzRrL7 zuCVsk%jNM?r%d6oDtdAvsJQs^u8xilOHgAXJu&g)qO;#pH-~Q9woMe&^!fGo=bO#v zuj$9^Fi^CyktvX2pX$ZRFhN>YmRG{*jIYa<!z=TxFE3+r>bP(>VTrqs6|Z7Tu!!pe zi*;A;zqpdM^^N&a0WTGy<X*SKMg|5GUe20RvU^vlQcFRrlVX6@)Ed3%t1sQ3@wOw( zYVXdSH)ouFx~jxnfA*|dKAcS#E;KXl6<NRk=Gu!HJD3_BZiV_Jx|@_AGnUF<w9vZd z-5TFnd3N*lugcD_derTql69bPj*{o3-p4z_uCKq8wKa$5@U5kxVPR4Jv(4T%E?=Jh zN<6-1<EqklpA9)TH%-}H{@%*aUi5ya(M!Fo7w`36bF;N2PI>p{!?I1k7EEv4eOa$9 zF(i9O|CZh7FT9lfdhx`G6@KU6SM^@Iwr!WF#+}ID`Hv3I&UnE$-#UA<b;;|`OBequ zcPaPt>vK;{U3%f<$(QRoJ3ZIF`_}ECkdUUu##5&cYL=K+etM#Q_UzdQuV2r;w%EOY z*PJ;r{m1*|zxVg{&OHa}-q$nm%h?owN~*9YPoMT4H0UWRD%xdR{OnA#pP%1$$)!mL z9_X_b&lZ9W30$>j^I96TpxR-=%g^>9D-Rtybg8zcMy{f|TD-NTB_(EmT`iZxX|CgI zA~)y#{Qdj+&!0a<Wo)ZTa-E%<BOM$Z)@|Qj9_ZlUkXKYxl;J+r&Bev#+)U%=RSpgg z?@mqCo-E+B!)vL~n;RRG-?wlI&#SDi7MHcFsgQLz&A4@{cDNeY%-_GCzrDRZe{$IB z)L@a;_aNr>?d21vPY?I3s;W|8Xb8~~b#-xZ`StUs=#QU2ML}KVeKkKf)kj1`SjqN8 zg@l-xSXlfh%FSKtnwj}>!Gi}6PK%0)UMtz}<m6<Om6fG4&#u-=1*9Y-<ceRzw7H)_ zU8I=ZWw~6s2KVcJzdg4yc=^9)FJDG}yXY<-d)4;ylI}%|7A@=+*SA|OowBkU6wr~I z)9!xy__5NU_}Q5?i{1OzE&ZNY_U6XM@@s1%w=*#@6@{;lo9hrLvaj;<vt~v{#-0EE z{i_rd6r5-@^Uc=aqo4{aerHjtkZi5u<dZI^r|bLAv@A{w1BFy0GrL*V)~K?Gh=^b7 z_y4o<ntp$}e*8CPhKTKXcMWHK2lco-C#77!b}g!<wRI^w8(SJX3(J$ddwYI9kbhYm z7Iv)#?7GjNwK;fr&h&M5-dq*5l7)fce(m?WVNq_NU@(#5HCIwnn)I%?qT<KCzE@|@ zpO<&NZVB>COH0erlB$S^h+Sc;Q}6Gqy`BB?(o*}&jt99~oql{gE<b-+YUR^YQ$73T zY>SqO%YaOil9D>Zz|hs*-41e)xvA;QOGR7q@9*<v(5;U5p04+I<}+2@?kzPfEiEY~ zrlvESB6Qrk#dNKt<>mL6yt}hATvtaYATI9SibIDEElk=d;p*nL=*g3mkeHaBd3Lp3 zN0JP!N?r&=?XR;H>OQ(+!-j$t|0Mr*3ad}^nPVX+Ygv?%TU7MPX_Cs#&(F>}^YQV$ za&G5adwWyrX~&HbJ$*8ko5U1ZnA!PUPEXVI{`qeAd$Z1?NmJ&|?Y(sA(u4>dH+8=` z5%VTZ5{d~8y&AqYthl+UDevaZn+sR0STQ#+FwmNtiz^0%k0u#T@=#G~5qR?CNkzxe zq>!knuA<`Ni4i((pulkAaICBQr?D}j$IHv>!rk5FAc>@n5>KB!+ojyHAbx+{iyt2! z&kqo3WoKo*yJ`D&_v&wNe$Kyf<Hpt7+j4J*hli(MySSHS>C&ZTYjbavPMJSr#*U74 z)wj3h{yvgq7`4ByR;O0KZTog}FHcX$>3XrB7He>o7Z+EHiiniFJ~2@_`)HD37bvph z)4jaBHq4zHdwVZGsOKprCYJH_)m05MGqJn7O1VwV&6PJs^ytOzdeSbyv^K1pU&dlX z?{`qRt>6EzDjyV<8zXvxf`S4<Lq&zUkG}Z*e!u(k^Yh&!BO`_XdCd2pW3e$tM{F_3 z<-5z@-%HKR>~wN=zAWe@AR<z7`ucV8xpuWubM0!Y6g?-s@tmwCdUn43e<zTmmM&Gj zwWIK{;$N%Fmo7cKP?C3lpKRyRq>$LyT<}ob#)uvhDPAuhAD3y<rgiL_zIfxti&sva z;yQZdNRDm!yO;^vw|^J5wzdul3{0&3{LEK>V?>XZmev|UrwLQ1nmX!;Enc-stK|2$ zw`M;pzPy+?Icn{*sHmt#XU_Q4Z;d+p_3KyNf|8ODH+T2^-rnBWy~WSZ<*N#HcDM?# z^vK!%N(u<L@NdC_1%D5>^H2Zt<8lA?ur(2kERF|GOjJ(%@!{ctq>T@LetzyCz;b4W zA+wx)9Zz9lq3ki&jS)I$7dSR2{QL8BqC{I@Wo6~NnKNfjm@>tr^vjEjGZ`43K7D%4 z{?CWQw?Kx=@U?UC@YvXty}7XkRMLfNhy(;*7V1n&PX2u3>ea7G4ySu<!q>;iiptBs zUtG<72~-Gloqp<+nfX#-qQ{khz`(@bM2QC$d@PO*uhVrMPPfTB3OF3k{rIy+fP-a2 z<>zP2%l+m`X$p0Q*j9bHQT_SZ*}dWG<64WKpX)6vDth%POit$b%4=m-y<+C(=Idu0 zr=R<O$)>BX?_Ub2TL1X7X6O9*@;%b#d^d8wxmp<|e0y{AcWq5g-JN~4zt=r`_Dt^A z*Fp=Ksd)lAZHXfN$C=H|%|Cql#AG+0-)pJRj~cs>(9lS``hR!))`k^V+Qdcw5N<yl zxO3;uSSkCunpa(-+I17WmO2Qq2(U1knVA{X{3tLmFxc_Y{a4Rpi`1MPA69mDcSeR8 zGiF?=`}uVGZqSe|D^uf?!w(ylFIV3Xu|}n8^3{tM4UeBcub+2&Tdv`kh5mc3w#Mj9 ze<nI()~u`wn|Vyf3%gD~z4VElsd0hsz6sAxKRDR@zE|Gf4jdtUeSPcyeO+H~TU=Vo z+VrD5!PZegN^d&1L>psU;(@0{jfWo|xVAR>^P@+P95h6l7A}1Fl3QHQp{&d-W@pjS zi|5Y0`<HDuHSfWqy?blxDl087DE{ac*Jm>~H}~-IVQF+=5OH;Ma9~&yxtT3&ZIq~K z#)Spdzhuo#Omh5ueOblDr!Tv@I$V9q)Tz7*987IIl12W@=Qi!yWo6vzq$t?w^5fUn z*U6wUwPk*Df1N%tQJHs{-`rcruU<91fB*h}r-X!rGSI+M`uTY`1z8w>Ir#~+xUCI4 z4C<9H^PT-I<?Jle;{`J8zn)~JFVNt!km1vb+apm_T-<)-`0>*$OpM~k3om4tB;@4q zyx;fxoovIj%X>jJ)0dqy`{K&7XXp16Eo(M;X?NxN_5DJfF3kIXK9m0N;X^~{>M&J? zEl1e%Zf;7QKYe<5=j_?Hd7})h8$#SyHXMI^@K~?(!@b|{H6L#0Zw}C4k?UuV-j>rj z(=7Ma<d>J1i<_94ZFA-4U}1XM#w%U7pz{6e*V&5#G;$(!#MVS?WV%=V-qxb-&kyzb zW#_lN^pdY#xqf}Unh4k4b+NnI<mBW8q@-r?F(?RiN+l;J+kgG^No(V#O<Hk#tG-T` z<-L)$Rm#TJR?);n#KzY4zp7BD)QiPN`Atp>A24rmDg5&G_V#Ui_U!TgDZtgbA?2jd zj;gO(b1aM5czAgk4;!2~f1Z6~gw9gYRiHtOl$0myZrzIF7V}-vH}{Q2;-MC^#yi{d z<#+7Z!7%%5o49^lgM$LYBo)Vn0SA`PuiLe7aiG`2fDd=?-d(>YYHL=rhf0=?mX_42 zt62-TZM!yy&s$Sld$Xab=~__^mcI-OdJaFFVORO-$d?0+%)vWj*6j&jANR>P{T$Ek z;^*gDb{0R6yRkXlf9CAj(l4$vUl5vq^kKn+Bb~x|N)uNsT(ICk>B&i|$2GdLjHP$P ztm9gs>Jjw)OkaprYeNIWj<UB>F0QVOu7O{EYG&l+wY9ae1q%yLz7@Vc?(4sAxAVjM zWv#!ZZ;be}r&-(~K;-Jvg?3e9ReyeL6m}FyNJ_f2dFM{c?6b2>nbXhAV6>6TpLfnj zrRK+ng$1v#t?e#lF8aDqdh+rRt;FBo-adHwlGACSz>*-%x!aOJWn9+QS=P0`zA)Y5 zKU_HHQGvy>etCPd-oCzhc^Mfu0)m5+9Ve-{xVkoO-fS!(CH3yT%Zpu?)90Lis>Q%C z&!+Mb3&VxY>HgX)Lw+^y-o5+!ySuv^4?p~|b)Wm43l}E*{_ybdzu({A&$mxF(9r&C z>O_^3&k8IGo}H1@(9vnB{QQhnCu+-yrHgM*e!&nG_3~vx{L&!J6>HX*Y~Hjft2=M` zW4)U>+uBr4n*E&awbY>eUCfCSCmLdRmo)~hWNA`3aN-2VtJkkvjb{3!BqUsj2@k(+ zZDdrmcKi14QF9h)RD64L^Fa0YcRTC9-Aw;Db?Vebm7kySs(W4vTz%CkHdc1Zlqn9y z#l^S1Z*N`wG_MELbuKFjb6Xk0<>Tv{J!j6GyxTW!*hrb>+~8$qX8!SN^?JUi&!6{q z_4miuy}GipVZww79CH2Y>({S0kKIwA=rhxZwW+yT|Mb(Mg)T~lbsruydY_+XyE>}h z_V~_SyP^tr#zgEcd;4+Cnl+r)*Tv2bij2&>E5*ZUW@gsEX6;&TU0q#oK_`bvPafRc zTm7Ax!Nc2oc5q~5X6>^xGg+A$8LGa%O7)oZ<ag9su^TztDqde(d-(OMR|^&{Wb~Lc zCp$Mc_h{0_grA?DuDp5k=3`LIcyK4WPja55vU}@Uzw`2*OM@={{rx@Gf1b@w6D_T* zyMKOu=9iX~ys9a})fl7KK5LfLigoL@IdD8&`#r$H!-E6V<SQ|A_F5YB@a^sGdp~{p zbSG3xbowHVjEsziS+k@vGBP-|Lsnl+$jgh%%gv3o07dcIt_x*VUstc+*R(bJ`XSKN z#Hkb`!P#fSGPg#pSic@*%ZnVvMXT+$-`mImnhyE<^Z9)HTU#<O+u7Ui-*Rtn^?p!? zaAgRWsi`Tby7Ubc(VKkIg^`i*!&&qDplmA@9TH-)WwDj#B$lN?oL8@2-QuL7(RJvh z@^21MXR_e&G2Zug?!@rV^ht9G6tSuORTALm*LVEU(eCq`B6L1{{kql2$Vh6<)htC* z)6%-s)TO0CL6;86*;Zxr^!8dx^`@=zTFTVukRT!_XSZ$Brb*NKJ14987AbfN+5LPn zdC4^a)#YYNwl+2snwy!6N=ib0{rV*qv$v|0%ZWqIw(7}~7cV+wWMn|HxAs<>uUfUr zsjsgumv7$Qy|%aZ*Z+5`O*hiecyVo+?`*zT@%Jp!&diXqwzhuq;K72vo}N25Z&e<g zVVImHBrGg$YGN|O%G%mHY;9EQyZih5-@JKq;laV?t;NsJ?Trczy(+HA0vfb`_wL<P zGc&V{4-XFB`uzMnyO_8*e_>&vV{dQoG7iNPr%y{ieet3L)W%n6QBYG$TfKPk;!8Jg zO77gbbFWqTyBLADQ>?747J){II23Pe$-L~y&d&bz=H~R~j9JI~<>TEh8)jZwvgq8L zPmdlwQrwmM>VIlV3d@#HU<10kx^8*SH=Apoe=l{`dHI?Tj&h!pa^mCfH*MLn#Zqf( z*Xwuh;&x_TUB$9Cto!w~%CE1kYJMqBKGx&t>gsyp^5xBM=jPtr^mIYg+Gl+dhKoAu z)`RpseE88wQ&V$FT*$7vzrU6&Tc-9{P}$Ao?Y+IySFc=A5Eq}mt!m%DU$6JpFFF7G z++6NUZ$EF#z5Q)#+*-EmYilh1uD=J(;Vum-e12|jwW*p~nzn1;j_upOPp<s@EcV*| zn$MS(de`ys@twGNQ?ggmcv;)D{o3K{e2UA;rcF>exvbK6y0@R7+hjFgCy=6(Cq2a^ zBxX#VKi|G9ZpY2N)!+5l+1X8F)%UI_2DN0<)6+wuqqEm}e_k8Ceb0-3l@%3xmOM>9 zHAQoOXh=vzvQQ_>L={enwy#&rS3W7)Im>M7j~crTH*+R<EmaWUuwZe_P!Z}hbPe25 zw`60Cp7<jRznAw@-6yH+Ubf6FHzOm%$vs`UrC_GdvZn<WHhk@igS4hLwY9O$oH<kS z%C&1uZHZx^8S*b@`1UMY=63q|=V~cQ$*UK)aJ4!y9X9Ct=XaU&LeUWirHOltjE#*K zEU%iRa+9moDK{a(;ev5Maq(uu`RAv<o)r=r8d_T@bN$lyU!^QNWAti%eOZ}upn<VX z)^%d`)~IbETA{%rtV$C*7EAxtnSQ!e#nVf`$w8oHVt_`@w38`Hdec{Dd{x{b)ajC$ zl;re6F8@N-)|{C>%a)x_kd%;Ua9YUlE5fGzu;G)>KZ815lFmH;ymZS<{i$BAF?!*k ziQS-;A)u)s89w)=K`U8|X8NS1q_7n2+;evQv!b1BvUk02gwFSzlyW-7sC0Gyq07d> ztXW&5u6gb5^iavVFjabz%1vKi-&b<BRa+j5dQQqM%1lVO5SIRWw}_OKlv##})H<hy z0k1x}t_*2%Tg=#`;A3SadEv&546UhN@n7HFjoyFG?56|AL!nL=Z2=Ao6MaFaiqg`p m(-b=F($dmI85sVXGl&?xn3%WkojwBt1B0ilpUXO@geCxSZ0|Mz literal 0 HcmV?d00001 -- GitLab