From f9879ab449902ed89a21ea86d5726048a65242d6 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Wed, 29 Nov 2023 14:16:15 -0500 Subject: [PATCH] added part 4 --- .idea/.gitignore | 8 + .idea/OS_Project.iml | 8 + .idea/editor.xml | 91 ++++ .idea/modules.xml | 8 + .idea/vcs.xml | 6 + Part3/09_memory/kernel/kernel.c | 5 + Part4/10_scheduler/Makefile | 51 +++ Part4/10_scheduler/boot/32bit_print.asm | 26 ++ Part4/10_scheduler/boot/32bit_print.bin_ | Bin 0 -> 592 bytes Part4/10_scheduler/boot/bootsect.asm | 51 +++ Part4/10_scheduler/boot/disk.asm | 46 ++ Part4/10_scheduler/boot/gdt.asm | 35 ++ Part4/10_scheduler/boot/kernel_entry.asm | 4 + Part4/10_scheduler/boot/print.asm | 37 ++ Part4/10_scheduler/boot/print_hex.asm | 46 ++ Part4/10_scheduler/boot/switch_pm.asm | 22 + Part4/10_scheduler/cpu/idt.c | 16 + Part4/10_scheduler/cpu/idt.h | 39 ++ Part4/10_scheduler/cpu/interrupt.asm | 425 ++++++++++++++++++ Part4/10_scheduler/cpu/isr.c | 153 +++++++ Part4/10_scheduler/cpu/isr.h | 89 ++++ Part4/10_scheduler/cpu/ports.c | 37 ++ Part4/10_scheduler/cpu/ports.h | 11 + Part4/10_scheduler/cpu/timer.c | 25 ++ Part4/10_scheduler/cpu/timer.h | 8 + Part4/10_scheduler/cpu/types.h | 18 + Part4/10_scheduler/drivers/keyboard.c | 51 +++ Part4/10_scheduler/drivers/keyboard.h | 7 + Part4/10_scheduler/drivers/screen.c | 149 ++++++ Part4/10_scheduler/drivers/screen.h | 22 + Part4/10_scheduler/e_compile.sh | 14 + Part4/10_scheduler/hello.c | 55 +++ Part4/10_scheduler/hey_there | Bin 0 -> 8552 bytes Part4/10_scheduler/kernel/kernel.c | 41 ++ Part4/10_scheduler/kernel/kernel.h | 12 + Part4/10_scheduler/libc/function.h | 8 + Part4/10_scheduler/libc/globals.c | 5 + Part4/10_scheduler/libc/globals.h | 9 + Part4/10_scheduler/libc/mem.c | 43 ++ Part4/10_scheduler/libc/mem.h | 22 + Part4/10_scheduler/libc/string.c | 79 ++++ Part4/10_scheduler/libc/string.h | 14 + Part4/10_scheduler/s_compile.sh | 14 + ...S3502S01_Project_IV_Scheduler_Stub(1).docx | Bin 0 -> 103019 bytes 44 files changed, 1810 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/OS_Project.iml create mode 100644 .idea/editor.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 Part4/10_scheduler/Makefile create mode 100644 Part4/10_scheduler/boot/32bit_print.asm create mode 100644 Part4/10_scheduler/boot/32bit_print.bin_ create mode 100644 Part4/10_scheduler/boot/bootsect.asm create mode 100644 Part4/10_scheduler/boot/disk.asm create mode 100644 Part4/10_scheduler/boot/gdt.asm create mode 100644 Part4/10_scheduler/boot/kernel_entry.asm create mode 100644 Part4/10_scheduler/boot/print.asm create mode 100644 Part4/10_scheduler/boot/print_hex.asm create mode 100644 Part4/10_scheduler/boot/switch_pm.asm create mode 100644 Part4/10_scheduler/cpu/idt.c create mode 100644 Part4/10_scheduler/cpu/idt.h create mode 100644 Part4/10_scheduler/cpu/interrupt.asm create mode 100644 Part4/10_scheduler/cpu/isr.c create mode 100644 Part4/10_scheduler/cpu/isr.h create mode 100644 Part4/10_scheduler/cpu/ports.c create mode 100644 Part4/10_scheduler/cpu/ports.h create mode 100644 Part4/10_scheduler/cpu/timer.c create mode 100644 Part4/10_scheduler/cpu/timer.h create mode 100644 Part4/10_scheduler/cpu/types.h create mode 100644 Part4/10_scheduler/drivers/keyboard.c create mode 100644 Part4/10_scheduler/drivers/keyboard.h create mode 100644 Part4/10_scheduler/drivers/screen.c create mode 100644 Part4/10_scheduler/drivers/screen.h create mode 100644 Part4/10_scheduler/e_compile.sh create mode 100644 Part4/10_scheduler/hello.c create mode 100644 Part4/10_scheduler/hey_there create mode 100644 Part4/10_scheduler/kernel/kernel.c create mode 100644 Part4/10_scheduler/kernel/kernel.h create mode 100644 Part4/10_scheduler/libc/function.h create mode 100644 Part4/10_scheduler/libc/globals.c create mode 100644 Part4/10_scheduler/libc/globals.h create mode 100644 Part4/10_scheduler/libc/mem.c create mode 100644 Part4/10_scheduler/libc/mem.h create mode 100644 Part4/10_scheduler/libc/string.c create mode 100644 Part4/10_scheduler/libc/string.h create mode 100644 Part4/10_scheduler/s_compile.sh create mode 100644 Part4/CS3502S01_Project_IV_Scheduler_Stub(1).docx diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/OS_Project.iml b/.idea/OS_Project.iml new file mode 100644 index 0000000..bc2cd87 --- /dev/null +++ b/.idea/OS_Project.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/editor.xml b/.idea/editor.xml new file mode 100644 index 0000000..25eca97 --- /dev/null +++ b/.idea/editor.xml @@ -0,0 +1,91 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..9071f6f --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Part3/09_memory/kernel/kernel.c b/Part3/09_memory/kernel/kernel.c index 2c47aee..70309d9 100644 --- a/Part3/09_memory/kernel/kernel.c +++ b/Part3/09_memory/kernel/kernel.c @@ -153,3 +153,8 @@ } return result; } + + +void print_holes(node* umem_head) { + +} \ No newline at end of file diff --git a/Part4/10_scheduler/Makefile b/Part4/10_scheduler/Makefile new file mode 100644 index 0000000..504d70f --- /dev/null +++ b/Part4/10_scheduler/Makefile @@ -0,0 +1,51 @@ +C_SOURCES = $(wildcard kernel/*.c drivers/*.c cpu/*.c libc/*.c) +HEADERS = $(wildcard kernel/*.h drivers/*.h cpu/*.h libc/*.h) +# Nice syntax for file extension replacement +OBJ = ${C_SOURCES:.c=.o cpu/interrupt.o} + +# Change this if your cross-compiler is somewhere else +CC = /usr/bin/gcc +GDB = /usr/bin/gdb +# -g: Use debugging symbols in gcc +CFLAGS = -g -m32 -fno-pie -ffreestanding -nostdlib -nostdinc -fno-builtin -fno-stack-protector -nostartfiles -nodefaultlibs -Wall -Wextra -Werror + +# First rule is run by default +os-image.bin: boot/bootsect.bin kernel.bin + cat $^ > os-image.bin + +# '--oformat binary' deletes all symbols as a collateral, so we don't need +# to 'strip' them manually on this case +kernel.bin: boot/kernel_entry.o ${OBJ} + /usr/bin/ld -m elf_i386 -o $@ -Ttext 0x1000 $^ --oformat binary + +# Used for debugging purposes +kernel.elf: boot/kernel_entry.o ${OBJ} + /usr/bin/ld -m elf_i386 -o $@ -Ttext 0x1000 $^ + +run: os-image.bin + qemu-system-i386 -vga std -drive file=$<,index=0,if=floppy,format=raw + +curses: os-image.bin + qemu-system-i386 -curses -drive file=$<,index=0,if=floppy,format=raw + +# Open the connection to qemu and load our kernel-object file with symbols +debug: os-image.bin kernel.elf + qemu-system-i386 -curses -s -drive file=os-image.bin,index=0,if=floppy,format=raw -d guest_errors,int + +gdb: + ${GDB} -ex "target remote localhost:1234" -ex "symbol-file kernel.elf" + +# Generic rules for wildcards +# To make an object, always compile from its .c +%.o: %.c ${HEADERS} + ${CC} ${CFLAGS} -c $< -o $@ + +%.o: %.asm + nasm $< -f elf -o $@ + +%.bin: %.asm + nasm $< -f bin -o $@ + +clean: + rm -rf *.bin *.dis *.o *.s os-image.bin *.elf + rm -rf kernel/*.o boot/*.bin drivers/*.o boot/*.o cpu/*.o libc/*.o diff --git a/Part4/10_scheduler/boot/32bit_print.asm b/Part4/10_scheduler/boot/32bit_print.asm new file mode 100644 index 0000000..4169a17 --- /dev/null +++ b/Part4/10_scheduler/boot/32bit_print.asm @@ -0,0 +1,26 @@ +[bits 32] ; using 32-bit protected mode + +; this is how constants are defined +VIDEO_MEMORY equ 0xb8000 +WHITE_OB_BLACK equ 0x0f ; the color byte for each character + +print_string_pm: + pusha + mov edx, VIDEO_MEMORY + +print_string_pm_loop: + mov al, [ebx] ; [ebx] is the address of our character + mov ah, WHITE_OB_BLACK + + cmp al, 0 ; check if end of string + je print_string_pm_done + + mov [edx], ax ; store character + attribute in video memory + add ebx, 1 ; next char + add edx, 2 ; next video memory position + + jmp print_string_pm_loop + +print_string_pm_done: + popa + ret diff --git a/Part4/10_scheduler/boot/32bit_print.bin_ b/Part4/10_scheduler/boot/32bit_print.bin_ new file mode 100644 index 0000000000000000000000000000000000000000..674afb14e43f76a4059986cb0630b283b4636042 GIT binary patch literal 592 zcmb<-^>JflWMqH=Mh0dE1doBi0V-hvrZpH?8JJ*7Nuoh!f-oCYmjI9>jbwrVl+6yL znUTZ|fa(;H_#iVtKoE$LU6KHlXaI__05J!Y2AL@d#K`770IEv|iopQPJQzP=7efO# zLl^TFejA1o?zB#(=EIE5hnQZ!O*{-yqF0hyQNo~CoKaj-RFaqkWL4%uXb2x>5DpsI zJ{E?L|B;n}LLTHVkP9H-<9|6IgCELc0IJu8vq20-23sHr3sVq32*?Nd83KT|85<>K zmc$nnW#*OWB^Kv0gn7ES`p5ga`uYb&GK710hPcN2JH 0x0004 by masking first three to zeros + add al, 0x30 ; add 0x30 to N to convert it to ASCII "N" + cmp al, 0x39 ; if > 9, add extra 8 to represent 'A' to 'F' + jle step2 + add al, 7 ; 'A' is ASCII 65 instead of 58, so 65-58=7 + +step2: + ; 2. get the correct position of the string to place our ASCII char + ; bx <- base address + string length - index of char + mov bx, HEX_OUT + 5 ; base + length + sub bx, cx ; our index variable + mov [bx], al ; copy the ASCII char on 'al' to the position pointed by 'bx' + ror dx, 4 ; 0x1234 -> 0x4123 -> 0x3412 -> 0x2341 -> 0x1234 + + ; increment index and loop + add cx, 1 + jmp hex_loop + +end: + ; prepare the parameter and call the function + ; remember that print receives parameters in 'bx' + mov bx, HEX_OUT + call print + + popa + ret + +HEX_OUT: + db '0x0000',0 ; reserve memory for our new string diff --git a/Part4/10_scheduler/boot/switch_pm.asm b/Part4/10_scheduler/boot/switch_pm.asm new file mode 100644 index 0000000..9394da3 --- /dev/null +++ b/Part4/10_scheduler/boot/switch_pm.asm @@ -0,0 +1,22 @@ +[bits 16] +switch_to_pm: + cli ; 1. disable interrupts + lgdt [gdt_descriptor] ; 2. load the GDT descriptor + mov eax, cr0 + or eax, 0x1 ; 3. set 32-bit mode bit in cr0 + mov cr0, eax + jmp CODE_SEG:init_pm ; 4. far jump by using a different segment + +[bits 32] +init_pm: ; we are now using 32-bit instructions + mov ax, DATA_SEG ; 5. update the segment registers + mov ds, ax + mov ss, ax + mov es, ax + mov fs, ax + mov gs, ax + + mov ebp, 0x90000 ; 6. update the stack right at the top of the free space + mov esp, ebp + + call BEGIN_PM ; 7. Call a well-known label with useful code diff --git a/Part4/10_scheduler/cpu/idt.c b/Part4/10_scheduler/cpu/idt.c new file mode 100644 index 0000000..f904a00 --- /dev/null +++ b/Part4/10_scheduler/cpu/idt.c @@ -0,0 +1,16 @@ +#include "idt.h" + +void set_idt_gate(int n, u32 handler) { + idt[n].low_offset = low_16(handler); + idt[n].sel = KERNEL_CS; + idt[n].always0 = 0; + idt[n].flags = 0x8E; + idt[n].high_offset = high_16(handler); +} + +void set_idt() { + idt_reg.base = (u32) &idt; + idt_reg.limit = IDT_ENTRIES * sizeof(idt_gate_t) - 1; + /* Don't make the mistake of loading &idt -- always load &idt_reg */ + __asm__ __volatile__("lidtl (%0)" : : "r" (&idt_reg)); +} diff --git a/Part4/10_scheduler/cpu/idt.h b/Part4/10_scheduler/cpu/idt.h new file mode 100644 index 0000000..27bfac5 --- /dev/null +++ b/Part4/10_scheduler/cpu/idt.h @@ -0,0 +1,39 @@ +#ifndef IDT_H +#define IDT_H + +#include "types.h" + +/* Segment selectors */ +#define KERNEL_CS 0x08 + +/* How every interrupt gate (handler) is defined */ +typedef struct { + u16 low_offset; /* Lower 16 bits of handler function address */ + u16 sel; /* Kernel segment selector */ + u8 always0; + /* First byte + * Bit 7: "Interrupt is present" + * Bits 6-5: Privilege level of caller (0=kernel..3=user) + * Bit 4: Set to 0 for interrupt gates + * Bits 3-0: bits 1110 = decimal 14 = "32 bit interrupt gate" */ + u8 flags; + u16 high_offset; /* Higher 16 bits of handler function address */ +} __attribute__((packed)) idt_gate_t ; + +/* A pointer to the array of interrupt handlers. + * Assembly instruction 'lidt' will read it */ +typedef struct { + u16 limit; + u32 base; +} __attribute__((packed)) idt_register_t; + +#define IDT_ENTRIES 256 +idt_gate_t idt[IDT_ENTRIES]; +idt_register_t idt_reg; + + +/* Functions implemented in idt.c */ +void set_idt_gate(int n, u32 handler); +void set_idt(); + +#endif diff --git a/Part4/10_scheduler/cpu/interrupt.asm b/Part4/10_scheduler/cpu/interrupt.asm new file mode 100644 index 0000000..bf83b7a --- /dev/null +++ b/Part4/10_scheduler/cpu/interrupt.asm @@ -0,0 +1,425 @@ +; Defined in isr.c +[extern isr_handler] +[extern irq_handler] + +; Common ISR code +isr_common_stub: + ; 1. Save CPU state + pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax + mov ax, ds ; Lower 16-bits of eax = ds. + push eax ; save the data segment descriptor + mov ax, 0x10 ; kernel data segment descriptor + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + ; 2. Call C handler + call isr_handler + + ; 3. Restore state + pop eax + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + popa + add esp, 8 ; Cleans up the pushed error code and pushed ISR number + sti + iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP + +; Common IRQ code. Identical to ISR code except for the 'call' +; and the 'pop ebx' +irq_common_stub: + pusha + mov ax, ds + push eax + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + call irq_handler ; Different than the ISR code + pop ebx ; Different than the ISR code + mov ds, bx + mov es, bx + mov fs, bx + mov gs, bx + popa + add esp, 8 + sti + iret + +; We don't get information about which interrupt was caller +; when the handler is run, so we will need to have a different handler +; for every interrupt. +; Furthermore, some interrupts push an error code onto the stack but others +; don't, so we will push a dummy error code for those which don't, so that +; we have a consistent stack for all of them. + +; First make the ISRs global +global isr0 +global isr1 +global isr2 +global isr3 +global isr4 +global isr5 +global isr6 +global isr7 +global isr8 +global isr9 +global isr10 +global isr11 +global isr12 +global isr13 +global isr14 +global isr15 +global isr16 +global isr17 +global isr18 +global isr19 +global isr20 +global isr21 +global isr22 +global isr23 +global isr24 +global isr25 +global isr26 +global isr27 +global isr28 +global isr29 +global isr30 +global isr31 +; IRQs +global irq0 +global irq1 +global irq2 +global irq3 +global irq4 +global irq5 +global irq6 +global irq7 +global irq8 +global irq9 +global irq10 +global irq11 +global irq12 +global irq13 +global irq14 +global irq15 + +; 0: Divide By Zero Exception +isr0: + cli + push byte 0 + push byte 0 + jmp isr_common_stub + +; 1: Debug Exception +isr1: + cli + push byte 0 + push byte 1 + jmp isr_common_stub + +; 2: Non Maskable Interrupt Exception +isr2: + cli + push byte 0 + push byte 2 + jmp isr_common_stub + +; 3: Int 3 Exception +isr3: + cli + push byte 0 + push byte 3 + jmp isr_common_stub + +; 4: INTO Exception +isr4: + cli + push byte 0 + push byte 4 + jmp isr_common_stub + +; 5: Out of Bounds Exception +isr5: + cli + push byte 0 + push byte 5 + jmp isr_common_stub + +; 6: Invalid Opcode Exception +isr6: + cli + push byte 0 + push byte 6 + jmp isr_common_stub + +; 7: Coprocessor Not Available Exception +isr7: + cli + push byte 0 + push byte 7 + jmp isr_common_stub + +; 8: Double Fault Exception (With Error Code!) +isr8: + cli + push byte 8 + jmp isr_common_stub + +; 9: Coprocessor Segment Overrun Exception +isr9: + cli + push byte 0 + push byte 9 + jmp isr_common_stub + +; 10: Bad TSS Exception (With Error Code!) +isr10: + cli + push byte 10 + jmp isr_common_stub + +; 11: Segment Not Present Exception (With Error Code!) +isr11: + cli + push byte 11 + jmp isr_common_stub + +; 12: Stack Fault Exception (With Error Code!) +isr12: + cli + push byte 12 + jmp isr_common_stub + +; 13: General Protection Fault Exception (With Error Code!) +isr13: + cli + push byte 13 + jmp isr_common_stub + +; 14: Page Fault Exception (With Error Code!) +isr14: + cli + push byte 14 + jmp isr_common_stub + +; 15: Reserved Exception +isr15: + cli + push byte 0 + push byte 15 + jmp isr_common_stub + +; 16: Floating Point Exception +isr16: + cli + push byte 0 + push byte 16 + jmp isr_common_stub + +; 17: Alignment Check Exception +isr17: + cli + push byte 0 + push byte 17 + jmp isr_common_stub + +; 18: Machine Check Exception +isr18: + cli + push byte 0 + push byte 18 + jmp isr_common_stub + +; 19: Reserved +isr19: + cli + push byte 0 + push byte 19 + jmp isr_common_stub + +; 20: Reserved +isr20: + cli + push byte 0 + push byte 20 + jmp isr_common_stub + +; 21: Reserved +isr21: + cli + push byte 0 + push byte 21 + jmp isr_common_stub + +; 22: Reserved +isr22: + cli + push byte 0 + push byte 22 + jmp isr_common_stub + +; 23: Reserved +isr23: + cli + push byte 0 + push byte 23 + jmp isr_common_stub + +; 24: Reserved +isr24: + cli + push byte 0 + push byte 24 + jmp isr_common_stub + +; 25: Reserved +isr25: + cli + push byte 0 + push byte 25 + jmp isr_common_stub + +; 26: Reserved +isr26: + cli + push byte 0 + push byte 26 + jmp isr_common_stub + +; 27: Reserved +isr27: + cli + push byte 0 + push byte 27 + jmp isr_common_stub + +; 28: Reserved +isr28: + cli + push byte 0 + push byte 28 + jmp isr_common_stub + +; 29: Reserved +isr29: + cli + push byte 0 + push byte 29 + jmp isr_common_stub + +; 30: Reserved +isr30: + cli + push byte 0 + push byte 30 + jmp isr_common_stub + +; 31: Reserved +isr31: + cli + push byte 0 + push byte 31 + jmp isr_common_stub + +; IRQ handlers +irq0: + cli + push byte 0 + push byte 32 + jmp irq_common_stub + +irq1: + cli + push byte 1 + push byte 33 + jmp irq_common_stub + +irq2: + cli + push byte 2 + push byte 34 + jmp irq_common_stub + +irq3: + cli + push byte 3 + push byte 35 + jmp irq_common_stub + +irq4: + cli + push byte 4 + push byte 36 + jmp irq_common_stub + +irq5: + cli + push byte 5 + push byte 37 + jmp irq_common_stub + +irq6: + cli + push byte 6 + push byte 38 + jmp irq_common_stub + +irq7: + cli + push byte 7 + push byte 39 + jmp irq_common_stub + +irq8: + cli + push byte 8 + push byte 40 + jmp irq_common_stub + +irq9: + cli + push byte 9 + push byte 41 + jmp irq_common_stub + +irq10: + cli + push byte 10 + push byte 42 + jmp irq_common_stub + +irq11: + cli + push byte 11 + push byte 43 + jmp irq_common_stub + +irq12: + cli + push byte 12 + push byte 44 + jmp irq_common_stub + +irq13: + cli + push byte 13 + push byte 45 + jmp irq_common_stub + +irq14: + cli + push byte 14 + push byte 46 + jmp irq_common_stub + +irq15: + cli + push byte 15 + push byte 47 + jmp irq_common_stub + diff --git a/Part4/10_scheduler/cpu/isr.c b/Part4/10_scheduler/cpu/isr.c new file mode 100644 index 0000000..c46a1d8 --- /dev/null +++ b/Part4/10_scheduler/cpu/isr.c @@ -0,0 +1,153 @@ +#include "isr.h" +#include "idt.h" +#include "../drivers/screen.h" +#include "../drivers/keyboard.h" +#include "../libc/string.h" +#include "timer.h" +#include "ports.h" + +isr_t interrupt_handlers[256]; + +/* Can't do this with a loop because we need the address + * of the function names */ +void isr_install() { + set_idt_gate(0, (u32)isr0); + set_idt_gate(1, (u32)isr1); + set_idt_gate(2, (u32)isr2); + set_idt_gate(3, (u32)isr3); + set_idt_gate(4, (u32)isr4); + set_idt_gate(5, (u32)isr5); + set_idt_gate(6, (u32)isr6); + set_idt_gate(7, (u32)isr7); + set_idt_gate(8, (u32)isr8); + set_idt_gate(9, (u32)isr9); + set_idt_gate(10, (u32)isr10); + set_idt_gate(11, (u32)isr11); + set_idt_gate(12, (u32)isr12); + set_idt_gate(13, (u32)isr13); + set_idt_gate(14, (u32)isr14); + set_idt_gate(15, (u32)isr15); + set_idt_gate(16, (u32)isr16); + set_idt_gate(17, (u32)isr17); + set_idt_gate(18, (u32)isr18); + set_idt_gate(19, (u32)isr19); + set_idt_gate(20, (u32)isr20); + set_idt_gate(21, (u32)isr21); + set_idt_gate(22, (u32)isr22); + set_idt_gate(23, (u32)isr23); + set_idt_gate(24, (u32)isr24); + set_idt_gate(25, (u32)isr25); + set_idt_gate(26, (u32)isr26); + set_idt_gate(27, (u32)isr27); + set_idt_gate(28, (u32)isr28); + set_idt_gate(29, (u32)isr29); + set_idt_gate(30, (u32)isr30); + set_idt_gate(31, (u32)isr31); + + // Remap the PIC + port_byte_out(0x20, 0x11); + port_byte_out(0xA0, 0x11); + port_byte_out(0x21, 0x20); + port_byte_out(0xA1, 0x28); + port_byte_out(0x21, 0x04); + port_byte_out(0xA1, 0x02); + port_byte_out(0x21, 0x01); + port_byte_out(0xA1, 0x01); + port_byte_out(0x21, 0x0); + port_byte_out(0xA1, 0x0); + + // Install the IRQs + set_idt_gate(32, (u32)irq0); + set_idt_gate(33, (u32)irq1); + set_idt_gate(34, (u32)irq2); + set_idt_gate(35, (u32)irq3); + set_idt_gate(36, (u32)irq4); + set_idt_gate(37, (u32)irq5); + set_idt_gate(38, (u32)irq6); + set_idt_gate(39, (u32)irq7); + set_idt_gate(40, (u32)irq8); + set_idt_gate(41, (u32)irq9); + set_idt_gate(42, (u32)irq10); + set_idt_gate(43, (u32)irq11); + set_idt_gate(44, (u32)irq12); + set_idt_gate(45, (u32)irq13); + set_idt_gate(46, (u32)irq14); + set_idt_gate(47, (u32)irq15); + + set_idt(); // Load with ASM +} + +/* To print the message which defines every exception */ +char *exception_messages[] = { + "Division By Zero", + "Debug", + "Non Maskable Interrupt", + "Breakpoint", + "Into Detected Overflow", + "Out of Bounds", + "Invalid Opcode", + "No Coprocessor", + + "Double Fault", + "Coprocessor Segment Overrun", + "Bad TSS", + "Segment Not Present", + "Stack Fault", + "General Protection Fault", + "Page Fault", + "Unknown Interrupt", + + "Coprocessor Fault", + "Alignment Check", + "Machine Check", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved" +}; + +void isr_handler(registers_t r) { + kprint("received interrupt: "); + char s[3]; + int_to_ascii(r.int_no, s); + kprint(s); + kprint("\n"); + kprint(exception_messages[r.int_no]); + kprint("\n"); +} + +void register_interrupt_handler(u8 n, isr_t handler) { + interrupt_handlers[n] = handler; +} + +void irq_handler(registers_t r) { + /* After every interrupt we need to send an EOI to the PICs + * or they will not send another interrupt again */ + if (r.int_no >= 40) port_byte_out(0xA0, 0x20); /* slave */ + port_byte_out(0x20, 0x20); /* master */ + + /* Handle the interrupt in a more modular way */ + if (interrupt_handlers[r.int_no] != 0) { + isr_t handler = interrupt_handlers[r.int_no]; + handler(r); + } +} + +void irq_install() { + /* Enable interruptions */ + asm volatile("sti"); + /* IRQ0: timer */ + init_timer(50); + /* IRQ1: keyboard */ + init_keyboard(); +} diff --git a/Part4/10_scheduler/cpu/isr.h b/Part4/10_scheduler/cpu/isr.h new file mode 100644 index 0000000..337fbf3 --- /dev/null +++ b/Part4/10_scheduler/cpu/isr.h @@ -0,0 +1,89 @@ +#ifndef ISR_H +#define ISR_H + +#include "types.h" + +/* ISRs reserved for CPU exceptions */ +extern void isr0(); +extern void isr1(); +extern void isr2(); +extern void isr3(); +extern void isr4(); +extern void isr5(); +extern void isr6(); +extern void isr7(); +extern void isr8(); +extern void isr9(); +extern void isr10(); +extern void isr11(); +extern void isr12(); +extern void isr13(); +extern void isr14(); +extern void isr15(); +extern void isr16(); +extern void isr17(); +extern void isr18(); +extern void isr19(); +extern void isr20(); +extern void isr21(); +extern void isr22(); +extern void isr23(); +extern void isr24(); +extern void isr25(); +extern void isr26(); +extern void isr27(); +extern void isr28(); +extern void isr29(); +extern void isr30(); +extern void isr31(); +/* IRQ definitions */ +extern void irq0(); +extern void irq1(); +extern void irq2(); +extern void irq3(); +extern void irq4(); +extern void irq5(); +extern void irq6(); +extern void irq7(); +extern void irq8(); +extern void irq9(); +extern void irq10(); +extern void irq11(); +extern void irq12(); +extern void irq13(); +extern void irq14(); +extern void irq15(); + +#define IRQ0 32 +#define IRQ1 33 +#define IRQ2 34 +#define IRQ3 35 +#define IRQ4 36 +#define IRQ5 37 +#define IRQ6 38 +#define IRQ7 39 +#define IRQ8 40 +#define IRQ9 41 +#define IRQ10 42 +#define IRQ11 43 +#define IRQ12 44 +#define IRQ13 45 +#define IRQ14 46 +#define IRQ15 47 + +/* Struct which aggregates many registers */ +typedef struct { + u32 ds; /* Data segment selector */ + u32 edi, esi, ebp, esp, ebx, edx, ecx, eax; /* Pushed by pusha. */ + u32 int_no, err_code; /* Interrupt number and error code (if applicable) */ + u32 eip, cs, eflags, useresp, ss; /* Pushed by the processor automatically */ +} registers_t; + +void isr_install(); +void isr_handler(registers_t r); +void irq_install(); + +typedef void (*isr_t)(registers_t); +void register_interrupt_handler(u8 n, isr_t handler); + +#endif diff --git a/Part4/10_scheduler/cpu/ports.c b/Part4/10_scheduler/cpu/ports.c new file mode 100644 index 0000000..f015689 --- /dev/null +++ b/Part4/10_scheduler/cpu/ports.c @@ -0,0 +1,37 @@ +#include "ports.h" + +/** + * Read a byte from the specified port + */ +u8 port_byte_in (u16 port) { + u8 result; + /* Inline assembler syntax + * !! Notice how the source and destination registers are switched from NASM !! + * + * '"=a" (result)'; set '=' the C variable '(result)' to the value of register e'a'x + * '"d" (port)': map the C variable '(port)' into e'd'x register + * + * Inputs and outputs are separated by colons + */ + __asm__("in %%dx, %%al" : "=a" (result) : "d" (port)); + return result; +} + +void port_byte_out (u16 port, u8 data) { + /* Notice how here both registers are mapped to C variables and + * nothing is returned, thus, no equals '=' in the asm syntax + * However we see a comma since there are two variables in the input area + * and none in the 'return' area + */ + __asm__ __volatile__("out %%al, %%dx" : : "a" (data), "d" (port)); +} + +u16 port_word_in (u16 port) { + u16 result; + __asm__("in %%dx, %%ax" : "=a" (result) : "d" (port)); + return result; +} + +void port_word_out (u16 port, u16 data) { + __asm__ __volatile__("out %%ax, %%dx" : : "a" (data), "d" (port)); +} diff --git a/Part4/10_scheduler/cpu/ports.h b/Part4/10_scheduler/cpu/ports.h new file mode 100644 index 0000000..0b7fa2c --- /dev/null +++ b/Part4/10_scheduler/cpu/ports.h @@ -0,0 +1,11 @@ +#ifndef PORTS_H +#define PORTS_H + +#include "../cpu/types.h" + +unsigned char port_byte_in (u16 port); +void port_byte_out (u16 port, u8 data); +unsigned short port_word_in (u16 port); +void port_word_out (u16 port, u16 data); + +#endif diff --git a/Part4/10_scheduler/cpu/timer.c b/Part4/10_scheduler/cpu/timer.c new file mode 100644 index 0000000..c0f4357 --- /dev/null +++ b/Part4/10_scheduler/cpu/timer.c @@ -0,0 +1,25 @@ +#include "timer.h" +#include "isr.h" +#include "ports.h" +#include "../libc/function.h" + +u32 tick = 0; + +static void timer_callback(registers_t regs) { + tick++; + UNUSED(regs); +} + +void init_timer(u32 freq) { + /* Install the function we just wrote */ + register_interrupt_handler(IRQ0, timer_callback); + + /* Get the PIT value: hardware clock at 1193180 Hz */ + u32 divisor = 1193180 / freq; + u8 low = (u8)(divisor & 0xFF); + u8 high = (u8)( (divisor >> 8) & 0xFF); + /* Send the command */ + port_byte_out(0x43, 0x36); /* Command port */ + port_byte_out(0x40, low); + port_byte_out(0x40, high); +} diff --git a/Part4/10_scheduler/cpu/timer.h b/Part4/10_scheduler/cpu/timer.h new file mode 100644 index 0000000..5d0195b --- /dev/null +++ b/Part4/10_scheduler/cpu/timer.h @@ -0,0 +1,8 @@ +#ifndef TIMER_H +#define TIMER_H + +#include "types.h" + +void init_timer(u32 freq); + +#endif diff --git a/Part4/10_scheduler/cpu/types.h b/Part4/10_scheduler/cpu/types.h new file mode 100644 index 0000000..48f450f --- /dev/null +++ b/Part4/10_scheduler/cpu/types.h @@ -0,0 +1,18 @@ +#ifndef TYPES_H +#define TYPES_H + +/* Instead of using 'chars' to allocate non-character bytes, + * we will use these new type with no semantic meaning */ +typedef unsigned int u32; +typedef int s32; +typedef unsigned short u16; +typedef short s16; +typedef unsigned char u8; +typedef char s8; + +#define NULL ((void *) 0) + +#define low_16(address) (u16)((address) & 0xFFFF) +#define high_16(address) (u16)(((address) >> 16) & 0xFFFF) + +#endif diff --git a/Part4/10_scheduler/drivers/keyboard.c b/Part4/10_scheduler/drivers/keyboard.c new file mode 100644 index 0000000..6f40ac6 --- /dev/null +++ b/Part4/10_scheduler/drivers/keyboard.c @@ -0,0 +1,51 @@ +#include "keyboard.h" +#include "../cpu/ports.h" +#include "../cpu/isr.h" +#include "screen.h" +#include "../libc/string.h" +#include "../libc/function.h" +#include "../kernel/kernel.h" + +#define BACKSPACE 0x0E +#define ENTER 0x1C + +static char key_buffer[256]; + +#define SC_MAX 57 +const char *sc_name[] = { "ERROR", "Esc", "1", "2", "3", "4", "5", "6", + "7", "8", "9", "0", "-", "=", "Backspace", "Tab", "Q", "W", "E", + "R", "T", "Y", "U", "I", "O", "P", "[", "]", "Enter", "Lctrl", + "A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "`", + "LShift", "\\", "Z", "X", "C", "V", "B", "N", "M", ",", ".", + "/", "RShift", "Keypad *", "LAlt", "Spacebar"}; +const char sc_ascii[] = { '?', '?', '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '-', '=', '?', '?', 'Q', 'W', 'E', 'R', 'T', 'Y', + 'U', 'I', 'O', 'P', '[', ']', '?', '?', 'A', 'S', 'D', 'F', 'G', + 'H', 'J', 'K', 'L', ';', '\'', '`', '?', '\\', 'Z', 'X', 'C', 'V', + 'B', 'N', 'M', ',', '.', '/', '?', '?', '?', ' '}; + +static void keyboard_callback(registers_t regs) { + /* The PIC leaves us the scancode in port 0x60 */ + u8 scancode = port_byte_in(0x60); + + if (scancode > SC_MAX) return; + if (scancode == BACKSPACE) { + backspace(key_buffer); + kprint_backspace(); + } else if (scancode == ENTER) { + kprint("\n"); + user_input(key_buffer); /* kernel-controlled function */ + key_buffer[0] = '\0'; + } else { + char letter = sc_ascii[(int)scancode]; + /* Remember that kprint only accepts char[] */ + char str[2] = {letter, '\0'}; + append(key_buffer, letter); + kprint(str); + } + UNUSED(regs); +} + +void init_keyboard() { + register_interrupt_handler(IRQ1, keyboard_callback); +} diff --git a/Part4/10_scheduler/drivers/keyboard.h b/Part4/10_scheduler/drivers/keyboard.h new file mode 100644 index 0000000..ff317a5 --- /dev/null +++ b/Part4/10_scheduler/drivers/keyboard.h @@ -0,0 +1,7 @@ +#ifndef KEYBOARD_H +#define KEYBOARD_H +#include "../cpu/types.h" + +void init_keyboard(); + +#endif diff --git a/Part4/10_scheduler/drivers/screen.c b/Part4/10_scheduler/drivers/screen.c new file mode 100644 index 0000000..e955688 --- /dev/null +++ b/Part4/10_scheduler/drivers/screen.c @@ -0,0 +1,149 @@ +#include "screen.h" +#include "../cpu/ports.h" +#include "../libc/mem.h" + +/* Declaration of private functions */ +int get_cursor_offset(); +void set_cursor_offset(int offset); +int print_char(char c, int col, int row, char attr); +int get_offset(int col, int row); +int get_offset_row(int offset); +int get_offset_col(int offset); + +/********************************************************** + * Public Kernel API functions * + **********************************************************/ + +/** + * Print a message on the specified location + * If col, row, are negative, we will use the current offset + */ +void kprint_at(char *message, int col, int row) { + /* Set cursor if col/row are negative */ + int offset; + if (col >= 0 && row >= 0) + offset = get_offset(col, row); + else { + offset = get_cursor_offset(); + row = get_offset_row(offset); + col = get_offset_col(offset); + } + + /* Loop through message and print it */ + int i = 0; + while (message[i] != 0) { + offset = print_char(message[i++], col, row, WHITE_ON_BLACK); + /* Compute row/col for next iteration */ + row = get_offset_row(offset); + col = get_offset_col(offset); + } +} + +void kprint(char *message) { + kprint_at(message, -1, -1); +} + +void kprint_backspace() { + int offset = get_cursor_offset()-2; + int row = get_offset_row(offset); + int col = get_offset_col(offset); + print_char(0x08, col, row, WHITE_ON_BLACK); +} + + +/********************************************************** + * Private kernel functions * + **********************************************************/ + + +/** + * Innermost print function for our kernel, directly accesses the video memory + * + * If 'col' and 'row' are negative, we will print at current cursor location + * If 'attr' is zero it will use 'white on black' as default + * Returns the offset of the next character + * Sets the video cursor to the returned offset + */ +int print_char(char c, int col, int row, char attr) { + u8 *vidmem = (u8*) VIDEO_ADDRESS; + if (!attr) attr = WHITE_ON_BLACK; + + /* Error control: print a red 'E' if the coords aren't right */ + if (col >= MAX_COLS || row >= MAX_ROWS) { + vidmem[2*(MAX_COLS)*(MAX_ROWS)-2] = 'E'; + vidmem[2*(MAX_COLS)*(MAX_ROWS)-1] = RED_ON_WHITE; + return get_offset(col, row); + } + + int offset; + if (col >= 0 && row >= 0) offset = get_offset(col, row); + else offset = get_cursor_offset(); + + if (c == '\n') { + row = get_offset_row(offset); + offset = get_offset(0, row+1); + } else if (c == 0x08) { /* Backspace */ + vidmem[offset] = ' '; + vidmem[offset+1] = attr; + } else { + vidmem[offset] = c; + vidmem[offset+1] = attr; + offset += 2; + } + + /* Check if the offset is over screen size and scroll */ + if (offset >= MAX_ROWS * MAX_COLS * 2) { + int i; + for (i = 1; i < MAX_ROWS; i++) + memory_copy((u8*)(get_offset(0, i) + VIDEO_ADDRESS), + (u8*)(get_offset(0, i-1) + VIDEO_ADDRESS), + MAX_COLS * 2); + + /* Blank last line */ + char *last_line = (char*) (get_offset(0, MAX_ROWS-1) + (u8*) VIDEO_ADDRESS); + for (i = 0; i < MAX_COLS * 2; i++) last_line[i] = 0; + + offset -= 2 * MAX_COLS; + } + + set_cursor_offset(offset); + return offset; +} + +int get_cursor_offset() { + /* Use the VGA ports to get the current cursor position + * 1. Ask for high byte of the cursor offset (data 14) + * 2. Ask for low byte (data 15) + */ + port_byte_out(REG_SCREEN_CTRL, 14); + int offset = port_byte_in(REG_SCREEN_DATA) << 8; /* High byte: << 8 */ + port_byte_out(REG_SCREEN_CTRL, 15); + offset += port_byte_in(REG_SCREEN_DATA); + return offset * 2; /* Position * size of character cell */ +} + +void set_cursor_offset(int offset) { + /* Similar to get_cursor_offset, but instead of reading we write data */ + offset /= 2; + port_byte_out(REG_SCREEN_CTRL, 14); + port_byte_out(REG_SCREEN_DATA, (u8)(offset >> 8)); + port_byte_out(REG_SCREEN_CTRL, 15); + port_byte_out(REG_SCREEN_DATA, (u8)(offset & 0xff)); +} + +void clear_screen() { + int screen_size = MAX_COLS * MAX_ROWS; + int i; + u8 *screen = (u8*) VIDEO_ADDRESS; + + for (i = 0; i < screen_size; i++) { + screen[i*2] = ' '; + screen[i*2+1] = WHITE_ON_BLACK; + } + set_cursor_offset(get_offset(0, 0)); +} + + +int get_offset(int col, int row) { return 2 * (row * MAX_COLS + col); } +int get_offset_row(int offset) { return offset / (2 * MAX_COLS); } +int get_offset_col(int offset) { return (offset - (get_offset_row(offset)*2*MAX_COLS))/2; } diff --git a/Part4/10_scheduler/drivers/screen.h b/Part4/10_scheduler/drivers/screen.h new file mode 100644 index 0000000..24ec3e4 --- /dev/null +++ b/Part4/10_scheduler/drivers/screen.h @@ -0,0 +1,22 @@ +#ifndef SCREEN_H +#define SCREEN_H + +#include "../cpu/types.h" + +#define VIDEO_ADDRESS 0xb8000 +#define MAX_ROWS 25 +#define MAX_COLS 80 +#define WHITE_ON_BLACK 0x0f +#define RED_ON_WHITE 0xf4 + +/* Screen i/o ports */ +#define REG_SCREEN_CTRL 0x3d4 +#define REG_SCREEN_DATA 0x3d5 + +/* Public kernel API */ +void clear_screen(); +void kprint_at(char *message, int col, int row); +void kprint(char *message); +void kprint_backspace(); + +#endif diff --git a/Part4/10_scheduler/e_compile.sh b/Part4/10_scheduler/e_compile.sh new file mode 100644 index 0000000..f6f8b9c --- /dev/null +++ b/Part4/10_scheduler/e_compile.sh @@ -0,0 +1,14 @@ +#!/bin/bash +### interrupt.asm has no .c counterpart so it needs to be built first +nasm ./cpu/interrupt.asm -f elf -o interrupt.o + +### Alternatively to see assembly output -S +### Generate .s the assembly language output prior to generating .o machine files -S +### gcc -g -m32 -fno-pie -ffreestanding -nostdlib -nostdinc -fno-builtin -fno-stack-protector -nostartfiles -nodefaultlibs -Wall -Wextra -Werror ./libc/mem.c ./libc/string.c ./drivers/keyboard.c ./drivers/screen.c ./cpu/isr.c ./cpu/ports.c ./cpu/idt.c ./cpu/timer.c ./libc/globals.c -S hello.c + + +### Generate .o machine files but do not link -c +gcc -g -m32 -fno-pie -ffreestanding -nostdlib -nostdinc -fno-builtin -fno-stack-protector -nostartfiles -nodefaultlibs -Wall -Wextra -Werror ./libc/mem.c ./libc/string.c ./drivers/keyboard.c ./drivers/screen.c ./cpu/isr.c ./cpu/ports.c ./cpu/idt.c ./cpu/timer.c ./libc/globals.c -c --entry start_ hello.c + +### Do the final link to create executable "final" and set entry to 0x10000 +ld -m elf_i386 -o hey_there -Ttext 0x10000 *.o --oformat binary --entry start_ diff --git a/Part4/10_scheduler/hello.c b/Part4/10_scheduler/hello.c new file mode 100644 index 0000000..29fafdf --- /dev/null +++ b/Part4/10_scheduler/hello.c @@ -0,0 +1,55 @@ +#include "./cpu/types.h" +#include "./libc/globals.h" + +#include "./cpu/isr.h" +#include "./cpu/idt.h" +#include "./cpu/ports.h" +#include "./cpu/timer.h" + +#include "./drivers/keyboard.h" +#include "./drivers/screen.h" + +#include "./libc/mem.h" +#include "./libc/string.h" +#include "./libc/function.h" + + +void start_( void) +{ + int pid = 0; + char c[16]; + kprint("Process "); + hex_to_ascii( (u32 ) pid, c); + kprint( c); + kprint("has been entered. Hey there.\n"); + return; +} + +void user_input(char *input) { + if (strcmp(input, "END") == 0) { + kprint("Stopping the CPU. Bye!\n"); + asm volatile("hlt"); + } else if (strcmp(input, "ADD") == 0) { + u32 *n0; n0 = (u32 *) 16; n0++; + node *n1; n1 = NULL; + kmalloc( 20, 0, (u32 *) &n1); + n1->id = global_id++; + n1->base = global_id*100; + n1->size = global_id*10; + n1->next = NULL; + n1->previous = NULL; + kprint("ADDED: "); + char c[16]; + hex_to_ascii( (u32 ) n1, c); + kprint( c); + kprint( " id: "); + hex_to_ascii( n1->id, c); + kprint( c); + } else if (strcmp(input, "ZOO") == 0) { + kprint("ZOO.\n"); + } + + kprint("You said: "); + kprint(input); + kprint("\n> "); +} diff --git a/Part4/10_scheduler/hey_there b/Part4/10_scheduler/hey_there new file mode 100644 index 0000000000000000000000000000000000000000..a7068422bd8b8ea16458056bd704eb99ab708d2a GIT binary patch literal 8552 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 "); +} + +void user_input(char *input) { + if (strcmp(input, "END") == 0) { + kprint("Stopping the CPU. Bye!\n"); + asm volatile("hlt"); + } else if (strcmp(input, "ADD") == 0) { + u32 *n0; n0 = (u32 *) 16; n0++; + node *n1; n1 = NULL; + kmalloc( 20, 0, (u32 *) &n1); + n1->id = global_id++; + n1->base = global_id*100; + n1->size = global_id*10; + n1->next = NULL; + n1->previous = NULL; + kprint("ADDED: "); + char c[16]; + hex_to_ascii( (u32 ) n1, c); + kprint( c); + kprint( " id: "); + hex_to_ascii( n1->id, c); + kprint( c); + } else if (strcmp(input, "ZOO") == 0) { + kprint("ZOO.\n"); + } + + kprint("You said: "); + kprint(input); + kprint("\n> "); +} diff --git a/Part4/10_scheduler/kernel/kernel.h b/Part4/10_scheduler/kernel/kernel.h new file mode 100644 index 0000000..c31ef35 --- /dev/null +++ b/Part4/10_scheduler/kernel/kernel.h @@ -0,0 +1,12 @@ +#ifndef KERNEL_H +#define KERNEL_H + +void user_input(char *input); + +#include "../cpu/isr.h" +#include "../drivers/screen.h" +#include "../libc/string.h" +#include "../libc/mem.h" +#include "../libc/globals.h" + +#endif diff --git a/Part4/10_scheduler/libc/function.h b/Part4/10_scheduler/libc/function.h new file mode 100644 index 0000000..bf656ed --- /dev/null +++ b/Part4/10_scheduler/libc/function.h @@ -0,0 +1,8 @@ +#ifndef FUNCTION_H +#define FUNCTION_H + +/* Sometimes we want to keep parameters to a function for later use + * and this is a solution to avoid the 'unused parameter' compiler warning */ +#define UNUSED(x) (void)(x) + +#endif diff --git a/Part4/10_scheduler/libc/globals.c b/Part4/10_scheduler/libc/globals.c new file mode 100644 index 0000000..d89540b --- /dev/null +++ b/Part4/10_scheduler/libc/globals.c @@ -0,0 +1,5 @@ +#include "../cpu/types.h" +#include "globals.h" +u32 free_mem_addr; +u32 global_id; +u32 memory_limit; diff --git a/Part4/10_scheduler/libc/globals.h b/Part4/10_scheduler/libc/globals.h new file mode 100644 index 0000000..8599466 --- /dev/null +++ b/Part4/10_scheduler/libc/globals.h @@ -0,0 +1,9 @@ +#ifndef GLOBAL_H +#define GLOBAL_H + +#include "../cpu/types.h" +extern u32 free_mem_addr; +extern u32 global_id; +extern u32 memory_limit; + +#endif // GLOBAL_H diff --git a/Part4/10_scheduler/libc/mem.c b/Part4/10_scheduler/libc/mem.c new file mode 100644 index 0000000..68ffb59 --- /dev/null +++ b/Part4/10_scheduler/libc/mem.c @@ -0,0 +1,43 @@ +#include "mem.h" + +void memory_copy(u8 *source, u8 *dest, int nbytes) { + int i; + for (i = 0; i < nbytes; i++) { + *(dest + i) = *(source + i); + } +} + +void memory_set(u8 *dest, u8 val, u32 len) { + u8 *temp = (u8 *)dest; + for ( ; len != 0; len--) *temp++ = val; +} + +// See mem.h for free_mem_addr global declaration +/* Implementation is just a pointer to some free memory which + * keeps growing */ +u32 kmalloc(u32 size, int align, u32 *phys_addr) { + /* Pages are aligned to 4K, or 0x1000 */ + if (align == 1 && (free_mem_addr & 0xFFFFF000)) { + free_mem_addr &= 0xFFFFF000; + free_mem_addr += 0x1000; + } + + + char c[16]; + hex_to_ascii( (u32) *phys_addr, c); + kprint("Inside kmalloc phys_addr = "); + kprint(c); + kprint("\n"); + + /* Save also the physical address */ + *phys_addr = free_mem_addr; + + hex_to_ascii( (u32) *phys_addr, c); + kprint("Inside kmalloc phys_addr = "); + kprint(c); + kprint("\n"); + + u32 ret = free_mem_addr; + free_mem_addr += size; /* Remember to increment the pointer */ + return ret; +} diff --git a/Part4/10_scheduler/libc/mem.h b/Part4/10_scheduler/libc/mem.h new file mode 100644 index 0000000..1d198d1 --- /dev/null +++ b/Part4/10_scheduler/libc/mem.h @@ -0,0 +1,22 @@ +#ifndef MEM_H +#define MEM_H + +#include "../cpu/types.h" +#include "../libc/string.h" +#include "../drivers/screen.h" +#include "globals.h" + +typedef struct _node { + u32 id; + u32 base; + u32 size; + struct _node *next; + struct _node *previous; +} node; + +void memory_copy(u8 *source, u8 *dest, int nbytes); +void memory_set(u8 *dest, u8 val, u32 len); + +u32 kmalloc(u32 size, int align, u32 *phys_addr); + +#endif diff --git a/Part4/10_scheduler/libc/string.c b/Part4/10_scheduler/libc/string.c new file mode 100644 index 0000000..0d3de2d --- /dev/null +++ b/Part4/10_scheduler/libc/string.c @@ -0,0 +1,79 @@ +#include "string.h" + +/** + * K&R implementation + */ +void int_to_ascii(int n, char str[]) { + int i, sign; + if ((sign = n) < 0) n = -n; + i = 0; + do { + str[i++] = n % 10 + '0'; + } while ((n /= 10) > 0); + + if (sign < 0) str[i++] = '-'; + str[i] = '\0'; + + reverse(str); +} + +void hex_to_ascii(int n, char str[]) { + str[0] = 0; + append(str, '0'); + append(str, 'x'); + char zeros = 0; + + s32 tmp; + int i; + for (i = 28; i > 0; i -= 4) { + tmp = (n >> i) & 0xF; + if (tmp == 0 && zeros == 0) continue; + zeros = 1; + if (tmp > 0x0A) append(str, tmp - 0x0a + 'a'); + else append(str, tmp + '0'); + } + + tmp = n & 0xF; + if (tmp >= 0x0A) append(str, tmp - 0x0a + 'a'); + else append(str, tmp + '0'); + + return; +} + +/* K&R */ +void reverse(char s[]) { + int c, i, j; + for (i = 0, j = strlen(s)-1; i < j; i++, j--) { + c = s[i]; + s[i] = s[j]; + s[j] = c; + } +} + +/* K&R */ +int strlen(char s[]) { + int i = 0; + while (s[i] != '\0') ++i; + return i; +} + +void append(char s[], char n) { + int len = strlen(s); + s[len] = n; + s[len+1] = '\0'; +} + +void backspace(char s[]) { + int len = strlen(s); + s[len-1] = '\0'; +} + +/* K&R + * Returns <0 if s10 if s1>s2 */ +int strcmp(char s1[], char s2[]) { + int i; + for (i = 0; s1[i] == s2[i]; i++) { + if (s1[i] == '\0') return 0; + } + return s1[i] - s2[i]; +} diff --git a/Part4/10_scheduler/libc/string.h b/Part4/10_scheduler/libc/string.h new file mode 100644 index 0000000..db4200c --- /dev/null +++ b/Part4/10_scheduler/libc/string.h @@ -0,0 +1,14 @@ +#ifndef STRINGS_H +#define STRINGS_H + +#include "../cpu/types.h" + +void int_to_ascii(int n, char str[]); +void hex_to_ascii(int n, char str[]); +void reverse(char s[]); +int strlen(char s[]); +void backspace(char s[]); +void append(char s[], char n); +int strcmp(char s1[], char s2[]); + +#endif diff --git a/Part4/10_scheduler/s_compile.sh b/Part4/10_scheduler/s_compile.sh new file mode 100644 index 0000000..20ddf8b --- /dev/null +++ b/Part4/10_scheduler/s_compile.sh @@ -0,0 +1,14 @@ +#!/bin/bash +### interrupt.asm has no .c counterpart so it needs to be built first +nasm ./cpu/interrupt.asm -f elf -o interrupt.o + +### Alternatively to see assembly output -S +### Generate .s the assembly language output prior to generating .o machine files -S +gcc -g -m32 -fno-pie -ffreestanding -nostdlib -nostdinc -fno-builtin -fno-stack-protector -nostartfiles -nodefaultlibs -Wall -Wextra -Werror ./libc/mem.c ./libc/string.c ./drivers/keyboard.c ./drivers/screen.c ./cpu/isr.c ./cpu/ports.c ./cpu/idt.c ./cpu/timer.c ./libc/globals.c -S hello.c + + +### Generate .o machine files but do not link -c +### gcc -g -m32 -fno-pie -ffreestanding -nostdlib -nostdinc -fno-builtin -fno-stack-protector -nostartfiles -nodefaultlibs -Wall -Wextra -Werror ./libc/mem.c ./libc/string.c ./drivers/keyboard.c ./drivers/screen.c ./cpu/isr.c ./cpu/ports.c ./cpu/idt.c ./cpu/timer.c ./libc/globals.c -c --entry start_ hello.c + +### Do the final link to create executable "final" and set entry to 0x10000 +### ld -m elf_i386 -o hey_there -Ttext 0x10000 *.o --oformat binary --entry start_ diff --git a/Part4/CS3502S01_Project_IV_Scheduler_Stub(1).docx b/Part4/CS3502S01_Project_IV_Scheduler_Stub(1).docx new file mode 100644 index 0000000000000000000000000000000000000000..7b327ef110cb13bd7f6ff72d90095c58be63afbd GIT binary patch literal 103019 zcmeFZgOe!Fw(r?CciXmY+qP}nwr$(C-M!nkZELq?|IT@L=FYq`f5CkjQ597cSy7Q$ zpS5yju5XpR6fg)f02lxS00001KuB4Kd>$YGfcD>0Bmf8?Eg?HwXA@gzJ!KDj6DJ*7 zcN=T`LJ%PGd;p-o_5V-#AKU}Ysgt&Y^avuaDSzM-+E5sr6;x0HMDQk2E1rO(c>t^K zg1WU=;ctaR0_YM^ri;P$Y31fGA$2Kh_<$V*vHtz2>z) zrw$x}OU1RG^9#_Pf|k}*Yt~M1=Q5daT2>P^kY=XktXb5$3^6#u;z=V(+0Bf9VgwzHP z>zE^SkD~Eg9L;c>?J*mjh(Ohr5eBDQ;q<@-_)oQR@)&t8@HIzjqh?1+x#`GrU;`_E z>sa{nKX-o;v$B>ERyZMN$1%qb^0oG4;gxg>VZ9*8=Y20+2sie+`^m?Wf?m|EJL1k~ zL>*FP0q=W1+R?xLwcei}U;z35mtAM5_=0}_g?0b0*+T!dYduF3YbQF|fA;^!p8p3M z@qcT2b)t+EFatv9ZQu{VR1eoCCE>!huJDCV{T@ixp9jOQVIm1z$uES& z-^gi{XCi|*h6_Aek|FR{4>FfUBokw62KZlsIER(gcJ$w-{5%GgH5K@_(H$eOuNBTFOjve@uoGwU9*r=K}&o@gW5eyUHI9&3V=;xzhz|C6~;Lh`2z zkO2T}8v+6#{_P_-J4a(WV>=@ko4;e>KZD>E&!+96XzDHW6(54G{yg9YD&0ty*#=-8 z2Jp57(an^89#Cc>wX9NcYO(jk4bXcGpsC*L&;yB=Y(lblWT8buBS{NTF-^m8CFiSB znQYFV$Je+f|Bly#;kZF~vn^1sQTGC@n6JB=p>;aFE2raV2}Lq&E&*guyqVnYqpOc9 zzppetKJ8c{H-^W-;GYi`=o=bQ1d9Ly)&QN7T17K36N7?5?nwJt=wPj#?#n+w(t6qt1mlEo?66>{PEUuX~ zOzzCDg67%6_fr!4R^Dux9QUgupV*waTorzo;J$xAd>R$!V-Cag+R_obTdoX9qxH6e zxHCnJ=nzIl=;p(kM6h*FZu97N$13zpZ%_SF?c4?03=G&^j(AE15>anQb?no6Y)>LX z3~i9T0QVT6k}CN0EW_4Ydjt-f&yIRw0biT)-?oRcFUc*ll(RAt43-Vj&QF`OK-Z@> zy^hx4mWF9l?VK|NU8W34nfCUU`?U&6gSBgm9w<2XRypIf>xvr4|Hwb^irz?eHsJLY zsiS-uD-Za7q8N6>a@O-^D1sl3M0M_k7~;Nx>(M=@L@(YynQWslWA1m!UP$K{Q!uX; zy)pufn7GL`{pvk+`wG4YW7nKg>v{k3?9#1R1$TDVol~RDHVH|1%9@&9$_QG?=}233 zGeG8Q1Dt{ojsdhVAP2qE)93sY;`5Aq;#kNO@Nsbk#oe%B_8shVGABxNB6F<`7~lw6 zrjB8mIa8{)qu@oMksygQ7+RFN0~_P>V>i-}(pM4C=4I@OXo66*Rv=bIHs<{O=_LKL zRV)WMb@{LZNOg}kD}a~Cg=L_{=%)P!7So1%h6W(2(1gkdf=&x;7ud59@YzM-&6~D% z1@7k-MXMu!pqtGT)5KuJ1+@s`yGL9L4|6w?=K=Xx^xFT4J)Mp4k!5MHuysIs8CUSA zu=8OKsqr#>}bX3_e(pt-E5))y}pSzPW@4sn8p(7JV zDYh=csPukG#AU?{r&Ef{pgZtLc9&*0Sg6ROmrZ+;a) z=*RJGztgv`vmxF@MPYS<2p#UXEwI9My4v;rMVtzFYi*KgA+(LLy+NYTg|3 z^4*%a1yf9JIZWz0J!D`b!bq(Ms@UqGL@+6qcNiK*GG0ZKCl#j~9BtsDad_lq|1^Ez zdP3H|49oWr;p}UG0Y&YMJNDtO)?8V>_A2WAu>ws- zlT6cWdCtmtX}QDRkm@uv9Ry>fu#T}X(DL~t0C8sJK^ zdoFYBXcbMEos^%mX+~}LkT-a8juxFP)YyDnMxJdt77S;Abpcvd6iV$XUMb=u!ie5L zU&yFoUK#WzVw9Tt$l1Xv&M%V802Ka1s!G}=ZFWP5K#94A57qVB-xToApc-%w(BK~J z+Q{(q%OrP}L|kp}uZ!Vji13!fXs)`ct=a*3AUDhh2t+mb=?`q3W9Q{OJ7OB?xc+8dLzxu96j_=M>NO` zLPX0(8y#R)TQa`a-Pn9kfJK{veD0fVEE0jpz8=wp0t33EbgT(%Md~N5L?NX_vF5^l zdV-Spsqc(qQ3`pZ3669u*2n9&`#wkwhFvzT)71=o%`3=@WlGC;87F<1IOz$6COs_z zq*7%%IA0E<0_TW!^`^-0Dd1TNZc?3L<`G0+ET(xOb;)f$_dr|zsMGdEqx@UYA#;HR z-}IRB?tUq7i86#o2>2*jHRgbMiBzDJ5`M!#BL`{kTrw8ZintjY=UW|Re{0tC!s0A! zv8G$Oo#9Ts3du~HmG~eJ!cc*@-?bA%3WR0Ee=@S_CJD=$>S#V~k%ie2Ih8g|_xpeX z0h0mk~SM z^xKl^83@S1@4D-DG2&;6FXg1^T=qQm=Ldsl(m>ozar4m44&y)U*uBmZ8tjbZUV;c< zHhpJ}5iKb0}Mje7*>}?N5M*Z>Tof-@PpHMoJJtTkfn}q9Nmxf~E zcJFM>M$H>jzzoRc_9pm(gM1lT;N8aV#dg(jzN?+;Qy!-v*7xK1;(Vkz03Ge~F2rTGqu6 z-;SY1lZ0)M%h^F~<=t(s*fhYnhLA@ze;cc3r zEZ(2T^|)L{L=0E^-7SedlY#W-zKgab#~n_*`a(yN%f|}{|031;E~hXaimKk*2$|7t z9qGv04ny)lo%Zj7)r@egf&*7_IYnL?%5Dtv|XbgViC+uWPQ0Zgfu&QJRZrQ3&IPsRf z-bRFfm|*{9U#_`Zd9zn5!c#=Bm)xMUgI3r@K0rIV*v%nc-w)kTchT#Ge(_TmlyK3B z3RKy6r{zkd;Gs%tV)<&SJ=BhDy|=RNpvm9HFH)M&u^*rki07T4%emg95_U(xLLf%e zRJcD+IYp@?q`@>&J}3*w1KS<(@nP_hpb4raN!j>*BQ zc-+5thveo>`)LpERP8cri0wOw4)FebCK+ruo5I)X9ow^GN#r%-wcu6faiN1?EcH^} zw@8`0CnQx5~@1Di>O&jE@NHSf}OG=bVa-@_so!f;#Ea*O1*Q z+C`5|+FLR95tKTTT%PF_q zhikMPmzzHhAka%`3E5!#U<=L%xQ zBolE}N<2X2D!q2uR~^^`T{)V=B6q0rNBiw4_zVZ4o9v=#slRPAeuK>=YTF}mKL>~a zEH~5aU`+f!R&{=Z%=e*fM*iYUP5xsgx!Zd0aRfP4jIBsZ z2&HAhp*x4rG8WZ^X*-8%Xh?<%SMp3HSi8F7GC!iiQVa^^?^7X48ZR)n0VQClu~}Wr zkG&biSJWaY7#S4w$E?Xo;{reh5<;yCr+K&67L`5?MmX=bp-7d5dIW!#Q1pElnx`$`3BNl}ek`7OutWt^2 z!u;Qp)b~ceCaNy6J4PA<9X8K$ips~_mB_k>kgz!*8Akdt+HDpQgzpZ#ba>x; zYd%~eFhi@(@AtgaF$t8~I)gf3&j9t&*7rCjkgYKtYtk(g6og$-#I4g}EGHEvLZ8z| z)uZwWXvnB!Am zyJB|psfm-owKO-wX?`{{p3rdZOr3dfnoEfwhEQs-907Isee{sxJs;N>({YaC)g4?HGxOs z*EH5D$|AOoe>Y0Qa{GA@a? z&^X!~`gVn%@cT$(db}|JF0pOvoEnpiM%*)-_*&skQ&d1!l8TWD;{6o|O2nF{$zjt61Ne0a-N>L+? zM54LMjRGCWEbSMl)J5-x;{)b~vwUpTK)DZtr|3B>gZ^$#NkM=wVw6*(1q5XbHD4Qk zImPb>UCY0(0u>~Y_P)}#`gB?fRZl8uNjRWB#%ug9M{p;y!-2Ei3X@ATXZUMx5=3Af=b@aL2sE2%OlN6Lhzb4;(0*_*k=D`pWv) zNvC*c(}o?f>-=JA@QsovN>Un9m{?QOf-_QzIcptUz3f6z?-h6adPyB}zJa>=%^Nm< z${tDj-bJ@x?r_E3AH9EweG*j}hVdcsCu9bl?|f1YFD(zj0bmx}{xbN6Ig(<=Bv-{6 zx{bPF0P6!|K_i5ORcib5okSieF1bBU9a~BH&Judm=Z`&UIF#6f7ww)}Qp9Pg>dU4- zTxtOV=xcPxh+mUlAm|@#Cf;aZXqoQq^PzRKyi_`qy@53;ZTDm7=s&kVFXdkm-$n;Q zezH*?oKeh~92Ie|_}ny;OEHf#+jzHr;W_V1ZrA9YqQM+#ZY5-RM6XtXzp12YbKuPu znRE1FMcbQLof4tvh8D6$6lz>@Ar^mOk?o|n~SWul%!4oSn9<@3tsL& zVl^**J1d5141c5QOfzW<+1;Hx_GY7cUuf9i$B(O!;QQd}R%3ol2kVfa;H@MT)>8Q&4Dc zG=MInTfE+pqx?$6NFt+$#JT%=>G+T0A>R~vvZ1-Gpp2S5ym3iS;B=V`Z-Dl&OoiKA zuK;2%iw9(H?9ukR&hhxw+~_89XP*wE?_zIxttrG6pFBv1(lv@DT}!PtqFKuxIV~+4 zP+wZ%(q}-3EwXAt*hpK|qfwDId&QH87*Qmp6-#@pAOe;!t-mBx%^8A=qQ;r&;Cuyc zxumXh*k2W{%5Z~d!Kw9kwm)tK#)i^fVajpT`@B~>6BnEf?}zC0=5}gku$|NS@5!}t zt7j|iBz3Pm_C+o^EyU8xf%*oF)J#IupK?!5gZn~j9n~8b9ML7?j!CkbEJF@WWJoDz z_d9Js*~k!^k{c83lx>zEmh<`;7&X(TgUTbS=+>{x-0@IJ2e<&4G=gniFR`XealLE- z)Ms<`ALO&h#~JBv3B~$sq@|MFO;7@7nL<}d7v$i#JkIO(R7iH1SXRMs+c0p_YToux z1RC9Pe{UOrsZ3SNU8chEn(sr`8`&Ts!KfZwoWH&g322PO1ddQ&B^r=H3LmmpMQvt2 zss=4ow#t{N7!H3;)i;@F=|5{O10<}n=+dNMc`|GflA*2^xcPHwPdO%nzY5$ZeeTGc zcZpWdnQ6C*QuYZbw6bB@`(<%bs2uKbwM6(^AQ`GCGKbECqw9#**9#B51;MY>2B8Rs zE38*+1^|8jx#WHsdWM$sinq6L-#ja;>NeVO4B>IG5(OkSnc=ceCWPn&R zcvj-RR$3Yn#a$~CG8n?=w}eiN5ndfXHmrD&c2E1R+8=BdPF+S^ti~A4fwq(QfI+Bf z75+*Z@O^uz&eF?P?I5js*m%K~%h}EUvzw- z9enu%b|pH9!b};P(w=hjVfy2iEHCHjddY$y7pOkS>#jY6*MtI7)OtjS;x@F>dnBf~ zOz%C)^$78B#fglIb14I!7FLuTc=k_f-Sm-0fuCQ~^zN{W6q4N#-1(Q0t&y{eFNy9Y z#fg*MUTa22=HJOE9S(^EIzv@0 zmGNC+B_m;!BF6p~O&wcU6FV&Osw< zR&f}wVCdTN_Mkgv;8hC2lG3RqrmpzDar<vSSl_oAO zSxDETIS<%M9+Pd@j@G7Z-6ZIX`)46F`Jx#SVTeJy-Py1Y2m~q+XfQ%UsVOw1(FU!J zlw+5wb%W9Cn5nwj8anjLq6;iL2OrVR0w46NPY3o}u0{E6(*Z3I6LyoEzcf!_`KOL^ zJuTaf^RXguP87I*H}jQ2gj%MMtMpe=dc@~!jhf5lV(Ejcs zFQDu!|3x|7d#VW1EAz=N!57$WI%q?h;v1Rg+ou|A z`w`1V?hk^qwJms5R}&8w2E?L{)+D7o-HOtYT160%Xq#D5$b5}mcab=wiqygmx3ZhV z@$K&VhhE3U$3;=p$QNg557}?BrpJKU8MQ@RVQrgS8pqG4$p%f`DE`t7YCW`J)9QM8 zm}d9Sh9%_}+}jh`)o7w*;Z5x6iUk8Jr{4L{LlF_X zswQ*sut*)!fLWS;CzrmjaIB+&0Jd)Z@u4D}^k6n=nKtF>{YUHASy9r8R_x)wF%E(% za8d(FiqWvX#1;XO%v70vEOYE+EKs>PhGM)Q0JaMLqxox6uXNi=p;kbl(S zROY0<3d39zx)|ET0kamvm1Y1<#93zzKLTQQ@ zUhWPuf=8$ulOoKRdQnWPSv%l|ss{$<*(ZoIT1F!Ai0UP{Rc}DF@-nK1O1XxGLYw>a zugcmj(-wkzLJbtXZKif;SuA;1J=Hpju^D}7o@d;#sP$|Pw*I0mceVk0qgRxRg8edu zqd)ON&%FW~KWt1{v_-2i*qgl&EAS%tOvVp4N z4XY5lQH>~tHtL)@!zq)h;=*&nlf_(;UDR3wtCJYU!t5w{Ym)~^);XHUI$rXEK<`h= zf(Ocih2lsk#3^Q%6&^9EUhqKRLmt$^ixCA9I;!50q~=ep87}QqG++DQet+|8KR;L6 zm$sYisJ4%ujb$3n8`etsTpwoqQq46L)KG*tBVWtl>!2^IyyLu* zdB(E^#$%4w%Mv-G9U$U{3XC4MpYAjJ1(Ao`xG~2Q0k)jrVr705v5$|~KM``p?7hVk z69MzIcHwfpI>OA;~Ik}%)N%pk&6im zig;y+TjFa7T}oe9v3Bj)7zH)9E(8RD{}pNR?KXcPs+ zMMR?H^aHhL#IhI(MxtO2l8+b|qy5imvp<+k7%$Y5-zXAJ3c06Jirpj)Blpfb`26{h zTE}~@%L;u0nEk3Vz24t$Q3wy2k8#H1P9s#9aQhX1s-49~@ndB^3ENt2)Oo&Iw`dWC zYDp&=#?8lN;TY$BP13CoP+$;qe~Q1!CoBo`>p4j;Ztwtt{th1w438#>Sj%~0iv}-s z$$dnaYL3{fy^!LrCl95iOT*SVZ5Fzz1e!Kg=MVb(FWXSx2@+U)%%sD zX#0HWZN)`@dnfhQnX}?4N1OCfta+q|DLK+|QRQ&{fh~FbWrR=1?iFv8nuG~prj%n9 z9%gr|2bi^V4|SJMQg+ca+PN#$AnnE8%+Cy~?;^K*oG$MN`g_Ina|1TYa0)tHS2&$1 zbr973dasMue?GrYH@ZT&jbrjqxiP%|H-o9#ymR7q9fGD-e#`Nhr`#<*uMcdE&Gt%5 zOSwwlBl+CMa!~K;O*Q*tt3{@)T$ihA)_iA~)l5sg?wsfH8*ptsW;PwK5z~2I}?D6#j_>uWfQz+Z7}Gzm6u)#AUX2bm!T*<2rq(b z&<1qDe-DNshg!Dk{Tf*k9m3;VB^Wz8&04!iNf-K1Tb-$;7B`|wOO|_lPa$h=E=^8A zcs4IDsjv!TOSM$@&SrH?A1Cg&%la$OL>NfRECf5bbD$nxDUjCW<*4oCEjQUVbo{d3 zzDx+G28irEb+q1}r5G2zA-<+%i>4}%JToXg#RYizgYB6FTy4>nCk z)>ALt7|?$Fsk37>67N*kgv$=GTscm9BQl2*gSk_fWeN7k`aJ!-K4M{zG?^O~FD-K2 zddRxvu0A73v7<}FkJF`1RsK+*0`<2>6xr&(&>RN9p3i>R3YO6bdTZKF4 z3|UlKLV>W#f=JQ!0TG9uo40I)hUr5}y~jty%aOie^y8dRogB60_tX|;!7N+B+^m*j zvOT^8?`*2k-*n6kST?d-pnmaIr`2GFh*=c@^lY;7>}s#$_fy998fX)dDz-H~YCJRt zR!_3{ws28Gm1iQOkR)u10@fwnJ62ZP71Q$5rR)F1H)l}}L>-ATlpW`W+02K!~`FS|% z#WT6SWbP1=^2`@+xkd+q4RS`PRmP2Dhz&aLR+NcMCBE zV|5ds38h36c2Yf;F&t$*LgdP(N;Kp^zo-3dV&b-8DfksdglI9DWMYUJdtb1E_mqg6 zsLC3|XOOzTJ1X9_y^<|^+5izVQUB~L4G_rb3i-B}sMeTJGgd+@xYJGY!_7tZ)wJ3Z z#c6c;h08|oQe?9yuy_o#*n8daqPSLG7+X8vT8q>!+BA&bmgj3|s$VaEC6)l(v#cdRvQFfV9 zA)Jli9 zNVW`oflM_NXjL!v7QHQ|^j4BMunOgl@Fx+fkhiqE->flP&yZ3&X2cQ5nS#)u`n7$f zoNmCM7-U8CSYXW~FA`tnkVl`t;R4ng9JMsLjITy7ZG-@$A^DhD0$?rPQ+rmCH4SNw z$@oGd6JY?^-`2=I^wvE9V~-&5xLb6$javpscgx&erT-JX`d)DPHAoOD*N+>@;+HH^ zWn;r;czL9RYNgne?CK+POG@t#1Ee6bEGqwGfpI?jP-X9H%{)|*peJGJE|Py+WQkhz z-ab2KvfnL{nmybek+Lf_AYTIIeoS>4JeSWbtX%akloH)H(03s{hUHGrSFvt9I zc2%5W>CySy?~wIo++7NEFX6-%wG6+;Y|B}V>Cq+yr^B5DGtE>rsta#J_KZh9b#g43 z?OS!6S@%xHw=pM%XV{3O@Gv#LG#73W>NSJM1jR*{?2X=Yq@fyDG8q@X425jb)BK z(*=}10!B0k2BGb};DG{3o+(5mtzf-OQWk_}QE9rR?T}XL#xMt{a{`=NxPm6xXluwoW;SEI-c6)y9}6~PXy!>J$IK_H!5DFRbQBLVr^V>%6e;_6vtZl$H@Nf_vv*l zChcpWI8j?U01rXC$Cp{DQxZdu2O=1kaOc@=5_S>Bk?J)F(h5xa0Rk_)s;Jx>|G4Ip zTCq4ZIj(DN=H7G;Y(ty$O@i$hX-@X7yS|2jHdnkpn%qxo0kIA#YWEY05>>C)sETPb z52%Y#+;rB6$pX&2c}!E(V6B60jj7fgW@c8vSi=O>e{LHx`0JWsOtqFXj{zs*jp+}( zYb;S#gw?5VA8PU^TN3^E8(4t1eX1P|0lg&*rbku%wOT^1Q-ASHUI?R zzw~zh)~Nn>)!l#TRRRC%&;Qo`pIy3BCS`~I(O-*y3LWt{DCTo76=MZ2(Ims$A5I7j zACBh&eR)-@%IKKWprTH8B;4|J`WmzTDEd4Aj=Ew(rgrDE=A#{jkHZ<4y{pPS+4m>)V3)>o{~)bwK4hHL3VH5eK-A8*>WiVdV#q$7QdEB{=nm z-Yh~d(_v7Ub^l^xc;qv9{&N}fFpMxRBpr_${1mk|ZG`xF2CnS;ALXB1R17f%f0fc^&;S6x z{!;cY98K-)oNeu#O`QJGe^#e%I%d)T70Yrhy6HRLLeRTnle&^3k>zZ$UIUX0vS#KF zi4U&X=|MVK+Vk*VKnJK@mFabDgnWb%O?Cq-WJ2|V4aC564>pLC@74|6>d`f!+%*eu z3uNpW!^#Q=g-yTOy^3@r4cZ%ozfcEVw#U1}DjFHX6pT_Bi0{%zrpy_d+1BgJU%4V9 zsY9gn&%u8_$WjJGthf%44a18EL50N)nMVkQxVZL193WE&#nKR=!)o+%wO<4cLgIG~ z(VrEa6e&oZDL?bi6UVD86Va3=&|2Ga#2~*&v@ME1@>;OOEOE(J`}KzqZ^_;S8;-B_ zS;Au|;&o(e)C-69E=Ff2nf#f=3?lzY&mZ?>0b!LBMY1J8f}A*!kU_MHr@~eHZW`T{ zh@1UhF1g2FuQ$1Nbc@H9DV4dd3LU<=>P2BU3(jJ+luwu%Rj|)dTz3X%O)(`~#B^*& z^#`83IEBK1p>FYOX}#uvrLhnHq;#X^qUw`{`2<{d4j(lN5AIv7PNDY-+zcTLDMi}S z*MF=4G=Q%kHr|^oG_9rt8@6%bg2Pc)WjW1887r{S4+`M9Yf6X1pAaJ$^r#uq$@U5> zK}sq?X&6wk4mPRO{a~d;bP~{x*C+bGJ z(I?WsY^n`nZ|#}-FQEa|t;zMdwm?t*<+7$KtTRWnv$4Y*lj17rrZnNi zN0IwK;%pc4Z=4sh|G`-yNFcdSM&7tb6DX^!2+}P+BKhdCxgZ>c99hotN8|Fgn9S_w z&w^*X_gbTChnILP>1ye{ijbk3>n@Zw{h$mAOS!o1A$j{uxpfzCmSj_s1~7*=@?V^@ zP9^^zoN@l*%;`qWNA;7A{s!E5j!-j(0O?n^PHyl5;sz}TH7#Nv6fj)|7|g>TJkg&f zG8AqFHmvh+oMHckv(CS8?n#H{*NheneiRMsVt<8Bm6gei8DilGoI%4#CfG)eAxd<> z>b7wpb49f4_|aDQQZ9_giSdnnS!!8b@HvatUmo#Tr++#f<~9@GsGYQbXg(DzSlyy* zEIC=Xysw05pU35NtFWDDXzbGVs?`f{c?~&9iQtfsniD1riI(rr+|tMcU3OadL;H*E z)i@@~?w-^$x;N;z<*whT#_dI(Q;S~Ic^%5#7rSn7l#JCzA`Yda6T{)zZ`kVv`<~#G z>DWe0tCUp`qXF1sk>#Jf-Kf_(^EgAkjnJ&IpUSVwNcfle?aODpzuxzM|C&YizM>)P zFV5{y000R8<)6(>42(@28UFFk#i^UNTlfh4yHwA3)H_Jt6Sl0XtO}XUDm#_LUjTvY zEKukm?sQ*&;CgK@SsQbF=&27mn5O8BYVF_^LAXq*)kZKyP6?pY1yn|(t}(y7-(6b; z16+#7!{tG>iin!dUQQm%E`2i1NCB<~OTA=P$=zhj(6us|B(6G+mdLAEZ?Y*PmQ9B! zhP+G|vBMP9r<)a$HK0pxBpQfNS=c?%#U^3agBrng^)rzU*9y#plL(-_L)3)ixq(5r zqKgP9Gom#OZh4CZJ#}6Jm$E zRqF=glbR(nfR*8UHQIJAASUfr^uee$4BP-!v3LpA4EufL;yvi5nfXCW*k7Oe^9$zCA*a@?6=PjZg_T{o_$bQM%+qtWn%LZb_ zSo6~0;{v26$9$?cN2?6=H`m$D?h{Q`9xrL!WAA{oVy*-KxSoK-rz9abEd1FAuk#&j z%$R(zXlE5$yZj~QXxLSFFU)Ea6b0v&Om@Gr8Hcj$RwTK-_%>!9=i{~g!8HS-s+3&@ zJLEf+ahh#@)|pruw<(D6K-o`3-U3ibQqH)SXMgr7FSA~t`Pu>J-6zOq&#_qVnqX-- zPK14R#@qejnI>GW8FHKXSd}&nud37zU@B*Y9IBUeN2%c~1#c}Rxi3qM@)cGQYUYN# zC)Y`I=kiwAcnF=3_`+BP8FK9}Z;!V`{vyriNBNa1ey;pgT4C^_1|2Cx*B=AIcJist zv%llGuy&^F`VwK3U6i&JRLo9zx6mnnrz-xItC(6MoA`M%JNJs&ibi6C z$;}#O>t3e^=3(CI_qDZMIY3&pCa%CluS5eoacW{rI^pa4d8Ydz_f*AX^LLGZiWK*= z<+Q+jrl+3ASyW51>#Z6y_@#Ny#`DxL*QmWc97)eg|BK9CIr2cBEeQl>q)MQcbebw# z*B53wd>M#bs2{GB%Q8Fjm4VS#Z3g-;7Z)My*PzLZP$eu65jCuKCDNu{&8MVfmS=$el%sj zpcM3qeQ&rMR3ey*%8HBf37>g>;YTN=;v4&vpV8ffuT#`zdbp-Dl<6-g^FuXHnmvqD zB=yyi_f+~sKC`Lc3Pk;#y*pT&0_atl;M71;HGry8z#;&=0t*9Zl$j)nL+Wh!dMtfG zLmD8)Il9H87wE*S1BYAwR!K6%pdXr0CEJ(q;$C|I=G1vv?7ZfO)>)lVAd8AjbRje_ zF-q6AF}>mQRw=5u^<`;Q`fg`oqAg%^GBB+q36(+T{-U!XvLt(Z<=sXzaC^E2v#d13!kd&*~YPYa6YOeuK zT{2;(owxb{xPIA-H0_7{nP8UJldBn|#sTj>_Ylwb)KwqflfJ1yynqSvY&n&o-&_S- zv{zuRGerI_cWWzCAe@8ZEodv$MJA=)QW0}w8es?NvMk;(t%30zPfbZbe`Q@B5m*b5 z+Lg3h#ykO^OM~}s%wd&s^@IKssLan8kj}E_bkeLet}CcsZpry9x;T(Vx? zQXf^pJ>c`!vkzLlr;K7^4Yr(Ws!FuDF?a5UOm9uDi-*2Y{m}MeNFy0)bq^i7Rc)ab>t;% zO1mRCxGZ97)Y=Kkv!(!c_!obp-Q{zrQV@~TZ5N*_A5s2cAOx$i%(9$$Njqn{)J~9b z*vg*QCgYa!&J{@vLNy-whgw9?Zr?8;GK)8rn!wZi&Dd3?7UHMIrOzQXqj+^WdzokP z&^J+e1y7_>gQZK?ja_kaDs3VcPvH+Ov=waU6@L}fC0aRslT4G_h`~*pz#HdtK1a3= z-=wpGLhw+@L9%ulUIHV}2@a)0HbwVtKqO`>tvff&e4g70h4dYp`9WsT)rHP;)_1Z! zp;sV9k>{Pa{VzDVHegZsTpHgiP&k>2s-Is+E1yWh-yj)J6>ui-(vYE3t&;9P9=5h% z5p%ax+Pf#C*l#f?xy^JpP)!0NxK9I4u*X{7xmE)Uz&|UK<5X~69SpG9%1NqHCW|Ph zU%hXyeJNXb)V@p5R^2JA&T9MCaXWH%C^KP220zWTWQ#-f#VbN&e2R=5!)lY)+}-** zq~mLXbaDsQ>}}^xrP*aqi9-JFg4Y&or4Px^AcB;C2HWG!7L1W&y2(q|BTS-WRXQGw z+)S?NYNjdIXkT<_n@)_D)90E3n5i^qf7Q$L`!}}54y~;x-Y?l|b1}{?9 zOmi$$51Me_M)5Xi*o zY;3(VktTJNv?Ja$$I%{Wt)?)_6_(Ssc!$Of%?TLgN;6n*SleHi6SriRdYM^2j3PK5 zS!Al}2vh1v*?zL{}sKVv|#O4fn3&)lc< zQoo}(c62kKxf6m?K(Y#_uFO+dm%4kndcHeH79szjZkz`T$37_UAP6K5etM| zS)^oBNw8Qqm8gN*6k|KXrS(#VUOQ8okLxrk1l2`!$s+CfImTF|2?9wSWztnz&9HrF z!C*GKI`_3A7~nd|Y{ba5RfSH8Lh<#`8hO-l_3FfveSSK9#(W`>+JUpcy5N`AL9{Ad zVB`Ep*bqCw_sN(q$0>xw&WcpsWrTu$=8W@s%_H(+SduJeF2%uKsVS$uB;#4NoEg_+ zxo{gB^rYkm_A$8FdR{WKl6GihGn5&X_iu6xAnurynhLK{E;9}dD;;N_Qk>Ky3SRBb z0p=WB7ZxbE4|0|Bn?Nj@pvrM%I$k8NeGwEHgRUEA;oiQ5$A}mJtrz`fjRa?3W08op z%t--tVicNlQQh^#PA&{g5&dY}EAi@LUoqS-0KnET$9aW(h%lH&cbN+l+jwP{wQD9P zapFscE_JtLL;B5QMgBOrvdD>6E@{N=BvvX_;QB}e{G4uc+=e!X)iF0uzT4KEi*TAL ziiixA`OJk-KPYL^eI7QvkL=0?$QlPJQncq0<7tgwczCVVgIf2N%4DuuSGnoVqO`zK zI21?%ITY2-8+(U74)L_x)IJ!kg)t0irPo6N+8bFnvT1H*E!v}oy)3{H_kgbW(6qp=NMgYU9s6m63?Lne*NWUrl$y-z-EpNF?;vTS0`pceXv1zhdtXn-w|4}3 zqkr`cHg3m`VAAXEKV9&7om&udatow5>@Yh!_LUVvluiefIRW1XGjo%Gw%hj5pDG5D zJ|3^s!O<-0-pm*f)RUIhUuW3I3Isrot)z{Sg(TRp;^Qj{rOW_AEOK$rfYx9P;lorhu3NO{i^%1>vjDz>2=L>82}eh zR2RKUW##ep=~1J)N{LGz}e-=_3`=kNb21OT$5 zUs~Q$0094ND1Wd0YsuBd#Mr`s&cepP%!Gl~-qtKaURDei3iF@4U?s$b6#)SLFZSL$ zs;RD9AH|A_!Ye9>Gz&$#f`C%(^dh}SL3#zk_Z@j z2!u```Q?4Td(ORg+%xX^-7(Jn@5>mwjjZgQ%&fiEGw1Wnxlf^(7?o(wF=7EstW6b+ zjD4mPJ_c$}nd(M)mKg`99iQktVPa}bW;uFuhH-q}Q{CK$(X{99NH~xu?_~bo0V>sfU{mG>*POufsQbxpF%1{Hyaprh$=E%+c2=>{b}A^n>hav* zThqsnUwrm7e*IhOoRV>Ybc1x)hFj{KDfDNgE9SP`ee;H9yLlzN7f)ctcaGg@j^vX` z!e*CGYy2=F?`=QA!N?uBFp#>!;p|?u(Jsk{T7bpDfCN2=3XX*HK`LLk@;gmWY4#a>F6m(*u|4kHxs>gpcazc^Oj_D?Wal%g-@OIcSfZo{pLWID&7+6qF zU#0%m8$=_+l{U(OP&%^h@8Up@FKgh<1IB|$biC{XC8dW(b9#LTL~cY={ohnf)tqC~ zokyE=8jQY60)`E-epfG4vS$`Gn$uNik;QLb0fin#b zN4WU=F2%IIDxMAO7<&yLoH^IHJSK(ARnp;nS$`3b$vp%wBQxT4T(sDyLy<}L3=^+YdP0s`oa7>f7p!T!wvifgx;@C|MA0|m^^*| zWQz~wY#O6JKreodjBt*b88^2Fu9m&_KbdQ>Clr07w7|x-?<>*R@6Tq&;n*CRKB`jw ztPAglH4S!!Oc|?`dYpf`W3p?NV`iFE>q4Ag8Fh54_*&CKG^PeuN}4GZW+d}JqU=A@ z1MK`NmCB8<#J5PbuLU>=nW%K`i^v@FDi&Dq81W?i%ONRp_>Z%nXeY!qh6isS^EvzF1E9$f`rRrD6H zN_s&lqc4L29kYF&@M=lx8jGnG><#-Rb)@2gms{}oqNLwQY{wL9$KlFc;tNB(7d>BM z_f6p!^CXuk{svHS@MLDZcP4{-SuApdgsg)O0E%<7*zX=9>E+rQ*P2rIvYQnQr1stN z~#@N>Wr-8;&f8$O!^z>$ut~i$bbu-!&z$$dK9K&ZCe3=t0fazS`{NQP+t@7SebUQ?a z_O)rqB0BwmX-)sjJ=B7v`^W&pPL(7!{$B`?=dL7A;(!6lx(%j?45&FIiz3VCmia9A@ z?bA20Tk`&YJ#q?W`EUtFF^Z8$FIqaNxNOwd;AX{YLow@mPx<~dSJ92O3)dk-;na3{ zzj3oX_A6Ifm`8B0#3!Ewh$ntv&$e8j;f9Rr_a`=H>OJeuDfp9j_g)8v*P*%LE;MVX z5S$ciL#gO3Yf$PXQp#SjCZdQUW9@-n8RoUanYb49zjQ+3v*x>+Z#hf8epiy*9^I4A zK>f^oi!oJbf4v);thL5bnzr}paA>Xd zPV_`V^;bM&QrT zWV)UO&9KWwEGWF6`AhZ{bOv){yYFLSrct1I_4w>ln#_4gx5t?!Dfldl3gW0DFi;kK zTjXt=FK5KvtLe|=KTPv*?MP}YUDyBgK+!jbJ-65WYU?J^Gq&^K_>zNYfdTA0r+2n5 zHCQs^g-Ffgr$Ga|e(iwEk_9Eb8OHAW-r1;%*{}Mv@20EEEwQ{37s^xzOC6L`_jziR zTIK9sdB4fI!H&*5LQnse0CFeeyGHH0bj_XZEHw`&p|08u!2=hrhlLaa{nm%L!7T=-`8NE< z@xPj-gHtZ8NfDfKIf+5-xkW?UZ`JF>lB)cd&!mY+#R|bbhbc?w3a5iFF27P;b^?8N z^0GJPhAS0QeqDJ*FncW^*EGd6c%>4e+ByYUan+MvTsb^P9VNH(3AFjvJcO@uTv|qr-k_&M|en*wyp;)z?@$4YqiRjje9qZOilqC#bb>CoTva>by=D5ZuKu6pc%mW=FN5 zuTYKW;Uwd_A$9Yjv~l0i`!9&7SR?%Ua?J2$8aIG-`o@l|lIXDndhxI5O9bBJD4);e zB3TN&c10d63U`SC+d4vHOVM{X)Qz7YuRr5oLIQ2pmd^DguhYcsR$v#ohuvR24KUZx z>#CVPyLGSUM>}z{9(x=35k_E4eRhY9BFS-nuoD?S6I|M^l!&8BdX05kqz$~~*CJxk zI?X~$g9a?)o?aT6H|JHasTLVLcO)r7+GLL2y&WTXF6O_=(zVIb@G*toyw)fqL;}WR`@j9N!^PY#>CqT;YVDt8*g_MyPLSwA1ro2-Z+FSyx=<~5nPt& z4p9#e3vOwh-oA<{v4-n)fJ^^SfARU9-m>SYJ5k2M+Q}b{uY^Dw zzWi>9O0&nyt3+SqOt^f0RjycAFN06SB#)l@v^6%dK=0Ms zHL30~n{Ogyo8*8uILY+-!mS{N;)6+2ogx|Leuc5eWT*BIw6?nWuQxuy|3UhTb z9m{_Ov7Zo>!&j$j{r|zlB3lb1&B=pPV`EQp|F1Z_(3i5S1l-l@XjR>DQ9^R)hyr6x z={bAZ=!qFL9HUkCU0~$m7UFPhJY$IT?V_~xf-Ahtr)eQz9NfGpL7yApw+_|Fz@8?j zf;)Y;dVFMH-ae+ZU9Eu75_)G_7f0gzMTuiPi&QAkdHHN6>Xf z3D|*eAR~Lp)x64+9cyf$VTri8gVc9lJzs6ytr5PiE+OSWkk8XWVjGrr+oL1*bn*a| z2V3Q&i#LM593;Qg(zvSaIOly=6e$5y-#nVG)XAw#D37z3f_&I(Nz2I%EIuMyiEJhL zG2ci!?#xlxxqyI|=V^%2_C*D=snA6jR36jSxo!zO9J{6XNtd!W#R7t^;7R`1neJ5z zRY726>K(!+Gh$vZd@a-L=oAqM6+x-4f!cINR_^HueYzZ7x24*u8`efh`z6YDwtkC+ zy$b#6db=yA_O137ry%a4qx@-}z_2aq4Kkkv@lb{%pwMW02Hp=*;-9NB5Z2thNHm(@WXTqV+G%C9GDV)jZ zOZ_H-ndKAphGkb*4vigG+kjfJ^nNPq8M|FR7_zg47#Fz4ab~O34q#`BymDzXSb7k} z%j*Hx%8ccW6U!kKqSRIw01gG(S0JNbh@YS{a~Bp&PYVX*8MrP=H3&x6k=jOQ=M_nw zWvN5uzr+0EI*$8S%-#?)q!zh;d|%H90a}N-20%WnPgW1b;+WoLcL@P;FGJ#m>ER2q zf*{I6QF%che$k6u&3qRi7Zi&E(IL{)YmgQ1fscOmL7S|%S~me(+DaLBZ{5kguhYu) zsMf0XRr8_mvzBn44ZXYMr_`?(@a(|RU|Duok$UHGKa<5ZpSJVUt}T(6w|uUq6*5T7 z6OCW~oxu|r72|f%yNM~skY;K|KnibyUOB?@K&RE?S=X&KT>H)wxAs3;6!;~8S=m|q zv5s3q(C;0q`OV+>`qh3d@}y1{79tz<3>a?OjpEGAxiz%M2B%w~J?-9%4h5K77vG@$ z?6lSm+JUI}8_7xztY3S56=^zOR9tR@O3d+B;9TC$Gx4y=nENqsO6>**2*YaZvA?aj z`)bU$Oe!Xw$RS#z1{Q~aytX!CkOeAb7s{ZtDt;+_Ykr=VNG?rDNW|V`c6jSbm@S6N zpL4Q0jwo&%wz=>*Ky8DQtWl&G^MQEKVb#gg`3JT+D7cN?+-gsMP8_?;w^cS4l7V7* zAuuHs(je_lsSg^|T}*W~k=r4K%{RDoHdO9?FZ|_UP`U=D?H1Qq(Od18&cB1*rlcU%hnEdpEIlNv^g)x> zm-_ifS~#T449fj?Ic0k$A?Ttc1bd6CX5fuAQ@_P)rAR~U*~45JgG#b03S=c~rKtZ? z5SDis`3bEQ>Sj40d7{X(Gc&yQ2``sYDgSg5M^)?k(Kf{`#)iwrpL`@e)ltZnoW(2@ zGZ1-r(8?!L^jZOx`E1%d{_1GGSwm;xD^R-hB|pykWcI@0g%?BVAAaAG$*Y~9hy((% zf2%6dcLLknjSsx1+L_;A5l1g@>JfGNt#;CzP7QV>-@hNbY)J=0w~1-+Jd{ym9%oo>;9gl{(1_>YHXGc78nnt=@cY+CcUJHOM)6>|9@owF?)6((_|{_L6f_Q%VkEgdfL-(_PpedhByA{b+0?I-9Nii2zr(2 z9#>JtF=a?9mpOJ;F%v$-`5-RYcVYCVxQfsHQI^pJqgk%^k-60eiI-)&N|}5eFQ%DO z(}9!#@p6+ts1YbKnl~v0m#nAgXPP-}a11S$5oadr674OcU~*R z(9>;f;*y$=qm;+4s2?ZR?kvJs`NN>}rIhGiLIHO*B2Zz-oOP4vATV5Ca2coAE6^Pk zpT6vQ+ivAF&v$cN>!ZND7Ihi0UN^O@(&drXKI`s-2$=x8k)!jtyz!+zhH4m{{=0rd z+p19Uz^EL4$P$PjkN0&<~$w3fu_oyz1&H@OyO&+xVBrs}uZI|!-?t`NE zijo#H;qee&!ns5Ihq3Q)B|PMLAR7D;2jy$dy{xUbF0PF^{uFe+ynO$n)_`PL$jhH6 z2LWCbfNL^L!S+Rhd2 zjw{DP zeH4vw!c{x-(WaFZ8CSdH)xp)bQV~0?k5;zwi}lpa><(Fi!0@ZqtmD2l@-ZfF&w@WV z+LUS3B0l^+8tiG^lIZW=W9w*?hlZVI(vA-Nt;<3%AFzatp5+v+1dv0-C~Yc`u*dn% zA_pI$mtbOdVa8WuGjoqdaFroxY9q4?E}~~H;iWs*5(5X3e!tI4 z(o;>63kq~gyO%2wSSToWS~PW)IZv-UTjhy_(!21K;OD|d^z3=PnfpB3uqpS7#Ld^wZl&JMr(Q)+GH>(? zWn7>`wk|gHi^&7TlUygC{FU>%j-ifU5v`K&n*npaWfC!8h(b~tHRTPmZ4=q`T;rK~ z)82BNhv(`zY)ult+M0Dvk3tSO<;J$SZODT4oSL&OI_z1+%CC&eNLK8-)OtS=AKEuc zLBTJs%!QwEl0cxcNQn58HxHB*igWcIxkc*Ls3u}$@hz@)xh~kRuHeqj-y?bsRKyaD;0sMEg2Tk-BDI^uOX&rKi_( z*|iO$19cYPj*zvj8A|W0hp5UC%cb0%58#)N+A(5Zg>K%ni8zas2*Rl+Y?N)v3^Q7` zLi0{A$-MM)$D_pm@p02U7WU-+_HxUl{>2?d=;9Y#%!xDkZw&&$@brNC&a1mQ0Q-bk z_4TH=_A`+^R=sN}e%HkDaVrp~`G?1bE}d0|p}4)1j4xf)37flU;@zrazi_AJ)MV9M z$O8_;Amtj5pd8sBA8iW0+7MsnL9twUxn(>4Kl)D0j_(`aglaK zs}Lt=lqznq`ocW>^gEFu6qhP2RjsS*ViIQ%I0gn~fEEevzr0Y%aULnxWD=n=Zv3M< zq3e^`k2-YLF5Q42>i6+tOc(aUH<~38N1*`GF7MpNOsg*q^?J2%hsw@a%($zGDAx@T zMbd>(P-My1X!AzsP1q=h9v;9-zP^WDg3gY)Vq+ctJXFniuZ z4jz%hpsxH4@u2upF>tPYDx$(mSu_@5=ZQr8g8yNAxzn#$Q8EcpMHs>yb#H_$2@6qQ zd(rl#JwpEo&Kd??dfL|UL-e}pldkP_C2#BH{cKGggk)V4ZJ3z(+G?@-WNUzgLL9FI zb69fkJ1+C+oM~82c^ts_b<=`tQKLd2Z37rX1@dOOIJ@V&}=;RnR?6j}H-D z-^s6N+l#gISS&M_r43KVOTJw1S8zUu>j)w=07xEm&HOQJ?K6vqkXoWF=C;)a%?r4^ z4FUf3sc|cMZ_5r+{9fs_#_CadN{wE|6{Pi->GKJD@QWT>^^tw@c(_pfJo=5p-dCjk zHz^OsRS0vG1myjZui}n|FXk2ts+FNCtAZOp_J(Co3n^DHug52ckn!Y=R|a8EoqvPtS%VSIkNO@Q#=k6l1HZm*Fcj{V`Xy+!AX07Qp$U!Dw3A;)4aid| zV!tJ=r4MT~0D+Obe5&~S)P>kaRuvW{HWTG72 za-~l8DH&5nP(9lr45h*h_i%UeXXLQCT5aYa^U|=|I-Gt-+kr0Z16M zDiFH5Ha(3OU;(1*?r|>#k55%Um~ZNko|ec2xc4MQI$2+ZiQQ z=!5Qy!ojAE)u-4EB{l2ln@IV2A0T#rWG~{-Pj;4Uk>h1P$^{8oIh>i27AdlmyZ!gS7%>!)GPE!KqrYnXBlo2%(V z@)8z9eqN8J>m)rC1`U??MT(YHLyJs>RQF5G1Nb{6?|`cMjcq4`4YgEG@~GvU||q{oMc zke0B!7AnSdF?Ilt5l*=QgrYz&@Yl^Q>}X78YnWI-P|m~KCyMl>l&*A_m{__W^tp#z z`{B-3j1&t|lp9;!`lZ@Gkn!Nyb%&Xura|YFPaN`xbz&gYP96E&!(xK0VS$T5rq8_t zH9{Kjoi*ZZ&nw%o0&gsGGX;aB9!<5;3T`Rh#B;3!>l9TxLgC^J&o=4e*+kU&LpBB$ zC(ghXeu+8Ng4Me4PZ5~Oi5+<ol*&+L9vHDq*nwJrheic;DY_ntSr*LO7Of)j zNjiTHl^C5i76r8EG%#KIv!lAa#fw0OxkxOo9puIsB#e*8b>#Ch)Ud|0L&!Y@fm)i9Q4*bfKwe3?MK!WV>d%PC-aNEhsJ_(d$sH;2o zj*G;qA6dv83p`@7j!LCMd_x+*{Gx}WJ1d3ZS}f@62;rwHlN@`KkB0Vg_SBtoWk z^_bU;DhvMuvyW@b^-e)a$>*y8QcE}aOj9ZD0$>REtu!^fS8?+a1T$Qa(br#0aWhspxn zD|a$uRkf|T@Bo`QBJpZ3^=6X1lv&Cu)>;J>*~_YZrE4s2Y2Tqv#zYi{XeQ;tFcQ7f zG4jwI(unKH3rpTuvZ36FKg0&F6*qE@c&`Jn_V}^OxzUye<(n*5lU4nNY|_`bO)VC@ zeN+M0;&l+(H6Fnq$5i{D^q*4X$vL}4)IZo#j2#*wgx9aja7Fj7?ST4a+Cqq@#6pVK zna_A*-%soyx=GI%3OKJJiTiWR?<>D=n|@L1_lQ^lv=??b6Zmk{QaB0p{tGGc)luv4 z8tG-|;fUSAH}=IZX48w7xJ8w*p+{67ss4$)`dALtp7GtzpXGdK9bak=hSH-HqkC8~ z#NEE|ent)IC^N!xd+94~ywCbCTGL&vMJwnOqO$UVqZvoMq*9U0VUa`>IbTY!xidOv_CNZ;M=h@)3MUMwRm}Q>@!N5AZ@Ewl6G>U$qt@Az!6d z@A;R`o4)A}>yq>q@HsGo&BQ&*s()^dqJP%?%it#eeC>gINX&?jJ^gMdow=Bsai|YUk&m~KWL72tN^oeAf2{pkTeylAfWWhx0f#maCEvEFqc3xk)+yVI5Osyw*3u5_!=^VQ5V*`0{y`FPUS@Jk9`+F1FK zUY+4HtiyCb&&;`%sUjA1S;igd)m!znOs=oBR(tBpLqFRdOqMx5&E{U(<>6U96WdqK z_pOv`Lor0xyXn6oHs zN~N21u=ydt#F7)M04CUG%i+wu^i+sUm;_OTY zBE#KzqW?}vyNke-%$RgYbLgWiRQIwtts`rFJ8q8wJ%icn{QNVn^sWZ&?#EKl&pK{T z3kzxNl67x~JIV-zcXDCHf;1UIMA?6MgR!jJ?jhHeuYo&UbXs;cc;2SL++Io{phTm9 z9!pD_CXJP({Ce<3PmATmY8!m_?2ih5G0I@2kzdSU;MM9MlLkAe)vOD<& zK?6SxgXLd!Ixr|V7m)iZ7rxAa{v4w(xViLVXF0rn!9#Ysa&)^gCq6PRy{ZFinoHVm z4u9QWzwKn&iy{;{>|i#Dz$y`tIL<0?0}H0z}O*~gRPZUj#ML3 z)$c~_Em0!L^iGVS<;`Ku+hUVTa_xMqc)*;`u$i7fC)&C)dMYq7zrdn?IQdEGs&P(& z%`+{uEt{{}kB-&lo)(7mI(n$M(Ot29)skf;W3%+@nqAsR~g1#aEjaS%S zqF0UkwgswekB5cE4jAZOY6&r4D`9#xn|ydD^DA6`;4?mOcQ*i9M}=}3PDo&J!JA11 z|AFXvqR`Q<Uz3o)60wMhPN5n2&f#Ajn$xD^Np#B*3 z!K!PaEPtqDzHgc(b*+(xeR{<}tqIrF%W2_TKN1M}&yPkOw2nfXVWzRzo;WDdmeh0D zL^Y^zT}A=Z|MQOzu-nR+jU>n-Zl5`81AMs4C|kX~P<$$pK~ml8y`tVZ&>}XGy}0%p zvzU%}nvGj}&|)eEvV0}#V%(y$GK}*70kTMxtDK(t?FErmWWM(GXzYgI@%cFGiD!}R*fn9 z=ZU7%J00{*#%4hVho4-NrQ=0Hjy9WsX&plbUkb7)wt`dqn4?_9hNU>$@j=5sQ&{P# z>bDv7kZj53M(QFm>kSh7^Xt-5tB%Df!*ca%;Z+L>Z&9UBVdia?f!em-XTPB zd-n3=*SB>xywa=L0%N-X-eCL3EyI_fbS?xZ%CbR$KdfFaYIUePKJ#tuqQ?9xUD^ni znEx=t?b&|5MC~{dHb;6hyNlV%wE3b>!WN_T2&&tCcmpb^&&ZMud0!zY1W##AblLAA zWEBmdtKKGN;jZyDkty~+wdf8je)S^z-B-Vw1%puyIpM~XXI zgQ`E}Ob+EJO+&mmY*R;N0)NtJ1|}!s5^cg`n>wiuT4N#ILWKk1&7c8f^nvjw0B7kR z)3-|Y^}?i&|_EAgJ9XlCNu@7JS zEKnMuuQl>rY<{Y|ZnLq%gq#J7Nrei2fLYgK5k%NdPR4;{yMUp)vJx}#FbJK$XHUJG zNPF{8I&hFx=kwW?$m(II7&h79H70!O5*hSGxlLhmKa0KU0iWJS!RqX)P~ za-}Y~%W2ey1=?8>@bcXs{$LD6e9BuecWg=AWk1I1){v`fKAN?rK6S&qx+8Lj1*Ffm zF(~8a0#j+){`jUJQFe1wc)o@9rv)Q^jNjtMY6rb<;hxUjC1Lo&`Qyv`@7fTW&`8mJ z1_iR7#~TeKfXe8BJ`<+xF7w97)6R^@^6Y+bld%2*xi{ezF1Vn9uP@8}GjG<(!2{g= zc}5pVnnTLFhsgRjm09DUK-7vS@*ceeyxhW9ptx4B@*6J}%nB8U}sX4{!M4sz${4Y{feMVbC+eeSmC}^yvgS-gV zOU{slgQjAd%pzp|{84lp4X*n;M(oX8H9q*_1&V*tjKm z39GF3RCN{j`nQILK;Y((fD$c#@|2@)PLk^~CCR^cbh$v>9AdiBKDU!W#r{^U9ldJ| zz@He=L~m*K>!t5La!@?_6N#$|bETaa{Jv9u;R(Uq8d+D%NfW1kFM=le3yzh4?F~0# zFBg7wZPihu>#Sk--n-WChV)(I@*6w5KWWAxh}`eN-K!O$6Kyr-XDo3mD|*$!?X>SC zP#?ph4HIA)kHB}5Bh_X@%S@0nB%WuU&=_{&K2V=+hs$z*ZS+)EO82p7k29~LMbnpZTPy| ztA6n5<=^8vyTe*Y%e@WBFy*^)xgNv0@<YQ+{q{xd9GBIW4gr{t535M@Miw@Y*R3vydCa@#4e1%+T^fc!nluW&RA!E*5B zMW)ePrPQEYSEdmId+QRPB8|1WRRc%G$scbBN-E7S0Zy29d^P>$?A4shF58K9;(#DW zg~@EbYu1w$|04>a#7&#%!z6W5tuSO?ue{jsyj0LKWrI(HG4SwChdkyy%b8>K(VW#9|EJR?52fP_G0oR-EGRBuQKzPgtmJ5*Sq1e>|tyX9Ig z=UgUTAez|`%8p0tx_HbbQouf?!-^(h*Ni&4rN|t>}XQW{%=&S;TD)(ccT- z^r1kXWUe53uC7=*&usTJBR*kvt7acETtSN%Uhq4v zYWB-RZmLy0#KjbjwEXWl&pjPhtRZouAM20peMC^3(`oSSedb zCEt1ImV0aOwc+}6n(Gfsr$zy z;7(2m?By+K`S8GJrm^hOOgw3DS4K> z*#wjHiP3rpJN|1rj)&gr<{pLJ!M+2O15SB1(Ei%8UDa!s)%wHDlao77xWHi&t)Un2 zrjCcis=ZiyGRWydjc8`Gk-bN~6Kzge!*}shgAxKf1nvPJ$=S4i2v-ab2d7pjDRkT6 z9|YHX2N!<)erV5TQl>+b)x#`Xd5;X1{if|O(9%x9^?BTb6HF+rx{-E=4nRQZ4U75S zTx&JRxO?3*>;;gYz)PeFbi}VjZ&KN5sN-7rNPL?tY+?Pg>Ptvfs~K1;q8@i82>}?P zY1Ac7C5RB)NV}G0+G3L6nMZAE;ha9P@LjXN6o$^diPdHa_BHj4J(cR=O5W8$Q9e)< zj7DgGByYzq1N_+?Gz>r%s+r3?m@;s3=u2B&umP6QRf38RtJhr~(wypA0=rTbTAC3R zTy-=!hu={~g|%Tf>NTQDvHosY!L-~@LSBky7(JUde^@th#@c(RQuSQWNKZdBV~zdh zg+F2ln@l2c*M>ZqO+(tjyq)_!kP$_~eUxbZRQwRe_M1q8C1a{EG=jQgV! zhIDZDDDKQE_l+Gj5tM$w=HcDTgKjoov^CE0N%vqhB^Yw6jPtafEkH7?-7-VUu_NR! z=rO|+PZU_XkfA7a1xN*cH3@i_@-!@9?^>hXjln4t76PidBMzeOtdKL)O%N59(Dt1< z-nMK+yOspC5zqDTA0}Y87O5J#^K?D%1k+-U6(#AAr@FvQ?~lM4QcGKHKorUTRz|{_ zQ88Jh1rQL)QI>7O9y(zX=AV2(xRDr~tUi;#c&Z;|n&JH2$KCJ2mW9~A)qAUv+TaSZ z4m^dG*`r40DhFu_Q!kKt^{EoXoyz7eD;7*zil(pf3*qv?lX)E~FsAvp>n?|s^(?2P zYr`bU{H8_b;!g+J_8~|+$~1Q?xObmc$dCKtGO42)H$CosDQ4FB4g1w1ho>lU1Rf=Rm7W6a&YO!G8hS|H@XfgE?b>j9yViT1Qylv z2#is1Rr{mr_Tb~S$Is{Ebp1BkgSeC}4=EZpqs~=kqw$?4@DS85xWhyHLuMP;F?@$r z&(rNYw1o^a{DnZcKCEbF)QxoB$?dWV*forai9ES=siVcRrA1bQiE#X*?eldePu-6@ zTdY(bYNx8z1iyk_bt>RmY?z$6|ABNCZm63@O1-Eb(Y{8Y-VRTuzQ!)X$CdYHNcL7|jbLp0*H7Q}(kU9B2`rELjbR&H za#HYZtJ-ZfLoDuB0%>G~q##h$tN-2e$=^(2{>Np)0c5YqpH?=DzrP>2thr5Q*UvJX zbvXZnP77yZ_TQAv{@l)v|J`(HMB9P6a&Qx(f?s#c*Fh>~j_3fnTP0i&8@cNpamVU3=eGe)6BE|6{$sJikp$%e^uj zJI0k6xhJd_?JxH7R&7pkE;rOcrqb%AR7pbk6! z6Y%So$bGL@A&%Bhfb-gIYR~COsPc&KfU0nM@?L(rvt>d1f=1DwgF%q{`~}5)XJS{p z<|pO%Z4337_u>)|K%Fl-2&Z^dch)lNZ%Z<#Sb8|`<$DFz_>8j&(6W- z6WEXkv_pC&V1;#t7~OQ+raJYfs$;q8s&Xkc&MG^;!6prWkZE!CyFqsjyHU}4<276> z;Yfp6Hs4-AlRYF|7<9k(qKGI2@(EbM|9R!}wKYfcNhB;mD&$T9#fLXAVhB+(SzKOj zSm_zOLWYtEWze`khbI=(Jj?X-S=c@UO8CakPl6WquLN9VKCboScCkAO9(L6RGojcN z$p-z6;m9(d){^YfH?c>{TgZrD=~d*|2tHBJA_ujg1v?bO&Q$BgvXslz!XIb=6J3i0 zYOjp|e+o@ol?O+lxCnn!jVw|>@*n;S=?!SHuZp-OO8PChMt>ouLGwnUR3fUQvaZbw zrlpEmjM~tmbheM8(IEq?Q3iqTX{Q&Q^o%l`6~P~lX|C3Td8!TYa$*1I(nnv4hOm}; zgM3>0*L9Ldmlh0JvA?gZ>e=}x29TzIl}*d7PnXt91#YErnLZ3sjS9QLbgwqOGi`L@ zl~269T83Yud-^k&UJUGA;|rN?-|YI$oY8?CLUtSN>uhbvTl8dz39cQ-TCT-{;k5F6 z&rnWfUA*EaoL|{PsO1jUiE+U3@!0tCOm1%J9pv0E8wyQC`|3^|jZW+^GrfzI$)AQt zb(-r1I;S`1c0{Ed+Mmbb*S~im!MPMCXB3e_a12dojvlc zB=_K7#KrP|5*L3basTgUn*86Bx&OBlRQ~<3|0XT|-z7t9`K` z1nPlviD8UfOzF}KiRYXGm!T;E&MtCKl$a)BmYJ5 zi~q?B|5v8@_b~hKVfMez7X5cG`FAh*cQ0XLN*G9#$2;*y#c7@Xr&7`N>c9!z1YE>F zlAeT9SH7ZbVgDMj?I`~w-M-7eE~>&dA8J{62Ny9^KQa_KoBf$-DafueV2rtZ#nVJ zj7PzDsTPJ$l`wX7T|L8TbyKkEd}`u&cN7a)3gFQ<@at~&r5q(EXXk8rAbucC*#5&( zlvL+_(M1}GKqJLo5!Rlq58tU~Q`!G51~}04@oBy|IHe8!MEOmot&>%#7$l8~pi>dF zRm5NxW!>N|_6=rk0Kv#yPYW*jvouyr-v!czkU0{~aI2S}E-kCl=2Zu8z7x@`r1N*o z_ZTL6xm5o>=WD#seO~wUb%egwsnh>wxvpuJ$AT?zCZ@la|EgS<^#5<=y5O4sN4c(J z99aShCNLA(Ue_HcvM&spp7V;-5Bzke)9lAhui0C7K79BvdZzp7JN>+iP|&E?a~|7o zthZ7!uJhjM)8GklQ?q&~XTUSJaqr}tPmjB0_>c*){R2_vddAk)#?@6OWPHdTZJSyO z8C|yMSh04kUC~1;Py;%tN6+ZI8$98goS@CUziSCFF@5?yO8uuM7h_-PitpdfAL9i- z`Tuz@LSylmjebX!4mr|0E;ps^F%IbGbN_V}CZ{Z4JZJ@QyosjeBmQ22>JJEnebpmB z8Ub>Erc)Rz8v8LBbX-pRGV*tV2jlfXTY(IkCmdxE4yYhH`FQjX=+D+7tsBtv=wA(Z z=J+q(F9&a!(gy(t^)x)eHS(nNxCHm^&Gl5Asi@o=G*0Y}V?0p(iPYM!GR{|{Up{HG( zp$2jKn%C=(N)vCA-ATQYORN*cPA=cxo&3Q+bK{%I$Y=8mi+FT}d3*K?A$&G#2PsBP zzJPBpG8V=Z-AZkO^4r4qZ8@w_VCCKLfpsmjQKrfuou-sJi;ScTtKO3Y`hk&+;;*S1 zUr#+Wk}XD`)qNA1ON)%c9H%>^V-$6L7o;_7nNN0I&+EdMe z$%9`QOch8U|Y;8629)E-N1p>2CR_VdEZI1HZ z{0hdXbg#AgYG0{H$9?sZTTGfAm5!Iixl`DL3ZMMwOe;SIj%)TjjFAs&sMZ7r(3;(Z zX)ToF8n|!{VITR;;FoT+s*_0rN6G!DdXb5}mm_-IP!azbXLDl(2?G`&8n%^qs_nV4 zkDK2(G(Q{JI5dH2fHvxP`D1YekV)7!7fv77Z*)q0igH^96Vts%i*Tt=G1(CCKDYJlECJ%YFN?+O8QX=5Nlqjjo%b-_VS|cn;as<{?~_ z%5}bpjNI=K60?)T<4U|R%SLb+SocUTdB~*XdIf`BO+Y&8*csQ)fa^JVzkyp~I2(mc zCmtrAti#sHm&_*zoiOH;xD{Z_!`Xq@DfOaVeDBt9f*p9z!Afq);sx#d-TaOw%jX^~ zSOVu)bXn~WSKf!SP4!%}CH`Eea2Tr_p^uh%CG791PAnMUH)<1|AHnuX)@f0y#ZoUl z!v7P6ksZrOP?5aNv~F}oF?C#7#}H+kX6T2#-1~HHRd1?voNT-qJ15KT*Qn>1S$N6K z#ge$3Zf{sUbgDJB^nFvuVf}n~ASmxM*JoOCqfaHdLjg9N5eZmkDfk1ESLU2E{jyia zMeO7*RE>D+Ek#krRh(|xTAm?i%w-qGKDry+vbt86zHy@pI1=zjdM{?A;5L3GB5?0} zNaaM6+Tv;AX*%pkY+w4U7q$gElE;mR;gnBeaC0~nF)Ru;K4*6VJHtQi!Ete{>Btk9 z*#FSQqJ@apD0>v|rEiWhns5(jnpCd6MtnoFfl?{hf@f!POv-o_qQs{rUTW6>T~((NE`pkBrbVH%m5IWHHmDaj!6U$fL~q#99&{9G@LM z?llz#5%qJE+BN!$Ls7!+6dR`%^f0y)+IhWcMuindr6oSKf-tb5?f6 zQXzc`_6oL<&yDgiS_T8@$Na}k zKsbV_P-hWNSCalEN|gayb~9JA0t0e*wb)st?C@Z5-JrDpwRL19T(DV}jrb73lkOA4 zW!cc!5s)!|ysY=yruU;O3*F8FnWWPh0P}{VwIA1VjNbxBe~&BHFA&$*e*o?ahU3K3 z8)BycxIWmt5pZ51`fL!kUw@Wauex|@1!IRy*6&%t_BYPxKBYmMK~T|8aH&D0-noKBr(Vywrb*OZoT58UjDI%6{WFy*P0!KIluMHza!&0JS;v-&8&rh<$} zIZm6OesAbr{Oe?!n8qQeUP~Jj^+8|SKrSY>PR+vDf>L!0D%W|v=rsfFhSHqi2xY76 z(ecql6?x}CS5u)w3SfUF(}5@7*4Nh+=~)ZIL8aqL@gz3jriIVU56ryR?^y{oGv&A6 z*z=rka#y6vkI!$q?&PRn_nDh=^jsl9UIp!~p05LH@bM}^{02Zb3Qwzy4nxjTahsK% zSUcSC)HLpN&+c^i{N>@=)XAs%eTEa9=i zT4oY*?XJap-L_5``n;V+nnP+n&eQ-f#~eTg^9X zwY@2>rY#@GW}12Dx*t3o%u1gU%COq=*D42p>9l(yprhILcz9-JSK z@!OfQq0w}RVNcrur`Q&B5d?^G z2PB?n;~@-Fo|E`L9=|lg`|@yDQTpj3>DR*(TDoRf_t!8I)QlG$z1RxHK+kEyCp$vm zQ?@~nfoo3iedVcq?H{j`p%I>eB9eW#xznChxSf3Ov6+7JwB7K&2Tt}AfdD(ABd3K* zrA55}(@dR`SKJ`y$QG{yJc3#HsrvDmI_pQLi3>H~L^e-gvhZAyMaeQUf~3|=1vz?F z*Iw&~+3i|^RF9y8>`Etx)r>=RczEmHz_lw-@l#0-FLgRU$2BV#ODDH8n|NRBnUpeV zJL8in&aT}KaF7!QX$+HhswXvr^C{w9a5cH$DR$wDRv+zejHQpHn09Olf9P2Bygy)o zp3Pgt$**LQS7CbbH#|`i5CMGI#XLe?OSgW*DHn_@->sCeu^*kPYs7dzM0NP-8bBK> zQE(J5NJ_M^pz-RHsMljjUrU|CpcMlKGt=IWj6P4KAe!3s;*$7S`0T0>X=?B4dQE?+n+%2f zn8jOA<;MvB)iTnWrH^|@kx)4;FD4{3-15tU3l=Q!sq|HKL5A5S23ezFmS=|sYo>^n zM^fQAMQUysC)xCl8xf%GVw|`cg4zpo`ijTP{0ehYH#w5G6<$+5j*!?Lq4h)&Z25yTLT$6P zL@YEx%IQbMV(NK(0m}=Xl)o3xm0>Vzm!68}g5rq2+wu5yhF6&w>6e<(c@SZ@0Li9g z-M5E4JYCDC*AQxiF~QLCYqVl?%~$g{s!zIlKMq49xbLuGwFP52~Wj zH)(sl;-rb3;_JTHK9>(?cRD!4<$!#;eq?(u`r9Gr1f8)&D+)}4dX4y$VudCW!Hut= ze0_t1<9|%6Px*NN+i}eS_e@}M2aQ{4_&Hqk_+a4gALbpQVMW)2$iBEaV+@xyuL7GQ zsLA6!=ve6|@T!exd7&sn8*Wq=)L^Z4Tb=ve>Fu$A0Z>TTOXmS9boYmE3!#|VQOL-4 zI)sm)2WQq(MFrC^Cu)zfyrbNi0fB=N&z=BJ@%tkZ$stQ^iDr;pTvzvn`m)3PZuIiQ zL$dEn=gaMK%dsO8E$ zJT2u`N{QildigsT31L?o9Z~G$sc>_bg%gV|8lI@axznOc@8y6t_1N&mH!5-y%@*ff z(=kVGsHW0c_X>E{-W7n6<;5$NdF*9jE4<~{48sy%kr&@!3whfrniOlyW#%Ev)2u6y zq^GAY#E!TNs)a^wx9B{8YqB`mLS|_P474FK8vdBKZ;-1EM9zC2|~fDk~|@06H~yGdAJM_SJhOFD!n$%)7rPQZh^ z*X7b%{k-_#cPJpaih2_}K~J2O?q@7;z5Gt}=f}=*n(-q5Z@>qBV)oUR>gB(d0E6!j zp087uU+#@i{es?J7jNa1lNCN%$PZf$;6hPMXO~(ly-_sp#$QcnYH}@#hEysw(#wfbk#7wG432Lgr%8V3RvhFJ8>za8K4 zeIuONB=&Vcj2#skti1@JccTxYN8Pi)C_?*#?Fj(_dqLyNW43(L;~N(Y75={I!9Mxe z1?)325+SMqG5jsg8d@E(I*(K%XV$Vs2A1wgI=vj(ZBSW55n&QkgISSx@#nQ4xZ~)L zE6J%a%hSt}*p(DV+2{UzpQX~xmddQcph^L-ueuN+DQS;31Ao4(M9%0u&#U4~4}y9Y z*~HL=?d+2LXHfzYq2gM1^R}0eQ;NT1xr{;1N6zp(^X+$emf2Rb3T`Ignc`A<(_`e% zq|t^SfJBh$!t^~9Tsof5?rdvXSI7o?Z4J|5Di1&&HDn@CMX4uk;j=0PeYziV?1Nf( z_F|GqN^-cHfM7Ju4b5+szYqC9on9|xoLtp#)%^5DVmy@<8vs}C`p5&S*%$toJ7jj? z*i+UsUSF3Nw6qyxRCr%KiflpRE6BBXKPoGbUDWjT?Mf2q;4D7_oRq2Y=?}$GB@WdI zrS9E*3njn8kQQAf4b$qTyG+WU_|fWoPby{eoT(I^F{{{Gy~Q#OLjP-@%zq@N+?s#f zd_GTE08XcZf`To`WJ<00V>yrJ80*JBF`3;N+H7`N?pQ02v5R?jG60N~UUm|E-!`8@ z49fBw53dEH;wNeMZdbC4%1)YA`s_)^k@}wnwS606t1*)Liw(;hD5E@;YOfV`HAj*v zL-)I7Y{B@7^A_XX&Vy@@5NEpf&mj~D77avum-y@L zz9<`&&^5~O)jl<5W~DbYdVIH0LEE>56I~_N)LXXP?CIZuJG1)DC!56+x>IxC-Tx=F zjvgeTr%i;4XL5a~5;{2*a~IeZLnLRi!kAV<0Hik&zJfjfyWW-S;>h^d^-0nN0DO=>}u%NH7}@o5E>> zE~~##4$~3Hd36wsgu;p1jhWtsKRaQ!FOaA%^COKD-y-VN$5TrCV<;FOA487P&iWeBFLnZ3R|=44rfi> z9MP)B;-U2DGDWMV#W0QKM)+hi3juJqb#JQ4w_4^Q=n+a!3gKd58LQn9Aoj=UY@K(v zR!=)WkR_%nXOG_nnQ3LCgu>=cI|bJwn->S%$flySdDCCGCfNB>!T3>)p*qw7oN_nI zrdQa-`IApoz2E_30lyj2U;2yZT1H1wW6d9!c?s{U`8%?WxIb7f9$w-F5Yo!a*I@qNIb&VSF2U zRPWgTyvzt>^2jEgq*f}>3HxwwXFi)Gb|?!9Vv_T?SweFK1FwYm_&WC8d8|pKs^<~X zP~BH;5m1+DM~s5*MVF}Z_4gC3@aQ<#iqf<9G!jJx>XI+yMvQITTpt&y2;JM=TBXli zf?Q=~~Nr*A?0LY^e36P(Fqwo{2?ri^n zwW=EWEi-sSQw`iWxJ#ugoKGc|UWE4<>m`d?A3RzcW!G3c-iPzVmYjKmcSVp8@5dCWQ>HZLu9z$&qTNri)?*|?*$VDi9r7NQB8u#IM!7Iqt z0*Q3tA*~bbtMIk7Yryxk8+CNzl0F4xoM1%QbJyCoignMvf;wsE2@^y{VUw z40Bed7w`n$0mR`al%IfDRs)p-_(vZyy?=2KjPN2p!xY7Z-c);P@g_B_uDVxh-kSRX zPnfHLe2_l^7(at}n!I>4J9O`Yrk5l?ihBYgu}eJ|>kn4{to2$Uy!dP6rNisj)$E9A z-F(xntj2FDJFfEOPjk>od6_@xF@4R%bGX#OcfZXkXiWt^^%;FD&_uQAmGVdLLXZU+ zRHxce$c{Kn;K8=j@ctFN&F1q=co*BAKJc?^vm$DK#y$G-!*gqI z>bM^*)~_@}Rk8`*dZ2n;L@)r`J9q^k0~2I&duC!XO*m5fNBk-%GJZVt)^VY_VwXe} z<4Sx>HQV_f|wR_!agc|DP3dZpj> z>USE2l5lUtim<@!>l=2PNBXDfC$k6)BkPQWjsiEwDxTBrSis?>uysnAXPbP z5q?Xd(fffjlGKe%tcwPr&0)exas3%uD{dsiA}ai`eS)ur-KY$rkv1H(S>)V?&gr5) z+Kcy6(pMiKkz{k@CwMwDh>6B==bm-@I3)u@va_ci9~_i~%(ehrJZwSYhrVD{chg@- z_)L5|PS=Nhif94lEv-<+0zyUO*dXZ4r_we<&c;C6B?jJmaRiWqS%EYFWHlfO6p;LP znsCQo+AJX4yYiEAUq07WHmUzR-<*^9e>nX44}X~e)Aj4UKkRs4+*l>Xt8D(s@x=(w zwAfu6_@^wcpi)kvd1%vrSpNCvoZyw7`fR0k8Q|*y=;z0C@+m{+6dk=O*B~Zu*0g;|_`Ut-s_*&v^?LOyG9!;?)yD;v| zrqrK2{S6sUfn<+ivgK6$MnZe!E<;-G#&rI1NA<%L3y~3tgk5*npVu7p{|mv4R-tzx*`Ewc%p5~DTXuM=5 z+HDoom36~_!USg^2%V98U(3ri zthTr1c1Zv3qPt3ignDJe#~dtT_^=a;^tgccf)>c2X{d2BMo&nGRpj(m{OXgg4g-<9@{gxzS>hO0 z0)GkgIp@aT@&Qw5-EepgN#H9njzQY~N(fO$d6y-?=<=%CY6x{xqeL|u3B_Zz|U z$UOpav`I&(?*A~o@oOyAEev#5cVNE_v;93ycF&>;30;c5KLo+v;?mGO#xpeRTWlB# z7+zzh6Mwxq_zZs7l6+Lk+h0A<>XOM3Xp5dGli%>3 z=+usu<*`W+IC-I|ynVdwfKXBcKmcj0W&qfQ5cWeO1yKSX|EM{Otc9=1=qe!&YVTwR!Ev>HAl-O^O@iMHhd( z_^tC4VUWAya@4Lt6h^whA~%NjmcTxgf;$SgS<+3v&p|GfyG5Sq&fQ`|p!QKtfcPX$8b_D`@3N0Qk*5=OGo z-;`A+N5u6ro*wLd^2`?sw-pgV9+B*vuMQE(GL+VZLTp7mHVr=^oXTEnLa9%c!2z92 zx{?{hQae_Vl*=KSIOzx#D16ZRGn8A*#VJWvA|+IeO)~%r)zSY=_5`EROkZ#}wIC~9&_X#|}5 zm`qTZ{Q+Osfp&!vl$xa`{jL5rQ%&U~j}8GY!ePeT+cgQA{|lH;i}+6?_X5&J2@-qw zxRj0j2^d8*>3KX+4a*$s0BOPiq{#Vb&3P|Vgp42!+ET<@wZP!fPQoE-{nz}n}EXR~1(H05% z72o@c?T15-1)VDoH%TbZS@P~VOYU*|C7Yq*iii=(=cw%0H@`%q=lRg?ve|tL#6;3ZGF9Qqg5 zpQoKsN6+anf1Ys-Z2G2pvr)%zCgtQ{FCvOHhv)6m%6P2+^KAiVzc&gi!ADV;KCRV++LJ2p6H|=A5$e%t~Jj?IFDHF4DH#OjOoa(XUtSUac*6xnXbWwa@ zwt?4D!>++uc=xJD;8lA*Vg7fwdd1C6;o8ui}>0@i0yi8AV5koBPZ4vyid$Y+N0 zV*?)Uauf7@Y^lnS$p8-K^hn1swxFKOecI>PG4Ni{bI1oPn*gQexL_6U%wp2` z@Q%xTqdEe)H)`YIOXoK(8BmECW6lq}cmX`uPxw$mJk$Gf>v^}*=HGrM{l;d$^x>PD zp38um^EbObSJ0pOJ1Z7({VUR+^YQpX$rkzg7-m98ds2}K(Q$RbamQa zI(4@sF^-gG!t>RJ3G~{XR$n=%cM_zrEFIGKGo7CLKT48liH#ub)nJh8 z-lfp%SIjOYS~jDdC#w;ps7AL*IU%F=mgRhO(H{%Hz_1%QC$AD6zY1220jKYEeZ}E% zM884b0dvy`fM=P3Vz1pwNR^pOQ~>Kc`tVq`PG8R#3xxToRE;5phMYSeM)ff8h^r-5 zke@506}yYTzNwSskGTZ$0qTHaN7tu^=*VFi$rG34vNKfG(EcWdr{8W1a^ytk`a$1Z zwZ{`rEk(fkhkCwFI@VgLtMZ%MWVpw%!Ko4c!ld80jpcKbWcb6|$!%=Svl>;(Oi$x8E2aeq4{Ga;|2(Y6% zI#aufk!17nYNm@Tg5>k;qDL2sO0HbZkN06ZyCYj)%6%oXILbK0LZs%1etsuMwBr>s z0;N%Zrz&z2++#a16Z!+3`IjzK|2|s7zvnqsWka?`kG|o3$oJ@qgE|U5sM&84Kmq5k z6S>dF6y$_om?=QCq7Los0^+^b$X!BbhoGw|Oh}P(R zGSSi4s6L}QjN$npZI>l-xv(x|DrjJK3n`51K$}|ktUi#gK@^IL&6!Kk>k3N313$xoVqpK8nn3C5-`b`8YLjF)ZRIp=T6XbD0f1=HQJ#` zW&+|<_F^mCchT%54dr#&wHX=M4_)@jABz54m^awAreOu{Dw%*+CGVBXXO8NGQLplY zRmJS0DU+SXA+^VH|EA>?4vq*>s;&Q#$5G3W-h7^Y9lq$!efF^;G+s%GBdhTN=?PwY zmzI(LCAAj|%gdMvO5F;b%7FS`jRS+G{L(CQF+4U^TE5L}trt@4s{bLA; z(S0g2z5mQ9%Tdi693mBxSercsQGAHNu2GYuRHl46V8en*u_oT)8*JJuh5-HBxCF`` zJr5+*dYc2T5SSHcOmE&E;Np^%MoN@&sFyU8$eVh2J)NwT5lsMoyqa*iT|7!0+bm8XUm1ZZ zhl@4wFb&p5{V*_oyXzC0(H(x@GrU4k^;4osRItapt|gAe^H4QtXqc<%rq`uk8}+;~ zr><~=Ky{4xeOvg_j>GjVlxeh4u3&@a(i;;1mH2+)7s&=%0_<2eIz&Yi-pN)|CxRclE^}E{RGWpC(R$Z{xQ+~k52FZy-M`od2AJAcUqz5 zH+iQSMvdikJB+FZx8~L1K)!G9$Z9%wKt!sy(zsxn2YzFz3F(gS_TudW9wVY=u1=i+R>$=oxHiK^ZQp!tj|7F>DyZQd$=^EH--;03 zu{Pn7fI6TF4P=S7iQuGPcBe_CFc+fP!LxmsJQHu-h(U*F)P*!Az(o-snV}QbRn5j$ zCj02`>uRlJ=j$B*5D6|gJ3St&r$`OhU4hBff#GW*R|7M}iSyBYP~=hC{pgB~+MdP> zDVi4xFC1U|ndH47lMdCJv8m$A!YKngB2LvnbE${qgk0Ss+_a{k^-{cF|xlQu4;f%>F4m&2?`^1*tFOpEJkpRo$ zR%e(TkA4q*yz05L$f=I@Z-wu-01G>|dGXmLi^3X+kb)))c+%v2VIe;KqX)(H&vqE< z*p*^Gt?bAxAnL2>7};!zGV(X!VFv>Aie8_e>-ehD?O{MZM5BP0DI_etQbz88%wL$O zJvYR>(t^}{`F=Qsy30Kt;#jue=cebn&u4Tnj4e{S*$=R7;Pke7c+B|FWmU7TJF*RbJM5SMFzQYN}f(O80MR@MRQAU5I+o z>_@xzF6T_St5PSu*`vT~>wXCCyV=UoYE&&lu0oQi^&TX_mkjsaCG|D5Zy$@@~!68-k~=?R8g}tE*^xi<4*= zdPFk}xTVT+BEF9rHMjig?pA%-pdSEXQ`mm6+4w|%?ZobG6E&w6MH;Euv~6W9r_B#X4?XI1=dCe(&Rria}B< zX~VJF6m-|+9StmBqdt#4C%sfd!~ec{BpY;()3uFa(Tzk6>K*2gXa*bDGmj5W0R7ABWA0fU2uHl8ZpE zF;AK)Kk5!9<@93*G_L=>$-fc@Am2AilihOT&6Joi*t@KL(Y(XBZkWvK1W*`cFY< z&)4;&=izyOcUi>0@91i^bqPFAAw{=in5=v{|{lP-my$uhk|l!0Vx0vjffH%II3Yocm`=F7JCL24pd@#z0n$y z-W-BtkgIT24HMk*4%;l!)ZRPKa@7IQtcGIIx>7bj?!J1yY^SR8#`clVd8Mg_1P{-u zR+NRq(i2kR`Yx~cz*VJsrfR=Er4$H zt);eyLRlFy7mpg^OB5+I=`F(t_Djxbe0HlNQGU}mdi8t2b3sHpmM1`!M+WCklpvre zFsqomn*vUE3MqgQC7U7)IvESg#=D)#&}->^pB+3g^_+l*pS>*|pISs1?iY zrxz)LNZrfQhfUvPbw*QBE28j!-2azGFCmw^jSH=6X70`?I>~0FdQlAcWy{N$@5Jc(s-R7|q$*qv^3i-f4x~w5O$3pk(9*z z^3KpN%?S2GGtK3?f_?tnk~Q*OUX>y>rm}5E$zz98b=mD)f+MOjGIo>-V9{Pt0BFEq z)wgcv=$FkF5FuIrP-DtgcC8DmGljnlNm877pKc5_RiS!~ z`~Y$FgE-d|Q1!AE1pnI|V1Uu^Lm?kT6Ju8dKQ5$y7{4bjIlG1EA=-;OZGTH5HKtW4 zg+UHAq>N80zgC_fU=ry1LvoG3hZPd2jokI%h_frbvHX2bKlVNBFJ*tK^ajtq3+YN^ zIw4Q0H4?#JA6jT--tBY3SI1|sI5Ob4V6V`H@T4ITKDpl7Q1 zpyp3&k=rB7k*zw}clZZIeT_DJ$(YpOXb&n8TB0~?YTw4pka>>L^m?Jm{>b4Ci;hX* zLhM%~+x+2ClThud#}BQw{4)pFuE8H4X;i}7#MR^kGvOr%?yi9N#wGsx%dzL&qOXj+ zojvCVg=AjPO)HQ%sb32phnfuPn`l}osIO);VEx|;1aN15je7Q9GSRypJi5t0Oh4xq z&P!k@`tsj|^rwsdoV9=ZUkyZ}mrnBi{=;DOV<^(7LA!zjL3f{FY+7^5;b8Z-g7vKc zJ8Z{pw)9ZV-E3KZb-7dhW?ixqAgG1cc~xRh^8gEX%2DzWiGWmVF3e1G)@rFm45}pD zQD}%_qwU>#vr8p|_Ip8F0rsd?~m`7*H z2X92dKt>Na@0Meb=|R7}oP9KF!%?>p{A*PBq+p)C;^JrD-(S3v?j`p0ZK$F<2rWRu0|t(RP8_*% z6!QTvZ1zTtW70se1tc?xExLC^kDe6*vQYolttIm^YrfB__X=c=u4i&c0d`J67h13T zJEKTBuuU%`CNfB;tE5CMzSKE;ADA)k-ptI-cu-4lZE94ak^0P)l7LQ60B1n;D!a*qG&) zVe@rUt7ML`Osh#!;oI-lBOE3```3~tV|l*ZUxAgwuVVFAw_zjPd>qhd025LDU$hfN zlHLdNWCW$#!fi;R0g`2fWC)N55+!zDzGdmJd#jpuZv`8-ioZoWD{%vY8_?$)GLWEu{Zx_!h@Lq+2c$VIig^;kueccf*y3_O7O<`A{SD;u>;a7q() zRgd=ec<6ejw6hT}B2BbOeU@WSs?L$6xv|pg=+EBAPy48QF`4q1(YlMx{rrc#6`&Kw z-wocsjr@hfE{>T7;K}3XC*Hpy{AW5iAgMF-Z|&Y|k*=7y{CmID|4XUoICAQWpZ0?< zw>LaQ55+#FYQ}G9UFyOABNzQ{HxwUH9{+Ij5`ka6bh;Fy&ysz*-#ivm|Ck~}*WYJ_ z=LZG+u_ruf@4R}@nIGO>8IBcTDV(u*Nw1vGLcuzH=#S_zpX&^_Vgqk&Z?Dp84_L5G zakr?l`R>Sk{bN%Yu;D@U^_)i0**)G=yJ8G)Y_8R}0YdIx)+UuoXZrpTpnCY^Iibi@ zy7yexGlepz=bbt@CvN1WQK$+IEv0>U=CNkv(|6ewBFe&5joLH68W?fwz-m+r(Zf1_ zEVH;a57F|NOfS7?C7L0TtfIn)7xRba(=W9pm@4ityi|<6CuC$@E4A%#3i%S8Y1eo< zapC%Xw-PTNsR$+)n*9&M(*6%KSKf;9nc|e39#~#txW*#~3;HJR=*@%#C4L6{W5puk z@f*nk2Drzo+=~nPX=Vo5W8>~3NF*w!rv^-ch-9=Yz4xHoM1?W`F;wXHo(r|bZgW4n zc89J%zvxznRaui4(!?&i97LlC@W8)xA6BT$qnN z{wgM?UH_$=R6F!5NZs^Wkki-qM_@tub2>hBZ(p=vmZmXe3;CanJTU_8Aj6XCe%C(u zbf67x=pa`&6qv_+#(srsYa5g+YBvxoxM@S_NJq&;7hZhf3(4>C0H%et(aE7rg)Hz~ zi=XyZ0r^Sc?&}&|)74{UWS54BNO>6$^_Vl4cOSB*#6t?co9M51xH=OU3^7p0%Il)0cZF2gLc0>9r=o~(-bEt#vu&L1WY@Xj(nM-d9pRV%_5=uEq zp1Uw#Djip`a3C(m_dkF2zD}5noNG!Yq3J8^^iY_6s-%=6>>(eQ5jhtZ(8uM4KcmZY zs?}GO35>K3m0{?s6e1SFTK}h`@rXDvwK>O;TTozr>L3f4udZk%L$(oQ#< zH){KQ_&55Q0txl$H2j?8{mI2&+4v?-=zc4JI{k_3z?qeA&3dN|{xCKEw_N>eZ`A+b z(*Sw?*JKa;@bng-F8%#pSnl*6hJ6pRdF{~Ynd;{Mxt0q!baRZ2Sr25_junW{! zB{5VfNRdl70+eoR=z)Lev~?n8V2-C5|HPV+HVdZ@bxPRCmpD&m@xPMU!t8rP`eh@Z z3~yDbDYN|#N8~EL8&en2hn3HLcW(5``~nK9sMY*o%D%JxeU$@ne?h!oL_KnsIm=LAU6J={;|Q z-vh`du;`Zc4%}6k1n=&Afrc3PgSm_scSghlyZK~qFx~yM<9dxSb-)6$Tho@^MU-H~ zbhCS32d>YV-3TdWI(8;1Na5Qo9^$xsgK4(o`%UC#HO7e=ZEhePHbecSF)zR}|H1^M zeZ(@@0^_*kvUC8eMp0Z(I^?^ma~-~4^KTe{FB<$btyCqLz^~P=WFYjp>$4(l(KcG# z{l^B9vg)4NLb2$nWHz7h$H?Hb&yO1{zl0Yq;+6r7l%+FssF6-FiMs@}wzy1fc~jFg z||i-KG9ZTscxIGDlIPlu^eK&DE=VsX9R!RUckoO!bKbO zA!6j-M?T;Wt5Ym%O~Sf%6PF-X7@pr(ej}Pa^7PSK)7=^6`BD42O0x6bm8};*tIu~S zxw>r<%j4uy&O^ZR8c`N?wuxQFe0T{lXvh_;lyl(YGaR-HyUfo~}pTbBoz|2v6LrdRr#AuJPfXf{)INm{dbm%y4E*;iS#aB}vrH z`jF)}v=rZ1T7eGx5ObBKW9Pz+b(ykjG zgeHp>SyO8Hx4O|--1T$Ud1B%X8vcZu4f^YowyryXUHZl_;8H|N(=;~hbX5VPFgu^y zNZErM_{Bfpe+^$k_5rkg(g*nWe_B}HbQl{0+eG&$-9~SW5J;yhD=$9cNW3h+U2I{( zV4wEV>Pqv#M*kjXpSuVyWVp}#-FKU;8>Y6eJ?bM{_a|l}7aOkcVM?=1+IPMm410+; z&q6T6=5cnu=aX)d<-q*<(laXyZ;|D@`+KbOqcKris%XDZQrM-w8v!abNgre=O1Jv_^2yX2xCm#a`WGv%#+H^G6uWTU z2K}AACG4a8o)j|Gg=lqkmq0atjPUXz%ZaeS&-<_}=ML41g3JCWoq5|CFyuM}Dd%o> z#b0iAV7um*$Ny(P`2Vv1=ufx^&V(F_z zoe9Pz(x}fbmF)W`uJ6>fBpa&|Sm zZccNW(6TVk(w)@%Am7o0u`qlWRb!w{N_`HOx7Cg{NVaXL^Jx01RXlyMa)$JV!hHfg zfvn5mG5GFchsnGPJKJezS_(+A4A{zr(mlEyRi&`^$vPzRQE-m?MPJliW=$e+zbcM% zlAWak0_^17eD%vre}W(G-7p!x%-{hHGAOL!l2m4udxGNp1&U{n1Tgb;ZH%6Pc~R6Z zMtl2?Kxr&RpFxa*F6>%VHfpTb^V(#!DqYAEH?;`1UolA|W`3gUE+u%M-{--cM{$En z;J3cCevK;8v{ccc-5mj|`j${h)OzjP$DLJg)(@HH;x^xuaTUJ5Bbbgrj{?&e1ZW>X z+0;+BeV8P^e3CLSW8hSGban&x;B&}gVIw4EYpF=;r1C~{imejGe+dh%c6S}Ky*a2C zHGS0m$I@#!sV&mbL1puw)~Wgo_TL5j6OF!9R;@%ysLeDxGNK}8lA}ggMW}?#0a8k{ ze1E*UT?~`sJ;zJPmbyXI&7H$jut>ScaZA}e4~BORxlndJJ({j8&_;@=yXK>O$1a!x z(aINbzevt=j|$bfPk+#5{QdvM+gpc4x%L0TDk>HrjZ%UjAfLrj*|7Y6 z-)0gJkERd$oLN624tcH+21wr8AmkL1fZOaHl2Uh3y=N`&lZLT0J>2IC=Wmg8jk*R@ z!7y`f7Ark2<8~I72qFdB;Cx`H!hz_qNgqCWJpOuvEc5w8XfCsaKe-}LNAW~U_-W>m zL&uB0&O41zJ4ZgeO zuT?0-RLFln?PG1Dr@q8%y;Yqhz0C!A3)j4wid^D=rZj^_&Dc%Gw9}!GS z>MdzP3n(n^vdTyWS#lADqB2+n)=sF zyFz*{cn6|+;>(R>GGvLqgI?3;=pNgcnDpX|8vJ%9Qc4tQ8_QjVEXRcPL#69`j%6al zhDnE{*S~2sFy#6Ji^f<37`Q;85kbv_dC3-W1ojorGt`P~XOZVZhMY}+?6kXC({4r~1F4L)J6JOUhsgYT$AXs>2 zlQ@(pMb=!g&^ysU9I&1P=OU^tJ14Dp*8fG2qjKYffq`-vgSQChwNCDHj48<+!;Wtj zCg-pG40^aO-FDteg1hk36?x}mzPo*28o9xmgFr*FsopbyopEBRRRCI(8@l4PCY(_ z;VfAXp*J)h%pc>8V|^sSgEInITc0z}-e3OY`H&&1XF~jdHH+Q#>bHt!Fh-$R*Zc7t z@j0F&xw~Xe8)?u^---FxKTC`094HsgM#r`^-EN{0ws`?R`RPWzZ3^dn4^~os+YQ^f(8%bw) zrQqmT{K}MT_Y-g+(r;Y4<2mrV)3dn?Xg%%k7)KReh?Pq)>r0TJTr@q%-ar@$+fH#rio2nj zUQ8KPSe<;Yb>4JrwdjY#k%6Xl$XCP*=4jnZXyMvDdJiQi4ywXy1?kP4s-Q&$el1&( zM_;k2*g-3kpps3Ba0%VuzU#E=y)c;@EB<=cIbjPE5?59v^+PrlD%sZf;-y{!o$K@c z;|&aR0+pw4Q5q}@k{(|-maSz3f6cJC-egbcI&WZdHc;Sq2lhYQknj5*r`Xa)f6;zK zE4{v$K+1nvgJAkzZMM#Zd`rlchvO#kVJW_FdxCsna6Y0&j~EpSXA;JUrO#xpMHxKpUBlY7pxJRfpTVp(kp%V_;CQUZUY>Xr zQchGi$v1##E?+1guNA3xhYQyGPjeLkB()u}n7kEN?hBAgF0fJfh7}8{q;=&g&flp8NOn1V zLzxj6b0?DOIEv!gE&mhAa%fvOh+K zu*R77D=$aWT5HP6md73={@31suc_u&-5VT%d7H6omu&`vMa)Y!GHFtHuFq#&)+_1A zt@du;m?URW=x!7ngfVhbriqm1Wx?n!w(nLs`*u`LByMwJr+*)I`mb>>FD(@x)TAsI zrC;WXgdaLO{5_PGKduFM)f^3?qyAz*6`QkTn9JpC&yg*pjt#J`aSUuLK_^rS^vkn` zPBSD)5BG*Vxlg*eNcwwyIyubhE}>XcR-_$F#=G@n_HrUeP@nfoFRAo2IB?sW(!8o? z)}TZMIo5omnOphS=MD7tbLuIgTvL3VV0y|dT|?`8V}LnegB4^RRQ0>W^8k&fK-~)) zI8IjJcn*rEL!Jr#R9)Ff&`Cnu*_K$AA%Dt1>~hUjUH|&zOE(Cr4yfyFFO|MEwhA$l z-0)SaP6if&4603t4#hxD9a&(7`|SN)h&iFR@_xwfmp-G?@r1K!!FT2d$6Ta5bhN%A z^sz%SA8SYJMRYwAe!4wfXGJSy3G|Zou6*AfEHWb9NEDe;IP=Zz%M%s)o8pFuDeuE~ zo`0JkgM^oaJboWE9ihWestA)oLD+h|Gdg6aA3(3yKs6aHFl0|x1m(8M=~;RXk;6AX z7T3Hmpa3e%|$@;NW?o=tM)ZyrnnhN-C$9&-pS?l1Rwrh-f zDF_&)4RH5s@9VnQH=2ol&O~`GYSTz&!*+b$DNcjdcv#+8Ao+C3g_d7ahbg&0aVZBT zMAH}5e*4X0frXY@!oP+3*M4)Qi3+>40Vl}$`QN_=Hg#ZLBKwaY!6m4c6~O7(+tBZS z(kJ`FqB;+B+;^E*JX;|T{+ z?LbKwO;b0xywY$@!^ou{E+s(<4-=iMX1!ncuCGmW8eFg%6+`2U_pGyvaH>jq)SJKb z(T!}_6{HNDD2$<+{0<3j^u#&^lmZ<_)^Lx&Hc}MJ_d$HqlJY+M{y`$>;t%G&Ur z`!y6Q`n{d(*Uq|4nBF7uZh34ckrIPIto8?6T_=>+Fg=J$@MhoQ5yNz$%a3(EE2kJ9 ztXr%wj)kI<*M+0vn>B?* zmLC}bQS<3D-6=yRqI@g`#jm#;W;9CxjJP-|eBKVDb@GQPC-qbd>ymN)(HizwdA^8#D1PIqyX9Oh=CO%mYQzq}UYHTkQvO5vxdTC*^C3cuA921o>-gy4#--kW-M-Hu}$WLAZi;g-sD}Q1OykdhoYg%-89k&cz-9mo?Tt zqh(WRy|Tog@=BSg5Ah3CN~+D0R0{j>_OCC(1@Y(X0IU2GmjSG*~;{FBJF#>qamx2`Rl5RyThTceo(G&f!mKPn^_ zy8Mlq6xgQjd5Otps_#yE)7=bPuv5r9a(Avoquo&ztIX5!h27+bV1LrKFjDDVO8!>v zBo0$3jEYqV9}v1v6NCdfmb$xpgJ%Td&HnI>SoX3u>fCSoF(WL{<2cRi|3C_}g@16V zV0qptFnOh1q4P3)sWQ8EQt*R5P0+I8j=BvKO^aeHx$`9p@ARN7Jdf|=E~z5E`x3AA zBVNVj4)aI+fjlcaV)f-)4`KTpm6F|~$@^J)Dy@;KV2hp3f9t1cI@!`6@8#SEgNYVd zO@t?2$0Zq&yN34N+js)?-g<$u{1}A$RcRvXok z-yl8ks&zTB9AGHsgW*_CVmajbGPFKR>slX+B3FePb;z^q4+2=fHOvdD>mwFhz( z_m>IZp#aIkoyc8gnoP94iZ-v>jGe*eIhL5tM&jI~{?SK4Q%0KmFY>B)udMV=-{UF{ zKCjku3%_USwR401t(cJ+IX;sjyyx)M{sLxQ@i295H#Bsj$2QoC9P9Ws018iM1AA2% zK$?L#^MR6d#n%Q6*R%Y+U+y5|Ug05l`mDx%_tWXL7H4Z*jyA)ltWo%y$-l8!Y{c5w zm}X*CEexx{*}&He@54E|T2$bAC$0Z(umWcnThu!9q*~7cL!0#A2XAtM(Fq^%5~dOQ zi#`cCvYOB2=)z;dP|Xsvk>L>54chI5FioO+?JhBTC>SgY%K4@{RE2FE-dd}%@CXpM z-yB1O%{aaVcuOTCu8@9Y2D-M*P_B4OAzAO!SpQb4PQvXgA%kylZ@B9syflKx;Jn*IZet^0N8K>chQ`$=gD zmy3o1)&lh3QG(4}^7STD@PZ~&yYSmchyvx(zEDz%_BT3aZ13djo$5NEufXIjPC|C9ORdQkdkjvYiD+6h2{ZMi$oz{U z%_#{I3HxuH@!#m(0QVEeGQfhJ3@)nekCb9WBmsD5eSb1(Kus!>(TEL{HJ6xMP|4NO zkGk+oynZYbtOpVk30DK3_q>Ga~U9by;Tp>1(FKSq_3qUDvU85!nZIXIu zJ;`!bXO&|rHN8@9q+>EE#Zkq|K+%9sOPjF|v%HfKp$V^vgQf3LB&powncAozSvZ|GijK4kOUPHwh-=?@@N~=zD1}MZ+_kPxN}s*F)Be>Eve+ zKg8voZ!(g4k%xXX{e%z_@&B`tVBs=zSJKuyHFTo}ipCy;+{haIzRoV|t`^B)<}!Qg zG6o0R=5edK(iIfEe=vAhJIe#UVKCfG7n5WQ0^rz@M_LGptu`ILmi~IS{5s}{>vWOy z9VM^ub#8kLzMY9}xo0) z|ETh7zq4f#j9&Az5x4rcnJp%s!qqk*f1YqbN9?V1O}-ku9Y_`PsHtKfxVD6=FeN>8+IjJRlT$fA0mqndbQ&4LFdC`Wf$k zhb5ZLs*|Xw`82xK+Tso!U zS3bqKC|)s*jfzW|Y|^o-<@FSwYiCoLr`F>VAgEXkFL;KA7NTD>X3P0^_=6$)jFHE8Wv?peNk5`mu?Tdv4QlZxVwTyy21IY6*1 zd~NUh0m4-j1~{Mkds`$+X}p)nx)kPGW^y6C0KYPRf{aPNt7YC2lP}TiL8|AHRGRGv zWvwWJ=3|(ZE1P_G|Kghd@9RXz7vddu^z_h9rK{xO;}y z;XqJ)DuU+wWZc=WeudW=0Ia<{f@^PcPS5_}uzOQ?3%H_SuZ`!^^UwZpK6>F}BB*!t z)2IZ*&+#|vY`ugM^zQtG-%bJ-M@)`rOLhDZN#^zR{**8R2%^N#V%r*QR#^OEBh-~H7h_W;@O9;<}RTu)xyp8;5+LEyjvqnJULjx6^0+S*OIT zycNEyETMhFatsI?O4wiPp#uSwOzd%FMV$;t4yXEVZJH;B~a0h-AHNfN0DD z)t9zMv$LfX1c@@dQsR@>ZhpF>^^mB{U_pbabB3S2tZMyf^(1PLzp3PK$Fqf}(#1uDVkZhh#N732{>S=JPR3NB*jIXr!saFeXvs64D_2AIht9PGh6YDtrnCg1; zfSkOfBi^YGq*yQyJB-dn5p)B8af~-OYSs6<#mht+Y1t4dwtaU$=fGk|7=7s?^L6wW z{ocY#oHR%XikA<`Xc~{~GZX9(?S!BAA(DJ5J%irUQVFR+LEc8D%OqxDzL-@LiSlt? z&hza`#^{sESPp3GeRH{(2JTAd;&d2ISKH;qbVi#paYmuO^)0N|(Ihd7+PvEpYF^*` z7GNZ#MW5&xDEuT|Bp_FLRA{N^@0}XcI1v-?yAF=nae>;B*u{om%faKoITog9X+d^~ zyP)~^8j21luEz!T2 zJA}_M6jD+6Ejgagf^#YHu!1tW$pU8@n{8D4zeCZm;eY$0R*MWh@6x;c# z$PYHCANOwV+C1uh_+0#ZmCi&iX+YC@l+^Yc{B)2p_XSfA2|DP*EG}vCAUOuJO{)bL zB}!?sJ|D6ae5vp`SAu@Q*g=G@SwIyZUSj(;B{5~+(G&CN;3eYhrXE z?|{|#z6Dvr3u7_mx}Rjybw1U?H+lPuGj0+v=!J!_|D^Ovy0!72`9&+?6Y4;;OXo1y zmxQ5x8kVS;RxMw?l{50Vhx1m!+v^+CdP+0Q=eQ-2p$W%8i^WOKeTS@ws9EDMO-$Hs2l08|Yb6S>n z|4z&Mr7sxyT(bCE_;!3D!{(W?r=Y)gNsf&!9Q{$|{Su*m9k05)S9$C6*39w^gMXs^ zkAby68Y}Eie_}BHB{~2aEUO1Kw{i|Jp`2p9d@rAQD2{7TLs!LQq-&P+3bB99?<#=J z(cl$-OQ$ZOA!PMh*&(ziLm}K4Bfe3SqOfbD>&4^~;;{c<)eolY9BXR$`-1i%#=Wh~eH-8|l~)5M z3==lL2bkN4J@oB1m%nxTD@Y_*MB&ID!90d5?`08B4}jn~&dg-tsXQ^tl#iVqL(g4C z4`dmiweI?-G&p2SV%9I9dOckEMor>66F3Rbw2;@k!Ik(H1#Yz{k!7zN)2P;a(YHtXS0Rn}BF~NAZ$f1K#P;Sw0J!3k!2E;|l}N8V0Ke=ymw5 z%VNx#GPc|7hX4-Ny6E@J{NCkH`z=y8tDp?t28RB&{su996w-qxhS|N>zs^wRiy+Rr zR@?PY?1)Jc9(CB})xGr_9J|V}|Ne7vXSc;m5{_ADN~x|N2AlaPeX>2+zg$tKYdT*y z$uwk|5su$;C#AUgfuv=C!a!*8#6C!$hg%E5ijazfh}n;+Io@BcQrkq1_9#5>(WUd! z{fwb$Zo6qT-(j@lMUxb}JkH~|beJ>9H<0W_z95lic5XAeIHxs{82o3!Th+f=QgppZq zczPH&?5M*oM1NAXC~~IJkPp{M8(hAA+Gw`1!piZ?}+3zy^0m=gm0GGx%-c7rN z%9K-cI)L$U1!1iJJP2%7+ZS?Zqn)*t z{X{W1`XheC#;olr=_z%t3P-C3zWxp4w)0M8uoNXb`A216t-_09Dh{I^{=-i-gnvF2 z4ig^A<19YolrI5G!UhNpnJ!ps#OZ6KzwCp)32?&rDZB|1iJYHfqjBZR6w)w6;4vGv z(q#(fX4S!3oe>moxp&v6$HDi4Ww>hAd3A^CflY36C8Q(IC2B=@T7sJ8I=NErZos=e zTK5Nn^~L{@V05hF|DIB}_kjnf)&9=lkF|rZxsfU*?RRpyojtTTJQ6^W|BK%i1{`=h z{;2( zZ466Ekb}2)5wg5gV|wBgMwej_U-u5XtB1P~` zmVxYwWkW=1*0^g1W=@OF8e)M!<5{z>6A(KJSIw@hq5_xtPK7$9@O#3UcbnQ=b!f28 z$iweT%A0Sk;cmf+1mvj;qXMW~9WSF?GE?dOF zY}DcCv;RN-WDLlPPQ)Wia-SZ3>yfYNMQEp~uZD)7uDCYAuU-*V5o2;HG#oPbU8;nq+$*rCk(0K#9yp)^{ zjKc-fYVnA8_3rb+^v}Z&$-KN~&V#U0uuQ)neI!Km7b)wn)hAyxPG}OVA|=4yR&4>> z4{#-a&n74e;#w5{MrK|~Wgs1b$xv}(m(4*!u)&9mxwI&jA#vsDL^A7r*DbqmrrM3q zv4K7k(i0)6x8mjR3Y9FAVlg2J|D=fsBZ-S;^+p`^>Q))XD>VksINNHav)f)mP6U0lf10`U~c#drW zo7!cp!t_Y<^4bIL%p$N0N}pyNAi1T7!7Ej~R!`g&B50b1hbTd7zk9wgKj$8kt~pPT zK~HCQOOGKS#AoN{LUPH8VY%VSD5Ck(9UQN_$V2!r8E5{Sa0MiAIPD%Vh5Zp{{Z9XU z9u!GWXDvGPwW#wY{>;fjc`6ONS4kK{+YGqzQF=4dkrx@jje4`oomjTxwPAaZKPKoqKDv&Bp^FHXE>M2j0Q}3hUs#2w`l2zLU zZ@yZM=nu_)UFD}O5fCT%E=acgu=9gB?#HC*-^O1=$KK__zjHv5!J7B1EA&;R0%wM9 zC{PD^)rqxj7p_>g9kXEA3@;EB=Sl}`-!!ePJ1zFqL_IB0nTx9N5~!O>IH{Dp$ngds zjYW`&bq+8+#?#TIjvg3<@!yz_W(vAqWbV(VlQUGW|I3)nxoS3{)>PM{&+%bmnsiuF zv#Id-q|dz!LUe3R>< zcx>0TvWKv#|76#d8oTl;LqjHjgG;AE7u=6Lu5IF)0lXue( zz7vrty33p1EPO!QhFL+!hBU9q8@n7p{Z?nmJ+IFvI6}WE>X0X4#xU z#0!Bkgdd<hYt&U>C4K&K(>$*|rhnT0IE46LT+e1F6;WLc;h;3ye$e2gyB}>q7<1 zAPi{FXrYD9szqmGrt%nn#uW&JGl(mj4hX|HQ(%46T|w?e-20 zZ>6MhDjGEp=Xj*sp3?dFl||bmO}oPXjZEhdKcQdo7fmJxC&EsgQCz_cW8k#~N8!G& zx#{HTO@1PkB(hXv;j^vDI=G-IAbn0efi-AOSYzZlsVIVQc#D7#oS>2+ILu#f4-hA0 zmtXa(IduJ5VpQsq+oAXyBFB1sUr0e8Y?8^!j}$N2j2#{ux8j|j^+GkiBc7Kz!0_K+ z0-?@>Y+RjE`Q*yc9feg?>AO=fi{P0oP^~r5Q|wP3gimS_p|*a`4)c-7xFzYxGrl}; zZQHho@ux0O=rS$jh-lJuy0B#;>r9}YTZ&RmAjat}-9@5e_u8Z&)9NUteeJqo=z6nR zb_C*O4d5!Uogc?)`keL1F8@)n+uaBG0+aB`Dc|_Q#z+fbV+=IHUj*eJbBze5Q*7&k9?LL18Q9jb&`g!A_1V1c; zjtz2oK)e}y5P#;+G!KV;HHi9AVLTrW(q{d_G@sD2@?5L%nVGI~n}E0+W&AchtmVZ! zC>vL*IPrpS@HuSY54HkGD&E0*rTK-=_-fb^kD83PpI~&pF$B|WhY$*Tz8Z6DefK_( zm(u5PY9Cb;1AcVQ-EfHDvviAo#&&y`R!97~M%5ysD~bN4eO>&rtq`@1xJIqT+ki>md7TnIgGmCE4si4!Ia)ksKY_9OxK%zNSfTC4Q%q{$!aYy z%Nl1Q@^edFhay~|Am{MJp@Kc1dslfb`i;sdmg$V`X&RgxO}w@n88@GkEMsR7V`|!^ zacS?B9hEt0@{27u>JS9MJp2RDrQHv`Nyor(+ z{U+07#?njiGUO3}vHntDRS`XqDR%NGgP-+5x!^SLW}+|rp>j6H5~WnlvLUHkA>wv| zM|G=kEN$)nWYAZ#epHnCFl&8AKH26g+N+8(z?ATxm4iv)g1b7zR5OOONPi(g)!*58 zaZ|R~C$ob-rw-fnqPb$$ksBJ98bHv%!u`13FG3hMG!yGU>$$8hM^1Ft-|Q_pHW|(p zs(v;h#Djw*<(U#1gu_)FN~0&n?_b^q>9=8X_a4t6FpZhLF+>;m48Lw8^bQvHbFNsga z2O@D=Q_(SK!2bv0cz&cer&JBe8526K{%9$Rwp3#$YV2UYZah7<;@TM9ztlV9M6Hib)1crh>I0cucgNu`yJ4~Yxy6OxtmrZ3}h zdDr(`govP$7M&13tBrz@Fng>ACSJf*O~f6h!Um zLlFy8H|swWo5xXLsBX{>@hVIib~Or5e7KCf(2z+R7*dG``wT63VJ>Yf6Q*#fxlt@~ zLMuB+q4c3Ucn2;e92C#U#4#d|eoQ@|EbBFRoX)iNWSGs}g<1nBaAld)?MgL5_z{w-+1k?*x~(*R`dcxLAlO|<^G$kc4Dm2bmbRMXsn3kW zABv+NVs*bZeE7xOM|+oO(iJE6s!18pEi+H`CQ2rMEdB#3y2tpfoSA-CA%ARyyalWH zB^#N{6qYLs^PK^+4_vZXj93Qw0gL-{VP<^C%D#v+sNR6aIS*BVfX#6|-Xe*=iH?ZU ztP*`N^%5!`R{Lq|?JO;D3~Tq)sb+BRshHR-WzUOlg6&G~I_6IDrl6)Qa<~G6zsVRw z{!shRrd5U|!~cH>kGQwLWMCJ}J4$_?BXBF%R{xKZ3adyxNsrjH0O#oWY;}jxunGbH zO09Dz28(%FC@J#&=EHs5f=jv6L%B@WpHQN&C$?7BZX;0ZmRquT(ULOcS#?i_qk7h* zOIB$ys456ZD2?nmB@@JBzQTCnKzFhFb?m%z>88%MBiI8U*Mnn;&TM;=C)Jfrd)cE8 zwP2dOJi<962%&zt6WZvo4aV9B-f|Od`G!t9dvq_ExsG5*yr31OG4YA&sd*ZYgW zp6_Shk#6mqAAjUc z5a1m=5IS3pq-n{9`rFx@YH0{)^4Gs#949;9+t6dZ$dy^A1uS!h+T&=C>`-JX3pR93 z6C2ii0^ElX+8Z%7aW9c=AI`NF$iKg67QMh`!{5O{B&dogTP67VtGKILoQCL|2HIgd z;!@0KDWkL(Rf(G{p4(y&nOIHg^Z;`T`X*K1$BV6U-?L+*onR|-d6YfZ7H<;Fr`-t@ zSEi%nPwCl*$8BRe%xUfYvnTs4w6W{L8tTSmpOi|!^;ccuRFCq9>?=Fs{rOx^3>Or@ zaPb}73v+#N?gM~iB*h;L0PjijkP|a;%{Z{n!Tx0?9t|PSSEUnRJF7I&K-)uCfiM!< z7{A|^%E7{fFAg71tk&VXC{Pl_h#1ZYBqtaqO07WBczP``GALB`jWy`c%Sz33{qy)t zgiQy=WZ#nls|EX5<66D(`UcqT3w*$>OJ$awvt+4$f-Zp!T-$?#Z~FbPiX^IL_0|01C%Dy;5Y|=e(|=l>vLkt+Tuw%}r7GO%M!do^m-*^2gfmHnr4No!+VD zpJ^?jX2Bl!^^sBKy*#6rI1hsZqoQVxOJk_tz#QobdfSOi7Vb=cN=VK_x7w<74s-U< zy{Ja^j*^Wu>X+Uq{hxl} zGEXfQs26x{Z8@(-U)(nq`1ob0&zC5mE7><(ztwXaH{2F7%c|}-jfrxVC`UeX(}ebf z+ss>6lX`9&LSW}L(CrFkr7A%zTbTL^yoIk^kNHx>KCE`Le(~4nXr|NBtivXQ^KjMe zI!tbPP>uDBC+-Tq=YCT%=sl}PJ-R}P zouegPRNda%#@2(`;fCu==YRi!f5*z9%hK~vOU{Z}pvCcGNOhdL0bMD!;U$f-##_@{ zsTy07$b5J@Q#dXB?SXS8$r)dgZ@wG8!e|=kFsK<3j91-c)Nu3N&*{hsIC^)eh23pW zrAl7s{XjGOV;R?a)dfNR*TTUp7N(hcQeZ1|kW7FsYx{)l{Ms%3!O*?Fw>2#C0=RX) zeq=}%qwLOJR|$%vAKn&1L0+%9$V2G>?@r&IXA?bp|G{Mg&w9_l7D0`sq1SfHuDyna z@*U#r8u!d*!a9P_`VNda0?&2d*u>r%M^2|@!O$t^i{Oa$B);5^(pfko7$vgt0S@j5 zAKb_G_8WO|8&KxAN7wA^J}5xZZ*o-g73QAut`Oc${%JM2wE{9^x4xqu%MLUxPY-bg zy6Jh(HKN{GMcpn7{h`e&o?uLnZ}~r$4j4CLO9wO;&?=O@O+8iu*}}&2a&)I-tUNJy zGipX!r;KM_y!_XL0x?0e|MrGCAXu{Fb%S}uFwa{aWL;s7e zyu~Sa+VGiCT0Osx_m^X{)BEI@UbD5TU1~8u{kFwg{+h zCq*(%c08$eHf<*Qj0W1#auM%CpPg|>s1XuX(CDQ^NG8Sv)%;qm{$1>q0Dwy87+r3~ z-1=d}-Lja4Smj(W)}?N;?7H6ZEgI-W8_xG7=hZ|cc&p%W_>Sy8)pgb%@wzvNXHWTx z(;e)%z-ql=KE`M0>MneO_fPUZ)3?sc^M+u2i1JN7Z3qWpCxR*J6lyzNifs>ac0J-6 z!E6IYO$z^$2e9|RR0xL>83n$SdqqXPHb;4T_1X!ZWCTsOz95h{I+$%Zjz4NXxD?AO z!}d|-$Sl!@7Q@)T*fcpkjd8%b*|6Pg9mh282O8Kx?mq97Q>&qfF8S2I-c*1kAy_P} zVE}#5-Mz``t^utmZpN4N7*K7d6C!WO9wP6Ie{osg5bvF`r7egfRR{7aA8P*z>&%SuD(ry&V5MMkpHA zPyeF|Mdd~-_I25yZagX#Y(zb!Kx8U9Y}^r|Ikp&UoPyR zA9M$p$=b)dQ#LivJ7Ozie8=at z)lRl?tFyY?QtQ*S*FY<4HNPv4(T6?PQiXNr^>q;qeBRp@IykKt?>;=q7JoOK#&_U` z0qIRsEyi_6Cv~^#1RG9eCd#8X9i?bO0G=KKT`9O-@`%J2hr`6?IqG)Dy?)n^kP*6r&R^xOh_`NV3f8ZjRgf8~h zEC(H->D>KM9O}Mn;b}H)pRO7S>O2KefD8e0g8A+sixU?BP>~%J-^^$`9AI&|dSR)B zc=OeZlX(~FU2XMg(`_QLy#xjSY~TP}`DbpV`v3Lf{-J9@nnlIqGimB z@>iGGfBgslK`vl__y2`75R5O*D^iaeY@Hxj{oo~}3B~!u1VHmI#m-1J_Ziw#KuS32kf|KB8gP53^ zCK$mZ6^U>`ppLc3TdCcGMD3TtwIc~?;#Vlu6jo+dXyq2Air;=?zAtkY}0BRA;6jiOW`4C*w>B1mHyH~)FDY*1Xk{)!FX3sDIjCtm=aabFL_b1r+i`6+0U?OLxJ zjq&qEeXM!BA*tZ&m+0d^q6`)m7?qDt@bX3$Zs)hbvGaeg7&KK;KeN$Zsr3E@J>hzx z1|0^}z-Vbte}BGD%U{Tz4krC~7qB`tXvk}qtt=5N*G}~(7l~H4^&+vkn7@~Y0@a@N zlbu1fwC~so@hVdW@)Yq08}WyaJLByNHyy7VOKW*&b$}iN!6OK-b*BOOMX|Wej%OV) ztl^j$%){y?pGO<~RIpYI{@;r{87%`(G@YLc4p_P`2QfD|lg1?eGg-b|e%B&-v*_W& zGMz7VlOn1;cm0@8n4-*~di0Z(?G3JXR2vR~*Q^>UV2!FHX#}=pg~;smSnG*%%h= z!(`=NKxO&bwDDAi-;L@cMb(O$0jyS;-E^FUnum0#ejfX&B9PO#|RONr#@qe*SkHwPDXDdmd#~2jUpvk(- zr&9Ase$=0Pa;NQF3ovTH`ah$s#PB(}T{?z$U!DbmA^1r=!9{Il%I~lKewN3MI^Az9 zski|q!ozu2I?BG2&A-ek_Hm_<;No4(h2~-m6snpd?3gR@8BgX36#9`-c~339-rucI zSX|pV{RuV^$x07R^K|~>!ZjVRCb`z^xrqRt7{~V4*w$dj zNB*Z50ZdYSrbZ4IgU>u`*CEjw3@#opiE{jBK{J)1ni-Zx`%Mcs!v+nPg}}pmG`Tw0 zC~dwM>nD(^_DvnW~PYiSa<+9km^6#Xj{}>P0A6^3l z;+GI;rTqHeRh9Z-YuR6r)(nC=w6B`Rt=yB-i+Aupp#KNX;=pcixluWuteO$SE9|G~4RS$2Lybb`>VlS54;->7oRTm8i3)k#4&+(B1-Vhe+zr$@%&14&QvYZ_`!7Xs)oOsT%% za#=&A%$|_fKZW8=;uU}OmTmgRZOlfJ=^gBCrP_bp`?&qyxe@?hk6Zj710Cs}Xj;zE zh4iV|%%q~`u8~!3!J^Xc^>Em-Ct3ITHZ|;!z=r$(84^|H^LU2Sa_l-1o}JM`0-eiFj=<{=!?2}#J}&QJFn zyb;LuG#moJrp5Epa1rw5_NdZumwjk8`{cGK#1iTyM{Pz90z$ZrxdIJM272Wood+>0 z5~<6PF4WJKKy0viFCE4EbETiSc(Spy{_lGE8)01@qe54L63o*RRUj+DO}p+1pJyLU z_x5OcKQCWy#o5)14~;_wPS^q*Sp6VwTF)xLqLF${}3`Aj6fZFy2>=a5w#Xv&u%UJ{UJHao zx0x#N*k$q7C3f(UivPl>`Wf?e1a#iE%GGBFMT34%u)+G_!H45-Ql7cXb5lF)`v{IVAyT*Nb&lJ z!Z9-8pceJ=LM6_^pyH>x-gzL$ok@EZ(E31vgu5|Cxr(m3zHd`QB2-E9B*VHP0iUN8Tv+aPi4DoJwW&TX|~3jmO2!#Z$09+c-NX)M`rDS z`MLm-w83Llg=L9D4!d^YYOszK+s@!R8YLm+<<>qI;dtzYgkau$)g0nn7{LmL0ce}) z;V8M{=8Cg-&+Dv7H6C0~w!hK02&sPM$=iQ@b3iWj_-F4kHSagx6JlA1O>@?RC5jeX zmw22xmQsq@S2B`ZPwA)?=JQhB&d`xkW~nNta?JCOd{>iH)UWCgaP0qF1u5CZ5sY_t zjl$N`Yb_a)#G?Ax#wAp1RR=GyyGPApPOc*&DU;Ks82*6|x%a#doH_`4o6cB(s#LGg z;#)ktt>3`{@x`y<7+9Uke5Xy)e~~={Zxap?$I90Ce%&u{9U$NH9I%6(-6x(bCK?x1>dtUfKU$gSu^rs+Q2QvC>kN2MZ5|n~?sZABS zP0mu|p(XiND{k(X#FTdc2+Gj7!B}Y>>gpLx>Lv)69OUe?Np;QsU+d)Gk{tZmo$@26AK=GR4E(}x`#Kd^%%+sVA3O^)f3{H<%0 zBymak*c-;aSmDq786q=~OS+@~gs_~;Rn^Dt)G^~AA?ebr=gr$6C90DuSwW>|RMp964IU^SaC5!_Zj2w+hqaSqNcOjip%U5=2=Gw$O2IX8Xcmh zp91z?F1B$)l)840n4V4tClw@06!O`xPAD>6I*P$jPvEFl7|p8#U)kdpn}3>&znoe| z1kPle8>GPj^Oj_5>JdP!Zm!pn>lPa|u_WuSiEaQC=v~^cE#ZYiMf!SD8E<*#qpXE1 z>f^61M}1$4(zN>Bd=21>`zG7*^qjPBniR{rlvt>5_Y1k8?*17ikmRb!f&G}?DS)Zn zcG0T1B4*bt>8hE)0o`{@n$pdh)&|fHM;HWjv-tF7AhB70-xdeu(?D*nO!Sj`x?ePn z)%t))phcqGTC@#Zt+cjZ?>em0hc0MyMEa2!=%c}DzHDIMO^I3O6kR+KyC+lxyX3sL z3^2c2%*pKMuBHxhvgeJ^Pg&NW9P7@5jA5)a_=NPfU-S#|VH#q8c_b&p-7egt)x<*r zb(cumg~4Z_;;eEvNvLgQt=zgg&-Gi%2Be_2F~p94(G!2?10HwVTRfg+`8{E5L-V(E zCAJD*-!xmh#3H5gWqj8O(OEj8v_}$Vy)fS}K)+g$fQNXtnlc`$kfyNWey|{FV-#`Q zB`|6_2s0YzSYuw)+6#8d2VlN=^mv+wm{5@?H3TPF%_S9x6a&BjfZ%n&-wUaV- zG>iMA6)H$n07{Y4*4iEJidY&4>CmCT20yXDZy((~4zk6u9mqmEjRhSeqHHaNQg<3Q z3>Y2-mQkEvi`XM2>T;d1qvcNOTYa{tT@?DMZbQHAMeBR;8b8lE6ImCmkd`$&ez0~! z005jRHHBmhD;ZmDW&U3w>+A2!Z~yt0r2u0h+YqI<_gX8WNYDFqoTZ&x@m0r}X{~y& zWW+{BwL`cDak6z$7F80JrkGanB~Dj)^WyskSh(-_#pMObAF0!rlxSWBaf~3Nh%)cn z8H|u7mu*+{QZl{2Ll2t_<(}GUr&Z2ww{Y^|g4HY5%iXqjJLJ^esi10-rWk~I&G}%e z_VS0x1T-ll`9Jylzm8V_d7j6Y5T0*3j|i@II#=jP8k^Ys(0yoDk0yV9_1j$X7jpR&IxR;5B09sx(3jFq#{+G*EAusm`bqR zg6q~~F^zKas{L4d?9GVfjemFoJo6;D@I*JI?_P!5BUE#i8>!$EFJ)a%qDy+|PD=wDsarOGJdSixn~LvUo)H00{BO zUufBClk`~LOnCk0G5+aOcDjjWGT8s2FCeI`BwCN5_ox0YLcrcjs-pJGz1K#il>ax| zHr?dcMkN_qZ+VEc7$McXtX%x6&=$4blxtcXvv6*Il4{pMB1EzI*TZ z-!blQjHRpBbh_4j=Nr%S#5ZkirnOAxa>&g&3Voc)QLoZB!jvfj)U5#`2jY0dw8L4; zIrubn4_T4U3q~XO*09|NoQ!8Jw7`4&SC+p1Xp4@uc$=|@IQTbHS5&yvFj6#rA05hx<#c&5Bp@W zd`Z8+6za*^oIa*Z&e7^KFVx2DGpPI(S10Xj5mu^Ee6RY>_OEw)1ZNbIjM)Mc^5l>C zL+GQwzRp!Co4mDL6h)nsy^Y0u*Qe8ttdYdtj6v7&T%8 zu$O!a(_{vU0134IXGk2PiLxth(lqLmg|~Ho=rbJ#&dWTBRcfn~q*>{Y-vE$|($~+I zf9ISEW?)l5i%hiT0)2o2XqA>paN;k%r7ij`K0s|;4g$f;YlyqO(LwG)g-2EXGUi&) zldu!ysaR_KlL;~X#$Iv&+OO(?J7CIN=ijZMqcA5*HPXL<5@HNh5|cGJ^JO9U9?U&L zwO`h1P+^*cr(60rLkG~La>pg7w)fp9#}v!q-!C;_cnzZVhKVrI zMw%?X`4Ki`m)0CgBeBGS>eP-*-4DWArbaGrOepr*u{QjfVuhV92VV{c&U$(If-5C= zyhx^o+~7AUci$SIzc^g9i4txMZTg~kFK|hCf5f|Ux^wtHn*&VYOQHWUNd7aS0PZvY z4ATR^3n0fB8J&%!{{)XcPyYW#E3fXo>g9FPEu-zLOa z0>9cLyP*-sYD#$_%De!+zCSqR=TW-yd6bR?Mrkn|54h62D(M1C;(}e+M8`fKt9!xs zL+6G7JoSZu+uWsTNW4Cl9h`QV#_wURk+5b7!sSkACbjqUVwXjwE;P@+uf>12toklL z?xK&<@*dD5eD)yDlG3#)#@7iW?JZi_xYw-6>P-zWQvm;t%OyO-Zu-YPC8|?Nr*&QlW1TCuKaN9wI!zq(<_v$I zYb@)x8=i#zdRg0LmBhb$2;lB!N4YMR&2)$uDF9g9HAmlR9G)dNIlK>GnV%e8rKgaJ z$^N7zW4jL5lej%^lkO!9NSSr2L6y}9{~+v9F~)vsfE^8YrC+8|vgo>Xux>@}AKQrc zEjZp~(W>iyu1osWZcg!yFAh79BWQ@2LUZO#@WiK+GS^p))A}mu3J!n-a&5}*Koo#7 z)1b(1$Z@1LV;!mrI-Gv@qh@kO3tRqgrx+OK+uO@1+--NRe>!1O|%t$Vw(935y8+m zB%Az1^hfVpynJor(Luw%1kx_e9-2KRH6yy|28RassQ$xq2qXxXziCc&E)9N@S+^u4 zuKC*CmG19p)Nl9$M-3$p$us=nVgOzQE4M;pkEw-oGB^gA6@2{T^-zop&Qm6vkpCYw z1lb$~+{=F?vElpvB(WQ{1rxUjm5BX!$Ar`fGU6)gn;Xdgw6uH0b%g+;6B-%W8gFmN zx>X}|(Rz(ns<&dkI^Z8sDGsP^xsVCR@p3rs27;xULlDSSvZZq8dyI^~H6;P@1YDT= z%K_Rc%Vg6+rxwMCl%4?JGu1mh@pNUPBO!8?sQp z=<9ZVS0IzE@oS$)iUdu?Z7y;{{wEvOCCbO!!2OISbsn(D-_wN=1vd2PdO=7O^%f`s&9Yueb z3SF^EKrY83nHM7Q5C15hVu&crJ`L+pWp{aOf=c#G-Oye4w*q;dxzj$D54Ci#H&L{k z{aQVUms}2M<(ID{=Q1-vOCpR$zF~1y+H-qRbGve#krr%&Gd^I3In+ae7ig~24WLwDw_n?Z-HZt3!&Vid4APS-2k5g|A$z=!AP8;> ziP2ZM!Ddt^j?f~GoGW@*yQ5WA-kJNE9UIMH!(>L5h66YHPaX^%*^u?s+2{J!8F$Mn zv?B*V^6MKzbwc>(R2SQ?u*YkWJ+s9NLB-t)Kt`L!S~BO&3EuQ-b@9rg2SmPijdsYw zE_R@1(?j3!iCPy%chS7VB48HFX*Hc51(PaSX(w7!qITDV;ePda$H4-M<IT z-#XQIrsSM$){6!@4?e6VAQ#G=b$iQf{>{(%7qj``bCP0ee&{M2V5*VsB2*i{T7&CO zY@z!27soj;pilOGjj2d43*2rMdq+uv$z`4C2~-6+P1$?(wFvGlmsA-cAGFO~50A+K zHK#(`%)G6NxxGTT+cRF=Sm8h4l>OtefJ;EI;ZyO5-`w#WV%mGjO~{J?dYM5K-cK#( zw1qAwfoqC*cGH{y4&!>b=W7RaYT?V9!QZG`{D{1}Q z+@fSIhgG@>hYeUCs~lbcITOz=hTrXu9zftsot>iWN|bcuSDzBmW8gP!_Ycxn>b%$K zC=_3Z5I7uxT6szkR)kCc8v-$aHrOu)u8?Kl2!I+91?#jqTtt<3-f*@Z0U;XHz?3%%+U@?S~o|t2H5`H zpD%I}`;KPHPOrJgpYzsjsL7>)bF#)bO3%6KZJ|k?+>j@g6v7V0w4V!b--%J)f7b0k zm9@_I>;uBO5xLcSk5@{Fxv_E$kEmH41!WSJ(eMT%P1jSE(w_$pCZ$ZLU+DWN-wcDo zv7;MhL{%`O#BGr8R1Fh<*DmdTv3G_hOsO^nr!$tv|aaY{4p509Lk6KR?UT`p|L+T z#{L5<1%7U);i9SP?_ooJzB$TTq7@I5U@jbfHVH&2b;b!jnW4Q=eC8b2EhGBm zxSK1WN6-JPwf0gCrH~qu^7&15_c~Sl$%|?J7wE43S$hu5;+SXm!Hum<;oqAEKv4lU zi`<=qpVK=imllmN!**D?wk=D87mib_(+(AS62I6A*2ws6%_26eI)%f39QZu5k>>(0 z;tB7!PWw$alI0kry)5XD8|vgMpeh**nrL#341-MTzd?7SxA9*cOF7CXU6O!N1}K)5 z9%X;HImZuf5*JoJD!Ha|uhI74oeT+-QCB|M#{_7Y)0%1iNdht7o`HN+W;}mk_)+JG z*}b3sxm1akrG}FO0$`+2VC;N_+#4K-@xDSeyqgqey%iAXP%C&M!XBSi_1lh04@w-uUmmI2;D!VKpZ-$e)DG`^VEn4W*mGw&fi?3z#>ztP5jz(4;fcyin)+hkhnu_zxYfbwsP)P4+ z?-yMNm047X>KPvp67PDr*0lL8qVQOB zWZJUsTiVK4k?NmzlFQ$!qFA@3(r18J-^Y?1?!Q$8u@MnZX@Vh;u`&P#95KZhVUZTCQs|PF9 zvNRkI3m}ny7tzZ7Wix(?DAzuhR#}+K6!>>RS_NHCX~K_HV|% zW_+||poHKIC_sOabc4Bf>Zcv~%PU!3B1j#u2LRB)uBp3j;yB)1(uwU*aRw(9R>Ei% zd~m9H{C00q`$C^o+RrSo$hhu6(pIgZM7S3!+gnsd1257E-B4;jil%GI6E^O7cK4}k zIuz{iY^Brwu23a)WP4GDbCi{7p)akff|szP0_2{#h4fbQLv*Ri=$X>1Eo`_8!31(B zSA#2U#a2cexRXPlLw&A)>Y-V}2$1Wgrx|Fy1FCpe0a%Ef!Pv)?FypHcTuPBi`2+sYWaWnZeGZM@5^ve`Gn17r zm$f*Z7+c3K;FU*YXhd@A0RS~G@lyNadj+)?=_J#2e`W8+0|o9+qfNO{AFvJ_^V5q| zAGlrC9wR07*tF`5?N5M|Ef?HhfQ%oa)?(Z|g3st}o{CHBW5-lSmrr`#aU&IS-7@}b z6KOFEmNWSX_1qN|et&Qn`LNL}RcULp+%t>I(H}gMnm+EfimDb35Z&&lyr$t4LYTEX zDgV6ZQF6XE7Fqudkgsr0`DVX19LjzGFj!usKTFG%ZZd!VHmGV`joA#<)ILP|Q?6e- z&Pr1xUAp<>5B>Q=#x>%hN~9Os*FS<5IEvyYQ|`5z+D72_TJ!8k?*I!k{VT;7S=H9U z#bKSyooUFkr-|;j#Kl*u6l)-#9R*7up1R&ww-MJNX?YI5VhoKp?>jtiZ&d#%A{Qs0!V)L%$_T04Gc9(AiAU0$1RTNa&&zhUl zHsV@>Hz*xIXiGb?{R&=W9eckFfNPvgaqr!*7d>izyC`cKY%s1kvpO3K5#ppS<9Qy` zQ>X9m1JY!U*u$obL8y;i}!H&LvFFH5{!0vorK-`+UDO{=W z9PtJYCVmgQZq=>(OdKSCa2M+Gx61Zewy>AVC@tRFR(S4vX&3i`XHc0*fKD+Mm7oN4 znm`NV_|8_&bf)oLaYO32-~34vGH4P3cEuw~sOi6311+{uEYro{IoWu)cajaf;2L-@ zFF17`aylH~g)nnaKYJlO`PYw+U4&gGQLO6NI5?$WrmG0{CW??65`fZIIuf#~%e5=? z?V3^n2YsypRt5I#Ukjdq{;-R;r4u5nIh^%k#cxq&I;h@nK`g3v9=rIrXC{o8DKO%m zgw&&kDy$(s-h&joAtS>`GwN}3q8)aGI2Q~SnQ>}t)v+|V8s-`L&tjkOz*b;R#08%Sn z3}9|ljc7PDgGqXpiYdAqT%Xn`=8bnFT(rZdCQ=mwC`dOCX zrB=%QVGbo7{TaDE7%cP)8jCoWgTO#8S6*~W8U*D=rB+uwzO?bg9r`q6$3(pG(7UKG z-a2$QU!5aX)fj#|fdY{~_E!f}=rftO`optx!$cR)phv(P zX)+0P1{DIbssF0AT2I$DCWzZmAx>Cx3+d{RL+Mn}(tknnaTT`llY_2_J?CS1UM3c- ztuCRgv~Zh~cR)pL@NJhkF2{hR;|oAz9O(z(e*h?^rVfsRh~H?8PI9U$M=z1x^fd+< zTxNsWxSfXINfGTXPuxpixre5323rZnpWivOv{ZlWOV42ZgZN|EvC7tuMv{g_`gnXI zsuN3=JMfS3Sf3c~EVddJUe@Pa!W{nk_Y3=?E?U-b?litGz?5#KT!<7ZYCL5m*TWI| zD>>D`Vy0Mn!>O$YRts9|9#>22g#|?G=X91G&BaB;T<^0tB4*R(vUm~3m0I!0u~-i` z+3Et@FD)lno4{?c>Zzra7kdEO@OS(wY23>SGBmF(_gUn^+*K;m#C|GqBCi%jrAB#J zAog_qR(#^{q}1i#(Q@;AImo@8FZHxDOXl7FYhN85zI|nIW2vmDC_M8q6UUHe^@`-v z>UCtJrZi$*el_2MOek3W==Y#>%{EUv+O6&kxNkdxXQwke@M31xX%nr81lEmmyHSpr z4vS4q_yB?%;0Vdv*=Hzs`{)|$h$TB@nn%TxzGRO+Xbz-F2tB_0P2ihabb9th?ok4a zt&M9Z|KBYJ(D{$^=ILQ5&sGDl74bmY^Cg|~y!Cg1?eoUpWmL}_&-TUU``OkJ6X4(p z)$m?7YM=drQF#Ue0za2$?g+LySB0`cld5K{CUDB%`$1>{a6}jFeFyD~(zhC}F<0-q z%P$V|fR}fEz!@1T)5e@}9_dBTpntcUQz`S5_HP@pAPFvkGf!22Z0!O;P5l z?DoStXWi0*i@ivRCX4pQV?DOXux01ko2Q!CiS+ns0w(X@kJJKc5FjmUf_ED>Otz)C z8JveE+@8*nn3u-H?T1smWD@Y?oK}HCB%R%zqJK6YO{FoF&YW-5)qZ;ZMxD@;lX<`{ z5p#Qj;RtJ|GWL*l^7Hq~hxnvL$KW*0z~7H*db5{%r82%~-WUwQbGB4BYLtJsSAulp zyd+iR1^v%1cvE&j3hT6FiIvJ>((*;!l;M!4JV>B`iPPJw0u1ahnE44(>ef5fhRYEalhnm6ZSmLk4*R@)p=f z01{VIvUUOv0wN3006f1e&enDYv<@bQmWIFoq^EJQwAfdbutpNWZdKlOMnAy055kFg z3(*|`Lk;$=OV$?qD8d=Q8xS1`_ ztyw>^JxVd>HD1%%^}}*xY6Y!U0~Vu$pno=(scX%d5?plG_A9B5IOnQm&bn2C0vkk~ z9;C5TQbD))THgB=!Xx_>Xymb0N)%&(hE&66Ux~|EHwb&6atVvUUgLo- zCn)Vs?z)lmFrCQy>g%}cvt{$}c@B=vr!gEcT#J95c*lbjn8aN19-0Mx@?1dLAP~~Q zU$q~U{T1)wm&QH;XbEsE>M}DPEyFv#9DF@9NXy_-V;*)*Y51_+0BL_e-|{JQ3#}RI zYb+3j(C=1t^E*>eUT=In@u&tJ$n~+B!`0mTs=)dJLYp`zjcRn)CGMwDkCP9a8tYA0 zVcui0pdMpQUi3&Wc3{b}SkUY)FYP!?Q8&FZ?7RT?IO^DP>+Hdj?J{9d`>^MN8cmKb zFjUI6iUqQqK-vbaL~f`ooStu3kGjsOaSo#68;T+om6UA|mkEWlXwu zqyIAr^*b@`5yhIONCjvVdcP)@+x5`A$kCt8WMo%f?DgJH8%x8mg_LZN{ffh_Pisek z>EBv$y|3=um93hn*1ey0s+PST#$Xf;SE|bJ9!@q!tE_pR&H^D|uOr(07@B1C2}d36 z!eCvX1K7c$KDls*c=?+q>XAW`NSEi@W;9Y%j!cs!Y>rmgSn9bS$N8YHyw<{9u0ZAq z>r#<}I5tC8Z{r?PO@5arrCd{7iPj_b3zeqFaN$*t2+eG2{k2ms`Nk;|wWWz574sE_ zKXxE70n`pR4`COdQ?h)2nfnBq#%U&h9l4qQu7g-QY_UZWf@UUtm*JW`{F>#B(GjYd z{gz&iGORnI2KYlV8aJeHFQDBFtZQt5_gdo@NzO zCoZ+=;!P8ZV(nCl7RamcNnE(f&6?Bhavgo6%z6)L@DkHEMNsOEHXOP&(BHpRC&^jL zsp(cKB)M)Z`I~)E(Y`a^yO3lufHoo?@ft>#?6lh=h(UlA#U--5`bNOKUWc-fOY2%B zF+X7;Ltq(;AKT3w7nCe~#3Yx*kRT*BeW1Z!*_D>5KT@b_?e?SBv>&U304l&1>OR}* zL&9gV{xc=3KFUznB^_tAsX_^uTET4oLQSfyus(}TL8`#EEvVz_78ys7BuLshY&XkGHazYyKQ9wl?IF|SEtzB#D|THMAy);DY`2}FNfW{7;AE?jWPjP;-CSRF z7QMM=hs&;^sY*2}zC);Q^zMn{q#Y-!`5jsgy~5ax$YF<472`uI$h83?%+4h*U;&<< zKtcZ9Mi?w@sUskOfC$NefB=8}wh{J*4i2VP#`e$lp;}|!ide+XlXb-#|JowNHM9vH zlls)mH1h;=i|Ss(04)&a0%mfszIfH!S&`M9jgg~1A)0_MD#?+eijatiP)5*bGSd5| zTuZYFEAPRs(bbXM8$KRweaov+#cHXg;r=e!X_J=rGElb){p0-L_3r8V_tyJ$c$UxBL+SU~smb>JOhob)8PF-hv&*oNd?CH+OzyqrVy6f`Psm@PNDN9;qfjf11 zi<1vd%~-Jgjhkk!*DfXgLtn-0^n-ACbt@fci z>S^v~^0ikod$#s$JST3L%2b_BRo)thm)lEI-qoyc@P<>H?u`9h>a~33NCyqGE zuhs*P_Bwg5YzL`%kBsZDTfFx3yy9p>VlN{h&r~7qx^+*kHJkIRw92+?J9S;KFVl-n z4sGvwGJh#J<4x0Y%$2otn@Nw9^*5R(Nb}rSFznqWYcE;Vj@#7f+0Ho7xLndkj14{+ zk_j=EUaI=utgR$E#DlW~pXS zpQ;0?@o;;B@yfAb*Uec@Hmg0oC(ee~%U3>M%D5eld)-^NBK!#Uz|R1%_a#!~j34#z~coz`S~b9!ov-DbwV{Mf5tz(K1H{fk>Q#3%7{B zQ(j#GIc{z)+r~OVysepC9T7Kj+q(j`i4JolN?W|Jzxm?_v5!PxBO^D#5yMRhBE)}!Uwrui(!WjW== zf{D@XP=<6i ztBxWb4qj4e*?CB~a7`5srEpMlI<5Rbm`b+K)qzY2-ATms{_KKbyC18y?PEEius_2$ z!qPdzS=Pqg71M?&sDv}cH&LM9JenI+!b&b@WBpTb*>pX-%_&M{`n!~o_$SBI*%cj! z=*gLg1Ew!f6Ul3_SXG!L4sDo*(;qQ*KZqH86mS3Ja~}4!-!VwDlYdl{$ROs_NUtZ7?mPW0!pb!TDuT&-=?e<)Oup7m2-+#sVL3*;Q~Gptx9!{h%+m8Ec!*4 z&N4+pA0H2X>u^epQ?m)%fWiU;SQ3b ziFM9dQ<~h_@&eu)7K2t|G9v4f>(TUBeEl*FyY?<_uFBLI-e^f>I*sE3RM^ay#f&Qu zjf(j$sN;;WY)A!SlzBg#v|?U&Hs+iyol$H%0t~x^`jGm|JC*6#ngH&iAfNSQa*lO2 zvk+SsLp@qcHmziF$#{aXeB|E~fh%^I`C{<}njLw}W<= zBbu4Ec~yMb8`@OygejZ4b|A!IfobS|`^8Y&DZe(`gPW2f>Ecy6@Wvgoib5kW zXP-Kv8+E_DPE+ysrB}BU9T; z-73OQ+hkag=7lVr;YIRQo-0lM(E)oWwY$<<)|6$&Dp`|C!Q0idq#0n+KLR|5Y^RVp zEiEWzr<=ggG?46KRLN2l$Sm99etnfn;AY=^dnC$f`PSG{no-8Dwo{a4qzav!O~iR% zl78N14zj6nAZSPIfXZlT=tqD(M(-%1JydTsR4)bV7nOVL{x2{keX5)E%esm0w9v3+ z;EkAvOqFz@S5tg!NM_iFoGMEFb`8L3Y&P2Gf&*+UM{J?np}R@4fKOb**t*Y<+BRE9 zP=7fM0ed|$xW*SDg1|+&O9>X)1vM!M(*2`CP8QATN(iE2Sb>c1sQO|_;C?`VwIQVTSf33ExopdYhQ>NCeU8S^O2EX9f(EfK!HwY3jw|ysW-PN!`bxeSF?zhc-qe^{xK;v(V@O5{tPNKRA~ECxnF&b+?CUD{rg$Va&+N_B0l(}dcb;H!JES-`|`d!pbSgTG5<2b~p1`L}N)VTj@Oq(-rwI=W?z z?G2J*>k8zC$dm_gok<5NYM~ulu#$70WJI^;nPb?xh=fOvxkpeZzzAnj8b!(3GzB~& z%{tk>VWACY3lJ2tutB$lOxF!jb4&Rw9Km_*Z#&T=Xp%LGo|^HQ?qnz-Q&1kY%260I zVmi8d=U0+O+Y)*t32D%GS2SosEfWvS_inMa`{B{?R9s^w94KMvmK~Gp=&47dQ7#Q9 zqKWD67t|Rp?&JEEMW;}z@)D%FsPK(M*h0Dq4ZAts=i1|vqvqKvv3@jqHL|Uz1X(pS zBiWT`jwr4Rx7C&h8DR_?%;s(krFmR%;xGV5&@lk+{^0Qz;Yf@)hnfd3hAq8o&uMIG z{T3^5&&NKjE6v9_0Fgb^*);}bY?UPrlqznn!FM=tAdrIIUdK^fLvwXy$_6IpOEIka zHp%#!MM(4#l?{zwQ3iRwkIW;(82c3vIX_YnRU}wX3@vmzN3H2}wgQWfHR%6^KDtXOLiPn+BlbWrA`4i?XHR$t)_^t&g-o{c9qW$WDt2kV|rZ$3IcV~ z`v+cgG~43Wj7Zqofv2PYP=znu-74nb^k+8@U6$(?LiAE6Q4YDLaX5H93>?gg}Sh#(zNfo1YMZJS`kG6 zGu@H42jyOik06sdOfSsABQq)*r&;c(+J->=7^6zBro;AYbjXc*MG6Mr@)o$j%J@z( zNa*q{WrVy4L`v4WV+2B=`Cile_xD?3kYjq6U1C|iMMh#N@gG8sv)9DM$Q!EQRG@@B zk}?%1*-Mlt9NAn=E6Yn2naAELy!+9JG4P{oT%|`=r5cH*C7z%+0+q_J+CiUa^-n&~cCoL3yB1 zA+-u@GIU7V_M%W{tIZb$`@tNZMZdt0KB05!J$9+~v2GMmWBC(-7n#?=3W)lZX%FA9aVOtM~Rr?RRzQLbqg5Y_vKiKCU--6BS+) z+gE*Dp}>;yZL7Dp&$Sn>VmG_a-uLiFwa;d;mS0mnW>{rJr=}zCK@_aS!6DYP&1oS? z#!ds5-sfyE$_?4;qb>>=KB~U)BrQ&rL`m1MnB5t=|9ayACal;qS@zLk8z!Wup1>>wzUdlaz>qnD&x^8!4M`t)lO%3RHkGBP7H$}Yb=SSn0rq2A!GM$I#uj0>35JInenZf+lU4lftX7$xy|{nA)MTbq+3+}z}b?~*&$zw>zg*qUCw*8RHPyuP)2 zRCksq*`ww~o_OVe_!W!?9ki#gpsD%^~Ph z4SMc!g!e+T(r^NY-mX8+6Z+vc!r9_5uU2WnSww3`|+ zc(GNILpN7X^;*?wraB?gIBne$*KQ6ck8ST9uGf|@lC76KXFKl;inihAG`vTzO>VV+ zGI&$(di^wVyR-GYI&IIxllCo(yX!poj+MJwo;ozsibHQ|g*tzyJ=1wT{d1-=Xh2_D zPGXEKLHhVfFn1!wXqs~Emz!ZqxpHvl0!ko~bVfoWX7uCLEZ^{Q>)p=Ne~q71d*87V z0O9uUfHE!OU-1(wM@v0JJ0ODc5@6R{w3=r@Zow;erh|r_p}`DB77`O4Z*LU{ECozm z<3|Gy)IwfSyOjM(+A5J5{R@;Hyq~tkcoKHlj?C_IB*-^ADUsW<+Hj^<7sFRAtlx=j z*8DtL|vr!tGbd{pnj$a#6nR1$-k0mS~O7T;lcgWfZff&DS zu9J;1Sts;Ry>&os*a0=p07&#&@c|pjRU~=_b5N;Dh$@&bj!%9dJaT6Bl&p&GM-(4f zGJG?oS7Jv2ifh=10brq`!mPw4K?Y6&6#iedp^xbZUp3c5=`Ty~l%15U&7b5+ork;@ zaoSz_o|eobD~YmASBvGbtAl`3BXC?}XbvWD(n)esZ5V;51;=Vj*VofJ7jB#z*>$~N ziN)7s6qyrQg>0AZCYBT#o@_%FFwAef{sn)tn4JFPeWY$w@uEo`$F=6@uR%vxJ7tl! z)T7OZS_G2>GbM?6Ny$zk9i+3W`ZI1_S8hUCtN~KLnQ#-mj&b9yxN9a~JiLYAByKyt z&TcXYA8?TUr~ukf?9Kr?hAWc?lhIf3R?t9`h|bsxJF{rs zPX^Nq*)U*H>_@bo$Y0^q6D{=y25opw!Le2}-iI%q&2W#hUJ%h9(f1&Yx9w^yoE*-; z#B2G>Wig%pO8zKRm{SO1gY`Z9#sq^xCqCtJ`hGV>N(%&6qbT0iyD&&c2umS`H51?u`!E(k{eYlhJ%_1R7s05I-R#5^vUtRFg(vl7wUQwpn9jr$qA`u7i!3cST0$ zfgh|XM3HD#Mkg(jgYX{4*d$HA?};6sajo-DHWgINdV>~~5mn%LVPkO z`oJ$c%&5`u8GKkkWzpxAXnuv#PpX&&RPrLY+wt`xDWxWl8;geH>XXZqt*PLu&cdA%Qs$WBA+kTQ8oTGn`6PssR=%NXRIQr=n+1NRy0Ex_>$M{Jb$PYmy z+wmz#>GB;h~bE5F%SG}ex2dZ0~B)qfp%?J!a_k*B&rD_STy25Qs3-xA`*jpUA zaL1VF;laM}FXyTKLzS#=>vG%Asjs1Ee<&aLdZ6IBeTUY*cz24T9aYu?eq-h}-cmck zBN<&c%`=_|%fy8m;Yb}jK#eoF8htjY6Sjp)Co!ecY%#QPW2Qn4Jtb~X zA~+@9lBoun+%x6&N?k!o{n!1CrWuI|OZ(QqkDeo$c4d37Lg~8H)$^}kCem^^NI9fQ z57?z;Cgq%#vJ}Fa_45jL$t~3S+3#qqaDulvxw_vLFOQexm6^KcPgfs!xa?}U&R362 z=r1|(&|mNa>t2)QOKC?769vFJ@sv5RpVhIn$x=;YkKURSFU~C!Sg+b+wjOpiDD+&S zI56P8%aepq&5H*!lW6nw!&ANRT{7Qcqc!C zFjr)%#=S9Pt1!2P#`%y%I{^(lA|kia+)5a5JA2^j}h3&WRm%!1~u(>xoZXS)3s zp36DYSyXL}O0E6eVsG@iZSH{shaJZ-Jfy0Hf`34E)A=+Uixq{h!6#88S23y>N63j1 z^$(xsBY9gbh>n6uO@FL~j$Q|@M~mpEgX`Yg(BIm5KWtfS*1Eepe7(hLAlZSl5Ycb3AB>^?c|E+bY9bNS`*0XO zT+12rxrh#`YC7xZ$%#j{ZVbrijkr*7|4nOnlTP?|8WHMO@1-a^v`c!mYni5}wTG7l1u&Vy@I z7ir5e6L6jGOCP-AEPu$j*kk0a1|4M*57LZBF&!=h@nT+Gn|_?Vr-AMmjb_uoC0o7` z{1!TD5M!+xggQ|xMC|pWZuELE-mr!wR*Evhou2S#@@5Vl*BFk%lX62N=RJu`)A9i# zO+~+FkCm1)7G@rlz@hRJ+DDPLOpOJNU5QxRYpsSB!$%^RIE-amdJfcsb*xs8>#zP) ztE!uN4qm0KG&?L!kbXWrv7qZx=p$uK7~1lfU+29W;}ZF-k7s$dyk%szV>aHyEVW)c zkexy=Vo2Q0?Gg1Dug_C5?WZF=+MmcN!35Dy%WedvHLg9cVQGCC3|(M*{{(#A|8 zuyaSTZ=|~OC|iLYUgIVa_qn41cLzKJgo$fKRS~vNHH|`DUCe&%2Py$@^s7idtDWIm zj2Ar7{#?Wcbthfl>=`X;hG)*2^xKP^kMtxdqcjHh41=g#$~s+m7c!Zdl-DSZv40k| z*%Oz)w*KCAc+I3LIbyXi!Px&mVUAoPxJxoe5`1aKTajD@S415(;a>`3Zoqym9( zFDGdXo=U@@J=?bmLs=2fze`8SZkZO~Fwz%v6KOSeJh&G@+C=4!9p*6jEr@%(4QGu( zA|a%vaDyx+Mk~g0I5cS)YP`zAe%gI^=&Kw63e+az?m+c?b|dmw;#>4+GzyCI5F zZjtj<5fxVM-6Y-wUfM1X!|>0(k+M6hg;k+J*`_8<{$}CZg^lcKdylZRk4(6sDwRtjhu8_A9A`SPzXm>2%~`Kc7)Fw$ zb;3$;O+PrIGawGP$E0-Ki6Fii`Vpm5ngA>&z`_=#BMph}6(|jEac#+gQoee%`<_lj z!3Qd#h|Qkkp0lA(;gvm#G2(zyiWr@;Eor+(_w0FJ)*f>@SRFXVq!>4>$cGG65>i(LmG^2Kr@uw?U4LnuGBcluPv!Q%Rz*i{fn zyryB+~{4o8JkI4yn7R%pf1ZT<^scX^FI(JR?pRd?yml+PvAM1W` z?U$;U)Bc=@=d88`?mk$2=P$*Rz8zV_l(;yGzhHe9&=E+!HU8Mc@XfrZ%4*$?RIZ9^ z#}smy{iv48_$PD!cv{?XiZM5Jjd3|Z$xQbs{bVtvq`hCbQ|wi!~IMD~9iSt3>ELr%6})-{LNx$_ehjKB0cv7UkNOt^D*0pFr-nUV8AYr7mQB-#9(8u=d!%ThCcWqVt^5 zFrT&Yw|-<((4UQFpbbTszhcChxo0LJlq(8=Q5L=mW&c_G19oJkwIz#L3Moq~Y3 zz{S2OlOR25z|EwX{VTID6@Qw%+%U)oI7LMcMrR+m+mxa}K1<;yg?P9bawm%Y0&%fk z5LOgr!1oOe`s(~RimA9sdGPj1HD8U*l=Z?K3R5Hhmi z!0nZ(ndK~L6&ZmhYt$HI1KTz7;YD$31wBd#nL$-E7N~xX;f(~0MTgx?bxs`f8itF^t9G$E)9x|T1IqzE+|KtW*{N^i! z*V~X`MM(WoL>ccR3F|nRsd)3v<=Z07VcoX0ZpH=3P&*`yyqmyAXgpRVXO#UfQKU;E zw^Va-UefzI|5tnG;SJaJJ#eCzAVG@gAtcJ^j2@lQTlC&z24e;ZqPNjv5Fxs#(R-qY zQ6hSYE`$)hWD>;VJ9*FhO1$^`3x40b)}3|Nn)})3%$FMthg(Nj~{APz}{sFt!Lr6ncuz zN;0K+B?qq+ejWBj-Px>PtaD91%6gM?Vj5mnEb%}JH-F!BQ`QwaElr>iMK*r7qq7Yz z@!Ti9C_nY}rb^>Mbe*pGTPc>HQ>BjZ4nH+?_ik851{75p9Z_l$wh5aJGfqKxp(U%h z;(D@KN-gvA$}M9V_gyimw(=AZ)h*3*@_Kjr^F*05GnUCd+Usz}qK~s^dYz2xa*i*5 zPbf2gYu}xGWIKf#$=uVM3gZ@NbesMtkmmfZV}3){y@8(>T32ltvr*DxcKJj>U$DfK zYiZL^9zlQ7MWDQ0b+VP^-5|ezkZ3diZ(Js3pI0b^g zz>Zmq){>h3BV0uf-{7pzx;Hq^h37 z#B_o+$)juv&R7x2=H_RUI*lC)*CKpMHC{05w;XM zUSL{k;SW1+bu}>s4&J#-S*x3B;L?6w>s^FzlWC*7d9x5vwfO)K!`)fmB?5MYG#zhp zk0HLH`}KVf^`k^^9a9EhfhPk%nRD9`K)I&)jQ91V@$vq3m)8Y0WB6imhM-7}BRQ)* zX{2V?s4(X`@dvs+%_m2>kwl-q)?HJ26Y9?Q%4JLC(?)S>3fed-Mc!-5k&Ml}!xKPFM zZDwUNPYNl?ZF$fal8n(-EM1p@;f17FFa0)8`BTQ0?L^&e15SH$+pmI~V+$XuK^+Ve zTLLwOM=2cvrMToh!+PRUt*^!rO;_oKM&TuX6S#jgEtc-T)eEW=qSqYKcqeL(Q_Dy8=o$HHAJ6{$=KBznds`2rz{qGsMHvi_x%%5|G4~_V z9!|FSSG#boDqR3;@8%)y52WYmXLwf|qUX6f&*iFN>n|c`of~Viu$1n|8}Ni7)P#*JUT&K9=TE#AG%xN(b2Qfn3KCdS)Y@eKjL%pP;}85DHSuf zSRV5X%9Q2-L?0YC=9GNeJ#XfzHk8h0X&B^8HeO?t{xF2@4 ze?(93EwDZZZ$@DZPVBt{Z)(>a#%!2TP?41O-m&(_@QCn2UT5&}Q>&cs%k-)3VJ0aD z^B!I&4~|A!FwrOf^hq6scI!7|zKO&{L{R;`1mbCHrSpqh>PBK4WSWOGbQ|XzS?E^u zMm1VHM>!yyUDG1J#2d>HX>EygP*O?V_@a1MeNj+sv}vO<5*;~w8bEdb;Kb4%R-4$* zQ4Z364@D~X-e+$xLo$>NJRm_Hwia8^6q_KMzAjm!4@Z2>(Um9MvaK&9WfADa1<-Kl zpkBh`IhFQfQc=gv%tua`Wq~Lh4m)SmIRdp4QiQkCpu1u zMGCHc`%1Bk-b!rsi9|Jh>ME`47m0D}uL1VYE7?@t+_Cu(VmpJuH?Q&ABxpJS_FhIw z;z07TKVSDp_Rb1)T3KkqVt^{DpAy(&uHNqNLf*t~B+O2eOJXeXQD>Mu=^0fVID)|i-*oihpeabv3_H* z?Q8Kj{*clC_y7Aeo4rXBvqg_}B#*TR~Knjomm>86{e)Q7QGs(Zww#^uOla010J`7IhaaU>`4v!Ueo z0^JA>mpV^qIahmzAJ6hLSzX6DY}G0*4VU) zb3E#BS9#&K>pl1D$*2hn9ix09S*gJt3L|VQFBP?qSq>6H<2Ij{NIN?9ti`+xCHYu9 zv!%K0Wh#qOt({t^%Y2^ZJNt6->aFp|_wOu-$tdkXB*`DLqzCKB;kVD(2C;l=nGtk) zx-TKai3HMrr}-eB{Au!g+i8>&YYf%vxxElhv5?gTI?5LUI8-ccb@%HidNQtL(`j?b z`Gn7qRLF{k+@NP>Bj!zfh$^W3?A3Y=r}}O8Wcw5|x)Lu5sAmeL+KBm_|AJZK^j6+M z%t)YkvB?QWbc5TXK{pK?ORvD()fC4TT@HCF*dOz{ZzeBnBw$c7ZxIk7c)kmZl~LF8SLud zZ)(wue*<{?5Z7FBBC*or*1Djgxi{`NjwKDTBP7nPml3mrWJS-b+K5y-a=M%c#aAPL z29W);zrC;0b2$pr-(sRqF);vy*fuWKnot*4cYw7E^v~wUn2n3go{5FI<^T8LgEZG@ zXQV>Ss~wYF-X?XpZkj^&DPy%a>Q29dk8Hh%1Bi%crMW2qJcdFE*RSmKF3%XJ`PQg? zBkEu8SG{seD8 z+-jX_!nS9@Ua$T2542#<*_+{|)J$fkYQ;|(vhk5Rk7bMqWg-}r$U8h3v$?c;upN_1 zm9bcf1O@|%(#x;hmYTyVMH4WvEGJcsS%Mcb;cR4EfHHzlPBk1;k0ikmDNic(~`ANy2nJB_ zo@zS=7bdyoi`+OqcnZC#@f zRGl8ow27kW`l=LR<8;DeZs~n~LRu>9Hy!@VOYgOBzbKHqy3`T<15Kw~!7L0+%oiq^ z7w;!Uq1{bc6$yt#8muNoY>5muiLJkL)b_SSUE_=>aL&4CZ;4W;n5;QIxbGaePcbO1 z8veGET8#0Cbw!IIQ{PS15)?NaV#JheIbdo?bGc4kYRn?eJoig#JAWWo=8ePjr|_uW z+b00W1y~M1a*0jDM|(;0hYC|SLtmehiAXWtb`!H_LD9@8WB&dC)v8*BmUlSxo)*YQU?=xYtxO}}3-};r!kN8xY*2Y~$r&>2JUT|ZCidVc%zM+RY(x189%xptC7x>- z!Xox?>NJ2YWdo$bk1%&zarc}q9sorG(t?`21iU65=Q`R|O>S7p;xkpS0;mM`p4c_X z&J2;rj!|Vcc#xxjE8xt@*I`?Vz0Q*AU#dYK--fcknyZ~)LV*9->Bl#NLO3xk<_V_L zr~I|WSi{|6F5v$)n)9Kq7^w!r;iU-O4m@RAO1BdN*EDQEDjGI>f-LlQu6a~}E#f(q z-xzhALXMURyeOzY^S$3`+-_7A_0{KE3xN->k}Be~Dy_a7)h^@nsWW*>q|onfxD?AQ+`}i&`G2td(}P-1dp2S+-4ENP=RvCBM-b-1jL^j-pRV zJPJUhiZu~M9eLn%g3zinw!7h2`u0l*^-QGb&f^S$N@}xvar_q2jCY0{h@Nh&^X6s< zYd;=7&52*Q&W4FVsGg1A7xLq&om;2>;ip5Frd#%Uzpn9=J0Kj3gz15EEj4 zrexTcxG+}R-!bSR`L8uIFluIk@sXoEf23zu#Z}|E=7xUQtu|7qTwANagy zlI&buU=SDBU$6Kt{t$7b_*5o_x5V&2Lp0Bi5Bz7mEyU*k#MO5TD_&smdQ1uej9*x8q2zKN@Mev=AIM>08 zc@WMY0fh$kzh_0b_!usR$)1Z4&^r_HYtZaP{GylWIS#Ws!+-M`y~tm53OVOdkiU!n zuZze<_~LTPIo$1c247fQxhUbHfqpKbKHyBkZ|3?%{&xf8oW{Zu3Bktthq-YP|9x`z uEB+(w7yN9hcai>mp!=2Piu{E>ANDjsc$hZ-v%8|iYRAkck