From 93656a3a3af0ed38be139c2e8b957eeb13a9bf59 Mon Sep 17 00:00:00 2001 From: hzx Date: Tue, 29 Oct 2024 19:32:47 +0800 Subject: [PATCH 01/13] first commit for Sampler --- .gitignore | 6 + CMakeLists.txt | 6 +- TODO.md | 24 + docs/transformers/optimizations.md | 393 +++++++++++++ express/NeuralNetWorkOp.cpp | 3 + include/MNN/expr/NeuralNetWorkOp.hpp | 1 + source/backend/cpu/CPUAttention.cpp | 2 +- transformers/llm/engine/CMakeLists.txt | 9 +- transformers/llm/engine/app/chat_demo.cpp | 14 + .../llm/engine/include/app/chat/chat.hpp | 46 ++ .../engine/include/evaluation/MemMonitor.hpp | 42 ++ .../engine/include/evaluation/evaluation.hpp | 65 +++ .../engine/include/evaluation/perplexity.hpp | 50 ++ transformers/llm/engine/include/llm/llm.hpp | 31 +- .../llm/engine/{src => include}/llmconfig.hpp | 141 ++++- .../llm/engine/include/prompt/prompt.hpp | 58 ++ .../llm/engine/include/sampler/sampler.hpp | 146 +++++ transformers/llm/engine/src/chat.cpp | 93 +++ transformers/llm/engine/src/llm.cpp | 299 ++-------- transformers/llm/engine/src/llmconfig.cpp | 47 ++ transformers/llm/engine/src/prompt.cpp | 98 ++++ transformers/llm/engine/src/sampler.cpp | 552 ++++++++++++++++++ transformers/llm/export/.gitignore | 4 + transformers/llm/export/README.md | 36 +- transformers/llm/export/llmexport.py | 110 +++- 25 files changed, 1934 insertions(+), 342 deletions(-) create mode 100644 TODO.md create mode 100644 docs/transformers/optimizations.md create mode 100644 transformers/llm/engine/app/chat_demo.cpp create mode 100644 transformers/llm/engine/include/app/chat/chat.hpp create mode 100644 transformers/llm/engine/include/evaluation/MemMonitor.hpp create mode 100644 transformers/llm/engine/include/evaluation/evaluation.hpp create mode 100644 transformers/llm/engine/include/evaluation/perplexity.hpp rename transformers/llm/engine/{src => include}/llmconfig.hpp (73%) create mode 100644 transformers/llm/engine/include/prompt/prompt.hpp create mode 100644 transformers/llm/engine/include/sampler/sampler.hpp create mode 100644 transformers/llm/engine/src/chat.cpp create mode 100644 transformers/llm/engine/src/llmconfig.cpp create mode 100644 transformers/llm/engine/src/prompt.cpp create mode 100644 transformers/llm/engine/src/sampler.cpp create mode 100644 transformers/llm/export/.gitignore diff --git a/.gitignore b/.gitignore index a6391ada9..6ca0ca9fc 100644 --- a/.gitignore +++ b/.gitignore @@ -360,3 +360,9 @@ pymnn_build/ # mnncompress generated MNN_compression_pb2.py + +# model path +model/ + +# datasets +datasets/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b940476e..4676d62c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,9 @@ endif() project(MNN VERSION ${MNN_VERSION} LANGUAGES C CXX ASM) # complier options set(CMAKE_C_STANDARD 99) -set(CMAKE_CXX_STANDARD 11) +IF (NOT (CMAKE_CXX_STANDARD EQUAL 17)) + set(CMAKE_CXX_STANDARD 11) +ENDIF() set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/cmake" @@ -274,7 +276,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "^Android") endif() option(MNN_USE_CPP11 "Enable MNN use c++11" ON) if (NOT MSVC) - if(MNN_CUDA AND MNN_SUPPORT_TRANSFORMER_FUSE) + if((MNN_CUDA AND MNN_SUPPORT_TRANSFORMER_FUSE) OR (CMAKE_CXX_STANDARD EQUAL 17)) set(CMAKE_CXX_STANDARD 17) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") diff --git a/TODO.md b/TODO.md new file mode 100644 index 000000000..d17bbdd5c --- /dev/null +++ b/TODO.md @@ -0,0 +1,24 @@ +## TODO Lists + +### 1. Engineering TODO Lists +- [x] llm-export convert Qwen2.5-1.5B-Instructx, Qwen2.5-3B-Instructx, Qwen2.5-7B-Instruct (Qwen2.5 language series) https://qwenlm.github.io/zh/blog/qwen2.5/ (<7B: 32K/8K, >=7B: 128K/8K) +- [x] llm-export convert Llama-3.2-1B-Instructx, Llama-3.2-3B-Instruct (Llama-3.2 language series) https://ai.meta.com/blog/llama-3-2-connect-2024-vision-edge-mobile-devices/ (128K) +- [ ] (optional) llm-export convert Llama-3.2-11B-Vision-Instruct (Llama-3.2 Vision series) +- [ ] (optional) llm-export convert Qwen2-VL-2B-Instruct, Qwen2-VL-7B-Instruct (Qwen2-VL series) +- [ ] (optional) llm-export convert Qwen2-Audio-7B-Instruct (Qwen2 Audio series) +- [x] implement `Chat` application in transformers/llm/app/chat. +- [x] implement `LocalSampler` module. +- [x] implement `PromptLib` module. +- [x] implement `Llm` module. (before StateCacheManager's existence) +- [x] build MNN on pc end. +- [x] build MNN and run on android (fp32+fp16) +- [ ] build and deploy an Llama-3.2-3B-Instruct model chatbot on Android cell phone, show the demo. +- [ ] add RAG implementation. + +```bash +python llmexport.py --path ../../../model/Qwen2.5-1.5B-Instruct/ --dst_path ../../../model/qwen2_5-1_5b-instruct-mnn/ --export mnn --quant_bit 4 --quant_block 128 +``` + + +### 2. Experiments TODO Lists +- [ ] test `Chat` on ShareGPT datasets, measuring time and space. \ No newline at end of file diff --git a/docs/transformers/optimizations.md b/docs/transformers/optimizations.md new file mode 100644 index 000000000..b2a8ededa --- /dev/null +++ b/docs/transformers/optimizations.md @@ -0,0 +1,393 @@ +# Version 1 +## v1.0.1 + +### 1. Compilation +#### 1.1 compile for phone + +```bash +# windows +set ANDROID_NDK=D:\NDK\android-ndk +cmake ../.. -DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK%/build/cmake/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="arm64-v8a" -DANDROID_STL=c++_static -DMNN_USE_LOGCAT=false -DCMAKE_CXX_STANDARD=17 -DMNN_USE_SYSTEM_LIB=OFF -DMNN_BUILD_BENCHMARK=ON -DMNN_USE_SSE=OFF -DMNN_SUPPORT_BF16=OFF -DMNN_BUILD_TEST=ON -DANDROID_NATIVE_API_LEVEL=android-21 -DMNN_BUILD_FOR_ANDROID_COMMAND=true -DNATIVE_LIBRARY_OUTPUT=. -DMNN_LOW_MEMORY=ON -DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON -DMNN_BUILD_SHARED_LIBS=ON +# arm v82 & OPENCL +cmake ../.. -DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK%/build/cmake/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="arm64-v8a" -DANDROID_STL=c++_static -DMNN_USE_LOGCAT=false -DCMAKE_CXX_STANDARD=17 -DMNN_USE_SYSTEM_LIB=OFF -DMNN_BUILD_BENCHMARK=ON -DMNN_USE_SSE=OFF -DMNN_SUPPORT_BF16=OFF -DMNN_BUILD_TEST=ON -DANDROID_NATIVE_API_LEVEL=android-21 -DMNN_BUILD_FOR_ANDROID_COMMAND=true -DNATIVE_LIBRARY_OUTPUT=. -DMNN_LOW_MEMORY=ON -DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON -DMNN_BUILD_SHARED_LIBS=ON -DMNN_ARM82=ON -DMNN_OPENCL=ON + +# linux +export ANDROID_NDK=~/NDK/android-ndk +cmake ../.. -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="arm64-v8a" -DANDROID_STL=c++_static -DMNN_USE_LOGCAT=false -DCMAKE_CXX_STANDARD=17 -DMNN_USE_SYSTEM_LIB=OFF -DMNN_BUILD_BENCHMARK=ON -DMNN_USE_SSE=OFF -DMNN_SUPPORT_BF16=OFF -DMNN_BUILD_TEST=ON -DANDROID_NATIVE_API_LEVEL=android-21 -DMNN_BUILD_FOR_ANDROID_COMMAND=true -DNATIVE_LIBRARY_OUTPUT=. -DMNN_LOW_MEMORY=ON -DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON -DMNN_BUILD_SHARED_LIBS=ON +# arm v82 & OPENCL +cmake ../.. -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="arm64-v8a" -DANDROID_STL=c++_static -DMNN_USE_LOGCAT=false -DCMAKE_CXX_STANDARD=17 -DMNN_USE_SYSTEM_LIB=OFF -DMNN_BUILD_BENCHMARK=ON -DMNN_USE_SSE=OFF -DMNN_SUPPORT_BF16=OFF -DMNN_BUILD_TEST=ON -DANDROID_NATIVE_API_LEVEL=android-21 -DMNN_BUILD_FOR_ANDROID_COMMAND=true -DNATIVE_LIBRARY_OUTPUT=. -DMNN_LOW_MEMORY=ON -DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON -DMNN_BUILD_SHARED_LIBS=ON -DMNN_ARM82=ON -DMNN_OPENCL=ON +``` + +#### 1.2 compile for pc +LLM and TRANSFORMER_FUSE shall be set ON: `-DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON` + +```bash +mkdir build && mkdir build/pc && cd build/pc +# linux +cmake ../.. -DCMAKE_CXX_STANDARD=17 -DMNN_USE_SYSTEM_LIB=OFF -DMNN_BUILD_SHARED_LIBS=ON -DMNN_BUILD_TRAIN=ON -DMNN_BUILD_QUANTOOLS=ON -DMNN_EVALUATION=ON -DMNN_BUILD_CONVERTER=ON -DMNN_PORTABLE_BUILD=ON -DTFMODEL_OPTIMIZE=ON -DMNN_LOW_MEMORY=ON -DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON -DMNN_BUILD_TEST=ON -DMNN_BUILD_OPENCV=ON +# windows +cmake ../.. -DCMAKE_CXX_STANDARD=17 -DMNN_USE_SYSTEM_LIB=OFF -DMNN_BUILD_SHARED_LIBS=ON -DMNN_BUILD_TRAIN=ON -DMNN_BUILD_QUANTOOLS=ON -DMNN_EVALUATION=ON -DMNN_BUILD_CONVERTER=ON -DMNN_PORTABLE_BUILD=ON -DTFMODEL_OPTIMIZE=ON -DMNN_LOW_MEMORY=ON -DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON -DMNN_BUILD_TEST=ON -DMNN_SEP_BUILD=ON -DMNN_BUILD_OPENCV=ON +make -j20 + +./llm_demo ../../model/qwen1_5-4b-chat-mnn-f/llm_config.json +``` + +### 2. Model Convertion + +#### 2.1 Direct Model Download +Transformer path: +Download from https://github.com/wangzhaode/mnn-llm/releases + +#### 2.2 Model Export +export +```bash +cd transformers/llm/export/ +python llm_export.py \ + --path ../../../model/Qwen1_5-4B-Chat \ + --type Qwen1_5-4B-Chat \ + --export_split \ + --export_token \ + --export_mnn \ + --export_embed --embed_bin --embed_bf16 \ + --onnx_path ../../../model/qwen1_5-4b-chat-onnx \ + --mnn_path ../../../model/qwen1_5-4b-chat-mnn + +python llm_export.py \ + --path ../../../model/Qwen1_5-1_8B-Chat \ + --type Qwen1_5-1_8B-Chat \ + --export_split \ + --export_token \ + --export_mnn \ + --export_embed --embed_bin --embed_bf16 \ + --onnx_path ../../../model/qwen1_5-1_8b-chat-onnx \ + --mnn_path ../../../model/qwen1_5-1_8b-chat-mnn +``` + +Currently fuse attention haven't added to python MNN package converter. To use it, you need directly use MNNConvert. +```bash +for i in $(seq 0 39) +do + ./build/MNNConvert -f ONNX --modelFile ./model/qwen1_5-4b-chat-onnx/block_${i}.onnx --MNNModel ./model/qwen1_5-4b-chat-mnn/block_${i}.mnn --weightQuantBits 4 --weightQuantAsymmetric --transformerFuse +done + +for i in $(seq 0 24) +do + ./build/pc/MNNConvert -f ONNX --modelFile ./model/qwen1_5-1_8b-chat-onnx/block_${i}.onnx --MNNModel ./model/qwen1_5-1_8b-chat-mnn/block_${i}.mnn --weightQuantBits 4 --weightQuantAsymmetric --transformerFuse +done +``` + + +### 3. StateCacheManager + +Implemented in `core/StateCacheManager.hpp` and `core/StateCacheManager.cpp`. + +#### 3.1 Config + +1. StateCacheType: implementation type of StateCacheManager +2. StateCacheQuantType: quantization type of StateCacheManager + +2 fields are added to RuntimeHint, can be modified by `runtime_manager_->setHint(mode, value);`. +```cpp +struct RuntimeHint { + // 0: Defer, 1: Eager + int memoryAllocatorType = 0; + int winogradMemoryUsed = 3; + + // 0-100, 50 means litter core has 50% capacity of large core + int cpuDecreaseRate = 50; + int dynamicQuantOption = 0; + + // 0: Do not quantize kvcache, just store float + // 1: Only quantize key cache, use int8 asymmetric quantization + // 2: Only quantize value cache, use fp8 quantization + // 3: quantize both key and value cache as described above + int kvcacheQuantOption = (int)MNNStateCacheQuantType::NoQuant; + + int kvcacheImplOption = (int)MNNStateCacheType::MNN_STATECACHE_ADVANCED; +}; +``` + +Also, add cases to `Session::ModeGroup` and field to `Interpreter::HintMode`, +```cpp +void Session::ModeGroup::setHint(Interpreter::HintMode mode, int hint) { + // ... + switch (mode) { + case Interpreter::KVCACHE_QUANT_OPTIONS: + runtimeHint.kvcacheQuantOption = hint; + break; + case Interpreter::KVCACHE_IMPL_OPTIONS: + runtimeHint.kvcacheImplOption = hint; + break; + default: + break; + } +} +``` + +```Cpp +class MNN_PUBLIC StateCacheManager{ + // ... + void setHint(MNNStateCacheQuantType quantType = MNNStateCacheQuantType::NoQuant, MNNStateCacheType type = MNNStateCacheType::MNN_STATECACHE_ADVANCED); + // ... +}; +``` + +#### 3.2 Creation and Clone + + + +### 4. Sampler + +#### 4.1 sampler specification +llama.cpp sampler support. +sampling: + repeat_last_n = 64, repeat_penalty = 1.000, frequency_penalty = 0.000, presence_penalty = 0.000 + top_k = 40, tfs_z = 1.000, top_p = 0.950, min_p = 0.050, typical_p = 1.000, temp = 0.800 + mirostat = 0, mirostat_lr = 0.100, mirostat_ent = 5.000 +sampling order: +CFG -> Penalties -> top_k -> tfs_z -> typical_p -> top_p -> min_p -> temperature + +#### 4.2 sampler references + +#### 4.3 process of adding new sampler +1. add hyperparameters to `llm_config.hpp`. +2. add parsing selections to function `void Llm::initSampler()` in `llm.cpp`. +3. add implementation in `sampler.hpp` and `sampler.cpp`. + +### 5. CPUAttention + +#### 5.1 Matmul Layout v1.0 + +Layerwise concatenation of all input blocks. Assume enough memory for activation buffer and enough memory for one layer's calculation. + +For StateCacheBlock: +- Tensor shape: + - K: [kvnum_heads, block_size / hp, head_dim, hp], + - V: [kvnum_heads, head_dim / hp, block_size, hp] +- block_size % hp == 0, block_size % core->pack == 0 +- mSlotNum: mSlotNum shall not be modified in thread to ensure thread-safe. Besides, no lock is ever implemented. + + +1. Prepare inputs: pack new k and v into pastKV (StateCacheBlock). +2. Calculation: perform multi-threaded tiled CPU Matmul. +3. Prepare outputs: pack the dispersed outputs to one outputs Tensors. +4. Update pastKV mSlotNum after all calculation threads are finished. + + +In the future, modify the operators to enable fused flash attention, further curbing memory buffer size and computation time. + +q @ k: q @ [k1, k2, k3, k4] = [q @ k1, q @ k2 + q @ k3 + q @ k4] + +qk @ v: [a1, a2, a3, a4] @ [b1, b2, b3, b4]^T = a1 @ b1 + a2 @ b2 + a3 @ b3 + a4 @ b4 +(ai @ bi are all of the same shape of qk @ v) +(qk shall be dispersed and v shall be dispersed) + + +To Do List: +- [x] dispersed pastKV +- [x] dispersed packQK +- [x] dispersed packQKV +- [x] pack_key +- [x] pack_value +- [x] query @ key +- [x] unpack_QK (for softmax) +- [x] pack_QK (for qk @ v) +- [x] dequant_value_fp16 +- [x] dequant_value_float +- [x] qk @ v +- [x] update mSlotNum for all blocks + + +Coding Cautions: + +- When creating a new backend, make sure that they share the very same StateCacheManager. This happens during load() and clone() of a Module. + +- std::shared_ptr is only set in global Executor, while all the other pointers are simple naive pointer. + +- We keep lots of pointers, but only the malloc one can be freed, because of an a block area indicating the block size for following free(). + +- Remember to flush when debugging with print. + +- finish single-threaded debugging first, and then multi-threading. + +- take good care of memory layout please. + +- look at the code! Not the doc nor function names! + +- realize the functionality of std::move + + + +```cpp +// mPackQ +mPackQ.reset(Tensor::createDevice({mThreadNum, UP_DIV(seq_len, eP), mResource->mHeadDim, eP})); +// mPackQKV +mPackQKV.reset(Tensor::createDevice({mThreadNum, UP_DIV(mResource->mHeadDim, unit), seq_len, unit})); +// packQK +// length: pastKV.size() +packQK.emplace_back(Tensor::createDevice({mThreadNum, UP_DIV(block_size, unit), seq_len, unit})); +// pack_q +auto pack_q = mPackQ->host() + tId * UP_DIV(seq_len, eP) * mResource->mHeadDim * eP * bytes; +auto pack_qk = packQK[j]->host() + tId * UP_DIV(block_size, unit) * seq_len * unit * bytes; + +// Tensor shape: +// K: [num_heads, block_size / hP, head_dim, hP] +// V: [num_heads, head_dim / hP, block_size, hP] +std::shared_ptr unpackQK(Tensor::createDevice({mThreadNum, seq_len, kv_seq_len})); +auto unpack_qk = unpackQK->host() + tId * seq_len * kv_seq_len; + + +// newPackQK.emplace_back(Tensor::createDevice({mThreadNum, UP_DIV(seq_len, eP), block_size, eP})); +// newPackQK.emplace_back(Tensor::createDevice({mThreadNum, UP_DIV(seq_len, eP), last_block_slot_num, eP})); + +std::shared_ptr newPackQK(Tensor::createDevice({mThreadNum, UP_DIV(seq_len, eP), kv_seq_len, eP})); +std::shared_ptr VBuffer(Tensor::createDevice({mThreadNum, UP_DIV(mResource->mHeadDim, hP), kv_seq_len, hP})); + + +std::shared_ptr QKVBuffer(Tensor::createDevice({mThreadNum, UP_DIV(mResource->mHeadDim, unit), seq_len, unit})); +char* qkv_buffer = QKVBuffer->host() + tId * UP_DIV(mResource->mHeadDim, unit) * seq_len * unit * bytes; + + +mPackQKV.reset(Tensor::createDevice({mThreadNum, UP_DIV(mResource->mHeadDim, unit), seq_len, unit})); +auto pack_qkv = mPackQKV->host() + tId * UP_DIV(mResource->mHeadDim, unit) * seq_len * unit * bytes; +``` + +#### 5.2 Speed Evaluation of CPUAttention + +1. test case 1 +Processor: HUAWEI Kirin 990 5G +Mem: 8GB + 2GB Swap +Model: Qwen1.5-4B-Chat +Precision: attn-fp32, mlp-W4A8 +"type_kv": 1 (8-8) + +| Phase | prev_seq_len | seq_len | Layer time (ms) | Attention time (ms) | proportion| +| :---: | :---: | :---: | :-----: | :----: | :---: | +| prefill | 0 | 9 | 24.987 | 0.195 | 0.78% | +| prefill | 0 | 18 | 33.978 | 0.333 | 0.98% | +| decode | 10 | 1 | 4.261 | 0.058 | 1.4% | +| decode | 20 | 1 | 4.187 | 0.086 | 2% | +| decode | 60 | 1 | 4.019 | 0.147 | 3.6% | +| decode | 64(malloc) | 1 | 4.005 | 0.222 | 5.5% | +| decode | 80 | 1 | 4.062 | 0.207 | 5.1% | + +"type_kv": 0 (63-8) + +| Phase | prev_seq_len | seq_len | Layer time (ms) | Attention time (ms) | proportion| +| :---: | :---: | :---: | :-----: | :----: | :---: | +| prefill | 0 | 9 | 25.141 | 0.262 | 1.0% | +| prefill | 0 | 18 | 33.742 | 0.394 | 1.2% | +| decode | 10 | 1 | 4.093 | 0.064 | 1.6% | +| decode | 20 | 1 | 4.163 | 0.073 | 1.75% | +| decode | 60 | 1 | 4.141 | 0.101 | 2.4% | +| decode | 80 | 1 | 4.131 | 0.11 | 2.7% | +| decode | 89(malloc) | 1 | 6.382 | 1.42 | 22.2% | +| decode | 110 | 1 | 4.101 | 0.167 | 4.0% | + +2. test case 2 + +Processor: intel i9-13900 +Mem: 32GB + 12GB Swap +Model: Qwen1.5-4B-Chat +Precision: attn-fp32, mlp-W4A8 +"type_kv": 1 (24-3) + +Q: what's gpu? +A: GPU, or Graphics Processing Unit, is a type of processor that is specifically designed for handling graphics and mathematical calculations. It is commonly used in gaming consoles, high-end graphics workstations, and other applications that require high levels of performance in these areas. The GPU is able to perform these tasks much faster than a traditional CPU, making it an essential component in modern computing systems. + +Q: what's cpu? +A: CPU, or Central Processing Unit, is a type of processor that is responsible for executing instructions and performing calculations. It is the primary component of a computer system, and it is responsible for managing all of the system's tasks, including running applications, managing data, and performing calculations. The CPU is able to perform these tasks much faster than a traditional GPU, making it an essential component in modern computing systems. + +Q: how do they differ from each other? +A: GPU and CPU are two different types of processors that are used in different types of computing systems. The main difference between them is that GPU is specifically designed for handling graphics and mathematical calculations, while CPU is responsible for executing instructions and performing calculations. The GPU is able to perform these tasks much faster than a traditional CPU, making it an essential component in modern computing systems. The CPU, on the other hand, is able to perform these tasks much faster than a traditional GPU, making it an essential component in modern computing systems. + +| Phase | prev_seq_len | seq_len | Layer time (ms) | Attention time (ms) | proportion (%) | +| :---: | :---: | :---: | :-----: | :----: | :---: | +| prefill | 0 | 18 | 18.5903 | 0.1532 | 0.8238 | +| decode | 30 | 1 | 2.9778 | 0.0569 | 1.9116 | +| decode | 60 | 1 | 2.2643 | 0.0702 | 3.0980 | +| decode | 64 | 1 | 2.8403 | 0.0731 | 2.5745 | +| decode | 72(malloc) | 1 | 2.7708 | 0.1302 | 4.6972 | +| decode | 78 | 1 | 2.4339 | 0.0853 | 3.5026 | +| decode | 80 | 1 | 2.6721 | 0.0871 | 3.2606 | +| decode | 82 | 1 | 2.3748 | 0.0824 | 3.4698 | +| decode | 88 | 1 | 2.5643 | 0.0895 | 3.4882 | +| decode | 108 | 1 | 1.9229 | 0.1038 | 5.3993 | +| decode | 119 | 1 | 2.2829 | 0.1093 | 4.7878 | +| decode | 120(new) | 1 | 2.3890 | 0.1534 | 6.4201 | +| decode | 140 | 1 | 2.8935 | 0.1347 | 4.6561 | +| decode | 144(malloc) | 1 | 2.9495 | 0.2027 | 6.8714 | +| decode | 160 | 1 | 2.5395 | 0.1353 | 5.3288 | +| decode | 180(new) | 1 | 2.7440 | 0.1890 | 6.8895 | +| decode | 210 | 1 | 2.5207 | 0.1857 | 7.3670 | +| decode | 216(malloc) | 1 | 2.4529 | 0.2630 | 10.7211 | +| decode | 220 | 1 | 2.2560 | 0.1847 | 8.1872 | +| decode | 240(new) | 1 | 2.6265 | 0.2428 | 9.2423 | +| decode | 280 | 1 | 2.0357 | 0.2051 | 10.0775 | +| decode | 288(malloc) | 1 | 2.1922 | 0.2640 | 12.0404 | +| decode | 300 | 1 | 2.4628 | 0.2314 | 9.3957 | + +"type_kv": 0 (63-24) + +Q: what's gpu? +A: GPU, or Graphics Processing Unit, is a type of hardware that is specifically designed to perform mathematical calculations and graphical tasks. It is commonly used in applications such as gaming, video editing, and scientific simulations. The GPU is able to perform these tasks much faster than a traditional CPU, which is responsible for handling general-purpose tasks such as file I/O and web browsing. The GPU is typically connected to the CPU via a graphics card, which is a specialized device that is designed to handle graphics tasks. + +Q: what's cpu? +A: CPU, or Central Processing Unit, is a type of hardware that is specifically designed to perform general-purpose tasks such as file I/O, web browsing, and scientific simulations. It is commonly used in applications such as gaming, video editing, and scientific simulations. The CPU is able to perform these tasks much faster than a traditional GPU, which is responsible for handling graphics tasks. The CPU is typically connected to the GPU via a graphics card, which is a specialized device that is designed to handle graphics tasks. + +Q: how do they differ from each other? +A: GPUs and CPUs differ from each other in several ways. The most significant difference is that GPUs are specifically designed to handle graphics tasks, while CPUs are specifically designed to handle general-purpose tasks. This means that GPUs are much faster than CPUs when it comes to performing graphics tasks, such as rendering images and videos. CPUs, on the other hand, are much faster than GPUs when it comes to performing general-purpose tasks, such as file I/O and web browsing. +GPUs are also able to perform certain tasks much faster than CPUs, such as matrix multiplication and vector addition. This is because GPUs are able to perform these tasks using a technique called "parallel processing," which involves dividing a task into smaller pieces and performing each piece in parallel. CPUs, on the other hand, are able to perform these tasks using a technique called "serial processing," which involves performing a task one piece at a time. +GPUs are also able to perform certain tasks much faster than CPUs, such as + +| Phase | prev_seq_len | seq_len | Layer time (ms) | Attention time (ms) | proportion (%) | +| :---: | :---: | :---: | :-----: | :----: | :---: | +| prefill | 0 | 18 | 18.5213 | 0.1994 | 1.0767 | +| decode | 30 | 1 | 3.0043 | 0.0592 | 1.9697 | +| decode | 60 | 1 | 2.4122 | 0.0641 | 2.6552 | +| decode | 64 | 1 | 2.2182 | 0.0640 | 2.8830 | +| decode | 72 | 1 | 2.5079 | 0.0739 | 2.9467 | +| decode | 78 | 1 | 2.5453 | 0.0689 | 2.7070 | +| decode | 80 | 1 | 2.1048 | 0.0694 | 3.2948 | +| decode | 82 | 1 | 2.2666 | 0.0668 | 2.9483 | +| decode | 88 | 1 | 2.5103 | 0.0788 | 3.1380 | +| decode | 96(re-alloc) | 1 | 3.8289 | 1.2392 | 32.3657 | +| decode | 100 | 1 | 2.7265 | 0.0884 | 3.2404 | +| decode | 140 | 1 | 2.5288 | 0.1024 | 4.0483 | +| decode | 144 | 1 | 2.9095 | 0.1088 | 3.7377 | +| decode | 160 | 1 | 2.6942 | 0.1125 | 4.1737 | +| decode | 168(re-alloc) | 1 | 3.7834 | 1.1970 | 31.6375 | +| decode | 180 | 1 | 2.7585 | 0.1271 | 4.6076 | +| decode | 200 | 1 | 2.4005 | 0.1234 | 5.1385 | +| decode | 220 | 1 | 2.4310 | 0.1324 | 5.4473 | +| decode | 280 | 1 | 2.4475 | 0.1602 | 6.5476 | +| decode | 288 | 1 | 2.5880 | 0.1681 | 6.4964 | +| decode | 300 | 1 | 2.7049 | 0.1711 | 6.3264 | +| decode | 312(re-alloc) | 1 | 5.7744 | 2.1637 | 37.4697 | +| decode | 320 | 1 | 2.4353 | 0.1894 | 7.7772 | +| decode | 360 | 1 | 3.6315 | 0.2687 | 7.3985 | +| decode | 384(re-alloc) | 1 | 6.2943 | 2.5750 | 40.9104 | +| decode | 400 | 1 | 3.4962 | 0.2542 | 7.2700 | + + + +100 6.20021 +200 6.13895 +300 6.05897 +400 5.99104 +500 5.91477 +600 5.83586 + +100 6.25798 +200 6.16745 +300 6.09691 +400 6.03272 +500 5.9634 +600 5.90768 + +block_size = 64 +assume one 220 us +addition: ~0.7 us/block, normal allocation: 3~4 us +q @ k: 5 blocks, 16 us vs 13 us +qk @ v: 5 blocks, +transform+mask+softmax, 300 tokens: 7us \ No newline at end of file diff --git a/express/NeuralNetWorkOp.cpp b/express/NeuralNetWorkOp.cpp index 18d58c3ec..589e4df91 100644 --- a/express/NeuralNetWorkOp.cpp +++ b/express/NeuralNetWorkOp.cpp @@ -476,6 +476,9 @@ VARP _Softmax(VARP logits, int axis) { softmax->main.AsAxis()->axis = axis; return (Variable::create(Expr::create(softmax.get(), {logits}))); } +VARP _TempratureSoftmax(VARP logits, float temperature, int axis) { + return _Softmax(logits * _Scalar(1.0f / temperature), axis); +} /*Computes softplus: log(exp(features) + 1). Args: features: A variable. Must be Halide_Type_Float. diff --git a/include/MNN/expr/NeuralNetWorkOp.hpp b/include/MNN/expr/NeuralNetWorkOp.hpp index 2a6bdfd61..181f029ec 100644 --- a/include/MNN/expr/NeuralNetWorkOp.hpp +++ b/include/MNN/expr/NeuralNetWorkOp.hpp @@ -58,6 +58,7 @@ MNN_PUBLIC VARP _Relu(VARP x, float slope = 0.0f); MNN_PUBLIC VARP _Relu6(VARP x, float minValue = 0.0f, float maxValue = 6.0f); MNN_PUBLIC VARP _PRelu(VARP x, std::vector &&slopes); MNN_PUBLIC VARP _Softmax(VARP logits, int axis = -1); +MNN_PUBLIC VARP _TempratureSoftmax(VARP logits, float temperature, int axis = -1); MNN_PUBLIC VARP _Softplus(VARP features); MNN_PUBLIC VARP _Softsign(VARP features); MNN_PUBLIC std::vector _Split(VARP value, INTS size_splits, int axis = 0); diff --git a/source/backend/cpu/CPUAttention.cpp b/source/backend/cpu/CPUAttention.cpp index 7f4c6ff44..61253ede3 100644 --- a/source/backend/cpu/CPUAttention.cpp +++ b/source/backend/cpu/CPUAttention.cpp @@ -25,7 +25,7 @@ #endif // reduce the value of 'query' to 'query * FP16_QSCALE', avoid fp16 overflow -#define FP16_QSCALE 0.5 +#define FP16_QSCALE 0.25 namespace MNN { diff --git a/transformers/llm/engine/CMakeLists.txt b/transformers/llm/engine/CMakeLists.txt index 6f1b34c8b..e79ac477e 100644 --- a/transformers/llm/engine/CMakeLists.txt +++ b/transformers/llm/engine/CMakeLists.txt @@ -25,9 +25,12 @@ else() add_library(llm OBJECT ${SRCS}) endif() -add_executable(llm_demo ${CMAKE_CURRENT_LIST_DIR}/llm_demo.cpp) +# add_executable(llm_demo ${CMAKE_CURRENT_LIST_DIR}/ llm_demo.cpp) +add_executable(chat_demo ${CMAKE_CURRENT_LIST_DIR}/app/chat_demo.cpp) IF (NOT MNN_SEP_BUILD) - target_link_libraries(llm_demo ${MNN_DEPS}) + # target_link_libraries(llm_demo ${MNN_DEPS}) + target_link_libraries(chat_demo ${MNN_DEPS}) ELSE () - target_link_libraries(llm_demo ${MNN_DEPS} llm) + # target_link_libraries(llm_demo ${MNN_DEPS} llm) + target_link_libraries(chat_demo ${MNN_DEPS} llm) ENDIF () \ No newline at end of file diff --git a/transformers/llm/engine/app/chat_demo.cpp b/transformers/llm/engine/app/chat_demo.cpp new file mode 100644 index 000000000..d22d25baf --- /dev/null +++ b/transformers/llm/engine/app/chat_demo.cpp @@ -0,0 +1,14 @@ +#include "app/chat/chat.hpp" + +using namespace MNN::Transformer; + +int main(int argc, const char* argv[]) { + if (argc < 2) { + std::cout << "Usage: " << argv[0] << " config.json" << std::endl; + return 0; + } + std::string config_path = argv[1]; + Chat chat(config_path); + chat.chat(); + return 0; +} \ No newline at end of file diff --git a/transformers/llm/engine/include/app/chat/chat.hpp b/transformers/llm/engine/include/app/chat/chat.hpp new file mode 100644 index 000000000..7d0ca7aa2 --- /dev/null +++ b/transformers/llm/engine/include/app/chat/chat.hpp @@ -0,0 +1,46 @@ +// +// llm_demo.cpp +// +// Created by MNN on 2023/03/24. +// ZhaodeWang +// + +#ifndef CHAT_Hpp +#define CHAT_Hpp + + +#include "llm/llm.hpp" +#include "sampler/sampler.hpp" +#include "prompt/prompt.hpp" +#define MNN_OPEN_TIME_TRACE +#include +#include +#include +#include +#include +#include + + +using namespace MNN::Express; +namespace MNN { +namespace Transformer { + +class MNN_PUBLIC Chat { +protected: + std::unique_ptr mLlm; + std::unique_ptr mSampler; + std::unique_ptr mPromptLib; + void generate_init(); + std::string generate(const std::string& prompt, std::ostream* os = &std::cout, const char* end_with = "\n"); +public: + Chat(std::string config_path); + void chat(std::istream* is = &std::cin, std::ostream* os = &std::cout, const char* end_with = "\n"); + ~Chat() {} +}; + + +} // Transformer +} // MNN + + +#endif \ No newline at end of file diff --git a/transformers/llm/engine/include/evaluation/MemMonitor.hpp b/transformers/llm/engine/include/evaluation/MemMonitor.hpp new file mode 100644 index 000000000..7750eb56c --- /dev/null +++ b/transformers/llm/engine/include/evaluation/MemMonitor.hpp @@ -0,0 +1,42 @@ +#ifndef MEMMONITOR_hpp +#define MEMMONITOR_hpp + +#include +#include +#include +#include +#include +#include +#include + +#define BUFFER_SIZE 256 + +struct MemoryInfo { + // in MB + float total_phys_mem; + float free_phys_mem; + float total_swap; + float free_swap; + float process_resident_set_size; + float process_swap; + float process_virtual_mem_total; + float process_virtual_mem_used; +}; + + +#if defined(__ANDROID__) || defined(linux) || defined(__APPLE__) || defined(__MACOSX) +#define SELF_FILE "/proc/self/status" +#define MEMINFO_FILE "/proc/meminfo" +#endif // linux + +int readMemInfo(MemoryInfo *mem_info); + +int readProcStatus(MemoryInfo *mem_info); + +void printMemoryInfo(const MemoryInfo *mem_info); + +float getSysMemInc(MemoryInfo* prev, MemoryInfo* now); + +float getProcMem(MemoryInfo* info); + +#endif \ No newline at end of file diff --git a/transformers/llm/engine/include/evaluation/evaluation.hpp b/transformers/llm/engine/include/evaluation/evaluation.hpp new file mode 100644 index 000000000..d4136f4f5 --- /dev/null +++ b/transformers/llm/engine/include/evaluation/evaluation.hpp @@ -0,0 +1,65 @@ + + +#ifndef TRANSFORMER_EVALUATION_hpp +#define TRANSFORMER_EVALUATION_hpp + +#include +#include +#include "MemMonitor.hpp" + +namespace MNN { +namespace Transformer { + +#define MICRO_TO_MILLI 1e-3f +#define MILLI_TO_MICRO 1000 +#define MICRO_TO_SEC 1e-6f +#define SEC_TO_MICRO 1000000 + +#define MEGA_TO_GIGA (1/1024.f) +#define GIGA_TO_MEGA 1024.f +#define KILLO_TO_GIGA (1/1024.f/1024.f) +#define GIGA_TO_KILLO (1024.f*1024.f) +#define KILLO_TO_MEGA (1/1024.f) +#define MEGA_TO_KILLO 1024.f +#define BYTE_TO_MEGA (1/1024.f/1024.f) +#define MEGA_TO_BYTE (1024.f*1024.f) + +struct PrefillTimePerformance { + size_t prefill_prev_token_ = 0; + size_t prefill_token_ = 0; + size_t prefill_us_ = 0; +}; + +struct DecodeTimePerformance { + size_t decode_prev_token_ = 0; + size_t decode_us_ = 0; +}; + +struct TimePerformance { + std::vector prefill_record_; + std::vector decode_record_; +}; + +struct PrefillMemPerformance { + size_t prefill_prev_token_ = 0; + size_t prefill_token_ = 0; + float prefill_MB_ = 0; +}; + +struct DecodeMemPerformance { + size_t decode_prev_token_ = 0; + float decode_MB_ = 0; +}; + +struct MemPerformance { + std::vector prefill_record_; + std::vector decode_record_; +}; + +void mergePerformance(struct TimePerformance* dst, struct TimePerformance* src); +void mergePerformance(struct MemPerformance* dst, struct MemPerformance* src); +void clearPerformance(struct TimePerformance* perf); +void clearPerformance(struct MemPerformance* perf); +} // namespace Transformer +} // namespace MNN +#endif // TRANSFORMER_EVALUATION_hpp \ No newline at end of file diff --git a/transformers/llm/engine/include/evaluation/perplexity.hpp b/transformers/llm/engine/include/evaluation/perplexity.hpp new file mode 100644 index 000000000..a096656ab --- /dev/null +++ b/transformers/llm/engine/include/evaluation/perplexity.hpp @@ -0,0 +1,50 @@ +#ifndef PERPLEXITY_hpp +#define PERPLEXITY_hpp + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace MNN { +namespace Transformer { +class Llm; + +class MNN_PUBLIC PPLMeasurer { +protected: + Llm* mLlm; + StateCacheManager* mStateCacheManager; + std::vector> mPrompts; + std::shared_ptr mCandidate; + int mStride, mMaxLen; + void init(Llm* llm, StateCacheManager* manager, std::vector> prompts, int max_len, int stride); +public: + PPLMeasurer(Llm* llm, StateCacheManager* manager, std::vector> prompts, int max_len=2048, int stride=0); + PPLMeasurer(Llm* llm, StateCacheManager* manager, std::vector prompts, int max_len=2048, int stride=0); + float perplexity_one(const std::vector& prompt); + std::vector perplexity(); + // prepare for another round of sampling + // in the future, only reset its own. + void reset(); + void reset(int max_len, int stride); +}; + + + +} // Transformer +} // MNN + + +#endif // SAMPLER_hpp \ No newline at end of file diff --git a/transformers/llm/engine/include/llm/llm.hpp b/transformers/llm/engine/include/llm/llm.hpp index 5337afc3c..18e24f14f 100644 --- a/transformers/llm/engine/include/llm/llm.hpp +++ b/transformers/llm/engine/include/llm/llm.hpp @@ -53,19 +53,12 @@ class MNN_PUBLIC Llm { Llm(std::shared_ptr config) : config_(config) {} virtual ~Llm(); static Llm* createLLM(const std::string& config_path); - void chat(); void reset(); void trace(bool start); virtual void load(); - MNN::Express::VARP forward(const std::vector& input_ids); - int sample(MNN::Express::VARP logits, const std::vector& pre_ids); - std::string apply_prompt_template(const std::string& user_content) const; - std::string apply_chat_template(const std::vector& chat_prompts) const; - std::string response(const std::string& user_content, std::ostream* os = &std::cout, const char* end_with = nullptr); - std::string response(const std::vector& chat_prompts, std::ostream* os = &std::cout, const char* end_with = nullptr); + MNN::Express::VARP forward(const std::vector& input_ids, int kv_seq_len_, int gen_seq_len_, bool is_prefill); void generate_init(); - std::string generate(const std::vector& input_ids, std::ostream* os, const char* end_with); - std::vector generate(const std::vector& input_ids, int max_new_tokens = -1); + std::string generateTrace(const std::vector& input_ids, std::ostream* os, const char* end_with); void print_speed(); // config function std::string dump_config(); @@ -77,16 +70,15 @@ class MNN_PUBLIC Llm { bool select_module(size_t index); friend class Pipeline; public: - // forward info - int prompt_len_ = 0; - int gen_seq_len_ = 0; - int all_seq_len_ = 0; - std::vector history_ids_; // time int64_t prefill_us_ = 0; int64_t decode_us_ = 0; bool is_single_ = true; bool attention_fused_ = true; + virtual std::vector tokenizer(const std::string& query); + std::string decode(int id); + bool is_stop(int token_id); + bool reuse_kv() const; protected: std::shared_ptr config_; std::shared_ptr tokenizer_; @@ -98,12 +90,9 @@ class MNN_PUBLIC Llm { std::vector> prefill_modules_, decode_modules_, current_modules_; const MNN::Express::Module* base_module_ = nullptr; void init_runtime(); - std::string decode(int id); - bool is_stop(int token_id); - virtual std::vector tokenizer(const std::string& query); virtual MNN::Express::VARP embedding(const std::vector& input_ids); - virtual MNN::Express::VARP gen_attention_mask(int seq_len); - virtual MNN::Express::VARP gen_position_ids(int seq_len); + virtual MNN::Express::VARP gen_attention_mask(int seq_len, int kv_seq_len_, int gen_seq_len_); + virtual MNN::Express::VARP gen_position_ids(int seq_len, int kv_seq_len_, int gen_seq_len); bool mTracing = false; }; @@ -119,8 +108,8 @@ class Embedding : public Llm { int dim() const; private: virtual std::vector tokenizer(const std::string& query) override; - virtual MNN::Express::VARP gen_attention_mask(int seq_len) override; - virtual MNN::Express::VARP gen_position_ids(int seq_len) override; + virtual MNN::Express::VARP gen_attention_mask(int seq_len); + virtual MNN::Express::VARP gen_position_ids(int seq_len); }; // Embedding end } diff --git a/transformers/llm/engine/src/llmconfig.hpp b/transformers/llm/engine/include/llmconfig.hpp similarity index 73% rename from transformers/llm/engine/src/llmconfig.hpp rename to transformers/llm/engine/include/llmconfig.hpp index 78bd3bc61..f94067353 100644 --- a/transformers/llm/engine/src/llmconfig.hpp +++ b/transformers/llm/engine/include/llmconfig.hpp @@ -5,9 +5,18 @@ // ZhaodeWang // +#ifndef LLMCONFIG_Hpp +#define LLMCONFIG_Hpp + +#include +#include +#include +#include #include "rapidjson/document.h" #include #include + + namespace MNN { namespace Transformer { @@ -36,31 +45,7 @@ static inline std::string file_name(const std::string& path) { } bool merge_json(rapidjson::Value& destination, const rapidjson::Value& source, - rapidjson::Document::AllocatorType& allocator) { - if (!source.IsObject() || !destination.IsObject()) { - return false; - } - - for (auto it = source.MemberBegin(); it != source.MemberEnd(); ++it) { - const char* key = it->name.GetString(); - if (destination.HasMember(key)) { - if (destination[key].IsObject() && it->value.IsObject()) { - // Recursively merge the two JSON objects - merge_json(destination[key], it->value, allocator); - } else { - // Overwrite the value in the destination - destination[key].CopyFrom(it->value, allocator); - } - } else { - // Add the value to the destination - rapidjson::Value newKey(key, allocator); - rapidjson::Value newValue; - newValue.CopyFrom(it->value, allocator); - destination.AddMember(newKey, newValue, allocator); - } - } - return true; -} + rapidjson::Document::AllocatorType& allocator); class rapid_json_wrapper { public: @@ -98,6 +83,13 @@ class rapid_json_wrapper { return buffer.GetString(); } // read value + float value(const char* key, const float& default_value) const { + if (document.HasMember(key)) { + const auto& value = document[key]; + if (value.IsFloat()) return value.GetFloat(); + } + return default_value; + } int value(const char* key, const int& default_value) const { if (document.HasMember(key)) { const auto& value = document[key]; @@ -149,6 +141,21 @@ class rapid_json_wrapper { } return default_value; } + std::vector value(const char* key, const std::vector& default_value) const { + if (document.HasMember(key)) { + const auto& value = document[key]; + if (value.IsArray()) { + std::vector result; + for (auto& v : value.GetArray()) { + if (v.IsString()) { + result.push_back(v.GetString()); + } + } + return result; + } + } + return default_value; + } std::string value(const char key[], const char default_value[]) const { return value(key, std::string(default_value)); } @@ -235,12 +242,16 @@ class LlmConfig { // model file config end > // < generate config start + int max_all_tokens() const { + return config_.value("max_all_tokens", 2048); + } + int max_new_tokens() const { return config_.value("max_new_tokens", 512); } bool reuse_kv() const { - return config_.value("reuse_kv", false); + return config_.value("reuse_kv", true); } // generate config end > @@ -311,14 +322,84 @@ class LlmConfig { return llm_config_.value("attention_fused", true); } - std::string chat_template() const { - return llm_config_.value("chat_template", ""); + // std::string chat_template() const { + // return llm_config_.value("chat_template", ""); + // } + + // std::string prompt_template() const { + // return llm_config_.value("prompt_template", ""); + // } + + // std::string eos_token() const { + // return llm_config_.value("eos_token", "") + // } + + std::string system_prompt_template() const { + return llm_config_.value("system_prompt_template", "<|im_start|>system\n%s<|im_end|>\n"); } - std::string prompt_template() const { - return llm_config_.value("prompt_template", ""); + std::string user_prompt_template() const { + return llm_config_.value("user_prompt_template", "<|im_start|>user\n%s<|im_end|>\n"); + } + std::string assistant_prefix() const { + return llm_config_.value("assistant_prefix", "<|im_start|>assistant\n"); + } + std::string assistant_suffix() const { + return llm_config_.value("assistant_suffix", "<|im_end|>\n"); } // llm model config end > + + // < sampler config start + std::string sampler_type() const { + return config_.value("sampler_type", "greedy"); + } + + std::vector mixed_samplers() const { + return config_.value("mixed_samplers", std::vector({"topK", "tfs", "typical", "topP", "min_p", "temperature"})); + } + + float temperature() const { + return config_.value("temperature", 1.0f); + } + + int topK() const { + return config_.value("topK", 40); + } + + float topP() const { + return config_.value("topP", 0.9f); + } + + float minP() const { + return config_.value("minP", 0.1f); + } + + float tfsZ() const { + return config_.value("tfsZ", 1.0f); + } + + float typical() const { + return config_.value("typical", 1.0f); + } + + float penalty() const { + return config_.value("penalty", 0.0f); + } + + int ngram() const { + return config_.value("n_gram", 8); + } + + float ngram_factor() const { + return config_.value("ngram_factor", 1.0f); + } + + std::string penalty_sampler() const { + return config_.value("penalty_sampler", "greedy"); + } + // sampler config end > }; } // Transformer } // MNN + +#endif diff --git a/transformers/llm/engine/include/prompt/prompt.hpp b/transformers/llm/engine/include/prompt/prompt.hpp new file mode 100644 index 000000000..ecd096ee7 --- /dev/null +++ b/transformers/llm/engine/include/prompt/prompt.hpp @@ -0,0 +1,58 @@ + + +#ifndef PROMPT_Hpp +#define PROMPT_Hpp + +#include "llm/llm.hpp" +#include "sampler/sampler.hpp" +#include "llmconfig.hpp" +#define MNN_OPEN_TIME_TRACE +#include +#include +#include +#include +#include + +// +#define PromptItem std::pair + + +namespace MNN { +namespace Transformer { + +/* PromptLib: history organization + input organization */ +class MNN_PUBLIC PromptLib { +public: + std::vector mHistory; + std::vector mInputs; +public: + static PromptLib* createPromptLib(const std::string prompt_type, const std::string& config_path); + virtual void appendSystemPrompt(const std::string& sys_prompt) = 0; + virtual void appendUserPrompt(const std::string& use_prompt) = 0; + virtual void appendLLMOutput(std::string out_str) = 0; + virtual std::string getLLMInput() = 0; + virtual void reset(); +}; + +class MNN_PUBLIC BaseChatPromptLib : public PromptLib { +protected: + bool mReuseKV; + std::string mSystemTemplate; + std::string mUserTemplate; + std::string mAssistantPrefix; + std::string mAssistantSuffix; + std::string applyTemplate(PromptItem item, std::string prompt_template, std::string placeholder = "%s"); + std::string applyTemplates(std::vector inputs); +public: + BaseChatPromptLib(std::shared_ptr config); + virtual void appendSystemPrompt(const std::string& sys_prompt) override; + virtual void appendUserPrompt(const std::string& user_prompt) override; + virtual void appendLLMOutput(std::string out_str) override; + virtual std::string getLLMInput() override; +}; + +} +} + + +#endif \ No newline at end of file diff --git a/transformers/llm/engine/include/sampler/sampler.hpp b/transformers/llm/engine/include/sampler/sampler.hpp new file mode 100644 index 000000000..3d36a3007 --- /dev/null +++ b/transformers/llm/engine/include/sampler/sampler.hpp @@ -0,0 +1,146 @@ +#ifndef SAMPLER_hpp +#define SAMPLER_hpp + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "evaluation/evaluation.hpp" +#include "llmconfig.hpp" + + +namespace MNN { +namespace Transformer { + +class Llm; + +// a index and its corresponding score +struct IndexScore { + int index; + float score; +}; +struct IndexScoreCmpLess{ + bool operator()(IndexScore a, IndexScore b) { + return a.score < b.score; + } +}; +struct IndexScoreCmpGreater{ + bool operator()(IndexScore a, IndexScore b) { + return a.score > b.score; + } +}; +// a series of index and their corresponding logits +struct SubsetLogits{ + std::vector index; + MNN::Express::VARP logits; + bool is_subset; +}; +// sample candidate +struct SampleCandidate { + // StateCacheReference + int all_seq_len_=0, gen_seq_len_=0; + std::vector tokens; +}; + +class MNN_PUBLIC Sampler { +public: + class LlmSamplerConfig { + public: + int max_new_tokens = 512; + int max_all_tokens = 2048; + }; +protected: + Llm* mLlm; + std::vector mCandidates; + int select(struct SubsetLogits& subset, int id); + int randomSelect(float* probs, size_t size); + int randomSelect(MNN::Express::VARP probs); + int reSoftmaxSelect(struct SubsetLogits subset, float temperature=1.0); + SubsetLogits createSubsetLogits(MNN::Express::VARP logits); + SubsetLogits createSubsetLogits(MNN::Express::VARP logits, const std::vector& index); + SubsetLogits createSubsetLogits(int size); + SubsetLogits createSubsetLogits(const std::vector& scores, const std::vector& index); + void transformIndex(struct SubsetLogits& superset, struct SubsetLogits& subset); +public: + static Sampler* createSampler(Llm* llm, const std::string& config_path); + virtual std::string sample(const std::vector& input_ids, std::ostream* os = &std::cout, const char* end_with = nullptr, struct TimePerformance* time_perf = nullptr) = 0; + // prepare for another round of sampling + // in the future, only reset its own. + virtual void reset(Llm* llm) {} + virtual void reset() {} +}; + + +class MNN_PUBLIC LocalSampler: public Sampler { +public: + class LocalSamplerConfig : public LlmSamplerConfig { + public: + struct SamplerPenaltyConfig { + float penalty = 1.05; + int ngram = 8; + float ngram_factor = 1.02; // panalize repeated ngram with a multiplied ngram_factor. + float max_penalty = 10.; + std::string sampler = "temperature"; // "greedy", "temperature". + }; + std::string type = "temperature"; + std::string select_type = "temperature"; + float temperature = 0.8; + int topK = 40; + float topP = 0.9; + float minP = 0.05; + float tfsZ = 1.0; + float typical = 0.95; + struct SamplerPenaltyConfig penaltyConfig; + std::vector mixedSamplers= {"topK", "tfs", "typical", "topP", "min_p", "temperature"}; + void configSampler(std::string sampler_type, std::shared_ptr llmConfig); + void configGreedy(std::shared_ptr llmConfig); + void configTemperature(std::shared_ptr llmConfig); + void configTopK(std::shared_ptr llmConfig); + void configTopP(std::shared_ptr llmConfig); + void configMinP(std::shared_ptr llmConfig); + void configTFS(std::shared_ptr llmConfig); + void configTypical(std::shared_ptr llmConfig); + void configPenalty(std::shared_ptr llmConfig); + void configMixed(std::shared_ptr llmConfig); + }; +protected: + LocalSamplerConfig mConfig; + LocalSamplerConfig getSamplerConfig(std::shared_ptr llmConfig); + int argmaxSelect(struct SubsetLogits superset); + int packSoftmax(MNN::Express::VARP logits, std::vector& index_scores, float temperature = 1.0); + struct SubsetLogits penalty(struct SubsetLogits superset); + struct SubsetLogits topK(struct SubsetLogits superset); + struct SubsetLogits topP(struct SubsetLogits superset); + struct SubsetLogits minP(struct SubsetLogits superset); + struct SubsetLogits tfs(struct SubsetLogits superset); + struct SubsetLogits typical(struct SubsetLogits superset); + struct SubsetLogits mixed(struct SubsetLogits subset); + struct SubsetLogits subsetSampler(std::string sampler_type, struct SubsetLogits subset); + int handleSelect(struct SubsetLogits subset); + std::string handleToken(int token, std::ostream* os = &std::cout, const char* end_with = nullptr); +public: + LocalSampler(Llm* llm, const std::string& config_path); + int algorithm(MNN::Express::VARP logits); + virtual std::string sample(const std::vector& input_ids, std::ostream* os = &std::cout, const char* end_with = nullptr, struct TimePerformance* time_perf = nullptr) override; + virtual void reset(Llm* llm) override; + virtual void reset() override; +}; + + +} // Transformer +} // MNN + + +#endif // SAMPLER_hpp \ No newline at end of file diff --git a/transformers/llm/engine/src/chat.cpp b/transformers/llm/engine/src/chat.cpp new file mode 100644 index 000000000..e5fc726bf --- /dev/null +++ b/transformers/llm/engine/src/chat.cpp @@ -0,0 +1,93 @@ +// +// llm_demo.cpp +// +// Created by MNN on 2023/03/24. +// ZhaodeWang +// + +#include "app/chat/chat.hpp" +#include "llm/llm.hpp" +#include "sampler/sampler.hpp" +#include "prompt/prompt.hpp" +#include "evaluation/evaluation.hpp" +#define MNN_OPEN_TIME_TRACE +#include +#include +#include +#include +#include + +using namespace MNN::Express; +namespace MNN { +namespace Transformer { + +Chat::Chat(std::string config_path) { + // 0. create Executor + MNN::BackendConfig backendConfig; + auto executor = MNN::Express::Executor::newExecutor(MNN_FORWARD_CPU, backendConfig, 1); + MNN::Express::ExecutorScope s(executor); + // 1. create Llm + std::cout << "LLM config path is " << config_path << std::endl; + mLlm.reset(Llm::createLLM(config_path)); + mLlm->load(); + mLlm->set_config("{\"tmp_path\":\"tmp\"}"); + // 2. create Sampler + mSampler.reset(Sampler::createSampler(mLlm.get(), config_path)); + // 3. create PromptLib + mPromptLib.reset(PromptLib::createPromptLib("BaseChat", config_path)); +} + +void Chat::generate_init() { + // init status + mLlm->generate_init(); + if (!mLlm->reuse_kv()) { + // no reuse, clear cached tokens. A brand-new prompt starts! + mSampler->reset(); + mLlm->reset(); + } +} + +std::string Chat::generate(const std::string& prompt, std::ostream* os, const char* end_with) { + if (prompt.empty()) { return ""; } + if (!end_with) { end_with = "\n"; } + generate_init(); + // std::cout << "# prompt : " << prompt << std::endl; + auto input_ids = mLlm->tokenizer(prompt); + // printf("input_ids (%lu): ", input_ids.size()); for (auto id : input_ids) printf("%d, ", id); printf("\n"); + struct TimePerformance* time_perf = new struct TimePerformance; + std::string out_str = mSampler->sample(input_ids, os, end_with, time_perf); + delete time_perf; + return out_str; +} + + +void Chat::chat(std::istream* is, std::ostream* os, const char* end_with) { + // handle system prompt + mPromptLib->reset(); + mPromptLib->appendSystemPrompt("You are a helpful assistant!\n"); + while (true) { + // get user string + std::cout << "\nQ: "; + std::string user_str; + std::getline(*is, user_str); + // special instructions + if (user_str == "/exit") { + mPromptLib->reset(); + break; + } + if (user_str == "/reset") { + mPromptLib->reset(); + std::cout << "\nA: reset done." << std::endl; + continue; + } + // get answer + std::cout << "\nA: " << std::flush; + mPromptLib->appendUserPrompt(user_str); + auto assistant_str = generate(mPromptLib->getLLMInput(), os, end_with); + mPromptLib->appendLLMOutput(assistant_str); + std::cout << std::endl; + } +} + +} // Transformer +} // MNN diff --git a/transformers/llm/engine/src/llm.cpp b/transformers/llm/engine/src/llm.cpp index 991c6c7ef..bffe7b5d7 100644 --- a/transformers/llm/engine/src/llm.cpp +++ b/transformers/llm/engine/src/llm.cpp @@ -16,6 +16,7 @@ #include #include "cpp/ExprDebug.hpp" #include "llm/llm.hpp" +#include "sampler/sampler.hpp" #include "tokenizer.hpp" #include "llmconfig.hpp" // 0: no debug, 1: test op time, 2: print tensor info @@ -248,10 +249,12 @@ void Llm::trace(bool start) { mTracing = start; } -VARP Llm::forward(const std::vector& input_ids) { +VARP Llm::forward(const std::vector& input_ids, int kv_seq_len_, int gen_seq_len_, bool is_prefill) { + if (is_prefill) current_modules_ = prefill_modules_; + else current_modules_ = decode_modules_; int seq_len = input_ids.size(); - auto attention_mask = gen_attention_mask(seq_len); - auto position_ids = gen_position_ids(seq_len); + auto attention_mask = gen_attention_mask(seq_len, kv_seq_len_, gen_seq_len_); + auto position_ids = gen_position_ids(seq_len, kv_seq_len_, gen_seq_len_); VARP logits; if (is_single_) { std::vector outputs; @@ -272,238 +275,50 @@ VARP Llm::forward(const std::vector& input_ids) { MNN_ERROR("Split models is depercarate\n"); return nullptr; } - all_seq_len_ += seq_len; - gen_seq_len_++; return logits; } -int Llm::sample(VARP logits, const std::vector& pre_ids) { - std::unordered_set ids_set(pre_ids.begin(), pre_ids.end()); - auto scores = (float*)(logits->readMap()); - auto size = logits->getInfo()->size; - // repetition penalty - const float repetition_penalty = 1.1; - for (auto id : ids_set) { - float score = scores[id]; - scores[id] = score < 0 ? score * repetition_penalty : score / repetition_penalty; - } - // argmax - float max_score = 0; - int token_id = 0; - for (int i = 0; i < size; i++) { - float score = scores[i]; - if (score > max_score) { - max_score = score; - token_id = i; - } - } - return token_id; -} -static std::string apply_template(std::string prompt_template, const std::string& content, const std::string& role = "") { - if (prompt_template.empty()) return content; - if (!role.empty()) { - const std::string placeholder = "%r"; - size_t start_pos = prompt_template.find(placeholder); - if (start_pos == std::string::npos) return content; - prompt_template.replace(start_pos, placeholder.length(), role); - } - const std::string placeholder = "%s"; - size_t start_pos = prompt_template.find(placeholder); - if (start_pos == std::string::npos) return content; - prompt_template.replace(start_pos, placeholder.length(), content); - return prompt_template; -} -std::string Llm::apply_prompt_template(const std::string& user_content) const { - auto chat_prompt = config_->prompt_template(); - return apply_template(chat_prompt, user_content); -} -std::string Llm::apply_chat_template(const std::vector& chat_prompts) const { - auto chat_template = config_->chat_template(); - std::string prompt_result; - auto iter = chat_prompts.begin(); - for (; iter != chat_prompts.end() - 1; ++iter) { - prompt_result += apply_template(chat_template, iter->second, iter->first); - } - if (iter->first == "user") { - prompt_result += apply_prompt_template(iter->second); - } else { - prompt_result += apply_template(chat_template, iter->second, iter->first); - } - return prompt_result; -} - -void Llm::chat() { - std::vector history; - history.push_back(std::make_pair("system", "You are a helpful assistant.")); - while (true) { - std::cout << "\nQ: "; - std::string user_str; - std::cin >> user_str; - if (user_str == "/exit") { - break; - } - if (user_str == "/reset") { - history.resize(1); - std::cout << "\nA: reset done." << std::endl; - continue; - } - std::cout << "\nA: " << std::flush; - if (config_->reuse_kv()) { - response(user_str); - } else { - history.emplace_back(std::make_pair("user", user_str)); - auto assistant_str = response(history); - history.emplace_back(std::make_pair("assistant", assistant_str)); - } - std::cout << std::endl; - } +void Llm::reset() { + // clear KV cache } -void Llm::reset() { - history_ids_.clear(); - all_seq_len_ = 0; +bool Llm::reuse_kv() const { + return config_->reuse_kv(); } void Llm::generate_init() { - // init status - gen_seq_len_ = 0; - prefill_us_ = 0; - decode_us_ = 0; + // handle past_key_values if not attention_fused_ past_key_values_.clear(); - if (is_single_) { - past_key_values_.push_back(_Input(key_value_shape_, NCHW)); - } else { - for (int i = 0; i < config_->layer_nums(); i++) { + if (!attention_fused_) { + if (is_single_) { past_key_values_.push_back(_Input(key_value_shape_, NCHW)); + } else { + MNN_ERROR("Split version is depercerate\n"); } } - if (!config_->reuse_kv()) { - all_seq_len_ = 0; - history_ids_.clear(); - } -} - -std::vector Llm::generate(const std::vector& input_ids, int max_new_tokens) { - generate_init(); - std::vector output_ids, all_ids = input_ids; - prompt_len_ = static_cast(input_ids.size()); - if (max_new_tokens < 0) { max_new_tokens = config_->max_new_tokens(); } - // prefill - current_modules_ = prefill_modules_; - auto logits = forward(input_ids); - if (logits.get() == nullptr) { - return {}; - } - int token = sample(logits, all_ids); - output_ids.push_back(token); - all_ids.push_back(token); - // decode - current_modules_ = decode_modules_; - while (gen_seq_len_ < max_new_tokens) { - logits = nullptr; - logits = forward({token}); - if (logits.get() == nullptr) { - return {}; - } - token = sample(logits, all_ids); - if (is_stop(token)) { break; } - output_ids.push_back(token); - all_ids.push_back(token); - } - return output_ids; } -std::string Llm::generate(const std::vector& input_ids, std::ostream* os, const char* end_with) { + +std::string Llm::generateTrace(const std::vector& input_ids, std::ostream* os, const char* end_with) { if (mTracing) { // Skip real forward current_modules_ = prefill_modules_; - forward(input_ids); + forward(input_ids, input_ids.size(), 0, true); current_modules_ = decode_modules_; - forward({input_ids[0]}); - forward({input_ids[0]}); + forward({input_ids[0]}, input_ids.size() + 1, 1, false); + forward({input_ids[0]}, input_ids.size() + 2, 1, false); return "Test"; } - prompt_len_ = static_cast(input_ids.size()); - history_ids_.insert(history_ids_.end(), input_ids.begin(), input_ids.end()); // push to history_ids_ - auto st = std::chrono::system_clock::now(); - current_modules_ = prefill_modules_; - auto logits = forward(input_ids); - if (nullptr == logits.get()) { - return ""; - } - int token = sample(logits, history_ids_); - auto et = std::chrono::system_clock::now(); - current_modules_ = decode_modules_; - std::string output_str = decode(token); - prefill_us_ = std::chrono::duration_cast(et - st).count(); - *os << output_str << std::flush; - while (gen_seq_len_ < config_->max_new_tokens()) { - st = std::chrono::system_clock::now(); - history_ids_.push_back(token); - logits = nullptr; - logits = forward({token}); - if (nullptr == logits.get()) { - return ""; - } - if (logits->getInfo()->size == 0) { - return ""; - } - token = sample(logits, history_ids_); - et = std::chrono::system_clock::now(); - decode_us_ += std::chrono::duration_cast(et - st).count(); - if (is_stop(token)) { - *os << end_with << std::flush; - break; - } - auto word = decode(token); - *os << word << std::flush; - output_str += word; - } - ExecutorScope::Current()->gc(Executor::FULL); -#ifdef DUMP_PROFILE_INFO - print_speed(); -#endif - return output_str; + return "Test"; } -std::vector Llm::tokenizer(const std::string& user_content) { - auto prompt = apply_prompt_template(user_content); - auto input_ids = tokenizer_->encode(prompt); - return input_ids; +std::vector Llm::tokenizer(const std::string& prompt) { + return tokenizer_->encode(prompt); } -std::string Llm::response(const std::string& user_content, std::ostream* os, const char* end_with) { - generate_init(); - if (!end_with) { end_with = "\n"; } - std::vector input_ids; - if (config_->reuse_kv()) { - auto prompt = apply_prompt_template(user_content); - if (all_seq_len_ > 0) { - prompt = "<|im_end|>\n" + prompt; - } - input_ids = tokenizer_->encode(prompt); - } else { - input_ids = tokenizer(user_content); - } - return generate(input_ids, os, end_with); -} - -std::string Llm::response(const std::vector& chat_prompts, std::ostream* os, const char* end_with) { - if (chat_prompts.empty()) { return ""; } - generate_init(); - if (!end_with) { end_with = "\n"; } - auto prompt = apply_chat_template(chat_prompts); - if (config_->reuse_kv() && all_seq_len_ > 0) { - prompt = "<|im_end|>\n" + prompt; - } - // std::cout << "# prompt : " << prompt << std::endl; - auto input_ids = tokenizer_->encode(prompt); - // printf("input_ids (%lu): ", input_ids.size()); for (auto id : input_ids) printf("%d, ", id); printf("\n"); - return generate(input_ids, os, end_with); -} Llm::~Llm() { #if DEBUG_MODE==1 @@ -536,21 +351,21 @@ Llm::~Llm() { } void Llm::print_speed() { - auto prefill_s = prefill_us_ * 1e-6; - auto decode_s = decode_us_ * 1e-6; - auto total_s = prefill_s + decode_s; - printf("\n#################################\n"); - printf(" total tokens num = %d\n", prompt_len_ + gen_seq_len_); - printf("prompt tokens num = %d\n", prompt_len_); - printf("output tokens num = %d\n", gen_seq_len_); - printf(" total time = %.2f s\n", total_s); - printf("prefill time = %.2f s\n", prefill_s); - printf(" decode time = %.2f s\n", decode_s); - printf(" total speed = %.2f tok/s\n", (prompt_len_ + gen_seq_len_) / total_s); - printf("prefill speed = %.2f tok/s\n", prompt_len_ / prefill_s); - printf(" decode speed = %.2f tok/s\n", gen_seq_len_ / decode_s); - printf(" chat speed = %.2f tok/s\n", gen_seq_len_ / total_s); - printf("##################################\n"); + // auto prefill_s = prefill_us_ * 1e-6; + // auto decode_s = decode_us_ * 1e-6; + // auto total_s = prefill_s + decode_s; + // printf("\n#################################\n"); + // printf(" total tokens num = %d\n", prompt_len_ + gen_seq_len_); + // printf("prompt tokens num = %d\n", prompt_len_); + // printf("output tokens num = %d\n", gen_seq_len_); + // printf(" total time = %.2f s\n", total_s); + // printf("prefill time = %.2f s\n", prefill_s); + // printf(" decode time = %.2f s\n", decode_s); + // printf(" total speed = %.2f tok/s\n", (prompt_len_ + gen_seq_len_) / total_s); + // printf("prefill speed = %.2f tok/s\n", prompt_len_ / prefill_s); + // printf(" decode speed = %.2f tok/s\n", gen_seq_len_ / decode_s); + // printf(" chat speed = %.2f tok/s\n", gen_seq_len_ / total_s); + // printf("##################################\n"); } static inline bool needNewVar(VARP var, int axis, int seq_len) { @@ -599,35 +414,35 @@ std::string Llm::decode(int id) { return word; } -VARP Llm::gen_attention_mask(int seq_len) { - int kv_seq_len = all_seq_len_ + seq_len; +VARP Llm::gen_attention_mask(int seq_len, int kv_seq_len_, int gen_seq_len_) { + int prev_seq_len_ = kv_seq_len_ - seq_len; if (seq_len == 1) { - kv_seq_len = seq_len; + kv_seq_len_ = seq_len; } if (config_->attention_mask() == "float") { if (needNewVar(attention_mask_, 2, seq_len)) { - attention_mask_ = _Input({1, 1, seq_len, kv_seq_len}, NCHW, halide_type_of()); + attention_mask_ = _Input({1, 1, seq_len, kv_seq_len_}, NCHW, halide_type_of()); } else { return attention_mask_; } auto ptr = attention_mask_->writeMap(); for (int i = 0; i < seq_len; i++) { - for (int j = 0; j < kv_seq_len; j++) { - int row = i + all_seq_len_; - ptr[kv_seq_len * i + j] = (j > row) * std::numeric_limits::lowest(); + for (int j = 0; j < kv_seq_len_; j++) { + int row = i + prev_seq_len_; + ptr[kv_seq_len_ * i + j] = (j > row) * std::numeric_limits::lowest(); } } return attention_mask_; } else { if (needNewVar(attention_mask_, 2, seq_len)) { - attention_mask_ = _Input({1, 1, seq_len, kv_seq_len}, NCHW, halide_type_of()); + attention_mask_ = _Input({1, 1, seq_len, kv_seq_len_}, NCHW, halide_type_of()); } else { return attention_mask_; } auto ptr = attention_mask_->writeMap(); if (config_->attention_mask() == "glm") { // chatglm - for (int i = 0; i < seq_len * kv_seq_len; i++) { + for (int i = 0; i < seq_len * kv_seq_len_; i++) { ptr[i] = 0; } if (seq_len > 1) { @@ -638,8 +453,8 @@ VARP Llm::gen_attention_mask(int seq_len) { } else { bool is_glm2 = config_->attention_mask() == "glm2"; for (int i = 0; i < seq_len; i++) { - for (int j = 0; j < kv_seq_len; j++) { - int row = i + all_seq_len_; + for (int j = 0; j < kv_seq_len_; j++) { + int row = i + prev_seq_len_; ptr[seq_len * i + j] = is_glm2 ? j > row : j <= row; } } @@ -648,7 +463,8 @@ VARP Llm::gen_attention_mask(int seq_len) { } } -VARP Llm::gen_position_ids(int seq_len) { +VARP Llm::gen_position_ids(int seq_len, int kv_seq_len_, int gen_seq_len_) { + int prev_seq_len_ = kv_seq_len_ - seq_len; if (config_->attention_mask() == "glm") { // chatglm if (needNewVar(position_ids_, 2, seq_len)) { @@ -656,7 +472,7 @@ VARP Llm::gen_position_ids(int seq_len) { } auto ptr = position_ids_->writeMap(); if (seq_len == 1) { - ptr[0] = all_seq_len_ - gen_seq_len_ - 2; + ptr[0] = prev_seq_len_ - gen_seq_len_ - 2; ptr[1] = gen_seq_len_ + 1; } else { for (int i = 0; i < seq_len - 1; i++) { @@ -674,10 +490,10 @@ VARP Llm::gen_position_ids(int seq_len) { } auto ptr = position_ids_->writeMap(); if (seq_len == 1) { - ptr[0] = is_glm2 ? gen_seq_len_ : all_seq_len_; + ptr[0] = is_glm2 ? gen_seq_len_ : prev_seq_len_; } else { for (int i = 0; i < seq_len; i++) { - ptr[i] = i + all_seq_len_; + ptr[i] = i + prev_seq_len_; } } return position_ids_; @@ -745,8 +561,7 @@ std::vector Lvlm::image_process(const std::string& image_info) { #endif } -std::vector Lvlm::tokenizer(const std::string& query) { - auto prompt = apply_prompt_template(query); +std::vector Lvlm::tokenizer(const std::string& prompt) { // split query std::regex img_regex("(.*?)"); std::string::const_iterator searchStart(prompt.cbegin()); @@ -857,9 +672,7 @@ VARP Embedding::txt_embedding(const std::string& txt) { } std::vector Embedding::tokenizer(const std::string& query) { - auto prompt = apply_prompt_template(query); - auto ids = tokenizer_->encode(prompt); - return ids; + return tokenizer_->encode(query); } VARP Embedding::gen_attention_mask(int seq_len) { diff --git a/transformers/llm/engine/src/llmconfig.cpp b/transformers/llm/engine/src/llmconfig.cpp new file mode 100644 index 000000000..458f3c4d1 --- /dev/null +++ b/transformers/llm/engine/src/llmconfig.cpp @@ -0,0 +1,47 @@ +// +// llmconfig.hpp +// +// Created by MNN on 2024/07/19. +// ZhaodeWang +// + + + +#include "rapidjson/document.h" +#include +#include +#include "llmconfig.hpp" + +namespace MNN { +namespace Transformer { + +bool merge_json(rapidjson::Value& destination, const rapidjson::Value& source, + rapidjson::Document::AllocatorType& allocator) { + if (!source.IsObject() || !destination.IsObject()) { + return false; + } + + for (auto it = source.MemberBegin(); it != source.MemberEnd(); ++it) { + const char* key = it->name.GetString(); + if (destination.HasMember(key)) { + if (destination[key].IsObject() && it->value.IsObject()) { + // Recursively merge the two JSON objects + merge_json(destination[key], it->value, allocator); + } else { + // Overwrite the value in the destination + destination[key].CopyFrom(it->value, allocator); + } + } else { + // Add the value to the destination + rapidjson::Value newKey(key, allocator); + rapidjson::Value newValue; + newValue.CopyFrom(it->value, allocator); + destination.AddMember(newKey, newValue, allocator); + } + } + return true; +} + +} // Transformer +} // MNN + diff --git a/transformers/llm/engine/src/prompt.cpp b/transformers/llm/engine/src/prompt.cpp new file mode 100644 index 000000000..20a0b86ac --- /dev/null +++ b/transformers/llm/engine/src/prompt.cpp @@ -0,0 +1,98 @@ +#include "prompt/prompt.hpp" + +namespace MNN { +namespace Transformer { + +/* ----------PromptLib---------- */ +PromptLib* PromptLib::createPromptLib(const std::string prompt_type, const std::string& config_path) { + std::shared_ptr config(new LlmConfig(config_path)); + if (prompt_type == "BaseChat") { + return new BaseChatPromptLib(config); + } else { + std::cout << "PromptLib not Implemented!\n" << std::endl; + return nullptr; + } +} + +void PromptLib::reset() { + mHistory.clear(); + mInputs.clear(); +} + +/* ----------BaseChatPromptLib---------- */ +BaseChatPromptLib::BaseChatPromptLib(std::shared_ptr config) { + mReuseKV = config->reuse_kv(); + mSystemTemplate = config->system_prompt_template(); + mUserTemplate = config->user_prompt_template(); + mAssistantPrefix = config->assistant_prefix(); + mAssistantSuffix = config->assistant_suffix(); + mHistory.clear(); + mInputs.clear(); +} + +void BaseChatPromptLib::appendSystemPrompt(const std::string& sys_prompt) { + mHistory.emplace_back(std::make_pair("system", sys_prompt)); + mInputs.emplace_back(std::make_pair("system", sys_prompt)); +} +void BaseChatPromptLib::appendUserPrompt(const std::string& user_prompt) { + mHistory.emplace_back(std::make_pair("user", user_prompt)); + mInputs.emplace_back(std::make_pair("user", user_prompt)); +} +void BaseChatPromptLib::appendLLMOutput(std::string out_str) { + mHistory.emplace_back(std::make_pair("assistant", out_str)); + if (mReuseKV) { + // clear input + mInputs.clear(); + } else { + // keep input, append output + mInputs.emplace_back(std::make_pair("assistant", out_str)); + } +} + +std::string BaseChatPromptLib::getLLMInput() { + std::string input_str; + if (mReuseKV) { + if (mHistory.size() != mInputs.size()) { + // 1.1 not first prefill, add end of speech. + input_str += mAssistantSuffix; + } + } + // 1.2 generate from template + input_str += applyTemplates(mInputs); + input_str += mAssistantPrefix; + return input_str; +} + +std::string BaseChatPromptLib::applyTemplate(PromptItem item, std::string prompt_template, std::string placeholder) { + size_t start_pos = prompt_template.find(placeholder); + if (start_pos == std::string::npos) return item.first + "\n" + item.second + "\n"; + else { + prompt_template.replace(start_pos, placeholder.length(), item.second); + return prompt_template; + } +} + +std::string BaseChatPromptLib::applyTemplates(std::vector inputs) { + std::string input_str; + for (auto input : inputs) { + if (input.first == "") continue; + if (input.first == "system") { + if (input.second == "") continue; + input_str += applyTemplate(input, mSystemTemplate, "%s"); + continue; + } + if (input.first == "user") { + input_str += applyTemplate(input, mUserTemplate, "%s"); + continue; + } + if (input.first == "assistant") { + input_str += mAssistantPrefix + input.second + mAssistantSuffix; + continue; + } + // Invalid role!!! + } + return input_str; +} + +} +} \ No newline at end of file diff --git a/transformers/llm/engine/src/sampler.cpp b/transformers/llm/engine/src/sampler.cpp new file mode 100644 index 000000000..805c31fce --- /dev/null +++ b/transformers/llm/engine/src/sampler.cpp @@ -0,0 +1,552 @@ +#include +#include +#include +#include +#include + +#include +#include +#include "llm/llm.hpp" +#include "sampler/sampler.hpp" +#include "llmconfig.hpp" + +namespace MNN{ +namespace Transformer{ + +/* ----------Sampler's members---------- */ +int Sampler::select(struct SubsetLogits& subset, int id) { + if (!(subset.is_subset)) return id; + return subset.index[id]; +} + +int Sampler::randomSelect(float* probs, size_t size) { + std::random_device rd; + std::mt19937 generator(rd()); + std::uniform_real_distribution distribution(0.0, 1.0); + float target = distribution(generator); + float cumulative = 0.0; + for (int i = 0; i < size; i++) { + cumulative += probs[i]; + if (target < cumulative) { + return i; + } + } + return size - 1; +} + +int Sampler::randomSelect(MNN::Express::VARP probs) { + return randomSelect((float*)(probs->readMap()), probs->getInfo()->size); +} + +int Sampler::reSoftmaxSelect(struct SubsetLogits subset, float temperature) { + int token_index_id = randomSelect(MNN::Express::_TempratureSoftmax(subset.logits, temperature)); + return ((subset.is_subset) ? subset.index[token_index_id] : token_index_id); +} + +SubsetLogits Sampler::createSubsetLogits(MNN::Express::VARP logits) { + struct SubsetLogits subset; + subset.logits = logits; + subset.is_subset = false; + return subset; +} + +SubsetLogits Sampler::createSubsetLogits(MNN::Express::VARP logits, const std::vector& index) { + struct SubsetLogits subset; + subset.logits = logits; + subset.index = index; + subset.is_subset = true; + return subset; +} + +SubsetLogits Sampler::createSubsetLogits(int size) { + struct SubsetLogits subset; + subset.logits = MNN::Express::_Input({size}, MNN::Express::NHWC); + subset.index.resize(size); + subset.is_subset = true; + return subset; +} + +SubsetLogits Sampler::createSubsetLogits(const std::vector& scores, const std::vector& index) { + int size = (int)(index.size()); + struct SubsetLogits subset; + subset.logits = MNN::Express::_Input({size}, MNN::Express::NHWC); + auto pointer = (float*)(subset.logits->writeMap()); + for (int i = 0; i < size; ++i) { + pointer[i] = scores[i]; + } + subset.index = index; + subset.is_subset = true; + return subset; +} + +void Sampler::transformIndex(struct SubsetLogits& superset, struct SubsetLogits& subset) { + if (!(superset.is_subset)) return; + for (auto& id : subset.index) { + id = superset.index[id]; + } +} + +Sampler* Sampler::createSampler(Llm* llm, const std::string& config_path) { + std::shared_ptr config(new LlmConfig(config_path)); + std::string sampler_type = config->sampler_type(); + if (sampler_type == "greedy" + || sampler_type == "temperature" + || sampler_type == "penalty" || sampler_type == "penalize_ngram" + || sampler_type == "topK" + || sampler_type == "topP" + || sampler_type == "minP" + || sampler_type == "tfs" + || sampler_type == "typical" + || sampler_type == "mixed" + ) { + return new LocalSampler(llm, config_path); + } else { + std::cout << "Designated Sampler Not Supported yet!"; + exit(1); + } + return nullptr; +} + + +/* ----------LocalSamplerConfig---------- */ +void LocalSampler::LocalSamplerConfig::configSampler( std::string sampler_type, std::shared_ptr llmConfig) { + if (sampler_type == "greedy"){ + this->configGreedy(llmConfig); + } else if (sampler_type == "temperature"){ + this->configTemperature(llmConfig); + } else if (sampler_type == "topK"){ + this->configTopK(llmConfig); + } else if (sampler_type == "topP"){ + this->configTopP(llmConfig); + } else if (sampler_type == "minP"){ + this->configMinP(llmConfig); + } else if (sampler_type == "tfs"){ + this->configTFS(llmConfig); + } else if (sampler_type == "typical"){ + this->configTypical(llmConfig); + } else if (sampler_type == "penalty" || sampler_type == "penalize_ngram"){ + this->configPenalty(llmConfig); + } else if (sampler_type == "mixed"){ + this->configMixed(llmConfig); + } +} +void LocalSampler::LocalSamplerConfig::configGreedy(std::shared_ptr llmConfig) { + select_type = "greedy"; +} +void LocalSampler::LocalSamplerConfig::configTemperature(std::shared_ptr llmConfig) { + temperature = llmConfig->temperature(); + select_type = "temperature"; +} +void LocalSampler::LocalSamplerConfig::configTopK(std::shared_ptr llmConfig) { + topK = llmConfig->topK(); + select_type = "temperature"; +} +void LocalSampler::LocalSamplerConfig::configTopP(std::shared_ptr llmConfig) { + topP = llmConfig->topP(); + temperature = llmConfig->temperature(); + select_type = "temperature"; +} +void LocalSampler::LocalSamplerConfig::configMinP(std::shared_ptr llmConfig) { + minP = llmConfig->minP(); + temperature = llmConfig->temperature(); + select_type = "temperature"; +} +void LocalSampler::LocalSamplerConfig::configTFS(std::shared_ptr llmConfig) { + tfsZ = llmConfig->tfsZ(); + temperature = llmConfig->temperature(); + select_type = "temperature"; +} +void LocalSampler::LocalSamplerConfig::configTypical(std::shared_ptr llmConfig) { + typical = llmConfig->typical(); + temperature = llmConfig->temperature(); + select_type = "temperature"; +} +void LocalSampler::LocalSamplerConfig::configPenalty(std::shared_ptr llmConfig) { + penaltyConfig.penalty = llmConfig->penalty(); + penaltyConfig.ngram = llmConfig->ngram(); + penaltyConfig.ngram_factor = llmConfig->ngram_factor(); + penaltyConfig.sampler = llmConfig->penalty_sampler(); + select_type = penaltyConfig.sampler; +} +void LocalSampler::LocalSamplerConfig::configMixed(std::shared_ptr llmConfig) { + mixedSamplers = llmConfig->mixed_samplers(); + std::cout << "Mixed Sampler Sequence: " << std::flush; + for (auto samplerName : mixedSamplers) { + this->configSampler(samplerName, llmConfig); + std::cout << samplerName << " " << std::flush; + } + std::cout << std::endl; + // set select type + // the final sampler select the token + if (mixedSamplers.back() == "greedy") select_type = "greedy"; + else if(mixedSamplers.back()=="temperature") select_type = "temperature"; + else select_type = "temperature"; // By default temperature is used. +} + + +/* ----------LocalSampler's members---------- */ +LocalSampler::LocalSamplerConfig LocalSampler::getSamplerConfig(std::shared_ptr llmConfig) { + LocalSampler::LocalSamplerConfig samplerConfig; + samplerConfig.max_all_tokens = llmConfig->max_all_tokens(); + samplerConfig.max_new_tokens = llmConfig->max_new_tokens(); + samplerConfig.type = llmConfig->sampler_type(); + std::string sampler_type = samplerConfig.type; + std::cout << "Sampler: " << sampler_type << std::endl; + samplerConfig.configSampler(sampler_type, llmConfig); + return samplerConfig; +} + +LocalSampler::LocalSampler(Llm* llm, const std::string& config_path) { + // initialize model and candidates + mLlm = llm; + mCandidates.emplace_back(SampleCandidate()); // for LocalSampler, reference have never been modified manually. + // initialize config + std::shared_ptr llmConfig(new LlmConfig(config_path)); + mConfig = getSamplerConfig(llmConfig); +} + +int LocalSampler::argmaxSelect(struct SubsetLogits superset) { + auto scores = (float*)(superset.logits->readMap()); + auto size = superset.logits->getInfo()->size; + float max_score = scores[0]; + int token_id = 0; + for (int i = 0; i < size; i++) { + float score = scores[i]; + if (score > max_score) { + max_score = score; + token_id = i; + } + } + return select(superset, token_id); +} + +struct SubsetLogits LocalSampler::topK(struct SubsetLogits superset) { + int K = mConfig.topK; + auto scores = (float*)(superset.logits->readMap()); + auto size = superset.logits->getInfo()->size; + // 1. time complexity: O(nlogk) + std::priority_queue, IndexScoreCmpGreater> heap; + for (int i = 0; i < size; i++) { + IndexScore m; + m.index = i; + m.score = scores[i]; + if (heap.size() < K) { + heap.push(m); + } + else { + if (heap.top().score < m.score) { + heap.pop(); + heap.push(m); + } + } + } + // 2. store top K results + auto subset = createSubsetLogits(K); + float* topKscores = (float*)(subset.logits->writeMap()); + for (int i = 0; i < K; i++) { + subset.index[K-i-1] = heap.top().index; + topKscores[K-i-1] = heap.top().score; + heap.pop(); + } + transformIndex(superset, subset); + return subset; +} + +int LocalSampler::packSoftmax(MNN::Express::VARP logits, std::vector& index_scores, float temperature) { + auto prob_varp = MNN::Express::_TempratureSoftmax(logits, temperature); + auto probs = (float*)(prob_varp->readMap()); + auto size = prob_varp->getInfo()->size; + index_scores.resize(size); + for (int i = 0; i < size; i++) { + IndexScore m; + m.index = i; + m.score = probs[i]; + index_scores[i] = m; + } + return size; +} + +struct SubsetLogits LocalSampler::topP(struct SubsetLogits superset) { + float p = mConfig.topP, temperature = mConfig.temperature; + std::vector index_scores; + int size = packSoftmax(superset.logits, index_scores, temperature); + // 1. make max heap + std::make_heap(index_scores.begin(), index_scores.end(), IndexScoreCmpLess()); + // 2. top p algorithm + auto scores = (float*)(superset.logits->readMap()); + std::vector index; + std::vector subset_logits; + float cumulative = 0.0f; + while (cumulative < p && !index_scores.empty()) { + std::pop_heap(index_scores.begin(), index_scores.end(), IndexScoreCmpLess()); + IndexScore m = index_scores.back(); + index_scores.pop_back(); + index.push_back(m.index); + subset_logits.push_back(scores[m.index]); + cumulative += m.score; + } + auto subset = createSubsetLogits(subset_logits, index); + transformIndex(superset, subset); + return subset; +} + +struct SubsetLogits LocalSampler::minP(struct SubsetLogits superset) { + float p = mConfig.minP, temperature = mConfig.temperature; + std::vector index_scores; + int size = packSoftmax(superset.logits, index_scores, temperature); + // 1. make max heap + std::make_heap(index_scores.begin(), index_scores.end(), IndexScoreCmpLess()); + // 2. min p algorithm + auto scores = (float*)(superset.logits->readMap()); + std::vector index; + std::vector subset_logits; + for (int i = 0; i < size; ++i) { + std::pop_heap(index_scores.begin(), index_scores.end(), IndexScoreCmpLess()); + IndexScore m = index_scores.back(); + if (m.score < p && !index.empty()) break; + index_scores.pop_back(); + index.push_back(m.index); + subset_logits.push_back(scores[m.index]); + } + auto subset = createSubsetLogits(subset_logits, index); + transformIndex(superset, subset); + return subset; +} + +struct SubsetLogits LocalSampler::tfs(struct SubsetLogits superset) { + float z = mConfig.tfsZ, temperature = mConfig.temperature; + // tfs algorithm + // 1. softmax + std::vector index_scores; + int size = packSoftmax(superset.logits, index_scores, temperature); + // 2. sort + std::sort(index_scores.begin(), index_scores.end(), IndexScoreCmpGreater()); + auto scores = (float*)(superset.logits->readMap()); + // 3. calculate derivatives + std::vector derivatives(size - 2, 0.0f); + float first = index_scores[0].score - index_scores[1].score; + float second = index_scores[1].score - index_scores[2].score; + for (int i = 0; i < size - 2; ++i) { + second = index_scores[i+1].score - index_scores[i+2].score; + derivatives[i] = std::fabs(first - second); + first = second; + } + // 4. normalize derivatives + float derivatives_sum = 0.0; + for (int i = 0; i < size - 2; ++i) derivatives_sum += derivatives[i]; + float derivatives_sum_rec = 1.0f / derivatives_sum; + for (int i = 0; i < size - 2; ++i) derivatives[i] *= derivatives_sum_rec; + // 5. cumulate, discard last 2 for sure. + float cumulative = 0.0; + std::vector index; + std::vector subset_logits; + for (int i = 0; i < size - 2; ++i) { + IndexScore m = index_scores[i]; + cumulative += derivatives[i]; + if (cumulative >= z && !index.empty()) break; + index.push_back(m.index); + subset_logits.push_back(scores[m.index]); + } + auto subset = createSubsetLogits(subset_logits, index); + transformIndex(superset, subset); + return subset; +} + +struct SubsetLogits LocalSampler::typical(struct SubsetLogits superset) { + float p = mConfig.typical, temperature = mConfig.temperature; + auto prob_varp = MNN::Express::_TempratureSoftmax(superset.logits, temperature); + auto probs = (float*)(prob_varp->readMap()); + auto size = prob_varp->getInfo()->size; + std::vector index_scores; + index_scores.resize(size); + // 1. calcaluate dist + float entropy = 0.0f; + for (int i = 0; i < size; i++) entropy -= probs[i] * std::log(probs[i]); + for (int i = 0; i < size; i++) { + IndexScore m; + m.index = i; + m.score = std::fabs(entropy + std::log(probs[i])); + index_scores[i] = m; + } + // 2. make min heap for dist + std::make_heap(index_scores.begin(), index_scores.end(), IndexScoreCmpGreater()); + // 3. typical p algorithm + auto scores = (float*)(superset.logits->readMap()); + float cumulative = 0.0f; + std::vector index; + std::vector subset_logits; + for (int i = 0; i < size; ++i) { + std::pop_heap(index_scores.begin(), index_scores.end(), IndexScoreCmpGreater()); + IndexScore m = index_scores.back(); + cumulative += probs[m.index]; + if (cumulative >= p && !index.empty()) break; + index_scores.pop_back(); + index.push_back(m.index); + subset_logits.push_back(scores[m.index]); + } + auto subset = createSubsetLogits(subset_logits, index); + transformIndex(superset, subset); + return subset; +} + +// presence penalty +// no frequency penalty now! +struct SubsetLogits LocalSampler::penalty(struct SubsetLogits subset) { + float penalty = mConfig.penaltyConfig.penalty; + int ngram = mConfig.penaltyConfig.ngram; + float ngram_factor = mConfig.penaltyConfig.ngram_factor; + float temperature = mConfig.temperature; + bool penalizeNgram = (mConfig.type == "penalize_ngram"); + if (penalty <= 1.0f) return subset; // no penalty! + if (ngram_factor <= 1.0f) penalizeNgram = false; // no extra penalty for n gram. + penalty = std::min(penalty, mConfig.penaltyConfig.max_penalty); + // initialization + std::vector& prev = mCandidates[0].tokens; + std::unordered_map penalty_map; + // 1. local ngram info, reversed order + std::vector ngram_info(ngram-1); + if (penalizeNgram) { + for (int n = 0; n < ngram_info.size(); ++n) { + ngram_info[n] = prev[prev.size()-1-n]; + } + } + // 2. generate penalty map + for (int i = 0; i < prev.size(); ++i) { + if (penalty_map.count(prev[i]) == 0) penalty_map[prev[i]] = penalty; + if (penalizeNgram) { + float ngram_penalty = penalty; + for (int j = i-1; i-j < ngram && j>=0; --j) { + int idx = i-j-1; + if (prev[j] != ngram_info[idx]) break; + ngram_penalty *= ngram_factor; + // no repeat larger than ngram! + if (idx == ngram_info.size()-1) ngram_penalty = mConfig.penaltyConfig.max_penalty; + } + if (ngram_penalty > penalty_map[prev[i]]) penalty_map[prev[i]] = ngram_penalty; + } + } + // 3. penalize logits according to penalty_map + auto scoresMap = (float*)(subset.logits->writeMap()); + for (auto it = penalty_map.begin(); it != penalty_map.end(); ++it) { + scoresMap[it->first] = (scoresMap[it->first] >= 0.0f) ? (scoresMap[it->first]/it->second) : (scoresMap[it->first]*it->second); + } + return subset; +} + +struct SubsetLogits LocalSampler::mixed(struct SubsetLogits subset) { + for (auto sampler : mConfig.mixedSamplers) { + subset = subsetSampler(sampler, subset); + } + return subset; +} + +struct SubsetLogits LocalSampler::subsetSampler(std::string sampler_type, struct SubsetLogits subset) { + if (sampler_type == "penalty") subset = penalty(subset); + if (sampler_type == "topK") subset = topK(subset); + if (sampler_type == "topP") subset = topP(subset); + if (sampler_type == "minP") subset = minP(subset); + if (sampler_type == "tfs") subset = tfs(subset); + if (sampler_type == "typical") subset = typical(subset); + if (sampler_type == "mixed") subset = mixed(subset); + // if greedy and temperate, just let the Selector handle it. + return subset; +} + +int LocalSampler::handleSelect(struct SubsetLogits subset) { + if (mConfig.select_type == "greedy") return argmaxSelect(subset); + else if(mConfig.select_type =="temperature") return reSoftmaxSelect(subset, mConfig.temperature); + return 0; +} + +int LocalSampler::algorithm(MNN::Express::VARP logits) { + struct SubsetLogits subset = createSubsetLogits(logits); + // process subsetSampler + subset = subsetSampler(mConfig.type, subset); + // select token from the subset + int res = handleSelect(subset); + // return + Express::ExecutorScope::Current()->gc(Express::Executor::FULL); + return res; +} + +std::string LocalSampler::handleToken(int token, std::ostream* os, const char* end_with) { + // CommonPrefix and Candidates managements + mCandidates[0].tokens.push_back(token); + mCandidates[0].all_seq_len_++; + mCandidates[0].gen_seq_len_++; + std::string output_str = mLlm->decode(mCandidates[0].tokens.back()); + // print + *os << output_str << std::flush; + return output_str; +} + +std::string LocalSampler::sample(const std::vector& input_ids, std::ostream* os, const char* end_with, struct TimePerformance* time_perf) { + // initialization for time performance + PrefillTimePerformance prefill_time; + prefill_time.prefill_prev_token_ = mCandidates[0].tokens.size(); + prefill_time.prefill_token_ = input_ids.size(); + // initialization + std::string output_str; + mCandidates[0].tokens.insert(mCandidates[0].tokens.end(), input_ids.begin(), input_ids.end()); + // all_seq_len_ in sampler functions as kv_seq_len_, prev_seq_len_ = all_seq_len_ - seq_len + mCandidates[0].all_seq_len_ = mCandidates[0].tokens.size(); + mCandidates[0].gen_seq_len_ = 0; + // prefill + auto st = std::chrono::system_clock::now(); + auto logits = mLlm->forward(input_ids, mCandidates[0].all_seq_len_, mCandidates[0].gen_seq_len_, true); + if (nullptr == logits.get()) { + return ""; + } + int token = algorithm(logits); + // record time + auto et = std::chrono::system_clock::now(); + prefill_time.prefill_us_ = std::chrono::duration_cast(et - st).count(); + time_perf->prefill_record_.push_back(prefill_time); + // handle the new token + output_str += handleToken(token, os, end_with); + // decode + while (mCandidates[0].gen_seq_len_ < mConfig.max_new_tokens + && mCandidates[0].all_seq_len_ < mConfig.max_all_tokens) { + DecodeTimePerformance decode_time; + decode_time.decode_prev_token_ = mCandidates[0].tokens.size(); + st = std::chrono::system_clock::now(); + // next token + logits = mLlm->forward({mCandidates[0].tokens.back()}, mCandidates[0].all_seq_len_, mCandidates[0].gen_seq_len_, false); + if (nullptr == logits.get()) { + return output_str; + } + if (logits->getInfo()->size == 0) { + return output_str; + } + token = algorithm(logits); + et = std::chrono::system_clock::now(); + decode_time.decode_us_ = std::chrono::duration_cast(et - st).count(); + time_perf->decode_record_.push_back(decode_time); + if (mLlm->is_stop(token)) { + *os << end_with << std::flush; + break; + } else { + output_str += handleToken(token); + } + } + if (mCandidates[0].all_seq_len_ == mConfig.max_all_tokens) { + std::cout << "sequence length reaches maximum allowed." << std::endl; + } + // return output_str + return output_str; +} + +void LocalSampler::reset(Llm* llm) { + mLlm = llm; + reset(); +} + +void LocalSampler::reset() { + // in the future, only reset its own. + mCandidates.clear(); + mCandidates.emplace_back(SampleCandidate()); // for LocalSampler, reference have never been modified manually. +} + + +} // Transformer +} // MNN \ No newline at end of file diff --git a/transformers/llm/export/.gitignore b/transformers/llm/export/.gitignore new file mode 100644 index 000000000..ddb5fb2d5 --- /dev/null +++ b/transformers/llm/export/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!llmexport.py +!README.md \ No newline at end of file diff --git a/transformers/llm/export/README.md b/transformers/llm/export/README.md index 233f738ad..86f990c32 100644 --- a/transformers/llm/export/README.md +++ b/transformers/llm/export/README.md @@ -25,18 +25,26 @@ pip install . ## 用法 -1. 将需要导出的LLM项目clone到本地,如:chatglm2-6b +1. 下载模型 ```sh -git clone https://huggingface.co/THUDM/chatglm2-6b +git clone https://huggingface.co/Qwen/Qwen2-1.5B-Instruct # 如果huggingface下载慢可以使用modelscope -git clone https://modelscope.cn/ZhipuAI/chatglm2-6b.git +git clone https://modelscope.cn/qwen/Qwen2-1.5B-Instruct.git ``` -2. 导出模型 +2. 测试模型 ```sh -# 将chatglm2-6b导出为onnx模型 -llmexport --path ../chatglm2-6b --export onnx -# 将chatglm2-6b导出为mnn模型, 量化参数为4bit, blokc-wise = 128 -llmexport --path ../chatglm2-6b --export mnn --quant_bit 4 --quant_block 128 +# 测试文本输入 +llmexport --path Qwen2-1.5B-Instruct --test "你好" +# 测试图像文本 +llmexport --path Qwen2-VL-2B-Instruct --test "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-VL/assets/demo.jpeg介绍一下图片里的内容" +``` + +3. 导出模型 +```sh +# 将Qwen2-1.5B-Instruct导出为onnx模型 +llmexport --path Qwen2-1.5B-Instruct --export onnx +# 将Qwen2-1.5B-Instruct导出为mnn模型, 量化参数为4bit, blokc-wise = 128 +llmexport --path Qwen2-1.5B-Instruct --export mnn --quant_bit 4 --quant_block 128 ``` ## 功能 @@ -48,14 +56,6 @@ llmexport --path ../chatglm2-6b --export mnn --quant_bit 4 --quant_block 128 - 使用`--lm_quant_bit`来制定lm_head层权重的量化bit数,不指定则使用`--quant_bit`的量化bit数 - 支持使用自己编译的`MNNConvert`,使用`--mnnconvert` -`--test`测试示例 -```sh -# 测试文本输入 -llmexport --path Qwen2-1.5B-Instruct --test "你好" -# 测试图像文本 -llmexport --path Qwen2-VL-2B-Instruct --test "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-VL/assets/demo.jpeg介绍一下图片里的内容" -``` - ## 参数 ``` usage: llmexport.py [-h] --path PATH [--type TYPE] [--lora_path LORA_PATH] [--dst_path DST_PATH] [--test TEST] [--export EXPORT] @@ -90,8 +90,8 @@ options: ## 支持模型 -- llama/llama2/llama3/tinyllama -- qwen/qwen1.5/qwen2/qwen-vl +- llama/llama2/llama3/llama3.2/tinyllama +- qwen/qwen1.5/qwen2/qwen-vl/qwen2-vl/qwen2.5 - baichuan2/phi-2/internlm/yi/deepseek - chatglm/codegeex/chatglm2/chatglm3 - phi-2/gemma-2 diff --git a/transformers/llm/export/llmexport.py b/transformers/llm/export/llmexport.py index dacf40d04..dd859e4bf 100644 --- a/transformers/llm/export/llmexport.py +++ b/transformers/llm/export/llmexport.py @@ -9,7 +9,7 @@ import warnings import argparse import functools -from typing import Optional, Tuple +from typing import Optional, Tuple, Dict from yaspin import yaspin @@ -569,6 +569,7 @@ def rebuild_op(self, op, graph): (linear.bias is not None) == has_bias) quant_bit = self.lm_quant_bit if 'lm_head' in name else self.quant_bit + block_size = ic if self.quant_block == 0 else self.quant_block external, q_min, shape_int32 = self.build_weight(linear, quant_bit, self.quant_block) origin_input = op['inputIndexes'] @@ -626,7 +627,7 @@ def rebuild_op(self, op, graph): "quanParameter": { "quantScale": 1.0, "scaleIn": 0.0, "scaleOut": 0.0, "useInt32": False, "has_scaleInt": False, "shapeInt32": shape_int32, - "type": 1, "aMax": 0, "aMin": q_min, "readType": oc * (ic // self.quant_block), "weightSize": 0 + "type": 1, "aMax": 0, "aMin": q_min, "readType": oc * (ic // block_size), "weightSize": 0 }, "external": external }, @@ -1195,12 +1196,16 @@ def load_model(self, model_path): "position_ids" : { 0: "seq_len" }, "past_key_values" : { 2: "history_len" } } + prompt_template = self.build_prompt_template() self.llm_config = { 'hidden_size' : self.hidden_size, 'layer_nums' : self.num_hidden_layers, 'attention_mask': self.attention_mask_type, 'key_value_shape': self.past_kv_shape[1:], - "prompt_template": self.build_prompt('%s'), + "system_prompt_template": prompt_template['system'].format(query='%s'), + 'user_prompt_template': prompt_template['user'].format(query='%s'), + 'assistant_prefix': prompt_template['assistant_prefix'], + 'assistant_suffix': prompt_template['assistant_suffix'], 'is_visual': False } # load modules @@ -1280,39 +1285,96 @@ def forward(self, input_ids, attention_mask, position_ids, past_key_values): return logits, presents # some test functions - def build_prompt(self, query): + def build_prompt_template(self) -> Dict[str, str]: + template = { + 'system': '', + 'user': '', + 'assistant_prefix': '', + 'assistant_suffix': '', + } # just for test - if 'Qwen2' in self.path: - return f'<|im_start|>user\n{query}<|im_end|>\n<|im_start|>assistant\n' - if 'Qwen' in self.path: - return f'\n<|im_start|>user\n{query}<|im_end|>\n<|im_start|>assistant\n' + if 'Qwen' in self.path or 'Qwen2' in self.path or 'reader' in self.path: + template['system'] = '<|im_start|>system\n{query}<|im_end|>\n' + template['user'] = '<|im_start|>user\n{query}<|im_end|>\n' + template['assistant_prefix'] = '<|im_start|>assistant\n' + template['assistant_suffix'] = '<|im_end|>\n' + return template if 'Baichuan2' in self.path: - return f'{query}' + template['user'] = '{query}' + return template if 'internlm' in self.path: - return f'<|User|>:{query}\n<|Bot|>:' + template['user'] = '<|User|>:{query}\n' + template['assistant_prefix'] = '<|Bot|>:' + template['assistant_suffix'] = '\n' + return template if 'TinyLlama' in self.path: - return f'<|system|>\nYou are a friendly chatbot who always responds in the style of a pirate\n<|user|>\n{query}\n<|assistant|>\n' + template['system'] = '<|system|>\n{query}\n' + template['user'] = '<|user|>\n{query}\n' + template['assistant_prefix'] = '<|assistant|>\n' + template['assistant_suffix'] = '\n' + return template if 'Yi' in self.path: - return f'<|im_start|> user\n{query}<|im_end|>\n<|im_start|> assistant\n' + template['user'] = '<|im_start|> user\n{query}<|im_end|>\n' + template['assistant_prefix'] = '<|im_start|> assistant\n' + template['assistant_suffix'] = '<|im_end|>\n' + return template if 'deepseek' in self.path: - return f'<|begin_of_sentence|>User: {query}\n\nAssistant:' + template['user'] = '<|begin_of_sentence|>User: {query}\n' + template['assistant_prefix'] = '\nAssistant: ' + template['assistant_suffix'] = '\n<|end_of_sentence|>' + return template if 'Llama-3.1' in self.path: - return f'<|start_header_id|>user<|end_header_id|>\n\n{query}<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n\n' + template['system'] = '<|start_header_id|>system<|end_header_id|>\n\n{query}<|eot_id|>' + template['user'] = '<|start_header_id|>user<|end_header_id|>\n\n{query}<|eot_id|>' + template['assistant_prefix'] = '<|start_header_id|>assistant<|end_header_id|>\n\n' + template['assistant_suffix'] = '<|eot_id|>' + return template if 'Llama-3' in self.path: - return f'<|begin_of_text|><|start_header_id|>user<|end_header_id|>\n\n{query}<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n\n' + template['system'] = '<|start_header_id|>system<|end_header_id|>\n\n{query}<|eot_id|>' + template['user'] = '<|begin_of_text|><|start_header_id|>user<|end_header_id|>\n\n{query}<|eot_id|>' + template['assistant_prefix'] = '<|start_header_id|>assistant<|end_header_id|>\n\n' + template['assistant_suffix'] = '<|eot_id|>' + return template if 'Llama-2' in self.path: - return f'[INST]{query}[/INST]' + template['user'] = '[INST]{query}[/INST]' + return template if 'chatglm2' in self.path: - return f'[Round 1]\n\n问:{query}\n\n答:' + template['user'] = '[Round 1]\n\n问:{query}\n\n' + template['assistant_prefix'] = '答:' + template['assistant_suffix'] = '\n\n' + return template if 'chatglm3' in self.path or 'glm-4' in self.path: - return f'<|user|>\n{query}\n<|assistant|>\n' + template['user'] = '<|user|>\n{query}\n' + template['assistant_prefix'] = '<|assistant|>\n' + template['assistant_suffix'] = '\n' + return template if 'chatglm' in self.path: - return f'{query}[gMASK]' + template['user'] = '{query}[gMASK]' + return template if 'phi-2' in self.path: - return f'Instruct: {query}\nOutput:' + template['user'] = 'Instruct: {query}\n' + template['assistant_prefix'] = 'Output:' + template['assistant_suffix'] = '\n' + return template if 'gemma-2' in self.path: - return f'user\n{query}\nmodel\n' - return query + template['system'] = 'system\n{query}\n' + template['user'] = 'user\n{query}\n' + template['assistant_prefix'] = 'model\n' + template['assistant_suffix'] = '\n' + return template + # not matched + return template + + def build_prompt(self, queries, roles): + template = self.build_prompt_template(self) + prompt = "" + for item in zip(queries, roles): + query, role = item + if '{query}' in template[role]: + prompt += template[role].format(query=query) + else: + prompt += role + '\n' + query +'\n' + return prompt + template['assistant_prefix'] def str_to_ids(self, prompt): if self.visual is not None: @@ -1327,7 +1389,7 @@ def id_to_str(self, token_id): def response(self, query): self.imitate_quant() - prompt = self.build_prompt(query) + prompt = self.build_prompt([query], roles=['user']) input_ids = self.str_to_ids(prompt) self.seq_len = input_ids.numel() self.context_len = self.seq_len - 2 @@ -1886,4 +1948,4 @@ def main(): llm_exporter.export(args.export) if __name__ == '__main__': - main() \ No newline at end of file + main() From beea99f29478e003122fe960aa0753eda559e416 Mon Sep 17 00:00:00 2001 From: hzx Date: Wed, 30 Oct 2024 12:01:19 +0800 Subject: [PATCH 02/13] update docs and remove penalize_ngram with penalty --- TODO.md | 25 +++++++++++- docs/transformers/llm.md | 39 ++++++++++++++----- transformers/llm/engine/include/llmconfig.hpp | 2 +- transformers/llm/engine/src/sampler.cpp | 7 ++-- 4 files changed, 58 insertions(+), 15 deletions(-) diff --git a/TODO.md b/TODO.md index d17bbdd5c..01d8efb65 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,25 @@ +## Change Log +- [x] implement an independent `Sampler` Module. +- [x] implement 8 individual basic samplers: `greedy`, `temperature`, `topK`, `topP`, `minP`, `tfs`, `typical`, `penalty`. (can be configured through config.json) +- [x] implement `mixed` sampler, whose sampling order (Penalties -> top_k -> tfs_z -> typical_p -> top_p -> min_p -> temperature). one can change the samplers through configuring `mixed_samplers`. field in config.json +- [x] implement `PromptLib` to enable `chat_demo` for all LLM. +- [x] remove the `seq_len` control in `Llm` to `Sampler` and higher level modules to migrate design complexity. +- [x] implement `Chat` to organize the workflow of a chatbot APP. +- [x] change `#define FP16_QSCALE 0.25` in `CPUAttention` to ensure Llama3.2 FP16 correctness. +- [x] `chat_demo` tested on ubuntu 22.04, android(including ARM64, ARM82, OPENCL backend). + +Motivation: +1. Sampler: performance, variety, different user-preferrence. +2. System Prompt: support history context, memory; few-shot generation (examples); role-play role profile. + ## TODO Lists +### 0. Overall TODO Lists +- [ ] test ShareGPT, VQA, Audio... +- [ ] merge KV cache implementation +- [ ] verify the possibility of hetereogeneous computing (CPU + opencl/...) +- [ ] Kv cache + sampler + ### 1. Engineering TODO Lists - [x] llm-export convert Qwen2.5-1.5B-Instructx, Qwen2.5-3B-Instructx, Qwen2.5-7B-Instruct (Qwen2.5 language series) https://qwenlm.github.io/zh/blog/qwen2.5/ (<7B: 32K/8K, >=7B: 128K/8K) - [x] llm-export convert Llama-3.2-1B-Instructx, Llama-3.2-3B-Instruct (Llama-3.2 language series) https://ai.meta.com/blog/llama-3-2-connect-2024-vision-edge-mobile-devices/ (128K) @@ -17,8 +37,11 @@ ```bash python llmexport.py --path ../../../model/Qwen2.5-1.5B-Instruct/ --dst_path ../../../model/qwen2_5-1_5b-instruct-mnn/ --export mnn --quant_bit 4 --quant_block 128 + +python llmexport.py --path ../../../model/Llama-3.2-3B-Instruct/ --dst_path ../../../model/llama3_2-3b-instruct-mnn --export mnn --quant_bit 4 --quant_block 128 ``` ### 2. Experiments TODO Lists -- [ ] test `Chat` on ShareGPT datasets, measuring time and space. \ No newline at end of file +- [ ] test `Chat` on ShareGPT datasets, measuring time and space +- [ ] test VQA \ No newline at end of file diff --git a/docs/transformers/llm.md b/docs/transformers/llm.md index 4677821cf..3d03b6e28 100644 --- a/docs/transformers/llm.md +++ b/docs/transformers/llm.md @@ -157,7 +157,7 @@ sh package_scripts/ios/buildiOS.sh "-DMNN_ARM82=true -DMNN_LOW_MEMORY=true -DMNN - visual_model: 当使用VL模型时,visual_model的实际路径为`base_dir + visual_model`,默认为`base_dir + 'visual.mnn'` - 推理配置 - max_new_tokens: 生成时最大token数,默认为`512` - - reuse_kv: 多轮对话时是否复用之前对话的`kv cache`,默认为`false` + - reuse_kv: 多轮对话时是否复用之前对话的`kv cache`,默认为`false`, 目前只有CPU后端支持设置为`true`. - quant_qkv: CPU attention 算子中`query, key, value`是否量化,可选为:`0, 1, 2, 3, 4`,默认为`0`,含义如下: - 0: key和value都不量化 - 1: 使用非对称8bit量化存储key @@ -173,6 +173,19 @@ sh package_scripts/ios/buildiOS.sh "-DMNN_ARM82=true -DMNN_LOW_MEMORY=true -DMNN - thread_num: CPU推理使用硬件线程数,默认为:`4`; OpenCL推理时使用`68` - precision: 推理使用精度策略,默认为:`"low"`,尽量使用`fp16` - memory: 推理使用内存策略,默认为:`"low"`,开启运行时量化 +- Sampler配置 + - sampler_type: 使用的sampler种类,目前支持`greedy`, `temperature`, `topK`, `topP`, `minP`, `tfs`, `typical`, `penalty`8种基本sampler,外加`mixed`(混合sampler)。当选择`mixed`时,依次执行mixed_samplers中的sampler。默认为`mixed`。 + - mixed_samplers: 当`sampler_type`为`mixed`时有效,默认为`["topK", "tfs", "typical", "topP", "min_p", "temperature"]` + - temperature: `temperature`, `topP`, `minP`, `tfsZ`, `typical`中temerature值,默认为1.0 + - topK: `topK`中top K 个的个数,默认为40 + - topP: `topP`中top P的值,默认为0.9 + - minP: `minP`中min P的值,默认为0.1 + - tfsZ: `tfs`中Z的值,默认为1.0,即不使用tfs算法 + - typical: `typical`中p的值,默认为1.0,即不使用typical算法 + - penalty: `penalty`中对于logits的惩罚项,默认为0.0,即不惩罚 + - n_gram: `penalty`中最大存储的ngram大小,默认为8 + - ngram_factor: `penalty`中对于重复ngram的额外惩罚,默认为1.0,即没有额外惩罚 + - penalty_sampler: `penalty`中最后一步采用的sampling策略,可选"greedy"或"temperature",默认greedy. ##### 配置文件示例 - `config.json` @@ -184,7 +197,15 @@ sh package_scripts/ios/buildiOS.sh "-DMNN_ARM82=true -DMNN_LOW_MEMORY=true -DMNN "backend_type": "cpu", "thread_num": 4, "precision": "low", - "memory": "low" + "memory": "low", + "sampler_type": "mixed", + "mixed_samplers": ["topK", "tfs", "typical", "topP", "min_p", "temperature"], + "temperature": 1.0, + "topK": 40, + "topP": 0.9, + "tfsZ": 1.0, + "minP": 0.1, + "reuse_kv": true } ``` - `llm_config.json` @@ -207,19 +228,19 @@ sh package_scripts/ios/buildiOS.sh "-DMNN_ARM82=true -DMNN_LOW_MEMORY=true -DMNN ``` #### 推理用法 -`llm_demo`的用法如下: +`chat_demo`的用法如下: ``` # 使用config.json ## 交互式聊天 -./llm_demo model_dir/config.json -## 针对prompt中的每行进行回复 -./llm_demo model_dir/config.json prompt.txt +./chat_demo model_dir/config.json + # 不使用config.json, 使用默认配置 ## 交互式聊天 -./llm_demo model_dir/llm.mnn -## 针对prompt中的每行进行回复 -./llm_demo model_dir/llm.mnn prompt.txt +./chat_demo model_dir/llm.mnn + ``` #### GPTQ权重加载 diff --git a/transformers/llm/engine/include/llmconfig.hpp b/transformers/llm/engine/include/llmconfig.hpp index f94067353..c2b7a34fe 100644 --- a/transformers/llm/engine/include/llmconfig.hpp +++ b/transformers/llm/engine/include/llmconfig.hpp @@ -351,7 +351,7 @@ class LlmConfig { // < sampler config start std::string sampler_type() const { - return config_.value("sampler_type", "greedy"); + return config_.value("sampler_type", "mixed"); } std::vector mixed_samplers() const { diff --git a/transformers/llm/engine/src/sampler.cpp b/transformers/llm/engine/src/sampler.cpp index 805c31fce..217c70d18 100644 --- a/transformers/llm/engine/src/sampler.cpp +++ b/transformers/llm/engine/src/sampler.cpp @@ -91,7 +91,7 @@ Sampler* Sampler::createSampler(Llm* llm, const std::string& config_path) { std::string sampler_type = config->sampler_type(); if (sampler_type == "greedy" || sampler_type == "temperature" - || sampler_type == "penalty" || sampler_type == "penalize_ngram" + || sampler_type == "penalty" || sampler_type == "topK" || sampler_type == "topP" || sampler_type == "minP" @@ -124,7 +124,7 @@ void LocalSampler::LocalSamplerConfig::configSampler( std::string sampler_type, this->configTFS(llmConfig); } else if (sampler_type == "typical"){ this->configTypical(llmConfig); - } else if (sampler_type == "penalty" || sampler_type == "penalize_ngram"){ + } else if (sampler_type == "penalty"){ this->configPenalty(llmConfig); } else if (sampler_type == "mixed"){ this->configMixed(llmConfig); @@ -396,9 +396,8 @@ struct SubsetLogits LocalSampler::penalty(struct SubsetLogits subset) { int ngram = mConfig.penaltyConfig.ngram; float ngram_factor = mConfig.penaltyConfig.ngram_factor; float temperature = mConfig.temperature; - bool penalizeNgram = (mConfig.type == "penalize_ngram"); + bool penalizeNgram = (ngram_factor > 1.0f); if (penalty <= 1.0f) return subset; // no penalty! - if (ngram_factor <= 1.0f) penalizeNgram = false; // no extra penalty for n gram. penalty = std::min(penalty, mConfig.penaltyConfig.max_penalty); // initialization std::vector& prev = mCandidates[0].tokens; From 06736c31f681299e925499e6661757cb59e9c5fc Mon Sep 17 00:00:00 2001 From: hzx Date: Wed, 30 Oct 2024 15:33:19 +0800 Subject: [PATCH 03/13] fix the bug of reset --- .../engine => backupcode/llm}/llm_demo.cpp | 0 .../llm}/perplexity.hpp | 0 docs/transformers/llm.md | 8 ++--- transformers/llm/engine/app/chat_demo.cpp | 14 +++++++-- .../llm/engine/include/app/chat/chat.hpp | 5 +++- transformers/llm/engine/include/llmconfig.hpp | 2 +- transformers/llm/engine/model/bench.txt | 4 --- transformers/llm/engine/src/chat.cpp | 30 +++++++++++-------- transformers/llm/engine/src/llm.cpp | 1 + transformers/llm/engine/src/sampler.cpp | 2 ++ 10 files changed, 42 insertions(+), 24 deletions(-) rename {transformers/llm/engine => backupcode/llm}/llm_demo.cpp (100%) rename {transformers/llm/engine/include/evaluation => backupcode/llm}/perplexity.hpp (100%) delete mode 100644 transformers/llm/engine/model/bench.txt diff --git a/transformers/llm/engine/llm_demo.cpp b/backupcode/llm/llm_demo.cpp similarity index 100% rename from transformers/llm/engine/llm_demo.cpp rename to backupcode/llm/llm_demo.cpp diff --git a/transformers/llm/engine/include/evaluation/perplexity.hpp b/backupcode/llm/perplexity.hpp similarity index 100% rename from transformers/llm/engine/include/evaluation/perplexity.hpp rename to backupcode/llm/perplexity.hpp diff --git a/docs/transformers/llm.md b/docs/transformers/llm.md index 3d03b6e28..0863b8473 100644 --- a/docs/transformers/llm.md +++ b/docs/transformers/llm.md @@ -233,14 +233,14 @@ sh package_scripts/ios/buildiOS.sh "-DMNN_ARM82=true -DMNN_LOW_MEMORY=true -DMNN # 使用config.json ## 交互式聊天 ./chat_demo model_dir/config.json - +## 针对prompt中的每行进行回复 +./chat_demo model_dir/config.json prompt.txt # 不使用config.json, 使用默认配置 ## 交互式聊天 ./chat_demo model_dir/llm.mnn - +## 针对prompt中的每行进行回复 +./chat_demo model_dir/llm.mnn prompt.txt ``` #### GPTQ权重加载 diff --git a/transformers/llm/engine/app/chat_demo.cpp b/transformers/llm/engine/app/chat_demo.cpp index d22d25baf..e9122e13a 100644 --- a/transformers/llm/engine/app/chat_demo.cpp +++ b/transformers/llm/engine/app/chat_demo.cpp @@ -1,14 +1,24 @@ +#include #include "app/chat/chat.hpp" using namespace MNN::Transformer; int main(int argc, const char* argv[]) { if (argc < 2) { - std::cout << "Usage: " << argv[0] << " config.json" << std::endl; + std::cout << "Usage: " << argv[0] << " config.json [prompt.txt]" << std::endl; return 0; } std::string config_path = argv[1]; Chat chat(config_path); - chat.chat(); + if (argc == 3) { + // prompt from file + std::string prompt_file = argv[2]; + std::cout << "prompt file is " << prompt_file << std::endl; + std::ifstream prompt_fs(prompt_file); + chat.chat(false, true, &prompt_fs); + } else { + // chat in terminal + chat.chat(); + } return 0; } \ No newline at end of file diff --git a/transformers/llm/engine/include/app/chat/chat.hpp b/transformers/llm/engine/include/app/chat/chat.hpp index 7d0ca7aa2..bcb52251f 100644 --- a/transformers/llm/engine/include/app/chat/chat.hpp +++ b/transformers/llm/engine/include/app/chat/chat.hpp @@ -30,11 +30,14 @@ class MNN_PUBLIC Chat { std::unique_ptr mLlm; std::unique_ptr mSampler; std::unique_ptr mPromptLib; + bool getPrompt(bool from_file, std::istream* is, std::string& user_str); void generate_init(); std::string generate(const std::string& prompt, std::ostream* os = &std::cout, const char* end_with = "\n"); public: Chat(std::string config_path); - void chat(std::istream* is = &std::cin, std::ostream* os = &std::cout, const char* end_with = "\n"); + void chat(bool session_by_line = false, bool from_file = false, + std::istream* is = &std::cin, std::ostream* os = &std::cout, + const char* end_with = "\n", std::string exit_prompt = "/exit", std::string reset_token = "/reset"); ~Chat() {} }; diff --git a/transformers/llm/engine/include/llmconfig.hpp b/transformers/llm/engine/include/llmconfig.hpp index c2b7a34fe..bd031dbdd 100644 --- a/transformers/llm/engine/include/llmconfig.hpp +++ b/transformers/llm/engine/include/llmconfig.hpp @@ -251,7 +251,7 @@ class LlmConfig { } bool reuse_kv() const { - return config_.value("reuse_kv", true); + return config_.value("reuse_kv", false); } // generate config end > diff --git a/transformers/llm/engine/model/bench.txt b/transformers/llm/engine/model/bench.txt deleted file mode 100644 index 87e49b7f1..000000000 --- a/transformers/llm/engine/model/bench.txt +++ /dev/null @@ -1,4 +0,0 @@ -计算8乘以12 -将下面的句子翻译成中文:It's a beautiful day to learn something new. -描述优秀的领导者应具备的五个特质,并解释每个特质为什么重要 -近年来,随着技术的快速发展和全球化的深入推进,数字经济已成为推动世界经济增长的新引擎。数字经济不仅改变了人们的生活方式,促进了信息和资源的快速流通,还重塑了传统行业的业务模式和竞争格局。尽管数字经济的发展为全球经济增长提供了新的动能,但同时也带来了数据安全、隐私保护、数字鸿沟和市场垄断等一系列挑战。考虑到这些背景,请详细分析数字经济在促进世界经济增长方面的作用,包括但不限于数字经济对提高生产效率、创造就业机会和促进可持续发展的贡献。同时,探讨如何应对数字经济发展过程中出现的挑战,具体包括如何保护个人数据安全和隐私、缩小数字鸿沟以确保数字经济的包容性和公平性,以及如何制定有效政策以避免市场垄断情况的出现,最终实现数字经济的健康和可持续发展。 \ No newline at end of file diff --git a/transformers/llm/engine/src/chat.cpp b/transformers/llm/engine/src/chat.cpp index e5fc726bf..41e82b25e 100644 --- a/transformers/llm/engine/src/chat.cpp +++ b/transformers/llm/engine/src/chat.cpp @@ -60,33 +60,39 @@ std::string Chat::generate(const std::string& prompt, std::ostream* os, const ch return out_str; } +bool Chat::getPrompt(bool from_file, std::istream* is, std::string& user_str) { + if (!from_file) std::cout << "\nQ: "; + return (bool)std::getline(*is, user_str); +} -void Chat::chat(std::istream* is, std::ostream* os, const char* end_with) { +void Chat::chat(bool session_by_line, bool from_file, std::istream* is, std::ostream* os, const char* end_with, + std::string exit_token, std::string reset_token) { // handle system prompt mPromptLib->reset(); mPromptLib->appendSystemPrompt("You are a helpful assistant!\n"); - while (true) { - // get user string - std::cout << "\nQ: "; - std::string user_str; - std::getline(*is, user_str); - // special instructions - if (user_str == "/exit") { + std::string user_str; + while (getPrompt(from_file, is, user_str)) { + // whether to end + if (user_str == exit_token) { mPromptLib->reset(); + mSampler->reset(); break; } - if (user_str == "/reset") { + // whether to reset + if (session_by_line || user_str == reset_token) { mPromptLib->reset(); - std::cout << "\nA: reset done." << std::endl; + mSampler->reset(); + if (!from_file) std::cout << "\nreset done." << std::endl; continue; } // get answer - std::cout << "\nA: " << std::flush; + (*os) << "\nA: " << std::flush; mPromptLib->appendUserPrompt(user_str); auto assistant_str = generate(mPromptLib->getLLMInput(), os, end_with); mPromptLib->appendLLMOutput(assistant_str); - std::cout << std::endl; + (*os) << std::endl; } + mPromptLib->reset(); } } // Transformer diff --git a/transformers/llm/engine/src/llm.cpp b/transformers/llm/engine/src/llm.cpp index 9ec79cb51..5f44d3f76 100644 --- a/transformers/llm/engine/src/llm.cpp +++ b/transformers/llm/engine/src/llm.cpp @@ -289,6 +289,7 @@ VARP Llm::forward(const std::vector& input_ids, int kv_seq_len_, int gen_se void Llm::reset() { // clear KV cache + // KV cache automatically cleared as long as seq_len reset! } bool Llm::reuse_kv() const { diff --git a/transformers/llm/engine/src/sampler.cpp b/transformers/llm/engine/src/sampler.cpp index 217c70d18..c32b14d7c 100644 --- a/transformers/llm/engine/src/sampler.cpp +++ b/transformers/llm/engine/src/sampler.cpp @@ -544,6 +544,8 @@ void LocalSampler::reset() { // in the future, only reset its own. mCandidates.clear(); mCandidates.emplace_back(SampleCandidate()); // for LocalSampler, reference have never been modified manually. + // KV cache reset as long as seq_len becomes 0. + mLlm->reset(); } From 215a21cc6d717dcdbccbdb9da601dc4e126ecbbf Mon Sep 17 00:00:00 2001 From: hzx Date: Thu, 31 Oct 2024 09:20:02 +0800 Subject: [PATCH 04/13] add android demo --- TODO.md | 14 +- docs/transformers/optimizations.md | 12 +- .../llm/engine/android/app/.gitignore | 1 + .../llm/engine/android/app/build.gradle | 67 ++++ .../llm/engine/android/app/proguard-rules.pro | 21 ++ .../android/app/src/main/AndroidManifest.xml | 29 ++ .../app/src/main/ic_launcher-playstore.png | Bin 0 -> 132557 bytes .../main/java/com/mnn/llm/BaseActivity.java | 54 ++++ .../app/src/main/java/com/mnn/llm/Chat.java | 15 + .../app/src/main/java/com/mnn/llm/Common.java | 67 ++++ .../main/java/com/mnn/llm/Conversation.java | 302 ++++++++++++++++++ .../main/java/com/mnn/llm/MainActivity.java | 115 +++++++ .../android/app/src/main/jni/llm_mnn_jni.cpp | 72 +++++ .../main/res/drawable-hdpi/ic_action_add.png | Bin 0 -> 260 bytes .../main/res/drawable-hdpi/ic_action_back.png | Bin 0 -> 461 bytes .../res/drawable-hdpi/ic_action_chats.png | Bin 0 -> 537 bytes .../res/drawable-hdpi/ic_action_contacts.png | Bin 0 -> 339 bytes .../res/drawable-hdpi/ic_action_edit_icon.png | Bin 0 -> 513 bytes .../res/drawable-hdpi/ic_action_logout.png | Bin 0 -> 390 bytes .../res/drawable-hdpi/ic_action_settings.png | Bin 0 -> 1046 bytes .../res/drawable-hdpi/ic_action_trash.png | Bin 0 -> 398 bytes .../main/res/drawable-mdpi/ic_action_add.png | Bin 0 -> 164 bytes .../main/res/drawable-mdpi/ic_action_back.png | Bin 0 -> 346 bytes .../res/drawable-mdpi/ic_action_chats.png | Bin 0 -> 321 bytes .../res/drawable-mdpi/ic_action_contacts.png | Bin 0 -> 264 bytes .../res/drawable-mdpi/ic_action_edit_icon.png | Bin 0 -> 371 bytes .../res/drawable-mdpi/ic_action_logout.png | Bin 0 -> 244 bytes .../res/drawable-mdpi/ic_action_settings.png | Bin 0 -> 557 bytes .../res/drawable-mdpi/ic_action_trash.png | Bin 0 -> 272 bytes .../app/src/main/res/drawable-nodpi/logo.png | Bin 0 -> 182787 bytes .../main/res/drawable-v21/ic_menu_camera.xml | 12 + .../main/res/drawable-v21/ic_menu_gallery.xml | 9 + .../main/res/drawable-v21/ic_menu_manage.xml | 9 + .../main/res/drawable-v21/ic_menu_send.xml | 9 + .../main/res/drawable-v21/ic_menu_share.xml | 9 + .../res/drawable-v21/ic_menu_slideshow.xml | 9 + .../drawable-v24/ic_launcher_foreground.xml | 34 ++ .../main/res/drawable-xhdpi/ic_action_add.png | Bin 0 -> 221 bytes .../res/drawable-xhdpi/ic_action_back.png | Bin 0 -> 729 bytes .../res/drawable-xhdpi/ic_action_chats.png | Bin 0 -> 620 bytes .../res/drawable-xhdpi/ic_action_contacts.png | Bin 0 -> 476 bytes .../drawable-xhdpi/ic_action_edit_icon.png | Bin 0 -> 688 bytes .../res/drawable-xhdpi/ic_action_logout.png | Bin 0 -> 462 bytes .../res/drawable-xhdpi/ic_action_settings.png | Bin 0 -> 1162 bytes .../res/drawable-xhdpi/ic_action_trash.png | Bin 0 -> 387 bytes .../res/drawable-xxhdpi/ic_action_add.png | Bin 0 -> 343 bytes .../res/drawable-xxhdpi/ic_action_back.png | Bin 0 -> 952 bytes .../res/drawable-xxhdpi/ic_action_chats.png | Bin 0 -> 1110 bytes .../drawable-xxhdpi/ic_action_contacts.png | Bin 0 -> 711 bytes .../drawable-xxhdpi/ic_action_edit_icon.png | Bin 0 -> 927 bytes .../res/drawable-xxhdpi/ic_action_logout.png | Bin 0 -> 792 bytes .../drawable-xxhdpi/ic_action_settings.png | Bin 0 -> 2184 bytes .../res/drawable-xxhdpi/ic_action_trash.png | Bin 0 -> 759 bytes .../res/drawable-xxxhdpi/ic_action_add.png | Bin 0 -> 380 bytes .../res/drawable-xxxhdpi/ic_action_back.png | Bin 0 -> 1499 bytes .../res/drawable-xxxhdpi/ic_action_chats.png | Bin 0 -> 1681 bytes .../drawable-xxxhdpi/ic_action_contacts.png | Bin 0 -> 1319 bytes .../drawable-xxxhdpi/ic_action_edit_icon.png | Bin 0 -> 1198 bytes .../res/drawable-xxxhdpi/ic_action_logout.png | Bin 0 -> 1158 bytes .../drawable-xxxhdpi/ic_action_settings.png | Bin 0 -> 3560 bytes .../res/drawable-xxxhdpi/ic_action_trash.png | Bin 0 -> 1057 bytes .../src/main/res/drawable/bg_bottom_grey.xml | 9 + .../app/src/main/res/drawable/bg_chat_me.xml | 5 + .../app/src/main/res/drawable/bg_chat_you.xml | 5 + .../app/src/main/res/drawable/bg_gradient.xml | 8 + .../src/main/res/drawable/bg_item_list.xml | 12 + .../app/src/main/res/drawable/bg_online.xml | 16 + .../app/src/main/res/drawable/bg_top_grey.xml | 14 + .../app/src/main/res/drawable/bg_unread.xml | 23 ++ .../main/res/drawable/bg_white_rounded.xml | 5 + .../app/src/main/res/drawable/btn_grey.xml | 12 + .../app/src/main/res/drawable/btn_pink.xml | 12 + .../app/src/main/res/drawable/checkbox.xml | 5 + .../src/main/res/drawable/ic_arrow_right.xml | 11 + .../src/main/res/drawable/ic_attachment.xml | 11 + .../app/src/main/res/drawable/ic_clock.xml | 16 + .../app/src/main/res/drawable/ic_image.xml | 5 + .../app/src/main/res/drawable/ic_menu.xml | 21 ++ .../app/src/main/res/drawable/ic_radio.xml | 6 + .../main/res/drawable/ic_radio_checked.xml | 9 + .../app/src/main/res/drawable/ic_trash.xml | 11 + .../src/main/res/drawable/side_nav_bar.xml | 9 + .../main/res/layout/activity_conversation.xml | 19 ++ .../app/src/main/res/layout/activity_main.xml | 113 +++++++ .../app/src/main/res/layout/app_bar_main.xml | 19 ++ .../main/res/layout/content_conversation.xml | 90 ++++++ .../app/src/main/res/layout/content_main.xml | 15 + .../main/res/layout/layout_holder_date.xml | 15 + .../src/main/res/layout/layout_holder_me.xml | 47 +++ .../src/main/res/layout/layout_holder_you.xml | 30 ++ .../app/src/main/res/layout/toolbar.xml | 25 ++ .../android/app/src/main/res/menu/main.xml | 9 + .../app/src/main/res/menu/menu_add.xml | 11 + .../app/src/main/res/menu/menu_drawer.xml | 21 ++ .../src/main/res/menu/menu_drawer_bottom.xml | 15 + .../app/src/main/res/menu/menu_edit.xml | 11 + .../app/src/main/res/menu/menu_userphoto.xml | 11 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 4435 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2509 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 6773 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 12127 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 19181 bytes .../app/src/main/res/values-hdpi/dimens.xml | 9 + .../app/src/main/res/values-mdpi/dimens.xml | 9 + .../app/src/main/res/values-v21/styles.xml | 21 ++ .../app/src/main/res/values-w820dp/dimens.xml | 11 + .../app/src/main/res/values-xhdpi/dimens.xml | 9 + .../app/src/main/res/values-xxhdpi/dimens.xml | 9 + .../src/main/res/values-xxxhdpi/dimens.xml | 9 + .../app/src/main/res/values/colors.xml | 11 + .../app/src/main/res/values/dimens.xml | 15 + .../app/src/main/res/values/drawables.xml | 8 + .../res/values/ic_launcher_background.xml | 4 + .../app/src/main/res/values/strings.xml | 9 + .../app/src/main/res/values/styles.xml | 67 ++++ transformers/llm/engine/android/build.gradle | 27 ++ .../llm/engine/android/gradle.properties | 20 ++ .../android/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 + transformers/llm/engine/android/gradlew | 172 ++++++++++ transformers/llm/engine/android/gradlew.bat | 89 ++++++ .../llm/engine/android/settings.gradle | 2 + transformers/llm/engine/test/bench_cn.txt | 4 + transformers/llm/engine/test/bench_en.txt | 3 + 124 files changed, 2042 insertions(+), 7 deletions(-) create mode 100644 transformers/llm/engine/android/app/.gitignore create mode 100644 transformers/llm/engine/android/app/build.gradle create mode 100644 transformers/llm/engine/android/app/proguard-rules.pro create mode 100644 transformers/llm/engine/android/app/src/main/AndroidManifest.xml create mode 100644 transformers/llm/engine/android/app/src/main/ic_launcher-playstore.png create mode 100644 transformers/llm/engine/android/app/src/main/java/com/mnn/llm/BaseActivity.java create mode 100644 transformers/llm/engine/android/app/src/main/java/com/mnn/llm/Chat.java create mode 100644 transformers/llm/engine/android/app/src/main/java/com/mnn/llm/Common.java create mode 100644 transformers/llm/engine/android/app/src/main/java/com/mnn/llm/Conversation.java create mode 100644 transformers/llm/engine/android/app/src/main/java/com/mnn/llm/MainActivity.java create mode 100644 transformers/llm/engine/android/app/src/main/jni/llm_mnn_jni.cpp create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-hdpi/ic_action_add.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-hdpi/ic_action_back.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-hdpi/ic_action_chats.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-hdpi/ic_action_contacts.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-hdpi/ic_action_edit_icon.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-hdpi/ic_action_logout.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-hdpi/ic_action_settings.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-hdpi/ic_action_trash.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-mdpi/ic_action_add.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-mdpi/ic_action_back.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-mdpi/ic_action_chats.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-mdpi/ic_action_contacts.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-mdpi/ic_action_edit_icon.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-mdpi/ic_action_logout.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-mdpi/ic_action_settings.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-mdpi/ic_action_trash.png create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable-nodpi/logo.png create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_camera.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_gallery.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_manage.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_send.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_share.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_slideshow.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xhdpi/ic_action_add.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xhdpi/ic_action_back.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xhdpi/ic_action_chats.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xhdpi/ic_action_contacts.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xhdpi/ic_action_edit_icon.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xhdpi/ic_action_logout.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xhdpi/ic_action_settings.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xhdpi/ic_action_trash.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xxhdpi/ic_action_add.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xxhdpi/ic_action_back.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xxhdpi/ic_action_chats.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xxhdpi/ic_action_contacts.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xxhdpi/ic_action_edit_icon.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xxhdpi/ic_action_logout.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xxhdpi/ic_action_settings.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xxhdpi/ic_action_trash.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xxxhdpi/ic_action_add.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xxxhdpi/ic_action_back.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xxxhdpi/ic_action_chats.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xxxhdpi/ic_action_contacts.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xxxhdpi/ic_action_edit_icon.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xxxhdpi/ic_action_logout.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xxxhdpi/ic_action_settings.png create mode 100755 transformers/llm/engine/android/app/src/main/res/drawable-xxxhdpi/ic_action_trash.png create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/bg_bottom_grey.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/bg_chat_me.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/bg_chat_you.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/bg_gradient.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/bg_item_list.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/bg_online.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/bg_top_grey.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/bg_unread.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/bg_white_rounded.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/btn_grey.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/btn_pink.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/checkbox.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/ic_arrow_right.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/ic_attachment.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/ic_clock.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/ic_image.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/ic_menu.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/ic_radio.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/ic_radio_checked.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/ic_trash.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/drawable/side_nav_bar.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/layout/activity_conversation.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/layout/activity_main.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/layout/app_bar_main.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/layout/content_conversation.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/layout/content_main.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/layout/layout_holder_date.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/layout/layout_holder_me.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/layout/layout_holder_you.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/layout/toolbar.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/menu/main.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/menu/menu_add.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/menu/menu_drawer.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/menu/menu_drawer_bottom.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/menu/menu_edit.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/menu/menu_userphoto.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 transformers/llm/engine/android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 transformers/llm/engine/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 transformers/llm/engine/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 transformers/llm/engine/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 transformers/llm/engine/android/app/src/main/res/values-hdpi/dimens.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/values-mdpi/dimens.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/values-v21/styles.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/values-w820dp/dimens.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/values-xhdpi/dimens.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/values-xxhdpi/dimens.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/values-xxxhdpi/dimens.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/values/colors.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/values/dimens.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/values/drawables.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/values/ic_launcher_background.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/values/strings.xml create mode 100644 transformers/llm/engine/android/app/src/main/res/values/styles.xml create mode 100644 transformers/llm/engine/android/build.gradle create mode 100644 transformers/llm/engine/android/gradle.properties create mode 100644 transformers/llm/engine/android/gradle/wrapper/gradle-wrapper.jar create mode 100644 transformers/llm/engine/android/gradle/wrapper/gradle-wrapper.properties create mode 100755 transformers/llm/engine/android/gradlew create mode 100644 transformers/llm/engine/android/gradlew.bat create mode 100644 transformers/llm/engine/android/settings.gradle create mode 100644 transformers/llm/engine/test/bench_cn.txt create mode 100644 transformers/llm/engine/test/bench_en.txt diff --git a/TODO.md b/TODO.md index 01d8efb65..e33a88661 100644 --- a/TODO.md +++ b/TODO.md @@ -7,6 +7,9 @@ - [x] implement `Chat` to organize the workflow of a chatbot APP. - [x] change `#define FP16_QSCALE 0.25` in `CPUAttention` to ensure Llama3.2 FP16 correctness. - [x] `chat_demo` tested on ubuntu 22.04, android(including ARM64, ARM82, OPENCL backend). +- [ ] `chat_demo` supports visual model tasks (support Qwen2-VL demo). +- [ ] `transformers/llm/engine/android` gives an text-only chatbot app based on `Qwen2.5-1.5B-Instruct`. +- [ ] `transformers/llm/engine/android` gives an text+image chatbot app based on `Qwen2-VL-2B-Instruct`. Motivation: 1. Sampler: performance, variety, different user-preferrence. @@ -24,7 +27,7 @@ Motivation: - [x] llm-export convert Qwen2.5-1.5B-Instructx, Qwen2.5-3B-Instructx, Qwen2.5-7B-Instruct (Qwen2.5 language series) https://qwenlm.github.io/zh/blog/qwen2.5/ (<7B: 32K/8K, >=7B: 128K/8K) - [x] llm-export convert Llama-3.2-1B-Instructx, Llama-3.2-3B-Instruct (Llama-3.2 language series) https://ai.meta.com/blog/llama-3-2-connect-2024-vision-edge-mobile-devices/ (128K) - [ ] (optional) llm-export convert Llama-3.2-11B-Vision-Instruct (Llama-3.2 Vision series) -- [ ] (optional) llm-export convert Qwen2-VL-2B-Instruct, Qwen2-VL-7B-Instruct (Qwen2-VL series) +- [x] (optional) llm-export convert Qwen2-VL-2B-Instruct, Qwen2-VL-7B-Instruct (Qwen2-VL series) - [ ] (optional) llm-export convert Qwen2-Audio-7B-Instruct (Qwen2 Audio series) - [x] implement `Chat` application in transformers/llm/app/chat. - [x] implement `LocalSampler` module. @@ -38,7 +41,16 @@ Motivation: ```bash python llmexport.py --path ../../../model/Qwen2.5-1.5B-Instruct/ --dst_path ../../../model/qwen2_5-1_5b-instruct-mnn/ --export mnn --quant_bit 4 --quant_block 128 +python llmexport.py --path ../../../model/Qwen2-VL-2B-Instruct/ --dst_path ../../../model/qwen2-vl-2b-instruct-mnn/ --export mnn --quant_bit 4 --quant_block 128 + python llmexport.py --path ../../../model/Llama-3.2-3B-Instruct/ --dst_path ../../../model/llama3_2-3b-instruct-mnn --export mnn --quant_bit 4 --quant_block 128 + +adb push ../../model/qwen2_5-1_5b-instruct-mnn/ /data/local/tmp/llm +adb push ../../model/qwen2-vl-2b-instruct-mnn/ /data/local/tmp/llm +adb push ../../model/llama3_2-3b-instruct-mnn/ /data/local/tmp/llm + +cd build/phone +adb push chat_demo libllm.so libMNN_CL.so libMNN_Express.so libMNN.so tools/cv/libMNNOpenCV.so /data/local/tmp/llm ``` diff --git a/docs/transformers/optimizations.md b/docs/transformers/optimizations.md index b2a8ededa..70faa1295 100644 --- a/docs/transformers/optimizations.md +++ b/docs/transformers/optimizations.md @@ -7,15 +7,15 @@ ```bash # windows set ANDROID_NDK=D:\NDK\android-ndk -cmake ../.. -DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK%/build/cmake/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="arm64-v8a" -DANDROID_STL=c++_static -DMNN_USE_LOGCAT=false -DCMAKE_CXX_STANDARD=17 -DMNN_USE_SYSTEM_LIB=OFF -DMNN_BUILD_BENCHMARK=ON -DMNN_USE_SSE=OFF -DMNN_SUPPORT_BF16=OFF -DMNN_BUILD_TEST=ON -DANDROID_NATIVE_API_LEVEL=android-21 -DMNN_BUILD_FOR_ANDROID_COMMAND=true -DNATIVE_LIBRARY_OUTPUT=. -DMNN_LOW_MEMORY=ON -DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON -DMNN_BUILD_SHARED_LIBS=ON +cmake ../.. -DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK%/build/cmake/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="arm64-v8a" -DANDROID_STL=c++_static -DMNN_USE_LOGCAT=false -DCMAKE_CXX_STANDARD=17 -DMNN_USE_SYSTEM_LIB=OFF -DMNN_BUILD_BENCHMARK=ON -DMNN_USE_SSE=OFF -DMNN_SUPPORT_BF16=OFF -DMNN_BUILD_TEST=ON -DANDROID_NATIVE_API_LEVEL=android-21 -DMNN_BUILD_FOR_ANDROID_COMMAND=true -DNATIVE_LIBRARY_OUTPUT=. -DMNN_LOW_MEMORY=ON -DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON -DMNN_BUILD_SHARED_LIBS=ON -DMNN_BUILD_OPENCV=ON -DMNN_IMGCODECS=ON -DLLM_SUPPORT_VISION=ON # arm v82 & OPENCL -cmake ../.. -DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK%/build/cmake/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="arm64-v8a" -DANDROID_STL=c++_static -DMNN_USE_LOGCAT=false -DCMAKE_CXX_STANDARD=17 -DMNN_USE_SYSTEM_LIB=OFF -DMNN_BUILD_BENCHMARK=ON -DMNN_USE_SSE=OFF -DMNN_SUPPORT_BF16=OFF -DMNN_BUILD_TEST=ON -DANDROID_NATIVE_API_LEVEL=android-21 -DMNN_BUILD_FOR_ANDROID_COMMAND=true -DNATIVE_LIBRARY_OUTPUT=. -DMNN_LOW_MEMORY=ON -DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON -DMNN_BUILD_SHARED_LIBS=ON -DMNN_ARM82=ON -DMNN_OPENCL=ON +cmake ../.. -DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK%/build/cmake/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="arm64-v8a" -DANDROID_STL=c++_static -DMNN_USE_LOGCAT=false -DCMAKE_CXX_STANDARD=17 -DMNN_USE_SYSTEM_LIB=OFF -DMNN_BUILD_BENCHMARK=ON -DMNN_USE_SSE=OFF -DMNN_SUPPORT_BF16=OFF -DMNN_BUILD_TEST=ON -DANDROID_NATIVE_API_LEVEL=android-21 -DMNN_BUILD_FOR_ANDROID_COMMAND=true -DNATIVE_LIBRARY_OUTPUT=. -DMNN_LOW_MEMORY=ON -DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON -DMNN_BUILD_SHARED_LIBS=ON -DMNN_BUILD_OPENCV=ON -DMNN_IMGCODECS=ON -DMNN_ARM82=ON -DMNN_OPENCL=ON -DLLM_SUPPORT_VISION=ON # linux export ANDROID_NDK=~/NDK/android-ndk -cmake ../.. -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="arm64-v8a" -DANDROID_STL=c++_static -DMNN_USE_LOGCAT=false -DCMAKE_CXX_STANDARD=17 -DMNN_USE_SYSTEM_LIB=OFF -DMNN_BUILD_BENCHMARK=ON -DMNN_USE_SSE=OFF -DMNN_SUPPORT_BF16=OFF -DMNN_BUILD_TEST=ON -DANDROID_NATIVE_API_LEVEL=android-21 -DMNN_BUILD_FOR_ANDROID_COMMAND=true -DNATIVE_LIBRARY_OUTPUT=. -DMNN_LOW_MEMORY=ON -DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON -DMNN_BUILD_SHARED_LIBS=ON +cmake ../.. -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="arm64-v8a" -DANDROID_STL=c++_static -DMNN_USE_LOGCAT=false -DCMAKE_CXX_STANDARD=17 -DMNN_USE_SYSTEM_LIB=OFF -DMNN_BUILD_BENCHMARK=ON -DMNN_USE_SSE=OFF -DMNN_SUPPORT_BF16=OFF -DMNN_BUILD_TEST=ON -DANDROID_NATIVE_API_LEVEL=android-21 -DMNN_BUILD_FOR_ANDROID_COMMAND=true -DNATIVE_LIBRARY_OUTPUT=. -DMNN_LOW_MEMORY=ON -DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON -DMNN_BUILD_SHARED_LIBS=ON -DMNN_BUILD_OPENCV=ON -DMNN_IMGCODECS=ON -DLLM_SUPPORT_VISION=ON # arm v82 & OPENCL -cmake ../.. -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="arm64-v8a" -DANDROID_STL=c++_static -DMNN_USE_LOGCAT=false -DCMAKE_CXX_STANDARD=17 -DMNN_USE_SYSTEM_LIB=OFF -DMNN_BUILD_BENCHMARK=ON -DMNN_USE_SSE=OFF -DMNN_SUPPORT_BF16=OFF -DMNN_BUILD_TEST=ON -DANDROID_NATIVE_API_LEVEL=android-21 -DMNN_BUILD_FOR_ANDROID_COMMAND=true -DNATIVE_LIBRARY_OUTPUT=. -DMNN_LOW_MEMORY=ON -DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON -DMNN_BUILD_SHARED_LIBS=ON -DMNN_ARM82=ON -DMNN_OPENCL=ON +cmake ../.. -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="arm64-v8a" -DANDROID_STL=c++_static -DMNN_USE_LOGCAT=false -DCMAKE_CXX_STANDARD=17 -DMNN_USE_SYSTEM_LIB=OFF -DMNN_BUILD_BENCHMARK=ON -DMNN_USE_SSE=OFF -DMNN_SUPPORT_BF16=OFF -DMNN_BUILD_TEST=ON -DANDROID_NATIVE_API_LEVEL=android-21 -DMNN_BUILD_FOR_ANDROID_COMMAND=true -DNATIVE_LIBRARY_OUTPUT=. -DMNN_LOW_MEMORY=ON -DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON -DMNN_BUILD_SHARED_LIBS=ON -DMNN_BUILD_OPENCV=ON -DMNN_IMGCODECS=ON -DMNN_ARM82=ON -DMNN_OPENCL=ON -DLLM_SUPPORT_VISION=ON ``` #### 1.2 compile for pc @@ -24,9 +24,9 @@ LLM and TRANSFORMER_FUSE shall be set ON: `-DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRAN ```bash mkdir build && mkdir build/pc && cd build/pc # linux -cmake ../.. -DCMAKE_CXX_STANDARD=17 -DMNN_USE_SYSTEM_LIB=OFF -DMNN_BUILD_SHARED_LIBS=ON -DMNN_BUILD_TRAIN=ON -DMNN_BUILD_QUANTOOLS=ON -DMNN_EVALUATION=ON -DMNN_BUILD_CONVERTER=ON -DMNN_PORTABLE_BUILD=ON -DTFMODEL_OPTIMIZE=ON -DMNN_LOW_MEMORY=ON -DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON -DMNN_BUILD_TEST=ON -DMNN_BUILD_OPENCV=ON +cmake ../.. -DCMAKE_CXX_STANDARD=17 -DMNN_USE_SYSTEM_LIB=OFF -DMNN_BUILD_SHARED_LIBS=ON -DMNN_BUILD_TRAIN=ON -DMNN_BUILD_QUANTOOLS=ON -DMNN_EVALUATION=ON -DMNN_BUILD_CONVERTER=ON -DMNN_PORTABLE_BUILD=ON -DTFMODEL_OPTIMIZE=ON -DMNN_LOW_MEMORY=ON -DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON -DMNN_BUILD_TEST=ON -DMNN_SEP_BUILD=ON -DMNN_BUILD_OPENCV=ON -DMNN_IMGCODECS=ON -DLLM_SUPPORT_VISION=ON # windows -cmake ../.. -DCMAKE_CXX_STANDARD=17 -DMNN_USE_SYSTEM_LIB=OFF -DMNN_BUILD_SHARED_LIBS=ON -DMNN_BUILD_TRAIN=ON -DMNN_BUILD_QUANTOOLS=ON -DMNN_EVALUATION=ON -DMNN_BUILD_CONVERTER=ON -DMNN_PORTABLE_BUILD=ON -DTFMODEL_OPTIMIZE=ON -DMNN_LOW_MEMORY=ON -DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON -DMNN_BUILD_TEST=ON -DMNN_SEP_BUILD=ON -DMNN_BUILD_OPENCV=ON +cmake ../.. -DCMAKE_CXX_STANDARD=17 -DMNN_USE_SYSTEM_LIB=OFF -DMNN_BUILD_SHARED_LIBS=ON -DMNN_BUILD_TRAIN=ON -DMNN_BUILD_QUANTOOLS=ON -DMNN_EVALUATION=ON -DMNN_BUILD_CONVERTER=ON -DMNN_PORTABLE_BUILD=ON -DTFMODEL_OPTIMIZE=ON -DMNN_LOW_MEMORY=ON -DMNN_BUILD_LLM=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON -DMNN_BUILD_TEST=ON -DMNN_SEP_BUILD=ON -DMNN_BUILD_OPENCV=ON -DMNN_IMGCODECS=ON -DLLM_SUPPORT_VISION=ON make -j20 ./llm_demo ../../model/qwen1_5-4b-chat-mnn-f/llm_config.json diff --git a/transformers/llm/engine/android/app/.gitignore b/transformers/llm/engine/android/app/.gitignore new file mode 100644 index 000000000..796b96d1c --- /dev/null +++ b/transformers/llm/engine/android/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/transformers/llm/engine/android/app/build.gradle b/transformers/llm/engine/android/app/build.gradle new file mode 100644 index 000000000..88e2a4e29 --- /dev/null +++ b/transformers/llm/engine/android/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 28 + buildToolsVersion "29.0.2" + defaultConfig { + applicationId "com.mnn.llm" + minSdkVersion 21 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + externalNativeBuild { + cmake { + arguments "-DBUILD_JNI=TRUE", "-DANDROID_STL=c++_shared", "-DLLM_SUPPORT_VISION=TRUE", "-DMNN_OPENCL=TRUE" + abiFilters 'arm64-v8a' + } + } + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + externalNativeBuild { + cmake { + path file('../../CMakeLists.txt') + } + } + sourceSets { + main { + jniLibs.srcDirs = ['src/main/jni/libs'] + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + packagingOptions { + exclude("META-INF/DEPENDENCIES") + exclude("META-INF/LICENSE") + exclude("META-INF/LICENSE.txt") + exclude("META-INF/license.txt") + exclude("META-INF/NOTICE") + exclude("META-INF/NOTICE.txt") + exclude("META-INF/notice.txt") + exclude("META-INF/ASL2.0") + exclude("META-INF/*.kotlin_module") + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'androidx.appcompat:appcompat:1.0.2' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' + implementation 'androidx.recyclerview:recyclerview:1.1.0' + implementation 'com.android.support:appcompat-v7:28.0.0' + implementation 'com.android.support:design:28.0.0' + implementation 'uk.co.chrisjenx:calligraphy:2.2.0' + implementation 'com.android.support:support-v4:28.0.0' + implementation 'com.google.android.material:material:1.0.0' + implementation "com.squareup.okhttp3:okhttp:4.11.0" +} diff --git a/transformers/llm/engine/android/app/proguard-rules.pro b/transformers/llm/engine/android/app/proguard-rules.pro new file mode 100644 index 000000000..f1b424510 --- /dev/null +++ b/transformers/llm/engine/android/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/transformers/llm/engine/android/app/src/main/AndroidManifest.xml b/transformers/llm/engine/android/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..3f2185878 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/transformers/llm/engine/android/app/src/main/ic_launcher-playstore.png b/transformers/llm/engine/android/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000000000000000000000000000000000000..1d3481e617f36d4bf80cc36832fd4b69077b3e3d GIT binary patch literal 132557 zcmeFY`#%)@A3pw?*}*!mvqDBGqFPZmrR?Z%tL{Q2Dng}nMhbJ=kt1A&+EG8q_?Msw#HNq z0D$)DRVy|C08^JRpsP~9Mq)n803g8X74AMUfdl0yIR$>3dRWS;u-&;+qIa$T+lO&s zBrovMk+G4pp3Bf=3|8Ns>W+MbvZm|`2%qwI?e-Nd*7qPIMuc~@$_nh$lkv`Nlb`U)sNPykj!15cWA5-Iv$eA1)fcAGmD8H_rG(Zlq{9Y+1VT+^vuIeBAM&hAXk8 zF0QSl{*ovE2=f12Y<;{r>Hl8--*fo?Q3N$-BNB$=-bc=Fc%3?-X;L|*zA3k0?Yq#S zor2n`h9r(I_l*3~+^zSz)9^V98knzHmJ;2!m2vXn!?HM+$e}nF?M2aUxtC5aige5U zQQfmhHdS6Wv9YJBGDlO`QJGR4^LtrYxSQhn+^t7e(g@>~JpL4kXu9Fxx%mYRL39t3 zhSZ`fOHJHjcU!$2|B)m9>Qqqq_15mH%d z!@}pLf9rBIgC@T=37MVF2Azt+@50vKtf`%4{lPKan`Q{fqsxUV4O6wAF1^p{kj2Mu z7j2YPZEG;sVv;#R@zC5ELTzVrEpFWSM{#PHo1UA*W23MRKW1m%=TF~gQ=jr|H9;d1 zRgt;x_JGD^JE0nK$tgu^!@Lt-d3m~`Tvww&la=Jkog0M{*Ut$jieJCnZjOx-af{ z+k=q@~$XBeObmOf3#7$Pjj`>T-3lrjBy6=~AN< zjZf4n^9pp6`?)q6^6`8kv-RXl~$+7Ij6{P>wAN|_2T_U zLs0>Q7273_;9qIR>yemRqJ9~=fe%x`8>X3zo zX#P1#SOFg3V%8bkw^n-d&N<<(^&=w5wXhnl?}XoqAUoWMyf;*^FQ_TaZ4vkZcN|-x zj|JOxSg>LRZAYZtl4s&qIZi_RP@Yj4F|0m!YrsATUcBhJX@$JCpfa{|z8;%A=21C} z@3!rb8|st&*Tq5O<+Frah9)N~J>N*bKlq-!^j6&IjqG|)WxqRYn|~d6H?~5^WYvd= zZ$?*z^#x<8t$_>mJ4a6#2sJHpGvNHI$k! zlKBAJJw6VD6U6(m=uP-M^4v=k3C9PN&G;>HS$iz>eNSyqmiZN(uqjuxMR|)YDvrnw zn5r@M{N9!R4~j`^GpOE`r=JsU<1R1`jP1V~K3Sq#wQhYtkurg8IKH;m{WD%{IlT3a zWna2_tjyd`6G&RcXg&xwfC!Xm$-ea@|2_>$z$atMCiqLI9Xd@EGf5dUh-J?1f3;Is zBD$h}J+(fi=I<|FvOPd-tD z+&3I~O`xfj{mv2sHJt4Nhov*<)rxpMg#EkvfHde_K_%aVL9}4s31gEP!I_5+$>OA+ z3cOB4SL|Kzvg>t{t=!p7CE2pNf>U^0Kiu%x8_SLD)nD1ljRNdi6e zJwx|i9d!(#*Ms-!SUOtCyRWBpD4qM0)_8h8P+hu6A1)#!HsS|t=_%p3T2*Y z2wUQ2K!)@k=?&U^U>KU~yD-0jB_5p+*K+@w7I>`bRk3a|%U9m&zKgkIZgV-EjU??4 z5ut$H;knISu1$9U!Tw+cXM7XzrnhCNN2E2r&$9!5rBWzX^BOk7C z8RTB!0qJ1-Mxl{`lQ2&*^SInj8dqVt5_dFF?rY|(;JcYrvFFI|j5pA5bj;&UE0f{v zJNcNqEd~EH@V!UPX1*wGB2g-D{P;^;FF7Zy3#}J^NE$4E^80t;@6eIdr~C+)IAK-E_TvZiEHaI=@C6`79|_2%WsS$# z`6|M$T+(DdxFQr?K*uy_-ztNAl+)#pOg=Wu!QaIVaaQtm$Xyq>_hklvj-*NX>`Zq7 zAb378>*W#LBRl5FCkEn7mqxqIDgC)CU4-$PpI`T=Pw^@bnb$6ge8*EXG zmV`jgim$a*ozk5_7O#4Q{9L*kc@!#|cIZa@F%KG1=d$OGXqoh9d!%rwO@rWceE5wb zhO|56eqRwFd?($mNcns3;yEc3LD9&W_msPL!1N#Xy1wvN9#j*`P3jF@l#<%kPh z%))hwoDSh0Po%zZA!&O!Ug>DrsW>AM^R(5fKCu4Etlm0@ELg7dV`2e--|gS7@-ZVA zott0|2V3-JYxmZkgXy%mefg^3$YNrg`pJ0$ZdW+UkMzAA!J8Tk51{AP&03GGp%_3yGPie*b8I+-kg3sUr!}0eg0rv%d~E zq;QK#3y?OL0lbrdD%cFcW2dY6_78N;^K`gQQI7KOze=PP31iVd={EZ4z5>rYU8UGB zc!EQZ4x6IxEVmsWy_#yNBJZP~A!Ie+c?Uy00$UTMA!w~bK}&)b97Q(r98n?wFyh}m zZa~3T$e8LETja(?5a^g3t=@PNa#<{uOO@RRpIYj0CV6YKmpp7k1&*gxLDqI2=gA%0 zeH=~@ox6BxYN)LIHq%-2qlm$ND6cDwuk#VMz6)BxF9Y7AvGg|waQ}&dJlu-RwI#Jc z=F{4j&g9FWMe|K6!Vg1M)CSb8`f{(Rh;`KQ-n)4PON-H&|!Lf!5A01PJRD%sOup7yGo6R-gyctLj=Ek_)z-yGsqh`w5O zmJMUl&&oWFov95^o)L8pQ$fJ)gpFi+PgOxf<9VgQ@9}>giA^qWO~|RhX9cTBzHWDv z(t6v_IdzsuQ{o)2oC;!u&Rtq^q zcMhvTCLfjSJ=rH37M5HD$|WZf3QMLyt5jhGgqv3HS~V9cw?S#ZRA+?2Tb|gaBY<87 z0s)G?a7o*UVgR);v!=Hh;P3m3rm9;izMTv|5)Spu+#2Bar)V_FvNcaA1ZjN#g5BI1 zT^W_SFkcfq?qf2glCC0<-^|u$4~|!bj%9Ob)NCHF459(Xqy`u;yA?;i@rh~r*e*6H z8Q%Wf!sx)q8M|khR28_n7zCDx!ppjCRI5CV58M;49C6(Mc&@alzc7e6_Y>ap7x2r` zEFOklYiA0vbt&KhIe&8E2)4_%F=X-d>}tzzKm|HPbD*l8SD2#QmQ0A+EdxuATE~f7 zYpW8%>c4AdZVj0B=l0bz@9$jy(k*JA+smAwj*aw5gH?BAv71PAEM-sxzzNb}bYBoe zIHup_W{-sm)e@p>6^H9^I|Jp`(J%-M9h=V&KQb$B$8oo{3+a2-pZsM@TE;dUiPBEXU*zi`pE_JI4!m3WJl0pUD5YYr6FMf+#Xh`eU!Y(j;E9t0*yS z%ua5>@Ya%Tx{K$IrOvra7071{Ls4x-cXLGoMRFfVVC?ItiYgrGuo|u4sO?HZ^oJG`oV)P!r_*!31gU zB4`fT91GjM1)0l8t)vY~IUz$VIp;S$GL0!7cp^1?kl_lSm z_tRLnAmZN8(=AUFu{5v@`#4_IvjH?N`W03`843g|IZdZ32Ii-Bi40o(EH9~Za&vUg z>A_pCJSzRZ%<#^yleQ#9qnIxw!DVEv>T0Rgdg)HG=e*zY;}X9=#DIbdcp5N-Z66xt zpTTtC@?4MtL`ZfiZv%rUntAaaAa>uh$Y+{%T~7p1(HBQ^x1svC4#$h#c{itNgLy&_ zaj7EQO5QAACM{~>pO8jw{mSZB_}M98aJN!)OW}G~d3P{ufMUm5;Q0XlK>7mYPnVsI zJ@(C+di1uDIMZ6qBsq7&c)wMBtx_C*Uu4tCGWh*M7~D3cCh)j)^Pq<*Pu@UVEsqFG z;aFMGKwDGMPBlai1P7%MKU6~~as#7sW8}xyz@t1wvW$^+Qoo_v5kcPvAoxRaR} zVT7we;!DETLze0sdDR_=!C+tj_a}e0#^@DA>2D_M;EHSRX1Jw6%D?x^0G2| z&Z#DwP7`~jzs`yMn~S&C>rXzItwgpuiyKC114K4(Ic(0B+gDZp`GEkdCI0r@pk$U#!tp}V{1FunCsDC(Lw?!!Jyy6a}?_6y~Sm^Ltl_qg#M z(~oP@hh{E2;s}yC)yjR0*kiw8&}0lu%Tym2{07ibmBlEA1s7DfqV8B2KDrq0@};T{xqcr@%j&LoEx2StF3G>|eX znu|yOU~VGSk>1-uE2WzK_}!i@)YS27@>RTis?HD}KS4aCLm%$P9abB;QJZmYP&xE% zz5G?Zha~hPKC63^n-fDY2k<_qjlduZ28cewTN4}iyBjtI#U)T{us?AQ09K zV$Cl#oi@ok5EI;bHC#K5wRy}}j^`p=P57_}&mEM~%@Lxokp@3EPv~Aos1cuy8DQ1y zdBmTV{OqaP`-{Tp%}qb{$g^Dmvp5}O* zYYSIT@r7qeFHch*elTt%Y4|Pm1L2Hd75+&s9gld;t&@#k3wo%afEtENyPkG2XEVe- zPSm~rYt^L;&8Sbw8eDvD+38Bfd&rRewlH|tM-vaU+gsO$NL3NG9-Vy#@Ceu)0%HnT zvDc-T;6b0FAzBND#cZjxoIr5c(8!2?Y@}B}jRXc!&%B|}5v)4UpEBrG%5WX&Xtd6hA zeIkz^ZI~XE#!8D{DKF`x=m|uDqcSAM0>dKVJfDOv*3=s1f9+yHXO(a&BZ9HJcU&oD zoFb$2l$`uf6-fGA4-ar3Y1gxL=e<{R0k-q>cSyK>91E7Bm|VyG7kFmu6Cq#_zmgv#d7tuR1r2gyO(2`j=KFg173+e~nNP^|Dj2XXT; zC8wZf<-gS9dFMV0hnSPc6hGFMy_h~ww}wgDj+|RL>XlQ?xr-mW5O(|~^Fb+}g3BkO zqHCO%0O>QCb8|%^NOOD8A+o%K@itt*Q>7c9u>M2%)bg3fesi*z>ayTcciuVc4c%T{ z_@Gzjx{N4xM_5k>RGCpofcux`kbcmT?2FjKquz}-Xv7a>WQJCVjmkZ*p2%OAQ^VAl zjSy=ZDAB>I&eD!;th^=)(j&`l$-P|NT!N+z&l@N9;F7{IruWZakPP!n4{TvY;CdES186VABH>C zZ!hPu?~>b@Is}g}(|Hf_VW?GETWbUhVkrJMjQ@U36I!z3A8j*=JGp{J{9`?9=bfRv za|Km(Hn%up0cT9M3s1Dd?kY8qwo{g48%7H?z3FbO%WPJ8yY7m>6|7Bi$8N7*D_JL5 zKGG}A6+eBpNz0p=*BTi4K(K<7j9MrFN4cknC!*9kPR#_##vk>E47n{+0VZtKjd?rTY+}8~508<$Q z4H%INXh^+w@flvT*Pv5Z1K<_rX{0%1UeN-Ka3_jM_l5v>;sG6A1cDQLLp=}+BwwnD zESYxbUq*OOldMuyA#>@}Z~LuUCjIj!>8A3@%M&T$i+9??y;cgcF0Ab4XmU?+zbFU5 zo@UNG*?%UJA<>h5ciH!(PGD6Oe%#Z8)JLpM8Gu30H&L8lif?%VuoQk8zJ9{Y6#Flf zA)d$kU7?OZ1krlteX^J5hg5^XNBMQLFu6y@6-|y*a3BWtCH<1ZlNd^uG$neH1%sIy zthjkyOb!I{X_-&ei=BhW0Fek`Sx3Sg(v6=!qn&fAw!n^)Le}|o9ja@xmC1jGKBb!~m zy?l~xL9v$v!byoQh?bqyC0BQ6*pE+K8RS%R5LSs|T@B|XcTDlDHK>jBnTY-)FNrS6 z{Dh$<`ClQ_w0G}BEaUb`Zjt=7;OjeFm(qRMiA3#GB)}Nz!r^%nCod?Io|Z_HY+WV% z6S3@zeH??8oUb$(o&vJnU&VRyW~sA$l{!H1m;1~0jf=R75HH!6%zQEK6+Vj&Z1Sl}{-vrVKYhia zD-1D9A=`5SpnA1hn+T0U4y^GfI=~5#qbml%82Uuzh6V4}6#yk{Rul+%M8B)z<*~tp74Y?>_AAb^y%`#7wwj=7APTY@B>Dkj3O2Z+Y6Jq;t7KlqR1+?L zZ?)`jFm#*j{1vrau<{J`s^)s?mu`L5f+5dW8xfN9?wRDy8>d< z1vibu>pFf&cfiY@t9pYv4{8@hB02UJw!V8eWI-MedH5OzlU;{61uX{zZP z3~UD$2^yfyhasrGo_KzN31htdeu64B4h1R8V93u*V&hDp*f!|d+{X7v?=E*bIPa*n zIR)fs7c=tDfM;OrH7{Pm>AzC6WZD_+xl-l%xxVu$4pL3TJ|rgwo{2Bocq{sEaNAq$ zaC_2DUI&PmLtaK)m?u2{OzIDU)p&l20}~q?sDAWF>@}Ikdy2|q*LDYOC4EO$54_Mv z1sAlSrt}YLW#@Ms@1xe3_!qkUTiAv;L(Xwjzoy*yw_Jse=xZUHP4eArduv#`qH-8? zx1zn60|d0yUl&EY6KTo}oln!48jgD(=-&ED6W*YlSaucL1ow8^9D6rU{{yCH7e1OQc>8L?@05QS2O#Pc)Y72QI|6t zSU+rC>MLI@S440Re6d9M{-iMoX-MSwDUW>2U=5{SV9~inVHx3k%_qk z9kS%OG@*j&wIiQ*NZZtQSN=0*uHmON^y~Njkkren^&wyKA8_;xdCwK?nd%xxW&sS# zGXj{jY4|LI*Q#}H253mKmjBhgV|uxJCW`r~Bs^YYj}>XZ-U$EPMr~cYXXTsg+_=#M zHR_|1EJJ$Pm|B+;M+;*#eou%(Gg~^;^V@+@{88Fj`|wD4gzmv>~WwksXfVxJ97vW{SjkTo%~Q5WIol}G`|Ie zK3V9%DBU?!f?=vO+Ru6dfuz@_w;D5?dCQ4`!LKT#T_}@$RH+4uvRU-m0L-O`ZUTti z!l;Ks&R`bc0qs?^2U4R_HtZp*+KDeP`swwAwcKO|)z3Gw7vs}Ja?#O#%TpEYp;6pO zFmQu)(rv9WU0m=F`_p`u9@~GSXDPMAMZ16ptzp~1q%UiV)V_W^@>*M+U7{!j-?JvA zqU;Nf=DS$9IY!*lR(-HTz~i^=h#B$P z*{vHrsT^@Qr7R8AJ=<0rYN+JQlJM*8>E+9y=kUWJN~YeS%P~0wb}e3%*+DEY<8?9Z zeUuusCFj7~S|nl@J%0imh6ZZfYt~YgFFI;l%nz7a-ORd?qn)1v0=4OFt?G44u%E~Z zx){ye3OSn70kzib8w51kiwYe7V{htw_h^tQ-_P~6qD~_jTs5UOfTC@EN4Z-Smz_vs zI8GLbZ&yy<*d?OC=0gS zb}w_6E?O_gPqa#RjyN4b4h%J{qz9)8+5;w%E(eeOKp04VBP;z=C2>%5&m(Em(Mp82 z*9}y2cEdxlv^^P&Obe6bcHrh{TEoGBZv^NqL#Itykd$ydh__KT5(4sc8l#B!Py5IgD?N|EBtB>DEuR?EaQzRIahK-$0QjR zL;X|7>JH!!$k;84$DT$-BkMMjKEDbTVX2Cc3s&3%Z5bPnlg~v*-|C*Mz_6BaXH;;X zyeA74@|`jtjMmIaW<6E(H?u--4mA|wG)TFI+N14~!Sgw{-Ffej++oY5)9jVw^~sZA z85Ei1V1g}~xzdb>fqIp= zr)2;@k7k(!d&%SZ%Kq=dfn}3PC0{6RI=wn>&Q5mZPoJ2Nj!^L1cl;2qO}IMPt0HNA#Zmz@xKza4az{QF zV4Y({da&wQgGSPBvi^iGi7&SJ&HWx;HukK_x*nyFBYU~EoJCDlOpps5r3rfK-p%e3 zUk$@85>-wko2@~bZsKcdAWYH;H_apO> z$7oRt*MRLh5?ZJT8QmD=t1KOAm_wWcH}%FpzsqG%wg^kwQ^+=^Y{c{BUTqIO6_E){@Arlss5WOYB8L?kAWdL)Q}#(ELx*XLS_Z zE?>^0QSH4DhTJ zslP3F=s_2hd-bb^f0?9({EZRVZ#~{u)kTVL(2)W#I6Maa=oh@GMYC?#s$4G{{sy&g zs=UI$w!B=PU!}q`QGfQ7elbf$@`BcJ;nm@d`DLIF88O$OB!5p{^m4O&mV9t$B*}_T zH~Pawt=x|6tH>ptH*tU4U(0yw%hghJSK)iREcv}^vHQor@4HLF;KoqTkuHvx%vBP7 zk^59(1a2t#bz`9tCS|WZRNhp{^iv+2^)V|D4;;-Zr(Vg*f#$JLHLS*RYygQ%$|W)u z(50n2_fbiWp^D8D{3$iKMH;S8+H?MSw&@W}yQB&mB8IR&<41v-7UJTEp%}!&u%D{E zykIq?*er9KdGffLiw)rqHILJ6wH!dc86_ipO2CAObPG62t5!!DtHx>8YWWA$Zd}BU z+3`49C@7mr9>=9W=PNnf8V$<2OJ{JG9Gs_om>AYl|BinWpDizyJ=GzO!qpH%=p3tu z-9L1>m|dTzT~AK z8`H8uvn2)&Ur>R+w&5Qz%IZ979q@vU*dH-GY)qZr0uK#9lYLJjM~D={g5@5K(2>j;JO@Ig&rn05S7({ViQC=3(|cz_YBay4_nF^JZ|e{d z@PGw`l8?619Z=K*QAenaBlk2MRHz_rs zZBeXSi@p~Dhnr!e=kmColl!}w@yfRYY~{YuuoYZ$X}<~>H71_OpJ)qG_&y5uC+;f0 z!TyTr@(mLOn(TLd+@>*SBQBl$`w0bP;dQOEA%p?TUa4niFdE6-vD2YamJd0eBn>mQ zdU)}!^3;FX#jhLCEz%-Hm~qEju#I|2A>obpK27C~0UGAFpGU(~ki&Eo5V44OVfA!U z11feze7=FK*HczGG=`!1oXC6vye}BLs7+ zH7Umpm7j)~ciHFK=X2Leza7LW9qS%$823P~Nf%d!f&AWy=r81JD7-6Usj^b$%m^MJ z=hX$-FN*@i1)1I~h@`;Pg~mQpyT9l~T>uBqW@YYJxJw zUrUx^cMcKX%;@=b$!O}{pacK`!+3lH;idTlP%8fyTD^8-yc)e&Dgq3K#DsC%1^P8w z2|)Z3OJ4s*;R9;W5TJe<@Gb+NbTHsB2x1p_2Y}=RH-uQ~WkHV*a{JDmx%FP~0!b_twHecP}%spg%V2ks={TKRIN!97^9@i5D?*i*`vT}_IEY->- ztPUAiOPGY9V70u-sH$V0m?7TiXol@Swu9IPJQ3(UG^~XNTk%eEDf^JU8i9^Nvb{kO zu!ad1N|V_!G6TS(>6;(ZI+lQ0090ZbIUtI5D1HqtT`Ldc?->2x>!0+xqCS46*#a=B z9xvKLx;aUh7={uxd4=pH!$nbCA4)QKvy#6IEBc3hSRz^|E@&q8K|XWrVVCaoqRB57 z%0);phhxPXlb5h5B)B6hT#Bm_m!xK(tb6}C;YIu;x3*Oud2B|jbFoyW5K`6D||o2`SDFLa<>;^4)z z1rV?MFGd_hW3ZE<6F?P8p{Pdq4&bHjWA(?|?;XQ5q4=2;7*Ov#q3b+xl(r8Dt`J|| z0#`L2gLsO(ez}M|E;`3^&r5!k;fzNCnD$jc}%X4(T|M8q1V< z%ENvh^?RQ>=0P`IYB1~TTJZWu^|e#VGoy1p`Gq%g-DaL**|^2hu~6O(8oZ84Vb%ab z*V;@4l!Apt?^VxJ6BY}QOoR4n2B)K`36GX~LzD$_R{mSm%Hjn!!nHRO|^mVqE45EW`V_8k|57!uL~?MX()5- z4#3t+dVu$sJPQJWBd4Xzp0k#3Zr;Ti6Z^Q_SJYZD+~| zzfAW4D#mfam&$eIw`i=Q_5|%llLr|=v8&~xj{nn~s^;Oxs(u_eH0cNOZ_717c&*${ zL3WmM+Z35l zxxeU%fzw+^yos`35x|&OCZDY-j9!XQt_gaB(B{Z=sCdTnTZ*imlcCqR=cUZ+GEweW zG$T`!@>3rxR*NGk%Nty4Xu);BO{qyKt}8UD3##Em1VtogAaRb%fVp0PeXB}>v}%#k zi}FO@e)G7qkDEBDK!2NU^Cft$usUql6?VALdO0Yig(6{gLZCDTg7y(6J$g$W*WXLVobxp8!Hg-M>GPtn!U{$nNgTF zvhO~KUEMhT<{`CHz4*?pyYsQ;4+o**rQlBNAYY3wI5=PnV7 zRd=Sd+)BiJ>wZ=(zZK(I=jw?03%njNB>2EiYx1k}BdLcw|K)#=0Qf-LK74|fV=vg2 z*fGWQ=Z|t1s7yzXVd{r+w}o5N5_Zf(T^I6VS!RqByfBTs40ERE&j6JfgCO#V!zs2< z)yE3c4$AtkFykGH0quMO&s-3-%@zeC~b-d%w4(YYDdkDXk@KOgmpJ9$XCVWhA} z@ocE!!Pww!Qd2U%3HMcKg6xyZHCtb>HYt51tq{62z1gcp8M0;671&}tA4)0=7hctb>=)K-(L7o=F88as!ePx;5pR|@QC6H!b#IiJly;N<1n1SAtOq`J_dqk{w zyIlOyIq^(=3eo1fIdK_*KLL0!dVg$k+h|Z)MMXPPH1V~Q>r08ey2H&CJ0>khP;Xzw zl@?YSE7VsK?MvS3@-sm-7P&y4(yZfmyo$E7CbtIpD@@|?(n%-bI3xHjnODla@l;+e zE$RI_daLN)ovs3-46oGM*FURzD<_Jj)=5N-ExFUixXNZnw{l0ZVr8-WOXnnMH=TIg`r}S45L>SW?>qSbxaj@(d$R{`85VUM+s-S4FZe|Bz$@Q=;B!Lt zj*-Lp4$!3E*h1|eHw@sn+G!jQVb+KzaYdWq9IV!W1gHS-NXQW0U{CeS+kqq4!D-+w zzGdPp8Udl>ukl;8ol8#_x9#Yrf(3T3s|tQr#p?mb$sjwnF0i1q0DSm>9lo@wC<(tQ zE)cRrK>Yl?*cFJIxn4%Gfm!Tl83uTeBKBi+DQlbPGKO9rDe|0*xl@un5@^-#`uJ)0ywYr&g%8f>pfuU!MVVJ%U z5Jwsumt;SKR2csXp0BLtgz6vhZ9rs}F;Lw-iH;pdC8R zZH;BeFPY=ErDB39p}r9~CBb($B*%I{0P9tU9fi>s@sB;@Z{zVrJ)BWl`5-efh)&6k zzLWJsB17dR@rypo8n;4n-PTtm*=)&bLCzbyM#mzZj6!Eu&MLb)Lf>!B5 zno9O%6)KhZ8O0(^H`ee&4y#}z@sFe>_P|-=>Tmgy1 z4r3yf7Iuu{vPsSve}T<6|92#@P6bs<9YEVmGG#CKz#+pZ~ba zDwJmd!jo=$kFpRn5P=al^Y4+SP2AD``1BR88m!Q#lkuZL4@qkM(O29o#McZA$M#dz zwsB(rD6^|!6aEvzj*FL0{QVn|^}mNgvGGPEIjp!a{OB8AWb`pD;0czomYjnLRd z>;SD=@qyK0$^L%TK-kel43?grTEfSx@ColGLe=5P%7J;E;O(Vm4qf33;8$HySxDU?5#U^1_N60 z;jh$N0mQeY-Wggvr;{wofjMaH&O3ZYpNbe8bUyI?Bw<7`0OhYqOGL9rR?NtDk?vjXnaD88%(55PCB^7JV#3^2h7%Rb$( z7vnM1e5K5YLQ~~ISx8KR32q~AgnMU`QH{E>WT(t|zt>kj%=^R~+j6Le*+q#pHXlXX z6-*Og*MhqZWZhGCowd9#`_Sn_Ua1T!k;k9vWkG-;{F74}3iC|$I=wBhfQHF!W>K(d zd0CUm{emN*s5HVD0VN!S5mXMV#Dq8`fI$nu`=SD3A{e^{6_7C^-nER?lCheB z&Lc2P2V_4m@_tNhIgN!D!JaC;b3lmvi~sM%E!1Z7KU(#*z_UvoFv!4AMU#RI=>A&n z+SR&6k^YVOYb9r+9jOH`uEw{3;$(5C4tN0;N<3bPW|9wN%)tKrelA_(>t>Mq6j>LP zXBAZLHtkzjjpaRdhu2*}XbVe&Eb}D;<@1%Z*>iu|lM9#edb=TLI+?Ljf~)(G-p`V{ zbuX0Dm!^>|kGIl!7dT-c zjU}=NsEOvsUCUll8ej8bxDNpcosRuOG*R-bSunsJFm6R*DnNs78g8PJ<4Z(BpS8tk zus>94kqPnGQSjI~Gr<|vSvJ9V**rI8N5u?kw9cLi?(L9&3PHe>kwO<>Jrei0Xt{h> zTf;K&;6b04{U-7z4Q--)$LV8609>WQ7wIJ9Wch;@O1kCVCv7O__d_|ZN5b&G-+}@q z`{&??pv`sMfyuf{s!H!4M&QSLR(Xrx3T`;%2*)*N6sA?&k!jZPm+@GqzaOXF(*uVl z9Nl>~Gmy0bm0^0xb^fz#+~r=^q+zuAJ$EfrELQ}5!a(;c1ZY6w$b+$9EH_ZzuHE)> zuS@*AdYbiPO9XMW6?~ooMIh#&H_|XPg+OS=Kt4C=voR6+T_bx+0%eZ2WKSn`z(^V8 z$U+e9mXQNhCZ#k}cnN(;3I8!7v(HkQ$>3d2Fh=t7ItUA|{*6@r04)KE_3}w0L>vNO z;xY6|#r?1|fOw?%#L`qVaBl-8n$$>(Hrkw11m%on^;wSR42G@X98|6y`LLeFA8x2& zSxAOyc$o(X&r-}O8F~uxD}x|#Pd){HbeB>Q4=Ma5(N%0!F!YWJ*Nk3e?VOCPp~ST> zD_NU9jsw8}`^rf41xhuIlsNaZnytVgt(Tw4;>wQ0%NbmN(bX*4zPvpbr1$ zJTTpDo4FA&26Gt2W*Exr5^aUrRBcgeX@j73CxDAZz76u|8Q7zyC7$ozsuOHOC8$0f z10r|@14y`br&!kI3nzbpN9jpL)Bgu^*tRo7z{osG|v=kzA= z%p?VOIW<9r>_=n`lsSX_%|jvGlFTW@nX-l8_9-{Zi4te|CJ0-}v6EZNM{+e;MM~R# zmr`0FdHR=FJqoU$3@c7I+%bs{e2)|c7AvmjU*AJf{<70Gmc9(~pcXu|Xc?FZ13>YU zBOnBy=?c@~_4kfFc>pS@G;0VOB%qXlxcEl^(1p6R-h{>^Gg_^V(DogK4`^?uoP+!p z;$AMxHI0GI8{VBmpI-C{BK;Qa`+mJy#q*@Z}&LGfUYB3pwJWaHLQ z-^V=qC(-t;cCQl(y25fno*H0aKx(xr9KNmX{TRmNQ;@)?{oel{aC1!|P_Ojw=WF5- z9bU)D7V>En%WHCfO~ZcQQU9;3Na( zi9duIgCS!m^rLZp$Mm_B-)4+ES?_5oRiOg}L0~&HpW%?{sa9-Itep#8(Y3V#7KCL_ zpQSGWEt-N-=L-%IEDL}NzCtiG4Jk814}xbiy@BA8r2|t_MzRBf{(RCHMNW_3SoDx$ zk82`k{k&`wTGz)_1qUXxLgnYAp|LdRGwcA+X7bSk=@mPfLK<*KUNa`TOAac?8vA(n z-gVt!h2+hcmGc;WUsN;?XtEyM z`eM=_bgqz`qfDUEItfJ$$rrxmki|?;aNX4ihKXL3_8@JtgP=ldAq<%>@%;J^FkBBb1tfuoJUJ?o2z9@4N)ixJ8jl_xe9Wk(ijhMph2s1GzkOv zd@l$&g#C$qAmD(y0}|qa7=RE@a03RSUAEpLjbOl#I5WJXAq4FCu#GSW1K)rnP0U-U zR(X{y89YrCGN|sf0-&Oz*fenAU;lJ9jNyxivXc3;(&E2C`6Hq7x~r_avPenM%TKN8 z%0>f2WjCE`pnN&>w5y?%YlJ_M9pv)k4i(66${J3P8=izsQdp<3@8XvX6{X>!EqAG) z*sUQoiHRDp5{PQ`;6NF(N%(PRXyxZ;%@byk$7OLbKR&jHJEu`e)_~ElHuql;s{Gd+ zI-=6m8j;~mP09O72<ok-fy_Jc6mas0QtNdery!{ z4Mc&(7{=7Ni-9~wV`1X(Ro($K^9m9B9WN?k3$-dduGPHzKQ*;~LNm1fgqnv62QxjCa0xp=79D=5+dlk8Wj0>PSeE(YkzNVScz*a_Ohxxo;j zrZRCqaj^;7N>8HJYvahJ@qu_e3tk7wY?J$xTK$o#Yy8TPOkpV(Tv#>KbM7O;@kDai|^_3Mv`jxCr5Cpe4-;Decnm4Aw zYISJV{kf*6u9Vl4U=sg?3?c?!EJ)~qhjs2CXF0DJ=4{T|XJht~#fgfc#S zkJ6*b8#W6(a_TrF-KfL9l3i$YIkcrxJ0QR?Y_}hZs(u;P#^A4 z4|snr#?K8GoeMA452zIP$%LcY=rX9FeW)j}5L~CEUzZ5+=9{9VDI@zo=N0w@L}yZQ z+h(ZPFhJD5bIo-JK1bd!P=6GQ5Fi_6{5PsixTX$xBA7-Nx>wCmZv4Ux(xT{r?{=wi z)5r*Uz!KSFoQB&-=4`_7V%&hZp=>J=`~shI1p449g+Ji;v*|)%5wWYmNNMCFH9w&{ z9$s>acXY;X$%W}h&Ewf|=8!aEB83l>B|qj<(j5tuVq*PkT(W3QBO*k0>rJ@TDcQOX z3*KuYt;Fvz6Gpz~?_=Ck--WvWQC5fpNMn02@v6S)1Aqxj)X7OqTDk#*tR2ZhqsxcD ze8lI@)bz7Be$37uJH{*J<^~tD0NluX82}2yODj3xD%8t;7cD3s1a#^g2MGR70MDkf zQ&4Y0qddVGQ^q{V01He&mvQ$pEB>g!mMI{dwr<{Bgh*G6G4D)(b1!?ET^DTeXgCt* zu^4|$ent2Bj3^@iEp#d z{v1T)E%=862GdoigY^+h`spy-2+uwXSR)w|Q3dNT+n3D&(peCwGNyl-3i_?W!4kXc zKU0GZqy0E9?^t7a%|c{$zx9nrw0aAyDV*KDQ$NsXO{_E#h>Xe`fyY!_uUR)C#G81l zS9lhYuXr)Tmjl1)EnSxaq9|+XG~(IuhvfNGyJJ5P>?2y9nXsTMpgHfnWJI@TSQMrW`VIxhhZ+<%29$4#yZ#p> z*?{tzTn2n+;t*C&#%%!}u3fKucv6?$rpO}Ir4XG@s{bBu9yg|9YS2w=dEejVdss68`8}5 z^}{xTF5tThE0uXmFBs70|3Pd_R9^8*nq!4+N24&81qeVcaY#T}WR>nMb)En42<`>n z*CRxIPG9^6@~WTaz3SKtc2YK2adnD356jj7!6{kc%nMNQGm4BXsYLK9St9h!;UKTe!-Mfo!`Gog?T^M`peb_eY~(#NivG#kHUd;5nqm%+SM$IoYRXP zx>fy{_2~uv-ei%dxVb6{07yZG|F3iOa9)RO59!THMB?NEi!OzWI z!y8^Mo6QrL@u_40Tm=*zz0LM59M+P(a%rX*84r_969pE)d`YFClZ-9n8`r3)T*Qzb^Q*lSh-;jXt#C zj;c(+>S?b=^>|k>2iU1Vqvc=1cPIN#4mMHJKK$8iY{5;{t*S7*s@#o8?^wkjqZ>0& z@LNwM?zzr)4?1Y@RS%uq>dKBMHzXK5VTCAb_1dFA?lJx2m9C3{vHrJC*?jQLGJh5x zp>OVNleximZ8Xf$5UcCla2n#Oj~6h$0I@Y|3cPX3d-d9B(0KSn=U71fOk)G_A^Zt= zAe2r(qbxb7^m{KCLY@{kAx~8L^pb9?dTo8o?&;f);s4Hls(v%?q4sTSKr`JEx$--4(G;3RVnE=AzMsdqVL?M(Pjss<65EP-|EXP>E?)#W1HsTBgDr*p zd-@8=PVMtf-b`q7&T594C@U-lHKWd@x>G+lJGA}Puexo5dL8&RboMSqepRP|wWM=g zgt@NEw=}0O_?+ZSptu*CsoM2Hui9cGJ=D{D#}(`&5k za7ah+MBsxbAy?M>fd@Epu6IBjnmIWz8fBwrDR@UXI>UfNO}ByO=(%iWL@09p5XAUC z)1`z-1+f=+jkiYlj3kiC#c_a-V-k7rw3<3r;mjx{4gy$>?_I`#g_$||y|KS2?we#1 z`C%Y<3}GoFb!Sfek37=>T&h$Ixv!UeDcGV5YjU0r?MzW@&P~Zxzl6CLeRbLA;7@BXQ=~7*zH$(%m47_ZpFI6{_APCiEBm+w^&ZR`aMV1}5TUM}d+Ln+n+p z2Rqjm8bVeM_RuVFX~Xs^(Ou&CbV0Z_yf|`Xht}DL@ctD$rgrjUaDsGCn)61r-a|Q! z&b5%K4;t#Y$19*<#iI4P)vB;AXoq|bgA+76Wi2PTdXgcH(@h0~JWWYIqx@@O6SQX~ zL+Rlqf!~p>R3U>r;;|@H2uyWPqpFgi>v`njm=w0P$$;(#W>~XB(ux(M29zL9)CcL~ zxvte2bkuG0r|?Ja_XELA5r_ZKz~tK@AtL;%!8ZSE{O;K!%I++vmB0vuoZ-lk8DxuC^!8?FRhghow#tQi`uN4A(67e7Y|lSBEmij> zgoyMnmKe<`ma1oX6H`5{*#^~BT;KHv={qEUk9N_}5W<2!-AI@WOw@nX{rUhBrbRR& z5r!_zf0B*?blOa?jqNhQt!#?5b*sM%4y0Kx!mv%)uQbC?e=atF4KAcYH8sd~$Lc3& z>IMAB-+{FV2KY>Ne*v5S4e6vS58()SY9qBZ{^t;MM;x{Sn=Gd&SomaNoS(dFWTMgJ zc>N~gCK>c?3k@DrEJmCz;o#=kFB0M|ApBI0oaqBlpkK5Pq-NUL^T!1V$_5HJ`J>+< z*Zf-aaJ4oz3vy3-g3)Tb6GgXji1ojAH9H>?Y}T|z4nI7^wH?iZa6k+1KV8jw-7}@; z--M@qS5ie2@dg^d>0$-6Q8|-(%sC&O0e{g3jr+d8j+9tA6#Gf$O!P9fmrJ1$?ia+0 zdl_e;kSJy<^rt5oP%)zB`h>&{@ZTB_WEKJ*Z3J7=ev8$tH$pS~Ia(i3r+zC8T*+qJ_UfU4$Sl#Xw-EKr@&^;I-d<{xsoOKz8KY?^#%(83r+e(U-a$~ z^}!*SMFE_R_5*n+vVI}9$#UC9$O=aB4$GfWnna{}ZLFPiOqFb5WDN+X1e5gnU@Azb zfJx5LAX)iyo}}Y(QEd@4HB#{ILeYPu1-QT#gmtvlX)dgX86WCh8Pf&-X`{Q~6=(@Q z9V|Nf*!jdu6npjwrdTu=^3u99iLzc^1xzOEdhQP#kLozYKdV(2*XTae^DT4-d2_3B z)m8u>PEmf1H$f9xq8~P?@;pu4WWE-jsf6M2*>$ogX7t2q@lTA(L}o?3-gq=+G4d4H z%zb4Ku^}MF`AuSdFu(sH<)2C90|*SXzM=w4)=?N6L2WM=3n98m0Z*0&HcaF{q~g1M z^Xb5CCUx5^DW8t6U&v{-#PQ3MIUH#LjRoXC9-%G^zrjO^g&3fV%nLUn(glbGC|pQt zR71zNe?KU7g3i!&^8vqUDK>ij(p$iXDKqh})l~qL77c{T785x=5W$2}U68+am{+fz z2+~K@gC}*NtzQHTVEwV+ydV<(bj(*jVquPer>XD-AV}WwANM+v zpU8VmjsqdeniZmrgCGCPAD;Q9IOY4lg|hNVc^Rj4N0+l>Qj&hKrF#G!|7BEt{Tq!K z9uHioQveXQwOz9Sy(rQ>%c$T^IW4_YvRxZ}TQXzp@;4weW-O6RB7*w!)@m1k zdg>LfLgVn!p{ec)IlVYdWAq(H-NZCQWd)S&ModUZ5YO%vISaJYVJqgEIyzS~=3< z$Z*&Z9q-O|tgMm>_6ZB00sc48B>uY|%^voy! z8X)b!-vP#N$bu2PB~>tuumJ4;oV#_YN-L-+)b8!SxB}{+msassmrAJkqAnxMt-B3~ zU3b;$<{Xn0D6b6NglJuSPF{~n=NY82gb!dzw%Mc$4pe@GQ3vCxc#;AUEu@K|w25aV)=7Lj_x&KB$6y zh8|?LUp5N_)mxJ$MsTEdR*y#MhppkoS!0O{oBWBIbwqeh~BVekRFa2D+>TnmONGE z!_WVN2{R7aaI-_si#cN|8Bh%i8A)&pk14pQ98JV;)V?xKuOM28PCiE#z?7&@ypD|FzOVdxK0FLx41$DD$Mt$K(pU}Su`%c+_X5%y9 z`PiYHFjA9lK>3Pso^ejD6Xi91 z{7|R$2y9X3usJc{8|CvPal>6&8g6yNjEe^v>kLiFz_k!mDTmy8#j@zN%XR>%d zwUeD6QNy106!`f-7P-Oz=`D%E5F;==@C*H>m- zGm;CX*%QG-FyA3HjaXyKLZbH>pwL8)U6%K)(A zdqB+vbQ(lQYQLw-dS13)w9qZFht9{ZMUzPWa4abARaPB^C?JIN3t_z(@l6!WCR)}( z4^QB$yb$t{Xhv2-4)Nx%zM5Te55wU72jl5p{;2DH+Ll(Fw#zg=w$ym37X^@&2)2^= zI1mHy9*~S=LV=ytZxF%BGC>O`!mN^A=DI8Y=KF*JvyrQG=A66Ge0~k3fWEk&-VOiC zODgn4k+^wNl^m}r!GSlzIJ60_j*XCLi_mM|Ej{sswi=pIrLu|mP07|{!3;2QFE-xv zRwr+D13rN|-(6_tQhEmDU1Pgcel-N4+AL-CLaD9UHY>Ow*ISI?g(%B`6N9+GOLUV> z!@=qJCi5i}p+f2Wrlj)oB<<2~Tb7R1;Pm{i8)bt{!FN_2Z(J5$kDNGSy#Z%Jm$b}@ zg9GfQAj~{=!-DwQ$fb6p9HkLjI#NZ~o$iD7kFTA1f9};>gvh0*=irZeGIUrlIp;Ss zCcidv7SRFkHBECnuWZB_+71W-y}v4p98ayEoG?XAmh)gQGNcV%MfmAt0UEzy-hwvB zBTO0j`eUswaM-UU&r`=@Zg|g*8g6@IKs}xEUc$DQtCkg86g*HSO_tkpk|?X#@vDx3 z6xu#RDjN7}vmN)lSY)@&F`v!p#rEs5*oC%BM1b#!f=b2&={T70bneO2^l#{7D(EvP zj-=BMdVyg03ruy*bLgy8^B0@kcbj?|DkiMr_hLPXnSrQnV?GJ4d72ajEr zeCcS9`-fR6?klgdo~OM}*OwZBX-u8{WlA{!(W#j9?qlu3QdzKWUYBe!woVljs@pwm zbzZ{l40nRcZmTcQP)9)?5DuzrF0UiZEPjpZ=Wvll|HbLD-lfW27bLmoJ0*+Sc+1yl z!@o#+G+BKP-$m;>N1dqi`+1$&f-hb0PW{I$xjnpA@-~ZG1#_^zFcIhZreAutz~iX> z!!QfwknrUqQqTAzavBcK8KBCa*5>=6eXv>&W=T`Q7en?kP9)CN!D6>5h5I!5(Ug>$(0vqQ1HKr#C9W*1w!p%1gnw=^tU5kW*+AL>5X6LhUp3L- ziZ|i94CjOIpus3T0}6asJK<$A3<_H-Ddo^}FU6YB-47kmY_q=4L(k;FjfWiLh83%h zKMcP@%U=zZ^E66Pr0x*8;jpUyZN7e{;5q^rU?YeE27u23VtFt}dZK6@h-*SMr%cNQJQ98A~6m*Y6 zGhIN(8RJj@OH+{j+grmZm;5~;vboIIZ0Hdd|4cMM9JU2t2lw2ax{d(&nxC7ZI=((^sove)4 zSlz8kiCt9*t2e#pG?1@$(1D3h@y^}0JUUKSZYCVW^tbh|Ten_J&S z$Vd@eRBd0l!Q|!T%7d^T&eyc;|H02P1lo+jPyG0PFEt*}T7Dv&?Maqr!X9nF04lme>16Bdpb zP^DKW@lL=s8lgWjlrvBoI)?#$N>or#Cdf^D8GfgcUO48Oqiyv#~hiyVn+2uLBbDRK?jQ7FnGk2r71 zD~_D5n>vlmDz3We3@?{Iv~A72A*i-xCCnmL4Lz*jot+3A$RjP0uqyM~IN+1@SerAf zn66tN{=2$_LPyW^Cvx(N#_PWGqAKKge3OnaWvcT~TpTarn=_E1F zoIvTOfM4sJ3q$QP<}YG)d`BC`*WWvWueJxJyfemkMzBK%U|5p@dLS<9*aH;tu*=^% z|Gl1z0f#NN;g^aKuo0;=F%{^KJ<--R=th`W1?^E%BgX25(2BhsZ4RGfz9Sqp2XtsR zW>Mw$Aw~McLOcsXuv9C6a9aQ3&bIdI<2sbwKQyj7b!;6P0Q`8stYa_VgnvaK6U)HA zgX4}CsL`t9FAYF!8411PrkU|3WU7|8R*OPvXk&}<;>axB>aGxWrh69M=`J`U}> zhS1SmbI1Yk0mkMt(~p4oKV5vJAHofejS?T0EM)!fiu_rbtly-K*56z=n*!kd{oVl@ zOEBda?DyyJEEu{;11WemG|Kg9gpwBuxc~km45`231u1|Xn=w-GMWPt3+td-3MLhj> zG2Wio2m;Lno0hi6BKQeO_qq1ATFEtK)gIk8t!BCI+apPct}LI|3jZwgn+m4{nGWXo z-Y3h{1UQh2YZB{O!y3N4c~lSpTowMfpFAupBI*qd)6^mc3&W*MU28h ze#Fan2me9QD^eQN;xu8$5IPctxkHKh?du z*(R$#K*z)wJ)C$0u#@e~LIISs>Pp6!*_{P=rtTN&Z^kt6@c=F`x;XNv?s2CKLW|c1 zoy!D?8uIN()pSA5$Wo%F=!N{vI_*DOhOL%qA9Qm6`~xPd7QPM9)mnme#OG1QDJT!h z?7R3zyYsxD?hna^q5Gc#+O$1Vk%_=0LC|1a3hU9&ikN0artW65dvo40?e3jr0XOrS zt7ZYF*EB^8(GpVF`A|+ho%~*M_{9M<%5zCH%IPD%dJw10t|Eh5rBkuH*cSu3(HwU5 zbdZlsL{bn6l}cem1;I8EeYveXx0#MPL1Od%RE{fRlRLHl_!^20rkrWMq+cfI;Jqf0 zs|+d?DcCUa2A1gfUkUT8VcUfG&_T*!Na$m8UO_yd5Md(023tbi`R9ZngAoXzA=QX) zGp6f-xXk{!QF;!TJ@hT_H*bk3+%wGX;m`BCKZYpIJAm6V{v=M~Z|EG57 zmrb69-%7?EM`E-4AU{Bruz()5^NHZ;&K3zwxbc&57XTP=(=9O7G~cw_@Rn3`s*(zm zw9boRk5lxm0Aen>(4$SGAkZRVA6Nu@FY5^ep99iVL0Qnmn+N+z8MMG^-(HQMnw}#4oO>i9+qDk|GbJfPEx*jv&cO6gx;=1_!kZQyy}$yqvzbh zDA)_qsjFi-h?EYf6yV_`trb+gOD?6!#|gW)ds_(Dal%BC6%ma33m{bojSAsA_0yGE z6qsM`Y`hvCWbpi~hILG77^SB3J95R%z=7#93oM3Q@;=nfdpI%_ZKeWn!X{sJmwwLz z>d!sQchD*C7eUQl@b-rwo{p-mf!Z7;mF}>H+&1<==Z{0=0o%s`j6l%BfxGt7LauKK z&VikCEL6tB0|JUa){I)*e+K7We;NAp9bdY47Zp)|*z=Q=OTvn0iKzJF{aC*Q2GXa4Zl!K1#e<9fPE z!W=Fp1)z)rx6LS%xBI5^VMOo9)lZh?958@?VD5&Iw_kDoe#)(hU=_5x%Rg~q_f@}s z?=#zwxqA)(5%yRqFOJ4Q%-{>x@K&s>eC0!pb2ABM$p@<0;sz_oexV}qz zD=Y!(pCe+6K24;Z;km7+pv(FH*b3SY^l)#S@~``@df*JMHI4?ZJ9S%8>I8Epr^~KP zWY0JD00zj0;iP)Mu|$XZopz!eXv39cZ*LYk3I5Z;B-aGVw37n27LjM$O95o*YX%sO z;wH&u=)=a0yCfHi21cIxA(vk|bBGl7n)E6@sOB-RM6#H+wPw$N>)-X*}IEBmzV~g$|j@ zMcugY#n-Xw(PrZk;eIau1fdU@!JOuJ1Ed?2#&uENEY`VO7C(*t3#^+2*LmR8Q>ue6 zXnk{0>C8U}J(LRW8Dc;>jwTpoPGw1cmx?`eEZGKzw!nI3@ zr|M-w=NSUa_#V|mN;-^l=nB>xwUUOBN8gEJz;(RuTsu@jtyNj&4d$GLsm6ozE< zrD#c$6C=~uQ31#B??#g$$piiUQ11Y*=n?!8^YGMuXmBfp$RZW0%G~zs;#@JFzvK*H zN<=1@yBsK%{?G7|Y>Y~PD)<V#^_Q!iPPEb?)kXjHq)NAO8e1*9v9aBadtutHNGG`C!xs>A~6ArM$k{!V0_7gVer9<_wk>n`1{TH{HI zoCIh1s+JJ{4dk8VhLJlpJ_%piLh4DYpPQX9>G#Rh7cNi1(m71&Rj9OlWNQ5nhi|qK zEa%!mnD`mhfU!vXEcY9hWb_1&T`X42HGKCODD zBu2g+nFJcf3nT#v{ApMBUPN+y;T?Aa@5<73fBu@^7J}kopAinIrxmB^-Gmc=_7|QV z2TCX4{>8@Z{3{wAle&s{tbn;QStGF{#F|>3kyZ~>@1*f^NTYXfD$Zr)C;+;365_9f z7DK_;bl&Yc7^t{YbFP+Wme8Z}E93bSHXnI(Fk>095I$7m?DUcC%Br=REgDS)FH>s@ z^Q>aneHs1v+Nw9E)EDqdzcW>C7DkOlz;4uFJ{!1WtG`j)))TG(I^FrwD#oP|`~!|zp9@L=1~om_rlk$DI4+ei^#t6Fp;VgyEBq=9KK2J#iO}b^ znHVa~xY<5Omjs5RSM|lNNZfQh6p_;p6oS^Z5LeklE3Jg^9H`SO`O0#Ue*uKn9mft$ z0OBU0(wt>&#qT+A6hXm~CW%FKDi(Bymq`E&fU|WT^=@i=9NYqPCSyNL7yN`;gp!1lopz;O46s!f-6C2^Wc4_6 z0<(x5=%o$t5gcp^7?Grsb4uaQPbMx~^(?n=@1EgCyk5#Z&c=|Mq0`8A|oP5zf}@*OcjN4#x~sv2W_5&lFUJhz=CtTJE&HwovF<7oSRW zab?P%;MWcK0On3b&Ee}m2QJ1OcPflFlx{Fy#I_}6Ynryfmi{EXSIndIs^7rf{R`nF z;o}lPE{sv)^cR5qclz8@+*W+sEaJJ^!B;tTS1@t3OB744uZ>L6X3N{YNLDUTz@q1! zjdlR$gcjv%VuQ4vpY$c3ox%R9tz}iBBVAmx_^rAtnOrNuJ>^t*qfh0Me!cl_OT$a{8!{c+b^$7 zUNHd_!9HVf_>P#h3lP6G^3Gd;P$>78Mx{dp#&Z?3SrK5A@5+f`-hzcT9nQKyckn9d zYk|0zdivO~B|3Bq6i}-Tty>pTQtqqkF0u@*IQci`*yMX(!wcP;C7WwpP%!NT?7^eJ zl&2PAwv+>V`8lX`+I5C+4=x;73l?MCiG~N*`R@&ArXbx6fW8~t%RAwz7zj^AAx?36 z*yeo9`2EadHffcs^RP=2=KOv{`)%zjMDwkC^ISH0MoJ`4td<_Xs7t^zi=WZ8Hc5^Kh+4}-H@(s^dx4B;?BWrBv4!a0TzV=+cPo3gFh z9X$YGQ-xrTz$8eAgPjaV>JFBagV&)EJZ=~Uk%P&Pkwld~G(r}di(wRwq!JBbVR|4G z+>DyZ{!Q8@P^^tn|LU797QG&iN&_|vgLp6ccaAc`^A5$BfGJZ4kN2+sMdc((pKen} z*im6!vB~}Y&cz@@(!E8U=a*vqcZa6x2XX2ZH8YzA=Ftk1 z%Vqu&Juocg31r-0U9G2X5)#NPPl@ytT#BcF&&okF$!hJp-YkKu7WrE+uf5Jp_XdtI zlD;8ttK8SFCC6)zm&-B)(DKxxSOYc~6UWUOpE$qe%NHWZsab~d!DkvkdFq+oMh&6T zZK?UA?-}WqRA#+0dKY$@TX7rxGT!&KRAT7PNP);V{XxaEw^hF-?A>$++yMXKGFIUI zXU%P=WhvxmV(`aYL5|XiHW-OfWNlw`w;=xn@h+AO?YE(>{V4di z)45sqiO^3@l^yyB=d!h&7Kl{~Yn)?sJC)xQ$G<*o8eOI{LaRsfDrFSu@)f`zZdb$? z{c+x3yK<*`gEq{MQ}GJFgVLzSZoC>#-!Pm9=X)SiLHlFx=U(*_Ot<|kxBykKdyJJ~ z6c%+G$)d!h_Q$f*sW_0{g=kA-Eul>pH<;vsV%aKLYW9xu7_QC>V%fpemGz{e|#}e_hM#*PS)la9!d5d!AY{+_+0{Yg3D5KTw zwOx&|X}n4R2Je!R9p2|T{7oDzMK_&!Y2WIfRyBe~6M$o2n7rX?t_x#{&vPq(0Br50 zgtVqp9l`yQEI3HfP3ct5-YH!MPZ8X|Hd^Y{;a9`Loj=&ZMts$P&km& zwa`v44Aiz=heH-dt#vCZWyVBL$84QNkZudHowQVCg?^M=<_4>OKm~--K?n=<7hR6t z;4xLb7L(otSkZ#OO1&jaM;x?@494$2iM{Z|9wOxU8&?ePVPXUZc2yD+sk?Di*c=xJ zj*9~&@n*G=<6g#zFUBZ7U5`De@IxH+@VSP3(B~sOX08;-rMzoO|yK}cZI9j;wpdli^o8QNTuX=-`H@0K(-@p+x6l1PC)Y^xxKc*fzMxyf#NXrX z+(aohIJysxjD=@Fh>5ANrJS`>$w0^RH^CA{8&=C=$<+}W3ElS!imVVs($)C5KdXq{`H?^j+*(Va#-QXw;X!>-- zMc_xt_LQ!+cCrUim@tk#w`Y40r~0t7n2IpKEWJJ$ zaW!GS4~Eah%#dgH)vng}e1ub;TezG<#581b4IL~sm9NHUeqvS2^a4TQuDCmzi+Q~E z+zsQ6(A<&#ISUbB>kn{uum#1&GeP)*ftXevhNF<>e|e8A8&V`US%GwW&KvjCX_t0G$Byj{wQf5F@X6`RQMZJF z+j|=qo;i3fGISC`pFU`HV`JbQINPFqMk_>W{OOqskiUXDVi==P_B#CCvOK z{L2hVgrmzCiTuJi|Eo8C8~B3meVkihk(rnxw5B%<>ilD5#FfFu7JHDb{=WxT6tD8w zi0nr3O3*M7$ZZ*5%Ix?dQnMNW>C5Bx@XrKGW{(soW%peKyx|hU6GSz@Ia%+5NEh{W z(db4aa5Rft*CL~Wj~L+B(-$$=+8i zI5W31`&ykV0H;;PKxUh;VHpX735VXg%JL*{lrj<+XiW8G zVa0)BhS0?rpMrDXe!LCHeVmD`TOxy1Ab(Kj(V#5}{$MPkkiTWy1H#-gG)Q+A$i)D7 z}=K_zvQ{>J*?;~r;s84n z_ev1}3JRu&J|SBA_m<>I>Q^=$l3vjuc&#yrXN&LSQz@P&0fHMEK(?2;!wd80y_cN@ z;Y1QgjDqe-reGL<9J727c{mOw7GZYG`_E%I0N`Nx67RLvpwAyiq#UMr z9k>g@nVMTDItk7+%ok#nX#N39ycID8-M;GA7po3lOab|wyO<#Bh0C2pcTjYwKQsn{ z*$9*oq4-kAD_lCzLtD?C?eGEM(~MIX=QVjV_Dntt?C=IhVT02V$Bc$bV>u%ZAaNtF zWu}#IyWE|6Dc%{J_?ma9MFxB1KYE@=pVsEIDNajLiHDzwu69XW-?A*7cMaKJq`H-#d)+_wle;N3?r(cI)aQpWJEUTu zHImIq?0=V$%l95^3)>Tp6|L* zf6-NY3`&xLawRSy2VEP#)|3>0b+LvB|Gbs;@NJvCLxRI2I}5lO5MOa2mYyM(53aI> zsAO-3@WUf}tWtzwmAdOzAuePrpP&LmCa1*eUn?g6F#vjS{{%y6PE+t2-Hm2vTUEp* z?y%Nw7X~VeEVKm)pMtXlU*ER>>CR5~5_onqR6@xEwe$3Z(NA{ciV&<&5dfqbX(sQN zovI_gCBRS?5je~<&@TOH)iF`mpot77om>;*7$sFetOt4o5P@bT2}d8Q)`VemRofY$ z{x?0}-)By*0aK`cC}KTfo1?q{>Vg10XuKR3?_g|W_9^K3t&KS6!{AF!elO5xOIxcn z9?KDb6W}tTok3}g;!|P$w0#_vh(&BszS^Ev?oQ>CM$`kgoW=NilnKh;gOy0%??7Uf zZjY}9yJ-F~VVsvH_!KM!DUff3E0^%^QxL8Fdn3rum}sS?G&2_-V*|yas>yYG59!EX z78IP~XM)C|0HmAq-JB>mGe}bYMmIXaYbC%;LEzxsYk+fYGjYI7?oS6FJ-5Lm%**Em zF1nNsO@$<`w=N^W7i3mQ5O7{qkf|%;jh@oOGl~pUs;&eJ@F-TdU?is1uBDl5N%$IB zR;x?$Y_;2>+uow+Rj(-v2#-^&h>3!RlVl+<=>1i7;6tH=PROb?4P-j<`ECW2@cJ za|5+j52%>=d-&0oyXdy5M<;Ay_Er3bqtb{K2%ngd0$kNh@Db`4s-Caa1(ZLv(C!+} zyQBCpUKJdyonF&+SRxs4wijoUw+D{**L-M=qzGoh7(#gMRJ8MKiHX5 z@>RTGc6=_;=p^vm2Y)Jf9XVr8e6Y6eb(ICz|GJYPk~r9%Hw}gY89|}>s`1p_+7u?c zFZpL9U5GCi0-0rB4q}WPSR;nvN6CQ zQ=@D!g!2S-V}achJSQ#31rwORVc&W}#UIcpG>RX0C$^n8>tLQdwKgi}8?0)kJA=*= zJzz8i6uQC)v*lneEs%+;)(ks8+jZgKX!n9S+Ql_9=ujeQr;UB;2Ag-l=~#dOiBIk* z?-Ca#s_CTl5*IR1m+B^4!j_O*`Z3UaV-p0sw856p3=0cF$quD68qF)AlRatkp27}kfH3wWn- z`0F7i6a|-9jKiQL%oKmVdE^tT{IxTNU&|Dv;JXRW)K=&7g1NeNwXz8#U9)vN)J5uG z;6kfutKhySf55e>pzG9kv`#gO+2jt0D|^Oh%lbwW6l)`Y!J4^(m=u+9yprC$ViKswE);rC zfv_)ZU}yfC0s=W~mt+-ics|{c9e5k;orQ-}05Z7V79C$A4BEwCz}#WLc%WLwzVz@5 z9-%SVW#i`!mg8@IV7x^QivH;&erDNDhkfr9L~Mi9JT(*>Q|xKJnk3l-RJt?o|85i7)+nGOHr*3@3hn!DPsk4~x1 z1*-gXk~yU9V4hlAq)rQxVAy5?0htM~2XW?bE*GVdw`GxSY!!r84%X)75swk^i%zTe z-0>14_4*;%R$^(3>~4svppth}7xzZ;u}fj2T=O#xiU1{llHTJrRv#rx$qz$et-8^@ z$BV9Wut>&>W#1rIRqqMRDM_|WM?Dygl1@L7dO>P)?xgOj?`oh+fiZE1;S4qxPW^XN zj&=21aSGU@U%wk?06%1}3F`Z>@!7^1JN551!~qJvSUTe|y&S%_9j5sSX8HgNk6`Ss z2kdfozCDIFvhH#Cp>*`IVR|@1{EO*^3fhiGBH06Dn{!rvN5&Oc3>_gu3nDuf$2e5V z-a~(buMOX}0`T3Ao%L-0%#xCy?U`|1R&nSq4ho4;=F zrA3dCRW%u2#`lPqsw*Auo@T0TYR9^M4(E3r3dU>d&coRVcB*KWe5E9tym&;;NWEj{ z1Tnu&ROF*_sRdQq7xqz5qKrntPY6{axJJ8Rq@XSSN~?3cAd<|vF1SZ7K%#;qrQ}ZX zR>*Md;G0@$o<6m33coYwEd52xjtr)w^rkbWn z%}g_Aey{HL_m4+2H>m9(RnD2qt#o1?Tq|+LbN+(C4j6uR zU8*FV++idPMv}JT;rUUD+ha5P%Au$f&r3qm`^FpuO7-t-Y6V86L)}cG2JIRlg~v^O zHcQ<|L_vj-4wH)YpKo=3Q~ns}FLyzIX*YyfH{uDit?&5qFe5bGsE*$IKelRtSqx=O zsp_B3FhO?gaEN8keci@SFuC^fy%UW|TRZQT>ZYfykoip<+NvlTopZ+3H`3f z6`7#5Y!pCV;5B%x^94lPzhSH!jM?2hV@DlK3O(QLvm{#H>Qa7Z~saH!xnr9gjRIe7f{@A)!wNr%FrLsx7}HEFT=Nc zVSKCue*3@jGD-Jv=E06FeV;FQ#2+}LQ7mc-9!KQp`ktwW1A1G2uXEWg%^OiZ23o$G z%I!ldoebjE&V|{*hg#jyu`eH2$MbbVP6^88M-0NAiZ;WZ;${!7kl*et(F)$FO4jIo z1|D(2KRs`@!tM}9G^N+M=S<0c<lT>(6?w40RW}r{ z7(B_XRx3P13XQ(q-ic+Jr~XShTYsA?+)#xQF)`j#X!P&! z^wt2`v zltNMZa3&2ecQI;kZ4lmMta{)7Y6Ip6aD_j}@x97|T}9!E4bZ{s_W%sl=y(ewU|l^!b$Opf5-r=x@5 zyCbx!CXdo+e%GibP>Q})Czx?zcbHpj$~oF6;e9;6!?76EJcw?7QO9hqA z?g~OYVKy5DvZmG5NZFt_80G@m>5^wu|BWrhFGXij!+u>x{DY|Y|E?6&a4Xkmtkw;! z`Zj~|-Kc~6!vc%MhNZF_8YaAvp-4Q2o9*G7X^IvOcWoTP*?VQ)e5>jkErL^Y5H8f6 z<;;v7<3zKlk=nkc)Xw)!X|EE#qO=dW{*&0>@8X273c}eg;y&YcIEIvigQUVTg z(xA7Yw`q4a@T@;y>z5&cGPk@Z zc(+Wxi40S2Z;w{ei$D$Vpo~A?Fql2fu--Uvv0(b=I|g-f{XhLS=E(ty$;R02 z%f^y<#2sw=;F}tcM~;c3WrF@mC zKTeHv;1dmmHeRT^J4;f4YqLD#66PK|L+v{RS_a8nboC3-K4BoPe1JRp_*}OhKsw^; zL+EpLE1`GU;hBmEp0JH$WvqROGEKQ0Nf@3SkM;Z}eOBKqzSucpU(0Ts`ofiN`|n-A z5s+l4NoGoAp>&MLNo7mZ;I$eCU%eJAM}g=c-Qrtqd^LVjP%hv#G^iqs(AzZSa_fe# z_PP*E0Zxzp^N!|ZO8V^pp#_eR3CL&^iHB4|#uo9_#rGs`qXV1CVC z>e7&~z#BXXz8@A>zPB1)>)MKV6agTr z1q;#xPPj@Fkv~eJDp+-=s6PkgJJMFEJ$Z&b8v&mgKY-7C{o76|6Vv~8?3zd=B;%lA z+r|XGQo9^ND-7Niu&BoZM^p99u#m#{$K5$wZ`evNiXt)FCIv>Eq*MJAA2&0hGI}F( zz4bx@nCMl*4MJvPmHe*8u1T?(jL?RD15Kp2-l0FNhIXKXv43OE|D$_B9{r##?3h@yb0u@Cj9%s``Y@R#@$D&c zdoaA~_=R=Wspb5q(CZS^BKF?-(&LDVUu3i+gu4@Husi3ejKP)h>=PQqcO#l$#N|pl zu!N;CZC8vYlZBkQrYL(IPI;S7#4ZgI@+7^~b*Pt`ZDWMng1vg#*z#hRC3yBaYtMOH zDQakjc4Qb^GMs1%=B4^Yr_GgO(*0tv{g!(o4tzf!Qz4N(vSM#FBf{{MJz`D$^7>mg z&&Ek>*1+iY;(o^0<-p*2j1aE+8@YBn^_(qnOWF zhmWkdogsOaI12b}BsGQlhNR^JM4de;KIekAN^KDVN>VO7+@!?GMq|^!151T76sjI` z9-|1r>~T2m!_6#MiGD`v?|sfcnj-GLp!XmBF|8I}^<5R~ir+uczj#yMInN3W84DaJ zmmTs`_UH^Cgf^(X4|!%nFI{PlA}nyr)YbxxGp{j>6W|MXcLNWU`-~ADvjt6GPEbQ> zeuiedHTR@=jNUnZIg@}Yy+oQ_&gXsmRv0X>@l%-{Oo`T`pP7oDZVU%XV5B-O3#+o<>lC*H<5*N}ur$YUd)0maK*0WPPi$Djva|S9 zL|i)i@^>>%K#XS~FMrkFlnFAy&9KX$RR|f0rXooIZVS=o$83?SsSpXbIw2n639Z_; z(NM>{UsO=`Xo`y@07kQccG@9x3#ZZvf}}oQCYma%!x{xop8b|FKodN;LVn*8FMF2^ zkh{GRZtrSD{7iv;?xa^jq+y3Kvb$&)3{b5<#X{275%RNMlG`rm$1lr-$CLz z15Rme3;nn|K1aP;-j*m{)$wxHO8p;NnH@=MntzC9FwN-#zmJv9PNEUI*e!7JI+Wn3 zJ@6xD12XMYb8o~I7 zQx5#OTY-)#pMg?ijgV@ZjfB@=!kTKDKLs_>%Q%%&q;sV6?Rmn?>!_NIer)BXV#3Wh zwvFY$p0bQ$qyE~8xM2Oag}Pj5)?x=rR_!0~-INU@8^Qh^0`Ist` zzGnEdPeHzu4Ri}%as<0-L7-RD1xU?3@(L3@Uq9ePcVS-8i3_2Tr2V4mgCq_V?{(1U`Ge(4FBhQ20q8hoYK01*Kel6r- zR6seou!_1mi`OLM<&TXxeP9vK%HsT=M}J=dBZ*DO&%9`kZ6KljRBcI(ap4b1opKQg ztM0SLtOX_pD`(Yp8nXtmyY_gF#{RTnA8U`J3c*4a8KH7(bo(+BG&WnXgVqF>;CWUA zO3zYg87f34TqRMg_7Rz_SN86KvwI)7u7&2Yw`2p@;TSl7`xc|=y|pdkhUkbGipH&)tsMU?ruuZ&JeDZUs!43u7mt{NO z)f{j25%i5x4SD8+%IxS&Cli01b;3Q zXI~x09qTUgyMSWW@f!9PDPvz2|0X{BR2o05W6bA2cv5eC|1?g1!o7^W+r72~V1$db z&=uO=(Pw+9`k`Gs$#Los)xJ0A*a+J+?CD4&i7T~{aG|oAVt0e zOoy9Qn17T>>Yiyrw>i=kUSz!^tX16-K867BSAGLCMgN+j7_-#3AB@w}H*!alrrn!uj&IRw{YNr|JbBuY5FeQt*+tYs0N=S-C%{K7Q*1S!Oy5J&lHMU66T1) zAKIc)4{p97N0f!KBKFx+8yjx>OA~L%^50zp`@CeFG|_EdaQ-%kk}A`S645&>UPj;6 z2LHn0)X>TOc6hsq=yscjyWy$=CY4N?y?#hMb6*SFXgUpIGj63pnsSI39rm+8S(~D( zl!!Yoq2F`l@M+vWp(m&5vz0%(#NKf8SM(e>NgqNdbgFB9gK=S3D9+tv*p%{)zWn2X zAcst+MQ+?mHoCyR-T%*``fnyFznxLoasnfShd7fhj zg>ZRW*P>EGsnImD-VV^s$|>OXB`BCFN+v}fM}<5d&x?~Di#%Tz83BZO=7T-#IE?a4 zwMm@eE!t_4zRnl$bStA@I1Ou|l^D3wgJ7@thtoJhg~MSFl4x`Yk61?S993N(X6RlQ z&wT1K!B%dDyW`xy$+dzG=3{GEna&*r9FYY|A4WM3GK_X0+VjSta`HpRCT5HYTBA{1 z0PiCN1hDWb{x#SthZ_0S9Y=+|g%_HlC!*ubL?$|&_D2^*bCxNgR`yvp!ey{pQ+tng zG(4MxahhaDJhBy9CiJKCRcP2s&B@Q|jw}42lGU2L=jxADespO6AI&FwAnInf1rc~$d-e-yMuw958^3iZqVP{GuQiZIZIO#vr z2$Uo}D>ms0q%OhS`7Z{g6R~d})hzO*cwhq#cZk{kf&WvH62D0GECc1<`|o=3L4Mlq zb5XTd3&9jKmMtBSc}%0c$#a+Zy$EFwft4rbLNbTx+x}f#F7CPPKp(3BV(~NzF{5TV z&|wtCN;!~u72XE2YqANxO}qc@SMo-PvUwxlxxe_e97&eyeQzlvIAa&fGx!%pkDKMo zJHnbgPQwCDt49jDeHPjJvpJCuxgfgx&9ZHl`qk}F3nw#I+Q<+w?P;h}z?JO7a4;9f zBiFEld6GazfCU&55)-~ZAf(Cl-;OT(Zn(RHIcwJP{ywKnHwaRg>TXj>RMzqS)plIh zMlqM0p6c>+<|tlMUNMF4v;K~e%!Zz&LK= zDbTxq){%cBVMIWXz=fB*nUou3DAhgTPA_aY+ozH}G5n&ft%KF+KI07|dyjtcU}5Jj zYr;xBc99#IS@&qg&mlI3m3k9y>JFE+}`l>Rau~;@rm~U-sze7KM>4eET_@}>{|X#$`L(I05f$ENuU2b#9RD~nK!{N5r* zWWS1yR9qf!YbWl8d9fN`O?_bt#|>paTLRAXI`yr#KAdw*>CS#I4Ya9+2O5W{1mjRU zc{wz_>!*y(_$=`0l)_QmX|Ywz zR^r`I$$5$(;DR=W^$ymaZg-Fg)_rZZ5xX#r0=I=|YRI<;e73I?3AvyiLY!4@Rs*?2 z!_6ibgJ5s3{;uZBVk&fC@;ZDt@gKLm&+VdrSyV8%&L_F5B9Qd1DLRfCW`^qRK;|?A z2{Su7UD0&6g<^4%P`l*rpqL0RgYQ&~QyN?)n^o$JQQ_HnhgyqcH!}YFW%MxvtSY<+ zY^_=2g;_)Srh!tgQpiY^B^V;rvq}Y_AYt2oO1@aPpiz;lTmM2nP1Kj!)1O;H&xhXX zuQPvdC*NE&c%jN2n7WK4e#%ekU+EGQg778*OL`;^;Y;@X;P>tJIUFZ7!LUWw*DaEm zvdlnBba1n@3R&TcIjhRJ4c6F|L0s-wB>c?d(T*W=C?-GkFCz!MY1J~C2W`=HoYui)z{zjrppSawYvVATG8be7YQaUp6?--PvTaTC@}LHV`>qFi_#1*YsW zVE=}p)c=KZ>S|4pEZNdOVl^9$U{`hKkly5FvHh&k`>PVs+e(|tt>;(js_+n%&n)B2 ztLrf&h85C^;p*7kVY->9?l-;>HND+!i(s8*dwPkFs6SACq&4p!-F-QIx%G$Rk!Wtn z%uX95?NcWY&z3a_UNTEhZRDpX+|=c6CC7?3lh^;6QnHS*GCXD4ueT-MU%HJ813XcVQ zu>;K-@to(m5#?6~upo#YhO5Zn{m%{_0ceoJZOAjXpY2Pn!Iw;NPIcuHIJ{E#Fy;*v;t&r3z=-%(D`opR@_})7M zFM9rl0nzw@hz+g19vceTydvyv1RBr*qvmktz+k=4SF+ucT$aIWfPlDJ-2daD+km}yuAE(6D_0h$4vt&j#bqI z!lPdGx$s^~l%;KEHykW-DisHj5WP~sg;Hb#VdHrK?-RZmhLUDk+HF`HK=9D~=&zt3 z=rpYTsjz_upXIjdJbNw>$kRhv(rXh|Fu?n->@RdjEvqZQJ%;0T>I6KbSAV^#_Q^3r zY5*uS9B zd4=8=MGmEX3|!5}i&sT=ncQOi7VXaOIsEh|nb*6+RJ8>VRm=Je(Ndlv+1NyGSD1-A z=h#GSyZJHA_K|QB7n%`1;K3U6HHerxBp;6Nh(T+FDh0@_us|D>$i{5?n*&OQhxilc zjNx8=xcn>d?uPC0ZJ0IkFtu$y96qmh*O_CVr*M=bn(;B8|4dy@ znb_Z+C@eDimLmy_;s_^EuE=w66esAhf6xBND}A-cJMBiJkZ~44)4A!C()sczmAEoa ziX9oCb~x!V@WV)mm%^5{v+TX#Y#X}_dL}knE^0`nuwzM+48=T!W{a1F{x!adcmeQ>Dt|{q zndNs7tOFFH2WQIp2}@8+#7Slz8?0QPb-_cpo(||a>^PNW%P$SUDt7uljGAv)nl#=p z0(o*BLNr!hfLq<|&bw-me11*eXtuJe;e!g6;el+EJlP+{M$1}Xw(&2C+!@7UY|S$f z8{J>1x*#(H`_XCk!Op#hs3FC#Qd}Ef%1mw86GC@lhtU;tF2sYt!cdC<;M1i%;;z|z zB-{nOitv!;fE|xFo{;>Gko0$)nvH_w7)Y_kvZw#dhH%`g^Q}W>qh-|UL)5`hl3_qb zc6~&S_yp5c2eJ=V=h_Dw0!c)Zn)!XwWJ?%72cf!C_K-nU=mhqf z#-nCv>>4y0wb!^dq*lk`nC!%5rQ*Pvw|p>0d>8R z*(%;-r=(rcy=H-hZk{SWTfUk3+@9Od3>xHRNc7O}s}7qQBrsuY0eo%Fk#FcLxJA|{ z{FJ?;d-d)pa;`y{X^3P(;UOXmd<}?fm=UOKB6Z};g8Ojx4e45sO(aHn%-O``0NKIx ze2;2te96YoKNwByOq|9(>tkf^6pK}kRDgIGbu}58;O3Ub_Fil*XTra{%7u_^)CAc? z0Dk^%OMHYiT|92X@TR;#>F*|#J^Q(<#0d08u8Z+$$tSiaJ{%xAOD;RE2e)TpB#AhZjlkpHIe3&D+|1muhe}(&vc=$>QcggvZU{$ z6fP~7y$!~IY=h_ehc{`0`me<7e+&RcFb{NvjIXorivu~@)vY?tp7G}MQxpef{Em3P z+h5J-99{BuktNt$#3sx(Rm5R|TD65=rgl1K*u5O)l#*t7h@Ixm9x_zv1FPQE@7r64 z88cTkPVBjj3XE!dEtsN%x0#E29KeRY6O}2+(4T$J4U19NIXW{q#;l751@Sb0Y4kSh z{1tO3O1ihkl6x3?x=U^!0_hT|JmIJN>{2`S!SRx0Y}~%*_D%GA44kY!K5YPd^B8iR4)$;~auA*|d6RneXDr@4gGZAsI=c2TWG|_za62jqx0+u=RLVDgfZKjU2elxA5Gfi3pM-&A!NaP z6f!i#pGqfxr>^WnNz@&03w(-|=b~D?b(`cb?4Ud00eRU2LSklBDLNu)nB-z3E$%x;@W}I2y}$CmGH!*&p*G9+7!IZi?j!U zqh}b4u))*9$ENbAEtnVj_7Z+?D!$`NdZ%A+;^z8-U@K^A&j0u1y4YO{1dpnAW(=s> z(mk3{T*W;O4(@^|1fc0c_)4OPzS`nkssOo~p`e+AZ1LXxXz#LkM78JC86QJktBjHF zv-VeA?|bfd=V81AgXdYl3{5S{m*pgkb;CmQ=$E>{cQDccc5t3WMQZ=(4y#t==~Pj3 zNY8!_EZ?2fdm{(*Y;Hfw1pKfjc}rj4Jf=qzo~N-vQ-bK#(DXzm5>xb7yJh2@)$hs# z6$06yMz?bbkk6t1GUkB#N-{cRfEY^WZ@uL+$RQdSh{Ro1 zcmhO-vYQHA2YGUjaV1UB;158mBp1{a%uW401IjwVlM1YEBcfdJ0Ym5r3dFx1Zy0Zs zK7G?TX}^45;el=?41~3Rg5_5FF;BaF5Nho$AhNH z3IIA!k@ZQr8?eWAPW-~=turQ{4%6#tmc$(jF zuiGO>wLVw9q+EYCMWLM&q!?|5DBAl%pv*VDvZs- zVIDvjY^6ui9q1xirB1lLX}V`2yHxHeKHKY$xJ~#%PWqcLcEZp~6Sy7+D5q48>u8i- z_bO*CI0GPPM?Pgv)k^ea5DyUrXo^KTPuL#NceiN5Z+zz6_s-H7i-y0TU)=EQQB1)P zM)~zr=fszj!ccyKtyJ?JBx&@pB8T~Ne6IZb<$xmsAXu%lhvJ6xoe&0`*FQ<}v8*?)LM`R8Q_r_Q|X zF~Y9`b-F50E;uEAd+$U1J#ycR;FJ6n255+W!mo;M)@5E2Vc6u}A>5n5FKR1v!IhS1 zl_3nAASx@aWM^Wfr3B!2VtL}Og%IElhSPD>A*p(;{U@qn_6Xao_t2x+2pdjKAW$Z` zWG;{A*|p!Epx(m#@KW*XWOn&)jafY)J>n3aS9rp8P|M(c$((?s>XP?SpLmiTCVM&Q zby&rUBKQ;>I9ax+I14TBokS#zYAC6lxJS@0Z!V6FfNn|NIZ&upEgC?M`!8;#C z!F5yVh{*=v=?XNP<+<6>n^dxKz>!@vI1Vls_dQ9uJeb3M_<7)?QJ-aBo&*Ldcpo#! z>qnGBz^tQ zX>+t5gUHcM^mj#yM>MlZUGZ9;0SU9_>{T=j^|3X1+p^G8wR`o20%!Gd@QZwf@ipum z9d?Ksmq;m7#x%Ndx(1SpMgY!adkg+6rb&seCfEqbFyamJ9L<%iAga(p$WoXN=m~L- zhbBS~A2ldlxtTs{1S0ewLCBGR9UaVmVgzM;hG}ISaR`G;iTK5aUG9i@M(K5Lxt@uu z5djr_pEJm|omM;ITRwThpx&Eh=rrg(+=?|1znqa46%X7u|DFzm5mfoSCR}^r(VbUa zMH+YkJ>yTGa^4ERAl>hHG?qV!%W21vR2OQANA~?+*-OV7p5WAtp=oTP)k(nzv_l(F z@P1KG-bgNNqpaY!4xT2$F`U}7?c2N28KD`>EpZYs5J@ zr1owAdR;;f)k|9F_=Y?T!PQ=*P!JLm@aBXaHW6(@H!JwG(z&0R!PNTEKbbS{qxz`HOL;|Nb{mbc3fAqRSeVG>q12jnBDx=1!m zqo{c;_zDzL-y2m%2UVuIaL*T8yHI_?GCci_gQCc58u9i#+4FXOLZp0LPp zaDeweplcL)C*`4rb(&m_Nuvjn$a*phKg9bw(!uD^m$g6TUQ9`wzy`h7I~leyyV}H? zMD_Qp^2!YlW_GwYuhOqIvV}%f30hVJ*IK8s$GA7?l!$W*<(hG!t?` zYzwX~R?F%w_!`JUKyKKQe=UW8D4ks7E^i%`h^)L8Fk&G12&VzKRiMqlrW6h^a;d}Zx^fLO9km7 zHW~u|Y4+hdF$5@#^w!%LqjRk{V#jXp2$oVatRrztmR4Za);=`-MC8fawFTtL% zspW#WOd|){`{MMupoESZBb;;tn`{&?RDJ~m&gvub;-IWu$#wWqa_7Yb1h8|svcu*emm z#CqAECmd0`OD`BgI6#Y*1|yy|r|wMo=j63uMjP?Ymgo&vA9xI}uP0mDvvz>DnQlk7 zEcj*grUF?tYy}0o!!aiJwV`;2uA+=y`tw4mbB<{63;myGhMuPLn8jZbo$qLKTj&#d zr&2{Z-M1j&sZV&@#%JQ$XxuG$74Lsq&=Ab3e z@=P&JEdrwU(@g2v;=x@_J%%@7^ufEnvHSPhHN^ePMNzTCi$Tx7AmZ+CCKo2fXPo)s z#AYMON>t9@YJws6`G&(Bly+I!7_$b^dB6US9RMK6vk^W12L|3T2@frZIzeDND zzS=TU*dxwm#&@T{o(v|-(3(c2j5JNPl?1TnDq!0Q$6>oGzFDyPEUX7gTGjR5v}cajg~~E!)`@Fh*Q7WEO_*!mDVfhgq*eO94ztAZ=q}1dH4PH zyf}mA+ti`x#>nIz|=galTeN>@J<^9Eo{?0?MYJh*U3AzK3|zc z7Kx)By)RWWRsaO*Oq{qOp?cw!&#B}`e^@9vqbp2zJI`Cc<(uNGh};keh7|G_pK>UFC5?Ga&RYEnjhHiw zjMgsGCx2;KmJ5y?VoS#aEVPPDW#ihFz1HLT?~^52$XG877QNlCCyE9rn_wfKz-& zCTfMY)7yPO2|WTZfN$mUhYJPYDxe*Iv6&zGU3`@33Dc=ByAY>JwgIBP_M0G`UW7jV zLt{kEk0F}Z&Rd*$lKs^%ie9MUhv`3F)x11G=V^DT|FHc>erjxfBesABQt;mtj zA#$}hZt~sGz6O~;vXEyso}(f6#0^UNP($*UH+O9q`~KwH+N1BPo4e1^TfTclfELG7 zG*`DpH?;3)9c_ZQ6+*7WFjo?3#$D^AGyR{|IZ5_qm`f*6(kYC|1{I`2HY$!Y=HU2{zhszm zv^Gba!u))!TMwgxyDFYrIYs1lLS4TvEml z14HdisBpx&lfyu%Mje8tUIUpjfd0Th8zXVWT`!tC6d!oI1-CW!v_cL-%(#ieEvPiKAGZ|C^&MyGtG>o?yH*0A6SaAwD^mB|+WxA? z5qX+`n$O;W&!e=4kvKf79I_D47f9N~d(y9)QXnNFcCjQ=$SeeKjs@fn0XVsZx$5?Z z1u9O{DCXkC0P2@WJ!b;2xTozV1Z6_quF`>(^AN;J{n#g)!-WQw@<$)mr;~Hubu~64 zbXb$Dyw=?}i!|JhUaHJ!9o2o|3tg#5VL=lFy0sUng30X{D(HPL>5bYXBn^`LOQj{i zr{*c+cW6hmS19^@77Ju|n;{Y}+2D;L;RBWPI~I+Rv#DYIAE(knZFu*cHhB(nA){1) zP!QjY+w~Ie9KW;U_t#ohYS6ON>> zF5PM3dTKnIm}Kf;$91UrLIi@r?jQ9NU5KQd#RXO;9Pv7aaHJ#rg~2(@PF{!$g$WNX z_)xS6U`#3v4d?vhp4jb+iM7v_QBiRmR0K&~G0En##pN4{-zT(vbFZJj!Z1<{GZ9Z| zn1)e1tDubS;QxKq7XJM*L{YFOF$wfj3qdq+`PygFnCg)~)de;?;#Xb=N|$))3ZHd} z1LUV2P(YQj5S2CMDfy0mCpT0$N7SUu^Gv7@t^>&@hsP`z@bN}P?wJhW>o$$OVcws4U(?J6Gw7;{dZ#L+-Zc(QDad=0-` zJlD=|Jb9OifAe-eIa1ycZ$}Csu2mkaHQ~fGMF;D8F(LqcwV@x%#j4+JT3^khOQ3l#ryGb3-9c zVy2U@gR%g%%p}uFTR7P1{Pk8VI6@U<P_He=M{VF#(E`qBqk~@k1yvBWv+~XjFy;C zzLN-avrm}P5ejt?PwFVzRVz3pSOITKQ%cTwhJ)Uuld2N}7OGPR!@km_@lbU~v3r8F zR@y-M_dNBC#^{SAg}imEG>dBTc9HK@(PbHQn<@>?peXSSyu1Ve$NlpZNuCq-79!00 zKfb6nGq5`b@cBK{2p7oo8Os@qTvsn5nlZrAkVPckRiLuK?Es|YtQracC_?9;sv`KE z?D_7T23P9$KZwJ~2>K=6bnXo_)10zx=qzq3_7Hsuir=pu*)S2@jGw;#B5JJZw0gVl z$6pnKyBJYUnvX`e?EyRn^-KFX8)QtyT3|=#eo&E1-rj91nzh0J7c({d2}7u~~@zorGKLzUp}p#Ep6Gr;ZhfY>YHL7f+K(8G%m68tl#;0=0`nA$NqVs_4*HGUi+7! z`TyM&FMj03(Xnl7iZ*ucp3IV<{C)rWOD%4ox_!nxH}ui60Jd6bO;LU{c_ow}yb{i& z^S_EhgJAK6RJSJ!e9 zV$A{&nR;Y{0_V*}{G zmR3>MFnn(G(P0+6L9iXn8h{w#X+%_`!zj~S8YI1W-^hWJil^=e*bCd|>3IWfVIob{ z&}kx-2agALMoW}2#F%EeAHuQCAGbK*T|xPe2T2Q1betXbPMn~7 zx4#$e>Ad0O^|fLPJ}%9EXgefd`BEs<~krq0|KJIT##$Hj349RX=AYfv9tA7Ct@Ud zn9AG&>pRw6SDfOTH%;OR=ga1hP~6JsP)%{*z%CdS^e&btrwlBmANs9o^+MgL60%zD zgdmcjzs>MtU&=YMy}x-YdD@|bmdi_icvv@j^p0qhohAd&el7D(eQjZ*EJe4fCT|NL z2BXs?3l%oYPckobgOHyXHN>{+7I=KWNTtl>tV%mCT~;*hxC?bZF2onQK7Xk-CS7wF z>ihOziI@&O7i>{?%~paG+ihZuJJp0stc~}2dj1DPrsC3rQLG1X#6@=b2ZC4byc3G% zO%`>p&I}s-*#r(p@!!Sqbho=lbudfr;3YjV&@paYzyJP^l3mLA@rHM~_1gD~>W!nB zNRzB>a5mCrqqrzmh|YOAbWl6Pp+Sqp^Jh8oO`8m#_I(E7CPjThUEXL16IIJ@aHA;K zbhHb)9bs(cz$>`0{%AiNS3eTd-Oc5KEGu1IrE?H{OkZ%YCwL^MY#cG`n_CSz zsyn)r`J-E~RmNYy?0Y1*Zq=W!d^3u_QgdOBXf%qX1?MncUw>xn(cw0RaNV7!{0QBf zl?K1Iyp#0V6!2%6Ipmk|gZr9uMf>Wk&e1qAE#ZRkUX@{HhC$u@UDq5)s+alnz8X@z z^f1B`!|NVQisa?bbEt# zIYd>{>Lpm#pcr|^`A2mBhr^v!*E5uPonP8OBlO_#VKHJ<1+~SQs<21D;pjZ>`pg9U z4?b>WwdjWSc|N(cH9WUdrFRl^dXv@g$erjX+BKs)4TI_Z+5lbv|`olWqB2Xb^S zP!$Houb`Cts~W{vYY-t0(<=gw&`AS6_z%c;oDpy`p3tx<`PL}y61ixZ@<5|}T>qrW zqO_H29N)$i({~`hjhqUxmP785rf42b-_*WoquJny+tVZ))>p8p$628cB(ix z8$JAzh3b3VR!Fjo&+oPQenX$6bW?`%7h|(~An`bfI`jbNd z#v$n4{%l~&7NVGtEF)?x9b|ZBLcCCNQ!_m9~ zbP2Z&q^_e#qpliazZ05p#NP) zIWF}|m_{ao&6C5<7ix$6sacCl&+*+e&nPplfWms=5qg#*6XzhB%0eps_5rvr_LEu5 zWW#X&%6rNT2wgbg+$1|tH76BxEPkVrCsTMvS=%I=ZJl~HNbr3#>9wCUwn$Y1N>jN$ ze87?k-XI@x2|H(j=(a4cG_M8>!jL#t6P=y6%WwzSkm9x>*U00#sh!a;nRWUF1NTzO z^OjgSn7XDieWePqdg4`PvX6xx87~ZhD8uqigL^?Fk|E?nr67O0I`O=SKC42=CIxSEvx>2+S}V6Q}zQ` zQTPPRHl9pJ%8Xf;u5-VB7`FrjhRL+DAn(oKfnCkQaa zsTKOLGJ00$g3K78mo0q?8QSnzYOU!dw(cASbbI;xLG8&gCcjN1*g4IWHL8b97VIsZ z95!$Q^-fqm*mmW)-ln>XD;lR9;=|x1Xv+Z!?6OsoLHw*>G6&EG{vZHBVPxJNYm$B( z0+SyL?681ZDN2LSPbBxWo$j*JR<|j80yR;9r)2!u+K20o;*xCryc$up*~(Vt5O}+N=2SaiTRL99_yb+j>j>Cl>*hE1M4~|? z2NKDBdWrA=8i^z!KclubkF!mLStN=){VTIuKx-=k{aZxBM4q}Axs>jKZjCl3v?km! z@c8?ib1c3mKlWxTmoXDUYJ4vOTISa=^JKx5ag{~h;*;pbQ`J8Dt>NP*6q4R0y_E+9PerWOxFxO(pc=@{kKiL;xTKj2c-0E_vyRD=V zy>=_YNVIX{bsH$mx?7`j9wmukp*DuKTU%(F# z`WqyBK7(`*!@e*tPkb&_rCu!Crz%NLdJhee^ZJL21B@Zn$e2q2Df8hI2;RC|oMJ=%%Es+mx`tuAU+%eyECoC{w#E#67$PYlrBn%w9`fz1X zt!#FlJ+e0iqew9S0H8Px#vYb$dWbsLlUKP;Q~8OWSnDT?iuEKe3CG;HwrHn4_nad? z&JqN5M6EFVTRp^Y5}HBgt%x-yt908h-*d)dufy`+-F0J38;v<5>R4$nEA&KX31SMd z0xs~BK(yfeLdH3GDSf;s=h)UuojJ!A!qaWFl@!9{u8_F!8He>U9(0it6E4YDjvWMY z*GyCAWpn5z?7N!$kPJiXPko&-=7f4|O#T*+0)6Zgy$VBTtwNMf*24g2wCF5I18E{Bf5hVW0lhLpH{ zFf8+$le2)W4THNt+v)CDB8M{Eu%-qfkt}Eu@Mz&`F5&ob6MM@F<8#|J?7hm*i|Flv zbDja+;@ryHYoTRS9lJFd*4CA=*fdzu>`XpZuC<5h+`YjzD1JH0;g9Z5tfIO z=Z64SPQ)Mh0rdd>>*tM(4{T`6|=t)eM1)BGs?rod3Cw0mq z!-Vy3)%jwMg!nDRCA~V!HiK4+>Q|S_sa0x*j$Blk1AvVrgj&Tz{RNa#kym~urZb^c z8rGKFt?fVhd(&RiB)yoAWbH6jUPi}gK$9qe`Op=>pN>Yau=V@UoiVywZ}XfWGzNG? z$}kBx&2a+tP3tZyL=pVM#r;J%fYpc16ESiE`iX7uBt;S=Qp0@~@s#Oli*H8JRlEMY z%eeOl%>uq*$=&Tj&{)nWUYlbL|6@KX8Pu!Xy9m9f!~Entw3Tdivq819)w}Q07jwWh zg~}6mpLA*9vG7kA|?b;(L!`McUyx#vc+47_}q1rn!eOX#MVmNU}X&0TVFQx))I(H=2I z4Qv+!E8E<69b8J*e*)#(=e$Jbo<{9VhjP{t9-?F`nZ2mL1OddnX+N2*h^l&ZI8qj7D*1eYu|JtYZ&P!Sw|v@3B z8#>M|qYIl#5cAKOr;fTo2yHIedyktLtIM^QF}qKkIQ%2_zc6e5 zJD+Ye{_SNHcHORIN#VzQCV=@h4IGKT-g_GdTa$P0?%l6G_Je`J)=UufVlV{KuF#!< zRKWc-U}3b*UdTYD1Q&G}v3~?ponC+1rB ztM1YjgqY?V4|aZkK3VDkXWE%2Z0P*><$8;kBYWv#)62yMJ5>Hzae_*Izv!Omp+U3*KS)IzB z`IW*UmKn>xWxfTp$O>*}J^g+yW6JG?GoLT6xbFdxb1E)E*e3w;gumKjBICdh;I<^7z8%CT1${i(P z)RsWofwq2^yc)}D&-9e7?FtV#18`7bylUOGu6yF3z*}JU+nwA8k4O6YnKxMJOKi?_ zTNwb1Qlt$9olP4{1f*GGLnz~anN;9XB|jruV0ATjoyeib8Fd+np~ z@NNh4yc?b-1G1#z;xFQ3=F8D&<<`!#kLk)|RtkOKK~i##1{G%ncQCo=HpsJl{5N@& zOmb%P8C~=2h#*SRtK;la*e_IzYd`+#^x-~Ur@Bi=jja^F_XoUln;SdX0<@dTo0^_W z!&T*fYR|Iv=;>pqNsj}fZ4dt{B1F@k9Ky^n#p~6Ivu7ajeP~UdD6vHI--1k3JqvP2 zzq_g(p}7Kgyy)B*T{4@j==|D28KikXssd_TjYYF>+XOlDeyh-#si8W7>y+3&>&R*XUtT5 zauyE7`Gy$raOo1!ilNXmiC#M=0rdSZGY^tg5^Ej7YeCtCh zG7#v$I)mXL$eGuQtV6(%Fw7n&I6{B?~73V9%OBN{sb`YRVP9FfumJjFrs z?FI;RO7+0pommrA_B4bIX;Ys$E`PtKSQ<3#hvs8LCQOIry<296R63uokJqyypRfM1 zX`;J!gK|RyCAI5t4rHCU2Dx|=$}0z}Qu(AL_R+M@kG&lD^wWzgYI66@7)Qd22MTbe zY)jtk05Hh{+c1LcPkCX-ONXwsS1zGA89bEL&D%uW3P`f*^YDwOmvVmcA!+`>f#n_C zRm%q&%elU?FzV<@G-5w4bCMP2hi=lOXRZ@(+A!L@_>h<_*&0eK_R67&iXcn$5%IiM9~35MR`bTXK!k3&*K=Le&;ja47rtd8?ZU+%G4{7?$Ojab z#JW$SLbsAvNt9>l2cDx6H)R-wY~xzLge(#4w89Tfg=$;mg>kVUYXr+$w%nca701jt z5f}Sv_rp5pKki!e#s=W-M0@3BbV5JcmYqzcRr{`$8e3NOklldyc~RBX*s?!S>N!o< z)N|`S|3ZG>*IoQ58idqH33~6EwQ;=GsIn`lC;a~&>wDWHQQ*B_N!YTD-}>aKa5#o| zF1j`vy=xih1C%`$p?KkXHzaEf;Gq(CZCB)cV?0QKHtj^PWmX#KqAxDmZ-&STlGml8 zWaBBik|B=PT^<3MWH@u`P-psX2+p(RA556>3JZ!2cd3$!vCp4h}BE!L9WtjJ_8Pv)hWxx_yLtp(`yAwth-G zx_~^MaGqISr=Cxg-lIQ9+Uf@FfVeJyl}1h=5qdI#B&j1@ENP3Ya?;k3z2QMWUxGaF zY4FjhzSLhZk#>=|qG8-~r}rapAV8FB1a`$ky92-4S27415EzVD;N3Kv^)J^at#gva z&%nv$T|djj% zM7H<2*|}A=emFn$uK^IG<2avfK&KF9q9s3r4qd~m0841SJot9s|7&_9T&$i$-=MVB zV#+*xAouy&Bp&kruSwh{jq0J{#4QGeoV@KFtY*#cgA4V!ACYzj=$M(28Mhp`3t{|* zpCSG?Tz-lqYn82+Y!Lh$LK#q;CAM|fD9<%Wdn*snM??fFFJTKMy4eRk9{Mn| zPV-zd0Zf%(@ijiDev${;aIu~PF(XG)h}&+NR^!bqU&=hGD9wKI{kg)DPp!CEzLab} z+gT}p{eW54{&pI%nDM&aQoUv*8;_BR(7Kg8mcH~ewOm#G_24A22<#W4fy%A=ZR!Hz zc#|riB{_!mGdgjvU)OY)0{JzA*d2FEq~na$<*LKw?Ohq~G#q5c)?9$;TFS$w7YZ}% zEgf^AZ^=UsEGg*W>yfg((>PV5ZDBgqNRDcXKe--FLLBNyN>OW>lO;c{wcXtvi*e1$ zL9k|wTj5_uD;C)TVJZx$7o$3!?|Pj#10KXQd^f~@V(>PFL42Z3bMJ{!FkLfTa)v{ zrnbIb!vXGGXguQzmpEldGB~j!gBYRrf9tq-Jsshsxcol%r*x}i5m<-)&x&&%U@%oR z=#5@(7J8j17NJ+F(7l?VM`sj!#M>xYB_NV76dg}>VayRl09$oMHG2`hPY?&T7NypV2veE! zH@y0QB>}Xs%C^LF0_6&_!MuIoUy~%d!Wn5zjYl4s1yHE7%s{OS8VM0V^i#2Zaawon z3oG1%yVAbIEQ~yf+|$rUX+SKAE|^`IV6Pkk{sHF%=gI7EOO;8y$7Lwx_Nt3ruVY_6 zQoT-p22)zAxH^{j^SfG~wOGhD{CO_@Z#m+S3+enPy2{RUx3P*v9^btJ z5AdKVerNweETIlH9gTd7O16g!k!b2-Rolm#mq#+dh7*wya-Y0Zx~hc$C+F2F)gZ4pCNE^vL!4^{5}XfR@1-NJ{3+Pew+kmXZ0_r zlcMM(z0{SM+xCoU+e4D{vjynHO4a7^~OJ?aXN=9u_!o&)LEIp1f~{s~?|R6>1N}v<>Y1W0sIY zUCCKU0z92jO)^_QC>w3LgLm4y$BmOnv=P&HAjhlR@m%-M&BifX$#HP7{n1L>tmlfg zS&QJBpfcCdNrR9z7wU!_rX#4UbHryKgGcGtrGSH2#Z}hZynK`?ZMgRG0z!+sAx)(b z7EcU{;8!YAGMwF;j*#<?^CL_>w*+ZL3FOSOFx#Bezu+svftsE#HFX{`LSPs6w zIaxlsi6mceF`NS>anV%igSRR^lDt*n)NCB~66N+WOi>6tZUvwLY2=W_%o%;JhfV)E zvZYWBciy8rk1`vF6QL2ux;GiY`zGHh-)kdV=;bsRue$RWJZ6x>pOv zSQ~WzOEN##sXflYKt@6E7>u_u7mHw5QMcvDQM184!%)(M?izplQL|5_hx?O@A(Oau z?~PFMN4F8&l26v?Fi0wX-+@vi+}jilz{ z_OJV)+`$?YLqGlQ7kBeRL?p}}K!WHC=dd0B@XJBe%>jv=P#+31$SWMGCFdUe^(6POoHTo8unjpcHeoU@8E)ie=+!m##J}7QhHFU&l zggZb)TA^Pa1KOuoicCNL6YpXgeyPC3mrk|N<$bq8{cyRXEwu)GiT_CKv(`?5YY}wo z&F6o^D08P9L$cN@%ycWY$HAZx&L%9y#mbNSsd?7tUihC4=v%P1M;bZKjUR2BrQh_b zLAh}%{-q*|39r`+hg6q^=Wd7 z`tI8m=P>lZPs^&mY#u#(eaw<__UZHK{x5C^+&+D7|IMO$ms?BDmF&&d&AauxJ* znqWViANF`$7Brhx__vJI6;tnL zY|!hv&L=mnaj=(FvKjk_z4UiPoAzl{bE)DXsJ55;3gp5J#w@eZ%AWKVd%Ai92AX#h z8Z&c9)s8#K_I|!N(v=xCDjvDgQf99!de3M2lPU}9?~#r9eBEh#TLI~D#OR<);*j<1 zN=h0+xocPQ*sm#5!|@(AIm93=-QlrKK(FhcLnZ)qOvgHuAIwzc3SSXF%ZoHjuW6D{ zH|$jcMvx}AnW|hQ`O?G&>Q6k8PVlW%nG-F?RG20Jy{aiLQW)Fx6}i=>wHie}{V|+9 z7;Cbk6LI}}&s2^o!gQMNSJOCBS9xDiz}$ON?1QAHvs}NLdwYq1#L>>p2whgMOdh<*G$uP9~PrrucS9qH$;*stn}SV5={JH5kPaO$pVMi+-3Yl@xM zw&tp;(Rlf-cq#Myi)Oycp_fjh&)q5>iOiTiT*GNGkb|$PA{jfnfE(>isA`K(Gh_a4 z(HuAr+sr~x3`&je%0~lr9J;SzF30vRmHSNYs4HqyO;d05#>C1kYf@ir1yml{C1!K4 z=p&K4vbHtnwV4Eb#np<*RR=rpwS6nbE_K^a9ttBjkE4e2uU)a$8azpNWqmM;fM4I% zFE?cpeo_D@LmeSk9YnjYp&|BY3FjnFW~Z~KlDUuPqIlk|KXV-(bULe@*0iQui8|JV zqNVbFAFmdVUi{sMW{3jxPmIJ3A+W@nMp+)I8G_Q-iEj|1v&gqmr@1bMQD+4V-;(qQ zC7&(eCODCu75K`Yh9t%f+BP3uR5kj$#kUFlV@CZ&il48lI>im;GJ_Er#HF-Nh3vg> z6pjx}&qjSFYsJ5Zj_t*au=hggn!oSd&xC0yVI!xQ_If^@UU`y@I^5p5ma1KI_O5ih zBt*pgVXS`l$LgDgYi-(8X@niNladZV<2%g_<1oLvt_;G?;K;0~m45E1En-&JDke%N z6ju_b=r!6XZ+7js(u8etuAKZL22Kc%UOWForWS??Bb&$R8h)q@QN~TWhAU0p?5CHi zqx2eGY~4q_VykL0+SDKMt1z$K+?5V1M@|UJMl0}eZcyxQRE1}eRYg@d#$nfbWcgF> zv0f0 zO_DCg;#zlHeemkh3h#cK=f@hw&FS*pa9g_8bX|+h=!p6=)J(vb4x~NcYLo4kptX*Y ziYX8MI?p15nJAns$10p;Z8N>GLtev7Ue;()+xPvUXai4)(LlCGiLimol^JWt*R*KQ zZDW_sV9%n8HwD6de5NC;N_)%M4ny=9uIZi&tpX5RL#-F{tB<83ng}2AO6^xS?sf- zthFML{G^8cJz9G{JL#u%2(x^CDWwre*4m(oD6Xs~WHwg9y`}75H-Ho?ywL*n)Nf`8 z;)v#S2b>*ap8Iu`HB6=2rB-2%qw0|4BVsfE;1#&kdm~gldJ)T)9tk{p)F71bZSsUM%py&{- zF24TUeeBrZ^O*AGJ@xN1 z^m7SPKFm;*qk5+E{jAWP&oh{6q!#2KI_ES&{44Y{)x8!TZxi2>9wC3%s1Fje*`k?5 zUdvo|Y+dPg_J-?za+W)G;6(K}!QsIl(LD3;r#~dOMUQkDFLBo%!9Ax&|eB_w+vn=~+NDf!I%SjYUeiHcEWvwGU_mjC-1XMhhh}T`d zhLTO%g{$7SwLVyJt2(vL%Q(gzbX=Hwe$!bD_&M94sq&%N*XC~3{I^A=k?N-vvZsDUd9vZ3 zg{hI=Y~5$M4Y94fidpW%`taKA45^k`kxZ90(GhFHX-DIq*NTGX2jXlJ5%OzKR9s?A zeJ(!zc60KorVfr?Ku>B^)+V1rpj*+8IW%IR*M6jpq^hej_z+ftm7Uw4#Bo2} zCJX%`pztkG>Q5)x410IjDh@?M&CXbjjKIH$`|DEdD;5gkdLIGB%p>H_vZtQPCk@D+ z!5=Lu-}PV zTXQ0uUGGM+_bdn?8?tY0mh?ONVsZvwtOFv|hSfLO)7QqNS4>u_K?RljPzh_u^R(N}dBZuG|LeTc7)VkFL^IdwC!l{qR+hq;|@ zohld0HzpMl`_e&*{pG($%P%IHWRqUeKX-_*h$K#VxLWE)jT0oE;lgQ@IEf$)SB#&E z+a+G&Z-5lA(_J?H5NT7ZaFeUJEy!j&E_olRm?)++=Fq#^DG)(rvtF9pZemVwb+rivbnInRcUmh=)mZ)46Xk*9p$G#jK*M>S zp|2?+4%OYV)W#YvqXS_)(SDRq$Dpbbw3FLseSQw2jzy7Dt$GNW!1|fpnu-;qYxWE@ zT*j`4;VX^1g3^ewrlMwN=Cz6NSkaPuT0FDMYaCnm4MN%Xr^2EjjmZaT-YF>q#~4k9;l9fUc;SG1oL z93suaB;QZym;KL9)(bGS+b9Rku^1^xERTAvg#)IlFh>F9O}^G1q@KB9>%GWo%o}q@ z=c{i=Us>x|F$vf07~r|va%jPjYmwi3&+B1&2W3O3{MZ*Loi}|yHvhM{1-G4R7HwG2 zBAjfgtR(mXith>JZi+p+6LG1#xI`;`ppy=q1>1D?x`la&UC5)_h%98SO|}MZg&ooj zAr76phUgFYp1^@=XiqPC)g_e3oWgWNI+9%I1DiiD`P-0-Q~h-djOK z+$62dDxAXfvr$jOme)-y9PFq;_L3Wp|Fc6iom?Hym_^=O@o;ufuA7KbZ}*^rIPLP+ zDcOWgR;KDpzz%uKkDxze_Nj>a>g#oc^tUI+VcA?+-;#aR*lRP}PcdlpJls~(Z9LmK@S8hO?atxf{AK4u z$u9z}CmF0<0^B2A19HI5K?j5ci7ok9Id8)*4~i>$+q>FHYHTn3R-cek#O4sw**^BD zW81jnHh(r;HTeBvol_>`SzkC*L)s_&R-(Pk2br@XwBOF0$Y-WFGX1%1%wcAxz|RoN zl?DC9+liD|mQh+rEI}n~l!xqhe@n`DxXj+K-Amvu+fzu~*NO`(#lzRDxVYb9T>CZi zsV1_39#hU#|5A9MidbFojif_&RK|V7lU7WbVMw;dWjU&FHl9a&;-ynXh<=_^PDu;p zj+g_PKfl*#+Vh{FHK<__(`WuxN*$w1k6y|?uYop6gqHkhI>Ua_3qQ9PZP3M@C93h@ zw}geM=AbzD!v_sjtp59#niSvECtOt}W5<7q9a6q)Jc)gpHZN!P9P{XnFtto^yCpZA zb*ux(?q6!2D+KCO%qn0tpW3Fniab$Xy%-6*h>qv@N~a%J_J%mv>l$a^u8%4)+vpHB*SzKkRNA5BZiy{u%S7X@Tmr2T!kZ;^!j4!%|&yNUYp{j!E6nXbio9Is7SaF_du(#!Ksas zf4dQu_-GV||8aoL*c4AEsHre!DXBST&6vrJ+&<4wL@>A>%(5c9!uL> zwHn0}aW#t8Cc`eb=0Civr_mA9s+HoL&FzjF4Lx<0VOrVlFa9_vC0LRd@OhNp*BXfz zwA9v1=R0FFFR)jk`G)TkPB39X5hW)9%F?WM0IRKL< zxS_mK>=yUB8LAL2uFFk9x6q#PWd%H0FpoTe`xy^#eMrQ54c|DYHFjZ8D0L

4%Up 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%0DRaD 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�#Jx`MX$ zp!ASiRb8s$UQvrluF+Tj8q+5qUpBFriL(Om$D8;+FS-Y&I@mu-aDL6x*CDS*&ARUo#iBNoDIdL<#auimwGeWyJQy z_P`rj5bXE2y<-*=0pt!=7JTs~1K5?oV+hx@0gTp{d-kuN2OxrgCG7Z0U smoothScrollToBottom()); + + findViewById(R.id.bt_select_image).setOnClickListener(view -> selectImage()); + send = findViewById(R.id.bt_send); + send.setOnClickListener(view -> handleSendClick()); + imagePreview = findViewById(R.id.image_preview); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == 1 && resultCode == RESULT_OK && data != null) { + imageUri = data.getData(); + selectedImagePath = getPathFromUri(imageUri); + imagePreview.setImageURI(imageUri); + imagePreview.setVisibility(View.VISIBLE); + } + } + + private String getPathFromUri(Uri uri) { + String[] projection = {MediaStore.Images.Media.DATA}; + Cursor cursor = getContentResolver().query(uri, projection, null, null, null); + if (cursor != null) { + int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); + cursor.moveToFirst(); + String path = cursor.getString(column_index); + cursor.close(); + return path; + } + return null; + } + + private void selectImage() { + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.setType("image/*"); + startActivityForResult(Intent.createChooser(intent, "Select Picture"), 1); + } + + private void smoothScrollToBottom() { + mRecyclerView.post(() -> { + int position = mAdapter.getItemCount() - 1; + mRecyclerView.scrollToPosition(position); + // 通过延迟来确保最后一个 Item 被完全展示 + mRecyclerView.post(() -> mRecyclerView.scrollToPosition(position)); + }); + } + + private void handleSendClick() { + if (imagePreview.getVisibility() == View.VISIBLE) { + imagePreview.setVisibility(View.GONE); + } else { + imageUri = null; + } + String inputString = text.getText().toString().trim(); + if (!inputString.isEmpty() || selectedImagePath != null) { + String combinedInput = inputString; + if (selectedImagePath != null) { + combinedInput = String.format("%s%s", selectedImagePath, combinedInput); + } + addUserMessage(inputString, imageUri); + text.setText(""); + selectedImagePath = null; + + if (inputString.equals("/reset")) { + mChat.Reset(); + } else { + addBotResponsePlaceholder(); + String finalCombinedInput = combinedInput; + executor.execute(() -> handleBotResponse(finalCombinedInput)); + } + } + } + + private void addUserMessage(String message, Uri image) { + ChatData userData = new ChatData(mDateFormat.format(new Date()), "2", message); + userData.setImageUri(image); + mAdapter.addItem(userData); + smoothScrollToBottom(); + } + + private void addBotResponsePlaceholder() { + mAdapter.addItem(new ChatData(mDateFormat.format(new Date()), "1", "")); + smoothScrollToBottom(); + } + + private void handleBotResponse(String input) { + mChat.Submit(input); + String lastResponse = ""; + while (!lastResponse.contains("")) { + try { + Thread.sleep(50); + String response = new String(mChat.Response()); + if (!response.equals(lastResponse)) { + lastResponse = response; + runOnUiThread(() -> updateBotResponse(response.replaceFirst("", ""))); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + mChat.Done(); + } + + private void updateBotResponse(String responseText) { + mAdapter.updateRecentItem(new ChatData(mDateFormat.format(new Date()), "1", responseText)); + } + + public List initData() { + List data = new ArrayList<>(); + data.add(new ChatData(new SimpleDateFormat("yyyy-MM-dd").format(new Date()), "0", "")); + data.add(new ChatData(mDateFormat.format(new Date()), "1", "你好,我是mnn-llm,欢迎向我提问。")); + return data; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_userphoto, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + Toast.makeText(getBaseContext(), "清空记忆", Toast.LENGTH_SHORT).show(); + mChat.Reset(); + return true; + } + + @Override + protected void onDestroy() { + super.onDestroy(); + executor.shutdownNow(); + } + + private static class ChatData { + private String time, type, text; + private Uri imageUri; + + public ChatData(String time, String type, String text) { + this.time = time; + this.type = type; + this.text = text; + } + + public String getTime() { return time; } + public String getType() { return type; } + public String getText() { return text; } + public Uri getImageUri() { return imageUri; } + public void setImageUri(Uri image) { imageUri = image; } + } + + private static class ConversationRecyclerView extends RecyclerView.Adapter { + private final List items; + private final Context mContext; + + private static final int DATE = 0, YOU = 1, ME = 2; + + public ConversationRecyclerView(Context context, List items) { + this.mContext = context; + this.items = items; + } + + @Override + public int getItemCount() { return items.size(); } + + @Override + public int getItemViewType(int position) { + switch (items.get(position).getType()) { + case "0": return DATE; + case "1": return YOU; + case "2": return ME; + default: return -1; + } + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + LayoutInflater inflater = LayoutInflater.from(parent.getContext()); + View view; + switch (viewType) { + case DATE: view = inflater.inflate(R.layout.layout_holder_date, parent, false); return new ViewHolder(view, true); + case YOU: view = inflater.inflate(R.layout.layout_holder_you, parent, false); return new ViewHolder(view, false); + case ME: default: view = inflater.inflate(R.layout.layout_holder_me, parent, false); return new ViewHolder(view, false); + } + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + ViewHolder viewHolder = (ViewHolder) holder; + ChatData chatData = items.get(position); + viewHolder.bind(chatData); + if (viewHolder.imageView == null) { + return; + } + if (chatData.getImageUri() != null) { + viewHolder.imageView.setVisibility(View.VISIBLE); + viewHolder.imageView.setImageURI(chatData.getImageUri()); + } else { + viewHolder.imageView.setVisibility(View.GONE); + } + } + + public void addItem(ChatData item) { + items.add(item); + notifyItemInserted(items.size() - 1); + } + + public void updateRecentItem(ChatData item) { + items.set(items.size() - 1, item); + notifyItemChanged(items.size() - 1); + } + + private static class ViewHolder extends RecyclerView.ViewHolder { + public ImageView imageView; + private TextView time, chatText; + + ViewHolder(View view, boolean isDate) { + super(view); + if (isDate) { + time = view.findViewById(R.id.tv_date); + } else { + time = view.findViewById(R.id.tv_time); + chatText = view.findViewById(R.id.tv_chat_text); + imageView = view.findViewById(R.id.tv_chat_image); + } + } + + void bind(ChatData data) { + if (chatText != null) { + chatText.setText(data.getText()); + } + if (time != null) { + time.setText(data.getTime()); + } + } + } + } +} \ No newline at end of file diff --git a/transformers/llm/engine/android/app/src/main/java/com/mnn/llm/MainActivity.java b/transformers/llm/engine/android/app/src/main/java/com/mnn/llm/MainActivity.java new file mode 100644 index 000000000..7afafdcce --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/java/com/mnn/llm/MainActivity.java @@ -0,0 +1,115 @@ +package com.mnn.llm; + +import androidx.appcompat.app.AppCompatActivity; + +import android.annotation.SuppressLint; +import android.content.Intent; +import android.graphics.Color; +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.Spinner; +import android.widget.TextView; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + +public class MainActivity extends AppCompatActivity { + private Chat mChat; + private Intent mIntent; + private Button mLoadButton; + private TextView mModelInfo; + private Spinner mSpinnerModels; + private final String mSearchPath = "/data/local/tmp/mnn-llm/"; + private String mModelName = "qwen-1.8b-int4"; + private String mModelDir = mSearchPath + mModelName; + + @SuppressLint("HandlerLeak") + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + mIntent = new Intent(this, Conversation.class); + mModelInfo = findViewById(R.id.model_info); + mLoadButton = findViewById(R.id.load_button); + mSpinnerModels = findViewById(R.id.spinner_models); + + mModelDir = this.getCacheDir() + "/" + mModelName; + populateFoldersSpinner(); + mSpinnerModels.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + if (position > 0) { + mModelName = (String) parent.getItemAtPosition(position); + mModelInfo.setText(String.format("选择模型:%s", mModelName)); + mModelInfo.setVisibility(View.VISIBLE); + mModelDir = mSearchPath + mModelName + "/config.json"; + } + } + @Override + public void onNothingSelected(AdapterView parent) {} + }); + } + + public void loadModel(View view) { + onCheckModels(); + mLoadButton.setClickable(false); + mLoadButton.setBackgroundColor(Color.parseColor("#2454e4")); + mLoadButton.setText("模型加载中 ..."); + + new Thread(() -> { + mChat = new Chat(); + mChat.Init(mModelDir); + runOnUiThread(() -> { + mIntent.putExtra("chat", mChat); + startActivity(mIntent); + }); + }).start(); + } + + private void onCheckModels() { + boolean modelReady = checkModelsReady(); + if (!modelReady) { + try { + mModelDir = Common.copyAssetResource2File(this, mModelName); + modelReady = checkModelsReady(); + } catch (IOException | InterruptedException e) { + throw new RuntimeException(e); + } + } + if (!modelReady) { + mModelInfo.setVisibility(View.VISIBLE); + mModelInfo.setText(String.format("%s模型文件就绪,模型加载中", mModelName)); + mLoadButton.setText("加载模型"); + } + } + + private boolean checkModelsReady() { + File dir = new File(mModelDir); + return dir.exists(); + } + + private ArrayList getFoldersList(String path) { + File directory = new File(path); + File[] files = directory.listFiles(); + ArrayList foldersList = new ArrayList<>(); + if (files != null) { + for (File file : files) { + if (file.isDirectory()) { + foldersList.add(file.getName()); + } + } + } + return foldersList; + } + + private void populateFoldersSpinner() { + ArrayList folders = getFoldersList("/data/local/tmp/mnn-llm"); + folders.add(0, getString(R.string.spinner_prompt)); + ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, folders); + mSpinnerModels.setAdapter(adapter); + } +} \ No newline at end of file diff --git a/transformers/llm/engine/android/app/src/main/jni/llm_mnn_jni.cpp b/transformers/llm/engine/android/app/src/main/jni/llm_mnn_jni.cpp new file mode 100644 index 000000000..adc68340e --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/jni/llm_mnn_jni.cpp @@ -0,0 +1,72 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "llm.hpp" + +static std::unique_ptr llm(nullptr); +static std::stringstream response_buffer; + +extern "C" { + +JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { + __android_log_print(ANDROID_LOG_DEBUG, "MNN_DEBUG", "JNI_OnLoad"); + return JNI_VERSION_1_4; +} + +JNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved) { + __android_log_print(ANDROID_LOG_DEBUG, "MNN_DEBUG", "JNI_OnUnload"); +} + +JNIEXPORT jboolean JNICALL Java_com_mnn_llm_Chat_Init(JNIEnv* env, jobject thiz, jstring modelDir) { + const char* model_dir = env->GetStringUTFChars(modelDir, 0); + if (!llm.get()) { + llm.reset(Llm::createLLM(model_dir)); + llm->load(); + } + return JNI_TRUE; +} + +JNIEXPORT jboolean JNICALL Java_com_mnn_llm_Chat_Ready(JNIEnv* env, jobject thiz) { + if (llm.get()) { + return JNI_TRUE; + } + return JNI_FALSE; +} + +JNIEXPORT jstring JNICALL Java_com_mnn_llm_Chat_Submit(JNIEnv* env, jobject thiz, jstring inputStr) { + if (!llm.get()) { + return env->NewStringUTF("Failed, Chat is not ready!"); + } + const char* input_str = env->GetStringUTFChars(inputStr, 0); + auto chat = [&](std::string str) { + llm->response(str, &response_buffer, ""); + }; + std::thread chat_thread(chat, input_str); + chat_thread.detach(); + jstring result = env->NewStringUTF("Submit success!"); + return result; +} + +JNIEXPORT jbyteArray JNICALL Java_com_mnn_llm_Chat_Response(JNIEnv* env, jobject thiz) { + auto len = response_buffer.str().size(); + jbyteArray res = env->NewByteArray(len); + env->SetByteArrayRegion(res, 0, len, (const jbyte*)response_buffer.str().c_str()); + return res; +} + +JNIEXPORT void JNICALL Java_com_mnn_llm_Chat_Done(JNIEnv* env, jobject thiz) { + response_buffer.str(""); +} + +JNIEXPORT void JNICALL Java_com_mnn_llm_Chat_Reset(JNIEnv* env, jobject thiz) { + llm->reset(); +} + +} // extern "C" \ No newline at end of file diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-hdpi/ic_action_add.png b/transformers/llm/engine/android/app/src/main/res/drawable-hdpi/ic_action_add.png new file mode 100755 index 0000000000000000000000000000000000000000..b84e18459ae9ca2a087bae6ebe7da25089cb0391 GIT binary patch literal 260 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbBPJ6mIhD5Z!y=Iu@=!Eixr z*McP>)t7e&n+q8{5DHpa#JqA7W4A!i(lXYvuy+TPINbV<%AZ)D&QCA@@ zc&|*laG0lij%AhU+|Xvmdw4(5D^W!MYAA8&=QDQ ziwJ@RQkhg3)q6h&uXy~1+TM9*{^0xZKj++gYqcg6MzDr?^flw3|H7QdFFRGowM@)q ze79FKIF^OE5|V-06iC60;7`Cj&BR>AkAQiGqgj|y{4J0Mp5s6kW~?A~>ro1%V8%n6 z8hD5!S(xh~l?I-mGYfOW{(6uCDVPcT49QI6PzI!}l1v?s(b05F0o|^&>3$ZZ9k)W8 z>X=M9XA0(KNac4~?e?Z)3g}*?O;cHrjxsY_0dqGqnL&ICn9t}+!35MPYzEX^DyX0? zm2`INWwxn?A$$v{*RtL@0d)dj1L}P$sGx=`gFc70Y}7@p2h>6xc?v-h4}M0Yl-yE0Q7tuRyPupCfta55V;h?UU3cj(PV^;EWR3q9GWvsenK zw>XoH8o-Cpz9lVi_x0L;A>T;_71U|GC|lS6zwfsJ`)KXh>V~d500000NkvXXu0mjf DP>Rh! literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-hdpi/ic_action_chats.png b/transformers/llm/engine/android/app/src/main/res/drawable-hdpi/ic_action_chats.png new file mode 100755 index 0000000000000000000000000000000000000000..a14910b93f5ffa4f3242aa175487b200f322523e GIT binary patch literal 537 zcmV+!0_OdRP)>l0$qXrHPFRfj7k;0m@FLv)YD3br(}StxD%8vF#~f;tWYE13ur2( zxR6dCcr*y~pecEQ*kntk69A(9Lt_J@6)z z!z7T5PqndqLEFi{M}^WtPTxTXN`VQ89|c|kYXCQAgCsoh10>&L4aWbKh*h=(&^FkrQgH}00000NkvXXu0mjfW-#G4 literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-hdpi/ic_action_contacts.png b/transformers/llm/engine/android/app/src/main/res/drawable-hdpi/ic_action_contacts.png new file mode 100755 index 0000000000000000000000000000000000000000..e393cf3449c38167c1b04aa8e858be3ae4b74e44 GIT binary patch literal 339 zcmV-Z0j&OsP)96@TX$ZZbvzey*wWsnrw(Oo1bC2c8!C z0mMKEv{Z&PW-kYwfeouh`IU^&O zZy*_8$|Q7DgE6o(h4~TG70^gEH~`v?K^*~&P5!P~5YPaEw>C0U|AH2Zd&Rv-P#~9l zx<410E0E2qK;-}dGkM6R`&=Yw2<+Z^TNub@RiJW!yj#@XUG_Gs0+j>g-3AR0x3GR~ z@@-Zw5YPvjK7nE&bPUqIN=LxOF=&n^Y)Imml?xEimglBAj*%}VfmKBQuu2zLg}@D6 lV3k58k={dbf3h0sy#OZUR}qH3^#K3?002ovPDHLkV1gcHjCKG3 literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-hdpi/ic_action_edit_icon.png b/transformers/llm/engine/android/app/src/main/res/drawable-hdpi/ic_action_edit_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..082b782afad468f0ec8c923c3232ec30923a1d20 GIT binary patch literal 513 zcmV+c0{;DpP)6y%6ae7HXzAdh^#?fEMZ_xTAV{T9YP%H_6hU0?G%pEl?u$bX+~wrm_rBbF?s>easWAjUoFb+dE=#3(NV}4wa z8qURNB&Z!+90%q_tjHo(@GC)mtQzw?9^Az3$S(&FK39o(9S?2be&nZd21|ij>P$F> zD;dUoV78KN*+`&U_=^P`PXEDGqmOSmrC1qQkLT5~9herDyO(s-pr1I4Cp|DT*u-vN zZuQ#Z6tsvF2OLMWPZRB$+33Ou%vxE|rJ(Z%Ea1ALW?G5@t|yo#7W&;}Bp^ir@5a6E zCBJPa+fD`I^3|=MMcMUi335T+P^ly64BEN%G z+=!L>k_BXN)9YX^NA6wZvVk^}d1Xy+HMu??2q$}B`Zm4Xp!K-^Wfz8$rk5M^HtJ(G zM(4K>Lje zXabsmCZHif-|;om__H5S6)_NW8c!=6kM;ZN_}}6m9KWW_a;*Tw00000NkvXXu0mjf DNi^nn literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-hdpi/ic_action_logout.png b/transformers/llm/engine/android/app/src/main/res/drawable-hdpi/ic_action_logout.png new file mode 100755 index 0000000000000000000000000000000000000000..3376b203dffe6e2e024a4c6acbf2a41d53bbd8b6 GIT binary patch literal 390 zcmV;10eSw3P)xUKHqb?iZBZHb5JoRR=-`C+OA=gf=emf;)8T2HL?8W4t5z(=01k zvi&g1acDF%QdJ~1_V64)leqsqr>d$l4DgtX)Sxz?7;8JXd_(M_Sqo4GDv2adq4qwZ ziU6S*{?aR`e4-C=h-Ois4$g7AfKoe{#PuG%qCjcb%iPc<=oba*;wolYL{FJ9(~3Jr zYmpr4nU?arIyCj6EXCePZ zm#zXR@+J%OhW@M$%iMkpqMZNtrLO>}gX@S&GBYw&0LA;eI79Eh9oB1;zX4i1pyw#h kGIXwlPtvyUZ@Q7gZ>pq3dkHWB7IO9` zP~*r(s=Y$&&4Iq#@2d)L6-+7{;a(~EDS&g}LX}lGoiqWucET>DwWVx)1y%xG z09)X!4NPAS<7z2^XW(~3nHRt)vNO`XrMutT*hTj5fRiRbmrfVIf$ypy4`3(O7P|i; zrd+8tMwhY`+jwzW%YgHmo(O%#9?V7iK!$HcdjZ^wfo?I@Sw9DU$?itMoXM6|~@NFQW8Z#r?BNWJ1J`3q9v4<=*d$BP&5P3qV!c>%( zT7{V2w2HN|G1l{@v+W-(5h}^_Q)=^~1I(?0Xqshv*-C+Vi;baDW)+(&z&{N2MSbRs zzRGbd+Div!FMTXT`AuXaC2Fz)^FURF2BzMRs2X2NJ$+MmPoFTi49tok{zR)MhgKjZ zuxbb>i@>yx7zxh?=QA*Kdo#C}d9aaWxs%?VVZ=3>-@_pl>cEcX2u* z8|HLNeRNz=m3uckdSDnabmsPAK<_(jxbHLqbmI1|BR~fS>_|YYNnW|V|08ABRO6#N zWrQZUcB0O4N6`jR-$v0VV#iJcC9sZscu^OG%50ovjbLI*CCbc!+7RZ}och7dsx&V9 z0oB+r8xQy)?QSwdnWBG}U$L-qpqd(^fjMu<#6ZF4&PIw&2*PAHV}%^HicO#va+)jJ zo&GZ!pS3+N8$H78%Uv)_An`)84&7P*NtfwjdxUy%S67VI{TP| zT;e~8Yzzh1Z0y8vDkl6{+dBF99hfL}sf_#(`YF{bkiB`dy>;ABZyyh0eoQz`E(Q2i z40acRa(_msfOju?(vO|=_C(`@YP95pMj12M6S%L0QPe%{Kk`$m?6kL_KCAqz^l?7P zQ12hl(%o8X@2>x+7V$TL1|0qz^LP|60(9tu)sAS&9|P2(PkO_{R+@kR0+|HAUXE5z Qn*aa+07*qoM6N<$f-y2nD8v>cdR36S8w=_6j*ehM7zZ2H*fw zLpdfHMgv#@_lEMv1bPDsLw#HVCVtX+qB1a>`i zP;Y48QnwfALgw^Y`x$U1fU73|r83~UdP6%P6;*J#Jf|ZlR}hu=2~3;%D3Ib52v2MO z)?U4nwF~LBRV*a9zrt9%!DqTIGO%3q52`m=im1`5>< z43zJQp8=8bSE@c411MGjI@sg)TM{dOt?C~vkOi_p7RUlwpnm`qr~qI2RY1MoQ^9dV z{n%0JNrb@rt^^MpWzI{V04v4qYB2O4Tvps|4>%&%X%JIqC9OaLwE%7}q-8z-8_C95`G9d_h5!Hn07*qoM6N<$f?P+a^Z)<= literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-mdpi/ic_action_add.png b/transformers/llm/engine/android/app/src/main/res/drawable-mdpi/ic_action_add.png new file mode 100755 index 0000000000000000000000000000000000000000..12c3ee862a6f1a6c4a72512dba4b1b489bbd8f8e GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gj*`6+rAs(G?FD~S5P7q*yaDRdT z%gQA>hZr=(UPy%=HS}EG!fMCEd1AG~${o{f%Jt{(2x@Zdet%JI7dQJ{<9-$)j|c1w zwrvi}xeeIN&o>>d{V8%Lg88oA;S+zmzW=rNP-tZN$GzgCRg`PFb-@#Z;ErwIW&*8c N@O1TaS?83{1OSpXI|2Xz literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-mdpi/ic_action_back.png b/transformers/llm/engine/android/app/src/main/res/drawable-mdpi/ic_action_back.png new file mode 100755 index 0000000000000000000000000000000000000000..87ecc4d62a2a3813b1ffd976a1fb1265529fba49 GIT binary patch literal 346 zcmV-g0j2(lP)sinHHZ?VPFphH^H_EC9pTZeFu$K*=!$rW4(3=UL#ua{Wg8oeSC@%4Z zQ*>s+XX4M_Vk{k5;ASiZ{1XQ#r@%unjywF}5Zzhe7L4FIw&frN9Pl<&aE~f>(UU2t z;5t@uJA3A1c)~Z<(Uk@d!B%X`6DCsOA!xxqUL%9qA|&Mqwia0|6d@^LGxq-x!|9R` z?L-gWFofo8L3c>1QMyI6W=s08fnVHUK2;EsPOL^hUNBjNq&>>_9+?y}uAaC)YIwkM s5y6+R7Qx?QFjWwe4y?rEKTz+Re~!|kiz|9wN&o-=07*qoM6N<$g6J)jtN;K2 literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-mdpi/ic_action_chats.png b/transformers/llm/engine/android/app/src/main/res/drawable-mdpi/ic_action_chats.png new file mode 100755 index 0000000000000000000000000000000000000000..18371ccdcafa03d7465566454a6cc86190b90156 GIT binary patch literal 321 zcmV-H0lxl;P)wG_~yVoq#@@_rZ6!^0eHX=*a0a} z)XY?8L%=h32)+gK2HTpN2}aJ5-6RAd1BinTazd|FrR)CK<|`T!C!dj|N{ zV)`uHl0;%o3^3EecPQwJIY0Nm0KVRWx1g~g)*^5y@WqUchEoA-9150VjttNOGJOag zzyqAjg#T;q;D`UlWRfVv?Gdg?? zh#!2Xa~FB)Dhmg+SmXZ6Sm6`93-5$|PJS23AF2V0dmWk!e}iK-YCQEmYdm0yHXDl+ zS3`yXj`40Myp#ZJqfk36CkKqxd;oaEd&It%X#&7&itXfpv6>H{_!AW`@>tCWP`p+A zN3$#5u4_D&95{a?b2AZOEsxAF4^fN8Z9~7oNAG`fURzqXtu3vzw)_IHjMe4Nt6s$L9rOT z4EMQpbMNJP?z1T0`fTTX-ks0+oD&2I4mz=pRkS4OT`*7K0q@vL41#W)VHfEL@P?59 zA?jl)L@%_7r4fFbO*<{!ANm_ z89ZSO%~fhRGB3o^iSrWkBETaCtGv*G3b9;a0%2@`d|R>=Vwu5kxlL68l(wZfmU&!a zAr=7rKg6u6o>ZzzwNlmq7l)eyA=fkZP}X<$&;6<{;gCqAEZg3tR#+N(NvU%_-W2 zUxr>PU{mmv3{nAo%o4N>uM4KhBT5NOVk{Yk`9u}ZbRNcMjPH|W7OkE$KVtBxs0^SP u8+>}W#bp7}-$L(M!FQkQuLAt$ui^$H?2|w3kz5G?0000Nkls`bN91I&O&N0b5gBC8zk1Xu$r z?dHhYC%`a9{>Rm}0_MP*vuzwU14>|{cP~oL)*GPkR_X+}5a7w#OcnhIJ`6C`y4x1Ow)p03*Ro9ltSRrMr9{UboB?CKTzPc_ zO`ZWa%Cr*JH@R?4UT%4SC+F}P`O`6Pk!h?icFJqXzmov}0s@60g vlYtY(WWV=e0op$LH@_92?QhG;A^!gXo$KI51F^FA00000NkvXXu0mjfO11}d literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-mdpi/ic_action_trash.png b/transformers/llm/engine/android/app/src/main/res/drawable-mdpi/ic_action_trash.png new file mode 100755 index 0000000000000000000000000000000000000000..65d2d9d80e93a2b4bed7aa38eea0909191e804bf GIT binary patch literal 272 zcmV+r0q_2aP)m)S(RS!IiYz*^>&TX$eB0u%!U~d{a(Uo#*=-YnIog=?Z@zfJku8VY#8Q~sIq-Y@cHY}sZH z*aQAC;2w_!V1t(;zl#nG223$4{1GOFpWwLgf9x#!DZm)_K`&qobpn$2OMVQcT=xx} Wg&WR}JvNj80000fG;iN2;mFVW1MD!oa{_D9B5HgMoqjZwLp2f&>Et8yv7__umY`QbJh* z2Bsz+?bQSk21Xo4L0aOwC+t~=SF)Lw-yso>PV_y-G+Tl;EfqR2n1dGu&8(V$R#RdP z2q59J;D{Ef-|)-`yPw@%d2ZeqDrvJk7$=Q~LI&^C27-MLuvBv$NJ2uU!xn#)*QefN z*f*F-k3ZbJz4@~nn#r2WTF9nEU9_jOUvzYxzc>0^`mh^Hy9%C~Z@{0DYd>_iA}<~U zDw6xYHbzr;zOLCO)pA~-#dqzuqQ$lBXQVi>7GJO-DI>Q$<`0FbVIm986JLL`Uoi68 zR{xvY!GJL-^t8AQGOe0B#u74!U0UELjS*@xoql?zDXH=t$LGq^C)(-(VK^Y?p@@P? zm>;We4jHB<0f+6cyb4R$enkH?wXXYM(aSrtdLIK^wyc?Jt!4Td)dqjhpwVEpk03O3 zJ^yMD+P1H1^*fSR%)zikw}icG=E{3HK+VeY&FDB2YcBxtsJiDb0P+6aKUlv3{Um~H8(RB?nfCgojkh{oWcEg~P40}?mX1Jh#!cawg zz+=yl*xB-#qtRfVcb{DmYq94~*fyz;>3bB&;_!Dpdhq7mR9WWk(9zH^yq-1{vy=1Z zXS(LBqc&PG5uE8fL}qsB)$@OjqYBf!9RUYoXiZRqO%L`w7v9F5sqIgZA)Bwbu33c(Q6XtrL`wZ-v=wRsQ8(%^oL+9jbq8C zkA-itS#R)I4PmlYVR6(kG7>$y4qk(Xr8E-b8-n~}UMK(lcJH0aaVv=->_D&YaSw@E z7e|VT;hhM}vsH~OkZ7CI@BCx`Mz$zaX9w~ zJL7gs_cx~GAVJDTx%6o6;S+X_cLpb2Izl7OC5qyI3F}aK5{LQ=r0^bo(7lpvk$LoH zPPPag2;XcbE)-~n%?=R(F*a2aPWXo~gHomVi{a~^bBmSEVQvjMua)~vEz|0mzlSAf z-E@+vcaiN6Xn{@`gnzcj8{HaXWqASqgXt}P%2_R058khxnqDz|)7tPy$SjL+ z5Y(n@>3Cl#!xnLt2#N4HZD0wLhEO*SLm%Dm;OLyRv9AO4JL3V{nZfUS!$Lx? zwpVh}aDpJ5s@TG)_jaWdgq^}zYE30#p1{@|X7HfgD6xt-{MKoh zg$r_jt|}G{uZ?2go=q8A55*bLT^OP^A}SDE1c$o*L;nTxWR=?`g+^xz8W=oa>7b<{ ziOySmF5Q?3B0LRV#lVn_PVMX+&4Au(Z3KW?ec~6s6Xhil8<>Bs#uVzE(bD^w4UpCt z(%y5?0_|n;P+L)Jd=`SF*o|Q;Nm@I$T4@yd2<>wiB67^|N&Svo!Bg#Bf44->Dq)bx&0dD9Fstw?tEh zU{D!IhBV}=mRTY0gDH^DmNJ4ZBr|z5#xa&sMhdPG#ruBFB5qBz!7xfJfS&rzUF^#$ zx-x(15A_$ARL}x!mH%wI#Fr~aes<2DxNbE}qC;1P9nM)~jj&FF(PdmZ#kYM_g$BEt zt5Ie2JwtsUHjjr@uiEo-Q`7gkgHS7Ca=!u+*A+sQP0|t$yMDfh#@Oult@Hcp9FI;0 zdegd#@xDB2TNnW$lsNZ<{ZUsUN+!c1+POJ#0#A}p>wZKFQ&u~)FCjJR^tP)Sa{iJQ zxBl*h2aVDRJC%{{vRjGqyleS{ii=@Py=@inoAu|%`G>_C8@zvNzBX_tp!Z1J_z|gc zFOX*=&Q9J@(U57#)B1$PP=Ao8E0U*KkdHLsCSuO-f47nI&Tu?}rM2ZBk7) z2TNN4QTkm&wH5GYnYD4HxNZ&b5GC3Z^H*`E@L%e?5nsxwvEtCX)9CT6hz+X~W+0)q z(2*sdj*1NyK~{`JK)Jc+ctB4B61LZ~SzjE6s$fneioSIHm90af{N*qn}KwTNOI}n?<-{q%653f?iA(@^0SvkR$>(>E{V}8 zXSsxl(QGI4`jmuYXf>@csM`+N#-0szpKqn+Xu`+#tJ5wIWwedyV~HlbYAGDWQ6(-) zqi~&eGooTx-}Biq@zlzJAXqnf8rMA})Vcm*KL+P6w@R(~0=MS6|Ag2jo7GaFXD; z9FyC7)e52iuG;;cb|m;M!?yfX6c!EWw+If5co8gMB{n}zK*aS?o0c1n6g>y8RTtFk zhG-ZF4;Z;U>|tbY2aaO@Lo>v4Ra|FK)|aj!DE-K2vX|QFuQfx;`+`OmoMiC$3$Tqu z3_=0k7y-{CMOEd2mSE_>nodjDH~{;N=`~pX zQxyOF1`pcVs~tkeuB#(%j9}yWIy@I7W1y3FRDv_XmKT9{*V!a{HSQsFGaAyP0)f&< zNBvQHAR2#;Mq0;B#G=a!R=Attd=#&tz$U^jnZ%uP$eTM7NfG%u+3XhHxMmXmchs;* za(>-@2ww2z%Y*AlD5?XX&-F#&y}17_4ZVLZb!e*!s5cta5f`zT>JV`03s17>)njy z+JEU&A~8LWG5VGuot&h>0?5_kMB9Fw$IKyw0~IEDQ^sD>VOA6g+wiq=8YZRxY?>8m zr`!cgI$xhiE;ipFuZ(El9It#P70tE@D)D(ckMy}JNuAaBe}VdJk-ttBaXMif-Mjm3 z%`~w_Wu(1$Ut!=Vl!-Phg?|s?p~k#oJRvoF`!O|k^zQHv@O7+nG0=-B;G8gb>n-}h zF{lS@YoyE3RZ8q>1} zDW0xV&{R5%OYa&y;1_De*P1Tsm4_$AI=o4|4~CtDtZsJ?9IyqoLt72(VBEdOz0fh_ ztXQfnXH*%s8KK32aZ_Nc4yqHkl_-$T86*wf7q4oro0L$L$x_y^15~H|o0J{%)x|(`?1RqYy>x{k; z_4Twu7<>?mLn5^e(|8zeD$UyQavB%h; zEGYuJmq(Moyq)JETq?q{gddEB0Z3KysyJR*Gg<82HvTKWvA*f_&~(=MG)uhfXQ|A$ z=^_ajA@>mdSwsC-by@R^OW^#_Aa`NJQ^mdoknhcyWqWt|oFcVoC;Y70a`d;a<+N#2 z%n=#e1ml!uji2$E$Q+8n0>X$zp;2sAl|_P1M#=6#lTa%VmEeDLKc^pb&Pve$mIg}Z zI*KLNDPqvm8m`bsTs`-r;}-_R`VO)!#lLxRW%o4eU1js=3;14x!tNpY|!lUwdHAjs%NS)gj zM6+Ijvy7u#Ph<3)#OmIy#`lRzKD;dTcS7ZkT>?l5en_6*)z5|pZu8vkL$39DSq_n* z{Q#X47M@T#NB*!9`-YTcuyAuS!2%Uq1{En0z>8}VGBxK}*|Hn8i%Pgml>>A#Zw z=+e8V^QWvlhKKRKkTtNW#Xoo7d33zgDf`*>DR&y|=^^r+nISVh`$vu}k`3(Eo zAR$W~y6Fix@$!mdu8kPGiG1X5**H`*#p0HaRZc~opS=Dg+r*&nmeI+Bsyc(#JUN6P z;}97Zd(TgU@Kgk#{2flEiJ2&KasD#7FmihM_9@}-OL(4q5>3;FLJvA5ipg|EnjTp@ zC4I?&oSU5@3mmUUVFR5rhJ7*rGNF&1;P^G|L^|U{44h_#MD~TD82+Qr=Z~DJNfgwR z6KY1}xXyn<9UG1jj%J$JoH83|#pLb)xhrueIdEpMgK`#Xrdo`$x7GvHX``Yys{$)R z?e!+3UaI{%#?7s3xv@hrJ|A~i8`}G}9^FK>Ut3LI2OS<{%zZODT;1mP`}$Igm%C~h z-dBU!*SdK0mmL0&))lF~2z0}GE%k;-VToK--EP1NvH3$IT^>>}2(vs-OW1|)Q@7jV zI-YiI$z0BUTIrhn7Jls?@b*4aJ>8+6tZSKty!TY!q$J(HzHil=vJ|x);rA)4in*+* z-X=(J+Wq?8EnD!YgSg-mn-b zp4#c;a&f&T#~L4#%z0I>-*CJa)*GYN?zWT3jS8SgV_If&Q4wR0^w-BQMh>eu{Ln0pFG51R|A0M^3{`Yb!|p~qwX--|x`!GzUdjXFD3tQ%FdZv5YA-?AioH z?CmQnH${3wu&1n=;}Pg|C&=`^myj_gMzL=-k%5NuWa5^RZVsReitS^w<-A?qL8s5uj>*4rSTX?b?R2yWc7VA>4BAq&1bbLh)>r({ zJx`=28~4X^jGrVPo}To)0ggfcv11^;n~-5XEB?qrI?`K~9Nzjx0+V}4LV7c9MnwDw z;X%ue1%HCTK?c)G^CdNrCLG%hlPNKLZF=^%<)}b#kMW#Pr_g8!*HkAL4F%4gPH5%q z>J&>gqUNZnuOMt84H~2eR4fg7!&ysBROG?wvTNBJ$*x*{>*q2FiLs`(=_`nLiskwu z_+rlxbA!Q`{c$emE_&5AW!H;MxE24K>Syt>JdI);U76d^W^}>i<2;^H!}{l}th|g8 z9WPZH(GiQtu}-BFSXHsQQ{A9w^@+s6rPXO^@&OXk+rr`aM%f;j!VQx-sxCj{BA(;Z zDR?|TqMi9vmcCHQoCJVw%2xbsup1_z(tGKqxP`T3Q!)Oa79dT9T?XQn?+c{M2I6tU& z8nF>XmPaU)sa<#p^@;K|)t1?e!*&!1Y4sB?=_Y^W@N*T7eMl}HHf2m?lR8J?ln|UD z$l;xw*^Owy-bvWDR@BWIE+d6BOlWz3Gt6<|q>8nZYvQOR^P*N3!&+T%B&89;d`@|! z2V5QlWs$J&D(p+ia0io^{DhEpBimj30D@T@8lJ}g>Cu^^%Ld94slwMZlPChDMjA1K zD}u^xH1f%>n6C-sJAKCHQfDs(9wAP$g8h>?HCY;MS+*irStz zD^x6{eVDy|h5??4PY=ln_`=c>krAfZ@Ahfb>PVUf{5Y98qV`amrfl%I^5u$|=_yV1 z8M-0OBR3FBY!_y;=-}sYdLp5W4VE;#T?S_gyr&kB?hU1438pyY(<}-<6(==DjY(l+ zHk=Y?5Y?)wY?CLLgyD^^(?x^0&`Fz;Bl*_y>!Tz}8ZZl^oFhlcm^Cd0ezNn$I^ao* z)qgwY%c=%ko9_ty{$6BcVw1X}v}hgeB%Q2I5B_GD%L*CoS~QjHsQ43jQ_KG-l*9^p%_+={jYiDo-RGW4b1 z05v*%UIBb{krSmhXhVoD(ek6touq`{yv1vxF(2s_Y&Db6LVqYLo7~5#<}QkYEO9h z9n*X5yZ{njgS~9T9il75kJ2iZxd&wQF0o7W(nnr5(Xl-l^|<32c@~Y-EV!zz`!h^Y zkx8a6x;TEh*ro2zV?;GDsF=9Qv&KS^J#&;KunPB?tG7Xa*;YZicRXQx1R~T=@8JAS zvFHn;*+*9iP23jd^+)p zO?2yyH{_qHE!f~kX)Ut$q-_ff4Bj8wLlDIoJOn@T0*V8h#Ip04DnzxW`NrBWD*h#0 z*07|*f@Om(4-cDxi6S2?te-QmH^NmkW=SZRp>(SRJ8u%bT5}W!VouBiit>&jm)MJsSv{Yd znhC=nF|OK$U+oI_5l$S>8PA&5jhlR(H*atc4XpfU_~PR6ULvyGb!Z@7zKUJnr#OC< zlLgUJaYmPw&G?(@{O;h`llCzg)&G*TYs1Bp#?RflK1MhmCRO54f!59Kyn~LsG^mJW znee3RtdfA&`1^}B3stWmmj@X?zs5wQdAx?W%~v@?w|hDhAedU-E%R0dsL_vP+ztU+ zGBBdGj>0@3-Uw3HcbzzDm`RP;#VC^yBS&t&3TVzW*{+g*0Ezs?@(ZoF7N=1Q9~YLT zsG6fkkNGZRcoYZuH}JiLq<$5uTn@y!|&HM@?Sf}@bc_0s{9eNta=TY&HgEM5s18HZrI6LJ0R+7JqNnAogUaZ6@=|JEh3E8P-gjZ>ipvWaOC~7Z;fxk|tHg1Khp~)gb znF}w7Y{ilx9&m*!(atGvhftzRf%!>tE#;?&m`$dKOID`F}#s zOyy<{Jk1Y*WZchcr0Lx%-GI3=ie{3Fn%ZGl98so=9y;+opeYT8#_jw=mX`9-PaB9+ z7LH1ko4EUkz%&{70Q{MX{fr`s_(-a)&|S`7cc_y&XP_<(oRumR;H1Hp4QkzRQbI6pigRRLb9_y z$O+rNzq?bnGTv!!mwffpjlF)At$sC8>ahdv<{Qs182*Z{8$jHmndOHp|E-sPDfnZ~ zKWM#eN{Z@Mfe1v!w9JFi+i$+w#O>gB7t#~s>$oD9XJ2}MuBoBd?i^&?6=95m89U_juQ0B%4CWb?>0oBIPbNcT8#8(`1j4(H(9u zKgp)RfE$g*(R21Bwe9Yd{Qdl0!vz@~>*BaJqiM@WFqVeZ_d~T`{|NL)%P37Yv#R%6 zYsE&jgxu;0=oc9zD)}+yb4YVr@;3I8W^H0dG&`?ddFGm0&g8ipQxq9PWIlY%&hKxk z>L@~?WERO;OY=)zPn;9p5~}^0XC7-T62aT9l-*(8-tXb?l)d{i+Aan&yTbEC3$ym3 zdlmj3#%>x?ioa8S@mN>eSV9<@A4{^Z9sz zZ}gQ=u_EGi#{?(xTLuOb_bmVgXtNI6w7xofAqNKu+%p(E`g_5#jW0~5t#ur;9n{ketap=^1x;2- z-Lil^Z{M-bgm(YLjV*53D~EGB2L+lRY42$`#?09#Z4&LvkTAxjEeZN9r~%Q|U2UXAUzcUmLoJ;$a_Nna$yzYss67SrI0OP4lmyJVfH*&d?vau(bUQ;=R`f zc{SATg7LX6CO>k=03$C4cOj~dA8Cta0eU!1c%TT(uQH>}ih^`L{*-`M?)+6iM zGx03iJC{!UW&_Xshj%Yui<6R5;My(Vd zg!g3*eRj)3Q~ev?o_;mY_9W8EXi}0BGCN45V`TZ%gW_Ygu!PJyr{l493D4LB63H5T z-IzqdoBL%qAL8G5^@S07i{=o3e!IZUuCt~!H$Gc+nB~8gV0j0im5?*Ijn}Iu2Hg1> z|Bk|iYt6$F-3=s}db1MA`W?mam>bZ|I{ z29H7dBN8_Jv)8gCbua9yVxy)=1Dk$+Yk%)B#CUdV6a)NsW2}lNIQrC6i^z>IZ0<8t zyLZXSuDrN)iuAL)=~-H@^ve}335z3j#aw?@B_75mH5seLijiZx z7E^Nv>eA{j@RQ@Dw@utnuRLy&P|#tveVpL?u;Wa=N1_OKwMkHU(FpuVf`uaqJ8=lV zSQLX-7H4iI2v!V%kE?opY*C3=5f#S4ZLAY&-;m;j#(ed5lAWbJkirr@nCA9rEMz}4 z=9v5z8~8Wl3at_sR9{8@t#bd+)A{V8%YWevcl)1M!^GC^;V{n6aVl?wl%Fr9G$721 z?b%WFA96f`nFQ}A!Ak+GZwMP(hVf^~myS(@j*kAGD|{DX=fcuc1>^pR-2`jF`Sl|l z#Ob!2RG%*WGo|!}BUC#)qJb=k+wZvDzm7nqzNs93BoDNfz^gr$q{kD}`_G{|3 zJ52f%?}qEGbvB)$`*Aay%kUu9qMYT2*io+~uc7QWKD3s354boVqcx|3kX+iGIV~QfIoUvy_fMx# zuo27HX&Ow2@GUT+^0XkhC~Uw z0iPL*ZTmB77Hq9vJZ+-j(Rc5wA58>uL7W||s;*Y4BfHW;p}vVOzADBe)IZbHO#aJn zj3VLk9YDUSX(Ss+7&6pQI@eTA#Ul9FJ3%8rU>3eKN?8uz@)r;YRz5T$XYT#DnJdKK z9&g(EN5tM?qkr71M5nT>!Ho8`>F)mF30%Pnlle&^=*V2p4=qs9RU2P2k(rnhfxJN= z#66Q9gCVr%su#k=!lev;5PR(Z;Y+>FAObAJ4J+IApP!6H;0YVMwvvNJH$6@`P;v&Z ze97Nxlm!-o3QBwfWYR94Em7 zVUuA*Rk&%}5KpbW1$$`!y7G1<$-$*PqkP*JG^~(Q`b0%)zAaVMij9mG*{3s5>HlC8 zxCd$Yy+RL8?h~axr}bcnX_V?tTzIy%XfI5_4Ce8&DVE)$-o_l_oTL>13>ol{D}kSYO;6?`obr!(yg#ZSmu#7)z@?_ZhXWPRKTZ!_A)^z@1^7#y7qJ)qj z{wVetOys!&KTckp4(gj-bY|h9e3&zViP~yD+LiL?Y03YOM3?f4?hpJ3-eZzSe)}w@ zTqWJ?T5{7Jr~><^@X%zW*KoTgAVkZ1rIR!Zfod2Xi}i2tbMe&5Wm9-)Jc)dTsIFy5 z^!I%?cXJB>=%Pc_{`7Pg8iFWvCeILj9z)n3{5<$Vm&i|r&IRZ+2~+Fa5ge!3P({&! zQsE)*0EL!ry=TM^9@OjwgRrm9JRkL(S+Io5Pxz01`UMo;Lo7eCn)tEDmX7+Iac@HrCh$3u3vHWg9f4uIKGf(I> z3WO_Jr4aef2ghVNDmaBe8jZ)OU|T|K_o-29p(OZwDu1BlHsIpv%!#oLJLIzuE=DXf^Xd6#4J#zdI%@^(+83l0X2=Bcmj?cr%WOjve@SA zf@^v09g)|-$Qgc=LhcD_$T1j+0v76rV1EF%Zzl_$LEt(`qoX3I&EVnDAe``&;|QMq z)ufF%n~=Gy1ffBP#vT_Y4Lp6QM&^ZdV;Qz4!e^hw>H0yR(ZnLUAB&o*`jrg)>$>I- zkx1TybEVdL)+aY9-b-v%pW3VcvT-SZo7SI_I~^p)y5=J?39a*D5{`KXear+TUEQ&9 zif5d)r|HP+NMURQf63+sJiuSL-^UhjobdI>um>r$)2ntC#{&Bx3R?JGk@QD}I)Wd$ zPlnA)v5|Z#oHR_IJR6mM!M;{X98y&J9%uY)K4686w|TrT zCO9IQD=6+WN5BCHRIcCYg{BwlR51VP*jSpFPNt%gZ&uZLTPPzM6;aWc4032xz$Yr` z+L)cNYhpe^G%<+W=CB0g6Md8RVK7?CbzhlO7uM6CPkbh3dpwqjgL0DOPQ`QW#d+?j z`wo$8T8%u%kaAxT6kwE)L-F%UE|Cmv6`cMO-V6%m99UZ#J-ifQ!GkJ=&(JMfP=)$* z{$tvdLZ$^qu+|pv2-?x4Z&!#BhH%jd9N6$g=bB1{4Sc7!`!)wASLA=Fw zxELWr%%$9h#KfEq>pJ|Be}$S6DAh4=5%AclD%GFd3RR`}r1J{PBo9_+{3FHT4crGA z0%rbs4Hj0pNq}N5TmNWXx;^jsz*SZWKeVYJ02#dK)P%GU;Lh+z_!VXVv$Olf7xt*zL))*I^tsqdsoM@EUV=T%GLRdC}PXicaFyiG=eQ`rhw(n zT7kvnMxQ_4_hlhz*1-G;v29b>rMqkUcj$%k{nV--p1#kaUcG|c`UVV)(pqY_=cWyCo z4%7Q71Ip9EZ~jip(d_ztiCGdU`vytOQv5%kTn%dVS63l#LR+^1e|?No)%EuZ_P4Yv zQjWj7vr|M-G$3*$(~33z@J?`K@RZ8;4cbU(qBKACgFmUX_0j4Zh((18uqwL^66zQ( zL)3O3Jk*Y{d_Vim5^W3Ord0dFqBo(rbxxg+Wa(QU?s3$ZZo$Qs!3x)Pl@;{H*mh0< zp@n~~3{Ev#xTh>J%tfgA{9TM!zZ${pyigo#S9juqZAFj}Uf% z|IJ8Jw0ds^T$7+c{6!(6>ld%`tuTstZo*UK_h}b2re5Bb%^k< zO;Z_Dcb$P-x41a=E^z6DWNC+FTf?wMN~$eH>!(QGf9$O_p=uM&0O-z4K_FBWn701pBM=ygC5l?*KK^c1 z*xq4lhzMfUhUZ`id9FgJX4(A{{$5bk_<*>OAz^T@%_RpR72hlR%wHI^ zkh3ilzJ4W?=#v_(Jy!P`>N+F0S%6QK)RT0GBVhR(K>+9b%|t!EFC6=dA%Iihad9=a z&HJ+LS&!i@B{pNn{D&TRzIwOC`|4T|`ZiRgsfXY$zKH*dnq~^V?v>Jmty~rT&t2Yk zU1>pLA&`YGQTWk_J||QbG-awFi@&9{!a|>_9dcb2{A(kGPIY3GQd$4VP?$zGB;-8w zrX_42&lQUEij*5WO@#yyq`GAWE*=B^)jszC8etjW4^h9Ob`~vO5>?anJFl-S5WW84 zmqVfnh~(s<;#6rfFG+n*ds3<(C&_fZ>hQ5XVHJOKmS=gHl?^PX6f~6~adfl5m_R z%(gRbzMtl}Jx(#AP?NMTOed%by8(A`@>0IBcy{=t_@c`!9?5!*PJ{E&IkHCJ@tfl#r@|v5URTFxTeI`xT>y5MvGa^pxQoZRcSPvot>OE2lHWq3 zuVjU6ee@z_L=xYL`&MLgmhi4d>MGih)!3;pOq}PP$aDp1++H*3oN4CM5tUr)g_H1=>aUv$ zPv5vaU9quUW&|S{`Q#J5kF!vBotQ6AZaQ$wDvOS&$Ke})jBKCejAZZzS^)h-ok=i# zAuc10mMur0jUjhm&W9d_Cf4%+abapBcBn@nl%$iDjf1fpL}tnB8x_qd$!j*-98pFQ)EBPrzJ zFg4-q1|4l~&@%NpeSf9h>!(Wh-WO1u&DLSHZVWeA$fia?hUUb^^x)MwZoNiA`|$RT>*V*b zv~=PgLwPPQzaQFh^XACMBA3pH?{70>8qQv%HE?b^+5bSJl3?|w=K_o3IxRc5gVcqL zkJ0bmZfxe$VN}Qwv07-uRgcE22+;?L>{t;p+%?dU46mQw1dl-7sZ;D9F3LN)jsF!V zQj8C4;Howd{rTA+HZ4%G^(5F~PA@DJVcm0?HCp$%jY2ez7p747K+@~{U5z2Km2^5a zZ@K34#gS{{`*9?0W3v*1r2G0pTbN6${GMQI$ppD%I^j#FAdcsEjc^!T>^H6?1#D#b zp7MT>8YhQr&!;wc63!sGpP%F{TAa|g#pft`Xe6ZfLMTmwa=Nz~gL2Dpm*zvIoA0)f zedDU9EZTh|FBv91seiui;19n~vi4vlT^xzFpMUWC&$xsP8-9=LaQ2^GD@w`jKAbh; z+Q?OQ$pi4tMCMTrOW;`zn*#z663r;{?6At;T3QI!|2x_c-iYSUd5H+P@*q~NhBerm zKKdQEAe7EKKCKVMAHRg%sBj#-Ah5YK+;v7a@}|hN8$Z1kcryse!UF&CigGsi_MfEi zYq>_TZPV33^QA&+XNHF78Q4jX-zFF~Z!U8J*h@e6{191~>MHnvtPl2}HMXAJ~Ru5k2h;A5?{~Vqagp74DLB@x-zp69&Ccq&$yIVW4JA z-h1mlcOXWB`lj6$I{HgTG>q{MQ zMM%1Ay~o??nSX}Ltfi)W2*tWnKpoE)4Tj0b5R%KIl7F+bZKl37t$=Ic<9g}{CvHPU zOeb-N*@e;iw|E*r1_J-}^^=K~8T3c1!)IF(!F_^@km4;I9oyL*BGgZvoDdAy3tp<5)g|yAJ@v3E$YmG0_E-Z9{M{ zn}s;0Fi#I`>S%NBiYC`8?5A-q-N2%-t;l?LpW^uY58!Xb0Uxo~LL5(P;s2Iv+q4&z zAR0-O#v8o~n~zilV)1jsVTQr`mwtr;F+%=RHZ-`_H=0kEqwS8_C8?oYw+Wy``3u%2 zwMzAmz_tVOz+i|6X*(G+f}4GVhy7Chy30kz)JFk$)!M7@LojYkgisU97xweFTvK$6 zhYRLN(8L67&{<<{Ew8a8i4nwYMkVWNWGU5hwNZFbJ@U$Vp=R7B_%>tXnAH1^Kd;Kn zEz45#`z@11>i2z_d1-^$amnm3X=Ni%M4*h4+=NmU7;Px#!3KtP1XkqBUADX(R>sxC zTW{wFkF0gw5?UnmjpQ><@9(im&lg>PC)&TMW6-~-#*#ehaX-V1^1)kktqb84o0C+u z;LQ`fbX6Ew&KoA4wc|n7tq=|n88&rVjatR(Ed#>FXkkked@NcvoBBn-hs%Rv@~m+# zKJIq;X$ng1n$rT>cFo6n>gUIh$e!G_e8V}UV#%&Ra|*CYs*Zg^BFZptn<43eRA)&9 z6Y80SAz}gx?iMnLIoSS7c^CpRrY2#q@Q@y6{!BP{Z2t9B#6umXg-7g3ig^G^9f-Z zjt2{Mf006sM5^p=qlXM0|LGw1Y()DV+57EdI`qR0$`( zE0E_=d~i-qamv$7bK8SE69L8(`j9PZ_)a&-wH6o_)h)0?99u@JzK1F7d_6{ftO zUu^?QR3Q`s0XNId)&G90giANSqT<2^gvy=C@%(PR8JgF3*hjH`T0O@ke>RFc%x{j+ zA@N$q=qo(%Kqse?dpY&e#FoKAP@9#uG{m3cv)Zz>n=rJ{49%fm3rqEYgqka21lXO}CpOqWDWP zmo8U9xm?ie0ZAwKixDtgWzMbK4eS5Sp#C3N>i-k+j1z%obvXuHNyT@_#J9Xw=2-gt zBWLjve{Vh`lcRVqd+>PcNSmthvEX|}WN+O~o~+CcD6kar{}w-ZwLXu(VR(sWwDmsQ zX2~}?N+-eq$jcitMSFruiVQ=L$xvlk!T#WDEH;t%h=4}txg4Lk8>8lZ-W4cr);L${ zJDc$j|8HL#C$5C6a}xI=Kf6`E4EB|DcpKSvsN&@Te07h(yIH;!6;IIMXXn_gUp#LY z>x5m-v)f&5Rb=%USCc~fizS~fgTuYCCn@{~h?RQCl_VIk{CNE&5OU|1+5j)mB??jd z8A5^XTE0E5Rr%$Y zs>4pRXn%k5HR|b!LTAjz+?+iD1v&&I1`I&uhv30&sH#!G-mM>QW{2o79hR7Tu$@TZ zx%ZS^kW%6{CO4+B10>p2rCILL8JqU=iz#kaz_WeT`9t^?33LOs7WVW+in#GRuQUdA zPQI()GVj?SNHl>&Rdeb%>09Q3Ap3hXvdUK2gwJ2-(`1L{|HNBkgh&)LrsUkbmSWk) z_Mjhju#bO~r^0`TR^O>hJmflG5H)2Bi2?nqrZg@+lS@jT?6NTfQf$*`q;RW7qe*${ zQ#i_>oXL)!pG!rz&To4P8%Z1aST}3|ppo79E@_=N4f}nr5jieF*c>L*vbM?<;)1OT z6cn57&48EpL<9sQiir0`P+g~BUk`0w>1XqOgN|0^JY-Z5f*}IYqdIlOG(~q_7@L)U zvk5eW(&yh<1H$yf@+NO_g9ue0|J2o4swrpQ?VLssYzY0yiI${VTWP1&7|ntrr1RgT z-#*#lecOg3#-~@*A~7Wz7wYcXAX>F*m!EC-pJ6d1QnL-|tZ*=ns0b$&@}@4^Z@l;} zd4wLm!m)_1X+i8I*$z(lt1;Wr?eFrzyhr=k_)Um?2A?!zcDjxh4=w2UA9zsTt3Oy% zZBjwV(Ro)4G8j@i%&hxd)hUe6XEDd}pQa*Xq@j4PUx3f=#VUt>a$EOY5t(i)%z$dO zk$ZBsy6;d_@(9B_8l0m*MQ-vuZoh32m%Sok0pBgw7hb?-C1mOW-}n3}=V}}z99ga` z1kw}>7B1C^eHS&;ysmyo`c(57CZ4sg(I#?vCi4T?#M00r2S)JpV{W$A!r6tu5hjo> zW8SS)BA?T4zN+X;`6DM3Bl`KW!+MLhXU)iCs0Dt)H}x%JVNwe*-gprwCsmNrTh-Z6yiPshVmX6ek zsz_9rdb?U5s$5XyduF#clV+dp1&3W9>C<^z369&?!S};kwj<2`EpFU!NJ8;e(Bo5h zB}s6->9%3l7+kkie@==KK-9y4!`#gg%#-sIZrt+RcY+vpoG9kK<}(7B*c~xHM|$|) zFfY+A!Y`3|qI490+Q8=jc0B`zQ0#t>kUIMh2oKb7h6wZQu~&deYU>Q;~1U$eC}y~ zy!w^2j6RehJu^d@<-xpAgboWII+dhPnBGuIG*KhOQfqQRosz)dg^63bQ@SZ{14vFsx1yC$imDpxVyV15Zv8egS!U_?tEczcXx;21Pv~OySuvt zhoFOP_G16S-u6}Z)Adw$SDo{=01o@uIkMzL^+*`MeHBCthW_$-#@3PnuJQNe@TnQC zH<>Y3kwZIs=f)@MWXUSnrs&K-G(iGir*_(>)fT(eD>Rm~rx4a48yC=uxOTj0`Ni3P zKh)U1FH#=B0}Xtewwj`rG@ z+ya(i=45JAhRLQWK6rEWW!~iAfDJwZt%85w$YyUn#cbJBu=uc|vSr)>N3=Bja6QO}p!FxS|{5 z5yv$?I-O*(JO6ZcOlNM-^u$=1^u!*6Hyc&r9+8MdhM)P*z^nnD^pfY>Af>UVY;Eai z9kQn#2keq06rUqi{l`?=Yr3gp)S_W6mm=LNtnA72F{RK@eW3-~e!R#^v}w~pa*Qph zMAU}0Kpf_8!p1Q9Z`INCpx|Y~K5>Vf?|=Zc-s5wdQ7=)#skfK#@V7k2TRy@)b&$1FKUp?b$@ z0hiP;rr)#AI|Gx`I1AA!xn!~6;Cvd1Qe*DVtx6It_^>ol{h zopOk@1col_)ialN?aYNcY#tXgnL4ipR^r8$rtFxb7;=$a9NuOfN zl0l}4FUc?yKbTN}b_iLup=ar%Cm0v8M(eXNH|hO%GneaeouL`=ub*&0*CiYxMg}7B zNmKWBhAH~WI;;pjaG44BJq>W?Fs9P=G3T?4o)MMb&AjB{Y8$C|$RH|TTc&Z|!x74Z z4^o01p_p{Tzua45n53TbOy}lDoxBZNz^b52$CQwII zo)uc}yziTN2B8xTa^Jy0Wg&q9so)Tm8T12 zy)kdCx5}VgXgFW}gyfxI_AFqZBqQ6q2g25!LzFG(!kd|L76u?=jxXn_-7W0<^KEoJ-1JKS>0IAehODCIx%mVpRw9CfjK` z;FUPt4xE=^#@>rEah#Yy!t--_?h0#-gV2Y&bEX>(U z!txe?qtq)?HH3&i8XTj*cwm_?R-FIz1-2tLS)?!51KOM%nkV1enVFh#@ihywqpMYY zK08SK)6WuGh7L`g94~xl+_Cksn?0;=?;D199Gz;}p^cf~5R$RkSGMWFEyPsv$_= zL>~WXH=qZ~7A|DsLn}?E6RUPd8<#xHq+meq8U%$z?+>sAF%}37*~fPeO^Yp#QaK0V zj`u7^QWjayRYqnVdF(9m_&1Uv*0P_n3BUHy6mJueGhJq;WYWQ)SE)j=N#4#N8jJ9% z5+j)JN>0>WAS|}RPPocLsRE3xKo0RcZ)s!P&Wa=>n@ueW?8n|kz*Z#of1s{|Mc2hW z*{Q&urcnTmOCh~k`TtzVQd_I5IndMjRzMUL5r}BuK$nryl7nD6G50DJP%7{2 z0p4thaDD|&UOeBWixEQEaK>u~;tP6-?L-d7Ahy(bQqD3M&sq5J&dyfP2 z%8F7L1QwNL9M>Dl4yaJZVWD2`h&4rbUb)8X&ixc?scT<8c3n#h+MzolNNuA{T zKaJl9ITy0R{91h1ml61!6;f)m!C1GTkp3egVsOxjgV^u&BQHCvzL7$_O#ImLPy(a5 z{xb>Xj?R4^@(^Rx=wdao-RQU)>f@x2!2 zKVbCoBX&Yz@Btz*cZ1W)if3_e^5vJ>HE2(y#boHNwb~5wa0m`Nru9(e1b<*coBb?^ zAWf~R7FNH6iw|e649nHF-H9}}WIBrt?q4caQ{KY}vCTzYZRy-luw!l2sZ=Z{R)P#Nc-DxaUAwgf5Bezm z)onYLuamo@l9EskPPYah?NE)t__zQhh`*a0dG2-C`W@X|U6EUQ`a!g9$uDd7>qhUE zml0;a10s{xPcs%M_$Z?P$>)!lyS2t+s@n_6Qs7%w9RD(d+v>&1(r3(ntMY`zj(3^Z zT)h}C(X_fa0vzTvUH@(9fppPL`$NzO5pIqGc8MDu`vwlUsnmq(E?@@b1T;#7=P*0l z!raOjLT!a~04Wd4?++D-U)!fqD|$Q)K91t^wf3t|Wgu~v*dS1(1@2c_UBo42tz?%DSqhBAq+!Td=0SZM046KFNhEWT)7(WP)c`QgJBVRfU)Zlz+Po? z2Bc9*3ZeCI7vglO89s8w^51FP3=mi^;TKeemEnhE;JFBZA;4St$gYE#wS?^k;=Ft*ASrjC^1;w4jhveyp(t$FaLv zaPr@&eY9nA46{W~DmJ^A28jK09UH<=l@P45G@jd&D)n$Nb!_}C>@7}W^v*I^zl?_MBWr%AM=Trt zSh!!%L`JIV_Q+3u;zq9(>5;om_s3h+tZ3AAej;M6s9BFrLFbt)ZTx5ZNK~VijH2Fs z#iqsG`H1FPqb1jkfk{Y{*~UE=Lvv=oxy_fg5oO?zj}`Ql1q@HW`}a~~g}7zIz>(eU zOq}psCrApNzlQW%2=v~huLmuXn=}P-b83DreaMK2Aa7XQwb}h6OD%_hh)ofR^G3+} zyz2m>R=n{qZiW?B*5nilsukHH|6$@#~SvJ zui=OVhevq>%0hW%rearP;#7dwmaPEDUc>;U8BCLnB0VZK4>;MG>WBSw`0`8QXfipa zG0CXu6Cpx-f(F2=3o||<aNAG|k^xTh);!6mAfaTS>QbIlkJz}FKsEVq9YAjmDRscNSSw}f_lGGm zsEh$FYOt+_FTPr!W=~R|oB^Ej22D8=@am14)EQ;9bA;9=M=319wH*=!%Zwq;d&=vs zrki%cq!yH^4Nmi*ouSxY4!C=4J^ta#{*7pV+1q?d>fH0c+Ide%u0;L}Qdt0ROLUt) zC6H)^{?mf>XuJVr=TLG!()hd@*_cc&ggcF!E= zM@AqLepRaS*!hw;PRS^N74(b%`qENcJEpk#6C!je;C&S_me^ko60;z9J1xtMDD$75 za&jpz=ve?-&6zY`1nqtGc=t3)JR6cusF=LH#lNVv;C0`rLB!U7yOt`* z*73*;Vv44*z0rj53F%K5oj?b>-mVY>>^aKM6|2nw&8WSbsUbEz4S<~!LJI14Dr%yI zQavU388mdSSOT=4w(~YO1~#XRnk!fykB1}z{n;-9KX4>cmDM-@L>qrRBz_ZEnhzgR z?6SKZXGqMXEKTYGhpU$_rfD%i&YCa0Jyu@TSpX^aD=v<#$7eIs?z#ng?1FP9oUCQN4xq_hKI1gUBgu_!98m_7EJld}IAa zG2XFa-Q|3a(v>e2hBAaK^C~9|%HTwZ?#ki^6qUKS=)m8kYx=kKAdxhqg=5FS9L-9y zN1Qt*O{cA9#SE=fty-9vZy%VNcQgqLa*bB4!kuva_RrsJdj1E)z)!yluqM^=iNocc*(SNw0{GA zD}H?le}h-C`@~|i$QQ!Xn0-c+=KCT~TkV;F#g+}Q#l@luhy8D7!aFAnXOBbOPSJQK zK~sF+g)(SVmfxStQ&2a}>1SblZzr-Q0j6uEZmEE6wB9Q<2@b*SZZrhH=ey~NY~Z_e zdu^`*gy5?KF3T0tKo{&E!$-uBhyA0Bnx8$tV6w)Cxs~>{=pZKB-5STWy9>9fi|7h# z$1kuF39u=Md{flkfC2XUg<;Q~w$C~B*I6vXN!PCBEdc)cDuBu&`^+dVdKmqQM4TENG)CXPtx+CkZH=KWnp!Ou&kcfrG#Vl zaS`>|i8x6z>_CTTy?ErJ(4lSXl#6`dzcdU;je8Aa8@uS9t+0~Uu>j8m0m`!iB)RYj zM7~boLM7zu)RJk*j)&vHCkzY#PnKZdu8@tnp%73BZ*Y_b{#Q26(42fWrS^=n9gxxn zp96@IdlJ3v4c&hgPk0?s4NJ1lC1TV>b)ALlrn>@3dv>Uxj#q&U7=oKIs4Bv*P!mDS zg$ohd$`a>Wcl{l%v|97&T68cEYWB5c#$}OUSlz+aT~dQeF0P?V*IE?d0Ga;{9!W$aEK^t}T#p^t%UR5& zB3LIRxUwp9gAEv}FNzc%fvx`4Q%K~N`(-E9CeRK{`}f7c?(2*u0L!{A(hr58-p|uO z?HrieR*&Um1#u>Fz!5f_l?&!kNKwx3|1x=K3v|uPB*Ua#L-ZEBk|_I=w5a05oN2pY zlj15~kYcbprPHw!zF?}{;tzp77;E~$v8 z>@@!J;E6*3nbm#rpMc3l>Pt;wA+}VK7h>LRoVix3GW#)0(bh)Vshm+rwTnTTvv<#}VN;Tng+ecYvBcX-I$Sz1Zd@mz&VJ2`R`08t^v2kXEFT>H4i22l*c-~S#gkqfmJ#orHx4Y2aXzb(`+DJd>$AiBq85hT& zVCd}l%RNxX+87;Q(yKF4o)0E zw--PrN%%Yei~Y1)-gpAdlpRb1X@Utw0GEE1}t(hie5Ph;Y(9VDg- zvsCa*T~>M6GxAIo(Q9ctRLkKECOd#kYrq4DhA<24zD*TYnD>%d%6lC_F*{q_Y!cd3 zI4D!)w^%93y(GN>a+R1Nl^Q~B^1u+nR=Zdk5wM1AYK|2ecpA7BOyqiwImwBL#{biV z5mU@`ccln`*$ZnSZDdx_PTW68HZ=7Mnij8K@jV8Cx-UFHF07mcj0w1;BwIrl*g^-5 zd*Oohrm?_(?O^IBY;MKZR{wktH#3IA_CV(~HmH zd&jSnkkDoOE(OCfL3g9X58j-+_SUh`UyB3|oym*>ZPY^%v>YEQyIv<;ilQT@H>TnM z0u9A(Z-TpIu~ZwW?K;H0W}=L;pPZzhFo16eJU0bKau0+Ub^}~Y@T5>;$>?7Mc61(p zuxdzU$!>nxd{xbbVePO@&wE!MmP5L$tJhm^Bb0!FNF-#EqqF=CL}+31a*Nbh|9S16 zAa3%zSK0qStzRCV%QYw>&j$u0Qhii>udW)A*SB+h)jetL2zhm+mtIl3W7Z(^J6^&* z5D&CEIrd+9F1c9154zup;o%{$!o;l5h|hkiKo|s&*7E{E2W_Crt9cTe#XxwM$aJ7> zI|sPgJ$!7CnHY86(8gJA7(Og8;Qs44?>{zZ4^>Jp$Yk}B&n%pH@QjDcBcQ6;5*1fz zn;1X81p#P)@X~YA1?Mcy#`<5E)!gyQ?Ae6q>K`GG`wdU{Xh=vOm4Auk30mT{UbS0s zxEis4iTl|1eJo_8)LpJVvqZ%GeLadsTGEdDMsC<<(3Dy0oyDo$sFUA9P)BHxi|kFz z<3^;6Mrwr)Ov%r+tstK>-U|-;25yc;UKM*7!x?Te532}hDHq?39W1P6_*jUp7RY9; zXp;6C4D)Aa^#Vrjm$UJE<{yZ6er{HWT{WT|h9}C98&Ss(-mNE5p)0%~&#h}~jAq|B z_@a8p%C97_qY_O3@U< z45>L|wTpkNq_j-<1qXvex+l<%o4n|vT52@%L_Sfup|Hl~B;KJRkKxZbNqfbI$ z`{>n_HHPX1*g>eqzsrAzLv0}I|EcC z!3fCKGbp}%f^v|Rz&_cpTn*bc=ecQ$lw*Z_CZs$v-D8^)1 zX!nD^cA!enV+-$xmu%M{kfGDiWt1How?WwVJ9B^IbVeXT!G~tUY|SFYE?#ws2W2p~ z=@%d1dUFz-YIPR(x47ZF+S)HsURZR3I)GY4V>nQD5py<7f0>s_@e21KawWm4+!K<$ z?mP(884qbgi;UNunkW-XE!<6!V=xX}wr7ACn}O_sEQEAVvXO!4e#CkzR;!N&14-N& zSKz-x+oGq2oL_ES2gBo=cj)D4aR#B5Mn=5_lGA-UqIar7cR*bbYsz^>9E&-hkg;MO zlyTw2qUhlGp)M&P)wEUo_C8GQZzOFEi1h_xG#%wS+F%c?Q`ggpba6nK$F5@KUrZxc z0e&%}kq$0Ib;Bo#&q379;S2FIqrc{J{@fiA5H0JFPZ}kt4cz@MEyjS&{t|Qe2qy-0br8xvcU!CT-p~xIH1UYRM7B0c1v4EUCghaGlo(Dq!27n8tHxfZY#95m{Rxp*FeB)+Tn zQw?Q zq{Xt?n(CLBiF7Ub%rv8CZq#>tr2$i}W@?G$&gCcA#{rcW0g{q+y^%agVn#?cUT_{n zPm9?f&sYTF?OCpiwKCY=h9FBw?#QCD@E4PdIYD1gwEgr!NbXlA;4O1QtZW{11WB*5 zpcqA$wZMp&m^P)e0GbFxGowqTL ze`M4&59LV)O9xpoMVLNd`Ckb_bLF4kYY*v)?ml2{458U zfJ)oJC6CuwtX(|PjBkA+o+`N>?l`+$C2ZX1bC>XcZz3%5VOIi~@~R+%zNejHie8W0 zh8@lxV=!JoV%-^Cnx!Sj84(Im3=`7ZRC&)mvy(k>WWgAXRKVzzOva$pxYH*USu< zVLvB=Qav6etB7<5=!AeBjZYxFH7LFX!P;sM^4Ho52{$lU7J+j;h<&g9n9t9d#Xn zZM8tAhA#({WGV8gq(-H7`|Y;o<8B0F@LvM%I>H%-p2CQ>>atf@SyYp2%TR`J5_xcv z^dX>Yl58hg=b!v+RtgF6=Q5AArf#S487fQ}o=3qLbd?yvFJOpPc^?t>x6CEzR8oS; z7(FFa1&&a7Ax5o%Vu{9>)d*gqjFr<%RX3z8J%JeYpwelHJWBL-JCZ85FyyA>F^k=Z zh0)s-!nDDsx%8cnrQIK2o@|uc9+Cyv7rbe*>y&;5B?C#F`qcgG^GMex-at2-*(0^)6e{J zUqFnKI_-Sou*)DO7qMWT$Je>dK;&)R6w4Wu{NDXI6T3l3c*=<+L|eT(!Y_M!p|cL} zWWf2WUJA@6zp#UhGaW`^j2`DETbCM6iGFE8bOG%b>o*=QY?^EKPS|vGNr@3$BdJU* zWnCsI8eaCW=*Tr45c2!d_J&t429rSUndl_H_-8tQb^GYk6X|V4Nout_Bz=$q(B4sO zr_9MuZPmJ=4R`AewUaKi(=>qNM3Ulnn?-r*PD%WBbVxl%8jP%w$j5PaUWil%@wVZA zE=FTEnAXj5-IP7jr6ZiiSY*>u*Q>G_GCTm*3!1;LHjXvp+Y`ktF zxFhjV2$HXY=>9YN_FzQ(Q|pgwGs=tbJ4;|MwBlQrkj^ybdV(6+=~tAGEh(S0d4MCj zv0n(c?s~)9AjCfIIgDBC{Zl{JMZha`VtM1Yuyla^^_vrWG6z@KDk7qHY`}-Sph8$s zICmODUjhLRKtvFgLO1MSM@)fD_gBZW`Fl}n295}OH!>HJ^FrFL88f%>JA1{q$}IG+ zaX8la&Ap!NXH*!HU(M#R#V}vbq;Dm3a(9r=1mRdtZpuvueDm+=DD0+uc>n14ay@uo!9ROfJVa;w5DISv=VZ)5L_?Q4@v?m&~$@5K8NULUH;Z!U(|}^zyr} zWS*>DfA?ReCuBE0+y3NBVQcPOu>QG%NS=7!<-QWeI4s~^YqkM((#M}&F)b&ztgDG1#uq(*CBk6w}wRDuqq zeCh9@k_|9bYD+Vr96?jX7Q{s82gS&=xNR_8eLUXf!n|i-34e1uRatIGnr&2bNMmUV zx00amlB>CXEfVK{SxPnQY&(!mzuKx3l{O4aB?s!P`ER|hOf^LcDA!c9OY5Ax!$C?j1o4xV z;u(CW^8SV|e&7tr){k$l0fPI$3&J?>Fl?2IF)r@w81 z^Ty&>J*)Ui{XT62QF>O!xh7%i_0DN{4c;IjLLuU-?t!v%(G;RSc&@GqBs$dw|w}`>f=`yOcms6pW%a1GeFGGT%?sJ{o4(ENvTM`gtMq~UtvB; zwkM0E%D5W~Mj)KTU@9yc_%0Vw8?${DYx*K{GT5Nm*v@qS56$psLD)k!Tf>h(V2W2( zi=%Laz58a?Z`h_y65?!QEgzyku7HkbT1$^pZJsQ^U2HWZB%nkq;u^BebiMhYA{OYU z?BJ3GoWtUOHZ{XbGM&oLRUqdr-n%0>w-ouH$~XL=WyvZ!<~Jsb(<=EGnl zazt@y{~&`!W`9P~*GVX_J4PlM0ZzfsfpZBKQ@GmR`?b|X0Sk$ZUq`T!n09o?8xre1*KGJ=l@FJQZ-tHXYe|MZ42XVI_P9a+9!+iFtfzm}{X!yTCHwZef z`$=Y5F!8kEVzd8!Abp0aTIbm0{+#X^JrDf~s(u0Tm{KMG>;lq0e8~A5|6?*BZ_X;T zF_Q2Te`*_YbHcX&|^0kUq8qq(0#1c8Yh`x377si9iMyA)wO@ch3OS^ zg5H}4o$Buv8O>CI?W5*pTBGVVTe@G!eAIdDrrhQnvbWf~U#xILM8i6DW%Pj3lI4)i zfa!#c@9qf%k4;{*%7mSUSLXN~LFCZst*f7TXB@J|;rv$kg+xLX0D*)oVdWMTXT}1LpZ!XH1BqgHBiC@T2-COLkF(~w+QTpNvH7@Cfsb9+q=%kw#Zv6^ z0gGuF^eCxMy`p}5^26vv=KO{_FR!P$G?R@P)<}LAvk&di$vDoWjz1=(e2S?$uCxs z5bQuYpdu&@kr_*ux=zaU|7Bo@HWtG0D!a=t{&b&9eCE{g0Hs)>nE7yf3+#ALtsLtX zt-P#%;H5mk`1Lmyare*kujR9R{>SPU|0|!f`^i|7QyiSYTJRIy^oBi;Xi-nn$HsfV zcXu7-wl4eMNU0=EJeOgUxw0;BaX0hhi{D$8>_<1?F`-|+2O#vAh4H?fg}V*z^j$JU zWcpilgkaLn2}VN*@MXt{oyd;FNFP0@J@tNO6}g)bd|W4F^TJ>;d09<=|6QD2Okg9p z^uZ&)@$6X~`=8!xD&?Tfwe9p@#a{_OGmOFD{?V;nc!h8OdCQyTBLf^w}l%Af+iQGKOa!ffKl~|>QdLpjUCku_b zxy94&N8!H!*8g^(|7kKGCdWfKr@Kz*pvXBrS7-*GR!-V$2;A`-a4=!*{`)F@V?4mDz#srd8ZBK`|;@5K6R42uaI?b>h*qTJCfSj_0d446#Nl`e~ z0R6#xM!8`dPVT;)ZuFMP8}j2(IIeZWDEzwfyU3IA;eO8gZT?1_yoRZb1xtlRjJJqI zfOzQ`-&r>Pr}6K5nG8@=kuyYt_MeZ}wL-TO^ZLhMDM$jXg^u>D8RKdL`!l=8U#oKl zRhn=N*t)l`x^=q>+&onsN3#?e6ny?P`kQ>=iivI8JhwCM5dTfBHrq2)#%Ujmu>}1sm)V?-r;+oi}a_0wUKw;xE zyNmWjSGm0RVAt76gM`JaR!h^!JSxf*c(%1p?uTa(1RnLtSGmd&%h+dgpE>Mgvtr{* z?$V)O*;#A-CDMEwjrzd~zhqKenRaBqS6cEyJ<$Z)Oor|e)n(GP-V)bAaRrukRosO} z2bs}aS?o?8So%6g#j{#H9253wnDpb z$bA&*1}A4Fgb*RT?kEBss*!ruYMN^M7Gku%|6xR7)bo_OEWGp)Dm;eqUT*=u7ETS{ z{;wa++CjwcDayc=2SY>7JHR$qBh7LY#b-s->#z@IP$) zCzCBoExMm6mqkvELgKq_vxYZ^BfCgQ*REi%PFsxq-->y8 zowj@w;{?=GM*=IlnE+ptnI9bR(51vY@W0JQ5qc_9vzf@58zbx(8s&>8-t&8k02X`5MW1xH;$NHGY?i-N!HQpTOBt6YOO`o_j{b!U7 zQ(Y0W`$Ij^O_6~_j)w&5fxpb$vJWAPyh?u!gHg{Fsv+evw zn;h&kf4EXPi6qyZ48k^Ui&|2D-`Y+0pBnv*Rd>w`9un0mR>e%}={DCu6`~?T4Ei}I zuI{F!eH`10e8opXWIy@<%}E`ym)AO?tp0*|>D zy%Jhvj(5dX(aHoYD`u3K9^lf7(eq|L0RnQr=l!d#7I@Vc;Fs6Q(!5ig4`%)0m0rT| z4S4U3piCuG?Bzs~6I|HOd!e?uaY98az%}24CLedlK7t|@P%l0OQJ0~bnnNCvy+^5R z_{E((NC>y?^EEozmfs80FTV}e3}-P6@_xYmq$Bu@ds)=Kar3oFa0)iuV$*Yj?1h%n zCu3JCqh3}b`SUGLdR0V7N!;CeI_t=FRoyIS<9g*zdTgGO14+bTNPX5Ep1SJq{*QYk zuiDsvP=EKTP}P&xg)*Dhm~W`@@LUeQf&)NZ1qUy(4y157RzuAep=cfy!KM=yI_;8j z0{Hs+f66(NwaClk+8-&w z1WWP3RG5n71xG=W(>q{%NSKkgs$9x3?|EU$P{^he2??kUEcopPwtNmnXj31AuY~;Y zmmwT7#Q*%?)3V5w={B+NAc4`t-9_T!cfA7Hd%cMmm10k3(l6m+A9BvT40uvBA@@Mp zp}P$g90dFPzBxOy(_{XZ*$>Zy4 zl~6^UffI!;vb*hxpU8_vW53u{0Z89BL?g5{5S|Q$k*%J81!c!O?Kx?$YkW+Z7Q z1)F@FA$+HKx@BGJ@1j{>W-G19JJtAnN=}TDj>yMicSxZwsev{9T#&gFzverxrBs7f z*|aXUcfk<8B12%mMtV~2I**!RE9U55cczTM7@Ikf_7*OJ;MXQ#V z)`YoJDdu%cxAK#gf&qgu&A9ilASEGIf(Ol zqqp{17ZasIxk%pU(V!nx9BR+j+zQ*Er}{ZS=BzHdpQ16~yuX!#x{s60o&Mtp6O4V^ zWZk2u16o5gzIpb#kb(4xwhKeoiqDGMSt?w{+UoyA9l(9PWN0G3(~VqQAhs&RMxSb8 zCXM#qt#4O5_*YG_P$sDkcAp(;XYTmL?PPAw4ddg!U}TR}a9P3`)evsKhlH4HRpms) zY|+0bhcVcKbjrbcGhpw{h3?EhLlUs}jLWeAP^~fLjQkc#cr~<|Sw}izkN?7^9hQVd zBKearcNcy0ukvttp`@^&dP5$E18+C_2eU=3IgC2n9K`9+V&umm(uT< zKD<4r@)+$JwTRuXirart-}o=T$DJH$r&DszkxSyo#vj;N2aXBb#7O?5*LtR&xB zM!>`NU&|%p;r%8x)p4<3AuN59Py?{d5iV}VULGlN`&Ok^FZGP)EFmkMvCH+Tu|ABf zxM5xB$RRv<7x2QsUB{^031zftTBg_NK|%`3*O4YHX%?x%$TP(Aa?~a>D}nz-Dfp|- zWGH9{TBfUx>n}2^pPh4>r43lZGy8?dhx|0uVxoQh`}31`i6(J7O}y&hTD8hc7O!!! zO|_HXBEd#INv}peG_UOJqIQ{lbv_yK{b38GV9%nbU^l{ePdy}OC^CB|p!dvk9;+ZD z&XBtT%oE2Fj|XQXUdTiBPyAXU(i0aCJ^5CkC>+VyFHvAW6kcHjmf}7z!7dR=Da3A<^nJs$VTf`>cQiV<|DoV*cAc7QH?J>{J$3dMRO6{=`Ddd?vmy4D zFc%g>YczR7IPX&zz_7IdD#rLCj;jg_bIwo3dER!O))MD}D^i(MhzWM7dem6YO!pWzlGaAvKM>=O7 zJ7a-cFcE1MHQpWMyEGMfm*}pl-9wm9jtuI(53e@drZJ(WB&jQa6L=_$J4M9|M~yAP z^!*I+Ufj9VXCxGiXZmK5`|Na=|3)KLAlJfu;_LVE)}ZOv`R@Zp+pnh|&r42ddAC|u zKJD)VS{RQdiK25vlIj+xE8Z{MLRb`{0aha;JDMqk@dU=ER9=@eSm2TJ{Yk!z0YY*1 zu-TLQR35JA&~48>)-0`=PZ>^%@V&7kuF_^M&D3kFn8>@a!~O;ZMjr98;@p?sZa3v_ zyb}2>e93e?KxxYkXv31*j9vVF0e`6I@gEeyZI{DvbR4<&qpZk2L+T6C(jPX6)S2SN z#ww;b(LB!bYOIWj*0)M#M-usTpQSk1nkoXp+bGo49OpXg@1s{fL>XxWy=#lS4Ljs# z*Cr81#i(>UN3W#>*_Q{RT@gRcww?U$2`(H#s?Vp7LST;)*84Va#^^bt7_Sv@1nE)%#crXY`Ax&zL^ z22^LIF+Cd(Wd1O8wiJ=VP=IhUL|=L?1pc1dYeacnI*fndR;0z4x`7x2480d+-`}W$ ze&w#ZMXZVHMOfS<2^C$?3J5zUt=vT^n^UPF#|>S|=H=NWNpI#j-S0)>b>GWwHED~5 zo8T}6yZ=xxDthBw0;6k0s`!3dn_-|(V4Pp83_1fKXJe&+-B$q6cJ3LxUe5O?V*j`u zC`IR=RcPbJvSUWxy@&`tSfZ)hm9k9VMZfIi9NT`1({SoC@n+ex*+~3io^O8a$APXG zw6I`!Ejo?IHSy;*Nzaxefe~&*b7AFilx^=^h!e`lz(O3UlJnax?F*feoX?7RRyYfC z{p}GvJuBDD)X=JoRKoc`Zg!>Hb=1Dw^@jexZYH>Nw7)ejPxBK!8atR17} zlFIBSylr`=HG1_n5fbh39cFX;KM75e;Eedz^>S@D7HCbgO;X&(7B*i{6DEu@G3=hUP+#?T*iwW2l@je1(F1#ky^(z2M9$XNF< z2rv4bGd(~TEu3YF-9M+!k*s{uku74rB;2oGQw!Qa?s0A#gJAL$vtDG9udK|HN=V+7 ziT|5yO8p0HVM$QN(jSH|s_x-}xVeI(K`@4aQ~`F_F2XqtT|jle8@&_EQ$ z9aNLB{UUQYtpbZh!#3^XE8jXmcWwzGR&{mu6MuFXv;UJOC8o;6BnGaSCUk;@x_h^b z^<3-zO-O@@a29gNLDTXdVKQneyWw+)<(q}j31=Ew5!(*BO??%@Y)kFG4;G=uPSVMn z`dWke6Ykaf&Fw5&UUOuAUK|56p_;Je3{}>Op#?D7#r*^M75S@dJ*iVC7bveAvgVD3 z~e98L$Ps%O$WR4!bvdvW_ey8*?r=k8v{{v`1 zm%mrDl-YB!h$#A8a0EDVv_&U>kXR7>0`)s8%@eMq1GJ*Zdm%R0IOzPA3~jxjV8?}8 zFY8p@WUd@zr-;p<)~oSWcnmG7t*m(9Y!e3>uR65o)SD>cZC8iZr~c?`-}%`;P+AU5 zm3SN&cP2-^UK;?;t?R6xwg@B8v)#3WE|4dK53`|(kC+SXr zU3|1d%VO=et=VwotFLOuzL_zJHM%>K-u*gw<+QwLZC^sxY5wG2>q9Ae-M0Z`cgq-4 z>jKRc!Ow6-px;u!!qw*s%ARzHj#(R^s=lw(Bt%Rg0-->k@Uxhk*+$%n46`7?O$~%I zzJBae$+aEWb{IcqJa0H~L=UFg=r*?O&~+bqS>dvv`W95%<8d9{;Md7YRLimW?W1Zv z7`*Ynz4P1y_jduE7koZ23~D0`l6 z<~LC_P%_)a&1v|}n?tNS(+J^oXDY0!^c+`yX3H=RHZa*8km3!T857R>&5Xp3pZJJ> zGk%Ld)KxpqS^Swo(#sn(XV+@c$0N# z8)FukL2qV%=!gsELPNgXm>ehqyjJe%I^iv^WSsF`r~4VfM}Og_+(T1}GHY zt_a51EJ(w1%>+O1u$qdA?F=Y(@qu4#AzUrG+93T*qT|Vi$w!%E3@rz$9LNnomusI( zlpJ0iI+kR-Cy<%qIsBsMau9IgJK*ZORPBmOwN7FwH@z{Ud9s-&;-F8unr}13A2>Do z4Aaxhe&Ovjm`q~PEI!l0bc#Io!Wd%ehElPp-cBWe$2VJ~mWg2Ob}a4FG%io&mX}dH zLAOP<5!~lHvJrgjKkI*@;*=S9n*xb8FFrV9HnTqo5?yV?$N?LMfwd0+c3*bUgO9-7 z;WMF!OPOTzu6zCAB<@wK#-S+$P z{sSfK#}{PTFd7p($fH}EiTx;B{dW%dfo)cNP{GeBS+rUozVXWpi-F0jwF2Vin z$6fOOqV*sZ5Az^7gfCzFz7N-YQpj2P6jkJfTJfy~3PT0Da4e{4cQ;2engrrEeP>}H zN9HKtT)Q_N3X=t4*u?7=`f2xp*|o3W!>|F**a>I-rbW>BG<6hizkf35bEww{$W(H+7&rjiGWS?sOa17y~_?TrEVI z^XIsx@3|1@WJ9bT#~2#}((km{rr$!a;~W0vWxw4Hw)wtl2|8Hj++2p+87XA1!jC=g zGNK7bdvCKo`a5rb)PcI{K2XjmRI6uR@zED-H~L$1wF#Qf40KdFx!Dtx7P2R#@44Ip zB}xEJxFQs=Q{2CuvwVGn_N6dLjyDdAmUtC z`)+odRfj$W`Th9xTLM7vbL=Ej9yFnKw*ic(ge|OQ{Jp+KUqhgWXCMC+JtGJ^e48x) zolKb7sC^oy>m5D*co3E;OeyR8>fRK*wpehSecMm#;`G}N6Ta~6`Wz>+Hy<0sh~|;7 zDv{QeMXQm{Do)_ja8+f^tA==$ky*qJ&oZy}ko-9I!X<4<$ zB#U26Sg|I1#7FZr;2n*5Ak7rdyM-)uOpsN{rkruO4;~(-k_7i5`=h{3vu_Y(pVciP z&r?jHh)qek@!zsa*H#Y>P#GqTgH!C+!Er~PY`2G;FM_Io6Hq@)qCu=xl4!?2d?tqY zg+#Nqh?&UnoR zo(E{N@nRIsA>+PYvc|H4)!wMKZu80xn-sn@-oEI7O^P-ibV#}V5IQ`bBS_9V@kysr z>lU`hoBLR7?|EGK@a0dq_=TuAD21UNsPc^WenjzBGQ9w5`fG-bOF-Iqthh4qXtVp8 zpd-096(W2RV*Y>>9R_+eDbN+E35%Lp0b`I2+k+X`s(b+E;>LvYf*Q==!_Bcb9NR&` z4C`+9t9I42!iP2|N_TaS(T|KvV-g3G<|+!){twn@M9WTmyjnx|QSra=*YwFkhRRO7 zpD$9P0N)ZihzOKdmzon!m?U~k&bi^_Q(%TUyqDisrhaV>+5Axfaa?ocJ)zGq7!kMz3{uop{U`-E0G;8vKYiHumv{L*Sc7 z9;z5mSFh8)PX7&Eskr%7`d`{G^6Sj(w1xH64|1fA6EV7Z`HWtIBIGKGjQ}uo=7v+L zV-@t7s6MqzH4wvt@+ZO?vDkfu<=Y0KSp2>V5#IW|k%^`=jBmN{wTd?kDf5+pXpSLx zjYW@1>e8aoC$@G7POJ-)^{2h}23-N_!jE7p%64v+9QwSH0OkV=hgU-G1Uk1mbV3lQ z_PF=NBuQ39vfVJv6!j&*q_Qy>Dus`6Se1B##I{ot&J(95$&P&K;?g7&*s2YgY)C)+ zeL8pi9DF&6+a>I#dY*KaXAsBnPl%!40KId?3iK7e<}2<6e6v zwpPL6SL;7$3hK<^C!K;QqsfbPRT9MWn22fNV0(1*A!FAvv_qro4s*)f5^nz7wrI9i zkYT4V!@g8{E`eii4PDTyUw-DD01=4=SayIjA9d>Q{oeYR|8*(uU0x2<6@U`u_$7;q zMepotW*TVG5lD6D^Oa$}_%oTA0MHN+LbbopL0w9?Zm0vu5a%z6LoxK6c4!(E=s}w`m>1<=BRz0ds954g{j3OZzm&Dk?hLA3FR@{s5pm^KXYA zpIEf*OXSssVuNWnA!pr**4DrpuX^}1VA2mz_uZ#{4Oax~)#2Z|DQ8!rVOao`Lt1pn zvl@;G7tdbI(DjQkrOQwB-4|VD8j9kK4z3=+_JVaNV1O;Z#P0{FX2AAf+>5-GAO1K4JSLOTNhdl= zewJf`=Ufp)u^f2fPEzSXhoQE4BEX_;dhvU5L`HfMQL(6XsU?sn3{B+BEgD!WY{}Md z4b~N9^b1ou;$J}wkIbN_8*yOOr*?AyCzcuJ$IBt(#>_`eNSCT64PYcI{xPgbjQB-H z_yKHyH3S!JBFtgeXjiG_nneBDkXXB#Hxv{(VsbFPHlO_%gI8Dxb7Nl)vf;fYxi zwa|yW8osI^VQ3wq*b>pQC^OKtRr{cB)!h{Zh5YW8S>L>woPC+`hYtptJN%;8(6-@8 zkF_Rrvw`qbUARV$K*3EdW3h5gVoWxYyh5DsAv^P?=7vM44ht6|=qpOen!3B@HpL!>>9EdA`zxAFQ zU%uMtnMlRk5g|~DAi?g~()I#3j}D0Hz$_WpYQt-?Wwi~H0Dq_hUQZsO<_TrKX7h+n zWbwf|Y(p*ghjk&~M-LD`#6+MsB+G$Hu|1kix4v{ua$oui!@|H_d!bG&n=lClp#FY- zqwSFKp`g$3G~5Z{Ht+ETo8pHI!sQR%;V^yEW5e+&&+*ZV7%@O4&xi@xDPMM~g079= z_t^;e1%N&}Jb+b?vpi&IZOV&!$|vk#_SfRfuM!Ltv=%J-DDAV`ZN9K5?v31YMzV;F zD*<$IwW7BJ{doq-t@W-HR}^}FUsi(fO?0^zj zH^e9SJ$XhO5*?LF!bmzau{=kH4zNnC>9l!?;%0@UCe@^;d?~n9Ma;7HNlyChqfm-I z*t>o8%F^&J>U4Bta4nY&DlGdQZIc%H+aZX+02niuKb9{_o3#?zjx$3^>mG47XTlBo zJ~@vP-KC)Q48^6V{d2c{DG-bD=pP+UzMzTkTxovT90zE{1FtXQG|g?A=Ia28-GdsU zur8479P@%$f)kUvSl-lyGt6`?W@^(oln;p2-1Y53e;xq7Ui$WB*Qabg?Ti254d?uc z4V<9Efw%%-?8Jo^;r5eL1=gED(H&d>E_n;CX(sz)SXrd}WuVi>p=8`7v7Q|2i9Xa- z5~I5oI-Q;z)U&fIf+mTa$pCw{_=jSY6vmC%v~N51%NHv%*K+Nk)qx*+3o{WW-oOMu z&S1!w4^gfo1XRH@6V7CRu+1NUVCLO!cTMIdg;s9X;A2O{{TWt$NW+7|6Z%6>(G`If z($PQ76@gKl!CB1u9r4Gmb0uEM;|p=1Z#HL|_K&Cav^&RO+5=x9gztr`d1944FX%IO zMD<^<*2cm^%Df9;PObv5p-X?;Iz=*SAKl*cN22t3PtCi&obV0cOWyUd8+)>_@cB;l zY0@fC#Fqd&F^U$oUQVca^hF>wV-b>=Au6oi4G^{$zwsp!RDn&4ELM^8MYOu4DhU?HJ`3L8d$wMF(g%Gdd}zgifXymC^vxT!5dh+>Ozjs3 z+3LkxeC80?X)XlMgE~v-kW2SzTregY@*1b-i7kW&MlVUJUpm#dQWn0N!$0x;*%at% zA3Cyn-=F;1qaF(6M3fVH1@Jd7zw!6D79v(oiXxT8nNTnxC<$shPB#0f7YmWsFG&g1 zZ7Wni82EXi-FPc)eI<(%CD{1ZNlq#D157)nBwE_C^4!2I%l@mi_$v{7z`T{0zEnP1 z#caa5Z-3eg?1$O{SWmHH^_ZYV>bkl>O){W#&N0RB#U0(~je_VcQ0p{vj+yL7tb`SJ z>udi@O?feCQ~c(3TN;4vkHOK0t5|=*sgCXD0^J%Af9Mv}VeBZ~jIWmM911q_YY}{n z8ggcR%r$(+VO>f>_Ee&wvqQVZ{2<3|*7CXvFkMofAL!t=!yx?!!Bf`fpzcH!+&N+8 zi!S?^?%Z|8Cms$qaZ#X%wfh{@=0I?vtLZu{_0clx!htm>`^+bFfMAQ)n+5 zv7<*kL<(*sym=oYG*yPuz&>=B$v1b6^u6L7EJ1s0)ukQG0I5ha}H+=O&Q$^b}8bZ~km6K4j(bz+Ic0!lWdmEZdDRBsF?0?Fy)cIBfL{IV$b+R2Guuu4 z{18wE{2WVkeHI`-9^R~8|HqHYKqGmV9Z!f+M)x-^{h06lNk2~brNG%C0_cQ`2QAmm zNscq5keiMspz2sAV!JxjgNGep!on~0J2Y_Pwn2$+Jx;I$dXcoeCsOI^#ojis7oDFb@n4>nObnC_(JBni0kY-6E?&6UZ*H^<8ho5q@x6H1mKpIW8rS2Sw{b-v zd@brc4Hm$(_-nWqDs=tsYz8x1gWfdZdAdxgaVP)k8;gE(dF1c5`Pkx1LfDu@=j-nG zj_iH?pZ@V9eyz}VS#?650es=*H+}O;U;9PzGMmj9679e!Uj9ZEZK0X`iHSD@DBI5DLngTBk{*>u zFxfh@tb;)SoQrDpsuNxG2OmzetL?4<9#mu-qnc*hO|Nk9j4MziLF+Z?VvM^m_lz;8 zVqo!RxswBD!)WO7Ow9fEjT?CoPWnQd$(T4B1Be~Fitgj}=$*X%6&r!DOgljGh5L6@ z_$8MAa$H^i*)KAT$4~M_M2-*jG~Qzo&5!gm9#04Ks`za{VTt!zn}ol}g!mzkpPC2x zQ}_J6%J$Iazaj?rt}J)CK?e5)m-N|RBUaQ19LeoJox~|_> z85yAV({3wap#0SdY$Gd+;YYEDYHh-_3cy2`s{W z#dc=?C1!vSim%SYkb{=-bbNufIeXllQsXX|i?xzj*brE(yxfMyEA}QnH2wA*R68;> z3R`D)%Rr`Kz4B2_&kx&Dhko0vwyy%DVs3Nn8{Bzo)TO2MB2){}pcc?jsRGZtN0VDjee_LoGxOE&?3Z|BoQ2>sIMHKT@mXn_v`s6%XvEk&H5_F43brQhaQy@0=+S6W(S7o zB$^31_|jurkUG&!0`%z+|7eSXXH%^^?!?#C$R0e24(+(-~H@k9TeowD0i75od5ibIQuJ@w(4cX)Y3}?1&0OF?MxzQ30jF% zK#8JCRn%Er(1JIO6;ELG(-Yh>GdZgv@hbSzeAG-fgJb#MON zM?45scXqkUo&o&zi*NKNG&+8n!0Od*>|iLQ1PY#~C2Y47z$6n53EoJC`c8mYBjJE7 z4>mGXzLGF6H0;}&n7OTJTk^n*8a=!>K=x?Ek9{=Ycl*Hu_euZpXnlxUcyhwieC7l<@j8ofMSzdS>rk4~fW^ijoaw&tM=|p9 zN@lpS@Ryp1=dV1|m`z`=9*EAnq70w!Ok?L>yS?9iuDj`aRtw?9XrBJ7MY1ujxF`&> zc4$cq(S#2k5#dyamVS0uh|!sa4F-W!Z3hyzA|E_7`gzglcA9O^WD@9xkMYNSwXbi_=5+O2@ZKe$fPrqN*8^E+MN&wU7_M)SMG0Ji9!dX=S zIhF`$c-A#MEp@H4_||QKQh|N_0Bir~J1jtKGy;?T@BxLk%TEv4h}WJm(}m*drde3L zK)MR@`mul3)p?M=*J$-~iO$)X1iG@#FwF`^C#}5s8iuFhi zm|o~Y2e$U~oct}n{fO*FVDF?di^82`L25tuoj2-3KM6)I|8uq*#_J7O63`2zgMwFS zXA)ROsxo&_!39`R21cO5x!bb5FnSQ&Vaa@hw1YFgzF7 zJACK`Z~5)dI?tFp=`cm$PBQTLiw?i%(CX+zF{IG>EarAang@L@^z|AG5xhxx80erG z0|JHs^>Xq!yP6<<#x*}WAw?f_1oz=Yi9Yc>DOHoiqQ^%1PO8A@+tD-ES#q(Zj6AwHy!vWgU3L;b*12G)97#ed3axkN=6egie$2ltJfcr%RgVHY1J z1eN``9p%b|`Gr^23oOFYG4NoctVw0^I5r~PNAPoO^pt;qqSo-X5n3?Na#aMDn9j=R z2n(1Xug$<`a^?_=z81XYYd-k|1Wz*4CP5p#Ip z%}0oE=aoBEIc`5*XMfIcocXgrRjci58wN}e;JK~Ch;-3V0)~Sz0t=&~`wl(|d{&32 zUxHWs=!4$!=#n<$qa%8YFH+u(sHB&iWw2`>P~JKq#BTJMV?VHoc-xzNk_dFf$`3FZ zLwGtG6YVFei*Mbu%g6TB zliT#U4iSom4w`e_J)STMpiaiqeaS%ZOFY$Uec>*{H&K2NgZ-uBLft+##_*PbKO7LE z=q*DxZKP$?coWk{x@6*Hc&6d38qLRLL(!pEvD2AGZO~9@EIkicb;|G$RvRdcWlbyl zEktc*MA{$wQkX3p0h>T?2H-h^bE`mGFWynWzIFN5L7K+Kkk7s3RzX-`%pu{R@pl62 zqo4M_y!AI8{E9MphgNsmy8w@U+s#)q8e%~4L?(h2MF)pY1FCj#8zVkV3yG1b-U1Ts zrs{Cf2QjsE(KR1x6#K2VCYs+elTJ1wa%9-h37?H9IFF89ACPT^o)suA$!oUcrcVr_ zpu~!w2~z$S+jfAV$F9%LdeH2b{_&*FBpoS_U)b19V|}9(a$9hk>drX!=cR1g4@sLn z!`PIA(Lyk#zcH$bM{rG^Fhd@3W2-@BZ;4ka+pUb?Kpe2KW4F2JY~uzOZqA?iXY#<; zVx1goDf=31nk`Z;u2%OZ29p1{W~Vj*zhiJjx#q-&zZ#SO7)))>^3IECYR`FG5*MDg z0{pHM?=)!hkn&#_*P{024m{i`O8?rG+xy(~p_^~;Wxr-IM*Px&NxNfI<8xnh-^VH_ zc_@|;dtwvyT6k*sm(}UZvJG_bSzPd0Q8(ie)_~Y~OM0;yUoiTZx(GPk6_4^ z7ho)Y>j(yX&jI||Q9nAu!W;egQ!bZta3@gFM(%zittnch2s} z>)@yUYz`2(|EF*Tp*~Fd;@@o zF=&i66PSUjZ^5+bfa5itK`S5#79SDIc3(A$ffz$gsebAie?Jc>i&npEQnKhB*#zs- zR4P8AY(VoXiT1_vrEA)}EaCCE)n@`bOF;CiHabSz_UHa;Lhyvxn*ajAPG^;p#egRi zeSzvNC?=r4xRSB)@Jf^HsQw4XeLgR`P-mSwAU53t$3K|RyD+x?K7ctL9l)~iCV_z& zq}m)?VbOyl`puVpl_5X(k9-K{QUI&bAt#4Yiaem|0-eUUO9uuHevglSiMpXk9LK*x zbaj(3eDZ~F0A}&`20$N7=LkA|>Ndoqf~Z*}g4 zH)|*wz?e5`c*HWnxXj|fgwEJ~#;>-65vWs}yb4>4d17&h z&*7^%XQ|*us0+Tj(eg#7(wNX^ z7px&X@b-rWd^BKB6{H9Zi|U#xdT4Z;+j#nv^wVxaqzgeuFV9VyQno%#JiXR>w_vNQ z0)OB~i+N38kQoOMlaXcQ8kQLPJ$1btZxb0frZ)+hldL!*b9evna%L z;@yr910Qx4liHbF!h^NW8b`GaSKF6#B^xXNbo=OfYzEdPh9@<8X;b&B`;srL{k1;% z(q|75vE{L;9zIsveHJ|rrjG8t`NAJL^GULBOkpE<_f1#TMgZH9wLiUJaLxWvy98st znIe|k1yIHK6Km5NHvv5K=oPNwHDi~~nPTfG{{$TV&2^7<*+=1^mGUjFcD z;DUTAuNoOrN9M-GxEg=kIZ(%v*Ci1F$(nE-$npIepWhUAj8$Cq6U|`!+D=)B#Y9Jz_+^30a?2w?a4DwA0|D{PYDM$(YaVu-h~UFZ z+X+;2$VxA5Zv?9CEAo1w4!hF=h8W&4b=wo$JS}7t*q-%p5XqASh`f>v{ib=0f^n(8 zcXaP}F8rZ0pJt)kd0-=W*T=77%3>%*HO=I)iK2D0YazTSO04CBlh@kC6Dvn>k{1xn ze!i`WZuQM?qcb|@hWw1*^mYgT$31?@m}gy?2k}4tp|ov-o8+0rDl=R3C;wqi>~z#; z(R%|Bx}M4K;L!7tjX;atd1OA2Yn1Bcs|Wsz_K`#X-#cFR&~LN8PvKCb`xG=t^bvn? z^G1t(%?D2ihtJTWqnvgYV)~52bn$!!Q!iHpnK0fnG-v{xGd&}xNQz)kitj{oP{7dX zgwhqw6yQS!y837+Pr0xWT>eqr8juhf^f;`Q zsH+sslYYi8?hJ2e9h!^0f33=G8%X}!R_BzVPYUs;#7YK2%a}u6ik6nU5vrr{=qUiU zYIX#nuI+35u;L3W1nB#ygZjmX(tH4hm_PaF69ReUGX&ZY{1=GiPHpF!O~N@BrshSi z7}VEh@x&vab;`?L<{JqCKe>_-d~&jude~bI|K;8(n zQv;yRE7*|Z%f#F7n{6UqukPC>$z{||G5~emR}-3kTYt{-8IN)DJv7EA`q9;^-tmG5 zJ{t{pbYUa7>;`QF<)W-rnKnDS4s|pFVcen7$U+LIjv_l7b2%^G@QF30st`@!ka!p| zmv5A4Eq6!V3P@p3-`q27SybA1mF(C@B6XI=&pcQ@60WNyR`>(*D5qL`Xdjk-G#l{%D z=q%4TN{_1c1^c~dvw`gDZ9Pu#Ox}qdw$)$)z^{9L`$St~%5#JGq)Yu@d;570xI^C} z!j0nKsb(zlZz7cPG6EK!UWVw*?kj=13RvqS#h#zc zgSsuqMj#n&8v4ZH_TpcBC>PG3RGCKmNr->epWnRoWj|W<>ILquW`B`Az;4@&Mye^S zS9V4o8+63HFZ3tdOrLPmg0i{D6ejY*YO(sPiA$~5w6-B4bOqF-~IB^;gZfgP>*ZU=<`q(o;?)i@l$uxR$}#9YL3QNPOvWWzRXk)B)bz%G8w zOmm9(x(HxM;gHWW0{IDGC`fY}-w;p3SREK2bA{pU*cMOyTcVpOzH_eyzvp*uAV?R} zVB8i+k2VXQ73|%-z4_u_df4ge-R@GOzuj`HbF}z*$mf6S&1mvFY82;h{%5*14&UQ5 z7y#D%KOFmR@AL5?}?dT2HOrqx@=%9#>m_io7i`E$U6d|fP=_DTE<_IRVv8ZHEOvm{4YI&?ncE2^%O9+?Sn}<%>3iy#mfKq5)w89k;d(UHiy#>pZdtZ zddXRr%@o{bbFy%o&;ZVQ(~+AGow7aEi(k?V#S2(%pWOwcZ^arc_xg-ELslP-2!3+z zQL~%`&@V6K2HySPZGC6KM#j<-7@LGK;SGJzC?Z?A^{UB&GR@qy`_dX8B{%#joP9%# zWR$w-lqXHsMqoIYlJjm29-9>2`cWBrDxta5N0FGak3HIZ+wDu=`G1`GEyx`7!bWh> zwRJ^+vkb=rY0t?izr--}!#&2TGUD1jazVTJCeu}aj@>b_4{x3iiM!b|eZxP~8bhc2 z+oyc$3aif4N3+U~?(~~9_qnkiVFNs>{o@mpU*=?833z_chNc(K1TO!D&uZtb`nC?Y z3;f_W9RB0I)3$$;Mcs=Y1$+sGYpgK{bz1R6PqO`~KrjOKrF=&ZY!(DT@67@tBS%Js zy82#RgBG%PNvzLgTIXCAwgV?@&dz0{^_Sl1%$+fL0Rz>`W1KBg^!KLGn}O}1i-kWn z7xiJ#rwPxO`Anqvp38p4=*ae^7yrQBW8r%+vjZE!JFn@7g^ba^J{Na#14k)1s4MUHwT5IOxa-d@b9p|wq7ph+m3jNhib=y3vF z=oQwr&iI?vOE3Nx_rF`5@#Xog7B+&vy6OY^D+G-Xqz6fZJW@lV;RsG_bCPS=%r(PG z#%#-S&@19IU4;;jxYfBAZBPHmM~>Wx zea`lK^+A97jNWw3>Q=@?&ki1S(8Cj$1t0OSIPQBw>GSIBL^Z=?x*gmd)mX zyrY-PxtCu0&rgnppOH^TZvW*a}~Zq!ECu+n24Lnq9A{)uPy@i5XmY#_Q1_ z@BRcffyo1u-a`4zHyqyX>66FU?6>_aSU3IN0K}_Mx^BhP4BWe?H1soo9)K4QcBLGw z@$71lG#+mQ_RS#omh*A7e~MJk^N2xRH0i_>6S)!S-eVG5v`@ z$(m+e!qoyrl{c8$2w+b<^u`x1pVUgyY+DBgi&E*zrc(e|JGAzxWV{(f6#KTPs(tpQ zTKCbTOZ`i~=bo|f8TP!e5xo8VxgzNNIc5Tl&9(%Z4vq=$E6m!&4KZL^4Ey=LNWcQk z6)FjWP*v6LYjXD7o!d6t^3fB?S=%}|M4sBEl(eqh@ikURiAH)xLxJ^HrS>#FYtP(G zGk$YBsf}QLc<(RY`*RQZykZ?wm3PO`P5AWJAJHH9NQo9b23ZNz+y>x~Nv(mth+b5Z zrtP8;TZRtpBAbl@FPOO;u)-A<6P#tO8yZn8p3kK4tjk8SXsZdd?WRp%-dUfTwOLpn zc45~7w+iz$eWb@j^_2uFZDEm9@uiu4fG!Qjng7zuzWbiJ@DrKo$VTwC z_v#rzg{O1d2tqarVK%|p2pO7wvZ%rjH%E)N%#cU4b##82wcRd@)~&XcgtlY9=%_~< z-R5_{hyqA|08!NTMYBu=z!)Js9*`m+mhl0GI2CuB2HOg1Y@FN7|LMUmm?WlF zp(aAN9{6WRHu`w4KH{&yvH|Gj6))x726SOTk1GM%z+ei;qQn`l7^oQlyk3040aig4 z=k;S08$;2}1A-2pnbm<`5N|59TV%#F4SL-INX5(tI~F<7y;udcJ^J;+=CCayZJ*g| zk;jHGY$_#VVRm7#j7YqCvj5U|{o`ff6XyMejo`xf>|PNJOviO3*|TS2JI=}3M5Gm5 z@}Ms1m>2guPy6H>H*AYg`9y4Z03WRD?m!rb%mag<&+QaOdTR&;NR{I)_&3uR+pT!A zYsZ8;WpDN5cfIiJ3+7sB&yW-A0k1oGMWK~g>WwqrGFhZ8A9@zP z2im%j5}t)Q&eF2RnRrLG`u0PYL>4O@md7S9e4?n$CSjWDq0hA1jlmXfOfJ*H_mv8E zk8WS`uK(?R&qeK0ZeIl02>$Z&z9Jy_iY-AW?wWAUOU=fnV}aE6)u$~Ys^YohM)>3V z0HV@*i*2m~Uqq`Jhsv{knv}Q9Sh&c7X-4_7LjzLuRzHmoX0aP1UDNn9t6Qh)j>CR_ z)35lcbG!_q6)$Gx{(o@vZR^uEpTpwsOMcfjC~$8EKGh?r1uPnaW57{HTUZiQbVnX1 z^+I&+us0Pg9Fw(RkTageqypV|%g2s`i7ve$_tX9f7nywQR(|kQRK<9j$jLX(CZ=K6 zXBN@Qu63#1wtVJkUTr9-2wvf(ZGCEU-?d%8e~NB+=% z*RMrAHUL(LUMS=?pbeomMpUyg07ET{NmUkd(c*zIVvQQrE+|DF$#Oosd$3u^Ad9bs z<{%*N7YA{BfzqYjd>Y8q!u4WCz7mZ>%>(pPm1P1;)CwGR9i&5K&?*zC2MkF;ln6uC>D_AS1Km5Ap6w3!Mw=Y2q?jKLNvFabSPQ zPIk<$x!iEvK>L1t`jG(B_z63=(f$=)mA#|uBK~^)(^vlVL;i`8_y3clKdZks`K~N@ z@z@B!2+TZpyZXp`!Am6r?c$cb6ji4|^K5V*t`;`XmbN|?8ilHP)ec>q{N_wwJamkE zL6q{_Jf8fE;IlPKiaxF$>MY)PZ#leoTG;tj2v-Y@Ydz33&X>IRdCS5lWOsF8Blz=+ zbVWd3DdfItPCR|qAM_cANXGmr{i71b{`H&} z!(t_CyTgBZ+B#MDLY~GKzUgHE_^y93U^S%+{*^y_wwK=Oet&Y*U+C$xy{`hKG`}|J zv$*=aCCH%qqrj{Pc%11eF(CdJe6Yw!+{HCOy#|eyW#P~bgg>V>W=3mW4m5PXL{;6% z^Vu1N#rKCJuw0m&$!n7+jO~vF4-kFvr{4+Cs9*BF=PnE1u{yyAHiEbORXrn6vYe}# zPxPJtqPaigkNh$%oNMN*XO~gIqhvO3%qa{q`ay-ZT)-1kql0r+ws8Gx$%f(=?jp|74-r4?W{bdx!h zVmC2piK>A+Na<&RmP}Mx-jQlOmIj;vW&i*{07*naR1ujoEymd~&6@(5v%4(80`Eg% zRqZ?rkRFNyFrEoSCwg7z);k3N{q@=~kX4_Dd++=E%fff84%mT>;LUHJJtJuUD#gh$ z9na+Ey7sg&P6vvs3Fk#sEVI=PH%ItpH>PVVtNB`b2WvE9&s{q*+3k60vO1})RENSv zaN^DN7N-3#s1->1b=JTJ;Qw5ro?O*p(}Lnk0E1E#fN8Pw8sKsoeF;Zils`}EZFHI@?$4w~Zh;O7bR4pYdmP1pv`k z0=2L;^S#8qMOa)-7cGoSa0mf{Gz52dmmtAH65J)YyEU#a4#6!*a1E}F1PvNo8+U8G zn})u8gMa!D?;W1euBU3Bs$FaCT8jcVn_OWujw*<~mPnrtbCy@5LZU9_og_Toz|69U zRA(}yQOb%g7JP3cuVkh8z}R`G;PQAqB(ktdWwthyYLg-!^0~tp*$~I{or(Jp*l_Cc z58^^+8H=mEp$==56}1ADzX^0RZN(Hx8T#nnp~*0@b3hh_&Z8lq{&hnL=1!S$Xtr>S z6WQ&xC_&x+xSc*1_^lb(D695AkCv@};At2Cr?6mq({VAqe2BjjQuE2akg-P#?fSv; z;zEXEu-+&}c%zM&S+`^?zE)p4nJu5Ui1;1F(N>&e$MDxz#=dBL`K7%UR@US?xkU8L zFe_$*z56L78YmNSm^#xLpX6?QQW!i0?peB-Hyq!PKygHKfvFY{`LZ!AWq+s9FJl~= z&ZCHP!c6nSUt7U(` zMl+sV_^QSTnxSvMq!bp82`H@9G3?Ne0~Glu>tb-2{ch;xOf~>>Rd^GMY-!~tX(_N+ z%Hr^>4rd%}dQn7PE{rpK8K1~Y_EJMa&<5LP-;Kw0o@Gh}KjDa3*T3vi!Cl2Kk@AA~ zJu)H-%?gc_gu;YhhDf1Qp@(x>lLhhxl#*6A$7pFE|4P_}oXlP{`Pqi!Hj7tnG>46G z5t7fI)>@^quJup6b3PTYJTP5j$+spOez_d2)zR%aa(o#NZV`Kqzms={j~)!-F6M@4 zBn;bsZ)jLOY>$?m)rVu43qEc}9?1SB4e23AZTc&9DwN-^9=H6BJIIdD`8^yf|LxOX zX*3fD%pJ7?*$f(}G7eeK>{gkVT;)?hiv-4Oq|v+H9XGzrOkfEjZfcdXzfjW!z(+5k zrI_!>ACtq7ecE)S7t`CobK?-AJGvD&FTq|(VI*M5DcCkk{-e}swut}BOqF1h`FBy= z?)N1dfxytLUX5yw<6A`8GN3^ojC=U+>e?F>2kHNyD zmFX;%jBMaLfG$#_z1!TMA!9`+;5>HkJ_fZR(jWOmYhxmri^-qBf1CqQUEqfMux9h6 z{{JSqJDWYs;E!aWX5j?jpsSoj;^^B1J+J?!oN)CcI*Zhs4`eHzf#a2aV&!dhv8KO& zl>k>>Q`j>-xF_S&Q1{Lms0q2Rdz#V%Z=!e?cUlIHn2|d;5tl5&(}IVMvJq^Q1Qq#&^ZhaFK~@vi{9O^^P%XSvMDOFUlT{ z2=Ma!FVfvUx$c~P!%a1^#Jha;QXe`PuXzEfk3w^9)>1)T( zw*LYHekFEW(cAVq^t(0yFb=M1VfUsNCBp)SiM=$g?*jL*qUZ!}9Ylq2ome~r=8o$Z zFA}0A`(MK3qlM8uYo|f5>~cx&)y!SuP{YL6nnd_kk%yD(fF#my#p$&T@vp-4YVt>c zi~`>@HFN7nldX3gtjjgr(~su#SO8uF45khKm)^2EC}V|*C!ba%8bTR0Qofh3CijVFwBBhd!U*3vz+;YV2@$W1;Jgs+a z;$~03Fr2sptzM4t-?Ww+xet;?XKSjllD#j8=;7r-F4Eo?{oB00 zKV457q5&UOzdrULzTvO2Ccs>UbAim-^dudD_jWG+vpK;Ey6W++#rkx*q-lf6yGetp5*j}Y3u zMWnJ<1@m)VP8=|@0e<0^*P8{`OM_4toBl+0eL*di?}F#l-o$!yjBkc{sOMVzfXv+V z^4l4~-4U7y@+{8kKIeUwe2~XN+;q??r>wQfCb0tGt^eu0M{9JO%Z)*LMC6`T0nr~f zf>l(G%WcE&g_EkF9tY_bBX3qcp`nosy7 z8H2>3;ykZ=IT`Tic@>Kfd{8B+4y<5xIKX8#X{2Ag0qJ5-z%O>^CfD0WlX1>65rH=#w(a9$<_&0@$Odo@E;7wZ7DB_m4M-oY4wjzFw(9YaN>9S`IGP^$B|D@+d~>4@Prld_Ec5> zgX@P6t{0&09e%0%*#*p2_zKIfGTZ5=?X;t}x)a8eh_&vKOKsENv#xo&{$8^S++v5k zBirjttQugZvsUC)LX++d$6jD>Nl`bZ819`J`8o&T$klU*CgrPaqy?b=j`?GJhpE`1SQG$McW1#=(Q)Ieic0b6+B3R6WDr%iT4LaFBbaJ#r-_q6jUrV z94MSPumk&lp%VUoM~nRbKZ?j}5|qCLTy@DO7X(a>OzAth1ZBK1LivT)76x_J?&NQi z#-+a^8sMvw_D?|zmxeA&pcWIC;2UY_N94?P>S0gKdr0?9YXBJ>&Zucvn<(YbqA#gc zA6;|5Xj9(`Q@YDtARWIUg|)4@EE`h8CQU)tDF|akP{1L;9Xw~@leC8P((eTb8c&%# z7`X+lBFZ&{5KZ|qzDzSKRk{%~?^!b*Pw!67tM6E)ul_Y%JXFOtHESrKO$D6X{}48D zhXjAKcxgOy0G=x2Z)g!$=kMtlw9KV#-g>UrCBAtesc(lhf`c{J2#GNe-~;a zxl?@8ntKjnRGl*A^yD?G8gxB{hCHJ>V8qPD#KZhhzng9-W)5;D*_QKX9%Yjq2kbjhtqQ-#P zvIgv_<-5)4-q*+y;J&n5o*lQ}373Al!AGCeQ!xQ9Mm2^Q7p#5eo_uZ-SF9yW#5U;@ zWSShWpK48fthO)qPY})Eqima(J%1oc`>%E0|3&A9zMOmC&@Yx{xs1iWd&%ni0~S^O z(A_YW5ah#4B2C$z%%sBHViGX#h_SFlu_bQeH)$EX*{b<_FlKU$ukO(JrU>xO0&xc! zPHU2jQgaR%5P=jheI642s!gu->+g`%=_CHXG}Q5$2{C`y$KR&@kJ(_6U9L&Z4=B@q z1KKw0R}cbVgiKR~aNcpt6^SpAdLe7wM}qH;D9!A`4NFrF>cF{lt%9eY6TkzR)qqv3 zMG5}pIz;gOCWlTNXV<0J;d;Pn#^2c8?!L4fi;cO7` z@RZcJxcX!w%&;ENyL-JJP%C;!j+mX`Jp?9 z^8kTh?rv_92MB1@HZK54!!srKh=Y9fdq-d=Q&cPbt29nz3m>sj`foj*yELVwV5l_W zHVJq~e?Ih&qA<975fFH&30K8FFSJP6OzG!7ED8!!&0E1y_SgYoYe=I70T^En*O4}2 zL$gf*=gQ7vw<+qfOH;@9g@Gc|7)2oXwJI2K7Z{z?u;?QscsDo12%0!OCb-Q*scYNEYt z9lp#Xf_!`)x?&-7neGQZ7CqQ;1o9Lnk*9egC)M5q?tZ+8(qpNt8nIkb@E%XYCcpg;p3gWN78 zzt>HdO23dh7rP_i2OFuIHU!T)n8SrC)a9wW5N>7xXVZssjJb4^4ANKT zXJU&iq-S>I&Tq~DeDLx)uF}u7rH=A17qrvIr_riC-1_vfHKl%Zg)%1vUqpi+{9GQ3 zMU%;juT+k4^k33#rlnv@X>f5!S8^i5x!92cCR*@P7~fy;QJ+!Y)&09P=OlAIw^jAx z;*K}Zy1|bw!CL{k`!0(Q^jEbEh!Umx&7Rvo>>whB8y`^Fl)0~+2FO6}``l=0-(miy zq?Dcr@f?-D>q$vLYfWB={}Q2yaO~EWRzYtLS?Y8FaOWX#01O9z^5dQ6KEt^3xO|EP zAsiyRMZ4NU#l4gTdG`TxoxJvR% zLCZIKaJ1I~;Op!=WZy~;SHxCdV`t_y1q6PiHocYvAcSAOs&H?y$_GHk33@M4L0O`( zEYmTM!}KvvbP>?u5T%7~j9^^I7%62W*MIX2Ui+x{rr9_EG$ifVUyNfpeRWeqCeS1k ze|S&ueN)g=64ncrH1O{sVh@w#Quk7MzJq}XgfWw$Zh$Gd?R>`UiwEL!9-Ww+xz|v) zvR!C|RdNf++j%*dNLaL~?jJSqtf~L0yN|qW82#aN9m@b?0*ozqnAZyDL%OsZUxC!q zw)AZp;ISYS_(unPjoxz}4Eypy!sQ7Y19HPAnR2WY^y{xFO0Mt`J$wI*=7~R=q(s$h z;7kTHJJQ*g?vmted@`iS4!ypigPE_AKtmdRsoPsb$Zauc^i8qIv;1^H54_;vd7vKl zF`iy2n@%wkwocv|?vuK)Mi8{UUkI`F^$k~pXwaSC>i~J=4PRKn8Ta~HP$xqt=@y{i&vBa|N&dIZOxbC~YF3-1E$+-1F3Z0h zd>&mz>xISzvjK|t#|txUO$?G=y`OzauHoj|sEX0vLBe)E8a3vVvZxa&GYebUtoov! zT2=K<(?#;Af33Bi)xE!LB(U|40(iA0nG*PtD5j&OZ~sb5){qtZn+t_36-d392LFoT zqkGFdcqaCw^d-Y8Rd`nRFy<=dhY}!R9}JQgfmqfKl;qlbHL|pU7Ylf^S_6gh|6NMS zZDI%BT>29L?s^i~rDK8W_GvCVt+P7`fvAgFDKS58>O$|cZ%GN*8cyQygb5uNHhT># z4wRJvV>*_D_L*{a8sxeCCrKG8=7a44`?DpNFQuTDA$q@?1)N6YtNMEeBJlE3U9_4n zbN&jCUGyeJNE`gK*v$j;2x-&!_-ac-jcxnr49y?PBYA7p{Shg4Oi3~+5qMX?`9(Ac z;S#vjrF$W4@T?B1ZhMxv@z`g6>--~L@|>Pw4gaeYB=jAUO6$#5-axL5tV=3ppgw0h z1>u{LqwdaVDaGXP8u`UW3$xWzjUj4uTd(7%t_B?W!dKJC4!V#tc|?D#Nk~4;nEKO? z#E6p!%(;a&DCgOb#HpMUBp2IxeMO>pzo(C+YjWt#8Skh&JgQ4YF-~hOI3H!NnMkt) z%Ht)Zk)DUV{*(01C}23_CDg3$vEzI?b=L{;b~l;*HrptI%VQiPrEqf!6MWTt{~ryy z;UL2()(TqQhXlntt*^e_N1Q<{G7r>flS^Yw8GU5zCXDM|e+J(i1(!YpVXaEs&wXT4 z0hA4f+}y($S1gFSwO?8M$NWC|{b?#+ge#*KMSV`3qNGca=0E@Bk3VwHhJ58dcP4)r z`{1n|gT2p&Y4%hik0>=htFG9x@$mr_35B}A{;l61s!D0zFan5^3InDeRX*5!C&`d% z{2)PtM|*~MXJrqglVkSG>^%Rhgb~!(`1U=zfv`zebYP==$-r5fe6z82mrGe^3Z)4-tk{9+@$fa z%BfrB7I!IT`QlO1&!`z)F%~Mgl?e*I-KS>WJ4!#u;6y z=wk{Jj$lLD4J_+AZwZC5C$#2>u7nf{<-;=yzZ0S#RRpAmmT@(1d7u?dS2UpEusdBr zDIdxFNgju}|2j#VUhcCuVZUuWkyZOAJf@NhCqKLSUck#kjI9`P^mS&A-4A_+S<@e> z##X=R%N+XNr~1Ww=Fy=r+3C@EuGxp9s%k(tRL(&$Xe3_2#%6 zg1{{9U6vc`QIb2Rn^|>K=XWY-YGp)LVFpacd5vZV7s#8duKg8H#RwX+hVbJPPW5w+ zczvwsFMFKEA~~2%igcy(0aL8olE93SP_iqHEz01_fak%2peeAC+XO|Ld_G;yx}E%n zx>;H(%-4#CResB7=QJSfcBs-TO!-VmG@8K9Zuy!BZ8Q1w>k{6kt^7*Z@M$=H!7ur9 z_J~GHQv{79?8@{pRyy&;kgE-ZOxUB4{z%gy_d~u2JVeMPn~Codha}Emo#s^T&g8_~*eI(3yY81a)HzqDD;Ue66>e{^T5kfuJX zlnLt8ys@}?dRfKnb+}u%e@*~h_V^tHA7lo?pikKxXpt$C0&4NZcoyka0%b-TU;T3n zqhjA8skw^&w=5=k#Hw&N1CV^-w_t#OEL-lUUuEGjLF99fVxfN-#|>KH!LB*qZ5l71mk#9$GiWgg)xF}GlWB3c%V0UAh=t+dCU_7 zx%~ENk9yWE`687gF#|5LPSoNxN?4Ohl^Sf_gPp&Vu7B5F1BE6VTm9_M^8E?GKv0|J zWm(EAqK|1u@iX|&+cjPVv8W5|0A(M86AGODQAa%ksbghp@{8zW`2Di6N!YQ1(cVpt zyJfRXa}*7b;O^&mmOFb=?f238d`@CgS+%T3Bb)hoi}x9}AbGEA>`M(EcLu@|>(lEg z9Z|qfx-OSMw_c6VMbh-UiN!RZHdb5-gMN z4?=KdMPC!BUFp_e0mE{6X_T6}pfFn5#|Wd|!aH$I^N%*BMjtjC8;3jT(!uI#cqcmB zc!mEPcQ??pZI3@p{Sia&M4)m)kjY^?KjGdkTFVbf?eP~b0rg2o13n-l6NZNq81xNg zClpT^)8&!C)9y*G3-&>@9M0?`eGLrW_ol(zd?tO(iD4yR+B^f(Sc~ZQqavchyb57f zx-Z=%woTZ^d8Vt_E9|1~kqSzwZcbMOk0ltrS+XkZB|b!UmITDEo@Qi4=G6W;gmdB{ zZ;DoYuvbS4|7ivMXzrKY0da{R2`{%FiC1_!9PQrPZ0GJ4|ns>8hly z0lWK&{m?167gdu_kmx$!cOzd4Kf28a6(7}1UQi|1*;ayBK%YL%V!aME30G?aZ##>} zib#gJTug3+i|<6U?Ha3T$ zdzib454ht77Ra=CFYIAmv0BQ;qBf&C~i^qiTKE z|KGcxGndfvq|f$WS@g8g)#ZbuUj22_v7>8mWyKqluaEmYHqd%ss@>NLgU1f_3!t3e zP6c|)YfoFnGon?rWv8~u2|Rf+=ZmVEI%Twczk)x16eq82E;`(*qRF}4msed2(NOOO z?5JJ+-B5uNeJ&GZ`mb7QiS(7c_pq)#EEEX7zf%Pb!CHkw{#f1JD6mle{UYsZJ+$tZq!5)BqE0x+G=INOS^hbuYCJJB=4xFRCJEf&mY*{)Ne%c z-tq8PMlm77RB6grNAo&9YW}kpRu>r5W-90gKV%DD^7dUQ&e-TBhmjz5a-ZCaO0J#9 zzn=i~NFHNjRj1!!Uo>7OyjDN`Wiip>J)PDE*pnqmRGYtfVf808ndWvNmDmFxhRFrI z6wLwx*o8yuHLnjVnOvSoxFZuxIrz%lG2>l63|}k&covMo?)(tHWak#b zf?Up;aQ^L+GL^R$B$Oc_{-}F)fw-;FPqf*3R};kJtb;x~Wrn@$-`jRORL&SoE7lxS z3tu`|E4yE^upRm!+n-BEkoBmj0q2cmF*K$Px7r``)wjA{u5%FxzoKGxs$Z574y6{B6HOG4nB_hwZVHt*Xc4su zQq-WapNLpx9NTCgVZA+W^3qURlp!}^bDQ^|eGx$Pt8@w*CKjz1M|ZVj+mQr!t3_a6 zYaQWm-O&&v2ewdsn9R$TLA%#efDLl8!%j6T1p3N<2qm2N(MTECE+U8tHtVt$n)oVJ zk_S;?e&OEc(LStNde44Tj}YNYx2@CO4EEsOy+I{lL@1Kh?s&7^MQwus)>}7O{Ghbp z3%Dx5WxM5jsxh!c-Xw}PA%pe0ijE~?LD2h*e@R?>{qu@Yadc`_AttEOh|~ubTy<*d zE^dUJj1E*4r|ZQ3{tOS{;J*Ow``=kKoHpZ~d1=L$#!Bb%CDJg*%f{A^$q-F8uf4iE zK1I3=%9BuF5BijeQlD*d-txKN4KuIiSX$eQ9oDpl4p4MhSjre`*?KVNX4R64_S`6J zN%GiPkFYa+ggn5NQit8aXGsW%8_9n^w<%fxE$VocrkIIpscR@1OtKBm2>+*EA9P2o z6QjUC4NbXPcag<)3^uM0fu9QhY-lpvlHi7g=htq(nvljUq`!aTw%mnYTwe>RhwXuH z0cacd7-m`6-UInD?yh|8cHU!y>b$T9O=pTLIA_wm9DWGD0adpoeh_79V=xPO2hJ-7 zLafKTMng>i!xZ+^CzJ9SP%6sbZ3enJjuw3F6@nv9cl(x7;k{Rb-{uC_t{G%Zk0OUZ zdt~`Y)N8JlQt0-apt_bO?AnUk9ocB3sLCdx8;=I} z?*vs9hc~#1Rcxk6pA+SGXTR13pxt2TNHEpos*fxCi(PudOi}6N^dK*wt9P1D9wo6 zlIG&lwlt{*k6^1x&bUv+{0x;8u2_gOW<&y8WfOu6Tr{QO<_IT=@J|vp+FFfQx!+>D z`8yqLB3G`=QmE1fjL^EO9MN>JEB58<6ZR9-$dA%GXjx}I)cj|bZX;S+%BN+MhW|*kLB~o9$-Qs^2j7--U%0QIhFsfdCym5n>P33j(J3%Yd zm&~K#dBrYRXu{LA`U{U6w1C3BFXu48Jt=aUBo!N{)|=0g_=1<2yMg5XbUXQ{R@aA# z>lc4Yhsx)KfUpUeZu1KFH-Emad0O2lMBIaJ5zlj>_0PkF*=^4Y z&D^i-3DAh-n4)r~7HYs11BcnPzKLpOcd{Sr7f`tpAomO?pJ9+p)!2B{>RBMg^}&V; ze*TSzRC^^d`=zP(YCQ>|egz>TZ>RdWm;?udcJ8T1{K$wnK5jT&Q22TM{QL`q;)?G4 zbJMN^S@)tV`55|v?2kgu_a&=Sfl%wtE-GE2w=ve^|B_Dw`@^^c><_gR{XVVud@Swa zHr2oY07sDMIcvvTq`FME>q<{HH|F$g)1AGVq?t`Mp^$}9Xq071DDTPh z%ERc6Mrb!PSCO~8_oQP^(bM6J{3+Y##nOFl8ciDWCO!G=BET(8Q z2vlIn-i)IJ!+*wCN)=^_o?gtilwn%`IVFypK5B(ZpHS3ns8Vj4o4TIo6UJJa?eI@A zX9T}2HDL!%3L_>Ucp!cvm3V{W^VeqBi7b!2WnR|)11v@C2CLxaDud*d_qogZIfJaN9&5-`r`;>hFmI{y_PP=1SJaWwEI*CO8-eQA!NOo|7c=J!r?|^^Tg`>GVi`W%a{Jn3;w0P zWekQjy-)^C->XWEDs5y*-_}t8N5_gn!p$s3-cWu-3s@q=N8QW9`*lt@ykyx#?)PXD zrUdwHm@#sag@!3}Ek54Q7xbp3b1UhC=n*nu&TeVpZccanHV;jKlifmGp@h_}#?Cyt zr`PTh!E^GOVnv(o>-vns#f&xVi;p9|@FTw)kofp=^@pS6?qdG-tz}4Qq|KS( zEe)E8Cn*`x^%4(Gha0>znue>3Q-H8iS?{hXWBerDderq*67G9328?|0(zV4EOyp_- zoU``gcc9eVHe~#M-9HlpIG-a>#21(pQaVckW6Ul(#%G(=N@(rU&ueDKU*kfFSpL>b z`o2>zj}0BRc~Tv`Lds=3W%e*@DO^EcFz)t!n*0`|cV72ySjA9s9vD3%PTh6AM|OY2 zjUc;xrc!Wj$D&Pw$n$RGCYiy@h3@W-ZkCBgNX(_sMzCuMoaT{ z9RPN(s1~9y=w%HATT6xC6ndX|+&2m2Fr=X8$!n+e-79k)eHAvh;3sb!oh9}-A6`sJuKb(+t%V z@5PEOz8UAXkQ8Pz6N>Ty!EXyWckZW1R@Xe@d2ZC%nEo5^+0K^~CzLTtL%vrN`atUO zTjvipjPuaC$hKFq!g zyGBAU5|w6?k@DPws&oY{O67d^Sq6k%!$jbBq(Pr(nqE#bH=)q-phD( zVztcy? zKVt4ln(50`1p1p{dem6#hr0$sG<*Mi6bn~j6EQ0bmM`SpPnDm#9 z0X2h@+d^zU44b^Ws;2QPb^pMkw`{c~bluo?{{u+E;SUrWG^QaQ{Zhh@PRZ)bAs}F} zo1f>>xb>o*QFp4w)g(9L<6UvQJmQs=&_k{_SW+O0>^nYMPn9-*vCQ_{b#Geb8?PQD zPW-VUvq|t?lfZ0HwBzA9tv94@`KM3dBbjxgpnPo*x)v_NBIG`vfO`>St6c9o{E&G0 zm+5MSJ7Lp3_Zu>!-NS5OwQv}V<$9U`1B$;y_kfaccmLR-p$}2`A|BIjigf3&n=QMp z_;HdETU?-l*^S3U%5$~E^dY~2(>DEmby^dIQZ(yxA{x!cIIYs4oXr^zAQ>GGFTQij z9I@h}eTJba+=Wc|RbD9sn+o~-KN|zCG+wwcma|vI(N=NE-(cmg&L|dXax#oK`bwJ0w5@c17*kbQ;oFvjIF|l~B zPvGSmP0#g;KEC$Xo*X6LyRs<7R1a+$M+X?h`bb$nglRXUm+t__pXHmKFoZbZE-}h8 zIa+V+Q;b%$*&c<@C#!_*M>@q|ZV4Gn7ilp8$n4Ma<@Zuz&sDB(A#d%whe}DVIw)#E z{YR+q3|D8NY3F~9mq7?_;CDnSTZ-CN*Qh?09Y4-zA?(-y{4RdXrB(@Ax=%ilv>^qY zC1!Sm)&=={dF;|5LmdWY1DF9BcNA|VlFX$;#?O3_$UKiq>bse<T}|a%sPA82swF)R6G)kvm1(c}9Cu{BS!r5)+)75AoQ!ER^}w-!WnD0rYt zs+z<&ZR=!0g=)E?AwTUa4e*O{cS;I(VvGVBZo}+OI`z;A^~OE2lH6jvO*-pkWv4AZ z{^XC%T0#f}V1O@-au<)8A`W0p?yhxDqm+3;IU?AM3q&~)leWmrR1PW?PWyAFMkGwq z&|FKG`?g7>8G^JHVG#SZ{=@DFox8aylpQ$F{!^m-^`yQPSCqBTGa`t4i3LrETfK>Y zq*Fp1l>*O|0g~bJ2qoYWdy+|kddLutMcTZL0ru?2^EaOc|EwjTY?2$O*{6{>F<3rI zedXq=QlklcgSKI>e4dYa`xeaEtWU}0ove*hjHz<55Yz{m<|Slw(oyt;tqxib%Tqz! zP{T7yWMy>s6(Tp4VsHRZ9Gd4gBWHJ1boHCcm+8Jr;CS9tJNIS#EDVE6b|It@F)gZsRtY} zVmPR+=@w^G0j{FfsG&)@BgRpWTervpZ$>ci1d`W}e#UW{iu_Z_-j~CT5BFxPr+ze4 zRA@Ph!#!a!n*}9_=_0P|L*tbZS2+3_nd`HzK!xACCePKN-nfLeo^*0XS8IS#yuqyo>ejvDe|Om8hi&oLw{wHM1M?yZ7PtL z!5g`G(DrTe*kX934kwDb-5J}l2BTR49Opw3kr>b-Fwog)SyTe&+8@gJB`Ipw^5COP=+W#N=y_j> zJ9rr0!Roq-;ZkQ64y=87ev;VBP(Ms}uT&fLdq zMH5O00v}s!f^o-dN#*?=Gz1;7O?CEKV_R|NSK>yneW7V#$oE6Ew^Iqba{V*{v-%&I zqR+#V{#oGTSuA|>y58p7jcZw%J7F_4aedv?%#Pbb4} zZ4aUDr;~0TFL4?F*H$eRgKK6{uviU#Wy7YA+*hh;35P;+LM%yOSKa@m!p+EUw|)p{ z4Tn}pk+eD)V?B@2@%yLGNs=_ZcOM?EJ2LD3tJgL9`3o;5XL_YewRkgxEZDmy8u6aO zu$ob9HppUYgvhb~uiI-Al_V;t(tgnEs|K|eWxdgs+IwWL&@YErbm@Yh>%6&qZFv$= z^g_Q}Ky)zwT99LcBt{?Z%x~1>w8JR^7S}@G^-(ewU-f$#ov)|)Xct*{R@4Jgi;30u z=BKtDc0PvIbW4h_+4rEfYkFzPvxy@(uG)I9kA7($W(54HcxLWX$PNr}NNNzx^j{aV zC#4scxQ#V`vF%?=t#euJ|2acHk&dh}@Sm;$;;f$Lq(i(?vp;uz9zB#y=o!}V=6yH{ z(xT?B3_cB1g`I)~I9gXhG z(E)|O^b!0i%bC9j=&?Q`#G|T>IgNdXN0y5iU-K_j6Enz0D71zub<~PB`x~{|YM)BX zsgl)ob+Lxp&Jook^q5`|Yepn>eMA#R%Xv*7>10tOy&a=+K92wF#YYz3`Qefjl-nQl zR%JeC{?~(ZG2)`n92L-N84#El3*o!3K0JPH9*GL{7~x zY*rUfchrOc^I>X-iP@gp_|A7&-P{fYK_92b43|fX9||5%AF~u=xi}tVf#0Xdxnt6$ zb*`7o-1lNkuas=u9J_nPc;lY~V4C_WgTYV2hxvWw`3PBMmz(gcQXxB% zfI;cDIZOh6M=B=0ldPXgJ#$0Dv%)aKxXM6Si6$P=)f<}CBD37jpR>SBzF4fIeto$~ zI9>e_7YFFnqVPhoT?;!R;f84V2?4IS;kt-SqbMo0@h`3eos--(q=N4ITQIH2#ml^C zC%ZW6{XW5^V|XbKgEf5-LF}N=q4&QNM^RA=wt(xD&yJo(Uj4RO`Pat)|2lT_GO&1p z3|s;bl!#h*AmYD_Nxa(Gb$jk0i+LK&t;YTZ#pc!!yfino`4P9cY-C!n0g@8SF1F^+ z(f!&I_DeH=Bvi!8!fd8AMk+54ZPxUOPE?ZNg5}fsF5mLDAf#Arf`RHPfUktUc{4U- zB=pjE*{87kb2Kiuo0$&6EDlsQk_%B}jnCEriw>^3$9B=j19G~nR2&9mXq|GVy-@<* z4T6j4Uut~wV%`Ad0dY9yS>wVRAu3p)-3nl2iP<(RJn#42;inQ#?}h3%-y?^YWP)nT z9EgQ6a-c z{*(Lu{ih2J!aauH*Ck8UmDl2*U7>f&igyoTDZFR{+Z%sckH2=0X9Db^q?Z%Fk2E0^ z^hQEjhZ~~KPoh;43*s(Uhx;vQ?KbsRDm$p#3M63+JNprY;wW`KcnnT;rNim1-58sZ z)c<`2h5GQ4MQDsOX_JHwnRJc|3^F7UTtyKCEx%!5uJ0wy^ma@ln{66s33WQx9Xx%E zs{#gA!);S~UMyV}2HU|G?VkpvkzTt~f_Z+pa6S#VnD&iEegKf>lMFwO3wK{1jjdz< zFg9GhvX3o`iIO<6fzS3+HQFIz-NQv8S3iskwE=q!IhP;sRg81@6n*d=L-LtgqJHY7C9m@2yUKQR?XoX`2`Zr~XdE=h6Tr#4*HH0-^ z2D5lejRA3z@7`~OBTJ!o=!^Pxz!fc4$`LK$wELyiickAyia;Wf5wbV9Nn3=!jqdsg z+@94ap}OGb-$|&Ou&FQ`SRON)ZPP#N7B737w>y1Pyt>vSJpy`m)zVI%?%Hap5B%^e zhdFoSsJJpS_*Js2lJJfuv5+9*BhKV?IXJ<*ukz84ZxRxYJur8qy)t@R-J|YNO&`yk zDxIs=*D_|E_ z(JNJ!ovE}2n2NZfbX`e0eme`ukP`^u*G!J?>aJE5ZAdBOleZ4mZ>&bqo31n~zVwYp z(+u~Tb;qAR`$*q0&$_AZ9|$3ZXOmq1jcE|CB>B+4+(F3nU)NSTPC|sE8j1RPfEy?g|PX8E|*rtSD46+yb3CfBb5Cfd{^Hx3i6KwtJ7TguvaWO7P%ND` z`)UVh4PX^lOi;w0Kv*2kSq~EjKoCjst+|!X&Zx9}CKP!n0j*e-LS10oTn2Uf z4Fu1{I)2a9N$DLhnyd8SnwdGxb(5#unummWpYTcv9WJ4N;?LEXdEkuKozoFT15elf z*?Ceqsha;kHJt0-EHO@_b`}Z?fO9tP67UHSR9Ol z^G&<$46>UJG9`mv%kw~7lri%!Yg1#Lx&}gYX%c!P$~z2pKl{@F1-a?&3)(=!FV=$M z-E^YhqlhFt;#qGE1`p!r#7WGR`Hx}vT+;w?)AsOEEE=W9Cl)KXc;)S&=PnYOsd!EQ zk(|i)n&sZ~xrj5Nb!bOd@Z%-uooHNBNT2hYLJ;V&OZykb3cA=(M;d#{dpWdCa zncRRL<&o_*t}mNcOm*>%2b?72C8(qU=1FK+0w|4R8TaO8t(7&52EcSuuh-TmRf98P zf>uvBiJs%r3fZUKOyHGCr%Q{Fq(d(B%GI)f#CmUuL6fsl+Hvh_jR2^g|{@z$^RBI&EVtpW2E{pQI7drXptgD&hM+E(pT9!V#)LI(SCNf zq~|n?AG9P@Z(?oio-Rq`E^~0-^f-P{rWN|#qO~56e4$P{;L5*0)>Q7N$oDNGfSCSS zVc{cOOf&q`I<{n7JZ@zAEe1NQQrdd1YE>~2+Q;PMf>>>3ORkO( z7Q)5p9S77^_YsQkp-B=zyKw5jiq+_7{PXZ#<=EE2@;euxF;JZ8t>c>BzeAfH*CSmI zjn(!y|Sl-`hZo^6%b zJM67cxtb4`o-v8H-O`()Z(+m*JBoS9K(GHh&L3??l?U!7JkynW(|$u1S^^BBn=?;r|Eej?twVf%kLdS=agqze=mq`*T>s)9#yZU%9?{9RuehE8?rIMgv2TpGc{8F? zn5x?&U-33y&qG`=j>rc9_o3p4TfGR{`V^Tvx!+iTsP+an0GO?SW$<7`9W zpu#Wd{dRZxFd7Qsr0NY5}PmB*mj3V4gk`C}zfU*_BB;Q?~~{^iUea9Z7-kWV5&Q(^;>JAM5~5uv9`=5kTV9+705puV6lIFGgx7z^12$W zc;<>>yc?#}R>);$dDc*x8xyLuK*@Dt#)>%|)UPhoeuQo9mi%wUs;L^qz(!xHWEl;t z_0s|RN#>FC&8`t*5!c^nZ``&hd}fSrVML_rTh}$d+_@&%db$&4%hyHcu7x;6eW11! z_2V9gpz;JdpEFuKfdR~z6EMS|ev-#G4G1S|6-qk4Q2cX7b18_Fsj?iOsrE zQZOKc%D$L#k1qUl15<>UGAHnAeB>P^ru*?FJxcQn@3#Z9k+-A5K`WX-!5KqV8&Bsy z^vs;SSrypqarPu(EQ4T6<1)<^bSx7!YumK74mL+$GGra||AJ-ERyHXMtGaaMtOK3G zbmGti=8IKo2hMj7v$IaYtc8mrAraR+Ksu}NOaF8u z<%s+fLA*A6r!P?n;Xd$|uRic&FY}d(;{=5`gejIgcCK17u`hZ<)aqxICTC_sn09Ws zI7V7rZ+<)(@)4T~K;m~=1f#CL@n6wDC%Dvsj=D5)Gyg?1Q76quCygEo3nht%^@lDD zZx5CzX-YpHMbG%NN6u`hnKu$Ph!YF9ME}9tBhHS|C#U0;G_(7L`J);2wN7Yo3U({{ zKLBw+j=xDh?LdIEK2TH6I)uZ>Nf#ro3+Ip-`7z|8I+dXcef4c+4qFhe1!$Ou%1WOI zco$)DCs?yhOcagS)~f~itB$mfO(2*nTOAMNwJ$AW3fSgg=<&lQ@Z^*G>41rfZId-M z$$}^$;VRF{B&mFck93mgeqvW9=Mz+M(`E_16FPo%9aDtiIt9AGU z*8qDCRzjx04`|ET+kPNwVS%PyZfg4Ksf}fwAF>LopBVyP%rPI3bdsSL)>##@vT+I#*i>rUwsNb!ZOYiiL-s_99Rd9G$`J8p2 zI*#~+{K_AA`O%Y4%6kD;-oobUY(jD?&l~mOn`ya?@7wvx7{;7-!|*DvLF|Dk4;{xH z0Q0d!KtX;z#ty3tS&r+KTOaZB@HaU6Is9~H^(+lNL(|?pKXV6=C!%%Z7HWod6XoT< z^TGdc9bu|SD~^5y#>|vUHO)@8tl}YDlc5ue9%Pu6)O6Bh4Xhq!jKyw|5q;?%{Bk^t zTP%tmfDS!Zdn2#d1z(SrnHrlHemS+FKk(8xZ4`0HD9@?7y26X$Tyn?OReJK;THb|@ z(2RxF;RhXxtG!LTI-}4@l#x@&`2O`S$ZVC&+cKQZa70TK~uxeFNJ4s_jK+K zN-7>c2lS(jiou1(l^Pyu!BTnJMruE%oFw--pR0b6pwn7?3dM)4sP!*$>IVlc<#-%G zCp795zUtoAZJfugTX5#-_Z<^U;3xhjw2WDt<7%;)6dReI5n+M(<01;U0Ozug7LmEU zS?@>K)mGWaczHs$Zb+xCF6OVs+Fv^URZjpAD{K>whDJ?UHucC|#f2ag;?mdtaW4R4 zjvWq3D5$dQI%rw~qmu zLJ#^l@GoZ%^@b9@`r$9L(B4VVzL7#$Z=z&r{x%%hHAVpa{GWOPxr@}PVq)cm89MdcfcnW_*+o7ORi+=SOx<$}0yR>i9=9WqpN({)_7NgIM22;E<_9 z6Q2mzOz;zHeA2&Fp8hLe{_>;8zav&Bp?uz-=WRnyBGD(YstV8UCn>}CSX}C%^-8X% zbBbTXt4*-@HSDd^C3+OE75afMIpT}76?aP!aPZ&Pzzmr0zu>HB7vEF0w4itFCS?kqySV+y;}ZT$EjI*0@FjqPia0~*ZMx(*#e3VlE3Lq110-wD>S?GS%0QK;QKx z@BP=%aSJ8x-d5SG6gx0MCg8KyXVMbjF!peQ(qUShBndM~R=bz0tc#l6f(fa>)U{L8 z=#NG>iU8LhA{>@9j)@Q9-eMofLw@C}fivlHlrk>{4vsjba?++lm`PJ7Eg z>|gv-UjQ%v9v%m>9KC(60mDuoP}Em0V_@a8(WH{E z{`P@Wn4z_UFZv^6JJgYn0&nl5k5ZXP(}#cfUwwB^o_?&r8#vv>2Jm%1^AG=R1IJ7- znG+ZS*99jdJ1W8K(MI`=c<9UolQtM8>_|n3Q+Cmr^3Ey~m#YLA-T|cHqz+FyGl{-n z)b9y}$d2s-1;9RerySJsI9C?J`UIb{sG%e=@7Mh@O|sM0<*sR!(F zP~E3E@{k&Yr9)ZUOWPWrB?SGyC|*}iem)5J(rf}B&;Laje9ZLunN5Mmy7VWZbOAR= z=p25o&q|&{I-$+6?{m|$FAX~USn}?HjetJ#%5cJm@B`#%^J7T`;A(ASQB4w;Oh^bOhennT1w8ZWsX`&-*h{Wuzz3 zv$C2S)u^5{QHQPl3NhR+S{UP31@S_BPh(_wRGVnSQNHZiz@iciBRERr7Sk~o^!#?=Ux(|--;8giHT*~SI;_g%>oWQV0?imrnJ3+Lxa}?9djT@TX~#7o_flqxg`A^ z`{>zac-V~&boM~`lwGIDrp+CU>Vd@O5Bz}tqQHQkU$sMfejZ?%%$(As%7hxgA*V{1 z8)PF1oqn$ZiKu)htF5lH%Y^!FfCYw~nA_wXO{MF@@URbJTZf>h)jJ1+Y!W zmJU$b)gB+z?dc8VFa85T9$DqFM0qgo2ke)ASMCBnKFd>8iAb)d$JB@Bt^M^5fw<)N zxcv{0E3nB9Z?Rx<(Dz^anfCJ4@sI`)dAv^3Xso>pc1CrC$jv2uA7#X+gM8Y5@4bKf z&w_v60X}1%>Oy9q?4?TeuGpbN{s8Kn5j#+%u#!3ajW7jEG z3tb&!;@YW>q3`1aD0cc0uR3X}lipkT5RuKna7#-kg0$<~>0eQ>%Lhl>el+Z6flAt8 z)i#6+zxEhJ`QmYa0xgHSU~o)1X#g4@?T0V#81wjtoKB!5i100T8Q+Bs!!eKjD>lHF zzBqRRYyy6a7X9;WLBx8=2q@|m+q(gn>>HXLe)`1qdWQgC8n|tf4bwkp^jCg($IHFL zW^^+r=-C79Y1g+4T^s&Y;deyyb1%5_T+287yt;Z939ZnVNLr=?}WSPp%12r%Gt)&J^7Ax z48}Els$y(yY3ocXMsn~^Sm2}Y0UtaC?KD+QP5(hT#(3ohNYe9za4{F@ZBA?t{?e5v zMtY#d!~gWwKh@h$?tM{S41OFRMp-}33V-Dh@U&7HvY`F#b!5^p91nU!mwb7|!P0Iq;-R*t-T6OUBcTf3ns zyLO6!e~yG+3apcjHT&Qs=cJ$3XdZv8hbeIMjBn^Uk|_$>kNx#s!adViHa=~P-R-Dh z{YN+l=F?j9K+o|JtJecgK601%0L^iZZxo}PgF+p%PrfjJK$K137>fxN25$LJc!2{r zG%Cj(pJs*A2ab@5NGCMS9d&7-#0{1Q3F64kU1D8WWh#W|^m{#q=nY!(BD zJ(b(0iwHb61nXi{eZb)dM_*cP97(Ch^1-+mfFd)zkti_$ewJ5A`}o!6>;Ojx()3r~ zXj=oT2>!NFy6vg)7k;H5V8w^2g4(;MYvu_ZM*>~|n}XVOe3)McP+oVStbN$@*#w?_ zT&PSjKLBXwHr(fa+o7e{rxBWZ;N>tpd)uDPf;s4m#jS~NtRVz%4%_J3tNZ9$dGXl0 z2;sB3Bu8&_`5uZoKJY%{779aouEqZd1P_SV6q}xykQ}p!tU|Y+jz16+)agaT`ECGp z%Bxq9tr|<;nWHWx;OL%yD@bDx3;?9Uj9nH0MZc)khXjRs0bnA%EV!38or52`tmRK# z{&p_%2QH0O3N7tTxal738WdO6B1%CiN1rH6r3y zTleExr-2>x37&i);|cZZbRRKvAhk8JMghtwj|(O z#oIoWG@jv`q|v;|iV;?P>U$p%9*K*c6#1>iFKudQ=VJivFrdMwr0=H`P*_(UWw9X{ zj?zA|H-NACyU#w$un@T%o$v-SOQX+RM%B|9-~jpjpK?rgdtwefqq8$a;)cNFrdE1@ zv|Y^BV;@=i>OD^fPEwPd^#zW16*Nd0O4Vb~u6<6cqp0%stY_erIS~g*dCORXDAjsg%Omn`=-TVLFVWjBn-_r1@ANQhbz1r3bKfJ>WiXkz*Y+U zIcj8mhpy1Mao8Up5gq>V_x#fbA+O@LX%0IrI%ogT6Tod{^4BS~$KLjLv%mWHHS>_fd$zaW zBp~VrYmE`IdPFk?Wn&;S*SN!7{5>UTE(KR1T)R4Pz+JtvuHa zAQSv4294oQgMju0NeR11?$|bgK?akfi!R*=I1w`m#90_ne!xn}#FD(Ku6}gxL_l8_ zX{r>;GNam9uoH+8Fsb$g6dgIbXrl!fd`dd%452gxI1uZC8f6M~t0*6gKB1ouMc*)x zb`JQ|=!OJa>7jAe(=N;@UJ2=kQ9i!aKlSM|?D7>u2?rMS0eQM-JY)+VTG7R6ufFM@ z!hrFQNbo}!ZjN-cZyVo=c=CDqh>&*zDI}<07xrtvxl5QNH5qB|flmC)%J)i48(I0) z(+%a6kq=J)bf>-{mjiE%18oilAAI$PJ9MxLj7{i2^g~*M@m$LD-T({Z zwOfx}sF7jm)HmpxG$*EtcAWJKuFG5lX%{ZkxClV+$pBATer-zX>4a7;{d@B1BU}0U ztl^cjZtSc3zJ1K=J@Yf=&>!CV2MARjoI*HQx{&{z5Y z_P=@W|A5HzDh%PdmWGHRPcce~PG-<&Fv*5BtxQhnJ`$vd%q|eyVk4LA^?96rX0TVO z$j*;fXC_;r)`$I-8C~c|FtNIOL<#c8Rh5T>q6|+4U&LKxOyq)LcV?vRB*EW=1KOldk_V+M zKqp?Vn}9wk2rV|&$i-Q0!A?2H*Z#_20UmvnRL}O;uOMW{$YE3XX&1GJ54FLV(1$ik zb+^5Qj{CHCavL}J$EJEwP@f0woM3((C>=PItNm3WZ2@8?h6s$B`akh$0IKh^^Efb@ zK>tVIXd_8eDauOsqrvoZwdOef79cD(iOzk{kvpFAxw6Ykje|N#ML(Un@*`V&*epoe z;-_BQ=y}Gs8ham+`uUXSwgKGT-TjNN8**a06K#m;OPc7}%hfiEL{=iq)zvlQDsozs z08#POY51Z^dDsxjzh2#sjX+(1vCB-+u9&NY_Vf!S84FVNflXulV9Ab}`m#0--T1kk zv4!{)c^AGOxWWq1?iyI3t)(y1MJH#Yx=FQ&6{B9!!~THQ6)~aJewp$-J&fIG9=yFn zU+1awKE#37#)J4AytR=Ce>RT;Sr19zz3O|#-;E&Tr}_?ZYs>@V2(si zzX=~-wyh3Mw{SE*Ou=B*}#!0_V{<)yw>vJs6Z39S1{P)paI7ezESQ~AE6sGIw zNTN;(S08@Db>&qDvgtY#5#C*xKDs;=bHrP9%P%#gfZ0^gkK7zl9%MS9^w-+ke)>7& z1Mx8h_GzyPG>G_i{O2bK2Dd*KEz#NW!)w{P_LeU%tb>cn@kzT2NG*o3UHE%77q(jD z56F1KMS882=eQ@@7k6A=+W>0>i7OJ$j_q?n&(qkKZoUB)sJo(Uge2t3JKM6S-22ZM<%t4 zX=(IxR4BR%Ht368*|MTb?&#^_Vs>4B!LV>pv&Uf@`4sKBitG)Iaj4ogfd%!2=6`)< zr-MB84#ri7;@VW<%C~blN5|k$iLSG35JQ2t4xE5fVE97hkL`F ztj6F}vA4dX3r#7hYvZJyeYA{>vK3;TmD{d8v)?g)6nY!IJ~c>Hq=jZ z6{h{@GqSXI6UbGan38;(_$DHKUKVo2pG0ngrZ1j21o$+1cCr+%F>Il^yv3Rc++r1*9rYP1&&worNUc zK6rbPoH4iCK{2ZIfpn8<8;I68EgvY1J-{#)N*G?rQkyWrs4sls!(VI_ff#uh2X^cT z9(mYcQAR<3x=QO5#Ew<_?G6onTm+Dhp!oI=o$9;9M+^qEF!qo?RXqOmJj(r+{1xF# zS>`6Y<|?vDj|eJWilDT#P1H$^xq^FlkhahA@`Iz$-baS$X}qIrF?ES0*f@_p?*o1l18fzZi)M)UgAprE=v$q($AiJJd!SXQ=q~Ja^j!2!)-ki}$aYY* zw_FsS?b9cWmJXhHx=7Q}zDh<;Ty$^D#jJ2K_}xXmIH21B3B_tp7-~{&6iH_{rb*aUW)>HcqB7DA2uomEXxOkhi z`h}dUj|I7OHO)q|d}_31QO+S2XiDFr0`^~p*Sg=S6)}nfpgv? zK+Q~4zBNP_jxz_JK3KsJ=B<4UK*BzE7tp~#P9-IcijD4L)^#ozYLFE;HwQ>7v%HW- zu?u1zF)EG@7U+qQjvB;aZ<+Rz(0S!w+pD|ds?V#p>gpr>CN}-mtVe4#HS!n#?4ACV zJHDbKhcp}-mGt#*_^7D=L=J9_01Ds!3Kij45S*fV1PC5Q1F1hXo9;(vxqDSlpTy(} z3@!)BeJeaGeSd(8*l?Z?+KwyNi16-Sy8EaI zzUAdD-vI8O{_>x8ZZp)K8w1ABO#&7$NBH?6oVMY4rG(xCku!`#L{9l~oZx7YhCqsQ zE^YL%0JIbwHUMnd#8q$U=&E1X$PW%uthjraX6XBkL|BLa_=la*%{wMV>CEJ2GM~YHzVlJpv zA<`Vh6q+-%6mPMOV9+e8(A*coRu47s{P^}d*|-a@@`FnUjcQd7U*)YGZ0!Fe?B{pE zse2XBhd@1AO#0BIPh!Kb{%NroOme9Qwz3`18sgEXiHmIXM5I#bj5FA3Vu;{0_OMf5 z;P2JE@}p&C0Zwd@E*4EyAp5Xs7y0vFk7yP>G!$^%Oo z*$3)ZkK_yQo`#`!!&=aZILEiq$KJ`O*YVl9e>!vrk~YV^a_Os`|CT&=0w#G9kAG93 zpW{brukbOw8-!Qx^mn5$$#HEqgSr_bWD^In9w)7j0^K}I*ZZz^s;)}H_v)G87I)u(irQyNlh)im&(&XUO->HL^7t}>5r0NMQn}RGB-a*fT zuw9kcuNhyhYm4z%!m+)E=$6--O{BIs%SqqbO{}&?nVk{WN9b!w44oX(4j{d;fAGMR zzJ9E{baC*5OV#n6{vpbmfWG4qJb3ssibEd08ke`h*U#~fP2lfkE&jvUWPuRy@PR(2 zO(H9w+Q}e(VAFR}haVh|bF&gdtZg9q?YyfW;Se}DMaE5s*hj~cr}DA-mX^2H;Iq3Q zbo}>*2ql3h_>GS7CP;n)aA3PAKovKd5;rD>qcWjq7P$he*K@J8Av;j?L7zhz zvWM9A#1j0BP5AI>pGrW~24oDZYHgHw(8Q`h1_mmyMfUYReL93O`o!MkdJ9(9YC)BypzC>xBA})h{?CG9GTMj*?Dp@4mY|e zSOiS2$rj#(J}n~E=^=hj0F8jrQ_WPt7}e0(!I@$CvH)7v2a|EFgxG}b=I>*|p!Gxh zsH;tN6mCKnNa?N&r^>kdJM|J|XSjlA34s942!TlCKO)OV!OG80aQ$;+Lj&hQIFx96Y+< zgBO<>Jlf@HI~z?W6Kv@}_7~p!7t?#o%3HPp{Oi&%a`UaD`kS|00ttzadS49a#P>DD*83JMCE8hIdhaG|@Ns#UZqb4_8N6G|&gMi{G0S z-%3TJa+B}@ipA)v&_5hI3ky_T`hR#efR4j>84UX4fQT!;ZFK<|*!sN4`c%F&0b>sG zMHVXhuJ!>`HPSi6bLyRh_7SAqV{0wMO7|?PHrrgcr$>doMX$oB=D#4z_XK=dXF>)_ z!t*$gSbArGNkyW8$APpBGam!4D&`d{VmVDo(|=21agcqa;0`b{F^`?R0J{jS@S9h^ zWg9?7^>GHqv7~3@(h0GPq?6KVUpB#PJofgQ$chi0iL4rEJX1sIPeVpq6Hz#}q*N!E zl7mApS6MeD^i{526FgUQI&Wi zVgr2_1NV5q<%4Nk4R$IEe-Ft3LOaJttT~iCumdX*=EtV_(UBtYxn*Y~K#9pY?fJU` z7hZTwooZA2u0VWZAU!s{vct^p9%P+IHx}10r_eIhkG|~Pf9Li8Rz^hLjDj1_r_5xy zD43i?2vQdcjT{LE^I`&tDUDRv3Ej`j0XIb=gkXxY$nPN$eJF2%NB5ATvB}G9kgx+6 zI(VejD|Xr;;8*=XCzhb016}-985@Mnc9rX@!GZGB?Cq8NSuo+O3^{Ffg*G|0>~Rf!-tC z=tlLSzK{!l2p5bd#>Prl{?u~yuiAs;pBw+^DB4Yc&&iS{J_4{Qn7G;0*&K#mUXynn z^>&}+kH}2DS9)JGUSb8WI;ZB24H59+v_X}7KE&vkmk%<>nRl5kZFr7kS4NorFCJ9k^RPAKWY?+!qI`6CbICH zRxJ*g%s~r}h$FQwO$JnFdvI3Ri3y+gi;}?R;J{E~qcwJi2e}^);($_CYr9gMhdGhz zqDTLgS9!3RMwa>zU%k`|85|ho->7u_ z;l2R?amSy!?3^Dcga7zrcoYccAIt}k2L?wvCg1q7CUg7G{DF6Eu|W2dZWl|)71Q0m zOG-1FgY(X^W=dY9`Y4gePN#^?Q7T0 z>u4ax;PMV7_5a`p$$0K5Mch&y%U`XBszDw7k)yxEm6X%g6`>b|#IZlRHgSzPG%!&( z(4wxLw4eR`EWBTe#w7Gz4!$2?va=rZxxK!S?CMI*+M^x**3M~YTv!~hca;xudE>L;A1Srw~#Q&o$M}7J>;}mQAP>4|+XuQ||VZ)+SJEmrQD;}QWjga_o=`1G&q7mej26PCG>2>h^O5-Kr#eqRqNO) zfQ}&o!+A=S;I%Ir@h>{>p8P-mXE=O7`KFdPeFOM{pZL(f>ELD<4xf|p%xNYpQ#%0@ zA-XU)XL4-J>8h;}&(UBaF?}uQ+_jK-FMmx_=g?|EZZL?2hWsWu3mO_H zs_R`xHzoebQkBCUXlllcE|gIaUf;zJI&?JGKY%P)Eh(c_nCM|)sjo_vLmD^*T>}N! zM1fd#&u8ZN8C+LIciOI$;9|!`8NgN7s=K#9hNvz)P2cHHJxlJeN27@v z3FZ>eUo~*=nX_@+rO2q!FGrM+Zn23iyy*EH1oId>Q3{stvg_*+v&KDx}VF z$)+U(u_%9mYjByhaa@(Le~*8~>2>%8ER34i8OJp!Gp7Zq_cGoK3w640%;L|=Sko_{ zcJU8J{l;9`OE2L*0(kKGLtQtQe~>;&%SM12Zs#enZ|o7qmyo%d^Vr}T8<<}V3dVVN zp2A;)!Q5pcSvSx4*NLdJ*i%5fY2{7d05ZVlM}}}O{xhtN4T0VT;*J`@jSZvsGg4(n zAboKt1@j-m39E2|HYIq8WDSBdcb%o;T=G#bINV8d@>VQU;N7lN&7bdiNNq*Tk+ zdQNK}gft1XS{8ryt8DF~07@m)P^IzH#r{Bn(m9J%IlrkJz!&|k*S?SYrVZzH2+|m6eh76V(@=I{gtEb! zNn+B#HF*`vDKgPh9qFNXEi#$(uZPI7S?~%Wm{Kc<9DYehO{cwGdV|7GGPu8~M+f?8 zr}lj^aLY8TW>Ib%qjR^T2NxMO4i^UrukATUMmh^K?I*c{xR5de#8q*gE(DC#0It%r zq>Y|oEg}Sn_1BF?aB=rzbBI~LH(#3?kAWRXXU21kll zgh>p88M^T#f}>->sA2(OmttV216@<~ZfC*85D z`=Nhp`CoM-Psf+eDhDcW022W+tff=)~2qy5ko3KJzk+aX{R(jLr8exh68+_wK#d@Ly}Mz1Due>6{B)j~p5$D!zOTiOyI3U_+S#y9rN{tE{Bprc)1mSRCd0NRil){wk@~fy z1)?(m#RCHYe+;QXX$ z(Vm)UK?|3>BoR=3xe5efZStq#>AFj+rRJ_hTeM-fe1y_lGX_?PFP;7=&Nr# z1<=#}RE4?gL3|@xR}(EH>xNnjgjWFV7k$Svtg>8k0bPtQHar?JK_V1vtY%Gwq{`Xe zH(oKtFWK#VaT&pU5IJ8hk|w3BP$JhKm6KN3SIbpanx;^9iO3suKmhf|Uos zht_=iH?XB=Q(V)`?@8(VGhi?b1U|Uot_5 z)E&1r5^dXd@$+RBCy{V3L~_wD(Zs>RqR8jiWeV%Qc!-gy8rfvOR z^&#wD3>)dSI&c(^H?d+z=irb5o&bYxCE<$PvPpuLvnZ2l!Z(nn0He=lXlOsGN4S%9 z$3Gh>`AQH!-CpSfWHD$G<<3qEe%=J^yE>@~OhoXl;()iZ?VXhwgsXiiVsC_C|l-<$r?Xa&=!7yuldlzMIQ)XqQ(^+3q*gg zq0`hCI}_AZLE8&O)va{HGc6UdzsM`n`Zoyq9RSM$P|b736h1NYLwNMyszc`SPrQaN z1)Y<2PM!fg_U*@hsNMw`F~xi0$N{N!Ws#!vrkEE_1RZS>Mca)Ky?)rVaW@sUP(4DW zC54@0|!j^I1p^k+NuW8G{Kt(5%&;>BHjDYhWt-@NG&q z92b`l z^bpYi^jNLFWz;h?|0Dw?WC7vp5VIBLdK5SDJLKPDyBJ!4a{@nX2PEv4{oJQL7=?zO$S_#C{*@}{2N6YyWbVLJF>-B)v`%m0{&wHc|GiB z(L7t}Gi?6i?_%3`drkc*!V1r_qW8y13`xEuJ>&I56AlU7Yr5rQ+eGn>UIa0!1HTCC zA~Fe_ZW@n0a$$)fLx>PNn)xQg3HxDAF74O)={_{HQ9H?>L$tPU4J(w*wSDP$FRfcb z@HO1g7h%Ug^HGw1+~4&_^sGGcNzGfDQuh>v81_Hyb^?R=;_x+)=Li zCQx>rcl8nPrrzM)aO&&ezW9TG>wWNHZaXK>0JN;+0}CTi)q0o>@8VA+iO)C$ zLaJbAGuaXJgdH?>-eeJt3m=eEHFi^N+5Fl+>qI{iQN}{%Tx+J?!M=+xVwSQ$#upR5 zG~Lx0r4bC+b$ED)O!L`&5@ancUO!8)mzIxjeegI@uqfTcLzv(o%V8E1i4C^JyZM^! z-UWY4@#bk}@iRgi|Jw^qY51Wo>o6tw9!kf2B-GSd)>B&#x!7hRW(T8dwdR|bHCmB* zgL*Y4G;8UNS5rG64E3xewmezn?MV4oEN0zy;J|Bn#nACtC$`rwdp!NW&#oP8^FI)8 z>#jz}9|MhL*3ZApZJRy89?qMss7wC(2mkp^qMr5N4LIuuz@z@~*e`AR7VZ_TE-YS) zV)0zp8^fC?Vpm`+ps{`=Jl?n=FozpKg6@m-nFFMTev(H4Ug<8wL!-h#w=sHy=!XrB z?Yny0;8_QJTJ>wbKOwLPm#jX8ZQ{UkvIr44+p?@yfSA^VW^h@g9^66r5#K!K$cpD@ zGNSqouDav!abbU)c;fBby-#?I0G*7)3506xBa6{Lg1W@dmO^ja;@huyVG#WCKXu&g zu|TUOWo%~+UtE*J<7x;zTYQV3g@wMG_$7j$iAl@A!n)>84hvYTea!kIU#qiiguEwS z-{J#^mgeH%uj0e&d3|ee`!SeFME)D_{S!I__yLBGX?Z$J^IY=axB%4iPjn6xkCEHo zbpuYZ`2wR4kB?bYtu{J2c3bO1I*k*){fDP1@$ei$Xd<@V6g_X| ziHToTv@YPbiym}*N30$cHQzh;Ye{;ZiWcpFHv{!J&>MpX^`_v#EqYdYY_s=>`&^{= zm^atrOPp5+uqIr`YBMPrO?uwZ=s7IL{V+x@gS3)aVz~&~KEmB<-1=U7^RVBtB@q7+ zSn-&epSZOOWVa@$AO1IQjbnZZwa$=hS77MjHwIN+dVhfbUW_*eUHrI3)v@??(PPPQ z&@kpb1)fdl;P9UgM^5^m^G$#8dE%bccGjN(D1scgJB^S~{Jg*OW1ISBF zxAzgL8@j5t{I?j%OCyQw1EE!&vlR~nbXa&VMZe|Pu{VmsSB=hEJFCwCKI3h-T$e8~ zpV~jx*z0r}IJgdj8OUUd@Wcynd^U_(X)V6@q@VcTUTEENLl$qAA0Si9VL;aPs6Tbt)Y01H+~Nq z!;&p|W-E%uwPxUqhafF@E^aem1~0VOjDFh=K=bi0hjy@=YyUI>cK8RAhuUzNxtuji z7rRjcq3Q6ka4{izMZH1@y}t61r|=ilgJ%MWQgMDrR&#%3$Q+&?{hyKgj7MLM1H#{_ zJ;J*-XSbbIKrQJKuZo4?xPA2&W!&_NF6X&Ir5{#46g)&Bul?b{Oi@y})CY$`--LrB zd%|tI!7U%84;@{bF2#&NRx4gylRf4>C2FH0WjZUeM-oooOmq;D4mRMb_f!2yS}-=m zYMuzt{E&o(9(#ZWa`L6$8SZtY5V4_u%9wFb$p`*^po?BSo&oUmAKK$S@00t^5AtZQ zzw(kRw5m7TXX0gl@QXo-srRaCKVak_7%(-EzD9nOE-(!QhMQ=iSDZ|=1>?34C0$*j zZ#`Ys_Jc*bfCu(45MBGA;aFeUZ@PM0=VI@>GXbKS#_0Q}Y(OrIcvtfH$MC573$zDE zRc_qBc{!jVUl;ZlwRDTmSAiwN?cQ|RkZ!(GEFEy9_qcC-_dnCYE*phC2^odhfx%2&mj~^0d%D-x@A5xPJ&n;elyjh zZ6L_Ua?JaI$1ZSDy3YY63BxVg?K3#+CIy+I)EL=n_Dl0oY^>K0FoVZoG2Zj2b@`o+ztXDtw6MK0q z`+y5Dp>v_vqc( z38?2;fVT7pfIeFd__NYZeC*gYe)=yo2Wo|yz!91R+X+ix6l8u9*GewWBj?~rnI9Td zk8}Z(4Gp%&Dj1liGqhkf1qQlCgleaT<( zIj6q!+nv?r_0N3h7s>wrn|NTS{FID~9a(6#mRi|BK$^!|c0nj+NfQmjuLQEEohg!N zKgYr8k;8Lyd2Q` z0)EY}%JZ`To(*sqP~`<3OlGK>u-xsAsR8wF5w(RdTNNx)W$ky>|N? zzdhHcut`w*t`@oIGgjXEK_ccy1lkZ}077tKb!$uHXeV;>y7bT{H&RHokt3;@2Rr$r zc^S4|6&RTCd9BVfH~YfIL4#KhICYA6=x=+e*!^q(L9M}wk9~?;6c?_gv%(xMbr>03 z9;xqV6t?NZXVE9N=w0#I54qJlf0-HG8?L(e@9CS|zaB!?WB)Lce_0%{*PI5c$CfdH z7^bcH>v3_j{=(X|Q4$V7??QpPTlqH}fB{%y;o;gpxSF?jjI+L|*$VQbiDIE5SbjCu zaKy)BF2%2IsMp=!)uOTgn{p+O4+A;0;kJ)sR3^DZVlmdk&mJ^?%s0LJFAMfgcR=6i z_Ni|>{&G7zLb?m-K)axdPNM7K+!tvl;1xI*ZUq`r7w%#L)NlxX3O)Gb3K6TEDJhbn zby~A}=^M#<$VASYCR%!mPjUjatfbaDu1U;_*uK~=Xu|V>qN48tkB!2xvUuvTWnj7j z^)rBab^y;J93VBO?}GpgeApUcpU}04mRJgkFkV_HcJ(Ja%OhIR_RMU$vN#t(y8y}%3IN!bOhW8HUh=4!D| zJo2eS+YJw!{NSr>OK0gBi)T~py#-U8&l4@YNYLP}iv~#0;10oq!;j$Z!QGa{-6cS9 zNPrMzahJs*xC9BZxV!D*m;YP!eu!Ij>-hll^h{TG&z$aa*fD~3=;LH2>Uf~0X%`Mb zHw8EPwqG6*G67HZocHckFAE=MNgh;=w+jhb#Z}r3*S(2Q^@)y=SUc7RD*A-p&9^_(m zfs$WL6*q8v{%;qpG%y*b`)v);=Ca~lY+U~6!3G8jZhJ2wFol|M_)1YlEMvvi*lj5P zR(U7=#3$ctL^tN5f*fYt{7Xo-ti_^vkN&Fxs8{W(ZP4Z#)V#+zqV5?MmmfsQZP#bx zN*2(hL-t?g*;?$@M@LtwzCEpn$`qu7fWWwyrJRB4lCObUbg=U!y0;0HA^Ts|6zE#E zD%J%bcix#$&Y434?7{EoOdoG7h_6+O{tTfHPCs?~$Mu|U@2CL*XZK;2z+3Ha-u)F+ z4mgb{Mc=VA2Z(4mxGS|nVL}gXYZS80K+C{G=Wfu zah02ThxY59_Z_#LrO)nD(j<~T0S|^;*uEKN*>R?n*WgIHq$IQBiDuD2!2a9}P}L^T zWJZbBujhOqF`TLKH|hr^H@yW&V+jIrhVQDZc&SNH!$MGZ2 zC~Jm%ewxtQkZ0912Ufz=lcu?eZb@7xr7-zqffkXM=HZs@rs${n&6$(v>T1m|pVHgt})=SI%<@UEaKE_ttu2>{ET;M>|SBLObT zl83Dsewh0}5_QchmEh0?^YyZO2GI}yT~i}Jr$f)M=k%@>ByT2RU5jG%(|IBQi5qxg zXZSaN8Ib1)Cd94NX!`5G>3b;H68i$TCW}+HoN$}&7i8R17RU6KPk^|S^77d|+4j4j z{Bd<`9mX1+!xy*D3qC%_+IrPfx6JZ-M~g;|ZY;ZAMnk`hAX0MfV!KCU&7V zVOKu1%+&?Ds5h6CSL}sYKmy7-by&b~%Dq3t-uB^jQ^5N{^kb$qM8TtWFfV=juIb-b z9kUiu8!`NVU;0&nRghX2;*4N=E9i3Y!L;puC{GYU&GSc`aOqmv}5G z5N!)KF7`nqPeMFdqTlBQ4F!AM(^I!D9(f2AxRBy|dijRC#e0^O5w8 z=81&KWia5t{0GoO$_7xb zY`{W3Ou~sU!!gp3tKqu-{^?RX;QWu;GvF74(b2ijC^P&zEQ;FiB2FFdkfkRPaDx4O z^8hw+c#Kr@g_Nu-7|na!EmV08qonEo0E&0@UhwCb}bajXpXGJbKlO z@U0vAFwY|Tfaz79SV3c7@lhK~FS(Ae@qBYEp_YF?ixKzVG@~ML5}cmaBCm`c{&4v! zsdNO6-}ONr{Hd4L;I%=I+GI}`SeLjslL!iETC@Lh?~Trf&mapBKP`4TIg1=5=$f{Y z_+KC!Wxn4*NQ97&e{0SSrrrO_%-{{5#%YqsZRH`Fzt8?kc0ei@GIqo@er}gK2#ym~PMq zDL4$W=7M`@4UIV&I-MI0=9K_|k2r>2vdh?8pKJ*b>PJGpP~^gc6v5+UGiE-H8vid| z?q-F_0A`)9xz)tWm+3*%vU4DNc`A(DUr|n^$xe*wj7o7D#sWCvi%VM09rj~UZ_<+C z39SpExOmeXv627Xj-Q~|=OI~E)rrE+Eq7ZAJ-!Txy7W3Yr*C3O06up5 z2%{NZS0nLR??Lq7$IdCQ2y0|EL2C5?hP?v^OWc6{8bV?5bzy>JpW?J*jhmXT6nw8Z z_BKT;2McykHSSk)^3lx;wkY`!`VaBdlZa5Td9+!;WnX^rd`BJa(k;bNt)+0%M#{dI z5M8f`^_(ktS;#UUIsKh;Qgt4+tg6?H*jALJ#6S{NgJ9s%fciXc$GdtXng{-(!9*fU zi;Zu*?>0^RIs2h;5tOt)oN0#WXW~z*AW8#V+s3(O#~2Mw0n0!~LbIqq{}-k`ud3~* z>(#@Eu(4R+HUga@|0(QeG5o>wm7HsZ?|p_sCl@p)G6{4au*Ud@qLKGCB<{cyUn))G z;TEnnx>L@+Jm2Hxv=zJLK8Mr-Q>W8+0apL{rj~!g1&SMyuDX-IR!(*NT;MJJFKIVu z-{-wY%cvF5GT8Ov4=8*IOF`$WhCfT2!k?u64H8Vr9F3WyeF4Gi9OX>t-{paCq2Ye} zsgN*w7oPrt4?zebNlu?WcGB1Imt-24QuX=!82Si|pl!Qmgn1YSMPmsN93raQ^ zLLO6nOXEl2uALUtGQx$gQ(K0RTUcq4gFhmJ3C_kSxqUjE@VZ7ms~vw6@!*HVNgWlC zDd8EXozE@g;Yq}FJG03Ol#_osR7GJ8PO#Ok%S&4OY>QwpT(?uRWp#8|4-KUQTzT?H zreX991{?TNT>F|Cd~&}r30p7&QX1ZCed3b3_MAu-4`?H|iTBC4$E+9!G)Gf&Xo>yjy)}4&;xlXKZXJZ8q#je zS#54m@Q$wV8;+6TFz(BM1GL$7~EeE+xw{JPv#Aq<vlwsJiV_GB7RhnGR5n9`~ycUw-m1xc}L*|tNZWW5(pT@S@Z1t4tOx;JlFhd z*GWf^48-OLnbH&dk%3w7H>S0HjyXR=E*ea!*L5%Zxvs18^KfXd{(o^8KPaVdZ7OU2 zi+^&oQd%G0sw+6Phqk1E_H5Shgg$(?=Ab?*iBKf#UiTYGwMCn14$ysGU)`F36&*g0 zPj(~h{pI0*2+nFJDo1rqz2i7Xy82W4O|V*HixN=39^-7|<_wYeHF0?ukJ{AA2J1(l zwIgAPt|>*fE=rb9xq41_k` zZ|Z*HMEJ<0@h8T|{kohl+{tOvZqm};$HSWotBr^NKbPmGxPofH5q@EC+D6z(79K10?KtSC>z3U#6lfRK z3uMbt;}BijM*1mge~pa5Q~vlHrEt&fiEfa!o<}zq9j(1*2sn_{hn2@UsJ#z8_}SmZ zg5gZQ@I6M>&3%iN@rA4<87rTXkX?on)G+VOgIYqC6;*}HTE~TTw&quMWDxPxcwSd1 zW~8r78Ey`7K&FM~#U#0t9&cX;Sago3x`bS^&3aU{5z)k?dbP1(dKXQzw7&okwEND* z-dr3-!uJ0peM#mrYV3I;{thIDr73Q3SC57mC_px1bR&?%MW_+?&sOnw6g444Y< zZ;efm73t_YT?}hs2zCNF=z?%4lh_?{$b(J)tS#I^tU}NrZ@1L1Wom-P*}pF)oxO|c z{(vlvw?rF-9C~Ddo>g4tF9*+z;Cqg@eHj>!UQ6+g!VQk&uBVFWWQF;IuJe>U?kiB?x*FWs15kp@LrN5{vwY(CBOa63EGK`lk|921EBZZ zvIhCSCVf#)0ILI+#du2r*ZlCW*Q((QJmHdi&zU z%RD#|@8eXGLe$m+kEDNrE~Yv*Oi$p&IpWsJmDcdlNH@7#N`oKV2mM3dw3LcY7XT!J zFOOo&Y>vKPEtDlCuIuTCG{L)xkd<`1XaD4FMHz94C;hX)FeK+aW(q&iaIX72qL)U= zkS#WJwe%lsbfiks8Aww zm`Yrr6$>s2Z1I-$3I@T%>k&i|ot?0UMCJUVzj>SA0faHl)|uR*vNX4Y`tV(PQxQ?2 zWM=MLrz*WIW7>e3_-pL$%OV~oTa!`2)xfHOkD_l?El?T};JP3b!a(XeZlQ?LWP>RZ z;Qj-?>#7^PEcMR1_{Va0)%1yT^8-N0-RdFigc`e+2w@A{V&$WZ3L~qi#Y3tUuCnX6 zXsm5!eE1vEAzAL!NH#@B|ww0 z#PTu0VUF-|M~n;ayZ_K7nu7n!W5rejRSH|&WaH;ns_|Wyo4n4H+bVH;VTf%SuEB38 zSF63-af8u2tOIJlNLvplt5U7-{4O8TaQhkHl4bMGGZk*rP*}t?6E$cqbrCn0dX(U< z!K!y1MJLTAR@{rJzf!#=^sgy0j5^Bk~@*3-*Xd>zU-+hv(y>{t!rmoEl&aT#0!z%~V27KQxFAL8U1}9Za#O%Baes zCsM6mGA5f(tm9xBF6O;j`#P4iqZ&6p2vH@dW;(|+^|gBol9a6_vN^KQw|ke>SUf^| z|7ZrJ*w_pCjL;BIlj@j!PmuHy(yT}JEQApbxv=qg+#Bzv$z1jVtej;KEl{*jH}PJK zK5zZjw=}O~FFNLkn}20YB+apo9?JV3tL0HS@O66rqT}5G1F&_S3P3IV&nF;va{`O5 z?rpm(6*`O}%#LC=_#ibQl*mB3$9Vor@4TEs-6DqK>8X5k&*J;@Z#0evMW(l{%_QAn zC8LHW2<||Uw)dLMc8SUc5j* zJC8dbXD+@uCnM(tB&2F6+gXY5VEuQ7MIdYMB+;&Bm7L!n-!s3S4)FpNmQKihIAqrMU$w4 zQMaph@#4A*k>LP_Xd<;92AmoDfO~74UHmo%)EDYZ4^Zh`or~>Mgs5%zu{3t4`kL(q zChzf+<)%~vCPAyv0|X_@5>G#$9>N-SFT-$)J^N7V=5Y{pS1QvW<#Ar1lOD9$Sa3ah zpB%Py|Myi3s(~3#rdHypkNDeI%NkzGon_G7!v4ya_HmT;;sqdRuG^ng(2>;AKOMWr z1&^QVx|lxEMxsxBx^b(^yicKtG*ya#{dD`B9D9I^Wt-E}&cJOgybsw4^S|9doV@iL zI7YS%-s-J`3e#0KVf&_`p1?W8082#7<@4PEG(FO^d44pq(Zz(fWphUrO8#o^>5>b= z%h9KMJJeg$1Q%bvh~wcA1Ushx4lR>iD6*B>C>%({JA>zNNzON2|=SgB4S9iY{3!}boNvskK*7Ldo ziy+MHoe4oh4R2n{I_hU!Vx}W9uW`p4nZmkvYPZ8v*-ZxUUu``OdtYY*C?&eM0P`-% zhj3hpSA;Qo!_Aj@nNe*4utUz^Xm-rwt;l!9;$X&&i>($^T&5s~j#wWSJ< z*@C!Y8nS;SA$cZZE_4>rvMNWLONto3_71FKMXwR;n1Xg<)C@R?4_vyP`yue(f{*@H z&3`>GSdk%~xzzi{3H^G6gc^2#@AEr`i;e0N?D#i2{dc|X|--x z@Sg>p#~pU4Q>0Y2vwpRGv;7i)|0Lf003{Rc8kXC~eKTo)k|~w@wePPk)y;aXQ33n2 z^92v^bW$|wO^vi5!83^D_6!LE}6F$lkwF)q$_BFGs z(#?{(=>xeQZU~d1My@fyBofQ+2@NHyCVNRca_uk3d@6@T_|aghg8?!p=paYs;l&T8 z$>>{4drNteAqLehf9VT15#J+HeVJ=iPXKW&TCu$;Nzktt=G(=san6?Vz*652-XTNL zUb>lX9stv8njGZmmF>30D4OqY95S1|>F%svDh)ema_444=YJreW36T7FWJc^gkq0( zLFL^mp7-AWP}YkeFmORqm&o(65Za;n+DA8TGE@Dxk_QjfiBv*aL@7wb)Bn9?yQk*n zSwdpVAxy%nRQrt4n)F;_TvMwKJxA6L*VH`2;jo@A{t%E_>oVg;7Z=6!(eDhYTb3vP z*Ik*3C++!MW!iv0?!cM#Yac-O{-ggtQ)!{{hp@A*?axkK1(^8N)6o@sOV~sD;VURH zB}`sQ&DSv<#YtdJ!utPioO+N4Lx8!vC0vdB^odiytvQX+Pyl#oC{^p3MbXLI&O4?^ z@{&S!sRjuYi`ocuTD@xr>a92%x*G*t#FbN-Q<*rRDS*Y~j{_z|E|9vfzPP;4`LE8r zfun3oUmqiRYgjS*pP4Lr2Um0+s?iW=@eJ2xJUg0c4Z^w@tv_YXYX4`%K2>Pckrv7*BzSI95 z6po5<{~nwtiTWLgV0+6@`7UH$dQgzkO80Wu?oa{O=b*?L!(LS3Ygek=5C`Ws@bu?` zr-r~ZIoSf>1AvDx{#ddpo{GY;`6Zd68M0rv2D!{X&TDC}Nlg%%Uv;>u&%+|LIEGsi zXxex-3_p`S%sg9Tl?NWT^KJ^i4RxZ3Mq~9OFdTgL-dI+`&h(rcn_sSeM#;Oigv#le zh}ekyLMT^HcKMSAy|F3V!k@xL=*DzHVoR>FvN%PJEwSDpS+Se3M>3sgv66CgA&bjO zwk6C0=J4@c+$$>Zy8SQM_6LL8TIi2Z=mZR!&Hcp}O&(154;`Trm3NCjH)#77ZS7+1 zH{MC?#(CBFJeFw+>xk|kxfbN8cX-JnIZ|!)wyfCYOhsZdwP*X1v*11|eCs(hkws)P zY<=<2&MD0wh||Ff&!*s?l-*U5N)nffDLvd?a9jq?(oylWl+v>}az7fQ`3DvETY;@`W{=?Gur48gC$B8mu9c$GwklD4zJFNs}e8t z<-5=CQO*tmYaKUH|C+mov#tvw^%9R6B-cC9YnY$1V5s___eH`!iVwC8 zx-(byKz`M_l`Q9clb|%q=Av+P^EoZsktPXSqzH33U#W0s(>tQmboT~o&VFV57`E@V z?QGf+9A%3X{zZU)P>@UKxv?dHplB8W5y`)zdA)EXEc*m5OO6E~$2AoHQ$k9itMH1a z@gVrHj0U8LGZ5FBvP;1UElR<3*q@t=FTtNqxurKpsPZ~Qap7FW{i?QJ5Kwb}9T>Nx zH~m*3ZQmSRwgUrj8V6=@07b0A0%nkEmJYcR8ErI;uU*KUQRG}TK9i!KxQr03n=qOF zzCfjwffXs6WQ80t*yJ-fdPrbDOxYC&j8yYrkNT=+O5<2s$$hvX&^z)3Syfm}zK>M# zJV$$p{|dX}w|1jnD$3dla`T&LmR#?6%4(izLhP&t>MLTbc*%};f^~N4DIYj z1wTaxdv(@UMZE0*Te$>4#w+43ILfeh6JUfrF=L0$&fXV%gA$TeH1U^6xS&44s)w8V zx;n(vEfN<6V5RuTVTW#gadjd>tlsLI2`kv0_KS;*kvYHTSMPK=zUfEuVD%$$`J-`nV zq+g1r6EEt>LaewdYH1P!Y!71vt?>6peyd-81G{D)Eh`-Sv<%`EiHJCl#7SjSoS=!E zS)HD@igx&K%Bkyq9eVYnHO@k6ENU_SvZl=N8NGM4$pgR|0sJZUE_3!jDOv%k6kb&V zp3;fq7W8=4s;-p-3*ymx>oA7K7HrDZ_e=sMw5p>+;G)d7n&hO;4MA|MjR-qcc-H)F z0*jXHXGI!A;+!gas-}7XR6XvcBtahqJlZ_52?4B@PecW;5xMFG6fEukV}X-gbE>?p zi`ppn;G8;Z)B3vGd~CpQIl`FK8e#`CCV7ipb5*&=S=a{>d++zLY-rIk-eDl}XUt29 z>C!=^4DGv0IpBN3l)8jX#^J}A3P|9G?A5{7vw7J=sNZK|#BRxvlD1Az3kGgsOYkZ! z>}`jkN$t~?Lldl>AVZF#oJieGK1G>V6=BGMh3+h`K_h8Df>506i|0eM-6}!;J)^kW7Q3(+ zX=(oaUH2|Mp$deL=hyrvWS^{xdpPE`7AJ^^Fn-aKBpk8+T?9@3i?SRR*#>5JFy^*D z0i08yPg1M=TS7#2r5gfdv1KFOK(jg@o16^(>y>Olu6VVq@Wpf8@7Y-l?Ly{TVqOaY z;6oL)Mc(5)trMcZWf!SVnPJnYk#dn3*J4t{ZDmXPgCl|EkH_B;Wa$n1)dY-Wdr{-J zXWJ0Euo{HG_HpLE0MsTU=~Mjpe2>k=HQ|2iWcv$f{46?mH4ZoAQ8Q)D)~VN-XYQTQ zn>v?sM(r*;TJPKVgzIM;nfjRM*l|voCW(d&`v*C_D@F_KL7LlzLrPI~oUUGlcOy2y z5L?QbO-LT2;5d68c~fOYp~DZPSeOGMy#fZ8`?$Az*tzMn{BVwq>dbC}<*lXeN6Bd7 zC9U|YKS~R&)uJYM_{eQHF7~M>aaat+wUF<0a-H93or8tq_?sGU!jG8d&mCep7|u;1 ziZW^_R=iO|9oIONjJvwY^5&a+2`pWd&%67PW-rTbg%LWuir9M~dY^X2V8w@^znd<_ry`0EL-`*q;bfJrH7 z?`wjvD+S*x93PMUFTZf$9%Xa!+DP1k_M9j@7-=*tj8QKeLmZnUEE!)5yF@_2W0{TC z_)q8cd5J*3nDN*&!%5Q4^z;e@9?Mk}%4g!rT)B&)_GdESwBw3}Vej@{K@tif^uVa` za8x-{*W<<2X2t^IRNfze4I0H6_0InU%xiE^ulYhvW7*q3)o8ged z#L{@WKO{9f>0w1bXjbgE)^dm70OAeB@hJzv!n|v43VKx{_hym!hQ&$=bWAOsY$YuI zEa>-l0Z8)3W=Nl?sr`*FS^dR`6>3wau3ig;0^e1glO*u)B&tb-_?e>1%%b!yw#B9G zQa9_{JT!dzR%BovF@+-?KQAmf8NiK!Y|jYGqJ)tDm1FtbV@~~oA42NPRw+uZIYal{ zF_;DUk4;6~t#6$Cit}F*E`j`X|1e!oSy!bz9QCY?+Kr33uv52$|-H~ogAG`ny zJ}w(e0vXtlU9hE-^<)G^P}L7}YEqj9)e(_%Y%o8U$yRBJ>C+SPRWZtBEvsR^ZXuSM zaTYc$1@-V;EjQc6{gin3N8)Ab%?n;o?rpgZ9hB)o`*9 z8dZX@P3mdpUkOHH6`^>F%20>ab2B{1mqfm%za?@G;|SV?co+GWK;!F&NVGCwWSon4 zq4>VZ;}*JP=-hK!^Zl%}`&h~Jz1HQ3c`k8*Wl1Ye1^mb}afAaHK_(!j|O^e8<8 z=KXI}A#_TkE;x5-`C;C6T(leI+O6&J0#E$d{@*M$GD2#tPP|dBud0nr|0kD>jZ%2B zrz)XuGrBy^y?k1^CwA1zIX-ZVePuIe?wRDvk%${}l)hv(Oq~3tCNO*jcd6#t-a>|fuCs39n_ z)r$EjVB>mN> zU5}tCZSUJjdeO|s^o4wV_{U}UPwK2Sz*)tC!uOFig%Nu;r*pq3RaOz=x2LiPy5Iid zrd#(%JS@y|$H>u8=Dx?&*7>Sef!}?{bkfk2Jc02`hQ5G*py*?m_{-n*z^A_jEF!HR zM&6{6V^|S0&j0;A8x*0?b2g(JjW+0Js9T53NzZ|W{eKOcdxFnj7Ww(Kt#LzZ zYtM$JCVP+)44g#ghiC{+cvY~2<>Fw&cl7kngQhjuEb)X>c`v{38em23IY!U2QNi9X zI>)aw)o6U~(#Crc_C~POUy1cr^LsmPJ^ptIi$DB>0Q!)x@{`xwTdXVWCr?RpvvWMmXZ=ZEsNXAc$X|OgZ0Nw|@ zg{4`X&)?0|xRZ+yXsX6bg3(Gz4(?(s(Huk%#T9ZEj+pz>1!|0jd+o(9K=|jCP{_#F zY56`AE5nted1jB1`QlnAFE;#*In_CVH+ufNM`c@5ba|6WMiyzy(xgr)t79kjF|(j$ zcJQ0i(`6ylhHeO@oQ%ZOZ=ZbbTd{z{zT!)_?LSl6U#hR10pwmIII0n)E3p=~9QATQ zByqKAc9#2KvZAA3bs9$O$A7Yt!}0J?f-ed~X1zB2#2h5)PmXAwM-B4Z-HDknGzGp} zitP4;>v=?X5F`g}HR4)PnFpiz1DXxt+&8HGTts|7L;8*yiWtSmoi;TtGV~wPGMV(C z&T~U7Z%f??GE_Fn&KWV{dE!Marbto)&Y}L#->xRqiO)_?@+5l$kUOZO%a%q59A43o z+B~jt{_z+X;R<&@4c&LqC@DpTDl1v4%WukPcGwni-7@cw%|EGJjrP#!_dzrHnl8*S ztZ*mJA%kCzM!AVmK!9P`ad~hJ6bm16byH8A9j-B0diH3&ED@~<1^3C22POyOB=%{3 zM2xw1;={f(zsXZ4FoLT17Y(wBE5~Sz3sEvo{8exN8D+eTv~aXjT>EA~`wUKP#WjhW z++27g^+WuH0-guFVJ3!09|@tJ3n--+T`gi73McOfsi(gk!7iuM^-l>#>+Xr|OueW< z927ETLPKr7qZz@u4HiTQI8XLtT^?{|o@zoS=;o6f2dhs6bGoeVR$sdLBCU)YZoaL{ z^~`*6B`DXsSA`DNnwWny0ZZmvq!GXD2gt3)afi0yV(5X{LAyUj2nw*@)dZ&C!Lar1 zx=!L?EZ>C{v6d}s$fM>J6O-oeAIru!ee6!nGu<$J8JA8{JPni*8V|NjeaF?$az8EH zb09&yw3BPlZ&TC1ptR3b{UxRT6KZnEu+r5O_+V>P2{qOTO|qJeWGNnyY8h{~-V^bp zEck1z%rC7do#h;uR9S(o_A5I1YVV>X>_pQr+qWk|Zd%`17f7hpM8nCKHHg`>z#3lV z_H6i3waV`De6|OLst&Pu8&*El$*IDV_!60__3%fzfL4Law;q9cEZ*FCHQ;aQ8U%xp zQ&*5v84;(N|4r3a)w}%uw(i&Uk2+3)5z+Dtv5%iDkKXZ(#SZ$G-K=yFay#j~)e258 zhA4duBKz~{L#kUws}sZyRCVH`mzufN&aAT#c~I|qBqeB=iNB5iakRH*Gx)q2m7t!L zi`jzYKufJTHqwvKfiMu40LP3HyRmL)gP#6jN`jF{yNOA&*|VZC%Pg)0*eY;&qMqmT zoH#7rx`(fUyPqI^8LDbZSRVJ}3KOm=P4mdpo1nZ*gznF@cBc85fA1cYe)BZ%)ZGSr zrq>SkdsVca`J!$MZR`r&jYK62%|Qb$j@ki~g*br0?c!Ph`CIL@28W z4P-hcB|mT%)|8Mg14qRrV^nTJE@H=2mvp7%#_ zezMd|&Nuv}t{biKH)P?)%aVSIrRjW`Ja--N0o9Vh4Y^4PnQ4t_<7$&YB-h;ULQ`MF?qGGl(s zdhQ5dBeg-2Tt2subI!Do6jEKmwBQ;qPz&zd--G~Fd42B;PR*jel_YTr1Q>I7Z7E$% zK)6>OmJ7OMVMJ33;oHGEm;HWwN_)NQ@`Fk_AoXgdBr}E)w~v(J;I|f|B~fSBo)Z}o zA_=qitD*`h^S4eiOs=FaGTd|cfTq``yY`-$n<4T$K=OnWQQ4nHc4$C?_L3Ix2`0Dmy z22&idYaYnN)-KN;dNGoPq~p&~$&u?GOZ^9JI!bgRKmK>;3m>y3_It5Sk(bef*J>Zm zq8O{9)Rvl^H(cd|=UdR`mBW(VH1K3y=Yb!G{~D<5+uRdY<_~dy1oI=Qv4xWw6|(vR zxvwogdYfXMo*PR({uq#PoU7GA$LXGY33bUGIHSvB$@F=eef8C!M&P*QM@3|2WaWSC z9($Up_O0)1^K7C#-;?Ox6DY2oVueLLy-=_ugUuqRRS;;; z7L!BG>@t#}^Xc65JxRfLBW{z`&NrA!LwcZkys^I>zVNYoeAdAJH}FtMfe*OYqpQj1 zN$}n?7=kkk@+k6|x2IFX8^?30De{uhwY=gJV&~o6{RY4qS(9gbi$ztl*$!m*U^1=N zBPnZ;?$FR3v|W*tl?li$C-0^zKC2!(irPGr8G*JfN-yMcau*#8weh2m%8drgPgi3t zd`?YJ*^qVbk4URh7j{X$o~`TOZ6)jbZzUxxFj#5}=?m(o7Jt%iWFD%h;Nn6-v~SEm zwB+1yr+Jyeyq7H39#01}N}2zve0b`K8nujA7F1ipEOXY|36tD29Z~SR*!%DK+bF3x z$Pbnz>G%i(Yyl8QTq}>*cUfhdBGY!9lsH%LXO+ud_A)kkN28CWOXj$t^SHPbp=W>f z(L0F+WnCZ1{IV5_WM=z5&%;qevoYQz@CbqTEeg=;Us#pa#NPJWoE<`P)E{UD{oGKi zH(qhWtFL=A!}NOF`j=@PhdGuk)NENs>T5T=8de;ZV8U-AFFsAR#Go`@WXttbAv?e1Ji zX8eoq^l`rdRM_kE-6Z~v)1=LhpJ|0*E_a)jljz9_i~n(2W54iIdkZT;z?*@)4$nHj zcDV^!c1toPzR3iO8DX(S{Ntf)oxdxw@>KI7)GaWYu-eC9A}-RcODhP2kqgK_O?lr< z4e#B$3<+$O>}=R`o;{2x2bqok69!1!-zk`&61^Pj2^$!9J|t>~a2xCFr{OWYjE$1B zsedrbuzkbu4#Rvg||8lpg{Vq%91z-DPg4o3sngNv#LqGyJh#IKB(`0yIpc0 z^k4nQ#m5>i@j#*s$p=&AV`>0*qNBhhrFy4Z^6uK&*W9wdLO5?SK~Y08q+11AweFn5 zq09ba4p1LbA@ByeCh2c<5Nv~gL&DjxnCPcDSpXoL_81_QmMcQb+Hvk+dqK3eht06?@ zvCiZ7>64_}5;pFv`fHcy<6TbXD9_W9dTz3~4u>RW6vhefvqC>8a=28W%;Re`>R%RI{TYxw!N7GzsS)kyPo-Ev_O=c?)huHLl#-8O~3Gs%6aT z_hg`0f7(+rBa#`8F+t&cdlQqvJXIr`cr>FCd4j9SGBxS3F#f%RSQS*kYL+t*SM`seeG?nG^}Uf6>b_ws{sk@qDWQje>fg{oU3mp<11J-UCp3x{t@?7>g~evN^N-9JpB_M=@4{WCz$v7I2|48Ado}k z&r#S-n#=HMI)pr|?vN;YAfw(1NqkmAb^*S7BjVw!R}GU*HySFv*CPN2zBfbcCPc(( zpeLMXh!1wX-LvfKVIsE3Wjb}T;BhD(rsbVtV%9fb$gkGq5i2CKs`1C>CbOA2==&Drm)P#NqX*>4E`V_m|ka3W1J&juI*y|T{W!<1=o+e{M#Ux%{34sj%cMtE;O-^w=cEMitwX;ie&XBO^`qw zhJNQM;%P{y=Ef{cT48@qTtA+)L0!B0;V)d%4Cgg-M^R}?@v$;4r4Y9Nu#i?T?gLTA zqRAsEu*Vc?=jZVx+GwmwZEtk;xZdAe`Ev2&tYn2!w*i3-JD@P)ao zmmi<(BM)IvXpb2tSqg!m?3LJ-*cFq$n1i2z6i0kdf{DRl92-{{DbCT}Rs4yGiYaRQBy$-(tZc#z7;z?jV5EIZZKv ze(1tt#>Rof`2D)`+Dp&NW2o|{+y#md52}!;moSHd!WZC`?ucZW<6hO+{opSN;UwV7 zj>D<_p+%Xz_ccLr%9X`-K|q?z*5$f-%Q4Z~UETP2Grho~j=m*0Ck*|i=Qd@?S=g5) z)FfQ&ZFDs!nD^KR-zSAl@Osm4FUc$n zR&l8Ky8I;zqz!WTShl$|R!-h5*Zz{z)XfD4x|~IP#1dvCbE-0Ly+Zl3`5QrDSW1c) z8Mo?Tyw1|48QvwP2HM=+mx0`=3kt@FEXPBKn2|F(_qm?G)m^tvDEmqIzw7>x$xq{V z;&|4_&^w&NHGc82hc1CRWZ5o@u2LvO$$NCGfq7 zYkrWt=y8DP`h&G#&{UXvLXPo{;L-}eMcIfwP6i6Y=J_vz|6Hm@1}6`yUw#^B}`JtMWO8Bn_hIWdjlSaB(eTSb1QB#km5qnsMA_QfNB&lbGyZ7YQQ!5~|Kx*L&_3N?q>8@5y6fYSoe(|5A{<%8N;G6yDwIrj5 zZll}5vB~F~Tv|Yx2Ry`OMdEtj`^@}-?06NCS5WVB5~qD#MpSV9`rF2+o&ZOQr^6$z zR_prK<8{PE(yHxC*Fx9Bki^Ac!0M;HP#e_$_x<0$1I|IHP0J^{x60}x6d@EL?IOta z@@I$9u=?nwSwg@|YiF)enH0?Hf*>`z_WQwf^4(4S3Z=G5B^^wf( ztztvxr3b=qOPPlkaGji_FVn^?n$}tY*Te?jHhwM4eny82phG0; zn&GoAw=+?XrTHp+KM?gf1T8)a>oEnliQN_MzPoEZJ=$Jz;9m~1sIc{Rv)_Zia3z(< z1o^WT5hk1_x@#eW5BPuC)pdHJJOMhYS7z3KR&eM6a~olfUAFB@k7Liz&+47GftlTn zKW%)tVx>Orm^2h#xv@>&4J&YpyoM+r`xD(GS497EJkp!V3Ed5!CqoxoEk$O@)739V zC5aULz&d{N!p%%0pjCtfZo~N6Gf$q#%R|aZN@myN2Ht(z?j%@#J)brN(*3xaBU^E;mgM5KK&{Q(UMi}!&{^@XR24eBWp0b+0z_Hdq~{y6?pCOE1$ zkp8k#^6hA4z4@V>vMdNP{-*JF(r=a{GM71(qn2VF(+YoHWslQ?u&!My>~hU$_YXHq zU6<8Ri8I>VLhp)i^*JZI;l$ugFueUdDrk4Lz~8doHfS;$x;PmS*}ezKob0@SNbDgl zEML+X&IfEMBSd7}J#JI_6Yh!abXIaTD>kyWcRO-Kx;6xD94OieYQC|Mq*Tec4IAi9 zY`b2E=;L08Fs&8PF2P=^3;bW{t#*h_)Ms83FF&#={Fmgzr6milN$Fc~Jk3G6P4Nnh zc6DJ~Vk-r6N8xc)#5W_S zram#z&-1W1fUS#7&?nn(Uz6)CZ<6mh)xYikCD%g?(9Msvo7Mny7LzJaAaRq@R`mzx z+m5!$r!?Kkk&~|PrMOyp0~B6|UM)~2=F%t~nT>%&(;&uPG^U&!dfECE9@#4tWxlHcrI@j}`*D9uYN*Xa)pd^9Dj?0m zDaF6m1IDA-Quf8x(xTE@@VYrve;+1`%0mv+7A{MA%{s>~=DC)} zcTG*sYZQVe9oCv!-`p&n(h>}tz{EkqkWNGfUf_OOB8@15nPff)^aWXSpsjj|`0zBN zY`yi)TUu9=I47+S$r;E=>UOcm8g0`dSdIEn7$Sm8h9bo}_5~Ou?)g&5E zzWLV}i1oPfEME+NS+FrmuXS9L;<@Ps!sdi*9PlLqpB-y1pc4_i>EC z*yE3*59hV%{JP%pUsKUM;?4xZhXZz~z)KB`Q zaOQPJ;LIcN)t~uiU#^?}&+A6{fRTrSJJ9d2uAdDj?>ie8d(O*2)~xDh+uQ zM9B9BqI=!`k-e|{x%WTz_gjAUcYOrb`*YV@KaVY5{oxOP@<(nt_)QgJzA$tKu^0uW zT^wWKxD>hc?xr?vAve%9qs9P?st(4G5{t26EC-Zs%KC{+-^l$8U%s@#L)d6E3y9JB z1`k0x5<+YT+fN>%@54&`#zM|x4dj8wF{1G?olZ}E<)=O5wGx?aM&J%b;0cd==M(l$ z?7ddmG=6Pw{ki@+0m-{DFDuSV)5UVFKvC<&UFk%YdRk;UmrWCS)b7v^oHgX+sF|dH zn8>PNhRmpql{{8OZ+-X1uuofj$-SDAbRJlFjj3dyMS^!nkE;x@}tt<4BcL9sM zl=>QAHxI0NZn@!G4_Y?9^wNg94Pwov}=2)^=CG<%$g%c>Gfh}&ZuJUyN!z-) z1Ja4fxSI2JHR-zTdK^76C2U{F@wQj_-Z1Sey7*yCjV-pCdyS0?oF4WTy`CfQ8Rm1Y zv`-Ca9C$-=xLTmilMf{qUqsiN0Y~&31kClP!=L-w4?gP*}T;k8dLOJ&O=BH)K=;t)D^x^tO{w2OHT~_#lg)} zUVZs|N1#G>UUyG;yl(s_bmQOKT-eFQD}LVY@5ZZH5~*{`bkR(%{3g$up4?pOrE8#b z);THVL6>4=Ff$)G#z0L^a>=!t-aZ@u7t_y3Px^WI1NO$6ulTt#5) z)wwcozT-aY#*h5{?eXKkacASuhXXakrnz>ifKG*-8}2Cc)S?9&A$1$1IvCbK7<5aD z^kLKoLAbgOG09nHkzebZrz&q8=2k8JJ_vhtZ9Zu2WlSuxh76(Mk!!%N>0 z*ytUB`9z>2cwY6~_zwq*XhWup_rdq6wgQ zprN1I)IiPi42u_9*Hu569G;qyd*j|a9#j(pWGy#GRR4AN2e0F6^ zuAFOq%D3fhx(lANUN2_4z*E=-2P>C!dqerw#yFqvpiR*qKjmRdPAch8X!3+}wbz z-07={1dX-iW~nB}S9U@`uJC{w`el5~&GdR~mnm4j`KCC)u~ykfWEVRsi$Cbqto-u% z#K$0LisiEcnV1kg>(9K1gSW=2IJE`66R@w}8ql8n@Go5dn13enZ08^XwFBn>`8V_L%uB89wGY-R{T4AI5a9U$_!69y$?gyaFu$qpc70)>u3%s9|z%Hat3V!wKYHIgoy1Ni(smsu65=^&XY11hAo&< zx{z@zkPz1~>a~k5zvDJEny$5mya+JS?6l}*7Y~NN=5aQI}(cANGS|yu`AR~j{#y_EjKcWsq#`s2#e`Tq}RiwE<&(0EaznR#+m3<_H$u5x+A-N;>pp89%QQwVAS}%; z*AyF#&ss8%{NZ@&*OZR!9hvV4ERnotkG|sbuFd=NKV%;J&>>PwHDdV+WXw}dgwxEGQtD0JkLv6aG z5N!QknB|LZEWYS~v-&4H)Tp1_Sh3|w2`tn5Mh{`Rx%asJ?U-7-*HG&;4c##xs|rh3 zSWx%%BtWBI`Gp%E^R^9M8gSQJJ89F-m1=0!zKhV zH>)bTDn@f$NCE?IB@eH$gWJr$*(0&spd-J?Fb{x$1=MDCZG>mrT#%C*uB@^9Mr*Pz z#$G_C?O|(SZI~$&+98sE7Q*usH|! zm*(~&Wj zXp!q1wjsuIlIXQQ2+l{qBIrSohOB6&w2iXerv=>b*Z#zhT4sC-J8s)yY1QI5HQEL) zFmC(Q6Z6Ca70nf!(3iSi>!9vA*Ojf%;HK#*Io}I-#p`Z(%rlxc`#T?j!*Razi03iF zRUf$NpX-0%(Es^;8?6hh#9Uh%vl*^g=wrYn&Gn&S-^7N90d}`?+}zgkrO^5X>jKTV zJy5@ci6W&x06dSAEgOVLo#O13A}Tc(!OW4i=@7>RIC&C(>RSW$aOuhs`s zCcqT~&6d$1$0Z7T$2R+$r@rPf^A8F+W_R<;SAM}YUvqH$;ODe~dBv}r(1HI`p4C3H zze$v=1{T|2BHnu^p6Dj_%@esr7;5sTl+_tlBJ?!R85p~CJvV`oWco&lSZTI1%rzc2 zR!c1MJ5NB2g?Qy}8wabNsKlNj%hF+cl92qCx9(T^wqsVXV`Ew8u!#Ze9r9a5{cFJV zy>3*XWL^_oPS9ZYI|2W*z7z056XxYkM}U~mb`~P=><`?eKNq_Fcee?()P)niDYLRfQ+xP zG~>4hp8T_qo$m+`qq|%CiZ9f!^Bq6XxB9pGj6ZvSpkL?9&XNkDRkARv;X+4dCzqWZ ztCdz>pcvWW9ZD$MN@iJryeki!Ytgc$K{qsvi0;VQR@t;}*&F`0p88%FJy=U#FFvHc zEg=EukTcSd?#SD`G(iM z|1tBAdac5Iro*upX9_U&_V&JQyS?AXZn)|FipBkJH6CQJYas)I?;1d94470CEt16^ zlOD97_%7lUOG;%atP~y?b!b_Zdh8puoeJ0}zV$(f9PHT5L7?f7UHn@x0~eLxN4ssV z?U!t;NN^pSF}4p`D|To;SLi*fOAH+%E_#U-viQ}Ct+bYdx6qeE%QAD< zD*m{|Ng*XgFA(?zf{g2~>0(-ag&ld+%D>i?j&t6!H5PQ%i6gXH>9AS$;S>vB+OPJ- zy>%sMd+3!@^fknS>ENpY>8o`-8S}QW;J{~1hSNI%n~z=iz#|WP&7VE;LvUt0^9W=g z&RlSUk}=lO%`ayL4r;W+ z>i986ziWaH@vZ z#Gh(G$~CqljE_6DhCF%_7KNb4rU%dV?Pi&mopIHPd@@J+zwf6R&^MQ{%?!>|I zx1BN;$>q-5;|!ah*sVc*<# zam#^K;kp)A`io~Zl1gb+zZ_U=*@nccc#@TP+=Ly4LvjXKt$iiyb!$ayKgHP9KN{aQyV04|L}ffkUA?ms4*12ivXR>bD)`A%Ct{-_xkQTC6*-v|S^= z`X)ALo%16j7Ul6901`gjlp9?uW@(O8-1Ew<8W*{YS)EBrb3%9mis>ZCk>;o#rh9~e_n!_j) z_~AvylfFQbKk+sC?Uz|CS3QuYY(=-pcGtpfoi&#Ky`B}&g1cCaPX$)8UQ;``#wlAJ zN5mt`Xu;@phN?Fw`HsMRM}Tmg_4XBiS2z9>Tm2q?KI8ZOnOEiG5BS97*qz#X=a5-& zR*9v3Y+3K)$XjkPb;I@_xgn(`DWK|h(FD212@`pb+@t5#G$zJNtw3&(lk_SVt#2mS z(%8WY7mOXOkQZWMd4;9F^HD%!sy9~4tZ^6{r-{rn_Swg<&AslNhkDMvG^w^LMQ1XZ4x!?j&nAXX7SKf%Ve{F~!o9OdT z>({vV>s0#4_jYVH`+QmONk4zZLw>Q>GW#=+z?bR9ufGcC&-mFb;_SEj$DTq>>l=wH z$J-g6>E6_qT=i?5-b6OO_S}+|S?Or#oN#tHT@Xjh=}bRn(94(jXQt#*U-qzM{5HMq z+I-=8HKl}fSt(!JZUl5KK<8~q!)t#T+gan(xa^N*+6SEe|Ji%nXUn$px@(`l-F>g* zIB^WfF@-~%*x>`1kQl`%5lHqmmgKiMdNEZY2}Mx_p9n>T@AwnNUjY9ARZzGvdNDEu zAqWU5mqTJDv8yOTuq-8db0iDLmah8tIfwBZV?1-seY)?x-6{f!@1A}3nsYwSc*gUx z=3Hx?efBwRbPiUglDzZfI4T2Zf6O;7M_LXZG!oN+84k?A4$tA37>YN-S0MkF!o=|K zh5LW-zxq3W;BVRVa(M0v@cevf-)IHyJwE@PRIO9isMjmwOtaURu#QoB8|0>fc$WU! zY|FM=Li22{+FO6eezU>H_%S^`*TtehDT1kgi#a3#bn(93{NXvwlb7bfMRmk!&*uls z&+HKdvWYEl$cz$BWI7&sC4cPvU}RllF_#@RG7HFK>@^TEziE-S;Z!Gl*pJ4^2izeC z%`34mj=f{H{mp~ho12fk|8IWz(ffb-*MB@dF30Dsz{~IWmG{2pNv8~5NhoG~KK*Bsz$4ASF+|~yV=9FnkKfBz%>(t&Iz$au4_h<$zBj{k{chzE}llQ=3~Enb|ATR#P<~L+|G17Qnxi2f%?kWc)i3Fi{kuL zaC6BeEgN;=&2f&O8_^MgxYiEDZ}9Qk>58`4M6!-G$=v1#Zc#fH;!}%@P8N*^gE!~1 zU`;oKo*bz$6_GDAaH*Z;U$e9N6(1aR-ncjW)VSwn1-s!Zi!~RdyI7)01BzvuJ|pnL z)#V+5DaRZ1-1t@6537dy-}!X5SbF?AUkmEa1xAsxkz=OTbE82>Q{VeW;1YqcO({GV z7wc+`HS(G{lR?-Uetj?ea7_=ip1d9jqBit?0H7b7b%I0?`O2Y5cs@cIuHkTxNA=PL z-gT;(v#TE?JNDWq7JM(xyW{eV%>+8UHcZX%?WW%8Z1ZYdTl_jE*_syoiUEH#9i@bV z`KYmb;r8lpf8_6e_jiH1wCArt>ihh57YkM3&;Ht19&2Ip--vi|dIfv+vR=E{mXZOu z*+iO5^}9LNMFO06!)y&3b|2KfJkr>?w}*E~NaG)6Zd4idg0{9$qz&F(tOr+p08Cbj zgm)Hxb1-OdOayW&OA*;dX-zOrAko=DJ#5@lqu~T$wGLBT2wgv&3+oLom(d!Z$zmJT zZUfU`Gaer~Kd2A=5%N(#*aoW${;T>~<_CY~4_$sVKsE2Sm*4T3_uif!e^~zmUH)>P zYU>+6Cx(-(QtQk0%vp-eb+S)=%|Oz1hsw#oTi{_n(v ziTya>@O#Zl3Y528kNI(p@cykW$$EKuu7jFws0Rv&)FvN44A&sC>YJl&jE5&Ntr$Bu zWyiz6iePSHy;uK6$G^aExe4cS$?U5!-2E?vfvkrFj6=D4n@L91l9T%8UvKqwb@Q`- z_q%-!b_|!pb5&q!`CLX9@agn#-QIrdtH1V@FU`7L3;0fP_DwM3Y)F;ft2_oHi^$t! z6v9a=(cPQRYzPxUPMeEW$>Wm?2g>l`3qJ>T?K^L(xnKZE!+$POvl$^+~=^ZTSgICOx$x3v>1@uBG3G&Q`Jf^+^BUz=tjm0xsg|<#+1Fe{BcB6}bGCA> zvJP*&9+v?a*2~zb_qgXj^0hLC(93|+O^bc^PGxixg9-UDk_;@55y!Lyxni&oxCU1F z4yYM~YRMyGj^NxP^3b-%N9*IJpZyfv_!2;0$+mm1K6n1zW|wD-6C=*z&=6HEQy+_n5k#hrfca>{LeY^DfL=${Ui2q&O;_z zF`NK3uOE~?A@YG+re_9G>-P$`b%eE=aK_8fpG;>jE!08c(K^JreepAMEU?!+w&P+ z(5k@A?GMhPT=keW?>;M>A?wxHk*l8@Ol)%@Vr+x-trIzXC^yFtz#q756D4#<=Xg(%8_3@be<_zFocnQR_j>%)RS z@yRcL{r!La>VFZu~#+&QHB^b9?=B`Ud(%eu#GSP~Y`GNY#Cu6F}WKF*;ZNa32ND zS>gViChWR_*UskwIX6Kp80(*HIPb;L+xBdZo|iov>%TFuVdg_{yr&;~@H0-oVi?=c(PuYSEZe`+2~DW_)00Z}v}MSmM}B3nxLu?uj+?M5+nr=-w3%0GIX+RN(Rs zz&B7dOl}{azQ>zJ>(vXJ9(nsk>rE()ia)dwD8+IGk%;{KM_{fpvCV516#&|XX8}ixcOr4{n zN)ADw$VJV8kFbI7Ha-U_cu*n*MlBNf407QzsBr*X*w)Vi^oQ9Up7KKkZm`U2lbW0! zKEBaA0-yZyBc<}ekNlx;{TPtnZjBrN&DHgXulbIjrknGPZvK=awNZh5GSu~)vYM9~ zm`*|=G3v=%=LUFd>wy)FMu98*oS91^fn_;S;C;Fle{7JsSvm0tOI%W9Uk8intY1bZ z#8~otw-2C1v#+Iu$2U3-o`^+c8Me2t!yF(taxfgszj*M0`}p!P!C7Y40Ayz|fK|7# z0}y-n0_w9GZrHe0y;7>!W{z(J>V;j`D-+;6a_cl9uGAr(ZH*5#yR-?TtM9S!a(M0v zTpj?PyJRuYhWx#~M0oSFXy-c=uhDhzQq2XzyNksPSUj_Hv|~J-)$Zk;i%OTez(N$? zn+99N!Fa=gfP~)1*atzRTpXBbG(h7HyJ+P`dXLLzn8#xuLuPK)iMRPJvE*Bd_7C*% z4?|)j=v)vE8z;08mn4%rpGV z%oTm7D>kq6@*IX$o5%;TK`1KacfM~CM$I5O#eT#N4|53^)9#hWe3m9}=Vn5IT|+yK z5yvE(cW_!OWL$IZ-@Eru9l*=zc`7jH>UnG~SXJOpfAK5&{bXIxv}h?}E>11ytoEr? z=kC0arI?Li%xs|8pKmmi8}9`V$(*(2M*?^)&-j3`!EzBec~-?WQGM#5eq@qly`~1Pi)2epaa^BDFkEXwJm`k3bqtdg$IzpL)uV;i zKwoPu49v1n_{dxX^2%HSHKNTP8bga$+$%iR?8L8r)^PgW22<8IO-JW@aPQ9?#w3go zbR4ueeDjo0UzX7i71$ZiusD;Ur)~9y$2R|Ht+bd$or(6rCXbxxn8TCO(LC8#*Gce*YqVg zuy$GkbsKK#QIl?PW`NSxg+SB6uM5En;J`AP`prcp+HtJD2_&*ZKJ^biN9R$&;EBVn zUDZRor`tRw3V*ZZ5H?byv+%P6_ z^(y?-25A}v>P$m!xSox;=M`*Fvo|vLxwN8t5FbX~DLmZupCwk5@rlHYCY-r?=JmX! zmUU*e0;oGe$@<1D@;Tp;8<7x(5L>;1Lx>%@iuvpzWH>``myZ}sMQ;d)v0=oyym#~8eERaMfLo=Xd3gB| zz%!TX9H;dE zMPxQ4GR06m5t?o0b;0zAG!QJOEqy^XZ(u?Z8m)cwOz>U#?qK0kqu~o=ccSr3!)Csi zqZl9U4NpDy`U!Y68wXFFxqJk>Tp8<}?K^&AF=Lagd=K()pmk2R2PQx3Tf+lwAA=on zTsWp&+5p5=y+73Sqd)#vzx)sNgTT9A)_43jH~v(=Ys_2y^GS5-;m2jkRD@L;-@sJE zuHiZN^wiY(3+$eHJ1q#cy8by*d8x17K+);0445eQDw&_AL7G?d68ES$=liyTiq_!&tj9hA~ z7CO$3>?Rtmq@*?0;}G*5Mgs^ z&sBj-;hw8p0sooX+i$x5!ms}(i*c?;-t??kHJ0jXvm-3bBK9T{z!$06Nz2Ns9<5&9 zUU=!|jD05%2oi5OVg+_)6GgcsUV4evcwp0Geo!+^bW1)L(NP>Z8(Z8;sl2X{VorQ` zKkSkR5@d5B%`A07K>}mn`0Ye?E9YU2%%QYS3G1+Tk`2<-xKld|KLi{9G2F`k6vJ~7 zq>I8_yOcjn? zg}#$*3p3(X6b7-oW8i7(b0D%LwzVohS#_KX#@o3pq1Qp(50iJ{cCyVOAfJH)dhjG* z{$P$<0$4*RR%>pv))$CDb>UTQbgv6SUTg=39BPwA z-c5tJI(MFzTjSaA2L@rbmi;g5`msHnYHQpW5hC2=UK9*R;CH30~UN#<2=xj>@NgI1V=@g^#w! zW`T{P3s1|xY>P@)AiTWH#&}U7Y_64~8{7sA!Di>2lgPu<_3cN0?5}+3>p%JnU;h8? z|3v4;|E`yR^_82Oo1ary`gK0lP`}RSzl}Kwsb|P{eg4j`zq{uWpj+}xTqpLFrrbx} zQv(6>D}0i{#}Qj}Z9az(TFyF`qH`lX*ND4|~;`=HL$5edrLK5i$wyk*y#mt;$*_unQNG_aUi00%(i#j;(*FJ z9cYvJ0mB0VBcV~1tK2HTMKLU83Y8Cs!>GnO@uUd)TM_R7EQh91z7A!+Hw>PX8 zz7{he6J)`2J$kKXtexPiK=q8gF)E7$mT2fb(%}qi8YF2$InmOewF7Fg^^22`!tV4p zY+{p%{mmwZf}GXHjUEM7;LXBxfmpXbrFOCQeF;lp)5pq)IZ>nVT9S#_NXJm zv|s~){@fRW0-w?uJ96X5i?8H-UWbiJ`Fh=K*l>0Iz;Ju@P~Ulf^v8bTOZu?j)dxQI zec$@C625$z1vQrp zId35gk0w&W8gA77Z8ZC^);CV{)4WD?b3u|{k1J=put`b0<+e2nwLCDuC_OPLzgyoS ziLB=lTwflUI|R;Y=`^5C2+q&0QzttXgG>uCuVEvb7>Sp7R$Q{cP>rMI<%>*ME5?aI zb4cx_pNzt!`EZmwd#PqpI=}huy@8Jjesc~rNKi?ZDOl{OC&ThP@#eJb&8uGn+i$1j|HSm$rClBXzJW7&dv)^;uX_F77Mp_wxfVC8akXqv5Z0sX=FP5I zK&iKl+>1i&O1QbGN820>=OgbIiM*$5Tb{G{Vk5P~o8Hn5j+~Ya>TJo#Hda`-5>K4x}6`;#85*YczQD&oy6!<+8~HB3}KksQRAtV?Xu_`t`xv z(?75Wfp@=$KiPY$-{a@k`Q)GfnU5%YGJJj~Ea%%CD4f@Qa}}OiL`#myWxz+i>D{p( zXqxbqNovc)nBEXv9|TA9O-dllMw9wWP_A%fK9~W=pQKCC;hc*Jf$v&3%$&33UpRgS z?a0nia2Tm`*Z(J={>Q#_A)GZJr8(g0^$6;h*lVAACZ|GX}&G%TCtXvLWgp?CO%9=&qP4k4j3%$0m#O~Za zOxb9Q3CPyGPc>%)b+1@Ea))D^#5eNH1hq~F6CA|mN&t&DP#+iG7Xh2IS&umOS{w>u zjJ+?C6AYr20EzHb9NSyC;E6Z#!F#5|gzpOoX$+16Fa`i?&4JW~yQXTfRmH_h=7o>_ z%)`+KxMd9(g0LPV#1lYt;H;kn$}#IFjt_>hPo9!5I`N51Z$hxf7`b~BG%M~x;eJ0XUw@lgaDWjJcE*&#n`=vZBhu?>fhW` z7k};P4!fmYPa|vZ6>sbq(N}IujX5vK=6s|M1#NopE2gR!7d0iS{so~qCzIpOo%+P* z&N+UQoA`JqMoq`x`1q&(;P3L}a(Lznqn z>}BbaMaQC^Jwf5UpRM=IBikGb$-2?$&*ZW93DjX!-XPworDJQ1S2-X5*4jvVLmFev zP$A|p+-EkLI38UYVjg>s1B@}_&FPWDfpm^?Vy2MQGcgi2yo-qcZm8ue%<(S;hza7{$_Cab3849gH%3>D|wN?k#mRBC1KQK z2bcb>9PzDh$-_`wCpL5K@BuEp)jC-3Z^32XA5AQ79D+Bfo#wIiF@)tb^Iq$b+rC5u zP)s5o5W#Kk9CPzDL}>9$z4kovUH?&!RSDZYeNC*JaLN(KLz+Y!ka3gK7GDb44Dds| z!g?;5AfDy=t^=9>?gK^nTG+-YZu$`P2P5IGNe>3U(!MAw`=ZQ|J++5^#e0r+DcExqYoNL)@;#8&U^Zp8aTc~W2uqfY;FWLSm|En0$Yx*_4;I8)>Cr@# z#lE-@)@;!;Z?peVSa#SiSna(b!B}x-WTCg-GCFW8Z|5L$Cj`+E_j&rM)2dAz3SFPO zy~f`9mc^5ad%z;$_d+1_ng4RpnO#>1<9(5+5CN~YnphUJ6gDbs!`f?g6MyU{myk}4 zm^qfJZBv2swEl2#)M$7Pg1BwI@U{MSV7P?k#=p28D*ccB$j^W2k^TbPGd~Et^M^nC z-mB}!y7A{{{I~rZ{i#W!o>*`@>%=!$$B~0;sTiG|;<61l;ioiX6#kr5-t+g*_GQ19 zZkZy4b866aFgN+ZQ4Zd%AWFwsvV4L+a8DK1iu@mALU&6r` z4Cd4zq(w`0=RC^BUh3aIpoEhba@|B%zV=leV-N8gxJ@Fo?}-P$#6WHyWdhQTX_`j* zvVX^(9L!UjIWx-!@S2Qm*!)(#hRrf5d0rOT;UNU-{pG49P6?b_0y3%pd*Uno5GwJ! z#>z7Ea(ImjY^Uor5Et=T1^(1mzVf>tzjFFAt4(W9O$(F7>V>Jr?8TUQid%tMvgv)X zSqr(RK=WDt-U`*9W8sxnChmtbyT!9PEPb)a9mzPM-<#&MIRSF9NiqU$SYJ34z~bN4 z6C5&)=K?Xci95(90U}bXZ~GB<;vA=*HHKbcfH9~{E>*-p0f~fJ=Gu>IsxjZ{BIFX+y$*Wqu2UgZzc7DiE3@)3lOZ4Dedq4aRwtGi9AZ~V0=Zwcwb21fUZ0?*FLr3m+ zT4KIncQ|IhuC*ih{Jj%ufqUkTjmcgV{2;Q7qww}Ek@}Z@=Y!w<;ZJ_&R}8rvo~Z(t zcL1KLOb6)I$5%h<|0L8me-At>-rI&HYK&AUGoFpIc8N{vq!;hbh7Uv* zyY#*}131Ul#AJ(_4I%~p8=7O>Hz0P7&&a_gA9T}>izsMV$Bsc|>Q>GsO>L~Umm_9B zI91jFOo;u8I!W8p!E0hc4lYa*5us3LQ+e#GVFHj8y}P^O2o2zHLULR+eil+&Y&C_)fgV zk5ys~|Mr2tVwPipa}R4>?2$t(*SaJQ$AiHFW$3!Od_LfU*X&!UFbN~Jt@)xcI7U%h zV~)?FEj=dy7>ByX}=aR}m3%~tXX)Z&@Z)3HsAvUsY;tH=>iL-tf)j=Kx><1A!MGMxx zmyP6p3LX9F^y*hn@0Hbm0o$cLTLmr;0MAyZ1NHdo{kh;s#2REnuqeHtfn|~Vp+I_H zU=Vk~uZ_T5uUWou%;p8|hSGGx!KEoT|JjJf2l>R&?kcs9ab%vvxMR!>KQ=l{WVr-r zF7U+Y9@u~#SvWBt9Ajq2ap;A@H5nh}a84ntjTPo{JWS=nam)n=d|>9bBVYMaFT7*Z zKs{|3fsU;;;AU``$d%iu93nyldX0SC41W2n;H-X<*?i@Ti#oEmt_4dc04(s^UbFrD z=bSVecO944dDlkRhx(6sKKj1D^rct7`d>aeJ^ovd^?82r-4}o3#Vczd-V-kv%SCNi zl!yh^q;q@rxKYV@)YAA<^TXToL_G-5H;^IkdZSWsIe|F9H&Zu6=2V|2%0q6u0jozp zzCg(zG_&@IHWHNhPz=T6(@wF$NH02bXkc6L`sZB0(*WZdx#LSMhdUr}`m&83g!FmQ34zM04_6Q`jB6i&(nfN${5yjqN+suBa#)6Qg6=fi!gHu|tbDhF3 zV43J^<*>qOeXJ!6gK9$UHS|LO6w>+E01>KD&;6Z`o5wdFkofWd;Oacv;qn0RY;{^F zEzq~;I_0I=70cq(>huoGWs|+mil6_M(-ZVG^-LazAGDZt1eSD!cYurD0%TMawfBoR})eq}I;BWVB zEif3#LnO_0Y)RW%a2-fSWNwme>09Ai9qIxk@QqFUx@n|AsHX00O^R?3=&tzN1N1>V zr&&+#{Vt7^045ks%sxiy_n*(FE+FI!9e6pJ-xgRrXPgPZHzWIr&v5|@c3HEL#++E> z%Q=7v&-5#Y$|qNB&|#2s6o27CXG&w7tJM->;?w}xv$3%Q6u{U_9M&(=a?o+}RZk-} zT40sV1B0ijXC4X&BN*3KM()ipM4lvEiTLG79^SYXCUe>@Am3tjSTrvSV_wHm!3b;#VaENH{Hw9q2=@a_Ry5I|V#U|$11IQM}s ztoKN{bHRx3!7k1_++#O3j$?wsI6=ivH!(6p>@R_5bIXA6En@p?j)-|+qg(>SwBe)Y z#YF~V_ZE7JFwKU5!eESAONid*En3i1TBn&D}deG zTm;pd8|aKoWd7t5`H`VjO?RX@51!TBaSWAR>j0s?uJn=Cx4!@3=}JEb_^prVLE!)L z`&T9gnu{**;9V$&{;%3nH%-r*ec0GOu+6904?cJ(&DgrW5`cBdhGSzkHunQbH8Uo_ zu{WFtiXrx}XAGIiV|!#8I&`R=tD$fcdtBK(6637ppg<^(sTmX45@2P>BC*6|HpYYF z&CDM2owVzQt-;3Fc7O@ijwfbZ;d2Oopt%{xjgA{U zzTum5Nj=o?)w)<`=`f_n&2ahQ%y~=4lc?h^Pvf;OVSILPZoUokOMCVTTpj?Py;erv zoNgZSD*)cGS$3Lbp|fyV#(syuXsuf<+}T*U1j#ZxqzHAjGY*2bGnnPxg==#UuT=ui z1$HRty`j{@m4^|=MVNrisd@Fm#cpzRIHLgC@2=*?U~(uOo{2oc&*6VA2)F`Fi*|)0 z$KokFPV|3WT8~$ZJywFsA;5m0=lMB_(n>dC)n(?3bA#J6IFRme!I9{-t z@gbLWPvF$w&j#kgB5Nv;8Ha!QuYEY-6O&vbwoeq(918Zr_}hBw8KuLNp5JYG>z{n+ zi|to=5crk({y*_g{Y^f`zCed}T+Q43K5Yo4_MgdhaG6h?2#Y{kK~1`5;9qzGO>V$x zu9fYWG-+!xO^hQ@Z#v<4c+fxlMGQ5)UL&&riLkD<>E|3QZ3ebHLYTi)XJxtJb?t~V zUnS`kL2~qSUXTAr;W(cpOpVr>8Jm&WiD;*f2j^F}o2>)NLjb&vGr=;>lz1SSGZQ_M zsULcuCQIVldauLalQ&YeDYo#=b#lgM%ulzg>uJfd z(XAVTWhDDG7JT03tocq3E)fXVF?}vFXtD{R%VnrILIr2CG5~^Y*=If%tmVmMAwU=2 zZuapPatIuYO@>2)FBk|3EZpWqq?e_|+ZdVWhD($f5_9>6TUemsXph;*=E|tKKfDN@ zn-KH*z!%HW*;*bQxehLsK$#qpGdR7}kWQTFR?S9N8S=p`n^*@q{(0wPYwJ9$SRo34 z_~Vb-Q}e3OH(Vr((F1T*YQEMGWAyHIFn9QoFFL!4C-W;4;q~D#q(TAX{|9zswIO2OcsKh|boY z?$~2&*GxBpctoQ{FGZHBRB}oAX9+Q!mF`PK=71_#Kxu@YSvW06+jqL_t)swR5flH8%celi!JvJU92= zbTyYn^8&B0#nV_Mo46BaaE`A!>I<*?iCJdka-1t1sZB1#rYYw&&+(9{4JX55EYsZQ zf5#L%JgA%zeue(||Lp(#Q^+pu*(%T_|7_qlJL=Wj+Yho&=NmUJw%$y==z8&6(1q@T zamiZ00>fgcV03B4om@4iLv2=tOc$hwL7CZMrXKt*lnxrrw&g*oHk@dFGq->Agzn?|W~ z11Uh5fSKDOY3rslIIn5xe6s+e7tu%0Xj)eh*svrB)V0fvjkyHogg3tOzx~0Re4HnC zYROUgxdxb?`yiIY)7}opF0vWL#3E6e`om|&OIOHxVA34j?dgSo zeN>nJjVo~Z48R-L=s?`uelLrbJ=I58>sZ8G6a42&b#(*d#jNo_ndgHy;6SkCS+K=h zavZ$S;aoU_Yc$dWe=x$2k$1xZz?^s_kAJ)uy9Ti#qHOE{vM~+PA@;Tg?i^zWf_CsL z5Q1?m$<(|KP{0)nMuCkz{G@RnGulwnmzLpK3%w&;^#kBg=>4M;>Bk8&y@-u=W{+Z; z38sF*TfH!`hmD#+`qWy+L0MzGD5x)nTg@iWxIg?OPpw6D5NMorhl7Ufejt|B`*g^r zW!zklGgR--2>kfN)9vHi)7L)!>gn;P_@Nd}l`}kk<1?`#Pc2fDIiC=6ac`ROVK#C3 zs&Cpk*uUe5qcwN_JPZ(q4(7wk@kACosnLUT%h^t?BX{1*P$2WQ#x+cBAdsMhbB=*n zKk*cn;A&z_YaxUD76L#TdGy>ZG7m;=44*T=JsG&32~;|G9d@rrG24$kaB-~~4s@pD zqNV{`V>ohxB=8q;sM#;j#L1~Tvp1yYLr*AJ$-IXS8Uu3cHNaJb3Zmm#XyQvu zVBip1Nuj%Ub^S*py&RvV0+$DXXQ|R)ZcpFB!t_GZqGRD_?RDE~5qewr(Ok-WrN>aa zg%4`Y2AiK}&m1>i_+vM76!@aKH!A)kwH>N~p=9jMft(F1N7=a9WX7%}#93o(z@;@$ z=40Q0jgi<{R~L@M-u{gV+a3ooj?WZD^JcQS-(n#Thhe*gX{6>#X^cZmsIu&jZm>Bk*;^Q0F<-N4f_vbvb1Cq`Bs+7!pjtwP)%WH5lxff8ty= zXTyjmIe1JY432$>4D+Fwe1U*L9vAYjzZdY9AJc~g^;-j9{rIEP^{?hZAawz#m!p-V z1Z`v2WNway*dG|$-1xyrVX>SZwG1S3@Oq7H6B*Ib1JKNSFW^dQA+<=rC)V_9O(S>f zxs$Q$Pkh{w>?phpmmPW+y0VZM@9&1~(CBE)E4Af@$&rK`KVDpyC9e-V&Umefgyfte zQ`9DaQU;nVzTW)pT0-{|FWHt09^#wzKakL(h{QSQ5FCWEV{k&Lj>q}mY7F+$Jm)Ams+k|+F@WYxAVlMP%p zqC}jD=0d;Z0GdE$zv12mgLNp*15C)s1=HA%g9^yWydyvQnv)QLJC_!^^tgZdc8Md`(Ag*7Z&T4PLHhYwJiO@KD;E5& zn?HDDn1EwW52|D4NGw>nV3!!I2cw%9yymbUJoPL)M|jjWUh07z|D!GUKI_I;bM(6f z;u{KI0|fPLPIi+Qw&a&p1!II~cQh;M92k6~eKFEgtE~l?>86_U4Oxw}Dz;;VvHg2ob9#1qbQdAVx^rkCU8Km3X9Zancx9Id&)xoF1M!rKi2 z_zNXN+g0K*_}Cxy3(nx=zesjj#wKU+elia}*S zvHagXe^P?g)#Sw=)`P&mtq%+S-u%|Ux+zW|;_!pOTzQa}mtY5Pk#*?v@=aYs@ToFf z2qfZ0vEiKuB$gkF;kVp|81v#F{~Q=IRgCsyj^=Fa;K25!ZtP4oa@oQGFM0c>Pj5qn zQ0U*pIdD2UU1@CGS)aKfRN|d5%P|fX?y3Gn3a@to8zf`fXzZpw ze`JJNgubb09Ix5{GMG&yhJ{-@Mxx`!rPwDCJIA=(lE?b+12OpV0dnl^A03-p|3(fb zq_7=$PduN|-pgnGBPD`ZTdZ+>po<@Qj7eh-4*hCPjo8DMyzpZW5MXV6J9Ls;WBHLk zEY8zEyXn~Wu?a6ITI^O`>H`h&Hxj0C+&V|VQHTWYeuilF@k-u`QZZHoH#J%l%TvqA z(HHFEv9s?CG89i%Ms&w{Hp3u&BYN?D4^A&#U!7k0@AU_TKCOlA8q1y=m70%}nr~>w zc`Zb!0?^wxmZ3V26*ghHA+d)vuDg^48pN4_JZruoA+&9{lBam!EdAWLTu=K_%-B^A zsi&UH4nfBZBT(M}!Y8o^Ss#%{IkuiHC*iP;y(YOo%qIck@Gz+l%f+v^7{VHRW73B2x)8vOA8R1x`F_T#n_^_T{1LVQSU|kk#51tq8h^ZVy6m^bW2TUB6ddDKH zYbl}rObfDi#^7>%qY7Le0N$uVhyGi=CON3lWy3MkGUnS8EkG|!u3-8)wuTYDzGTs7 z1C|N`w`?q|glB`Rhi`3?UiH{kY#9F0yqVY7BKz-1=x%D0$;LsVE%VIfYp`H)u^vp= z_6^ra>p%L$5*J|2=p2}kS-aADS~1}qH8nC8=!+-kNduu-Z6CmqN^&0l#KO!L=_{O= z2WyBYjd&c&kNr;`PuPpw0p$E9B8b{1Pfx=HX37w01@vk2Ny!hUSrx*2G1F!rKk5AX1)`tbKVSkuL z=V%2;yj`dC#HoKYe2**OBfZ-bN4H@yvJ1%a8AE3U#M0XjINxCGO_TJl&4?sLPGng5 z9SMfg6M5>AxL0k_U@u&9mA7RRxgT7R(dfye`J30m>V}IbHXQD!IYK*0NWSq_Ic^*j znA#<)XlFgz#BtOq1=6t8i4~9&90%Nl5y7qZ;{~2LLG1o{7t%Fx97|&&&!CXMeB+}* zzO1)G`ddBmxmM!vyC{B$yZ0>tU5;;50hauwy+H+j>h|`&)>>+%MYx(bM;5gg?Chp} z$5n6<`qh?+9zEna>3 zp_A{f^$&U88kZi7_4HF80K8;JpxU8+o86GemyKjzieTACn$sc^pE)E@fA(@*I^*?e zJH~o(ubH>>HH_W#eaJDFWyvY{JJ_+AUU~Q}cjqRL^ws&HV?KYt6{+#&Cd)iOnndp0 zgt0kut2G!KDN?V=pBT{}{qk+O2+q!X{kKB}Uus2gne!lEKLnyL*ATG%=v*M{%SIeD z_h&=sjH{h-_!!J27=6y;?Y$3uh{w-Md!q{EEWHuxO|JjNFMRC-_xJ!H3*0X*APiEN zxtw_F9XdGHaY2Im;j|kG>C*5s{nmIE`)rOdaLZvoaD-cU0x3JzVPJPej|B){7_hd3 z+BgZA)XYP#S7F1AI{G`jwYQIrODMPa>{!H!UUSC~%H>wF8OP#$zUvsX@%PU!n6td& zC%8nj+uIQr6A4o8*eE#nTJl!G&9<+>Dn4VDgMguc4irhkJO0Uq62~NAO-8vWhL%dU1uTAM|-w zD>D1yJShfu8iHLf4QcqBm${JX#agg0Z0aYr5{xfwrS{DX9BpLIG5LEvS}wGD;_(L! zf%jno+0@oG!w2l({m_K3=zr`nOFz-C9?rM78wgZulO*Vu==t;>r4?boLa7Oglbyn!Ui2LnN*wESm4ZmeS#C(9O&m}%BU zuL1JBia{pr$+#hRn%9uZH;kYngW+vV+k{%8SlUW-J~Rf{2ZY*z*qE*+ll>XoJn?Br27@E`sqf2m9Q$CTRR-&Dg}% z9p=$d&qONCW}m3Ycj}j%4*S6)0T*+kcKwJ4Y>XWj&s^C3BJ`|9rqy!b;8PH+7) zFP`pyhrUq*!gkRsH*ay`gPR)i(W{>ulznQxZs-ObSj+kDUCnidFH`fH+c%dapBs<- znNvM>hJaqyCA-oW=;M-=J_@>W;oLfbx~trr+>V+xf(4 zAG`w)fAPs!M0J|;Fm@8!Z+eEn@CTJmG>?y?hc9(P)|Ya$jf}i*Cnl+_pyPb_dbKWmOBNn^bH#zI^TVX?_qLDM^)$`VN;G{q1!Hp?_l7!mII z?l7=>jnEC<3{n$G<=@pQ;NXc4Jn^PhW_Iq$u9%3;6;BnwZC8m$SRO?vAAk43AD8u*^Oftmg!U3)NoU{5yY@H4^phpm!=s0SQe%*}0 zOp{+863ic&EgFD1Bp%wZP5zQP$oAk29B%9+s0{ZsrZMYzlF@olkP@BSj13M~bVFn& zLy_=u*p_6Tp)}b{4JCG7Cp}MA@C^;I$O(UXdHz0#YwpCx3#_Su^J6NTtWfn=r+*I7 zrM-RyE)M{&Umt6=%wEdM?t*4nkr&_w3>?sgT&(+)S4X5THGBX&#BkOZ_=?#4=lCcaIg&4J@behiQ=Jt zO&|%?-?D>4ZOlC|MnY^MK#8ow5usjfY=DBtx0HijxETx|7`<$xk!fmgCb0?+V@{wz4{kjsH`_HvTQh3TkF%_TPG{fi_|Mr^R-~%@Wh&V zDE6ZDeuBsNoSITCdv5^y;(#~c8tW_e8E0aM`J(TIW=OHt7$#b`eOb#}jUB|BV+}si zMPTf4z)iB)t)(A_g(jT2fW^iT4m-iZhaeX`gvvppRT~#Y(g+i^#tW~psa3FbA&med zh#Dh8T5!X^Y}N@o%mxnuRJ64winn;&jEg|ejt-@g35#j`w=l8~1#2wlca_Wm%+aIZiFf#7?c?FvF(bp% z#6Rxp-6jDh2Y78!znMqm^ECv5Ee?&1lOUff+JlG-=UwX5;5;s);Lex(6}JaMY_VY- zeMmj#$3ejKiY`5Z+{jZ?csxRmqB#0l_*fQt zHniRd6xPoi`A>WUN;Aov5pPe5~nNSR@n8#KjD*^_>+Ew_)fM%#f4w z1TZI{Fd%2=$u_}5J*;CtH}bJbElakz9pzch{xE0B%*z4x7j924e!qS+po{v~{}+BV zz^@NV1DBey=4B=sd02Po2WN!tCV?aeP_Et1XPIc&(jIp&*qgoN;1~fgb*7nkreQ*` zKG5(4jUH)ZruUr=iKDVA2?_?XVo%1mv39Y}Il%k~!&W5d=&*P0>mf>wHDbC89DBi9ui;r)jaZVf8bIOZJV! zHsHmPF>GOWXB~QMY}#?6_XHh-xU+~jhT9i(>6i~g#+blEK+#hw^C0s;y@lva07)R* zAR3P0vVWmqL1wmP4<=YRgE26N!%b}u?4VXG3)_Jo#Kc(__PdNaST-w+BZj4eAoxTN z7D1w2sW4de$uMSH0K>kFM6+`>tSL8B*H0MEo#{ooa+Y>t$@zmXl#{n9350MHa$H&w zu7>R!#Eb9JCF>CylE>gnclx@%#UMAo}!{Jb9$LeE120|AX&k@Q(O>(4|$X5WAf zja9yRiD1vs;Z7o&m_BG9Bj83{_bZWLlWvYjfXs=pv6F|#l6ruA8-pHx_fneTDeJY^ zRcFoZOKUN|H6Q{%HTJyW$KDquf}@mng)=n=CAETaniVH_>7mvu1jo9duIsZF))II0 zrCk1eY8=z%r%$=K3%>?3bPT<~nqTMg=Jx7c(q7u@RN(Re@H)jor3L<09#p*;S=3$O zEZS-Fji|RE8-fLGoCyr$w*kCJmnaP0BXD{3>(l-s^F<7W7r$A(*drISbh$u5mYDKZ zp5u+ZBQQa!W#{W>iH`{F$Kj%KBe%m(##J8X#nyb;Ry=d4Xk)Ivsaia0^wezCmARCo zUz#N% z;Ol158nTR104Qmz*I?`y)CmIu6{$zZ)GFJJlMRbaYIk0Ldxe`;{M0D;Ia|U=pV|iQ zfNL6af>Co!!ACG>uPz3&#ZF2O-<5X+9{r_!M!&Xt5RKqm8s_@q2O-Vz5wA@2nyxq6Bkn2ytGUy`_5`5jab=95 zyW(1h4mlt-bmP?Lg5Mn2u8H$OMPf~rN{VrZu5Gk$MSN+mT>+Ks(q5|q@BQpo|Kz=! z>z`pk`F~r}>YPiSZMrbohq*9z8Rr|7(0W13O156yl2Y_F_5{JEFip6;%mI7B$In{n zGV$)Iad>Mdykjz^^mTgp#v+^>WToo*9O~ zoW>1d`zq!_nYcC`!MRPK#C4pr8IQe_X^;*{wkub2iN{n4CakFsZstP2Tw16Dz_z=& z5aIY57eFnO@=R}q4i+{PV;hO&iwo?u`cIeqJ+2e43pgPj*$TQcUqwsg0Dy|C>nheq zEygvR!#}aDnnHKie*BKBgD44abNC$A_3i1^|MmKG{W*PD5P$kdPxHA2$5;pNO^rQ= zKtlgsy=7bc_zy+>wr=EH1^2yyOxUj9s?{JBk+DKEpmm7-CaNzZwsC_QAnMI`xZx>I z>hRW==RFUYjx8~)BpT2i>n z84vfJIUH%K_lzZ)8uXbkpAWdY_ksWMm;S)d)Zo(HsleqOfI9^_o8H|12i(i`M}R8s z()D8FkWGd*i!b_IU^HHKT%xkZgDV{}bE%iY)+S@5m&P}`+m0MnUN3!RUq%k8 zbx>3k7#BYnHk>(4v3T%jJ9Kcw*vQ=cLktUTa}fcuD&eBdJbk6YjBQZIF}X1xY>>#; zWp+qyHlAWL_Gj3hubp%J?>9EnEpG7=r(RRz!P*A|v?!C1rep4?1~YPm$n>&Ghdbs~ z2tzB*W+IM%iN|==NLV{WXQhb)8b zcU*gWpBSY&tOu9A=_FT8Y@+W9ANX1a?apSRZte!{Lz%m$k7?_umsRUOL_(&{)UVX_U`GX)d9D!GzBNTpj?Z=~LR} z0pKY`IYc*aXJO^;%(B#rRi)nR&q~&8E+)aE4W{a4V=6X+6y7l63K9)=YErI^2a~Qk zv$?pC9a|9{SZpE|2RVK@Am5sKZL)l=z)Cmh6}tpxul^3~&;Fc52KqJ*3W`t25*@@SOzLx|nAiB$9|C!z#AKMGMA5Nd`OTA?FSl zu@JqQeaB)yhOd&DsGpEx*Ymg=Y7BfLac}!#OAxoIrSZmKC<~OHTjM!3L)NMbVnAR% z;t9X_8Qt)AUOA}2@X(7`68&?u@$DgYk!2blhtjoaNyPOZb0+4M;c`1NUELqNQwM!U z;8i^c+;xl!p;GcpQ+MgN0W^q*w`8$ z_~ff~%G5E&=s3EL#wHB=z}WuCC0NV3NtO%t@ry1dj^0BX3g8+*LVR3POlLNUkl`Ty z=tgFo&k>wyhH5f%q#kpStyvhWcEo0}jOaO}LK%bhis431n`_m)&A5IwQ&mJ~JVysP z>DkwMXP^Pn-CW>4QS$rv%)#Vh z!@>txnKhas88a5Jnr+papB}2}*eH=>1a~+Ap*ueH3lji(VTi@kT&xf?r+J*AIgDTP z!HxaQ12Cru8b!HET#o6Mzuj+wGGubRi=X-Ak{b*j)nsp8a~?6e=vEYGC?L%(N6=w$ zb0dtO=oe38mUNkWu*uhntZcbqzT;-DKDof^Q*>}gl;dVgHe(b1U3uh6EztyDGDE4+ zXcE@MIW|Gtau_VaE|~b_XxsAETg*pCKavi{9~#EI@HVj;#=(Oz4vyK_$5x=?u=kj` zu3``V`2Ew1Kk?$}>i6h@03|mcFdF*1Ajh#f(qhr67Lw_~ow!(yy3W6vs9k3fA8l^EQPzGA1B3 z5^*qz5gszLFCN@9-^XaNf!_zXOEq#?h0?fHg*a1xWp#cI;_-n(ECh`;E`P@*irIdg*Doc_n+_X%Z>R z7`eXuVkS6a{lk!NPV*pOF=*7?Od8F?MlOn0jOW`Z#8qi#5g(3dPv60#x!84i<)y}Q2gW!V6W%GVFO+biX)a|Y$b;R-5FS? zR%Gma@eO>4_3i%SpVyBDzUcRkOH^Ah0k5DRf?<5*oMl}~?DXja zRo&%)b7mYy827Dg#&e#gU&KJsgT;m>*=i2J1QHcsy$;1q?8}D16C8JCor^NpCydl& zH(_`x|0^d0g2}LP*%yb-V{tq@Pb^!Hk13P=H&6R!>}wBw;~PEKS$*+bU{UqP-JCxE ziC_AzZ%=HO<6eQwX8`tUY-4TsxA}%xnHLqSsm%*jb1zKE){TdSr7()7+xk`MU~_aK>?X9r| z2-V=^D+c6Da|pKS*s!@kL^giI9s7*YA3i4JaT`tX>U>d?GM*FTVLvyU^udTfkskw- zqK#(RYuYn6sw1{ucwBqilX=<-f0H|p2>{sANyu2;S%tY#Oh~3JXl!d{!&M{<)K&m9 zj@%3!^fEVCc_m-YT~FVUV|6H~gITcE>uGrhP`$Ys&$)?Q$7nNB!Noj1C^(zv84rwFvxnk}>f?GZ%cNoRzG8RAJ_x)ms z%vUXSUM$1tP7~&BcSM(IE5HNOrQNB(4}9*G_i1D2^TMoAUaT%3SdbER&PMdy2QXR0 zUW`nP3mzIbF7|rmCkzF67fY^xY>41wF=Gj0FN6oe5ColdvLzM?j+kN;yM&ThCEr}w zen8U;;4c6s(6+?P1nCOe)3vb=&{(A}-$VdD7ya>(c-D>J z+}faAcwKYE`sly#r2@d<-4j+tQBFqed#d#3;mmZuR{^-Ngy>ENL+r~F_fVu+mr|SKIJ#OyE^cFpGzdf&? zzx&%tV`t1njlIbqA)@E2y~8QQSui#qz0QH={#yhdGf$xT&>%$86Fhe8Y2z6uKIXUr z<(oJ5eg)$nZ;0FW@_W{=CxOkLp_CXq)Z!bWPPbi9bm(s8lR0A{l*y|^((!uWA}dGdp`9(OfK!b0xXY9yHkOC zkFWnD-$;?Oz-V4^{$@fGR#g_duS{LIJJ#^p*qpJ<=vcHv8=V&N!sf{z|K9w)N{^Z; z7rI>R_`^ZWVWF)-riyDmgMi9f9SC>XY=NNnCL63-ve~Tj58mR&AJT0W$Avd!V0|%! zN3Z3=PKk-yfl5ps`9NUUFu^L=xiDa}-~6#pBGlvXgZd!C9v=6_6G;o;%PSK zkgu4Vb8fJ?=}W;4lD7Nz1A?r$N|%Ek7t5D)xp7k~Uo}#HjqMLp8F*itLkIKXOV=88 zAgvFpB($;4Y#k>*1jOM7iaRkjUT*HdjjIpyVB=S>b;Jr+F-NS4BJpDruK10PD5sVH z7}My&sfpsbzPkC3t+*V{DscG`z*#xg!60%V*$C_eznwS{vomNI!LcH=)Ca4K zXBrG<$(p!=wO?=U=%2%3jTt z05nvy|61Zeo~Cx4L0 z9pT~L1mT|80qUix{X4*N4sm4(c3Y1&!aM}#)pw2$-p*eZ)E^Z3tNMQi{@&SBwEST2 z&i>-uVddaOR*W`9wv&4M$oghXo}HfC^QNQN2r)Fk%UGF-kuBD2Nd$X_zOf~$Xl zmThf7OlTCzV?Ky;&PcIW6l$uw zkDhp(9MF!Yy}JFJ#bU>m!`$#@y``R|GbHPU0BkK@`ov-IZleE+F zgPA9I$q$p(nb`Di_OJDw&)$G8a#A_)$L<$Ea(xvSzOk{w;YfnLi&-x6;^t_*)gB)? zha2_88NXd2T)$l9aw`VkR2vJi+rQ`XrGK_>yr|6(psDN!oVhWd_~HY1TvIU_TY9(F z+BUU!&gLJ?Q6JZM_`&EeN84oq7#3#S=Q?jD{e;Uc$}x>A)dzDV(aJQlFfp)&Sd44)%rO*8E$+!5<(T8;qdC$mfD*n7KI=UlWTpHmjW>Y4Zg$UXUy|*lzY7S9YMqxrJ87bi1v2 zBiN4tI;xtcmPnSl2O|mgs24d+{h>I=A<20Jb9i=+i+5}QgU2fVJ)C)aG~=HOto^GW zySfQUdCa%*WZeYf<&JLCTeHbxKLD_kjmGQ&siIXb6G-iYth@_2*jo4m+M}<6_y5Hg zP7mIrza#KZ^zR5z9w#b1V_hkEOZ%+UmdUkx`-9VVip@P7ymB7wQgiV6^+N2dHjZ}% z@*@GHViYz%&(~CQ?87%bg2u8Vx9_pK;^Rgo|n&Sos_7}Wk$DiXNfAq~49RAViK;6vA+%L&8 zP#nSC-rW2&beDEi;PNAYqZS@%V}7r%C0bP8q*`yxx#01|g7;WQmM$;u{E;1c)~aU) zXc%)_kKy8#APnKOH`(zJLCb@HFrJ#&6x+c=H2zdF&TWsaDPTbvlj;q!M!QlCTk^mS zK7A9{#AE9frESH-(~c<(z#`lZ5~pz-kHQR(`iTQBP;+DOSiq?-xHM@rj&G={1FS)&QKeGn{3yIr2T9&v#ihx4m;N z*PNTNpBQGIQ!!69>X|VB`YK?mb0*~q9Am;=kG2ZLzYCca&0@Ncm1N9E1+`BO7l1#Kv{FR3g}#*!ZJLSGWJdCcF$)fwMBb z*(>scUwrh3Z(n)z*QkTnTvk}dUTkQNg?IjAfT*zZf-Ihk63v@s%551u*$B4j#(@7g zDQpPEG7H}t?7}&A2R`!X0ZB9PJ2vRL-v!~v9f`#bp=mtXP{g$Bvpx5X?Mt$Jcq7Wz zF**3gfMCgS0AGSKx3P{&um%eZCeMpUWpeckCLP?CXN)Cn=LT;#wI4T37ZpZllT3}V zoI?oqb4o6$N_;@`M3d>{eB>q6Q?6QzTdrn2H6Gq0mm_EAO9GDdF1Hv)4hiF=lDZ&k zEQjjgMs1%A)P`!+MuRmDB*y~XP0*Q0p8#_HGCm6*KVVJF_{sBpoa3AUFlps$qKCZd zfr&il5BZj_Zl2fkAW#!`e)!EpbMLSgJGB+)W*|R~+qxN}SA1u&0+hIM(X9-~duGOL zT62VJNnZm4Ut9*6dAMDl5?JnshsGfJ*iF5`Ob+P0|FGvpn?AD;Se6p=s*3`^OOeh%*Y@ zK9^rumR)%&Gp7$R^s&BpV$MZz?9tXf@6qKuePnX5F*~NgnzI{qF0#vy2SU>8l^^sl+p3m%>vAVXiHj6r%h^uWkmxlls6z*m+@1Y`Q>3=NSYON;os^cwyII z;gOK>*t>pr1KNT!1Banw2`QEEEc1+!v<2{0Cm3p>BYTKM8df(@_5 zYrF&_1BlF$Imlue#A|#a-&DoKc1XDScWqd4XZ_eOiel<=xtkDbo9Wanvz0$nT^(Qe zBll1Df8gQi>L26R2ZiN)`R#L6+IJQ0b*`e8D}Kqm6(n;{TBOO34=P)~`d0ZF&NBEy z=>mJqLGn2XjO|y+Fm^1l@wLQy)yEjH66nj{oK!~0SudNtbdi@!s&xY4oaQkEN4{1e z6367U-(g(4a>SgY;?F4ybNweb>4}vn;WRH}&RNWSE?WE4NAfub(CbBx#1p%({UEFlplq$Zfgx+Kzb%kSxVS2@ zaM5afkVH6$eh%cm7V)X9QW$ieBxOTLSTrHm{6(%C2&1|V8al}nMs7!{_ z*eDjk=q%P`)l`Coho)iRmuCNxry`Lqu7YOn^Wk$bL}jqQdPHS)VgRwPiCJT--cx}I zQa`JEN0yQxn=P$93e()h1X-LTf-c_53H@}1L zdNn?gIJDN&{J{i^UfBH^Xtb z!)QPFM(*;NBj*h1U3-{ZPyAb{o)XM=?y|Ra&xP^mY4kDbbq1eNmP!zKCu2!{EtQ!s zw#jh$?}eq8*W_R)$%P-uGW9u^pB0j1`qRMQ>zFPFS0HEMQjF90f9BP9-QIlt6YS%z z%~XXAtUDitnoqE1cX;Va&PofE1?THP=Pqu?2C)fPkb--N8G~|o0~wOdfEsQP<0IAx zFil)$7#=IEuAgkG+`S`TzRR)D=5usMd~5dr1{pqYF3r|PuK(ngxX8H~H=7arCRlK4oyjDDQV6O3s=gbDf`XK-9uD8|$`nl=#=7?WE zuw%>^ryB50$yvOP0c>(SVv{VU4K{PQa{k~GV(c}x9ABHA$CA+)(|l7`Kf0BZ$pL^; zbFV{VK9f@~Vy2%x!9zpsxW<@&WYk4e$X+_#|5yLQU-_s10?;>mbG_c|MIirwJz^78j-qk&ToO1hS}DbeeN;vt*6EATH)Xb1;G%3+((*&5wWH+UN#ZVZ#G@N)$eqtjs3$-ag# zeuf|wOg_L;vtg$nnTImt0^H`o%nt0-X8OYbyPca0{g74H1kwe&yIGty8~b=~{+ign zy`keLl!wR!V_i~pbHQHcWN@23=via?&EGk$0E}`8;-xo(siS#?VXYWSpm%N<(exA5=YvqN+XUL8XvTrBS04 zY8AI41(Hx`Dd5<~U}FbbVJJ8@_WQp3WA*x7*SO}K_uAVis@n4Iy_tJG_Z)MKYg}WD zdCz&@_j=Y^&&Ik+K}2Uh9VWKd!^{J4Gu9Wy_^kE7O<(^~o9sOJsGa#au5b9l#T*{6 z^1rYD8{qH#+&BHv{|%sd`=cKLc=>n*{qb|LE_oIZpSYLBoyCXR3vHGotDB`s%Y|S8 z@-`sWamvLOU>I1Py#U8Ii`)TF*w0HG`b#rjCUZ|N-68|&@2XSL0lF*ulL3p)y@i45h$^UcEO9umo;V%2+{GZu*-qzYJj zA^zunNG1d;QQ~_2N{6;>$t^$%5ak2cIZpxgnBFnUHX%JMp$Ss8-tK$wow|hT+VF%2 zf!}j5rX{tNdef1Nj6PVqe))EM97X2L(-25`L>Cf(H15&|=^2qa^#ZV-0|Ye7osZC1 zjb8OMZke#HW)1=M)pHkIA|(XJoZDzUbh_|3Bl~CM2fT<$(bp4_QPaFy5+%KJL&je( zb2aCA2L!h+6Xz&BSWlOHo!$MLe;(W)wfyAjrJsi%_~aMNRdpQ{%lQ(7@ zQMtjVz-v6}p{h76O&r_$x!hv`=DS&;)C)0r+BO9uBgbdvp5c z&zw$7yK(Rf-1unB2$=hUsB>E>OF-_}>)2ccsy_%Y(Tb06wK5#o6PNtZq&5HOyYgh4 zH5SH_Nk2I)qyuA*smHDq8D<%CmfkpS^W@1_=;I>2 z&X|xjF{drLr`k+b)rYH=$(ZsWvnl zd%=i_x4@?PA}EK&Yb=K$k<_^8*sA<U+nVA|j+Hs+Z}an#F&<>F(Yba#k*Q%gR?X+q;a_|CiI3zIVd{KQ8_ zm7DU;W1RyM2*CN(zxdX$@|?v1GpW!{{#9f19Dw;GpFWt}N~XSfxqkE)!oaOn&{eZA z=X`}O36L8t_ABnl#t3k$et9?-=M?|sk_r}1^MPFc9d9z9_yX)w97uE&8ck2O5DF2prQU!>x=*MKm3NbI>1YO@O-_* z_22t*zjOQbk3aW?Pcsob0ML-Vfwb89E%k057GQq4WL6hQ7Nk97#BK&1LeJwHbFb=>#c{FwR}sIp*4_+W`(XW*QrX5O7Oab1>$Cxf|Ja zOSX^sg&ms(WO4Z>d(sr6-W)DFbBc+q=4-sxEV(9>_?5BuXQfU zH5`-@zZfz{bH-*=3lifdo~@+PMJ=bGeI(KxG@pfBf7KBgHC$+`Z;?z)*@KLn7QKJZNPTW??eCjBzt zuQh|0vFE|+rEYKh{_Fo;CxFkvV|}q{E`QR;*b7>{F`#(cUcJ^8mz8{sCNkK(;4K$2 z%|2(3QWrk^aYP`7xka9JYaSM`-=_D)LIxU}#5rv4MN=LDa^qF@#1c34HBb8Wk;LQU zOQrQCr^in>W_v(;9Ca>6C72m#P{$j;D~&DT)f{@%bCUCcYOk>4}WH6Lu*o z9Qv*=f{<3n2V~;s{1IuTKR$P3oxZHq5Q9pd#K^pyT=DYp2mr1_WRF)y&9`$zjDs^n zDG+9k;JfR8B<%W+@ul8jX+EZ(!E#xGtf!1GbAj6Wk*%@TDL(l2SMELdGy0E*zFKy^ zfa#FG&zB>gP{-T%+_AVCW2g1)?CQ|Z+x7mtWQg!l&;Dos;)`4!ZSm-)U;g$L&@tps zj5ausC;s_2^*8;|#@HN>obaDle%!z~dDTC8MR(@eACaUM0w=!bR=KP>p87mL)JP*& zYGM9}FHAqK+3}?Ab&WAEespldDzSPEKx<-R!^L4#k;I3fM14U)Fb}*(^B@{H?4x1m;7(nxTRSli zGGm{)f-MZ?o>H^b!GlNzTy zi344zuq=P!ZOS_6{B3mjI!AVvG2@|XT%1_EN3O(&zbfYgj@QgcjbKjq`kemugAaEa zatCLRtXHxJQ=`>(^+AC9JP7>hx7@q^Dh9Iq<}EAEyz~jgP7E7YWpvZ88*H)5CSiE| zK%pBUwYe3mK^`^`CNE+XH2B^i4Z;oPKl{~Y1{Yz z`Wt^ucPf_WYRD{{Ud+0ut!E&cHc}c1`kkHt-Xyah${Gkkv4|U3MB8Gt7~E zPCvy}%{!m)7~`jf_@;&=keWohc*s3C- zVTf0mo>I*@GCn!SHaH#jdr0uV^TJ!4JVLh|C(fLE|(vY2seK2b?7`| zsxA*R8Yh!Q@Fq&PxP#X$`bvJWm z_u(kF;X2g6l>u}1&&h5VQ-BAfC~mga!aktJwP1?J0VaX-gkK8w9=MOu?Z6U-Q%j?=&8RG-}xi{ zujoG=nm-=|%3jb{dKZ`#$dBxz6bJwZ_lzx|99>k-Q#N{IfoYKa4`viHuIrej<{o~W z)%4J2j6~;HUI@#h-Xa)$)EFbTuMR~pwhEAb;pA7Dp4Pa-ICaRc0Ahh1y#1H2a-#-6 zInaaSGXZWM{`BAfhPS}~GPalY9f0rq)ayT_74fRq-JLVf<-_YnYs)`do5j)%Gi%BV zt+LmZco?&|@>hi{YUwm)xf?r+6}dX=by2X1zCWLr57!DD-GuY?Q0ChX-dzaJBm~2lo*FaIm|Rgem*6`G z2{H8yE{S5{C0`^Hs;>N;!g?R38;5X z4JX2KSLL~3u&~S(MD%hV$P5dmT#m^t%w~lYEcUPpn zy?OHL_y4JX{Fj7!DI4?nQnv5?4h-26*@TY3EU2w4gf5=3(lx z-Tvb)P%4;tjYA#NFP`yP{#<nrja&In6t|7@~xa=BY7Qk_XXyel&mOp6s26 z5%tla*m!1Y*8B|a$;b6q1OH^A(lvqdSXbrPHAKU;B=e~Rh3{H*TnAO2{Z8I?l)>6u zTKbV4mcfiOx7bI49GXbe1qUTB=Zrr&&-~0cz9WE_>*)D>xk|ow?|VOe`_10i>;uiF!A4v=1JZbJ0&g&LpaoTDje#Bw zSF_Pqh{m)_Wgm^Y3yX)Jw*nM{STu6Zr;|nR2+}zhRL0VW&ogLVM>7ks;B5`|sG}g? zsG*{n8)5Pco$8vo@z}Frce}`E*%K7CTj##xv(Lq&zF6dJe`0GmvCZL$m6|y~2I_jj zF~%X?%B47yVI5rc<5N6{Gp>2107fb_%kp2b&pd+=mi2P=vFXmC9OpR=q|q{R&69yI z*u&qN6DfJ(k@&M#P`J)=?#wRn$v9s#zt6x;-Q}O@b7r93BzSt4LfTC=^A}zHPXgCE z=coFUYH>-q@^@ZDN2%_P|Czwa?^V3;2t{)KG=Dra|LWs=Pd=yXj~}3O9ZFoyf(o#g z4$O&*3ypJ&&a~lXk1Mx47=tI^IDi7wU9zc&z_$}jH zuGyrHBgcfzMWOYgO%C#Na=1?(a)_;n_5@K|b0K+r={mRTLP+G=VH{oy#DWSwU>-3* zGxIYS#^?+J5O?uXpNHn%xmyVgj0YU?k5BR|N;c=1-r|_9xKPXqakk}d9OD(nZD_&p z@{e33L=I#f@v#9M#V{DzhSWA{8T=*7;EV=?e%IXmeO_%L4D&t&<6pMoO}FApAh5~h zck#zG^NwDaAi{tPA;=Pu@g;uJx6v4b;_G7xsv174N4NYK%bprCGnH2cef$w~1raFEWjhn1qo;9UA0_JPegq-1gz-Yt<`hijJs->8iU zR0@6dn#5pHSjsgzoU-(K%8wW(7@g|@#E&R6Z{)&{ckgTLYx?b@AD8u;!}IbSneLaW zeg9`}-}dkNFSnb#SdckEZAxo1+GM%tEctxZ$qmCt7;F7T(;9BQ#e);P=IJdIC}oMu&udtc9TfFSGHerZB~hkJ%#^{P*y?OO-qKL}?# z05x+(lvBN`h$@&_4>cLf0Bf4(XvUojdN8LAbnD+4h^L&aQEv3V&N~8%D~eTHw;{B= zXp?ti_(N}c_rq8J!ol9H(-E&K^;BcXlF#!vKE)ropsH_sB6knbTfcmUq+HZNV{9D< z;^|8X?KyxYt$IM%ja8@r_$M_;UVaqCobVukyD+*I-@bD1ZC~|MKlQbrL-n$>`L&Lh zrQCb>9{&CtAJU5Od7pLS#nJ_n6_Ew(S@ELNg4J);fbW{+sj(=Fa-{bnmnG{9Oj~93 zh;+&#G+Z!IaommN`GhBb1D&#sEcPPtXH@=m0AECWCp)+kNXy&;vQ? zwRvioeiI~jf+b+P5Wp~cdv>iH{xcH-@QZ$Y*ULF} zr-R4fqw}BErG!j|WO%@zFZ}#V(Oxe~jPuBg1}8ZY8x&Iqafv5SwlUVj4hww18j}-jCgwOsbr0amAJoY0_ePuJpy_-k3pZm~+d1*SPT+DRBO^Qdp?01nIIid_nNVY3y_Wd;y@(igS;{mZ z2c9p|G2P_hDCHK=8x_#f4NWMl#{|dXXMDIU{(v@@G2^YSb8S2UF-_pi$r?6bayQIi zB(5h)GlwYQsMRb69n?RmoG-Q)1%xTu)#pxRQtIIN`Dtt(`LCRiljhdR|1u9)COF-?29!^|+hF1=O~VU=JwrR_nt5R(I35eL+Y2J@m%!Mw9kC%;s2lwqO-kAM$C{!FnZRbMD`Dj z#gs<|6#6(@S-l9c0Vs~K6~e3UYXJn@PtZ8386VNZ5FCn#jz4*!AwG>vT#`5UQ3H>> z;)32-UkvaF2K_bk)`RkQ)D95_7lT1w^>fb!xtcX$<-(RY^)Uqpai;+< z-(}%l5dT>qerj-06aFsi@Xeb$Sn|m4cRe&}GY=OeNcs{}#wcjybIJ@g)6`1u$hZqr zj@BLm<4WPabi)G-e{8(qj?UfY9VPA{E?AVj+GZS_28=1CcJ-|Tm1C2GWY>gXaOwn` zsN*Np^6$h85vSzuAvlQ2Wk|R>e=Em0=y>`Q?_|w9g(f_96UaEJ%(uAWe+-QS1b&}C zA)q@b>qDOWb5_O-$OLF@5npoX`HTMq0_&iJ$hukcCq1&%dgiO~*op|^FA;$V*%dMVw5*W`r3;v(>>IaBF zpR?>m*ynPP6b0?hayc}cXe1H!FImps6T+DB3R6f|i z^yRt9y8<>aKYat4V4tAilKQ z*1psVVsWv#^JMMiD3J6c!q=Ntx%>WtH!(_MS(wQ9#@TVi&!{gTZH5sag~73~!1GUI z7BJrQC2@N5cO5I< zxL$~>$jfs8)T2;K)jsaq(8YbYvQ?{uRVVgV);UNnZM5CniCLe8lS#VM(=4GNU z#3!C!Ug+LYXN;l5v|7@`&9!hlAfE+jWqG#(as$ zHe}}1|Aq$__A7C~qaL3;3}Aqa4q5)a0< zfqOCzk-?Nb0$Pa~;+q1NbqN4xZV;C~^XIX2D?0X2f!=NWh-WP0GnetH%Dph{7tsP> z8&Vms=TBs{IgW<!t)B@LZRdMMhbS)?B{PIC=Px5`{)GN&;M??$z}u7y zmn46PkYwtd5B%}Xo+~~&Zo1sS`N#H|2LbDG(+#$m%XjwXQ=afZ1IIjQptCF;+rv%0 zXF>{oA0e^f<^_T5yzuQ<>U>a7bU>QGGZq;ddE<%64yr!Gb)Gr z^?MMifjM~c;P&Rnf8rA#lFLicW-4CnTEB%9HXx~9>wKHR(}SSD)PWo$05 z6Bbg}i_O90m+Fd#ryCdF_*lSq`32*RI~NQ8CBbpwz;{^fhrCjpytoLh%@02aIJ`@= z5v(JLs3Q#zglY?;F&n8l`8x{P`7W4uJXSlzg*|vM->tj8y@9wkc=fL}fT?~YX~2wy z{P3CDn4HAQrp^dYc}%{RxiB!+S6y?3kb(t(-b@bUn6^6^%#*{=n$u44#hzhmDa-Cd zL<&eW%OoSmN!9wHvfgte>GTQcdd!@Hn<^GzJ%c~zIW;{Czw_xjzVen+#Y|?`_?Zhw zT$3Fi<0P6-IhMaQ&vY=H`RqKUH)jtGPdGcsK$wwTtK)C|1;$|TD}Uj`C8O=hTgWsU zqg(v4)Zc`YOz4}?_6gCm^_l01Js~$fal*uTV@;-S&2{N~bo%jm@*DcypfAXaCtMnx zUz1D6WAi(l1Kn6DAl18ST*t^^-H8>{O!)9()I_TD_|TKTY`!MiUt=D|eI8^m4_sit z@^+tE^+50&Jeb&|Grqv>lUOsZnIwdFO~?wvn;T9}{f(X${<*il=PQ2f$8KJi_JwYG zWPI`4?I&LUS#JJR%6YbM8SL$a)gvu3etw+$g*^E3BH0`aLncXIU6@{6DEy@ZoL%rJ zry<1}a@Jy-MIF5993)S=my0P@oG7TyY}m?D*AzZBE&omk^#UYE1U2{i+2Sa`xB1~f z1FkFP8H1tYZ~T(S+xUqkPt3mPn1$GJ(5G|f0mS4ujm`dzsX^e5zD0Ps7)b4JQD%OQ zOnt$@oq5WaW9NY<{uoHdJd=lGOpXN2G+XN&Qjjeo-)AjcT(nRV80T@3jF=FLDIs#~ zPaW;P2{LDkVZ)7s3tK`mO8WTI7)S29W$5)qk~YP^Nf#e~X~)0k=rV_)4xe#}ml(v6 zKi78&mKisGc~_taRu8W=Ry0Ql^wRKjH+Oy1cg~_8hi1^B@f}QFUWdex-XT+u#Rfg} z&M&}AVy2F9a$z9HgBN*6R~-F=dd>IpPbyhkrI@_Fj_+R7ep8eD1-)2Y#ApKa4E4gF zH%HeEQ6_Z0@#DsK_&!$*@L@eGPA>w2p3Upn{F4h<`v`?zesnI%v1fmvs-F=gac#uK zMNW`T2W3Jx%=f=Rf(=f_~39ys#b9@~*2SmTD}OeQ`@0Hffyuz>1zw6*JPHTU7!};c z-X+-h)Od^+(GZAXtt*GqIa9(uXA`nf=&N^J;+JM&5w`Nk%m}A{!R|Ux7ym4r?Eusq zKVk^1sY3nWTH6c<3l4@f&kfhK9|fWYfoZL8e5 z7<_F!C_KJ*`!!$op0|DQgEzmg(F@z=G4X}1@7~)!`}+T;MZpq!X7f53Yu4F@W^rj@ z%F_$0y&(BcSc1M{A9@YEIjxN@;n^Ty;pf$s3j-WDn#-nOe6(M3n0@K^sVe@ZbPVt; z;yYziL*gfY!sK@w9NiZghX&;$CLbr2d9V+D*6GRHG3ZTZcZ=c(Mx)`1uQ;6tc*BP* zoqYlvBb|JxN6+WXWiC$iV;i2%EP8Ktd#YAoV8*wfme#XiPA))GOK{|aPL6zy4PX9c zeuo!+wd8|T=2M40W2_siLE(qev+bPm51l?-{6c9_DCRmg&YCHHMuj?E8WCp0OpJpmqS&>V4)d29oy-22Q@(~dI-R= zM)k*assF|Y_ip}K?IHb)-fwLZhC2Y`^-F$olkDH?^UwE@1tcc_=5qzu4*G#=lJR#< zi1Ews0?01&tc1tIJ&GF$u><{6n=vS?(`XsT+vDhgaI;zs+ra1yy=xaBZ=Vlz+1VuI z*nY82E)b56egYVe!L|u*9<+{V3@i2I!K4-pkN%}rJWoIAh3!Rdtae2< zg&jO{+Q}8$J|{ptFOECq+0Uuv?LFtv2sI{g;?%-aaIK-|==Gt&H5yi4^^zoU=X;p# zJ2~N^_7pbiP)asThbd?4U9$oacDR^Z6jnI_BwF;A@Do|zy6rl-5Q)Ka3T_I?`hY6Q zT=gpfLa1GmifVLm-@MPp?u;k=aO^Jer`D<`jSkyS$|m*toBC{D6H95CC#yy_rUWwI z_1|musF_-qzdYo(aWKyOS}fM-Ih>iEswMm@74D8wJsX?wsl$}PA*Mvvdh=Tv_#J^@ zu<<$h%!A|jPB~8aov%@&1M8-KUB{MA>uoU3XRepM=Hl#F=bSih3B-&Dhq`dF1DQjj zTB{C#w4)0r_L$b+{cG$wdpr}!*g1($z4tp0_~`V7-z$$_dG9~?$#?z=TrXmKp??S9 z@sl@xnqTf<@vX)p(U{H)QS!M+7Y?(RS~Oa!Ya_3PIJ?YGtK-;E_9YJSv2{l}u*O-z zS&*2)(1f#TaCEkr2uT{r{m$Jme6(o&-)tIzJRycBiD+>{;YAOy8%grcAdb!h=MaevnF)Z&CI0yS}&lwsAv~B4p57&Og^Thxg7Y_B_#w6*KeAaw^ zZ3Q;I#4yBxBS4DRxrG1yaRC2c!IIW*RqfjSH5*5h-8Kqfemh9p`q0W(MAEm z9yavcP|UdukX|NnJV~5Weual`{B>+~OlR&uQk3M07as0t1N0I{tZhX{@WF(`8 zT6KYt5*(3f7r6v6*}wCaSQDeToqo6`AlQTwPy~)Y^SAWE2 z6RXLseB)p2s9m$q3AIm-*vg&rC&h#(6$TE06Zmx7r*xmI$6PDL#HpkW3TK?<%lmhbIsU3(z%fYe`}{N$I;O5B-jxf&dyW==2V@) zxsHtt7A-WxoB5n`0J(l7V4XMyZ7@}`r_uWJ5eO$PQ|eue%KR08mDK3mT4#>-x% z`nx(Pi0MUX+~kr~zdW6naEX9d-og`t3&E}4U-MhjY+7-puJnmV%)HDb<<^q} z!P4_14c8}?eN;r>=EjFcw>FMON@4jU($?(2hX>By!Lf3|2w&gM&wLpTT(C7y3>c&5 z%INX*Rz@|Vkj^fBeLPPgay}wqWF#0)mcLX_3es5H0-at7o|xnio%%V+hA>xyk6nJa z&Vj!1tg-V2=)RuLNl{urYY=Q|gvM_wnPOM#`9Pi1A80N$QfZCWCU+P8=W^l;M z_0XGRFvW&8#KefI83trXHaw>6u55a9;Uq6VsagV*#zvGyFOK2%=0xv!qeY20Eq=xC*tsakQGoLT zw08VNatw0?YjN=tOWrJWHDi4kUM1!@GAD1vGL(eD$Bz*reP!&_!6wh2G%^mpwmg`W z6D@OtlM(KHbCBQZihYod7e1Vl*9K>7EIvm)_)rtAF`c_c`3>P%k_+>I|LE|OqI1%O z%Li(xCCJfNCJ1cVhXl-c2Uzx8h{-;#^ll^Ao}`pcPz_%um?AcmcDRH7q|1vf!Q0@`2a$me{|--T`kNUdIL zM-1ob`E9_%sCh~qQ}0s+3};diI{38)p&D9?l9PRoU6a_ZZFra4`fJ?* z5+m6sS5S#Qbe90q{f?6SqHceEFeYc#HaLB)7c5J+Z9sheK%k8ey3TbUx;tOMP9JEU zqkVA%k%r#im@vfT{K3mI58^qUlb_upo3~slk-53A+RP!n|CCVQ1tb^!MSvV`AL|+5 z$<4!``_OydVyYMHkbBw-R@8U@+8h75POtvw46l)AR_ArYy1>c>1nev(2G)-!GMm~@ zg<5Ffd?6Ws?-hYGlx_A-7o$0}kS5^j0Z*%#@XZC|EKd4@8{1=+@X;VR6_&%!cenly z*EcG@`^Haya_6Fg3ERY%wetb=q)oj+ThAu45>B|tJ3jQ@=)+-7=MV*G|Gn=SK)N(p zy+Olg-mwIZJyPExI4=%BiPxCU3Ai|W&g|!WxlqbzQ0g(%l@n*SO2UPcb8Mo?1Dkck zm>2Wg<|`8+niB?U6WBTp>xU?vFKjknFXZvT|KJmMI#BM;8?$V0J9mhiUV?elqupzj1&FL%EK zAY8uVmVy*C24{IxToQPBj*%sL3^#fAyYzvm6IS(&zP#>bTE7%X99Nidjmdlb%*UA* z?|kILiW2X!^HJ{iZ(seMKmY0f0;U(OQQ`~Lepv5||2Mz-+9MS<+jXs}sgtEOi$UV- z39TjcT5RgQW>_hby@C8ln6X!;8Eh7o%@c(u({i|KfTJ6J@r{o?FLDNc8pYTgMmB!< z%ImncgV&c7{pFV6p_y7HU+3Y(@lFlp!^c{2g_}!6Wy8a#$ukAGI^a=Woa7mfnFCa` z;f6VJ;h!jnzayLf=~#x1zk@_Ed=Bn7gzI^B2o!3-$*rk--m1jiaYMlpKt)SENYQZg zd=3$@iUquu&-gBz^92A^SR~o`7;P>));sfwE5+pk?kt2C#<08GvebRzq?m&%$*gqt znsAcVJ7&^^Wv7q4a(SRwChj5xPS>uijmJGlSB)D)a9X255rbhWFAKw$ER{o=) zf9ub_`;{O5VgE{@XyCxh zhk~x2E+%+@*$)bjS!@$y>HM&(wa$XWD1`YPH4C#o>YWZfZ8(CT%$wVA&?P37Xn@c7 zp&uA*9$05tl8ozOJv_KBzu^JCboMREgVZJQqMg95S>E1QCr024=N(?#qzgu1$k%xE zvTl1kT2JPh5_3*gZo?BcY~%*94&41|5__7mKBBJ8L8}^U^4phFq{%K^#j7{BgJ{s0 zCfM3Vnc@qUxn4yM zXS&R?Y#U#H61!qO8r`^WK-0JwW^nlI^M}#}Y>ySM>oca-AAI~eXCS;5Kda*x<;SxC z>sEnsgEW9)bn}aU`aAlpBW~=pv0r5C(6Baj=`HHv`n@ zv5%8FGnzZO_(_?htUIvflgZ>fnVRcNWZV>B#boiW(a9@){SOM$Ydk3}VdqIsr>~R6 zO)WOl0U-~?=*1-S6C`tBPlHDWuXB(KEmpO$?}Sj6^BEk)1EV!giPrcUbAc_Ce`;f0 z&~!qd&bd741H7ArX3tlYDQ8H0{>-a`T+X`JTACEXD~#s;oKy6UwoX`b4GwE+L2`!Y zxvNgSFY=T2I@hMsVR0vxQvxetVd0RDB}J>t!bbh9t2;wsV?s&K^YC82Zc-H)x z%jh#P{5hAS6IbRN(&!S0Vb?-znb$jW3V*)F`>=P9;jY#>avv40GXbMuC_vW-*wv6z z)KVb?vukoa>tt+b>$Y7)JH06Ya(%^)*jh3#_x_3Q>|abgU*CFz=eO|*qj76<&)E90 zgEFSMDkH9CjZ;2+aMZXtnx8ZWZwMH_IM9SrV6gtYk4#L)Sm7sedTe%^8i^%!_~?}t z81&%v;XtoGxc_H<_Q&7#v%p@2_G0}R;A^k{lopH6p%;M8P){i5x%=Tface{PMhS++ z5X4%PS`pR{#;jib;Wuvs$hjBjsOF<>9e)pT;oJ(7X;Cf`tx-L=A0WTwlv{H z=>15o`e#3k4k}}VOGRu>0Y7#zP)YhJ9)nca5IwBFO^Rb1mbm(7_bxJH{5#i|d6!G7 z;bM?;Vv^yh9G2vt4B(Sifs>DpT{GsKe0fT3;zr^lot+8dfx|Q}`nJeK*zJnj^O{N6 zHDtbrYf(~z22L7I3>gr%YsJyL&c<{@-Mk_Ihn;St3sSu@NVK~Ze$IwWY5XO&DsHJg1GpY!{TSyT+Jnq?P9Raaob1L znt6^YnMj_Ag+KXimyHZ;t)By8KPAxo%nK*YJsMK(nwk3TV~hUR!3Xzl-zMm-t%0w;0zO6UnLjonM4nze^xI=NcGE@=Ji^U?2TQK@T54`Fk3Dxn3_sbDb|j zCGY$A>wjIpwfRF7#CGjkY=PF#z>5#rt1s2BxBI2*=4WM{Z%Y{&>MV%3W-&JqI##M) z-Ds%b%*M)S%K+tk=h5^;-Q%@|QLBkVI5+pK5DE58 z4bD*v@dPCOs>#gZH%WXD;WZazjE$0DUyTeEVkixogIRSjq>FMcHpv5^t)4s2k>aG6 zY2{a3^KMSn7u)(A`Ql#g#G8EOmguV-h$p@T!nK9cBdbpvTE@bVa?Y!vo8#~|d}<>v zkDnrlf7YE)<(4|}CjlGK9qUNC&=1B`B}m_?^-TiKDsX`l#>2hy=e`DGO`f{VGxeiB z{DYdK^iP>a(K_sYfRfQ>X})XzlvDRzauv3D;x_YChWg786Kgb)>aE#Jpw24QmqvF;tX$nw}~`fSTi;*&I^mKO)~oHMuj&#Ky%Xo$Au`) z_Hq2^PMdQZe`+EhzPqN@v~aKCXyJBT#)Z;1j`hI=JFvkvCs$V0n!_z z{0^1T=#mWa?ljqrL%pyYNE1nUI~Df-t#DNa_hPe*VD%X?$f*ImJmujdwLT6lKu=1e#f6R(Q}I# z-j=~oww~kkfToS#WzQ`FVVvU-HU_-{bZ*LRMt!OvKN?_;e3J#rLjh>6Rk}$#miKj5 zb8h(3qtlo75%cVd*nMtfxYE#j?Rhi`X^Xdd{E`zEmaK0ZHQ(91_BO84Eb9p- zrYR!?p!_!qvX4P3N6-Z17hs^vMG#-sKS&NMe@_-lTCwRpm*`yC)-kWYWRYE_=9U&?4Z}9O6w_ z^O1n;7acaKxj^~9p6W%+dMmd-f8IpiQo}K&+1aOyKrC`E^YZ3D~_DF zxPDNS*S%x924S%Lgi+nDUudRrahYJ|3jBdHpAR;SPk3`GX0PFHPP^-agrs<@USH5% z|8>RVKkcE>u}^%lm7PD^lWiXT)e9h7Z~hFu?ewDs$HQNnVAe8=yc)vLKi&as-T z`j;bP-1WhK;X)CZ4d6@+&UzhO6nZQ0un#=`Q2?=DxxM+l-@N~ulAild2;{Up*X`Rs z`sm-+?d%=Bkp4l%_#^`0B)0Q;#)6=QBasEw3l+=BV_CCEW{oh`%WG(4ZmRi*VH$++ zF7EM@7L$MO4+&$vj%Bxjw#JxE9C@W)FDE3MV~&$`n>m{U+s=vq(8rrWI?IgZf{x8- z3TTmzi$yL%%nujb_mFj`Asg@+NHMr=)vh99`*4}6Nq!KLtIzwR_lP{hFD(y()%I|HI4BF zJnF+A{&myVVCSEDhUCiPq*8%vnTvAfbRrVNe95Cct(i=6Z2)*@{w6<%k=&d-X8y(= zE{>CnR{fV6Oe9gT%!I+%kzxcC0+jcV2 zRG;$_?~#c=dm(SZhaGo&QG-5F@aC&^Tlr`7%?BTy^QwIKJON(%*}qSQejk9(7C1jc zpr0||PZHG4-#_OUjP$|zKmFlEa>p_c7|Aq!nqc(Wi~d{y;z)11;v78I*`@<_Y9b$+ z`2D*8)@y7o;uo7-;C}qz_U-Tg*FXIq*zY+$Oy$pK1zPks@B7#rkM$eYUfUFtmzSf9 za)COqc4*#1r;L)#Vb93f`SyI;X8iDsOh@yD##|oRmr&+jdaD~vq0ZRY&T+iSM_+Da zRhf0Fd&JbXBAEj)aeHB46vy@;)NnI*{E-!H`Fa+tGs9qU+!qM)X)&uXrolZwq|P7KkqZ#4}HQ8 zm-L7C;eO?E0tGJaBitlJ7-xLAd(ROCe;Y|?91xw`X&AYBhIidH9yJ64#OLXnSw{mo z6Ik(c{*%pOG#`0o`a@6`*F(%9uGk#mGSj5B@CkD7-WxLLjdH&uz{N^0|6Y}UJdm|^ z2<~WQ7>77ZywUK=w``e5y45Dr)Be$mfnjB4>b+?)?O0UT>`Kt6cZ3|mcnTkH;Nu_Kv4j_;5870+NI5 zaLqhr_$;j8gqRK%+7*vNuNud$F0HoVv2t`1zR2C5*wOAfHf-m1>;ajB1xHe6uq4@Q zi*aint_8%4a}w@na!vxCk0aK`l0#bN?2z>!aQm8~5Qv*U>zV6nZ@kFZ;H}IUH5k%m zeBQWipM3GbSAp}6A3mz5T(X)=usl?R)8~W(`LvCX_w14dVM~JX%^x3a!$ptP_L-buQ4B8zUU2fAf!?lv zq6=F1GWVv&#TXJm=8)KYM^W1oWK80KC%pW}MACaKAAT%gjQU5yKAfJpcVLYxBFtJr za$82hrJywP*~lo(R2`@{6=Mm@wv-!KhIKw`dIlDZ*ZN=#@%g8QtAk^XDxD%(**+v$ z*_c2jo72~*vC;Lxb5ckry&)dK-*Nfi9$mwu(#wdE0|FPkea3I$mJ$PlH2ZYi9uxA6 znWJ^Bh?|bdam~$wFQ=)kiGx1_#Q)5BQ7<8Q&!6Iv$6`3c8(+R1=JqYpeWiXZpx+g+ z{EEE!6TEd zum3ZmVo~bLcu_d6bo>rcb8xM2srg3|{4RpVPafQR?|1&&pZ<4ZdH#;i?Jog7e*ENb z_?J60=RPk!LmhB3M?dGpPj8&$Ig{L|IDu>?{QaA%Cc@X6c;cY18~wm38^i?WA8L%c z@dXFt+Q=*{kh)NtT8C^PsmEkC;hI-_`wiEMNC*$2;hqAGsjNzDUm&D(jfzj5`MAzx z%)(9qxtMsCWl>d zXGUEQ8PM!PUs(opZ4U+<8vp=607*naRM`h&I`y`PA=oWDciA(0jW0Wp;jN7r<+p4= zxRONuGbbk&yqgkO^EqP&kRa>kcG3jk30W<2&qw`e5WCmOuT1wPyU{pBm5)vlGuI_PK}C^zdK(J=6iu zxJ^wAq&2sV3osnA+c~qBdXe|JoJj6mkH59BQ+%Cn;!N;dxbSek>Sh6S4SSlU!<7pr z7uNn_lv9o?45lr5mOpMdb@+zv)uNZ}pg zDK_V|=YZZ(LgJ%5bJ9%UnTPN2Hw-`PB;;$nbGCfeI(fF_U}}kWpFW8mphJ9$0>?Y; z#H_jplX@9+ZgPEC^I+Ur0QHZvy3T+7J2&>9`R^Rzwbw*4X>M83P!GAfjh%Ry%o&W2 z5fi?$V4g=(t&VrOUem>7-u-eIt}Wbj`I77z@K_SI`qFFMnr`_(A8!iz;Hw}$pXCyq zpQ1Ikx6?U>dN?H}2X&qixQNBrF%yG4_5TF$K>qPx{JZb^7Tlhv=DB^I5`OPT-}sO8 z+01{{zo5z4RHKL%!aA%R8)tX`fyWML7RXu=ve z2{|#OZ?mtgA)21CgJ(=mD$Y-%@++4qYQx`LXyfk@mxq!@AH7NIufDIHLeXEY#0tqRnpotX4i-6 z;7M7NhYiEy;=y7&8X?imMb#E`6O-FYa>0Tj-6A<-*k{(DfQ^*j0a&vNk=-3bJ~>b1 zAVVJl_%5qB3FjKdpRi6DklLi10mso>fh>T1YFhqdH1Ie`jit@}hoW;vp9bP+R&%&> zV?L9{CjWRkg7L8UhE-}5MvX#UnD>4#U?Wv)A zc3n%xzbCNsXPg4A)#F?yfwK_ijKuVHcTI$Pa*@w?Pk)`OP+oOS%{|U{nti0Zm{5`v zA0_;TL~hnR44`h$O<($b?Ng5Ez|1Q)>EUBzs9$>-EHTjGQa`k|Mdy8ljb;!$`r;;! zj@)SDZ@hCGp8K!=N%tZzuCaIQe)6`% zvmtiB{AF|o_~HP7HutbX*uTwL6iLgnLHW3u57|Ns-mv zbI$7rqU}3F=$Z9Dq5XlYWp~hTe3(4w|#eQa5e9mkElOM3{3_^;*5Xa(- zYnx0p1fX0^eE5zN(U$;kK#;$2K)A%i*?aNU-x@ZMoVw_v+jHWqMUtCQJX^ys64m~V z--}-7w7v5unhExNT>KBN`n6AS#>ReEVZ1bxqs;JQYtfJk3A(0!2yu zJ%8~z7!LjmzRBR=dD}kOH_=;$A2Y$+RIn7s$a3d<83tYchU|2KgM;ze?&3C{n0vJ~ zr_1``2LDKRR6Y}fxAxgXe7KPIfp5Tbv%h^T8<9zXhi3gVAJ7@2Z!QQz2ak_l>$=O3 zcOpDb5Qxnf4ilHmF`=(+jDg>U`H!~ax^_y_pK zKjzvm4tH8rJ|PTrf-K9!{|fMk6Iq4&wMxc^ldR^OU&PB1xV^zSNF2t^SkyKHsbM=! z7Bb3q#vxbh)U#ycE1iA8TZ_eUFz|1Mh`ZAY5*XNdO*}>^d;HNG6Fl~<(TGhk_DI=q z(H&?K0V`GUi9O?qgDvxjFZ@@0v>esoys+VY$KMEWYIAP;E&yXx-n23&uf#MS7sqd( z=>9ukpU4@LhhB8~DC2PLI$}rbm;f!O_mG1w988espRr$)k7VB{$Qc~HUjA-q#`#Vp z_WZ?waJq2%qWMUAe!+@fpVj{Oa|-uaJqWywn0mPpa0U|B`XlxrusS~r=)0Q8C;pj7 z93ok5h84(`tq(TDBQNjrMh_z~ou>$%$_oqUX0?@QG@f5_o|;O)Sn}x_7UB)Kv=<)+ zr=c=Vk{JqeL1{4R1obF&QD0^){^Yag2`@F1#bBG&95B$ZrHi~~%u1i9Azm<95+}LU z-}7CAFk`iJQKM;iTQ~B=omqnK`mx?XMP%T%gplbk1pJ>3Q6FCbf$-9Oz-N`GVJk%L z?+jb}@XE(E*Of6Bfe?!Lx1X%4|TCn1;$?h#1l6oe{()Kk zGUC@300VOlh^#U)n)gz0=kJ z(^2Y*SscCRPpD_%dJ`-@SVl#wCz!|3&wg#>!)6YTw8LgOgTn+r`%f%tAs(^CELV+~onqP$747=Awm%;_F{Z13Vn)6`z#x_ktfDb-M{b zocxKOmcHcu_x@S%fW_>?%1?gQ5yyGL$_s6J$JB@hWRYMW*uG%ng+2yXH5)4%(loXk zH$!-w(-5xwG~V&aXR;c8kEy}A6LXqG&I<`*vgDrJto2;muXW&RKX;jLjnVCv95PM? zxfn>EAcn)^xgBT5a#A+FK$Nrb)5EG-biTFAL^d-0i@XC+&5T# zjN3l=(Js6m&-}^YwPVyUI}mdGGRre|JjpW;MHuY!AwUz2GLXv2WFRm*v&?qG3!7+B z9O=j}c)Jb0)E*MP3i{?5!etC6=P%%N0@?pqKa8bb?g;uU0e_;P-fH*c@nZt}Wz5Yu zf4+>~-{zsv#{-KOoL(kvaE9~eecd*mc(@%#Abki~O25#KD|>FEBjJ z^z#PbYc2FN&xw*E=Bm}ZPj%~5`n-{^u#TjIebu9Lv+i0)K(gY*L32|M+pMpBY!G`6 z6VGmfkR#2V4(4It{G>4b`13$)B8Ii z=^o#F>N`I0j&JX4jz zzDYq0OYfwdt8{{1xH4P8l6=ppHLO$Vtd_hcNF*c60 z-lT__**9l)@A<{szx>LBH-3c0;6&*sV>-V))~p|GAn`#zC(FKb!dU#^dNDEAjMoJm zT7xG3jF+Fr@OS};7d>(}R&XfCU%hWq^x);|`1t7G+SsQ|%(HboHOa{_Ju%h|m`&jX z)Z-&LH;=Isf8wC29H_veVr@=tq@kDR8uimKv~DZ?bG#g{7)EzYQ*SK{m7D8skL@gg`q8Cz z{=-_j`)KiT15(@)!qIX7lPUKqp;9;J$nbAiH218 zo-;U>yNP`mLj3343gz{02gzF7`TZB+S@YTh_w;iUomfsny>BN)?p)MTUE7XdgZZhT6jT z%5V8f#)sCp^fc?iYG{aIjT5fo>;uS{$q?W2m_3}0GuHUnFL4qb$0fxu^!2wD9ktKJ zu@ju{0?5u8n9H{n;^;M6_lz?K(z?+0!qwKdA@QdjedorUiV2`!44vWAfanbInKV zOf~>%>RMP=CY<#E?#Q*{icIc_eDpRBGJ6Enf_X3p{3it2nXdNQbkW||gc_fXJqfyg z)*9HZ%X!tUdUMk~K+J&x$DcI4(%gf}6it#-ZRe8!ao_%%nM&0JxOzVuyW_94$3NXu zN0Guy^PD=-i5c}eI!BGpJZv;auL;A}y|}z_lx^ndoF9jT6&v3;5MJkzUwX}-4&o~_ zzZbw4H)i#IalS|Atl2ALTh}-6G~;sa{NUhyC;agF`r#+*aOf`p#3ej9Fg$eV4;g;w zyWaVx{nNl_pE-*ELvG*j%MZWs;O6!#I9vYFi%y15wDO`q6Spkf(s4q;rQ5R4G)rlW zoGkrgtMuf1Y`rkXhX)bAQH2AZiG=|%F~#CR7KU}j;X`ArS7OJ@i^s-{9qbu?Seu7= zOr;uT;oh}3cT<<|ZcirCIr3dw#}HHot0L`Vojf(Lhz+R5GuxAJFg}68;7en!?8!|} zm5aUN|1aP1-Cy%B|I^<1 zo!@cbLEuxbf9CHi#0OBf{sUs&oNcMeewvGzJZ9tKpSE$GODt2JrHvgIS&Q9qrrttU zKXan-8F7VQxLs4?2TyjB{wA<)vNT{!0I9EmhI{cXq9L8RFiarVB%SNM@Py&4Ihf89 zzOeX^&i)z?-`zUG=*T*dvsYIY*S@r&v(5469M2Ra|IwWU$qmhpnp*JO?d05ANsT}L zsbzB&TTUwRej%`aN5Jn4bf0*SNuL|CxsAPRpX;Z&B|B5O^&12K$P|8kEg3La!1#|n z?=&ci#`;T~FMjlIz3Z(&-)!xAHr^!JedGWB@F(=0{||Bo)Ms*)Ta)!<&$v2L*EZT9 z6r2oc7e>SU1pu6!96@sT0i6>Y$wzyN1OF_v_C&%N7^p3GLB^Pkor}FGbC|sBpClkQ z*R_|*F~(PNb7@_TxAR*T``R79lLtEDal;GYj&tJhYv?0CR}2oj0Qtom38RZJp6F<{ zbueQ(tFn1pYikc8=v_}O~?14zs$K4Nt)DB>4MWD={a?dBBFQg;}718$tMaPHDrt1AAUoyH(a3| zPw!ZTC7{!*KWn#gV&OPV_`0BRDvP&92>1fodM0K291JBWUVR=|<7=_({K@)h`@nlCLbz)&@pt!R4Cz6pl$&t3GmTUW_xp8eFaP;m zo*9zxtSK)H+cfFc(a*;Nb7H*?=0x>f1n_wXKoUq_v~wbQA@jZYv;l|L9`#j@XfU|# zi`Cx1ryuh8fXA(_Cf{6N>H}oz?~Nee*6#4op>v-&#W&6xOA#zNClAjVgMPOuwd=*M zR^Rqrf4Tt zsA>IZKz#u+2Lkjo<&akzSpZ?{HDQ_2nqclvX zajwX@&P*h44ZJ1}E*SW76G7J6sH&F{7q9)wI1JwYD-edXoeN{g2GkrG9x;p}PSwSE zeAGP27-#>JTi`KlcPTs|!pLAo-rkwpr}f+2)VQi$=Q5gAkVu`HkvbfM9WTbFmh(3b z_Wx2fhhgPX?xmP;CB9R0&auGyGK7PI+ue!~)jgx+b*cH1u(-I+%%2Fd@77HjB5dj$ zYRRgP-y^`pjoUK&O)@pHPjNtQves$neQB-j_7{$ryhQa^KK3`>^&@z`Sz0Q6lVtP0 z+uOH%;g=u1cB5J6X^$CqcjVWE(bLwL0VhQY{q!^EhoLz9CsERv6AUL)1S}4=SM=jN zp73&>X*^Sm=y+?f%I1>{NPPMEtoRtW;j35pu#MG(95i;I=|@Gt_y|(Fv*@N6y>A>1 z7LGGNTO8})X<;k&5etVCZ@Cv?XLQ)j?mT^;6}GA7rj~k>57?;@5nk}oK68#*2R*=v zo}RJv@h|W6vq^hX?FGU!SD#Rl$;xHPPVC?^hDfyPGves{w7X?-J}cLicmA@$7ZBqE zG`<%UsWNBc;KHMSdC*9_$oOf@g$6a>*{Iz-x&NW}{Yzi{ul;{@<4=@*%#Q|s`-95! z2hn!7b)G#(nF(2wKl>w#Bc1o3FxzMNb3)g82tO=YgM+$sOfyXpR@5!nl*8aA#D

  • ^fi#j?i}yN3 z^9(F%N0-e#inhCWFoc&qK9!^xv3nPaH5J(04!p+A%jb9#$O1cUkxJIw=-<;=aLqjP z7w_PGv*#x7o3Z%Rdrv{l#Y%aV$f7Ji$K}i3QkDcK^gtoMJV81aM?`k&i(pKg+{6 zbf3jI0%H+!ma}j;*^!N~apFlHsN?3kC2Tiyh|B}&cx4fDlH))q^EgElCbzgdBLlqX z?8Ax-+l0{g$T#Ub&KdKR2{_ENn3K0}D2m~YwsOgMA`&XTM<1maS@>>}0d`odY{c~@ z8;IfHRxzzD&VKm9X>lPO&h|CSB`-AIh{o1Fwb>{Z`I^?T%SkY`BmZ?%wZ8S^yc2WQ z^1*HMnrVW-*||j4m$5p~uvv+WLX7J5yFuy|M{{fS*gS`mWA(jIk(Eyc2EFb-x%uFC zeAnCm&Huk{{A7PNKL~u`Ge4#>{?%T@U7tW6d&+g79=DmNuEo*K#AMzM9H*H1-`rvG zv6Q3okb`3;4s7Blj~M4D3@bTRVwXbx z;X09!HL2m3X6+Gd7pG$3$XvQ+CtNHxF(hPgw&Rhx0O2;*GCw@?y8@&Gmhbe{|KIGr z3#|58b>4T*`DQQ|!!V}6F!O<9IhV?py118AX`;GPo5ZOdr*1qm5POInyT%YVww0)9 z?Wj|!s#Nt7M-5|wn@F7*Y(pGHZiQP_kt)YFHempRNgVJ1V=yoml7NFKVZL+TKELN# zYw!Jk&l!ff5Ag2qy#KxTTF-jc+H3Fs-v9SKm(TkWKn{J0J&)YO{J<^aVVeez9T2tq z69eqA^ZeikO!3$cf71B$_;c@j^UIz#e;m&cK^-uiOyb_#$2H=7S zty`jZQwjH)CGjpirDYz_PjOmao=o7fNSdz`#}RSt%Q^sX=u*_^ zHg&ZdLwEfI!V9kAjlXi#9FUsaqZ@vDA=?29T9{s_;lWU)d8$sFGe@1X#sceD%_9Na zo`|~H+QwKeU1(dV8Z0-MD%(?w+1%2l6+D{-{q@1dcJM-zDm6DGeaUlCjVc`wg9Gj-d(2kd;W`~gBt5DlO-<3QZ#NTPKO$Pt0bSek|V=x1eQ3%Bu#TU zdIK$sb>+{l)?CJ#E9MTPM5FD1rZ3A&HmxDhYZy(9c_klf5!D6u!`!;=fmPc%vqCNu ze>?M-A#BHX6s_|VzsY6nCpOfvZcchCcE51p6JPq$|0?SP-}e;vRqidz{b26B1KaR8 zMD_yqPuDnrPr$}svO79GzWcZT?n|E*|8+1SKIP@5zj^vUUfNyx z%g6fL&;Bb+%9vWdlDzzfJ=-wXz*!&eGYKj~=YDv2knjX9GT+c__!KE=p&ndn^n?N# z@=-Q^jF);BZUwH6nd=ui| zSuwApu;Dtd@f9NC>TzO%h0BmHxkM2&)if9{O?l+dMy+?eLf@0R|P%+hvllX1qo&Q*F`Yc`$N zm6tZ-@7u>~!IQC%n*B~|&$0XEw%s=`b#o7fCNP-k@=9}Tn**KUP)v{}SJp<#h(O(} zkK7C4WEi-}`mPS%%6xx+K_34FC@&_lQUa;0<+8d*B^jYo+6Qe!wxOd&w}*KPtZ4#p z$qQy(!rKOoRbP&Ck2BXQYXBqAuyp=%rvZ(h_-FPZpYkPZQ40{`&jh{QG`Pkf*fN z>^yZbe9e1z-*mQn@Ll>LJ>^P?(d705rS?*Bofrw2Jg$MeU5e3WQs4qy7Fl-7jf_f| zEJ}CkU8TgfL*_Xh{)T+fdr^Yu)o7y`BjS7#vD_{dpKahG4#^z9`Zb({UVKzrUxhM0 z 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 literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_camera.xml b/transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_camera.xml new file mode 100644 index 000000000..0d9ea104b --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_camera.xml @@ -0,0 +1,12 @@ + + + + diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_gallery.xml b/transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_gallery.xml new file mode 100644 index 000000000..f6872c409 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_gallery.xml @@ -0,0 +1,9 @@ + + + diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_manage.xml b/transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_manage.xml new file mode 100644 index 000000000..c1be60b36 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_manage.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_send.xml b/transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_send.xml new file mode 100644 index 000000000..00c668c60 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_send.xml @@ -0,0 +1,9 @@ + + + diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_share.xml b/transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_share.xml new file mode 100644 index 000000000..a28fb9e28 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_share.xml @@ -0,0 +1,9 @@ + + + diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_slideshow.xml b/transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_slideshow.xml new file mode 100644 index 000000000..209aa6430 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable-v21/ic_menu_slideshow.xml @@ -0,0 +1,9 @@ + + + diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/transformers/llm/engine/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 000000000..1f6bb2906 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-xhdpi/ic_action_add.png b/transformers/llm/engine/android/app/src/main/res/drawable-xhdpi/ic_action_add.png new file mode 100755 index 0000000000000000000000000000000000000000..a4b78100e34a97eed37202b25072f023f2266bbc GIT binary patch literal 221 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpUtC7v#hAsLNtuPo$ca+F|wSgaz_ z(8f2xq(y0`)CLh}Lz4zYMU|3#`XlnA>lzjmj})eDibL z=KEhav)m9$@NUp$+=j&XC&w_SVc(-zF2?7lq>mRKSZ=VRfgj^q52iou vjXv$Kcz=Z!iZ+NrW(nLe>DxEn-|E3E(JrZ0wER~u(7g5P)98pMb)j^(zGPRm+~R75R0{Vm!BB670q8O3klh8vAnlB@x<# z=_p^+{2DG}XKueFLVIwlk~GWlv)#G)7X;RFA4hbMsG{p z5iTf=|K|7N{aOM=6A8WX1A2QIZiejG07Bg?nr{g_dwHw_9z5 z3;Iicjz;ckdgE3gT-5K!eNeC*%ezl0{G*c<1E?%{15q-i? zwtAVFYg0M(#rpqVT0|$7SZmISA)%>Ts6^}|O>eOausz0UnH9W6e{R28V52YtDi5_* zwP6-oAWY__@U66nE^cc2BSrxRg;8SpoLG*D)tW^N;ELWifi=9tNN&H{2=4<6dI!BT z7|rcg3%_3_zmyiS5*N|zQG0>Vil6i6iTzsB-^dE$FL6rmePUhcoet#os|`*Ht$2A) z%(tnW25=_siE=s}&FxkjVX8f$ciPeX|4Eb){&sLg7}3o7&)522smeQ?j3$p#00000 LNkvXXu0mjfdlq6f literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-xhdpi/ic_action_chats.png b/transformers/llm/engine/android/app/src/main/res/drawable-xhdpi/ic_action_chats.png new file mode 100755 index 0000000000000000000000000000000000000000..03052f14945c73c58c529f200b54003c0223fc22 GIT binary patch literal 620 zcmV-y0+aoTP)IK-iljp}0lG!x4}nGCSeMo} z-?A<2vwZ2g1Uh*F#-1a50ZxF{#>ZF^Knv&sPo5N>0!`ndz6e|aH@hMo0?@NN?{a&T zK^@O=^^`bg09<(Zb=`m);e1x)>jm&AI1Um=6L@nRU;MT9ZW%VM6P_cWnY=J_@sb>9 zll1}k5EZGFbX&J%jkSq}fa%U|g={AR+}s*z6Ac0LN#k;@1?&{H0BzI)v{4JtMlC=a zwE%783E1ne(H7}R#3y@pA7}zY$FZWiH!^pl&5g`D?nG`4l(}XA+zO5luJc$pBj8+- zZwi>XlpJ)O%Ai*fFv|of05jm43U0$t@Js~8K!3-aT|T#-onHd&(1J6}SY<72g&8}( z+mrH+88NffHyc;R#$=~)Ys>ATNcAb{F^jahPk=4Qlbm&BZCOZOka^iu0Hzr(*xtW{ zVK8k9gmi%c>H3=zVAIAo)n1gasZFJO{-cnPZgf8a?9R&y5dl}FANrs03BXLWry^}) zDm2ypfk(h`AZ@BgzR}1C_##_sV=C0SGY|r#Rd?qTYi)jo2ndMTw6SQzBcS?e z<3b3C_Gaf3I0CBIq&9&Supck1513D6^~=ql0UT*_2;mz7zDiM(1P2BH0000)PW%| z1=hevg4hG^z!NY4YBs$l@iSnTNVq9>V#IAi#82g-tz6UxT9INdxo$1vm!jwRV@{kV zbY(>ksHpu-?a>F@wdebdfuV3$E>a8V1Xbx471qFCqZrTz?|^$ljDc1Z^(w3ZTh-kI z{V3{HSOX7I1FG=|Ttrc?${a|KVjwk&0d24g^ej=2qF#kHu#s9&jcqPvqDT;yAD3e$l%zhcozL4epDUk}rKxz~NsS$D&%6nUdf3UHY z_ts)66axlQGv=f<vd#lOG%1`cZ?m)PXkXjv910d?jq~IclJp$n&sA#l+bkxA_Dn(#B?_ SiY8S60000TMIsUg3zNxUkr=EJi%AGE zSO^mTLJcBS?a)?xKZf_T-d?xud+*CVS8|`^x7>5jo9BDZbI*IuxeX09EHt7Ud$0wq zu{~uL7U4KvqkswAMNe#RnS@n%Z?=Bo0anEJH>c2qZRkQDK86`c>mfR0d;LQpHYYHM zd+5bJye$G4!>QPQXDOIJgW+JZfJz6A5*xQUL?z68foae9TzSU&xL#n_DPRj!pKVk3-vXYke(;D+!R8?hcO=@IC{ z8`aY!o?w}IViU|C#7Jl#!v!=JPhm9yrf?tYEF7ED7!Bst!;G$f>^t zFnv4S9ievNQ(k~VfEbEU!+zfhRSZx|$_%g?&%_z^`D$-gfM)EF{Fz)!)sYF{f7dVd Wsn`=|0h_x30000g|Nn1${IDz8lv#we%T&`hnQ!g%eR_AZ0@Q)6L3G83 zB0zuuYhZqcXjcU=_LBHqiU8J%0M?2C)(QatXqG+~tN}9f%dG8QnFMA4Km%Af?LPy_ zDM>5=5@4jJm>xzGCdW*>LvQmEqy8H8^A)06oT!0;8@9ZfqxP1?-+VD%nGsdsPjQ`YACh~ zv2m2+d>t4^Sfh|c>;Zowj<0uM3^)W{Bl1h&S`K9#(LGAt*4l`^=2#$QGJzpEoR?4N zU1=0p0Zf#_dC5t?0nb2R_5k>k(EkJI;Bsr|K{a>Jh}BYrEV0BTSrfRGpZybB2e|cv zgv+-lL+?_cWFaCj>8TuK%lrJd3gX#Pa;0HWVzd>z zN(rWA}QgR}|=hWfW_(*SWa;=S25D{b7yi=c*q_4ou7J4-^7Qm@5@L(8y z#o+UZfhJ+CQQtXH;5JgXdtu0&Zj&=w$v`Oy8gartxU@tD&dP2KN4dVtppx^V zL|?acQV&YzXNKM*oi7JjJ18L)UXjFs(V#VdMa zt?R>w1C>+Kj8fp3DBXwFHnmih(c&{XO}f+F!EQyLHbD@U16e0;7#rZK*jPEeNaaXE zZ;Nnrx$*<(5w>;Rs)jscUCEoN!0S$IR4WHQ>eZ}x>wkD);D4EW&AVQN{d$3BFKkL2 zE16?~))>Dd`n-c}(K*F$RB9V$)bNQi(V2nYKCZEz8lTODDO#q&w9^eaSq+VKf?nau zjw{NVdZk#`KskGbQ7a{EoRA)JrFKwMYUOpRQKEjpqSG^hpsum1?04$SI3fLjY^Dlw zt*NP9(0&SJtl8*#fIJYmzC`rq4R}3+L+^_tTz)jY&l~bPYZwqDxZqijZ(dO&e9_zC zeHysQ#cbzAQ4?2>B)MB4cc&c7`TM}63=X&#{*qn)Im&P@7+w*M2&>ijyIcYff6_cL zWb`d%4b8q~3EcD}xKLZaAzPOfJ6S?;Ro;zCh2qW^)gHhAVtZe>vLNT5JyvWp=lPDs cp8nnDKY&EYb&qFdP5=M^07*qoM6N<$f+t%iod5s; literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-xhdpi/ic_action_trash.png b/transformers/llm/engine/android/app/src/main/res/drawable-xhdpi/ic_action_trash.png new file mode 100755 index 0000000000000000000000000000000000000000..d9f8731f607953d6abbe5f947c6e1db464bbcd06 GIT binary patch literal 387 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezr3(FnW2qIEG|2zMXkDugO8c&6Q=P z?<}=imfKuiK~Mh9e_L^IQjWRuu1}BE&Z*qLnwZF^lhbhY(Nu1ahOY;foEJIKn3mwB z5XLClz;)x^%*!vB4qUo3#ZGgLTTy?ZecypwpLcA${YO2Z-$3@67jI4J+2aQc8)i_*tt&nRAKKh9dBzW(u*QW; znZ9!{2nu|Cqs}y~|HDbv2Hv+`F%0=k=XL(+eV9`A^&YeQd4Ux=aU6TL{0Mwt-5tJ} zYlipzI~fn|A1Z##V)8B|h*2~E70qxtkds`Wc#gGhLxtvt`0n{Eb~_#1e*5iaHfmhn z_Vj?;18wDr%KMGkKZib2wCg@FWhs-E!G@3nk};S6&6sUmpUl-V;kvK}^XaekNwz`< dpG3_UFWT_*&gNxPgn)s|;OXk;vd$@?2>>rcr|AFy literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-xxhdpi/ic_action_add.png b/transformers/llm/engine/android/app/src/main/res/drawable-xxhdpi/ic_action_add.png new file mode 100755 index 0000000000000000000000000000000000000000..4f84e9b00d916bcb0cf53fac46235b08fa23c15e GIT binary patch literal 343 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2V3hN8aSW-L^Y+?Ctz(Q5ZXegr z5c!_CQS+UH=HwzqH}ePUjyz(@@!BMPM$hqO#MFQHPcGQ5|2+KtzmjF;Tcy}?n5((B zo9@k*DPXyyf9KzqeT4@kPxmeV-m5)9gDiNX!{LBt0rwr=JCA2M@H@}WYxw-Wab3fC zQ|JG)`5)|ZIL)O3f^{sr80IxjZ>)|s{!*H8S-9Y5c>Lk@8#wDPEMe*-6LLOasfgck o_+{m1>iznh&-eR%|K`m3AAt+7 z10(nzccz_A8E`iK@K45ZVcIPYF2OIRXG_{I3NFUa9pS*Hv||jMiz7uiKcpRF;7aT( z!ubZP)1DD<1%4~S`3@`7o)NGbgGD&srX6G8S{x|C*^O0c&j@We`-^bC#_4I#2v~!m zBAh*G#~8Q~hl+4M#W`uu2yHkAJA#?S7dS2L83AiCTujccv||k1hChqR`4DHNJtMT? zbUi*y;xjBudq&XQkVlGI?MOSuz&ac&Cg)wf`1pXixEn`{a6ZA3v}*)hhtZ-|+tZFQ zaF6bP<&$^|E7G1bPFt&cal9j(34DOXY1at21!G06wxu0oU<3XtCg%+-PkYWdn1_u; zIOBK+3)8L<(BFp8Melx|!2>u^)M~R{yyvvFdbkK@3|p}v?HWOIAWsyvdM)i31CJDE z&N!aKqO|9XgFZY~gmVI~V}9B-LVM;+7PWdY?HB`(7iZ2mp3#d3a$Bn>i*QEq68h4v z5%9!GYBi8{jDdk7oH1WQ?HC1T zYL=V2_#M}$J)>X=b`>G*!{uquIQX~-X$Wi5j#01@AL)K9*^isko>AJm?JPn%fUDD< zaqxaow_&VJJ4V47ZAe{{bP#u>J)>ZeW+|#Gq(itN?HLDe7j+xKWogGKSkZ>mHA#oj zpZ1K>)@^$c(h=N>xoOuZ*izJO6xXC3qi9~bZ7n8g5cj1$qhKN4)BSzzDDIlATl4L{ zixaph?HC11HM@#klQe{lY0oHFpt%BcZHXM$>{<7G-Ci#0Hip~Nj!`sk0bVKUHjIbT zo>4Gga|P(C+X(JA`oJN4_3EZrjtl zdEYNJW3-l9EY`aBnbdl|Sn-{E)ZK#;(;rA^s)Soa)_hXpObEPF7I?Mi979{fTDr8xs`e8Fj z?1_6t;d{w~WPT~jJ2@w%u33jJ{dj%qS+{Qs*u@u!UBA1+=H~B%avvUinCHv3#iv0> z)j^O{G?n#9RmT3JSn2z^OSn~j`TXK5k3JFCot^LEVch(B>-o91FHSv9n_K%fr)5u_ z9#a%U_&0_4-FIt2Do%J`e)RGugWp?6_7mK{l@^p+-ME>^^5)gP?vLd>Z*DVhpYU#@ z(#bdW;jd>jc>6c}`>g56n7$+0QSHF`Y2N~7PbjkqKYW8{cj3WZ3F7tr7q|^F66LpY zWJXk!&6!bfcm`Yc_2q1mAHtRYMO}A$W$E8{CiPpT*scocmrSLiy~|jCbeXQ{pD=B= z_o1~1{Et{gl`Jwp&$4sUe5I@3B`?h_TM=gUSdsNs;#so`ruSaY5}!AF|CRmIqxb9C zeF^nnH|?dp>9>fYe~goC#dssq)?VK}pMTXh3+*MI2|?3i!yAHA?^)$`#eNQH+0rbt zwDJj`#OG^19&1Z`MCPYHTXp%&@v{D@w#PSa%vIUFSK$Ay3!EpKjB_RZmQ`1{CSCr% zRbrL-T*ZlXuNc2_PGC)c(~z9x9Q!eSox{Da|LqlH*M3b+Jam6jtmv^kX7wG~Va4wA zCtO;nXMJ6Ii+`}GOpt+}bA#7`lM^L2l$nNx7&>r0uTXyYr7F>(ilu$tjO4znva)qO zLQExV3)C1b7W*B3`L(HG-pA!dk1g-ogl%JLFyfyh^D}MB?Rm)}3{O@^y*Fp`TOZCD z;CI~axz19d2A|S9e;eKeu}o;(TnSQ=@}Oipht6UTvD;^oQ%^Hz7&CA3=5x4tZ0V;7 zTn$D~{(kej{W?lAvcYKW1YwzIu8cJWX6Dg9TlUPf@SOKp@Y9*}wegPAui9_>Yg5SE Tqj~^XUNCsN`njxgN@xNAYD@As literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-xxhdpi/ic_action_contacts.png b/transformers/llm/engine/android/app/src/main/res/drawable-xxhdpi/ic_action_contacts.png new file mode 100755 index 0000000000000000000000000000000000000000..579ae6afd6e8965b0707772b5391dac37953ca73 GIT binary patch literal 711 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2VCwU9aSW-L^L9?OzqFx%+fI`P zjp^GOv=+2DEf%;nY1x{>uIII!{f*iQySwKIeyC-h^m4Or0 z=kuIKciq$c2mAuXY=g8kzT9Q4bNT!HWtp4KEyXo8Z32s=p~{I4MMt+D6UPJW4}zVnba11zd$qMfmN=~^?{3%<7;ns`)Bpb-bERc)94lsu9(`B9Hn^K)U>E#j-U z&92u1Yxc{S#~GQMT=x{K<}CpxAH+(S6DUpp!B|l93Djue# zx#7$96PG0OS7$vHkKmdVvPip7ZRLsRrWHGU9<1l}FxZ|towJ6~%#`SQTpOewR%i(*x@DrkL?wHzgAsER@UhIy@RPTwIW6bAKl#(yJhAd#Yku~|=Nq-ZhFb_qrmT_S zw$$&;U)^0{XLLNZMzqsjee2pM$}i4Nc%LE|@%&?(<*_GgvOoLA$u-?Or2EKK;p(Z( zNySD&``hk%TF&IC(toluP*CD_nD-AgpqP8~$(s%rxcGV=a#;FBv)t=lul(`#t#xx+ z7Njq;^6a0nk0T~)Lh(7ByN3qi8Lcvy~u|jD2 zq1QjTK;r6ZPo8Ld@VhGTJ(_>(_fO7C!Gayzl?^L7FC`1k*sEYG-ZV*SULTI~nA8w|z}u~Ix!K`H znG=mND;7Ka?R!?J-VpWHW%}Vpp@$Bg1q)m(0+eJl1o@_LuzR&Is~&0;3S<)4ki7Go z;L*)&Ml-Y%7-VW(m~S#M-aerEA?5GBY#Gh)1yXZ7|FP~fy%|vEa6sw;v)t=nd_0YZ zmr0%G1KJt;K&qlo;V$$2*%=z%3M+rjjCGxG>;Us>xeZTwR6GwXJDXs*r2fE3E#4Gf zAorNe67lLVS^cekT8u!=rN8w)Pw;E}`dv(q3CPv|R_oTQIF&^u)Wg1Vx7{o^D@HRh z-3XBhA!{d}>s&v1UW5FBXG%xAm?y28Sdz9mLiQ5J4v)SiL5)jZ9jx_=;MZ*rF`5vf z_?1KZwbhdJLrI(eJrA>*u*KjK!;MwH3qCpowU)TtIB{&ky2iIR`L{8-+%W&TR(SqY z=0k-ZInhRvp06*<=5uG^{KzQ1NEjJ>mNY{0iC*#Kj)J%@n14CdFF!xn1IE!D!~*xBTJ% z&6emcIL~pY?v20?;e#vVf1eT26guJdM)0$ETX=Ednt+uK$Iskf5~l`a7CN-Z*1VeW z`0YOJpfwT-m)KL450#}G%4kQiOn4Y0F#nwT@{VrVt$w2C literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-xxhdpi/ic_action_settings.png b/transformers/llm/engine/android/app/src/main/res/drawable-xxhdpi/ic_action_settings.png new file mode 100755 index 0000000000000000000000000000000000000000..1deb180cb1eb006ee65c0641e397e7571142c262 GIT binary patch literal 2184 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 literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-xxxhdpi/ic_action_add.png b/transformers/llm/engine/android/app/src/main/res/drawable-xxxhdpi/ic_action_add.png new file mode 100755 index 0000000000000000000000000000000000000000..236143b01e0e26b337919e08e825da71ccdfd275 GIT binary patch literal 380 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7Ro>V089$aSW-L^Y;2eUzR|Twu^6> zS{;MfN)ui*tjl0*U&0`CZ9@?&>jHh&4JUgPex|8ESJ}T`e|}Xv^BPm*@5Z0^Y`FdF z+}&9-mq&gJxW6-+=?F^)r+~16nuAZn3d-7c=N0EGRQPaQn=j{F>#W{lD)VnCo5rQ}}_@nR)ext~*f4B`ChhNqd*} htT561>)ZoT`}^-iKl0L=6b}ql22WQ%mvv4FO#oU(gTMd) literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-xxxhdpi/ic_action_back.png b/transformers/llm/engine/android/app/src/main/res/drawable-xxxhdpi/ic_action_back.png new file mode 100755 index 0000000000000000000000000000000000000000..de6d4009c6a33ce6a29dfe084112b0883bcab0f7 GIT binary patch literal 1499 zcmV<11tj{3P)8r_P(o`LYfzNf5*mUF zE>wtJwSC&>`FXiG-zS#HGjlP`B$Ijn1K&^1%$%7y-*e7vutDcvU>lr=kFXN&;!JE= zTU+yBCoI4k|7IPo#ueHigggId=Kqs%%&V=nIWQgfOkwy* zR^$BIdYb~f;uef$48ZHyv$p1Dzzp0bPC6;xz}(uJn*p2Pq0E{88uqEJxf!rM9?3BL z2upEjZOzSqJ;a8)Hgo15SzB{6UoVQWVYM|kg9xlG5;xcsPhh{=nwvp{lwZu8`HQhzZOzRf!V52F z7=8lJV(;3Tn*sabaS^$kia*81+&A1(V0SE$4ln$PhcUah=4KFqwWXOe|3U0rTXPd& zL+pjO5{5Sn&SLCQTXz!-#y<$pWX${#9@976a)?XTbJF33kqE%`qh=|vBi<87$&~T$ z!mQewn_zG|`{ILy;fYJw!`P*^?j{(FKUdsvQ!{@;oOX7vt-Bd;fVknN!VBZL89UY1 z+zjGR*2ft$e;hYq``VhDz~4vBEbDV99BWU?Un}nh>V7um2g#Uy-k9{@TPRclL$TZ zpj&Bhv`8;Wv04P*X4cl+95_T?<>D{6wy%Ws0A}N*%$0CMZM{t*@;qOY&U}D{dN{f~ zBJt{#i~(39e!}-O^U~lzQKg>ZH_^+pXF`+)dx{FjoRx4FHma?;Ik3OHk|QGbzo(^? zMjTOJ$QXbz+=^XmYi?S&$r2Zj{iSpA;YHMx|>@7}5IeWsR zdNE#kL^sCP==n8!q4=-w%@G?3&SE1fqB85#1dXW^hM0W(>ke)H@%e-xJC*xT7ni z--qB_KgUv)J;=*C$y&lJ6v-SDizW~KAJxk*84VC}^002ovPDHLkV1fbY B;#L3v literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-xxxhdpi/ic_action_chats.png b/transformers/llm/engine/android/app/src/main/res/drawable-xxxhdpi/ic_action_chats.png new file mode 100755 index 0000000000000000000000000000000000000000..40340b0acfddb5cfd5cd4e5314301e21f3f906e4 GIT binary patch literal 1681 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 FO#qpDV=Djv literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-xxxhdpi/ic_action_edit_icon.png b/transformers/llm/engine/android/app/src/main/res/drawable-xxxhdpi/ic_action_edit_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..a58f1c0a4a43d5dbac7cd372ab24e102580e0d8f GIT binary patch literal 1198 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7Ro>U@7%SZ7IiM^RJiq{T|}&_)kR?TirAb`ot&Q5sf)t6w4ylT(igXg zJSr7jtiChh%*&^Ho+N)%yLTrgz5IP%*}Zf7zPCR7_vX!B`}=$EpR4|yR+go8nd3&= z%SW%5-T3Os_U7Q}3ix%ngFWzHVU3s>JDWL@fRt^P3}^Z&xf8fm+&8n12)K3=|K;io-`k1`a)fC2}b z*QB0#aB9|b{;tLRxATJ24J^v0eT@7%_5S1cSB_qs@3nENX5x+;GcTr3;vPvihOh_KE%_;1nN#eH*CUt8WX+{yIpL(0WtAG_wV zu;@HcjmeWqPUmIn6X`F{-Mu;EcEz!CQY<#R-`UGZK9;eb>ZIn^P}o1$%TZX>K|E=B z(1Rl!7pC4=DPkeWRH9j?)mj$Uu)*nyZ|4`)@Gbed)}Gwdx&FJDw#Zvw z=e}N}JN27qFi2dj=Jh4fyqBC8>fZQp&%EEgg{8ybgizSlzjO95Ok|6UJP>kc=iDc( z9X8u1v$n9VQ_p&JxZ`=*Br%0Ozv9=g^wthOwUYZrV}6#^{;8Tzudv?f+FyNT@m3IX z&#lFL_ph7Y;y9P0s_if%fBxDj|MmI4RGxF>oqy6R@<6lgsrg6W&HC$Jq^6z9_&)5^ zz6O88*qixF)GtgH2{8G!-0NnyMaZpm>vzW!m2Dd5t!k(}q#JwcPvh>5-WA331lR3f zbx-MyQtuoGf4_!b2d_&$jJmyxZ+%&v^6Ro7kpS}_Qq$b7zg?oSAn$`IPw)EMo`DYQ z4_@Ce_x_KfgG*Rm*#3BRT&eG&vP{;l&)rt4stc|^Sbd6VpUAs_>gfd`C0hmWGU%H! zK0SE7@*(fn@`r5Y?-TY<%P*SP)39ja@ii`|vMXe^Yvz>+Hcw&k5udyFG>3BPS{3Dl zn3GIOlUZHVxI28r1ZL_e7)3gyY-%`>!Z?v=iN|UWRussFdEM^*;hP^N{-OWF!>O9N z>8+tv$%+b_XCa#@+1c=Rhiv(i+y~okFX&f0lVUV8?}Pjf*%@8k7f##*mO~7lu6{1- HoD!M21*yz_+v!g|=X3A<2kyO`&;2|RdS-e600fQd z99h<=B!K^qwUt=|<0o1=Gq z&_EWl($w$!2&`M)3?W*K-AUz}7IjecAKYDenbU);QmP~8* za(g;IpCuHLVhCSgSg4~lRmeH~es-vUxWG`xQyKt;=hN?b(p37fh19y)bu_fj_>mU; z{103iC_$qh>%EGNvHU3k{K$gJ%P6_NL(y5AOj{I&MfL2(-dpChaQP-;t9$GSLKm=LEKa(yt(rRlSSva#!T`aeO-{mA5 zs6G6qnDLrc=m08!v@O_j)j6Lj9Y`+Pu0hht*vX1)PMgc&!SS)bsIeeVKg7I((e2;D z{Wf9Tp+FnfTFwgh#XmgZK}j4||Fd+i1TeTt%bA@L`UR0j&{Qv>I>RE8(4y{>gj6!q zH|2g9`9u8m`Y}AX@zu_u^+l_hu3Zsx*-i;Q)2GXULV+wLrfillL7D!p&M$*!VXa0@ z9X80ahz@UnEL>X&|6R$yWu!_Fp-n|*c)*Lq-uAg z5D{V;W7?n$Gg_%{T6S9$Z0C09Ry9$UNh`^+r>=G?%eYXfx!bwz!Sn)*sLl&HdAoY8 zqtVh@Vf@HU{Q1Tp2sH58(#sUQ811O;`QsR%*y?+6;Gk)%ODD;ef0rKPtlmGw# literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable-xxxhdpi/ic_action_settings.png b/transformers/llm/engine/android/app/src/main/res/drawable-xxxhdpi/ic_action_settings.png new file mode 100755 index 0000000000000000000000000000000000000000..e9e98f4f81bd9d6885b5a4f875573b01cef3e06f GIT binary patch literal 3560 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 StjB>_pTX1B&t;ucLK6TVF~~gt literal 0 HcmV?d00001 diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/bg_bottom_grey.xml b/transformers/llm/engine/android/app/src/main/res/drawable/bg_bottom_grey.xml new file mode 100644 index 000000000..ff3709ed5 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/bg_bottom_grey.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/bg_chat_me.xml b/transformers/llm/engine/android/app/src/main/res/drawable/bg_chat_me.xml new file mode 100644 index 000000000..d354ac72d --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/bg_chat_me.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/bg_chat_you.xml b/transformers/llm/engine/android/app/src/main/res/drawable/bg_chat_you.xml new file mode 100644 index 000000000..c9ef32f00 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/bg_chat_you.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/bg_gradient.xml b/transformers/llm/engine/android/app/src/main/res/drawable/bg_gradient.xml new file mode 100644 index 000000000..0ece605ed --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/bg_gradient.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/bg_item_list.xml b/transformers/llm/engine/android/app/src/main/res/drawable/bg_item_list.xml new file mode 100644 index 000000000..b50e4bc67 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/bg_item_list.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/bg_online.xml b/transformers/llm/engine/android/app/src/main/res/drawable/bg_online.xml new file mode 100644 index 000000000..b3eda8f72 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/bg_online.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/bg_top_grey.xml b/transformers/llm/engine/android/app/src/main/res/drawable/bg_top_grey.xml new file mode 100644 index 000000000..ea005f9c3 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/bg_top_grey.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/bg_unread.xml b/transformers/llm/engine/android/app/src/main/res/drawable/bg_unread.xml new file mode 100644 index 000000000..1da11cda4 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/bg_unread.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/bg_white_rounded.xml b/transformers/llm/engine/android/app/src/main/res/drawable/bg_white_rounded.xml new file mode 100644 index 000000000..69dda84ee --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/bg_white_rounded.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/btn_grey.xml b/transformers/llm/engine/android/app/src/main/res/drawable/btn_grey.xml new file mode 100644 index 000000000..72a854619 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/btn_grey.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/btn_pink.xml b/transformers/llm/engine/android/app/src/main/res/drawable/btn_pink.xml new file mode 100644 index 000000000..c35438bbd --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/btn_pink.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/checkbox.xml b/transformers/llm/engine/android/app/src/main/res/drawable/checkbox.xml new file mode 100644 index 000000000..9a5877b3d --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/checkbox.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/ic_arrow_right.xml b/transformers/llm/engine/android/app/src/main/res/drawable/ic_arrow_right.xml new file mode 100644 index 000000000..e2ca33421 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/ic_arrow_right.xml @@ -0,0 +1,11 @@ + + + diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/ic_attachment.xml b/transformers/llm/engine/android/app/src/main/res/drawable/ic_attachment.xml new file mode 100644 index 000000000..82073232a --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/ic_attachment.xml @@ -0,0 +1,11 @@ + + + diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/ic_clock.xml b/transformers/llm/engine/android/app/src/main/res/drawable/ic_clock.xml new file mode 100644 index 000000000..b410c4922 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/ic_clock.xml @@ -0,0 +1,16 @@ + + + + diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/ic_image.xml b/transformers/llm/engine/android/app/src/main/res/drawable/ic_image.xml new file mode 100644 index 000000000..d710d2711 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/ic_image.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/ic_menu.xml b/transformers/llm/engine/android/app/src/main/res/drawable/ic_menu.xml new file mode 100644 index 000000000..5a31e6ec2 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/ic_menu.xml @@ -0,0 +1,21 @@ + + + + + diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/ic_radio.xml b/transformers/llm/engine/android/app/src/main/res/drawable/ic_radio.xml new file mode 100644 index 000000000..49de9a072 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/ic_radio.xml @@ -0,0 +1,6 @@ + + + diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/ic_radio_checked.xml b/transformers/llm/engine/android/app/src/main/res/drawable/ic_radio_checked.xml new file mode 100644 index 000000000..333aa3e44 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/ic_radio_checked.xml @@ -0,0 +1,9 @@ + + + diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/ic_trash.xml b/transformers/llm/engine/android/app/src/main/res/drawable/ic_trash.xml new file mode 100644 index 000000000..f27c8a261 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/ic_trash.xml @@ -0,0 +1,11 @@ + + + diff --git a/transformers/llm/engine/android/app/src/main/res/drawable/side_nav_bar.xml b/transformers/llm/engine/android/app/src/main/res/drawable/side_nav_bar.xml new file mode 100644 index 000000000..458b4b07d --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/drawable/side_nav_bar.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/transformers/llm/engine/android/app/src/main/res/layout/activity_conversation.xml b/transformers/llm/engine/android/app/src/main/res/layout/activity_conversation.xml new file mode 100644 index 000000000..319260201 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/layout/activity_conversation.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/transformers/llm/engine/android/app/src/main/res/layout/activity_main.xml b/transformers/llm/engine/android/app/src/main/res/layout/activity_main.xml new file mode 100644 index 000000000..aad4c3972 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/transformers/llm/engine/android/app/src/main/res/layout/app_bar_main.xml b/transformers/llm/engine/android/app/src/main/res/layout/app_bar_main.xml new file mode 100644 index 000000000..eff218617 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/layout/app_bar_main.xml @@ -0,0 +1,19 @@ + + + + + + + + diff --git a/transformers/llm/engine/android/app/src/main/res/layout/content_conversation.xml b/transformers/llm/engine/android/app/src/main/res/layout/content_conversation.xml new file mode 100644 index 000000000..19c0f19b8 --- /dev/null +++ b/transformers/llm/engine/android/app/src/main/res/layout/content_conversation.xml @@ -0,0 +1,90 @@ + + + + + + + + + +