From 93ec62b9d3fdcb9c9eafc08e1bd0530cb53aa929 Mon Sep 17 00:00:00 2001 From: diaoshizhe <654745845@qq.com> Date: Mon, 27 Mar 2023 23:28:32 +0800 Subject: [PATCH] initial release --- .github/workflows/documentation.yaml | 35 ++ .gitignore | 180 +++++++ LICENSE | 201 ++++++++ README.md | 266 +++++++++++ assets/features.png | Bin 0 -> 397394 bytes assets/logo.png | Bin 0 -> 139180 bytes configs/ds_config_zero2.json | 45 ++ configs/ds_config_zero3.json | 52 ++ docs/requirements.txt | 5 + docs/source/_static/IT_sample1.png | Bin 0 -> 523440 bytes docs/source/_static/IT_sample2.png | Bin 0 -> 282807 bytes docs/source/_static/IT_sample3.png | Bin 0 -> 400679 bytes docs/source/_static/IT_sample4.png | Bin 0 -> 334618 bytes docs/source/_static/IT_sample5.png | Bin 0 -> 632293 bytes docs/source/_static/IT_sample6.png | Bin 0 -> 365253 bytes docs/source/_static/IT_sample7.png | Bin 0 -> 578291 bytes .../check_before_after_lora_tuning.jsonl | 252 ++++++++++ docs/source/_static/logo.png | Bin 0 -> 139180 bytes docs/source/_static/logo.svg | 1 + docs/source/_static/logo2.svg | 1 + docs/source/_static/logo3.svg | 1 + docs/source/_static/logo4.svg | 1 + docs/source/_static/logo5.svg | 1 + docs/source/_static/logo6.svg | 1 + docs/source/about/authors.md | 4 + docs/source/about/changelog.md | 15 + docs/source/about/index.md | 15 + docs/source/api/_autosummary/lmflow.args.rst | 32 ++ docs/source/conf.py | 74 +++ docs/source/documentation/data.md | 1 + docs/source/documentation/index.md | 37 ++ docs/source/documentation/infer.md | 1 + docs/source/documentation/model.md | 1 + docs/source/documentation/tuning.md | 1 + docs/source/examples/DATASETS.md | 111 +++++ docs/source/examples/index.md | 23 + docs/source/examples/medical_finetune.md | 55 +++ docs/source/index.md | 185 +++++++ examples/ds_config.json | 12 + examples/finetune.py | 70 +++ examples/inference.py | 42 ++ .../download_finetune_regression_test.sh | 8 + .../commit.txt | 1 + .../compare.sh | 1 + .../cuda_version.txt | 1 + .../ds_config_zero2.json | 54 +++ .../gpu_type.txt | 1 + .../new_test-finetune-00001_gpt2-example.sh | 43 ++ .../nvcc_version.txt | 5 + .../pip_list.txt | 98 ++++ .../server.txt | 1 + .../test-finetune-00001_gpt2-example.sh | 50 ++ .../uname_-a.txt | 1 + .../ds_config_zero2.json | 54 +++ ...new_test-finetune-00002-from-00001_fp16.sh | 43 ++ .../ds_config_zero2.json | 54 +++ ...inetune-00003-from-00001_full-precision.sh | 42 ++ ...inetune-00003-from-00001_full-precision.sh | 49 ++ .../ds_config_zero2.json | 54 +++ ...est-finetune-00004-from-00001_larger-lr.sh | 43 ++ ...est-finetune-00004-from-00001_larger-lr.sh | 50 ++ .../ds_config_zero2.json | 54 +++ ...st-finetune-00005-from-00001_default-lr.sh | 42 ++ ...st-finetune-00005-from-00001_default-lr.sh | 49 ++ .../ds_config_zero2.json | 54 +++ ...test-finetune-00006-from-00001_multigpu.sh | 43 ++ ...test-finetune-00006-from-00001_multigpu.sh | 50 ++ .../ds_config_zero2.json | 54 +++ ...netune-00007-from-00001_longer-training.sh | 43 ++ ...netune-00007-from-00001_longer-training.sh | 50 ++ .../ds_config_zero2.json | 54 +++ ...st-finetune-00008-from-00001_gpt2-large.sh | 43 ++ ...st-finetune-00008-from-00001_gpt2-large.sh | 50 ++ .../comparison.sh | 2 + .../input_new.json | 0 .../input_old.json | 10 + ...ew_test_galactica1.3b_gsm8k_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../sys_info/commit.txt | 1 + .../sys_info/cuda_version.txt | 1 + .../sys_info/gpu_type.txt | 1 + .../sys_info/nvcc_version.txt | 5 + .../sys_info/pip_list.txt | 419 ++++++++++++++++ .../sys_info/server.txt | 1 + .../sys_info/uname_-a.txt | 1 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 92 ++++ ..._test_galactica1.3b_medmcqa_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 72 +++ ...test_galactica1.3b_pubmedqa_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 82 ++++ ...ew_test_galactica1.3b_usmle_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../test_gpt2_gsm8k_4gpu_max100/comparison.sh | 2 + .../input_new.json | 0 .../input_old.json | 10 + .../new_test_gpt2_gsm8k_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 92 ++++ .../new_test_gpt2_medmcqa_1gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 10 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 92 ++++ .../new_test_gpt2_medmcqa_1gpu_max25.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 10 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 92 ++++ .../new_test_gpt2_medmcqa_2gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 10 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 92 ++++ .../new_test_gpt2_medmcqa_2gpu_max25.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 10 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 92 ++++ .../new_test_gpt2_medmcqa_2gpu_max50.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 10 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 92 ++++ .../new_test_gpt2_medmcqa_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 72 +++ .../new_test_gpt2_pubmedqa_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../test_gpt2_usmle_4gpu_max100/comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 82 ++++ .../new_test_gpt2_usmle_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 0 .../input_old.json | 10 + .../new_test_gpt2l_gsm8k_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 92 ++++ .../new_test_gpt2l_medmcqa_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 72 +++ .../new_test_gpt2l_pubmedqa_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 82 ++++ .../new_test_gpt2l_usmle_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 0 .../input_old.json | 10 + .../new_test_gpt2m_gsm8k_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 92 ++++ .../new_test_gpt2m_medmcqa_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 72 +++ .../new_test_gpt2m_pubmedqa_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 82 ++++ .../new_test_gpt2m_usmle_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + requirements.txt | 22 + scripts/bash.sh | 3 + scripts/convert_llama_weights_to_hf.py | 279 +++++++++++ scripts/run_finetune.sh | 39 ++ scripts/run_finetune_with_lora.sh | 41 ++ scripts/run_inference.sh | 9 + scripts/run_inference_with_lora.sh | 13 + scripts/run_regression_test.sh | 43 ++ scripts/run_unittest.sh | 3 + setup.py | 44 ++ src/lmflow/__init__.py | 13 + src/lmflow/args.py | 451 ++++++++++++++++++ src/lmflow/datasets/__init__.py | 6 + src/lmflow/datasets/dataset.py | 205 ++++++++ src/lmflow/models/__init__.py | 0 src/lmflow/models/auto_model.py | 14 + src/lmflow/models/base_model.py | 12 + src/lmflow/models/decoder_model.py | 22 + src/lmflow/models/hf_decoder_model.py | 371 ++++++++++++++ src/lmflow/models/interfaces/__init__.py | 0 src/lmflow/models/interfaces/tunable.py | 10 + src/lmflow/pipeline/__init__.py | 0 src/lmflow/pipeline/auto_pipeline.py | 41 ++ src/lmflow/pipeline/base_pipeline.py | 9 + src/lmflow/pipeline/base_tuner.py | 20 + src/lmflow/pipeline/finetuner.py | 264 ++++++++++ src/lmflow/pipeline/inferencer.py | 185 +++++++ src/lmflow/utils/__init__.py | 0 src/lmflow/utils/data_utils.py | 212 ++++++++ src/lmflow/version.py | 1 + tests/__init__.py | 0 tests/datasets/__init__.py | 0 tests/datasets/test_dataset.py | 39 ++ tests/models/__init__.py | 0 tests/models/test_hf_decoder_model.py | 108 +++++ tests/utils/__init__.py | 1 + tests/utils/test_data_utils.py | 87 ++++ 243 files changed, 8720 insertions(+) create mode 100644 .github/workflows/documentation.yaml create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 assets/features.png create mode 100644 assets/logo.png create mode 100644 configs/ds_config_zero2.json create mode 100644 configs/ds_config_zero3.json create mode 100644 docs/requirements.txt create mode 100644 docs/source/_static/IT_sample1.png create mode 100644 docs/source/_static/IT_sample2.png create mode 100644 docs/source/_static/IT_sample3.png create mode 100644 docs/source/_static/IT_sample4.png create mode 100644 docs/source/_static/IT_sample5.png create mode 100644 docs/source/_static/IT_sample6.png create mode 100644 docs/source/_static/IT_sample7.png create mode 100644 docs/source/_static/check_before_after_lora_tuning.jsonl create mode 100644 docs/source/_static/logo.png create mode 100644 docs/source/_static/logo.svg create mode 100644 docs/source/_static/logo2.svg create mode 100644 docs/source/_static/logo3.svg create mode 100644 docs/source/_static/logo4.svg create mode 100644 docs/source/_static/logo5.svg create mode 100644 docs/source/_static/logo6.svg create mode 100644 docs/source/about/authors.md create mode 100644 docs/source/about/changelog.md create mode 100644 docs/source/about/index.md create mode 100644 docs/source/api/_autosummary/lmflow.args.rst create mode 100644 docs/source/conf.py create mode 100644 docs/source/documentation/data.md create mode 100644 docs/source/documentation/index.md create mode 100644 docs/source/documentation/infer.md create mode 100644 docs/source/documentation/model.md create mode 100644 docs/source/documentation/tuning.md create mode 100644 docs/source/examples/DATASETS.md create mode 100644 docs/source/examples/index.md create mode 100644 docs/source/examples/medical_finetune.md create mode 100644 docs/source/index.md create mode 100644 examples/ds_config.json create mode 100644 examples/finetune.py create mode 100644 examples/inference.py create mode 100644 regression_test/download_finetune_regression_test.sh create mode 100644 regression_test/test-finetune-00001_gpt2-example/commit.txt create mode 100644 regression_test/test-finetune-00001_gpt2-example/compare.sh create mode 100644 regression_test/test-finetune-00001_gpt2-example/cuda_version.txt create mode 100644 regression_test/test-finetune-00001_gpt2-example/ds_config_zero2.json create mode 100644 regression_test/test-finetune-00001_gpt2-example/gpu_type.txt create mode 100755 regression_test/test-finetune-00001_gpt2-example/new_test-finetune-00001_gpt2-example.sh create mode 100644 regression_test/test-finetune-00001_gpt2-example/nvcc_version.txt create mode 100644 regression_test/test-finetune-00001_gpt2-example/pip_list.txt create mode 100644 regression_test/test-finetune-00001_gpt2-example/server.txt create mode 100755 regression_test/test-finetune-00001_gpt2-example/test-finetune-00001_gpt2-example.sh create mode 100644 regression_test/test-finetune-00001_gpt2-example/uname_-a.txt create mode 100644 regression_test/test-finetune-00002-from-00001_fp16/ds_config_zero2.json create mode 100755 regression_test/test-finetune-00002-from-00001_fp16/new_test-finetune-00002-from-00001_fp16.sh create mode 100644 regression_test/test-finetune-00003-from-00001_full-precision/ds_config_zero2.json create mode 100755 regression_test/test-finetune-00003-from-00001_full-precision/new_test-finetune-00003-from-00001_full-precision.sh create mode 100755 regression_test/test-finetune-00003-from-00001_full-precision/test-finetune-00003-from-00001_full-precision.sh create mode 100644 regression_test/test-finetune-00004-from-00001_larger-lr/ds_config_zero2.json create mode 100755 regression_test/test-finetune-00004-from-00001_larger-lr/new_test-finetune-00004-from-00001_larger-lr.sh create mode 100755 regression_test/test-finetune-00004-from-00001_larger-lr/test-finetune-00004-from-00001_larger-lr.sh create mode 100644 regression_test/test-finetune-00005-from-00001_default-lr/ds_config_zero2.json create mode 100755 regression_test/test-finetune-00005-from-00001_default-lr/new_test-finetune-00005-from-00001_default-lr.sh create mode 100755 regression_test/test-finetune-00005-from-00001_default-lr/test-finetune-00005-from-00001_default-lr.sh create mode 100644 regression_test/test-finetune-00006-from-00001_multigpu/ds_config_zero2.json create mode 100755 regression_test/test-finetune-00006-from-00001_multigpu/new_test-finetune-00006-from-00001_multigpu.sh create mode 100755 regression_test/test-finetune-00006-from-00001_multigpu/test-finetune-00006-from-00001_multigpu.sh create mode 100644 regression_test/test-finetune-00007-from-00001_longer-training/ds_config_zero2.json create mode 100755 regression_test/test-finetune-00007-from-00001_longer-training/new_test-finetune-00007-from-00001_longer-training.sh create mode 100755 regression_test/test-finetune-00007-from-00001_longer-training/test-finetune-00007-from-00001_longer-training.sh create mode 100644 regression_test/test-finetune-00008-from-00001_gpt2-large/ds_config_zero2.json create mode 100755 regression_test/test-finetune-00008-from-00001_gpt2-large/new_test-finetune-00008-from-00001_gpt2-large.sh create mode 100755 regression_test/test-finetune-00008-from-00001_gpt2-large/test-finetune-00008-from-00001_gpt2-large.sh create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/comparison.sh create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/input_new.json create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/input_old.json create mode 120000 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/new_test_galactica1.3b_gsm8k_4gpu_max100.sh create mode 100755 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/output_old.json create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/sys_info/commit.txt create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/sys_info/cuda_version.txt create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/sys_info/gpu_type.txt create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/sys_info/nvcc_version.txt create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/sys_info/pip_list.txt create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/sys_info/server.txt create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/sys_info/uname_-a.txt create mode 100644 regression_test/test_galactica1.3b_medmcqa_4gpu_max100/comparison.sh create mode 100644 regression_test/test_galactica1.3b_medmcqa_4gpu_max100/input_new.json create mode 100644 regression_test/test_galactica1.3b_medmcqa_4gpu_max100/input_old.json create mode 120000 regression_test/test_galactica1.3b_medmcqa_4gpu_max100/new_test_galactica1.3b_medmcqa_4gpu_max100.sh create mode 100755 regression_test/test_galactica1.3b_medmcqa_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_galactica1.3b_medmcqa_4gpu_max100/output_old.json create mode 100644 regression_test/test_galactica1.3b_pubmedqa_4gpu_max100/comparison.sh create mode 100644 regression_test/test_galactica1.3b_pubmedqa_4gpu_max100/input_new.json create mode 100644 regression_test/test_galactica1.3b_pubmedqa_4gpu_max100/input_old.json create mode 120000 regression_test/test_galactica1.3b_pubmedqa_4gpu_max100/new_test_galactica1.3b_pubmedqa_4gpu_max100.sh create mode 100755 regression_test/test_galactica1.3b_pubmedqa_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_galactica1.3b_pubmedqa_4gpu_max100/output_old.json create mode 100644 regression_test/test_galactica1.3b_usmle_4gpu_max100/comparison.sh create mode 100644 regression_test/test_galactica1.3b_usmle_4gpu_max100/input_new.json create mode 100644 regression_test/test_galactica1.3b_usmle_4gpu_max100/input_old.json create mode 120000 regression_test/test_galactica1.3b_usmle_4gpu_max100/new_test_galactica1.3b_usmle_4gpu_max100.sh create mode 100755 regression_test/test_galactica1.3b_usmle_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_galactica1.3b_usmle_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2_gsm8k_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2_gsm8k_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2_gsm8k_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2_gsm8k_4gpu_max100/new_test_gpt2_gsm8k_4gpu_max100.sh create mode 100755 regression_test/test_gpt2_gsm8k_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2_gsm8k_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2_medmcqa_1gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_1gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2_medmcqa_1gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2_medmcqa_1gpu_max100/new_test_gpt2_medmcqa_1gpu_max100.sh create mode 100755 regression_test/test_gpt2_medmcqa_1gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_1gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2_medmcqa_1gpu_max25/comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_1gpu_max25/input_new.json create mode 100644 regression_test/test_gpt2_medmcqa_1gpu_max25/input_old.json create mode 120000 regression_test/test_gpt2_medmcqa_1gpu_max25/new_test_gpt2_medmcqa_1gpu_max25.sh create mode 100755 regression_test/test_gpt2_medmcqa_1gpu_max25/old_comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_1gpu_max25/output_old.json create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2_medmcqa_2gpu_max100/new_test_gpt2_medmcqa_2gpu_max100.sh create mode 100755 regression_test/test_gpt2_medmcqa_2gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max25/comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max25/input_new.json create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max25/input_old.json create mode 120000 regression_test/test_gpt2_medmcqa_2gpu_max25/new_test_gpt2_medmcqa_2gpu_max25.sh create mode 100755 regression_test/test_gpt2_medmcqa_2gpu_max25/old_comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max25/output_old.json create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max50/comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max50/input_new.json create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max50/input_old.json create mode 120000 regression_test/test_gpt2_medmcqa_2gpu_max50/new_test_gpt2_medmcqa_2gpu_max50.sh create mode 100755 regression_test/test_gpt2_medmcqa_2gpu_max50/old_comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max50/output_old.json create mode 100644 regression_test/test_gpt2_medmcqa_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2_medmcqa_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2_medmcqa_4gpu_max100/new_test_gpt2_medmcqa_4gpu_max100.sh create mode 100755 regression_test/test_gpt2_medmcqa_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2_pubmedqa_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2_pubmedqa_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2_pubmedqa_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2_pubmedqa_4gpu_max100/new_test_gpt2_pubmedqa_4gpu_max100.sh create mode 100755 regression_test/test_gpt2_pubmedqa_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2_pubmedqa_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2_usmle_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2_usmle_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2_usmle_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2_usmle_4gpu_max100/new_test_gpt2_usmle_4gpu_max100.sh create mode 100755 regression_test/test_gpt2_usmle_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2_usmle_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2l_gsm8k_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2l_gsm8k_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2l_gsm8k_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2l_gsm8k_4gpu_max100/new_test_gpt2l_gsm8k_4gpu_max100.sh create mode 100755 regression_test/test_gpt2l_gsm8k_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2l_gsm8k_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2l_medmcqa_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2l_medmcqa_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2l_medmcqa_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2l_medmcqa_4gpu_max100/new_test_gpt2l_medmcqa_4gpu_max100.sh create mode 100755 regression_test/test_gpt2l_medmcqa_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2l_medmcqa_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2l_pubmedqa_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2l_pubmedqa_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2l_pubmedqa_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2l_pubmedqa_4gpu_max100/new_test_gpt2l_pubmedqa_4gpu_max100.sh create mode 100755 regression_test/test_gpt2l_pubmedqa_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2l_pubmedqa_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2l_usmle_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2l_usmle_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2l_usmle_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2l_usmle_4gpu_max100/new_test_gpt2l_usmle_4gpu_max100.sh create mode 100755 regression_test/test_gpt2l_usmle_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2l_usmle_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2m_gsm8k_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2m_gsm8k_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2m_gsm8k_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2m_gsm8k_4gpu_max100/new_test_gpt2m_gsm8k_4gpu_max100.sh create mode 100755 regression_test/test_gpt2m_gsm8k_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2m_gsm8k_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2m_medmcqa_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2m_medmcqa_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2m_medmcqa_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2m_medmcqa_4gpu_max100/new_test_gpt2m_medmcqa_4gpu_max100.sh create mode 100755 regression_test/test_gpt2m_medmcqa_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2m_medmcqa_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2m_pubmedqa_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2m_pubmedqa_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2m_pubmedqa_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2m_pubmedqa_4gpu_max100/new_test_gpt2m_pubmedqa_4gpu_max100.sh create mode 100755 regression_test/test_gpt2m_pubmedqa_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2m_pubmedqa_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2m_usmle_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2m_usmle_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2m_usmle_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2m_usmle_4gpu_max100/new_test_gpt2m_usmle_4gpu_max100.sh create mode 100755 regression_test/test_gpt2m_usmle_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2m_usmle_4gpu_max100/output_old.json create mode 100644 requirements.txt create mode 100644 scripts/bash.sh create mode 100644 scripts/convert_llama_weights_to_hf.py create mode 100755 scripts/run_finetune.sh create mode 100755 scripts/run_finetune_with_lora.sh create mode 100755 scripts/run_inference.sh create mode 100755 scripts/run_inference_with_lora.sh create mode 100755 scripts/run_regression_test.sh create mode 100755 scripts/run_unittest.sh create mode 100644 setup.py create mode 100644 src/lmflow/__init__.py create mode 100644 src/lmflow/args.py create mode 100644 src/lmflow/datasets/__init__.py create mode 100644 src/lmflow/datasets/dataset.py create mode 100644 src/lmflow/models/__init__.py create mode 100644 src/lmflow/models/auto_model.py create mode 100644 src/lmflow/models/base_model.py create mode 100644 src/lmflow/models/decoder_model.py create mode 100644 src/lmflow/models/hf_decoder_model.py create mode 100644 src/lmflow/models/interfaces/__init__.py create mode 100644 src/lmflow/models/interfaces/tunable.py create mode 100644 src/lmflow/pipeline/__init__.py create mode 100644 src/lmflow/pipeline/auto_pipeline.py create mode 100644 src/lmflow/pipeline/base_pipeline.py create mode 100644 src/lmflow/pipeline/base_tuner.py create mode 100644 src/lmflow/pipeline/finetuner.py create mode 100644 src/lmflow/pipeline/inferencer.py create mode 100644 src/lmflow/utils/__init__.py create mode 100644 src/lmflow/utils/data_utils.py create mode 100644 src/lmflow/version.py create mode 100644 tests/__init__.py create mode 100644 tests/datasets/__init__.py create mode 100644 tests/datasets/test_dataset.py create mode 100644 tests/models/__init__.py create mode 100644 tests/models/test_hf_decoder_model.py create mode 100644 tests/utils/__init__.py create mode 100644 tests/utils/test_data_utils.py diff --git a/.github/workflows/documentation.yaml b/.github/workflows/documentation.yaml new file mode 100644 index 000000000..0f2e57b40 --- /dev/null +++ b/.github/workflows/documentation.yaml @@ -0,0 +1,35 @@ +name: Docs +on: [push, pull_request, workflow_dispatch] +jobs: + docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 + - name: Install dependencies + run: | + pip install sphinx + pip install matplotlib + pip install numpydoc + - name: Install torch + run: | + pip install torch + - name: Install numpy + run: | + pip install numpy + - name: Install dependencies + run: | + pip install -r ./docs/requirements.txt + - name: Install current pkg + run: | + pip install -e . + - name: Sphinx build + run: | + sphinx-build docs/source _build + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + publish_branch: gh-pages + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: _build/ + force_orphan: true diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..b7a594dbd --- /dev/null +++ b/.gitignore @@ -0,0 +1,180 @@ +# Initially taken from Github's Python gitignore file + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class +_build + +# C extensions +*.so + +# tests and logs +tests/fixtures/cached_*_text.txt +logs/ +lightning_logs/ +lang_code_data/ +log/ +regression_test/*/new_output_models +regression_test/*/new_log +output_dir/ + +# data files +data/ + +# output models +output_models/ + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# vscode +.vs +.vscode + +# Pycharm +.idea + +# TF code +tensorflow_code + +# Models +proc_data + +# examples +runs +/runs_old +/wandb +/examples/runs +/examples/**/*.args +/examples/rag/sweep + +# data +# /data +serialization_dir + +# emacs +*.*~ +debug.env + +# vim +.*.swp + +#ctags +tags + +# pre-commit +.pre-commit* + +# .lock +*.lock + +# DS_Store (MacOS) +.DS_Store + +# ruff +.ruff_cache diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..f49a4e16e --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 000000000..903863e7b --- /dev/null +++ b/README.md @@ -0,0 +1,266 @@ +
+
+
+
+
$jHlsR}Eu?iHVKFV_U})H^alg2jq5lbR8g& za~!x|0(td|zd`%`=9+LvxRRo%v8^@lgGaUxO?aPJ+u_=Qh(8epZ>>!nAFw>Jwz6>$ zeImhjaD^y%kNcR9jpg7HM@tDdxRNT1j4i^1MTnQ5m!A!GoP~u&9P!9hR9*J=-`l~z zB-kE1I@*cy@wvFT@VW@{+9J&Ou0f$tK7Ii{0RbLx1&@QPjpKtSJT?yOe;UEJBWvPd zj4-!zG`F>3!L|F~p{;?6B8?4S#xV(GtdX@hKPXp!S(;kH%C4Gb0_@hP646oBLCj{&sYC>tCoWaLdMn_ z^yvsYTCcx1|NG_N8^!r>Q~$>lf9!nlDKIqbxH#Y8qQQ=T_hT;w>&Rd(tD*^B0m^Vc z1nl6? fWi_<5272t*1ZFDtG2gkUkjJl{k|w^mqQlt%vTB|*09*NcgQzp?~- zac9{jBGnZXj`1)kWUTt$qtbFerBM5rl}e=Zc#3~f%H;`f8j)wuh`63hxe#8wc8wLe z58K{Y-Wa~>w(QnX-aWVp%eELt=ekr|4s`0y#Bb*A{_ Rt z|K@EenRpYVmFL{?|Mtd%PTp}Ed4Hgg{;zw*-F%(+M81_bJmS9_@87wRz$-}pn`s_i zD )Q$PIw>$BYV-1oP~Ycn#P z4^eE?NiIGsO+B=Bjp2tlfk)jMcLbhaM4k|0pKb47n5F(D=^%&aHlrBtnjiep)jjhR zzc>uGqyAE!kuD+DxAnB%*chZ073(D0epRX{0MFiTccmI#RaRi{9CqtSS=3nnvOAK1 z<{R@!Ev=NH-9B9G4gTuDQ{QOygSu_ta}>WwZf)a(fKeGa7>Q69#kL@F^(GVb<++QJ zkbvWO@-w|H<@Xd#t7vHF fF71;7> ?i2vjV+5%jZFS-fdQ zUZCS6kzV{D?|_xjOp uRN(7j6&h1?#;Jv12YPzJ2J3i_|_C4(yfIH6i3GLlJi(>J%*h*09dG zSt6cZ{J8BR$ckZ~oo8xjVZ;p_%pduH{Tr5S zIAQ$$)=8PYANOCEj6!oYb_?@52S)s`Vaw-v(0^v+lX}ajN##6yzRup4P`)OH4U4LR zH9g^7fxLES2U}dDWs@e=e=zVP 1ayLP>S;s zG-oJxsj(0b_0#Z|NN3ovGg`xV>HU&sEvZ^rMqX*g=r`!%`z2McdAuuzBAtoPt@NKO zpu1q!>n!7u<7=a4XsuSc5wC6CzhSI f2cs0Ohq;+-I@SOuMOTZdwETzxiyVp8UYE7*%2x)c5n|AK7(HoCS zKlfFjRAU#;i6^oy*8Gn}6+s@B!%=!I!@Xr23+ne9NQXO0b8K6O6V?hhhS6q!u`NaD z7l$m|>lfINDV3=>nV1#WE;`+cHPqOUagwRHM%6kHj849fX9?gmbj)DRmrFOS%Q>nI zJS=N@Q6}#BOIE|!(yCD?$Z!q3`tSy}`$W#Y;KgGs`AF j8N zzo*yZ|Bu$?jOhHF(o1pk?Ay}PZ6J*+WXz)f{<;9(;QW#LujdkwGe{7&VvSk{s0XR$ z-oergH+3HAGF!FO f*>d@zSxxQ_ZyutLrGfg!hsG zW `7w`BPsl6TX$k)5aW=HkfZ7->lh0lR9O}(Z;Qhmu7q17Q)+5 zim>%0yifPF$4=B+L7Ns@14lJU%AM$9^O>{57?A>nv7tPNa;$aiOlYt}>y~yUXsG(i zMpc&A`R(;+#D%snooO3hJT&WQ;0@9KJg#n2ir*$F-b|K-Qh%6jUhz ri zax5%*kp7Xo`}tteXfBm@6NCAeJNZkFP}^0EZw}v`*fYaT)rC9cdCAuTV^i>CcKQj# z2Xl%# yqUx4&Jxzkv9`JV7!2GH&P+V%5%~QL*}e4EfbQ(vzjeh>)wf zNchR1Ni^Ec7sHQv{fjb@lX^j)v%yP&j yT@Qtpb(SK13)C*gKFU5~f75Hf zO!9K7Sy))vlAukcfBu)Ti-&R|iq%`C3wt)OSfvufCDN&5=;7qjexrZgCn}=b)@rV- z#XN51p`>>3-n%vDu_bp4kH`XrScY*PpGcQcC!J-A3EC8j^lSUMCbz~lYS__7-oh{I zt<+_rfxh+Ia-i`c(TzP8`b?R+NOL)++RMi2ye6xx204;s CWwKb+xFHX{Q*V7=b0JflCRg346jS}+)g+G58KIF;|v=`9gkBx)EfoA z2_~rvg=0L874D<@Y~>9Y9q#BXP^Y?ICgdKbb(wvUC8U86Qnim66h}!lrc5@gjQorg zt3992` B#M|AH;g3DMry7=x6l3~g8`eg96%*og7Du;pQ^ked% zt#dgBEf@xw8Wwc<9EoA5lGculkcJ?M>!ZcFtEj2j@RyF6V*c)@yt0QBn@2Q#B>_?p zju@|A+UKm9g&7ExYGd}(Bdqh^HfqZ|UnCd8=Rf|rE|G;)z>^uqQo};qzhXH-A)p)# zhWnv6J@G$>>s~kV_{$gzgZ#=daz#5^yP)Eyc#t{=0+62bRCKR +~qw)vo1T~^v zgnBA-?>=KljfH`ma&Kvl*hdumDI+NA^302`ms~FXyk5IKy8KI6-Ttkv{!Z~F3Z9O& z&`Cu@U0J8LS%Ih{4;r8#EPt0s*<(eFP&@BMoHWf!?Rsaq|3~*D_Q-P8&Mqv!hG(1R z=>7O{c#=~`;6ObLY8?vwP5QGzNyufyUXJ;(E|KPg^IrTjN#e%o@p~G||F|b;9K&Rl zXi5~B#8Xc_^<(;!`}stRjxZL5od||DawzPC$ r8gZ|1{+-zp?5yqDI;N?xc@k)v}W3uxHMPGFtv2LNTKOcOPWHK+b z(eFWUgog0-nam2-?dtEn(2&=s;-&^l1WYz`7J!8Z>7Ua{ldl~68NH^GSfHW2e ~f&duZ9MrpLdurFWSB?vmAaHjnn1b;QpRk=TE9P)newAK`z- z_eDCcFHatFX=$h;9vuTiZ->pe4;S3?;L(Y7UO5KUA-uYBtXzh1Kjig{WnOjZCWYU# z6Ma6?Zoi`NK}w{8cw#1$2EGMKrP-BBrNdaHG%wjCHIt-g)nv0+xt@e|mZ5LZvJ9hK z4#g;|!Tg3`=gvaR@SKGNVn;g0#P+1e28qL@6C;tU!TI8~LT|E&*6D_KIk@8n#>$Po2D|ZmmqE!ZKK@)rV{ d7JIzE4X z(2?eFPT4?Hs{`IV=avO?p2jzR$H-r5CnC8*n|2t(G&TF%-Y&j8KRC%Z(Oa6zJz-v? zn-g6UvaZpnu {1DMB6}%#|F^42EG0V{^G`kRkB&xPbCI?xRlqXqBI=O{cw1*80g-7Jp#a=iF_4 zS*28BpjQ@+5*2PRZ>6i8XYXgwUZg}6QC9s B z55olgt=*|t7hMYYnxsQHuIy0?k56Te6z5qNq_&0CbcH=E(;eCod!LPV<0u0PjIM0n z?-BfzV`z0<%d2W>LiI`dZZnB-E;I4fAVFqtBtaGIqCXcn$UAx}BPM&&11e6_SY zle-kt^*gW<;XBN8oV$X~j!WVV>p7$PtwmJ%ANh>#doMYbzyzRyuhP$;l7dFUB5r-X zX_Oq+e@hM3#_EbqDh$Xu96w;p`sl}K8PovP7UM|58D>9 oXp+no_wp$Hr7z%+er)_k h#TPFc#sk{LL3CGTt1L_WrdpKUhSuNYBO3_KcN`oKD8r zo@M96wcK5s^lWrk^C11jPp1t-jWmT~S7IN0g|W_@+kTp;#T3^Vqg0~vKNg$mV6jn8s-{Lyvi=B1n!@6A>Zb?Qotjm;Eez2VBixN~`Z|>5eGvs&kC1yeT z##sX|NP_O7^uy&0*VZLXG?xBZ1dfx2Df10e1Erp%CIAP8Q?xd#{7g*zU(gd3!Z9^~ zgb-L|30E=Y`G)n(BnQv;gxm{(_f6s-1s9ohZm3o6q}DxrNEG>6^EA5nXYQVf2BYO* z=@4G!+Fd7KtS9)o>A!!fQJA)O#bw}R+vND#83lL7hBoQ#rlqU=H_9?AN|Qz}&xm*H z=;dPX^|!=J!hQ^o?`^>R)OMtKGmM#UqnQKOYYpx<4tMk&Mw*KdAFW-konVF)y-%*s z1LrZ%FyesQ9wfZhBqT3d{u*O0!yGoO^T@(R!^v7wjE8y)u2FH1Ha4D!Wcf*>*i&VF z{Sdx8zX`4cjnI$GWt+O;L)baie3~S#J<7=+oods!=?O`<%I$V)7b)3h0;YpveTBk? zx0KthvvQZrgj?E*(n{k+*GqCESI}f4Mz*1Gy+5BxHc6l4+8D6&G=?D>EY?J|_00Yi z2=Ly#&znuBYF`+xw2rZC-*>VNU3iCq%HzhX5$%o}ueoI7&NpIsFf?6@+4ZtnDqVW4 zSdXsANSLf0hYKg_Yq~*X`u*PnN`r@~yEn0OpwtdM_6v2UiQ`uJ7d@Nu7Z3M~gfOBz zRZ72*X^f;D2!^>?>}?b^Hu-uQbKxkZfkY=)e@&{bgH=jvciYb| 1}3xseaH5 z#~Tiz&k}h(6juFk_bA+m`YgHA?9khMV)YKK&f7sy(Dn^(r$~^(6or&EObcad+Cy#H zocmQU`hMuDY<-|Lrb>f&M1|hkR-^l17;nS|NjdA4nO8L}PVw5o2H9nJ3I_r5nH1Xo zx6F`$v@gbI(c|Z`eJZ8o* ?_+PHEk m{=2`D}T~unRlGhSLbZ^;`OKQC9cb&*?mtNK~RIx9$iqmK2sVXv<$G{h+zVVnu z7T -a@CEivEb+IJWQC#<1=3X3eMA=hf2Bc)HW3s}Ymb9+X=iG8M@i zb7sG`l8=KTK}H}+InT_oY$sxd{D8L*g?Xm!fyRxliY6zuV${0XKkdJeLhEF;v5$|h zrwOAa9RPX8Js*^{_T`$~zt~yci-^=na?j!wstj}RywNLw& DEx_0dI7?8{aQG@hB<1$R;i8{Sn 3$k{AhE^{gv%*`EI(zMyF z95O_2exn|2FpY(@ioX1(@+nNX;`+Nct4-Vw5d0-Bp_P>;_Eb(_dtuAY{e&zr+Y*N> zGjb|gxu`5#R75m+{>awHrK4TuMIHk8c#N?Y6Gi? }b?v zXP0fHMs5Ww9b=;aK~$v&)dt>U0ds{*fw+HTYQBi_7<}3^ZlG5jF|E_8rR=c^YJY7! zlHd+qsVb?aE8%N`QfSW41$1uDIGm0$&HN7H-?kH $I9_FHWr^n*Pqndh9?EAy-_QZjg=eImWvY# zZ{%*PWTCih`)u|YyLIBqo8{P$0)c+CoC2;?yeST95|XEa69}SI`SI=W%MoHk?Dez7 z&l%}1tIxQb$8Bg)1@?Ru!oJms%Nn SdLz25LqNB^mU3s< zDd2Kok|BsHf5)`{x~ipEfi5-zv8uGRRcnl0J6Fk$+L_I1DFLOiTfvFq!iF=PpFx!~ zp}+Aye%2!A2{FPejags}t`Qp~Kc(675FXDs&?NAib@*Zfl7YOwv5r|b*s!Vm#4&h> ztF4`+VbUN8+*F!aTkm!VuUtzn%!vg4^3|b+^Yekgl;crcWdu>e )Mc4F&Y8Q6Dk3-(~5Pz!g)}56I-q-szgQUVMU3!^(qb%kQfRdj3mIQ>D~?G zo4^K6<@kZ857l;rpHZ-PgKEt+M(leF`ca!1XxX}$_U)vKsbXnUl~BzjqX3o1-X bgyrMM^AjYb@`RbRK+ma*Vie|Ai#nLpsR9 z8>J*X+OtC3DuhJvy7|(^ufxtz-2xRGxmF4fs`-bs2CKyInn}jx*#t8yV7xPmhdqWt zU>)BsSy1Lz?X0$LEA=SwRXbiqz7c|oEU#aS(us@G7%Ik&ay8~Dcv;hVxK{&5gBcB> z$fIoChKHX5w44<92Q2{PjahBw7m=rTUki^7NKCO(&k3uQXMnX=(o}D0_H!)BwRQZ} ziNm~RM|qb@WVfy3lvc3E`qUu(I(by`A$ud^$$yO3GiR@=dUMeBK=boRXOdtIs}|j> zcjL5c^-Mal(@GT?D`xd#vCg)k5QQD-H!Asy*D!MUodLSj{`&{yS4a#`nUNOn*LP?q z@?>)d_SxS3&M*WLu=A@7$Q-Ol$Dk|+ay3}&*Q}v0@T{S}7iHsoQIq&-vH08~(@gr% zLY`l>{j0JPSGaSDALfKpjYewjGEbF?Ur)CX)U4Goa2ExY%_Uloc{b|EE?^-If~bKd zv}^CyRlI6t@zElyAFs2`6!7SUv?g=Hzh5HVSn()rEy%gDp;b1F=y>g!9dDn)-g#;` zA{^wK6!V}K);~+bT`(Tv& Of`K9j4;+)tKNte$$QTwCl?HJ z3iE53{j~Mgvi|>lEatn>7mT3m#H|?56<75R@hm2TmP{2`n#wN2+Tby`DXZpyam8%2 z!#7^Us#QwO?vm|tg4zAYMBG;&92R`0Wg*PC_y8!L*7cdmFU@BJyJ^c2egm3u$=HNh zk@UAii22_ucY0>dXMM>ffj<;nCsx1?w63*`v>m2xNM*8m;m h#{cvY%q|K^`x6KLUbuOuj6PVG|&{G~Qbn|t6#xZjp*q}wg_#YcP zv7a0#OG-l |qt2 z-|P=_>JxF(ZUxw#uQylrGInjf>YU@5j>0&XBwaIDpMpN7EuSWVYp1jvx??N^Mn&%R zv1K-jGG9@05S{~LLhu;JT?fmN<=T;MJwC5-sZ% NU#$J80fwb@-)fH z*7tGv*y<~T>~VAGp8k^AUz_DZ-F!iBSx3D^9`tsi9BX0?^2$>kl){U I(~V0C1MX`O7*`f+#SVbKWZX;wM^%9sZs?U{E6L)y+lF8@U33;WE4{ zD?;4gY(MQjbUjTbse% o_|VOeGco#`&M zL`S63ze!a{td>qP8hlfNm-2w)e@p^G0R1$N9qd9R8a0>qc}TUahqId?)O&3$I`-Q! zGdIMdMWT~?fSr=wXsF!xVv8@|CT?Z@ez;d0Lxf}N>rK6UamVxPgHtK yHBb z#*gBi*^IG$HiH5)-D%p<0$VZqUTkE*U}a-ZEyt@RPmQUU9!^D{tbV_aIa^@OmWVrq zS+d3{`l)**>o}j&1J%|h>kHpYgt8+XVAjLhDo|j*3c!sQk*m3tzg9Uv>miQ}dG@a~ zI-bvf4ftIle7=@%mw*j1|MEw@X@-p! )o zWNIv_9!@$GIdmG?ShxRbyt_qFoFJ;H-_UEf?~(=j*yNY6GSa0xUA9rYJ9@*0@S-*K zj+~{;dG_!bBn+WvxJlBPC^5YKJf6tS*Gk|YRmDICfJIFYM%sL%3()(-v+BCV{SVX~ zbgqg?*eIppnw)WYsHgt0T(6GnAV?Tb6@e-edA?QSVX4rYxGzC!hjm9_YCeer`Njb` z{*&|bAgy932X-L5j1>KTR#<^{FK3DGW30>E9b&lYN+>lW3B1GYl-OZ;K#1>r )8a&PtDM#D& mX^D!r za%tml!Ek#`wV*S7rFqz E-kN-j-fYOJKViu)CUQ6kxr`&Z)BBY%Euv zhFgbNu>S)n20n3yI?@sdC tS%s2;!yfYqpQK1?Bd=mF1olK`EemV}=*z-0|^TB!&35;l%skW?X0? za$FoJ$Po*lIFX(dF?q*VsG^DIS1}{lw~pokuK$V`if)1qA=YmQBMU!R99pCN6tb+2 zmYuUipyGm&D^NmCjUmj;>&GU$!#JA+JT8S$qW)RXkeX=?0VlAv@ln`to8~8vK`S0l zZ9b41CHK5* C|Cd9eCi4I;rb)c;gF@ zLGF}k2irE5bDsuBO-{N^VFIpj=Iy2^WMKgwa<`Jn^V}JeJ-% xY^oulm96o=m~Z%xC`RuuK;ig0)U5{H;1PY`k0@) zB(^22#&WDBLcVygJ;K3qTh?&F0=lYtf0JZwK?qh?_`woyNFV4)WPiZ&jZ2)!RU8xM z0;=OBhyt6M%t7P*({}#6iUOwdDa>5`6 3MT$-{=2bBJ}1bA zlOSqN5XS5})f3jQxsdG%$W41#PB>CS*s%vU)~j0oa+@J1Aoi+oh{BWiUaMSwT8_r3 zS)F!}>1r{qszR|nVbn{M7mNnKA8`f{E1h-BmZ V?F0ZVWfa&JHFExb^`YVjKx8(b{Q)CDf%8ruJmB>D{Jzu>Cl %hgRHrLPbQjM{m0pIQtq;18PV5(fMom{UQjV zNUObm<5VW3)hbHcPh|DM@%-mXZs(2W-0t9+;foXtj0H+=nA eT(pEMKEFHf(HVS)dvm}HcWS@_Dl^Yz_kCFI z`Jlg)ZIip24Ag#j8wE{yJK##2|C}HOikl!Ye9WO!Vid>LqfaJZkAf3V6@h#;pCo7f zV0Q1=%cu}7B{jlhnD7;iU?rYq&FK+~ER(5Z#JY^@4#-(_GmoSQsGo^qj92{b#X10e zB%rbg^W4Ei@trs1jmsR6RW@i3(`bk)HgN5>K-YrmkZNlfj=L6483I_Iyn!#k8s!rI zwx0-m-3&?)%Qf2-2WN+VzN9bRAX)G O !@M2wqO)+%1j5x zs1^E-JcaEfGg)nRWHw(EM8UD&z{S7?oVqc{7jA-@NuG>jnDu+)Xl>zSU0#x;fI9=L zTnr?gZefQ8-X~abexrKeH^l}sN}3&F`)8g@^RV|Lgyg$Hij}GGzu;d4 @6y1&e8m^{fea7?2MyZn6%&u=$A1|!+8M!$YBC~t%*Oc?)#a28 z=0P#`Unqh)yu;A0)cVSrNO~r)alsAb>C@DTaze;L(e@@1ILyvI1Ak!L2u7UcD}JdT zqTtCEFIOABHoGa(? ^KwPlu_T 5pnlhNsBS!@f~&PBy(td zk4;8O_Q8O8vyABt3#*Y#9wh QLwGDQH=74yx&fT!(aAlatCxM%0MAN528A zPQd*rCQ%c(zr`3BBPjDfN}hs6$K@T+7=ov9CRJ(v4LGz06i(q`k{d(ggOLJ9AQ_m$ z)~+EDXdO^3bco9!f#=rvTj4k6kaaZp!MpAex{b=-n$EmsC6EMlNUKG5&?Era==7WK zqagnI5Gg{6)Be;0HYwl5JyQsx;`WT(>!vWz261^n-LdpoyiT*c1-6~S|K m~&D?-di3K!Lk_ zH>K MK < 0(%`}2s=-|dR|uNrt?p~njXHzcZ<*w&SS8g}ZROaS@OuV& z!J}NR9h}ydK-7h$2QLDZMVE54R{~0LDuAzCD}mU_SsP su6JqP6B;0Ptkn%91jCGK|D&N$r#A58NPgK z>lCns;A`+D7{5b`>>#TrwGvjFyMY75%&xS^S55#1Gt16Cd;-KEjw6{zia-!l@tv3C zhb2p%@&xBD>F_R{FG}Ek;SE7lw%|za2ZAUPxJ}vZ!^7@IB*YCu%GrBhp-j6Yq6O&F zr@{t-1V)fhj9$T4iumuccrrsXM^$f`d84)h=U0fDDf1sW#o#x9VsJbc|0Tv9Bosfx z*xd_t{FwmJLi0Rl@DqW+D8ahQCei0*Zjwi-!g=V7bQ#P5{D#;HBk{N i(6f wlTnNazr@;{cz*{^P*oYiJ^tT-RX)e5BgqfU>TrLz!{9H`13Rc! zGQ)Ro&VwF4TL1!bpdA=rOWbrU8~1cOsFdwLiHCVqh}lonTWDHy9B#00#7a4ZHa;Ta zP8SBF8=1MaV28K=B9{-wd+NQj%-I7->ASCd)pIE|bnLpNC$MWD%9cKIwR6`TM4utv zs~{rg;v%B!e3Oze*zC$Ul8PMOoiw$Uim A><_x6@aYI$23-~zu=AN-K1~c?C2p2A_so5@K#(3|74E#WsV&E0dV>$IbnTqV_9D z0Y0*s_%)_C*|}( PV5(N`^-+V-!umdVpab0WffDgQhCel5EvoCQZgEVl|B$)vYcCI<}iYs_n8N) zMFLM8zr#3$^GhqI%tN*WdF|h^fxQOd-MasEV1N7)kk0zpJC*$SH8EuQUlkuL XBH0z$W|||LJ)WV~hYGdvjiWielfvUH8gNd!NkW;gzwh+x z1P2ROgE9EOBL4he0Ds*1{3UQI$XPNU`=S_7Y0Nm=JtA&!`J;r#?D&n_w=@}`41zP; zr7VId%bKQyL_9}@AJ}||Qp*umhv;TjG%^8uC;!{n2CW7e9V&jD0M9>m#pFRtq}sJ7 zZ{lpNd?FuokM1>AIGp~=|1tglFgcKLfW$$kFH9cM;BPU#3nFPZGpH8EkKt58THv@j zK26I 3Um*%a+&YF5M^BbolWCH=g1CWrN(0nOiEf9oEZ&%BLD;#- zSwf#R>;4RtCKSemqD{n;{AyFnks$Jbe0A5FAwuox}No@-m3Z(C)9x z#dwMMn>=bepX9)p%u%s2cp&EY9|Sh=EbkmHiflfO9IC~S06c36;u+`$e2%CdEW>}k zfYVh)I9>I}n$>;9MR*})Wd9eu!eDG7-F@G2cMsoqa9FFNJN++a1obh857qd9$60~u zI50$s$QeAOMb?QYC=e+JmcZr7OxUsj&dYxwC{p~#hE2`%z<8(mk>7!r>V)v%Ck>}R z&^ow*;z+?ds)*)rpvR7S`#-iJ=jY7_l;?5&2;&y?!|PF_Jn|sxc $Ws1s((;y2cDY1 zxm##B*aARvfG5v^2Fhd7!>gKnp@S3(H_!mExi-XY#>s{!fa6EK{hzwq50&T3UoIT1 zln30D>hKBi`!xR&>BxeX#XcVHiyS@}kEx3|`Wb0On~vi@|456IbQTA$i7S7h?{# {g#OFK@jpMi9PaN} zo${x?qbz`P$egdqf1hX%MJ96shN5A_Q^)GJS|xGmKR$s>=HM^IsZM1;M!nJA|C> `=7U)1b9_^7 zN=8JpJ zasHXr(>3y_KtXFBN)XOgpWW!HDd){7X7QmUTy`7Zt^nt8@+xN%-74IctIPNtx~9J? z@GXH2+*iNA-oi3(#cT=%yz6DEQt{;DCA~_mmXD~QSibP}FHhXAnPLyl&DxzLo_E0< z2IK6U5!}O-)hZClzWaTKJI`8qE3Ha`T?)=ReCBH!X_8;L^=5e@)cFPt;YSMIcR%{U zlcoO;Rc{^+Wgqtc7ou*VQX$J!D!I!Ng<+O p~<}jVLC!0}!%2RgnF&|Sg?97cahwPG6K(grHNA$vo zk_nX9hRLjW_Y@k?uoYSW3TeS&dz!MlS*pR@+Q7H? cCKYp! zhUbwy*3vEm*58j=umTNY+4VTg);k4ALgm$PKdCt3-u|%mq=_pNr$u>xk?5&NvmC{Z zSpApoqDMRmNhX9YU2@c=1AJ3_2dv2lg*2Xn*1iP(#RSX$ %OH(e*I z&;Say|A~+c8;7U3H1Rkz-f+c|N6!4S)lVi2(q$MwsXCm )!cL-Bk^Z zd_@cK+K(3oF^A)d49uJ<@*9QA+Afm?{uYxy&-z{OBkoEAc!*WcdMI`-1Ijt`2>W`H z@u*%lUmuyC)>2&;9$m3uJq%~p!e8(5FFf8Mi5S>i5-ek9fx=xFv3>bH8ETa(HpvK3 zX7#6r$R2=}Qf=~W@+o !}<)-Xpq6zl%>s`&nIe(A#D{Yqc^R^_{tLr}0nW$lHh zSTiyiU_Svic*JWv-V$*70qFqE6MKdshfP$rT&Ysa(a8Y}Qcg%{_H?|C#uJ4?VnR_N zX*0ll{%I_WVKTqQxz2f5qnz$n*#kU1Q;RHe5jAkH?=v>#FHdl0Mgg0L|I2*@JSCo@ zPEv!(D|gV5@#qf3G=Xb*6g<(bws_tu+J{VsUVTxSO_jGjSlqoQ{*`X!8AmH3Kq;Kd zQMCGT!!WjjrCB~EG7Mr@gBU#23N<%vtGFJT?b{hn=*BM8`z=IK!VAOl+<|mZj;$>2 zUK{wmJ ;zSY dI{8%;l1Qfp%{j$}bMv zX^>xsdP(wKL>X>B8?ErqHrRHYDj!@vywG78UX(Sosarxdl4BVrf*2lt{a@{f=)$S= zQqrmhj=JgLEENo)546d9OgbgHkp5h#?=P4znm#FVsXu%8VO+ugr~&>-dM9Zr+sXmg zCs`FXKy{z5-POj$L?;2aU|u?fq(`+5(=;f=%M5BoXxVl5unG{NPCCzI$_nZ iH(u2+C%}O>O3??g;_WuYbZHmLv z@qjW5=_Zs?1>-{EV82=)f@X!{{*X4ZhV_xG&ZR3kXagSeIp5L#{!+j{VTrWa!gmIS z qNOCRlq04f!IHhN54+#0;|ey!iL`0f&!_g=P| zn1fw(DDx_xki{O_$4ah;OkWx{CbGJ-6g+OiyS>Z;MJB9U3aXV$3oh->)VV}~we7z# zyA639t#W0o>@7r%G#U?l8V-bI`PWW~%B+S6aIv@UT`ZLx3PcmQ6||j-(12wNXXiIc zd!rN(ga!U?0+*4t1(S2?I%fr(VsnkZM8QQ2Jl=$U9jaS#GG4>{yh6+*f;)*Q^&+i* zH_L%8uEKY-B3_{NOQ5b{%zCRC)+Un?ww-(rx_ Z+Fycp)d z%hRp2xLa1_LQUcIC+9Gb^qA8AUKGND`X13VIV)_|B-0OAh2fWs3`1c~9d*jszuB#3 zI!)%8Q;o9l4P$r@XTFl_fV**MeeC*Tpx;cOXQl<8(ke>N3G^s19{g7s{awW~x!Wm9 zquCxWDkU8X=dHt+1B7?wm$)<~7;^%|WBP>(U?(^35U=E5O|X$&D(HozT2YJXNHwrV zp+VLS4FECP(LK3bSMC)!k`Jhkem1LUv9!qr{njg0zq518H#??$HE4&^a~$N08jS;$ zgq%9g-U3-T{zO>Fipdt`*%~Hi%pa4-*%5EXMKr1#&V}2yL<~Z(-CS=@Nh}l2oq!i% zZd0vC5a=dj7FLD8x|@ji6dg0bF6v-^ hGij2Llz{UNran@gV6p{ *=i1|b) BantcL)WaWO2 n?C|IoW_(oY&RY?bcXB!gXiV{P8n>oTJdefg zG3C=LKwG&QYSjq*Srrrabn`}AJpzkbjF>+$>
O=AM7n{$UCbWjgrl9*+~*PfCXq_Fqo5qc>M?gQk1V3jlDU1f2Ti1X-d0( zM$>nI-Tdt)D7BCl(o@u|HLEa{*C(yxNcHO^#G~C+#ny0KI&O)yQ&w3fmi^MHLsQ6u zUEU9 tFWi5S7pz^x+iVR66YH*%WXiZqgT%p`DJr7rE3Mk-2BeWrBA$2 zlrSujtlN?=Wy&m`Xf3@?%zMFKCQ&hSYdD8Hm$O-I--D};+Ecju!&3c=ct#|Ib8kvY z-APiM=&$CHTuuN-GXh04&Dg^ T3jP{%8HZ)r^>M)j?70-bJdQ3_)}CM5MkZoFWJ z3{%Oei^1+$4ud8;@nRZalR3pS3wEj}J3$R$Gi5*S7#cnkaA_v|`E|a1b6pi3;a}zH z(67ORjIb-U)7p#ZuP^#LQ`@3RGyIhy(u1bN^fYCwRh%Ha{+s(+|JQn$2T*Rb7rrLy zgSRVzMHpT=ejC5aqRS`Ga vMGLn SSk2Z*y$I5!>}OdUruY#E8ofpY1`AhPNd{E+Da1t1Ol9A-}hzg+i>PcO8j!P zCp7om9gnR0p|W5P8NC^;nQ(sOxTTnHf3KwKEuuz*1ISVio){XfA*E^63z |WP{-A;x6E3S{23O8FmrO nFnlxsJ-`*Guq3k$BE1 z!>r!=tCadi$63%fWZ`F7^btRKME2yBYOgcx0q-hnsg}#DairNeR$st&Sd5V3#K!y2 z@L14P|4Dr7Db^{o*X1_--F>9ZK#_aK01DY(z_E>=@vRMm_q%tKE@feF-bN4=O~4*4 z!B#DSw(-e~@S+Zt@IKfVR9nklun^W={-|anr&EPvROy*#36t3^XRtAGSOO0h{$`Mo z-(p@6S!H?VKF!2RjV1&z*YCL}GnpY{W%S&ArlDD=HVNLF`G$cs%jNyZy|g{D4(~a& z3({j3M&%Dpwvj}voiRUYdQZG2WwzylhUQ{Hr7W-^_yD%)Q7UZeDbX)O6wG3nq2|_Q zjTbw0fnIu3riW-?vCt(4bq_7j!>$$Ju}zG6(}<*6iBl;#q*2g+lc?4jFdp8$K-Uqt zv#Y8;JP5$5uUv1s#?yghmP`iw;_dmHW0JdxNDmzSibMpsey*WNg0}Wy{BxA1G`2HT zZKHs`bmr|iY3>&(g9fpl?J0`rf=%3#&}lj|ji^y}QhV$WOemRz)Gx3^ }?8;+dIteR>)grT|us28Lr0;)q8-L{-AzJT(Bk%7;J{H!0HwpG8Hu4 zYTEBwznxFm$mD|5S&iV+Y0L2nr5ctukWX|QRCg9>+{GmczcC4x%6_g?h{$3rO%qeA z$?z&)7kfUpMzs!!_a!3;EDhvKl9Tj*3WsO#9^$p__!Hr)V*NL#P+`I^*$0)qPEANm zs(*o~ae4wuQiqzryI4qn&zj*RrneWCDDN_rpr#GmvBI}(Ey?g-jMb!9f3S`7rV2@X zM1Q(0F_70he`7^b;w*g17?#3=wK&Krua?Y&dv=E#gJelkaoO+{et0|l$%m5X^^*Nx z3BOm9i7M COOVg&yo7sA=D%cFuXM|RfNrpB9)y0|S6K$f z48(bFMIyH&hXXMUfefw -nHyw;#g_8IX|E>6ySzC=tHoX0NBr+-R5j5 z2!VM~*+?j|C&Ekv*~t(XRhq^mXQdsoB=&`;C3Kl!E>owkkd?7vbo0a{F~>o-u54=8 zhqP=iD~IO;dfC`zpl6S8-K#kP*(#wd5|8MCJmeNlJwpE7`W^)@knaKCHY|Hp8zUgJ z9?`E^x!r2Em^%jDYO#go?|fC+{>rsU$#h~Nkh9XVir6$5z3hqa*v_Y-ez%ip_YC1P zgPXGoPSnlxU4>-x!&U6^rRyVq!T?)ph;80XH+3gstDel)btej-lK+@x|F9`efRs?bsg{-DM-h kkiAAR zU81rE(dqKC? zajwBww=$M?A6n{~u@P3Auo=F7RkK@T!}7g|?(|K O2nRqQjHq?W6Srv6 z0R2MhNy(lLruJw&N`=zfAa}~M!EkaKAufT-KmbPFERj3Q -~n= zw9tf${z-R!kTiD%X9`Yp1uOt)12Cj0kXt6E$0LS;3Ov0If{*UDB&EB>a5-mtH8z;? z1|PG$XpU>My@=_*FouejHd@^a+W4uvfhd?%*T!1u-i2H4w)>WpYq9c9J3tORPanJ) zFReI{Ldy1{8X>L|BVb17C|cn9?jCN2GDl>ihx#avDyjqUh||^85VbAsv;u@&+@#dt z|5&PkzsG`hG;QbrQ{8|5p0wdXQ7KW{5D*YH{yX;K!2RjZ)z#CAUf$fcWwzl~G;TY( z!uU3p`Zv#Dr@P}gSW(R<9;{)A0MKUax+V_AQ*ZBoU}EePKvJqN>Hz}13~5;~>bd+O zTVku>(lfGhkpR=pKU(MK+;DT=7)D;KRS6~eyIKxAt^V+~iTI{oNbBKEpdps9=#l@k zZb+PrRaYyLF;)b&+i2Y2{5^+VM@UHYR?>Y*X|!a8pM28X2NQ*-?)aD04-8F;Y8;X1 zIFJiW>FjE5MU fn|MEvJOosv9tn|63^&8%bFw6Xq6(hB&p}< z5ng~e(Pa|jvOZ8ha*~G1)xokDy(8o$l96wpS??YMcOu;d6Kacihia-u%PUy7-VYT~ zBhr|Svl6n38W=C}H(N@yH6`quDVxQWEn%!{yTYQn&00%Z?=3?MRt}n~D>3+(=(E;; zGf-(Sc1R0o#SFkL;#k%;6}Z{l15pPq-vgy1z}RzXaw8jMxzyfE83t69uePFjDJ`w? znCOXM_i$O5+pzwWhczVB6WT7eV+~m(T-C>%+GNS`nDtwTUw5V5+ujFk9Rh2UDd5oW z$Z46f7NF5zxb{1A05OSe+zHoSSdoU0%fk|P$S!O$tRXH=EF z1_=8ifY1LG=d?Qu0Sb|Z&HSX8cY=sW=A3}(k(HZJA-a$I1P`C)IMh WqzhZx3E>R<7}GB+zUKx3KN~8Jn>lib${4gyj6f)NmNJA!yUY=_Wv5xKaPy* zynR@ydAe^|1mNonr-1WX^SG4ZsnB)c09-e!Up &JXV2UFO0~%6c`horLX68V*X;`|RVmzo71O4wa9h z!R;_WJjrkZ%4?wk`BSKjEcTWzXf{sFoKK?UD&h;D^oAq#u({rfl5`uMT0Ht~9bm}& z=6AK4B8{opXzr2cu|U3dh;`zUa*-a;to>@MptcJE3DG(M<#_S?H&4g-cMF;({=#+< zwiBdJfOax+7Q+m7O*qlFdx-iQ`Hpw~bN)R-_eNzFVie9&94PyGcJ<(e01)chKhmK9 zLNr+xPREpD`izON7eqC57F{P?Vcu=!rVQr(5s8-r=9~};Gh_(`-$JP{^{&lzAqR0; zH&S^sxo5-ZzS>iy7ZYNfahI^%1gJzfZxzJL k7Bn0{yBn0}o?z8u#J-wuZlRE&wZ%$U7gVj8kDJ8iMOwj2K0^wPoK*X|HK4l =wM^R1&>B@t0HJWQM~|;=NBI?yS#*zGE~wkOmB#qu|tUYmJOg^F87i>o*e+;Lf^X z2=*v!@jmnVN(#0|=`^r)Y^BM&0DsT$Mf}jgTW`+teue*}dv}vZ){QmzE)sWTTAtTt zBo_cDibnK*H0)$V0sz5s_=*&Pa%{5p$n!?q^TfjKrKT+vnzVVB6+Q%d+PSKM?l1zg zk6!*$gwIqUZ4C^*P Mj3e016zDbZhy2__kD9jL0>@cs*h;*Z%{5lt`ME<>ZWUn{+Uc zpJh$(UGf}?HC!40gB|?ip+K<+vEA+<+>C3OEz3ENn-QC4$fo5!+&ZmMKmn)7LE#Tt zjlGNccPy5DOk8x~A+5tk<|paduLyT8YX~vQr(^l2&am{Z6V=ovY%}}6n3QGI6Wsb| z5@kK}3@Ur%Vl`G0L^SeT7S9{&zS_BtfTt&s3TH0}aaA=G7ZkfpOb=^S2Pz|KPkTob z4?ph;#r=Q*GIXIWCH$ro-m@F%uZ@%3m1BjyB-fMqm6P+q`q 1{rzllh5`VrRlQeN43L~`M O1Su#t^FmivLZ^h;XnYafw4YW6nf)N#F0eF4e8f{+oRweCi3iL( z$EUnEusaNW3nO+kL*H+6VZd)aM&XECo{a2bgSezA|3$C@IUALVBPScowO`T@k{DG- zGR`<(_itS%^4Q$;&okrU6S$RkH~kF5iS`N|n(2!QR-2L1ICm1bZzj$C?S=gz>{#M< ztY3UcUHL3M3C>C?TV}T{FJOUgTr>jg_10sR=gkMi$hGH2BZP-3z9Z{Je2>y|GGjmz z_1kDyHk$2CwUxnm`MsD!!RRQ~^VUVJNtwrm!YXh7EpbKc;giUS)r7~jiA#E)7WJ2R zJ#lwY=6sjjx#VtnbxO-IEVTX4{AUe4Kv#wT2I9g>R<5cld>6OvZz}(+&2Kw3kwQ#| zpw8NUUt^We+)|k%E;SCdcY$)Q`04m}QG9yyi=M$9-AAMX!C#+Z=K%QLe^}wm)~k`O za+hB%9|7TX>-+Os+hbr_4u;#haUd%GhA7Mnx$B?qjT#!NBFH)H#bPAd;?#UXnGy}# zOJdRsFU;VB9d7a(JK784 RGe@9QY2=YFB6i;Kf z(iWcWQ2RFh6I;d P|b_@;rs@vwP0mkARyTg9EbbZM#e3IOP76G M?(T%3OXllTa zTQ~=zB1Pyoo962XLcTgf?*c?=nwl!lo4xpHY4(9)d*YafJS^Uw;w0gyU4&jFXfi)` zvs?Xk?_p29LZ|8DvS{kbE)&v(gDlpXP)N(WWOYN@@eZ(0Dc xxchYJPJ&)C1$UrquOVSBP1C^~=iAqB8{aRDXra%(q7G!Q>2+*{Jz?@U{Zms5D zjr*Erg|P82S=XoEE~xO mVDfePn|{EZyCY z)E!P`Ma=4;LM>kRhq(Q8`tr*HK3W2wv5LEte%++mUVQK=Ih*=e`ekSc(Q`6S->i4< zUj8ADVHID_Uaw%3?Fn9pxOr@FyX(ZbNVTkrceOBUwM)$7KrUu8pExY^yL(kFutf)T z54_P~Y)G3~6CX3bH%k25ZCqcsLx*jZaAcPc ~smqo%uR~?tz#7eU3S!NW zfLlMfDJ%Wf=D;36beD$TVOAB?;>P$U)rn}XLQQ&FPD_$nLZ}~j4GRLZ3hF@hNLKbT zE1UaPmBpy56MkzBq>{z8(?g$lbR=2H81-y?3W5tXyIHb!NXt7uzY1F8(X2BF!V3#m z|9wym@cH$Zu7nqD^YK@%+Rg?`=aDwdDhtJi>Ol8E{U^hjm1q33SAyiCARBM4USk*R znmrX*Zk1BGx|~Nrjz>pWUrAa#i~2$MpK?Qi+G%Xfx3di=kdcMgkp-uwDmo-IxRWw! zIT6N4RB;D^zpURTyFbw?Gef@W>s2WYm=Rt{LqJdbWuy5vQUPm(IPuNob=>hdt4?Jf zj4j^@roH=HggP-^XKxfl>0?~-oVPvEuPeLfzxBQSSU$80y`pg^rzr%Wg8?E!1M@g+ zT?z^;lqx5C+yd4(ECfv|)U1Qsz$g;X=ao-LPvysvOyM#eh4TlXnnUj57k1u34#fS% z KFIS=pQH?xRrMCW8)DsD4;4~po zSNR95wCr Sd#Y^uQG3 A+xtf$v-*e)zteuj6d^I)3>hr(bIZKyLIH*T6Z#EY)kgZ++!97pl}M z7b3Vobe9o_F2LH{TkD^WZ@-nQ3_SaNbLrChV4=A|QsND~MOz?6CEJA!U@DHh<~`{F ztBv6bI}`%5+G-*ry6S=am#uSj=(+VL0Mq%N`y7S@l+b}}R9oN#FW+kmPL%cF)bGUc z$c5yaLFZ10pFKB{`N-;FreM}xr@ZTmx6bdgx6it7=6usG;kxjV2TxLtT^Tu4cN2H1 z=kMRLzuw}@*I(ei(%8}@`lUXYmo2`p(08$OG1|fF9GHk|8v@X@ h z>w?sbdM;yGk{mZ)JRd-Jt106?jwv3ywOpr5%fA#ys7j6NE1$k{gLcKGJgm}zEYvx5 zLSoGU5<{!I#gE@%cEm1s9#`RUd>QYfZ7C_U&xXb~LWxbfqJ$DC5jD~o^~~H-_kD1F zT5V48aEGb0-t+&x-UysPh8*6ZqlZidqxwdkMfpz&-hNXnU0wCtW^^L=`F72w*D0@j%Sk?~9=<7^s z-jEoJ=$@)YLU6LLI Ih^7iCL@Q(%CU0mnZ2S! zI@TxIP_@>kvn+#~HIK8;ye+T21DRemjGvq-xfE@5$vh9S3^kFn`yov@G_oTTh(r4j zWO?4rL{KfbxC04O%Z-rWJ~vh{Rm;T;&p*>Ne0EQCDoFI3d3oJ0EsHv-!+$_rlI90r zfR(ICp;UF!PI$hZihnF4VL~Eox0bK!1a*<5W}qBKSCW!9edY7HgPc^&3VXJNcI-+H z7oy&x<+U`Vn)~{n$A*%A?YU#q1m7ho1-P7}Frm{#aJ5iGuo3~?=pIcd`g+hQ!e?-B zM8mN8kExuKJ>7lFoV5C{oC%@hJ588qFM;rNMblSuzPsAptoL;*m5@_%b4NXE8cHm? zoZ>~CjZR%bVCRgJxX*wflm6ssLR~Nj7~Mg|rA2C8al{G5(u!y=x7Egv{{AUk`DgFT zT26gmYOMNND`dj$kS5S^o9H&nc{K18j;4fPr8&?nX@xQ@QQ!tx60?_2r!A59aA@|B zYWHjxkF0x!JNX00HvRRqoPMlI9e< i*jRUI6zE#nV_&D;z(JriMbnw zXh+e$!$p;Yv*=(BEOU#=ARu24mq2Bg>r`;d%m7d@GTtu2IjXT?l#OTBBtC&u*R0G5 z=nIKyJ$feFYMJ9*cfq-2KD*3$8!(Vqc?U@B+sTUxq|&5VohC$#R?R;Y6~DW _z|0pFlYG@?yN!L&as zm@W *C{#p}e8I%&uWYD#YL|reoqf+#r$42&R_)jLQCxd)C-2%b z+ai%6jl(#~7KUP~>l|XxR#6|l^FS1?Tf#inTYRa0qCQBo9;zo}zxt%aMsB+NlSFIH zUlY>W=EV@5PtoHCBwRu-gj}$2uLYUF2>Nt%$yxvZyU2$oYPo1Rb>L7c{1a*YykzgO zJ%?Rkz@M4n1FY&Uz8l0pN)4JkS_$aUm9k37`2Ebplh*H;tw38X0j%$M=s)}|k{OY0 zsJ8d#_nWU>T~&{|j<2bRoLCpq9~-+K5I=0;eHcHa=%a5!h}1Jj`$XftBmSP_JKkh) z@LiDn!Y{z={jjPqm94i2E-E%YnqNMYG6m@qJ-@JWHj{xm@w#2Vw==j5PXQTV$|PW2 z_ktA7NsUHN4b9c6{u~JPX+WA@4y13YN8>@?dOnw7% L9h$&h ztw6ChU&v;5Kx#J+(51jl5|o!S$+AxE T1Q{mR%T9`s^h87nlXE3@XB1-Z^`Hr!Q5>k4=rg8E@`LLPyJ0$^ v{XPjvyc0R`YnwtDuf2G1YYp!_;b4_jFs{xNH+kX?jZXFY zz;C#+>Q#TdImJtFSwO!y%<_jgk~t Bzl1U~%V0-=JH<|h&5Kpfn; zWTV$i*EhyKL)zUJcqI&()=IIAJb*ZOQL!_UE?v1Qt^4F1s%C0?*Q>Z8XE%*RcL#LA z8sEz#e}=nNgsYb?5NH?03(Pwmga{~gCBHcpZcR(w7)aKmwNiEatd5%v3Ha~EydUJ$ zG@I>I*}63u`;Ak!IlJFICBxHJmrp&LU4crQ{wqGvvS p4)o#bq)N;!|@;9V% z4R~oF$Y;T*IS l3B zieQl8)MK$3&qibgb>W_-joejAu$XCU(Bp%u0EonW6(2u5n-+P1*mRvJB&_=5s+DJx zzKiLJRr*?(gW4UjZy_t`hBH@7*d3$qE`)2TPvc4MlaOFa0{=wdldokuPsbAu8&J#{ z@5-jV3QGS01r>p2JI=bGg9BYCcExw)v%M|GBTTH1(bNF|Ys+f_^bfmMT>hln)ca5o zebN)bDAg-Z%~8K&akKv{m#nRL9RrEDO@@W6_!f#nJ)Xcun)$J!Shi1ESI=?Wu4UQM zGo?aOU6*k3mNI?jq?F0jEEQngj#w|ITR%tlZ+$^vEhwzCF1zPJxNK54Y9oinsgWSL zHs@1dzRkPttyqZN&}am*m?S|+5`y|}E|}`{QcmDM6Ib$J0|y3Pe?F*`5=jgmDwm#c z8V5GZk6hC5pg6cN!=m$OP`Q;;nQr%yD&-gC>Mm50P3@U_%U_GUwgwK+nMt2*%Of7c zlrNjdV@^bWsNa;Y@HR(J>OP*57v(8iN&D1HUBF>l3Yttx8lDX`oq@Y;C&(-P|IW}e z?OHF{1Mu}`CI03!ZW~*`De50q)op({ccJ$F27&+iIlT}ncehKHG!>lwyMC`@&4RXJ z@rPX{#;&>}?^M8t=~y7Zt87+7hR!>D|1xmh9dz#LICycbCDkrJ3Cx-a3KSFex>`}` zv-e+H)%{nCl1^Z&z9*>`+~MxxpjK|*iLYnk1WeoaaR;wCr9~Q}NvvO$K7ZrT5gLI) zpKjvtKg>fk6$Mu9U%Vl7y>3qod8je^E!=Bub*L;zu ~qu4ifW18I<;<(~ZdT&(L*Aof( zx0awW1xd2_Wa4qIJUE`61;{C< ;Vr z{1>DI<0i)*JX2S?93E7*k4@tY(`3VS7t@Np>n1o`G=Mv3mf?X#;Tv!8yB>hlqTzsI zdXLEV*j{ABJayklL3N32QvT5Y9>b^hVq-`lI!jM*cJcZ5Q(dkI-e0*t^zPJ YQG8-FT& z^vo*SKs4X~Z0ub#9|nXDmn$M-VPw6 4Dtx zsBJ&o_9pV;;~GOkV{7B`c$ie}!?cu-7ZBSeUxSz$dt*(i?l$oWVF4IYX1nHkyo;!y zzg|RedAmPWDdgYv5Rc^aXAo3R>)2o ^(&u_8s z*?GLGTG5xCdVp`5xS4j`=e?pB35*Q_lf`%|Vt8Zldj$zf#Om}p;CQcG#l@UO#;jBe zfn=B_Y%o-NE$h3f%$w$TDu2!_r9s@YXcS~~GdeQ`-^ZLv3+-;*g{BT-Ak8-`lJ? |3!b0?U+`NKD~y)72u<`&bI|k*G&j>tC^f z3u!Jlwa`h#mVcYix3iucF+Ec340K?x=`2BCmuWX|B^b-wl&0XUrCNj@fQXJc}pz zN@)Js8myF9e!3LtL WL1RR!zy zdZsU=btT$OFGe_PrbOCd?6}h{68W~(SI;QXPv&E%XFJr7mpqrV3fzHcv|@lW)Yz7+ zDE(w|uXs}$r2FjC*T%VzSjv<&QRyF=U1ZHC%wQ*4&{_)yaI@GgJaDzz!t DbTg?HQ}2bT|4CUppQ-b#k#F-o{#EqMn1R-Wm?=UhVK6|xF!D7? zU5V0oZ6_(|F@5qwln*(rC`(55JG;(Ug?b_LJZzxZ1l;CWibB`Enu)-d9wUZ4M;Am^ z51q5n_WL`r0%Ut!?#hOhtySA)ml!-0ot@OXJ^flWt2A5%?B@M`IYKx!h4-)sohf-Z zXXVE6mwS9K2wiMbf%WXAdcRj{Y(>5!4r*|i)2r$Dj?e}ZGc}w)D%uRV<604KmXnuv zifuUs%NFpN9Yf8TxJ{`05;RE@S>sEC`_jk9Rsgc#d?lEjOlk6nXr@)@mnRX{yKrq3 zRt!*nz|A*er&$T>s>)p#Bu&OF+!!g1fv~Awr`ko}{cT%#?y=jd=jaXlNC^u0+v0wg z4JD($BAsrR0z3t%Y-+*grylKCn;oQgGsH4K{Bh-y+Ht!i@&TVSF)iNyE(IaqS=fnG z=4UVF&(Bws&k0$Yk9{5^%a@z#M5aMPrpS<(4pRk?6^PeKDG(f641_qo?(l24FmzfZ zmT3aDme) 6?;H#D)^R#rQ(Ar1ra!;j6Y+~`BACS!rV`(Wqtp* z3t(V!>}pN*`KvF6mHG@!p?`;(K5HKtc-cY504blzaovSFB{GybS(`8c10+90MNU z4YL4(=W${aI@cf9^u$_T=#xgc>>KLjW2hp&F+?wbY4|vCl+6EZvNqBSfHe(Z5zTs< zO?RBv-%I?EU0icDIk$Zt>7hYSYWwbY)9~oqMsd(f4q21rcE0vrd&Iz*vG I9_Jo5Wg5i zm72!L4+oJ}!)g$*2Bi&%vR}#~mybrW{&5<97kuQ)rHfC-eV4~0dF*ohpOI*RDB#L| z%!eYn59M>e@aZCLLiB<%C>qMHOVGYQo)UgT`KpG@5!tCfcvPpC^ ~dV+&kW~3@y`#_s#Aq z)p>cka^Nv)qzIIIw^)Nr#0)n|i~bH06ivD;f=|=BVkm9gBQ$l|>W(m;>>Zp;w#hEN zxwSFa*nhBcvN7G*wE1lb EfmXiSW|g*v+;_2*Q+zulk|Qty!wx)Zx_DbSuIA zcE_fdjBKgT*Y_6`(2nw4PnR1Ob^bEbieq0i55FY}El&?{VWqm9_~d23THPubm7*9@ z-a0?&0JB`R(9s0_tgzRoma3KPY-06CI>IVfuMKWMzrKeZ<{AtjOQv$N5|cR7?e0E` zwfbvfDik%9rT-)_bNB(~ >?G-rJmA6QYNQZuZZtx5{cwcp8FeWwyba Brc5NTTt*`u5 s=?ds72eKvF^l0FX<{J=pM%kMGpOAdj y(H|IYk&bhj 8NW=&mrcx2xtP_{F!w17bFZl%CK~wr(XM<#r~@W6JC;{We%#)DGWUJ7 zs2@&vn`$%4M&%X!YmS6KC*}P%8bF@4X{APem0P}*nsbsGz;c`JB<&8uiZOUa(Hx_F zt-qn7yx`c{5oJQr+Yg(3>KPZ-ulnfv7&@K(wlo!x+IoI6nKHV9*klAy)#X}IGt+f} zzc517JN-SHKMZDFp5Kx*kbZDZl=kvgJzj&`lc&buc+~#_`vqHdUWhiHu3X+BQRdHv z9-Q$Sd%~_LmMT91!sw4Vsu{W1O*E&f_xEZxKkw7Q8Ja6geU4t#rG3(XsDPaK2_}NS z4 <&@WeV#S=d)W7D8${>)ivYWVG@e^_VYi6gyi6kKPDs8Any0jDpO1G+)IBYkA5Fd zNQb8(lWru)t7TsiJcfA62+?_c>~qKDD;Za{O9vIcUtYW9*Ex|Q93HsJC+M%Tn#I!< z=DyJh0rozN)=0iG{~Xw~{7h~wNmEbA{-WA+b(nWtp6FAut&iA5{3S~9WE=dOI<~w9 zzC_k6KPRpB9@qXpT*~wW?K8dU+%t5d%f*N1OlwYL eln+)6jkxfhm3Mg}1*4?B`CInbJ|~~fA`6z^Cw;#ih-*4= zwI}G7XX}EjJao@i58x1<&k CZd};L9Y?oCz&Kz_UC+(VjecI z28?EDOeJJ?P6Q?zl_f6R Ggg+phEpve4=NUnJC)nC#pUB+&Q;F?PIPio!v*UR$ zGr67;9LJ~X*PdOjUQttcrRmmU&CB*T?`SnCDi##xv;T1%MpM32k#GZBCTl+~J{63T zIF|Nux|1jEaz57O48Ojx^}&l$_0?MWNtpqbYQQc; PaMVOy{SLORH zv!*9;(DT~hRV`-s>2swu7wPZ(Pa zUtGGCaM{ZOii4jC {9^xkdU(GAysOHkttWg7d{pPDOYX^{?-vkfQT4Wh z8tE1)%$9&ZyW^GtP`)@hU|`#R3jyaaeu9KYIwRUFO0?WcUQSs^*6#6eNsxYAf8%nZ z`jKqnZs#`t?_OG}3-HDl-o
QeYBTM@CZRl1|+v082>k=Wc+ zbtL=6M+eMw^87!PFL9ToH($QAYdLp=JLw>Eub2FJ?VQ!NnsdIlW6L7aJ_J!?s~}b! zdQBSALB=!Ph_YN};|)^C^m9I(gF#v^AKL1;Y#&!ZpOHw3`J&tt6Ai!j98)yba2t8K zm;{w w?moV^a*jnhu)? zrZJF)y#a6BKfa3v{`6W**FJ_YO9*&pSsTA E}y~ z(A-#-DDl($_{s;8@r^ ?Gb;cIlstWs z9Lg>RleVY|QZZsxt<+nXPsH^QFG%eeNft67aFeEFz?f2OQ_H>QGfz6>dfuOO*rgsS zodj4dDc)Z)8JAe(F6ZY@hA)WgM(;^eT~Lp5|9orZIDbtau$ACO&JP!2eKZSapQsBX zd;6STw3E~MJJEjmcDu-IUx#JG{>qLARGGUY?2h+hGtO;}lKb%9ZHGY6)$x?q-hq2( zG&BDnQ)e00bl8S{LP`cGARQ_(kPhikkQ@vV6;M)I>5yh1B{I5&(V?QWbPgCWx;sbr z2Fk#J@9=q^_kE9j<>15kbKTc{p15p0+0Mfwiibev#VFP5;QoN6^x>bGy8K5{LsDkvR29* zrj;p(jga8Lp=e&&ey5*>#JUjjQx-Wt>RJ0(<6!cLeZkEM*N$5$jsr#6j*~z{o|Tj z%y_vml!1gz^gt037M4e~@-J0n q(}$Qm6^vle4*w$GcRm_jmN_9FGq(q Rz20PMzBxA>8to} zYWeBMqDSk)rhV;W-n?y?68q=V^zRsc>b}L7{4r+BRISHJd+Ad1G9`~g3HT7*TiU9m z%tlhiQM}=D-SwU)!tc;JRYOkl1-jG+v0QB#IoQrf_g ?FGQuYW9 z`=3#2QhH-kX#;z&3qJEHZ%{QtWU zcr)T{?3-nHZPtIs>;i22=VG9JtUg0$@h2D4K%clj4^V*+czHc&+pUjN{nF