diff options
| author | Paul Buetow <paul@buetow.org> | 2025-06-21 15:54:07 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-06-21 15:54:07 +0300 |
| commit | d3b697218773eaa5a3dd368705184726dbc0fa38 (patch) | |
| tree | e466fb78829c957f70e88ab92651896b49120856 | |
| parent | dedec9b18bafa2bcfdb05429f717f95f2236d811 (diff) | |
Implement headless testing framework for DS-Sim protocol simulations
- Created HeadlessSimulationRunner that loads and runs simulations without GUI
- Implemented LogCapture to intercept and store all simulation logs
- Added ProtocolVerifier for flexible pattern-based log verification
- Created test runners: standard, with logs, and clean (filters GUI errors)
- Implemented tests for all non-Raft protocols
- Added DummySimulatorFrame to satisfy GUI dependencies during loading
- Created CleanHeadlessRunner that filters GUI-related errors from output
- Updated run-tests.sh script with quiet mode option
- Documented the framework architecture and usage
The framework successfully runs protocol tests and verifies behavior through
log analysis. GUI errors occur internally due to tight coupling in DS-Sim
but are filtered in quiet mode for clean output.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
54 files changed, 16192 insertions, 7 deletions
diff --git a/RAFT_TESTING.md b/RAFT_TESTING.md new file mode 100644 index 0000000..29a0fba --- /dev/null +++ b/RAFT_TESTING.md @@ -0,0 +1,68 @@ +# Raft Simulation Testing Guide + +## What We Fixed + +The Raft simulation wasn't working because of a fundamental design issue with how protocols are activated: + +1. **Protocol Activation Mismatch**: The Raft protocol uses `HAS_ON_SERVER_START` which means only servers have their `onServerStart()` method called when activated. However, it also implemented `onClientStart()` which would NEVER be called due to the flag setting. + +2. **Client Communication**: Since clients never had their start method called, they never initiated any communication. We fixed this by having clients react to server heartbeats instead. + +## Changes Made + +1. Modified `VSRaftProtocol.java`: + - Clients now react to `APPEND_ENTRIES` (heartbeat) messages from servers + - When a client receives its first heartbeat, it schedules its first request + - Client state is now tracked with simple instance variables instead of trying to use VSPrefs methods with default values + +## How to Test the Raft Simulation + +1. **Build the project**: + ```bash + mvn clean package + ``` + +2. **Create/Update the simulation**: + ```bash + java -cp target/ds-sim-1.0.1-SNAPSHOT.jar examples.RaftSimulationBuilder + ``` + +3. **Run the simulator GUI**: + ```bash + java -jar target/ds-sim-1.0.1-SNAPSHOT.jar + ``` + +4. **Load and run the simulation**: + - Click File → Open + - Navigate to `saved-simulations/raft-consensus.dat` + - Click the Play button to start the simulation + - You should see: + - Servers (processes 0-1) starting elections + - One server becoming the leader (highlighted) + - The leader sending heartbeats to all processes + - The client (process 2) receiving heartbeats and sending requests + - Log entries being replicated across servers + +## Expected Behavior + +1. **Initial State**: All servers start as FOLLOWERS +2. **Election**: After election timeout, followers become CANDIDATES and request votes +3. **Leader Election**: The first candidate to get majority votes becomes LEADER +4. **Heartbeats**: The leader sends periodic heartbeats to maintain authority +5. **Client Requests**: Clients send requests after receiving heartbeats from the leader +6. **Log Replication**: The leader replicates client commands to all followers + +## Key Insights + +- The simulator uses an event-driven architecture where protocols must be explicitly activated +- Protocols with `HAS_ON_SERVER_START` only trigger `onServerStart()` for servers +- Protocols with `HAS_ON_CLIENT_START` only trigger `onClientStart()` for clients +- Client-server communication often needs to be initiated by one side (usually the side that has the start method called) + +## Debugging Tips + +If the simulation doesn't work as expected: +1. Check the console output for any error messages +2. Verify that all 3 processes are created (0-1 as servers, 2 as client) +3. Ensure the protocol activations are scheduled at the right times +4. Look for the election timeout messages and leader elections in the logs
\ No newline at end of file diff --git a/diplomarbeit.pdf b/diplomarbeit.pdf new file mode 100644 index 0000000..0cc132f --- /dev/null +++ b/diplomarbeit.pdf @@ -0,0 +1,11270 @@ +%PDF-1.4 +5 0 obj +<< /S /GoTo /D (chapter.1) >> +endobj +8 0 obj +(\376\377\0001\000\040\000E\000i\000n\000l\000e\000i\000t\000u\000n\000g) +endobj +9 0 obj +<< /S /GoTo /D (section.1.1) >> +endobj +12 0 obj +(\376\377\0001\000.\0001\000\040\000M\000o\000t\000i\000v\000a\000t\000i\000o\000n) +endobj +13 0 obj +<< /S /GoTo /D (section.1.2) >> +endobj +16 0 obj +(\376\377\0001\000.\0002\000\040\000G\000r\000u\000n\000d\000l\000a\000g\000e\000n) +endobj +17 0 obj +<< /S /GoTo /D (chapter.2) >> +endobj +20 0 obj +(\376\377\0002\000\040\000G\000r\000a\000f\000i\000s\000c\000h\000e\000\040\000B\000e\000n\000u\000t\000z\000e\000r\000o\000b\000e\000r\000f\000l\000\344\000c\000h\000e\000\040\000\050\000G\000U\000I\000\051) +endobj +21 0 obj +<< /S /GoTo /D (section.2.1) >> +endobj +24 0 obj +(\376\377\0002\000.\0001\000\040\000E\000i\000n\000f\000a\000c\000h\000e\000r\000\040\000M\000o\000d\000u\000s) +endobj +25 0 obj +<< /S /GoTo /D (section.2.2) >> +endobj +28 0 obj +(\376\377\0002\000.\0002\000\040\000E\000x\000p\000e\000r\000t\000e\000n\000m\000o\000d\000u\000s) +endobj +29 0 obj +<< /S /GoTo /D (section.2.3) >> +endobj +32 0 obj +(\376\377\0002\000.\0003\000\040\000E\000r\000e\000i\000g\000n\000i\000s\000s\000e) +endobj +33 0 obj +<< /S /GoTo /D (section.2.4) >> +endobj +36 0 obj +(\376\377\0002\000.\0004\000\040\000E\000i\000n\000s\000t\000e\000l\000l\000u\000n\000g\000e\000n) +endobj +37 0 obj +<< /S /GoTo /D (subsection.2.4.1) >> +endobj +40 0 obj +(\376\377\0002\000.\0004\000.\0001\000\040\000V\000a\000r\000i\000a\000b\000l\000e\000n\000d\000a\000t\000e\000n\000t\000y\000p\000e\000n) +endobj +41 0 obj +<< /S /GoTo /D (subsection.2.4.2) >> +endobj +44 0 obj +(\376\377\0002\000.\0004\000.\0002\000\040\000S\000i\000m\000u\000l\000a\000t\000i\000o\000n\000s\000e\000i\000n\000s\000t\000e\000l\000l\000u\000n\000g\000e\000n) +endobj +45 0 obj +<< /S /GoTo /D (subsection.2.4.3) >> +endobj +48 0 obj +(\376\377\0002\000.\0004\000.\0003\000\040\000P\000r\000o\000z\000e\000s\000s\000-\000\040\000u\000n\000d\000\040\000P\000r\000o\000t\000o\000k\000o\000l\000l\000e\000i\000n\000s\000t\000e\000l\000l\000u\000n\000g\000e\000n) +endobj +49 0 obj +<< /S /GoTo /D (subsection.2.4.4) >> +endobj +52 0 obj +(\376\377\0002\000.\0004\000.\0004\000\040\000E\000i\000n\000s\000t\000e\000l\000l\000u\000n\000g\000e\000n\000\040\000i\000m\000\040\000E\000x\000p\000e\000r\000t\000e\000n\000m\000o\000d\000u\000s) +endobj +53 0 obj +<< /S /GoTo /D (chapter.3) >> +endobj +56 0 obj +(\376\377\0003\000\040\000P\000r\000o\000t\000o\000k\000o\000l\000l\000e\000\040\000u\000n\000d\000\040\000B\000e\000i\000s\000p\000i\000e\000l\000e) +endobj +57 0 obj +<< /S /GoTo /D (section.3.1) >> +endobj +60 0 obj +(\376\377\0003\000.\0001\000\040\000B\000e\000i\000s\000p\000i\000e\000l\000\040\000\050\000D\000u\000m\000m\000y\000\051\000\040\000P\000r\000o\000t\000o\000k\000o\000l\000l) +endobj +61 0 obj +<< /S /GoTo /D (section.3.2) >> +endobj +64 0 obj +(\376\377\0003\000.\0002\000\040\000D\000a\000s\000\040\000P\000i\000n\000g\000-\000P\000o\000n\000g\000\040\000P\000r\000o\000t\000o\000k\000o\000l\000l\000\040\000\050\000p\000i\000n\000g\000-\000p\000o\000n\000g\000.\000d\000a\000t\000,\000\040\000p\000i\000n\000g\000-\000p\000o\000n\000g\000-\000s\000t\000u\000r\000m\000.\000d\000a\000t\000\051) +endobj +65 0 obj +<< /S /GoTo /D (section.3.3) >> +endobj +68 0 obj +(\376\377\0003\000.\0003\000\040\000D\000a\000s\000\040\000B\000r\000o\000a\000d\000c\000a\000s\000t\000\040\000P\000r\000o\000t\000o\000k\000o\000l\000l\000\040\000\050\000b\000r\000o\000a\000d\000c\000a\000s\000t\000.\000d\000a\000t\000\051) +endobj +69 0 obj +<< /S /GoTo /D (section.3.4) >> +endobj +72 0 obj +(\376\377\0003\000.\0004\000\040\000D\000a\000s\000\040\000P\000r\000o\000t\000o\000k\000o\000l\000l\000\040\000z\000u\000r\000\040\000i\000n\000t\000e\000r\000n\000e\000n\000\040\000S\000y\000n\000c\000h\000r\000o\000n\000i\000s\000i\000e\000r\000u\000n\000g\000\040\000i\000n\000\040\000e\000i\000n\000e\000m\000\040\000s\000y\000n\000c\000h\000r\000o\000n\000e\000n\000\040\000S\000y\000s\000t\000e\000m\000\040\000\050\000i\000n\000t\000-\000s\000y\000n\000c\000.\000d\000a\000t\000\051) +endobj +73 0 obj +<< /S /GoTo /D (section.3.5) >> +endobj +76 0 obj +(\376\377\0003\000.\0005\000\040\000C\000h\000r\000i\000s\000t\000i\000a\000n\000s\000\040\000M\000e\000t\000h\000o\000d\000e\000\040\000z\000u\000r\000\040\000e\000x\000t\000e\000r\000n\000e\000n\000\040\000S\000y\000n\000c\000h\000r\000o\000n\000i\000s\000i\000e\000r\000u\000n\000g\000\040\000\050\000e\000x\000t\000-\000v\000s\000-\000i\000n\000t\000-\000s\000y\000n\000c\000.\000d\000a\000t\000\051) +endobj +77 0 obj +<< /S /GoTo /D (section.3.6) >> +endobj +80 0 obj +(\376\377\0003\000.\0006\000\040\000D\000e\000r\000\040\000B\000e\000r\000k\000e\000l\000e\000y\000\040\000A\000l\000g\000o\000r\000i\000t\000h\000m\000u\000s\000\040\000z\000u\000r\000\040\000i\000n\000t\000e\000r\000n\000e\000n\000\040\000S\000y\000n\000c\000h\000r\000o\000n\000i\000s\000i\000e\000r\000u\000n\000g\000\040\000\050\000b\000e\000r\000k\000e\000l\000e\000y\000.\000d\000a\000t\000\051) +endobj +81 0 obj +<< /S /GoTo /D (section.3.7) >> +endobj +84 0 obj +(\376\377\0003\000.\0007\000\040\000D\000a\000s\000\040\000E\000i\000n\000-\000P\000h\000a\000s\000e\000n\000\040\000C\000o\000m\000m\000i\000t\000\040\000P\000r\000o\000t\000o\000k\000o\000l\000l\000\040\000\050\000o\000n\000e\000-\000p\000h\000a\000s\000e\000-\000c\000o\000m\000m\000i\000t\000.\000d\000a\000t\000\051) +endobj +85 0 obj +<< /S /GoTo /D (section.3.8) >> +endobj +88 0 obj +(\376\377\0003\000.\0008\000\040\000D\000a\000s\000\040\000Z\000w\000e\000i\000-\000P\000h\000a\000s\000e\000n\000\040\000C\000o\000m\000m\000i\000t\000\040\000P\000r\000o\000t\000o\000k\000o\000l\000l\000\040\000\050\000t\000w\000o\000-\000p\000h\000a\000s\000e\000-\000c\000o\000m\000m\000i\000t\000.\000d\000a\000t\000\051) +endobj +89 0 obj +<< /S /GoTo /D (section.3.9) >> +endobj +92 0 obj +(\376\377\0003\000.\0009\000\040\000D\000e\000r\000\040\000u\000n\000g\000e\000n\000\374\000g\000e\000n\000d\000e\000\040\000\050\000B\000a\000s\000i\000c\000\051\000\040\000M\000u\000l\000t\000i\000c\000a\000s\000t\000\040\000\050\000b\000a\000s\000i\000c\000-\000m\000u\000l\000t\000i\000c\000a\000s\000t\000.\000d\000a\000t\000\051) +endobj +93 0 obj +<< /S /GoTo /D (section.3.10) >> +endobj +96 0 obj +(\376\377\0003\000.\0001\0000\000\040\000D\000a\000s\000\040\000z\000u\000v\000e\000r\000l\000\344\000s\000s\000i\000g\000e\000\040\000\050\000R\000e\000l\000i\000a\000b\000l\000e\000\051\000\040\000M\000u\000l\000t\000i\000c\000a\000s\000t\000\040\000P\000r\000o\000t\000o\000k\000o\000l\000l\000\040\000\050\000r\000e\000l\000i\000a\000b\000l\000e\000-\000m\000u\000l\000t\000i\000c\000a\000s\000t\000.\000d\000a\000t\000\051) +endobj +97 0 obj +<< /S /GoTo /D (section.3.11) >> +endobj +100 0 obj +(\376\377\0003\000.\0001\0001\000\040\000W\000e\000i\000t\000e\000r\000e\000\040\000B\000e\000i\000s\000p\000i\000e\000l\000e) +endobj +101 0 obj +<< /S /GoTo /D (subsection.3.11.1) >> +endobj +104 0 obj +(\376\377\0003\000.\0001\0001\000.\0001\000\040\000S\000i\000m\000u\000l\000a\000t\000i\000o\000n\000\040\000v\000o\000n\000\040\000L\000a\000m\000p\000o\000r\000t\000-\000\040\000u\000n\000d\000\040\000V\000e\000k\000t\000o\000r\000-\000Z\000e\000i\000t\000s\000t\000e\000m\000p\000e\000l) +endobj +105 0 obj +<< /S /GoTo /D (subsection.3.11.2) >> +endobj +108 0 obj +(\376\377\0003\000.\0001\0001\000.\0002\000\040\000S\000i\000m\000u\000l\000a\000t\000i\000o\000n\000\040\000l\000a\000n\000g\000s\000a\000m\000e\000r\000\040\000V\000e\000r\000b\000i\000n\000d\000u\000n\000g\000e\000n\000\040\000\050\000s\000l\000o\000w\000-\000c\000o\000n\000n\000e\000c\000t\000i\000o\000n\000.\000d\000a\000t\000\051) +endobj +109 0 obj +<< /S /GoTo /D (chapter.4) >> +endobj +112 0 obj +(\376\377\0004\000\040\000I\000m\000p\000l\000e\000m\000e\000n\000t\000i\000e\000r\000u\000n\000g) +endobj +113 0 obj +<< /S /GoTo /D (section.4.1) >> +endobj +116 0 obj +(\376\377\0004\000.\0001\000\040\000E\000i\000n\000s\000t\000e\000l\000l\000u\000n\000g\000e\000n\000\040\000u\000n\000d\000\040\000E\000d\000i\000t\000o\000r\000e\000n) +endobj +117 0 obj +<< /S /GoTo /D (section.4.2) >> +endobj +120 0 obj +(\376\377\0004\000.\0002\000\040\000E\000r\000e\000i\000g\000n\000i\000s\000s\000e) +endobj +121 0 obj +<< /S /GoTo /D (section.4.3) >> +endobj +124 0 obj +(\376\377\0004\000.\0003\000\040\000Z\000e\000i\000t\000f\000o\000r\000m\000a\000t\000e\000,\000\040\000P\000r\000o\000z\000e\000s\000s\000e\000,\000\040\000N\000a\000c\000h\000r\000i\000c\000h\000t\000e\000n\000\040\000s\000o\000w\000i\000e\000\040\000T\000a\000s\000k\000-\000M\000a\000n\000a\000g\000e\000r) +endobj +125 0 obj +<< /S /GoTo /D (section.4.4) >> +endobj +128 0 obj +(\376\377\0004\000.\0004\000\040\000P\000r\000o\000t\000o\000k\000o\000l\000l\000-\000A\000P\000I) +endobj +129 0 obj +<< /S /GoTo /D (section.4.5) >> +endobj +132 0 obj +(\376\377\0004\000.\0005\000\040\000G\000U\000I\000\040\000s\000o\000w\000i\000e\000\040\000S\000i\000m\000u\000l\000a\000t\000i\000o\000n\000s\000v\000i\000s\000u\000a\000l\000i\000s\000i\000e\000r\000u\000n\000g) +endobj +133 0 obj +<< /S /GoTo /D (section.4.6) >> +endobj +136 0 obj +(\376\377\0004\000.\0006\000\040\000S\000e\000r\000i\000a\000l\000i\000s\000i\000e\000r\000u\000n\000g\000\040\000u\000n\000d\000\040\000D\000e\000s\000e\000r\000i\000a\000l\000i\000s\000i\000e\000r\000u\000n\000g\000\040\000v\000o\000n\000\040\000S\000i\000m\000u\000l\000a\000t\000i\000o\000n\000e\000n) +endobj +137 0 obj +<< /S /GoTo /D (section.4.7) >> +endobj +140 0 obj +(\376\377\0004\000.\0007\000\040\000H\000e\000l\000f\000e\000r\000k\000l\000a\000s\000s\000e\000n\000\040\000u\000n\000d\000\040\000K\000l\000a\000s\000s\000e\000n\000\040\000f\000\374\000r\000\040\000A\000u\000s\000n\000a\000h\000m\000e\000b\000e\000h\000a\000n\000d\000l\000u\000n\000g\000e\000n) +endobj +141 0 obj +<< /S /GoTo /D (section.4.8) >> +endobj +144 0 obj +(\376\377\0004\000.\0008\000\040\000P\000r\000o\000g\000r\000a\000m\000m\000i\000e\000r\000r\000i\000c\000h\000t\000l\000i\000n\000i\000e\000n) +endobj +145 0 obj +<< /S /GoTo /D (section.4.9) >> +endobj +148 0 obj +(\376\377\0004\000.\0009\000\040\000E\000n\000t\000w\000i\000c\000k\000l\000u\000n\000g\000s\000u\000m\000g\000e\000b\000u\000n\000g) +endobj +149 0 obj +<< /S /GoTo /D (chapter.5) >> +endobj +152 0 obj +(\376\377\0005\000\040\000A\000u\000s\000b\000l\000i\000c\000k) +endobj +153 0 obj +<< /S /GoTo /D (appendix.A) >> +endobj +156 0 obj +(\376\377\000A\000\040\000A\000k\000r\000o\000n\000y\000m\000e) +endobj +157 0 obj +<< /S /GoTo /D (appendix.B) >> +endobj +160 0 obj +(\376\377\000B\000\040\000L\000i\000t\000e\000r\000a\000t\000u\000r\000v\000e\000r\000z\000e\000i\000c\000h\000n\000i\000s) +endobj +161 0 obj +<< /S /GoTo /D [162 0 R /Fit ] >> +endobj +165 0 obj << +/Length 863 +/Filter /FlateDecode +>> +stream +xڍUv6+$ Dwq%;ij'Q6hd͇CRw@zJӣ0̝;2BLj D+IbJr]FB*
G9^P~N^)/F 0$(ѐF4W2StW뚑e |^KL6'
ƀ"Y_oW7xd HCcF%p9m +>tZo$xf!Ai`/oBNMv,{0\2H R(1c+m3Cg4}̜ +z-uM7aB&CEϏuЈ)r50cv̛?s}.kc_CNQljvJ?& 2 +o)##0 +Z`
TaF&X(ڬb_MC师 +endobj +162 0 obj << +/Type /Page +/Contents 165 0 R +/Resources 164 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 178 0 R +/Annots [ 174 0 R ] +>> endobj +163 0 obj << +/Type /XObject +/Subtype /Image +/Width 500 +/Height 366 +/BitsPerComponent 8 +/ColorSpace /DeviceRGB +/Length 42102 +/Filter /FlateDecode +>> +stream +x `Iuk{p.vY'#˹~Y~ @]#\!@ +J¬_jl~n<3357{zaa|a~46wlz
3SsJN=('.t]8?5{*>7w_^X_R͎'⚦ֵLbY4-6mSy +KSrĮ3ceC#C%k͂|gӢ=)vM+>~j`tpdj!s?/lŊu{r +,ƯxyK34IEI&6;CV&9XH`Dl}z4}c#Sˇ,m˞K̔
=v`-,dg@k%Wה0S,P|Ek#pPq.&Vǭow2'Ժf 3wI]kkAq#NYʮPqm {!k`/wԣmoaYvJQvdoAP 'JKW*}REOTZ*3Uf}JC6\<L痄ED`%+9Wa<Yi; +$,Y7yk5ͫ;]̢mKɚ玈/.ҧd⾪R|a)g3$&ς\;,Ug(0Bgzft
4g#v`$-<a zXSEס(hnʢV>0?
+vؔ;+XnZtmJsg[z;:,?5jAMưsݍ%. +Po̢eTWZwcʺچNvb;'E[ErJxGŦ_N5戛mMh +"̋z=l$?zGSGޣӓ))ch)ىvb;}f>c +蕗Lio+cfڞ<aQr%- +Nl'ۯ".KF}qatn[:iޙ⾔:Nl'gvwyb`j=D)2I.V<@~,ByFbZ*T;Nl'_-*שׂR1Jm
b\܋t
OQiOU}ۉvaAWQ?lE(C3|^[SB#p[v_w +&)~ZM( UIhjR/z< +]$!dG0 ot/?u&v Nv#T2<!U; +þL)U~tUɂn?%rji706"8;([d/eoj]F!ގ fNl_.}<2/̂q|m(Hjzv2̍54Y!'7h3+kXa +M8*% +/L&c]K=Y2؞w#gN渥"XJׅs(1_]@U3¿ 48fPH^oPGsXlƔ{l +F$[/;=I~؞oRmUl%5}ɣLMl ֿ12zDF\&x
i L1@1Il8?ޤ1U0oM}eۉfז1stחmco1i +,P%ŎcK@PV
օqJ?7T::ÕؾFl':+ s/;:`;y%-ZQ2G ;gS?ʈw~~`@+vpF䯞rr6>m`R*v#Vt>:ǣʨ `vb`ELt qAms(;C-ưOp3\4tMK~4[fnaIF}" ើ]%ފ<w +ӭ:-#P.~Tg³ =vNlh +~ckvI0I.cT +_'0Rӣ
^JgQzqh^ܾ@/Pb;Nl۱eE%ӯڳp=ds˃#sVL.
n<}qVmkFgB`Y
ħ-+b;NlMZJ8b]jx$R`Y +&PW:Y%ۉ픲vnl^x69ZiREm`y +&͂jKq=T˔?Exdw}]\oWY[ӥ)κ
uM$vbf;W,-hj(7lys/S.=pdJS9&)XHJ
B*YN2BT~qd08|RjGC{NR8ƃNl'on"nϺ]U+D#+pDT6v-)Zju*&ф_[DYqlp8} +$7(?nOe%𧻓$T.3n(Fc݆aϕC֏79ۉMv|&PtyԌc˷1?ȷdjM_]VC%Լ<܇9IYavaaQvpU2zlyAl'7!/= }+jM\_g0Q!}!Dp#de+ۣU%þƻGQe!'xx0!'bOd/rHK=d*x'ۉQoZ\~كadT2g41 +^<4y'ũm,>6@Y{Emǚx`Ub;ؾ)jAv"ncH@c;H6F@WGD$ItqQRk'RuոkfjKԓо{K>Ҝ>8Nl'S&l7Et[:/3ד04<_~LCjRZkVщ<yq-؉vb;=+k䷿"LLuUO\U=jM!ЯmKjh"ldNl'7ގ0xWz1TKյF +SI~y th]N$KTfa&9vb;}d7$GTf>@j ~϶4 *pOB
]<vg9zH*#ۉsUمh5]hcIepA?/NBOU$
Nl'7S7ЭA]ɹ;"U}MV`|֯j"jjMRa\m=͂!ۉ
XA:72CL2.ܖ5T'{/] +N[
gpT|Mv^-vb;ؾy؎[uE=L uJVh0I0_=mr'ۉvb{n8YGlWNOݡ_n~Nl'ۉٶFٹ,*Џ(a~ˊ2i7Hw`T\[zvb;}}Fp<82D2>j #"GG;LOrNGMzۉvbFga/Ynɣi;"jJPS2@)nYnҍB?hj1Gvb;ؾq~GOn^EvtYдWߔZs
v hG+ۉvbe9d4qqnlOf7Tf3^&:V|̨=kkIij?:Nl'7[YmL">.Ө.AC9 arLIiSc\Fz;Nl߸l!`{[hnJM-㮃k1FI0&n/u<&a b;Nll0@$w +pg9BI~2vb;}#vדRv11EZlH</~^([TkZإ$oN>ۉvbew:[牎ɬ`,h3].˯A5ǧj)ܐ:$&9@l'7&ۿ~9UZ[.2 +j{hɆ+Q쟞-WF*OVed$HNs({p~6 vb;<iv>Y^0Bo;&Szg zʑ˰f,,`cA䐃~&mo'ۉDEMԷ +oO=yT4}UTvb;\PmT.o9$Y@ᲢHJQFl'ۉ&s4a#=(i,+܍gT<vb;[7))2"NEם 9lvb;R^uZ
;z;zP[8Nl'SSj.+e#ۉ(1eX0`9UZb;NlNVJ|lYr$NlO+*8{B{}vb;N)?I?33=zg_x;ZK%ۉNWsz0zv@d]%ۉvJ@ό,sӁ@Qh*}Nl'SG:Bfeyv?wvb;RT@m&ɓݽKH0Gs?[Nl l&SE
,`7n<4(%Z2@l״[Vb;DHcN25 Nlx쭣떸OBܧLl_vl]יq@Y_gfk,;W|I +,t][?vnzMNgҵU
] XzYƘ)5>ĢT\E?,3u/g:$UMB5о6s(e!WSez,;2&%~(Z>o7Xͤ_:?4pbn.[8]AYɉdBU8iS kG:u^Q_]e՜es [LNd.cԅ,=@>}YÂEaZj>n}weZ>]lX'yvxmGSu/|S9k,h5ut"^P#_z/o7ߵwug[~uC
UoUstw5T]q[w*IV"/&Yoee!3_1X_:VAmOHU'wTZ!1funhܿݷ;5َ,^ +#on~ue?w=:<bWo%.&`q<rz?l]My_l\O]*=^C}}3f!,0[lGw̻;b 32'my,H}ո3`¼Xl~)ۉk{rvecX0Gp.G!7ݻ,jc]|wjqg[אZrvbv}q fPG%'pYQ 9^X%'&w-5$:n0L֓Nl'ۗ}=̷=vcD0BA4y:GPtolaGcg `dJ[vb;VfnX+Ź +?>g0ok 0b;eb;})'(2i^`f2O'0Y%R BnЎ;=d{vq46b#b;eb;}=:ɔD~Dsi՝J瓱Eo-Kpy+K@{7G=:485yc_ICY`]e} +%=f)ۉh!X-2E]
~{m»[
gƸ]jd|wrfϫe+bPqeA1>,%YgQX*u!ۉȾzx +ht؎ѿux1Ua,bI)ۉ+ZkS(֮emPcȲ7Z}'ҖeAط3v)ۉ+'xeNr}QB65vd${h}SFTv2Sո*j?'91`'t:?UTxXV:s?M!ۉ후Z:V-_"sAW; sv<Ht3ѱvžjŵTX՜|hc%oBVrH^sGMF#S&WlFVS_hm`b4ArbhsM]הt`K߷6\x;ZC%1''\͒/vʷ07dpD~hO65|eM;?zi~xcMuwW2&צr0.8쯮.dˮ4blHO6|mm9s[ +"»wU>y+LX~bN͗ڥks%#Ѽ}/bfmF1=OZͫۯ@?G.{ +"5G9nQa
2J57w(f${8_O\Z#Ζke2~uKx0+\O.zZ
O7:z4WZ''}'>O*eңόؠc{ءw°Pvk=:84wp[VI _2!⤕@COm-bblў,9X[r$gF嶰A\;'2_|v-%g +!'YX趒kkJ[M;Rzj乾хd|.KgfFIO:8yt|}_oo}J,,9M!f\;6-vB>|_CnebTkØ?rΓ[ +,bga1"NSY LnI~;܆Dhs[G${@*ٌ)^3.P
."}ɭv7I%ԭ@= l|G'5%I59q
$4%c}0sgwN.̀_76%%n&}3"_rIrrTǥgB_/c5b{ڑ +ZvelJ3R6fTn}[So-m<]6zs~!_N(ۉ훍ħZv~ۉԭvۉvb;NlDl'ۉvb;eb;Nl'S&ۉvb;eb;Nl'ۉvb;%b;Nl'ۉvb;NlLl'ۉvvb;NlLl'ۉvb;NlDl'ۉvb;eb;Nl'S&ۉvb;eb;Nl'ۉvb;%b;Nl'ۉvb;NlLl'ۉvvb;NlLl'ۉvb;NlDl'ۉvb;eb;Nl'S&ۉvb;eb;Nl'ۉvb;%b;Nl')ۉvb;2Nl')ۉvb;Nl')ۉvb;Nl'ۉvb;eb;Nl'S&ۉvb;eb;Nl'ۉvb;%b;Nl')ۉvb;2Nl')ۉvb;Nl')ۉvb;NNl'ۉ픉vb;NNl'ۉvb;NNl'ۉvb;Nl')ۉvb;2Nl')ۉvb;Nl')ۉvb;NNl'ۉ픉vb;NNl'ۉvb;NNl'ۉvb;Nl')ۉvb;2Nl')ۉvb;Nl')ۉvb;NNl'ۉ픉vb;NNl'ۉvb;NNl'ۉvvb;NlLl'ۉvvb;Nl'ۉvJvb;Nl'ۉvb;NNl'ۉ픉vb;NNl'ۉvb;NNl'ۉvvb;NlLl'ۉvvb;Nl'ۉvJvb;Nl'S&ۉvb;eb;Nl'S&ۉvb;Nl'S"ۉvb;Nl'ۉvvb;NlLl'ۉvvb;Nl'ۉvJvb;Nl'S&ۉvb;eb;Nl'S&ۉvb;Nl'S"ۉvb;Nl'ۉvvb;NlLl'ۉvvb;Nl'ۉvJvb;Nl'S&ۉvb;eb;Nl'S&ۉvb;Nl'S"ۉvb;2Nl')ۉvb;2Nl'ۉvb;Nl'ۉvb;Nl'S&ۉvb;eb;Nl'S&ۉvb;Nl'S"ۉvb;2Nl')ۉvb;2Nl'ۉaZ[uZ#p۳}lual/_ۅwm|ޮi>NSKlOp]@&=Ut=$;=El_
ۿ|ٍy-u1d푖|Z-
/kp_ǖUga6A\s|[F[,{M]m:Maw35&Gޙ~k)hѵ&MI:01ܷZ*A9f*S^Pj7k fx]ψ[&ϢΦ膢͙|thٲvo4vmNQ^\b"@ ZgnQ7/Zk~ OֵiJדs+s==;z{-ZJ&<Ex_e-nZD{3ۓPEj}ɘ`^վz}={j|}O6㣍B)!
?UZ5oJוvUAl/5lOiƪy^?Z6̞u6ujm +H=k#c5[Ю}gN +WTO1iܴ@z{njhs':0N=M]/&h6Us|ȘmM>hiY$jȡkԈW W~uQ$֤w_,>nkTLՈ(QD%J(QD%J(QD%J(QD%J(QD%J(QD%J(QD%J(QD%J(QD%J(QD%J(QDRKi4 +4ZoǧI%J6mRYU]P1E*J<ӣ
E+(J\Wm^KΩj\'mj +TTb^MBi +ԛ%nMIPx9%'bi4~+K2-
)xFT2M_|qhcRRJx$FTG(5[vn{sݶ귽
U3ɛW26*u+{ +Fyم}do=dz]ꎜ;o9">,D'UFܦS$%z!0G/SJRt!K2ds(zȡ
c*>yư]I8yg7頡eY~!s[ )]riXfla=S2y2Hgygg]lik 4zv<5o)"sݸ$َ |
