From 68bb4b3f9c17b571cd68f2640c0b866cad8e3b84 Mon Sep 17 00:00:00 2001 From: 1iaan <139833683+1iaan@users.noreply.github.com> Date: Wed, 11 Feb 2026 11:59:40 +0000 Subject: [PATCH] =?UTF-8?q?uring=E8=90=BD=E7=9B=98=E7=9A=84=E6=97=A0?= =?UTF-8?q?=E9=94=81=E9=98=9F=E5=88=97=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 17 +- config/config.xml | 2 +- diskuring/diskuring.c | 215 +++++++++-------- diskuring/diskuring.h | 24 +- dump/kvs_dump.h | 4 +- dump/kvs_snapshot.c | 20 +- ebpf/c/Makefile | 10 +- img/主从同步.png | Bin 0 -> 146225 bytes kvs_protocol_resp.c | 4 +- kvstore.c | 127 ++++++---- memory/mempool.c | 56 ++--- memory/mempool.h | 4 +- test-redis/test.c | 25 +- test/test_client.c | 220 ----------------- test/test_client.h | 161 ------------- test/testcase.c | 539 ------------------------------------------ 16 files changed, 293 insertions(+), 1135 deletions(-) create mode 100755 img/主从同步.png delete mode 100644 test/test_client.c delete mode 100644 test/test_client.h delete mode 100644 test/testcase.c diff --git a/README.md b/README.md index 917883e..7c3e1c5 100644 --- a/README.md +++ b/README.md @@ -353,8 +353,15 @@ ALL TESTS PASSED. 10. 能够跟哪些系统交互使用? -### 架构设计 -![image](https://disk.0voice.com/p/py) - - - +## 项目收获 +reactor网络模型,用户态网络缓冲区的写法。\ +特殊字符串支持的引擎层数据结构设计,支持\0作为键值存储。\ +实现RESP协议的服务端协议解析。\ +使用fork的Copy On Write机制,实现的异步快照创建,不会受到原字符串的影响。\ +基于BinLog上OffSet的主从同步设计。\ +基于bpf的实时数据同步设计。\ +基于共享缓冲区+额外进程的实时数据同步设计。\ +基于bpf的内存泄露探测功能,实现热插拔。\ +实现支持分配可变长度内存块的内存池。\ +实现专门uring线程实现异步的增量、全量落盘操作。\ +使用配置文件规定端口、保存文件路径等,使用mmap加载到内存,使用libxml解析。\ \ No newline at end of file diff --git a/config/config.xml b/config/config.xml index df40a51..f13c407 100644 --- a/config/config.xml +++ b/config/config.xml @@ -18,7 +18,7 @@ - none + incremental data kvs_oplog.db diff --git a/diskuring/diskuring.c b/diskuring/diskuring.c index 5914653..b4ad9be 100644 --- a/diskuring/diskuring.c +++ b/diskuring/diskuring.c @@ -3,7 +3,8 @@ #include #include -static destroy_queue_t g_destroy_queue = {NULL, PTHREAD_MUTEX_INITIALIZER}; +static destroy_queue_t g_destroy_queue = {ATOMIC_VAR_INIT(NULL)}; +static destroy_queue_t g_submit_queue = {ATOMIC_VAR_INIT(NULL)}; static long long push_to_queue = 0; static long long push_to_sqe = 0; @@ -13,8 +14,6 @@ static long long release_cnt = 0; void task_init(task_t *t) { push_to_queue ++; - pthread_mutex_init(&t->m, NULL); - pthread_cond_init(&t->cv, NULL); t->done = 0; t->res = 0; t->next = NULL; @@ -22,27 +21,18 @@ void task_init(task_t *t) void task_finish(task_t *t, int res) { - pthread_mutex_lock(&t->m); t->res = res; t->done = 1; - pthread_cond_broadcast(&t->cv); - pthread_mutex_unlock(&t->m); } int task_wait(task_t *t) { - pthread_mutex_lock(&t->m); - while (!t->done) - pthread_cond_wait(&t->cv, &t->m); - int r = t->res; - pthread_mutex_unlock(&t->m); - return r; + } void task_destroy(task_t *t) { - pthread_mutex_destroy(&t->m); - pthread_cond_destroy(&t->cv); + if (t->iovs) { for (int i = 0; i < t->iovcnt; i++) { if (t->iovs[i].iov_base) { @@ -55,49 +45,71 @@ void task_destroy(task_t *t) kvs_free(t); } -static void queue_push(iouring_ctx_t *ctx, task_t *t) +static void submit_queue_push(iouring_ctx_t *ctx, task_t *t) { - pthread_mutex_lock(&ctx->q_m); - if (ctx->q_tail) - ctx->q_tail->next = t; - else - ctx->q_head = t; - ctx->q_tail = t; - pthread_cond_signal(&ctx->q_cv); - pthread_mutex_unlock(&ctx->q_m); + task_t *old_head; + do { + old_head = atomic_load_explicit(&g_submit_queue.head, memory_order_relaxed); + t->next = old_head; + } while (!atomic_compare_exchange_weak_explicit( + &g_submit_queue.head, &old_head, t, + memory_order_release, + memory_order_relaxed)); + + /* 若之前队列为空,通知 worker */ + if (old_head == NULL) { + uint64_t val = 1; + write(ctx->event_fd, &val, sizeof(val)); + } } -static task_t *queue_pop(iouring_ctx_t *ctx) +static task_t *submit_steal_all(iouring_ctx_t *ctx) { - pthread_mutex_lock(&ctx->q_m); - task_t *t = ctx->q_head; - if (t) { - ctx->q_head = t->next; - if (!ctx->q_head) { - ctx->q_tail = NULL; - } - t->next = NULL; - } - pthread_mutex_unlock(&ctx->q_m); - return t; + return atomic_exchange_explicit(&g_submit_queue.head, NULL, + memory_order_acquire); } -static void queue_push_front(iouring_ctx_t *ctx, task_t *t) +static void submit_queue_putback(iouring_ctx_t *ctx, task_t *head) { - pthread_mutex_lock(&ctx->q_m); - t->next = ctx->q_head; - ctx->q_head = t; - if (!ctx->q_tail) { - ctx->q_tail = t; + while (head) { + task_t *nxt = head->next; + submit_queue_push(ctx, head); + head = nxt; } - pthread_mutex_unlock(&ctx->q_m); } +static int submit_queue_empty(iouring_ctx_t *ctx) +{ + return atomic_load_explicit(&g_submit_queue.head, + memory_order_acquire) == NULL; +} + +static void destroy_queue_push(task_t *t) +{ + task_t *old_head; + do { + old_head = atomic_load_explicit(&g_destroy_queue.head, memory_order_relaxed); + t->next = old_head; + } while (!atomic_compare_exchange_strong_explicit( + &g_destroy_queue.head, + &old_head, + t, + memory_order_release, + memory_order_relaxed)); +} + +static task_t *destroy_queue_steal_all(void) +{ + return atomic_exchange_explicit(&g_destroy_queue.head, NULL, memory_order_acquire); +} + +/* =============================================================================================== */ + extern void sync_wakeup(); static void *worker_main(void *arg) { iouring_ctx_t *ctx = (iouring_ctx_t *)arg; - const int BATCH_SIZE = 256; // 每次最多准备这么多,防止一次占满 SQ + const int BATCH_SIZE = 512; // 每次最多准备这么多,防止一次占满 SQ while (!ctx->stop) { @@ -115,6 +127,9 @@ static void *worker_main(void *arg) unsigned head; io_uring_for_each_cqe(&ctx->ring, head, cqe) { + if (cqe->user_data == 0) { + continue; + } task_t *done = (task_t *)(uintptr_t)cqe->user_data; atomic_fetch_sub(&ctx->in_flight, 1); task_finish(done, cqe->res); @@ -123,10 +138,7 @@ static void *worker_main(void *arg) fprintf(stderr, "write fail: fd=%d res=%d, offset=%ld\n", done->fd, cqe->res, done->off); } - pthread_mutex_lock(&g_destroy_queue.lock); - done->next = g_destroy_queue.head; - g_destroy_queue.head = done; - pthread_mutex_unlock(&g_destroy_queue.lock); + destroy_queue_push(done); get_from_cqe++; cq_count++; @@ -145,19 +157,25 @@ static void *worker_main(void *arg) // ========== 2. 批量准备 SQE ========== int batch_count = 0; - while (true) { - int current_in_flight = atomic_load(&ctx->in_flight); - if (current_in_flight >= ctx->max_in_flight) { + task_t *pending = submit_steal_all(ctx); + while (pending) { + if (atomic_load(&ctx->in_flight) >= ctx->max_in_flight) { + submit_queue_putback(ctx, pending); + pending = NULL; break; // 满了,停止取任务 } - task_t *t = queue_pop(ctx); - if (!t) break; + struct io_uring_sqe *sqe = io_uring_get_sqe(&ctx->ring); if (!sqe) { - queue_push_front(ctx, t); + submit_queue_putback(ctx, pending); + pending = NULL; break; } + task_t *t = pending; + pending = pending->next; + t->next = NULL; + io_uring_prep_writev(sqe, t->fd, t->iovs, t->iovcnt, t->off); sqe->user_data = (uint64_t)(uintptr_t)t; batch_count++; @@ -168,24 +186,32 @@ static void *worker_main(void *arg) int submitted = io_uring_submit(&ctx->ring); push_to_sqe += submitted; atomic_fetch_add(&ctx->in_flight, submitted); - continue; } // ========== 4. 没事做就等待 ========== - if (batch_count == 0) { - int inflight = atomic_load(&ctx->in_flight); - if (inflight > 0) { - // 有任务在飞,等一个CQE - continue; - } else { - // 真没事了,等新任务 - pthread_mutex_lock(&ctx->q_m); - while (ctx->q_head == NULL && !ctx->stop) { - pthread_cond_wait(&ctx->q_cv, &ctx->q_m); + int inflight = atomic_load(&ctx->in_flight); + if (inflight > 0) { + io_uring_submit_and_wait(&ctx->ring, 1); + // 有任务在飞,等一个CQE + continue; + } else { + // 真没事了,等新任务 + if (submit_queue_empty(ctx)) { + struct io_uring_sqe *sqe = io_uring_get_sqe(&ctx->ring); + if (sqe) { + uint64_t buf; + io_uring_prep_read(sqe, ctx->event_fd, &buf, sizeof(buf), 0); + sqe->user_data = 0; // Special for event + io_uring_submit_and_wait(&ctx->ring, 1); + // After wait, consume the cqe + struct io_uring_cqe *cqe; + io_uring_peek_cqe(&ctx->ring, &cqe); + if (cqe && cqe->user_data == 0) { + io_uring_cq_advance(&ctx->ring, 1); + } } - pthread_mutex_unlock(&ctx->q_m); } } } @@ -201,10 +227,7 @@ static void *worker_main(void *arg) atomic_fetch_sub(&ctx->in_flight, 1); task_finish(done, cqe->res); - pthread_mutex_lock(&g_destroy_queue.lock); - done->next = g_destroy_queue.head; - g_destroy_queue.head = done; - pthread_mutex_unlock(&g_destroy_queue.lock); + destroy_queue_push(done); get_from_cqe++; final_cq++; @@ -229,16 +252,21 @@ static void *worker_main(void *arg) int iouring_init(iouring_ctx_t *ctx, unsigned entries) { memset(ctx, 0, sizeof(*ctx)); - pthread_mutex_init(&ctx->q_m, NULL); - pthread_cond_init(&ctx->q_cv, NULL); ctx->stop = 0; + atomic_init(&g_submit_queue.head, NULL); + atomic_init(&g_destroy_queue.head, NULL); + + + ctx->event_fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); + if (ctx->event_fd < 0) { + // Handle error + return -errno; + } + struct io_uring_params params; memset(¶ms, 0, sizeof(params)); - // params.flags |= IORING_SETUP_CQSIZE; - // params.cq_entries = 256 * 1024; - // params.sq_entries = 128 * 1024; int ret = io_uring_queue_init_params(entries, &ctx->ring, ¶ms); if (ret < 0) { fprintf(stderr, "io_uring_queue_init_params failed: %d (%s)\n", @@ -263,16 +291,15 @@ int iouring_init(iouring_ctx_t *ctx, unsigned entries) void iouring_shutdown(iouring_ctx_t *ctx) { - pthread_mutex_lock(&ctx->q_m); ctx->stop = 1; - pthread_cond_broadcast(&ctx->q_cv); - pthread_mutex_unlock(&ctx->q_m); + uint64_t val = 1; + write(ctx->event_fd, &val, sizeof(val)); + pthread_join(ctx->th, NULL); io_uring_queue_exit(&ctx->ring); - pthread_mutex_destroy(&ctx->q_m); - pthread_cond_destroy(&ctx->q_cv); + close(ctx->event_fd); } task_t* submit_write(iouring_ctx_t *ctx, int fd, void **bufs, size_t *lens, int count, off_t off){ @@ -304,37 +331,35 @@ task_t* submit_write(iouring_ctx_t *ctx, int fd, void **bufs, size_t *lens, int memcpy(buf, bufs[i], len); t->iovs[i].iov_base = buf; t->iovs[i].iov_len = len; + + // t->iovs[i].iov_base = bufs[i]; + // t->iovs[i].iov_len = lens[i]; + } t->iovcnt = count; - queue_push(ctx, t); + submit_queue_push(ctx, t); return t; } int uring_task_complete(iouring_ctx_t *ctx){ - pthread_mutex_lock(&ctx->q_m); - int notask = ctx->q_head == NULL; - pthread_mutex_unlock(&ctx->q_m); - int noflight = atomic_load(&ctx->in_flight); - // printf("%d\n", noflight); - return (noflight == 0) && notask; + return submit_queue_empty(ctx) && atomic_load(&ctx->in_flight) == 0; } // 主线程定期调用此函数清理 void cleanup_finished_iouring_tasks(iouring_ctx_t *ctx) { - pthread_mutex_lock(&g_destroy_queue.lock); - task_t *list = g_destroy_queue.head; - g_destroy_queue.head = NULL; - pthread_mutex_unlock(&g_destroy_queue.lock); + task_t *list = destroy_queue_steal_all(); int cnt = 0; - while (list) { - cnt ++; - task_t *next = list->next; - task_destroy(list); // 在主线程执行销毁 - list = next; + task_t *cur = list; + while (cur) { + cnt++; + task_t *next = cur->next; + task_destroy(cur); + cur = next; } + release_cnt += cnt; // printf("push:%lld, sqe:%lld, cqe:%lld, rls:%lld\n", push_to_queue, push_to_sqe, get_from_cqe, release_cnt); } \ No newline at end of file diff --git a/diskuring/diskuring.h b/diskuring/diskuring.h index 4f985d2..f5b5942 100644 --- a/diskuring/diskuring.h +++ b/diskuring/diskuring.h @@ -9,7 +9,7 @@ #include #include #include - +#include typedef enum { TASK_READ, TASK_WRITE } task_op_t; @@ -24,30 +24,28 @@ typedef struct task { struct iovec *iovs; // iovec 数组 int iovcnt; // iovec 数量 - pthread_mutex_t m; - pthread_cond_t cv; - struct task *next; } task_t; +typedef struct { + _Atomic(task_t *) head; +} task_stack_t; + +typedef struct { + _Atomic(task_t *) head; +} destroy_queue_t; + typedef struct { struct io_uring ring; pthread_t th; - pthread_mutex_t q_m; - pthread_cond_t q_cv; - task_t *q_head, *q_tail; + int event_fd; int stop; - atomic_int in_flight; + _Atomic int in_flight; int max_in_flight; } iouring_ctx_t; -typedef struct { - task_t *head; - pthread_mutex_t lock; -} destroy_queue_t; - void task_init(task_t *t); void task_finish(task_t *t, int res); diff --git a/dump/kvs_dump.h b/dump/kvs_dump.h index bab43b3..58fffe8 100644 --- a/dump/kvs_dump.h +++ b/dump/kvs_dump.h @@ -10,8 +10,8 @@ extern char global_rbtree_file[256]; extern char global_hash_file[256]; int kvs_create_snapshot(iouring_ctx_t *uring, const char* array_file, const char* rbtree_file, const char* hash_file); -int kvs_create_snapshot_async(const char *ip, int port); - +int kvs_create_snapshot_async_1(iouring_ctx_t *uring, const char* array_file, const char* rbtree_file, const char* hash_file); +int kvs_create_snapshot_async_2(const char *ip, int port); extern int global_oplog_fd; diff --git a/dump/kvs_snapshot.c b/dump/kvs_snapshot.c index 17d8564..8930225 100644 --- a/dump/kvs_snapshot.c +++ b/dump/kvs_snapshot.c @@ -40,6 +40,24 @@ int kvs_create_snapshot(iouring_ctx_t *uring, const char* array_file, const char return ret; } +int kvs_create_snapshot_async_1(iouring_ctx_t *uring, const char* array_file, const char* rbtree_file, const char* hash_file){ + pid_t pid = fork(); + if (pid == -1) { perror("fork"); return -1; } + + if (pid == 0) { + int ret = kvs_create_snapshot(uring, array_file, rbtree_file, hash_file); + if (ret != 0) { + fprintf(stderr, "snapshot creation failed\n"); + _exit(1); + } + + _exit(0); + } else { + + return 0; + } +} + static int send_file_to_ipport(const char *ip, int port, const char *filename) { int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("socket"); return -1; } @@ -86,7 +104,7 @@ static int send_file_to_ipport(const char *ip, int port, const char *filename) { return 0; } -int kvs_create_snapshot_async(const char *ip, int port){ +int kvs_create_snapshot_async_2(const char *ip, int port){ pid_t pid = fork(); if (pid == -1) { perror("fork"); return -1; } diff --git a/ebpf/c/Makefile b/ebpf/c/Makefile index 5580d5d..3dab8ea 100644 --- a/ebpf/c/Makefile +++ b/ebpf/c/Makefile @@ -1,12 +1,12 @@ # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) OUTPUT := .output CLANG ?= clang -LIBBPF_SRC := $(abspath ../../libbpf/src) -BPFTOOL_SRC := $(abspath ../../bpftool/src) +LIBBPF_SRC := $(abspath ../../libbpf-bootstrap/libbpf/src) +BPFTOOL_SRC := $(abspath ../../libbpf-bootstrap/bpftool/src) LIBBPF_OBJ := $(abspath $(OUTPUT)/libbpf.a) BPFTOOL_OUTPUT ?= $(abspath $(OUTPUT)/bpftool) BPFTOOL ?= $(BPFTOOL_OUTPUT)/bootstrap/bpftool -LIBBLAZESYM_SRC := $(abspath ../../blazesym/) +LIBBLAZESYM_SRC := $(abspath ../../libbpf-bootstrap/blazesym/) LIBBLAZESYM_INC := $(abspath $(LIBBLAZESYM_SRC)/capi/include) LIBBLAZESYM_OBJ := $(abspath $(OUTPUT)/libblazesym_c.a) ARCH ?= $(shell uname -m | sed 's/x86_64/x86/' \ @@ -16,11 +16,11 @@ ARCH ?= $(shell uname -m | sed 's/x86_64/x86/' \ | sed 's/mips.*/mips/' \ | sed 's/riscv64/riscv/' \ | sed 's/loongarch64/loongarch/') -VMLINUX := ../../vmlinux.h/include/$(ARCH)/vmlinux.h +VMLINUX := ../../libbpf-bootstrap/vmlinux.h/include/$(ARCH)/vmlinux.h # Use our own libbpf API headers and Linux UAPI headers distributed with # libbpf to avoid dependency on system-wide headers, which could be missing or # outdated -INCLUDES := -I$(OUTPUT) -I../../libbpf/include/uapi -I$(dir $(VMLINUX)) -I$(LIBBLAZESYM_INC) +INCLUDES := -I$(OUTPUT) -I../../libbpf-bootstrap/libbpf/include/uapi -I$(dir $(VMLINUX)) -I$(LIBBLAZESYM_INC) CFLAGS := -g -Wall ALL_LDFLAGS := $(LDFLAGS) $(EXTRA_LDFLAGS) diff --git a/img/主从同步.png b/img/主从同步.png new file mode 100755 index 0000000000000000000000000000000000000000..903b927857c465315d25e5cebd51a7b5a61c73f1 GIT binary patch literal 146225 zcma%j1yq!4*Y+@uGIT24-HmiND2O0kD$+=IGl0|((m8~Hh=4Q*h@=9N(n!OAh%`g< zKj`ti=e*yy*8i=UHS2+S;*P!VdtcYS_C#vkSH{64#{_{uII1cN+91%)D-h@gAM_UR zA6?zg!yphoNL4{r#|!O8HhMFa;$hDqzKR?xGo1|7+*Bs%4iv4h1B>7$B-SlBen_?x zoUgAcb6ikD7f$H9v*(nhk0sgPIwJf-_>VLWBg^U1^ zzV-R@HS$tNdRp-Rd}Cp(>-~LCOX#QLdH!O<+qZw;H~1%nnBjl9h<+#wlHYx`R+eYW z^uK+L&xCOQt6})TcW7ys1F^E6>OT1EIZ;GIkN$l7r~TKx2!6&e^zC@wUP#CPuTK8% z>YvXhBCVJ|U6gr96u(le+Ipn3x|Fie>L$qKj zDys1Whu3N+&%R_>RvRi9F8ZZt_uTqsC|36CelnO~oV%C%a6w|g{=vUnHCt)X!Kq?olv&Fa|DTSCBl{aqF%KPYri(b|*GAQ} zpK!i{4~(I5T*}Xv6?4%gi2g_SjFb2VWf`eS@boxv2JLcYWE0y}o#`ai>ln(=RWX&9 zeSEHTTzxYXWh68%WI8wqbaWJfTb zI(=$%MTU>*sE_E;Q+^;!m-27A{c;^g%2(E8+2SbdUOX_Y#wvq}ThPsaKaQmJID)pi^88 z8|gO68{q3^@jApdd}O3%#!`iKtZ=Xex4!0Jm+7eNqK3Z4; zKJM)1JB_o}GC?Z8O*$L5XtfcM`W-(py$h!8Kt{vX>lyRQEfjokx$dbV!A*VtC9`Tz zj42P`FqEgZ_|rF`KK2K#Hl02uF;}xII&-2(Ni=I2v~-eDWg7pL+f3u$lS*O!BWi9R zT*gHMn6x*raB#=s;c(nRfh3myOg29EI4e#2^#iz*n6nrhA%AsAh2od*Qr>mU8Z+{O zTB?e~9VQw|wl#z^R@;x486?tU+qz#^vdteIdDvAH9Jq0k3&#@X?Cx4gS->0sBO4YO zPl(T9vVgfi9q*Yid51E}6YM&&pg0RdarW&rKa+$yTVw-YAJXnR2^~awQ7`I`>1(6Z z!dxG|)=*izO$8_DrTC6V)4));7_itRyIX7_%Mj*1;GB}f;LVDq(a{*pAYlE!steeV5;0j?=s!Xz!q9-a#Xc!-ecJnP+EQ$2UvdZhn6@57so3LgBkGgcx2hMV+ zF!m+_wlLrzGQqj{Py0vKOt%ZM7zi%Ob9U1AO@IaiAfZ%%5#e90eN+`JVEdedc?^*Mw!ei-D+{Zw< z0wd3C0(`6)ggcTkvT0EI;G&2uvE(jgv+T;MwaAyH-C5O3M0&-e#PRNu-xti#Cmf75 ze$+kvnih>*Y8d@Fuy}H}YD(ach#@)tGUk^{Dt$PyFpB6y+Rm^)PP^=E{NylYh_t^q z(U)txT|i!YHdDiIO@FRpUvPD>*Oe)$U~X_?ebZK%8OCY&;2z>BezL#NOTBm@=75hc+d$9)Xi>nH?wh38o}>2*p=Bz zp1OE*u=J0(rqHntb$qxJlST(#T_q!T^O;vbIPyjr!Ov?G0KBFFFqRo$by4V8Z1C1^ z=hkfZ{_+yG`A#*(BQhTA4g58syk_WT^Hf=E|5+2iE@Z0Z8jX zJK>)VI9LK-i%d}lqDF@=b|YjjPAcXG_AQ5lB_CGQtE9VFHa0A6=pQFFZ$#Z9C|l<( z2v!gWrwAfm^vN~q-uiQoUz_*~LYY*YEi^YhF|;A~VLR0bxH_qS>Jivx17t2u8KLqJ zOZEA=rneh=@E$xLu7{iail5C>kN;oy_#}yz6x%^aMfObumHbBT<^mWitql_c zhau(yIx_|@0oz;BfmiW|r2gK`ZxhL+c6o=vLD-k1m+#UGZoCxTb;DfXg;nF9^6ZW! zm6BgQm}Fy3&X*hGEZHOc6LMH%qfzNX6cB!3)^pZf(&}AfMRF-d?Fwb41PFd zOH#EUTPypo>s(|&mNbeql4MWr;tF_uKqA(4x#-=CzqDCHr}6r?G(*w3btU8ZfuOGB z7TPM^pU6t<2Dk=iDDYi@0AUbs1YLikQ|&aSF5hKA!*Z8GsM7waYZT*OgE3?e(V+n% zDO>!u^;kr|0654}Xzz|NV@9N9BEJWIXn`TkFYg_wr$?mgM*5e=_HJLSs; z4?Df;;T$}s5w+D?dN6Bw92YcP`mex>5nm<`j|%iQUphkgMtESj`0~~~ySrusgqR6@ zLXQ}U`V)SAO#(UG5JMAzhF{@#Pf=f_AG^GIyeu7taMGUZle{_oCz#!nmtg`T&Jx_< zA+)xdyR64!pM^3TJ8`Z=a4f3}*^~eEbir^?0mvzFG1H<34?2p`_9944O($}9zWt-+ zam5O;wb?%`D)lN#-prAIHkZnkC>*aGwP#}t1Z$iKD{ z;lY%o-unWBZ3H-xw(syn%}2(pvp{%53ik34@gaabY;r+2r5I>B@=O`i=+D zHo{~Qcvj8TIR048kOV}B2x!B1z!c(4@1e_xV*0zQJ-9HoE{T7GeWexuFMuKA1D>37 zCd~KewHlx-5C|G>-*DAWtKwXij*{5N;p%U{8b6Qd#_yoO567$4;ApeRz24Y?D3=-D zt&dM``S%9*J8ZP*2siluMq+TSE3a=D4E9)wK&*_lVNgY7LB;0L3dGX;B;y8zO4mUb zy!&0wk=Pq6F|h^q1jE$isiRxItfrtY{0pHDE(gb(QL z@)%oslVwg>UM#1_cw>8oKrt zXOrn^=E1M;tf-%48F|g`l_9Ew_fy$#FcAhb)8gku8=r;2P)7JaiGYwtsiS#i1EP36 zxXkeTQ?#sDzvj-pvoUO&4XI`n&L2ZA)Z1&I=~F&VUp`q~nKNVipgw1h6WQE}axSmg zY;O$PXsioyYN5M^HvP2}k^$OjB0uA3htFUlKyOv@&f>i4&=*_g*Ol?y<-G!EW4Se7 z^+fO;F8b+Yq#lv{w))^^f(4U-_xKpw9SG0Lm5Wb6d#d?*Rk4&sFDYiS-55d`9L+?UCfK>%N96zeav-%&B18TM>Io2IG|z`O2}8 z14S8`li`g@eTt%ru6jVDG^$Nf{!%+9l8NH#wVy0rjy8N&-jF(8C+4Y643V-X`hxW7 zI>VEO8_CQj#;j(Bba6H9d>jP5CUzU^>pS*xqA%Oa{co-R;R61FW&T%iVcjsUfwfB0 ztNq1t+K%sDQw>Tc!)@2MOh4_Mm1b6dud=JHJJB}-odd;(s#AafyUHNrPpooRWY*pA z)IB*5$GpcxtBYBi*n7Aum$G6EBxNG?tY1P9+x8vuHALC15Cvm{SBYgN@!HQ?usItt1&iLH2qp`nxsA{cs_A9IVM59T1@@5 zIOF6Q8_#z=l_6J54Eqtx?PP73U1~SoFDUjmZu7$3$-(*sPXB>1Fd~+#3OWCU>KMux z%2L~#w5Ds2!a3zbhuW;IL$!LWtq%&aAqHi2*}3Ll+ozz4Uo z0PrDzmg4boPsy630sJDLRs-#k)yE^miSTa^fF%?`Z7~_E2?P{Yypi$Y^|+(f@a)q-G>{e6^oh-{jKj z)i8q5CfP5B5=4pMX;GJYzj@iq0e%2(PMs!U^)McFbJ>M2HLdv|o2-24@(Ri*>E>Nv z{K*WY38N~4_gHB({y=)JD4dYJ@PEQ#v34;eeE$xNSDRHs0tisAU;l={zm{oj9+=oI zRlrvM!qYHbBr_C=3mDz7UEYvShFwClPh!r`JUNuv3*}-ayq`0b3h&lhneQD0RP=~# z--FAO>96TFFnb|8-p#o$7`yz;ms^f?{gQZwo@Wot??PMvA*|AMz%xy3!kuh{kxM>6 zRlPU^=*1t>ueX%*e=O$guKll`&A+Qc-1MNHiUR{CCs9Tt@I!wD#Xr{Wo zC5~2a`We+FI&paFUhX84frkPS#$j3Xe)5N1j|t_^k6NDXbdo2|l(4NVyz)>VX=yhJ zf)W^Lo2J|*2XFnJ?8Ksfr#Qi4(=Te^$HP)YkB+*}$cGyLBB4at+5y+vJ+?!`w;rcX z^9tK<3mYo4e+B&z>MWz5WCxi@lx9c z-F}qtjl^Xw0{Bg*CH7t&@n~Sr%K`z@&X1>^GK-XG(0}f=r~@KkO#n^2bsgX(9co)O zxn1sH+ROB8!tHb8Jb^y#HO&GrQq*%?LB}O0F!>r8>r;*?hbF!WfAw( z{gbFFA(5l{rwPcVxe~!#BY@GCFdh1e7BJiQH5f&Nx{LCW-0XN~@kJ$4f})kxS8^)v zp_2r;B^0NIHcNSc2br{)dWQb7?L{Ru%%67>LZ{KeE_e&zB3>?eu|R^+e^Cgk&V@LC z^9+B1@_!L(@NVZg=T`k&|2^BPi`JBzP@7PECCso$EAfAJ31DunU%(Xo9bu@tI?9ok z@6*mo1Dk40c%vTk{jBw36-%ncfT(#RScl{%{}=eol7xG!Im-d7r1r@4Pc0^c$Vxa9 zfI1c=+s-1+;J%TYDVz0K%{6h*7c#=o9jPU%F3B(NiK((t#M?DW$?;ZLKDSqwOw#Kp znaHko+YnVY0z5)gw-GxMj1S05bY6S2wg6YwVK@cuBbF9bRVglZ3b6?ZRMbIX)Ll8A zx?13a@~Dx~Cg@5gXq)w?gPXRSY0S=HYY$(PYyy8}f2KKT(Ey{*CnwLYyfou$Tqxv!;u zL91>Qq9R6}MoeA83Q4$U2w(?me()@k^++c=f~CC)xT{)_CoPY6xe42mfuuTnDpcow zkZ;ymwkL5otJoP-FUPfsGNe3q^j?!>RdSTegnS$_Ye!?vD~qL_(_3nkw*s|KBA;ey=m&1ue_#j>(m zBK+Imv7z_nFxKwUbWo;iPv!7)S&8555sx@0JJP#PJ*^B;pf!Uu%!ekzLUJoc-qgHR z2tv{1ydqs~7n)H!yGbQ;D+ov3s5^XENyIdnI=NL&B?F<|zcQkMv zZZ(J6yl@_{^)_DR0@G`mfhD4c-?zIGWGeWpBMKsAoWae}UMyj#2fJUV*}?Qf*bpz4 zVJR7;;&&4k_@FBb=P0Fg?QU*=@6M7%y$+a{*b`JVEgK1RDI)~bt&_twdnJLMk*{5< zFiHRomu5S<=V_};N5HBQ#oaeGX@Sp;rJ>tT_Y3ixw+TIR8~EQ z;;O@AuxN4k zRbD3RtYT4hIJZ)9&`j5@k~~3B@~AKY#Lqf(zb*UnGV`!DgRP}G|1U} z_@Qc3g+4wIEV$0cD-eb~80<6lV%cJ$6v_AI!QEaXI}_>-X-gajBC^XoI)dOe<{*pP z@)52BLwyq<>bp)fnX8q0lc$K;2A>A8TLUs|&uD)e%UHbkB54;&f4%)O4ida5GN zc(3T&$N@e9b%yqwFX+`5`k_Jy=}5Hp;DOmaLq%PV9!N-Vq@7^TnAR|W)p}{${Nr2( z%h%gEH|aDO+MLP95DSy5(7`^#S`s;L>$^^-&{4KNZF(?$JRew>8+Xv6b>pMJyPUx# zc0KtiAu_b-^5vem=T(NU#Q?lwgR$di`xW~RWv0uX>C>r~g~FFFEr8%e^F+6%W&A`> zM`Vi=FoB0)*}RGk*`!8jl5CJt5%C#+n}2ik9r}1raC0uNZ2{KAd+u0~XH4!Z-elwq z$tw@7&9JYs@R~VS1$AB|E-4~JF(5{=b2-spyoGf*pgRL^+#~MxBmi*h=}V9p&o*<; z%|mVr5#ek+o4IIUSaeHNK5|-Xy-R4XP6AGaK#acQ(*#}L6S0})Yo}%U!r?x7%H!> z%Tdtpq8WsuN{$c3CuXD{YJyY}34YJ+d^eh?X?c!^Cv4haBfu?0rRMkg?ALO-k6*I7 z|H_;7HS-~}%#D{%Mkb%Kv84tb5e1(UE?mGM{teVZ7Gljll*M;?f^@m|m^8`tvd|^2 zFw_B)H;k5PKzZM(dGtkhrVKzPI(;aU@$YZ;fNn7oeTpWsvt14xqqfIr_VVtlOav)C z_?vzL4scksqO9)KVj8J`dv9nNvqmJQUf?`t+%qH>AcDObi?f>YLZ*+f7fmb1U$n7W5ruX$K!SB)87{+<69>UnD#n9B)baMQY$Ll zmTj_EO0TfIG{G$bs2Le%43+f36&srqxv)*`?UIxa#1KRm#yZ*1{!J|&f79-(oWU^d z7c#dnbl$2++_04#DX|UHRl28+Fx_r0x>*thBqwz=5J^X>?90-4by4cCu>V6QwZUW{ zd&&sn)h5GQyG|YXF?L_BeVfk45=;N2df?eMkOOyGngK@kD;(rw!{D&y_M%uc z0JvLP2#R4-_vKBpS8OXGPfr1)XiWh2VXpZU`AF!R0HKY59KhNAMvlYvxME!@X`}=E z7Qxohzb+poxv7A#ffjmGe?FcU zEPj8&u{Y~FIQ4>n;Rjs&r}brTY54V=4G}_gR0%$j1Pk`Mx7sFEj6?;t4x|EHPAxsc zO7`t1_W2r!8%`0^D>vY51KJ@cVBo*h)d^Q~4r!6~(mQ=-N=5h=q&OLxGrm8vla?#Z{WCmTWaSKWJqeZyo- z{ni$uSgWfs$)@)uvDB=JB!AnHtupQA_N%YmSJQOg6RW}W=3PpJejDm$doZ}<(PU@B zt%D}jVbqI*e`Kcb$&!z2y=m-Nn6A9)$waC9>_`?OTQdd+$SCT;m0c01Mg*_zG-RqC1Z`o{~w`}_l zT9fqWNX|S1a{C^4UtOo{gLNPWj`zb?3ECC>*{zuu~KNl$#01CVSjJKhFr&!TDv) z!R+{2cd#&cb#HdRt{FAvoK^ooKhzBQdNR_CtV_(eP0oc+V}Osd4Omw)rS{ohB(F>d zl=q9!eC^_yFb)R{H;W8xll_?A;+zN3Z*{8(b3_0we2Jg&ZmE9tWnAES2d2Z5Pdu2u zgN+=D9Qg4hnjBfH=i_`^>OvocbUs%rEd*Yj<$g&Q=xMz?te{W}81F5=qSa!#IA>(k#ZL}X`~Kh)KV2^n3gKd~BFpp`&&5jTy|h~KdrkVcnd8v!tYto* zMoOVXr9&UZ2`{xVwvVq;O~22e zxA>y!_?~o64hCMjzF&&sXm;&Kr}5Lu4lVo?=Ft|-)4Cpak7BW58D9PQCCkia#fQ1Z zySU;tI9aaYbD9)%u{=Rg2*i)0zQ$MDMriW_~0nQ*W>}*42Z8 zfwcLNe%}v@E8nsZLO}*JVn1Skw9Z1$kr!HHO(wC9G=&a^g5bC94tXcTvKJs`#ml_6+xQNXy@U)mA@|$lkn!Klv^(QteiL=7G!_Mj-NJ z#Ui1A9EQwjFEE_!FnZ$gx#(wfA1sH08%YVBClxKW@li5S3KCe_j1PfK7eIox?FU9O zrSKk{kqJDTM75$M&)P{^&D|JzT922y_d!(D%K2XI>5(D+o>P`2()q%zE&6EymV1N6 z-OzS4ZO1cDZQ$H>`{JDq17+a(?$O)l{(Uc89rJSTr#sDA%o|icn;KE)*~0rM4sU4S z9r4U`sN1#4m)1Djm~98z-`aUJ_VP>20Q$7buwU(56XcHFx6(IjWAr-+0gTj zdPDEMAm!mWY0Bs@Z^Wa`<6ZzI09ziS6>@sCWyd-pfxNmzeeexE?u;bb0#@ESd0f%X z6te*D_vd?kTh+N2WqFJr4o1|oZ)V+np0mr{z8{WzLkv@^6HojH@B8i6GtSQ(tdv%O z3mkM`-V>hc3^?wfnU=?sT#0k;=j)klMCRDB&U5y}0NJT;ZZC(SZ8BrtJM3jUm-!N_ zDmD9gn2HbX{Owo3fg;r0{^$BSYoc6csVb=D>YL~MA@z}wW8T!GI$H3L)Dh z$-}P?O(S|DtpRn)oG1%rE`#OGvh|j z9VSdXv-OV1eALmj`uWDikx(BX*Z;PD&S&mngeN5XM!<3i4fzePLxEm%*&$6)x7{uh z3R8KF-H!Oj&3?eD!Lq$2Ux2n9IHG3wGHC8Wtn{`RdaN|M0SB4`#x(JO=)BDjVorQ#O5 zxehs=o@jk0a&uToWD!PmE~pSgeuO?02Ys3(1BAUweHD)_gFxLrK2ON1VDFgO4|GP( zRC%lgbKI$CRp(x=+_j(NeO~ri=1>O$INKd&eDYK`&N|-kCcSKnmT252>n(xYlNb|^ zDNB!qVD#x5coOE)#~<;|m5^DB7_g;S`oR4!ch3gE#3%v=rAedbEvvU(#Zo%f!9^$w z1vD~VowP>z59g~q6b$$;qA^Fm^R~cU2jW~hCOe&skXb135|y$Kw%Py_Mb4yBhFp8) z?9tKD*KQ8r?z=jy(p|`08R}ed2M31}^a}E?F*00ke$#|CY}Q7Fw_{|5-V|PQ#XttG z1Op8l<+a-*pnTOs8&@p81rodYvk^(1YoDz9=$-j_PbSUtD+R=8;_fHsXMUW>}V|0p`4 zIAO&;JXLL_T>Ybt+95(@!aWd~*b$?)o{~Usm>~m1Ac7?ivu`r>QliD&7Q8PSVIftm zhH0>M&dwHn^jnu_%^6&HA4GhX%>nVXv2?HC_Hkuv(o^t?bhPB=@OueUne&5cw9iGAa$s*l?) z^LcAywsSXGKxqyTXN~ZVFGD)lA1mSRJ0eI>}4hrY$2fU*e+cx7Scv z%j1(w<8&&ARgIj;WXQ=;uiXB|(+X!GykEca@twzhLvfyIQ{fxr~J=%dvFw~<-N4r(zl850+V(c z^5MgQgOaG4-18L{DGG@TKK>IK3~4tlGoOuD-;Nf%NE3Nk-Di%SAu}rS({Tlu+}4%6 z71m$v(0Kx59`k%SugY6^Y4#DjChr+!=e*Qlt+zoLyfn{{-_N{o61fXrh7RsFn3pZ2 z-)FJ%qZn-7DZ{&seWKfk#m|YG?^yQ=lNkMVp;iWJMhY`+3Jpw zJ)aQ}++IAJyS;wywYN;U!oVQiFXG(GR!lk%dZNRJE0^%)wchT4@?hLHJ~k?h(!-jh z(#)_Wrw+{lGL5;YzuX%rWpwZ8}U7QC!qOYgOQTha8L-Hd%~Wxk`O4K%{f8~dge;>pJj))DZj~EiB2ilv4%hooyb##y zF29vaEoFFVw%NGXYY7u5D=j#kUZ(g-5$4yWFz>Ui`mJ^>o|-ShGyUS9?5jRA3%jhS zXolGYc%gVP(;6>qXtF%#yt}{3te?hQS{go>CU7HFkX*BQI5aGy6eHNZGvFrcMm!{C zUf4FODgEVHps^Sk^n6`edhem@$nMbG+?-`nrYqJVkZs{{KCrlYEN9@H)MdH`Z2D=2 zNyE3?{1j&HcI^$)TWqU_4r97l1@nAAs3DlA*5u+)-B{(Y2 zaWxTP`wN^U6Q=Q7M(L&T9WZo+UY!vW7v0%I(fRsGkmgSfIG{Hx;eZaomXAAU*tz^_@Ado zpew1MxieCwrNQ?ub_xMC47_tmnGr{QEND}>d){+8wge@2(AL(FCQDfY)94z*q429t zBF#x)jdYwW89H&7&m*IB{l6NFW-mJ<5BOCMKvefymsYgbb| zl<4TXMd)I{zKatooqbD#=4-JgP3|4>JM*|tlE@uk%W=|kPUP)xq-*f>AKxgT3O3ag zVRx3yZFYk0p&uV3fmOI>I0brwAG;_$Z6ljicnKjtbj)`MInY_wAieTsf4bzMD4YdS zyBoIfv8#$@@gw=xNnt%9LvP80g7b2(Mk$}@*e+I!11&8vN(KfRG{dG|ze-rIdgQ%!v6uQmaGF43zpqz8 zd^Ije4Il(*!F=HL<6+i=nuQv9zqC8V#WXSd5i|h}yHvc`wK2D3ezu-DW{NmJet@ns zXX1vx^Oj7Bs1k1rR78|d#p}AJadi(39?3`jew_RLkHR&CRXmS(mOI5It~1w1y(vwA_H5cUqCe8~*w9(ocHeLd|YF^peOdSL_Oe zrr#2g$&on(EfzzH@s2QWl{o;3us$ZHx^Y($-Qt`pUi?OCGBOND;^9OV9#eTter)$m zYG(YRD6`#Fj(jN5wD(CJ+5znjEOOu&cVyMc-6_MSjwdzXeKCZFK$_9nMgas>2@~4X zCtKB>Liqe2F5s@{^Q^!-W`52e5>TH%TwOeWzYv0T{=zh7-@YxA2C1DD0F^$Pd=fy+ z=Wv74$7yBCbKd`gb#7>m)+BK#yp8U~5!yDT7??zx z7r+{{Q{4D@r-N{@e%K5P%jg#a5~JWcxff4VC3^DTb^??#zKZ2Ji-nS67oc?m5+mA$ z89!ia&0GENnvDhrV??pVC8S4+>ec|)UMC%n67L8D>k+5= zZ833HtV2uNJZ+So4?)RIG_o~2*;>&(?1x3e78ylK60W-lSI5PDq6(!LQVoILeY^r` z>NMEsO0nQQMVVxRU=4gNioDBWG|3F_6VW}N&9_z}Z99(UmjN;RJk2{Hiw=Q6^i4Ku zmB_t5z3L`0I@RWeu)w6-i^lSiq#Bt&?!Mb(zvNXzaGVn4iZyQuv~IE(XL&Z?YtFm* zOpZBkmM+UfmD=p;bRu>`c_UuseeQ^^k~yIAO}5mEXn6>T&R-4f50&WxiRohbzo-X* z?o0={dIG|qdTg4-*k^-Dl5V$R$OO96qW6n39itq}KZ|8!k>-+qNpS;VYdxsQ;?hN)%Og@`KHtSlTVEYq(PTRLDMD)Q^ck63$6AQ^F>ebQ0hqK+D^ zEtL)^YmN1T~8ccalk^$TDBBl0_3T*J40bon@(3MffrQj0Zx+nrPf=_H{l0+^(OBv0RUQYzQ zZ&R4I;7J{~k>*FY_noJ+mQ{SXY+_>j$y!VLA=@=zE|7TRnqmTg$n*YPGh54JnaP>w zA55I?68lJD8uQAMQIxPmNlx5x=VHR@l~)dlF?*%;aQYc7ZGo9Umg1N!gq>w*eEg9& zb1!g6ix9TExuZ6FJ3Cz%JbD0mA|mD{K@qd=wfNz1+^Ac{+|74{ATA<6!e7&3n%FP( zjlNjS+1PlGGku1D75puLb-Hk~8)Emg%u*sThz*Fq-b0!cj^`B^-j+ZrEZzuk3K!q+ z8BGgK+;)LJnj(u3BLLsWvbjoKoeWZRZ+Y*pO#z&yRsV$d=G*$y!wy{W{xxH2^KlD98O@q z@~i`QE+4(fVds2*@N9Znp(E>RlE`_<;(IngSIi8(Y8k#tdU&5t46_?f zwTV*S50xLvy*yyK#<^TEf-2Q!5?`*#2D4j$IP7ZRcFz7hz`NPFovfx(xE?K2cB;&K zFa+5?TgC&G=)M*T*!-Rv5k?cd){=r_p140syYfALE2M$Sm@FhtF(U3?LR>x1n$j zE-IjiTW@dmB$Y|ykvpEF<5wO#J=7gY<_BE9Zf(UL-|u|KHLX-qC`mYIwzvmHqk2J4%e9@Q!r_Lp@Pu%$rs-*ZVqe9*riE8K=egDNccwV)!N%UTV`M( z2nP*@2yP@P{iTQgE{jOmepS=s_-Hv$a-aeZXt1>u!G8V4QB!Oj1SRajH9TXb)H>-v z3hZfkTaC?V*|4c(dhjqJWQX#RvVG{nX61E07h^CaCRwY?#skPEXSBdea{*3iAK$uR zmnO+;cYP59BNAG}jTT<1n(+MFe(qR?tI4xkdv-lK@O4D-dk(Chfvczl_ou!nfBUNR zsmEKJO%X8;*<0$&0DuHbD4utJhEVj__ed9DkN<>&_A`*|%GI^Wun3XoOqRm+&{=Xo_=+LmQh%=FBeVpn5chf`VnPmYgw74la z{s#9R89>=Rg@Z7Olx|~oUkn1FnE^wP6<(BNVr|uH3BVd_nS$>3zQ;7Fty9+iDM`?_ zP>giaOsWBbf=tjLNDQQ1OOZhlW;!)G3wzxvLWzp(ihRTbUoEo0a-~rNsD}6j1{4sMnJ1d5mXNH?Q9`j-D*fs17d$boep= zo+xa7nf9?rzp2c=54KA~>h%Z>Hz@FQG&g1=P~XbvwxYqca|D4<9=zuTg3eb~2z~Yt zC?lavV{xcjuRlGtVwB87!nU@UCz#30msV^xoM<^+Niu_vSydDeLKr*tYX)s4{Yj7{ z4T!B0=>6?2Lwh|T@fX)5-6zIir}^cq#LwVv%w)1Em9_EF%N9>g#igc9G*H?MaT zM7Ot>Or{g)4#eyYC6cG5mL$$Od8uFgFlbAc$dVE8GEeaA=xiV9<%6V#3BJ;=Ewo~Y zYgvX}%4Tw^#Dp`Mfi($Wt1(0il3~L%c_q!oL-!1xCutQaQHe+Qtcv#Ury+RaV`MXWGbqZ5=6pv46G@Qgvrt8NEl6SnQd$*YLQ9qd@{wM8VJMx33cmAA$=fVr$4*|jPe6r>UEX$n zuXVscHw=l|CfoPZk^I`5%WQ#wkd3xE6-ZF+2hFM5d}hmruEc>*cTZUcWNU8k>4f$J z%7mU9#3f#rqtPF+a>B{7LH5gem`*S^K*pR!nj#C01Ilaz^=Qd~LI4*H*b|^a>soJ0 z8o|o*w^VpU)M`NJKC66ASL11wx>&BN^MfLLkxiTh=_`BXK?LYr7FraL#9|6wJb6#> z^<$t~}ZM)q`dsM<8lh3>@vt{0^4IV3KB z@>lUJP=_}$%M$7;4TXVN~y)k7Ab!#4r#tow|6>cLlzA&H#sqW z6%_xiNdBwB*R8x6zF+9~a!KSC;cABuzSnhuU;#4RH3_KY4J(h+x--`(C;{DG`n;1p1V@fN!&HcyDTk$)?lLL4A0KY?ysBpNY(eI51L8ZFciq| zIOcQ3FmNZnGcm|eM{hro;Ok4D!7Wbt&t_RZU8yqLerUf{5U>wf*Mv3z2M;b)+{bX{~Sf^3?F z42W)HQ_^Q|k~7bV_T)dzay2=!2z7;rk?0pCYY%d{vnpbm6nBav{UozCTY+L{(d$W< z6G>tScus(eGH+-tu=uGrQYoF)P~nY7fJ9sS!7|!?#j1XvvXbCFwEc65K9DKG&`mO@ z9ayT$IP8}<9kvVG47=9N7di>T-5Cq5{x3D|65LzfEYd%x)+Ni_39N;|#>=e7tQnk* zW+er#1J)o~*eGVNEk1FK+RZ_j+AAGJo*XGwZJU%`e-4}{kitvO|EPKi2QZML*X6s+ zRL{$3PKSeWA}Sn)Y7bQCTJ$;XG8{1N@CT3`XPMi4kvPM zm3mFG%NHuiVPE0(8e0Jo4jIa8@MwJIE$w`vGy^GnvZL70YLKr?*W3Zv2BJD%84%Qd zo$D0mrM@4Av`YXN}d zp1VRjaW^-br{cD5qawl>4B(aWjcK0L96%Gd#u7vr#~&<*pJY3(o?Q97HieZf8MF63 zQ%It5xk6l@z%S?C6=WTGa0@8)0-6SBcmZo%lu)9O*lqAitNHZ{0@{D_^OkAE+C zFM;15_-~PU%?|?;<%zxwM5@X&LpE%7(TG>Zna0b;Gr-8_TkI9I#MdM5=k29DJ?BYM zCF*>GNv{>(2IMF$^-SE8zohXMn3FsFjuK0_(a1GqLlPwZQ*EDLX`uo*Kd^G=06$0o zRihUJzB574cMo>Y;3VtsF^D_YC&B zlQT9WHWRxUV((!`aAJ%Sw7EyX?7oO1u_%;Y3|ZjAaNm@e$7pa+a>SaiXfO;khRDxl zZ#LoFQW2alJ4lrU(s;!s+I0s4I2 zL}HKfO;P7^q|>M3B+Ht9n~B9or3)vdsp~BS;~gy>iN3w_##jOE7q@uE8_@}R`w8iC zwz9B(8j0;Sc-;A6`X+GoPZ1)QyiE61is)FWbtB}O5Ty`tLYM?z9145yt+-SV2VAFd zfQ$_zLJo)-1qFi5wPHN9Ep!ytiCq>{poG&ta!PJql68un<&9Z+tNf!XW4@`=SRZA^5e)ExJ^^1;j7pgh!r^d1#U_ z12Lq&TNF@VlIW(ysqZ|%b!>95odpbTW4VR4SUoHJ6mq8wJ+eo!qmolsgyxl6hF$0; ztIGN5QiehUb0}b(eCp*}$L^YG4$c_fmDoK`KeyaT*3v8=tfc-nAo`!WN}af%n5zdV zh9todusU~Rp#y-|>vp>-X0ko!Y+f?os{%+Srb3;hKg7^A{(6Joh9C2h!a@?-y;riE z%1gM!>!pN~OGg2ga>O7XjzO9EQpKH1RUo{?tNnL!7Gw4()m4C|M}D+0=tb1Xjka3@n3ot7m!|; zTj2%)jKo0QoR1xaxJQ{JKo=L`205l(gHB+khgKktttZcX7sE(?952VAvKQ}}n&|Q{ z1@lU(8yOk(N&+E2fIj%;Wp4gOMFbZy1HT=kq`B?8-C_kuj_MXoQitj5p1uPlF`MEb zQmN?O<*yGlYvFKs%F{fxU-HX+0H-G< zv0L}427Z_Sk|bn);rLoyH6VTEw{0@9kiWje2X+J5*N#1^1EgX`9|A67aDxCm-J{LM z`bVPs%YLu>7LNsHFZ^pF1=-NZt^~Xu1DMml5qOdmy zI#mC*W<(9hRwL8JK>S|$I*ixIpEWed<8L13_p$ zOBa4V*9>MO&ejD3RW0ITVpWE5MeHOr_l#UVGdUcN>D6D@#8f_}f2Nlzagsg+iA#DL? zTUHE8F+;>MOnVPq2&@&sq?ejv8;sJmGgDT%-=d&8R=*gTU`!12l}13^hLb02YT+?$ z0;rMkhqNIs3JXioJaw-h7EkNynOI&O_ejThD8ZvD^4DTO|BtONkB0hf{~u#wl%2}H zmnE`qlQoQzHBw0;2_b~C?^_H?$iAd#mq?L)8A8TVL}e{&LiTlj*IS>@^E}^ke&;y- z(dlI7{l4$}x~|uD50W9Fq||XE$3II6mc-5K)ISrz2bMsR2&a^FFd~f#oaP;sF*n;U ze4Nh{MF6!<(7xeF&g=8|suRpFb_IjNA^RjNJ71QMb8P;;RpT_Y(fgJ_KhzOt@qv|M z|1NO#`oyq0c|GA{x_ld(M0-Ugxx_og>@f1NA4^bF7NyB-JcvE|8vY3>k~=hhWPs;P z`CFNg>VVCSX{V*4<~td@?Bt%Drxg#ieVR9U8UE~SZz4Lw>p)Sy$RU*+-P5VrdKirK zrl>ezJ=Umdm-{Zc-V-)DdQ5#5wgRX`k!+r0J|GS@@%x#4R=;Ojey-g7BOb2~4}28+MGbRr%?(Bl z)^`rADMSFYa?J=8#XmrI?DxBTiJGlHczcv-RPRm;F7)r(Gsm`rI(3c5)X(p|#M^H- zh<+5Bx@~&wXTbI!LPR2|K6w~7Ea|U%jKwK(P>~S|a_7XemlaRXPO?{ffgoX1Y5PhB ziW^nw4T3SJuRw45Q`aVmn(A|-`qf;;vap|GQKmbcb$);(dGaLQMP*UEh}NLTO3Cx{ zru5ty;>r}?Up$4iUdvJTC{SE_4sxIIOxaP$uKMihbtXbPcLW2bz!oVAJj2*>!Xp0= z;mUx+!2U-2cVEQPp}=I(zyV@E+(aMM9WOiyM^R^*bDCXBF}%_tzs1}iGh;Pb4l*_M zmJXh%d2Up}iZQjuxKY|(5wsV7@bUP%B{)=PRjf({b7fB-NfXRP@4|)$u){w|pXj}} zieUFwpJ-nIY4@NsfNFma5CenY^_}(WY&WBXv%Twie10(H3l4+&Kt2xRG;KOG-|GI+ zeOtbgPb^qC*w)5~J5XlF&+HJ{EP$G@ktsetZ5goq`TdWC(?;KrBRxTN<=lOjz3>G_BRC%2~Q}d>X@^f`DCiTX??blURRV91`bS_1U z+=Eh4oT7uyZqd&brBT^g8zUw)fW-BI1jt+!{MXzr8PS#y(C;R){ru0V3m8kFJCr$9 zykAY()_fMQsPVtDRTS>Ef3<18!Jrgm#5dc#`t9z&K}30pr;a)z$HBs#xs(%3X@@lu zRC<(W;Vdib);qGxlue^r{(k(!n4{%Cm~AU~@sw2?)6aI;>b&#qL!0w*2rQkJWOj8; zF{>UH>vUsWEHxd+l{}U-Jz1|w5T*;w1z7_GXpTuL!d?kSnZEo6yg0F)i9nSf5W*tb z!TwxUEcnT=+n1ITch3+G3v|A9y)?$*{6I`T;LMdRQj2Ky`glehJ&LxmOJG4tSK+&- zDWX4>w!`$0wR;>?c`=j8yfRm!7yh>{{uul8BuT({KU$^6rxy`56J@iQP*+qyCp4Cp z>qE}F%WHBH&V>U^)?XGL-08h`5+!JqI;VbZYa-R@#ha9_JpGB_N;1E|F10Z(RO^Ql zBqLLNQPoQNEvYR5!cB>Pu>c6!nw{7Rg3hGMg=WsVDko!cOR>T{jGAGk$3n4!3m52% zmf0z^KOh0^Pu?0J~Pq&hA+$a^1Ti?CT zs*4+Oqt=ygi9NxZ=~;tzwya&I?Td*n_s^0C4fm7tw4w&yxsPqFYRJv0YYX}C)kZ5U z9aL%mV{Dadg5(Ym$q)y|Hb+0cWQMzXVxrtnqsOAA zWa};6@(KP9Ej8yJnM?nzyZRHJpv3eHlW!wk@U9TKd1qnRbc+aym0PgX|B zzb%x*QMCS^I4zM=nbN&helF@{^)f1F+MM-vd%~QafV1n%foBSFLa#t`f31Uz&kmMJ zkQfU}8?Kl&zlve_g-AUa+G32>SxAZ0xE`(Cc3ZyV3kiiLO1v0vQJ~;iH8OiZ#QtG^ zZ-?&G89k@~r)i{qlJXPO2BwxtJ2nHb1D=EUjc7(!Vo$ny@81xi3MOkY;{kdC>v&d| zL|te!*Z>A1={T>tR<9Qn+_$XNA`2MHqFc`a&L3Rfn>I%V5q~js9wc)(M$~5+1SuTO z4lk>_4QtHw6edVNO-&QzFf-$Z=f@|A0gJ3t^{eTeH^|7ta9w56_(v=^h>d;S*+<({ zu7f7=M)8k<6nAKCrS^0pvL653*^~>{i~p^dRyXz|hAA_&X@P#R%iHh0q-EX}x}Kfk zb)#>F$7Zjjuktdlvm}EzrFP3qcGUO++I!~`sJDqHhQ0bOz8$V(GpHPkKQ;h`a$iB$ z-;Agbe`f6Bb`Omd96>O5c;1h(R;;gv2Z+qjBhF%TRzbgxql`Yx9GYQN{UF+MZcmja zDmR^YOdm{}Be&lGqbC&HM~1%H6^hQ~`>OfbWalr}-_H`(k1cfai~l=fh)@(PjQCl5 zZy%d@kWulxZL?+{J(#vqFyL4Fl!cm&82&t$S(1F#s{ei-sJftELtk)tlg!Ih%i06| zXMUHDex)`>>`?GXj>%yX3=faaJCbqC=bpzmcjsNkOa?S9=5Q7kiU!rce0UM+*lg3m zOG}ZLarE^H5{oB;=}{^{>rxCoC~5g<9O{qH(KFYWP6*UmlD!?feK^1KtZq#xzk-8} zbBN-0L65H$_Hm|waR8db>q0<*&qt;Px}LyMxq5%{g74ByA1ML*DuJB3nd5oT(ygvp z+T!o5BS%RwzCLm6jy`8a(}4?YrrXAnDm(cz-eg;QUl_*pH!$Hs$;@sY>>fKF24^6m zrAQJc7^k{pcG=$Bwp*8AVt)Z&;CPBkCv3}8o1Y5ReirV#ypi+Dpv|8pms);+!fpCV z;q;-bIn$@zvBAQKA?*udJ?YC=uUk~-cnfVFM?U6(JIuo3%#+{WzvV3#5e^s6=1zXX zPBXkrGGp*OZ2M{MN&G2^H%ZcSvO`$E`8sMpy_d64u9F!%s|AdO(d`SQ(k_4M#JTtL z7h5Lty4t*dvqXJ&xM!ds{mbxI*rMnHGt=WFIG5DW73wC@qrV0&sT^CNIj|)Td4U|K|?_5d^UX)9E&$F0PK8k`Z8;&B? z)o&#iW*4>?29<3DNjD?^T$|3(5DIF$Dk+T*;z%H9XQ~HP=RAGdKl6O!wgz-U>j^z1 z`eVPW{mIV?!3qWWUUH0ocIIxU><*yd4+Oazo6EkX;$(A+4?&ZP7B>na_tE41m+p5_ zfI#qFj(li9zT=yt=%38PUz5{U3N3x(`i;O2=PsEpOJ`r{2J%h1xnve2LXVY%r79EZu)=WZn_o+O-!WwY9ilHOS;Y*;jsrI!|fepfnsB z7a3>c*KQ)c@>4yHwA&gVX)3{h63H?}%PT5JVfYzk@ z;^-viYU?C4M;%`d3V%9E13Cp}8mWnz%AHf;DIq^(cKSAignp1HS1V>-$`<(7)@Iy! z*ev4fn#Ob7l)Mxz_LgSy4boveq2zm8XuQYO9o?rk!zEJc-}v^uS5Dnv<4kk@W8~dEA&eSJVvY!MY!lCy7e9gjOE0t+7=E!;=Tq0j-00eCft~x zQ`yTf0P{ne+Sa_5?PK$aNE!1$t_3Ii>Hjf}#9Op5m_poMJsGARw5ykvcfY$}bN68gGNuJ#&^C{f8>@aK< zoLRN1KG<7r=a>W-`Qf~GGB71;=l-xh1GOqgXndntBz(04w&BIDE~MihVjLd%cq;cn zd#OhOjkWeeO6y-=iiw^^1gwgyw^QBQ~)<4 zV$t=9Dl85iuVsA~J}M5$RbTp)DR1^dJ9hztcskZZIpzl%!-BwCC-Kbq*Vo?Os|+gh z!Bb%gcKqOMM$k4lwEj?J7o6RFlI7xvEo)@EXjS9GWT{qout!Jg&FP4PR?&^uu0^oF1ofSF zIq!KTcaHZT;7C@6)@R@5!qM80d}AI&GUK2IjdR~ZrW&A?c-L9P?Wq-FE%`{h|gPG>|iBW(1CuvVfKT=1CMHwTDeRA#C2{Du!0y8ewojtfJ6u zls5b3MIY2Fg>A+;L?=>uabaDcQ~c2^l(2$L$CP_de6OUVtjI`9VAZl66ff79-STt*}HaS=?rR|7UzB-ZjSIq!iEJ2HZa*u^oT)GG2CX)ty` z!u{p**-PBtfh!Zajq0;Gc}&E;0h!pFO>5265%1PLL)?cWf0B99sn--?M?U>|*3qXl zC;&Tuy7@?|V}2@CvQO@JROi_yyq&`n|y1b&WGG>ZwGI?u4-6hMbxA@>C|E|3T>tQy$q@ByosdKy} z@|#|ZwzYFY+^D8*r;L9`<;SV0e2QX=N~YSZ)<;hz4aIsg&S~6V+WN~@aEB6Y)7q)`>*SaGvhO!9sCzNag(2`I zoIMR(pR9D+nJESe5y*KetmZuKi0b`ELSsRseo>ukXgv}18NS-E`}DzJ!161S!l3~E zx)_m}90AWm88ct-&9N}+d8$c{e~V`dh zyT!6FnfxLdqUaT1F$q#s)=dAO%xh>6Jei+^U=x954!M|TVp$IjgF@FNeYHlUpxq^D zLEWS9ib;sKNYE%t&NqCuPQ230~$s*FUShJPyV6@vq{8d1P5SWdN zwR5L2Zaf#kZ1*g?NQN~;iQ?lruW;h*D+0M+O&!3}Bm)?r#`k=Ko{EqViS+#ncCD;l zs3ZfkV=)?DG%csfDpVG;E(Gcgy}#wU2}A;Ikxa^oK)oXH&nz-c_7&wIFmHkSe}D61 zY6_q2zOWml=G0@iUOsvw3Rfb?k~RuDyR;!F0&3rw22wbRZJP&R(tk=HEcWM&xq$Ie z3WH74qsp^=4rs*nqd4T>lVWjAwC0oB5I%>AyXG^E(nPy*-!z*Uh|DA@k}WY$^@kCU z?!(r8v13e=LVQJJL)Nr&>^RTIUY?$;60rob&VoZe_D2rV%u94EspnA+1KBmZFmi{S z{)|fC&PBBT=DqLTPp-rXBG*WU$JW(p(L%~zm{^~DjYd3fgh008iZ#L?^m}>mWf0U>|Becj-0F3_hII3Cw zp;($IY}Mna&2FTf7m84@yA9;xc^oH=oe%UHaoJzP4Puy)O&MH3IUGz${|a#h{2f9> z*z<2PhQwf{eloC22}C{8##AsHpZJHQL|Svmp@zKapr6)eIK^2L4vL9P>17hoAI1am zdf%m>$ScwY#84i&jr|l1PX(F7xqT<|%D|!j71)92^uZi%=FmDsYoz|sjq%|>{$D*U z_>zTk#daA&dMp%`W&o?gSoVuPAds2ZEcS<(^LN4u`Dz_T=L|s#h)*yM<&ex$M=SLboQy83axg{TL`m)M1ZK&g8UklJ37C!L8G9fXE0Lm+`vLnHCt!S-B2x}2wKA){*9AId zVau(yi#Uk_jyu3^;-j5QfjLf%8bTp@<6j-e=1TuTr#Or`xKHn{7d}0W8Kf}$=Le+R zJv#teaylkLa9fg&b<_T{pEAjIcb&c&0$n-Lk@fXm;&cn+ooJ1ZSm^&cU#PBpX{cUn zlH8yV7Bww+OqqMNG1>hYGqz_(yrf;`MU2MsUt>7(M1X@$3x-gnlNg7dRfxuT7?1=A zSnfIvX`ozngy0$2A`N;dt-|wBg&Fm!5FSJmkAfN5G9qZ;`rTTYIp7U3w~Ef-+l?hZUn|9tq)qpg&4muY%*f4=s_n;rOf{e+kc&x6w%QXO7& zXf79VBPDRx2K1g%Wa248kWHVMNy(!ZLdy#?;!yOsNj~+xKcPPXn(5<{8Pp4n;4b+W z#zvou%V}u2lsd;rIj%@e@i=St=AX-MfM+wNK@JO`x-u_JE~~o^s=T4#2vq1k2xH{Z z^Q6-li^Tu`>5x*%Y&La`sg^~zXU8n|>a+2D-~Xct(71)>Nbb+Nefg=8_55(%3K&z) zs@wiN$AXL(7$+}TyJ`g?>9e3<=Eg4l{{B_ri!~)DG?sDT){#T!(sz1A7aXcBRsXZ) zIsga~()j=V(U`@G*fULr)B>&g(lN-_`r*f9rdmxi_!z`jgMMvmmt05fxDuii7t4~1 zpWS2%dCD}bRr~Du>lp69wGpIA%D{O&Mbt*u){h7>IqV0}^{w8;Go%4#2kqaURAVNQ za-(aw0@#eV(2&$r^7HujS7+!J2FpfLD(2b+CZnT=X7^ zP;l%P8Vi%OvwNJSox6wT;cT9(rrgsTA21wm8<LNJO&U(#Yd`YFfF+%D6S$)h{Dl2y>RkwX zJ0l3`buci=XL@}&K_pjL_i7^g-%biC@Bw{=vCbI)=`tYu&A3q?Z>68f=U}uR$l%)&fwT;#Ij{Lv>D0JdL z5pWBY`Ip-?c`Gxifuxpk#Ah^@6v+H{?P`o;A8R0Ip|K*Apaz;HnC%~bmG;UV#Q-AY z{QFzE4$FtNORNbjs~`TCJP-)|(JjhNBU zi28f@{hvQWbO159)cByh*Nl_tvFxspfIirLjMxvMWA^r$?vYO@b324JquNwLpwe?+ zO_O{M{PF)B)eLB{M_7M-4Ue55+T*e5%+}L6$ZINSHXi>h2$=2iIWb`-2Ol(aJa@F{ zivzbe`u~>qlo~M%pB|t0j?+Mn$o>~+GlKuXsoKrJF^;xnhvD$tQAKJ zatbNFH6>DGZm`OL$IkJDXxu-0`BPRf{g+V;G6?CneH~>p+lK1{#urz=pFJFA@b~tOkP61fA2q3H*{r?UWZUoCZvz$V z3Zg3;7y1HA4=wACOyzRXXM1-MO?Y@8^>Tv%!+?dMrR&s-dukOYj8IqUl{=h4JbI!b z1oETKRws+(3m6U!R6^Jp^YcxJTMYKv^6p6v=~0TgLb!+6D^aiq99naJWili`ltFjJ z2e;nn9{kViIU|@$ut=$`4WZn=wbpCt@iE0NH>NKk7?1jt;Pps1aiQjPsQfpCbSvlJ z(L5ik;R25l5gc)<2UfZiHyv1MR^RDD5}p>vKR%lcNq!GGGAIwXmmpPOm&l6wOu(24 z|64DRW}}x+%5&0qb6l~;@z}3dT25x?-Z-;C>*t8kXqdn6Z_Q3Vg*UI^PPusVyzLkB zU#Z(ZI_;jG6MXG|SN3i70feiat?RmcvJ_#T`gt5WxjF2!vH@k@A($9Kf#d= zOi~qebcbe(8ez457Ot&YgIuvQ(1Rd4D_V?M6fJWuof{k~U)C1JT;MUR80wVr-vkW+ zP_TXex20d^+e>pc0-@{3=~BAuSzUo_uy)ST9N%ft%@Ky6$*+gN@;}r4+uE}huCAE9 zEu1Yiz>`-pjKpg32IR=Sk;}q1^Y}d{F%(vD-}=@S2-$cW9TAd2>uo#lfL9FJ-W(#A zT>`MO`lIIimV@T%5;_`IfsqB zUz_mrh}KAxMR-*uu7QgggQi4fdyzLH-$Xjgh7)EEHXVGl4&uJ|XM2Ugg@y855^8t(Lic(K!XbV^F&L$edQh$Fsj;UL$8wjd??d|Ig$SIBv>>I$07 ziz3)^d9+Jc^CNWR+Rs#J+vjkAUi@PWat`LlTekqPiOe%;@IPYzgiAZu0^@DO_qo+* z{cp==b{{oVwMkU09{IX=avGr}yQ)*+vN_ewUnM)%rLiD6Iu2WR(O+pR_txFWL-`3c zo8RXKKyf*y%Y`JB36H(M%r+fhT}MLFKEXA8@m1MmPFXuVZwJKCJ-CGs?9gsKldXe1 zOEs~$knH>xohHfgB+F(6ul-?emhrsU4(>QiDeMSfw-)BU1K-5vUd~Ym2y$AUae7`H>DuQej;DKGy)hl>!JNgEGzO^* zf2LLj{dVVh!c-(gZ#oh>?XSqj8>@u`LS?>j5=I5fYz4rM)1zQkptVOx7Z<=U6unS# zr1Foa3{umh%4OhOgXk7t9d?~H=p|Qr(yYHUZ$>1XVc=AFe&Nl0=hT66zR`cf&4`mJ z)I8p`f%9R!;?eTzdMHWWB(KUvkab+mFBx8~Ay%eu8{k3eY>~@DTjPpEtQDT#HkyIx)h(s2E=cJ=`h`I- z+%co^!S)I3>Syp9wn>2O$9H_p%L;Aa#s|jhP*Y@~^mX*!k0SG@AfwXt9JK&v5Ov89 zu!$Q42^fc?`e;nM51f2pz|N0Itqrv)WAn6PLF*$m`vK@W2X6@i3^()9)@!y6`wGyd z7z)BK%P{|hP$rbeczZE46`LI*;|kPhK~qFIy$O_#fs{$;4esyJAwl3DCURwX%FK_5 zmyK10jT%Pv;bxwXsSoJv=9B$A#vP8}LHqEl{;L`5 zE8yWsy@`z~q@-7>b;v+&L&Q&LetG!_%L)zsqN#4xeEq(rM8^wwL}YrGCGRpQ@L4oW z&f6uQ`32O8Vu4!S@Q0{V3-7LbDLf5wp&33ys$2(rPqAQDlj-P0bo&_l5Cf%pwmfZ5 z(^o1Z-tKw#qbgfdOBMiG-kxUVK zkGnpcu`(Rk?HB)kSBo&z;5K%Ms=+qhVoaq`#JXCZ__oSHlJB|fPZ7r$8mm5kLDbj| zRH5ts2WjnbD|y`YleWE%gIB z#)2B7negjwR+p3Hz8-pUGT21GGU&zm&8^QCMDkWv$w1P%@)!*&Y_2CQyG-M}+8Vqd zSAVx?6BG#iYCkxR3P5(74p+iP?!3&yl)QHY3|8-G%uy{n5@f2*OflGHC?8}0Sl|5i zT^Ur(Tl?_c!x0UuRL1ppAwlaq5w6#2|8O#F_=|1Aa#Y=B(4%DYKQmjHL)k?1jL3XD zo!&ZQ^%)IF_xu!t8hXeEWj$aa_R>CGes4DTl`OVf?vNpMp3;G zVG;l&bfn;(c-P4-w%=Vt>tzRtW|@)annjG1EQ|{#&qH~D`KjW4y~4l%(h;corxL$C#3?NOBmzJ2v%IcrkeKEk{e|ZG{9-0 zsg@oqtj4q9J(`cnKaqcK%!{O3Vw}xRA1fWtaOsfO3HL1A1a#~#ZL1kHEH2EiX3hCG zS8seSI(kl4D~;%2Gz>*JHZNRIRlLt0`bhcx z$7l0p*qLI2xm7bKPzizb&8+$Ut201t%6kT8Mj$#1 z)Y+&xR+6Q!s_jDhs0N`Ut>=!#Y7kH{NMN0?hqt&_hQu*R(=S_-`&n8r2y;Z0ctgN=%+(Yhc+<$Vm-T*7#C-p~a z4^uvsw-IZr#CRNx`l)s(+Fm&A>9eP|0=AD%Wh<353r zIsT7G5Rlm_{^XIn-uTCqe1gJ{PsW7YqK#RALGg0?B8mE~@v9zlNm{SQu*mXNBnKB- zy#(p-1C*+~Bh$bXNk^%#=SQ=U-dv0qFr=;n1b_S1-tH8WDR6>VFSSBk?Py`nUiUZW zWG=@#zL?Y=M~atR464uF4eJYy8bQ>{z0%3d z$71;%vNYPMNkQWw_a=fOjgn%_O<~R%eo>ow0|uFgHkLo_>P|f@pf(?u&mu6jy^b)V?FrAVc=Cq z3%gKw1G8&Tc8@>puYH%+LPuI^Mc8pQYleI5az3)gw zF^B25KV3sb{y&fGytgjQyb&X<$7aJ#3dHSUlP2Ud<38yfdC~YAf1#;JJFxQ+bb3>T zN1Do`6|lS$hiEDetiQ@OZ<&Lp`$UH2)QuCth7V5{#ol^_?|C9e?oA5#`K)mw(Vj5g`y?UkbuFPM(jRdxd=ZrOqC1aEF*I2T7t4 zp5t2(c{?zke7Y_#daUZ=G|-b4n0I(kgy6^CGbu6s0iwdYl#u* zaqwJ2P{Ict66#dNW@l$3$EbW+7^_A^^DCOY2hUA!flj zL?TkitK#i8&D2n7gs3YJ#i-q+n;PY|934fq%Po)iQZUfv&FRZwEma~Q8L0T!xhbj**+z-8W6urz3y_?lDx$B!tQ>Hm# z(;@~&d@rNN&dUaFd25Z-`K3+xnFYes+fO5$IZT%>qMrkTmTk*%fTLt-AF`RH4Q1}; zc^OyUZt&yS6GczOx|rKixTk&cVB}IFwchE0?WC7)5J$_K=H_pcQa{7oR3sT7^w$qC zW!fUCBo|!S&O$;ETb6})8esAbYuESC5u15~z9sA(u9$ z|JAXDd3@tmNAWe!qi!|x+_X6Nv;nss14VgUbMJZk8#gXA|BD514>>$49$}e5t_YH+ zpq2a93{%d<>3}5TUHlu;z*AQkzu%rxceEWAse4Q8?Dy@S?aE@y)4%OLZhZxnRb9F- zUTGAI@Io$t(3Bw}`J3O|brabgJ4rB<$qhxW+!YP%+~fFO>Z3!<54}WpxLp?N_Ek@z zyqU#?aR6eQtC6r}LnTkvk;X8J>Rx)yB#J_T%rUrr;at8!`x^tla0O*q)nViN?hnhw z2QQb4d*S!Sb@95&A3g1Bk;a2IGQ?qIPB*s3=5ZlCEnLOHV=tqz=SOVrg{}h{WTPG;n}Ty{9?7P* z2GSm#r$0Tp37FiiR`5DrpY*wZDX_c?{|?--wD$ZEQ|4QF5JHpa{LXw7dqj{uh1w3P z52qoDEK8wN@7B}+C+Yt+c+Q~HF?_5RLNLwFM&*LJ@N?%nJ6%Fu4!v0GheQ|8%XSBx z4fmCuGi(FGs;4Co{Ga~k-#N}d$iLgRMOt!jAL(uzXJK6*(Ny*MbERQ3F7mZU2kA}Q z$8!#fYK#px#~{tmssTs3e}|Vh8?T;wmwoiXse(0|>quxFEcowR zrDk2TsxNMNdae-=whP3*1~yeHLa zem1tQU7~-JunJK_@i`Ohf&zG+@eBEiDGcYNSYvs_398@RgyK#Y^Ei#;m{%02ak%+$(>bdT--?&DJAn&q&)y&u>EhI-Fx> z(Xo=CM7ue(uf=$0vUk92m<8TwaQ3fDi5h>2x)>y%e&I<%#c zx8X2d6#zKwJZ&a+nGDwp{ zKVM4ICpwjSAX?esL)1tecE)@0p6ea3J+>M#Xs33`{%XU~?TcKLNn%rte)n!Tuf14H zg`~q8i0hhE($GD=&hYh3yBY=V?(0jf#AL>cp;J5@XVHHtztb$n$AKf@VzCzTb8D?D zr=#Zl#ZI6)`P5vHJ9P5h0|Si$>Wdi1Nd#uo;TJ{? za_te3ckK(aZp!%D&Q;7DZE#3fh>A_kQ*hn|O}C7KHcZJBAJpMcC++|j9y`)Rs&uvd zqR$&5%{Yemdk1~|%WNhKH9HJqo7GMAUv*TISA)oX{n)~hoqkeaZ;+WQWQb<@gzqQZ zU3zF@7#Z0`!BplbiuMuIC}gwB|HkQ`*`hq5ey#Bof#=GF`6!!ML)`Ct0Bq(0r}zEt z0^IHEB%xs~Vj*jjs;EcmseRo`ylqy3$>nbk8iM1|xR0r%tg##Z-8zT3sKeMLWeP&_ zv>5W)nuo{kdlPybTW)~)^Xn~ttZvGPB2`d$QW@sgJgRFx*In)%Iaot^AHf)OL?Y(iN z+81R5trNPImP*%8@RsF~q!>gS5=6;x+0T9j_?qR1Yqzzcqz$p&ZVyO3R9Nn-Ybq!CMMkUeU zFkdeyq3YT`63L&K;3D-f)_Wq8m!_6_6Yf7SN;*gg2b5@aTUUDR#Gq(l=4J2YyOK1i zva3KWUimC#*zK;Ni;i>SWnZ_^MlJq2O+CI1|}Y9Q-0Oe4wO2*(A^MBDrKuQ&h{B+9}9dai(m~Ukk7^*DSgw{ zf|jt{A>k`p9Jj4>RFJxQwQ6qNXY6ExwSU9294d9201ThJO=wWj!Wmm}{*KwTWM~He-e1fBN!eJ6#fXyy?5jCSP47XHoM|PkKhU%Q6 z?YXDs>nGl$@-#J~L^|l@ggTwr=x$51OknYX4{AE6P7a=|uO$CqABsF0z7tNbl^dg_M!{>@g-H9VA{wye=qvpYV>+D-!*%N2U(eErNcWU3Yk*kfJMl#o}#%nKg*J&jf?iv4Lm#XUS zZ~O{-cV@UGj>3~UlO9oVAk+=noOX3@{w;R8TDeSp$`hOvl&Vut zjx-E*xpW?4<8BFvIa|KoY}`wAP#g^^^3z`^S((?}zw3Id!s@l}{GEZQ8UzCcf8rj z-GLWuaXWY#iAeT9PeRmTWyu2fam9BzXMI4t#YOk()~6nR>_sZwDWOL2$mS*B z@9#BD*uZWl=>w^fc-Lzvgec+hD^lW{_L6>HW>1Tq7&D$q$}>_N@d0ikMs7K(I?JngExJ(uM?x{LGRxtIK#B3Q2}2dm8>$b z%P2LQV2G{^pI5@4v)`zP6F>IH;FA!Oh)FIb+^|k#RQZ<{X;I2Z-FkPMbUE7GMrs|N zd;#CRRvnXC-s~lrQZ}I@Uo?REf=l80WO}G?xQ0KW$@j{m=t#2g{+aJ#{n%d5II{9y zyi%F$kATs}+mXNH1)08{@BmJiV^zf_oN5VjhJV!@AwK59vv;o7o;aDA=yr}Ts9QkE zRB2+%EJ{g^@!)>^VK-+;UZUvqdGHk+gZ}_bcev4n$%b0qr7iCdonMQOjViVK@xI^V zg6bY=3EM8_q1T+${c_r|M5y1+t#PaOZM9A@gq8p`v{ezV`+#|_Z*_#@+2&jbI(Q68w&me1|?rCwn=H0wG%XWSK&=KB8nVgIyTz$K!A#Ngb zLE5y&BZjv!n9W_oHY_9KVoTIm?xgHbhQW`G_r(V^F&rmAh$!bjrL-^7+vQq0Jo^P2d%o$W}jhd1|2GT^f zK{8vfzjYl0{>7esbMnnNQ_RQ{-F3!nUg!G=?Wj?X@#gtsX%iH=d^u@C8PYN)GW)dV z*KG9U#yRb$bEMAjlML{((#;cRtN-lRQXhVQ+?z}A`MqpIia!(QW8;rEAMwRdZSZbS z>Jk_3AlJu{P8wQ-PaNr?k=|w}8D_T;a_b#FxObhL{M6KzX1`8B&1EgJ6@g=HF%>}j z@Ye=}8XEePt9PE9{PG}9!!ofGZym#nqXS_Ut)SX$+{4lZrGmlH!3QoN5>QS#JMk|T zAY>~fwUbmFOZKW~r z1J01HLpkw8D`J>U8#azKY47JwkY~NY(M;Rcq!q;(FRD2jqe^GJVy8|B^WKz|U~E;G z(i#h%?NA=WKkR~AMK-&`njz;hEYqgxVH2Z(B32r3Okm zRN-rchQuBe{#m;g(I>HJy?Bv6n+Cby1pXH4CVz8D@aCPdM8n;?Q-6Y$xnDAHVV^CI z7cT&J*yWxwpJZ-tAj!r|2$4hzjAIX9mfLUo8_AalY}L#TFzE+4F5t%a9=izo$l-`E ziUrWh$l=v_Kzmu;5F&@=*-?^o^UuyA`2R?2E#acZF7apQ5N)9TzGm7HI-}-%4Wleg81mR2!bC4`l zNjv`$_{!*`GO+m`#Syt4xkJY$DzE>}lwBf2JbEEfF0cmB6xxe9x7~4!@G(XMcfTgIMn|d-nEM8uCZbGdb?y0Nlig7IQzCF@UtZF%xAa^p< z{Rjt1^|+BN-Q`h7tSm>AS3ybbkz~<8#4*y~*0jU+eBR-ayS{B!se2x+zkOKVswduB zW6UnHOFY}$1_6#mk`ZHL7%xLWc8E#_L~@UvXA8hf@4ao$)Is6>XHn%CsI2HDx2&D@ z#VCn>1N@gHchb1wSbU`9>Y)nNIGgba-R8Qx!Cv^4 z*V+^I(k``iG4*I`W>xHxr8oI z!(U3!E2r1|BG~09wK2xn*iQ2!!63>uUr?G(BtEhIA#;{a#BAap#7=nln93wuOxtgf zU$kdzxJUTgJ`$Vsiw^9S&z5y=SW93wNH};<$>UcCBuY6f$wXj1W~lfHy3(7{Njdz- zUZwnmTE! zk0{c-t1nxR9cnKLi3}(XD1D(!<0i2{JF(>UlL`DjPVa>?6;rUXOfUPsB?hOtMwVcVc2ks09eWV{m}DI4jF+x`-D7xU0=NG{af z0R&;h9VO{v2A6}LLU`V&yN!*=Mbg^2$u#qoO{wu#VK&M33i%T3OltNWnc8xbn<}RL ziqdtVC%Wfn?@MjBhCYtj@o}BE8o3}_s_JHG$Dv%{_-k@finct0UPD;Qaj%PTb|t$6 zJ|pv$&;_s+Hcv5r-Lrw7IELN8lyFj4z*&$_DMrCs-n?lC<-yc0azvuhEu5&$? zuBVQ3-k>C&6DM{kB=EfoBaEXD$6*PoV$#yn7=Hq6w z0!EoOGR4FBH&*)H4+>$qdT!L^CYHyoMF*|D@g_d`A+VR%!ykM zgmO`_0%X#$b!&K$ba~{W>L>%7vp~{UCW16C* zq`o0t!z<|#QVgAUyidGgJrvP--{+v26yk~T@fuh)yf#8UH$Jy6CnnKPjSEBE6ZdP? zibz8X34hETkAKueowTnR#$LYfSjhYhb5Aqz5HUEb9bL%R5v1eX;5%wxSm((P;rCp0 zpQ2M5l2-%^^n%0Z{D(Q+_;~>T>-u!YUnK@6P0b?mKg_beOS&|YFFFzO*L0dmqK>zv z!(qp~7KHl#Hh&Cy5$o;E1e7Gl*oG!UTLju0=PAmAKF^CLa$E+sw%25gz^!bWMXI_A z$=5mqHq4{&rcQ|EhXzQ8f$qk{bmzn8bNf}f71k5uWOO6;tIufLY?GE%1Ad$zTRZt# zd%gG89;r=<8q>oUn$(H?7ntNQt53C;_!hF}Bz~6Pyv}ach9~PjPUVfuSs z;LOIk)!w(gVI?YUI!Ep@66J9>Ai`R!YvUm-;dfBSx#ppN#bHX3@*&R9L|UAfqxb8R z4-ei;TvWj5afW+-_@tld`yA9I$-#av8DwFK&3u-GicuOVwq#^Fz2gz;C8*|PNu`CC zc=+piZn&KMLD{k#ckw=!U^lk9AI*X1uB4%G$@99Vr!1w6lI6mM=q2thz(M{-|2}B% zhjp87NgWwBxiT$GEKM(B;yj6wSec3sbK$Jh=sV`)I<6dRM?f4< zHz6S!@ztlHBC&D~NMEuF&##`RKC8!U(Bu8ak<}(Rmh~ptqOMYVNsfPw6PTLnoF~K) zMgF2QIebv;R|yl0FwCvY?MXD6#p8~Qc6w%B(!;TIt>@rw`t0|&H5O0hNbA^Fx~BF9 zHlES^avP@_8AySXBa?iF%0A?L8^Hu4PnuKrr*V#@6fG)v%o?>2Yg?}5U13dhmCKiU zj2SB~)VxD;wJJm2rRvRlzgTZ9vE>Ng0w>cbX_b34j@3AQ27!?CZ>2id4Z69#&C2*i z^(D+y=T{3$Y|6EvCdYEn&H!ydc0klbY~GXHlKd>4^wcAcLcUK_Qfdv|=osD?b?=x` zrsRUn0?xj%g%O&{vp2-#^BwbiP!p1e*_&Go1yt_14w1ag<+#kz>MtD}sXlb(?Sp5u zA+Ko~vqQrA*O(nVx5n-cM zx^x+O0fnzCfrumX9vi-|>gs2+Y6TRO>NhS`R+!d3z-C^?MnjFW9piZS@uK{w%SoZR&swnjgvrz&0zgmG4p?m6nFQYmjL}HD-J$@m^ zBu;ut%RxYsVqUZuQIx*&VddoJ%9G;7!{J_QfOJkKHPt_{A#d(5VexV3B~{DLl%;cK z7~%KSN&EHaahcQzJFqLR_bp49o#`JKRvR7L?)KiD!z|dvW5<=(5I57gy5M(!JkGy= z@2+WS*{^fIY?|-y2D;u}ZPQ)HHmCh|h?CGO1^D!$z}tR!S^ zZ^uc7e+BAwaX&Y?Km}YpO|4w;gj0ASRpGPDyHDRAN6hUk?~J~ZZUMMcf-KgVwV#3Rmz^T}2f5H^9O2cp%h?DuvPUH(jdqz`A?+%s z#xA8m=RscjN@9zL4m zF$n^4Uk0$TjJ*D)ANz~W-tEU0T$nU#en=6&>$&fCXeyG7f}8oH+2wgQE_PzZ_(fLN zy2^i7Rq>eC}uoN>)p1XH4SZQT6No259mxzk1Gcn43_tt|2 zFl{Q?n-)-At+mOyw_cD!Nn%aC7mau)n(8#Wu}kyB`f)$Ad<-Qt4Z4obhicWo{k+Vx zQV#~Juu>{Fhzj^y|F`B-Wl=7G=SR%(jj zhlodxBe3h{hZ4fz?n}jcwqr+ZwGD@D%ry=LSB-^b(f;25UWLhnIw5uaCoyJ53OXFQc1XWc+|&39Qt7@*C9!; zP}5(d`TY(MZFU; zH@}~1IXUpEY*Zy;ExNt%D_#4?LxK}nP8CFjYT|8JzdsC`rnau^m(cV+j0_VG57gq) z3Fe+a_>B|q+Fls&W*k8r+%KbzPP8kMwCLR+llHs|!^B@-Hu#9!7BsoFZoXmu6g{yI zqw&W^&({f%&CpHedPGJEUVQlVF>`1#C?`$jzN_UcqBNY$bP4Ugp^$Ir?t}GpJkSB@ z(isP?=f>$vr+iF$v=tnDM}bjuehswCRtujp&;O7XT4~vkS1P<}Cqbq>FW*y(A}K;! zdd3v5haAH2_~uI_ur>=iDr65wrsV%3`DqszIHFf~oq4g_FFGJC+?cF*71HJ0!=7gb z&cv4Ru`gHn)HQc$qLhig=({~}%Da2a`UDIR*L&QJI9y7>lPr%m`qr!z1+H7GoL!ov zi2dnN?8)|V<-BUM+*f4PHX$n#>aW^Prh1&GAUJtc;uBr0(8UC!A6mB*4&{hAwdz)C z-&2>r60V2e-y43K-K*YvREit@K*eVQ7#%^9>28<^Ry$$#Q!>Ji7bL8ub4}AKrUg*DP;Xkt5bhH%SX>dP}<$36?*6pUul*9iu2H%-)<~0&2pvRxCt5>X0SO zU4_VbjZ&L?UZ^jjyRflk+5EQ>4L{jP?c1D|nztQ24*av?X;!+AUZZmN*Llj&nQfN;G3ED!&1u2h$?R;DGfJlk4?G*0 zveMZy=l$yfQ$hPZ_x{-99@R&g5DF(oU6LfqkTJ^k0JU77p5KV(jFzuZacd#{REWMt z@m$m6h@S?S84eTHHJjJm#TA!6lFqaYMA}W>Y;ip z+x200Kd(BP*&S8q?qm1Job4OgO~HY@`-|$9StA1Ta`8^%+0ssSMa+lHpBSD?LJj_e z=A%?Y|J`+x04C#ih&5EG@41j{+BWNI~?vW`MVP&qO1h^n6SEx26X#|tM%b@S@M)I{!e!wru`g`a^ z=wnt&)T`e9c+s{2nY>!Le?=^?Sm>wXk=@?X;E+83tyxQr)Na8Mxgy&Qi+*~ITvA>U z<~4WY*C1840AN;O_lNN#*;(5b5t$b4(|rd8_7Y}g+#zuqT=zcsy+6Vb%w1}9&jS&V z=Cqk@v4q$*l&BFK6_Bc)yN66b+I@j4{u(l{l=f^nzD3T2D_+M&S>LqvU78u@DueqP za;e)HYH=NiLAPy6J3efyiTF!ZMId#UyaF<-GM{*_Ncp3yfwntPn$|VPdgDPy>V&2cA4fz^(#1vSvej#bxRT}s z{+?%qkDH1pn5x`O68@bbjGr!@Fr9fMQcFQ=lTPLlIyIw7n7k9YBN3*3It6($2e0pj z1@noKG(ev1k)>GnMD^}B5|B=uzl2z$l}n%Wg$}B`PEL}=N{fn7Lg?T=w9)5Ee%Y4! zQ*3+E+njO;Uj=*Cv%G;#V#@n=IVFSz78)aRPB_-9_i{B~3fR&&1C19(C0jCiq7}@8 zbciIrQE}iAaXJbCAzc3nlk_V^8YVOSzno|-pbmI$DUtDr6)K%tZZqgeBmDpl>^Mu< z+B@ARD|y4n=r+h-OVXc;Peb(PC2t-!)FD}E8Z{N4ecdV&<>~KpXAfzs`d^?Czm51( zZUujW;c7=-Mo;?iy<6w{=S@W^^Y9c+Gn$qUd=_LLO_)9r8{tP&7npS%JE4o3D7$a^ z02#s-?$X$)K@p7JG-6)`?)VEe=hNB*w+)=3}N*d5`$3A*$Sz$hePYMa{VSY5RkZ zK|nx11JwS{TQ3xo6ayQ=Cdd< z#@FJ%*Osn|XiS?$YP=I-;*j>yFW6u*xI;e{9jR$9Pya`RAo(a7>D+R5wWZSx3uhVd z!l8PGxmz)bSZ7M&l-vC3mTBTAKvYClhn49OFx8mf`XPGRJ6t|f(tCo1cLomQ+%Nuy z>%b{qrXcs^oKLHCY}TQu0b|9db9K8#35E{^y4lki?oEYtCxEb~P+px)W+KU`p}(Iq z%xa2c8neRoyaopbKO+5^27bPwXM+rlq}-m!k{1m$WMC;z=S@=TH?21_rb)k1yght5 z?Zk&y&6?)hjw^^nZ)vpMZo~ISkDXvbPfXuzw&h|wn@7AWwM2YPFDbM9jUp>>OKqdq zRzAT;-_!Ey_i?sKds7QcCwD;r@|z8VOKX?|TGH>mP)@z^M_kA82tiIdzftD6t_YI| z$$->a0J>iKjHuPo8hKp2EbUljkvUTijSU7pfc+_B4sEs%bPAqxy=@F$O(_GiY>Y=f zH5{CTzhfZjnrb_6GGrvd%Fu}6!PVSnL87v`bjX9AY zT8!Vq#E6R`=#wL3wSng{5TlCBxQZdA`GvD4_v$=w-9MucD70CnVjNdmk|#CE_=IuS zVGMNnTbLuQB~lPM!T))wJ*P9>`xAf;8^A-3oE&V@E;#l_uV1Z?Mwe{@r_eB+YKTxX zWuepPH=Uvzzdf>D(F=nO(zX(Kpa(gm%LjU8>IOc3TD>+TWXs}MZnj=&hS{wHjPVa`J!FKYK)KV~hI;W6$U5H7EZnqj~JZs-qgg+hd26R@D3;1FoyV!$k2F#l@;L&VljUrWnQ5b_f!{T{Ti zqipa_mGlRXo9Fqv(*kYPi0&!kX}t5PJaA^fVWK1mzn}Z|C7d7%-a*6_B)!%{(mF0xPNn$HI}v-je6e>vSc@ZE{vuvOA32Rg6f_lJcG&^)fz2~2R2@1C2i!uVV!q6HSPVu#~sgb_~hs8 zuHA##&u<{bXc8n!v1~=FgJvE>98MIclQnm-;mE9*hlu^3jQG1GS$Xk^*1w>WzaI^p9~$RRUgJ=aXl^|#$1l`U-y(t z%ge6!7+m^Nv#i>XQ~KcXb>BxWH$Rnr|K2pXCa*IGF8kEM=b7n z#ru(wg@rfE0p&k`{?rbvYbLFQah4Cz-maUI<6*>DaM?@{s;nfSf0&#nt!VuCnL^P0 zV3k60s7+=6gi|dpEA+_Ed@<{{^~u31TeZpBqt530xHpmMsx)(M=!I|xCdIeoL!9)x z0y%EzZauIxa+uyE+fH@iSS?tf$8VYK z!d~tB1u^227tD)l`kKgjjVB#GCakcW>_JtSJ-QpFaXaZy+VRPHkicJr124&lHZ7ow zpNfiRttF53QThI3>Bc%xc+=cJtCBN=eq`xlWjjZknR>V%%$YbN&I#zqi4-oxED3R} z=tC1I;@@#P*|aTDc7AXcrLIt04WaUHG~IaKLO6^l3CaoLVNycNR6m<^7ds1>0q^{XVe4SnVNvE2-w~#5peZUEsJAWYv%Fvr2Kn6$d0QM=!+)jjO zg7$quGl2oQGw6PLfs}z(JC+8et)#eG`8+P~+s+UTBQcEWi+zEAjR*<$EC?pN1 z=9y8Bu+deyf^8bA>|VN=_-#V-^%s}grfe z2eAu9{eL@#Cs~R>TO94o%{3ErzCy%|W{v~Rmi8P@fex@$vmp*2d$u0su{a#kQ?}Ir zcuik-K=(7;Va0vkx0%f zN_y4z=W6;%-9DP>4uc)h{cpeOhN)F=L_Ob&3CkVRWpfX&q*j0BJ!DI=gG`Nx3a>;G zTy4P>r5VREY9O|5Qzt?o7w@uQ-U0~#<(H=Fud%LYYz)>6gLCn9iz#Dl!VWy9oCGRb z#@2B*C7hSMEdweAtFWGm1R0=n`?q*hxPx-oFN}gr`m90?wNn|!{Wue6?GmH1_%uz@WjtPW&264Mth=)xguaI8_* z-EmW*;vBJ$QgLMh&-C|O94K9)6j?I=NwtaYH#w_4#=AE^Tee$>a)~jLTV!&H#@@mc zHwu7`%v>hdS{se}bO2buNsp3^TX2k;+w_f}%>R9ALkGRei&*&e73%8Z@E#O2GZPjC z_4O)KixHq&B708G2WCjH92xn%ep`VAV|q4bwouK;F2$i+_aW*F+!EoM<-6XEtys^G z$j`Ai9Ht40B&}fXba$cHs9fKpS)kN?$O_5kUH(Sqa7rdNrXkPEv40myi%S_z6ypns zN0LEv<=YhPpc{s8b$vaPAjOY<%iZX^$Bogv+QYIp!>8F70HkWx+R5RVB=f7FY?-2w zFTF3%_;5Gxr5~iZ&ye{r5S^v-wYx9la8}u1lR6YGEBCg zJ&bx0xgo)yn%ESLJn0=@yAU@vs#X&3m?+)=i%gr;H}l2Whili(M%P!rQKOqk>|v&< z8X19%!`7Xk)`(^#(TQiawchSLd*4kkYHVk8Q)i!zGTdDCwdn*^JLjq_q0x)Sb?BlT zpXckU0+wd~+&?#T3O)_nl3aW|b;|$Gk;>H$K4GUsHMINLQvR$9tWrN0oT%hC$!^g9hBm#w=Z9_*)vcyE-Ud-JYPNL{m9F-F z^TVpo#mB41gF~eqBiYe3{gQ3+h*C3}&|&R4c{Z<)+-+Plxp@2}jss4KFMid}^p{7Z zsw)XKNhoc;&(M5l0G5;SiuXP!2dgJ*V;-pJ61sD`GW(#s=2mqGIYshhozHnLP`k3O z%o1+fafjCMVUy5VZguX|8WN167J~A?YZsB4QPKA!?H%n1VRS6uLa3_$c|i<~4Vrzz z_I}PIMP}gSS4z6x1fFCT0wKJ#=F@OEKHs@vg}nxzzt4*x?Ec~49f)m`P+dz&V#dwd zjrp&4T~EBbvhcEeJCc#;GD^o%PAZy+a2kLNiF*4+GhI=I3bm$Hb}rbgu~-0R$!DZ&PSl8ODD<>Q_HFs;wh&W{Kq_L=FD*1Qvm z!uSh3@!H2#+(_p`9#RJjfj!J?9-Pi|+QGa|X1hCAiq5=!?4yN3!+Y(-4*hJh7Mwm` zwAaP;6w`P+6M!$c5IA^F<8Kd?HQ?zTsP|ovLidUL_r|^vF zDYXBca1Z;G`?t+zXhWPx1&{sDPH|+1O>w?m>P6<3gkb79bS$D%`V`~Co>mwjH;Y4@ z03rMHP!HUwnIhe~Uajz}Wa_awQ8bNPglfPb3{zi5fFs1YtCIQ|s0Cg=VS|`}rSR&G z0G}%DX1~Ed(%(@S&)J|uA`i~pR#^BASfYYx`?qW>A-rP2Qhw0BZ}xH5izL&hECEw@ zOh2rtLBb0bHs2Ma4&Dew)8y@2&G4kru_+oHiof4 zjZ+3ghWdryIEPs~ppC_02y{GM7+-Ca3}Cmi@VU2LXU_iLUHQ*$DL8>qIAWQ*GseQe zHxuOWG3^F)wtD&C-4OW{z}{VuA#g2Md=8i$c)@MpO&W5EA&qxkZkbc)%)3*E54KOp z6RaTnKO5=coko~>TcN#i`I@J9Zff)#8zh{P1mAs}}!cgc0>ZYFJ1dJ%e zl}aSTz^j>5U;2R`d_5P}?pj{e{q8-=7uakheL+X-u{=l`sdRtB%=iM z3$_NcJJ>CJ$)A6vsRmD_7SE-i`o{*Hc>lqq8-O47zQw@JL30#kbXVpbxXb=&s*5%J_Sr7=TJ=kO9eGsg!AgcnM$6WulcYS7R zz?G-~&5xenJ3G?v!)UMNpcI`=cdz4uz%tcAg;ey_bgFF7zW-Fl4I{7HGtwoU8UM3g zJS7P1tuS|wz~z&Mx><|-zoHYtc6LMCLBQV{2`8mnK&}_$H-JMxu2+9-gFbrU_npZG z{pi=qcQ8n~j@Y&$f=n+EuZ4?{_gt7gnME6NpT^Yp@AG9uJN1ssF*^4?jJVw_V-VaG z`}OfF6#beAY@-^NbZO+NF&{Z_bp`na<^YTjr1Le1Gg+}oei>1)y2keNt+Jrw>vuF~ z{)lZC2x2UvSpl+Ch6bayP-^Et2E8bPdd_xd$nA6P?FNA}l$(JCjgmv)M zT_p-m3Rtj{b?9b0ikiNEg|RC^f(F?l*OfXPM7Wu!*Rq(B) zxGUh~eA(Rw{@xM$)Q7b1V%1#wStKuMrQd-dATRY(ARi)qkHZ_mv&eTg%>WPqa@oZ z8Z;qKovR#TNT~R`hl$+Hz1YP8c@r=Se0DL2R)= z44dz~*RVa}mL|ja+FV~R1)k1FEwzw;P6d~-n!|qk)ebTAw-fNZm&$@NF2ep&Ln4Lk z1M_zXa)uOGz zDU0dkF`DGH27V*5BS?yos~#M+3?SSAoih=Ai2xuX@R1r|Au<*F_g%m9H=dV64iKUf zcysJA(sY1Vtfmbpl_hoC-05$SyLlIviip*j{Q}u|tfmVds^Kq>EHfp~IHyFYJVQ>F z8n_pMALpP&0^)DVl%t{nLRG0+^$R`&Cn$@Y9OgYj>CY8P}a@eEC@+F9zk`T6Uj*`6-+S^X$j_#YSj`F5{! zf@A;FO-`UzGwUfOczWuy>S`;U7XV%7c;muUgPyz!x?+! z_Cr*61XsU7miw!bkZK4npW_!ytqfCw)A2&hr#~Jnf(ttCXmutcoQkxBL1z|rMY3&# z+d>brzaibc5m_oMMB~UFauA3?zirOW{b_7QNW4*_+xzv>LVY&Lps3E^!vje4imQ#EPh@()5Mh!4y^J(DKXK{Ef{F zuH<`ARv$~`bduGWgf`^P0%)dJAePQuIwd>*ZofazBNZz%fBe>lqu-Y=qgN2^gKH|G zb^R$S2N)@GBf+e9{kseEzph~6Gf})rU$%eX1zESAJOcm}JiU|{izXZ;$_pR#{bYV@ ztUu@sjevkM=kU*i2RDfUtuPJ**0%?EHB5PXI&IZ3C71W;yGKQf6}0lSz|IiKavH)6`RyXbI#(EdVnj&FKGg8pC{t~$T-g*T1i&;aePr!1$FGY>wJFX|+wZl!6d29W19~7c0 z=Yby=MgHizBwATnS@O=4f6fjPjdM}!DjMz!RK-Oiq%s%gs6zoF^y(unK;#XC7rzUH zOmy$!wt4}^<5K9;QpDf;q*7|QJy!1|e9%~>4mm?@!zFj^qaY$|@t*)Ve(#CL%k%0! z>TH7YW+U@+`9w+^HS1Vto2&c+#To&H<#p)x9P`>1$OzR&)l;rOdVIu+V*{bdIwK0V z&;t-1*;DmVhnp^h0xL-RCy{gEX(XlP#@O+uGNN9W&YnN{nL1SR&Wut}_nxlsTcgaP z>rT{@T_Fc*2gI!g6RArX)&ZDa7Z_i1 zPB`|t;|Ya<9_DpSqtts*JEZ4}WFFs6Ic1za$Y%@C1c@m+t3Ccj8q~htgdxQ5J2Lm6 zk?~R)B1qpbzC}CieuFl0YPYfxhbumxdQ4SBG%{RK%$d zT+n434m1Tz**C+m)8VLEe0vfnXYS^^?meC7+Cgh&-f!MVm-oqe=KpUXRMW(KuNMlp zL5$rJSdWV-kfo=guO)c( z&50Ty)mK9w@3UVmQlC}j1oQl1PR%i**)|O;nW7WD-edTN?Douv&La zjbnIKkxtwfaOx?np{)Ua%No~>nqV~(lcZ0tEv-B8jHt8p2LU?;b1CcMwbBPpfSXkV zO+)tFy#}xm{c{gROFnAv6uVmgxKY{V5=`Hf&8_3^M-fiQdc2AxvL@v9g_|!0*)ob5ta(u_i|)d`co7N^l>r+UBi5oU(yz=mZK&CCbqI4r6J>1F;~sor+W=*oM6?9?#iVX8-R*jnhu zKLlyab#MymDdeJb@k(H#_iM0W|I>YnKaIObE^AR8V%lc|pk?aXbw^;`jEJM<_AwWm93XIWn#HQ088&nSXp!Mvr zC(MM4@im09WBwksko$Q~n`oO4TSHyzH)~*q1f(_H0#RM1X`%*jlt{V^TVp5Zze@b8qrbyjdd!W$14#;VgGAIdacAlJHz#|%pzaS@QljHOR zK%3)665IdXD_rP#y77mM^v|4(3{;Oj=mpLB4pCja6XZmFW_fV2wonH&0<1!8H(7@V zDEk{|+KaPqOY8A*G790>&8RxTZY~%*jdUE9=3qXHnw_8uLAA(Hi1}|aN#K%HUKoXB zV<5DXj1=)6rYxNrhS)l28Xq6ofJ;VkdXAHkIJJ8p*TK09rv%jEj=l>+jLaVz1=n~W zg9|-M>qawb3}qdEQ4ClbVH!2@3b=xFId>6RIXken=Ad{D6(ZG${F(#IE~T8;-PdBi zv91e<^r;A`gF4SyphAz>rx*Hqoe%+!D?(H+9xM`^XF;h-#CN@=BY*9zQ?7oR)V5b)1G5S?;0!eKkt0_Hx{ZXl73A0!Zsm&*z;Gi z?BjU@KukKH;#E>5NgNt!Z6h7AzOtZtZn-1LZ2x;=RUrxvHC+_Wh!jQTz@hBhM6Fqe zE_gi5#ScrLjh&~pIZLIx^%XvF9NXT>JgM4!PLQ{nawcHkK54A$f{1R+{71Jpl@y`M z^`TMO{zKc=f%GdN{csh@&cn48TwJqyVnr%qg`7<4kQ~~F$w#}_xQ6sRtMhviqH^s!Z2l`vZIwJGN~__OEe`v;+imjCW{8SSe4wB> zp}U`+mhzv6^Ni2*YTa#TvGj9gq#u)C0hSM_lov4A4`+umFYh?dk!G^41XLjU>Cl~K zidg+2^~D4(&|iZgHx8-=cFkZCMRF9hHe%20m)ETsWP^cEvIkzFSVG7l{Ttq2P=4kz z{Tu9MopBJSEvdx1K~eh!908f%K@Kf-B*2Rh^xXn}C3@Gjcux0F%iM@o)1@}$|C6CA z!oOH?J>BR!J^mAiFtLFaPW?_&97L0rg$q9po_8LIPgkoqz)dZ=G zPdW>VBPS=B6V2cub*VMl@faRd?VqrNL4y}mTSEt!!wSD7@u1)yta#AjcD^_BM>R1D zd8k-CB4W>RYmR%0_o6;ge~PO9spqlyFS&K+I=A|I@nHxq%l}eDT0}Q6;{+Rk+lCL z8F1g=?%M@0Z~9?JiC@AE==r&U@Ld*w*{Tk{XB%Xi{QqJBUVl>Tetrp~T|pGW3Iw{; z6jVBg;uulgpdVig;UVhPR4s{GP0Nzx0Y*!*y>PY15JFi}- zlhA3|odIZM$SqRAx`VT>=0Ilw*aI)$BBI7MOk}p?p~)3)lQZ9=k6PHp&2g%r;x7jC zhE(7nJalluMMGlN@ejll(pWL7G#5ZHj%ZhS)tO|=c6BRnUa*spSm+|E)7u{2F4qo5 zpDBx_r}2TVlmjwnvU+P7@ETs#{eoRw;SGN#8!$e8Yxw644-N`XvLwOT-_JF(3(pPL zrMNSuUvQv%nCUmWkBnp}gC|^=F5Ye00o&yHIY`^dxdB$^%j1Gu#F-a(KWPddFj1?b zP+=$tL3=@f&kg~Q7uvyAXdFKPc4B3-YPz&OJ$|Eh3&K0lOtwLK2Ufs(1}?|uFn}d8O$!}| zPZ!5&sIf-Inx_dzAx~4r*ai{56xw6Ol_-uKF>S(fQ*iv@mjVI$GVaan+jCn=HeT;TQ$N!fScK&qu+ABz6pm5d^o-DTTb2Mj^W z6%|f>-**{=oI33F4V7_TWtXiJ`)@i0YvV}~ z(i*?krmBmtSY1RyY%U;o)j--g5}Dz!gJ1~z3e2)33wh@uYDH2O#vQ~(T{I$OYmGv( z;034?tAM+3zK;ntL{td|E?>ZnKDqsxSsu7?VUSV>+FNzs-}_F1NND*}$c~T3S<^t` zG@TH<2E^Py`loo{ zAdJNj^gpU0G>-sXdZ4Ci+<=XhU>rd?w+?CyH z$hHsN_!s4k%Fsf(8E$C*p0L4ynvrWFo2f`Sz<@cWcaS(7RB;exk+!$M$JDh03nE{B zQ{7Q$Z~T+!d$rQ&4uLQ#TP~dsTp=TMzU$wk_0=J)uc_I9>^?$W`0)g`{Q7lnIatE&rVu5?%WsLp>$Br`3ChU>UD{g{Y`pbv z2yFZM7?tr3S#^G!rs8%Ln{nw3_mP*JTDrl%>!Nx`A@)8cqe0R zVDtx=kVLDDwro_A7AKvZEKa%_Db2#f9iKqGAf~@`M3pM(-A#<5)P<2xWpCe`KW1nA zNhbQ3)Lr(B-F9ubvq-PGFu*KI3)h8lecaL9}`U3 zO0HC6wp2t#uxbO{_izc{wAbl)-}nAC(@{D-EW_W-FJ_#C1?46Em~qt_HNKT^mnh$c zI2Iy~OE)LcC_*D*ONv{X7BEah9UNX^!$se08bnM>AxBM2y0MP+niOK1G&$Kh@OYL# zf10UjY0{-LLLykBqPF#$L?}_{x3}N8MW>mX(TcWuR2;tS7e4*8W5yb>hRW}1V8d!J zGn>Aa=LB6ldD~y5#?L`tYR7ah4}(4r{?aemr>*rSJIBx!PRe z_ZseWcfPqHf&{L&M;eDhS05#<`|r{;H?ML8y4zkb7gOOdl42R;DvAiFCT6HKJ{CUy zxr2h6g0zJ>Rg$Kd+@li; z1K|&uzK6u>mW1*JFoSx`zWPB??71&BbM1iFyCJ_tgqcAv2Ur9krO+1(`bk(Lyd8T>% z#f1*TH|89=$Bq-Sa87Uj{AoFs9cmpEq^cc#BwRwS(uO*`F;0p%oijojO~uqXzsp=l zD?mZRd_(+dipivA$H{a@lD#Y?-y2niQM)IvY&E9BU;aeIG1I(vRnJ%9=WFGjMcJtL zH8p%AY$u5KKN6w`_V)wp_+Z_S(U@}miA(~G%%PPSJHIxD%y?<$TB%6;-S^Bfm3ib- zwBdf=sM6fIZE4z$#e35%#M>sDmtKBAV9ORmt@}n}Kbq-aC#;!^U7VdTT5GdtNHvYT zanHXfL4TOWgjLarx|6i##>8E6+vq5n4)XnJCPn^r(wAlqFW1GU(`1RL)(qqYS!X5> zyL7f3)0f3$whYu?b@)i=;r^W@?e%@iD`{z+rJhx5oWZCECks*>go?5vR=&Gno63MC z{rEPA=#hZWgM)(%=1-N2d;`{kn;)6Q;2xKki$8kYX_a2)$rhp@{Q=$h(5%o20O04q z@RhtpXaitg8yux+g~Ioua*LTwN@2Fd=T)$8b9QH!3u|hQACC4bW)6QPu_B&fpu-%l zkDA<+auZ~l6k{T0nlV?|I`Q5rudMd{`rML_Z(WW%-664V5*@&x+k%C=Q`}l{?k7pA zn3|hE+je#xGa3&eR#ZV#>~-rI&G~bq^>1>?Zwds10O8G_qL$T%nyd8A|qqT!7Pdj zI@>)|)D~)m(v-GMG-NV?fe&ZCc6y(9oy~bGb%oG?cG8$uAwqN-n2eQxGOYKJC_Z{X z66dA&!k=OOmg3eK1L^B!t79SfGpT`w`{(1bSH}c4xAxLQ*80@fzO)+l?^^S-QS0Oy&OhPX>2Q1|Vn2*PoY49=6YvC=WqQq=BI=FR| z&5}CcLQS~!;r#wPrfptp(a>b?g;amq0?q=fKBfXz&7j~~t5;o5*Yb6`Ff4N1qNW>! zaWTvlC_Oue2k#Y6H@{xdG^SnBr=8TJoiw3sPSwTK8h$;Y;CUG9#pLa`FDL-v)%#@k zIieYLWpm*S9{cm9`f0!C7_Z(wt^D)k^*4U!?|tKfdwj-OY$>tk^hkMa+K6IcxDZp4 zxJ#SvO! zwqv_nvg+`iT0xHBdweCwi6N{(hWw6wUk-M(5N^;%ZTuMDPBuilf~)P9p9DcdyJ zmiJ=X9JXK5A$kcxBD3n1!pl6wGRsD*J%=+(bOTLAxrVGJUDn!T*^oQVQxKa=iTofF ze=fqffMcTRBiTKb*V=byPMhp~Jhwc0X41KRuk*`=uk5amtE|2KSbO@9I0ueZ@iM2F zq#xZNbnB23H+cL8<4<7IU!?yF0rY)1WL~3I08JkRz*e#raq$$RCqG%$4iz@dgJRxO zm{QsTlfq@20we2C-)I%ArLi+a)?%YLTHr`DM zlR?1UNKj!+WL^D{iR3oTJQaGAVVr{(kXw0Sagp8ME=$4jl+Ti^NIZ8x?TF>*gHQJ5 zFI2vldW^&yy1JJCJQQ6kX-L>(G*U!9_)a&_k89=$B-N~i&gNG}_&qE~L|yb9AOPvI z-(OZ2Z!%u2`^dK#A6Q;eBJlg6)5Wz6C*Yt9Kic~V{+~?%lvc&7h0#=^)S!0> z0~Rp$Wvj%7c;_M5$B)=m;8Rs2U5vgZyu8Qk$D6K767%a9?gy-i##*N-k71bWPC8IL zo6{Z1I{#aCgxa?;QD~k5{gG*^pE|VfwvUQ^iifMXWznbks}ec|7q@by@7SzU+g~~~ zp`qIS{B49=bZwShIx&61Qd?_+DU(>ygqP7*tXIF529`OJv-u{*&(n6?1WVpbVNrr&DDrMNxM~{7<$z>5@)SbrX(qs^Ytz7U{_AryiDHiTHiO@L`XVL0#R8 zwZ|_KA6_5PKX&h1f8=$VKnJlrZ*PwvY|~@|!J1m2riGgns==>}?hFswlD1&Es4JD< z<1D7O=sD?1PO-K6-1|A*FIGIimD+fw!~AV$&!ktzVlqv9l&cG^W^}eqaPLsDQOb0p zhvigd`4`n5>6tPih=6`$hL=(>%f|t;ON`Gdgg^3NZlAj*^abjyMHn-!IT)ZE&Ho4R z5vP@X7seX|%?TLUV&&A(qDi4IV^q!44Ie1rAj=il;EosR@U12OK(S&fD)o7_E}2sw zM_s^f7Nitqs$#pG^Ofm%$w!h-rdeviBl9I$iYtm!o84^95!$F4yGfl2-th7xt>@#C zU5;@Fy}-8feCFj4FrxOh|vuDQ%nvYJZit@PU|vH zYDE(wM<8*>R#!=h-vy%>%HFgT$|~gD@`b2PkMH>Y1>FkXp&zB2YZa|#$vUMfg5P#bftw#_qHA6%=NjDBMXRV5B=lcd&(xhMbw|(f z%q7j^QrhgUEgAR!@=q?Ay)^J`k-yO+0mroMIO7o~JGn~hoho{JI_m`|i~YE9`@0ra zMM_o)OPuyRQjvo>Vdf?|H>NPCprOO$P)6EetPI=be|ZxC@Xb*MBVLV&g9nt^WnI9# z9P-h`R>Nq<5VRy%+4t6K$M(cV(=U%n=v9Gt1VE4xqB;JoOC~aB~@`LiklukjqJCyE5>2AJ#eE)9@#~Y6~ z96Y$^?7i1sYtG-acp28*d{wV8`8Upz__&>&Hw|-L z5}$=?$#-dautWKgXum~Pl`Ks&$`WfCtlkshe zT@-Kj*Gfc@G@QBtR8+IT!vd3SdgMw6s(L2CAX3nb0jP>{QTA;B{&1MgNskA<_o(*F5RD4IBB zGF-)T#guR4L>gS&9&=l5M&__T*qu(~T4bdJm6;aW^g6lz3G+Ehf)uV|DuM`#%fpl2 zh}o^&5OV5*bm~r{S4aybR+gO{`N~AhEpyqFW)d@>&#ez{dKNBGJP$_%L*HoSfIIp3 zAsl?ueZKPJ7CTq6Frc2!B0+J>5A_qrmQwBrz|k4gLiyas4s?a*kz@r2~u76`%MU=aJ*UB!C=KM=O1fGPjWeumM+R)$Ps zqLq^s4UxLaax^MT>KlK)F$IG2#kgcGlWr$yUTdNtMNDpyZ_(>9{IbZV`}Ov&uO$un zjl-Q&0Y$!?Z&Og+wgFcq-VB+wtD8qIdK?c@6>C>{$?TJcw6MzWeLiHomP z-h^M!3BnN487LWU0jl^-sg+yT>Y)rSHd!-+NQB9H266uR-V)JbjMd?A35jvg*O^Q8sk=FzCeQWB?f zOv;0voT(eTs}P*FB|6FD;1iwa59eilg;{pLrS{G3zIhWN zlWr-#aeNnE)$sFin4Y)GOT%vcgi`Qp>6C>!Y*&&?_o)D(7v zt=7%B`&TWUU5JSE7A56m+yp7f;R76w5Z;mWkn0>1N2z!@eyDt^4lCi)(9x_JiFKWNg}htzpf}9c+BNiM%0bICg~Mu z!Dyz#8sk+B9AAhFJ{(2yOPc$Gi2#MR{j+2;?1R=R5Bxltx#dvOli3)EL#k{_>X|+; zHj1gv4X$zTCH-_mso0WP@zOm+hrbW?q)U+#{bM(VsXT0F=p|`}h1~V&l&Xx>1PUV&UucxIIUl#t%3v+I?W*P zzQ#Rg)@Ky`k%o-Kj!@R{7f_?BA*8okiRZS8Q5cig`ZT1A{<$f>&nx0};{beimxl*5LltGy&$6{aR~zgww+b`X zEO!y;RV<(KlV0`#rMnHpNZ18PwJLF-VTMCKMWA#OUGwybx|cc}j(XjM&jsMJVZxfC z#UBfBh>MH}kgbWBb}z;U8diw>#BdJ;gD>YdSdIE1s*?mpop#Xt{R#EuK>ok?kric2 zXC`)1I?7`PQQLaPbk`!QYi^HB^NMc79cAY9U{_4Lv-c2OzpNy$r-y@Cj`~$XOntsr zPgJZ%i4IAee$ki)sjly!K0WBu8uxfXn!k4d0Z;=8!XSOb+DoyajEsyroiot0XI3NX zbARW=qSqcu7-AWF6-pA5@ZB_>XGuV|ltB(0@Dvr^QCovkPYe22h$XD8<5~PQJL9WA}LhMLLu=4Y)Jqkcbd+ zW4A`%R9yQ&s=oJ4$LVlj3V3|gZGC!v-kn}S903Kj>paDMhpr?}%Qzx{^y}$Z4VH^m z+h<;a>Wb%_xQZdZ8<^V;&;KV|{7yeIAm+dM>ihX*{tffW1fipps&z*_jRmxNSe_uB zlB0f~e%Sc|yxqImAygF*)`kiY13bW$2?90MLKp58I?#utfCdxf2w);x0c5fwFAj*?`Tjgygy^(cwL#AuwY#j1*P<*O+pr;R5qZ$ie&$TonX|PBvGYjyHz|qx^uA zH_2;~)mQT%8q{PGAiQy=Tk_5ki1$u&1QEbzwl8avtY?Zb>$V#C4j2#N zz_z7-qlTnL@crPPFN@QYu+XrDeSu2pCk|zdud{CR9Ae^cSt8eB^gJoptvqBN?24J6 zMXMl4&yYFy<55WA4KS7Bd!NC*9 z9=|NB)2NQ$Pt*f(_r8PW;WukBdgHN`ifP z#v>kL(EqIb(-$>Ydp6Da_xAIJT24eo;~xcChrnJa>aKkQES9pOF(j(S8c5-bK>A9V zt`PY@JGtfqzb8^!Ta`GFT?f*XT0+JwuVqZ5GU&<)E%lPQdjMh}{`tt)1Mmf+ulAti z74Z6oY&9T)xXjwcyR+IFa6=-qCw>Lg-2uoSeAJ)!hH-+Y3w&Cc2tTItNuJq4P3#_i z#M9CG5~?@qC?df?nW)jdR!z_QGRgYn3&s64xJ;Go^hq;Mg3XwkT>WVSm&^NEaMTPV z!^srCJgW%BXD*0Khca6r3j%POVrz#Q#fHIZ@kVHx3~andohs4)NdYZV-&yQ??R(?~ zArRbIX1H6p4E&3Og~qLyvj~uD@n3>xA8X+hkVI2a-u}x5L4FX0`{e$jbY>=JAbchM z`MgDw`km3u3h^$49R@cg-BCdVZ=jx;72ZrUqqv5uS}>UZ z8zF~0E{SX94~tE>BdZb|#rd(O%PRBZpS^nvh9via>OIY!w1xh=uQ9)0>SUi-xT&Rl z#&|aQ6OvSTf$vufeO#j!O+W00q?Xuc;}h;VzB({mdP^z zg3!`n01;!U)qk28QxrY)B|VxZ>?KUZMqCE~#UKl>fN~Ziuu&y}`L-*{54uD{g0vLi zY4%4L1zWF~;zMQF>FizD?wZs!^qP75_DPjsl=Vl>+x=eP+4!+Qz*(wXF9+14O-0b4wVopjJ?j!p@&RCl0n5SQ9QLZ-xo2?;D1;l>P$|P>{{~NfTVVcl% zsZC&bIUEoq^&TCQ42F)WMsUQkVa-mEzK)ugqJ+7hZVBdY%BL@-Z&D!%G5Z*a^Rw#LEeefyi z`C|}w#BWy7OHR1vC&=S{l1n`eR5g`-{$sruh-gb#9Wr`CLl3i$AMAckNYO_ z0D8n(kTqotCCX-p2m$#`?x8*b%h@K-%Tz`RE=)n3K1k~MhpH6Pm6t*8I7oat1MCoX z6vM)R7ESNf)X=Gwwxx6js6O4=yX-bvGx0M@Ub|7kW)rTNt{+Zu^+`Uffx#i=Vn|ub zpw^acn1!{( zuoHznjeanIP!!oiLRQMGivyBDfSoD{Ashkn&m9^^_)ssY7+u9d^5Yr^8V6i3#JloP zMs&sCt8kswT~sCm*=xuj14TTqrlLVlDpzn6^zXiG(RTyx(~ByYT3wyPE6PR*fNmj) zue+#z3s1O(0_Jo1YJtL%99Y))rlHuBT(LBuORE7nk#dv8oxgi0NdsNA@A$1sn`=n! zM>Bu<6z<{p1)-#{jcl$QSC@J{lEI^=DMsg0$+EiTTV;7iQYHPrpfiG2QaH#ds7bJz=Q*7n(Qj?iqwl%FZA$qu|+rXqdL1E_DZ${qU9QbC!=ErRDBLJ8;U`g$m2 zZqI>O9Y1mO%=R}%op*u+9p{$mG)3f*#9nl|;NdEF?zh6lC9?C;_vOB!skK4k>>r*l zFkM0B<+;_n6aJ44Z#Wr7`1|gIbOMnjU_0{rLAKpwbxff(I2-3Mg#SBBe3S53=d@YvYpt-%s*$eZKRb42$Xe)_@7sfLA`awO8z8f&rlcRF zA%%1rW;b0H((ulvzpwWzz*Z;r!6uPJ>%`D`kUy9X>;0=cz-5|&ULh;NduEA4j8%>S z=&RB5Qa8~AH_!?2Wx+a!t_+Y~#h5Yy3Rw+D2gODt{1^)82w28&0oAblL+_}I+CYcFMd$yBjow%}VI+W(|qx@2T*{)SymC*v6lQt)mX`i)icGwjc zT*lQxTk9c*GKoEI;!|`_P&j;C5TjFF8GOB?UwPDASXh{!a>R9Lu^zfg`RDnaGd1#w z6Ad318Ex3z#UFf3BtB`~5;u>m8;N>wBL1O|3AxK{qF{5$z$n9ML4gE$0#V2!XH#am zp^x0p0ccGL-z2e#_?$3sH!5LesQ~-(QH~ffQT##Qy?@~ zSnKRKgtBD0G1iJ`Gs5!*qkNcrUag+)vpA&Qag~_xq{5H%^J3woMK+IS#tXh(%&Pew ziYQm(1V34nK?hH^v0`Xw0*B})RhuTG_`_=)qJ@wgwm@Uxp4`ITj>m;pmKR6XMmjQM zgw?|^)3a@R6JopfnEor?3;S(UgetF#q-< z!=TGy-5YqlK*5%a>I+&`5M@UOh~RD)SxD?r|DjrT?14=!XWt~2sKFZGv&iN3B50_g zC6wzx4LpH6l>2TWqnVK4Lcr_FW%ZrT?q2kP`H{jd1O7mlJx6LnSnNX)?G0($l_jel$CQodh@g0k3aDg^%2`?QwSX{uHj31+28Y* zG4KsxdJr-bW}UE(J5cDH0TvX^%p1}+|6arfcTIQ)IrB0kaR7f@@f5j*!Vy^9E;tcN z+2RTCNeAE$!+$}gPoxsHXt9u_PxI{=FI=0OOIrT~8t)0IhlCQ9T6Q0&@@=nP0e7|) zWV?z)MUC1PUQf_DhzjI2!KF|=%ka6ov?A_=Ohp0s=a4^X)V*Yf32HkJ>~Eer!fz@Y zGR=}c%8b>ckWgEXEYzPCrcG-2z8KklvD&usB#cwwsN=SL9Q$}eRg96~?A7u0t9qlm z!KYEn#yNem6Z@MzkBBh1<~0hytzi{K6R%olbHr_kcuwiAJX=pe$_J8b0_+c#TqD~g zM*HOrut{M{;RltQUZOT(wg}tl*b=mL^57nL%+#N#T1@^WfgEiZZ12sZg_L2G{UBtp49npr&jpnp|HEj397K{eu$Zv;Wh7iRb;Nne} zUT_cxUP7e1xy?itKFR>Ga5 zIU0jK9C020Ia9SQ)5^k;$B+5%N8vC*JXq_{^qm;~l;%_qNw_2BYMhgI#HpJMzR${e z9jVPqw_{WUZh6B&FoEbj09ju9bosXdw~QUT|CQ^fUD_=87}cJ#s~eK76Aj9-tbiQv zS?g;xJ@zFxLjho!d}>DDBzL~8;Un^c@HN{l*($F~*?_+ARfI4vX2RC1(Vy~ur_6LC z)t~{4jUvS3M`*hP*;Jp~(6C&%b3vlpV5g7Q-1oqtN*WoB@$gZU{2)03%iV1?KGEZ; z@4bJ7;;qO2(PDswTaD&7IdD1*c;aO@ciR@0d1P#2xG#~mu}w|=B^*NHXb#yV8ipB? zpZnpP=$#nH^*EQONukqzNKBP`2Y-JUAycQJErvu^MO>=>Jm(67tA34h;c@%7=R!Pe ztnAMIkXR(#lRn}S+4&Ju^`WzE{7MY4&cSw3^uB!;cWIKYXrNy9P?L~&BlAFkg9=nj zU5+sk%Q!op0bgEXXkIOXC)-sQC-_-2t-K6)sa?n#ag`||D7D&XA%gU7F7<6u`PSeD zz68}k$|rgs2Yd*%m+V-@04H!rt7;*=wVKL+o}1pQrU} zc&iaFn4WP$7|#&Tz`^!zH8eFWfeRey(MBD4I-2tF0G8&1uyklq@YfKEH$%yTl{ zDH-(eVergLQ#}q=p0mPx26jv1+?yQx&P-uMe1ofD9HPbwD(R0=kL7T?^OCL^lu$q| zH81D8|0Mg_W+Y9N`77YM%UN|L@fc+;{}SU!Y{s_3vhJ9yW9msF{jtk)XT$OZM;{;j zIumpTyXuC}?nV`|i^$8!9{O~Jpev9Vx&D6M#oy(!^~@VI>`23E0J(nIiiT2$%Oz(@l{;;}&5h)UC z@$ZYumDkpYzOSPKLCCV0e9i&RiM+aJhYE};jN%K9QEZ#hf98V`8b1R2{#jVK^PSdI zrI|klv1L^h=!gLfo#r)I!f!RiPoK#m2i*cFB!|k(^Um%SY4p*&==7IRO(oG|fqZ|r z>2ueuDgOva5E=)&v?NsNpwI`iv2N14j#hGelo{{q-CZz83m=Qd9i z`eB#+s%1sXkg$D9fMDPMJ4xDcjN8_b)pl4mv{<-l&E6A-`7n9!beN7rlcVb7vwW)R zEG@?=11}?~X!Beq2H6=vuyKEwjpQXFE#fXWwj^z6bK8xZ9Q@>qSM%y)^gf;&)u)t- z_yAs0eG(SzrvL-SWjC57E_s@rRuzrlMQP@<@OXpeQP+j-#`4y~1h)3|2+Dd}7BVom zD|h@DsSs#cp5R?qS~@(%5U3s5`vgG8Xah|Qxj_quUbPyeEk)+=gu`lajOXO^NBPUZ zO)QYB;4=u+;a)In>~uxRmjqI&QeL}8Fg1TR)wJjH zp&0)A!T+semD;6|4O%f_*2LdNqL8tU2fy3r6-dbNHrcz|M-^l1sNrN}*y9kwP?3H? z)4Go3Zu(S4hN%(i>kA{fI1P4Y0hd75ft-}m8uACClIh)h$Rw)?^IE~rECV(LuNW!x zR=uppCd-`cnJ0%`2>9|$UjNM4p3?Qh-7|V889;JmEViTf8rYh56eO==A$1#nf}YsD zVkZ4ZG-M{dslh&f(cyMbWDNBkr#Pq>G?IkmO(&O)(hOdV`xZ!fkUeXlAF^QLbZ6{f za0Xp?o+cmZ#a@(n?k2WFtsl>|2Uds6B_KY8@!^)_Ht|aQ7(=Jzxzl68a5VM`r$u9i z3TVMmA})~SjOm8thRF2h4@V!dlJw#JnHK*&KL!$08 z>BedBnd%*{XM8>c+0e2Y(AT8g`&&NF-+6ZIf-6KocHSm`_e+~LW-peK3kihyCS+`} z5s3P$dUSF32=mvD*iY~oZPpu9+sTH^kChT1(E1a@KxTvY2zMdu_tjvZ&6_wrR3Ezux7N99AEPbZfi_u_ixagho`c$ zCnz)0Q#342xplbS+@cGx-qC8Sxx7XR(^#UuzfgFl*iB(ovP$O&rVnN#T;x^eDFW_VCQZ#81n-c*s)T+jO*<}9zN6!a~ZE6 z&cOVQEcfi`XBQzjI2Z=!KW%hKcc62926khyOy)`+oSn_R3zAY zd^g~cq(gwZ_}OMl*Gk}4Z-4TgN#a+30S?Nw$Kti2nU?P%RrmS9PsW8C2BfGUp!}Fx zZR^5LxTEOpG05~xOa2QQQQ*VtFf1;kJpuxr68^fj>KNY{B}|hiUkA|Le01#nZO0%o zKezgEIYDZ9gDYYd5p)gwwDb$lq%hc|<@J+9_COqr04KCXquW0(a*u^#r-dIVrd4MjuoIMiPwv0oi zO+uwHZpJ$>*L!kf3n5{+rl7IE3xIn#g^%!#aJBf&wqR5_fjS80VEI*Nxbr zYPMM7IT>%1l#E{|gOdq(m=~L?>oetNs$fctN$PGUjvQ zy}mh9Bp=DMaT+U>_ReAC@DSsh)?T~*m*gfluJOv}?qsS@F5F0vZuS`w5?YInyo53h3H{FD#2>2tq zLl!la9kCnqr*EI%?WVd>_3fsW*8w&*nLRESH%Bw)dv0{A5yOZN&sb+&tM|{C ziFXWho4bazvQthDRUOKq@YWxxEntT6#tf@lE7EqvSf>YYDu}&&Ym;~{r?I4)+hZjm zyH@#^cr}K9X(35#wmwa}9m2B|$Q`rDz!s4D+HE;#bVcg>iPjQ#hIy{?_j8t4f6
t^pf(hB4*Kw1a|H?2o%(l-WqFT|H z^OU9WNHX$6zSMXb?oOVRSs`NAgX0Tk43pJ!rl8pWh#;_Q3@)j+?>RM#j{S__d$~K7 zM_q?vz!SUr4xHSTJ$ccnNJ!~Gk=gZk#q(9DAPUqSZH#m_g$jL{>0uy6B*1S5cpTv$ zhW(kR69!L3o+k0Rxi%(w%uq66pU&E$Wk|Rh_D=;O@~@`XEo~lRSppW_&`>V8-7klM zu)QC#5Bh`_lHTT3OpC2GOkUhNK4Y=G#ZLz7Ml+h_8#+NeLc>03W_F%sgzoo*h*pTE zPNs1A%IoxZ*R0acA4y}qS6q*k~cw*d8*K&AfWFwR=fGe~Z@rZ<#0;A+PIvJZ|B7NU(TY>? zQZw$TIe7OGo9*Qgz1tr$5pBJ$w=&mpHC zA(+L`%09(+1Ne)GT-;b6FvaWI=iz+XeB*Q*`zPuZF62$L1wQ$%?x^RP^e#;mT z@#P|840IRorvYSn_g|9EZf+ffeXiSc0vpQo&UEE2G+LH$dOi3EG3q&RPWSIX~vO3N*##Q35_LhO<_dQ8w1e+IO{;!3j10eiqmdl+Pc3CWTnxkN%yY zz|o}K%)(1R#Vztfus8dSqbdc>9J82^Snj9ShXuvFL3AzoqSOy4e!YGxCw%ATc(@ka zMY}J8zQH^I(!&K<`iIc@+=KYJ94MKE_kZKK@p}fKba0SYUh$1N)GMHL1MP|+cxi-Eyp?8-Hy z8JRTlp)76dgABU63r1j2_ztK>s(>2g*My30RSZn6 zmRqWbH47;ehKjTh%(w6bp$N8M{kyz28!7v35sUTVI~Lv_z^<9Kik??)ko@|d0v9;~ z2sgT*n=B+vcn5A8VQUa*6b#q``|D$%xjXRv-?2PR3(&}*?{1-vLjDXkb4buc>hS3H zU)vo*LZ#X_)w{cg1osr$>`awINFxQ&8|X?UdkT$D2RVP9Xs^DDgeEA^hQI^8FlT^s zvH-Qux2&>WD(7u#b0mb3%DXPco_L;3Ez(g$teslyR*bLw@3)?K-;8z9@K;X=B^E0!U}iLKKdPWdCve! zVHSP%^E2}3p!q$eaNM+8pR4V{Sx_y$_5kZAgrVgSwi97F>Pzng?Rwbt84BHCl=Ji& zyewuAe=!J$PVOFj;S8xp{=*wUP~uTJV!6IMF!y?TR9s78&Cc{Y^+Aw5HsT+N{sjK6 zfjGEj;d2!O{cn}wMRVW@f-CGt7&3}WIJ!B^*H3Q(KL{%4VD%GYYH|2mUm0e$H$KR6upxJHRD415p_@ z-vjlE9M>G7ca?jcMdkgEfP@dst8K}HH7I*QN9^+WbptCQ(9X zLLqJ`R6DRp`0-s~Prk{L^?~M`kW&ac6bMan%r`|536ag+OaSkehX_G2PK*}PGXRO{ z%h;SlD4paM1eb;mHD?Mt7x1_5gJDC(`^Htu(Y96qg0X{UhY>rv+>FJjd8T838um=`h$J3PBk;`T^F4ewwbnR?5GGEC{IJv2aXf zmV5~fwP#I2D06aMIRPPiE9DblV9Y!z{>GE?D5~IcG}_x7^h@>gNQ|Ja5Acjv0TG%V zSA+p%{S#dd#J2?pQP`MqHlk#+p`BCHJpl3T9<*ae6EPYunJ9*sIp|fj?1MT%V5pZG z0=FPI0C7Fp<~6i&!y&05;BF|D$>k;8+yg5|8Ne^i15+~oJQQd)DP;Q5Gm=_zfeLKz zTU!iGu`pk7{B`v#LZoiMGNLw=$xGr3nTv@F2+9NneS+zWDtG3XH}mHwCwfWS>*-#& z$H{MQC%)Yj#;YL1lY-Rf@52CAfW`x9!M^U3*W(1!Z1f^7x)?mfF7*=~MP((H83DX3 z!!N4>7E((8t<|beE&sUG#!0qfkct_M^Jk#^E*Xr)*;#Vd@k=hQ$yhK<=FmRb2TaCM z{-~l>pi(;bi97(;0HHusq?Js7CB8i^^{Iwb2O#app7cD9$YiB0=LE=A?K7`_73NT$ zu`4^6V_!=34oBUCNgOk%@iVmae!J+-tY|ymg zAZ()-c@k3OcI_vJc;pC9g;he&iK18O^8v!j%~rW-3zg6ZXi(#b62%Q+Oo=C}bX5SA z&~F(XtG?ijA4P$d@`T!&%}(5#dX5m!oR~PwGIkP7f_n0{ZVY*q6hpy@K@bLe>GdG& zEzA)v-e*13Ye_6d-Seg!D985gDLiCS>cAAgxeW7ZBiGT&jfcczPp~@3AD%+zyXMPW z8UhRGG_KC}RcR2ZpAs>znn@JwhHO?U+as_ErT4>Jw?aF(4UUOtRdQGx=$KJS zp*3o>E)+4GR<1i%t6lDsEbk^L=jC(FEBT&v(p5_)G{j3gs)*Z6 zu>S?t-nq~uT_u(LxJ0x((E7hZWBBeuVDEuG5~YlMI-BvUf$cZg8up%)DW`HHGQN0* z6tVtRE9{qncf#acfIrzA$+L_Ms#X2r3;)%3Lf)G|-yxAqx2)z1^%fz`0NKM!&=>9Q ziWQ?MZNIz%DxpS5rVskf#iXKB!ql0Rhadz|!9_A0i-Oe!!0Q$4?#fiC8Aag>^04~h zR76OWdKk7qbO9a_2_@+X5MzxC{k;bvJxV9KNQiE$2;=L}g$e3nd@yUdo%_aozlMtD zZ68Pa;upwuqOO6)!lRDjjny!HcjTN5zW6c4_UI3sfXVQh-a0Q^=vVmA}5ECnln15OAWTzOXjP_iLR< zRVPKIZ$XfF^ah4k;JDf)w=hFXWWq8)oguf=l~c;1n*Etw@g=(^LM%U%5}occlO^u8d{m7Dr%g+o(^*-Ujfy>@NK~ zmOG_@T126hkXi!0s)PCSK;~wO`hb;;*B2DLfz2xPmz(s>jg-rd9cn~E4#z*CI46#) zC9XXnGNYh>>1)NHrq?bI#*i-=v1|2$Y&IW7C}eaj*_{9VN8(I)uxf^w@E(T;8%7mt z3BZEnKJ9&S37K4$M?SK$NHVB`)$5B6OinbIL73_J=d{1~MqP2O0uivyW(?@h|73XL z!yHq8uS6BLUpAi@Tr%a({Z{sEYW-U?;XzO$jP&^_U$@5l7tC2Wo%Asi&hMd88$Qa+ zTC0_lTLh(fJbEJ%b^@i|1tU=hiM8$dBrLpIedi0|%Z2v3ZG3AH;WO6EX33I$cK~@W z*Ny5p46GKE*B#6fCeV}y(pn2RZwzed(L_xxHz0%a=bpH;Q+!G|3_ac+tIRK~@;)>` z5Y5vuQSN~r1RK{%g9Op-a4 z3tMw) z#lSt*VqyHFXk@)2+2yk|aFTU0mjQ_(*~32|LSzW^u;TTWK!rZ6S>Y^;6Xu+-55!4{ zhcyV@*Ux5fHOyI#EC*6>DO&?lg{DAefYI$+he8(X++Uk@G*L&(9EedDCataS?{oDO zvKPn4W%x#OT4NQcNI7Jeq=dPE_;hlsy#taFN7O$27;t=knS|)htSWxF2r%@KotQ*y zp3IVt9qZs^b~r>q6p3`so zYWmLwp-~h1MaeZha+TCR80XvT?ag8V?S3^2T;32^(IhY@4UE11mXy$g(^vDdZ2~{| zb)u^6$JDk-=h8ONN_3${gujH+6XstyB-U}DxXC;U`c70d>o1uoOKOucvx?F?j9m55)iXhj(+7xv8gLkqi|$OzMN8iUygOIII28L=F0>@NuaABK&Jr^*BlKFp zf|G4HheVX*-BV?M(<$$O0AeD>WvYC5`f8^PazR)^U25FqMJW4QHk`m4KO7xe8IeIj zP!uRhs%8`bDo+H+Ual0;^<97&ZI9loCA!P6{D5lj&g-`t^fBbRKd3Vv>ilZ1wdcF2O@hEO@4 zLz1t}>ZD>!V^$@cq0!^3b1#~P;Pt@lF++b&Oa}IZe#bM9zBq52anly6(&33N2|j_Y z9%xPmT2L2OO(Vw}Yqg@RMG*A=6c47=C4NGg;*KLx-~nDSxreS2N01XizG2}KXCF}U zj3Y#a!!voWl0n|Y=ZXmF<}oDMYIG=U#>+S*H%!bHo%ZT6qQYZGBFV$+>JLZ5xU%-{ z{RTG^!Gj;h^2DHK!y%K5*y1B*iGfI#J(A(q;3lQ@(}bF-j?_)tjfgD)c8Wu5Q1{M{1Tv+%Y_n~N zR_w8x>Bm-wqhG+n{W8&BroTSKs!2)Vo_edG^ufa;vMIdkcShETew)zLEKYnWyOYLe z{k-^dzKi)5r1(XLh2!EI!T?|8(My!Arz^t?jR_y;uhQNOABwPi5he>szoT$%Pen=V zl?2jC73a+lyzDcv_wYRZNZetDKzJ90Urm=-^^Dh#1z{ADQk`a?3@uuOZ>EW5VM{%g zPPKXOo#4HTLek9>-LkX2U9LMx?Wo(Yrq<^Z{V~{xqwPZp{?o|h-)yjh)vuf0LEu4e zJw`ea$11?N3Wu}q{|Km2)|YP~u}V~C%-yZNl6swyGzYBW5mJ)Ui&C!(;`*44KS%qs5G9&Sca%V^m!C+zfz=c*_??dcQ2k)s=m!z`lBV${ zR4N@>BA!*}pm$acj>cc$Mr20OT?wvU8@k)nn^RFYwe*8-pW=6H(O|g!b-tVUyXwwC z4BF|N-F3s=yAiiX+DIGu1D1{Rqr>Zr_NaXdD&cJu3AusXp()%$wHl>5{ni)edA!Z#R@k&9I3rFA zV3AE&@#WZ-om~$C29tHUt3D&(OaA%j_Jwx_7v7tLVl^3lC9uDG*ham4KIi!@ObX>K zZ5CI$a?3Tw>2&(bfb>}V4YUDV&7Pxl)GoJy7qj9EJ6Ins2N+keGDTx#{t)nj2bAj- zJB;HW`(jY-SX&hHSn5_&V}Q1ZzGURZL3*;TWU^xTMX?fiTx2A;mofw%#esEx2qa8; zd~+{(7r%kmISIL;%KdYM1q9SzMTi0Po+RQ5f!X2x(YVmKK-MSt^^ z;j|+@A=7Pv*hDuZq+3Sf3+4=ND%xS8p_R(3V*0+%0UyYI+Z8EYYB2D9K%1X3;8-vj zbHFvO7J1YOP^#dml5oY^Tv1=4>MoS8GUNKeabSmmcsTK`XuEL_MBWj;7d^`33&Ar+ zkoD3O1gwq{5{E~RetQ!m!;b!Vk-?ABH_v3Lij~G%eh_*qZP)xDQVRHhK`Yzs$t|&d z9%WQK{*@?`t?sASGtA87zg(*HPaU!-53iTbBg7+J2nx{|aAS-tahEPNqJ;GkKoYGr zzVWwSlBk+)PhUsmAG`!r7xWi}>CrD&H}xZbku~)!FTuR(E0QX-Gb8RvJeG!vN1A#> zSLu$zD?Y&$M6qZ|%$QIF-^G*xJXF_@gm^B_y5(hQ3dlvJb;z||(4A-=H~b-x=Xu`+#E(<2kdc(F?7&o|@2V4B`S zDeCQ*-KZq3w<1+G?n77B>XMyKci@C!vYaItD7Q;xClt>&9+Sr>L-JXnO_QmkU&$~H zwK0tr-q9XZw)ETjYdmma%e=aH!;z=)c~?2J>X^a7H~=S{?iaa5#!+D-C|B145N?rI zIWyc(ZZCThokky_j97AKc2@v$Sm{9stO z!sj(VF#tcb-J;HBQhI(M4vFp*qgq#xy&tN6%o))-sbNo z+87!wa(LCFV(=viyRQwFARs%Nt!AQdu<3o(R#&FDgm=E_ecnCvQxP4}Ow%|hrUr9Y zkaN!{S~vw3&T%N#aZFN+AIw9WA%?Z&M?S8Q~9LqO)sb;Y?_LwK5sM(-9)cv>k(eq@uqqT135p zeW4YsPTVKuk!x7Q8(5>SR&;L>Sd;nwOSR{3Jx9uto5wgiH$-6Q{73uFQVShnOwTIs zhUU`bsJ$zb`VEnL56>f!dtD6A3Op(-_qcC;uUXSA{&4l5C2dw2_qV4kHXP@f6-X{E zCvG;f*}s;j$*!x?qPkeHu&zZ9P(+L8tizoVVlu&*k@R|U-mqi=3&VNOZ&DUp({bDa z!Vn94UC|`L-|1UwbEa&7*nSSMr4`RI`k`U98xndPs#a>r74t@z7sE3h1vhTZ5Y{=I zKAHMpe3Cp`uEAVB?FlDu2RY-&weOAxsXb;*GrggU{HKbk9qQCD${Jn`WdOUSp+?!l zOi_p-&%iywonoXLd5lygN&WX|AV-boZoNJz)sf9#oHLM(IKv|`5We`tWT5wgvT{_2 zZGHTHoEBQa#XG&hA=@>*E9l()Z(buD8 zxOUbk4ivLs{G||=P`Y5Te)hvQd0Le+IA%^jx@fSu@zIL>io3E?a_v4t?X~da#Xg!O zpn4I%pFFxg;R2LoJH$5+n%x6K__hnDCjq>m=QBdH917}Frgs!3BiqP!-ZJQR_mLM_ z?n0HG2h-vNQN{}YKKAv~z|4^4jHAC!;V@?WCH)?fltsD1 z!~oC2PnO=-5gaCglyVPODd(&UitFTBFnR`v5w9pVnolrKFeI9KUT`L++A+gs*FNo; zP1lSk~NHYM4@gn`Jx8`uQRSJQo?0UykrOZ6FS$VNd7y_qn)q zuwZljqp+HD`Hi*xZdDWq|B_aY9V1`uu*$KaTj_f%ym{tG}Iu;n^Zieolz6kkbLNmZgV7U6lxMYa$NEZW~cS2?{MLv!9eIpqe9wM{y| zCvzXew_t8JbH=G>7PpHFRAe;fB+)&eONQG=R3SJos zAT^~23$!X%))RCX?&~aXZdGsDpP&#^@$^hBn=ol(vcvN5)!g=+jccK6J?OSU`q;75 zUiT?lac|7!yvK+0xYK#0>c(WnzK;w<)&Px`-)}*9L70}S(55K&_V^^>6E0~oMe!)- z=}_@dKB+buBKfk4G&#A!@T5s+)H!q}2e(i$HMJajsV$C8TkIlQKQ#BleN->p# zm{r-nq2Yyh^4|~YHg~0bN{$$>5=?+_K&x~mHOQ5_xP6p@68q~s)vs;C3=1b)3O_q% zXUiY3J~9;>CCQB&P?r@4u^w;cpSd@`gqJM&MDLc`Tb3ylA#>H^Yqw>H4wwpFpVDQvI!6c8`~WUhUtV1<(cHeznP#z8Nvjbo9Zl(B$-SPSyt!=b>JBb6NDuKT?6FhP&vM z4U5Y*w0m)Kk}N1+CC1aeTJQ;q#X-!92W#K&q3xE(YeKaM6MB@X-YWZu?gtb6oouP|?9BMAawg9ds`3Ht*Vr`BS$9YfEb|4)`^1BR3c3mE;_;D32)bBZlQgqvelI_C zzCn)^P-Q*5Df6B6m`SEkcA8 zEE`BHKh_oE)xwTVS*2+FTzLgm0uO%-E~oi7rGg_WYinzC3=5ZzJXlwFZufE}RTT=Q z>C6f-XeN^)S%qb;u-{KPSb>ns-VTCh#^)N0r`^5IwNq9PF0W{Mwo3udjv3Oi&9i;- zX*2Mv7op`p__6kbkg=Xmh+NA2G+OG+5FF@sBOlA9MTs+yX(RRZz+$B%Yv1=bWHcj0_vU>;ngJ;O2uiEU%_@KhaXN6mz1S|Y|%kKz&FC=vGoyP3o3 z3Qeznq$}+RLeSHKU&3|8+$@(tMzFbbqB%UYxnwB!=f)4S%cEhVN10rB@Mk3dudnV`0lrj&S2Nm@S{5AIQ@y&yH8AN@muBwB zd2;jg$_@j{(>>#Bi}^_qsX6dTIMHqhJ6oiEaJj#N-W4QhHZmn3PCX&`+J}xLi8$zA zs%6Ru^r@q!3*G`x9fVg2zfs*AylB&<8i!jxDcEYYGU-wT{6CJHXx6N_$z-2VMWo;IluZ<`Yde;s+ z>7ZSeW`WlK>?Srva4p+}CvR zh*qP0~976{u}U_$_LBzALIQ^3XPyr+%zWYP)~5AF&@5N>ej_wCAjT|!$>;~u9pG67;7LJ;ARB_ar;u8Zvj0?ac7XkSR#p^T&SioFc zWIg_~L6y4inK2+0Lk6J+$6^t)_4gWw4)Cul?ws03tZj=d6wp_MJSYI3olD&N*GK)F zeGAL{AmrMsjuRL_1#$o)tn7FVz-*8A3dI5~<9BcD0*ExhR%9|UD2srGajO2|;%R?o z5x;ejrF8)(_n%eBz=a8<%#K$e%jB68%DdpR9@YOm2@I-iqDDOhqf~BGE|Dj={F>hE z9Ed>^*h{Cm{Eptc+=sv<#yjw{8B@dE15u&)n-)AEqoAz!ix3gwYIlS@EKq}GuFZ%# ziqCoD9rI`?Y%Z}rLa^MFCO%Z1d?-AaiF29d0LgcP24jd|S$Kn#VRyhF>(gS}7>Q{R z&VHdR{3H_#Na}4e0nfd5ZwO{wH45Z%fu*DBh&Lm&{XE zpxbvq$YEb0Vi`H?uN%^)8OKPPns!x_+}P5yk(XH6D`t%KtS}r)5_-DizG`)fQ{|T5 z>xfG+3@ESs9@CYl-(17?U3N}8CI;gbcj>}PWI*A*6pTkq^Z7-cKesAus>KO+(|1=5 z`o8zoz_``r)6r5?)=j?Q^+L98@pjJzFOf)Fp@4{h{+Od2f4LF|`(cf2Ntup9kQ$+{ zQN_B@d{>O3@ImHq+kHvN*mnwkgl5mjDKHN@T^^{uh<2=TyzffOIlH_vzK>VU*c?yY z9sT=9^#GaS zDmW?w{BEX!B^%!RExWXQOC*g@m|fW;6cSiq+1x@EKesH&)yLJ_#Z*hkC{RXc)a7~8 z?aPle1Au{OPve@o&kq9@=Q0}f|Lt#tH%WN0IyBdiWegOkgCTjq-m}xz?Xw0|8o3M4 zJF9Z`LVHZi^R4P|j=!=N5olFX#{Zb@b#_XTt@pNeZ8w8}p~5xe_?`Gl!fOlH7V;^Z zY5eu;zS*f_4?QI7QAtNMR9AD_N0D74imdtY!!H{3@s|37q5-6{K3 zyOxaIzx)8Dt;Om=gYO%QV`UMeFHpIqBPvAdlAT0bFR#(Ne!J>c5^pq}6ujv~CDIn2 zifRzLNwKf#L>Rf5m_`-K0;;wsW(?UTVlHi^3f!>bOc{J6hL=r2^W*6M zR2{__bP)Ax-Wd036_k+;@wzOZz+xETfTQG2x&2+v z|MghFip_oR|FUA%MPS9m2sKLo*NRcY;{yJ?M7Jzhu?N;XxxfB28R+eJ=yLs@C}_|c z?l4klY6Cug2VvU3(+>XG`q=x^uXG?Z2mOG^(TIV||JStmxRYz-AH3CneuJs?f#v{D zbm)IQcAh=$&0ljs4;VFb$Ugmk?^YE46yU!5Yo&f&1M&I+iPya`E#v<+SYrGs*+1Xo zr2uju%wTYUW(NRFS!wpG&vY-Yn&+LwSj(3bm!0sQy0Gs9fD(y)K-3LGe{y%SR`3BT5h60}tSB(#6O z^6Rb*abUenMrUIFEccUyb*wk=k@(Pd~jYH zEL7#JQRcyUk{L!A@5|r+`HxmwCM0XD2*HC%v;g6G7Q1)W6ynkjZ_WzUy_Hfg7#A~UcYzk-AR z<-q^(^ciK|dEr<@Q&H`G*%?w1L6I+uXpb2Ja?t>n8_Pd=ZX@cf8NQY`*LzbRt+=O> z>G+RMKp!V0G3U7gGJ542n}JAH4iv>J&^Fo!9SEE^^_mD5n*;rEuL0F*rvT{j4yj+e zjBNkJ1KYVwIX!^;c3J+u*?8b@+d0uYlswsT_CKN2|2bRP z#~Np0|1<3RKR>%48ZCSi`{06qz)iHev~S`M9?D+2VdCN8(Idt@Ww$sYG~rS8EA;p) zTB}Q*Do*}cL~fPp|J}mzQQ1upg0X>B@;#Ejyp(-E`#y-$di8$~yUrf( z?_vK5SN`^wiB&!h4;#*UT!A>1{&AT8XPo$NxJsR#8n0RcKqIYyhb<#jb{G&HK4A@D z4<84RYbQQ)sGEQmyN`kYhyawnIx42s7LMwL>Mt47omS+QRgr(a$L|2S?1{&RAA9nI zwecfF#CZG{1yh>L$A}gN>tN)ecz$LMc&Pnu-oq&b7v^flLd8F0%zNo1(!LU&bz7ga z4n$SHNMugGu5`wt38YN_(v;sRjD@`A)7p-NhF%=z&~C0PqdVqAdT`S>son=v>66qsZQ zv26n4^+%l9t^c)A#i5&G^8C`zfOwPpGZ-8X z`BJ!GShy>I%E7nBXO=JOO(Kud@>LRG?jtzT!VdKcWiq-0NV2(0Je~1VhY+4$W)+k$kg#^> z)YB{Ybv)x1RDGFidmK+d(yeD9`u~n4Er*bu7stR-AK|rNb}iN!D=TyOuKVjJOL&I_ z`EYzh>;nnufhjb}nQr8wN2{&*`>+@6wyLz0jt!{t#8HJ8pxLjcbnooUGU zrT$uu?^yncYc=utROOvHHeiknOr|+l1!qpNl_&cO98^!9Gs*CV7q3C0{g8^ zEZ95sGD>HYq})or@O`;?&pGIU>s4ZuMLXr~s{uJ9D!nq--{kp4%}v|pX61H{DS$|I z!R7HAy^KN3&>N@z{nW3)o}04ciH#?rMicjc)GwA4>pge;?bd!LAKm&Ol$0o`?i%po z$um>PQUa0=01NZmH41`122E0R!nI4=!j^n+4)%7{xYR^$2jv#Exv7W3WrLAzln+sy z6nuW5HH)1G15Wda!ZTkI+ff!IPRVRVtL*7JEekGO7EVGoALW#Py^3 z1@4EMuPTHeDQj^o3)(pvmEQ>mRKbXwX|;`aS(sV@W%&E1A>}D_(qs0x%owB*2ce12 zim0DCMJ8{o!a9B!@E`lP;Yxx{Wx>L`|i8t<_TL=(`-QSQk zS#-uu%#(;c1eJIP=CW!7P0P~H`5pe}$Y?&vUq_>>IvYgx2FAsd^sx%#HEe?d%S&Gg zr#FyiTsiC~6V{dJm1~%`g3(#XG>_FvQWo0z$Np#g&p$+cyCak6$dckrT%+FhmBk(} zMA1z0)!V6+b)y`&vJvgPUcmptx#Hg5AQD`)RFz>rRzASvk-h>^km$pBlYTo+=+_9* zOsv(XM)RZcrp4D2mjrnl98^VN@l7|otVcAV1fj45n!aLm0ERlGMau8*mEYM{!YOGsLm=@)%xtXFCmt){T z?rOpk9nL-9?)&LKQ9n1Q4}CnY&EG2K;mT7&d&i)Dk0cke$I3z!x^pq@@X-hu(E2|D;30VypuA3kxsuvn8NDjrP1W zk$epT&t7hQZWUI^;9UnILH5f`2Ohl)|Pg-;Q4z7!#X#$WW(t zL&>#9X2iGaL^*r;G8^VCk%f)U%#juT&PN6PyKjr~DFqBuyHoemV;>dt+Xsm38Vk(E zUwD*v4THo`^HAQcS>0w?I^ziphpK099Mih)x2DezdA5v~n+|#*{)tb0o*}JOwlM7e zZ7RirUzZyji8IlaoQ9o`q&I-sAW_HjC$4eWCOM5qf>F7)Dqov=>5UO(9zU$msc&~R zet^>PIk$XT8r(%-`N_A^&c!6P(~0xk0-@t!{;n5G*gP`-D*i$WKtmOFj|Vq_aCfZF z;8`##NOrj{XG}v~ng65OXbc#}3xVEzH#YNj>}#AH3!XZ&;isr`!~4E;%A6(9p!@`& zOMtEnk@jBZud$7Q-D-j1RpQ!??5YU`y`luSmuF5BKC}pTFZu+;<?vTH9<=dP0qa`s2O z`&<;(*S9c}e$OQy^HizZ^$XSA;vA^}^rnDKfFH1%xS+b+!$8;fjZ5A`d))Z0vi@dX zHyGRkn_t+3qG^!E`WHZD|8~pj%d5Qi@J*;Re_NS@n2?zdM#_WhBUC2nOZV%`e)D4{ zP2qE|2bjZoHZ;yB#&?3MKY=)t9~MuTwmBi*Bttd-)=>$H!@0@vJr}En+F8*(Q>+Ht zDY>7uAMCGexHklza4l%UNOpw!-}&+5PIfk@@5nQshDpvw zIlE&;@`T@V8_Ki6{JCnMpq!>ZoNa!kOI>o6H;KBbm_7f^KkixDS2(@ao(SEIv^Td; zMyT5)PKq*yE`T1F8FLtRPcz@ykuGk-lzd5S@a~|x(CoELa$sOL&yixXbK`MU_cTu1 zA2i3zv!%ryM#&e#(V$0!Q${uDF<{mjX0$$cq5_nv(mdc9lh#abnfeSqI+C-uF1tyuZ{lx3I&fBn zd@AB`+;TClU#2@gc%919U=s1C_F*MQm$PyxlHD#@?Z~jYI^CPD0*IlJqk~>4>PjNZ z-EL=qY%Xf{ zv-xSP8XB-4$B1sc=6&?DWS3^&H$qnX{0`Ade5QiP+ zdnTWthuU%OG>YYi=`3psd=5UCKWo>k=K{0-&q_&uaJ*Q8r17txctm#|)(h$f5z*k2 zFRS(1ta%rz68mIK{QE1!U1I!2ii*rC-mLvGp!W!uJYG3ZXyIBx86;83&gPP=4gg(BLwD%q}4V@+@5W5@7Xa}I{M3vGEM(C{t zD=Yq!CT4Dd3v296m;G$NVTUMeNIja4r1l6k25>s-GtVRYApoV*_O6%4pAbCYV;0kX z85V?QL0D_PLVn4X2||B{7hPP*`c8uLTK@nyY=6Btfvb$msOI*+Ol&C=7O;@fck zn%jto)3*(r5$+PzpLsf%IWz)47{?;`=7}fFzmwXy8J+QSt=CAeugK!_$THqK^OXv} zLe})NR~8;^|HoVbF+z&Me(bk5P%5Cuy-dvS8t!XSW-h|bW^R%z;)G~lknnE33;O|J zIR0I!^RSy_I5HhdO!qQo6CzWws1%g+OiWSgmBbVScoFf5mSpiG8tMnCNI19_99y(D zsC4ek5XdPw6gqI>!<=>*x_9k5e4HG|F=&56_!>rz=(C9Zu;c)MOgjDPtjq>PxKSQ* zX#yGz9*j0yB<;x$(?{f+0J0}JTK{&R`FGL?$LoYiu9Oyf?f*%VMpZ*ME~W`o;Dq%l zqo0H1a8QbOBW^~QN^JVamz+E>Dmwz*h5*v}5Wf6E&)w}lfP!T6<&}0*-o+OyvpsoE z^T$t~@7n(P-3-t~Cx@Ss=n=fJLp2t^=$bNnX54+|^|Y<{qU(SiL?g2E?TI~>*SW0e zP6U3k=bT{iAEUi5&$RfbpiPhF_DO8QUAXtd?@{kN1bbZVX|j5R>u`xo$n>t$V6Lu+ zUa_T`%uZVSfv(h&O*3zc(J6Pd=>4jW+BF9lmSOk4e`;DE@$%v`dRG-MV9*~Sv2Y$V zwqVb(R`C^XO+g7Xat@WR01d(dpz!Q`6Zwc!oMRHRdkR1@JW9Z^>OPQL8}FYVEH8#| z`yc_o5lVepe>bIc%FSw~E4{>VN~JdeVv;%=pn(Y!3xkh+2j9KtDq|#gYjS#8;>g2k z+n2qodwtvKtBB}nSKQN$D%%aAi+(*hyNwjBF*U9fClt;e>bL_5GADuFJd7^s!sDwj z#3{fT@Z>CDQc9m6U8WUCp}dFvCB78>fpdBMWo&%h+z7krZV{j{Gsw8Fya*$u6|4>Z z?n^-G_|OH=q0NC)oo@jT55zkpwgX-Q0O}nt1~9r`$D2Y+*Zmg*08?2{yaxa<$i4CQ zmR|VL#j4c^mIeDx?8b2m>p)$Cpj`mbTM8u`U#KRH_m?dyD*NEEupRPEjJ*kbz4zv@Ilh*{uo_DigKhzxCP!f5Ffr}@e(PuA1%MtaOn z3){zy8~pD>ne3aFgj#N^o}Y}84J#xgm#z=C{NUiCKk@c;9Do zc07Y*wK>-c>;TVP$=Z)E9p64A--c9QPoCaDYcyM)?LbM1^+(oTY0T=}_H03^)cV(k zQ>*n>$C_bsZjHMWk*MLIbj(@uF~6lBR*&#o{7%wKx)km(vNU33Pe_?tJ#`3xIIQe; z0ECFdqSp%V6eoU4M=otS!GF^FQL*q(ynEB^%lverrc$zXtBkKXMIFKg5&o{riYqA@ zBx@$;jdS88Vbb|@W2uGoLGHvf0&!%_tzwrvD16`)=(5PG7GSaF0NB?Xz>`=DB_aV# z$83)cfITgUJ}-^krQ*|}O=W?2wTOFV%K>xPS3sq3%l#d4IFRn>B-bFO(4=7wkX4?w zWWFOHd2hb|UXBk#!&(p-oBnxL%xc(rD+=`VO;mQQ?g>3~8-C0XK#J@=a=+3B*$N}<~jdzLzs66tq;m}%SITqK71*Iy%F|MQJ>0> zO69JH$(LC{Sp)#?VY2h-}+_3*rAGh#SnT~6K-Q-$IRuMlkbu}1X4ipEfVZfH;~}A0lbmt0I>A!{x>h5$a_nB zYoN7XU3IwI_aJ3@o!HG4V2SsNvS?)L`bE_*KA*Y6>JM{eyUe7TMtv~MNAQiK+vU2jCmr>%jdc7kp>h87I?emH=% z^!_@=?==f=v9`)-pH#0sz+X<*kfrwI8{7ka$InIB0RzE-tWyD>5X zPLSWs(MW#?cxl`O98UNAY~xD(`uOba625>tC@_~YHI)cuMe7SP-L}`x&%sCh-A@P) z)Ykk2*b83)=FzS97mUvtXxeUBy!j`@^|2+KQ37Xd5(pbP_NIje!-vAIw@tJ}ikb4T z^-w3YO{aRfQ+ ztMRNR-VnJnik|H)NHqYMdICBqf*%mKD&kl-(B={V`iJKmIg8&{lNb0qjXPGPfI1|D zE5+quhd|?T0{i2MRG(gH^F24Xm@0`Gpr>wKB^oI(s4U@=Jtfc4BWO&LQkp5S?G8w0 z=rODT0ngfh+!!bHV~8Ukk$HUUYVqIp6kLnT0&D(Z@JAylrLQuDGEdGla1ABKecyTFTxNlepW05 zl8nP3c)91>ol6nOGIhppcSRCIxXYmuCuo_pHrMxg^FD;clw_6CmVXJLU^&0W3aRW9 z4p=EB2pEK20PqX5E28$pgAnS|&d<;4wg6S{?z9U_ z&&NboB%Ic>^uwl0$q)_!EWqab)Xl+Ne)lg1_$~>e-4`J`-K(W%w?=&T2ruqr$0otL z8(jO%n_<1@b^a8@p$w!8VK(r;(RSqA(GezrL>}L*jcl9M@$6g18UhEds7q;EC;Be+ z%hHH6636Nuaj}RwQQ#$WZd2yibevq8-B874YqmEnfV*sJ+<79IPnb2z8iv3bd91}# z1k#+oG3jSqLpoA9i0V1_7LNQPtJjFU11J}DUutERq@-N9_iCWv>dP3i&$w4P`NAaP zL5o3~w29?45Y~zQ3{!&moPQB0tvssU`t~HCRlTpy_n3r3YA$URfN4X^<|>9wyAdzC zzZ)nsd@2{jgc%s0T6D$P2nlGMDIVV({#oUf@0v1gsX#^^B&pKIrJvuGFEZ7HBghasJom6;DRp$x4C5vGw&i1hEH6| z$LlU3n5znx-IGPEE-zhp#b_bwqcMg9TS2Hk2g&vhcp`TCw5fv;hFUVUG;7OG7e{Jp z$O66tLwpwQ2;WBGu%G<{A<)Ls^o+y=YL52USQ49zp7i6W>9Iv+tss!|>NYMu52&(a68Y_35@z%GL7qvYS<`$RuiRLhnmdqxiN#`VP4_;FQS(o`u2gwdt;t#u3Krw}`Wjv1*P}l3 zt=z&Euldv^-6<-cAoyLa|D-l@2%(pH7;xt2)_`31%L_oshbS@!We$|u+bf=Q@SE+A zVv)50uBx5U8CH#xu#SW?Vk9b&sJ$}c)Q88;Vfw+PHGt2|B(uyszm{X;4i~I&Ntu@0 zT@o~MSvDhKKCN5S2=GoQjM#+YSj~}r#Ke~ZH!r$xF4;vs|B{?I1;Tt+x;?jj4Zdw zD^ym?!UJq6zu0ns`k#C2%PWC=3D(mh9}yD8#&xjO>Q?dTgwN;1;eZJGgjwEEzj;6g z(dmLIxc<7{6F?=+(>Fd(Icp|~adN;BhRbfA48sRzbwB_YaoJc^ztqkky>F%i&@xY2 zGEqI|i6Ev;dZnFX`TlrN=K0;auV_=$qoQ^Ol+WGsuQJApxjfOl{|S+h)-Z=)T+^;* zOazmb&pYBDPZ96{^wI^H>k&G6H|SWdBX%Hi2;vQ*o9%^A<%N!#71!Mz2( z{a1+J7SIPfK3pxb09;97v?GXO={c`+>)!#VX$gouD*LG4zcW@#w0N@E1iT2l+y+75 z3!C8pWAj^uaQbp5TDUrZl)V&<|9ONksNTe%9qScz9IaL_ zWA5Qlayjzq-@cS*oM~ae9+ab*1(s1{#^!iRaQQDRus-RuY|If!{ovh^XY$0K$7}i= zYCa1QRWWS|5mIFxDa9i%6*N{g`TqB+9+$aJcNL#zIOUUU1r7(b&w~%sMe?ve@ zPg}nNu%xWsv$OmplF3))PobW(jg(J0} zZAmh-2T|j~iCzl(BhjMoz-{IL(Cppe-FHio30r_C$pG<^SNjz$0jKF6g)d{Ilbl70 z+UJ@Ka$}Z}2Wvm*h__5f-5^Ffz?VMo_`%N^6F^P$*d$l^UQo)Ck4T5{=F*s*v(n~U z>xiV6=&i0MFWC-QS-{1=qe&U{hfBwzB!0l4c=2;vE1T$ul~6~IL26Cjptz0VQ zO+6;wf`p$gGh`$`F@%DZyDp5u~xL!TaA$Si(+Mz63_FnffEQeqPiEP!JyUJC9t5#QNc-GXpEQxh-1 z0lf~avG|FFLH2CTK#H%?ON(y16sVNVJ$}5fUewy?mQmh~vtkT*>PGLL2Yvi-mIKV^ zAY1KDD(2xJ!&VR3ZN>i>o(4!z?FUNomY?%BY`xrJjbek7qf}*Hfkc3wWW5Sd9pM@R znJV!`z>gUK1mNT&(q9ra;YbJq*sT(XFvJM%4A47ol(nFaY){6j=W1oDoHJ`Cxjj_z zmTWe4m0c274zaf;;`E&thm$X<01*&ZO0yq%C)9blLt2i$=(lx2>yUS)ffp|dhJqVb z85ZVT4b0M5Lve6cGe}1wIeZwU9$fFuH+cTO+V&g@i}5+eIO8{L(hyLN6d3sSNi!db z-n1e>V7fs@FHf)3&KV?jY$<*mqjuSiWDxtXv|vGGEDN-(g%77us6ukxf*-(pMhM_b(i3KS z-*^?E2LdHEgyF}kP~=H*UczNK+i@=s&uSA2Yf zgY@W4DxA*-faEO_@-(KRq%8BO2DvVCCj8-%cT1R^i)YT9Vez#Au_xIcmg?`xpC`#^%tc4xlSC_TAp76+i+O90Sq2V&VE8W{g!PTyhd{36ZTZU}*A;O##-}3o!ri+7{DeaG?IUJc^fok1hmn67g zevZg6z$#wd0vPa>U^@+)ZgAo4rD972-Aei=~ zOU(1*s2Py4Akl1Em7Gwd8Ln&8n|cfxh;QVh9^u#9-RL#_mw0G*$fa1RaZ*6@=K_Ze z(s_O045%$gzXaPUtQ`%i4dzO*h6sNfH}}$q*d-yFgIP-ge#5G-^rF^C2cc15jC9}L z`to$z%X+KCcA!Ew#X{027>8MX|GF}b2JE6-=32MMHPTy8;x-=WknpjlMC&7N(uA-?s-= zZ(RG;CtYdpB{a~jm7Rd#Ve|6M{x>(}eCq&#@?6zk$D`Agon>2gGKk5_Z1A*ZCshP< z7_99P^K+HDHqz!MsZ3^Il0`mHJ>oXHDpUKtr2IJfj%PatBi6rsW$&9AdCMEM z_KprG)bTzp5T;TG{;WD>|B|cU?>fD0J+bypzb%qyQ#w}xd-@fZiTz$X)&JoyHoSuRHu$EYS6NZW{{=Qj@MJZmG42 zd#i@uq|{IpyGdj>m<$IDD(=39ke-9SGYX6ceEZ_LfE?|U06_%6_jMMr3|vwTh#WSW zD+LA!GB|!l=h~UKSH&B4BCL|kyfigZc0q!`{@P`(60X{j<0?mW3UzHF#B9~ItwLnI z7e(GVxf-pyYCf%S%+DqGx4DlM=>l^I#kHNJlex6fDZ@HWglb%>kVDJW{scLb>L7t= z@^Mv@U@Ss(@80^ZC`f+UdWJcv674!LdRDO!gdOoE;1OK}5ad)3tWU;bW8buu?V6S7 zbG=^VifEhVYLCL2twaarrJm>9YO!HE6_{#9(xzhD|K_zEhoocZ6PKQGWy!2)t&9pJ zojX~y2YCzo`fj5ThAeoeT|~)rM14;PBg{&G5fAo2$zM=-8Y!k}Wc`eByUrs+ZMafW zRx+|G!SzF&95a9#K5_3ycbgr6UA+wgUAY1rgu4v1q%GL?k=%Qq?T3AasBs#r;M#IDs@Y#*uA`l{UOyP$7U z-=@cQq9>V(Gf6S4`en-RvbKiDtMmVE8rKlTH-Nh7_+dVjI9all=dnz_?4H>y@1i!N zsc*{!g>kW%HpkAS+FKiss6SoZ=yOyB({ggvtXnu$twHP~H<7 zP-+>QmRVGOwn2CMT$WOmsZhpdGs%MZBL4mh?phu5@dX1~i`<4#wSD?&jwc%-Km$PKZc!^nK(-_)yquqM;wMYQ74xbwkl-L*%& zWrL#4YeAOOY>sAqE1-`5vD^SVW`MP)Xpsvf1<4Dg;YzQgorCOb{89MTFBXru0uiqj9bAw zGAogN+bw&=wIb;Kt8@$vCef>^AyE7kNjp2Nj>CJ&=$YJPfn?8->u+zxuVN$5=~FJA z8up65Sm{3DT@xP1r3X0`PEf&$zWB6V&93vM#`7K#(*4`dUYCgQ>ypHH)NI*(^Ef%E zetJ#yk9B#diuM52^;Sw)bbOTR_v(X!XcPMqD09<=)(*Q)Czss(%=x+IJ@Zlvlh;?s z`2yJ|ex1PO%~a4i8GpuT7_gk5;Dgl5kB+r^mwTnRdp}$ToTK1lPpOALtR0h?h)lvO z<}ekY^n?BQx2ZM=%}l6-JuzvknI*^UM3_-I4GKIZJBu|V+iSDaJ)gN>q5LF%e9nqg zOBAdFgE=LO5a6xJKN^T9guM@HTTn{Mz_E>E9k9LigM5PN!f3reG359_6cV~X9h(Uh zz;MV~=2cMC82|~X!8Xt^&EP)d136oN{}e@d6M*GKy2HqEzFv{t4R{o_S5D%K*BZPp z&#&J8k>fm@SK1G(sV%5Eop!{oe(Nm$_*}74^3;X9g&^<*4i5YY9_#8;aVLE)8W8CC zJr)PrHP3OXUBJMhiAsPnxTDaQW*iHWW_`{OmsxtDbCf|sD6`o609;A)q zyK1U88{5D`T0Wp~?yHh#JWgHf(4;^w8I?O`vTOo#I&g7w^hm>u6GYV!Ld7=+veXWS zSjAKK;-X8lLx87f4eVzzNDEQNtMxu(7Id6cVlyWc5ndm5v**HMQc*_fUeAoP{sn)C zDu;JFfx$6T1nFWEtjweAv$h|pz+84g>T~tn-5CwpAXSTjTRC@N@x0o+SkqQ28LT9L z&|e^VCS;l^(RFE*urP{$Q3A6{Qs5DWXEWk5K{|c!@=OvGyf-Ibr0jigGGkPGFvXA1f{Mi$}xAs zIWGeQ)}CAk!#tv0iY?2G2^&!5&2`^e84#_$^@Udgj0-9!UXGd^2M{W@gJli@uhYP~ zuWTPv3CMV%_M{?Z+~Py^y<=WAalG2?h_S|<;@iFXmt8nXH26hi_VQJp&>}|HaG+XK zhG_(WZGQkML#|vfxm`|@rjYkloqtxe74*%N06$KUu<`UBTLs)nDQSSOF;=(OGO4C> zFnUq}!}MT=g^OPR_$O1Y=IC_# zYxM&V;K7{_MtJ90NMFWeAdNW(z&4E4D&_6eh0&M&jx-ON9?*CQFxq2ji@IO@LGrW- z!LkYxTV*a^K4+<8UM*Wp7$eI;t;?U7Mg@Cjg&=F)G)dTk3kbUnlMR!BHn&sz? z6x4qWrTae&fL@O61hQw1H7{(xA-@6*Zo4#Ew_k#9$Lvqyn z2+7BoEMR*Ki=Ij3X=BRUF)qZoABJJ+1t*6 z^8KfvwxocKGO#O~kq9d8;6)rr&fWkGGzPdW5{?WCk&6()(vXoNhwB-40#A@zQQ&?t z5h3v*(P0^AZ%{oaxqWZ8=WVLzw(^KoTjkNF{G^(*h)y||T+?eWi2l~Qa<%W_(jX8! z4`<&yHfcDTd;_S!hTAa$W91=S96Ks?>>AG%NX^JJ2|4R3P*vb$)b}rda>A5<&aFq+ zijI{%;4IwBvR~A;zx%xU#mx7twL1}vY?5Y^;-DESInb-vvh!(+7YK(-^XJhQGbhOs zMQ_HC2|$qiB_J(V82~cn13=eRe8tfoK_(6LN`V-lqn{575H77cGbtjxfQ<97H$ccm4tpx46geZ~bq95?qeE2ZD^^>k<7Pn0zLoXywKsy*FF8jP1D7W7KR z2;miufP6#F_1DilK#1SGtD^Dw6{ine@P$Kx;IMUGI{cxw_5ei}-9HKw=>tw?Z>Bm< z4uDqu6_7U{s5{0qClhNkSoRT#Qw*n{3WE(KfG@S$z}gn1QubUnDPsJVF1}H;@v4ty zrbYpmMSxR$I$k&uJ=Go`epYOWo$IIi3<9}Z@NWCoEU4YBp10}@1QbGkmLEMIA|SrK z53LV-Q3PTO$6&%Kdnwc9I+WWjCWxQJ3L;@=SGG?y+wy|090kR0;y*)GLgH(KrkE&0 zF!7%|M&4eo^76bp!ScODmGdN_LmSzdso-hB@AB|xoZeiwK}$=XYLf6k+_EGF89^3Q zS`HYQSZkjZfgT7U8SyWmWNtbl0kWe7HG37y{G-u~La~>d)$rKPHj9qTriP5F(u%^p zB-_LlSFDaMNwvJzDntklMC~+Hv%xhAA7l-iv*42gwz9w79%g^A>#~r}CTe7hULc4m zh1e1N6`7fqUy+q^swSp&q3{T;Srvq3gj4eI=S{sUGxLMd?r@MOFa|v>Z_;H0?RMXj z6tt~M()1Hfdzsc}@X zqCy)jksFJlyPkP|xVq;tf`ml76IVW-V<3dzR1Hc1j=<@nOZr}`onrGKw<02wN|~e! znn;KVNkGe-pla{SD^@wZsD{QIl;k(mv@($UR5I$IMbU`(hqB&H=Lg(4!Jn8TIIdQPf-~=e34CoyxqJphzyjC zQ|UzTh-S%Hgn#rF*o#=czvD1X+>y1)8f6O?bcb5K-hq6%1nAKSr@J*~*0?jWD!D3Y z|Kw8Te94o}WQks=e=4`3uv7k2Mm%0UD&iPuIT3TkWv%ICJNy}QD;W&R_@a6Ddt;`i zGK(U02dG)RkmQjUx2@S29XHWAS6`a??MVk+ok_iO;X7)5VwXagWw%=MM2IZja_Sv+ z7lDZ{s;XY~JCr(Bz*`UB$uC6tlYQE z*2mv-@`2jUcMk9A8k}nYK67=o=B&8#ejn*UKf=LpC3>H-MqI`kXA3Xqfr<1ET?P1 z_>EqPO%mC7Mwew0aM${pPZ9@3^JSo~!N3v0cUKQneO%GJ~f zayj5?lX9jmR>`OJe@GV2!*0F{hnR>;NexXh>R^=@$f~!jTmN@%q&|rgE5frslKE7uD?FBW>2u znQ~2>D+@sb(e*O=cK5}7^i*Y+!QFyMrsofpz(&69?L6rbQKA7^a#)-5YEjLX?{pUV zc}OmuNZaMMwm<$(gNp;jpOx}m*#XkW-Ik!GfW2c zCUE$idoTs~&UHt%f!fuDqG7}%S6jVXw&aZ#E2dhj^)u~qs`kY~5lx_QpXEV1w z3z{I8w6-%95X;+5ZY?>A5LlLpEA_$K8bDIDAgm@oNeVD6@iSGdOOVq(nT`& zpW)Ew(Xt{Gnzwq!@4S&?|AM0$k&ZUC0v*>f*^SYmvncNm(Y36+n1?Ui1?l8A0T=pr zVs-@M;(oI)>ObmeoV>BA{6r0Cv2C)NOM$JX#1AhUS3g9qKn$CI{?r&?g!16xn8ZPEE!w7gE*PW$*`P)6 zZQQd)P$F}rOUxfp8ta`lq#?lhhW!KQx8SqlUJQe>ak!|MtY9s9*{TNMMh!d0ZR5 zY$$zZW6GINpgIs360@hK8B@jPbhY#B=Zs_drqZ*o0cEa?t>2q>w&w1&01WX|f$Ad< zt8JIb`WTJ>qv1#-A%N_Xr-`Z9`Nub*e=3U52SpM!=AHM(?)yN;z*PMFA-fk*JSCA6 zJ#_rW1=-vRGPx=(9WP@bh*qoz(&o@@jo+|h>-&GnrIuE~%7a>`lq$EKENQ>|_}n@1 zk;;RpaJg;=c)5QSv#hqV_a129_}K0UHsut02vJaPhkfIY`N!?q5wrxiQmnf6LxsFt z6ZZ7ydzY+D!c~;let0tVNV?3A*m)}GM)z`hYty%z|Go=Q7s+JkXGnrbRlfQu^+c98 z4C+7q>EbIEkB`U=ic1E;Gi=~nkUi_PuVHVC7)_p0N}+49u5Qpmucy#mK!W=Mk*^AN z>#{G855k>!hQ_j&K`Ff_=q_vBsvuUst=@W@-E8?>tIQ2l(0n^h-Ij$Yibg;~aLG;o zm4Q@Q;aX&^@om`9ITvy!;~v~XC!y|4Yz#4Z&50QcBxLc z;u_vJGEfH`1Qm-q<{}yvL70+e9owEL5#N;VOWU8Zdb|%_SRdRX1^`Twm>&7wE_&do zdJ$Ym-V#JnW(1s3AfqX{?Nue1 zUo9F)%x&Ogg=YQ8ZTzZF!&Vy2n=79+^8~tFIjR=XWI1L@9CHVVedbjjr|q8B+VMrpf3y z1o}ey2xLv>Ij?>b5}I-JIZAn*!;2ZMOE#R9)_ad$Qjfbsh0Vh)1_Cxtl&uJghDdm~ zx{8EA9T3iN9$$bRsm<$qg?E=vl>%lp`nJIJ`;J3$(kW$d#vE|0x*WUwuP`e)PA-@z z_F<1jp+l_BM))twK9@Us-40WyUrDL(Yb*2_;yF?D_z8Bm!w)=(-j;4XQcJD|YW>GfiHsZ}Nt zWy`8uFq&pAS2^TO1pCT7FnSD&<%ypy*&+-s?l!4v%(P^m5Q2{9RM11h=k3uKkEEZ! z6%zT63I4yo0A2tNwU>R&Tf8_GchU^1W`XX?+%^d{^J=)L+qqDz;`~R_A!=bt9NZR_ zIbZYXZBM1oPDd{w3?HI*^@Wq&2A!lUY`&yjL`v9Gw&%!ptaI+BKLL5!(LoIyd6f)E z-KX(u(ozQtK9S6p>%IkyFU)E+tX;d7i;WCG0N2W!_mTs>Ka~lRMCGrzW!~wP$J92S zvMDjiT}mvAoD*+G3`G9YEs$^GvaH}2=z&)EWKg8pw~#eM0PVz@ic^{mj&9bK!Mf=0 z)k=WZ-=z)eAnk<4byp0o1d92qwHvo==GyndUN$$l(uqImE$mLah5lokDr4ieoYO${ zO$o4;`;$-Jn$;0cANT#ayEZSR+Lfp1=Ha7`#)7cf)qcP!<7AUYQZx0r7+QBF+bZut z&AZ_6-C^ycA`B|PsIh{mHwSg^a;u?z{>e7_?|4Ttgptz`%kSaKxYTtpIhyiKeko>v z1!Hmxv{$_&SKe<7N7?2?mrO1xa8x>MJm_lQahQnG@EdidP56UH4RL!I-lCRDH?1Wd z!DkeKR?Lak(X(7v$4y`3zp{Ama;XU5)Z$W-OUe~ti{a=8b1F|Dw=9%_vqO=WEb3Sc z+%GV>{s$~XMwkFx)=}h1;^9ed3NX7N-PZu$=tRwBeVQIATNgUl_2HP9YYw>R7hB)o zAj4Cv>mj2K*}ZzaPL#winh!yepeh zd%XX;oIMt|7~T?LDY3#?A>?gvX*&X36)jDE7->ECOr_&B5hZ$Y`qNVmRB?l*&!7_` zw2FgOHfr*uQ&Z#6&(e?eV76HEtqzr6JTPVD|mNgZ9^BYiPooj?L}ASN1=oE z`h5Jn+vF9z-Z!W-H_66|lLc;=Ft6%`cq&q&BrnuX>8QtkIl2|2(|u8~NyMv?;4W_G zjEaT*^7sX-rP&n6cqQzi9+u>hyhb^Wj0-dB)~)@!X8;>)6_48F5X}mzuN~4+9^F2> zZX)Ho8=ZN|(ErC{|9`N6hu=Q9;Sjuh{|)&w#oPdJun}-F=$ZZh2b5R~XZLQ%wP<bPT8j2c%&==I~wtL*>l^1^d*>v6l4GP^a%4p9CAc zn@|I-ubyl>{<6jrHwUT}CFj5kPpI&0#yzQ3z9R8+_w&T_NZE0CPhmAb zwN|}9@+5bT6VGu_iPg&#pk1kJCofe;%Z;%}?SvWeEf`?`{wiXoQZOS@8H#nc)bnaC zBcpsOO5FCwcAK*sw;b`*_1u-9a=7Y7b})=1U)_r*3}06n0)W{ljfM$KvoKSnFfl6 zehlUfWfYg-j>-+Yr%fvk-&XrhS>er*d3o#iU0LWe6x6!s;FW!KH(ukt&@NZvMf-l^ zt$=*~0wo`vnacFvwB-~Lt<6+)?wLtYQm!a`Hu`fHI_^LI%>SWUckpm})}ilykuc>$ z`>zNX$lh+g(!7h2BE~TgEgAnDq3n@@OnHCa4FX}{LG6@uGMo%Zx~7xKh z`Rd!UQhm}V7OL^@v)6ZSzG)?C>LFg{A~>e=8<7|O`-e1#{i+A|+G!}x36WPOqsc^c z=ag8+hpE1Pp-9;$+-WN!99eKQ|5&2trlaY@$U4`2yYjGXQR)s3)w5qWpM#Fq(eLv< zS$KN{6R%o6gdP>A8gZ2OcNBY?l3mYoI^)5&Be>A8u&_kQkt%(1>i=Q4@+Ca`Wy zzx_#Qw&Wc&yfAzR!C><#=)zH~1WzK9sxPnZ^H~*j!oUA|q_`cdCVx>}tOe?6-9uh` zEA6abo$Zg^j4ZP(Ug1UWeCIP~PnBADNDK-~tC$jF+f?PorOugS`wc__xGa%>A)G(m z5b^`-*`2n)I*5m$Q40GiuUNj9^LUJtDiz^EA-WI5`Iz(e_i;_;E$?jSk2h;Q)Ye(I zP+7~{baYPIvIGM>{#^brn`KCvzMkLStGT{`1qYuqdR4swu^Jxj1GnoPMdUz9-kp*# z#i5HO4&0EJOL~IWe&Z{|hFXVKX1fDKVU<^oQX|DX4Zx==Q^v`p^J#|82_;7!nH$cf z*NH|1C}5mraDTnXBusorB{gb~f&_jyn*V}97Xw9})KXYryiYxkx#a#F(D}8xpFz{( zM%g>q_WIe(L9&pjxr^Ci#zoE_CesB+({X%;cC}Ze^PN8msh-ozpsu}pO^`Y74iMHA zxnUFMc7>VMMhQD>j0OnJS`e4-Na{c=j&C1|+d|9clJ~)AtgbYl6x+s{hvOBZ<-wX09(KR3BBIrgNq zzhq4hx~}KYxc?l`yH=NYq}v0fW1?=(==CnvfzB;(`_P&v=${yL+~0{7=jr52w`55u z3H+K+D3pQ{`!*RIm5RXPg9#aJ`EEnBpvqs3v^y)n6uL<^9j=8x{ z>WisM%13(MB;98Q8u1tEpQVq)3M$7|2A{SW_TFxuIhMrZ$hmvW-*zB_*Tbd$)*ByR zwnbRHCTShNZ}@79Y_5)j{)H;;NuxABqxpiU;K7O4pJV#s{h==p?)L%`bh zY1!P}oGE{X6rvd4660B?ovGUK3mnzSUa=|h1GYybOzzQ=z3t^*YPZTnq_5M7hnTk! z!$9rNl+4`%tz$i-rE@(oH?sI1DXgRv7;3f$#_|%`DchHNcWT|VYL-fm0^L#B6`$}A zxoE=gHNC#^>#Zw3`eKCswyg9iLMx;mG^H{41&9g`}d?`xq^|)K55AjzJCp-+>YOn^EnP3gwxI7iy@be0Y2d z=d=SvzJRtK2lCmN&MGgwN}Cez{&BECpt55mFiZK(p%7*mlQx#Sv=sFEXE+yXLT4k? zxT#X07LMh+exKWFUi*@FvqjFWv~M?l$7ivv{$dh|cnpxb`T+5t9MC6OaFQ+%_|ZvE z0PBqio7_a|>#2?d8YOo}xJ30fSJ!x5#7YTT-p1y7|*X0RC%G6jXVhxK)%zId62hbTS&n zfoj4KwSx-4S^NzrAiX7*w~Tc8v~dl<0}ju~(ilCmJr(1<^($f3(FHX2Vn<`6C1Nk8Ju0^aUpHsCZIJxU7ME%qa}_7+Iyx>gPCuFTJGJ7 zp>(176HdGMI8gD|cU&cdU?6tvHB_aW#VqA1(Z|hZ1XGz+|3ASpjvM{7@bxv%z>UroF21>!RGgXn{WhR2gnUN3bY8#KlOh_~<^^>8aCQuSxx zN+6xF>@@fE!Vjal>M0oHkaPs*v;@ZL0C`oNMCSNS06^%haeon+Vu^{Cpx}DNAF)$; zKkTBn;+n&lyD;ur{c?AuF!S^Ck%UW9LZ5iYce6MJ;NtM73qUu-B^3(l%s0WcQ=RsW zpu7Kfwz@%R^hDf!dzTtsY35Aur=fD6a$Yh8Kf@nk*3e=0car3k8_?|VJ>$7v?~n2K z_x~x3qC7BWWlBK9pkVbv-=3N&!M|jj-Ddj8T>9OT$(N@N9OgG~)_-$WasT_FpM{5$ zxA6O{r$pj1cKoa1%WW%rkLu;{4uH&FuS~h$clw1MhO*K-lVCUOKe^B;{+z3ZJRru^ zHo4Rgl6HUl>hy!kedKrgBtQ7%+yifILEHv_k@%grA4c4vhEYh%WpZZgJy%Vf^Ryc#0vLy`I>%@$MkPwPU3wyiEE~-a%_s4@TqLA zZ*Ps>5c~ZQ$^~>WKV{L}ZavGgFN7a&_2c}SW78I~Qfq_BO}OQ$Gr5#-+dA=pV$5BT z1V!@dCN4fI`FAEjhFLGptYTar1}?@op2;ePgc@@U@K%c0HhB?xtq zPFE=_j(7t_nNxkFufN=I_}^xDdYX3od>Sw>?Ij$>&9T%6r{c8ouAv979 zz()ngVRZ4yKjRGfGY$!oh%_~x)Y>+ewzE+#yWqr|^N8A)sH|b$l6{jWv zhEk6k-;esO^YpAj8YdqgpVQR%%~k=BTE(@cF{hwsE#i&`9;+6#`bV9<>z@RR z=IwKSU1gz74^707-Q=z?rHp#3esX(MGQvq(`Y=Te+^(@YY9mn?yK_IGMh1B+f4QHP zmlGd{G0F;37@k7&Tg8ZeKt;+-B0CnDyRUDx@RghgJ`j=pd+KUrE|;>F zJ>YxX6!9!W|E}aUX_@}@#ij&ti6cIy1g*(v%?%gJvm(_JLa2zZ8jvRhMcCytcm%PA z#Q`FNc&I_Oc>W#SXQ!fPK#}5TTVSZ(YG7Ofa=P1IA?KtRoZa6VlJ^;Y?Vo&ddR97;H6GXmE<&sh1_a^F0WPM`NRCF6y8)Jdvr-smf*trt#l% zy$NlI)s73@ez<3<6pXaKBd?mz6O|@hBTjY&J_dr)(3KL)h1ga;FpM#D)z&`*m;k$E zIncCBt_{zMCoi894rf!wfSwXj8ozMeJ(h0828OZEh9QAPXTCge)78BHRQassKltDO z?m4&>5vkf;_hbzSBI|d0MXWSyU|Wo{s1wY zQ1?;Yz+zCs3LFq=u+@D-vvo|zZ>8Ca*K2g!s=fB?*6k%$Fu=-P`6&AU@!AV}Q_449 z)l#_p4O>L%NtCLYsRkVni&z&AmiLdvH%WlFR=|XLN!ohje-tgpZN_Yt@`mm2y`=~l{d5wsUhBDw*%#9Rbq+Ffjn%BU(}18rak z)4wXLgz|M!S1V7&(m2_`2blb`xY>JfomiCyFS{DC=8AjY`p)+!3meMD9suX-E@zBs zld42+M_E}YTikS=as%SSbVJe;x`W)`^z*+EY8ZkXknZ39;xxQ9-QzbWp;8Dnoltq4 z{e;DS5p=9(lD4vWGutaE3|i(+&fl#_Bn(37;;Q?9aBV;{&U9_OlybTGf@i=3`n_=S zmNxw$X~P8w2N^0}A{dATjqedyz;RQ#0A0_xsGIUGTy^@yfOaz{FJFK=w8MreMAoJ% z4q6#-kKe{um|7f|`rLFk&QQ%S)h`2P&Q|b>Np7IeX>DyE0ztO0?JOcK9Tm?AAbK>= zcW=9*!~_M{g^4A?!oF;7vh7^EXT^HopQ$b{hMMr?m&`6uJu1gy?rqH}U_dVZsk>rz z8xk+l?Nk;$&<6dtE2wqOr}0_^gfM-xWJi^%H#u6^_*{qg&Q^1iQs&vyGAFx? z=AHo>H6Wd)>OqgV988%vN!R{iOI`MnopirywI&pduiGl^wfYemRr}-sGnC@sZ z`|;OzO!UWobwr#>JS^p*;76~~q!3h07XK)xa7fOhbH_h!7CqOYtVoWs##k%Q zV#Z81`Dne-Q^MzoiBq6KS-;!u7Oa2;Rjc2r<(NK$f&K#cDIg|H)i5nz(n{HKo`ct3e`f_!p!j zb!K`q8vGfV5kje1k~e9gAudWMjr=tl;)9b#kX;+4NV*NVj?d1Ed z)@7PHP2USjoo@^aA;4h- z0lFbUOijV9{**OC@yaj9$@R*WE3#O;qtFhg=ygRE#soV1XT;5-rP|)ms5GSojzp~m zkbMyYY9ofriR8@Npni4rwpo*E64HR>QX-;uPBI;o~2J`*#2Bx?hmkNN5dS=W^&HP5#Bj-|ixp!0s+Mgax)y0UCC-*Hq|ij|0;b z>#ZeA+^DFC=eaxyz|{t~!kT4x6Eq!pd@6ajXVtv-QF6y*ONW_7H=gve$PD}YZJfdG zBolDjp*-bdnF0S{NXs(c0xp-T0t6FGq|T6Iw7km@r8Q6JooJ8Z7cHX9EM^Wv93Nud z_)`Qks6wjl#`#arz-L9qg+ePdWiAi(gy}yT5GSO<)iAz6L_^JF3~377jADu13`T*m z)pQs^>PwV2FeOEe#*~q~Mumn3!1YgWv(9gKj*DVc)pDWuXZkf}>8T{zO^vBK<)@%h zzqO0&p#1O$MsXdF{kFBbIPpzITxP|a;0gk^L$|2!%7M(9r}B>^LeMTi9eZ+=9eMT0 zSD&;McN+iK7sn%*Kbx_&X*NF9Cei;%R4a~yHtwiO<4vciBSD? z{a8)#8rZzTu@Fu-<{M;S^7gz52LFcogs7L8xR}|-Zh?eB5Cjyw$WXXtRM6iJ8iKln zAMw=+Ll{qObH)(JE@tzQP)1xckDSQ^dd2B0kHFpY8i=|z2-Dv_yKmqXA7DFfp8b0+?CXAT{;$Yrh0{L{`l6|r22moR{k?Qlhx27 zuvHl`-nINt2a^brmgpxgpoqn02M*RdV`yJ2i+rCFI*)UNd?bIK(-GEs=~y0x{}5J8 z+1L9??D&o6+bPboL(L82%^v@uQq&tu{?oEE=DRmlGlr1FR|qTiw)h7O*H_mwGdaO?5d3o5W|mj?PSScIVGG{tLg zgDA%}hqCix=U6X|=jdZ4i}kp9Jsfxad~HJ8nAl-wFl879Yb`EMCFR4^<-7md=I$nZ z3Z$CcbJc)#GKn0RAQ}9q+{R85_*Lm}#@{bMh!E0&Ow3pMN#$KDf!EYc_v(Fg#Ld6w zMm`?X!xDI7IDFy$C%--c3*wYmMIBjTDCZs5DcDJyb;*5=Xnd|SD#v%%;mAlk}-D8-a&E;t{q=J>jtM%Xn0xkm!ZLIagP*eiwF3=%wIkLHST-^D@Z20KB znEstQBb=||KUlz8qE2wJ2)v|Te$T+>6&dAG%t0#9M*J3M9J@BHG&#n~T*mP!_0H6I}N;3?oLRmVx) zd7JWZW^OrLD5qHs951lggvLGCWzfZwq6hN+=T!{wr&`IDYo`v)>UI3`72+ zdyy#7xymNy7z6Efjo$pMY zzB&b0@@}i^Kp@~w|Gmg7@faK|$4W?LqPz3yErD1Q$wc*k)&1S~-9`)7sos>JBy+7V zqs)f%vEW8-sKD+8-5daCr$q#I8=O7Bjp(!SfjbOS+d zkK_e+pYi)@W+dn@xKSr$f)V4_x|<^k5-1t?dn+@~s8-+_8$mLIA*AR-^qYgi!3?tL zSBXHP$UqUaY=F;|rsON(NyFTcqNA@JR;p2l{%bqEd=OQUcaqa#cOC)e3wI)BX=>%h z*wz*2u9VUP2o)$AW%kgcWWK7u-$T$Dh4`jQmnLJ7pt*<*V20}XsochLxgq7U^+=YT ziT3Y zxPw7p-NDT--b{AF}LH?EPD&RVJlZmM7FPrBLb1VRr0HGa8FK@Ns?6`KFM z9#_{1N&pBO;}i`l7poSxFBQi78N-0y;&{#8UT^eM`~f+m7dSh<1IK>UW?A?kAByaS zLzF^|+*`F`}4-zbmUcVn3hTK1~ zexWIad~%yNKLbuOtc!CH4}?r@LeZQq9Jl|KPJU>a{t^C&rk zM7;e77<&4O;c$o{94z&0>d_zKem(E#jG8+0LL?UU|kW3|u#L_$Rj-n4nDd z)2I%tij+m+i)Z?cr9y!gGUPg(RI}@dg*%~9`MUM2Ca=+lP9Zf3Jd*_)FrRu9QVcLl*n`#}O1sJO#E+djX)A&-#2u5T&CDa=cTd5raleHN$?H8p`z|Yt03vqt*!HDmhD2c9UXoTw&pp<9>G-&@`I99<{)Y$B)liS4 zQ#o}_Ik~`8Ayxd&*AE|uq%qQhe*xM(uhirC#NdsibjV?JJPJ3VP%@XPG~@}0;2)JI z0EZsLrANHz^lh`JV3*%^DSIfpF5_<$m@Nw~SazYIMJ zujHNuQmvryOoI14>_!E*^Y*5TO$gXhGPW88-=D)NR$y*W4pdo$?+5e- zd!1}rNp&VF#SCRciS8(I*`K`K?VfVIS_LvJubUbDZDk($-GwN#?A>kso)9P^uC{bs zt2(+oy5ME4?u+T9RI_B;fJdJM7LHiH4T?XMqG*>MxpX!^rw5ue$+13YFvH>?}qZpL%p0 zZW5uPwe}ZC+zk@(Yle;X%a6zK>d&cc+Poyl28qJlrP(m3yJL`uzEw5zULy2g4rPWR zva}6H$Ju7V?yOkc9X-*&?L`Z0!gguEa>S|~BXmmPwO=i{cc%tjI!%^ZoOA8@H)@ZU zu`PcYHPSdds7??%kSw;iyf~}65W7aK`Ff9RBgkt71O$~HZ?@mM!hd9k5Qb(HEpyUz zD(hsqWSMdV>EF;uT*hq#QKbyZfN=@5T~|CQ-oJBa;N~dJL#g z(;E#Tw?R?2R2;L&{4Viz@}j{B-=>@0dE0l&Xf0m*(9qyl<-QPMwg~WldlmU(U7qdR z0KtoUOr5!iYfek<6qh(G7CG5Cm9ZFILCFJcOF$7`i72Y*WY@kS;iSpQebd)>)q}*6 z*)4k9@4-m#M;0_)f>amU?2joe&HihLWAWtZAzHt^GbxX6>(R%34768VV2?iwx6(Z` zR}JS}c_qHQNGziS#5V468CMT!)XptpWN}Tz$*CxJtEdo1T@DDJ3iL!e> zSGF6XCvo;P0Ek}Acf+9hw6tD2ek2^%(xle+%Q;l-efA3ooT~I;51lSq9Q7Wm zbA`Y*%dG3;j$j+i5U-JVSrnUgQjzS@Q6OknvPQK!_46{*OOU!~}rIHAszEiu7y>z!6F;pS9{BD{nP-_T0mx$+E_+3_||I8!rBB~M^L z`JzkEbW|b!_wI(RJ1%fxv~7o?Ylt%Vh2>N{jQYEDzuOO!g5P$U2StJh7Ud#n8?pw3F|p zK-yi@j42bw-ygADTncqgOAvcH;!K}wPBkd=*6$dnm52NmfTXY$mz@oqvtoJ-utyKB z$aKGP)G02GHz2LSosRzd*W>xqv&ANh8_bD+Jf}$3ehPz8A@T2>`w6o@7Rz% zg28sZUREtH1GS`QA-_|gDO7CmTHLPg`ICruK0tfI|IE7bJ21o^TAD2u30yL0JC^e^ zTp^Pq?20by-k2O|dZT#$=jL$zm)RO&x=6fWBr$b#WjwVLSheOj8Hk?;(C@5jyJxt) zoeXW0=qO@N>9+YeyWVytNKAaP=TgF+o0LJizTcx@;D!)Tw0b zXbC(GuCv0AI8R8PkeTJ}rr>AhH}z>K^9*>yv5hmOOmm07gTBsT`gUO|;rW~6E?VzQ zLqdYUR^z$FA@iA(^M;qM-#>pmYj&hZr!nV2P-9RlaU4(p@WMZUe{63-tJP0Qu|6E%yVEBD6bMK33 z$+okA2kMwf5R``mo?F&i8K;m)#8o$<({A*7Q*iDg%}E_WVRM*;xP#6j2rza9&3WqW zWaPz*HBm_CnG{^&hbo!}4M&O3Tx=03{49UH|a*vi?>uo)p@i%1gQ z&ZCvH8t((pzb@X`|T$ltzE6O`M!4zrM43QjQXuY zNmTHV9@3gA4O}Y8t=W=3hFd1Csj22tuKW!y;I9#ssi{bhdH1rA5r4Y%t>iI5tum{n zjo~tx@{wm^G1uM&>Ky6oKSAlyOeztBl#RBCM|a19(h=k#hnPp48+N*Z>5Nl!nKdv#Tn2{Cp#P(kTvF2Hkh-H zT=)@DdNQYYa{pbErKfu`6NnKhq2<|lE*%4OSofmO!JO5 z<3odi0h|{=Sm{FoL8aT5nJ|l;JzMDCh-d^BKW#Do+-Lxdcny*z)^jE0H6Q%U?b#}6*Dex^cN-2xo~eO!B^@2KLsl^Z;yS1HAh z-NY@6Pnz#=&@s<+civgEEY6%S}}zkCCXVefaDdL52TM(dB`slNY5O2T>iv_#^5Pg(-xqs`A(utIb>E&Deq0`yT`^6y)q%Q$_{RbTyEB=ed8m$ zL%fKx&HjWzmLbYSmJ4fBY0gzb@e=qZ!052U8&=BladjWBN$4({((;v*(Ph{dJKrGM zc68IbgT=Y9E5T;gG#5r^QdFWc<>FOD!%=~XBgNr9-c+s&lDvn%Shd(Tr8Rro@H>M? zVuzcj$9Pb6BA%W+X5qY@mfoBzSd5dd(Lj49+~A}tlcpu-j1EV#r*ig&e_GSamHshX zl5imH)62VB5{VJmol>jXRy1KRl2W6TX)q3eg5{lF#(E)L~yPLLL(=p;4uS3#j-KQzZy^n@Be4f*754Z_|-Gv)f zoMVVz%(Ka+b@TTXR#KO|MS+lT8zfY}sdNh>G4kkHs(g?}EW0o1nF#Bs$;x zsg**;~l^1AEI68;=kClcD{?-T(ZM7pi(_4vgJiN*_gjYwdg-Ys3v z_xE$x_+(R9lD~W3edG^KzUYi0UEz4unY4I6?~+7WUWjk+S|cB9wU#xj#?< zWz<3;8HmNe6!#X%X+~V}y;JATm5U79UD&*39a!euOh9SoKPip*ISs=P(}TAJpLz^=O{*<1 zV7bxQhN%S)ijKeQQSTeDJjO9&KlYi(B}c1x3Db%vpat*#829{unt*N*X(=7vHW0u8 z)@KES6PHrTR7Di`>u!5aFEuUpvx!zssh&+MUUL^O^%nqScW7X?cv~0?78`Mui+QEE zgb(d`7u~oF+3zjDsoPV2fi$WW2^PoA!~E`Zu2c&ulOg5KxDwtao&7wrTL_4_8~@og z1Y39-suILJ)@plql3aXA5iJRS;M}$;a6UQ59 zLli?OcNaPj(?xjXYR?2%%I3>_3(go43Ekh$91Dc<@3=Lq9YNhC?|lBdc_+bJ&5Jev z)+dVYvF^=yk7)!kWAS2o@@s=WBTIcQrx>L>;G?KgX<9=8!meEieM{1wM0y2pnW7L) zreW&VL>a8TG50tv7{9NZ$w;WxOG6T6{TM3M_m(~)L6dyH)IO{0=ve1mg-p?Vj;u|~ z_dNatoIZN)SnvH~YOPDZKkI~KY5G!dZoe(xje?T~()1eB-1NoHw}F0#T=X3{%8-3% z$jHgXFGcg>ItHu1{2CnW+0H=AwjRdhbLy2W03j>Ev7IfU$D}p;fh4UBn3&T*4BVNp z5(xgG1CfH^BLL0q(&Zc3d@b>0RVU#7G?pMR%1tXgInh4raDhi4*-PhKlC|@01oEmc z3lF_lQ&&h-L6@|p{HR)3hsf0nZ|(RC*n}{@Lu6^h9c#Ph(wlyo@ss>das4QlsW&CDa_uObFJ+&Hgt574a@iP384#Kr*aX`-6kR zQ@j@?yo|+uDL9T-SKe^s;o3(u+dF*KZU=bp!>^|6TJgUcV|ISJvFq~wA4PtuRfOu^ zObIG)Sub5t7uLFV`O|X`q4V5Vw%@$5K2Nw{jHbT-z?v7&%}SWQ9sVx89=y)!PThDF zDFSW>dS+G73cPKX5qniGK_)*8N!k(h?;|+oR#-a7%H|6^-X;XhmZUEsA#D*n1}{!u zmNSXu>9So6Q@5`4;=$yl2jy-mzg4Nkxo3yD?&gH;Z%^0O2|V)1U=rDSCwQx+sO_Gl z`RZ{_=Jkx%Hb3}7Z^?v=H~4L`WdYq#cZOeRwT%~HHA0RP{&D%g%US=7%8(6$%d-AU zPRqu}VfT0-P9~DT41j3+$XTkn@Zo<%*@+Hd)Zh)~WFucrJLU~93jQxiEqq2A-N#0h)(phLPO@hIT@ z6*8>U%+`%qTeZLialiX;LZAeMsQNjOrhPP7X#X&3ZPJns_^;5pw!{~KF9FEH-V8wq zyj58xUZBYq6WFzpCv+RQdk+JPRv~#Mg>`(|Z=JwfnX4g#{Gro4DG*`!F-55Yclb5X zYSX@kPi3#8AXfe z00uEh#Zv;IK)%S89<&)P7T$U{Y1nI8G1JU67{ggn(RxO)l)1q405GEC5 zu|M8c)!bg<|MrKy`gex?4`J*D41>ak-PbpUe#8Ra;{;so!;6q{m4D&a=Z`MaupR=^ z>yyi18Xm2*<79mgOju634r~uV#!Tne;8}Q>`4o5Wc8JERj|v~#3>pG4l`W_ELTj)~ z1uRLU_?G~zr16)<*6nk-x`*s@nS7SBYsMrdsNNr9ubEz1*Y0D-m#R_Ey?PDbEj4@& z%(h>B4xHAaXAWa~kYc3mzC{{i&555yGL(?2oCcdouveZsy+lIU+z?+!FBRgYw)Zsv zd3MuH?<++Yho341(f{NUw|%A!0mp^*0Y}cNVwZ_nIM(icFM-jNXoM&h$=@vC@{!G$ zn(uRlBoa+AkBzbB24%B|1^x(u+fbAEdgBxfT3}0B1wq%iVT9h|Dv`z^yYkvetOOnr zeICs+Ek}&@5P^LuQSTx0|0PXvLNdFhC@YmJd{-20PaR)Dh+S7il*mE;8gU)jn6eT3 zHS(|7mJboABvD|UN~UC2^|BEW$%7KVrf*^XMxSJcJ(7TvN)HkH9i=u-XUhGgP9{Bk z#XhQRPsNSBMBD(KUS~!Uh5na+^PdlnM3saNAdorz`uWS`3~clwwUS_@_K6Atb#NCq z))oHwWd#qRBvB5E6D;MR&4a-N_^o7UiQkEO$%{#e$|? z71ErZDz)tchbV=ucVI`4PB+zZ+=9;XLLDIx_KKiEe!2QRYlFL?RD|a?K6DO8iX<$o z38g*Pxx6SQW^{c&77aUvYQ@O~V#Vc`(BLCHFJ$&KRHAGdGA3RSR*>+p(8097Wc>em zElhX9{bexq=_n!k5-Nj=FsR5L6<8=ydF0q1+b@Y1_k3WhEeix$8Kr}c6FAa>cPZ!m zOSnRMjy^ydkXqS0{HxEbK8XfU2cFovF|>zgT#v;C+&Qq}hua5_*kUgmkRuF8pRo84 zC07ZKt2{QPgX=`muy&*w0eOMb9$U#WTK%;pP-tnw=2-X}88rjNxXL{tjXH?y7E)%2 zxw)!fF*4e=<kE2r1@7hneB(IsF1>z4|FHx_J70nGl! zf3ScUoK!p+f`*W#D3P-)2wLa0$UVywT7b(+gnt#{up%3O>cQ6|5cX3s#RC5P1pvA? zSESR)5Tgk@C!|WnU#-4u5>H`wZdz@DjUj_LBO5Zu5Va{NmA?$bZja5!E^he~V7~`s zLMR1KY&U7}0@uZ(RqFu;_z=kOvv-^WMwNPXoCL%HF?f5XI)1`Xg$G^5}BkCCvXqu8&j4UXgu$o1QphFHD7IOL+=s+(O{m)i#kRWE;j zOcP!wZD^)%rB7nVex>0mO;8OU`+Mg>-lW9}O=9C@+a*p%4k$6$2~`uCmLtBpb8|wY z*YEk)rTNbldYKf`tRpcFQfr7jh(TRHm5jvB$uGoAL@k1dqDNjhBT^Ehu1l_1t&FMJ z2c^<`GXGrTF9}7+l4fqRh8>ARjTzy)ryKQvBUMb(p$6|4;HdKU`;=*rGZMJd$dc|eRd?rx~y=}yq)Awt`c z03;PdW9$QSE&x)dFBmBN8QC;w1&Zge+r679^!351cksey#jT9 z8-m3m63CK^i|*TuzQZn%H$J3};6*n?k4m7Xs<5BFnqSLH=a;v%`=jmX`1<(hheJBc z7yhhp1^ueeBCKP6Y1RpjnPEs>e~pMKKN{nn8C8GZOLpW5ZNY)tAIH|~4>r3v+n>y; z#q==|sN_q5j|i);ggzm3oN6-XwVM9&bHfsN1$5;SvPTIfzv0h7o1O((+>8Gzf4)4W zF9Hzs3I^r22ZwGK9z0BG?!DB&?^uqkn**VJDx@;M$M@9+ffmdPCdL+@U+vxvK0U>n zElaw%cnAZ2v+K+vvLzYVXb0i&JrMBp)Nib#$~YYH5()CBsDzlIB+DSK$DJmo@$25z z6FQuFG^4SfgUDhm#5P)nD`V2MSdu-pg;%3jf_qAo*`$Uz9-%Lh|Jd>Vc>&p z^&qdHVA8Q1A8$*#BZc|I)8!pgOlRhry(eJmra{bN=;W~Cc&|Pw<6O#L_kQA0?9P;S zDd>Mx$BGPXj4{#TkYF73 zQH2$7inT`PE+Mh#ABen)Lz@KSe=kml?XA$ z9WwO;G?Ig#{*Wt`dZ@b+>C&|IQ(A(k9{ZF_r-GgV;e%VOxXGQWwqXYF89Pl3#9{pV z1rpg1TXNaKCOoeRN{RN)>(P7`EDU6%KT+0nJ;Z9HB)CispQ=?vm^XQ3UJQ^_p{*$F95y{Z?pI%EaA51=8RQJZZjUKNIC70FyK#0Ztz*D-#kh+E%$% zZbeQZ-IyH2%F|WCXeF7HShFEk-hO?|s-TIG2v$=q*0yX&ynHbtMDnchgimlWGXqBc zbEbO|Z!Dol1RMTm+e_#$mufB06LY5b)jL6N6PgFk71o>ShpM{HnC``}*1g}{s;bS6bO-!7GY}M>k z>>XzN1kcBlGxkwd&8h$nKtgocfb%#GTOluZWAi@HS~T}af)!m$T$1A@Y7$0k(-^aF z-oz_7uuERWB-#fEc4vK<%)g&Ga6Fp5V-f4mRv{SHV5+3P?!R7c7r^`>UJWgf+INix zoO?Q;V|Y<9lh6fXS?lV&)JG9>rc@_!t}0}ZFiMyqF`D~nTM)l$%Rm>4C)s<+H9G@& zLNZK(C3g-QiCB34CbJ8ruFQ|Zz)VJS1Y1x^Z82JEuE64q7#dT`wPBoz{8 zRuAu6K*ZNM-P5R45;Vijl9!~lgBIU|1(*ZLi8si=hUFv-e4M)oe3uGO~}#- zs5t3c4n2M)tL_PSJ+N4p&xJy!LOZlaqEq!+Y{?3WU2q+K?9zl%Y?pf9crWs)9d&($nt&Qn6R`=p;hT`y~O*t!3(Idgji=vv>sy z_K-c8PHxf7i6;|g>-x-kT6f0n#d`xoyB;!*y2r_B-jbZ)y&dc{thkbuv_ESRU=XJ1J%i9O|efB;yH3yDEHiF{< zN?0J1Ct+b|!_TjE(*`UVV0bdq!mBL_`nV{C^1Dx{nknto~N(vdiMM#Z46)S697Lu}Y?fUI6eb^}Qw1_TSK@F|r{aWjs-P5)m5^85Jc6 zYi0856MSY&k%jPyH$dl#U(IrLSDMBBh-KbnqcOQHw~?Hp={t$Y0@so~A?GQDw%!3U=${00Acl zP~TMk0KCS<7b;f%noDCkdFMwVDKM9!L&EW0mRBepO^<_I{K}~sb=OW?wLz<(<$ylF zEwuTwVbuO=22>P2aqi#8{#_gMk~*VaXY=5e4L&w4sE=IQyJ(a^kNlqwlA}mc#;I-S zQ#uAFyM$7*@z0K?odJ#G9ALwc#^+fW6o5gCcmT+RPvNB4mQ>AvY;bURRZU)=y2(CC zh7@ogxXZrny1H!$I4gN*G#<2`f4~k2h9Z!lm81&D3Youlu!vP01JFk^w7Y5&PZRg5 z{zOHs-+r(>u?g#uFQ3d$`KHX0rn7j*2)Y6GO1$mPSLYL7&mPp^_Df-reDFuXPC1G= zd|Y`4{0*3~x+pW`gU{NX^+2=Zb%Y=7ye0z^YdS>KX6ZNm_tSpC%ry%TE~~cWtZPWz zpu7F<$SFi8{@K^}mItqP#^~EFp(y;}7=mSbKncLddqHjSZ1nkkTNYX766lVm*X%$h zuZips{$Fq03z4*-cppTL9Y0vBxrsN5AQnS;ec@+3joN(rNfQbn$Y!V!Q5aVZ*oIs3 zE-^9IP2OnX`MTQTI>130+BH=^8Mi$Pb6@J2qbUVrqpUXqG5<}vTk6T1jHRE6u=L&c zP*i{K0QhD{Jf*dZ8WdsnVO7zPjdHHy?IvL?-M#7%746##x3i2!x3CUy?cS-$rl(5!6Cr z3BC2T>kn5b^SRE}C;3qgkyWRo(Aq=y>;CBlB>g9WI)%EtJZ^6rn#@ILRi9tG+P8qw zZfa7JP)yK^3_AkWP5u%HFw=oXg(RhFCi7c)Jl2P0qc#K>S@39U+}CKMca}mmaBsW9 zkg-*#AHXV1@mvTxV<{7{U=VNRT@cq6aN~&`_#E_UtQTl!Z9UWZO=mn zGH&lN9szC@uP`Tqq(gFIWGvC}4DD}6@gjQ=b5r)ODxnh=k!?Ycoi?WPwczO}i!!RV zrWK~kG~^V<1o9nJpa2YXSevc@ig0T~PaD7r`5)CV9&NbSL9LQ*S#x->XkkQKe)60; zjOLs`2qCD*??BRAjzmEal$ktoxtu4nfSsqyvH!$t3Lv&YzAcA?Mr3u}1i0Fx8W<4)p)A*tY4)bq=5%gRNPO8(3`{3Ku(kL4Ng?*SVKB4=$! zq|W*bv}I5ltWK8!5o(=!4`5Oafh_CA(=fFNb;$hg26+RBnbVg?scFEkpMl@$=GPhq z#GwiX;%!Y?COH;fK^v9+ijj9NL~7L1jeaI>UuaUR-~i=%){ThJ6)3gTn*D*C*+Y} zH5RhruJA#gzmlU8Bu&0YY-1oCvyN6x7d8D^ghp&I4zTl3KmXjvJN2DJ2$OX3%3Nt6 zwd<|?)Xqgxvm6F_%o?mhsjIwjyh(o^U^FNO*v38{_{O211jY2e)DW>CQ9Fd!gVDAP zA}e-&@_@qjxR#by*UtT6cZufSz(3fvs_ekD$+boCUXb96GXoNj{Uaq z81L-CjMIT3?QZo`mLk8lNRX`p$}E=ENep*$Wnslen<9vZXw1_HzU_yq1XCpc?27#5 zoUtPiDy==Q4-MF75IPv^aDf3Llp3T~1oPmR^(4B7lHQur`&0LonZ7#r<4uqRxg2J| zgI#iYARdB5JooL|GnH88!S1-UN2+2Dnqwp@f1-;l5&2QC{Ct&LqidNP(C4Y=gV+ul z;CH6CxT?9rV@!)Av*JE|n^d8})RFbX=rHIH^9EUW)X}XWHZ2X_+v%1GZ}z$ragm&!@(EY)>w4S)X9O4&*M+l; zRzreZ61!zp?zS_Cuk}iC&3Q`0HpgTez!QP5FZ9;?$~4Oa7DC3$oF|}1lLeC5ae{nz z7r;r)F6;rco}|xZCmw5Q1-}eO9SfYbDQE_6T&aD*6rD~9315+k+EFL6)Z zu)!;|I)bGdlg)U(Q+Po9p%43Tq}V%O5mnM&%I;Q;QfYUhk6jfz{Ff{@7(Q9!FMh2qjXai# z0R|CPSmz~JD8+%o)VQi#`IvK1qH9@rTcNFX((J zvvP;bnv15EA}N~^b}+Tofb%vJVO#H6*JK+y2(jX7ZdvAs#Wi8Wk|8rfr$!8UD)0h{ zN4xGcbTz^B*s{Mn>m{n8H{R%bPl)uqB$q4Dy-bBq$v60#xJZR&dxgD*0Nq=8T=^>f zo$f~x4mv)AjrUc-=v?K|1_^9|@!BUJCEY-L#^ zBTRA0C2RW(0vujJAioz(N2*MshuQna8`Ys574Dl!>sIZH?=B(odvy4n`{56YFm>UV zA;Fu00_c?~5fUl6Fe2#3D1~hf3*=!&_2Do?+;e-eiJP4yLn&gooiX#MBN7%DQb@w> zpdRKezD}_0`Kg9~FpuQyNqE@-jt}A6+pT>00XTO-9#3F@5=qwNLVNk&%u6Vb;E-J` zM$DTNtm#ZSCPKV}u~xjoC2%b{`4Um~+}mNLzUhc`bb7ZS_-qJ2fiECG*_^(zeDD1A zCz>up?DQv)nwFK%=2P=6MTnWE9`#}Z$yptdLIC1^Awq+Ys?DqzSG#<}d z?-H4QEjDsCLls@M6*^nq;_QPzCRgV3tDk9|k!@k83{?`$LD8^#F>sW)!)lL2hLCKf zSi!M7!k?kfxqh{Y`9DrGSfTwQ7@z&zx;O|N~+FQZ>F+rj7woON_q^pz~kon_k3EwCW9a?QmGsfl#5uk=w@DnG982lGnK z#-^^15n6ufgc@z3rS%re0QFGRo=7Lji11Y~OddOMx0BWVOZSE z3(&q-=1YPJhaS(s+Pz_Sc$ky>Ad76_s6QaiSyU995n0D}P&{InPeeE-aXxi8GqG>}qr!z7ZHwc*Tn`m9TQmOw>J4p-7H*WPJtb76 zf2Ie9A+7?`A;Vxp=&G%3NfvxwlID%zvt2ZdE?*)q0gMx zu?N<7W5<_S%yj1j>=*;q&~Fvr6dd(!7G7eT2R&1#O^CK7e1&KIRJclAjgnBl@d1Hl z4-f04A_|2+8{{%YB7N{<{S~CE#F{?cnehFhTf;DIbmXcw{%#)8*xKlDAkqVFmM&5O zIwl>qsZI|f;hN{W`_Q3xn^v*?kD$IvlKyh_WcZV-nEPD9o+ht|>;>uWEHVB>-yd$@ zc&=z(Yt1a$o`t)vK2epnwr7Wb2hg{3(d@3grt++y^SpAKM`>V}mI5ea%&xQ1aWL~} zr^7J#oRy^=5oN^0(WemsDRsDO$+pBr5Z$&XOvZz{av;5PldSvr0_|H zlDT3>T-WkV=FW=3+Ehkuc2uGhCs`N+Trdw9oVq_5T2z#Q-Wq$xn5d^ICpKa~E4JqV z2ed!?kN0vE)%Savu?F2yTQjXLfJ-&{g0$Zoe&`GOoFc5$V1!dQwZ{Ymm)3vWxwFRZ z+LLv+{{zZ^#UYL3-FqG_j@ozojd2E;2v7B2>}}A{yQ~J?_1p9;;WZWwPPlJW`2M@4K0zzJm>bbpfzEe$}WlT`3x!G*#I%%mGS5t z&vxjX$b5_q;!xMP#;fd-#0_&rlAf%7(MG5PbFE5k1HeSE?`h|(MOtUn<$MP`sWy-02?m%JUTpw#&q z?IMDvlvfQa?fw}rkhL;*5dAJUiSr8~iUb_o`Yis1Etm#w|3c{a5#Aq>cj@u;iRHbl zSi2Cb9y`5FdNw5#tE%3`h&s2K($bHcAKQNYFK!D-$uvv~K`T%&;BAs7J^|CY4n&|8 zM6=gxS3>QT1{zO|(CWxjqI575^_jN0lpguJyRO zBdY_3oH>XqpWxBOvWQ$`f*Q8j(2R}Dknuv>0}n6JmCF`q?4=lQ8jMU|t@lhFF5y-5 zKF6tjo#%YO6+U^pFqZ^V>(}~vqA(FhUAaHSL>|UdLOqU4NlJ!1iTwZ-N)O2oabQvF zH{c3|WL<34D1dY%`Jue4B^3=}%0zh>E(~_oJHXusB-5DQl7#KPy02e!*^B1BKwTs% zwQ2BUKD6?sdw#&Wa!93?_IbmQhvRGf!2d2z5ghMsFXZI+B(M6+30NqH2-)X;Gz<97 zSzQK6fMFm*BNb-k5YDdl25QnEIhw3Cko&ui+7yXKs9Qq__*_HV^ZNaOeIw{>B+AN2 z_3xfbOchLLB1K^mTcnnZLeyBb11v7API2Mi#I3)6tEH89J&Jwy~j~N59I!}Kl zq1F=kd3*&!Z;aa@68+led-nA4Sy=$}^UfcNdXrtn|d0WB3cP zlmitQyR}5=DrF{Ang-=E%OIGBp7!srhXGJs z-?BU^3b$kzJ3$e+{jx>KXF5%uVV~ywslL-!Bw)Y*2G`7t(U_n@y`|KsjUh4VLBU`B8_ri?@KkL^Fr?jg6yQSK7rLP2 z%^vyj)(n#Aa8m|k;$>!^1U?xv=)}lku&YaOD%&2TWy#zDX#WzzSb^4(b6fsv_^q$_ zIGJ_-b^flOsD;Kiz6>Mlv!M3am}**K?|wbG{yZ!Z4joF)?>hwFtg_9-7>-WEO#*^! zdf84)Do+O=gNa%P02&m^e8X_&F9A3U@Qjb36Xk@cmU3rlP1qRo3!$vI^1^k7FSNcg z-v;?X_YYg1m_RMWszceo_|zBRPOz53>ly$V*R~VG$qRw-h!c$F@;Zmfr$0aB z=Ur9eDfQozHpwljnK7ewpcPlPjEdV1&pI@@&j|R&0Yef^;7fKHG zLSixQD5C{mq7Q#!VWIsEpT%%6YAY-(qMr&u$RLmpPvD*c;0T|{krXYO$5&7UZL1KX z3HzDiQG(6BL-I2(4jMPgU1pV^G`K=<&@vgXVeU(3Ilw@?!_sZfJHu_*c0$o{DM;&# z&Yo=eU*~c=j{PqWA%f8vmFHaWt_s8=AxJWqNpjDYd2l5BQlwUaRuVKADy$!a9xae7 zUN#|E3`{$e8@UOJ1XgH_fQ5XD8~*conXEL!1Vtpqp5|;|y?oW=AS&1UwSGnt}uurx% z=qe@QJNXhcpLmc*#JOtCP#ca#-!&SK&z1RdEQ)EfSqoVXK1sVrzZ~qcW2PRjR)M7s zlnRYqno0dW79S`+LUpjt?+mryaThPcF?%yDQAK>d(s8-lVPM@y&bB;*%H(dAb~gUY z{k}(A&DUxFQ6|CqzCmLG2QJ`J?KPQ(v+5Kc8-`Q6yZJmE2`vD$Ijc6DeRD4;J@PP) z6fB-o12)-@p(_sIxHW>e*duhccZOm@Uxj`TOA4PufdB3#&$8TgeeLWZW2eE7D8=qP-~PvyY#V@2!m z);{Nj+m>t`#-+vofRTlPHHa-?OWkD6Y~o%x%A zup;-<+Az#jf6GPh&PCbKTL47RgHgM$gGGYcLWGvEU!H95vsZbov$1QR!Nsn{hU@%s zJA{%U8cJ+QXOpeHx;^$xTdZMgC>c;Vzw5x+gf^*s57z->IS+^T+ z3eHsn3N&AV>U^JUS<&6UAG9dH{!V=hvWrIc_GVU%#}Ocds>oscnoiRG4!yK|`?r@y zM;7kQ1Z(sExdDiNQW8m>nd6Ry-iwq#_NjE@pM$U9ZRry`U+g?=0O98~UOOCz zlpm-X=qlld0IoLxDHuXCRW!e-)tEK6QNnimBX>UtGKt8RdTV?4iwGG+U8x(O%LvzqhD*w3v`N(Y z1>%46W>y9g<5CkYij|>B!%V1vPZ=0taX@=O#}xoY?Ew%O_VPZ-XdWkB{$2l~?*1N= zEwAv!viHfop|7_A1XNhN$m0C;3ufQLQ@4K9f=@DB`>+%Ya%|KdQ{T9r()jW z)vlZN`m-tNgL0bd;jB5pStQvJOx$`Vw+Qth>=+wT4wMqpn!;- z=HRR{L#5AB&*c_DDDK49h9JVb*ej87f|1&Y#-LWIVN)L7C_e&FT=2(~Py08Myo9`;nwKpc%@Shj?L|JjJakQ7?!F_2Ok~83`zOCbzLi#|-1pW= zQykuluCnxweb{AgQ7YPo{_c2#eDvTqS=PBMM(I}_xVHfNYHh}K$}_z>iKK0Fb3H>LDS?=!JkW(y}_;y zUCgE)+8dtiWIe0t$|O zmpG{qnm;a{u&wPSgz?4LS*}s%ir&e3r5#vShA2DMe3;gp3nB^(r*1wEc&OuxGs9`{ z=!2{}VD7jBHlZ&u)#PMH5Z}3Ukof@dX(UQ;|nCRLPW{&M8W;w;60}AplhI& z-V?l0d(C3cIJZqVvuh+ro8_Immd~bQxMH*(|DYd!NA;G@uDs0C%{%Ino8JysXBHNb z(JFnlYPgQqva=H?MfPt^8K4r+FJ4A-T9`UD#jCoq`WHj~)w@v;IclGfeAc2C^iMA! z86=LrEKL3Cw&S+>G zm=;uDBK+Ct^7pg!CjoR;n?3%D_dz)`CngmCDx&pUXKAp+qs66n-D|51Pg8D-ha*-2 zGR9JUY*}P@T<6*9(E4|e_Chp`DM518S9#3vu*96zUY`)!p1e9BYYKc?8k^ar<9n(z zv~pTE=eZaB(LsG7=PVO#ZOP)Z96A`YTHz}hKYbG32-s4M2<kVj{Z&Ez zbrD;9yaAv+H=MKHbZ@JyjJ6=r678KL*Z$8Us>UWNrqU#{Q;QHV5Q2?l#^}{ zPEIjl+vtS%Vw#+>jJJ3+>Q*d7q8H_vk%D2s#(}1+CxLv-vN&1SBmiF`aBH7cguM@x z1Yvb2u3Xwle#Awm`;AJRWN14-ZbFSV{}61stNB+{8t{&DdpQlzWc zxdvLWStel^ZyD=+yVNH7;htIoWDD!+Ms(M_T^eT48nAnQs|g=_`)*8(z4s;C8H0w) z>{SHZz{5Wel`wo42yZxwTD$uiOzN<(QFnAqU%SMw&0dMz*%Ei3iyaU5KFc zhLhNTD6bEw+a#1qOdMRf%aFX5BZ6P8G30ffNLg7A8Ofs#gMWa1Uh9Qxa{jbIFz0Bg zpmfv;#Hw9-u?$mR)V=^v&Noz~VM46X>D0@(?N%a=$c^1p5?#tU=X&kQmz0c4$LN{4bM$3gGmBs~K z7}==4Qk_4mHOcAM5w37b6m!;9-YbqLxIN;M(t!UgvNG8nBKT#=M7y<=;repQ%mCt4;o(rj7?Z|0`Y89=A*TY zx{|01@kUlR^=y$8W59|@BSY2GxW~mC4KX(2iB7xhK9`4y(Z(Yd&uhvV5QJkg82dIH_CyKA%PV>1-J%-r+s}3S_XFEuZk4eA3yNTZM!_n+$fbk+UlX7 z+$U;rVe6k{Wn=^N!Gz_Z`BJ6L4MBrF;WL5nOw`hr(B{^mnQE7F9l8)4t;f3?(+$0j zO&$5mq95U$A)#5f!)&$yIQwng=x3$iD#lFc(G>YLEjW*fOhJ@KKxytN#3A*D5tZF>X8n$jpv@a zdNJzVmtD|ziI<@54@$Y>5Irf2Pcpz|n72k*0nQgj-W5ft?}Qpz$R=q9s?rv~UpRq< zh!QB{FGA+-gp9y5))xcwfWwIUmNGL-2d22sbp3jb!QdL7pNm&7$4~oz#h{+k?=PW` z_y+GO{6XoJ#S=PJrIYRC#-r%hYeXpq8`IVuB=O%fR)9n-d61R3J4BI*z*#0mL--oN zbDGZy+2M#Q_6XV~6xm;pQZOVe>)N}gZz)nk^s|8o;)#b|tqrAoW=Z+u(uu%rg(spv zRk7xzq{S5^TyRU+@4FEpFJS@`@X|BRU2>v z_6i8md#7#FUWTZNF$NQh{HUt_cqlu>aNccVJ4W0eDqWPm#4@K%7FZ%I5|&X0j_4RO zfV<)apzLVrmEtF7BpT%2E?6Cn_x3F)F}P%A&>7 zzx!eYgU{s#)jvOmlvt85*IuFRUF3uVyDk|WL+b)8Q3xkZ+m-K}a>Ff!`RpJQqH0(>nLKU{f&D+FY51+tsc&plPc zZcggkoTRMxg_Q&FTMks-TGxZX*1Mqb^&{meM%IOh`ADVWy!k1Wa&O63`gS&J+HR=52g4mRyA)2 zq~G=n6mtp3V^Mc-z8NZd0vczrg|7!JP-pw!kO$^mu=)B#vH-AAk9fw5V6(A?U-O%Z z;{`bJ1A9L)!ny$RdP(`QgO66}9_NgaEORCz5U)iNkE?Vy1g{1NrxW--WFXBUz{J>) z7|b6>#;CgXn!p?_6;#`iD@zN2QQ0rJRlbE8@mo-iX^?(5br6yHkGwE%0>84sX2eHX zrE$S9=Q}v#xSQX(0P`c6u1Vzs_xXC9B?2Zv2KPZ#VGhTS7X$yLL$g<=R~-538{*VL5omMF++|nS)+2k-sz#5E*$>Kr=KfC)pqFv(=<}o7`+l56 zq+#$ILKC&GCOK!0@Ik={`aLJzQLzmn7HNy7BWi`I{XJWd8p(vL5R5xgnEe{LT9-;@ zC9Q|Ss0}%81PKcRRRnlP?xiOB_u{ggCXtead-e7_mE=S>UetO-#iq*&G+7l39-!tb z;$CS0@)Ko_+e|Zil-y2DV9j^DroSIj3lbkubsA&MJc4wJ{qXGj75~1BG5XNG%PDq8 zmV>{oaGeM_cQNKnufZWZ)1W}R&U{fW7OtZ~O-|SEaHp_ds|mU5$|}OTRr39Yc-1H| zrtsVQsrbH4*Q6T+A6<_&tqctqIjXH^y3*V9WV9yX(#)Mniuj6!vfuD)}#&TYy$>{LQ}3B9L^FJK@n8=)rdNJw}|px3_oV>r&!kYv1}_i7(K< zi{qPX>I#-vtFjVpcJ94|=sELa#JGQY0r}$<-Yv<1TH1EcrGn=dV7I9YpJNJc#U^!p z7r(ZPdG8Cl*g)+@vT5|sn+HvEM+)Z3W%kkMD#;Ur3ATeS@PBSlIi^!GYtop-3!h2V zWr`aXWv*T=1;-Id!;97X;^gI4@));O_^@s>&DE6rnCZr?!^m)qDcv+zAjY=ou^CfN z;I-jMN;kp8iX}Us2-Xs3#SDN$#HnkB@6>tQ6}Z&`Fa0)9|NOk&$ed#@J<7LTDD|dh z-68cyRA)-v19XMBn zkCuk-n7?4pyvN;+T{2z=RsxDACN8`ISmgA*74tIidn^tL>TVWj;;8MkVBVX`zI%GW~V_D1GQfyPD`|=13 z%TN$UZRF;jPJHc6++r2o8wF2&feWg zE}9GSQ$DY16PJ1`+B`VQ)M zz46O=xw-CTR`mHg>SySQMOPm3y|p}3(=9Sst_pZ6ZUVUoqcVhQ{ z&pCUn>(V^+{myk_l=ff7)P+MkSLV8dpK16=Y_zz=KlRbsS6+^1?Dk9V&0G?Alhlki zZ|C=8FV;NgE}TwtzTGP^ z%pf>NDag^L2Oy$+g35LEN6dU%R##291Whh~eYm9?+3WMogj+9DpX^Jmp?9)TW7}p6 zW*r+`G0gguTvJpQEpg(kHkHoV_#{RxAI2%*lhZFsgmN_R@sLif067`f}T3LX7Xi zm&D#*D^J<5Vf2QeClW5qTs|)|^HT@t{rcp)9&F`b5@xdfO=F3c*Mv6OZdg3ZEZ^|G z)aPXPfN9P_oZjxg!vMN3N%!z})=P;$ML&^99uqV_Q<4zV>+ICSQf4ggGt}?z^AudD z4<__>sqZ0-5!4n%*<4@bW9YDbg4tu6XDh7i6@~ol*ymtXM#?_RI=;|U=j-kTA1}ce zm%cU8>4@+6wUZC2;Cnj1LZ6fSz&Yal6P$i-!8Rogp_hKlo!`O8A}aNKnLPc}_)*Ne zA=^;uQe*j`E}c_4tUtM0(LtD z==PeEcLJhfpA30i^&9r9dOn~-d(WRs>G9>wKH4fF6(B?&^;7}eIj0`As}5rHR951$ z)O4Z5FSnPMPiQtZD3p?&4*#+8*9luHZm!3oFj;qFTg7!j2(O{V+svj}k8=yCvN2Qw z@_k{0*?jtrVMrp4QukG7>Wr={iYz{*MHe0NPpI?$>&5)6Skkw~y+3ok^wozCUab9q zeYWZfd^_}|4v(E5f%Iaj{N2zy+Dd|O@N{FwALH9`D*m3))@k%!q7rLx7lV}vJBkkU*LB)T-V$`2EJH)C#Va1 zrxIgX@3(&$oSt~1q;z(JkBs=E*aqQI8R~rXMZjJ>WTVcNhK4@tQVLf;p)Jt1u1Ji- zcj5RRp-$&3cYW{06?q(V%QjyPm1yh0YRL{Ss;ZzLU{-n{aExotN9zjF4LlpL$dP(gEC5zOmB-OehL0EYs z_|!x^uVDwwQ>q5TqgDcCysfNpyf$=@@w?4uX8JnOUS*8=0eNSK#vJ*xT+ir_x5~l^ z>pi;p+G7nC;Q`z=iK^SEv1tn0ubR})9owBfjTS~O6~?^)=c9`tL-@FlOrH-P{;{vk z*VZ&zc1%9wdItSV;>r}e+Ys6AXy?{N>AgNzLksq(f2wjnAa&JJjfyK0ftpMskjy7cRQ*3b$O-n7h~Y31bP-ETd{p0dehM}wwZN9$L;(l=GV6^~U&DlB*DamsoY?{G%`$@|=opZ}9{ z2;lC?t=P;})<eVObPtv?I4DrGzCoFlx`DnWu(w#SR{X?GYD$XBtHXw6j{R6;yl0sod5=i`;EB=QKpQw?{b&V_9Cx8cx|2i^F60Tg)qBc=ziQ0= zb{)KL7fRNiDD|&pKe@q2YGJ?n-h*LmWX`paR#5NX*u^#V(Lgj|7TYm;wKFjnPX2#_ zsUHvfST={l7QcNYdXvP)QnLRCUj}unE}nSnl+nUkRxj|s{ebe!SqXkt`Hb_R2QS7{ z=;&8;Muj8viTOHu{eBKoViD9%6*6TUV)fRz!sTJ-$wr?ZQ9;8c>G97e+Yb4&-{zjS zaQ&#r(n$sr!3je@Dt)m%v|ZX_sXEtf!x)N;A)(kV@K?JY@F_6{LmskXt3Fw4v;@48 z9rbOaJ?q9BT3`B3KPL<{Mqb9Py9aa8m%oaQfH~BMMT+232lL`hPMNs2 z6t-RDEp1U{hr}{e7)r^;yydl#F z;qO9u(l;{SUgo}DEY67mIF{$arwHGRCOaxP#o0=dPVPB%zIkw(gL5ruPL<8yazZv~ zb3)~}JC;KG3@Ny9G0R7r>q$7rh=Zw8+vc0@_kpwE$MAVl>ou>%mi7eatcivvnu;0| zQ4xD!gs`PLGvL6=o52@G>YWwNd@Io8P*d)iX!)S#Y%y^o=3$@a?CbeoDl5Wlo(3cB zLu`dNVI<|{)tHrVo4hOC)c1?Men)Cn?e12YxM={Iw@RFZq&^~L2#%_Y=lRO4Mb=99 zOMIetX?AbHeg0);HFxsFiI45<6mpoy=D#-MYJ~LLLLA$`;lS^g98Nz%gmU;SSGnVH zCcTJJpV7;&$3>WK^YNGAF)f?o!AU6Cw(}Jvzum#*>>Z!nEiMGpfpK9}?&m^UF;s)h z#^u&uG4~ecX4jX66D_QrT*u6#WNWh+`3v_VfXl*=JvpwBb}3S0-cwb!!XkI+H8glQ zhPxQkoG-Vud|s#A8u`5iG+HO#Rw+@`HPZ9*<251S>buDt_f_VzsbOuju0;HKZQZYp zfm*k3zlE9YbEy{@wx684EFRFg!aGh^f4A<37JSWvrh`$M#{^R56JO;XX_r@YcCUVJ zKlx`~Rqu#9q`Z=6+p=Dq(d22xZsnu-8qG=A@0aBOf7uZjPvD!a#4WX3>e!OKAgOT zvE6~Khr^7kIiTg4>_Bdg&yk#KEKhQBa-yz2pdW6vb^r`y=)09IsfL`GhGVdb{t3kj z@wBfolxu`NKjuzea)+#M(cs9boaP4t(v;X2D0momPkE&>Nxr&~`9*4jz1o#bjg@NY3#{HYIlRUU zvL@mAtkyjEL(+X$Jx;(G8HG>HhI&m7ccQf;$`6UjlT|Y*r+zdvHdLB zSBeZO=;EwrqNAfZo{uTF%wW2`SxrhepNo86-L{f?VUVAce_=?klD%&2FsWlAph(Cz zPXF(F>gUehKQW_48oxtIqE;MvMAajQ8#0OWg|rw%DPR8~nK;f7D}^+6N+P9i zu^SZaxTGaW^#A8^8YHd5JNn~!_ffj3r7}rhSKr02iL*XQZSkz-I20kO=bz6k zT@HIltlk7IaOLP*Tz_5@Tpswd{TTu5i1l;rVS}f(Z?5;mr52=Z#&3fNk$soK)$$4> znP5KgmX&w-_P4xu-x{NTuTVcR9E(C^QA0Rgb7y7NfVMHD^6K|=9PxY&=vG;CULPL3D9C@uN=;ssmVM>gB@UYCM&FwYEW@}K+n*JH}r zY*{Y0|1y01v((VkB)k|AuMp43@?$6ad821LPlS7Y3pBj%^{u`cUbvfm%;C>F*Kn<9 zPZ*td_kbIx2_M`?99}B(5I#2cxVibz;W($EF}%VGTV1N5{&}ByX@`UN(*8IZDU5h2 zZJeUG?2U11yk9uO1K##^NB6GoCOwg&QISGtQT`#V9EpycwB^m2S2$9*u-pF5^Zq(o z-VjOe=T63aFk^$Ta2d~Q7ckhyIB@>jYvmua&@;w-%l>=37i? zkym5wak!9wZrz?(TDehDG^+S6Sst#wT)f*bX$HSElCliGri_hiRS5}lqLJ$kgcN!IL-15;K7>$*G1ZuRq=Kb-ZpXuu#z7_V?w zu}9l2{VvJf28W0r!$N-UN}i`rZ*ev;Z&8=+5*%S)pTmX^bidl30x&XnrP`z6dx{wT zT%WQ=I2}Ivx5mbb7o!6M1K({;V5in^$5{oeWjM}Y=6u_1pCzDn=4WK9tE*W=Evw^N z7J987>O1~ATs~V1DcHf6-;BmjG)n|rRy%X-c}$M*==Bl8a>`@^0$YYAyiw#p1U zM5X-^Em8t#fd)xT=!GM+4z6o<=7OgiL@bKDD)&P8YtCK%&9rfukuS1S?i+U5#C^O< zUD)CPhK;v#{h!3V(x20Oo^81{ZVOg(@JRbMd8bH;L=tvwG~C^PqF_-r3xs+5v7Kjj z`G|QPz91mscaF1&c+k>&BB=o$Ny1WDb>RhYZ z7l?>oa7MTPeY4oDSYvT09%A2&C%R`&*MX2Fr@uuB*vmu~eIksVkUMSD`l;6WE?!T# z2#?XDieqJ^>pp(`c@slgr@y7n=9w_9IB~FKn&P72VQu5&w0&>)Tk(-~xhq-+g3lax z*m6^>Xxaah;CNF)V&coCi>=pgbD#0c5w#5b{m9_6$gV@J4*C7o9oOVe@rF-rf?e&( zVma5hcx5!aH@7QAQ90u$-s_!3NlML^ZR(7)Pmz~-85Cyog4*A=V@QsjA7=?n)E5l) zKX<0%5(jm5x_sHt*IUq$aGt~RZci}zSgTGe+1pNTX|hS6KrG^q_1G_qjg$6!ioyw* zsf9J6zQJsm1^R{+#3F;r+%@4()46UJG2vyUZBA8mT*F3P=JS^cI_b;JZZ$D|&4cwD zflBBWtqdkSAarx|dJEV3i-ehNysq+ra?77jB#fZ%voQFr{W?MZ*8%YbeCe~)conv3 z=udyr^T_I_xx1{Jv*`4SyyS1BblaiUSi?bC%E};)VEhP|a7qVfHP-j0Orz}GWQRZ7 zz9|;=gzG=j4~l1p(LP4~`}`t{POYwZ`moFM@{WyGvZOqz2uKo|4QZpytZt;S=B5(u z=Tq)iFthR%7Dw0FjFn@;<)YekHnjLyE^S*QdMZF}P4Jw?da|@t09p4Hfm>AkzO-;y zoOi8u0DGqj2zNy6jS`HJEiqmux|OZ7IxoYSIK0E9R*S3hkfxrGuGxWxI}4>M9yZy5 zYTsztRmx|%gBqf|KCN$NVt&Cn%XkwTa&}G2#{r`RUl+$hNmtPWF@|RzOrG1&esb3O zRbg8Bm|d#KJsTBery%ky^U~`=gKpOk%Q{}09{d~aAVx$HJRgV-Nr+1GL2=(cWlpAJ8{EQnb_Y3dc6kdo|6gg> z9uIZe#b=m?iIy3+k;@3tx;3H_G2|Yl*+sc!h8>q&G9g-*G0o5*bVDhZ)^?>~{v9M>$=Yne?gZOWy1EJcY=r0gtI>|(19dJP5+{@7g=W3pV){`$mQt7^}0 z!tW1IbpH{Jyv`m^v(gv!M(*O3=)?^EeBuw_F)P?>J6Zr8}`M$?f0DsdeIcIF-k4$byfAoTB8JwL20rL zw%GU=oGq5BeExfJ8Vld>&Lj1sy-!37rydw3^dPfk%t4|CS+m(y{!i3d6D_R^5#!jm zP5ftklk|a8&p+t3|Fugf`(3xImT@HMK(ZTQ${Q&n#%3Q^$LzW9NeY98yE-L3gFTV3W}^8w4p7UPsf;C5Hmf*myDm}tEm}uHVLa&Q zJs-3|x`sYNNj4M`kA38~KHfFA{^zPscjVyBMGC11y1fdrn%2r!dH&z z0Ed~}1|Kk>qhzrCJm2WYho+L@XBs;ddDAAxbMAboX|{m{yA^iNf|32wBS!5LdHn4A zpvlY!KjN4AQ|PFq{+`zRUzuoteG<2^KYz&R1wAQxO<)l8vLUmbB8FocVpVGz)L3x* z#%F4*8*u!0$HJL4(lZsXxh-iXmD*GN_w6e$)HFBm^$fl!FE8K4fzRw}FQ0QXw|G&( zcy4A;!ha@Hm@ovGJp`#qEPUayN=SK|P~dlPL}D&tpij944HFPs4{Bw!X5L%PTB&`KaP5_imwO zWMeYheG7+88D*t^@uyHWCquCcr<3wX;SpDQ>3|0>Xg=D*^TPJiO3})7$fZUVrVS|@Q6HV*tX7qQax5O|?wu6Un2$~g%nd)nuT#u2RO1yoOoyzREX z%fKrND&}Z95;Bc2eJ0UpkGuwaV#I)Ge3uM0pvFZbMq6zl2;$6K_C2dwSVW zjU1Ox)g74;fV}K`xY3HBEvRXx+P#0hYmFvfp_Yd#qc%g$3z;03PK0aCihod_TWD!CHF4B zTP6(NYFnu^G-ReN1@Z^2gBKKC!?pdA=Wg6&C#15gQ+1an9!b9ktd-k%-h=;?&2~8O z?c$;smUfWG0i%&k0e_jmFK_*-vLMD-p-zV_a?2@BV`z%I{#7fNPz%9=*vm=l1j|@5 zP-SB@@ZH-JzEw4CWp9O)IPU!ln);KM`W+jRj>%yn7`9Fw`DL z8!J~ZQ|aOa>Scr5@Oq)DwlyUwFuVE;LdR$+a`;eXosO1(JgzYmlPlFAPK_maV3*<^ z509p%XyOs@)leuv*`p8*A-z~HKSa^7blFt1=}tmAtA9J?ep?sO++4qx9V4@Sfs!rH&x*B^&PkXaw~Yt z3&y4SKX=c$JFG2H(a5+WD7&XBAvvK|FR9Kf#Xh}j;S;C451LQ8; z^`p*giKzz}-C#e3ov_1&pt-1@USZA<|np!A2@C|%ZkQrqKq#EenJJ@2t&=y^zd;K*z~9T0ek%^Rfa z9{V#+YOZna)XruZZe#qx;tWpR`OImJMe${mr-tK;?HLP7X77%E`6*6m>U)*D-ZJmS z-tT%J@?@ShemI~;LYMD&)TJcMv0MC*udqEWNw>ikv;0VPnlOe2(owQh(b%xaFR4}S zvQ_0nn`3*HJlUBj6F<(tGrg`@f4D5qBlpJb`#rP z-kD)e9KLBVrE0$${zG!?Z#Hr#Ye6#s!^whD4TXA^2JU?p)0UY&MUoc`689G=%#tR{ zk}a%DN=i^WZLm}BDLG4uKu zI~rRr{LJnd^HaaG*%r4z?cmL$qBIt-ihu0cl*T15-XwU-A8fV81-RCbT{|<0veCGn zw(`*h%;M)x1uJN0Sm{+AA5c)?ft!iLCg?1(K;~B89mEaqNc8_?RP6nhQ68EvHKpmy zT}PN#nl~;qe}Xd!@A*>q?Nb#PU~*la*O<5(L0R0MIi3V11FZh5@=EG2cktXNYHlLa@<1NhvKv zhU`5SA=s}LP93Em+>=ciiXt;eYpBvV%8CLKlt*|dpRoQF6p%T|En`he>MCKfS_M%| z+^D?}dcg|0^|p!LU8@KmKbQG+S8=&f5Eu;7(-+yl0{epryeEe)N{!@40>xY-Q0kb-&9&iJv5G9;6rC-{(+%jU+ zQ8)73a=qcrw+ak{%H5ye_7bt%b`}4ps{%{%K5##77WR2&SB>;n&;zV0{7rTI#!#ku z;GoH+AZNu|iNKChXgj6k)UDU;!G={xzY&nda+BE<2m7^9u)3d{x`2nZ0B3o%;cVuL z_y6lYtvQQeN~JJ-acj@M-#|R1Uy>p1!Q9J`Sz){aoc)VjtBV08S2r8Pg8yZf{|7&U zDNomC0W1Mmg>cCv8t(qMRaX~kyOBgi?1cCLAc76c?+?d$8Nfk9GD%;!JNGpc7x59H zR}sfR7d%pONeBc`rtWYTdEg|JQPV+JJ7(tgKme%M1`wf-*Yd?bX?;qYBw^+PPGcsH z!r`mgZ>1sVqefB^N~=}2;J+T;eRv0|gQO8rLLaSC;~)autB(vsGmD=ItNLcOj_o23 z4ho5;3yJo6@4$X2s8bN9gargc != 1) { *out_value = resp_error("ERR wrong number of arguments for 'save'"); return 0; } - int r = kvs_create_snapshot(&global_uring_ctx, global_array_file, global_rbtree_file, global_hash_file); + int r = kvs_create_snapshot_async_1(&global_uring_ctx, global_array_file, global_rbtree_file, global_hash_file); if(r == 0) ksv_clear_log(global_oplog_fd); if (r < 0) { *out_value = resp_error("ERR save failed"); return 0; } *out_value = resp_simple("OK"); @@ -547,7 +547,7 @@ int resp_dispatch(const resp_cmd_t *cmd, resp_value_t *out_value) { } case KVS_CMD_SSYNC: __ssync(cmd->argv[1].ptr, cmd->argv[1].len, atoi(cmd->argv[2].ptr), global_seq); - kvs_create_snapshot_async(cmd->argv[1].ptr, atoi(cmd->argv[2].ptr)); + kvs_create_snapshot_async_2(cmd->argv[1].ptr, atoi(cmd->argv[2].ptr)); *out_value = resp_simple("OK"); return 0; case KVS_CMD_SREADY: diff --git a/kvstore.c b/kvstore.c index 9d602bd..91bb092 100644 --- a/kvstore.c +++ b/kvstore.c @@ -45,7 +45,14 @@ void __completed_cmd(const uint8_t *cmd, size_t len, unsigned long long seq){ // asm volatile("" ::: "memory"); // } +#include +#define TIME_SUB_MS(tv1, tv2) ((tv1.tv_sec - tv2.tv_sec) * 1000 + (tv1.tv_usec - tv2.tv_usec) / 1000) +#define TIME_SUB_US(tv1, tv2) ((tv1.tv_sec - tv2.tv_sec) * 1000000 + (tv1.tv_usec - tv2.tv_usec)) int kvs_protocol(struct conn* conn){ + // struct timeval func_start; + // gettimeofday(&func_start, NULL); + // long total_oplog_us = 0; + if (!conn) return -1; char *request = conn->rbuffer; int request_length = conn->rlength; @@ -80,65 +87,80 @@ int kvs_protocol(struct conn* conn){ int dr = resp_dispatch(&cmd, &val); + + // if(global_cfg.persistence == PERSIST_INCREMENTAL){ + // kvs_oplog_append(p, len, global_oplog_fd); + // } + /* * 语义建议: * - resp_dispatch() 即使返回 -1(比如 unknown command / wrong argc), * 一般也已经把 out_value 设置成了 RESP error,这样客户端能收到错误响应。 * - 如果 dr < 0 但 val.type 没被正确设置,兜底回一个通用错误。 */ - if(dr < 0){ - if (val.type != RESP_T_SIMPLE_STR && - val.type != RESP_T_ERROR && - val.type != RESP_T_INTEGER && - val.type != RESP_T_BULK_STR && - val.type != RESP_T_NIL) { - val = resp_error("ERR dispatch failed"); - } - } else { - // persist into oplog - /* 执行成功:在这里保存到日志中(只记录更新类命令) */ - if (cmd.argc > 0 && cmd.argv[0].ptr) { - /* 更新类命令:SET/DEL/MOD/RSET/RDEL/RMOD/HSET/HDEL/HMOD/SAVE */ - const resp_slice_t *c0 = &cmd.argv[0]; - int is_update = 0; - if (c0->ptr && c0->len) { - if (ascii_casecmp(c0->ptr, c0->len, "SET") == 0 || - ascii_casecmp(c0->ptr, c0->len, "DEL") == 0 || - ascii_casecmp(c0->ptr, c0->len, "MOD") == 0 || - ascii_casecmp(c0->ptr, c0->len, "RSET") == 0 || - ascii_casecmp(c0->ptr, c0->len, "RDEL") == 0 || - ascii_casecmp(c0->ptr, c0->len, "RMOD") == 0 || - ascii_casecmp(c0->ptr, c0->len, "HSET") == 0 || - ascii_casecmp(c0->ptr, c0->len, "HDEL") == 0 || - ascii_casecmp(c0->ptr, c0->len, "HMOD") == 0) { - is_update = 1; - } - } + // struct timeval oplog_start, oplog_end; + // gettimeofday(&oplog_start, NULL); - if (is_update) { - if(global_cfg.persistence == PERSIST_INCREMENTAL){ - kvs_oplog_append(p, len, global_oplog_fd); - } + // if(dr < 0){ + // if (val.type != RESP_T_SIMPLE_STR && + // val.type != RESP_T_ERROR && + // val.type != RESP_T_INTEGER && + // val.type != RESP_T_BULK_STR && + // val.type != RESP_T_NIL) { + // val = resp_error("ERR dispatch failed"); + // } + // } else { + // // persist into oplog + // /* 执行成功:在这里保存到日志中(只记录更新类命令) */ + // if (cmd.argc > 0 && cmd.argv[0].ptr) { + // /* 更新类命令:SET/DEL/MOD/RSET/RDEL/RMOD/HSET/HDEL/HMOD/SAVE */ + // const resp_slice_t *c0 = &cmd.argv[0]; + // int is_update = 0; + // if (c0->ptr && c0->len) { + // if (ascii_casecmp(c0->ptr, c0->len, "SET") == 0 || + // ascii_casecmp(c0->ptr, c0->len, "DEL") == 0 || + // ascii_casecmp(c0->ptr, c0->len, "MOD") == 0 || + // ascii_casecmp(c0->ptr, c0->len, "RSET") == 0 || + // ascii_casecmp(c0->ptr, c0->len, "RDEL") == 0 || + // ascii_casecmp(c0->ptr, c0->len, "RMOD") == 0 || + // ascii_casecmp(c0->ptr, c0->len, "HSET") == 0 || + // ascii_casecmp(c0->ptr, c0->len, "HDEL") == 0 || + // ascii_casecmp(c0->ptr, c0->len, "HMOD") == 0) { + // is_update = 1; + // } + // } - // __completed_cmd(p, len, global_seq); - // global_seq ++; + // if (is_update) { + // if(global_cfg.persistence == PERSIST_INCREMENTAL){ + // kvs_oplog_append(p, len, global_oplog_fd); + // } + + // // __completed_cmd(p, len, global_seq); + // // global_seq ++; - if (global_cfg.replica_mode == REPLICA_ENABLE) { - uint32_t off = 0; - int ar = replica_shm_append(&g_rep_shm, global_seq, p, (uint32_t)len, &off); - if (ar == 0) { - // __replica_notify(global_seq, off, (uint32_t)len); - global_seq++; + // if (global_cfg.replica_mode == REPLICA_ENABLE) { + // uint32_t off = 0; + // int ar = replica_shm_append(&g_rep_shm, global_seq, p, (uint32_t)len, &off); + // if (ar == 0) { + // // __replica_notify(global_seq, off, (uint32_t)len); + // global_seq++; - } else { - // shm 满或异常:你可以选择降级(比如直接跳过复制,或阻塞/丢弃) - // 为了不影响主路径,这里先打印并跳过 - fprintf(stderr, "replica_shm_append failed %d\n", ar); - } - } - } - } - } + // } else { + // // shm 满或异常:你可以选择降级(比如直接跳过复制,或阻塞/丢弃) + // // 为了不影响主路径,这里先打印并跳过 + // fprintf(stderr, "replica_shm_append failed %d\n", ar); + // } + // } + // } + // } + // } + + if(global_cfg.persistence == PERSIST_INCREMENTAL){ + kvs_oplog_append(p, len, global_oplog_fd); + } + // gettimeofday(&oplog_end, NULL); + // total_oplog_us += (oplog_end.tv_sec - oplog_start.tv_sec) * 1000000 + + // (oplog_end.tv_usec - oplog_start.tv_usec); /* 构建响应 */ int cap = KVS_MAX_RESPONSE - out_len; @@ -157,6 +179,13 @@ int kvs_protocol(struct conn* conn){ consumed += len; } + + // struct timeval func_end; + // gettimeofday(&func_end, NULL); + // long func_us = (func_end.tv_sec - func_start.tv_sec) * 1000000 + + // (func_end.tv_usec - func_start.tv_usec); + // fprintf(stderr, "kvs_protocol: total %ld us, oplog %ld us\n", func_us, total_oplog_us); + *response_length = out_len; return consumed; } diff --git a/memory/mempool.c b/memory/mempool.c index f06e2bf..70a12c6 100644 --- a/memory/mempool.c +++ b/memory/mempool.c @@ -27,29 +27,29 @@ static inline int size_to_index(size_t size){ // bitmap 操作函数 -static inline void bitmap_set(uint64_t *bitmap, uint16_t index){ - bitmap[index / 64] |= (1ULL << (index % 64)); -} +// static inline void bitmap_set(uint64_t *bitmap, uint16_t index){ +// bitmap[index / 64] |= (1ULL << (index % 64)); +// } -static inline void bitmap_clear(uint64_t *bitmap, uint16_t index){ - bitmap[index / 64] &= ~(1ULL << (index % 64)); -} +// static inline void bitmap_clear(uint64_t *bitmap, uint16_t index){ +// bitmap[index / 64] &= ~(1ULL << (index % 64)); +// } -static inline int bitmap_test(uint64_t *bitmap, uint16_t index){ - return (bitmap[index / 64] & (1ULL << (index % 64))) != 0; -} +// static inline int bitmap_test(uint64_t *bitmap, uint16_t index){ +// return (bitmap[index / 64] & (1ULL << (index % 64))) != 0; +// } -static inline void bitmap_clear_all(uint64_t *bitmap, size_t size){ - memset(bitmap, 0, size * sizeof(uint64_t)); -} +// static inline void bitmap_clear_all(uint64_t *bitmap, size_t size){ +// memset(bitmap, 0, size * sizeof(uint64_t)); +// } -// 根据指针计算在页中的块索引 -static inline uint16_t ptr_to_block_index(mp_page_t *pg, void *ptr){ - char *base = (char*)page_payload(pg); - char *p = (char*)ptr; - size_t offset = p - base; - return (uint16_t)(offset / pg->owner->block_size); -} +// // 根据指针计算在页中的块索引 +// static inline uint16_t ptr_to_block_index(mp_page_t *pg, void *ptr){ +// char *base = (char*)page_payload(pg); +// char *p = (char*)ptr; +// size_t offset = p - base; +// return (uint16_t)(offset / pg->owner->block_size); +// } static mp_page_t* mp_page_create(mp_bucket_t *owner){ @@ -74,7 +74,7 @@ static mp_page_t* mp_page_create(mp_bucket_t *owner){ pg->prev = NULL; pg->next = NULL; - bitmap_clear_all(pg->bitmap, 16); + // bitmap_clear_all(pg->bitmap, 16); char *p = (char*)page_payload(pg); for(uint16_t i = 0;i < cap - 1; ++ i){ @@ -95,8 +95,8 @@ static void *mp_page_alloc(mp_page_t *pg){ pg->free_count --; // 标记该块为已分配 - uint16_t index = ptr_to_block_index(pg, ret); - bitmap_set(pg->bitmap, index); + // uint16_t index = ptr_to_block_index(pg, ret); + // bitmap_set(pg->bitmap, index); return ret; } @@ -105,14 +105,14 @@ static int mp_page_free(mp_page_t *pg, void *ptr){ if(!pg || !ptr) return MEMPOOL_INVALID_INPUT; // 检查是否是 double free - uint16_t index = ptr_to_block_index(pg, ptr); - if(!bitmap_test(pg->bitmap, index)){ - // 该块未被分配,可能是 double free - return MEMPOOL_DOUBLE_FREE; - } + // uint16_t index = ptr_to_block_index(pg, ptr); + // if(!bitmap_test(pg->bitmap, index)){ + // // 该块未被分配,可能是 double free + // return MEMPOOL_DOUBLE_FREE; + // } // 标记该块为空闲 - bitmap_clear(pg->bitmap, index); + // bitmap_clear(pg->bitmap, index); *(void**)ptr = pg->free_list; pg->free_list = ptr; diff --git a/memory/mempool.h b/memory/mempool.h index e44d50e..38782d0 100644 --- a/memory/mempool.h +++ b/memory/mempool.h @@ -8,7 +8,7 @@ #include // #define MEMPOOL_PAGE_SIZE 4096 -#define MEMPOOL_PAGE_SIZE (4096*2) +#define MEMPOOL_PAGE_SIZE (256 * 1024) #define MEMPOOL_BLOCK_MAX_SIZE 512 #define MEMPOOL_ALIGNMENT 8 #define MEMPOOL_NUM_CLASSES (MEMPOOL_BLOCK_MAX_SIZE / MEMPOOL_ALIGNMENT) @@ -36,7 +36,7 @@ struct mp_page_s{ uint16_t free_count; uint16_t capacity; - uint64_t bitmap[16]; // 最多支持 512/1280 个块 (64*20) + // uint64_t bitmap[16]; }; struct mp_bucket_s{ diff --git a/test-redis/test.c b/test-redis/test.c index e432a93..1c86a9d 100644 --- a/test-redis/test.c +++ b/test-redis/test.c @@ -10,48 +10,49 @@ static void die(redisContext *c, const char *msg) { fprintf(stderr, "%s: %s\n", msg, c && c->err ? c->errstr : "unknown"); + redisFree(c); exit(1); } -static void must_ok(redisReply *r, const char *what) { - if (!r) { fprintf(stderr, "%s: reply null\n", what); exit(1); } +static int must_ok(redisReply *r, const char *what) { + if (!r) { fprintf(stderr, "%s: reply null\n", what); return -1; } if (!(r->type == REDIS_REPLY_STATUS && r->str && strcasecmp(r->str, "OK") == 0)) { fprintf(stderr, "%s: expect +OK, got type=%d str=%s\n", what, r->type, r->str ? r->str : "(null)"); freeReplyObject(r); - exit(1); + return -1; } freeReplyObject(r); } -static void must_int(redisReply *r, long long expect, const char *what) { - if (!r) { fprintf(stderr, "%s: reply null\n", what); exit(1); } +static int must_int(redisReply *r, long long expect, const char *what) { + if (!r) { fprintf(stderr, "%s: reply null\n", what); return -1; } if (r->type != REDIS_REPLY_INTEGER || r->integer != expect) { fprintf(stderr, "%s: expect :%lld, got type=%d int=%lld\n", what, expect, r->type, (long long)r->integer); freeReplyObject(r); - exit(1); + return -1; } freeReplyObject(r); } -static void must_bulk_eq(redisReply *r, const void *buf, size_t n, const char *what) { - if (!r) { fprintf(stderr, "%s: reply null\n", what); exit(1); } +static int must_bulk_eq(redisReply *r, const void *buf, size_t n, const char *what) { + if (!r) { fprintf(stderr, "%s: reply null\n", what); return -1; } if (r->type != REDIS_REPLY_STRING || r->len != n || memcmp(r->str, buf, n) != 0) { fprintf(stderr, "%s: bulk mismatch. type=%d len=%zu\n", what, r->type, r->len); fprintf(stderr, "expect:%s, truely:%s\n", (const char*)buf, r->str); freeReplyObject(r); - exit(1); + return -1; } freeReplyObject(r); } -static void must_nil(redisReply *r, const char *what) { - if (!r) { fprintf(stderr, "%s: reply null\n", what); exit(1); } +static int must_nil(redisReply *r, const char *what) { + if (!r) { fprintf(stderr, "%s: reply null\n", what); return -1; } if (r->type != REDIS_REPLY_NIL) { fprintf(stderr, "%s: expect nil, got type=%d\n", what, r->type); freeReplyObject(r); - exit(1); + return -1; } freeReplyObject(r); } diff --git a/test/test_client.c b/test/test_client.c deleted file mode 100644 index fb64e68..0000000 --- a/test/test_client.c +++ /dev/null @@ -1,220 +0,0 @@ - -#include "test_client.h" -#include -#include -#include - -int kvs_need(const uint8_t *p, const uint8_t *end, size_t n) { - return (p + n <= end) ? 0 : -1; -} - -// 注意u8类型不需要ntoh或者hton -int kvs_read_u8(const uint8_t **pp, const uint8_t *end, uint8_t *out) { - const uint8_t *p = *pp; - if (kvs_need(p, end, 1) < 0) return -1; - *out = *p; - *pp = p + 1; - return 0; -} - -int kvs_read_u16(const uint8_t **pp, const uint8_t *end, uint16_t *out) { - const uint8_t *p = *pp; - if (kvs_need(p, end, 2) < 0) return -1; - uint16_t v; - memcpy(&v, p, 2); - *out = ntohs(v); - *pp = p + 2; - return 0; -} - -int kvs_read_u32(const uint8_t **pp, const uint8_t *end, uint32_t *out) { - const uint8_t *p = *pp; - if (kvs_need(p, end, 4) < 0) return -1; - uint32_t v; - memcpy(&v, p, 4); - *out = ntohl(v); - *pp = p + 4; - return 0; -} - -int kvs_write_u8(uint8_t **pp, const uint8_t *end, uint8_t v) { - uint8_t *p = *pp; - if (kvs_need(p, end, 1) < 0) return -1; - *p = v; - *pp = p + 1; - return 0; -} - -int kvs_write_u16(uint8_t **pp, const uint8_t *end, uint16_t v) { - uint8_t *p = *pp; - if (kvs_need(p, end, 2) < 0) return -1; - uint16_t be = htons(v); - memcpy(p, &be, 2); - *pp = p + 2; - return 0; -} - -int kvs_write_u32(uint8_t **pp, const uint8_t *end, uint32_t v) { - uint8_t *p = *pp; - if (kvs_need(p, end, 4) < 0) return -1; - uint32_t be = htonl(v); - memcpy(p, &be, 4); - *pp = p + 4; - return 0; -} - - - -int getcmd(uint8_t op, const char *key, uint32_t key_len, const char *value, uint32_t value_len, uint8_t *buf){ - if(!buf) return -1; - uint8_t *end = buf + CMD_SIZE; - uint8_t *p = buf; - uint8_t argc = (key == NULL)?0:1; - argc += (value == NULL)?0:1; - - - if (kvs_write_u8(&p, end, op) < 0) return -1; - if (kvs_write_u8(&p, end, argc) < 0) return -1; - - - // 写入 key - if(key){ - int keylen = key_len; - if (kvs_write_u32(&p, end, keylen) < 0) return -1; - if (kvs_need(p, end, keylen) < 0) return -1; - if (keylen > 0) { - memcpy(p, key, keylen); - p += keylen; - } - } - - if(value){ - int vallen = value_len; - if (kvs_write_u32(&p, end, vallen) < 0) return -1; - if (kvs_need(p, end, vallen) < 0) return -1; - if (vallen > 0) { - memcpy(p, value, vallen); - p += vallen; - } - } - - return (p - buf); -} - -int parse_response(const uint8_t *buf, int buflen, kvs_response_t *rsp) { - if(buflen == 0) return 0; - const uint8_t *p = buf; - const uint8_t *end = buf + buflen; - - // 读取 OP - if (kvs_read_u8(&p, end, &rsp->op) < 0) { - fprintf(stderr, "Failed to read op\n"); - return -1; - } - - // 读取 status - if (kvs_read_u8(&p, end, &rsp->status) < 0) { - fprintf(stderr, "Failed to read status\n"); - return -1; - } - - // 读取 datalen - if (kvs_read_u32(&p, end, &rsp->datalen) < 0) { - fprintf(stderr, "Failed to read datalen\n"); - return -1; - } - - // 检查数据长度 - if (kvs_need(p, end, rsp->datalen) < 0) { - fprintf(stderr, "Data length mismatch: expected %u bytes, but only %ld available\n", - rsp->datalen, end - p); - return -1; - } - - // 指向数据部分 - rsp->data = (uint8_t *)p; - - return (p - buf) + rsp->datalen; -} - - -void print_response(const char *cmd_name, const kvs_response_t *rsp) { - printf("%s ", cmd_name); - if(rsp->op == KVS_CMD_GET || rsp->op == KVS_CMD_HGET || rsp->op == KVS_CMD_RGET){ - if (rsp->datalen > 0 && rsp->data != NULL) { - printf("Data: "); - // 尝试以字符串形式打印(如果是可打印字符) - int is_printable = 1; - for (uint32_t i = 0; i < rsp->datalen; i++) { - if (rsp->data[i] < 32 || rsp->data[i] > 126) { - is_printable = 0; - break; - } - } - - if (is_printable) { - printf("\""); - for (uint32_t i = 0; i < rsp->datalen; i++) { - printf("%c", rsp->data[i]); - } - printf("\"\n"); - } else { - // 以十六进制打印 - printf("0x"); - for (uint32_t i = 0; i < rsp->datalen; i++) { - printf("%02x", rsp->data[i]); - } - printf("\n"); - } - } else { - printf("Data: (empty)\n"); - } - }else { - switch (rsp->status) { - case KVS_STATUS_OK: - printf("(OK)\n"); - break; - case KVS_STATUS_ERROR: - printf("(ERROR)\n"); - break; - case KVS_STATUS_NO_EXIST: - printf("(NO_EXIST)\n"); - break; - case KVS_STATUS_EXIST: - printf("(EXISTS)\n"); - break; - default: - printf("(UNKNOWN)\n"); - break; - } - } -} - -int verify_response(const kvs_response_t *rsp, uint8_t expected_op, - uint8_t expected_status, const char *expected_data, uint32_t expected_len) { - if (rsp->op != expected_op) { - printf("❌ OP mismatch: expected %u, got %u\n", expected_op, rsp->op); - return 0; - } - - if (rsp->status != expected_status) { - printf("❌ Status mismatch: expected %u, got %u\n", expected_status, rsp->status); - return 0; - } - - if (expected_data != NULL) { - if (rsp->datalen != expected_len) { - printf("❌ Data length mismatch: expected %u, got %u\n", expected_len, rsp->datalen); - return 0; - } - - if (memcmp(rsp->data, expected_data, expected_len) != 0) { - printf("❌ Data content mismatch\n"); - return 0; - } - } - - return 1; -} - - diff --git a/test/test_client.h b/test/test_client.h deleted file mode 100644 index 7325862..0000000 --- a/test/test_client.h +++ /dev/null @@ -1,161 +0,0 @@ - - /** - * Request - * Cmd: | OP(1) | argc(1) | repeat { arglen(4) | arg } | - * - * Response - * Rsp: | OP(1) | status(1) | datalen(4) | data | - */ -#include -#include -#include -#include -#include -#include -#include - -#define CMD_SIZE (1024) -#define BATCH_SIZE (65536) -#define KVS_BATCH_MAX 128 -#define TIME_SUB_MS(tv1, tv2) ((tv1.tv_sec - tv2.tv_sec) * 1000 + (tv1.tv_usec - tv2.tv_usec) / 1000) - -// #define PRESP print_response -#define PRESP - - -typedef enum { - KVS_STATUS_OK = 0, - KVS_STATUS_ERROR = 1, - KVS_STATUS_NO_EXIST = 2, - KVS_STATUS_EXIST = 3, - KVS_STATUS_BADREQ = 4 -}rsp_ret_status_e; - -enum { - KVS_CMD_START = 0, - // array - KVS_CMD_SET = KVS_CMD_START, - KVS_CMD_GET, - KVS_CMD_DEL, - KVS_CMD_MOD, - KVS_CMD_EXIST, - // rbtree - KVS_CMD_RSET, - KVS_CMD_RGET, - KVS_CMD_RDEL, - KVS_CMD_RMOD, - KVS_CMD_REXIST, - // hash - KVS_CMD_HSET, - KVS_CMD_HGET, - KVS_CMD_HDEL, - KVS_CMD_HMOD, - KVS_CMD_HEXIST, - - KVS_CMD_SSYNC, - KVS_CMD_SAVE, - - KVS_CMD_COUNT, -}; - -typedef struct { - uint8_t op; - uint8_t status; - uint32_t datalen; - uint8_t *data; -} kvs_response_t; - -int kvs_need(const uint8_t *p, const uint8_t *end, size_t n); -int kvs_read_u8(const uint8_t **pp, const uint8_t *end, uint8_t *out); -int kvs_read_u16(const uint8_t **pp, const uint8_t *end, uint16_t *out); -int kvs_read_u32(const uint8_t **pp, const uint8_t *end, uint32_t *out); - -int kvs_write_u8(uint8_t **pp, const uint8_t *end, uint8_t v); -int kvs_write_u16(uint8_t **pp, const uint8_t *end, uint16_t v); -int kvs_write_u32(uint8_t **pp, const uint8_t *end, uint32_t v); - -int getcmd(uint8_t op, const char *key, uint32_t key_len, const char *value, uint32_t value_len, uint8_t *buf); - -int parse_response(const uint8_t *buf, int buflen, kvs_response_t *rsp); -void print_response(const char *cmd_name, const kvs_response_t *rsp); -int verify_response(const kvs_response_t *rsp, uint8_t expected_op, - uint8_t expected_status, const char *expected_data, uint32_t expected_len); - - - - - -typedef struct { - uint8_t buf[BATCH_SIZE]; - int len; // 当前已写入的 batch 字节数 - int cnt; // 当前 batch 里命令条数 - int cmd_len[KVS_BATCH_MAX]; -} kvs_batch_t; - -static void kvs_batch_init(kvs_batch_t *b) -{ - b->len = 0; - b->cnt = 0; - memset(b->cmd_len, 0, sizeof(b->cmd_len)); -} - -/** - * 用 getcmd() 生成单条命令,然后 append 到 batch buffer - * 返回:0 成功,-1 失败(太多条 or buffer 不够) - */ -static int kvs_batch_add(kvs_batch_t *b, uint8_t op, const char *key, uint32_t key_len, const char *value, uint32_t value_len){ - if (b->cnt >= KVS_BATCH_MAX) return -1; - uint8_t tmp[CMD_SIZE]; - int n = getcmd(op, key, key_len, value, value_len, tmp); // 你提供的函数 - if (n <= 0) return -1; - - if (b->len + n > (int)sizeof(b->buf)) return -1; - - memcpy(b->buf + b->len, tmp, n); - b->cmd_len[b->cnt] = n; - b->cnt++; - b->len += n; - return 0; -} - -/** - * 一次性发送 batch - * 返回:发送字节数,<0 表示失败 - */ -static int kvs_batch_send(int fd, const kvs_batch_t *b) -{ - // printf("send : %d\n", b->len); - return (int)send(fd, b->buf, b->len, 0); -} - -/** - * 一次 recv 收回所有响应,然后批量解析为 rsp 数组 - * - * 返回:成功解析出的响应条数(期望是 b->cnt) - */ -static int kvs_batch_recv_parse(int fd, - const kvs_batch_t *b, - kvs_response_t *rsps, // 输出数组,长度 >= b->cnt - uint8_t *recvbuf, - int recvbuf_cap) -{ - int parsed = 0; - int used = 0; - - while(parsed < b->cnt){ - int nrecv = (int)recv(fd, recvbuf+used, recvbuf_cap, 0); - if (nrecv <= 0) return -1; - - int off = 0; - - while (parsed < b->cnt) { - int consumed = parse_response(recvbuf + used, nrecv - off, &rsps[parsed]); - if (consumed <= 0) break; // 不够解析/失败,简单处理:直接退出 - - off += consumed; - used+= consumed; - parsed++; - } - } - return parsed; -} \ No newline at end of file diff --git a/test/testcase.c b/test/testcase.c deleted file mode 100644 index 3e03fdb..0000000 --- a/test/testcase.c +++ /dev/null @@ -1,539 +0,0 @@ - -#include "test_client.h" -#include - - -int connect_tcpserver(const char *ip, unsigned short port) { - - int connfd = socket(AF_INET, SOCK_STREAM, 0); - - struct sockaddr_in server_addr; - memset(&server_addr, 0, sizeof(struct sockaddr_in)); - - server_addr.sin_family = AF_INET; - server_addr.sin_addr.s_addr = inet_addr(ip); - server_addr.sin_port = htons(port); - - if (0 != connect(connfd, (struct sockaddr*)&server_addr, sizeof(struct sockaddr_in))) { - perror("connect"); - return -1; - } - - return connfd; - -} - - -int send_msg(int connfd, char *msg, int length) { - - int res = send(connfd, msg, length, 0); - if (res < 0) { - perror("send"); - exit(1); - } - return res; -} - -int recv_msg(int connfd, char *msg, int length) { - - int res = recv(connfd, msg, length, 0); - if (res < 0) { - perror("recv"); - exit(1); - } - return res; - -} - -void testcase(int connfd, uint8_t op, const char* key, uint32_t key_len, const char* value, - uint32_t value_len, rsp_ret_status_e st, const char* rsp_value, uint32_t expect_len, const char* command_name){ - uint8_t buf[CMD_SIZE]; - uint8_t result[CMD_SIZE]; - kvs_response_t rsp; - int len, recv_len; - - len = getcmd(op, key, key_len, value, value_len, buf); - send_msg(connfd, buf, len); - recv_len = recv_msg(connfd, result, CMD_SIZE); - if (parse_response(result, recv_len, &rsp) > 0) { - PRESP(command_name, &rsp); - if(!verify_response(&rsp, op, st, rsp_value, expect_len)) printf("%s\n", command_name); - }else{ - printf("parser error\n"); - } - - return ; -} - - -void array_testcase_1w(int connfd) { - - int count = 1000; - int i = 0; - - struct timeval tv_begin; - gettimeofday(&tv_begin, NULL); - - for (i = 0;i < count;i ++) { - testcase(connfd, KVS_CMD_SET, "name", 4, "l\r\0n", 4, KVS_STATUS_OK, NULL, 0, "SET NAME"); - testcase(connfd, KVS_CMD_GET, "name", 4, NULL, 0, KVS_STATUS_OK, "l\r\0n", 4, "GET NAME"); - testcase(connfd, KVS_CMD_MOD, "name", 4, "liu", 3, KVS_STATUS_OK, NULL, 0, "MOD NAME"); - testcase(connfd, KVS_CMD_GET, "name", 4, NULL, 0, KVS_STATUS_OK, "liu", 3, "GET NAME"); - testcase(connfd, KVS_CMD_EXIST, "name", 4, NULL, 0, KVS_STATUS_EXIST, NULL, 0, "EXIST NAME"); - testcase(connfd, KVS_CMD_DEL, "name", 4, NULL, 0, KVS_STATUS_OK, NULL, 0, "DEL NAME"); - testcase(connfd, KVS_CMD_EXIST, "name", 4, NULL, 0, KVS_STATUS_NO_EXIST, NULL, 0, "EXIST NAME"); - - testcase(connfd, KVS_CMD_MOD, "stu", 3, "liu", 3, KVS_STATUS_NO_EXIST, NULL, 0, "MOD NAME"); - testcase(connfd, KVS_CMD_DEL, "stu", 3, NULL, 0, KVS_STATUS_NO_EXIST, NULL, 0, "DEL SUT"); - } - - struct timeval tv_end; - gettimeofday(&tv_end, NULL); - - int time_used = TIME_SUB_MS(tv_end, tv_begin); // ms - - printf("array testcase --> time_used: %d, qps: %d\n", time_used, 9000 * 1000 / time_used); - -} - -void rbtree_testcase_1w(int connfd) { - - int count = 1000; - int i = 0; - - struct timeval tv_begin; - gettimeofday(&tv_begin, NULL); - - for (i = 0;i < count;i ++) { - testcase(connfd, KVS_CMD_RSET, "name", 4, "l\r\0n", 4, KVS_STATUS_OK, NULL, 0, "RSET NAME"); - testcase(connfd, KVS_CMD_RGET, "name", 4, NULL, 0, KVS_STATUS_OK, "l\r\0n", 4, "RGET NAME"); - testcase(connfd, KVS_CMD_RMOD, "name", 4, "liu", 3, KVS_STATUS_OK, NULL, 0, "RMOD NAME"); - testcase(connfd, KVS_CMD_RGET, "name", 4, NULL, 0, KVS_STATUS_OK, "liu", 3, "RGET NAME"); - testcase(connfd, KVS_CMD_REXIST, "name", 4, NULL, 0, KVS_STATUS_EXIST, NULL, 0, "REXIST NAME"); - testcase(connfd, KVS_CMD_RDEL, "name", 4, NULL, 0, KVS_STATUS_OK, NULL, 0, "RDEL NAME"); - testcase(connfd, KVS_CMD_REXIST, "name", 4, NULL, 0, KVS_STATUS_NO_EXIST, NULL, 0, "REXIST NAME"); - - testcase(connfd, KVS_CMD_RMOD, "stu", 3, "liu", 3, KVS_STATUS_NO_EXIST, NULL, 0, "RMOD NAME"); - testcase(connfd, KVS_CMD_RDEL, "stu", 3, NULL, 0, KVS_STATUS_NO_EXIST, NULL, 0, "RDEL SUT"); - } - - struct timeval tv_end; - gettimeofday(&tv_end, NULL); - - int time_used = TIME_SUB_MS(tv_end, tv_begin); // ms - - printf("array testcase --> time_used: %d, qps: %d\n", time_used, 9000 * 1000 / time_used); - -} - -void hash_testcase_1w(int connfd) { - - int count = 1000; - int i = 0; - - struct timeval tv_begin; - gettimeofday(&tv_begin, NULL); - - for (i = 0;i < count;i ++) { - testcase(connfd, KVS_CMD_HSET, "name", 4, "l\r\0n", 4, KVS_STATUS_OK, NULL, 0, "HSET NAME"); - testcase(connfd, KVS_CMD_HGET, "name", 4, NULL, 0, KVS_STATUS_OK, "l\r\0n", 4, "HGET NAME"); - testcase(connfd, KVS_CMD_HMOD, "name", 4, "liu", 3, KVS_STATUS_OK, NULL, 0, "HMOD NAME"); - testcase(connfd, KVS_CMD_HGET, "name", 4, NULL, 0, KVS_STATUS_OK, "liu", 3, "HGET NAME"); - testcase(connfd, KVS_CMD_HEXIST, "name", 4, NULL, 0, KVS_STATUS_EXIST, NULL, 0, "HEXIST NAME"); - testcase(connfd, KVS_CMD_HDEL, "name", 4, NULL, 0, KVS_STATUS_OK, NULL, 0, "HDEL NAME"); - testcase(connfd, KVS_CMD_HEXIST, "name", 4, NULL, 0, KVS_STATUS_NO_EXIST, NULL, 0, "HEXIST NAME"); - - testcase(connfd, KVS_CMD_HMOD, "stu", 3, "liu", 3, KVS_STATUS_NO_EXIST, NULL, 0, "HMOD NAME"); - testcase(connfd, KVS_CMD_HDEL, "stu", 3, NULL, 0, KVS_STATUS_NO_EXIST, NULL, 0, "HDEL SUT"); - } - - struct timeval tv_end; - gettimeofday(&tv_end, NULL); - - int time_used = TIME_SUB_MS(tv_end, tv_begin); // ms - - printf("array testcase --> time_used: %d, qps: %d\n", time_used, 9*count * 1000 / time_used); - -} - -void do_batch_test(int fd, int op, const char *key, const char *value, rsp_ret_status_e st, const char *rsp_value){ - kvs_batch_t batch; - kvs_batch_init(&batch); - - char bkey[256]={0}, bval[256]={0}; - - // 组 batch(最多 64 条) - for(int i = 0;i < 100; ++ i){ - if(value == NULL){ - int klen = sprintf(bkey, "%s%d", key, i); - kvs_batch_add(&batch, op, bkey, klen, NULL, 0); - }else{ - int klen = sprintf(bkey, "%s%d", key, i); - int vlen = sprintf(bval, "%s%d", value, i); - kvs_batch_add(&batch, op, bkey, klen, bval, vlen); - } - } - - // 一次性发送 - kvs_batch_send(fd, &batch); - - // 一次性 recv + parse - uint8_t recvbuf[BATCH_SIZE]; - kvs_response_t rsps[KVS_BATCH_MAX]; - - int nrsp = kvs_batch_recv_parse(fd, &batch, rsps, recvbuf, sizeof(recvbuf)); - - // 打印/处理 - for (int i = 0; i < nrsp; i++) { - print_response(bkey, &rsps[i]); - int vlen; - if(rsp_value != NULL) vlen = sprintf(bval, "%s%d", rsp_value, i); - else vlen = 0; - verify_response(&rsps[i], op, st, bval, vlen); - } -} - -void array_testcase_1w_batch(int connfd) { - kvs_batch_t batch; - kvs_batch_init(&batch); - - int count = 1000; - int i = 0; - - struct timeval tv_begin; - gettimeofday(&tv_begin, NULL); - - for (i = 0;i < count;i ++) { - batch.cnt = 0; - batch.len = 0; - kvs_batch_add(&batch, KVS_CMD_SET, "name", 4, "l\r\0n", 4); - kvs_batch_add(&batch, KVS_CMD_GET, "name", 4, NULL, 0); - kvs_batch_add(&batch, KVS_CMD_MOD, "name", 4, "liu", 3); - kvs_batch_add(&batch, KVS_CMD_GET, "name", 4, NULL, 0); - kvs_batch_add(&batch, KVS_CMD_EXIST, "name", 4, NULL, 0); - kvs_batch_add(&batch, KVS_CMD_DEL, "name", 4, NULL, 0); - kvs_batch_add(&batch, KVS_CMD_EXIST, "name", 4, NULL, 0); - - kvs_batch_add(&batch, KVS_CMD_MOD, "stu", 3, "liu", 3); - kvs_batch_add(&batch, KVS_CMD_DEL, "stu", 3, NULL, 0); - - kvs_batch_send(connfd, &batch); - - uint8_t recvbuf[BATCH_SIZE]; - kvs_response_t rsps[KVS_BATCH_MAX]; - int nrsp = kvs_batch_recv_parse(connfd, &batch, rsps, recvbuf, sizeof(recvbuf)); - } - - struct timeval tv_end; - gettimeofday(&tv_end, NULL); - - int time_used = TIME_SUB_MS(tv_end, tv_begin); // ms - - printf("array testcase --> time_used: %d, qps: %d\n", time_used, 9000 * 1000 / time_used); - -} - -void batch_qps(int connfd) { - const int N = 1000000; - const int B = 100; // do_batch_test() 里写死 50 - static char valA[256]; - static char valB[256]; - static char valC[256]; - - static int inited = 0; - if (!inited) { - // 填充 255 字节,最后补 '\0' - memset(valA, 'A', 255); valA[255] = '\0'; - memset(valB, 'B', 255); valB[255] = '\0'; - memset(valC, 'C', 255); valC[255] = '\0'; - inited = 1; - } - - struct timeval tv_begin, tv_end; - gettimeofday(&tv_begin, NULL); - - // ---------------- Phase 1: ADD 两条 DEL 一条 (100w) ---------------- - // 每轮:ADD/SET A_i, ADD/SET B_i, DEL A_i - // 用 batch:每批处理 idx..idx+49 - for (int base = 0; base < N; base += B) { - // prefix 必须短,避免 do_batch_test 里 bkey[15] 溢出 - // do_batch_test 会生成: prefix + i (0..49) - // 我们把 base 编进 prefix,保证全局 key 唯一 - char preA[16], preB[16]; - - // 例:A123450_0..A123450_49(base=123450) - // 注意:这里 prefix 长度要尽量 <= 10 左右 - snprintf(preA, sizeof(preA), "A%d_", base/100); - snprintf(preB, sizeof(preB), "B%d_", base/100); - - do_batch_test(connfd, KVS_CMD_RSET, preA, valA, KVS_STATUS_OK, NULL); // 50次 RSET A - do_batch_test(connfd, KVS_CMD_RSET, preB, valB, KVS_STATUS_OK, NULL); // 50次 RSET B - do_batch_test(connfd, KVS_CMD_RDEL, preA, NULL, KVS_STATUS_OK, NULL); // 50次 RDEL A - - if (base % 10000 == 0) printf("P1 base:%d\n", base); - } - printf("phase 1 end\n"); - - // ---------------- Phase 2: ADD 一条 DEL 两条 (100w) ---------------- - // 每轮:ADD/SET C_i, DEL B_i, DEL C_i - for (int base = 0; base < N; base += B) { - char preB[16], preC[16]; - snprintf(preB, sizeof(preB), "B%d_", base/100); - snprintf(preC, sizeof(preC), "C%d_", base/100); - - do_batch_test(connfd, KVS_CMD_RSET, preC, valC, KVS_STATUS_OK, NULL); // 50次 RSET C - do_batch_test(connfd, KVS_CMD_RDEL, preB, NULL, KVS_STATUS_OK, NULL); // 50次 RDEL B - do_batch_test(connfd, KVS_CMD_RDEL, preC, NULL, KVS_STATUS_OK, NULL); // 50次 RDEL C - - if (base % 10000 == 0) printf("P2 base:%d\n", base); - } - printf("phase 2 end\n"); - - gettimeofday(&tv_end, NULL); - int time_used = TIME_SUB_MS(tv_end, tv_begin); - - // 真实总 ops 还是 6*N (每轮 6 个操作) - long long ops = (long long)N * 6; - long long qps = (time_used > 0) ? (ops * 1000 / time_used) : 0; - - printf("BATCH(do_batch_test) ADD2-DEL1 then ADD1-DEL2 (N=%d) --> time_used=%d ms, ops=%lld, qps=%lld\n", - N, time_used, ops, qps); -} - -void save(int connfd){ - testcase(connfd, KVS_CMD_SAVE, NULL, 0, NULL, 0, KVS_STATUS_OK, NULL, 0, "SAVE"); -} - -void testcase_add2_del1_then_add1_del2_100w(int connfd) { - const int N = 1000000; - - // 如果你有 KVS_CMD_ADD 就用 ADD;没有就用 SET(但 SET 会覆盖,意义不同) - // 这里按你说的“会返回 EXIST”,所以我用 KVS_CMD_ADD 来写。 - // 若你实际命令叫 KVS_CMD_SET 且语义是 ADD,请自行替换。 - const char *valA = "va"; - const char *valB = "vb"; - const char *valC = "vc"; - - char keyA[64], keyB[64], keyC[64]; - - struct timeval tv_begin, tv_end; - gettimeofday(&tv_begin, NULL); - - // ---------------- Phase 1: ADD 两条 DEL 一条 (100w) ---------------- - // 每轮:ADD A_i, ADD B_i, DEL A_i -> 留下 B_i - for (int i = 0; i < N; i++) { - int klenA = snprintf(keyA, sizeof(keyA), "A_%d", i); - int klenB = snprintf(keyB, sizeof(keyB), "B_%d", i); - - testcase(connfd, KVS_CMD_RSET, keyA, klenA, valA, 2, KVS_STATUS_OK, NULL, 0, "P1 ADD A_i"); - testcase(connfd, KVS_CMD_RSET, keyB, klenB, valB, 2, KVS_STATUS_OK, NULL, 0, "P1 ADD B_i"); - testcase(connfd, KVS_CMD_RDEL, keyA, klenA, NULL, 0, KVS_STATUS_OK, NULL, 0, "P1 DEL A_i"); - - if(i%10000 == 0) printf("i:%d\n", i); - } - - printf("phase 1 end\n"); - - // ---------------- Phase 2: ADD 一条 DEL 两条 (100w) ---------------- - // 每轮:ADD C_i, DEL B_i, DEL C_i -> 每轮净删一个 B_i - for (int i = 0; i < N; i++) { - int klenC = snprintf(keyC, sizeof(keyC), "C_%d", i); - int klenB = snprintf(keyB, sizeof(keyB), "B_%d", i); - - testcase(connfd, KVS_CMD_RSET, keyC, klenC, valC, 2, KVS_STATUS_OK, NULL, 0, "P2 ADD C_i"); - testcase(connfd, KVS_CMD_RDEL, keyB, klenB, NULL, 0, KVS_STATUS_OK, NULL, 0, "P2 DEL B_i"); - testcase(connfd, KVS_CMD_RDEL, keyC, klenC, NULL, 0, KVS_STATUS_OK, NULL, 0, "P2 DEL C_i"); - - if(i%10000 == 0) printf("i:%d\n", i); - } - - printf("phase 2 end\n"); - - // for (int j = 0; j < 5; j++) { - // int idx = (j == 0) ? 0 : (j == 1) ? (N/2) : (N-1); - - // int klenA = snprintf(keyA, sizeof(keyA), "A_%d", idx); - // int klenB = snprintf(keyB, sizeof(keyB), "B_%d", idx); - // int klenC = snprintf(keyC, sizeof(keyC), "C_%d", idx); - - // testcase(connfd, KVS_CMD_EXIST, keyA, klenA, NULL, 0, KVS_STATUS_NO_EXIST, NULL, 0, "FINAL A not exist"); - // testcase(connfd, KVS_CMD_EXIST, keyB, klenB, NULL, 0, KVS_STATUS_NO_EXIST, NULL, 0, "FINAL B not exist"); - // testcase(connfd, KVS_CMD_EXIST, keyC, klenC, NULL, 0, KVS_STATUS_NO_EXIST, NULL, 0, "FINAL C not exist"); - // } - - gettimeofday(&tv_end, NULL); - int time_used = TIME_SUB_MS(tv_end, tv_begin); - - // 统计:Phase1 每轮3 ops,Phase2 每轮3 ops - long long ops = (long long)N * 3 + (long long)N * 3; - long long qps = (time_used > 0) ? (ops * 1000 / time_used) : 0; - - printf("ADD2-DEL1 then ADD1-DEL2 (N=%d) --> time_used=%d ms, ops=%lld, qps=%lld\n", - N, time_used, ops, qps); -} - -void send_spec_chars(int connfd){ - const char *v_ws = "li an\tok\nend"; /* 内容含空格、\t、\n */ - int v_ws_len = 12; /* 手算:l i ' ' a n \t o k \n e n d = 12 */ - - testcase(connfd, KVS_CMD_RSET, - "ws", 2, - v_ws, v_ws_len, - KVS_STATUS_OK, - NULL, 0, - "RSET WHITESPACE"); - - testcase(connfd, KVS_CMD_RGET, - "ws", 2, - NULL, 0, - KVS_STATUS_OK, - v_ws, v_ws_len, - "RGET WHITESPACE"); - - /* 2) 引号与反斜杠:测试是否被错误转义 */ - const char *v_quote = "he\"llo\\world'!"; - /* 字节数:h e " l l o \ w o r l d ' ! = 15 */ - int v_quote_len = 15; - - testcase(connfd, KVS_CMD_RSET, - "quote", 5, - v_quote, v_quote_len, - KVS_STATUS_OK, - NULL, 0, - "RSET QUOTE BACKSLASH"); - - testcase(connfd, KVS_CMD_RGET, - "quote", 5, - NULL, 0, - KVS_STATUS_OK, - v_quote, v_quote_len, - "RGET QUOTE BACKSLASH"); - - - /* 3) 分隔符字符:冒号/逗号/分号/竖线 */ - const char *v_sep = "a:b,c;d|e"; - int v_sep_len = 9; /* a : b , c ; d | e = 9 */ - - testcase(connfd, KVS_CMD_RSET, - "sep", 3, - v_sep, v_sep_len, - KVS_STATUS_OK, - NULL, 0, - "RSET SEPARATORS"); - - testcase(connfd, KVS_CMD_RGET, - "sep", 3, - NULL, 0, - KVS_STATUS_OK, - v_sep, v_sep_len, - "RGET SEPARATORS"); - - /* 4) CRLF:\r\n 组合(最容易把一条请求拆错/响应拼错) */ - const char *v_crlf = "line1\r\nline2"; - int v_crlf_len = 12; /* line1(5) + \r(1) + \n(1) + line2(5) = 12 */ - - testcase(connfd, KVS_CMD_RSET, - "crlf", 4, - v_crlf, v_crlf_len, - KVS_STATUS_OK, - NULL, 0, - "RSET CRLF"); - - testcase(connfd, KVS_CMD_RGET, - "crlf", 4, - NULL, 0, - KVS_STATUS_OK, - v_crlf, v_crlf_len, - "RGET CRLF"); - - /* 5) 二进制数据:包含 \0,必须按长度处理,不能用 strlen */ - char v_bin[] = { 'A', 0x00, 'B', 'C', 0x00, 'D' }; - int v_bin_len = 6; - - testcase(connfd, KVS_CMD_RSET, - "bin", 3, - v_bin, v_bin_len, - KVS_STATUS_OK, - NULL, 0, - "RSET BINARY WITH NUL"); - - testcase(connfd, KVS_CMD_RGET, - "bin", 3, - NULL, 0, - KVS_STATUS_OK, - v_bin, v_bin_len, - "RGET BINARY WITH NUL"); - - /* 6) UTF-8:中文 + emoji(测试多字节) */ - const char *v_utf8 = "中文🙂"; - /* "中"(3字节) + "文"(3字节) + "🙂"(4字节) = 10字节 */ - int v_utf8_len = 10; - - testcase(connfd, KVS_CMD_RSET, - "utf8", 4, - v_utf8, v_utf8_len, - KVS_STATUS_OK, - NULL, 0, - "RSET UTF8"); - - testcase(connfd, KVS_CMD_RGET, - "utf8", 4, - NULL, 0, - KVS_STATUS_OK, - v_utf8, v_utf8_len, - "RGET UTF8"); - -} - -int main(int argc, char *argv[]) { - if (argc != 4) { - printf("arg error\n"); - return -1; - } - - char *ip = argv[1]; - int port = atoi(argv[2]); - int mode = atoi(argv[3]); - - int connfd = connect_tcpserver(ip, port); - - if(mode == 0){ - array_testcase_1w(connfd); - }else if(mode == 1){ - array_testcase_1w_batch(connfd); - }else if(mode == 2){ - rbtree_testcase_1w(connfd); - }else if(mode == 3){ - hash_testcase_1w(connfd); - }else if(mode == 4){ - testcase_add2_del1_then_add1_del2_100w(connfd); - }else if(mode == 10){ - do_batch_test(connfd, KVS_CMD_SET, "array_set", "array_val", KVS_STATUS_OK, NULL); - }else if(mode == 11){ - do_batch_test(connfd, KVS_CMD_GET, "array_set", NULL, KVS_STATUS_OK, "array_val"); - }else if(mode == 12){ - do_batch_test(connfd, KVS_CMD_EXIST, "array_set", NULL, KVS_STATUS_EXIST, NULL); - }else if(mode == 13){ - do_batch_test(connfd, KVS_CMD_DEL, "array_set", NULL, KVS_STATUS_OK, NULL); - }else if(mode == 20){ - do_batch_test(connfd, KVS_CMD_RSET, "rbtree_set", "rbtree_val", KVS_STATUS_OK, NULL); - }else if(mode == 21){ - do_batch_test(connfd, KVS_CMD_RGET, "rbtree_set", NULL, KVS_STATUS_OK, "rbtree_val"); - }else if(mode == 22){ - do_batch_test(connfd, KVS_CMD_REXIST, "rbtree_set", NULL, KVS_STATUS_OK, NULL); - }else if(mode == 30){ - do_batch_test(connfd, KVS_CMD_HSET, "hash_set", "hash_val", KVS_STATUS_OK, NULL); - }else if(mode == 31){ - do_batch_test(connfd, KVS_CMD_HGET, "hash_set", NULL, KVS_STATUS_OK, "hash_val"); - }else if(mode == 32){ - do_batch_test(connfd, KVS_CMD_HEXIST, "hash_set", NULL, KVS_STATUS_OK, NULL); - }else if(mode == -1){ - save(connfd); - }else if(mode == 5){ - batch_qps(connfd); - }else if(mode == 6){ - send_spec_chars(connfd); - } - - return 0; -} \ No newline at end of file