From 27188d46a9f4f7b36f15bb5ba8c6b380e47f5e73 Mon Sep 17 00:00:00 2001 From: Tim Rupp Date: Wed, 1 Nov 2017 12:00:06 -0700 Subject: [PATCH] Adds bigip_iapplx_package module (#32456) This module can be used to manage the iAppLX packages you have installed on a device. It can install and remove packages in their RPM format. --- .../network/f5/bigip_iapplx_package.py | 345 ++++++++++++++++++ .../f5/fixtures/MyApp-0.1.0-0001.noarch.rpm | Bin 0 -> 57508 bytes .../network/f5/test_bigip_iapplx_package.py | 104 ++++++ 3 files changed, 449 insertions(+) create mode 100644 lib/ansible/modules/network/f5/bigip_iapplx_package.py create mode 100644 test/units/modules/network/f5/fixtures/MyApp-0.1.0-0001.noarch.rpm create mode 100644 test/units/modules/network/f5/test_bigip_iapplx_package.py diff --git a/lib/ansible/modules/network/f5/bigip_iapplx_package.py b/lib/ansible/modules/network/f5/bigip_iapplx_package.py new file mode 100644 index 00000000000..07111acad86 --- /dev/null +++ b/lib/ansible/modules/network/f5/bigip_iapplx_package.py @@ -0,0 +1,345 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright (c) 2017 F5 Networks Inc. +# GNU General Public License v3.0 (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + +DOCUMENTATION = r''' +--- +module: bigip_iapplx_package +short_description: Manages Javascript iApp packages on a BIG-IP +description: + - Manages Javascript iApp packages on a BIG-IP. This module will allow + you to deploy iAppLX packages to the BIG-IP and manage their lifecycle. +version_added: "2.5" +options: + package: + description: + - The iAppLX package that you want to upload or remove. When C(state) is C(present), + and you intend to use this module in a C(role), it is recommended that you use + the C({{ role_path }}) variable. An example is provided in the C(EXAMPLES) section. + - When C(state) is C(absent), it is not necessary for the package to exist on the + Ansible controller. If the full path to the package is provided, the fileame will + specifically be cherry picked from it to properly remove the package. + state: + description: + - Whether the iAppLX package should exist or not. + default: present + choices: + - present + - absent +notes: + - Requires the f5-sdk Python package on the host. This is as easy as pip + install f5-sdk. + - Requires the rpm tool be installed on the host. This can be accomplished through + different ways on each platform. On Debian based systems with C(apt); + C(apt-get install rpm). On Mac with C(brew); C(brew install rpm). + This command is already present on RedHat based systems. + - Requires BIG-IP < 12.1.0 because the required functionality is missing + on versions earlier than that. +requirements: + - f5-sdk >= 2.2.3 + - Requires BIG-IP >= 12.1.0 +extends_documentation_fragment: f5 +author: + - Tim Rupp (@caphrim007) +''' + +EXAMPLES = r''' +- name: Add an iAppLX package + bigip_iapplx_package: + package: MyApp-0.1.0-0001.noarch.rpm + password: secret + server: lb.mydomain.com + state: present + user: admin + delegate_to: localhost + +- name: Add an iAppLX package stored in a role + bigip_iapplx_package: + package: "{{ roles_path }}/files/MyApp-0.1.0-0001.noarch.rpm'" + password: secret + server: lb.mydomain.com + state: present + user: admin + delegate_to: localhost + +- name: Remove an iAppLX package + bigip_iapplx_package: + package: MyApp-0.1.0-0001.noarch.rpm + password: secret + server: lb.mydomain.com + state: absent + user: admin + delegate_to: localhost +''' + +RETURN = r''' +# only common fields returned +''' + +import os +import subprocess +import time + +from ansible.module_utils.f5_utils import AnsibleF5Client +from ansible.module_utils.f5_utils import AnsibleF5Parameters +from ansible.module_utils.f5_utils import HAS_F5SDK +from ansible.module_utils.f5_utils import F5ModuleError +from distutils.version import LooseVersion + +try: + from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError +except ImportError: + HAS_F5SDK = False + + +class Parameters(AnsibleF5Parameters): + api_attributes = [] + returnables = [] + + @property + def package(self): + if self._values['package'] is None: + return None + return self._values['package'] + + @property + def package_file(self): + if self._values['package'] is None: + return None + return os.path.basename(self._values['package']) + + @property + def package_name(self): + """Return a valid name for the package + + BIG-IP determines the package name by the content of the RPM info. + It does not use the filename. Therefore, we do the same. This method + is only used though when the file actually exists on your Ansible + controller. + + If the package does not exist, then we instead use the filename + portion of the 'package' argument that is provided. + + Non-existence typically occurs when using 'state' = 'absent' + + :return: + """ + p = subprocess.Popen( + ['rpm', '-qp', '--queryformat', '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}', self.package], + stdout=subprocess.PIPE + ) + stdout, stderr = p.communicate() + if not stdout: + return self.package_file + return stdout + + @property + def package_root(self): + if self._values['package'] is None: + return None + base = os.path.basename(self._values['package']) + result = os.path.splitext(base) + return result[0] + + def to_return(self): + result = {} + try: + for returnable in self.returnables: + result[returnable] = getattr(self, returnable) + result = self._filter_params(result) + except Exception: + pass + return result + + +class ModuleManager(object): + def __init__(self, client): + self.client = client + self.want = Parameters(self.client.module.params) + self.changes = Parameters() + + def exec_module(self): + result = dict() + changed = False + state = self.want.state + + version = self.client.api.tmos_version + if LooseVersion(version) <= LooseVersion('12.0.0'): + raise F5ModuleError( + "This version of BIG-IP is not supported." + ) + + try: + if state == "present": + changed = self.present() + elif state == "absent": + changed = self.absent() + except iControlUnexpectedHTTPError as e: + raise F5ModuleError(str(e)) + + changes = self.changes.to_return() + result.update(**changes) + result.update(dict(changed=changed)) + return result + + def present(self): + if self.exists(): + return False + else: + return self.create() + + def absent(self): + changed = False + if self.exists(): + changed = self.remove() + return changed + + def exists(self): + exists = False + packages = self.get_installed_packages_on_device() + if os.path.exists(self.want.package): + exists = True + for package in packages: + if exists: + if self.want.package_name == package['packageName']: + return True + else: + if self.want.package_root == package['packageName']: + return True + return False + + def get_installed_packages_on_device(self): + collection = self.client.api.shared.iapp.package_management_tasks_s + task = collection.package_management_task.create( + operation='QUERY' + ) + status = self._wait_for_task(task) + if status == 'FINISHED': + return task.queryResponse + raise F5ModuleError( + "Failed to find the installed packages on the device" + ) + + def create(self): + if self.client.check_mode: + return True + if not os.path.exists(self.want.package): + raise F5ModuleError( + "The specified iAppLX package was not found." + ) + self.upload_to_device() + self.create_on_device() + self.enable_iapplx_on_device() + self.remove_package_file_from_device() + if self.exists(): + return True + else: + raise F5ModuleError("Failed to create the iApp template") + + def upload_to_device(self): + upload = self.client.api.shared.file_transfer.uploads + upload.upload_file( + self.want.package + ) + + def remove_package_file_from_device(self): + self.client.api.tm.util.unix_rm.exec_cmd( + 'run', + utilCmdArgs="/var/config/rest/downloads/{0}".format(self.want.package_file) + ) + + def create_on_device(self): + remote_path = "/var/config/rest/downloads/{0}".format(self.want.package_file) + collection = self.client.api.shared.iapp.package_management_tasks_s + task = collection.package_management_task.create( + operation='INSTALL', + packageFilePath=remote_path + ) + status = self._wait_for_task(task) + if status == 'FINISHED': + return True + else: + raise F5ModuleError(task.errorMessage) + + def remove(self): + if self.client.check_mode: + return True + self.remove_from_device() + if self.exists(): + raise F5ModuleError("Failed to delete the iAppLX package") + return True + + def remove_from_device(self): + collection = self.client.api.shared.iapp.package_management_tasks_s + task = collection.package_management_task.create( + operation='UNINSTALL', + packageName=self.want.package_root + ) + status = self._wait_for_task(task) + if status == 'FINISHED': + return True + return False + + def _wait_for_task(self, task): + for x in range(0, 60): + task.refresh() + if task.status in ['FINISHED', 'FAILED']: + return task.status + time.sleep(1) + return task.status + + def enable_iapplx_on_device(self): + self.client.api.tm.util.bash.exec_cmd( + 'run', + utilCmdArgs='-c "touch /var/config/rest/iapps/enable"' + ) + + +class ArgumentSpec(object): + def __init__(self): + self.supports_check_mode = True + self.argument_spec = dict( + state=dict( + default='present', + choices=['present', 'absent'] + ), + package=dict() + ) + self.f5_product_name = 'bigip' + self.required_if = [ + ['state', 'present', ['package']] + ] + + +def main(): + if not HAS_F5SDK: + raise F5ModuleError("The python f5-sdk module is required") + + spec = ArgumentSpec() + + client = AnsibleF5Client( + argument_spec=spec.argument_spec, + supports_check_mode=spec.supports_check_mode, + f5_product_name=spec.f5_product_name, + required_if=spec.required_if + ) + + try: + mm = ModuleManager(client) + results = mm.exec_module() + client.module.exit_json(**results) + except F5ModuleError as e: + client.module.fail_json(msg=str(e)) + +if __name__ == '__main__': + main() diff --git a/test/units/modules/network/f5/fixtures/MyApp-0.1.0-0001.noarch.rpm b/test/units/modules/network/f5/fixtures/MyApp-0.1.0-0001.noarch.rpm new file mode 100644 index 0000000000000000000000000000000000000000..1692813534236424a1935a101ba8cf9d5fe97924 GIT binary patch literal 57508 zcmb@t18}B66E6D2ww>(8wr$(CZ9CaG*%%w!wylkA+uV3>^8b6P&N=tox^=7WRCS*B z>F(+2nVy;Nt$fKv`Q;i2;IjeAcnH|r)6mm0(9+Y;)6+A2DgQq$skn>OcvVZA5?Lcs!2>vOkpYmnD`ou3A|9|;b zR4rEj3;4LOSD_UGjC2~khlwdOlOYq6kud`s3ll2`BZHw4vk9AtsR1JgGmEJKD?1ZC zJ);35(`WzBaMjbFKmU`{-@kurKA%6w1OWc0ys1B(C_hzvpYoX(2=*s_`51o+x~KmT~pKmPQIU*qNcXaKaTLvF8z;xt?_4nps)FT z`hlW;;%5#(zdrGEJweg_s|RZNXUF)&FaME$cFceF=}-Ku2`JV-`|>~jRmV?%;IH-n zvXg(}XMA9yPyC86_KBb40)Oeh#uxv`|4053pZu%;KRu}WKl@kyU;Q=y+2#Ln?SJ-v z2&(hXZv9_9sO~@hHNVew1vUJ{uYA7h_!ZCiAOEV;7dQDY2l=YO7dQRKKXdvI|BCzB zALOepKth23oNvH?&Ntvc=Ue#mM7UTx6Pmc&+c`R$7!z82UI2tnE;cp>jvlmt|FhZH z#L39f!rs}!&X)EwEgOx08$g*QoraEVM>;HoTvsxtdtp+1r@dI@3v87&;m_T9`NitSxL^ z+ySr25g25 z%m$w~8#6t#DXYonW$<~1+1c0_j2Re=3|W~zwH(Gq94s8n#!Re?riO+F#$QYRe{YT^ zPR_P=#wNyq|9_tT_nVj2$DJd{|W#9V*T$p zbO0JTMnW1hfRVk09l*@f!XCi!Z#U7{8`1oCcYV(1KR5f|zwi8?&xiz(UkB*3ft+`q zdE$u0le7C3US+tE=Wd7!0QZ)A14)-#MAWTRt|66PW(no@ev>C22bMQi7C_Y+@_l7) zzp9O`ldE$W*HS?TC?>{wO_>+TD65znn;L&LZPu>MCr=}%puaO)nG^0cJAa$spVq3o zVywT=bNl^ej(+JExu`q-L9n|XO|wj zs;M34&NjYycraLv4NalAcXMVKTdE&7$3|ErgBEP!m7SA-JDsd_bp{z8C6_gOR)D>N zSkAnFqf9=am$W{7+8#VR@*0L{e04J8ZAzIQTD&kfI=ivFV~~ZopL<=T)Tr_DdnbC=Lg>3&X^AaBbWE#2@`hbp3MzlHMt<0Ok1O&>mdg(>bwKFC*Bb&# zL3mO4%h=QdQOM~#^W*e*@)-@>hE{0Y)lqLEvhg6Y64yRF)e089%+{=8zY-iT} zvppd5Q9$haHO1ktPTa5Z4^k}W>iILTQ4jU=hw#A7#$KTnuQ~Q?nPCAJu#l4&9UI;A z6=v{Nggkv*z0%DP`dpxjW5R&H1Vo9i*nR%Uk-(p93$17OraB4{WKndoQSQK~kJCGsHc%kW>)mY%K}CW}QDXjI>Si@{Hxd z8QKhSp~IgNt@Rd*pz;nyYB0f^{Na%wpRatY2DoG9jWz9m^XI%U?97fKC4~M((oftC zUlsqxh*`YH!h$78FGXr(EeEbfk%NSlEZvsZw>?g`uzUQl8wEw?z8j_HwgCHW0B%e} zi|hf&ugs0Bm)l%TaGMkpMgt38*|p}3q&-e-2KH1zM@e(I{_J6S1*h3Ay zDZRIk2QGQ~eH9jyQCwew55jq)I~L}I8teP(T{OlIuxK6Fxq5TV{S%~lT)l>$gZy-t zAhu>6jKAffBLWQ^S)&2NH6c0!dzh<`w0k=PhQF~Gf~=AMBse`m--_Q8Nibc82Eyx5 z{7iZg?euWxbI0V4HsFYgdk&&T2fNDOi3+YY$32%Ro?%JsHS|jto-;@FHV$*57DN7) zA{GEyU_d!ip9MxRHS3Hiw&!8bor!dhd~O=om&MvC2}l`;zS{d`z8Gh$Od0G6$N3H^ zP%3a;mQ&r{-Y)Pi>}pW9Q0aC#l@iP74khSy-G7cdsgZ3`;tC=)JU%E10x$H7n-Jmy zpSx#fa;W1E+$oXz``1>t52XzPqR6ceLZHWG_0O!K-$<*7^kIwWi9}Dos2%nLeyBGBqjik&!fbi>VQn z%+xYJ+}NwMQ<`zqIa`{`_GfR>2J3g5`tqNpy&sZBMx;WA2PKXA7k_?_GV3Rzo!C|P z;L`Xh956MM{evIrc9zI67soD9-Qoa`5zDvehG_o)=R0cK%~Q>6+1@Kq@WT`nZ*Ye; zdaxiHK7p#H$44Ug_1*7Wem&mU({q=-*2IYN7>u03ndAD4V1QRrCSpXA=;`hEZ7y0> z%>-lQYVz7npSw5mn4w$E*6gcXYnv$yBn0bBNdR61b%jKdz#kJ=E(w zv?nvfEQ{&Nj0b8qcTWkzz>ME5S9Icz8jE&321>=G&s zR}oa;)58(-xaGAqcp&g6wJy8XD*h7RnK`Nrs`2C94p?nEFtv z`3{%tB{6t<@G!CQ9&qDM?@Ms|wsRx&l9T&F-nLF$%iS*HgiI8lL!!z~5UkuIBGJmw z9w#cDi<#&^eu4-IMK?VAho9uM0KGuzyC;x9huqeTq9e;HeegKI+^691`kI>^EZM>G z3>bL-!A#*Vo->YcO?|3vPhgs`#*o#Fc!P|&6{4Shyimw9{g4+|pwhy(2zwVX)eeJ% ztKBofpgO!0^d!%wgM+s2S@t9K$mPKK(1k>L+Y3rdj8uptBg)Fxhy$dVS}w&D!ksxF zZ-GGv6hiugifRbCIR_qu$uPO^7BNZ&XVVXVpf-CM1`P?^lGxwQsw33rt&Y~MQAiTL zH$PBkJ}Ssj-w9S8^hoHp!s+`I=d*VcizeQ6Mz*WhltLu$M_cU&%)<0>`Oxb5VVVhb z7!nj)1$VHR0}ihY*Ea!)`bej){q zIo#fji0?|k(iWJ|)7|k;U?`U%>M=sj4D}b{6JWSGInLd?Z?5wYgE5e;05tR$AiFq> z@8lbVF}4dCV0q`ErDtcfiN|Bm^g4&KQcE&ITb0zUO1C?avp|4W+ z03_K+0pvG8CCDbTgjmt09B~6K^by4v4x;7uc`|0^2qNNv$WCZK!vlqBdb)vn^g-#6 z)oT>FgC4jh^MmQ4>&;P7z;A#qyqNP6YBm3s^=r^e*ZoQp!SC#+9ej897v(JL4MIS= z4Q=Ai%F6nP-$BTa?^|QVRerkRmRajPTzu@ny1vRB*4uIUhWZ2FltS097$Y|dQj(cd z9QA}c`*#kVyk>ey+>JhNM#LOYS*ePexB|(R{gnJ|K(2xS%m%I5&SW(o@wG6V*8SFn z>9l2Ij=2H^SrKW#3W~eS2U-ehguk?(pf5Va_NlPvB$jvY%{pSOk_M+urxm!QiJH30 zV7mNo&Fm3&?=wB65n$RJ^*UN9?w-CuN1d(SAGpNIHcp6OW;KGwg~CArkogjq8gz;W z6)FPM3IlN|U%Jpzy>+`A^)0`ITwT0E=2muZ9TI*vMha0Nt*`8y#{LrNpM{F%o|BlwKHf4E! zK8i;i&Xr2n$C^wixJ(AtfNHqM9M+n%gg9=+S4qh?4I2Fc?b9RxYT)<0; zT)qS8P^9&f^#?<3!$I|Hv{?g<-$b*=Fjk`=GQKMBBo58boUCGuDI{_{63abj+@*+? z8m|q;PVN;z@;T~&pE)Krv}Q$LrH^eDk}tK&Opy3Tq0G3q3GJxk(>BQ1Bzt^_iCMn+ z8~CJxyR9eJVHt>yn}Q0n-V(Zf7ceu_g+7$vyUU$1s1&sDcGHTsO??&Ojo1=Ov?!I_ z7XH;Z91%8ilE5Sm@7TS}ACFrJr%sQA)}c<*XJNV?dRO#H)N%1-gN~S6DQ}hUFn?K? z*~DP(fU+Pg|0d5HO~rQalE3(eO^mrLV0dq?mQ?r%n^%`a5!@s_!6?hyCBoW(O#gL3 zwS9yDEjGXAP_Q#csjVkVYI^TYD1?I0L+hm<0V6vWQtVI6YSFGG%%2C`i(+a0< zm(|sOiAH8u8VI_>NKr7^!(`hFDy-h)d#$CR6@M>YiAMzVH)68wo)!e*?_#qASdP5C zllX$;-;vz|Su_{BOQ#RbVSm4i=6+ zv^SiqMgo6xWAnElAkkPi4+bZupLTx27p0H>$&ag&vY0v<+EWl}{YWolWr4n`&wWEY zAKg4em?edzJ*$amgwOBh!QhjcvbKFSp3Yu+kYev%;$pW38?cwph(QK63t%1CmLP1A zw?Pv>D$5p&T+wX3vgp&eybq=*K;ajfI9bD<+6XuHdlA~l=g6AJb#!E7{w2xcUv;c zE!T$zvrv-&o-59eU9O9qrEhh<_u?pJn=j_D6M!FtikUuDjsPB4fR56f@D(HFQ;6q- zF?S>tq4&mNT_<`)#3FHKj`Y0Mj-i6w0-|xhrB?`}Fq0fYkQF$$N<|c07XoV-%dcZL zt6ow$%I_J;lWHRrzxU8L!w|KWYhFxh8x0|(7i{5}sB^WG&7G+cPCBQ>u-W5)g)<1&2gL&2Mr!MB(HXsuZ`bZ>FzRH9 zh*$@kVPm?c!^VMJQyN()g@`9B>uUO}2mzPe6$! z=+&#xk{$TrqU{}nXLQ75aJ%(bV+06^S#et}nw`4Bzk|9_y8J7VcGIz~*pn2bczRE{ z_Sm39z|)>SexLH#Hn+?@POhs?P?r@g;8^SUVuTtQ1WcZsz#5nJMX`XKd#t57%-J!0 zz7-OhN?6%!lzQauNbwBUS>E@ZCWv{MyGhFB8grBdych2%;8%P}Y z!`>UCh$iZO!#>#Qx@AeTM-26M-z?q1IiJ+~Z-Vx5WQ|ZYsM{!wqfvjiNrU*n88jgl z+Gq?lswag)Hvts-Hgi9sk}6qRn%#Nze=lN>rI$Zl^}bA)IB|vwryd&%3;gwC7x(97olVntm)ajOO zapU^Ok{ZTZq+|sY-Kqmwopu!#JtaS1W@oH`O?nQ>CSw;I)tyzF9$W z@2`U84xQGw8jh?NC63h!>n*@t+#2-5bmG$XZ?Kv!Hovkm>G?DLOpcjIKA7&<@W9jO zcOD@&V0loGdaoQ}{<+LiXFZR8&FKGq2US)CZ!1xqQp94s=TfBWp?IEy5PWW@)iJ}Q zGUgAC0vWz|ytU>mHoOLad z@OlQ{1)MBnLcbl0IVkfoP!#NrjH~yh|BM(Pe)=eY9DT)29prfk-OfI90%rqkW6hGz zoN5mRMzVh=P!_6`-=Ji+Po_$9zx0=Xz6Jpg|ME=0k>j?kC?fQ{4);r$sKF^tBN}}Z z80OwqFk@9GB-7eLYA#7Fwyp6mYv%s%KIkOo^0DZFxLV_xHLDryW3xAxQ!KcoEMR%= z$s!oeEkBkbivknri54uWG1q0+B2zCFu^JW7MUJTGYn_=TZz)L+IgmH7=x|Ih2Kr`8 zuUUjA(9eJ83k(5k*eOAoK0zht5N2$BaM5>tbHstpznB%&a1k&((a#2;sA>Nsn-x%F zG1n%Z$6*yDavIh|18;Z`4Bb_~u!nu6k#3rR*k%|N#{n7-qs~wJ-V#lNRc+^h%t>XB zvCZUaiPc}5oa+?;l7s_uI)PD((>5(+4{Hg8Nm+pfu3ytsQ9)jwjKM5;`?h7O1-et$ zKvjiNk|CY`Me7<3O5gA*wcb9&6bO<6r ze(S2s)!AzZ4Tt_@>0xFB!M>6Z^1EmCdTOR*%fMvU!6`G>NVmofJPPm0hQ^!@{Mq%* z_LpvS8Xjo%%lnEmw9IuUU6Z2z>UpgHd54M?DbI8c#uz*m?M9~QH5~1R9R`igdKk^9 z!|3KMAaZZwo!sgPV@_=Y=fZ&wi|&|~#L2**6778NVah&C$&u=DuJ~nfvmzu@#OmWl z5SC8sjCwvXDq8BBglrZ_v-S8TdCdGr;^f7A^gfKCgB{bSC{j8&@kro%#UQ-C!mv{tS zZ?&N*;sjE{Xwn(mm z2-v!pc4)`Hp3f};9@U+hCwJY6_xm6&8A8YY;f zcBzx+({wCiIXx|HN?ajk< zD>RCd@{^K*0M=|M=+dCpv#o9_f!$Cb5&0pdMwCJe8NNnB^mB_gi*d_ zfCh0le9~MMdmN2wfrn7r_Z7!VC8BT8u3Tm2G%?c;fn7E>D%BR>&D$~*aNXVD3Pikf1FtJ=LcSZ9Afp`kz5%av+aWOL+F7+1O-oA zldHb=|LD~^S06yKU>qQ>paOWY4jeOJvW4t{V<g2Rjw{tH>zYJO0WFDDcN^#qv7&mVx(Quky&2eryva|b7%wrbbJ-i-1 z!JGRvc>1fW(camFUH67($KAu^Q1h0pBu=q4-3^3`A%{w>zH~k|Whf+Pj6F_splc+C zeDfqUs-R^l;-KddFlI%~^*cn2UWp{^b>BKoFOl3c6P^$BmW7Zin7s^oR|b8ej6*su zhNL-Lvf+#ZGX<&-lFYnV@~4Z3rZSSR26>;jnh5DRq#F76ONX*)<}QG$Joz1I7yDC= zSHj?+YmDIrB$Zyo)=43)AintEw|hmj)`)yJI!VlDobExwY(a9)?XXx>#d=QZd~dIE_S(0_Tzbmqg_!DnH7?mv<6nMCO(9?@kY6#uxbN~W>ZP;T0KhVS4IgM=A*=ur62-5W$0G=tIK&{WCgZAIy zDd^@(F}X*Xh3s~f=-)$_%jBXye)#!UVx{FjuqIIi5V9NCe0f&1Uz=X0x5{k7u`N>gOs3bW3m$IY)&Ob97`*gX!-#NM zbm>HiR+`*7+8VB~c9qLo{nrtWB>i|}55^wJRHX|Cm5MWncDM)Fo>Sy%GhQOC$)oIW!#MHZ&9U|hq_B{62vzZzNCNYXUQBG#ZLboPz3xb{QLGedZ z4W9-#H=hfqJ*b`Z9Trb(^c>gonH^>~>i+Nuq*FkFNTL9}ali3wqM}S#4E?1#g0nR!%_A!kMIg)inywPzX^}al1r{;71|Q|UIVxz2@p{LX>OjD`=oPmhzs=G6jz|Njf=AIT z2Tp19e-!s>tjE$1h{P{3wHW~`knHpm{91xX2%MN$^g+I?^$sJHV{L=Q;c==A^OYZp zITt_XE(~A*ukBQ!hdh9!ds>R^{ow?ad_3T#2V_+SL%YcTWLD98WU8-`lrjwtrYUb= z(jehctK4i4Mu4jgmiR%9-FM^V@A@u$SJTFS9(V0o>|8+dOqg$F!)&JJFua2TmUgh+ z=HDje?j^yt3WG=+JR&HT5;rR5gVLS0d*Ae?@XN(YeP#fzn13<|z|`RYr99Gl_YLmM zB3D%kC5VosgS=2p=_1X%Vm}Jp%GX8-i)1A8qY8E(>aU90yG?^~TlF3lx90$$E5Xv$ zTY3SL%~uetom7;qYabTAArm{Z3#~=}a)`H(bFx5=6!j$$xf9+f1}V^K@|KJaJ1Cu` zegwqzuqORaSa5j?0v3_*e72U{g4KNOxH7|Z5~<{Xo3ElC8G|ehcOgJi@@Xxm_NLF3wqQHj)hxq<$EGt=uOo2Vn@pFSg zTYKSBoa!JAQ8v@%0Apw|0V2yj+&MT%jbFVzTVX|QKSFoOH5*R}Wq(lW7Id>QGl`ha zz*fw#fNY$}nSH}eRqV;FP{Cy>i>^7FX z-zpmsDQH&ZzR0FM6-)@S&W;~ZSPw#(El-=5N``&?hOM_|4>)I5#lS9pA*nF>f6T*@@*S4|pcaM0rf23Z@Hh(Txh!=X?s5|Qr z@iZwR?<}^H2|r8Mp-gCvO`XMd67RheDgt`$x+FD7xAr7LNq2gm`TKzj$TvH*H5%!Z zQu8TH?DmpJ=(!N!waxoL`*mi0JlDb-0vWo9lelfA5-SBD(-+@}LJ%J4Tcdg>lEj8! z;qwfFPBl`^xj+_omK z3etjgjOaW5-`3_^h740ex$WX zpYe#(IiZS&$>ZItpZ(BQm*5~u5x^TR3BiCZn{a|Sd^ZS|S3iwYNOn3Sv+BW98{&P} z2DQ5JKpO!XQpH2+6b61C+P#A-6@d?3>oArQxyXNPI@4O$_FQSG88wkm+_AzY9>(XE z%9)N9ZMt+F|EpvJ z*1X@xb0pmvePWL>inG;6nMKRzCq1!u-Rs>H-;ZcLix*oa2pb&$jn18yNR_(d5-jdD z4TqRZ?BR;@mJpn#s2aIJV@JcW4;M-O$-O{L-`cAXrjVA_3&cwu5jSO6Etmw)#1nG6 zCy`TMpf*9E_73CNG7C$XFz2qvX^$K)uM9yr>d|L)N=-{kXaeX{nD(Fu5y$6mJJr%L zeHLN9K?_E>yhMOhRMw-~V9z)r(ATEt`V&f!or^-{(R?Q!Ig#1(m!iB8diss>Y|s?QDB&c+>C)ZjrG_(& z@){ll5W<2H9(KYeZ0B1E^foLt5#F8qIb>drWu`OrfYm-1(4wr2^9Cvts^~y+kew(} zjQ*jb45<4-j=MXU>le<7kRc?#1m08_i*D~eEE;kgAMH0vlaU$o`8|}RMe@$F^-#5E z#cxl@3Eem3vx2I*z0X%L9BG_yqarwg%SQ~e?8KNH9=3+l!e%?X4)_#H-y%#2GVdZz zxytiKoYXQER4+KRcD>qlIcE_|@nA+Gw0?qlQdRb+DK@LA?M_$1%ltvpC^Ee06@-I# zy{34@L{-s5o~PVHAY^9(Utb}oXl!_yN?oY~qc!ZpZtwBN$ah6^rdhaQu=R%KJ*RQr zAQZT<3$G}GsF)XLomnZDA)u;l(I4j2DW7U@7s)VEGbxFQjyW8`7>nq4)6aVRmOt*pW2cLj!e(x@gp7@Z=#~-nvvm}!^v56Nzu57$32sgutg${XJVLi6 z9hvwP-=Q5w=Ea{~Fj7S}&a|!{V0|B)tAXYsAcnX|kdVWCO+v(%Ow(YUN6yeBvZufQ zoa#^vp4X|vf_YI~e_z!=?dtP-h9;2IW77Epd6sOP!eI8B1Zj^A-5^V-|Mls^kBwtU z|4no@YA7XgDA%)7yo%#wQ{7afFokz?@bd6Vns}y!a*RY}U05MIZNPYAS21l zY3{aHJ34Eew7h)+EAkO{!Z;&q_;bY~_nHS$5TI>oQ`Qktx+~T5><<$p-`JHXC9By3 zAzwi`_M3#AQVhdZ;wcLdLm0CWcf~XgleHBB^5TFXmHBx3{QDibvf^XNw{M~K9FRaO z8uw`i4gE!UHWkxA$_2pz#DBKly9)fjpT|=HC(?@O|Dm9=;$++Muy|ry^(u7(p^o{L6i{Uj0D)@MD6*JqHaud0# zvFoDSG`{b?C=v&`zX+qvLca`-Dv(=-u@k{{Yeic1ZZ)JT_@?s1p-RIc`zTO`1})eJ z(vY;1ihDJbXy<7^4)OMqu(;}K3@LIkP=?9?H|3Gw1m-!4QN%h}2^+|(87IJ;NZ;H@N>NwZp1?px*`k4D0=EheSzQ(BQViaWtYQ#dI7NAtr%M_?L{eMjUpeBr0^B<*fdZ zX?y9k-80cfDu`hvs4feezkyeD9|HQ zo`LlN^Lm;yoJAZHDpUX4CIPDb@B_L*oVX`%NqZ97g`y0M!h1DIRNLxp;`B}_(t`5* z?QjHqb=^G91MFJ?lRS&|KcS|)x#L|_#^X4BqvFqm4QqoH%gf-QeA|y_Q6Q8(Fk1I) zaFL@U?qTECv^x%%wCzggCYY~74`pv~V38`HsHN*dh|GmHVj5j}n~E9oJBf%>88q4vM{2i&Ha3yXjf; zZh~4?kn!|WM{DneGlUX(BA0gpe?<=b>7&%ftL=AGqH*73WSWl*%YDHW7@ab9q^bI; z9dr0C;fJVFW#+=nL~qZrbVXLy(9OOwO%4SlPq5ij2ofm$Bbis&dY=z!u3GDk*>c5A zZ>+xH?r1#alxcsiPKadx>Is6`{>OLHK{Qz>vQX7-cB`it2JQl-pH&AhohNt@#MDYd@p_WiYlV(4(t&VL%MewAOT%?1 z1v)1J@f=;lA<&a9WE-iu>tVDPF>fU@9M?7$shBnah*}kS?f&kx4C>l%s?kM&h7j7< zvSh|*#r0vB2n@1|)CM;8Xd~%1=|Wc*OcmJINjr8+N{Kv6?sFPN{+N?*F=MoOVMPYn z3=}7@&H90b>8dL88r*l11Pa{ph5@z-T*|lTe~huGod+vQY)oP@Fm%`+_95j@dQnR9 zqd*?8R=Kn$y~CMe1Vaa}S_NnbTHhT=6;~aMc7Uqd+*oD_s#rXj9gx#aPrMH8CX4A5 zlV_^d<%)cu-Ar5G2!#}fn0m5bP7<9g5VcgLbsFf{r`{qLV4dHJz(-d=vUdYG{S$U4 zb&M7BY7`GDHOsX*l#(h3jnKOqRV5fe1Z_p7Ua^Mt{EPmC3OUt?z~4`DmljF)kc9&F z5?CACEm*l;twyEryaZT&cg+5zmM>h8E;A#6(<0sB9!(7I(I?3$4hdfh_!%^N*UqI;8M5X3cerm8IZx#{#}iqS0cq zn8>32Z%=6$Ka5D8Cm55fZ=Qsy<;NnV2kq2Vx`j``77*iZui6Zz(XS}l zD&80kGf(X#3Y2(AiZ2A|xa}(fR0GQ}=PFSx&QDE=7lD1=%u{1sHj6Gd=piS(w6Q>+>*_027Bv?@!Wqj9EjIoyLSC48_S2nl^4nk_SyJ z(0xy_&LX*GE7!4p+^E{tMp|v!P`UucESh1Nivc`z>Qw<|R3wZ+6-#6oskSzU$ z(4+MU8??g(UJ(Z%n$R-}S2?^u^nm1CD*oea`9y(&)DS-lQRP5oC5&|KABzHaq$u{5 zA_02%FG>cZWyYl%oe8_NxnSl^22XJ|3ka2uJYE#LQ+MhFwv_l}&B^ne%H2#L09$ej=TtaS{h)o{3;tE=kNyVa zB03nZoTO#On0AqKJ?1(WRsDPEcFbH;#lTcgL4UDNif1FT_&6D;Wn9TnSmosqO}SMA z1>~rHqIek_!|Yasc?Waz)VrkJvWPKWoc>ZeK2ZY_Wr_HRac8q?>`XLbu{CzX9aZP`zs$-$zV6x~HD>DS`J@12ft_VlU@7^L zrMcwTbmfI=+uuKJv1s1iWG@YMlz$O0qkJ2(=W?VIPG{QJeX2=ZS0Q#Mbvr-*{Pzo4 zCGSP9&Vcw}t83g_x$lpgsO_#kbXg>x*zXRqPPSnwWRl7*y7lUmN#kWG1Zerh6HuwD z-%OQ$T?@n>c0Ju)RjCH?-s7EJh7=VyuNuj?Sf$W(QlHl^x^2l?sWm@po;^(0&lRC4 z-lU0N4|s>|ZO{XEx(r$s!4BwyEt|i36HU3vwQZcXd3a{D+#eo_)!IX?cL#2vFVzT5 zIStF7RjDKOt3L8%s`SsD(I>4BMJSw@6j66tI~3XG;58hM?Xrg1!}u-)*Lr>|H`V`? z)|8-jy#rXx=v-b7d$>vLSq|Cxyhj~lvwN+|RKjwrf-pNfR)q z4LhHNZ>UZ$4o3L?fgP_$rXMRhchB}xAop>x5UCJfA{AY`pis~Wr&Mf6Qd^v`2+*f< zUhfYXqUBA{9=PgT3!idfacE8fU<|?lAWUGYAg%YGeYlV5Wj8^Zxqs0j@kI@FKCY_W&ZS<+V*VEW`=rEiW zW}ztxTL`10UNuiD*X$N90go$$_q9gQMMHJ^(R$>VqmE5a7jV$Zg=u3YGGcBghNTtr zO$iJauJ0ZM)#_dUz%8fmpsR4^Q+lt&XsJ&}V!&{PTvAkCBI8`Nyh(s>iGb+yc5NDt zR|$vQAkL|>Sg~{cLke;*P=EMQDWpp{wf*LT9{wD*2-*km*^xUboD^Lgc(G-9bER(y z6KGgo-|<9VNaQUYi2XCFs|%4fm>BI%5+;UR=`aBC>R%u3I)dPOQ82igoVNZ)haGbZ zHPVSzUP)0TpQZ3XMrzmK$9mK#tj(#Rw`MaMY)eET2T}<|>F#`6p~|{Sg@K|uYXcMA z)K5O*&U~G+E(#V=lXyh6Vd4hr4r7Hivo6Ol)mwqO{$b=EGSUcYUN&w+oHX>)h(lhA zc1d!p&?}r5T9aC`B3ms6GOJZCTN1J++qE$~bz04c+VaSZ6Ix{l!;7X$Yp;X6!qoP* zmbCLg7mX08f(b(ej&d}}Mf8jX&9IEM5w*=#)Qe4(dJv_-N%*~VS@f7*U64PDj-e$5 z9@8(NtTsYqELL;dAOQt(rf}y3@-7j-Vn$@sSv>Tf+&gAmjG>>-+wsr}buuS;9zw0C zS7(8IN~XeRdo;Jm>epZ3<)rE<(27)Dn+l!U?Ul4u_!@8D+SGnG72rU}i*T7cCFpSV z!ed3h(Du>L(bneHfsC~eMzr;UwS4yvA~cB{o=pyGB;fTI1=VJI`wECuX^4PsGzHX8BJ`e=LtLCSzddy` z@Hm{ceV8}*yB_fNpWI2kH2f7&)$kf);__FW#b0Bz>ZA(VzbwVZzIUP_eRp#zYUW8^ zXwuI^=mz)Sm$BPwc57;Zg$V&ZH+UKW8CbpX)|n2B7Yu1aU?r4heQbINRIJhRNod%! zc^6I_nD`Dte_&=CBIxLNRtaZz2<$j)SlWvb7252q=hLz7Otp%^%LyTBYU? zP3wt^ojCBf=ueyz15mSjh?Hzl^RQnkVM$beB>zsF#Y5vZAz_P--jWrNblB%}wpX~S z;GjP+hiknu#&sd7Kb8)wrH$phc|Y<$Mp-FPSx_Xi*L`>eb_gWk3F?nt~#6m z_-6NBRqDqy&$ThL)Z?hzPJQc@x6b&HnnoT}xQ1PXL6m%e(usV= zME12+_25rN@fX&*`fudtznY1G?-jCWq2O3*8%3r|qRcgFjs^Yc@>3=NAA3ONKes^P5u8qJsJz_)DK-+y{`jB< zx%p{MDF}L(lu>*7=-~xxv4wImv-g)G`uh=HkRt;||&ms(aU#VOaiIZ8ptHoehi zXX*}USFIIAwO9J+z|$e zqBi3R1T2?>9yHnw?r9U1O(rNGN$(_2L0&$4Gu9<~q(K{w31mgszR00NHP|Q;r$Kg( z1M_dZ(f;^T8WCw{^?w0dK%~E0O4AI_Z|d%xbsWbj?|HXSZ{(@$kiY9~O7Nuu$F4%| zA_Z(OAa*ID#K6Osy}#}~e|xZKGm$EX<8!>}zFwhdeY?JN8QBtx8(X~UGD^;DD_%M6 zmaf8PFq13w=P-| zJi>&3(vBBdlW%lm_;HGx1y5bL(Kuy0##4@mh3hx0*Bhse-}mWJX{c7AXW>@lRZ>OJ zH;}_Bg&}`AxgT3h#$`!q`MuwR2U?e9t^gHZx3Bi}Rm*a5imR7Tq1Jn2yA21=Qyd-1 z?bf+dZAW4T2VJjm{o3!DQ(8m330aY_x&mpfe2}z?SIgU;!Z)C^iUXlVP$ljubae~U z_;OtOqFub%vR|g-HBoR|D)N3BPx~=>7^r}-!BHG*Mtg7+U{vIr@8BY-qUVYZ!9Bt} zIfFQll40f}*CNv^kgq0J#`JF(t*1z$de)z%DQB^HsB+z*|H@{^dT|CXw&=xNYC|PE zM*@7`Hg^dWi4gY-C}oq}3Eu{s)w@BMDSmPgOK^*u$m~Oies!xZvuSN!^9D zfv`5w8^)&LcNJbq_Sw;d7;|$3q}r*W7|*CmouTF;B3r3=G|8`xuk(tWY_oLWe48i3 zrBm%`(03ms;iB+vF{eZUz+ZYT?X=NQvu58gavcZTC*5Xn((P6jRu_`;w7E=quR9Pr zv*hN8_F>v$x_5}*@)od&w-*pe=V1q1RJqCH?v@8m72JVKq%s)$C>_iIwebfw!QC}i zw{+wV{&w)g>%INI1b^Lo6CA$$^TGb{;j5R>#GH>+QV;spyNb^yQU6_Uig$?9xYrA} z9ydaU-)J-l%@5aud83JNA7eN9jk(F;!m!^hfQsX|Uz>>?A?)JNPf{fObbS1}_u}CA zr&mvp@E*MWZ5N6%+N3D$AyD#T@XvMtWr>+rcRtE5DOJ*1u%2DQK08=XqRC`^ zc-3Er^?#mRtivkE;K;EI%5n(azPo6c0u`(dXMF()y@|8@)kJn5Z<}*rI)#rwd-Gs6 zO}sds2dHMP0EbL!mhGp5xS}o$Bag>9ngLgUV6W9_#n+_RSIee7Mc$Ril?Bct;)Vug ze?^S|iEbpy+iHTTjXPg*0tdNsx4gx24acRHg}s2lN^LtpEQc@(q;9@A4xY*2wFF5% zslyy0KjBFvi36sl-c@m&dn|jT)0gRV6b<(oLEIFlq?dAoWN;`&$*lpqq9RH8ORe1{=por%%{uxurgK!v=8LEC-e!JO~$cH>6UyyQ@O2ar_|<8;#Zgc8x}7 z>0pfunhG?H&=6`%4wQD}?~n7A@8a8;77ppqXq19*s>txlrp&~+_F-DhL{LUE)Z}#F zfNN;}+G7+)y{#TQ9AON`xSzH!Uh!L43X1Nw%j9507iz-;Xl#0Y!0cZL{2(QlQcN%sT}!;;R+J z2$C2|a*hZTVQn@Y)*3~)U*EZSG6N})1Y?h&v;pl?#1A5z7SLdjI~@8wHc2r||Ep`TCljLs*q#bwDh6m$W>F$)Q$pdEKDdovmUp z7LA5Elh1(hl?lnn=e7@(P2OdqafVbQC~L#uv>=Q1VVn(Mxr(HUTP<#Xf~%TdN4!WJz872<`4LqWOip%kp-`AWHP-GN+kV)jr zur|fYA|}jo{t=x{+D6QFKZJaGDJM07m%;bD!PW*{h{=oZg6)kB*$80gQrxU1L?c`c z4ke>>+!m1ay*^t16gNbqsAiCZJi9&_MhX0Wxc;!NK{M&X+*5)Ror4v~5?Cev!6xfn zbJ-P0*%u`4yi7TO4?XbUik&^-k6j8m1`N94X>|f;cx-Gk<3Bj_)s6lw$uDoxEVnj_ zrx$VPlPen1tCBFKV4|?&$WhqJMvcyoU>@!rFZ{z4e zg{gK}LL(zkwP-}KSmq9O%1%`~I+8ulA=Rh^%;y4^@V>oM!mCEW8Juy#b7UNsWFhXV zSyid4X*3D#&@yOMEf`P%J=`3=!rt{!K7rC39r*Jd)m3o@gXGa8vv1&+lcY;wF$5eu zdiK2YaSK`Bbtt`VQq_hEhEl@j=Ej|`V~cVsmhm^%Dt^Pkg3#=D8q+OR6sXWbI{btp z2-zHptJUbBB=k_QXF1iODX6^9R0>*(Q&a_ldQpbJeppoiQXMT@x>{V5ixwM*I{A=N zQeiKf(wJ|BxmzlSCE_N8lfhc@34;;*Yi9BLS$$HeHRQ^Y&#!K0wiuoWW5 zMvr=pm)ON3EZaAX%u!e=n|HcWg#6!52Fo_Fo9sC^Tee`=RMZSAbXOw_;deA(wp zP0yzds`RM*BRHtDSzs^rbs``lHmaM7dT2I+k=fV=Jbt3o;sUeOxfLh^beYP1+H5-!~yh<(mGRyO9gts$_llp{0#@C@)$a~ zP*my`m2Fkp5h=a2fr3h-lx~*t4NKOj`$i|E&TR^#)=n-B;kt2hVKN5bt&V1)jOW+@ ziZuphMWI2nQS(~>9X%5*R=XmHp~n9{f`!tpdqF%{41@X>oWP%Msk(~|8nQ+OX*4)a z>U$fW-D`~Y1z+vY&>-r8VPX!CUb*TfE03&4=i~!Z&=kG50qI|yQ<~Cq30tIT1B~sW zWT9B4mC;sdn^ZUaDVR{8@d;l-u z@KRS-OYD#HT8vysnO3LGtKO!*qS6byte&$ux0v-WV>GU0Jr>0BlR> z3IwZu3vl&F;Q3+BA%I061v2PhNXZuP*f;?q3gY*8V5boEDxS8CHDe^=_n%a~U9stu zguu$+_M{%20cI%-0{)1}B7vk!{E?;ocX3|tYG!PV9SA%wgL_UxC-l^H>>?u8bKJW} z=9)c4Ipk&@kCL2Wkx~J=bWbTWF~aDWuCT(RhMq@4KtIA59D#xaf{kwNjRjp@ETt21 zCs2~~z64gLZb3UHT%}Dj_wT8t!G;9bee56)Lx5uVLjI+{sBZ12vvE#}81;oOW8wkA zjkN@TJ=n{0z%S;~Q8Ax^r{g@s*zO^F_jaAZ0?(?e&vnlr5vSbBn>b>NT~&rmnv2wP zkEN~QIT|`Z17^r$4nO|JoJ}0-7kv!6cMq$#dU9QsQYjXpNg<-wp#<~9_xTV$vQ3+=cgl^p9y;BwbF4$lg_exE;ueZx`elWCS43g(HMZ~?U*==|bYD8^{I z#4q$pFoCXki5`52`?EY&X1^cu0yzbt#13U;9Jkq6+OMU1t zmAW4Vgv9`zFC}1H{zP`g69v25HOp8w1uK(+p6~KTtUYD*&TL?IxWZJUnY+@TO%V+m z`$(hrTp%r};|{hN_!))angaSQ$w?@Z^1;&u(-78x5#47K-pTY9c>kU>?d~LoS7{|U z*GtCkR>(84j?VgdG(MXRgM@EDX)S|1$SlF^Z})VAz-VQw^6hzrMR_nrt$^90%p4*4 z9T%5sFq*-C&PY*!*C`+Hsxirj*Q~wstd~DP$%ajFNv2B47-^B%LXgVYd>OsRh5}6D zlw%wd=quM8UblpSmi8*&7N!`e`?jS+a_(w&s&EKRg@h^S-7ECfy-Ls;{R%5OedWH< z62KAjnEL92#K$Go26WQT5m{#A?3Q`C0Aq> z%Q&#Rbysiow&?v;Yo|@>r0owMf>5auQ~o8{n2R2CVC z3a_RPBrc-(dIc3Zz%$Zx&|=O#R3NQ88@Z@&sc*6?>7wW%=j=FqqSI$8GA<*7N_00S zQgm)X&{7;tE4JCR!uR#NU}s}PGa;8e_J9-;MC;K{uiid?N>TIhf^IyZ*gjK0Ma=bJ zUi;U5w73{*jFZS6Cat*D3~C9xW5+f7Gy2L;vPMfd)1yZ|q5S&-3hXnbW>{=Visk5( zqK`%9BD($}`k>p+C{9caRMes{arbB^@E|~ulGAHV=x7>EJfG|K@sLTreR7yYI(Rom zKSguo3{L*v|MUOqHn|477HJwDB^Q@D)dEg?$-=)-FPx%gW2&!~Nx8qRuVqDVd=0x+ zJc5Hbh~t6TX)4yUUeMT)9FBG|Uzk#SQTPF?4TdZ55?E72+ZdN#OJTH<5DwBtaZSEG zIu2gGIu80E7hJ@iqrT7(ISEX3aLBP)$qxEy@kZ39+5mYSb)2WHB(BMOwGsMO1Fk1T zAI2go2!|@d!`RjrG=u`ZMRx=8RH7XL#`hF$;-g@aW?6z#khN>79#7*TS!hs5Sp(O5 z7KN`QJ_&zJ#j{U%=0Xjmku~|?AHLPoSfhIvZW}dV|#2IXjh|pMHFgphkKQWNn3Q0FfdvSk)6v( z!X54O3U9Nu1bKyCHR=arrHBdL2j<5fod=y9=!k^=J8*coujkIeK&SY=B-U!-YVV9x zkGGbjNUv5t!TL^GTs9O7B{b$9&d?2z8du9%ZU}GHmve;oljdZrbjhw__3TKe@=Kor zf4LTw#V7SHi}RNP&F-7DP~AmSPnRwClU132iQ~!M5W93Y{XHr`wfh~9IcUDk1XR!Hmc*EQ7h%em;0j zDyL?mZ7F=Aon~Nn6U8;YiEU9_*s!R|HPnE1^J*4HNj4%IdRr2cs&%`C`}+KdhsA|= zQugATmu4MrB5ye7c+y&7zFoy{1>yL+SyoQzBzpATy2LA7xPSFY7w%5zjYQZeIctE3 zd;upqWF=>*7&}TrQ%R6|ru^|JPAgtHp}}*+6o+wrcs3h4c*g;mvYPkmL?Tzx?3BLX zrka=aQ>@)mm+IC#bO|9Z2=Y+0K6JFhIfo7+>p=WrJ`9pfRNnH-d}5ga7u?wQVW7VZ z%%{uQC>rD4XT`1m*Oq1VvDvvWoP3`+HV+TulXFBLzANXDNwBMD?~;j&uNHsfGpBlo z#q^!1G>2JQQ@QAghC%I*;~HNC;2N;v#8D*3OVyJaUnmpPMQ(2A!5-8oy7{8Afot zAW1FDqmjY}Un<4#QDQPxj^JEE7VEGM**;ZU`l*Nt)O(nw*oj)eQSmr#Ml?wRlPG50 z@zNcV8Vq2E8ji6A$B-VVOot(p9TFX#6FfB+3I|*i{rp4v_1$;D;|9hyfd{lC(&by| zc!!#hy*y0B%86?HN=^!N2Ta*-kXW|2&M>M2NBJ(;9+`y!ozG5Q;O%I1mWABn9}C}Q z8}F9Geo^*AAQX%vu5F_)5>&#T>Rz7~O`sPeU)%Z{^v}+Q6#U1=zO~R@>?5jGAz?Yj zsaKZy;EDDMd_ZN?s%~gwK5b(t_xA&4DGCsX=fKgD^Yc?fjJgW0YpC)_5v&I8nk+;dM?V?*hvQgWRh}5 zC=?{g((r$&&&+*Y1S3ubE+Y@+L&M6%th1h>j!QwaI$M&)B)Re+#NgDhtyANy%6p>5qe`v2(J72hezlB+ zba)c2{cCUSfBv!CK>KR5!K2L76dPk_T!4eCm<|my)cvEB8)y9pL;C&^XM2q5@H+AX zTsZ2EpW?_-zbu1OYJ^4BKmM`aFqx*|wX(6KI*%T8te_$q1=f5Sw4CryZKFzaX0m_n znpx9zTr1b9Sh_OZVDnvLEh=3$b=l4cR|bVkXz2JRgsgFTh1kNI0#@UX()YX`6zEe? z{wGWyL$XXuWZiHpry3$rN`}|WaVVJ>H!V|EdbPIZh5-pYXw?R*nzrKc`!#)yC4)oa z4Vf{6q?h+w?Dp=Wd=I;1;XvHXG%dm=`fRMY8U}bn4x~WHqZR(GMecU;LWV{l#GTD) zM3xAH)~uP1dh)xYKU>0-D_&VV-IShXF>SZ@IY_??t%8IeJg<7UXq9%`!LCls8_C_5 z5`$S10v?g0`$~3y5$);-M*vK_r&#Yo0@f&+0?XcFcGm+!LZ-G?mI%+T4F2k_<}4Mp_G?(R=43A>1di zT2*YBRW@E&QMr{g&;WGK)4>z_3kDi*&|=KP^^>2oX7>?AVOQzektpz^+LW|pR@k`U zv$J85s6aJgmugTXuVg%nN$65$FBGPcd&OMe?s1?h8#e#*Lvo&JJ$zzE+%T0?w8i?G zG+t_naU6+LZ?1C;h|PIi3Dimc=lIG*(1*;en%4h!2~Z` zx)zvW8R@w+Z@P@hn zPP}DX;u7C+GUQO#3mTZOeIR~_?@H!!GZB?2b%rm}b6t{d&ait}JaT@^&Bs0M^8QoO6G zyMdlwm{2ZmT?!~~GaLQJ1I@;Ko$DfB44oF91Q_20UOR8woNN^*q|~UHGJQc@rUtH6 zp3iUZ+)1_9i>{)C#dz)RMsdW{L(3F_HDg_Fsh9>meWGgyubY_DgQMXU+!Aqz313rU z#@Eo8gcWEsLdQPNcDc7t1Sawd8>s;Ywibx_=f?C=|1k1ls5{2d6eS&b$0_VY`6+=B zulTrF$>YYR`^$AcrMo9JT2Zy`Z`EaLp5yozLGoJ)LkYBR#Sy@_I{6Du_3QGy`upbr zQRr)-8bk9b`41u!*LkWMY=rcHX16@ra7XCZ&j~nL#$jXrjUQJ zV9-)KLP?J@w+^GTc!<%VK$surZQFx&oQFlc(Tx*Ii(kUQQ({o&C!5`l+L!USK@2AS zz0TSJM*B`D^aEa+X*WNw&ClHYyy)1=_<}l&SZW9F}Ep|F68PR7mP zeb=TkJIaf@VA4s^ul8I`4z34`wZ_JewI4N&;Ql$B#?b)I{&aPPiIi$qdsmkU$kt(R zHNHWOVwnGCz}f2YJav7NPMBD>V9Ba^fmO<{pQy=$H#MBrTDKt z1X_*#j<*ljEPn#`pun>y_?wq@w_G8+N{D??cYG`Y|IwYoMw|X@w!K9NE#w2#IRliw z>r?~UsfN&N(OP`;NG+z1ENZnG0ZlS9ZOa*BzMzfAtF&=V{l(=fi0XFqQL`HK*VUjo z&~Gcnvtl|48=YPY7r#6#hAsDM)xhacOk}}On*o!ET>F2|Ih68~+%g1UV&ciA75^3G z!qtykjjAcv*rHSV;;y?JfUn=C#ck@)gIxNt*+rvfS|DG_^LOyP-Cf=>o<==|3#jfU z{rigI7z^z0h?%e66Jq_#SHbfBe4Tg|rd1O5@|#r2+G6{MA|9(3xguo1Mj7-fS;}#4HI}AtnRcZZ?CRZewx# zYFgwf)+_}@!QqMkTG3z-F6P`6oF*9$KmyE1?IHZ{eKO5w(NO(Grwmy6OM#3jTrEw- z(y}l!l;kkMkg>IW35R)h9lW^Sdwp1234of~wnNxUYqB>Dw7Suv|6AW!p*bX(Hm{kb zWhW`x(GhVz3TkWkSX)?W{y8U;dV~MD`81mDfAWNW;`lj})K0Me@EW}UAFdnDg?3#O zqBm@Gmn_w-rAw7h+>3id{Cp5khUqn3X6laM#pv^7{4QHI8jM*mhM5c$ly(8=stDNz zgpg>32-#US{O!fVrwsrZ^fbIV@of!!{x0mK}d~b+EEA zvEIJ10%ke*<>QTwhQcy+r0w>i84$p>4gE8reW$$=&@BMUzaOqwfGmrx^OCl#q^&54 zAWzwY=eHF?TsdRwc5+6vRL+R*O3tu1Z5ZGVY}$`M`=(7t><11jX!wb4v%B(2*xA@A zu7uh?2iimzv-5N|9@K6}`rF-4lZ{s7>!`YPk@BgGK3a*x8AiPfJBsckXXYm`VK1H^ ze?ufH*c{%&mr*QVAXn*`W;p~5V_2w@JZ+dUv9QI!C9sh)< zVJEBJ=z0zRfE*?#*IEHUlD#Ht2Pa3D{WZ$6G;Pu4{PhS=1Mz~7M?Q6aZ!8qmj^Bbn=fpqjiT*3inZ$`7h{%8cy~w4Cs6A)BjUk>#?LV{^*5qkFb@_>8iEoJO=H2Tm*TRccv z?)5+6f@-%7gRJ|kKR#M*we5D%phWvJu|Rpp#ocM!{C!Out9s=Ud3Wh;vh%%Va&%(B zj9%7)C$_)e*)N#dNnLGV*{MujI)feKp|( zpO~(;-7YC~uw%?VMTshCt!>8`3+G9kg&bIhlX_-U)MFG&9}Dgr0mr&!O%ItuP$~4~ zuwJ*~@oWV67H2!}d$f-rJ3;$9hy9M7b>I4rd?4D=z;!h8&}!|v831BVLuwR3uLJwf?x_O|#tb=4?ma3TSL|L?jeYG2dBR<#5O6 z89lz0CzN#BI;T6iU7+08*4f?fD|YnPgEv2Xo+j`e$?q0SmSt_I@Wz1)&n3u8o-M-G zsW$7cUcNc_A8!vdOp~LKJ{`S&_3}stt!-j$=FU7>q6(HIguqIN*TRLu!SR|1=Q^E{ zlLu~{iMXg4=k@G*oJSwTbe3BTtaF!790@#41T1|4yMgZS6kaJi0K z(MOSXC2&WiLMic>O6O~+QLkGyE=|1fldcVEGF6caeyS`2H0&>PzkEDF24M?r%#8Dd z?pk1Cv@Nm>L8N+$VSSNgAOsO1U4qPoeb&+OaQ}}66!uq-C8XmYEaMR4DL2)JM#D_& z3Q5;jNV~pL;&u02NEI+*p-rXqqI4&ZMt~LR&s9os#MlXzD;T+0ADq?T;-f-k&a(?h zRqKP8BSXWqFE$AKKsGNMwa#^qy-DZofG^ZYoa(+tFcP0#J!&xnt@QoNtowiX- zQ^5PD{FS4wUG3; zH0^KM#J{yN^>2B|Uofw@&sIxkRM!T+G?OQn-D03%vkNZdFU&v+6_#<63f+}=wp>+j zd8+g(^sj-UE^qN#+;SGpH44YJh=%Wod*FpMh55DDc#)`_anD_F3(LyPP?Fq#c9#@oB@rjo?cR`Vx%(BA z>l56U zrYSh0c?COASLt@HFHdjg_DpI?#cf$um9={cH*$;3rioacS<6oSG3~$B3PZV?n97RxY{*E}^@%j&CbGdmkQo#p&x z@y5|;5h>XzNT;P>dwtKgMnSpAc9O`4?I=5rb`xLQNv$mFNCs#ZkfGU=VT0GjFf@9{ zH!r;Psn9OiIN#hfbl??uEF_tZr}o+0W7lftmi5Z)aW7fC&>dek61p0}*`|@<PtljEQCR1q&eM0J1CmCigD|wQ%RKwzE~^Z!PT72nE~llB%K|3RTw~6bi=88ip$rtS6*lxQ)5ZUc|D3dc(m7B_g#n(X{;* z_=UuzK-7IFsP)}*TIm7Z?Kl@N%*vW40Q%9RZh7l$Qh%J?!#Wa&1Xwr%#Xzk-zT09r z)LJBn6=dWOCFA*dW3j@@gkiRnc%8EBEwC$0TCm7kKbll&zf1yT9p0ODTqdKCGT*6JjcSu3Lw@qiU!N}Ay?lmtLh{{<1KG5-cQy|=2w4DAE4`T;=qOkG;!zXt;MH_~IkCGY5oz@ex7JgQJ+I##qOk z29FF(``_u27_oox(ex8g{R4CqUlulP@$H@sF^NO~JZgU0xbfOZXDfJtd2us3 zaFZF)`r?HnBlth0>t*%p3X8?)`Kp$Qr3qAoyWnC=8K?Lx99pAjVoiMFIf*B&JbjBP z3HITz7M3Pd&Nng(T6LP~Oy{CXb%3zt(As9TR!R0`Gtx%zcAU*7XyzO%gB!Bt72Op~ z6}_{!>SZ#k4PCMyszk``;Kabm*r3qy>nNLO)?ZkiQu&l4=F6Nt2aQ(h3l-8tgbxad zZ|q%K298AvdT)dK!dKtH!rOl$ebsT*zR!-ro_I&{tzm1baRQ9dSG zU5l}!7{UWrUk?XpwX>EK_77H4*n9h_xRIGky-?DrkprM#e)wLcW6!8jusL@byNjgh zn4pQcX>0rMyH2}8^VYD)xvoGawyRz77SV5N$KJa=-EJuc(Y&fb+0mA@Shn1|L6e?% zTb@QPD*$^y&I^YGTY+IS45U2gOwe}E1gPnwP^a}8{ZV=`C0i4Dq6OroCP=7OqY%;e ztD^Ijw+kT;*($QwjeD3E17;R2Gc8jZiDr1=fIz#&!p$B+Fs4%v9Ek3sa+|U$7A-+5 z!u&fBEDT5z3n}GWed1kJ_6qVBF8lZR%PB+UKj~w_qTT=g%6DhJi(5R%uxYXDPPDax zI}v#fmBucH?qTix@fs6%tx@t;+WvI#SI8U5A)yF-=k6o#{iO}hz9{Xs9B{}fMez`vKVUe)M;6QHfloQeyg}Tqv^B^}IMmI9 zWKj4D>~xL?*1~HApIxo#j6*+?G4EF4I)?2)I26fD37@sE} z+VyofN3~ilV8Dy|B^l7&5)bEepw=ACAGdr}Ht7!OzGETa)v?-68l|L^-doY80Ou{O z%FluohO`~gYP!KiJtwv@xAZIC&bucW0MJlw5alJRzRsn4=9obQu&Tp{Afmz2wD@~8 zG!)X z$wfg`qZDLX7f#CHk^x7j_Xru1h_bN#J-+qcS||;L{u7hs!nvDE3P*dL4zDq~H-En; z9|tk4-+tu8Dng-d-mwZHClHUB|Kud*`U52jwxe~QT`RHsKPh#q?neJI84jR$BPhHu zfc^fY3JJAg8V%wBx-Mhkd&bk1J(!#H))7%d8LUnNDoqcmxqEZ`@4T@}+sU1@o0Qx2 zPZGsMgwI&g0Rb;@YKqkJ)!hqE|Lykt-)_(U?e_e;mmOJ;qCJ|Aj`xn=9`*KLJv|U7 z;q+ZQ*xJ~@1ANr)$CDgGA#QDKH942jSuz;JusQE+Y~ve1=rfE~hA(#T1umQ+Fa~__ zExr(=yT=R?${(tf#R&NE#wNa=jidKbGGrzRplwgyrNXVcLn_LMAZSwPw>7B1zmjob z+YSCp+YcY;t(wIyY?D2+9}ExI#(-GN0a65Mh3dKl>Dn@|Hab3(yOf~ zk4r(V;@Z`CvA#OiI3B=u0obf9meopaIQByI1N#5kd)LOcjqG6f`K(_7v)LtSQ=llz zH!6zi*h=Eov0dBgrj-;4A|VMe39tldS!-*5`+IJ4#ek$_C)xH*y0r*k?sMkMxgV>9 zRZroGa2+%gIfo)n1?vd!h^Knc!;FggUS)Jp>Kx1HW6MrTNp?Pb&J*xu2h-YtFASRyKB2B>-#VRtaLQ<%r)^0a>>wU21`Jy;I>nE3$tv>8O|YO979YdhjPV^(Qy=CpY!`a8oE;dRx3s&){Iy zMSglH^8Yz03qwWjx4#%qB^o+ENK_zZkNc(NSlGBu3Y;suSEO0H{wplA{ zqmeqkm?jh5-9%gIp+`_0J)2=Tno^swWci?&0&3$NuxxV?>M{;X=WSCd`@N_4d?FW@ zW&IRT7TC>HJ_S_>0jE|)^{)_YX(fxPFvaghP!cIL86}hX3k-VPYFosnmOtD6pY#Q7 zul(3WMvi{v5UkR?Iyf!eZ^yJ{<-pdTH4zkJIy~#WDO&^8ZO2*ygMlc`cZgOF2VijB ze(DI31-?NQQv!uSBqXqH2cBCoe~o#RYez#`3u{|^Q?zOtXlp%ha$G%=t$=BS*aBHF zgl+01=Tf7?32;649ph3>_{4hdHp7z%7*U($RBJ=cKzsTjCey6)Z-66Os(2eqNMwBl zUiw>&5l4MjiyNw1iYjm+xdurGh&TK&Bhd{a!$f031!?hb>VXlm*@)KZe*Kn=$cu1L zxT;%o9SU7wC^}qx#Omz+T_fsK<0Pyqv|TS``xw}%I6W)5tfVvuQ;Cn34h`s4{&KQb;rZDE`U96h(_nO<9Hy=^iL1A+8*ddVWKF@S8usv1Rw5dvN=!u7@qz59i`l)ptl&v|ILS zOL^3KPDi+ta8*caHeMu@yQ}-@BMyc+%5#T(X~Qn-Y6Wyug8%VYd@D48k6A7MAG@tO z51$))_qdi%?9=3uv%4#}{nWVpTw#XmnUz1zyEQCd>hNW-_hB|o1~X-FK>js9y?(~h z^yt|s1pz%z-pje-vx&yK#?Gaq+MZaYkv@yED4&rYqq z4vI6lq$|&G4M(}iz9w|{vqQobhq@yabOhp6IBf@Tm+SOruVGsmMo}&wly4}2l54}h z2GB@KhY3|izshDPcqvGx3)>^7-Ckt*YA<#`_O;B^b%E7t4Yd)nup-JR^xCt!5-*~w zkjd)9&yuwVHK4r)R*?^RtD7|tF^N!%BDf^W~$Xq+h9y|E&OrYu~U&$3ZABYmRQ z!y+w@B(?a zi0=0b*m8`-oF=5GJ)HwIq~f(t$Pr1Db4t)YDlSTL>!M&KKq7GSQ8`HmSuzUrk~e{r zm?n7%C}fO{HCqSpU)&~ysD~-x#n#K&|2sJ7!*DO| zwCQ)NMSoytKJEX4e_QRt_MP^@LA$;CY2oMA{+-*q(CQ~>?RLA}Tsw?^Ewa4T{M2j% ziacwYbN!0WW1=o{yj2jGrpbjI6bsiKdi$da&%^MP^L&Xo%LY9X@dL3mWp`auX#+-IGv9-oSl@cbz|3 z@>gG86R1OGcziqLmPsK}e)kt3K}-M5;g%kR`6KnJ%&ocQ~+~^X_)j zK$pV4e!bnr^@i55;Z4Kh{+Y5Shz2-088z_cL2249k?mS5rdH8P^Xs^EMk@d|_^-ayTuYYwk0f?*Dm%q9n-j}}mq24RF=|{J2so$m!O|`G*yelW< zdz@}d-Xb5?(%`onHRIdl%C`RtlCWHXrSdI33zDTA-q~$3JYBVwcv#=bNq%Wx=;e$# zE2LX68jP5uGgkPTP=`yeJ4j`I0)M!$-4pP5cmk+s`XMWkhQxhCPEMbXG#{$o?4uDn z7*`f;&EMCqEUgPueEI?+Y2z#%Pey21t#1l-FOi_3_C~U^qSaka)_=i!N)ysjqa#|@ zowj#*DPlEneL1r=q-l!<9!~kTwHU9U-V6^TVCG^dd^Pe)%xb4+V+k=4oW3&+^UfME zHJd_%xavg?jZu%6GzDkmx+HxuBBA|*?(V-FcF*i|gafttQn&dRiVPGZoTAmk<5_E? z4P>}Ld+&bR)fB7|q?=XPqrPdk_4(0MW*ohNvoa#`0GJUP{&6Qdna>m{T#k~GiR8~( zrN^r4)z{{?Um51X66GCBhe8qZe0Ydt%G4<(xUod`_B1Q3REyv6m;n#yqX{U+T#4K` zb47GN(giH^Jo7w6=}Bt}|Ez`E6l7T{`7EEQL}?g8G7hI*N5)~vy_w`(%PM4jl6NJ2yJx-OYk zExnHnd4`US8UFDCsyo^Jz$dIFSe-yH0Vz`xYe8K=RLTTTb0|vBwV&j3 zXk!Cwwomm~U}Y5%)M$@JYPqDj9xAn>NCa1~inJjT3HeY{ZPL6@BSuf)HYcV1=uFOx zV~eJ%M3Ad20|p#SM{weohL`}@1po)SzM+9PRuZ)aqRNvrQVwYC#gQjOBqR>*{>t6r zwwa1*e}RFqa*Jp(!s63(kY?|p!f`;sPnS2(8j4B?F{<&8AB?#S8a71{swu)XF-;Wv0NCYg&= zZMUyAQ^e+Vv!x#FuNFRStgz*3ME<6GCr6#K)~~$fs6(+194bZV(V?{!+6c5*hmg$L za(fnq@6rtlR{PE-w4E3)tE~RbVC*`pPNmemI8=r|>ktm})=$b>#tC#sTEq*BB{A#V z*&GSDl;w+TKRadiB}~^VT7EIvX0cRNq74}yO{ul^<2$!^cYe9m|LWsatG$14`01c~ zaB$d0@~wGr@Kvwbu8y391;pH94=jo}5s3<=EvpJ#Ifq%2FPa=P$tzBeSj?zJb)5Op z8+(R3Fu8*+iUh-xdOVvY1D1f0?G%|SYMZcvc|a!fDnq{|a_?xGI`3J;$I3R3tFk5K z#=xJ(@bB1tYnpbbnwpie=;EeK6f|oJ-={Mg<>@FnlN@nMTu*9C{H7=+e+o+95@G>^ z>(8CELTsMuqXe2Lo57hvcAuF2tZ8$1DBmgIr{B3B)>TD!Lnb^!+4 z%9WpsD-;)^LZ$g26-vrsM~bB6NSO(3s-#Dx5ws#2X}OX6!3d4WysKkr>RD#wz1Bh_ z@4XQkRVs+Y2>aD>-h!NjITH3xSy1#=@q4IAXXPDnWc8q=0Hy*;)#Iw`EIJ-FXBis{ zfmuMZj|(V*{k1wpHh@w90H~%BFKH7_e1L1z?@^#pOQBedD%R3A+b3KfH?LJC#Pc;f zeD+Ox&hU0|yVVVQLYAF~T=5dM@smirvV1b1)yuS2zyP1IZQRWY`{s$XWZ_t##g$ZX zzj{c3;mY-rcb4#igRf#|6pB^0s2;2}p~Rv^yG)D9eBxDU?_5<^tRfX$edRp8vdBAv zYbTzJ%vTY7D0nvPKCF<^D(h`Ty*^zQpFWw@R9H|c#t5(-u>t*J$-$Zml#U)Xmf(P2 ztSPa=(E5Z=I!U8CGpI;q35LjsDa=zU2BJndM8=~G@Nn`Jv}^M2nnH&KB8L?P4m@zJ z!xBLo)e!va@^y}`s#-@#-?mlS=&G8w=*STpHPjV=bd=aq~gRMRj7j+h(ijb>7}>E|OW8widKuH?daJ)JhFi7D7XTlyYxgU)$wu zd!3rNZO#svEZSOT>P~dF>$;-W#2}>Vx9U9QQC{Tha!$u6<-15(qK&E%6ludLw8j@ks7y1cp$;}Jma^H5jwD*GqIq#XxQxjVh6-|PSt+4b-To8H zPNqXLjV!0{<7_w_r4ox9|2IZEoP^j!Y>sCt(V52-5&Gghg{^CFxU7aaF`$)-u(AAs z%{dxM?R1M5ON-bAMYXCsvg_=~MkfkvN}tQnl`r6Kww&JWd?iqRr6^hG$?YAF=vP$4 zhFi0}?xZnjIY3vSRdLnlD;M&dgX-epzVUGJ7?=4~xf z><(K1@2`K2Ld(a@3@kxqSw4N$Zq`$9q(X$2qZ{u>3=bBc;E#JwACdp6bqJqh&Vs zu!I~{qiVNpOrfSnDsiu6hjD7vG)WZ~ci6F4!9I{KiEsCyc#P}!a8-$-_2|Yi*r=O0 zE9o!!OlxggGIgbR;_s|IinZ>Pocg&q(t-P8Vopt>Gb;Ldx&ywu@g*JA$>-+?5KDGO zY3k9=nBtX^SB`ujFE5#b6t!mCnpI>X&_B}2J-A=tPcl85vjKo6m4SNBD`wuMUDh(@ zwi=!w_Ji#}*sQGSc~ZW-$dxxauPmB?wA-#qV1I(j(-QvJ!B7;RNNX<3a*+sSR9P4P z(sp+pKR%uUmOs+d=tQqN(OH^va9QsJ;Wg8Gg>AIZ>{cwM+wE%R1;nF-_UzQqniZXo zFnnA()Ulm8=~#qm*;=}DPWmR=v280C8b_8uQ&7%|V77{Im2E3WpsZX+PY}Nvh{WNT>A@bE)l4Rn(Pe1M zaX3A!{vT4;ceW+ z(9g245gHBR>s___@TP(L(l~5WNOr0`V~lu-TMOH*vOijg&+ng%mSL~jPy-1Q{LN?R z&@HSo4$v^FS)L>hz($|{_WBWvbhe{P9Dl3$RzEt539Rqj(SZ6gSH-c(*}Iy(26lvIzK6z}7R1yy=nPJ%{v0H!MCuy5U>+#xMmB^Ux@ zj=%D%q10Fwd#P*7GZcm2S`#|L#G8}Jg+nGHhih3`v*Q%@j z*XW+YS+ZS$Lq%wWce*brt<@<*=T&vcuJAGoNAb}lXyfQ8Eq^4!6yxZsPPiE-xcgDB zHmD32BU|6vQkzohnYb_m)~+pkS2gKo7^yGsN1<0ER=FX(s5d6iOk=+h-BBZtoq#h9 z4B`nNrs?#sp@zfHND)+BXRSzuT&%^>m@oktQTn=>A#ZV; zvSV6bFd&HsMAc5b20{e_?P#vnscd-Nk5_(;Th`D5CQt6D12Ha0rbP`oEStR+?IrD6 zkHId8cpIiA0L}18?U1Zw&wRC7%@PD!&zO}N@R(CVGf+pFZ#yMIeYcIH-u_W`SiRVV z`Wi^G3*tl@p?kY#T8uxD@NtfuIuflxyS)hW1uW8*b~dPO(S;S6S`Dx^n7>96(`n5E zjB4!)d>DAG7IsHkcPthHYM|1mPc9p~c%n6%8Xipb?O_az5m4S79dM zCySPeS)YoyYdeHDVlOwKx0B&g;qVrXXM?GG4K&)JWKmv^J2jou?&vB_vdG!JlJt4{ z7$7Q7=4X9%WZ-wFHhHSIIoV+Pgi?MQhyUs%xQ@DPV$qD+!L$O`izU_2*Oa0l)L&Ii zy4lvsf%(Y@Q<_q&Jki8jxP^{2Ff}MBhoLt2x(YHXS!*()B^65=FI(?qy z@7jGELm9mW|4~m@)wHiFpI{N4rbvJ>QdJQkw3SwQ3Ebh>i}_GW=Rm8UqUn@=7P|?K z7s9Ho^Vw|D?{-H8(17PfIqT{e5Y7hhAnf&5jn-^H7%%He++fSy2Di7zl#rm>;nFQP z1$9Gp9jORIPDeMTZ2lPfB(wr6&%oqjb{8m2SnFl80#i2hYBxI8dbl~;S~WSETY^3& zqvA3hirlJ#Y62-ibpx3S9ixV^t?a{`7Or)d7)(}4y0PX`XLIY@nvM3Zv3`U+m#m!{ zsl+EcGP-rByKRryO}FRg+Vg{G9R(n{?n?Z4wTPk$jLXgC_Xn)(d@_Usz&TKF0G#fW z?8bsK`sY}AdzgRt24vXqUeJFS3{U$yHe#`RS8nBl`2kbYxMCd?JFOK z+!}VG^A1b*zA%QcF8gPv=7!c0_B#>$nPXt5jH1os7mT?E(+}U!Mh%q=ht7RwZA0zd zrPvm$tjn)pAjX;^n$q_uVXI&`4Q|6)?M6L+qkipbMPcjXl{FL0hF&2@ePJvey)fAv zI)gQ|{sM|Md^&ZQJLh1UC>o3U_ReypnT7q@o3wx+3&O@V;xTseP!7rA`Wd;{niky=AS4>_rH7l+?rVg4!oqv(VeFA7!t8 zl&t$9Dc@0|4EnS_ZvQS^Qly=@-R(qM3+CY>o1>&E^9yXw{uVTUnWdv4HgDe*!Wtef znAGONrKh|Nl$4`RSz_%GV=#;$gl^L9mDc<2f}!2*FWB!pcb2b&<{ovKt{D->COh8NuW*TC#I zlVRWN4&nf63s|7`N_hVbH3N;Iy?+X;3!5}ZP~bPCG(H6G$eHjD3Z8YjsOhi{LQ!I9 zQ&PL7bpYriS{G;H5-eD!tHncgm*S5Zh~N&=zt`VE!_TD}par%xzUd1@wNXmvv}z$^xgcR49=4T@*kEl-$xwSL{~c@?DhU6PGb(gBG6V`dg6 zjvk*BQ?}>=9QHa*$|B!6Xb|SY5ya!PER!?R_QUIiNDD18T2!mOkld(;2_3cH8h=an zfUv3B4=B-YY_E0+U^w?iWI=w7y(%yqo?|t zV6dggJ}}ld;;3R%#40YLwReqWSBM-73VOK+d%N=UCESKN`S%v=^1W40{ym^hdwBGF zcNd*~#pL)DOtj;@T506>7mWP=N}P^AjwO80qm}s{zv0j1g0yBvPR>F^_+a6tEki^8 z4W^Uet$KkuEB5eamzM+f3}TMBFEl=8+1e{X&cg-E_wbAIZ1)%K)T91&@X3>6JkDm6 z%EH1Qi_k~68@&K<+}zkO`FzPU>m(J5kUh8v>0`U;2h96PIT7bG$(oB4Te_%=lG1x{ z5X}?ig_jQF`ejrijxRwZ(4yEx!YW6kw}AEdr(Lwz+V$5okk24!08cMkpWb4UX7ffQ z4TG`HlXOZHO&q<(&kWZ7)%b_=a7QO!5LD49b98M`T|n0!o!k^AIKOklA*X0~Ha&%E zCf+1A4`I-5(H~mTR*Qi_)b5JNghzVcUXj3a;R74Cb4S-epzdu4ORq%GZZ0Bddv~vg zj4=TpB|uUHmm`T-NYxz;f>hAv&8VQ>)}mQ$Ev177RXS*M2_4jXa8p8PbN^`Y8;gT` z_r5Isqc-?P^iS{p%?TjY@e=w+k8d^7r?-e|?kymjj|SHlSTAIodk?O4;+__HdaJR* zJ-3ns<#S};LD|?11mW-wXqV^3+5ZiRI5o}_@>^7ICE@awqg=J+1;M4YuMmz?J0oX5 z;ON;qkQsRX%?vyLMkjj0zs9KiGfi3>8g@vTkb#>nSCH$ydaz* zsNi%?WU+)Dy0ax&hQgN2*?IzA?XFiH?PCqi{z%B*Y4_aGawW~9! z0m)jhd^{Xt09h4}Myo-PfPO}#S{94x5Xrt?$vd_&}CcIa#@_NuUCXKWP`gjNGs2?JIYTnVs3SPiOt9V~AED+vQu7Hkor zDhb$;A+gqAS!1KRQ+i#+`YD+OU00Oqqq-P14k^{P1*qy;uUqT|?FSelb#M$O;7Cj1 ztOjVc9Guqy4tZ!^$HJ9Ev-jN}{Vv4V?}@>y4$%9Z1h zuP7%<0SK+BRC1Pcp(&z13Ql#t`7uX&zd_8AKZ9%h8C>Jf;2M7h*Z4EI#-G78{tT}1 zXK;-_gKPXj!8OwNc(c|=z);~e1|t~h(=?sb6x_O2u#RiS-%uXC-zDh8a#>sc{?>04 zu)`8JVayIiJ^#4(_J@~G@v^3^W3ClFl?zPyyT&*QY8ID$)T|-LD6dJd4lmDARdAe6 z&!{efrFtiVHs>Yt5cqPAb%pei`MorrYipLPxE0!8OHGtJwcRRnCc169fdX;~Cqpb7Km6H&OL@rD{+fwG)a$p~JHWYaju7 zQWT>!0eWh8abbq5?NCe)Tg`RL@_eI9yrziw&xK@CqL8&AcRVjC#g#bf!#;5Rn8(1D zbk&{$I@h3Sq2-0wZgc`F*AUI?mI}lQS?U*9rF|>NRO801{7;OTtqM5)U-izi+JAB< zs&5)a^uczkcfOWSy3Kc@cNsZ_9VIdT>Zml#@QlBqRr?GSoFAFV~YRFcR<}Cr_L_(m`xFcd$H(fUzgi!-DYg9s?__;ftr&!< zHdN35&G0-y{A{lSQP}qM=|#<~_wd^u+8x$Sn48;iTf5HmR0B9GMg7Niztt&SEr>o~ zVIC&{fr6S9!)v&JYUrciFm6KK$d%~+W+PX%|A>*RLELQQmNL3Fv_>fM(C6SX-QMpJ zD5GxKG$(Y8Rg*e@2z)ZPajoG>oj+o@B6er>_$ni=MkYdQN7Kw7F$p!AYc0B}wEc&` zG|(^CglMR-=j2yXu2zqW2%7_XtBkVj-Jf+=g{3k6vINv$`Gv^ zN6&I5z45JyD-$mzvcu%GYeQAXW_a3ce`GJG*%`_+X-wr#)m+N#P1xwE-i-3vo6fJsx?AeZTisnGD5FV4vWj3dG_2;;}Z++ z32Z2y=-2lZPZs)$C!gmlZrcyil3dfL@Viue2km%@^J&Hc76fxeLM^heO+MR|Hu>#b zX#w0??o2)}phmLPj9TGG6-#5OkE3|n>{J7|gpjWif4btiaA_k9U7>WHz%$&mC8(W* zZ-E7H_fo(OC5>^^3PPMV%#$fo35ootR)Gw9WRmuGJ#p2Bp;*|)Pi20@!sZ+EeSii} zfaAji@ZM)sI2U=^5bus<-mA=9qR~@}Bu!5W%<_eL2l{?(dv2KY=lWtND>(tMb4yQ= zdm2Jjj7gZwoD~6E8(Yhq1AMsk#PXjHyw?Wc(9vUGarI)A;aLY@$$BkD0*j9b=0&{m zF**9DKPO+{tkj>Emb=Nj-lq3?)7v+4Q>h_G|5(5ekSHtpoe>#O^>_PU33AY)xX0}T zV?f*t95DpNe2UPxC_IEqgfH2Rt1lRaqb35@=Q#f?A?lT*Bn9R)6gmd+ye#HXGEF6! zr4y^;zu?n(@;>GCr1_joI@pg{HEfq(fe{D>TiZm7x*Mwb3OZi01A9Y?p{2`cnC z*p)=F;*j#ffORAqdM8RI8MErbn^2%D`iD3c6$b0>KUp}y1zK}kF&9>%`~R(|PhS!) z)R|^bX|6HS>bmthEt4^dTC8}l)A?_IM&KFsfVfkBIoEV26J4aXpNGeVvuHKuRK+)> z@03rKE6q|znxz<-O$V!vCN=K4n}^rue?6f@{hilt+=wAv#c_9`qx-5+4pxqzwT#u} zMZaZ6pHi&eTZY)ETmSo?zy2rbX#uy#5P)Vn&hk`=g#`JP@lAK=3k0q_vE>wZJJCIq zQ`|rNt-xaIi-5)IL0Rst5c=ZeW}z=k3@?%cYI7bFQNayuu$;kGB-ZB5LLn)8G#|Um zdk>v^pX~_S^<$J=B|GFtLMXRy0$YkTU@%Cx6RtvCZ~=!nM5SWN7%5Z7`j&)fP}V$E zv$r}ymWW&y3VEuw{UM}c&q3Yr%j5@+)LkmAQb*NO3rPF}!enFB+BHb)t%I(N^Fvn7 z06D#ZD{tcaKrH+3MiCHKVOb+q6q?b>%D|-RnSgBTia2hV!X!j?+Q(ebm*(E zRQ(s__cWa@TfLA0utijBF__Y!dzAGxC7?oE-$Zz6aaj*;7^&0YvL0Yeg5}{=nPs&J z3L%Vd63}#IdN+*OsMPjfQVV}AO}VW~P{;J98sKFzokbB7Ng%x1x&t-$^UpsM$N*ah zs0UMl7MO(V9I(&I3rRh$pi`~ru8raHmz~?oSkNG3ZTCP;%9DFN!d!DK{ zN@R+`(U4_V4N@b@kDpq;iXIb%9_q5Yrq6>(U`<};PRD#y$f3Rf@c*D3ai|%u==PdY z<4Sisw9+jq>tyaDQmUhx#ATxU^hq(fj1spr67FV(yuAQufV74!^}Z8%UDPzKrm#|z zP779gLi`G69Co&=c6DZLj-EVAbQp%yA;C)`Kowr_lE9@K?R~%ymjZ!f1_ z-{8kA2NEOW@$+&iaHYT8jF^xUm{5nvnA^}$O5JL{bbh1P!iEG{2yX_wgcK1#&!!W3 z^*QX3HNz(qQ9Amo{CHcuOLG~Me5wfr@erD_%Tdj`5DPtBI4c)7`@r1*Sn+N-LBX}u zPu$Ff7^-8!BvI)sj-r#C0yKGUha0UMFNU0`BGkle>|=riM163aHQ0@@WK>?}v*ZJY zpGU6z4H=|(jaj#iYScr@_r5q%UI9_Ain~#cHpPJY#q`G{PdI8usKUMb3QG&+qQpKm z#nm9P5@^X{G@qqEy?$O-SX~o9@B@m&l6B+0zY(|vYO!+YB5;q4`q!=?c_2t%xmb%hwq@&9xs*jp=8JP8upXDSS zWT(J~@q%Qf7M`^TH;LVzGwn7lR?QVR*q`yHH zS^Bu*i0HVrn(2oG$;s|~I%@7KF~MOQ<~vH*7!YNBYfdx?r6mQ@zR7~hrXpgs0@X&s zioS(D`jL)Dx4&`7v}?zD*JFv%6<%|}whTgd77pY1j3xX^^DLb;vDty51bFUm<`Y6o zs7A%p#Glt3S+4qq>K5nhsRA&EwmVsTh1aM#d|qQ6tDu=34CsfVco)qlkpt4>Y&aaH zzyYL+)HzQwyifK$)X|CNIlHqB4;8T^2;Ky3j8&vTdo3#GNI_T(fU%bVTczO)n3nVG zbS7O|C#Gy!4d?~Ip~h0jE)ZK04ei$^y5Sl#*EOS)q&b!0p}_IAd|hpDlJ)sUBa^sz z+>o0n&n&$B;y{jEl$QgAaQ34C1-YrErY1~a3*To$y!tZ$q>@f;$uOJ_eH)uKJ|t>| z_M0r|Yub}`%-X@#PfZ!Kx3Zom01-JzEKb%h=50eR+wGXPiFa;gvi^N=$igNh*Tt$Vc3*gLo zo~a08KB8+_$*n!2tRiMlq?EuW-Ijc2_~2#bcL3XjORd(eBOtKtw!7baQjkD+9r?%R z;WiRY&(j&P7bnx=qD(ozhWH{}t@#5K`OwclKL24ho2a?B%|u2;GTf7pF3ln*!!SyR z23K`{mNrev4^N9R6Jp{Ov?h8Nm|65}FM8O06g_$Q`i;7x)#sP_=u*8aqgOBAyp584 zNZ!*JU$dmAVUd=3b0(X}#xGheBa0fV7N5R+(R>S4n5iJ{BBjvy(MfmU%@vJi#>Le%I*V*uYEmjnBl{Zs4y(ZM9KKn4AhL{5!@`KiY9Q1$XHdfPw?&6a zV7FZjr=Ye?)|p27)|xRXaDkP;xgi$1Na3a!A|67kyF_Ck=CxH`Nz)b&euzOKik!8< zD6~Ntr7nXsG=4RSC;Mi_(cF-I&VU6=`w`L3gJOh9lF%fIQG97yqao<{=;YI!l+gx7 z;)3Ri`Pn&K22FSiD0hGq9k6#sa-&yQEvV%ey}=mDEH%$vgaLuqI{iqK2H#|gZ)3%M zcr{HY=yGRcdh1xKSLTLAHtz9g^xFMkBhYBqp_KGgf)$be?2}d5cA#6i`)>)ntJio9 zBS3~;@9?GZ0WOW*%5uF$MMuB#I@Gn6=^56=9+e4kf(ER66pf^edYhYf73`q|b8}-W zYMsM1SoXW!GXTN)2_{18j{lyVOtbP`mUc=0)y>KhM%3Nh=(Vlv3J4Ttv=)$1KfBbt z|GneYe@poX>f30(C?X+mnw7?|vT0BVfW8kEez=#u@;bEOPvoNR5xCk`kjR9(PYrf- zPwj0BW}l#M1q!U()~s7tgVUA4jclY8q1(dkqMy;yDF~K|8z0&Zi9+!lyfk+!RjU#Jw@5##-FCKsU z^7Y%jr_C=h$;ZQC^r4)d3Vg5W8w&0k_#f>IrC5QTna=Z^)6*krpTTq!AWjqykmm2R zX_2D{SyRbxMEp(;%Sie{D;H@KHyYajzAM7bOQ)TPZ|%WsJqJqWeHvGomp9Vkx7^=e z{@!NaS@lu?QmNxkw|dTUg(fac2E6@GiDS5}(M2HahU}5soYUEeBl6^fWKbb z{kaTY%79 z5X|+ey&c$9AEcp6g)3mLIiVh(*YWC9n83<8v3WVSdxvgWrEj}}>DYCktB^cI6op77 z4exdm4V$dl`!FHh19193?&*B(WaFLVy{715LTi|W6wuZQTo)ee|D0~y&Dd`G+xbkW z`2k>TjMqM&ps8I6y&?C~{Ix9dCh_`6S!Xj7A-Uy+(KuWp{Bt%Q5?DJ&myVXrhZk7H0nZdM@*4h3;+%-sQ? zH&t)?UJNu_fq1mpLu(DaZ6XbV3lr-}7~$Gs|1?=JXqz|T=Bm@+_bblE?aiHwwU+~9 z>f#V(vMc;~WP}!4S!z{`9aWje!bSc>lDoIKu#bIjRq%V2)v}l^Yd_H^#kQhWlRPda|W9r*MqwdNM3AbetNtTcT_;Mc|8$_HB9eL_@y&mA<@2|cQ6N*=e zIrK%I3ld%P5X89Y+DmNcQkLPE=X!W+Djfeev5Bpn>qVIovOLi;P z-Pn&X-<^oZx`<*zhh*C+o=w=(;tEY>7B4ov!cYg95$7fM+_N=kE}0sBzfl z9dF3I;Ytr*@#BbUC{|8kkfUYtSQ^6+RYMSHW&Yg-qJD>+mmwG%NNI6LB#8J5ZesNl z?qh8NNkkhR9n*-`I#Vm#40Ay>SzN*j&sxm`z>ytqaMRW(%Z-u@a|Xe)5smblaxh?I z+L8m-bWHWEET&nz?Gj5$@;<7smI1fY)0_y-&!N?LW<&^~Ufz1zb)JCb=@2V~o%Pki z8LgV7q35*4 zd5RRIBSuAm8FFu2wM53FU{xH@6NCA5iW2xy!6z2!gqD@jFfeALml~HDQdHd*{`dro zg`{4)o5eVwR-U}i&L{&Wik%;y;Wwkb0oDld5FFVT#SmK=76URl5`)t{wy1A4lcrUR z2M#k*OshoLQb;YK*|Ia=0LbW9*a3N3daUAm3f{FJ!9sLKq=#dVq(vV?Xx z3A;kuBx}YMwwvl(bKQ0idW)MjM-^d3Z<={+X|E0SL7?l^z*n~4)>XTO!nQSG7W1Hd zvy56sWLb6`fn_^_WA#qm&~kaZS8HD6Z|ZN?Ws7ceENrJ{Br9qLYwZeAw6*a?i6U4X zGOC#rqf0c|B!R`Vy{~&4aO2LW0G5|gK<6_A!e9s|9pjLe-EV=oyuTIyS~8J^7=W~E zkH3BLbnma&X0X#IFm|B&haWhX^EkoO zsI(i~x=kh_F<~?fiUMs!erl@pRqy}TBEo!GfaPgD66s4unVSeT2QEp zHyE@PolZG?DbW8z0C=I>pigx};5a{_3oB~ld92NyCXfFwkqRygtv4P5F(GdOKR#@z z%$l!Lh4e@86C7%4-&V^G)QnjQUE;w3!wZhNT9L zk23H(m_NB2ZOJG}ilZug6K#C>?mJ7SX~MF!+S^w8Djvp;{QdfC7|ti%FIzHe?7)*D zH;M|6f-qM_6utlb+>_#&3}Zp6lvNoVkE*&3I;`yby5@@cn&!aP?mMr8x7M6 zY|$r7-Yym?!8xE>%$WtgsLX>dT>G#9e?c%7=fwpaw)N=Y{jClBukEQFSEj^%2SRKy z7C@81&Vs$QgnJ}Xj;zw*Rm2vTQ*)dD2TaM4KCCNq*D6yts@|4W=(~cv>1s;eYsXl~ zYICLXrFfrC>pX*%C+Xiu*-4#8sG7>;-C11`HIZ-Ur>FI9t1u`oa9wlxG(ShJ%A%sZ z9%~82p9WKUl4@$U&d^J4HTA-AT&$ZK!rRv13oPM>3ryh8Yi-|E2{fshnn%(;*=f#g zL)4!D5v-HYk`+hUl$EVzF-D?s`W}V$u1Pu65{*4sE+H+8rkf{enzK=SZaf^NpESCL zP2BxQnp{+BgZ-u%XY-H@CiNGTx~?burRv(^Rs`yqyP`|^-C2y&(>a1I9U5%_c4OVm zX)>nwZP#E{m0)o7ODIL`xhQRhMI6U#j%|e9$m8iWxvXnRpaKC*ir~+m0EQn@J*lx> z-@KwQmbc8lV$J#Nbp2t|Z?cj;Enx0tkr_?WGbX1ql-MiXec~m(W`Euea;DZIz;mR2 zq3>|S`(VlLA{*H7KWhOz(z?_y@ z(;sYFuLe|SGVf236%fkp(UE|m5St!ap5L+d5f(XC?Kn1b5lW;xjT)&2G z-?bY>=1a&e@uDpmXSulA zS4$p_tWV!KP^c1C48)}#6aj@m$8$t=yf->)p84{*Yqm`5)8{`OYdib&uVXDLaQorX zoF#fR$MzOIdop2s1?080RWZ;SFoTUwwBEzGugxPW{gHQzw8l^kiZ=>Tc9kg)sY0>wr)?o;02jfmf_|XqCEJ zVsxfA$IMK{ty7E0kOpJL7u$hCiwg+;Q3c&2j@enPgN-f(azmJRs84JA&C(auFFsTX zaFl9|&fr*dyH?ZJ9s#_w+qN~c>>|d{nb>&NKLHgOA~uht_b!QKO2^gP(|l79z|<5F zQ*Z=@4r_9=Hq3cjvfm^yU3YEf#e^|#23jn zGL>4+MZzp^It4&JgmSB=;_8uiRMf468OT@Xcdm49C`d)&{ zsBx4gQ{{F+wKNQI8_KHBGEKMczi>L)-w#q~xvB+CZ?7Ue)Nz52iqysW6 z^^KJ6wprrO#Vi;mP#Guh&^UkU0CL3auF8Z#7H6#Q{2&an@YJxP5`N6_6mf3_x5_s_ z5hIr;LxW<#GPm3Tw}sz^!ZpqKLGeQlXqB!@R2#eQXq7T>qgTDs+*AlxPMGG9dh&x<6h0)hf1IG9CyBlvep8q^#pp>(PU*$zet9LN=oCQc`CS}sy?H(#T4 z$#BZh95Yc`<(S++)-2~QX)F|8NiS-)4Nt}-WHTr;zkrrNu21V?V0wp?A0FH(~c0&|t8UL7lGmj<+V%KJwb~dYjO#3YO&lM+NA&eV8)p_B8$iW}cvu z)5UkR@sEo36A26v9;5Vo^U>&X%`^HO#?hM$%^ELw0ZgQYCj?9#d;#tKih9N&qfqfe zCi8D-%*@UWHoP>@p2C%tH}xp8V#ll^@?w;u^yFPO+f^PRzzq-HA)|FVf|gNVo^*Tn zx9&ZPadK1U-k215Oi0v=sZPKx4P*Dl$ez&b-ucQ=hmgIW^Z zRbWxH@s|1_o=uCs!BM{)rOQjif1|Z|Jej1)6sZ`rht<})C52IeW3q7V?ml|h+uSfK z7p=b0XdqJXI9u+kSb8S&TPJ5_BdCi~!aJ1`A{2zJ#MwR1yst4AqOJTCqYha@2{ zp)_Cr=}i}wt?a%nic#5xwK{sj{rt-tSUq5oj>HnYbmpxc*FsYdc(v8McD*OXXs;`C zIq0?yhIiWCw$|f5%V#Y%=ZnAUb)w!z8|QnsXRpPum=ks(ducuw2+(FEbexs&3XXoF zqpOg0-0wF{bOKI!gnFuNJC6I0$t3#AuZTsDz5I&p<4#l(?#c`APT&}eK&+Xl2i~Q| zH~$QkHow|&e&37vzm5j z=JG4-;W9Rd6lEa#` zB#+doI8~7jS-0fq4ao2mQ^cDOW+yOL4smwbd$o{9RpRtRZMPE+=$st)N8>-lV;?Jdy*m< zMK(HY=L4Pn1qM?Vcs|iE70v)R0jx2K7m=H15#w}9S$4_Gf|Jq!k4E2+bV0{;ol*yj z>~J1EC7^zyUdZkkYk|M)C+mNIy#C*RIqaSpsS8{E+ToR(fB8$3u50;X^VihnojcoB z;ek`w5(vOViP~dq1gijKC11rjm)khl+ps96LW`6X$Zd?1OLl`6k5MB3vS|b)or({q z=1L=~IEvelKqVO(99;A)e_y;y%jj5LLvTEiZMis40e8MnvJoCmJe$#rV!fE~2fOsK zk^m=BL#=0H`C+Dh6fH>P*Ew9!DIh6HPC-_O>{a!!`v_TCP97*w>kh#fRZ8$$TDT^n z;>)HXTACc`fH%v;Ho7q;T}2$N1k~Daz{TGIlZRtDeo$ajQuzY%?sR z@#|69$nL{}M!r%gve1>a7#L_Yyco*z+_-+4NW{P+yw8ex31@18tPUL~?jD%wrRy~^ z(M?Huz3twNm_af$we8A0)>PJV?mHu>6I0jcZ#ojgR2UD%;dH1kz-PqfeD!qi+n>Hy z_at)VY9`H87VKi9+52GKpbjjfH0Mwvoc4nN2XbF3IIO1*BA zBYds5c)=}({JF)bqlSijFQ{YV5U5xghkr!i8 zVM|LDWv*+tt@!H8Vy=cl8O11CYn06@5c%9%fUBjTW=kZ(G??XBt(tYIFm+};G1r4t zMU%4VKcu5cs>L9rxyP)y8yg#JAy0~JD0g3;(FA8~J)@-P9G*9~_!+Iah7o3BxEF8U z^W*CP(q>wXHuEgQfVju+laW5*FWH8oFOShWf>sW|1pL_v%Fl$BMK$?8S*RZd5#=ZL z^}0egv``|XeKFQJq>l_B(MO_Luf)AD$s>std`dA_^ktS8`8oo`rI;bJt#M8r2C$SG zO7PaJbsXTReoop_V`!;3H@WesP^XKE63eHH7YQ&GGRxCgRN%Hi8|M zd3-TGq3fI6PCjP?{h@=ZB(t$0)q+nbe@w_gCNl5!oJy1}xS<=8gNpFW`OF zwnWOI2XDdRqe zdK%k333NHN_?`c%QpSA_^;EiZGVtvUT7PigS2`X0y^gEha+e}{@jg1P8#awg2v1#x z$jls%t3^zy*nKhaG}%Q<+OK^a?tj+kV+5IY!oc4cD+gjKl~E9-XEzvoa+gy zW%2<`v5uc)%U-@$+- zcPVDcy-w7#RIJ~kOA!W2wewCNXDmbqrlUNTSeG1`A4^%`+O>jH(|b|$RYWZF(UX_Y zU%q~`lNa**bnn&MA9i{h^7!V5mw!9@;n~xtdoOlGo=qkfqRPY&KhA8dA!)unewSXB zt))DCJ3h@u=x3}Cv57P(2deuELCcW}M~L4s!(Kd1p&iQwxdp3X1r_gh;rbh=qjk}Q zik}QRsY4k$;1cc)$~ex=2&M=g}M9=2^^Yt%Y|KCQq2@4RGnS2|1TpuilM ziteYd9~`vw-`?<(i7&d6gOrLxj_3<$<;%4EROFvf@%l-2t^Ji+G~^oE(y~&`Y7Pl1 z=f$Vu^z;+)L7zm*P*YuetgZU=o*AsssHw`Spu1FzUr8_%W|@#XJoy#!AVXE0p6830+t}|R}Rs4Pj~Km$0EA>4UK^1tqSd)4i#U3s=*b-TF^Y}4uMD5 z+-4J|9*NMPIbdKn<+n+~7z5UyrUQ)nqVJD3=Co|GqL#Cq&W142)@GZSLwG_f#$FpG ze3z^R0UU<1EWqAs9Ej(2+rv0|sn$x*6`=s7P8Uf|BBwb;@I)0*Dk1UCtOH{y>f@~F z^67?|G%-5Hl?Zf{gF=t_^C3o-72^XQwI3sJGguHt>K9~N%)bH9;O4)X4YNYb`%Z@z zusthfd0-}Q-~QJwBXZ8^gaM^sQ50@uEdm~^<9Lawh!WlN1wf+D02Wq<%hbQ5wXA4r#5|Bt6q@2aj=>?_z0EC2zWH177ts1rnsbM*zus^JT z=F)H%_9)(WDoyxE_n^Feki$QSbej}~$C7(2nO$*#n05^JW;T)eS>f#Kr~2}DnyNFG z$HQS6J$~`#85 zkYhhpMlfEcyLLxp3l%?lgVVvbP>%D{+b1f@mY^M<{HF)0?Q_^#fk~jl8%YXG&S#$* z-xEtuP0AU(14;34%&4=1iHwR;XL%z(366YZ^~dT!dSh$;Xg%`gAE5zUtoLKZ6<$9j z<;NsOqaC^kdnXz8$Y$^PO5!kE>V z9Dvlfre-Ey6th$v;Uf|(qjjW8HiJa_I&;tKxI62p_N36PmT0+diZDc1CZHTItRswuzBBdHBy6OUmhf*-8b<($5_ygi)ZzFtL?jOi(9I-WZyk|zNgoW zn1DL*#l4=lX0o=YW&GwcAGpg43=#VF7f(h2W5;8KIy3 z{NoiD37ZcNSUQvaVlrk?79^2Q1{X(c+t z()|4qVMu9Q({;YGxA{!TKVh5W=%<|g6*Q=!+yWQ-me7)d$1%sbI5Qvsj?%Maa7j1U z1>DPGK?poJ+Ka_&dZr{(IOUvyYVzo&1~-kC@c5*jYblozTb>PArJ&7UFfQl7$P6W< zL_+fn${v-G^0DR)$c7GpAM0xw0OkTERX0$EvurRQCDmU2Ym|h!Eh@yD%>oBk-1zZI zo06i)(Gx%hSm(A5u}v12WLyb{*oExuXEA(kn{d%Khx{&@!+JefEj7h1N(G z*~-MxHH?uwRl=jsclCqoy6We5Z{zbDMz$i*a_{q7J}m?7Zhn5daF+xc{sOL=7;huc z^35GJKQ@l=Mgv-#VnF`uM%=p}_ZpqXQ8o;{%)gx@Mr-u>BE~nf^bD@OODJ8QC%yHH z=O=Ie`|Qcyv#mEzIxS+&X!9dT--V zdhbE6*E`)9ZVpc$Zf@QkBvgrq>~Alb7~{rZ_`b3`OWq}zD<rnpezSBhogE`WA7;SjQA7Z(Ev7^vla_;5bO z_gHy;R$|ThbY!jG@>r@|7oqs6rSsGfJ#=1vY@AZuq;(w%2KxG?7jMRQu^l7hw(7HN zpFv!L-bU=@NTDzXz(VFs7+N{8iTo4RwSld?f9ef{a$2E|0!OeJ_j>Uo0^R%T;zy6~ zx8jZX9=txA&hr@$b%XYnUaX%ad5-Jd_+=x$A8+XQFeWuG>t&H+Zl`sOtCXv@s-JPt zbGUZuOI)DwQuQ+jJ)-xIoDc7k={Vt8+OK)-@8i4mlXRBA7N}3cZ|Dg>gfAIV2q*K= zI?@VLX49v{+VTph!Tg$(n6n2)ORx`}ZqbVAQS{=wRFGb*vqSFsC;>cs&Mm27N&(uZ zv()Z`zli^rQ`apaV^JSA{SWKOugM4AzFyqBt3Okmqy_B?BK@^oP=>9D7Z#WgQtx}u z{+{K9hLd~dbupg~(s44e)_wz)^notn?A`-vkt7hZ?MeBLcK&XBk5&X0A_I7z*$`_c zI6>#bY&4ToLfu#+>ph6K;0<0Id`{H{;$i|SS?7FP>l|=XofL!zXOz9W_PcdBuIn5a zT0U>_O>hpNGGSO)0YTw{q?Z^Muf%%;P#wI%dWcPN<2wy?)Zq$)V~1A=dbi|s_NJcXWYWCr*%QirBHf?q%xpBB+4VQuwIqw91}vfMoJB-0NG@>19y@xyUfz3KAC za50$rOwkH7(+GwA$S>;O>i}_QRCb!0qHq}#kB!hY1AfHxQv&8bDLy#eP{}?cCsoaD z3%>ATP~TKe3aG)LbYT54+V9WoS5JO;{Nnq)=P$pH$HV9Z4G&_>v>G8CqPGA(;I_cV z0(ZzaCxmW+>*> z*~I41W_%x0ECA$YGt+Yunt1D;ug3T$$ovpua>3Mhb zr~@m_infoELsM$>&Ckx7iPVE1)UP!akVkvW*o}(C_pEIV}K+F^-on6Aj*8D2_ms4UNXinaF-N)G;C}A1u+_l|9R6GsNiF*mV!Db-uGS1`0P3M}nv zqytQsaE!xb;~K1d%pe-qpP0M?-dLB0kR~W*HC--Wb4i|Tue!>oe3~0O7?Wk$S?Ers z7OOm_Eyq>%oa|~SSB{o1p60FdK=7st!mN(IBAdDQ;15alqLUIxoVlP-UnLmHN{-o8 zXK(pH%83ZIuI~qqB zQWhI!o*kIX&I~Gd!WFflm{YE-(e9Ew=qhcCO4(vB|-T9N364lK9qO{J6`_6sMNstSgus+*XpdKTY}&;Te`(+Ev~ zG0Zrfo~5loS4dosVO?orp|R{cf&35a3-T8|Iv2B1`TZsv9AJ+1vvh`kurB^Z%9#Gn z`44V!lL9B;=$aD3-RP@PDDVUI`-BG3;^9^DICyiBNf^}F*0Oj3ek((Vyntyb#G&5V zs*1$TJ5&iLD0zuqqo{38$WuqJ)Yt2ZU|Rt?3GpjXSBW zR66Ahe$M77_lX81PID@gZ=u1RT(t~AoeO6s?FZ{Yx}?%ftX*#u)5JyzzZ2I8lj zF$s;5)yvYo3UBiz$Qg3!E;d6Ja9wy0x?sq;p%g^nsKli}#dgmNmMN_xRFv6SE&<+M zEPd((*4JHVYE`GD0s_pO)+;KoWf+fHxMRBMt z8C1va)v=$n-it4QRI%*hyLZ0gR8f>w291iXT6RXM?j0^Cz5>!xa4Wxjw&=yIyT~B*~SP39&}Nv}wkOgj{^LID8}=0I~#=R1=!{8jJu@houzg?>|TR5$>pd zP}BF=P-}=SRo0UEa3Bla2!*^+b(;=_N^p(#mSR1m>zIszdI*-ukVL6RJ+lxf+e#8A z>IAXHt7Pbu&wJ933IlJPUF}9Wiafrst|F2o;LOG3pS-(Na|Y0v?v&VhHc?7-W0zRv z#5KMoAQ_>_+NCEESgS?{7n03xS?2%59maNGlJ0;sW%mW77Ej#3=pw-K1q}`XQV~M9 zf<$-K7=o-171`lyL0A3}D)L!^_nKIAIVTQpn8Y4ZGV8E&6H4t!gnL`&&vxTZ_3F%7 zS!mCa-&i55xV3E$xXk|XK{HZT1#JUkp)B}iuE!d5YkB`ac*Af|=wmx*C%TDxn&TxHOxPEr1-tVzjGfD=qlDL$R znGKa`Z>x5ti@zbMb6igF*dMbUt*HDI)}N;9XpuWh^T4pUqS*&)Z0(jFO{LfBU4Vdo z!pZ~d%GckQ-0?CD)rfPYTdBsANh_%YBvqBXwc-FeSHau*?w15Xv6^IR6%ZucptH-C zZl!T_l$IP`pn+ECf`mQIg)b+^4!j6L$He5^vio~5&AVhh@m!h#S* zR$tpTrscL>ouJ*9c}S?qaC&4VpO%!GN^7!1AK~79Uu45*14yq%1E{7W;La2+sjF%_ zP7)|u$!I%)6xSW*0iRiUYvl#*68pg(nQ!`)ajN6oIoBR1^B^U!%F37IUuiU@AgV&$ZF8bRn{wr%>46srU$U3pFS=Mr*dyz<{!9{+~WY zjl9Uy1`@B0&YZqlIR+bTYm|B&>;du~lW{={x`!&!`Zv+n*bZ-`=Y|gjzJd8<+|zVK zHRRUb0f_dZZ1HySA#6l29%s&8ZmZ87i_^A32eijXjaX4EY^c`fN52W40F%bgk;u{A z%UTDMFDO>2W;juq{e|CXpmwBk+o59x5Pd>tDR90{Lg(v5pCYKkC&-*Pc%|XboFRB? zou3jey~i^;K=8plyJw3&{ckx}z|T#9*}-f>g!l9mcgf*2hHe3z*6lC-XuY@XO0P9K zk>+R}tfseDJ;&wmbB@1WzsA{tb!#zj(i?$X9E_SGy|-5qK8`64HLuTaaQc6r88kw8 z!)Ogcm_sKq^j~djE*!1FR1itqwxZyR8&-&%DB*XBVyy9;)c7XhJ-nL~Wtp9*cs>=R zq;q){Q-?bg-kG{a#<{_aOCta-B^q<3tvXPpaPJCFo+cRuX+R27j;eIRW8l@L7X+|Q zUa62KfJa`r0}=Ppr}*X=FpTkhy!hK;KzscEM0il&M?5~QhuZaC$TejlL9$ceJ8M~8 zD%O|aq+bC4I%~NC@*QFJ3(C34lLY|T+So$qz~hAw(qOP}tcb7+K4~{V+RG7`H3pHe zU|>sHLeg8eRqg~8)r}HX@F}Y=&`?fudY7n1Kk^Q$fiUV3z)QFn!@-^><;#m)@i83S zoY8uNns|dIVvTkcx9rnC90Dp2UJJ3QU4KI?x$R6BbX$0L0ae=}f0wA{UXZ2R;Vt52 z{Qa-I#nbq*Ll53{HF&vt@zFW3ZoNGQBA=h$`rpY<4@Pj9pQ1xjRc2UucyDWNUG zCGX!;CSYh|T-))cl)?=3PcvGkWO`X!{Qmu$F#bn)xZ^aA2QvLpEg2`kq z4`I2xT@1W9I8RIMa!g^!&x>-_9iNS7-PyQ1g8zS?O=t6D)cpsG#r~1(0!rQK-9_gJ z7C7vEzxVU2qi1jTe#98W@$FXY04g7JKOJ<-^JJP154!FBgNuXpgYMy-gYG}*_u(D> zdk`PqX}1n`8yJ?JTYVHPSXK84s=gX`|kg0M*HTcZ*Mx{!#hw~#(vO; z(fi}C88^4wMTfEO34D83b~k!kckez(AFZE0JlR^mJ4jB}A3c0{vYtMAaJrRjY}^~1 zoYv|IR};BgF;}q{V}7Yky;@|=ns=aG9=u7Tj6gitvJj*BZSu4YT0a={dBraap zn(o7xfpmW#oo`$BhLFKjpUGf8vJM$c_ijnYn2|4IxV*?!>>8>cb901KopuT163W@( z112vOyH+K&p*M>#4r#DV2{fJ5Nm>ok;Fi&|e=-=y4EfK3ty^8Aq~9BnGKaXMn%^k%vm!+zw{%ThtB$7pX() zTk3v|5UYlqMF)2HGExjZF#!^hD18`1(NfO{D$0jJ-V+xSyA(Iez+sa8!_HN#Y z;;j5njH!N~yKX!p^?bd%(V&Ii=4mOrk3k5~>Pm4^)|NQmFGxfIk zR!Vcb^pe<(MtfO(1=p1}G{AE^{!o>ll}<1b%Nv_sBxHpDnSd6#jyl1J#yeMWMBrn+ zJ}1WoHmjDLV13o-`hv^->tvGQbiV2S^Fc4zD~7UhV@rRt-Wo9 z4~%GN?8uA1_UX~M;2z>KFho>u8Y;^$*{_Gmx5>NIx>DGVX@;iHcD5>gcQROMa9sZ! z;f`t~vhlOjSg8kJOf#G3c{=LV3u~%f-nfYs>8{ldL6!Un(p`(rLbZwI=fP~db0ikA zZ|b!flaK5dVqP4zglpe%il7Ss;Xy`&-9+!m37T%4h{JQqBxarr4Q&)V1Gl7we4=Ux zs>h*=NQ!N%3A*(558L~_LuPljD-3EfMFA=|W+9K&@kN#QgeK*Xhj>o>%6C@{lj%&3 zFDR_zT~FSAafQ&HE!djwpgY9v8CJI^FP7|(l8}DpE~#ez+$kNsGMi4*Gm7WP^ieO4 zzD4P6XctK0yJQQ@+PO&1zUGwDxDm$I4bmc4tEpZ1N29H>oCm*$>VDp~QKWbh<`Ns; zK%FJN-jvrY?`~XUTd%j7SF7*eW*j|b@%Q&A{tg}{B|-mlE2~?nv6`XbxX{A}Ytso(%>| z4$yCldE+drKQEs7Xi#gUi;+ulOx-c-&{PqP6Fjbqa5KtYrdm~ld!7M@CyEgN*sDy|)KDExP|V*>v-x>w;gx7R3{I%%fof2L5$ig* z!IJjU{ctUG!r;CfpU|k=o}5{0Zs@NIaH80i5;Y2A!b&<{yZxVTnhb(Co3pPKs-9t$ z(R~`!Q(5Z~`dohsjFL@(m{xOQk~UGV1uoC4%9}8jsk=U{g_H%Uvp`*8ev3~yZg4+> zyJ2098fOBmXzFDgUk0Cw%<0JJttARtd~AQw zvm0JTTRI$ELMq@bpL*B+t&aLF4bRIKv~`P)2^QnC@LMk0i-HbiS5DzXS+52cPFd^P z3uoLeeuITm0U9NJs3t9H^slSQ6q&Oy45DJ(c8RaMrj(FdyPk}&Rz_6QnDDfeN!b_S z2L&itcpv|a`RFA<8w!0Db_=*W1VK5a6bdA(5@xx<7LXj4cez%lEr=mSrR^E6GR0DtXL=-u9or%<5 z{4_P&e5=t25`Fec=;C)oe5;e}u0Z>9^d5cQb^~^wei#4HeVBUi{vS@)e&*|7OErW2 zWA;&yS1PEY;+qsI;yaFgfgB4Kl~_%*aR2`Q4}}5uFS1h>{_8Xn|;N@y9m4{#xGY^oU1Re#C$= zG?(5#$_~RqK6{WFMTB@<;Y4*k+gqHaj}4#Ul`6!I3Kvq{-hI`;;Sx)Z1^lbyi;DHG z9GF?jw(9>L+-wHmX7gHbv-z2D;~5cNXWI{#&)2 g|KExF@%HuOXV3Ru-@0|{|G|I%9~o8up3tuY07)`or2qf` literal 0 HcmV?d00001 diff --git a/test/units/modules/network/f5/test_bigip_iapplx_package.py b/test/units/modules/network/f5/test_bigip_iapplx_package.py new file mode 100644 index 00000000000..3ddc252cf74 --- /dev/null +++ b/test/units/modules/network/f5/test_bigip_iapplx_package.py @@ -0,0 +1,104 @@ +# -*- coding: utf-8 -*- +# +# Copyright (c) 2017 F5 Networks Inc. +# GNU General Public License v3.0 (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import json +import sys + +from nose.plugins.skip import SkipTest +if sys.version_info < (2, 7): + raise SkipTest("F5 Ansible modules require Python >= 2.7") + +from ansible.compat.tests import unittest +from ansible.module_utils import basic +from ansible.compat.tests.mock import patch, Mock +from ansible.module_utils._text import to_bytes +from ansible.module_utils.f5_utils import AnsibleF5Client + +try: + from library.bigip_iapp_template import Parameters + from library.bigip_iapp_template import ModuleManager + from library.bigip_iapp_template import ArgumentSpec + from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError +except ImportError: + try: + from ansible.modules.network.f5.bigip_iapp_template import Parameters + from ansible.modules.network.f5.bigip_iapp_template import ArgumentSpec + from ansible.modules.network.f5.bigip_iapp_template import ModuleManager + from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError + except ImportError: + raise SkipTest("F5 Ansible modules require the f5-sdk Python library") + +fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures') +fixture_data = {} + + +def set_module_args(args): + args = json.dumps({'ANSIBLE_MODULE_ARGS': args}) + basic._ANSIBLE_ARGS = to_bytes(args) + + +def load_fixture(name): + path = os.path.join(fixture_path, name) + + if path in fixture_data: + return fixture_data[path] + + with open(path) as f: + data = f.read() + + try: + data = json.loads(data) + except Exception: + pass + + fixture_data[path] = data + return data + + +class TestParameters(unittest.TestCase): + def test_module_parameters(self): + args = dict( + package='MyApp-0.1.0-0001.noarch.rpm', + state='present' + ) + p = Parameters(args) + assert p.package == 'MyApp-0.1.0-0001.noarch.rpm' + + +@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root', + return_value=True) +class TestManager(unittest.TestCase): + + def setUp(self): + self.spec = ArgumentSpec() + + def test_create_iapp_template(self, *args): + # Configure the arguments that would be sent to the Ansible module + set_module_args(dict( + content='fixtures/MyApp-0.1.0-0001.noarch.rpm', + state='present', + password='passsword', + server='localhost', + user='admin' + )) + + client = AnsibleF5Client( + argument_spec=self.spec.argument_spec, + supports_check_mode=self.spec.supports_check_mode, + f5_product_name=self.spec.f5_product_name + ) + mm = ModuleManager(client) + + # Override methods to force specific logic in the module to happen + mm.exists = Mock(side_effect=[False, True]) + mm.create_on_device = Mock(return_value=True) + + results = mm.exec_module() + + assert results['changed'] is True