From 9e5f22ae1eeed57244093b1410e187537fa122f3 Mon Sep 17 00:00:00 2001 From: zhiboniu <31800336+zhiboniu@users.noreply.github.com> Date: Fri, 8 Jul 2022 10:37:54 +0800 Subject: [PATCH] attribute docs update (#6381) * attribute docs update * fix mtmct * update docs --- deploy/pipeline/config/infer_cfg_pphuman.yml | 2 +- deploy/pipeline/docs/tutorials/attribute.md | 36 +++++++-- .../pipeline/docs/tutorials/attribute_en.md | 27 ++++++- deploy/pipeline/pipeline.py | 20 ++--- deploy/pipeline/pphuman/mtmct.py | 3 + .../customization/attribute.md | 74 +++++++++++++----- docs/images/add_attribute.png | Bin 0 -> 168627 bytes 7 files changed, 121 insertions(+), 41 deletions(-) create mode 100644 docs/images/add_attribute.png diff --git a/deploy/pipeline/config/infer_cfg_pphuman.yml b/deploy/pipeline/config/infer_cfg_pphuman.yml index 6317c2672..2e91a4bff 100644 --- a/deploy/pipeline/config/infer_cfg_pphuman.yml +++ b/deploy/pipeline/config/infer_cfg_pphuman.yml @@ -20,7 +20,7 @@ KPT: batch_size: 8 ATTR: - model_dir: output_inference/strongbaseline_r50_30e_pa100k/ + model_dir: output_inference/PPLCNet_x1_0_person_attribute_945_infer/ batch_size: 8 basemode: "idbased" enable: False diff --git a/deploy/pipeline/docs/tutorials/attribute.md b/deploy/pipeline/docs/tutorials/attribute.md index 067a017e7..299cdf42f 100644 --- a/deploy/pipeline/docs/tutorials/attribute.md +++ b/deploy/pipeline/docs/tutorials/attribute.md @@ -6,21 +6,40 @@ | 任务 | 算法 | 精度 | 预测速度(ms) |下载链接 | |:---------------------|:---------:|:------:|:------:| :---------------------------------------------------------------------------------: | -| 行人属性高精度模型 | PP-HGNet_small | mA: 95.4 | 单人 1.54ms | [下载链接](https://bj.bcebos.com/v1/paddledet/models/pipeline/PPLCNet_x1_0_person_attribute_945_infer.tar) | -| 行人属性快速版模型 | PP-LCNet_x1_0 | mA: 94.5 | 单人 0.54ms | [下载链接](https://bj.bcebos.com/v1/paddledet/models/pipeline/PPLCNet_x1_0_person_attribute_945_infer.tar) | -| 行人属性平衡模型 | PP-HGNet_tiny | mA: 95.2 | 单人 1.14ms | [下载链接](https://bj.bcebos.com/v1/paddledet/models/pipeline/PPHGNet_tiny_person_attribute_952_infer.tar) | +| 行人属性高精度模型 | PP-HGNet_small | mA: 95.4 | 单人 1.54ms | [下载链接](https://bj.bcebos.com/v1/paddledet/models/pipeline/PPHGNet_small_person_attribute_954_infer.tar) | +| 行人属性轻量级模型 | PP-LCNet_x1_0 | mA: 94.5 | 单人 0.54ms | [下载链接](https://bj.bcebos.com/v1/paddledet/models/pipeline/PPLCNet_x1_0_person_attribute_945_infer.tar) | +| 行人属性精度与速度均衡模型 | PP-HGNet_tiny | mA: 95.2 | 单人 1.14ms | [下载链接](https://bj.bcebos.com/v1/paddledet/models/pipeline/PPHGNet_tiny_person_attribute_952_infer.tar) | 1. 行人属性分析精度为[PA100k](https://github.com/xh-liu/HydraPlus-Net#pa-100k-dataset),[RAPv2](http://www.rapdataset.com/rapv2.html),[PETA](http://mmlab.ie.cuhk.edu.hk/projects/PETA.html)和部分业务数据融合训练测试得到 -2. 预测速度为V100 机器上使用TensorRT FP16时的速度, 速度包含数据预处理、模型预测、后处理全流程 +2. 预测速度为V100 机器上使用TensorRT FP16时的速度, 该处测速速度为模型预测速度 +3. 属性模型应用依赖跟踪模型结果,请在[跟踪模型页面](./mot.md)下载跟踪模型,依自身需求选择高精或轻量级下载。 +4. 模型下载后解压放置在PaddleDetection/output_inference/目录下。 ## 使用方法 -1. 从上表链接中下载模型并解压到```./output_inference```路径下,并且设置infer_cfg_pphuman.yml中`ATTR`的enable: True +1. 从上表链接中下载模型并解压到```PaddleDetection/output_inference```路径下,并且设置```deploy/pipeline/config/infer_cfg_pphuman.yml```中`ATTR`的enable: True + +`infer_cfg_pphuman.yml`中配置项说明: +``` +ATTR: #模块名称 + model_dir: output_inference/PPLCNet_x1_0_person_attribute_945_infer/ #模型路径 + batch_size: 8 #推理最大batchsize + basemode: "idbased" #流程类型,'idbased'表示基于跟踪模型 + enable: False #功能是否开启 +``` + 2. 图片输入时,启动命令如下 ```python +#单张图片 python deploy/pipeline/pipeline.py --config deploy/pipeline/config/infer_cfg_pphuman.yml \ --image_file=test_image.jpg \ --device=gpu \ + +#图片文件夹 +python deploy/pipeline/pipeline.py --config deploy/pipeline/config/infer_cfg_pphuman.yml \ + --image_dir=images/ \ + --device=gpu \ + ``` 3. 视频输入时,启动命令如下 ```python @@ -28,15 +47,16 @@ python deploy/pipeline/pipeline.py --config deploy/pipeline/config/infer_cfg_pph --video_file=test_video.mp4 \ --device=gpu \ ``` + 4. 若修改模型路径,有以下两种方式: - - ```./deploy/pipeline/config/infer_cfg_pphuman.yml```下可以配置不同模型路径,属性识别模型修改ATTR字段下配置 - - **(推荐)**命令行中增加`--model_dir`修改模型路径: + - 方法一:```./deploy/pipeline/config/infer_cfg_pphuman.yml```下可以配置不同模型路径,属性识别模型修改ATTR字段下配置 + - 方法二:命令行中增加`--model_dir`修改模型路径: ```python python deploy/pipeline/pipeline.py --config deploy/pipeline/config/infer_cfg_pphuman.yml \ --video_file=test_video.mp4 \ --device=gpu \ - --model_dir det=ppyoloe/ + --model_dir attr=output_inference/PPLCNet_x1_0_person_attribute_945_infer/ ``` 测试效果如下: diff --git a/deploy/pipeline/docs/tutorials/attribute_en.md b/deploy/pipeline/docs/tutorials/attribute_en.md index 3d8fab989..d77bd0e3e 100644 --- a/deploy/pipeline/docs/tutorials/attribute_en.md +++ b/deploy/pipeline/docs/tutorials/attribute_en.md @@ -6,21 +6,40 @@ Pedestrian attribute recognition has been widely used in the intelligent communi | Task | Algorithm | Precision | Inference Speed(ms) | Download Link | |:---------------------|:---------:|:------:|:------:| :---------------------------------------------------------------------------------: | -| High-Precision Model | PP-HGNet_small | mA: 95.4 | per person 1.54ms | [Download](https://bj.bcebos.com/v1/paddledet/models/pipeline/PPLCNet_x1_0_person_attribute_945_infer.tar) | +| High-Precision Model | PP-HGNet_small | mA: 95.4 | per person 1.54ms | [Download](https://bj.bcebos.com/v1/paddledet/models/pipeline/PPHGNet_small_person_attribute_954_infer.tar) | | Fast Model | PP-LCNet_x1_0 | mA: 94.5 | per person 0.54ms | [Download](https://bj.bcebos.com/v1/paddledet/models/pipeline/PPLCNet_x1_0_person_attribute_945_infer.tar) | | Balanced Model | PP-HGNet_tiny | mA: 95.2 | per person 1.14ms | [Download](https://bj.bcebos.com/v1/paddledet/models/pipeline/PPHGNet_tiny_person_attribute_952_infer.tar) | 1. The precision of pedestiran attribute analysis is obtained by training and testing on the dataset consist of [PA100k](https://github.com/xh-liu/HydraPlus-Net#pa-100k-dataset),[RAPv2](http://www.rapdataset.com/rapv2.html),[PETA](http://mmlab.ie.cuhk.edu.hk/projects/PETA.html) and some business data. 2. The inference speed is V100, the speed of using TensorRT FP16. +3. This model of Attribute is based on the result of tracking, please download tracking model in the [Page of Mot](./mot_en.md). The High precision and Faster model are both available. +4. You should place the model unziped in the directory of `PaddleDetection/output_inference/`. ## Instruction 1. Download the model from the link in the above table, and unzip it to```./output_inference```, and set the "enable: True" in ATTR of infer_cfg_pphuman.yml + +The meaning of configs of `infer_cfg_pphuman.yml`: +``` +ATTR: #module name + model_dir: output_inference/PPLCNet_x1_0_person_attribute_945_infer/ #model path + batch_size: 8 #maxmum batchsize when inference + basemode: "idbased" #the routing type of pipeline,'idbased' means this model is based on tracking. + enable: False #whether to enable this model +``` + 2. When inputting the image, run the command as follows: ```python +#single image python deploy/pipeline/pipeline.py --config deploy/pipeline/config/infer_cfg_pphuman.yml \ --image_file=test_image.jpg \ --device=gpu \ + +#image directory +python deploy/pipeline/pipeline.py --config deploy/pipeline/config/infer_cfg_pphuman.yml \ + --image_dir=images/ \ + --device=gpu \ + ``` 3. When inputting the video, run the command as follows: ```python @@ -30,13 +49,13 @@ python deploy/pipeline/pipeline.py --config deploy/pipeline/config/infer_cfg_pph ``` 4. If you want to change the model path, there are two methods: - - In ```./deploy/pipeline/config/infer_cfg_pphuman.yml``` you can configurate different model paths. In attribute recognition models, you can modify the configuration in the field of ATTR. - - Add `--model_dir` in the command line to change the model path: + - The first: In ```./deploy/pipeline/config/infer_cfg_pphuman.yml``` you can configurate different model paths. In attribute recognition models, you can modify the configuration in the field of ATTR. + - The second: Add `--model_dir` in the command line to change the model path: ```python python deploy/pipeline/pipeline.py --config deploy/pipeline/config/infer_cfg_pphuman.yml \ --video_file=test_video.mp4 \ --device=gpu \ - --model_dir det=ppyoloe/ + --model_dir attr=output_inference/PPLCNet_x1_0_person_attribute_945_infer/ ``` The test result is: diff --git a/deploy/pipeline/pipeline.py b/deploy/pipeline/pipeline.py index 703221949..ef56e622d 100644 --- a/deploy/pipeline/pipeline.py +++ b/deploy/pipeline/pipeline.py @@ -444,6 +444,17 @@ class PipePredictor(object): trt_max_shape, trt_opt_shape, trt_calib_mode, cpu_threads, enable_mkldnn, color_threshold, type_threshold) + if self.with_mtmct: + reid_cfg = self.cfg['REID'] + model_dir = reid_cfg['model_dir'] + batch_size = reid_cfg['batch_size'] + basemode = reid_cfg['basemode'] + self.modebase[basemode] = True + self.reid_predictor = ReID( + model_dir, device, run_mode, batch_size, trt_min_shape, + trt_max_shape, trt_opt_shape, trt_calib_mode, cpu_threads, + enable_mkldnn) + if self.with_mot or self.modebase["idbased"] or self.modebase[ "skeletonbased"]: mot_cfg = self.cfg['MOT'] @@ -493,15 +504,6 @@ class PipePredictor(object): cpu_threads=cpu_threads, enable_mkldnn=enable_mkldnn) - if self.with_mtmct: - reid_cfg = self.cfg['REID'] - model_dir = reid_cfg['model_dir'] - batch_size = reid_cfg['batch_size'] - self.reid_predictor = ReID( - model_dir, device, run_mode, batch_size, trt_min_shape, - trt_max_shape, trt_opt_shape, trt_calib_mode, cpu_threads, - enable_mkldnn) - def set_file_name(self, path): if path is not None: self.file_name = os.path.split(path)[-1] diff --git a/deploy/pipeline/pphuman/mtmct.py b/deploy/pipeline/pphuman/mtmct.py index 721008f63..d873794a7 100644 --- a/deploy/pipeline/pphuman/mtmct.py +++ b/deploy/pipeline/pphuman/mtmct.py @@ -329,6 +329,9 @@ def res2dict(multi_res): def mtmct_process(multi_res, captures, mtmct_vis=True, output_dir="output"): cid_tid_dict = res2dict(multi_res) + if len(cid_tid_dict) == 0: + print("no tracking result found, mtmct will be skiped.") + return map_tid = sub_cluster(cid_tid_dict) if not os.path.exists(output_dir): diff --git a/docs/advanced_tutorials/customization/attribute.md b/docs/advanced_tutorials/customization/attribute.md index 763ee1359..15dcefb8e 100644 --- a/docs/advanced_tutorials/customization/attribute.md +++ b/docs/advanced_tutorials/customization/attribute.md @@ -70,36 +70,61 @@ train.txt文件内为所有训练图片名称(相对于根路径的文件路 00001.jpg 0,0,1,0,.... ``` -注意:图片与标注值之间是以Tab[\t]符号隔开, 标注值之间是以逗号[,]隔开。该格式不能错,否则解析失败。 +注意:1)图片与标注值之间是以Tab[\t]符号隔开, 2)标注值之间是以逗号[,]隔开。该格式不能错,否则解析失败。 ### 修改配置开始训练 -该任务的训练功能集成在[PaddleClas](https://github.com/PaddlePaddle/PaddleClas)套件中。 +首先执行以下命令下载训练代码: -需要在配置文件[PPLCNet_x1_0.yaml](https://github.com/PaddlePaddle/PaddleClas/blob/develop/ppcls/configs/PULC/person_attribute/PPLCNet_x1_0.yaml)中,修改的配置项如下: +```shell +git clone https://github.com/PaddlePaddle/PaddleClas +``` + +需要在配置文件`PaddleClas/blob/develop/ppcls/configs/PULC/person_attribute/PPLCNet_x1_0.yaml`中,修改的配置项如下: ``` - image_root: "dataset/attribute/data/" 指定训练图片所在根路径 - cls_label_path: "dataset/attribute/trainval.txt" 指定训练列表文件位置 +DataLoader: + Train: + dataset: + name: MultiLabelDataset + image_root: "dataset/pa100k/" #指定训练图片所在根路径 + cls_label_path: "dataset/pa100k/train_list.txt" #指定训练列表文件位置 + label_ratio: True + transform_ops: + + Eval: + dataset: + name: MultiLabelDataset + image_root: "dataset/pa100k/" #指定评估图片所在根路径 + cls_label_path: "dataset/pa100k/val_list.txt" #指定评估列表文件位置 + label_ratio: True + transform_ops: ``` 注意: - -1. 这里image_root路径+train.txt中图片相对路径,对应图片存放的完整路径。 - -如果有修改属性数量,则还需修改内容配置项: - +1. 这里image_root路径+train.txt中图片相对路径,对应图片的完整路径位置。 +2. 如果有修改属性数量,则还需修改内容配置项中属性种类数量: ``` - class_num: 26 #属性种类数量 +# model architecture +Arch: + name: "PPLCNet_x1_0" + pretrained: True + use_ssld: True + class_num: 26 #属性种类数量 ``` 然后运行以下命令开始训练。 ``` +#多卡训练 export CUDA_VISIBLE_DEVICES=0,1,2,3 python3 -m paddle.distributed.launch \ --gpus="0,1,2,3" \ tools/train.py \ -c ./ppcls/configs/PULC/person_attribute/PPLCNet_x1_0.yaml + +#单卡训练 +python3 tools/train.py \ + -c ./ppcls/configs/PULC/person_attribute/PPLCNet_x1_0.yaml ``` ### 模型导出 @@ -113,23 +138,34 @@ python3 tools/export_model.py \ -o Global.save_inference_dir=deploy/models/PPLCNet_x1_0_person_attribute_infer ``` -导出模型后,然后将PP-Human中提供的部署模型[PPLCNet_x1_0](https://bj.bcebos.com/v1/paddledet/models/pipeline/PPLCNet_x1_0_person_attribute_945_infer.tar)中的infer_cfg.yml文件拷贝到导出的模型文件夹'PPLCNet_x1_0_person_attribute_infer'中。 +导出模型后,将PP-Human中提供的部署模型[PPLCNet_x1_0](https://bj.bcebos.com/v1/paddledet/models/pipeline/PPLCNet_x1_0_person_attribute_945_infer.tar)中的`infer_cfg.yml`文件拷贝到导出的模型文件夹`PPLCNet_x1_0_person_attribute_infer`中。 -使用时在PP-Human中的配置文件infer_cfg_pphuman.yml中修改 +使用时在PP-Human中的配置文件`./deploy/pipeline/config/infer_cfg_pphuman.yml`中修改新的模型路径 ``` ATTR: - model_dir: [YOUR_DEPLOY_MODEL_DIR]/PPLCNet_x1_0_person_attribute_infer/ - enable: True + model_dir: [YOUR_DEPLOY_MODEL_DIR]/PPLCNet_x1_0_person_attribute_infer/ #新导出的模型路径位置 + enable: True #开启功能 ``` -然后可以使用。 +然后可以使用-->至此即完成新增属性类别识别任务。 ## 属性增减 上述是以26个属性为例的标注、训练过程。 -如果需要增加、减少属性数量,则只需修改1)标注、2)训练中train.txt所使用的属性数量和名称。 +如果需要增加、减少属性数量,则需要: +1)标注时需增加新属性类别信息或删减属性类别信息; +2)对应修改训练中train.txt所使用的属性数量和名称; +3)修改训练配置,例如``PaddleClas/blob/develop/ppcls/configs/PULC/person_attribute/PPLCNet_x1_0.yaml``文件中的属性数量,详细见上述`修改配置开始训练`部分。 + +增加属性示例: -删减属性,例如,如果不需要年龄属性,则位置[1,2,3]的数值可以去掉。只需在train.txt中标注的26个数字中全部删除第1-3位数值即可,同时标注数据时也不再需要标注这3位属性值。 +1. 在标注数据时在26位后继续增加新的属性标注数值; +2. 在train.txt文件的标注数值中也增加新的属性数值。 +3. 注意属性类型在train.txt中属性数值列表中的位置的对应关系需要时固定的,例如第1-3位表示年龄,所有图片都要使用1-3位置表示年龄,不再赘述。 -同理进行增加属性,在标注数据时在26位后继续增加新的属性标注数值,在train.txt文件的标注数值中也增加新的属性数值。注意属性类型在train.txt中属性数值列表中的位置的对应关系需要时固定的,例如第1-3位表示年龄,所有图片都要使用1-3位置表示年龄,不再赘述。 +
% zB*t@_ABVdah+|qzdmGJ+Z9Q}r27E53by_zaQCXIfXvDS7^r#q23>I5LMNP*`8h&TD zNxO^PutN`AqrG{U>pLVuM^C#`a-V-#5qYNN;5Mr`8?$Q5Sn@n-#n{x!)_c%6TQxR( zOc!_BbwIRL9=bXAUQ&E{&H#f~(4{@$6u@N`>9UP z_qJCENPxMx2B)0QV#6cPLo5Hj4;npmXw~b$&_vwXF7x)YW5~U@$CEP*O3RJ3*3z=@ z{#F=Iz5cLTX;13+84-jVj?j#jLWFMS6g?)Q(*eui@MeV>73yVafeK5&%9mDBD?3o3 zQciBI?{WmjVCL$o&bm}uijg@$v#*=#@Bs@Ps?!sEo-Q;W_dyKunLdIkPtl}lT;!#p zH*M_PHAGh{kwONHbK%N&hVR@#uWRH_Kim!v(TWcIT*i95PRVI{WlTaU&8w3^MHWjm z8oF{6$u|K!mFHoLtR)5Dt|3*PTuRocu5`_?D)yNz@Ifmj?x-E*K-czy6=j0e+~t@W zl_t=&V+W%|=xT*$TJP!|)TQi-;i#^W5u47hF<>ZjTYF9FFtXmg%;w!-g@Nz)3S^aG ztxK=NB5UJl7rGa8o<1mSYdKmNI6N#WR6g22f~Z(;|3rop*m+DC2Gt}=4vJ8f7okP# z^wsOb&`az#gYd`sT}mt*Ljk zJLLwUyZHDbs^oWaM><8LI?CEbImNee(Bau+*mAI=?tz(n$?n(ahLUWh5$=Vj=y_on z*|_K1?C~I@fq`FS8eaFH8sEV*H>YR^8@_>ZMWHF`27bP6jwU6$(<6<8<%caIBkRjn zI0GZ>=>!VmJ7C-!QXH6D1tj=2>YTR{&ALjWJCc%F4nj+{JL0g %Bm{73FZ?kEQY@i7bNXUxJR#-Dh8)1CMVX??H4Q+E4IUtq$U_d=9sN zND?x}qg%2=diwn{?VJhJG;}{`I0G+TUG-=?)8yOC+4mFn@c5&Ax~sCFC@Z0~67F?y zI&iJ}?dj65i2dbgjw(6XMZba_H`f}knz5RCX1Xk`_*niyfD~3>n34$!d@V=+mU@0b zc5!Q5pe~@MW_ZTc*;%S9j8marErVN9A-`de^lJ{e%n`C{c$y3&j#~wtNVg2L=6rL7 z-#1Uf_A^vBpO0`sG6zPgr2o`J(>9QE7H}}pbeKP=3DDZt0^zF()ollWCuovH+Be(t zU1nTy;~RaVi|^IZ1P0m{DqDSc7bL-;)qNs5XWvuh>~g>XJvoL|PJXFCL=953$}!P) z7jlLM{n)8QERs4*5i8_%Qy?E>M)5{ `BDN5vkqKx;=Vx6uu!F zJv2G-gR T9d^@HaVpf6+7^7k($A~=Z)iB55%Zf- z#aWhG7SR)k%=y|mxbprq(tu9mlyrb}9ZGird|Ax2K^E!$o>0PEUG%u^s5;2kvw5TR zX}x4r !b^$NmpbePmct79&?9Obr+R1Sdl zef{!uPd7CSS|vqN7lhN;Q8#*!g|UzQ!KnTx1|d*KVmuvvAKiR|8^QMS^N;Hog#VCo z+T#8~^FrNJn8v+Oi(q^M*vx4gSO`EWGl%68(_H~Nws}xja@9jEE%?ai%uN3w=Xgb7 zQU3!P(2uD;A6h&@#$vU0?eQzpjZ>o;e_ENJX{ih5y`UTKd-P_wbQ &=7sKrV H}mA8-8v?6+-N z@HCZ`L(6_ay6vU$2e~0_?x6=WHFIIOj;T}}u;2-!8}&U69czG(QZE$F0X{nvkhPd+ zChuQuPmj(qan%O DbEos=Yga}?LgxLqS__Gkxphp!Z_X WZq%h0S`UQf*H;FPeQG`@1liuBx;Bvb%45$=g1Ru&SMxx6%V zUlpPEIKQ bR8uZJ>pePAAI_1{VTbzeF|x;x<%>N6iKgv9ocml1n24Xc zlJ!LIx3V9u3Ojq$clj-mdLTY@t>gCxlt6*_sUd&(sUlKmuWa49I_2?~@iqMHR9nT( zd2N&}4>5~o?!KrfaQ7WU-r75-Thb?4G>IxyM@c2m0FyB?!;SPX5gx#3g4}yWJ~hGx z0~~PzH51@js8h`cjg6 m1$DVbE=VQ=YSQi7GWblCTK6 z10IfsyAUaozB3F0YwRa<_UiZQihyOq;w!xmrkI@&WK3>$vxz!%#{>bJj#k0k>${IW z0Lg#J6yNz2KD-(Z6XxI2Z6n4v4!K|u #SaC@E*Rofu)i9h=2ZpOe&pmf}IxV$gA#5&e=^p0@c=?`Nuza z1Kn>l(FH=L{YSp+X5^&{vcO*4?>J0V5)LbmRMFf1N<9SuOp9=Z%}Hoj%+|q|A+*tG zD^`69@3y`C;mw ;>Zs|xD_fMJiA5SLm0)oz%oQw{PH#m}jnVo; zAP|gCGuGuy`EtiN+)LK FAwk!lwh&{1W)L)7?ra=Kqep7rlG}- z{K|KY+JV=BX#b&fMup3{2?kA0yVjh2d64!ODP!Vp6%C+<#o(--aZJ);tJt!@VK&)X zgme%VPyW;Z<+3$L*|AWp)UO8NOREfjf|Ogs%_OjVFSuNrS9-QN5;1XTNbtMGHxKi7 z6$hY8m+>95Q{pN8E_+BHhpi%1vUvD$bvBxh-zMD%2y4Gpu*)?Hw#(J#=|xVJJO{pB zH(}Mqik(DSK!0N!3duH&BKdZi?xJwBZ`kJ7x!}j|mBPA0;^v0REo7TTSQ|3R7n@Im zP8${Xy#``W_Vt 1}adZ|wJXlikE*< D5%-`KIF zD_ksF@lG YawXUbRG^mqg IoGRf!b+F zY-=}*WXZAsv%{9bTXZ?krq@I@=s)0&Y+E%YYC(i*6Z{>KW!+9hA@OoE8{QiDz=!G{ z$dbMDW)r*T8!(R#QY<-am(>M-bcuJ^_`I(xQT2>ca#v=~DSW7ab$w_vK^pA=?^snf z3@HBXo `&tP{Nf&=0mXjNe{NvZ4t-2D|o@$j}wvW!vGfKE2Cm~QPrpP;9sE8 zBI9n?cUO2;`v^8|3h>PuStXA|r;X_B!ua-4#$%wqW#lI76|uJ@)sMfwX@AB%t`M34 zp|E^~>jsw&?gn5C5&%A_ f3mPWz2W&eQI z$F)L6{g pgt~aomj37SEpOz^7Sd0vNa()dfUcR!$T)A}#%Jj^@nmMH2)EbB@ z%f9!zb>f_)rXHR2Y2(nZWc<|+VJmAU64kS4)2>JBH)h8U($}CQ+O~Zw{4Iz<_r )fOewizD0>=IN=OYC4`lv%Y#FY|4o zJ*v_Q_{E5IEW_Y<@%~NNz2q=_wqGOOg1HpZ)t~wrl;?Ufq-H{RxPmV$20n;}oF{#o z%}S?>f1hRfs`)LRc|`=>nuc!RrUu~J uKbL>pa;$b31`@sRtouriN$!uC-w7GX606@- z4)eR~-*X8=g}w=?>0q$3^5euUMbCdr+X%(}$?_{CJ{qN$BL^qT ycB${2%=+saP_z&-ukQ zDXJZgNx#!Se|V=r50=`3rW$U##F5>7{+x8Pj8JZI2`{q$4h2r32P*gxpf5~M&$P`C zp6%PzhWjn%oH=F<) Sgma7v7zs~+_g-_YS9{|mCz-G>~cw2Su=N>D+s45 zkA}M?EU&~M-F_pvx+ctLkw1Uxq>HV6vusir>0vn?j-YR9uIn`5dp!F+JW!1Wb047r zR1_0K>UjQHM~dXO` %wjOR-L~`bSgvpc`HP>ss3*^IlNnXn zj;aWxjbIT#0X-RAdgxg0k!shi#Zf$h+bhI6C;XsCMF^ dxC13@BuHEB8Aq_ngtO)N#w96eYkxxR(XT1btfwz=u8_pwNadU0R#_J zCr~D}UMg`2Vo5kBD=EF_(Q+oaf1g&(@YY7c(*=kg$zqsXWo20;V{Ao^w743kEiUKe zd`La`BI969l32^9H;!QBBjj9sEb?K{VB6ZTPlVG)IDN6!JDIQ{+h&78zfm#&3H)2Q zB*NsaTQky2fiMzDln>7F*uUIWcJZ6?f=KRK|JkH$Scsa+=X*KaO){kPG(_b|u$pFi z0^oB}>A HJ|o2 ;v91q~ FQry z*%j1e@zA|!m8D{MvDEGG8n=qw w5n z2Uy#Q{?Xl)rr`BJD~~ga^I?T&U1!=T+^e0j!faj?^#X?FbR%Yh=IJHYo67pQDHobn z$@8B>KTl)Ea=%rP#eY2Pq;vDQ4;^5uZwlbTq6S`Y&0O0}wz}fBoCJ#rPh=(Oyv`$j zc+LwwvKiFBAoS#z0WTx~{hD%wa0(~JNZ@acNhT-Mk56hqqtNv2pD^mG!6fF7;tOP= zWNIM4m-6!`6u)*INi_+4*(CWTDg6`0Ft@Vf!P@G`-P-4U G<@TVQ<$C3eP8C1KL~((k*0K zPcPX}qV303_ORBTORO@(4lMlNk?CEH2cesa`@dl1{?>h3W*6?GU>5g1v3xIc>~`PV z$H#XqZ(m->a!mTZGSt?s+G~?wb2B@E Yyk>oOKQpkS%;#stA%T^mejeUo1aSAUX^qP{-ec!(&FX6BI zoP`7hILWOR$X4r|A7-aW00DR`^GbKbw-U8iD#>^;s}NQKTQL4p66Doyrr=aBU%@jl z+AZ^WBy`Pxb`7}lg#sj-F^lPd&pNbp7RIDgN*0S&`O~#&f+YVbeHN&D$1*(j{r*`A zLU#|O59*h3I@qn3`DhTd z HVP!I!ITWP&4@_HGPw8sd9DK4luMB@=v#+ Tu?Se 0f+77Z6CX{Pxnk8$v_=*GI%}q_)q5f()r4^J5VQDgb#-gul=%*qy);@^sJjoB^ zYU{sw?#%K8rmXV1DmB=VTPFJ0l0@&EK{D?9@=xD4dJ)$L$+`5x;=R$)e#uq!W}KFW zv6biu?93MI_II9bhzdzeB=g3Ytu0RC;VuE>J`DO+GPC@SHfk?Vm>xu|8s~eO&*R0L z;TE(F3)<=CoOV;ZvklE8md8B@^y~*dUvA3xm_fa$?R@#=y^_tsW?5@4N4Q thQb18`&%Z%FW9o1pRR| z3susu5fl${F>yEgJx$ulEmjG)uekR* nxA)%6C4-eO zBV=j9542_P>@jjyc&~m^O?_NST+c^JM t8;!rMhz)M2ghl=|D|yO$qgc209?7u_ zv7LddvtOh0)479qj2^m$=-nw1nd5t?bOEAr_0&I_Gp_B%tfj%X7X(ODTjC1_3e%SR z*-+wovYJn&<-2cRf$_}LWC?>w1oxw4C XYp94t zIHV>9HVBP6EUeT!EPmC#aN0z#g8NB(TkfY-=#i|S16`ot1#Om~{JU=w<4K0h!kGP> zIw#qY+-0U|iTW%f$6)0>D$-NWkd!-70$vQ0HGhtT3=Qf*+NkNpI8JCh;h(G9^tb;} z4kNwn9vpl0)@NA&O0ZRYd{!g&GxIT*O^AIU15R$%zaCgib+UKrdn7H_Gexc)7Y9~2 zwdp~ZjdbO=A&=(efT9)@cUYG~3XD8 >HWB72lI8 zKYPcVojRJ$Kq;7W?&AB8 %AQXD|V=Cy0mKrUaqr*c!5L*^Ex^etQ=idFA4@J6mm+bMJQ^2|~XOeLv!+2TaWt zEx-GE1<*Ro>JrW)l-*}nSBy|EQBbpkAF8ZoC}dXb%_O4fN`$_NqsuGJB^1ZR*lX3e z`UcliQRo8EIt^`VYiJWlp7FR2 2krC^}QqjyB6?;Ya}+C!f@5EG?`%@D-Hgn5|kAW*FHz)k-Mn$Op*=| o#M*O1N7TJ76-m z_r!T%%XJfM86EhWKg8Rxvo|snpxKAj;T^$^iyW@&BM=GqF1nnmE~A-~iP0yAyzb|Z z+4@RQgXQWRyu0ryW@9%yat>!NQ}0aX{nFt3CuXh*Xu*OO#6v~s=J0i_Yt!d;PA}2D zIj>K@QpU12#))eEVkpcL;l}nWp6B5whX`@T*;Q5%tFC(+FmUquUi7Nc1(?+NsL0rl z@7^Co6Aqg$o*idh?@azp!Z6jWTY7%zeaL5XlteFnRa5+Ic1|-?`Kr}*DZh^lHZJ0Q zwNok~Ho>8>*Vm@by19Z A{$6c~c&(P;-AeUM>=(0`EFN4%V!^_lYp< rM&g*ra z;mQ#4$(p()aNq29l-F@<#zjBQ;GLE63zE29qq7AXHnEE6d_s$MZ)*lwX6&sz5l(7o zp~T `*vyb^HY!)I9UNe{~9eR&|>8SOzJkd|Kqu9%PHJ%C(@>>2Lb$5%`=%_KzR zCH6X&8P^11CCx)isGT?_v2XzeF_gom UXKIBIx$+D={IKH=R^Y}p z7W)o2jaVwxhU)u#+-jJWhw7h@E&A`1X&uBjYT4{uv)3ISCBemn!Cum^PU-88AexX8 z-QeZvfl4Dp`bUkmMg0h(=RUWa<=^TJs1uXgsjtYy!#I@t8dZ2#aQ3%J5eECKf4VJa z%z)zYFag~?KXcZdF=ZfSro{H?c}f}fpK#aoopcSAYz!8f0wf+u)nz`jtu#7C-}70; zUjN2plzypHv+{3>k0T$24KMiY7TV8Sj1oZdaT(@ygc5V0*}F)ksH1PP%i?k?)S1#Z zwCgs@eGOd#Z^nTMS+?#j7VoRUd@@Dd`BUiUQ0s4(V=pEvfEO^F^zL5pDIrLRR{E~> zkuq9_aBVUYHU^bN9Rlt~ao_K}Jmtb}eFn%7B|)ahNHx7czdIpI_etv3@}wjph8`Dv zZpV4;PAkO@PgAUM9C!PV@(oOJr1s)w;VK|j!d(Sx6I~XiAM*qGzN${B+&Pz5HCy)6 zbDv#ae7Jg@6A*u1&ng>c&)xE47h%QN7(N#=g0v4it*2RW$>N>Z8eCYV4%T$}y>=mJ z)rfiy(4nO2)iZ7MP1+U`9`y!CoY#ly7tG!r66;|m-`UQG-a4NDqtv9b5+E8i0kTfL zoIUDkGCv9t*Oku}1T}m2sPejYHVCRODX+@b0Ngp;FF#a&e#?R3(YAz9# ZNEUD^xJ7^{g?fb*ed-FVA3(ezAhmZzL37ZB_e#9?e|{Kp65+G3R{a zQcwT=Juc&SURyx3R6kqNwT9FEEHjs4+J4L=S)_<9nkz1&*%TE*2>G;*Z4oUT9!m^K zK11a_+XyU^;EmBZEIpXA_|f;`w2*nqZ7M3IhZF4G_#yEthb{>TSJ{@ip^N(|ic%fX zznLl|8wvh8I{Ixh@syBxDwNYIK4~nOR3?|I5L%9OX{X^PZ}3?O>VFcr)|m~Z;M%k4 zuMkG9Zz(SlHrNb3rF?LFFwgL+KTAMfJA!F*=>1`YsQ1n3N!C3_-HuFH%Tv+-Rb12= zJT@PS6}c6exBlN!15u2%jRWofm^PXr*cq ((bla>BY(5^D4twf_>T))dq##* kE>gUeU25&E=MQGNanc^z1fwd{09X{uMuX*Xd5B780A5!IM~h~$ zHgThzPk&l)$&yzSh$!?YTr~Os;Z;W0F6^|_D7tv$>^oxO^J^H3eu1aQ9?Yf)@WkCT zo7R2U=RkFeIP82QVf|>*;`OEYZ|1jN_wg#p38Z48!GPH_n|_Ge%q(yoq7hoaU1Na} z^UZCot<^FGwNrpd&1a%n14(5I%aiG4LfLQOnA33Qc@#*KdDG{xfZ&z-Iw*bO BIf5KV9y3Z+1Q#!vwPMjIsv~4N3sn7Y? z0qy=L5&KCIfDjYOrz62vO0V&9R{q?PBvh-bjJodQh>w|3W6>h |@i+)nws{$m9ve{5`6@wR*g z4az@m@!3qc%M-`?!#t=d2sy8kdtdqq 7Qr$*3Y93?)h-ua!BLln39x9>Eo zZ&ypO53#P^|CX+IPsgQrIDwM!Ok@y}kIqN~yer@XS9}&5g&YfpN?fKT5xc2q0Y$74 zHS=m>4zZyI#W39hTp^$ap?rnk@oS8^;W4&~>07&|{Jx0CSu8HQ2Z}0BNz4+ohr?g1 zDR$wS!}Q8wTR=_!k6%GZ2f36k-~c|BbO72A9t1ANI_QbjKm9FKqL}>_6hK}T3|OIf z>rZ c6g0GO`9;3SCvE3|Rc24CLvW zwhg*E@!(Z$4_c&_ZY%TRGi>;HdsHI+V-IuPv9_$D{!pC^#qfqd`-tLrN6x$F-%}h< zII!62RUX*;1w>Mai3Gz-IDugr0lxY@0F*DErvoj9z&Zn2IT7n%EC`MtCgiPuewkSJ z3WQ%oanS?I&7S?5^IFL qm=TjT0%PN9e#g!Y-Kts7uxsaAP~P{X#%?$YI`HAlHjKrD6zizcW$P zM&VBHTZzB3xLb6SS2>!r5mt|=k|_W$m=fc@INV!ZeVHN5C$?z@)&De&MtqgMSGT zy?}$u+vDGeg6b{A#G Qs)f=-l^?1Y0rsZ zJn0(i{cKw^bVP>}MI@$HI%Y20*1uy2-v7xKzkHfhBzx2_w(?CB_7!Np|E~bP&fL8N z%*nbP$^XIcw+0yp1peZf$4%kpaVf-p8zF!i_I9(|`*gbyjAEalf7H{!zwG60M_F3d z*ok!FlX#eouHe0ru1Pb+Ew@~!QP$s?47i+7F^-E6fCa4_80KvSDXr=A+1~uiA6x`G ziI o-#>T~ec7}8QK`51{ ;X|9hYSwy7FmTQy_B?r9SZ1}he$ffKCuCluHaaS zpnOOdwuhZ4qD(jS+mb_4<}DEEU&ewNPL*6VSb`8#F!!k_T+2NcPchbeAxngi#l5iK z3>ZVCu-Uk<$NX3iXx7pAfi8JD$9Sf+q;#V|IX?}{rsUJnte-%e)guHxVmC=yG3|jW z_t-{{`E6KSyxDmxz|22JReZ^ZaLS&?e*e_In*K~!3EZTjCZ1X;WHbwWCt^M(J(5Lo zW_IRxxWVk&u9oq1*3^>qK8MW6l<~%x6yr 0@v;qe=+3pi=uk+aPz61;fJ_ME9c9` +wv zc*||hBATnp&*9}Glizk=?|6?0Pyd+P=5r_~l;f*A(X8|xYT074!=A(#r-$EFj)ANH zC602|_a}z4M0y$x7;m~Y(=+Nao>EgX6ymOS=Q+%C14bq6W2wIX3 #m}>PbLx+0bGpA=nZWQJrABdm=AOmMnneq z=M4Z7wgHd5C#KlfYi3Ot|6KHo (^&ZeBeguPC-oqS1;FZaXW1sLdyA-({q} zpZDe^n+Q}xMJ6Uudd88$JV5!s&~Sl$<&oz(WV&mEX0W&;rY*S}1gcBDY(C*(qOV|) zzN!!M_rD0w?1+GE*kNYPHw_q?!?%`7jo7% VI}RZe1+3CE166m! =!k~iToI&6nldU7Z9%|l);ZyzDv(n;aIpQ(@z1tn|u%C z{A;G3_$tM xOqtrYp!0D}Qpq^t-fw=!bOZ%2qEJ-F|gkL|kQ9S#X}Gti)di_XIZn z_PVjn8M-CH ^t-y}8A%CgWMLsI zQ-0&A>mq0QxQh0#VrLub0zcRdLTT{|>9olRvibHRt3s=lWz@U=xSm?%EhgCa|a7_R2NhSIV#2$dDT{*9=DDPiR;VfDw#vnNV zyQv>3yc`HJxhb)(q2&IIEB*uz3yIh2u?Bl<42=Ho)H@tI1-*v6E?tE{9%CG`WHRjk zJ3Xya+w@Gv9Z0f)wK)2y;5P=M92|>GTD+ASTHeWi?N5S^v!6PuJo=TgW3f^W|LwDC z@Trjq8g{A!?DN1k1PfYgJ&z@9IUX`+-wUohW#8#U?k~+QNu9KEtUDWtwUk%2${Ri& z&6Bforr{;D?a(7pYo5)tU2maVX|~}xH|F+i*|ZmQc|`=GqTU!MQvAt>Qtgp!%?pW| zbza(?EtJD7csX80>xFtBFGXImbXrUGR}2qoj`=m_IJYP*zMB+eS`dFqrFI! (NcR(6 zK5r`q0&KP?5{=Dnym*o#(0loZR^K&wZmI<8F(!L!rB-S-$-JR^t4HA#YQk;2mcPwG z NCGL#W`8&V_TcVweAWH?T>c)7%6t0{SbFd(n(-3e!Akb> zg96j#*u2rNZ*GonRfIl))g+{p_IWq_mLhwry3?y6Zf^xyB;5Buule3*i3b`{8wUmO zpP=m91xJ^4Dc5jg!qtYqCVK}gW;6;UM&`l`h?>wMjinloutLgvM`umu$cGS?dg6o0 zQcwzK?argwXrt(>=Lpnu-ayIwGEI$e&G zH)jr9`*K>j)NJ`-S>m#vJhc9G*M5GkaC&AsZ!VxN@LN&%9L+%w?v!IE5(ZGeZI@kP zSfkGXLx!;_9HW+rnb*w+?Efu3N{?*E!?D+IKPT16S4EtFV_Zy{n=eMA@ *1yegj*%M3scpupIPOIto zf&DUL1;YrRC{@dx1CO0fo}3d_RF2cLPLrC9-jlvvs#6e}+8&!{SsD;PoIij1ITYXG z7M;cajOp{X6drvJIPTxt6PMp~542gn9Q&kmt1U&11c#*Xt$gD>vI__|518926u@Ke z?k$chn-MJ%$l5yPCWslnQH{>24dsy7YW?h66v%5J2^f8styF3YP3p*glTCeaI0-3` ztyGcOBr&=SD~Szf%n3;jo+C7y;<{0xQMJ>x8WBc6F<>S5zU8Dr`IZ#dN7Z4gi>Y8K zLzc{DzB*HoAM6%3_8z?Eq#e`<-lF|PP @@6wVuZ*U?B=?@)zdZ=40YdqMGjojB0`ToBZdV2ie?=_ zhZ3y25R5L$xINg6{J(`+qv#};SJ$O5BMaC!fJEjm7 D~S8kmy%G*fA+|J_#*XrkZB{-RX`EK z6gh$1Bk!~glGMYPez=JP?(U6~Fa%n1n8&mElKD UxIzDEHWW{>~X zv}*Ju;8gAfj~z0hY$2A(*R&f$^GPa(D+0z|T-H(aNbHzwhOE45gk?5nJ1hfo@h80# z$6sWE*C-1hH2W`Isq=Flc6Bub?2=I{OY~TAoW30Je)GI#o1$VkQgiV2TeLX=iQ2Ry zymn+8s}Zx -I0N-Ga?tl9JLd#8Ls?O!~;lIpk06*^jgTK#7}dcf!- zs2?|GxK!di_ez_3a m-XpCFEwfK z8g0VocHN&JMH{150%&LY)*4Fd>qRBe14V^FhK-gKpf6wa6d`^%Kc<~}UTJ>AOV$rj z_IY$$66XUPTr{RIxjf+!j?Fw@p)btBe8%;H4hYbP?7Jjpd!G{J^YA6-dnKGdOP|FF zKKo%`bN$=e^NM9yM{bYn$wjTPdliPXElb2Usx{d7MRUH$W%9$3!s5 |#$zLI@P~(|DE0O_DG@k7V^`?|c^tlrwcm1EY75Zw z+{v=7sr-y-yS _1$BLT*Ll`K{!xcdI!P-%6iGya}qGH4PZ_ z%cwHho;#`T{(jnr_?pQ{kD5Op!=xwNrC6K@=hm<^>w&(0)(GgECckA@lf4@2k#XJ^ zZ6K@po?_RDxf$0E^OXl~W*|IxwT0zyY_3NlY(FRBJdz#vTg$eg$`D)UZ>d6Q$867H zB`@+rlZ5)9WyT}R>(fwrSK@H1-Fl%NWYm-h;QDSeF`@E=p}}rmezeBh<`M%1)CILf z`p^3d;!q5i5UmdsoY I=%II>8_0hbl~ICbzDvvWDlOZT zKIv{cKCs `bDTJT3S*YVaH{=l;43_FDdWYY-!F z 3?dzUH5L? zO^Ib{65d!RL~cx+WtW~SE~aLsU0sYZm1_BPKn_6NPV}kg`9c?D-zndAZ@VpcqCaJp z2#PSxP9D*~4NHm}0%vfORsI%Fb==kem<2|lIC9@vZzo@JgWp|Z9Sgu_{1qfDPki6v zp^`6Y>)OQzdB4s9$x$h#33dT$xPKPuI{zhwMEVVv;Q!Z}#P$~&jCNt>r(9|BljeB9 z>7$^CfBCW->LfvGW1Zjw?MY-Ngd5nKDj~#iGfHnwKj@49YF~9@*OG$C0rdPF0Gb0= zVhKULb3*u6l|z_tkn{yl9hQn&O!_qGg>F%J1h@f#1Lr+(z6=(4K!2A4n)?P(^0G^N zfwznkpjZtM-~aC_Cg>n#R~01_$gA{6zZ1zl4KCuxdzhwzH_fgdWN_pH-@4&sn7F*P zp-O=Hl2g#@$Q6BA7G`yx6!beidf14Ju{}Dt^(-Q|wH~^nqSK{<*}5qffb+mAju@*; z!QUOHwQoSgdGWCQn4{GB-k8&X9P!@Zv5W_oY3cRQQ=S &H#_0T{^Tq}eA {Rjr2P|kPzVZBPi e#FwNj-~6SYlRBDtyC@nnOCs1s`3PJOq+&QEOpeX% _pBvKghdPf%=GJA{%!58agC~c1T@*3G$RgGqpGBAD*SRw8^G_- zy}*5-K#qS?h_)L_*LY&AZ5(`+6l>b{^R p)ryB~c zfIQd-wQJaiX{Eg^`pN^{cb&v0d70-2PSU*ceJ!0FPx&>}_B=9)$l`5`|M{JloHzgG z15N~DsbvUpbGN!16HPdlVBzoj#2p-sf6Mn$t0k#}UY@T|$n@@MzoP`2Yi5=7Gu{L- zVW3Jjexl}UkrO-B#do<0pR Pc2Gnk?0UJ}zt(#1Xw1)-VR%1*#lFsXBU}ZezXP^@ zmGs~q1DOd&xJLGyKt;<}B7;)h7Y}(!F{v(-I7);qJTJzHm4;-Ben@_Kg+wMYMZY64 zuWRn0>N;HPxfFE-^`loZ&hZzo4fAP945Lu)W00A>@+q9rT`K;39OH#9{O3caM<>_I z>L3f9m@dI!wx43nxaJy*|6-B-q0H@F?J-x}#a1iRBN*20=qt4%P41)Av1e}^XlLG4 z6#>O~jiG?6eTHr({=`D?3`Ma8E3(q5&Uz2&^TfCIF7=;#j$_IM#Gk>yAD^$Z#a(Km zl;H=u`PIi `r# _T{NqVXFmGDdiJw2 zleEi= o(4WZP740DrTUpf<- z)nqnTVQ3^S&4;BYN2S_-J|eLD(X(Q ;axm(hNNpe;yBR+AQ($ceNG{5^9{Cgr;ReNwB%02of<8% zB!GT+rH+}9+93t3=_nB>|KZKrrq{@BWs@}2=xS%o{aIq}-sgZBa0}TD+hxzM &=v$u5*dqVO6C+O&1pLrzN*mo!}sEt>Lje|qw^~*{u=L~*0 z5>C@a>5$zFX+C!i>6}uanK)6Sb+ayTyK&r4R(o?atWB2 6&pFJ*x(FMovj0(ly2M4mW%r*_e?GkAhv5Y8mw%iOKLJ%{E;|1lw%@ z4qOVwty2aOrrWF0!?mEj1$p(dBi$NHBRkiDW%|57nxvxyq&r!6Q>RaEB8D^i5Xp4+ z8Xl=C1*NoK3CFy7o0xjTBaNB%z4s=A-_Aq4Zmc9HojZ+JF81KyFn%Q>Y3-2jY@0P- zf=?xd-0F6)o1+}R_WDm~%7}Fn@ ^*!AJ >7I01o~4v9%a2sP zPz1BT|3w01=+N@K*q$#MI-o&z0}lFqnc!Mp9> 6?uW|Qme@(eZO+q kA1eI>zr~gT4xl z1*G6#f@vHrqcRISR8v9r?wcCc&(MtZW)q73m-!L*BraY9bEt#a%7oXae`uv @Gj9hK{Tdfw4w*p(@SMGSScj s#m4|O? VsL29;pS?~4=#|hM!^Tphqo9JIG zdm Xt+pL@6r z>G?YX*p wHjd=_2ojVmfB;k0@xM^J6`c$H031bF}ctXr-^j@T@( zT82jN*{wSIQ#AOEFfq9cj7Lu%S}nC;Hp@RFYqMiUK0$cP%pMHAdf+rRq-oEbquC9w zjsCTzwx3E>n-zAndv-XTC^5I1Y_T(>UKl;G^AN9bSNjV$g{+r-2fYl)x}}Zm07-g& zJf)?9#EXglejx|Awdu*_98KWnWStjZ=ly!23CPR;7baiyjZ8-KYvyR`)~C2xLd p-8ifDnf zSB>|P2=JjRbO pAR0xE#}qPBjPiEOt#9#*=&Ce7E=T4 zP)60ICoo_?qwDYw1JANmDya8ye?ygljYsrV0;g;)j31_s9B2%D?Mrj9+NRFvvmQdR z{EBz21(q*Mo%_(|B!bLke$uAuiR^tr&jItPbi0mecCaZ8P ZAV-sBp513kv+38)NHz(=fqh5?;LI9@d?2CF8e^4Ney?YC zgs0-fHVWddZPwMWtD2BsgGWj-Od?wM-WA1&rg4BU26d(nWzW161I< Zt{UN_M z@zfHPAC6iQ;>)jOju }~`6kWR^4Bqjd8c;M|0NezfP(@>e}VDpx