From 35de8279757ad23d7dbc38ddce5e01083ec26d08 Mon Sep 17 00:00:00 2001 From: mrichomme Date: Mon, 1 Feb 2021 17:26:42 +0100 Subject: [PATCH] [TESTS] cleanup tests and remove reference to ubuntu16 the basic_vm test was historically called ubuntu16... as we are now delaing more with ubuntu18 or ubuntu20, the reference to the version16 is a bit old - Replace ubuntu16 by basic_vm - Use ubuntu20 instead of Ubuntu16 - Replace onap.small by m1.small to be natively compatible with any Openstack (default flavor) Issue-ID: TEST-299 Signed-off-by: mrichomme Change-Id: I69f573354c87c44c10581861450d48244db0c7df (cherry picked from commit ba1faac52b28f752516ab075a5bda56058548e49) --- README.md | 5 +- .../basic_network_nomulticloud_settings.py | 4 +- ...ngs.py => basic_vm_multicloud_yaml_settings.py} | 6 +- ...multicloud_settings.py => basic_vm_settings.py} | 6 +- src/onaptests/scenario/basic_vm.py | 3 +- .../templates/heat-files/ubuntu16/ubuntu16.zip | Bin 1641 -> 0 bytes .../heat-files/ubuntu18/base_ubuntu18.env | 19 --- .../heat-files/ubuntu18/base_ubuntu18.yaml | 153 --------------------- .../heat-files/ubuntu18/ubuntu18agent.zip | Bin 2496 -> 2495 bytes .../heat-files/ubuntu20/ubuntu20agent.zip | Bin 0 -> 2492 bytes .../vnf-services/basic_onboard-service.yaml.j2 | 3 +- ...tu16test-service.yaml => basic_vm-service.yaml} | 28 ++-- .../vnf-services/ubuntu18agent-service.yaml | 2 +- 13 files changed, 27 insertions(+), 202 deletions(-) rename src/onaptests/configuration/{ubuntu16_multicloud_yaml_settings.py => basic_vm_multicloud_yaml_settings.py} (90%) rename src/onaptests/configuration/{ubuntu16_nomulticloud_settings.py => basic_vm_settings.py} (93%) delete mode 100644 src/onaptests/templates/heat-files/ubuntu16/ubuntu16.zip delete mode 100644 src/onaptests/templates/heat-files/ubuntu18/base_ubuntu18.env delete mode 100644 src/onaptests/templates/heat-files/ubuntu18/base_ubuntu18.yaml create mode 100644 src/onaptests/templates/heat-files/ubuntu20/ubuntu20agent.zip rename src/onaptests/templates/vnf-services/{ubuntu16test-service.yaml => basic_vm-service.yaml} (61%) diff --git a/README.md b/README.md index dc833e0..367b08f 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,6 @@ adapted to your environment. In addition you must define your service in directory templates/vnf-services and create zip file for heat template templates/heat_files. -See ubuntu16test as example ### Prepare your environment and run tests @@ -52,7 +51,7 @@ See ubuntu16test as example - Export the setting file in a environment variable ```shell - export ONAP_PYTHON_SDK_SETTINGS=onaptests.configuration.ubuntu16_multicloud_yaml_settings + export ONAP_PYTHON_SDK_SETTINGS=onaptests.configuration.basic_vm_multicloud_yaml_settings ``` Note each "use case" may have its own settings corresponding to the test @@ -64,7 +63,7 @@ environment and configuration. ssh user@onap.pod4.opnfv.fr -D 1080 ``` -- Once the different input datas are updated in run\_\*.py files and +- Once the different input datas are updated in run_\*.py files and that the templates files for your service are defined, start to run the different steps: ```shell diff --git a/src/onaptests/configuration/basic_network_nomulticloud_settings.py b/src/onaptests/configuration/basic_network_nomulticloud_settings.py index fd7c561..cc22601 100644 --- a/src/onaptests/configuration/basic_network_nomulticloud_settings.py +++ b/src/onaptests/configuration/basic_network_nomulticloud_settings.py @@ -6,11 +6,11 @@ from yaml import load import onaptests.utils.exceptions as onap_test_exceptions from .settings import * # pylint: disable=W0614 -""" Specific ubuntu16 without multicloud.""" +""" Specific Basic Network without multicloud.""" # pylint: disable=bad-whitespace # The ONAP part -SERVICE_DETAILS="Onboarding, distribution and instanitation of asic Network using à la carte" +SERVICE_DETAILS="Onboarding, distribution and instantiation of Basic Network using à la carte" SERVICE_COMPONENTS="SDC, DMAAP, AAI, SO, SDNC" USE_MULTICLOUD = False # Set ONLY_INSTANTIATE to true to run an instantiation without repeating diff --git a/src/onaptests/configuration/ubuntu16_multicloud_yaml_settings.py b/src/onaptests/configuration/basic_vm_multicloud_yaml_settings.py similarity index 90% rename from src/onaptests/configuration/ubuntu16_multicloud_yaml_settings.py rename to src/onaptests/configuration/basic_vm_multicloud_yaml_settings.py index 5036ed8..437bd13 100644 --- a/src/onaptests/configuration/ubuntu16_multicloud_yaml_settings.py +++ b/src/onaptests/configuration/basic_vm_multicloud_yaml_settings.py @@ -1,7 +1,7 @@ import sys from .settings import * # pylint: disable=W0614 -""" Specific ubuntu16 with multicloud and yaml config scenario.""" +""" Specific Basic VM with multicloud and yaml config scenario.""" SERVICE_DETAILS = ("Onboarding, distribution and instantiation of a VM" + "using à la carte and Multicloud module") SERVICE_COMPONENTS="SDC, DMAAP, AAI, SO, SDNC, Multicloud" @@ -11,7 +11,7 @@ USE_MULTICLOUD = True # onboarding and related AAI configuration (Cloud config) ONLY_INSTANTIATE= False VENDOR_NAME = "sdktests_vendor" -SERVICE_NAME = "ubuntu16test" # must be the same as in YAML +SERVICE_NAME = "basicvmtest" # must be the same as in YAML CLOUD_REGION_CLOUD_OWNER = "sdktestsOwner" # must not contain _ CLOUD_REGION_ID = "RegionOne" # should be valid, as otherwise MultiCloud fails @@ -40,4 +40,4 @@ PLATFORM = "sdktests_platform" SERVICE_INSTANCE_NAME = "sdktests_service_instance_name" -SERVICE_YAML_TEMPLATE = sys.path[-1] + "/onaptests/templates/vnf-services/ubuntu16test-service.yaml" +SERVICE_YAML_TEMPLATE = sys.path[-1] + "/onaptests/templates/vnf-services/basic_vm-service.yaml" diff --git a/src/onaptests/configuration/ubuntu16_nomulticloud_settings.py b/src/onaptests/configuration/basic_vm_settings.py similarity index 93% rename from src/onaptests/configuration/ubuntu16_nomulticloud_settings.py rename to src/onaptests/configuration/basic_vm_settings.py index 24686af..a62e0b1 100644 --- a/src/onaptests/configuration/ubuntu16_nomulticloud_settings.py +++ b/src/onaptests/configuration/basic_vm_settings.py @@ -6,7 +6,7 @@ from yaml import load import onaptests.utils.exceptions as onap_test_exceptions from .settings import * # pylint: disable=W0614 -""" Specific ubuntu16 without multicloud.""" +""" Specific basic_vm without multicloud.""" # pylint: disable=bad-whitespace # The ONAP part @@ -21,7 +21,7 @@ ONLY_INSTANTIATE= False # if a yaml file is define, retrieve info from this yaml files # if not declare the parameters in the settings SERVICE_YAML_TEMPLATE = (sys.path[-1] + "/onaptests/templates/vnf-services/" + - "ubuntu16test-service.yaml") + "basic_vm-service.yaml") try: # Try to retrieve the SERVICE NAME from the yaml file @@ -55,7 +55,7 @@ PROJECT = "basicvm-project" LINE_OF_BUSINESS = "basicvm-lob" PLATFORM = "basicvm-platform" -SERVICE_INSTANCE_NAME = "basicvm_ubuntu16_service_instance" +SERVICE_INSTANCE_NAME = "basic_vm_service_instance" # The cloud Part # Assuming a cloud.yaml is available, use the openstack client diff --git a/src/onaptests/scenario/basic_vm.py b/src/onaptests/scenario/basic_vm.py index cbf9b7c..ff432db 100644 --- a/src/onaptests/scenario/basic_vm.py +++ b/src/onaptests/scenario/basic_vm.py @@ -16,7 +16,6 @@ class BasicVm(testcase.TestCase): def __init__(self, **kwargs): """Init BasicVM.""" - # import ubuntu16_nomulticloud_settings needed if "case_name" not in kwargs: kwargs["case_name"] = 'basic_vm' super(BasicVm, self).__init__(**kwargs) @@ -28,7 +27,7 @@ class BasicVm(testcase.TestCase): self.result = 0 def run(self): - """Run onap_tests with ubuntu16 VM.""" + """Run Basic VM onap test.""" self.start_time = time.time() self.__logger.debug("start time") try: diff --git a/src/onaptests/templates/heat-files/ubuntu16/ubuntu16.zip b/src/onaptests/templates/heat-files/ubuntu16/ubuntu16.zip deleted file mode 100644 index 9a98baad6608ec63e45f23577ded7f05182cfa82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1641 zcmZ`)doGJh@|Zm5x*C=kHB5?XmgKo%lx7=w3!9G0qp8eYNQ%m9 zqZ~4f%!o=zkGbZmpSNHcFhvN1~$}7rAB3%V6IYj8ofFjUjnBAO$*gB^_p{EJ{d; zRHqGpszYQj;A)X)F#hFWPrTU0+7j_m?YQ1bMu9v|;%5?4v1+9sg{iRNqWtO3465}q zzZzR`YkjmRCe*SOQXur3-ldy1(Rt{ny=gChKMB2CDCkTz?FPs!2z&gADB-4@MzL;% zx3z-J0$U!@mG|4{1J_l;W4!B3u{_9CzysC!%(y(Rm>rC|4P z3}^~pZyPcO!xcZa@MuYf8a(`BHp1ix?q4!d+`US+9+4;fTF=uPx6t5nM*^!Vlt2Y7 zLLUQ3Rl*@3of+OSIT8sbkf(TwSEoEE{UHl%ry62D+_TKr=M;|_qD|uM>-3wX!nplU zPkiw}H^~jSMc3S!>uJ-6>jXm_Q&9c9L9)0H8?7QrF<9P2f;H%+}V*AgWqD+o8}9rk0m-ZZ*_QW z-(@1mY@E-z_r)mXwB(~8C2!?+Md}q#9r9BjhI@}Ljc=*&&T)rft5#TIyxmdEtNlHP z=L_6(-$xj)%W_FpX{Q(F=kH8QSNb!wWKQ}RwCuUHME@Eqh51`ULU$Kexmr05-wpk= zZv_DG4;mul38B2>BgY1fm14Vb5j%{S4vz5z#aMeLBoMY2@hCMYeMr>ntyLqoOirI` zoSiale9Mk{$?nmi-kGhZuFp)#kW{^2M0FUXpiMcL>?Z!wQj}?|Ey8MB0%W0mGlBL# zL4x_v1WR)(36@byKlw8uVpVEJ8(GNt0QGimlfDefD;$N_swu1=NNR$d*ROkqsArA2 zYqPYf?4{q_I4sLCvlFb@bp+&@bjWWP{PW$SQWnWoJ#(IgvmxK0R%ZhJDs#dE+ z)b?tDckY+ z)yaKhR|7Vqj)rcL(!4RAAUM-LM1ta(2&ZNDe4Dy%n@UG$bE5NvNWyhlF7`w*C40Om zm3nj%;^}3hy4}WZ$#r2$W~qkf837hNS2!9a`WmJac6PEtg3B$|D$VxgE7Y4_7)|;V zCsaFEs$ZqpF*G}_yT?O|eKhx+P8DVItq3OuALD&>zh|7&(vhL;5}K-XA_wM@6dMIG z^t(Y%E9;`#_`h)7*Gi;O-(u}(?4A>D#Kme>!JtfHG_nNU(05!2$)FHKmJj=~4<4@J zd}vl+hkfPP!c0v~!Q?*gq?ofNd2?#^i=GckZ5a)8xhy})rbzI+wt}d%%WZJ8?aN?$LQC&3I2PCZQq4L&=OP~t%dET~PQGI2SUF3fHEeA*kUCcO2<9#d zQVm-1f=(W#%j(00YnOUYf65|GFH5qXWaz%^wnZQq&o6!==gbu{EL7GtT8G@GN64h% zb=8z9RU}={T0FHq`dUB<+}D1wev4H3U1auR_sx6GQy_~aH@<^{E3;h=x;oJwE}00_ z7AXhSj+Kj1<(EUOi?}S|XNQTe*clvPBc7G>SpF5F+hPk!S*a&$_66tcnii(K>UyV^ zKl?0}N)G84hOVt^F0CZL8ul`5UcfKXtEGaIf2oSGB#L2^hEp82;7ziukF^0{R^ zKi#N_$L)H(JO=f%D{(wxRF>HwQyVa1?ze3KKy_9&g<;TA(kh_;PxTE`{#oq!@9;y$ n|C9b-hW?8T0PJ{&jaTt+`geO{&@!^$Z=^RmZUg&dzE6Ju-b?d` diff --git a/src/onaptests/templates/heat-files/ubuntu18/base_ubuntu18.env b/src/onaptests/templates/heat-files/ubuntu18/base_ubuntu18.env deleted file mode 100644 index 062468a..0000000 --- a/src/onaptests/templates/heat-files/ubuntu18/base_ubuntu18.env +++ /dev/null @@ -1,19 +0,0 @@ -parameters: -# Metadata required by ONAP - vnf_id: Ubuntu18-VNF - vf_module_id: Ubuntu18-VF-module - vnf_name: Ubuntu18-VNF-name - -# Server parameters, naming required by ONAP - ubuntu18_image_name: ubuntu-18.04-daily - ubuntu18_flavor_name: onap.small - ubuntu18_pub_key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC3dbqgymZVpu2cIWqzlKNxnOy2Qjt07NZxaXtQyu9dr0kbmursTE5N0IW0qg/rsCXgw2vjjdPOxU6jtrTbyzbAmo9F6LtS9oqvct9LmLjDNyiQFuCPETIBGy43daDVgw3hrg3f9ihN88V/JwnI9n3ZFn8Wy15KV6XCHn3MASV31YnbkjruUtj7rZm5V8NUwAteZ91k5T7WBpywt483rrkeQjEzyKiVSmmOhHWNSmbnko9XzO7QDUHfVIk5qCf/aBES7hcE0YiqX5lfLamSyCqOGANnv+AN2opDEakUeCyJHZrsk3Nkk7A9p+CNlq42sUEKtrO0xiH63viMA6eBYSiaQPzckdq/T52naozx/Oj9ITCgX/6XjldMUF99afIydpC6+kymflTYA8P/9u1Ih93+Vjg1Bf2e4lJaf9z9frXcB9F+ZRDq6feN+XQ93Q8xQ9blu9Gq8BZUbPvAQxW0UaryeuzhCKx4QA33qqYA+tmWVXTsaG0uow6f0hm7z+pkYCM= master@Utilisateur-PC - ubuntu18_name_0: ubuntu18 - -# Network parameters, naming required by ONAP - admin_plane_net_name: admin - -# APP/USER_DATA - dcae_collector_ip: 10.4.2.166 - # 30417 is https node port to VES - dcae_collector_port: 30417 diff --git a/src/onaptests/templates/heat-files/ubuntu18/base_ubuntu18.yaml b/src/onaptests/templates/heat-files/ubuntu18/base_ubuntu18.yaml deleted file mode 100644 index 73612a0..0000000 --- a/src/onaptests/templates/heat-files/ubuntu18/base_ubuntu18.yaml +++ /dev/null @@ -1,153 +0,0 @@ -heat_template_version: 2013-05-23 - -description: Heat template to deploy ubuntu VM Closed Loop for ONAP - -parameters: - # Metadata required by ONAP - vnf_name: - type: string - label: VM name - description: The VM name - vnf_id: - type: string - label: VNF ID - description: The VNF ID is provided by ONAP - vf_module_id: - type: string - label: VF module ID - description: The VF Module ID is provided by ONAP - -# Server parameters, naming required by ONAP - ubuntu18_image_name: - type: string - label: Image name or ID - description: Image to be used for compute instance - ubuntu18_flavor_name: - type: string - label: Flavor - description: Type of instance (flavor) to be used - ubuntu18_pub_key: - type: string - label: Public key - description: Public key to be installed on the compute instance - ubuntu18_name_0: - type: string - label: VM name - description: The VM name - -# Network parameters, naming required by ONAP - admin_plane_net_name: - type: string - label: management network - description: The external management network - -# DCAE parameters - dcae_collector_ip: - type: string - label: DCAE collector IP address - description: IP address of the DCAE collector - dcae_collector_port: - type: string - label: DCAE collector port - description: Port of the DCAE collector - -resources: - random-str: - type: OS::Heat::RandomString - properties: - length: 4 - - ubuntu18_instantiated_key_name: - type: OS::Nova::KeyPair - properties: - name: - str_replace: - template: pre_base_rand - params: - pre: key_ - base: { get_param: vnf_name } - rand: { get_resource: random-str } - public_key: { get_param: ubuntu18_pub_key } - save_private_key: false - - ubuntu18_admin_security_group: - type: OS::Neutron::SecurityGroup - properties: - description: security group - name: - str_replace: - template: pre_base_rand - params: - pre: sg_ - base: { get_param: vnf_name } - rand: { get_resource: random-str } - rules: [ - {remote_ip_prefix: 0.0.0.0/0, protocol: tcp, port_range_min: 22, port_range_max: 22}, - {remote_ip_prefix: 0.0.0.0/0, protocol: icmp}] - - ubuntu18_0_admin_plane_port_0: - type: OS::Neutron::Port - properties: - name: - str_replace: - template: pre_base_rand - params: - pre: port_ - base: { get_param: vnf_name } - rand: { get_resource: random-str } - network: { get_param: admin_plane_net_name } - security_groups: [{ get_resource: ubuntu18_admin_security_group }] - - ubuntu18_VM_settings: - type: OS::Heat::SoftwareConfig - properties: - config: | - #!/bin/bash - sudo apt-get update - - ubuntu18_server_0: - type: OS::Nova::Server - properties: - image: { get_param: ubuntu18_image_name } - flavor: { get_param: ubuntu18_flavor_name } - name: { get_param: ubuntu18_name_0 } - metadata: {vnf_id: { get_param: vnf_id }, vf_module_id: { get_param: vf_module_id }, vnf_name: { get_param: vnf_name }} - key_name: { get_resource: ubuntu18_instantiated_key_name } - networks: - - port: { get_resource: ubuntu18_0_admin_plane_port_0 } - user_data_format: RAW - user_data: - str_replace: - params: - __dcae_collector_ip__: { get_param: dcae_collector_ip } - __dcae_collector_port__: { get_param: dcae_collector_port } - template: | - #!/bin/bash - - # Create configuration files - sudo mkdir /opt/config - echo __dcae_collector_ip__ > /opt/config/dcae_collector_ip.txt - echo __dcae_collector_port__ > /opt/config/dcae_collector_port.txt - cd /opt - sudo apt-get update - sudo apt-get install --allow-unauthenticated -y make gcc rpl - sudo apt-get update && sudo apt-get -y upgrade - sudo apt-get install -y libcurl4-openssl-dev - sudo git clone https://github.com/onap/vnfsdk-ves-agent.git - sudo cp -r vnfsdk-ves-agent/veslibrary/ves_clibrary/ /opt - sudo rm -rf /opt/vnfsdk-ves-agent/ - sudo chmod +x /opt/ves_clibrary/evel/evel-library/code/VESreporting_vFW/go-client.sh - cd /opt/ves_clibrary/evel/evel-library/bldjobs/ - sudo mv ../code/VESreporting_vFW ../code/VESreporting - # choose HTTPS - sudo rpl "0, /* HTTPS?" "1, /* HTTPS?" ../code/VESreporting/vpp_measurement_reporter.c - sudo make clean - sudo make all - sudo sleep 1 - cd /opt/ves_clibrary/evel/evel-library/libs/x86_64 - sudo cp libevel.so /usr/lib - sudo ldconfig - # Start VES client - cd /opt/ves_clibrary/evel/evel-library/code/VESreporting/ - ./go-client.sh &>/dev/null &disown - #get_resource: ubuntu18_VM_settings diff --git a/src/onaptests/templates/heat-files/ubuntu18/ubuntu18agent.zip b/src/onaptests/templates/heat-files/ubuntu18/ubuntu18agent.zip index 90b07e7ce56cbbc636d197b031b62b90e25433a2..aa32f857fd4433d84f8ce93a4f8385836b70f5da 100644 GIT binary patch delta 730 zcmX>gykA&6z?+#xgnEnWShe%02g_jgOmFPJKP_osH}4}oLhz9Ms99^ZT8P?P<7?vFP% zex9qme8ry3IWHTy`MuE5^b^a9vkRxJe&?62+*JY z?3)>tbvyFByj#MDl;Ji68T{2~7-v*!lM*WXiJ zyQ5d7S9|r;t{`dcyT_mT%$jojQi|Rn z^Vz;$nN`fH_51jj2?y3Lb$J(3Fj?ou?QD*~9dDbw1l=;Hx6dq{ophqSAALXrk>q0i!I>)hRiufc^BT4tE-~mxeNT868-l#mTybr7!E>?#G#W z`;XoG#}eSp&e6X@B;+a+1A{sX1H%Nd$==M$91Xx^1;U%lm>XGnL8%U|Xfg|@HcGOa zY|Uw@Zo1{&~Cc-R8O9 zH27rGRi;E{JZCRjd2y?Og3qg`x|uqq>kMxz2fGJf(#R`$p64m_qP<;LWlBWc_3EIw zLt8(1`bJzcpMU85ALGc(*qk-d^{(M-*Z#S8_6Nh-IWNw|dmd>w*q62Fg^&Haqhexz zDq}m2_sxATb1>A5b^mmq_H_T&>1s>1W^Ph=Uh}SFR_$~RJ7=@G(cOzmn+w{1gorm_UP5>Gn(t}R*Kavy7OjA z{jU#tnMZR~GGijwhD^B?@zTyL{nC;>)0S~_hAF$AekFPR#;d+b%%3~Vnd-a0PilBN zSyI{g{a=$6%dgGR4!CK*tequKSG8z))9jRk_u`y84&{o6bQyTp}H**(mUDepYVQ6bkNU!Sgm_1{r2VjNgpkY z%#>vFey`qCeTJv=`RiXQy%}{SF{>Tl`$XSsov`y+cU{O*_0<2?CjyNZ{A%}otdl2j zR9Eu#sq!WBcErwjs{hb)SKG_IDlh-L$g(yUuQUqbnUnmB>4*N;NVS*0u9#h&KYeP7 zr?brm!F@kcrzP6W=i71os?dfrDP|AV)+q4&<3C_*T*ml_Ek<*#RKOHQwop%v1*!!h zpYO~17ymT<_Dwy&o1KHn{-ggjCI$x0$%f1}9I)iHxst|IOW-1bAXa50ONf|Gynhq diff --git a/src/onaptests/templates/heat-files/ubuntu20/ubuntu20agent.zip b/src/onaptests/templates/heat-files/ubuntu20/ubuntu20agent.zip new file mode 100644 index 0000000000000000000000000000000000000000..49f9b719ab1bf2c03faed851ff3f6c85f9d8839e GIT binary patch literal 2492 zcmb7Gc{~*A8Xj8)kq{!p*v2^7w;E)kvSrPdWvHLVtyRHnVx=9Fe8+Y@(ib(W-#GJ9EVrad+`EWu_MNOr7kus;XkdG8_K?A## zI; z_pJ_|%E$k5m@lGRgmHZnOXB1;{}Dy9RkRB{eXyL|DpVEt1h#KMKHw&vQ*m{FsiGI} zFSP@lqhU!FIZ<5Jl}OXT_l%~zj}0HjXhM^0k&^FT5W%164nqb@;Dn~0J%5qVoz5zU zKJtrY9ddc<%xGXF>=`;T;(Wrg6Gs#t>;EN#U_CGQ?vhf7rqp9vT-di9$(B%*9SoMV z6xs}#m!bgaLotY`by?Ks$;`U(&fVf{wN8p*^~9sCfpIQ6N*|^Z6NtTl`M&YhnFeon zQSV$Es$FmXMRTow>QtfYI;}BaFb>CW%1_Ps{I$q?!XQ~8&2(XYM)Kywi@qGFICz-1 zi2l9SkGi8Yo^K5bOToq6h<04`@ev;V5bWID&S#ihn+Qc~5$jYwKM2bbe&HzQVo=xc zSU($5UiZL~qkDq<9hRGAI~XjE_m(WT*PazJ9<#c4NA!1_sk^`H@zn&YyJ3BrF}s^X zc|k04d&G^WZ7;wHebxaPJ-T+nK#Q7{eIx#>UKrMA5&W2OzIxh)2m7CHz--txq1|81 z0Z2h^V&;^4@J>q=8c+_pmhfu}YO%l9VcS8WC}qxD!y-CQkRzSzeUv0!OvQ=1)1;FE z%6;ie^zDZX=7fpE3sD29WgGHh2LLVa6Z)<8s(mvjEGQYZ($QC!*~r;DteY~^a>ZL2 z*w!S?HP!_OM5*95VS{N>Z26tZ5bg~^cCy-MfG?qeE{@vllJ5`|fv1+Afj=Yp;!W-J z1ostUJltuFA2}0cD}~InbWYqflr4~|IWv1GVivR+M4K}+H)aLmpAU-+FaiL_sxbeT zUSg4d>*WnE0KoHKdWmrL^ZipW>!$?a8%KT2{~?%WTfe(xb?$?2E`dHVaE0`_Vkf1= zD+v;Q!*0exLr#0Hf=m(z+)W%&xv>HmyLvbzaR~t!aOlomOBp$DVATPG;0`Y&VeOlwN(F z#XfJ@L0%Eic%43z>)}bduga(y3&BCBa~={}IbIpM)|V9k5IP=OuS9s-s`#$LEBJTt zVpvqX7q#@ik@clme6MWiR_=?AN6{gfiF?Y7)qH=HAmq zo+|Z3=cWNR6APjEUGCaW}RD?|X1c~}qt9vktbV_US9$xv~&*Y!Q%e|V+>BM3oV?(vQ2 zUkjJR*yu@@7Q9|EHtwv=be6}b-T@_Py|uIKaWf_fc(;muxy+fMp%IMHf32jwY1{2+ z+HeP#{ef!ay=T91<5h{=VsOko{coRO#6_9s^AQs7Vmxyz?v_|kr9JqX*VmSYIlP0= z8=KY5+Z$Elo`~(DIS-7<_@9U8{B>4Ti>OoV7^z-zwksIX52Xwoy zNP~Lqq2-g9b*KF1O6E&T+W`guA206Q1ADFPAS6-E`4j3wd@+KCKD|H4-a*osHld1l z`i))GFp!9a2&YY&%Z^_rgW9%P%1h+;;g!SH4A=H^)Ks6;L+nI)y;ILxddlA*XEinn zx7ns#zPp2A?}DpcLlMskDSOK&=B^(!=UbFj!(^z}XHy=B~MKagzOAO2BLnG^NcOawNk~?rTU)H_= z2#zJ-)j(8AxkG6`McZ0YK=tzn)65BJ*cI7q&RIWQe;q*uM6~==gcX=}p78yPsB0NJ z>Hcl5K_vkh=ea39!K~`7XdvS*nEpUwfu%Cm`a>m^AS3}lg&7@9)eSYqRye6L5Ri{-9l?`3vAKRg-d;Bg1xTvTiRrF&W6uz--ccc6*a=lJns=Z4x$7ud_Z)`VA}P=@4d{g^)N$nWKy|w)p_uE&jk9+Z&(k97i~lL zgkJKUEbXEi@2?QvArKTfm}ZoyWl4O5o*ya~2%^^qLeGW|3JL$V=yJTax$8z7Y*_$+ z