aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/constants.h12
-rw-r--r--src/defaultsettings.cpp4
-rw-r--r--src/main.cpp77
-rw-r--r--src/map.cpp564
-rw-r--r--src/map.h107
-rw-r--r--src/mapblock.cpp65
-rw-r--r--src/mapblock.h290
-rw-r--r--src/mapchunk.h51
-rw-r--r--src/mapsector.cpp9
-rw-r--r--src/mapsector.h1
-rw-r--r--src/server.cpp35
-rw-r--r--src/utility.h17
-rw-r--r--src/voxel.cpp7
13 files changed, 916 insertions, 323 deletions
diff --git a/src/constants.h b/src/constants.h
index f90b278d2..c8c210b13 100644
--- a/src/constants.h
+++ b/src/constants.h
@@ -76,21 +76,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
// is very low
#define BLOCK_SEND_DISABLE_LIMITS_MAX_D 1
-// The fps limiter will leave this much free time
-//#define FREETIME_RATIO 0.15
-//#define FREETIME_RATIO 0.0
-#define FREETIME_RATIO 0.05
-
#define PLAYER_INVENTORY_SIZE (8*4)
#define SIGN_TEXT_MAX_LENGTH 50
// Whether to catch all std::exceptions.
// Assert will be called on such an event.
-#ifdef DEBUG
- #define CATCH_UNHANDLED_EXCEPTIONS 0
-#else
+// In debug mode, leave these for the debugger and don't catch them.
+#ifdef NDEBUG
#define CATCH_UNHANDLED_EXCEPTIONS 1
+#else
+ #define CATCH_UNHANDLED_EXCEPTIONS 0
#endif
/*
diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp
index 4046b81b9..0665cd02e 100644
--- a/src/defaultsettings.cpp
+++ b/src/defaultsettings.cpp
@@ -49,8 +49,8 @@ void set_default_settings()
g_settings.setDefault("max_simultaneous_block_sends_per_client", "1");
//g_settings.setDefault("max_simultaneous_block_sends_per_client", "2");
g_settings.setDefault("max_simultaneous_block_sends_server_total", "4");
- g_settings.setDefault("max_block_send_distance", "6");
- g_settings.setDefault("max_block_generate_distance", "6");
+ g_settings.setDefault("max_block_send_distance", "7");
+ g_settings.setDefault("max_block_generate_distance", "7");
g_settings.setDefault("time_send_interval", "20");
g_settings.setDefault("time_speed", "96");
g_settings.setDefault("server_unload_unused_sectors_timeout", "60");
diff --git a/src/main.cpp b/src/main.cpp
index 0dc822474..dc4716fab 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -168,7 +168,7 @@ TODO: Make fetching sector's blocks more efficient when rendering
TODO: Flowing water animation
-FIXME: The new texture stuff is slow on wine
+FIXME(FIXED): The new texture stuff is slow on wine
- A basic grassy ground block takes 20-40ms
- A bit more complicated block can take 270ms
- On linux, a similar one doesn't take long at all (14ms)
@@ -182,6 +182,15 @@ FIXME: The new texture stuff is slow on wine
is fast to compare, which refers to a cached string, or
* Make TextureSpec for using instead of strings
+FIXME(FIXED): A lock condition is possible:
+ 1) MapBlock::updateMesh() is called from client asynchronously:
+ - AsyncProcessData() -> Map::updateMeshes()
+ 2) Asynchronous locks m_temp_mods_mutex
+ 3) MapBlock::updateMesh() is called from client synchronously:
+ - Client::step() -> Environment::step()
+ 4) Synchronous starts waiting for m_temp_mods_mutex
+ 5) Asynchronous calls getTexture, which starts waiting for main thread
+
Configuration:
--------------
@@ -255,6 +264,20 @@ Map:
NOTE: There are some lighting-related todos and fixmes in
ServerMap::emergeBlock. And there always will be. 8)
+TODO: Mineral and ground material properties
+ - This way mineral ground toughness can be calculated with just
+ some formula, as well as tool strengths
+
+TODO: Change AttributeList to split the area into smaller sections so
+ that searching won't be as heavy.
+
+TODO: Remove HMParams
+
+TODO: Flowing water to actually contain flow direction information
+
+TODO: Remove duplicate lighting implementation from Map (leave
+ VoxelManipulator, which is faster)
+
FEATURE: Map generator version 2
- Create surface areas based on central points; a given point's
area type is given by the nearest central point
@@ -269,6 +292,11 @@ FEATURE: Map generator version 2
FEATURE: The map could be generated procedually:
- This would need the map to be generated in larger pieces
- How large? How do they connect to each other?
+ - It has to be split vertically also
+ - Lighting would not have to be necessarily calculated until
+ the blocks are actually needed - it would be quite fast
+ - Something like 64*64*16 MapBlocks?
+ - TODO: Separate lighting and block generation
* Make the stone level with a heightmap
* Carve out stuff in the stone
* Dump dirt all around, and simulate it falling off steep
@@ -283,20 +311,13 @@ FEATURE: The map could be generated procedually:
parameter field is free for this.
- Simulate rock falling from cliffs when water has removed
enough solid rock from the bottom
-
-TODO: Mineral and ground material properties
- - This way mineral ground toughness can be calculated with just
- some formula, as well as tool strengths
-
-TODO: Change AttributeList to split the area into smaller sections so
- that searching won't be as heavy.
-
-TODO: Remove HMParams
-
-TODO: Flowing water to actually contain flow direction information
-
-TODO: Remove duplicate lighting implementation from Map (leave
- VoxelManipulator, which is faster)
+TODO: Lazy lighting updates:
+ - Set updateLighting to ignore MapBlocks with expired lighting,
+ except the blocks specified to it
+ - When a MapBlock is generated, lighting expires in all blocks
+ touching it (26 blocks + self)
+ - When a lighting-wise valid MapBlock is needed and lighting of it
+ has expired, what to do?
Doing now:
----------
@@ -1523,6 +1544,16 @@ int main(int argc, char *argv[])
mysrand(time(0));
/*
+ Pre-initialize some stuff with a dummy irrlicht wrapper.
+
+ These are needed for unit tests at least.
+ */
+
+ IIrrlichtWrapper irrlicht_dummy;
+
+ init_mapnode(&irrlicht_dummy);
+
+ /*
Run unit tests
*/
if((ENABLE_TESTS && cmd_args.getFlag("disable-unittests") == false)
@@ -1684,7 +1715,7 @@ int main(int argc, char *argv[])
skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(255,0,0,0));
/*
- Preload some textures
+ Preload some textures and stuff
*/
init_content_inventory_texture_paths();
@@ -2131,20 +2162,6 @@ int main(int argc, char *argv[])
dtime_jitter1_max_fraction
= dtime_jitter1_max_sample / (dtime_avg1+0.001);
jitter1_max = 0.0;
-
- /*
- Control freetime ratio
- */
- /*if(dtime_jitter1_max_fraction > DTIME_JITTER_MAX_FRACTION)
- {
- if(g_freetime_ratio < FREETIME_RATIO_MAX)
- g_freetime_ratio += 0.01;
- }
- else
- {
- if(g_freetime_ratio > FREETIME_RATIO_MIN)
- g_freetime_ratio -= 0.01;
- }*/
}
}
diff --git a/src/map.cpp b/src/map.cpp
index 2782cef03..cc1a6d638 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -67,10 +67,8 @@ Map::~Map()
}
}
-MapSector * Map::getSectorNoGenerate(v2s16 p)
+MapSector * Map::getSectorNoGenerateNoExNoLock(v2s16 p)
{
- JMutexAutoLock lock(m_sector_mutex);
-
if(m_sector_cache != NULL && p == m_sector_cache_p){
MapSector * sector = m_sector_cache;
// Reset inactivity timer
@@ -79,11 +77,9 @@ MapSector * Map::getSectorNoGenerate(v2s16 p)
}
core::map<v2s16, MapSector*>::Node *n = m_sectors.find(p);
- // If sector doesn't exist, throw an exception
+
if(n == NULL)
- {
- throw InvalidPositionException();
- }
+ return NULL;
MapSector *sector = n->getValue();
@@ -91,13 +87,27 @@ MapSector * Map::getSectorNoGenerate(v2s16 p)
m_sector_cache_p = p;
m_sector_cache = sector;
- //MapSector * ref(sector);
-
// Reset inactivity timer
sector->usage_timer = 0.0;
return sector;
}
+MapSector * Map::getSectorNoGenerateNoEx(v2s16 p)
+{
+ JMutexAutoLock lock(m_sector_mutex);
+
+ return getSectorNoGenerateNoExNoLock(p);
+}
+
+MapSector * Map::getSectorNoGenerate(v2s16 p)
+{
+ MapSector *sector = getSectorNoGenerateNoEx(p);
+ if(sector == NULL)
+ throw InvalidPositionException();
+
+ return sector;
+}
+
MapBlock * Map::getBlockNoCreate(v3s16 p3d)
{
v2s16 p2d(p3d.X, p3d.Z);
@@ -630,6 +640,8 @@ void Map::updateLighting(enum LightBank bank,
// For debugging
//bool debug=true;
//u32 count_was = modified_blocks.size();
+
+ core::map<v3s16, MapBlock*> blocks_to_update;
core::map<v3s16, bool> light_sources;
@@ -650,6 +662,8 @@ void Map::updateLighting(enum LightBank bank,
v3s16 pos = block->getPos();
modified_blocks.insert(pos, block);
+ blocks_to_update.insert(pos, block);
+
/*
Clear all light from block
*/
@@ -699,10 +713,12 @@ void Map::updateLighting(enum LightBank bank,
}
else if(bank == LIGHTBANK_NIGHT)
{
+ // For night lighting, sunlight is not propagated
break;
}
else
{
+ // Invalid lighting bank
assert(0);
}
@@ -710,7 +726,7 @@ void Map::updateLighting(enum LightBank bank,
<<pos.X<<","<<pos.Y<<","<<pos.Z<<") not valid"
<<std::endl;*/
- // Else get the block below and loop to it
+ // Bottom sunlight is not valid; get the block and loop to it
pos.Y--;
try{
@@ -737,13 +753,6 @@ void Map::updateLighting(enum LightBank bank,
dstream<<"unspreadLight modified "<<diff<<std::endl;
}
- // TODO: Spread light from propagated sunlight?
- // Yes, add it to light_sources... somehow.
- // It has to be added at somewhere above, in the loop.
- // TODO
- // NOTE: This actually works fine without doing so
- // - Find out why it works
-
{
TimeTaker timer("spreadLight");
spreadLight(bank, light_sources, modified_blocks);
@@ -759,17 +768,44 @@ void Map::updateLighting(enum LightBank bank,
{
//MapVoxelManipulator vmanip(this);
-
- ManualMapVoxelManipulator vmanip(this);
+ // Make a manual voxel manipulator and load all the blocks
+ // that touch the requested blocks
+ ManualMapVoxelManipulator vmanip(this);
core::map<v3s16, MapBlock*>::Iterator i;
- i = a_blocks.getIterator();
+ i = blocks_to_update.getIterator();
for(; i.atEnd() == false; i++)
{
MapBlock *block = i.getNode()->getValue();
v3s16 p = block->getPos();
+
+ // Add all surrounding blocks
vmanip.initialEmerge(p - v3s16(1,1,1), p + v3s16(1,1,1));
+
+ /*
+ Add all surrounding blocks that have up-to-date lighting
+ NOTE: This doesn't quite do the job (not everything
+ appropriate is lighted)
+ */
+ /*for(s16 z=-1; z<=1; z++)
+ for(s16 y=-1; y<=1; y++)
+ for(s16 x=-1; x<=1; x++)
+ {
+ v3s16 p(x,y,z);
+ MapBlock *block = getBlockNoCreateNoEx(p);
+ if(block == NULL)
+ continue;
+ if(block->isDummy())
+ continue;
+ if(block->getLightingExpired())
+ continue;
+ vmanip.initialEmerge(p, p);
+ }*/
+
+ // Lighting of block will be updated completely
+ block->setLightingExpired(false);
}
+
{
//TimeTaker timer("unSpreadLight");
vmanip.unspreadLight(bank, unlight_from, light_sources);
@@ -1407,6 +1443,8 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
u32 loopcount = 0;
u32 initial_size = m_transforming_liquid.size();
+ //dstream<<"transformLiquids(): initial_size="<<initial_size<<std::endl;
+
while(m_transforming_liquid.size() != 0)
{
/*
@@ -1682,6 +1720,12 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp):
Map(dout_server),
m_heightmap(NULL)
{
+
+ //m_chunksize = 64;
+ //m_chunksize = 16;
+ //m_chunksize = 8;
+ m_chunksize = 2;
+
/*
Experimental and debug stuff
*/
@@ -1862,7 +1906,7 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp):
list_randmax->addPoint(v3s16(0,0,0), Attribute(10));
list_randfactor->addPoint(v3s16(0,0,0), Attribute(0.65));*/
}
-
+
/*
Try to load map; if not found, create a new one.
*/
@@ -1917,18 +1961,6 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp):
dstream<<DTIME<<"Initializing new map."<<std::endl;
// Create master heightmap
- /*ValueGenerator *maxgen =
- ValueGenerator::deSerialize(hmp.randmax);
- ValueGenerator *factorgen =
- ValueGenerator::deSerialize(hmp.randfactor);
- ValueGenerator *basegen =
- ValueGenerator::deSerialize(hmp.base);
- m_heightmap = new UnlimitedHeightmap
- (hmp.blocksize, maxgen, factorgen, basegen, &m_padb);*/
-
- /*m_heightmap = new UnlimitedHeightmap
- (hmp.blocksize, &m_padb);*/
-
m_heightmap = new UnlimitedHeightmap
(32, &m_padb);
@@ -1966,30 +1998,135 @@ ServerMap::~ServerMap()
if(m_heightmap != NULL)
delete m_heightmap;
+
+ /*
+ Free all MapChunks
+ */
+ core::map<v2s16, MapChunk*>::Iterator i = m_chunks.getIterator();
+ for(; i.atEnd() == false; i++)
+ {
+ MapChunk *chunk = i.getNode()->getValue();
+ delete chunk;
+ }
}
-MapSector * ServerMap::emergeSector(v2s16 p2d)
+MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos)
{
- DSTACK("%s: p2d=(%d,%d)",
- __FUNCTION_NAME,
- p2d.X, p2d.Y);
- // Check that it doesn't exist already
- try{
- return getSectorNoGenerate(p2d);
+ // Return if chunk already exists
+ MapChunk *chunk = getChunk(chunkpos);
+ if(chunk)
+ return chunk;
+
+ /*
+ Add all sectors
+ */
+
+ dstream<<"generateChunkRaw(): "
+ <<"("<<chunkpos.X<<","<<chunkpos.Y<<")"
+ <<std::endl;
+
+ TimeTaker timer("generateChunkRaw()");
+
+ v2s16 sectorpos_base = chunk_to_sector(chunkpos);
+
+ core::map<v3s16, MapBlock*> changed_blocks;
+ core::map<v3s16, MapBlock*> lighting_invalidated_blocks;
+
+ u32 generated_block_count = 0;
+
+ for(s16 y=0; y<m_chunksize; y++)
+ {
+ /*dstream<<"Generating sectors "
+ <<"("<<sectorpos_base.X<<"..."
+ <<(sectorpos_base.X+m_chunksize-1)
+ <<", "<<y<<")"
+ <<std::endl;*/
+
+ // With caves_amount attribute fetch: ~90ms (379ms peaks)
+ // Without: ~38ms (396ms peaks)
+ //TimeTaker timer("Chunk sector row");
+
+ for(s16 x=0; x<m_chunksize; x++)
+ {
+ v2s16 sectorpos = sectorpos_base + v2s16(x,y);
+
+ /*dstream<<"Generating sector "
+ <<"("<<sectorpos.X<<","<<sectorpos.Y<<")"
+ <<std::endl;*/
+
+ // Generate sector
+ ServerMapSector *sector = generateSector(sectorpos);
+
+ /*
+ Generate main blocks of sector
+ */
+ s16 d = 8;
+ for(s16 y2=-d/2; y2<d/2; y2++)
+ {
+ v3s16 p(x,y2,y);
+
+ // Check that the block doesn't exist already
+ if(sector->getBlockNoCreateNoEx(y2))
+ continue;
+
+ generateBlock(p, NULL, sector, changed_blocks,
+ lighting_invalidated_blocks);
+
+ generated_block_count++;
+ }
+ }
}
- catch(InvalidPositionException &e)
+
+ dstream<<"generateChunkRaw generated "<<generated_block_count
+ <<" blocks"<<std::endl;
+
{
+ TimeTaker timer2("generateChunkRaw() lighting");
+ // Update lighting
+ core::map<v3s16, MapBlock*> lighting_modified_blocks;
+ updateLighting(lighting_invalidated_blocks, lighting_modified_blocks);
}
+ // Add chunk meta information
+ chunk = new MapChunk();
+ m_chunks.insert(chunkpos, chunk);
+ return chunk;
+}
+
+MapChunk* ServerMap::generateChunk(v2s16 chunkpos)
+{
/*
- Try to load the sector from disk.
+ Generate chunk and neighbors
*/
- if(loadSectorFull(p2d) == true)
+ for(s16 x=-1; x<=1; x++)
+ for(s16 y=-1; y<=1; y++)
{
- return getSectorNoGenerate(p2d);
+ generateChunkRaw(chunkpos + v2s16(x,y));
}
/*
+ Get chunk
+ */
+ MapChunk *chunk = getChunk(chunkpos);
+ assert(chunk);
+ // Set non-volatile
+ chunk->setIsVolatile(false);
+ // Return it
+ return chunk;
+}
+
+ServerMapSector * ServerMap::generateSector(v2s16 p2d)
+{
+ DSTACK("%s: p2d=(%d,%d)",
+ __FUNCTION_NAME,
+ p2d.X, p2d.Y);
+
+ // Check that it doesn't exist already
+ ServerMapSector *sector = (ServerMapSector*)getSectorNoGenerateNoEx(p2d);
+ if(sector != NULL)
+ return sector;
+
+ /*
If there is no master heightmap, throw.
*/
if(m_heightmap == NULL)
@@ -2016,7 +2153,7 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
// Heightmap side width
s16 hm_d = MAP_BLOCKSIZE / hm_split;
- ServerMapSector *sector = new ServerMapSector(this, p2d, hm_split);
+ sector = new ServerMapSector(this, p2d, hm_split);
// Sector position on map in nodes
v2s16 nodepos2d = p2d * MAP_BLOCKSIZE;
@@ -2068,7 +2205,9 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
Get local attributes
*/
- float local_plants_amount = 0.0;
+ float local_plants_amount = 0.5;
+
+#if 0
{
//dstream<<"emergeSector(): Reading point attribute lists"<<std::endl;
//TimeTaker attrtimer("emergeSector() attribute fetch");
@@ -2081,6 +2220,7 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
local_plants_amount =
palist->getInterpolatedFloat(nodepos2d);
}
+#endif
/*
Generate sector heightmap
@@ -2201,92 +2341,105 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
/*
Insert to container
*/
- JMutexAutoLock lock(m_sector_mutex);
m_sectors.insert(p2d, sector);
return sector;
}
-MapBlock * ServerMap::emergeBlock(
- v3s16 p,
- bool only_from_disk,
- core::map<v3s16, MapBlock*> &changed_blocks,
- core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
-)
+MapSector * ServerMap::emergeSector(v2s16 p2d)
{
- DSTACK("%s: p=(%d,%d,%d), only_from_disk=%d",
+ DSTACK("%s: p2d=(%d,%d)",
__FUNCTION_NAME,
- p.X, p.Y, p.Z, only_from_disk);
-
- /*dstream<<"ServerMap::emergeBlock(): "
- <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
- <<", only_from_disk="<<only_from_disk<<std::endl;*/
- v2s16 p2d(p.X, p.Z);
- s16 block_y = p.Y;
+ p2d.X, p2d.Y);
+
/*
- This will create or load a sector if not found in memory.
- If block exists on disk, it will be loaded.
-
- NOTE: On old save formats, this will be slow, as it generates
- lighting on blocks for them.
+ Check if it exists already in memory
*/
- ServerMapSector *sector = (ServerMapSector*)emergeSector(p2d);
- assert(sector->getId() == MAPSECTOR_SERVER);
-
- // Try to get a block from the sector
- MapBlock *block = NULL;
- bool not_on_disk = false;
- try{
- block = sector->getBlockNoCreate(block_y);
- if(block->isDummy() == true)
- not_on_disk = true;
- else
- return block;
- }
- catch(InvalidPositionException &e)
- {
- not_on_disk = true;
- }
+ MapSector *sector = getSectorNoGenerateNoEx(p2d);
+ if(sector != NULL)
+ return sector;
/*
- If block was not found on disk and not going to generate a
- new one, make sure there is a dummy block in place.
+ Try to load it from disk
*/
- if(not_on_disk && only_from_disk)
+ if(loadSectorFull(p2d) == true)
{
- if(block == NULL)
+ MapSector *sector = getSectorNoGenerateNoEx(p2d);
+ if(sector == NULL)
{
- // Create dummy block
- block = new MapBlock(this, p, true);
-
- // Add block to sector
- sector->insertBlock(block);
+ dstream<<"ServerMap::emergeSector(): loadSectorFull didn't make a sector"<<std::endl;
+ throw InvalidPositionException("");
}
- // Done.
- return block;
+ return sector;
}
- //dstream<<"Not found on disk, generating."<<std::endl;
- // 0ms
- //TimeTaker("emergeBlock() generate");
-
/*
- Do not generate over-limit
+ Check chunk status
*/
- if(blockpos_over_limit(p))
- throw InvalidPositionException("emergeBlock(): pos. over limit");
+ v2s16 chunkpos = sector_to_chunk(p2d);
+ bool chunk_exists = false;
+ MapChunk *chunk = getChunk(chunkpos);
+ if(chunk && chunk->getIsVolatile() == false)
+ chunk_exists = true;
/*
- OK; Not found.
-
- Go on generating the block.
+ If chunk is not generated, generate chunk
+ */
+ if(chunk_exists == false)
+ {
+ // Generate chunk and neighbors
+ generateChunk(chunkpos);
+ }
+
+ /*
+ Return sector if it exists now
+ */
+ sector = getSectorNoGenerateNoEx(p2d);
+ if(sector != NULL)
+ return sector;
+
+ /*
+ generateChunk should have generated the sector
+ */
+ assert(0);
- TODO: If a dungeon gets generated so that it's side gets
- revealed to the outside air, the lighting should be
- recalculated.
+ /*
+ Generate directly
*/
+ //return generateSector();
+}
+
+MapBlock * ServerMap::generateBlock(
+ v3s16 p,
+ MapBlock *original_dummy,
+ ServerMapSector *sector,
+ core::map<v3s16, MapBlock*> &changed_blocks,
+ core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
+)
+{
+ DSTACK("%s: p=(%d,%d,%d)",
+ __FUNCTION_NAME,
+ p.X, p.Y, p.Z);
+
+ /*dstream<<"generateBlock(): "
+ <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
+ <<std::endl;*/
+
+ MapBlock *block = original_dummy;
+
+ v2s16 p2d(p.X, p.Z);
+ s16 block_y = p.Y;
/*
+ Do not generate over-limit
+ */
+ if(blockpos_over_limit(p))
+ {
+ dstream<<__FUNCTION_NAME<<": Block position over limit"<<std::endl;
+ throw InvalidPositionException("generateBlock(): pos. over limit");
+ }
+
+ /*
If block doesn't exist, create one.
If it exists, it is a dummy. In that case unDummify() it.
@@ -2318,7 +2471,7 @@ MapBlock * ServerMap::emergeBlock(
for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
{
- //dstream<<"emergeBlock: x0="<<x0<<", z0="<<z0<<std::endl;
+ //dstream<<"generateBlock: x0="<<x0<<", z0="<<z0<<std::endl;
float surface_y_f = sector->getGroundHeight(v2s16(x0,z0));
//assert(surface_y_f > GROUNDHEIGHT_VALID_MINVALUE);
@@ -2451,23 +2604,25 @@ MapBlock * ServerMap::emergeBlock(
Get local attributes
*/
- //dstream<<"emergeBlock(): Getting local attributes"<<std::endl;
+ //dstream<<"generateBlock(): Getting local attributes"<<std::endl;
- float caves_amount = 0;
-
+ float caves_amount = 0.5;
+
+#if 0
{
/*
NOTE: BEWARE: Too big amount of attribute points slows verything
down by a lot.
1 interpolation from 5000 points takes 2-3ms.
*/
- //TimeTaker timer("emergeBlock() local attribute retrieval");
+ //TimeTaker timer("generateBlock() local attribute retrieval");
v2s16 nodepos2d = p2d * MAP_BLOCKSIZE;
PointAttributeList *list_caves_amount = m_padb.getList("caves_amount");
caves_amount = list_caves_amount->getInterpolatedFloat(nodepos2d);
}
+#endif
- //dstream<<"emergeBlock(): Done"<<std::endl;
+ //dstream<<"generateBlock(): Done"<<std::endl;
/*
Generate dungeons
@@ -2617,10 +2772,10 @@ continue_generating:
do_generate_dungeons = false;
}
// Don't generate if mostly underwater surface
- else if(mostly_underwater_surface)
+ /*else if(mostly_underwater_surface)
{
do_generate_dungeons = false;
- }
+ }*/
// Partly underground = cave
else if(!completely_underground)
{
@@ -2723,7 +2878,7 @@ continue_generating:
/*
This is used for guessing whether or not the block should
- receive sunlight from the top if the top block doesn't exist
+ receive sunlight from the top if the block above doesn't exist
*/
block->setIsUnderground(completely_underground);
@@ -3075,7 +3230,7 @@ continue_generating:
}
else
{
- dstream<<"ServerMap::emergeBlock(): "
+ dstream<<"ServerMap::generateBlock(): "
"Invalid heightmap object"
<<std::endl;
}
@@ -3098,6 +3253,148 @@ continue_generating:
{
objects->remove(*i);
}
+
+ /*
+ Translate sector's changed blocks to global changed blocks
+ */
+
+ for(core::map<s16, MapBlock*>::Iterator
+ i = changed_blocks_sector.getIterator();
+ i.atEnd() == false; i++)
+ {
+ MapBlock *block = i.getNode()->getValue();
+
+ changed_blocks.insert(block->getPos(), block);
+ }
+
+ block->setLightingExpired(true);
+
+#if 0
+ /*
+ Debug information
+ */
+ dstream
+ <<"lighting_invalidated_blocks.size()"
+ <<", has_dungeons"
+ <<", completely_ug"
+ <<", some_part_ug"
+ <<" "<<lighting_invalidated_blocks.size()
+ <<", "<<has_dungeons
+ <<", "<<completely_underground
+ <<", "<<some_part_underground
+ <<std::endl;
+#endif
+
+ return block;
+}
+
+MapBlock * ServerMap::emergeBlock(
+ v3s16 p,
+ bool only_from_disk,
+ core::map<v3s16, MapBlock*> &changed_blocks,
+ core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
+)
+{
+ DSTACK("%s: p=(%d,%d,%d), only_from_disk=%d",
+ __FUNCTION_NAME,
+ p.X, p.Y, p.Z, only_from_disk);
+
+ /*dstream<<"emergeBlock(): "
+ <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
+ <<std::endl;*/
+
+ v2s16 p2d(p.X, p.Z);
+ s16 block_y = p.Y;
+ /*
+ This will create or load a sector if not found in memory.
+ If block exists on disk, it will be loaded.
+
+ NOTE: On old save formats, this will be slow, as it generates
+ lighting on blocks for them.
+ */
+ ServerMapSector *sector;
+ try{
+ sector = (ServerMapSector*)emergeSector(p2d);
+ assert(sector->getId() == MAPSECTOR_SERVER);
+ }
+ /*catch(InvalidPositionException &e)
+ {
+ dstream<<"emergeBlock: emergeSector() failed"<<std::endl;
+ throw e;
+ }*/
+ catch(std::exception &e)
+ {
+ dstream<<"emergeBlock: emergeSector() failed: "
+ <<e.what()<<std::endl;
+ throw e;
+ }
+
+ /*
+ Try to get a block from the sector
+ */
+
+ bool does_not_exist = false;
+ bool lighting_expired = false;
+ MapBlock *block = sector->getBlockNoCreateNoEx(block_y);
+
+ if(block == NULL)
+ {
+ does_not_exist = true;
+ }
+ else if(block->isDummy() == true)
+ {
+ does_not_exist = true;
+ }
+ else if(block->getLightingExpired())
+ {
+ lighting_expired = true;
+ }
+ else
+ {
+ // Valid block
+ //dstream<<"emergeBlock(): Returning already valid block"<<std::endl;
+ return block;
+ }
+
+ /*
+ If block was not found on disk and not going to generate a
+ new one, make sure there is a dummy block in place.
+ */
+ if(only_from_disk && (does_not_exist || lighting_expired))
+ {
+ //dstream<<"emergeBlock(): Was not on disk but not generating"<<std::endl;
+
+ if(block == NULL)
+ {
+ // Create dummy block
+ block = new MapBlock(this, p, true);
+
+ // Add block to sector
+ sector->insertBlock(block);
+ }
+ // Done.
+ return block;
+ }
+
+ //dstream<<"Not found on disk, generating."<<std::endl;
+ // 0ms
+ //TimeTaker("emergeBlock() generate");
+
+ //dstream<<"emergeBlock(): Didn't find valid block -> making one"<<std::endl;
+
+ /*
+ If the block doesn't exist, generate the block.
+ */
+ if(does_not_exist)
+ {
+ block = generateBlock(p, block, sector, changed_blocks,
+ lighting_invalidated_blocks);
+ }
+
+ if(lighting_expired)
+ {
+ lighting_invalidated_blocks.insert(p, block);
+ }
/*
Initially update sunlight
@@ -3112,7 +3409,8 @@ continue_generating:
// If sunlight didn't reach everywhere and part of block is
// above ground, lighting has to be properly updated
- if(black_air_left && some_part_underground)
+ //if(black_air_left && some_part_underground)
+ if(black_air_left)
{
lighting_invalidated_blocks[block->getPos()] = block;
}
@@ -3122,37 +3420,7 @@ continue_generating:
lighting_invalidated_blocks[block->getPos()] = block;
}
}
-
- /*
- Translate sector's changed blocks to global changed blocks
- */
- for(core::map<s16, MapBlock*>::Iterator
- i = changed_blocks_sector.getIterator();
- i.atEnd() == false; i++)
- {
- MapBlock *block = i.getNode()->getValue();
-
- changed_blocks.insert(block->getPos(), block);
- }
-
- /*
- Debug information
- */
- if(0)
- {
- dstream
- <<"lighting_invalidated_blocks.size()"
- <<", has_dungeons"
- <<", completely_ug"
- <<", some_part_ug"
- <<" "<<lighting_invalidated_blocks.size()
- <<", "<<has_dungeons
- <<", "<<completely_underground
- <<", "<<some_part_underground
- <<std::endl;
- }
-
/*
Debug mode operation
*/
diff --git a/src/map.h b/src/map.h
index 9140d4bf2..bc6984c88 100644
--- a/src/map.h
+++ b/src/map.h
@@ -40,6 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapsector.h"
#include "constants.h"
#include "voxel.h"
+#include "mapchunk.h"
#define MAPTYPE_BASE 0
#define MAPTYPE_SERVER 1
@@ -85,9 +86,14 @@ public:
(float)p.Z * BS + 0.5*BS
);
}
-
- //bool sectorExists(v2s16 p);
+
+ // On failure returns NULL
+ MapSector * getSectorNoGenerateNoExNoLock(v2s16 p2d);
+ // On failure returns NULL
+ MapSector * getSectorNoGenerateNoEx(v2s16 p2d);
+ // On failure throws InvalidPositionException
MapSector * getSectorNoGenerate(v2s16 p2d);
+
/*
This is overloaded by ClientMap and ServerMap to allow
their differing fetch methods.
@@ -318,9 +324,90 @@ public:
}
/*
- Forcefully get a sector from somewhere
+ Map generation
+ */
+
+ // Returns the position of the chunk where the sector is in
+ v2s16 sector_to_chunk(v2s16 sectorpos)
+ {
+ sectorpos.X += m_chunksize / 2;
+ sectorpos.Y += m_chunksize / 2;
+ v2s16 chunkpos = getContainerPos(sectorpos, m_chunksize);
+ return chunkpos;
+ }
+
+ // Returns the position of the (0,0) sector of the chunk
+ v2s16 chunk_to_sector(v2s16 chunkpos)
+ {
+ v2s16 sectorpos(
+ chunkpos.X * m_chunksize,
+ chunkpos.Y * m_chunksize
+ );
+ sectorpos.X -= m_chunksize / 2;
+ sectorpos.Y -= m_chunksize / 2;
+ return sectorpos;
+ }
+
+ /*
+ Get a chunk.
+ */
+ MapChunk *getChunk(v2s16 chunkpos)
+ {
+ core::map<v2s16, MapChunk*>::Node *n;
+ n = m_chunks.find(chunkpos);
+ if(n == NULL)
+ return NULL;
+ return n->getValue();
+ }
+
+ /*
+ Generate a chunk.
+
+ All chunks touching this one can be altered also.
+
+ Doesn't update lighting.
+ */
+ MapChunk* generateChunkRaw(v2s16 chunkpos);
+
+ /*
+ Generate a chunk and its neighbors so that it won't be touched
+ anymore.
+
+ Doesn't update lighting.
+ */
+ MapChunk* generateChunk(v2s16 chunkpos);
+
+ /*
+ Generate a sector.
+
+ This is mainly called by generateChunkRaw.
+ */
+ ServerMapSector * generateSector(v2s16 p);
+
+ /*
+ Get a sector from somewhere.
+ - Check memory
+ - Check disk
+ - Generate chunk
*/
MapSector * emergeSector(v2s16 p);
+
+ MapBlock * generateBlock(
+ v3s16 p,
+ MapBlock *original_dummy,
+ ServerMapSector *sector,
+ core::map<v3s16, MapBlock*> &changed_blocks,
+ core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
+ );
+
+ MapBlock * emergeBlock(
+ v3s16 p,
+ bool only_from_disk,
+ core::map<v3s16, MapBlock*> &changed_blocks,
+ core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
+ );
+
+#if 0
/*
Forcefully get a block from somewhere.
@@ -346,7 +433,12 @@ public:
core::map<v3s16, MapBlock*> &changed_blocks,
core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
);
+#endif
+ /*
+ Misc. helper functions for fiddling with directory and file
+ names when saving
+ */
void createDir(std::string path);
void createSaveDir();
// returns something like "xxxxxxxx"
@@ -396,8 +488,17 @@ private:
std::string m_savedir;
bool m_map_saving_enabled;
+
+ // Chunk size in MapSectors
+ s16 m_chunksize;
+ // Chunks
+ core::map<v2s16, MapChunk*> m_chunks;
};
+/*
+ ClientMap stuff
+*/
+
#ifndef SERVER
struct MapDrawControl
diff --git a/src/mapblock.cpp b/src/mapblock.cpp
index b346b0980..a7bc730ce 100644
--- a/src/mapblock.cpp
+++ b/src/mapblock.cpp
@@ -293,7 +293,8 @@ void MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
Gets node tile from any place relative to block.
Returns TILE_NODE if doesn't exist or should not be drawn.
*/
-TileSpec MapBlock::getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir)
+TileSpec MapBlock::getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
+ NodeModMap &temp_mods)
{
TileSpec spec;
spec = mn.getTile(face_dir);
@@ -301,13 +302,15 @@ TileSpec MapBlock::getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir)
/*
Check temporary modifications on this node
*/
- core::map<v3s16, NodeMod>::Node *n;
+ /*core::map<v3s16, NodeMod>::Node *n;
n = m_temp_mods.find(p);
-
// If modified
if(n != NULL)
{
- struct NodeMod mod = n->getValue();
+ struct NodeMod mod = n->getValue();*/
+ NodeMod mod;
+ if(temp_mods.get(p, &mod))
+ {
if(mod.type == NODEMOD_CHANGECONTENT)
{
MapNode mn2(mod.param);
@@ -326,18 +329,20 @@ TileSpec MapBlock::getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir)
return spec;
}
-u8 MapBlock::getNodeContent(v3s16 p, MapNode mn)
+u8 MapBlock::getNodeContent(v3s16 p, MapNode mn, NodeModMap &temp_mods)
{
/*
Check temporary modifications on this node
*/
- core::map<v3s16, NodeMod>::Node *n;
+ /*core::map<v3s16, NodeMod>::Node *n;
n = m_temp_mods.find(p);
-
// If modified
if(n != NULL)
{
- struct NodeMod mod = n->getValue();
+ struct NodeMod mod = n->getValue();*/
+ NodeMod mod;
+ if(temp_mods.get(p, &mod))
+ {
if(mod.type == NODEMOD_CHANGECONTENT)
{
// Overrides content
@@ -376,7 +381,8 @@ void MapBlock::updateFastFaceRow(
v3f translate_dir_f,
v3s16 face_dir,
v3f face_dir_f,
- core::array<FastFace> &dest)
+ core::array<FastFace> &dest,
+ NodeModMap &temp_mods)
{
v3s16 p = startpos;
@@ -387,8 +393,8 @@ void MapBlock::updateFastFaceRow(
u8 light = getFaceLight(daynight_ratio, n0, n1, face_dir);
- TileSpec tile0 = getNodeTile(n0, p, face_dir);
- TileSpec tile1 = getNodeTile(n1, p + face_dir, -face_dir);
+ TileSpec tile0 = getNodeTile(n0, p, face_dir, temp_mods);
+ TileSpec tile1 = getNodeTile(n1, p + face_dir, -face_dir, temp_mods);
for(u16 j=0; j<length; j++)
{
@@ -406,8 +412,8 @@ void MapBlock::updateFastFaceRow(
p_next = p + translate_dir;
n0_next = getNodeParentNoEx(p_next);
n1_next = getNodeParentNoEx(p_next + face_dir);
- tile0_next = getNodeTile(n0_next, p_next, face_dir);
- tile1_next = getNodeTile(n1_next, p_next + face_dir, -face_dir);
+ tile0_next = getNodeTile(n0_next, p_next, face_dir, temp_mods);
+ tile1_next = getNodeTile(n1_next,p_next+face_dir,-face_dir, temp_mods);
light_next = getFaceLight(daynight_ratio, n0_next, n1_next, face_dir);
if(tile0_next == tile0
@@ -427,8 +433,8 @@ void MapBlock::updateFastFaceRow(
*/
//u8 mf = face_contents(tile0, tile1);
// This is hackish
- u8 content0 = getNodeContent(p, n0);
- u8 content1 = getNodeContent(p + face_dir, n1);
+ u8 content0 = getNodeContent(p, n0, temp_mods);
+ u8 content1 = getNodeContent(p + face_dir, n1, temp_mods);
u8 mf = face_contents(content0, content1);
if(mf != 0)
@@ -594,6 +600,16 @@ void MapBlock::updateMesh(u32 daynight_ratio)
v3f posRelative_f(getPosRelative().X, getPosRelative().Y,
getPosRelative().Z); // floating point conversion
+
+ /*
+ Avoid interlocks by copying m_temp_mods
+ */
+ NodeModMap temp_mods;
+ {
+ JMutexAutoLock lock(m_temp_mods_mutex);
+ m_temp_mods.copy(temp_mods);
+ }
+
/*
We are including the faces of the trailing edges of the block.
This means that when something changes, the caller must
@@ -606,9 +622,6 @@ void MapBlock::updateMesh(u32 daynight_ratio)
// 4-23ms for MAP_BLOCKSIZE=16
//TimeTaker timer2("updateMesh() collect");
- // Lock this, as m_temp_mods will be used directly
- JMutexAutoLock lock(m_temp_mods_mutex);
-
/*
Go through every y,z and get top faces in rows of x+
*/
@@ -620,7 +633,8 @@ void MapBlock::updateMesh(u32 daynight_ratio)
v3f (1,0,0),
v3s16(0,1,0), //face dir
v3f (0,1,0),
- fastfaces_new);
+ fastfaces_new,
+ temp_mods);
}
}
/*
@@ -634,7 +648,8 @@ void MapBlock::updateMesh(u32 daynight_ratio)
v3f (0,0,1),
v3s16(1,0,0),
v3f (1,0,0),
- fastfaces_new);
+ fastfaces_new,
+ temp_mods);
}
}
/*
@@ -648,7 +663,8 @@ void MapBlock::updateMesh(u32 daynight_ratio)
v3f (1,0,0),
v3s16(0,0,1),
v3f (0,0,1),
- fastfaces_new);
+ fastfaces_new,
+ temp_mods);
}
}
}
@@ -1297,10 +1313,6 @@ void MapBlock::copyTo(VoxelManipulator &dst)
getPosRelative(), data_size);
}
-/*void getPseudoObjects(v3f origin, f32 max_d,
- core::array<DistanceSortedObject> &dest)
-{
-}*/
void MapBlock::stepObjects(float dtime, bool server, u32 daynight_ratio)
{
/*
@@ -1501,6 +1513,8 @@ void MapBlock::serialize(std::ostream &os, u8 version)
flags |= 1;
if(m_day_night_differs)
flags |= 2;
+ if(m_lighting_expired)
+ flags |= 3;
os.write((char*)&flags, 1);
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
@@ -1622,6 +1636,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
is.read((char*)&flags, 1);
is_underground = (flags & 1) ? true : false;
m_day_night_differs = (flags & 2) ? true : false;
+ m_lighting_expired = (flags & 3) ? true : false;
// Uncompress data
std::ostringstream os(std::ios_base::binary);
diff --git a/src/mapblock.h b/src/mapblock.h
index dd5277668..e39db35bd 100644
--- a/src/mapblock.h
+++ b/src/mapblock.h
@@ -70,6 +70,74 @@ struct NodeMod
u16 param;
};
+class NodeModMap
+{
+public:
+ /*
+ returns true if the mod was different last time
+ */
+ bool set(v3s16 p, const NodeMod &mod)
+ {
+ // See if old is different, cancel if it is not different.
+ core::map<v3s16, NodeMod>::Node *n = m_mods.find(p);
+ if(n)
+ {
+ NodeMod old = n->getValue();
+ if(old == mod)
+ return false;
+
+ n->setValue(mod);
+ }
+ else
+ {
+ m_mods.insert(p, mod);
+ }
+
+ return true;
+ }
+ // Returns true if there was one
+ bool get(v3s16 p, NodeMod *mod)
+ {
+ core::map<v3s16, NodeMod>::Node *n;
+ n = m_mods.find(p);
+ if(n == NULL)
+ return false;
+ if(mod)
+ *mod = n->getValue();
+ return true;
+ }
+ bool clear(v3s16 p)
+ {
+ if(m_mods.find(p))
+ {
+ m_mods.remove(p);
+ return true;
+ }
+ return false;
+ }
+ bool clear()
+ {
+ if(m_mods.size() == 0)
+ return false;
+ m_mods.clear();
+ return true;
+ }
+ void copy(NodeModMap &dest)
+ {
+ dest.m_mods.clear();
+
+ for(core::map<v3s16, NodeMod>::Iterator
+ i = m_mods.getIterator();
+ i.atEnd() == false; i++)
+ {
+ dest.m_mods.insert(i.getNode()->getKey(), i.getNode()->getValue());
+ }
+ }
+
+private:
+ core::map<v3s16, NodeMod> m_mods;
+};
+
enum
{
NODECONTAINER_ID_MAPBLOCK,
@@ -104,11 +172,26 @@ public:
return m_parent;
}
+ void reallocate()
+ {
+ if(data != NULL)
+ delete[] data;
+ u32 l = MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE;
+ data = new MapNode[l];
+ for(u32 i=0; i<l; i++){
+ data[i] = MapNode();
+ }
+ setChangedFlag();
+ }
+
+ /*
+ Flags
+ */
+
bool isDummy()
{
return (data == NULL);
}
-
void unDummify()
{
assert(isDummy());
@@ -119,16 +202,26 @@ public:
{
return changed;
}
-
void resetChangedFlag()
{
changed = false;
}
-
void setChangedFlag()
{
changed = true;
}
+
+ bool getIsUnderground()
+ {
+ return is_underground;
+ }
+
+ void setIsUnderground(bool a_is_underground)
+ {
+ is_underground = a_is_underground;
+ setChangedFlag();
+ }
+
#ifndef SERVER
void setMeshExpired(bool expired)
{
@@ -140,6 +233,30 @@ public:
return m_mesh_expired;
}
#endif
+
+ void setLightingExpired(bool expired)
+ {
+ m_lighting_expired = expired;
+ setChangedFlag();
+ }
+ bool getLightingExpired()
+ {
+ return m_lighting_expired;
+ }
+
+ bool isValid()
+ {
+ if(m_lighting_expired)
+ return false;
+ if(data == NULL)
+ return false;
+ return true;
+ }
+
+ /*
+ Position stuff
+ */
+
v3s16 getPos()
{
return m_pos;
@@ -150,17 +267,6 @@ public:
return m_pos * MAP_BLOCKSIZE;
}
- bool getIsUnderground()
- {
- return is_underground;
- }
-
- void setIsUnderground(bool a_is_underground)
- {
- is_underground = a_is_underground;
- setChangedFlag();
- }
-
core::aabbox3d<s16> getBox()
{
return core::aabbox3d<s16>(getPosRelative(),
@@ -168,19 +274,11 @@ public:
+ v3s16(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE)
- v3s16(1,1,1));
}
-
- void reallocate()
- {
- if(data != NULL)
- delete[] data;
- u32 l = MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE;
- data = new MapNode[l];
- for(u32 i=0; i<l; i++){
- data[i] = MapNode();
- }
- setChangedFlag();
- }
+ /*
+ Regular MapNode get-setters
+ */
+
bool isValidPosition(v3s16 p)
{
if(data == NULL)
@@ -190,10 +288,6 @@ public:
&& p.Z >= 0 && p.Z < MAP_BLOCKSIZE);
}
- /*
- Regular MapNode get-setters
- */
-
MapNode getNode(s16 x, s16 y, s16 z)
{
if(data == NULL)
@@ -271,9 +365,14 @@ public:
setNode(x0+x, y0+y, z0+z, node);
}
+ /*
+ Graphics-related methods
+ */
+
+ // A quick version with nodes passed as parameters
u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
v3s16 face_dir);
-
+ // A more convenient version
u8 getFaceLight(u32 daynight_ratio, v3s16 p, v3s16 face_dir)
{
return getFaceLight(daynight_ratio,
@@ -288,11 +387,16 @@ public:
v3s16 dir, v3f scale, v3f posRelative_f,
core::array<FastFace> &dest);
- TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir);
- u8 getNodeContent(v3s16 p, MapNode mn);
+ TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
+ NodeModMap &temp_mods);
+ u8 getNodeContent(v3s16 p, MapNode mn,
+ NodeModMap &temp_mods);
/*
- startpos:
+ Generates the FastFaces of a node row. This has a
+ ridiculous amount of parameters because that way they
+ can be precalculated by the caller.
+
translate_dir: unit vector with only one of x, y or z
face_dir: unit vector with only one of x, y or z
*/
@@ -305,12 +409,14 @@ public:
v3f translate_dir_f,
v3s16 face_dir,
v3f face_dir_f,
- core::array<FastFace> &dest);
-
+ core::array<FastFace> &dest,
+ NodeModMap &temp_mods);
+
+ /*
+ Thread-safely updates the whole mesh of the mapblock.
+ */
void updateMesh(u32 daynight_ratio);
- /*void updateMesh(s32 daynight_i);
- // Updates all DAYNIGHT_CACHE_COUNT meshes
- void updateMeshes(s32 first_i=0);*/
+
#endif // !SERVER
// See comments in mapblock.cpp
@@ -322,7 +428,7 @@ public:
void copyTo(VoxelManipulator &dst);
/*
- Object stuff
+ MapBlockObject stuff
*/
void serializeObjects(std::ostream &os, u8 version)
@@ -384,9 +490,6 @@ public:
m_objects.getObjects(origin, max_d, dest);
}
- /*void getPseudoObjects(v3f origin, f32 max_d,
- core::array<DistanceSortedObject> &dest);*/
-
s32 getObjectCount()
{
return m_objects.getCount();
@@ -399,7 +502,7 @@ public:
returns true if the mod was different last time
*/
- bool setTempMod(v3s16 p, NodeMod mod)
+ bool setTempMod(v3s16 p, const NodeMod &mod)
{
/*dstream<<"setTempMod called on block"
<<" ("<<p.X<<","<<p.Y<<","<<p.Z<<")"
@@ -408,52 +511,33 @@ public:
<<std::endl;*/
JMutexAutoLock lock(m_temp_mods_mutex);
- // See if old is different, cancel if it is not different.
- core::map<v3s16, NodeMod>::Node *n = m_temp_mods.find(p);
- if(n)
- {
- NodeMod old = n->getValue();
- if(old == mod)
- return false;
- }
-
- m_temp_mods[p] = mod;
- return true;
+ return m_temp_mods.set(p, mod);
}
// Returns true if there was one
- bool getTempMod(v3s16 p, struct NodeMod *mod)
+ bool getTempMod(v3s16 p, NodeMod *mod)
{
JMutexAutoLock lock(m_temp_mods_mutex);
- core::map<v3s16, NodeMod>::Node *n;
- n = m_temp_mods.find(p);
- if(n == NULL)
- return false;
- if(mod)
- *mod = n->getValue();
- return true;
+
+ return m_temp_mods.get(p, mod);
}
bool clearTempMod(v3s16 p)
{
JMutexAutoLock lock(m_temp_mods_mutex);
- if(m_temp_mods.find(p))
- {
- m_temp_mods.remove(p);
- return true;
- }
- return false;
+
+ return m_temp_mods.clear(p);
}
bool clearTempMods()
{
JMutexAutoLock lock(m_temp_mods_mutex);
- if(m_temp_mods.size() == 0)
- return false;
- m_temp_mods.clear();
- return true;
+
+ return m_temp_mods.clear();
}
#endif
/*
- Day-night lighting difference
+ Update day-night lighting difference flag.
+
+ Sets m_day_night_differs to appropriate value.
These methods don't care about neighboring blocks.
It means that to know if a block really doesn't need a mesh
@@ -490,18 +574,11 @@ public:
void deSerialize(std::istream &is, u8 version);
+private:
/*
- Public member variables
+ Private methods
*/
-#ifndef SERVER
- //scene::SMesh *mesh[DAYNIGHT_CACHE_COUNT];
- scene::SMesh *mesh;
- JMutex mesh_mutex;
-#endif
-
-private:
-
/*
Used only internally, because changes can't be tracked
*/
@@ -520,28 +597,58 @@ private:
return getNodeRef(p.X, p.Y, p.Z);
}
+public:
+ /*
+ Public member variables
+ */
+
+#ifndef SERVER
+ scene::SMesh *mesh;
+ JMutex mesh_mutex;
+#endif
+private:
+ /*
+ Private member variables
+ */
+
+ // Parent container (practically the Map)
+ // Not a MapSector, it is just a structural element.
NodeContainer *m_parent;
// Position in blocks on parent
v3s16 m_pos;
+
/*
If NULL, block is a dummy block.
Dummy blocks are used for caching not-found-on-disk blocks.
*/
MapNode * data;
+
/*
- - On the client, this is used for checking whether to
- recalculate the face cache. (Is it anymore?)
- On the server, this is used for telling whether the
block has been changed from the one on disk.
+ - On the client, this is used for nothing.
*/
bool changed;
+
/*
- Used for some initial lighting stuff.
- At least /has been/ used. 8)
- It's probably useless now.
+ When propagating sunlight and the above block doesn't exist,
+ sunlight is assumed if this is false.
+
+ In practice this is set to true if the block is completely
+ undeground with nothing visible above the ground except
+ caves.
*/
bool is_underground;
+
+ /*
+ Set to true if changes has been made that make the old lighting
+ values wrong but the lighting hasn't been actually updated.
+
+ If this is false, lighting is exactly right.
+ If this is true, lighting might be wrong or right.
+ */
+ bool m_lighting_expired;
// Whether day and night lighting differs
bool m_day_night_differs;
@@ -552,11 +659,16 @@ private:
float m_spawn_timer;
#ifndef SERVER
+ /*
+ Set to true if the mesh has been ordered to be updated
+ sometime in the background.
+ In practice this is set when the day/night lighting switches.
+ */
bool m_mesh_expired;
// Temporary modifications to nodes
// These are only used when drawing
- core::map<v3s16, NodeMod> m_temp_mods;
+ NodeModMap m_temp_mods;
JMutex m_temp_mods_mutex;
#endif
};
diff --git a/src/mapchunk.h b/src/mapchunk.h
new file mode 100644
index 000000000..284eebe60
--- /dev/null
+++ b/src/mapchunk.h
@@ -0,0 +1,51 @@
+/*
+Minetest-c55
+Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef MAPCHUNK_HEADER
+#define MAPCHUNK_HEADER
+
+/*
+ MapChunk contains map-generation-time metadata for an area of
+ some MapSectors. (something like 64x64)
+*/
+
+class MapChunk
+{
+public:
+ MapChunk():
+ m_is_volatile(true)
+ {
+ }
+
+ /*
+ If is_volatile is true, chunk can be modified when
+ neighboring chunks are generated.
+
+ It is set to false when all the 8 neighboring chunks have
+ been generated.
+ */
+ bool getIsVolatile(){ return m_is_volatile; }
+ void setIsVolatile(bool is){ m_is_volatile = is; }
+
+private:
+ bool m_is_volatile;
+};
+
+#endif
+
diff --git a/src/mapsector.cpp b/src/mapsector.cpp
index 8a3728c8f..fa1bb68d0 100644
--- a/src/mapsector.cpp
+++ b/src/mapsector.cpp
@@ -82,11 +82,16 @@ MapBlock * MapSector::getBlockBuffered(s16 y)
return block;
}
-MapBlock * MapSector::getBlockNoCreate(s16 y)
+MapBlock * MapSector::getBlockNoCreateNoEx(s16 y)
{
JMutexAutoLock lock(m_mutex);
- MapBlock *block = getBlockBuffered(y);
+ return getBlockBuffered(y);
+}
+
+MapBlock * MapSector::getBlockNoCreate(s16 y)
+{
+ MapBlock *block = getBlockNoCreateNoEx(y);
if(block == NULL)
throw InvalidPositionException();
diff --git a/src/mapsector.h b/src/mapsector.h
index 0c32e2606..de93806b5 100644
--- a/src/mapsector.h
+++ b/src/mapsector.h
@@ -67,6 +67,7 @@ public:
return m_pos;
}
+ MapBlock * getBlockNoCreateNoEx(s16 y);
MapBlock * getBlockNoCreate(s16 y);
MapBlock * createBlankBlockNoInsert(s16 y);
MapBlock * createBlankBlock(s16 y);
diff --git a/src/server.cpp b/src/server.cpp
index 823a48b90..80aa47671 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -156,20 +156,18 @@ void * EmergeThread::Thread()
only_from_disk = true;
// First check if the block already exists
- if(only_from_disk)
- {
- block = map.getBlockNoCreate(p);
- }
+ //block = map.getBlockNoCreate(p);
if(block == NULL)
{
+ //dstream<<"Calling emergeBlock"<<std::endl;
block = map.emergeBlock(
p,
only_from_disk,
changed_blocks,
lighting_invalidated_blocks);
-#if 1
+#if 0
/*
EXPERIMENTAL: Create a few other blocks too
*/
@@ -206,6 +204,12 @@ void * EmergeThread::Thread()
{
//dstream<<"EmergeThread: Got a dummy block"<<std::endl;
got_block = false;
+
+ if(only_from_disk == false)
+ {
+ dstream<<"EmergeThread: wanted to generate a block but got a dummy"<<std::endl;
+ assert(0);
+ }
}
}
catch(InvalidPositionException &e)
@@ -581,16 +585,10 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
/*
Check if map has this block
*/
- MapBlock *block = NULL;
- try
- {
- block = server->m_env.getMap().getBlockNoCreate(p);
- }
- catch(InvalidPositionException &e)
- {
- }
+ MapBlock *block = server->m_env.getMap().getBlockNoCreateNoEx(p);
bool surely_not_found_on_disk = false;
+ bool block_is_invalid = false;
if(block != NULL)
{
/*if(block->isIncomplete())
@@ -603,6 +601,11 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
{
surely_not_found_on_disk = true;
}
+
+ if(block->isValid() == false)
+ {
+ block_is_invalid = true;
+ }
}
/*
@@ -627,8 +630,10 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
/*
Add inexistent block to emerge queue.
*/
- if(block == NULL || surely_not_found_on_disk)
+ if(block == NULL || surely_not_found_on_disk || block_is_invalid)
{
+ //dstream<<"asd"<<std::endl;
+
/*SharedPtr<JMutexAutoLock> lock
(m_num_blocks_in_emerge_queue.getLock());*/
@@ -636,6 +641,8 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
// Allow only one block in emerge queue
if(server->m_emerge_queue.peerItemCount(peer_id) < 1)
{
+ //dstream<<"Adding block to emerge queue"<<std::endl;
+
// Add it to the emerge queue and trigger the thread
u8 flags = 0;
diff --git a/src/utility.h b/src/utility.h
index 055c8db1a..a61de1c37 100644
--- a/src/utility.h
+++ b/src/utility.h
@@ -538,6 +538,23 @@ inline v3s16 getContainerPos(v3s16 p, s16 d)
);
}
+inline v2s16 getContainerPos(v2s16 p, v2s16 d)
+{
+ return v2s16(
+ getContainerPos(p.X, d.X),
+ getContainerPos(p.Y, d.Y)
+ );
+}
+
+inline v3s16 getContainerPos(v3s16 p, v3s16 d)
+{
+ return v3s16(
+ getContainerPos(p.X, d.X),
+ getContainerPos(p.Y, d.Y),
+ getContainerPos(p.Z, d.Z)
+ );
+}
+
inline bool isInArea(v3s16 p, s16 d)
{
return (
diff --git a/src/voxel.cpp b/src/voxel.cpp
index d68a8db02..02635d3af 100644
--- a/src/voxel.cpp
+++ b/src/voxel.cpp
@@ -536,10 +536,13 @@ void VoxelManipulator::spreadLight(enum LightBank bank, v3s16 p)
}
}
-#if 1
+#if 0
/*
Lights neighbors of from_nodes, collects all them and then
goes on recursively.
+
+ NOTE: This is faster in small areas but will overflow the
+ stack on large areas. Thus it is not used.
*/
void VoxelManipulator::spreadLight(enum LightBank bank,
core::map<v3s16, bool> & from_nodes)
@@ -560,7 +563,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank,
}
#endif
-#if 0
+#if 1
/*
Lights neighbors of from_nodes, collects all them and then
goes on recursively.
]Z0XD~P75 K}>5:Q;PF(N]ӓrsLm`0GZ2G)dt8dgo3fB<*sJlҝ:t6p0-MFZc1ee4FFEB2LIa2YqŷU \RG"cWYq]:eA#p @#D=VmRzV ~Wb%gD@?v<\2X1R̪`6cď2+%mj`I0`;lw-]I:K_ E3^x(")@zzǭQ(܂S\F;UU,9CTS<2yGy⤑,5f 3J9i7 msm ߇HOdOx8PCvkCf94S;h vav0蟠d3+KaY.0f37܍݌?H3&V7bl 6S6)l2zVgv)n~Ec{hڱ/^ M?Krcغ'k uzH>!WV;j 2 0Ia>[a'DWS3ɣ[˭ڇ*"b0b(zq+O;ɀ[ DŕmU+X[^!uJ9Ѫ7.q? n񓄑PuDXdԚmsIVfhrGFtgҞ~Ү?z&PN>/zޏF>C#<=vf^&ifNoDm0:QN9&y:f!5#;m+W"GhTϚ11'7(k5 Y5̪q*U&ʃI0jcBREF( A<ǔ>` AIjr#A*gIJJRppS Pӂ̔0YC6̚Mog&qц˰0٣B4 Sl玺RķN^jM"brUUUj0K{g{6QVSd̔d2טDD(sO= I2ڿx@~\ >ل GIDxD~I'G&{!^xo}1Gw{~ 99ۿwo]&Gh>QރsDO.Ms;H>V7֘m6WdFW5n;MqĜ#A8nkV,d` t7`0r(&,г3У2:E?4=@O)1L)t>8e:TE/ jX;b}5 &FSD*49n'9 Fccw F'LITiRʻv-4iU꺥T-,`Ye#0`0%FQp"O=C|e>n .)Nk8sIYM '!3TlH' a4,8r dd`rY&<)yrY$`Y%(S'&*>|g8{BѣѥX4dm92bjZXe ZaѦ`a0ȸdhA6q14YpeM4ZKUlOcVXL:,512ab.eEՄ-S -ŪIAѺV ,0"`H >"D"߷&AC_b}A)RdҊQkvi.uI5&4XۤƮ몓cSYLi]6RI&ҖIiMJ)w(ݹfbdeK3;uպf( K"(Ѣ-K3*s7.ۦ$JSvmwԤ$'n뤹ԫ 6&jvٓs%uK+QwnP%)%Ɖ]ΌerLĩ#U)ERTl,`uC16Lp2ՖT~`z #m0sdu &d}XO#YSda)ս-4xĪiKSKc{Q1D勠vHX'0!ˡLjD@J4La~ro9_ Op$Aώ?;W0>X͊@ߟ: ўrp-a)?h@DCD2a\23 #9{gM⣂vSq`>AMpzL!f"N #<ߘ`=JRd5 L#0ۧC$F] (5R03;js2<Ê n6ɱ)ejeUfffj^H@k%J:!|@qBJJJJm]qY&`ݙ`ȟ p 8E)26hlaC 0`f33~DhG#wHa=+eKEvp=pk8DudvqjI7c;dn )9bn<8"JS4r%bKU( w)UBeLe Xd jZfqɊ q$3cӌNP1!#=յǷNH98r"pN>XI:cFzs^ڔI#9bI oٞI4fPy?ѝ)vd[<{ϦmҩmI,Yd,zr/2Osd~|}{yF6 [\WN՟2kNύn0cJ5Z\)^p 4ox~\7;1RԲKʞlANԞstLc}B鍃96Y(?v&Q)ǻ]^{>ȰC?ڶ7v1k4Oi' 17e)Xx;fbwTJ>\?`ic}P>Y8(JpQG̒QE):4x2e*YnGdӘbgvl]$밙6S1bcA98O)L eYexa8. oOt& <퍔Ol~ze7DNYoMe!(NG漁)9Բ(Eڲᱶ6߻f_ޛd#ަm<ΙOYH,Y][ZG&yI&te-5Shv{0k^IeN,L12%n32vnړ4hd}FajR.iw|vq﫰;ΏDDq7g9ldgs>?~OstvnQ?s6|hzsrs$Β~(l;w!fݻkv[L&iY̿Оxh:wF)YJ1#IdY,K2X2)fV>r%Q(r,ZLc5}WÕֱ2N uZМ )ձ`kV7-JuMn9xskZWw͌rqH wZ]4cbȹQu"H &< L VjWVyekQ+-g,*2,eYV%2|:a=0 r~~6z&^fi`G'棷 LwxughdG:Osnnsi|_~ҲcfQY,K%c2Ybj1sES?q|&W9U|YVć'4ҍUU-ۨ NP;_u`J0S]G;@|ffZ9v0pJ%~(^M⌷wWz|;iet={<䚡Uj5TE-zG"rCmǏ5 5a#g9r-Ԑ2Cw$)} a$9p0s!7C o0osvGe4)nt="*jVV''N2$lTRG2{RDSr1N%NDpj7%)E60dpJdRIJR3S#bWO:*a}` ՞x8'OHѼ!&4-m,Jfc-~_c+N1[0.K+ -QN b|s%sNmcl0¥S">Q厤ɢh\,wK3x؁ q='6}-kX&?<8vMx#I1N~h#$28&F ųCE4lhs  tf2)I0hу 44lѳf 4[V ; .6p7upѣ 4at``Jaѱbb::8p0lh69pfc6x F UUUJ?Ly(4M KȹL0fԲ"Жoc&2|wFl֓ҬLp𞶭v:)N') xSԧtG@qOBx28):lxG#D6&SO2|OmH04n"=os)8?rIyALsL?Ob~RXY[zfMfnvą`sp–*VaR# ő#"`f`V`&hRՕZ2F%'?wֹDӐ>0駵JFRIXI'f5 $`S\R :Sf)L#AR'19’?\TO*NO26FyvFId=|ymZ6[#,nL|YS'RGzR}s*w~-hf$g>!h#A 86C]|`Rz- ~p冬΄b3 2N tr37cfO@5uo% GIdrlTqb}Ejw`lbq&;I(~!f$~qI=m݉M͕jG%KRT[jҶ$֒kdJcIVLRF($yqc&ktfDF4<QQ9ENNTh'rk8rz1sx96Ӿqǔq¥Iʔ9!K3f2\c0PDf Ih)Mq 3НfqMAt!DW=p"Oz;W&UjI)=HukZm|?|g; d=8Q{ؿeVv=ĵrk-~<$0*sC vJRkiH΍1 7nj8%M)S2j4r2RncPݓ&Dh4ᜁ&}NuゟG ԰'I "Og-c.bʩ21y1>ٮeEHyIrhrIzxɹs12cVFt5 ÷j7!l-tؚmdl(ڛa4U+#8d2;kZxrm::;3LƤS?qriC]bXYdٙ"V,IMl$ߏ*>!u*X\Lc aqq0ss&8u9Mۻkq;խkmUkh+mmmmc .C & vЉϐ0&C5 0G?Doxn>/Fѱ.ƌ8s"eidvtɭM/-o3]>=P#5:CK}1ȊRWqMQ(( 4 ?09rصm[V=xޝ/1.6:6QJ0Ē;1$gT֜F 5K k36:7k Ji6pzϒV:)gp";C-?i̧q2ze+NSJ8rhÇ;N11JuNMLhJx=CFP ٨(&yVߝo *I'll%$5ȎMMmWz0ĭB?GH}$G B";^CkƷnn7[9(q>(hnE?pv-"irS)X]B'y"&<#qTIIY8?(éoGDŽI.ٳ-Ħ1u%c LuNéUk K]QDXE{%UmSL;>?>,9dO([[,eXWf 1<+rS7\M(ǁ92I✙ɌÓ$LߤI0T,<|fC{rrH#\PiRG=Jg8CAچw6Cק=<~33j8#e$Ē6hNOpwqó~8=gffs1gO"q r㇛B(6)nSO}SRX?LSGiYݒ}?)F*լCJUJm$S9hrxrz0qɔȘI9E8(_>+VFZvk"FIcJK H04dK,:s!EtgHGZ#!}#"?$G >O#BB?Pt<9ofCFc^AԩGXfG}4"C<{A#{+1짆yo~i3K5&jLDjaO:q#ޓx1IĝP%T1#@&+Y1zm"Lhf GŖr'8fiȜdԓA3OYnikYf?_Ggͬol0ʗa@ReU?%LBxʪeك6R`2㠚"JUU^iN63]9)K:( U%ͶUXj(ljO/ʔbnN;4Nq&<3؟AUUUSME˲tjLʦI(xʶ#QuH*yW*_ ',=<۵'t'S@=*YQ| }(G)]LRwФ?q..ݟfk4888B~p i8C3 ߬*%݋8m,QgHr덭p9?> Yݹx|&tMTċTJPb< Q+YѬZkJ=id8H$!HZ%"|<+,٣HTnk"~,J$A3~uOruxQsi͟x;HښL@'?X>8b"P49?׳֫B ֊2SM.Cj^gtK*ôE;<9jhhǺ0L = df!ɜӓ40>Juz]S>`xԒfsICL'#>dēPGABU] ,a,be@4oFȦı=e4hZAD)D3'@|Nٮn8PruIXT?\sC 'c^nI߃ēs3BoI 5WZ2u# ē$-0'φwGI˥x6䍱Rf>`ԀZJ>'3yxf#ixգKbxg:O"r}!0a0#Xs,6Cc$J3 Mr םc:VUw nog7܅vI`Y#15JK¡Zmx#Wxey%&BOpw 撔 JVRU(Q,dL%&IM#M}-+^߳ <19ra=yT BvSޛyV.N)slES(g7fmesL͏<̶s`qqUq=PNqO%6 n$g*oH7mI3[i|X >VKfN>Nbywm/'њc>|e0ٽ|NaLA'{u)OvPݓӞp!6"%=d|u@5jR/ 7öP};/|c1v`;Cf6 I$ RU,YbO,_j>?2YV=)}Îi9"#rRBFCL_iOENO󜐡Yh*k423g53֤0fZAꊈ@llO@X,etѠvH[I5 R4SϟCIE(nvtC9$7h,e&ۛFh>kW u#AQbiFK\ ګ̞JUB)-iYQkBQU>S>k塖hMR?ebO=ANZ G:Fl cHÆ蛌;;Ѝ6=ۍ';?J,y$z&ISo mUm't$("I׏Fw3bvʑ= ?>3i5rs?r8g);JG-mr.z|#Ҕ2N%ǀ^ w94e|Cǜ+HtfDvZjӟvwI?0(i}2kҖDN I$*DH6{K6H:znԪ./ڸcKN xKa?r"gy,qp}MgU+ޘ)O%<#@ߦ`E2fQgssK,lQȶAfձq9lmn 45aćqGvs#d잍 k &Tӻ|=!Tw{<'z|f >Q<'5Ga<ѥ?bp8?,fùZjMs.MuΣ,2G(Ҭ'#Р(]gy*˧I1ӴF~q:SDB>`I Q#Ԅ섉!?pFOxwSđώK*xuC> $OcDx;#pOpN& j,} '脏F>MʑϐN;_.ms{"SNe# r}3y$kLO3CF#]9Sa*,瓞79.xb8?Z㏼xaC;Gz,fO"e2>ԝؚǢ3ЖilL%4=>kTӜJ)"Ȧ$J8^|ZX0_(JHyc-k,2yOV>;pR#:G8i6]o`N`rd&D'4IjkMcII5bm -'P>!Y#ڍ-sj[UZd0LRfL%NMg{vi6 qDX,>h_T#g4Bs؝A=VI+51YkJUîVo\ ĔR~vIFMG|uMqLF3[Z=lğs6 R1#2N0ԥ2 Pt8 .8xt" Z[RV8t^1w;\ Jp,(U+AiN a{KȐx2U\(|4:HpcsE.ӽ;íK:c& L8`f챋eL0'䓳׍掑J4f KIUm^t3ŝ\ۥWjiÀm TRa*|ra4|T~4UgLUZTRRF̢5^]}z34JY`)Ei&̣ei4&&[T{7u3c#fnu.ƔfdKFeU.SM^-+Ğ捒zoMySM4lKF ),%e<8jRIMvE*S"ac8L:Xb|FKvlيF0mlxN#E`il٢l,XgcáK Z5h٣F l,4Keŋ.GCF- dKF.CgGGc<b0TR3-dN83H_ymYm욃db4)33-ff3Hg21 8#8PT$FaXk>;877 q[m[mU[,1~zX|qQ 4YbL (i<1' ~Q( v;qMi'h&@t،\c:B[3C3N隻--٫J&%&& )5xPnNNU;tY-U)Ca:2J}OrϊbI 6[CM$5,rXcCDK4*ظʺk79XUh"Ɯ4풊Ol9SO sH#B--I̓>o66O@w7|I tXl JOLAd% e2= ?Wpa9(Բ!wla A$&*F;m nʞt)Ba V5i m_8}56dG+̝26bsvګmj"`&bnvRG@ybǧv~afLiy%k*^y-cٵq~,I-{`x:7?k%HI-P'JJ&sD,_D2Xv/tj'*~ )opjԩ/Ÿ8ì8{`3sPȯ,u=1-w4KfG/q$r$(z#9Lbű'$I7e^qB z&T]C/垢{Dr>)>ٖ_QۍxCa4 -ZJMDMDMDNOGJ5S8.m#9=AM3MF*]MKe&3!,^}Y3B:d'B9TV=8YNL(&q?9Uz/~~v`I`?uiuba=qMW!"zklE56?¶֖[lePcc,cH,Xpn|g>(g2oY[{amZ12YTxON?pPL ʛ3錞gӦS 3ĪSN3XT+*y?LjFyO4'^l}Ҳiٻ,v!TS 46 N)2=&%< !Ql>a{3ک gfIoEM tcqc:sÎ6l6ϺVRnv'BvG}3Ϟ;ճq;di/\&|ğ'%񳦟?nBf×'/9y˦6.7s!L|ù4R'oD(O[OF9 5'oޟnvn& ?p>dz7c9&^!3v*-3DxYe8܍ڞd{c>b9q?k xqߎ艹ONO5'?hkK;0ꤖY'v3GNb39Nv{I2tA_U&6ܺ6W7?8d?oza(j1@ 3@0u<3wFL8'xvG>C8>?8{n=Ǭ;xmw/+\K0x6S LL[28:< rd-H9#d? xʏRu#7<{O6Z?uFôz2~Qt?c<OH|_&jծqӔ<8sڟ:Cךpm?e*UJ~筬ggUKVJN02j`)I69ߧh.Ç;>f:a㣱tx4Ɏ&$L8U@ܧl41$0INѩ7I;K'%:rt4'P rH4#::֏zg9('K *bRi fnOJ;!{Ow2=٭;)ӛmN3.L7o0æ:Ŷ ռ[^1*ZHu#X ZӬH){',3fhxK܏2w {7 l,z:r%Ɣ2BfP,Iې^,#:1Slic;OlwC\wrwc߽LYq"<R]޼qOl饚{ݖZ]GuY;3g/zǶy BODtivؒ>+>1 Gxȟq|)[s{ærEuoxvy'$~Ox3zd>&'LN/1W px%1oz9ڧzJٶmf}Y"r`T'^[v*Jyt铞&~ Ϲ ń^:xu ԊD拯=H-JhG|/RJ\z/RS7psO'? L'.t$'Cyœ2žpcAJD¸|=6TC&dQvL Ocz O6;drJNԏNx)tcG;Q܆wS>;;G9㽟SjGf;MhƓߝe^r>r՝'f;Qb"b)00v|ҚwP1ii40m5Y[,?|}K u0Ri%.[_<_^oE Wf_D3DϞmКtUT񓭈gڇN؛i$hzmčNMO”j%{S߲{H̦ k5c UTfjXodBpG:Y腝Jj'Zv';f|͜Inpo~>)X:#Izu~B<|A\71zCg8͜yl,xҥ7ˎ!OqɏI8#pOvhݑ$'ۙ? `=)tF:6wcPpQN ~v|i2f)DZCxѰ e'1,ޟxٹȫ 韂ޚ#K;`é=чuc%̝К*F 띑VjvFU=33vwpd0w.IXj]F5jBJ80=IINDxQ-)xH9ʰ JM6?) ;DW%I+*V+JuqZUQRa 󕅎S+5u:) USzdc؝)I.koq! @ᑠHN 9)Qa  01)} ˥ a B0իhhUT-ZIlK0`h ?9HPB%#ԟY/hn ~mûӊ|27ɼ9Wӎ9Oxx?]8ɾ&O SI$MΏbdL#UmcgJu@ǺWsӈ);@&ߵku0vy1cB|N|aLÜnO6eI靨s$'|ݧN(S׏~FRwGry$c=8蛁GpO]0tXL,NAḲ&k諐P $p3۷$XJyiZef,lǷDՓɟh8wdCNLtC˔DᏖ7|:DA;;'vH#`~ێ9qf)Frgh>;ߞtӓ=rR#ιb{qΧ>W#'ʛس槨9a^OyTa>tI2Ӟ=t>vL&ae+9,m',\#Ӝꇎ<9wR=-sUq76u~I)l2Y_VٵsƮ$vVJoǼ=I:YRNx1DOTNvӼ@>J~9ON;Pcx=QqJx`i5G<7iSxzå91v<3}% O.:qV~uͿ1,-Gn=C!j-xsCt~蜉?}.USɏ=Zp4=՝P# sÄhN73ѝ Q͟ m|lϙLO??M>Y~ N ' ؊NtŠf#O~IN>Ȕ:?ҎxqM~U>;;4:37ғȏrzA:V5⟬xޟj'$~܏<> tyYgo?X)?3{czmPsYצR#pIS8%O{pW<|Ct{̻jG2s}o,9O ͐O_~y(7Pl&7+x.qq1¹oItWy"$=sF*[,ُ\ I4w=r~|i˷OzFg<)ݟ 5 N?Ux&'3#>YֹS;$v?$gï;ni*'7~/R6DZ}Mыǭ=Ogl6ڊ3ALKf1][~gXyg~`q.1=JB<ΓLN^Xp != | Z0F_mgte'23%ɛ>3o|feͩUv1qj}?gH~W2$#>O3uEEOf='L$dT5A0Å͗F ,0oeraoTՃd}9AXdJT}ҧ*d0:'8zFw7:dsH_ $fXyUFeFqJ:vNN8Ja96~ꢪI( ;7B:Վ]楏>s1mVΊ2!dwQSAڇi7#7CSWv};pi'Ű l\0W/d_rX&iw"x]Olf,՝2 .ձEUUſ` !p>AYXNlt| E~҇䪺LɆO1:O1.jK\].q4"SDDFx_Uw @.b_O7!A!2CrC\ 7tN#ifdAE Kk)~2AnPvd =:Di&V\]RYk[%׮oVdrV9sPDGI HIIgGG`OPM`NJ< '~gэy_It'K$ҕY,@q0&K(\`c89\ 7AiT- v۾j{//_}zAZ`gBP_in=#ﯱi}}_)b&a<לXfNeZ OG3( T)B)=PLTZGSg.C- @pWV%%x^z5/x+^e0=!URITND Ÿ.g|iIAP\63I)tZG#rWƟ-J!6Q7 Ȼ%ǿZT:Ub wY4sI/ Sd'N73cwu{)#Ve=6+ʹaOV9 lOQF:y;tIs'wts49\Y'st3ĎU;$6$x 6ǜ=܌mNNwXQÞ2V,ɅVivbN5T\Bb)~v4#''eNv|8ߓrCXNKyaFvvN@ww1 lds{]Kvk G>s)NXx聘's'"mJ|jIn^R|^DRe5Ψvl x"xk&89˝R7 ג<"bۏOfYeg^sqne+nB' 7ɯy$zȲRw3[nF=(/4Xh9ѓ#ysytffbϙALD )5_[b*g8ܐI!cn4qV6ؔ.>5cL{^Ćm^] צ'n&Yd2<3ua4'0lN`>-NN\9;"i;*QpZLvp ;7yUV܎D~^ǵsNٖfLhac%ϧ.lπ:>Zp]D죟9 䓝3'84QUMɟI6܃| '6Gf:)\wAώhOBz1L84܏ax7k&ܽ= |fIj nx8,ٛ4,̋aٍyK-LF-uʘzgTBmcP3\)-'6vG}X^ "%TJGB&#WbʎH˜TiwW433)YtfNJ/üLܪwϳt<əys.pNG[n*xݎ3&cI>svžAۏ8zsSOzL#<6sBI:{P3<8xfL,bنk.{9ӌ>n Μ͜Ŏ{2=l~p S/q62[1vpMqy,97I9*ys Xޜ͜˥z֝83=S͉3Kfɝp=:,΁7fygp^\β°fVk%bU\7VoC""p=fŌ$T K1a9p܎1yF1 uT ۦZJ2g`8&ǚbWeeɁIDt񽗠6g.%"MM椷p¡& 7؃cgm5F/ 1}/ a@vGԠq0-K` 'ظpc,`mms g*_4Mܻ]ˋm:F3 :qځ `?6mo8dLMxdA \Ǐ[m'x\;@'o2gȧM yI:z&;;?1[ )i‰oA1BA}p._G }5p5XU8v,.hmr5`付13H=LfӔw20u̧\/p V6W'$%R4)(OPLL89|C+~W0L.c&a0x! / 0;8mP:="6bxJ˹9'μ4F;Xfm7qڎF`HmH5 7'j9Ht& 0<GC_se;qДQBQЎVtYfnnlbTF4ZU`1KXStb̟y?>7ޯV4O_O4K(t5F<'sLc(PՙLN)sAJSܘ!=O",m'" žʯ$ᶌM 4"/%]fS']qJ4C4bR%Re,L2}teV|I|S1tt}M~Y!# Lq٦0_88bXx'=A~2*,ҔX0G6yzGh5XЉb9~[ l] e{T=dG`G=H@T;:4G3=}V'TQ܎Ͱr-Ru:%ua4lnZP*sRE2PHs‰4ȩJ%0NV0Z0h[6Q@Q)J(T K"S# J(hhaEѲZ f6dgL{9S2> P՜?),(Dz&0K,_7Ñ ' )J((((%)JRR)JP)JJ)JR`w/V*c",$S͔yO9l8Ά?HzyRC(H""I6gmUILRTMLU1 3"hD6l̤ %#%6drN t|Γʶ㏆A?80XO8MN !̔[~|cמ<;T,9͟?l34SNhxS6tc#tNb$90#.K571&W4${AI*~ikLSK=dzJRSڜзSv4J7jʹ[&chT7D  ~(߷$MYڶ73&+/8w"R`3徢f$,7νƩR?D9=@-eYe-.ae10dF *$566 ufHbTtHfw&ALb e3(2DYIXflJjI6U)fhu݌@I(Y/2l0%ʐ#$~=U.e,'xM.=Pl? gl)2Z"Q,KDbO,FɃ lh=P~Y ; 4$?40g ?[9p7%.<ޛ)G3Ŝ؂O 1F')[vЪ`vc8H~j0VRZyvilh9xRG1핔BIH+ۊr>՛(lw"c7T^_~ZAU^!>(?I?, I" ЩYђ1%S1f J)JJ)J)E20L%Y6j.Xa 0aՕEųF7tp5%3JYdS#% E4 )`Ȗf(K(3LHS")e,R*fK)LWf zCV7pѪa)dM&#"(0eY^e Ն4lj4thfS ]Z8pe2;hߍp3Ѫ=m h-ڶ끳$ QQH$*2W1Jb1w4ɋ#T&U[X\a9N$x=)MBON}wtHwǥo~[mo>O'r!wĝMS͞~8)Fc1)S9uc?r8*\tV?akM8cάNۦ2&1I$gf[Q ʵ+ 6%.3q'oH";@Û>!qDNM>}+GE;I:,hQNr,܇%e,c `6%31icO{:wqJCyx CĠO}M&rwL;cȩ^(6IMdz8d y6y2r`3H>Zeznpes.mm}'ǥ;Mlfg~ҚssD6I@~`JP!:YwŭEൊTEMX@0XȐBiNGh9Sv~K|ʆdfm3cjԟ|ݾ}_[3@L-8DF"1`6LNC=:^Q)""D!RT`c0d= . ![VU|w㾉&:?觺>Gj`~QI}Grͺ :Y94JTrM7#pn&ݔqFs9b,~t 9K-Fom٧)T+WP5cC a2Zȶ.33V)Uv"pSɖ1!<`FHJ!ꆪ5g^MY$) ,kf0T\7bm ˕mqp3gʞh!xΏI#R))ъAO<=fdd 4-6D EG8gpLN&%+$a6+ 4JbNfP1 RHP;@ k UQmkF؃Ecm¹gOӜG(;K1t)f z3<>?v'd;}lN;i9a:1 \PN|QЧ R:}?a`rX$f-[cSdĔ #JKBRV %J̘U%jbA(8鈚3&rg*rO#avCϛ'&qm6Rn9JRPPꉟ ư cA5dx_ ?ԯ. gMsYg4*mH̛9W`gem[pYh6yF=N3SVKMf5&M5?͹4;] -ijmRda);qZ 0|GZ('<}ّ hwI i$?=B<hG*H5%I6̦SaNz8n~XnѻRM2V'Lo#}5'^5aNnvV@ݙ[|wrǣw1XI!L?NS_/f<ۛDM#Xf;?Mo#,z2P(QC]5晉SXl6 yFO»[=43d6&1 Ud2&8'̞8qqD-S7w["ѓ2̹Гl3h<rhg#Tw }sJwwR;=qǫ>YލrG4xDN}qVN>{pԍYfsFLIv׳.⃈H_Aug"'$qPѥճ+-\֦Nmj8- #2<0Nl_0 ʫ@0 *QJJ)V28^chb&C=?~ޓFɪŖ#ȵ54~l! H0dfxU2Bi6o3mں,c'\<ѹ5 Ѻ&&CU6ƾ ,L̫V4%(R$e$ϒtCٔR(НJa|Iգգ)x[v/ EBF$a筁"2N sLLx `Jd< YF1B@Ie(DIHŀF3*PȤ C 6hša ͜e\ZrM ,1dbG| I%8DHե#F4ZvihƖR&*7{N޺jAB,$ $Deah#K* q2Q,#ّFF1ql-5c,atYjKveZ,kQa6ZZ2ݖpjJD:Y#80aK-2Ց#*-$gD*P4,P%gDYF2M,,YdeյőkJ]hhVRݑd'Ģ'YǁD8K$H锹t[bʵWp">p"zb9za;~xC' '6c2;"|91ȌdGNl1;@֛s:%)MySN5YtVy-%3NB 11V+e)V[53KBo:YǟbV-U_V.ZZjݥw,r呫W.g%YeYr1YF1e#4eRvriȄc$%iR2,HH0c,eX&p#$cL̲uufeeefeݖٛfnM5b3hx,fRthN0}ضIplm0iGQ(Nz6|r>#Ip>QHC])N{st96lNpoiY9'WjbUK+1V+b?=R6e5U\O~(O&L9NR_ODM#qgt'6h 95# ͊i0?fG83pf[dq +ƛq70wl`n)7Hܞ!-d$fY0!Sv7C9-|Q, Ħ\UŸ5Ӛ|U4 iTU[,*CpUu^rL*ʯ;hAFJ-cIUmb^ܓd3U;QNۍaAc od '' 9xvfMgJxfOO4I\<)OTN͔b2bpaŅP,,!ON8r6FO.)fZuLarpŞ/;34jD:Bd<(9Bm߸96CDkkUvbZ1-[-r5G(rG =PlG|Gw!72C!בtti j_/юhɒx'ݟU0(q*Pe&*i12bM lҐCE,f^Jz}qX<㏲#Uw"2VK$~:~6۝X&QщbV5-0DbLEl,X`{Q1j< u1]>i1KWZ8IZnM}s7Rj˵뮗]nȩ$YJwmI,e΄L0cJ1j"o5 J-[}kͤI+hS f#,ʖKlN*n ><2||Xgr[mm ca!Fu ܇=> (%'(3{?dNI|n[*pp8f&Շ6|Eeq0Qh0 T' 0fbg 8'o7o:ߏ_|3#w;]9qlֶ8{a:7A TOIê5֩71ND`vȦA*aYUW:#' RR}20Fa;4~&1mnTo>h(oS>}32)R6$ ٱCD31PpXL )JS)ԥ)Mz)@jD,̖La0iQJRMc2A"Q! *b)RT@lfaQRDEaKDb-Ɔ>YJJSDE*j-000oI3d''P'8=DOKmC㵓Ӈ߃__1Q?`fa`bb|0X41ז B5%?x=Y@x3 AYBO$39#"z} H넏=A#$~BGivݑ:`-b[X R"ʖ*aV :s#&KՌbךOT:qNxs>rS[ZmuŶ5 Y: Х =?I~t<ҶiRa`ޜ8`sDF0#F/z( le(j}$nxOLtńz>i4 Ia6r)E6wA> $7nHs橺3q&oVaaJt@5$%VC 3޽:I78 njc LUaΎ)6fݟқ}ӑTtF,kش/ Gh!=XxpOM>mY1K%fc6{qE{z:/NjpKv](t)&)(Q K1b:8pჷ6LpLcs 5WNzs'{e^/V'/KѥJ3]^oRajR bTQvAG9éÊ:Zצg͖uwd1=Kc<;ѮhFy%$A;!06wtddJ]rMC0|@'~9:^YQ"D8pO'>rl'q' 6FItԞ$jO:N[DM"4Bd]^BDƍZ2k-lmD-mZmiVjUe;;sr8Ntv:chD,m*Um/*ᅸb'*e6,9dJsXx3vO,sɧtr OL"_M"2y HyA `XjO;[Jvxa?)<邞});d`&d5& 3f=?JX!&xbg+r} 1Jbf)g!ӦME#ei>XZ5(_7?xfڭD}Uro^5 ~6ѽ Kex#z D18z}5%TFA]Y'iM&FFb:g WAi4'0CYѯ5,9#TچRj1tX5g|kp{|rϋt1[燈U-A5̀n% '7f1-/Go9N"Ri?{W]R?tS˓`nXLzCT#-E@<1T˄mK@lJ($Db qhcv%DB&4=l_D}1TV$IihjBPp<;k~[jq2e22?<rj"yDq1&23#\`L1nFRZx ̥PLٌٲ˺'%stY^v=Ll_JVz?sG^8@o~g?8?eUB;(֫|q _WJcbYy2:֧j<ئTfUەW'm{A/fdl3J#ly @:+mC!\le7c)=:5!,;JTwͯa=(ɥB6.\UkqE8p薆Ün tY٩$*p>6 06{|0Q^ᰪ_-dȌ* 'q[Sd. lu~h|#}x(c>҉%ɰLL1i ;E"ne{,0EpϽU1c,K*T%))Is$~9??2~fgεkTD3σ,jƬjƤjFiI&j0V) %y҈?0NQ(gURӨ34ƤjFH,mÍ2q Sքq|3 9zZ>a N,ʚyG64U4L 菄u8~wcԆ}u՟Tޚ/%!L꟎I~\< CG\ՔA[RQ/H Mg}pt+*NGw2Ȯ*^|I v#H-_u|2Y b3r8*8[T\FX:ꘖj zN;-xoP' l;Y"w{хeb_&0Y ðMp+LVoA]䝈HxI6Nbm55V(MpR)z[F1(? F6_ =翵p$sOoNކ9n-̳36kb<L%)‘30Qhzy܂i3> `_3ͣ࿜uYt|D)/mKz{58cE>x݇L38wQ;ȳ4"I&avMU|W2#Nd6tFXz]Z5yI79alsr4`bvb\2n6?XZYC0+62fH~@=pkId>S 0*sxhTϏ2󥛄"~kpӻ{f*e"O8# I{`DOd,'ER)yPUe CEVنΆh2cPɊYDxabK STX0M CL>ɒ~!8Ɠ 949&C+zv~6In SۤП4n̑!7M֚үd@(7DR3ƚ[+7fF SS̆v;唨'x< +gl,JUYe["ɣRԆD O7i:fej0aRP(vn^0nJ4ienFp.f$ߤbO,kHq'i=P:Sjmnq }xaK[YmZ:Sy# VXUVX.cdd6_&a04o㌌@i,^oJ$"PizrEgyYYCYF6mF43fwЎqdu2Ŏ7O Q 2joFRRɔL[0<^~I?~~Y~OXt&c|hl!~lN>쳰M/@d2 ™aH=DDCJZFPlbC>b{3nq\QѠq5 6\dpFqs-Z#!;hO 4l#lYfjdm[uʞXS[/)))0a*?=Tw>|lSFP8GAAO?^* [31܉l"Gqu# G8h!$ף#&RQ*gYff#ݹe@V(w.)hRE.['QMT)S:wf0#mԱJݶβ;$ $P ʝ{L!Y贵*CA5Y9dZcئ*Rq(s;ƚar%R)Q`Tɮ+Q7j*U%+dq $Ra0itix;8mmcFyhťN:0H!A(RrL`DX 0?=hvwsl8֜S8óTݶl SsX '5ɣMDvRvs4zu?@``tzNdʦѵ]n">L(tɽ 1q[@Z3OxeU]p[K~&Iɬͤ6@dci&5RC2M3JX1ͼѻ)̔϶SLOqӯh)y4tr};٤h)j%`Œٝ)l}iѹQ;Yg4̙*c_PjdpFzaٍΔpN0p5ulXu <b^k2Vl6eJk$@k46G!{Ɨ‰S '6mf 4ZXD% ς 0{LiF1ųIPYT_ӽ׎){0hz4~h=PoPB́2 ɚVڛqύ,V~pŋ)˫,XWkR}8(gÙJcz=I?֘bކ܈P1I# h&̦D36[7!S"jģA78ISMԳ9ncٓȓkw^7~(7S&C~Nֆ=2~ypL{JWV{Z øͥ'UyJUk:)\$LDJI')LD<5KmMjڳ00&^ԩj܅R~>ڲ;Yth!&B*xZ ;]+TUU"+-4l9SU&S>טscTLVle̘WunOl7'hdkL.11%EDYfX #@&`͗H;@Bε {S`ymT7o$4,$ZJIR"͞IgksNw<23JQ/4ᒙ3|LxpɆVc% 9Kd o=( k6myf0,eHQ5s UXndSFUsuۭǚtpD =*?СS `#<4P F'x簾den*뇿C ݎ=y$蜸v6^:خh/Hr?`aΒsLG cJ<ȎHhzS$ǚt ?|ι|5W7ߖG3L+ԣlg#Lsuꭶ898+ 09̚\z,fg0y8{a:;Պg1d/%mȕxroI6*, q )#ct t 0G LMѳ2\bR)Fq'y%M1l>?t7!e$`yQIkUm*%4&)`)(~x_̋EX- ؍\/f_NLw1E0=SӘ{C9 gy{P2C}y[+yӼ/4IԷWHk{cz5Mz^FYRK5H5,4%*EQM "_~){cN-梃;iww0MJB3Mɉl% )bڶ^z-G ϐ#3lmvRxL,|"W?[-h\:%ʘ  u&7&m%>>䞥16m10eoМtpgQ[_ G.bfEU*¢ѱ~GY]K.%lTvo z9NDV(4>ۅ)|e*E@R`آ#1AO7"g6Gya)AzSW 9ho"W凰:oZ# XMe⟠fdvQ S{xz|&rOҼE zf 29"8ɯ73qVoΒa6IM؍޼IJ˯jqVS -xxI9 c'7!ȴ*JF1coo՛v iK6WO'~.ފ#gYÆ!&Jz74>u1jեe5CLmTI;̚;ћ%$~|TŠ\Ҹ4lMqXVfm60)42+#"WKoIO\3of7oz ~A৶#Dˉ$k)ӟxͱD#'0FSy8nr&N;Yv)S}i%I  D{bs Ifq Bh}/q pa<#1TI:]ɧI岭\oǐlri& DڜrHrg9#!34$PqȦsTR9B90Tqs15P20j n VӉˌ,2Gr&cSIpb`$Jy'Vp#`3i`W ^g^$rutX)Ju٦iRԮg1)ӫٙgl᥆*ݐؑ?1AY&SYrm}l1xl%%H$ܻ vKm@*"U 0UP(TG]@It)up|:CH;f65) &jx^٪zxxQ4OebBi HL@J@: p9m)J V`ҰJ'@dcbi$ҕh d,`  -4 v2H@W@+l֫Jhmi %SMv tQpkC[9CKƫpJUƇGJݎLݺP v`Zvf8ђ PՀ*ݰҨ݅SY;iBE `B@$Jd4 @  rhf7`9H4a @U@h)HK04J &T8t F 1((c@ D(@@2(:j@ tb.*CZfJ :$ $@-D@@ P"(RAŰ`jPhU lP*+cV4M $PZ@hD I K&Th AI 9J:W]:v:;hRP!:$4@7v-h %`@:$"atP:iQZ@5A Bdr4ݗ`9nthH̑RT:d ;`h2$hjv ! P 7L8R  @(Д P)ñ@iMD H@ $ &ƄJ 4 v ( .! #aQ ::BI[[ZFl 6 :j" nEPI(@ۗh5#i:4S 4gc+@vDT:@ R?UTGOSMbicIyOFL( I)&'G6ji6Ii OIUUPIT~OSTҨ#&0%4 2 4MMMFF`2{)i=44TSi`eO5M zI)OQT?TOJzjz#mCѤlIM3P*jRHD4!jF<"i=5OhM2bDOѠe6ILi?"cFOFQ6ژAz2h#H"HeOS4Gx1 jzMOe=FM 4!#)=zh4ljLj'=~@Ꞛdi)mFGUU04OL0&>σkKIK#\rPOdxDdlY[$!M#xCɏs=Fm5o?|DvY4Bz#Y=x"4|GzVuR<;qykfjUi4Íƞ7 8<8$u"m6;UU5b nͬ^Xe1cfBn6=}AΓƑ3d EHoN)ǿqTȅw AubXPtP<.@X?hdUl{d%9–T)T  n8`ibL $mˬ)|Atu !(@`اJiV2#M Zp2G * # $I`EI2s#&8# 0ˋ_Ilb.d)ATG!)0FH䠱RG'279D%'$ra. )t9h.YZ 0R``L*ZHB^"]r1hLTcZЪ9#Iȋ9.uETdvxF91AI t1(tp` #yh,ӧ(PdLT `:؎ .:1A\b;Z AEɂ̴LDT 0Qi&2 w 7A GoAqt`/;;D' Y! ĒGI2tb<$G[]I.A~`h>}]Ri +} >\DtPz4O+ W+ezS**XdF%$$W7UUU!䔬(+uVH'ԫ|!FzH?VPe_>l)BX4^넰}z- R4b^BY]/CotAH-&bƙɈ2QK! [hlCՎ@FɖZEщ2%P=\KAdIreeg&=.I1K!gK0ZKƙr2Cܥɐ)aCzZ}%)b^grfv߮Hp eƗ>OLxPH/[/(K~6'ē P_LʼnL ,q\+H[2œűɘ|d\tP4qjD8(L3_(4|2KZ%XKb=d\ *zC`WK?N?r.@!iz L&P>0نZ,LcGۃC }bXqg!h0 D~] ?2!yPcO DaHAŠ0 b27~`.YaE1(TO 0.p_!Z,1‰Ȇ "T 0,1C(?1{d)P\r7xBHtX{(uh .&(e I#]ט7C(ÊD]{7aHԟPX 5)?A;|rr{^}T|HESĴOP <'N峈r#8**g"g$Z3Aggg%xv-n6iwWN.˲jջ~ۿۿsTZU4K;֩-ͥ ղ+MiT$ %jkKfif*mibHMY-ͥ el5$U5Y@4 "U٬YB ZVҴ4 "knkskrr8l+MSK&[Kefi[+Mib@DilY+ei5M,HYm-h$ ڲkMib@Dִ4$i[54 "UVVY l֖K&-YifDj[5%K4$jVijk4U-Rm+f5XDKilԳA!Vkf5XDilԳA!ښ٭-Mf 6[+5,HAZl֖KeVjYMl֖M&[Kef *[5D&-Rijk4 ͵kܭ\5s.s9Vkf6hmon]mַZۮu׫V٭-M$6m-,HAjY6M[- +ik5ib@mYRSjm4 "mVTA!ZZͩ6X6m-,HAVjmM$M[KeeK4UڛSiMZ˥m]:mVTA![zTQKY9%``2wFA+%(ʩ6C2CO&4}>OӴ}N5Zkuum]zuumڛSfj[Keeh$!tjծ[W]uzׯ[_mk,^ڛ4[Kf4DZ6ia<0G٬jmMX@CZ[Kf4D֥6ia Ym-,IZ٭KSjl[5Y -MKjilYfHښԵ6, !-Ye " jkRԵ6ia;mn[\-s\9r\5jZ4٬5jZ4eh$-]%jl;5fk,A$Afږ, !f4 jZSjZ4٬k,@ښjU6ia k5eh ZmJ, !f4 ZҴڕMY>S>Uwk]v뻺ZҴڕMY5٬DjmMT٥#Zk-,$AmZͩ* jlz'YlYfäxVVmM6ia#Zk-,$AmM6, !5eh!ʵ6m\ۚ\9\[5eh i6, !mf4 VҴڛSffx3@mJjmMX@B5eh JjmMX@Ck5f4 Ui6, !f٬f$+MjlYll@AJjZ4T[5,$ZZmKSfuy[kktzҺ{L嶾v pUIP"#o2Y4@H:#Dd@6[-i-""# F&&&MBj#Qj5 CP5FyjkMjll[5,$VҴږ, !fe m+MjlllA$Vi-MX@BKfYAkJjZ4k5,Ed[+Mjl kZ5͹k.r-rsԵ6iaueY٦$ T6jfYMHԵ6YaBnW-nms\9s.skek6e Զk54Dڛ,!-f4 miZmMk54Dڛ, Hlk6iښjmK, H٬Y$ ٭6Բk-eh"mjm^,żzMk-s\9s9qjmK,!-eh"jږYaCjfYfijmK,!KfYf֦6Bk5͚@m-Me!5f+f6Bk54@ږY% LSy/V6'C O95f(3)s@~#DIaJ~ի NEنYl,&aCz/\V?M4@bU`7;%o8oC&%3HoHHnT#qFaͭ>cqlEp '"RI<4&I&HU^ `H Uڃ+'lIaKDHH E]@4s"L&"!A~׼m U{Zד(TfZeϘm'-K31nlͿfg9m$ HjI$.,A(EKE9UeQ!|Q 8cg1OȎ<,gC ~ l.d,dk,@H rÐ48M܎nk3bkg1JZ' q󀞄pUђ%"&@U $eb,$T  Pd ,Dac I_1{/ 4EG$~QDp_ -+yrtdN8]Иz㏃CD- &dN$%dDwR^TԖHN%'uT,^HwɁPӮOP)@]Yz`!>P +-#; B " !œ`+u.1'[?-xe&W[%a{ny[r WL T ^@m?ہ@D?)`.)(-5?h Rޓ3r.`(T?న` r(r ssR .) ˀl|  RޓmI,t>G#r`,X.'Jم촞 ^;'9X?\3D;-#wH+CCc\rk)۩` "CrsrahbCc\'?Yv?۩`x<~%'lz '(hN2»`-6W8 D!'*'H>rEO%~K,{5*G==pΐb>SM֧' zzS;Щן GXÊIsX20p.eј$4ƿ:M܏M1={սHAR*RTd8DmƓ"uD!dx$f<( 6`h;3O*XH1f4'F4؆LANY,?H&`9>eƄh fc?1NunZXZ <=TSsUFvx ℩\l܏H`h7T#$Mp< ZUM89#!#f#$O<@kJ(PG%g('7QEApفA~HS"$G0=2|g~1op)n|&Vԙ߲:`)`K p9e'4`{.`=R(ړ;B! X=`r؃IB'?a^[cX ! 'l Ȝ"|N,BN#C.(P=&@vOPZ_Gyn`)V29@Ò)疆/hu,\〧u,LC)>)z\d4U@r!vL-հkD; \'lsrLNI&pCD;ɀ[ՎB!i.}F9;rE9ZM@aS r㐈vZ/w|r1}N]Ƹ; JaSCn\rZQw;$St ˰) r֎B!ܤPp9O^1{hu,kCÀ#з`8#CA59C׍'#C}Nn9ڇz9GprPa?;%!R;`Cɔ(2އ(+\FHPaynE9ZX8]S?ƹ^KF'͒d&yAO[NK ~QOf x 2D;-/`O'0 }P[|bvcb*J != ɚC{6Dz5Xb03"X c4MDs֟!DkY]VU>5gG i {^<0O`%F#cS5c&0AIE$Q< }Џ>'np$%D]6뉉?dyCIp"|5;#K,*0# ;dS=Y(@D_Pp0'T9[k;z]){ ,LGt7r40p;';r+#ǟNA0"4 2IDtֲ2*(. dt ?؜H ZZI6şJ}$hЙ{Bg &I`/g<1K1r:\itd?:"e/ƒĦp 10rr/۰^Zx FZ@&w9>(3w0s\cmޜ!ڢc~svSOֺ;ד7 A;򼚉Z읗ՙWmAsAet }r»mj y._`m78r88vNzD&x;ǞY7v(1ޜxj /&w\~ ~֠ScDg`Og~;T 8vޜ'T G@?8{~a;T l=6 ڠ_`C c`=xNR;%)@~H &JkWpψdKgğQkd_%͌Kyqi#c?؞Tc ;j,h t}s]1ebA@glB`QՊppG'0  P)%OXYdER9N$_%#dvFFN]ʓ$ 3`@,&&ZuG\?Н NPOI

$<@퓰[r'}@!s l{z;X' a lG9O~OIP/`{;Ô` G8G`vN۰6r>;kP/ll@ޜ_`zT` aL@ޜ}S'j~C`@}Շ) 5۰6r>;9O'j~9=S`S@`>ϲ_6y6yhX' l<6S/9Nj l@ޟ<`~ޜ'j~w8=h}CT l?:{aqjQG$`ޏzI߃ډ">|DH;HGtIqDo Dd &ORFHPcHI #F2;9SP/lK߈;ӑMa|v9cx|`('j qNosAs`:~C`{֧akp>}>z;T ?ENxaU& EHȡH֓9Cx8O%b\NE. J"嗉Ͽٚx\}g6Z\Ta/ W%CبV8AΓf-6EZ,"`U2ų:Jśoƣ>.KLY՗1i**7">=XBmDnCsURB.(EzR|y]ҍpA7 e Op I ؇am-.u?s5?+qWzLvWw6nH9/x:qO+af wfj'Y a{@ :PR4AN gSFiCԹ;Rdl&G}!sW+5H-vy|X^tIDO"'f",mW{"Y?%rǕ"nD+8BT,=a>|O ϐ)(l}i~?7?"$GQQG$N;2sC >0pC:(F<,Z;c 苌F&Fl204FA I n?BM6߿3~(ߠ0?4 Opk]O3{LK%M$"mdF"l?Ho 6FFFMB{8C3JhsqT.TM|azhi((ehȌ,2*c4l[qP`CK@'>u'6Hȍ|XV%8,"3gS_Yѧ*DON t+IT+y9tM/Dty9/)%dGMeuI:+ۦwãٛM-MЛ7i4îjk|\˦]#Ny>x[I99OsÞ %8-J[(T௰ #8,`"gTC$ ) @g">P$=HC){㜏+t^=Ol(&/oa1,h9zu団LD^}{hG}&FSLG>p(9b&AhW 53xPƭ  OK %bh p6G4G@CqoО2xy`^R6à\92r Q?(L|?%ߦ6lNc u, dԝ\FFO] gɘL'>#7n"=ZuO;Cۚ6zRJTO|RQ 5oRK1I7;Gfv|c$QI]_ awO0'︦ӎ18ο%L=}[:4(ڤZxǕ0!/4r!2xt1Yי]=>":>T]*Ӈ_]%_[ӫ륽W?Vs/}4n]{s+LJ2CT>>٪G~ڤiWÜl3ޖklNToU-$=[Z̪C~~FcϦU>Jemal޺?c*CmR6W)Xr<]utrW.M`I.XJ|a+c)eTc2 yOFx?b8qYǮn7Y9Z9psN o 7rdlhhf'ixzO%Nlxdl>dWe?a?D{p1RFuJv$ Xb:"/'',|rzOxեU](I)U^H%,Q >qquCqyV.=7s\81WrV:QFܢ𱀺qQ䉐t&/S̏,jzv^R<0 >i*T'XfQ"gF5tsW/3 lv-Lvk O%6Cd<0d&h< ]=@V[3W*bݜZMk6m#9zԮkY˞ԮFmi7zrlk6׏1YGJ墳+Lr+2Q^TfWUaLO].Z+2X+̮+=ʾ-V{ϲMoMLʑm/t5&uKM54)ecD>Ƶ+Țbb5󦸦}e5ӏjq7o%whuRLeﱞ7z^'xv~z3~ޞ'"BIz>cz ()_*c,QELdr|%i޶'n=rKΈy8ã/09PIP NkC iAXE)u5o5 jZJY-kL J6m,L&JbʬoL$L(BG{zl{ CfٽGXgZjgC)n=c,QE$ؙ&|+{R[tn_&?~rKAc'TF߽8-YZV+pݡ%|'u[DZpX]S#HTEh93ihU"]@E",S 8914N v`XeQ8/&ik P^ӂ#V p^ӂ#ѣN Jlf^{r6^W]I-+xaK `6koOZUZI՟3Kq%'&A1EEE*?gI'йIUU)`F<ʔ{\ 0ܸė)1dD¸1M7D~:`b,7b\z1.?(-esÓB6SΞTУd;4ԞݹLUTmE&]]TI(0xeR|i4K"5}2RQ9nϒ>I(j0ۚ727@cA>i7$"6w]zp:'TGhUD}Ҩ#N4G^6i#yZGN~Zp~ zp~*'TGQ8=&-DpO4mUp3wU$Ni?2lڔ߷SzMa8w\[k{;R$%B I B(ArLL$rJ (P(9PĹC$E *\劕*I1,dPF$1(S%{%S%{%AIC{ڬv;bJUZ/R/{ZZb.H\I$;ӆ!\rd b,>J8 鎠Ճ8>ɘK2ڗ3Íp};/Ոe% -\/_DX0N"dle[`d9'iО4@qIߍ9gzᝦd#:>S&F>zh9"4E0>;N#2?Usښ~ k)'x˼v41u,#׋g V6zqEG׭D{"DN8ͻs?>@6? BO0T|yy2I{> yQ^y?ne `="~h*k֩iɹgkq+Uj%FU9B3 2rV5C\MX2UIj&I.Q0`t*ɤrN`Appȇ'%&$ {l3yoNFDىzP.iǮM8q5pH'/ni 0``#'##fLdIRA>a?aÆ8R% .Bi0~e ˡNV ,3f 4%!6lAC d.8X`0ji  6,!14 (caͩJhn7faC`8r44c,V&/K0f^EB$o?"U7HDpp\:KTDq@bs#Y8݉׊MК>4Ǿ8sžL+7{4k t|I hN1Ӛm14MHَ8ed=p}N"%e%uRJ7JOB*QjԦaG'ҟP#=,OZ${sz@}b<K"\mX݈H(auĸ!GYD{#)r1LF#{%31Kmɯ&QLF"bbZys ݤoǝ;Mߓ5Q)OEJ\J(ԏc#(FS :(Rh~h|n26'ǟ|G\L\K%ۼ6뉧''nO5:ZRm;'2<5ۆUW;Ĕ],Όs,oq,*`%%0ߜh fFCPF=eӦ=wc*jT% j\2%oEQyhɨb$MƱ i0/xbeB:DG&qbde}cFj ZεUjlIdU+}Y,RULI,$N({p~t,B9(z$͓5g *^H 8xx"!7c̞0 ?ş J%|I5e)RTxra}/d.Z7y\~L)sd{66)DMkM&#D&Afv$2UY[֪JxTEK>y>ɜRs%&E1yzeJOb.JȎDO-h}W>7Tm&m&I$F$?$|Wt; 4 džy۳p@ªJb"̯?6'7I'OĞBĹ(IƦ/X`9u1IFXni?-x8ni#pG xMN'ƈQCpÜq@Gp}8Q,J%(p!< q %0'F{RP!ZRZhfE*1w<P'FАO1Єr~7zcne(Rmo7sKK+jدΥJ(&Uoo}Mdx??#]UJک]]V뮕ݳns.Zv*խ_Zq_d?#nμIn6xiܤx B8=!7H:#`T#4=DvEL:t)j\J-qK`L0NN˞r1iia71)ۓ x^< ȚgH̝b&q. V7dgEx%\n\UUUU(JIOkrK"8J'LW_h~mw4p҇Ї<H` !V5Ig">#0n?lz}+KDZQkMJ&a결SR'xVn76śʛ݅ɘLLdfdIu&|dv#Qɭ?rjQ0_*Tb؊zX}}H$v@'`EXb=Q7 >ndM?`zO>Mi<,,~?>k}SwÛ Gd1Ŗռ[OF+ G">Ms[ Fm*ZZ)5UJ M`DR̜*sV-J)@ؙi?=o#5*J(Iɰ#{hۨM N hNJ?uJgqL t$:t@ Urv)Dc% zwԪq+Oi"C pE06os'GjbĺqiKc %;3 zu&2O?<;ÿx| 1a=R# 5,5 k0Z"XT,X*G% r^2KZʁy/ygJ^_u:䳳=)gK /OqνB=4a1X$y2qH_Iq5KV,_p<rIt<yěr%6"ھ>>a2ɿ>;ԤJBK%RHZZɦXmO~^?u_H=Eba J0nQO8?n=@N'>O;If6ۦ&R-JY5IS?FS''Ɍ ,w cϔM2*脦x\eQhG&#L(Q">)$mTG)}S81熀P:Ѱ>CoqyNI3I'T? ^3niA2IIq$ړ,2(G'&Q=c7pؓs%6y(BC2^' Ș (نQ=ϟT}--hZ""" ~}iA/ P|qcX=(yy#J$;3 [Zw8&ْof2ܢH.8=M"e%BQb0QFӜ0=8x>@<)e̷%#LTdIoL|a .2I|eML"1䱈 %r R6ȓΏtZ8xĎČ&"Iy#b&HyDmF.YDmHjkjKE)UtED RsË-6јy RD 0ˋk?ᓰn)^>ϑHжYih>ߍ7Ƥ%kEZL Dy(#y/N<b Ҍ%V,[dZV)$Iqa,OjMA/8ŋFilTq EuKia:(~|V(;JYYYR֨'*)W,ejhi+ZdLl/F(XZƾ2%F 'BJ"B[)a KR<>'N{qN\f'"O:mG2ꪪVTUk_ܵ$y% % Ҏݟ XW6 AHK'rRJ8@26 k&Ild $W&t)(Ҧ|I~R8mEn!0Qq(=4+4^& ($#PPRnL,IJXْ101 )aq#' (,3 d]Rx;"Q:'\=(D0&a4e(Q%!5CR0(RNK5Г&\EMjҋjXhͼo7x^zacd O˔ns/력RZR] vO{1ELLB^:AݘFab0XF cX;2}A)6c!S8t݉EG9$I$߇5D_>~/,P|sƗͱCF#B H\K%4xD"8x47FHѿ%$"'C}}߸?L)O+M;/Wߎ[wI!|s &Q :BX8ʓ,-DCA PPJ\J 0.7./JƉ$[pcK5B $cJVY(ʑGv iBRf(Ȋ8r c]&XYU'ҤPF9Z{N96bx$co@ 0jH! !2pDP']TA@xծr$!2tcVn0r;<Κ$ew&n82X1%0VTdIl'&O:w7>|);F2(֦W甥)Jq!7p4Y!jXk\_0?$6-ge"ȴpdvnY2ݶ㳏7d"D"6VBR79hٳz=pxGtb༞Xsl{4u'.' cHGo эɾ1ʤET/KF<}Rϑ"f< :R#3ϰJIbK^*U*Eڵ8qN,X{GCgEb2c .3Ii_V{R%$rJ$N3tM9! ((}ELBQV*#tVBx#葯 > t(C;4BdXKpe(溡ÝAsryCc,OTL37 ?Β#UM:v\3G(O4$"cw `?Hp `E,``К (߸-dPޑAlqfXiM~g7a;vqП`<<%hdx"vLcg/82Q TD<0ы.e t=3^QunfԱ!V۶0A,))&xYB<0X[1K5 I' Ù uC }Է6l3b^^^nȈD""#@ޛwb2,E瑯#gi4U_D.¿6xbIUK9ʪK\[)/QL,)^%ݸ+FT,S}&z܉5g msQ8 Y\c$x #y*nDDMCJ%%='"xD((wA9):v YE]*MSl?4hk ϦҾkJ\e=n# 00:N iEXz č 6 zX|~Udwbh;X#Þ~=eDB֫MI~Z>&D D/*#>e{o[Sjd'7 Xp,nB}H?Iq chM)1϶<;x2{b?)jK g]KMDQqHpJt"A%|h|W. $ؒMYk\rK)^]ݞknx!? %,Xc?-?`?8$rM0%.UJ˅1@A'7bhA0 R%GxGOD8B{3ퟘ(0jm(QE(6#\mO>Hӣno3fdu[*TIB:C lPTIL)>U$ /e= v<=ޟ|'޴bcNș(mܻHÒuO 't} ./:qE^^`:{S\AqX7BX(R.30c`6y.kIַzgo DG#xq27)`"pIpێ[v~xBC&yF ’a CSI LL0{5ǣ `0 4Pp=3z28qz?T_+N3שFLySK7)s6XykEjDB%Ē'^&P}Ǐ̟w{bOjY&H"g$cF )d#,42 . b$"a Ьbdݽ1z{4iZXBCĄ$c2FS LŬZY&7=%ܷZ4biQVMѫGe%^&2!4cvDF.ǽyVkZUlL-,Y-kMkQ%!)ilq;YkM{[z޷q*RY֋E$$Z[Uj&-4ֵk6i6%#c7CzI*`ҽe;c&dRRY' ڃ ÿ&I탻2}uZE*p],,a:rXgU<`|mN0cDI#dNsD̗H#Ln)ͦ/J$ /"="Іꪾsp9$@J%&L,-1,X8;ä87&`'M;`(%,~3$\'T>Ce6ndIn# L pFu76n '&PNMxڒd 4m}{QJ'\vļMJ/"gIdKDx!*BXy!o֥Ec g#2YOO*#*D"BP/l& KOYB}B_w7p7^U5UITN6Myec=~y2&tѰ}Úa z(b%>1. h0eሸ ޞ|ݦZKo7*T'$#7#ɞM(#"3Di ,P4C f}FD᪦3 as|ZRgD5UN\\Ð$$%B6!,>x7QDQI(^Yxofz|# eQ./2Cz&YОM85Q(O9ߘIaQ,&jDD?1|ydO%f"ŏ䤩:'bK dHϮ'&Յi[3jO~XG,\|fӍ_(v g"cU?:8(sp˰Hĉ"Bȵ&B$a؃< `ztXf<'D$e&Y ڍ̸'SE)[a#y2 x2{`oL D'/'<2@&T*U0X֋C#>i|i%MiʓqMqMH(>?yEe,HhiֳRIi$*ID_ď&&1Y ԱCх\"A⅗ `{b\I7 ?n7wҽKoZl`Kk#kig?bHb{=!8 "`"BsD" 5L d* LDNxOIrOOd䓏q'o B`FB!`X^b/2cf3JDRem4K0֚Nͦ[%ȶ4s6NhQfj0xXDљ(P"!$Y j߈4 ~hg7rPO9 xNI~ |#j Y[ō ;s@%N,_?< VRRRQ{#&e[K@=lǗݳNdk ,mVV/4b-XXӷ/#TP듪RTeS_UzS0( E' tVOrߋwŇ"O&N|4u&@γUNU%,cVZQo)UW#" F?|o어jR;a7wޚ#ˑ\&rF'$NHGH!gq 8x#JiT`MbRȱ$y^zd9y(|(? *})&i7kyq>dpqނZ0IbJI407xw-rnB9RL=60hd KL%҈RbuRRQE,...RRnEI!DctDL)))0$"B& M˥͓cdHD!72$"B&K Zsr`Ll1Ŵ\l1.I1ę9V31ΌnHL:fΈO hfml vg%#ol4lt.ucg<^.rlƃi3V,3.dn6cLdlmn4H7&lX eN/s/Mݝ 5A$.f``},X.TeV bر@Ì؈$AH Xpظi3a`e\`>zRe cgV&yFID 32 E,T͛`| ؀Ph Yp4C]Sihm43^ۓ< gB$12Me*`Tb`04Tm1pt( =<v0^7LsQĖlLG D3@! ii|DɊ^]|2-eѥ4 y1fQ5$QFRJ'HI  # 9p2MQɷABI7o.t0Ė Iq$D" $n.S A;~0}~P%¬al)\ȸL3 ĎFi8Ġ qܶLYhX\{pmi([E.-sT(8 -fh> ?'C\CBk,dJ&bIJR )mm lĈѦZZ"iDI"Y-ATM&D̚j&@D&$HD)-T+K"KEVDd"idm$ȒH*$"$6&D$$ -m-&I-$e I&UUUURUUUUJm6ZHl#Mh"DD4UIUU M$B#"I$UUUUI$DU*6UTU*UIRU$IUUUU$*il$ETJ$&[+U#jԑk*$ZcMjlhZJb[D+UIUURIUUUU$5TURmVAiM I&(RRUUU)*JURZ)U*UUJKI)**ZUTBʪKKKU$6DU"&DI&L m~ei|BAcH_ x(HRO#Ae,-@! V M&`]I[,Id˅|@re2x\+h4!uU4pS$,<;璴8޽P?X.**0P֤6խ+U.y'yU/Gu=wzwvټJ˝ܫ, o]ʟ;?>}DyzE@,@(G|Gݾsl|'yj)ف$1 hX;t _bMQE2B*K*: d]鑆HAP H!Aa\(HmPh:Zz-I5RE/o[6J%TSBZYS4>Ϙc\`8D\3eCy&>8(M̱ ˗Lh3=ޙJ#*L>ehEEGR&SٟܕwfdsuO`HD"fu0hĪ`g>Ixw\QXf65;M[C8QH׭6xMqUH=MK+L(xHVbBB4Nky+C *5+l>?KI,LDD)Ho|cV Y%4ږJb|O|+bľA%)IU<%+z+`w+qb2^ J7) 7LVz- KJ:$+uYn ]ˀ~&˒b%! YK. , 2"аZR- apAe$B.C= ;r -!ahih.7[42lR غc4@M4d@'rȶKHEn΅9ׂ` ,% `Hbcp` Ȱ  Nж- -'qX],- mXU ЂB M-dqE7D2Rb'E,([U IsE ,åBHiptaMd]paJ%E (P^~,c inBH6alwc3˂-I{F4;"S@P˭Al d)0`Eܳ@\b-};C N'phP…r# 2K,cFYEqvĹan-DXXǛۜl9ۜ !"BmPd(5!,CO3cy7Hp^.0;Fo("!̉\ܠf hX6"i-P[!а[-TP7$"IQi i⳥DIґ2yA&I/0`9X#-I܉r [YMŲQf% X,V6We-"i`h.(H&uy% hԓ×#ϔ>Kȋ6иդHU9E(Nu: M"Ao*%@$aKw~Ct"@<t`2Iz&JP.0e#8 Ѱ`^W& :&ǦL ɥ2Y(JRfkhK2Vi .cEFlttuAdu8+pB ` \3!\vC`PZhw,;"hf8 !3h m&N lqtw0 b։P#%,S"1Y R*I&u(REKVpnOba(OFDJGsԉ DK r|Q3w9a?' ҉F%XM/Κa4BiD&M 4K҉J&M4"iD J&=L &L&M(O#y]=?< .~>|F1\5f2/ne ((QEʮfԟa& *R:Y =A>:0hrLҐio`4f{;9g}Y<\N?O}Frm'jŒYU?))2c.2\KC| zL$ٱ5_5Ŧ ՘|f}DDB"#js:ow!c}43|xr&piLӄ7 Кs)2 cΜ&7ci7 /YrxK]*Tg0 C ұ]b8(^$|ouG1$qg~ IF%Ur7Q'sU:oyA'iTC;6c'!C d7 dfSAB8BJ!9!9|ADQDgm$!Uj8Is,3T Pزa+%L)s<'6&nn)UN }Vכ]n0)E=6zx%t.Qs[m,+p!"&B*b>4p|0 <+tC^!(b]pAہv- )GJ,Aו>!4ŒOH{ya*FTyQ 6&5uXLI IRaQ!v /Rrn@l]62EupypvF,[["tXւ64BHezuP՘,D)DRY&" Pi !4%eQ]X8&! ~BԄtMպXd"K #nu!]We-@ځn! t- e` ``,X&Rd㪦B 2  Q@Q4;UQabf Ȱ6mt!cC24 ك9 }q|Ɓ|A @N7< V7H"]$ ,(|CAAbVl%.BICS'!V 43(fz=CG}(Vj`޺]ǽؑHO'xz=厘}/?(B~ўмC$_LhBzx#N: A4FK挢62ug|N3lL&26ecw aFHiKTJ׷ÛJ/st`eM^)ԼG%_ (SF--C̪{mVVj쮗utR4$_r1<Áqmč성ȜA@&pL#PO17bLL1'qGIQbe18bqFKÎ7q&o'Pv5QV !$ H+Ғ$Y ė gRlrDHBLD:@!`{v6ԔkC,D8 : Q @cF-5 $Soqıv: lH@듢^IQzU:e6 [ q:^Yup EN$h)'BL "D@0址j. B(C A.;@;CFC wwe.&ב A҂II%`8bx`@&t"(CO4yOYbo@%]*LNNꌠyid0~]?YYA'T\O`'wZ&"M)p:G'\IqHהf ̗LH\ˏzkَЉ=;3’"iNԚ *LH_F 00Ҫ#TJM>0笖(Pl2b RO SH`3K&%3 A?9Ԙ`&|cǓz#y$orJrI$ރxV\$[ױV.[DU*VG v߽NoWS>8YjG `,*np"q߅`ڂmA, 0 HN<70:*H~s5UUR)hK 0F7fF,LXNBB҈QyU]ywR.;=jT)lOC/8!U "HSQ7`y&TMŜPwl/vtOdP`FAōA5=LE 2j7ROnpuILOw% sX>xXj 9ۂImog4Hŷ24v K4{ &`ae`ci."FI.&܏F=|K[ .e\c# dIdMH`(1c8xT=#.\b,b. [|`>M<#uhqgА̅bNԲoFrAsDƵ/ٟO??qyYo5*tJ./QQ{O<ܳ>'lOH.\s_$XO)iE'J(.%І ׄnH*dM' p0+#4&K`LN Y%L!2teFX྅ /WT4f`C,Um7 tQ0  TnQ )!!@7:â|mKdmѺ/p`2 飤1L+IQ2 .jȪ*fHf$\2@4hq w8 dY7.%"@!҂E$3dd3b 8 ԜwW=>7C-P!lD6 ,o7fv)mdo ڗ4L ' Ix;W>i yz0:Pt.2)e1O6Ldz0F/0t,~A<ɶDxovbMوHօ‘ERhqo=<#vOn6(n75h0>)ZDU bS%ZT6Jg w{G,QFb‹0C6wz$)NE&!ux 1,G%db3&Gh c5;grvdINyCRF̙&QxP,N=5 1>N'$*$nj$'?ɞ/ϣwIHO8,R;(P9НIوhK~pDcL!?>8#{ %%X$X2G81>Xϭ4hg= qR?b q(֚v,i/hTM丌$򉻛Sqa(RzCuxdDFaFH s? L&XK/ĩOF4'05Xވ\-md^%Q&ؒ.bqk$UЩ#֪K=ov^.5FJ|r,1`iK )SQEF%FYRQ ўQ) >Q2J_dt tv=%LD5J:?HK=4of܄×x.0_T.g|ɄSyg184w'nxJxt] 0]D9gH#ϔnf}wD6`h4 ARޅy%{+dNi}6Mf1ӛ$imr N$f7j A9G#Ú`aaz {/j a\-go|ryO'cֵltx8xxxxx8q۷nݛw@d$1Ǐ>%e3=~i#Uǰ4 >@ΎBP qHN4 $8BhH:4mov߇l ܮW+iAw?9kZյkVCk@x!IhZ-E<єhY͉EL&GZ?mќfF:&G;üvcܵv۷x.2Id0oi9?skZ֭kZ֭jڶ888888>ohVյm }G<Z]XկVz@CTo8Ꮙ` vk<> i+j֚M)K(oU깼o`p?vX^6g8%8xxxxxz Zֵmz n qׯ^z58N'ޱJo @nȰ7VZ1sqn7{,}2aDEhtZhM̝S{jrI:G$d{ڑLRZ`bM! |ƄGTuK6LTc,m6Mi4[pnMivnݻvaw+n[իN:V`ݻnkZֵlg q?˼!̅<=Ǹ'%`,.vVگ+ %醬f^tg֫acƌLi:0M 2f#Ṟq(Hⴇ]c;L%!&S1sG3d9J5qdTLXiɭ O>!q+hL[I_WW}'w9g f`b?1hVxs2:ٿT;ɜ^`=ɭ>qNQEVO7Dt a?y/ɞ(04ͮql7n̙-s-34ƘK> I:AfM54:}H77< XbFYg0IM> w.Js 8{(M~ e@2L&]&FNbciS 쌣)A>qqO^Kh&oZiod:6'h\&)䆂b6'yR`gtٟYЯ78Vw%.1,'v<_2rZmy.wo$jͱƚs\sW3cŏC43:}`iOVTК77 "ŭ|fI/>'9Cl-%c9eS,uJs^88}?# ÆEo7 M D?'݁ltCPqٻOiX!E&OU<bYK5N&3pwh/t%(f vLts<񯝩y&SF-5I澋bleQ 31c3sƈa_{h848iCƛM\90f:r3'{6of2siAL(cOM ɸ5`M4Gynb75]M x#c8n&e8(Fݦ'K .hz&pZl4Ry 4D 2(QnfRgM\g;>uyyCcdma赯o ;uBʽRչg :vJSP&3=EPkIL139"BJ* gϩqC96Φ<*#ɊM10_1W uFsʚ(]9gc=Q7R8r#Xl\9ѝ;Ks&v0&EUr~{8M{/M{||CٻR}_JG`aba,` 2 62oUUC_rwc;wv &dЇ4j2n'ÇjyzL=9>?yFqe`+AAh2$%VM[9dY2 Xg3?3N34FhdUOlɴz³I3tΙӥ3 ՚sHwF5$VaϜ@h h |hMѴp5k6n\II4LdcLi4iSaۛcjݚM *ȟTa4,+4bNԉt4p \\\\\\e#&p8 ,~EQ쭑cYVZHشk nݏC8D`E $ݍ3^܍|-tkb8F#vd¼5_n6a5 v7mA'>l,5f5>l8c~;⍄$zz5;3lΈhi-;cL1 NXN𒄍y3Mȓrumo^Φ+մFveL5ZͅVDZyؽ&3vǁ?1Hkk8 `D7^{>h$&O2x#Pa14ƘP7BzySv3Md--,S|Iyg@zΖ,XC`4CHkGhQSILg3p0n]ѦAn0䵦QMY՞:SJg dIb= }4u2Vs&6)|l3pen 5JVjLӚBp׶ٌݷ܆~lLaš kt2dh1Ĝ6TiN\@LidE>7!0bgp`as<3)x (0FGQwS7s8X|˗,iHʛe̹^xjf[Mכs7>&h7S0δqbŌ1:cbpcٞQތBd> ̞x,vΫaf˚kSlIə3f3̓B"fMbǬb3)9 >df F)^e5\|{^ ao#BJQgfݭ]^nչI$] ҍ r &G㵮j;zlWIm6]̟ h9ь&'3ηYXՍFu7S8=EaLL%gss^pgB#EC9̹8\^7[M 3O2mam3!,ߌWMܙ,;1!j]Ur)j|ٗη~h lNs9dODtdlLQGr%ɥ8;8d,XpSI SDtՔjY/koö%ì=Fk89w+n`y=Ǹ ii&G&'&fUgrs̕¸춋KM™S9l&hCbM,fL20X\iCi4[-fLiyeGh9@m (1Ϧ$(s'*^0eO2 i0ipn9J)u>e2ri *k[tgEN\7,'LQYZLvl>y]Mއ`ǿ#lڪΰjq?uݺmwwۻӮ:wK.:uTZjy]äDm|URT*JRIZi-E%IUTC|z2eLvP|Łü <tz=9 AuO]Դtſ.,]N]}ZM|nݯ(;&aG4z?߭75]󨲭ZX(9SZQܖvg\yLxÞ=Ѵ7B;ASnߪr{'($a:$|2RTeTUIHJRU#N%2gU*T켟ܽqB|a3gmOTj'viNjs7sǜ |332O7ZsNNSi?֞A8۞y6ۜ!h"w5>|ؚp6g0y9@Qz4Q򌓸7'NG:qǎ'ZOSWuw>㮒cIyxήO@DzB*j>C|a9$ >orIۉ[?2؎e2sUYʌ^O=m';OuOç,HN;^VӜYnd ɟ #F1L&C慨n)59'OR\:v'nD +q \cDx1BNIDQ7ƃpDi=O>X22DNXI>؜Qq2GrtGdy4&n4F6D$\&y&EqOuZֶ} Z_w N[USK2w;]:yxO\m=C?:UR--eUXpi^Z鼠 (n7y#8;+*u,őz؎c7SfxI2Y˵SlUEM4:)8I.Bhf|۞\385|(sQ'NԜ0g&Tl&hMSFemu:Cz~ӗrh.9FOc y ̡d&EhKI/v`__|LY5L;C'}ܖvg0&LYrwdc喵[*/|篵ֿq=RNHs|JW2NǶs}RUVi}oJO*s< = {kkpßyA 98V2M{*|O>9,Gu9p^9_yrqN*oyVZwhHƔ '|OA+v{cҝ@Nq'zMZ<9>.}Ug?$<97zqKXt' qepEHχ7nwKNlMn nj<}*7׽5]eV*| S=MY5,\X/,Q\X:Vڭg;F6m#-'}_o~>YX=^pc̓w7n"kU`qC6gߜO`H4i<(czOSNr+Pn{Vp|Ŏǝ y6fi͙ 6F"jDB&Y6~dS[B֡JZmZi,"?!8% XXElw~jy?=}y*`lҾ8wGI'5,&nǹ3 ݅J+-MZZчqLəMgu|_.J.hSϱçx[n3x< |n '*XeUxMs⿲uhv2C:ѻeJeqg73''=cu}wwM>h}ztgF:?*F>%Z$W~mj3>|RͰxg?s=?G0WHHwtw6ߴQ:Bŋ6 ('М 6\{S67])7uWlg nNu,S*,v MQGF7 ]j[:uBo7OM  z4 < ϙq'8<2̒xƉ_cwxCN s3PzaqpG":@si}O(8~ֵxD&IFx8 > -}ґ&N=brr(G <^n]?`|(^=b,\XbXpļ*ܙ7rpɸstˣ=z*W-2kYzW=0i@gk-tH~7r<\\(r0a,QG@&<^>n|+57j5'}/' G}޽w7eMu8y~ﴜ:ָ'Or̲gmbgzMv8'xh3ۖ7=nyV%4wg=Oeʗ.xslyϝgs~m>1::rr  6ySq6bkp:s 2DXcLѠ/6G"Uu?p|Sd།l%R($?^mŌ~< <H#jrlM|Jx$˛=^<|ʵW< LGu(G7̯ݙq/~>AԜb&r,\7xkU-kUUK]uqs0Ixоu2>3>7w˹]>Iˏ0<7Sz46oqwOz][GjL^Os`0g!lmIԺϘp<OҺj~>X>Qq8׌f26Ŏ8r&vly1b`8c^of~6uuUן`jdCATd9ဎuj5'TwC>Fk4 ;|>/LpsLiM)3RrQVkf>{`9A4nI$n7A#Dҙ6ǀlm!Ip?w<~ytpV';lvBvQ}R>;BgLN;ß{Z_? 7(ʔng(o>鉖xyA =^hNӜN+_G8vG`J4GݍYbM!eI91w'Xy| ngi~>'ObqœՋyt$әqfouzpʭ ՎnH~߼Ήь-UkWOaK c4ؖ,X5fpk7UunWZZO]C6zp$}7wj^TƼ'+cVHݏTq郛4Rfu!xCq3eV˜QHy>1W6⧭Ƨ:;8LJѤ8<2{і&3*ֵjIlw[is;8X3HmMa>FI9ӳǬ[uٍ8Κ<3v'vQ8њG#F(B70M>MW9^=HK hޏ|{(f>C٧>A3QIKL7Z{[OKOy`7=lz1G=N0dp8Mp &`weP}LWuCsMIULF~ݣyeގN`0 M:%SUhZ즈O*4M^S^f:sv9܎f.| &,7vG?xc@s wM/kf.q3C9O9/PyT՞{3j7 92?ΐ8g?-M26|8#1ݚ8RϔxRN4ڍ:b|r7r&~6|:Š,xaEŠ(y˘tp&pa>L:6IYǼ8S30=)&{SPoNkq'0po/__~'=y)QAEv=M8bzytՓPش9[->K,vC=y<[U*U*RQHZUTNs*xS7$ÙQr=)dx"sqm ΰ<{-?V ?9}N8[r _y|?2G>;d'ffdj\]3I"~vݷe~OCᎴ*xbo<{>oAOU} XUxft)8^K>\t]=4vyW9tli_߭JvS ;SoV#ײV/5qCy4xW:l>y]3~\gß+內+:ۇl|7Kx_Dc4Oԛ:Co Æ8Sv5MC&[?%_>.ӽ{ii{B?|@7oO~Џ%KkI*R)jU%SJRpۖ5Ψ։|<v'bMǩ2/v|`y#dx&x2x xK[w6| NDu$3A7opݓ8Ѹ {}qzEDXi|5Uyu~jp|#ˌ?Л, vDexoW~YŹ{k++K 7xylA8tFSԏ(LajZ<#N\FiU_ְt^^>?R:~y]az}n>jwi]F')Y}pda4l>1 Nǣzǭ,>1t5ObJ$\&om >[fyFaab: R*'_ABxǬt>l#fǔ+ L4ruf32qlI#r9L/&K&!:fK?F!d{vJbbf<0J9f:g/Sg4?"XAE ,CؓT4p?2Yhq~ ޓC UQ%47f$lLN1yJ2T.F0"9UMŁK|6ZIJ1]J șf9mvR4{ukr ;'{o:2y+[}`=Ck}-jUŪ0| 鸓OUyӛx7أ nfNn̓DȺq3|{'r7zSsOn9ssvwҒRu0G:$\i8sM5,L&a7a爩y#z'Y4Ƌy15I٫MʧnN:j oE 84$nlLna;FsVu/ÓT 7Fe.4˰+F6BMA3U2QgOp>C#7Ssz3J)zvqN{uw\O/Gll8A4V mdbsb4ѡݛɒ^kS3t $Elo \r,ugy7rM܍ܛMę:y7XkL-eevMXN'cӅ_rR0`yc2Vɸ6$Ѧz|h-Ctii BHrеbԜkl(,Lܴmu9DMJ޽gU`QLu*؟ܢsCggL!z[Xt5ʩv]ur,(M ⌏0uA~#= qR&f?.׵#'0lw Wh͵uMOVs{ މe}W\>@w:ތќv~{_ys-x"zÒxq;<8sM9ˊ;Z8ĤRyg}")K.^F$bJE''%92$ID8)`p#yq i:bdNO"pDܜ&^6Q839ZLfR)6b,E%# N!ޛiUgha7:.C4*ّ{cI?blcyFjfb_jZLH@=a1X;W~*mL"v,<ۊ0MUTUVI6`*3̛zr-7GfMA#p-GSU6l&#%gA߄pKǞ'aɓ1BId,FN;&TOfI#dxxx w,eg{]č$BBihTXxq{>x52͈75.7!7msҜ=A)5$˕QJt oF›N@ۜYy\xfJFG~76py0991vwp4or&Ϝ`ט6`0 M63O/Q0h=x] _8ΦВ4d8qH#jj$= pD ^i?:6p9#|M#r8Ωv3Jtߎ&cT'9c98 އ@ trk,u~߻E{ֶ`W EXz>W<(E)ITn|<- 4+b=vVJAlG, NpS:D0.Iiq6d6j^p&mΤ"23Z\\M7MTҋxkXt#O-U++.W\sRxNw.OS_8&P,0}M$I'7ezwȝG'$OZL̾ȚL Sy7imc@q$mH7y.4DGezt#@#{!;1<>7vDh9;ڵ^иdDQ:SVpzE7ӄ⮻6DIp3 ԭrc8dÒG w~"'NpSgg9"(ϓA1ipLZГ)ba7f^<7td$ ؙ;&\N&oPoc\)$M좍`ɭw~&O4lGޙ웸qQZ۫{щDHX)'N3Ohm \XЗSf7ǵ#Zw8ɺ%(S;i e9{7sq4h]r⮺˔sZ^nt Ό8ErI3!a;'IkPG$z$S(gKܞͬw,3DϏ^uƃI$ܧўhI8sw|VK͓b%RifKaa`YݔUD0L]gAgjl'BG8967^571dx{QFGw{9@9J+4jTZeS"Ԭw-N?w_u=~7=q^o7m0ׯ۫ftg/.RUz]ׯp|@4ME)5ƈs<NNlS #d2Nɭ5fV"'wcnF x-Q)M%51bRd"cQ2=$cVwБfxCgtw'rd[̞8U)JR1óC<95xdVֵE^wY kuX`11dyA@ ~o}ߊ"KQ8XF^JueNz004#/9s:rL978N7`zo9'~,8]\V%ΩD݂vęMsؒr y\bQ7yGG@޹[mJ 녥UQ)c.dyM \WolnM[ZkLHdzbI:s>xC4Bp<8I4z/)um[nN͎gӢiJ5!qȈvyG쏒NxqDq 4#~^8.OJ%HC6:CΝ07ɣGjEZ5gM4̃8{Li@O`z4TsUk,zЪ-n,HlNf|47!՝uGb\5 2 ́'2LFgtDŽ<L2 ͚~I\S3ߴ^Q2 '`sҖs&rmu#8Mηۢviq Г[ѓ'0Mܛ~rnn[NГam1W Qf;[ƌ?'Ml&gg of3pO0ۓNMs-ik4dqXSna8')ԣqwq|qZoGY3ßfw74 DIBx_9vMMp8u64.!O5#47oČpn[n8h:5,p]j u.-E lIC"rzo#ix3oܭ <))xkz+[uZ2I,Mr^JG֦'A1$Jq'ddSSG)la4N 98@ћߤ=g2\tqr#4kSh2ބo&Kv8h{fK(ffN8ih29r:Nio3%bg݄6mk+"D9c~5Bв,X\v K Qqq=Gq=ayy`(b /0p7>|[Ed$TeoDj)x1]7qҷBS5sbG +׼o-y<'#X݆sx/ɵSy&ձ,NӤ:`+·wa<`v{_[2n#rq3N=q7"gLX|Ώ]CGi^8>O.uol|G}q~Fy&NvZ6h_F4ܲʭ~۪x7qv؇KC0Ξ"ӹv'N~nyp Ugwӓa7xOWjH"mzw9X&gQ luǖ0ySO74$5;T&~ 4ۡ2۩:#b(pn{CE ؓ=ј2Fyq˛FF7ofsҖ5 c=Q 0o&:8LOCHiTY8-RVNekRծ5:O%&r`)98P&:dԝ(N uB~UUOjNHѻ"2ӲLh/ӫ.K]Uy.;Uvpʲ>2g!)Y132ҕ]urEc ;*Ub2/14Z5Y(UdI$ѓDh4pDQ,eZ5Mfx.`\fFߍhPITR"mO:p',\Q ΐ[[|%9@0LL8_7#4':Ay^=O_a|>ϽirfDjukl^&;j'b&RJ7pGW80Ƀ|G5fcյwf+pޓNAu Z"i}10uwtS\cpeK~/+j^gO ڇ4<0mKpC=BYNʝ);:}cFsg*L釩5nwk88ĺ۷f9k٠,lmNff͘}z3|+\mmU= H3VJ 49)l#;)#":jj'/i[g''37C+s[7RY9gHMOxYBfꢶ\(3>!'I&>״]Kٍj| MxIɓ$ψo8Bgw1w퍘05$݀.qn7̷43cloմFię's*n dN纠?I=;lԪPyMGf w,B@ 0$;>*.˯'r|{N|J&{r{s\!4@m#bx"ov۶8):/,w0M:՚3DȍhR;!IZ>16bQ,:9 Ӿ RowLm-](~mvŏMW^d\*g΄sJ'@yDqdmUjڷn2Gum*W0!&|9~ݢuE+/{:BOD4ĝa2 ' N֯Sm8da 4iLuft&Mt(:cFyO:MŠ7HNd|/Sӄpvz]81Dl6;ze:߈něCALoY&Y:(_](^&F&[kOXJ&ri`$ŬA}k894\p!Ujj8MN\:29y s&NyRUx뎍W\OH;ӛ;a&wRy4LkJ(7@œ'x&#l^Nu8328LMptxSr8WbN8HP;XcNoj?Mܞ˝j{qfYV`NCv;Aԝ@&j[kjmvmIAm7no|EgKM4sֻh`.O3OYXv ׇ]wyVqDiN-*vxnWtVדy<6Zn'*n'4gpnnCT1jiq2L&v$Lir9#;0֒@DdQ1;r&w v Nk.udˉ7w8[Q7FsƐ?L7C=\mL]g0񼦷}l2rR&aɻL~볅=5x 64ג4x$t鉍Ḩ5۷3C#&k6w}hláM ,nOL=1=0 y鎀(CN6aܢF^euQ9*ss ׮9IHsa7983w܁#D<д;$d҇LNVXoƹij/7˘ 4>vkQ<xuz726:rBNVq4%wsu7v$$MRqw_ΛlxkKM*&.Fa4OX=ys|8Mq lױxףdދv;y __5܎И1myĞ'Nt}$7qoa 4Y%؟ NNs'oڞ^֯Gm9P4zXMΊjnu5ӡ-ǒwNj|c92&q8$ +ntP/R&hqxH~>(mږw7Bi۹6^:Cw'sG:#)Ø@MiŖ3M3"p& pRmIƝ2mNWBigՏP8톷Z5O*UћJ:΂uS4ӭ8DHnJ-I+(Jsn:skWEnl uNE{bi܍bB^e]5aҖS"t07p9G6&tNYI 7c0ybr4$ ϜoZ̍OJrGfaם݇N9)Tj$ɢꪷWaV3 r8 |H:/>۽G'&GqU|H䉩~辉'7uwtomr杻DIkvNn]_VI{mZm2*8쎠D^eu|8Qu*F (Кy84rS3MI4O(qڦ#^Lت}<';#'*%$t?Pc*Kv[R"0;o}ώgKntØ#󙜄D#ST JRzRE#o_9tϋ$7uhԦaG!bZnwD獨Ky)ZIlw=v~a|#v>׺|;Y׏J|Ыzn8Oo菰SɞO}(؄3<:tV/]199kw߷tiēO6 4ZM 8YYJS;Z\$'\>0hʓ:tX :jlת^+z9Z0w7?4Wv>q!aw!#)S8o!2g'(7(8s΃9gwvӝͲ5ҼI.M9!OFpx^viU&O.G'MayM͹=/,nܓ_qbQ^riMֲ3y5RܚvHf2n$N%S7;{om}E _\k졨dO4'?ʲn)qT6wRUW"xD!Ԛb7fjN/rÚṛy%|NJRUɍnnM9;Bo;jUZ&N[7Rry/&MN +qǞh C> 9s{r)N;s[Yn2g9C781iܻY;!MIp)ɨXluái77dCم?3 vt.QjZkKZ%u51ɚc8Tzq'*w[ֺǀ5v7bǓm5 GgmnvAyXt7M&3%ǶNɥnUIjdoN߽>WvsGXSܽ'$$*9&=ţu41fs_UK]X6Zwp 11Z!; `(wR/R^\f}txA =`6a!Bτa\XG|G"=ϰ>H ~aĨJA/9Hg!5^&3%5A6b7q.K,K65#$g ^%x7#Tp 8&C<&cqoCB!ariAc@ }UUU<:1%ѥlq%xQd%hɗ0diƌ(?b,<1_ ٻQEq zjQRFjC10#FuS>OTVjT"UbL&"@hC^&F312-&iQ3ŋ.J."<0LzLF!ʐЄ90l#X#fsKF%&0z)&YӥBY.2 h3G|IJ(0jHԉyw*9T%ԚQ5`"R,R3! =RjD37cDrg1(S淤6faK/e̤u& gL RX6!B8Q9(A.K)8!$,ZKEI6p"'=9C2fG5'''&2g&HxKIV}#?%Лلt2fK Jz=FK3 O̧IS úTM9,%*\-$"OvqGT?H M{!li܉0a$lŋF2eKX}# y'#s+\VC!OpK '(v8#t^{xNTO BoI7Ԉ~Ѽ ԗr<uPjO7ǜ? 5Ö} $JHQ&y5",K).#D2QyNY 0Y#=/:}0>qNUw2a. tǎ?mR4a4 A&#{N=JVdĆD/ύtԘLm{$eM?V{iuX\`6RXLjMh c(MN aiHi T{yҺy*yQG>Cr>9K1M|삾(<2h!&*^Z+6XZaQv5VR=*})!,%z[3:ɏo>̒s}J(',K%))T M$o6L0FXr>HKx Dё͓3{#2"&gtj# /'z&"ׯ)7 !o]ZZ "N&!}0y2 %BX:dLB^PAeBY,"_TJg%ȹMcxWYk]ے$U-{>"$Ue b)ғJX2`Rѧ.l TBO]Rɔ/]˛#dRRiM6OBsa8q=au?٦FpĺU)%I"%JnkIZZkd޶nY\/*، Fʖ.9,\YsqY>꫗)MH' Dz"Ic͎Dē.;0yt!',nxL#}8vvvMnۑ>rw!gd^Je. cli*MH:DЦ}"ꪪ¬*D52D|1:kn.M0THHzgUWU_OٰF,# bx xfSPMO&x@87gT7r7"?}qm{t"gIg wJV0DO.&2QB^ eD69,Yq2<}eCs;3& a^`b)Nݟ-I)iq.J/7#^L7,L0>F Zu`:&NГw$gҚ-Dº){(E)4 '>9L֐ 0`71\tE$ӗIa9‚^)3N?, ֧L)C hMГ,\|#۔>44\~aSNvFLAۉ8LC$s c4C3丂|x^IIF0$Nꤒҿݼ>אBq ]ȊUVJ˅UfG8> hRa l'>6aq0J"L/}:ը=>#)pH U?KbD'>hoIҒ)Ec|xǣU\YjR5'dkbmtHgxw)ҟvl{UVp\UR[7}gډ*$x*17ۧYB̈́Oyos %J%DNX&&'2bNLbmg*lW&U%QU%IPnfGPltf#Xk <UTTJjgOh41KE4q> %H{>N* H--U_ ''oچK%Reyv%0Ƀd7OߘIי%QG"{ `;h>"UTE.-j(Q( o~)S!*^T2(šC=*zbHπ}2MЯyO"iLgL^R"++$6EakʔJ Lx37>iJx=2I[U*+9Gt? 33%TUy0?c`J$n3p&FĘ% .ؙ5^g_".kMU(LTk?yRu†M(@oM2 n>*vqCГqK' (I;f՟e |T`DWnr)܌rby^7+XGZOMI%WCyꪪKUU%䒔ۧJJLd+C>B'J%۟<9C0oR>u$T6I?aGlnxRN=RX\KD Ib KzSs 0yiy V($4JԱ5%L 3&%QR+ޘܵK(2F5J&I,X*KDq"4BѢ",mQ5b\i haMa0kIL8/F`Z//IRJ$O<Ȍ`^M$Ί;~)x- 4D}&c%RgJ3UUVq!> >,l-p%ĺ}cC8Dg5ҥOL&J1&8@~R~#:TLcdQtBiVq!$L.hǼ"½hG&Vlkţ9m>I G8C+J^c.PA  ΆrgJ%4y qjؒ5M,'02pe#^OL] +2]oɀS}(&M>I D06D^WX(y[ 0~?`e6h]gI6Ɲ1U9S,Ov-i ч ĸj7"gc=Z}+In? $聠p (Fϳ$%OXDžRL)LLf2)e.@iXyL>32La7d .OJFxD""",Ye;v`FVDINMaUHE"sd1'yJ;M#s'%rjx#ާO:A7Qh4cB}u$1uNh]h.,Qy}׊r4𹟭dz-p<P3 +B( /pjգNdr/`ȹA ;rs)rv# (Sh0#r""#xx}qv BB74Aox,J({7iDTݪg qKd.'$aוE I>RNNN$JhJ(&P&P2;#L 8P HAݹvۖ;ghqhBhMztdUgȇOzC)$Id|VQt4>Hd R3M/Bi{Qq(M@DY%J`'GR0{_KYb=>h4C})=DGoEhZDz";yhDDDDDDzB=D"""#浻yo< 3szUU\be2l NLL S'_\4iQ1GJN3)0YOFʏ|{c>KI5F[./QE%<#N$Kd$fZ eC(Z9aEs矅gj#4`1G'dΖhwE,JycbEjA8_&dc9=%cۦ3byXK(QaD< TkS%bc4`zNq9W&^"zӸ)Lq&d A~P?1< 'i2ɰ' ۓLpHeQ8),Bz:2&!dZsC#y;faREJ*ZkikeZZ%kP>^0h"Iay(Ymdɤѡpz-k-ZZߘ??DDFTJLq2K0% Fcpsl_ɐg v,gL#I5sފ#VUU](q?aQSi4Zb_9iw%ʝup({y%wGsohzN|D>B4D"#-5AapR\^hi#1((()!p~S<'jSgF>1 ֪ҕKU>x|lA7~#~T'RnR>(Bheir/~w&h^ٺ굞,5FCԒ&LtfsmU Pq7q{xrqܛ.gn6z?"TDѾ7ñBsF91I83>,e≘!$"I Gَw6==dcmB{d}ILE*Q%,i (C.|$n0ccL)I‰dN(lk dНЖ&OhwG\{C:CQ7a&aTZkyEe]up3@i /MX@fAb!B_*u#ӓ; ƣ&? ?zaUR7TlDgn Z}7$7$&ЗFeQ|ׅN^ LdG􋮉i|&&];HJ 7(3 @.B=,\pKhr5(lK ,E[eYs!7#"mŶfmi2g6ޚЍ,H"K6JVE }8)RI*TJUJ)J)&p<$Ξ1=~ yEԽc(־tp-8Sh``/0?2ŊFMA37K~8)ky{P̙ yBz҆y̹RBzhzSN;3ϰFa1{J'GpC0„ĥ%Y77a"c[28!B""4dv|pY@n=Rv$93=d0}z?eNQŋ029IATNMdnzt 5u&%6 d% WDQ "$HFC) >akJy|1M4b,ekg(\YKa&/,\lmM)2fr}|X%P (Q,Th<0Q/(,ZvҞ%⧸~pBI֙hQi}!k.P7JJO ߾ҭhwuZZR;ҪwrnܝZ1tJ=>+EYe}߃ťV[-IkmmGBBѹom{&YIL&XX6FsYh{7+!d4f$ĥ2m,V(Ibd}1x8DB"FG'>XYM$c/U*Ui&bڏ%Lv^_Rc+FLFE$1I_0'7Nߓ đ "o(s<PЛRPCVty( (g9?4!?{h=fx e)LxYLs=ɸFݱ t&ꪫ!7]{)vst>z9ܒ8I4$I4DisiΪI" e87$;tk *T̓/UELLuȿ_\$s'O<݄<@nCEg6Qə‹X!8郛NQ$L  d''L 1` œ #|&H3 pN&^jc,7G''Xg*bO}Л_=gYgA;s!./1,X)>a0K,Xc pL!T|`0|Mh ΞldĒcI_ϸ6CܾwOK=UVդd}>0`1LzώKEZ#]}G?${Q>) 0g&Y~vN6k3 3 !bǀ.."Ea>ַmh<"mf>:"{zKĂeC EU(?83n3=b}Ҋ?BXE:A9ѓ󓵟H% JYd:'<`-|N!䐖 `»TTQ%R$IP@fDIc2%JO-ka`)ܓ QRz;>q{  ϧ(Մ7r#/)!$PY2`%USH5 5F$+UU `uB5$w',™e)>II޿ʎT72^j`ICsPV%LNldp\5RIO<#, +134FalRN %idҒq$֤&M0 ''"vn:0 T&kCURԲ&P~̵oke 1c;@1* BYA DJ AgD:-`0:oJ\y'ߔ|0&ŋvKS0 vMZE1OKz8SDEƕqL.d9I|[{O${"R$E E$G"D"ĈA"  P8884$O$PLNDQ#ua$'#oqcÎ8| Db\"yR"wb;|' |'df$pDz+FM"MȻi4uT\IӏJ~#ե%u ʞzoPC^U~ph珎)o! ɦnNv.0 $X݋D݉M؈焢c$1a#(Q;7V7p}2ɹd]60 N@0tf|(DF!&F  #l^"LaŸ,2FHP(Q8l`o6@7Z(΄b,0˥JLΎ{hۦ[q\4dhȁ #b:.-0E%߾<孪rnҒnz癧v==|὏Nnqu[x\˹iY-2Y7z,D"fhBhM4kHz˅JXJM`[㰫IaBF[3P?JL#wL9D7&7mId-B{wxώoD嚖A5]1 -U KnM&ס7<"VhhM4SUi#ݰᑖ4mB4DhhHKi(,^,(Z1\*}Hu_!<ŽOD9b6FDؙË (3j.+FK3܍^Yz 06nc⟓8ʌHhnM\J)%"9qM*Q)H"\QF0?"wS ˥R&DŖNw;wS/DLHlN.̜@D4ć@%a26"XHDÆhEㄸ %z~3zΌ9j-LULĆB D¤a+FT;sxNWH4SK<(#E, 'yn`X+操'bvG&FOON$0(` Rc}oZK*S{W.Ovo3;byƘuTK=1Iqӓ4JNdi3p ڧpwnϰdEsI7gqY3M((()0 xzfO%A?,r&?DJ{=kEkZ4$բmҭ4***DwfM`;F7BuP'7=IJLHj[ %?qA4V *^r"DJD8{k&X֟B8PJ,QFEpG4H6DeSJnD]ot!ZU)j(Q-'ډh=y&Q=%i^KISF'%c,k?Y̢U:8{1 so>$f"T,J/&I?&pJL>!+4/f1D 66İMbEĝdA)% K!MI##{ņIZZRTOzIs~)'{y{]%ǃƋ^_ CNKpTkimbbcǘImYepG^8r s !#g#q2ࠠQg EM?ͣ\VYe4nqQQ.I?- ޴4:"u?h*M$IHWOƝ?\|ǾiDŽ9sbɤ&MBab1|RXuTyB-U1(?2Nmo %DsINNSd=7:'IKDß}钒$vrI>ؤ(CnAm 4ۅAd\G%xs~:򍨛Xc#osYF xC (4' 2@QG$a&u$$sc٦7y YyRTq`6߉ae Xn|Ƹ%7@ v}Yhog2֫ZkKEQrθR䤹zS⏏',^/,Ol\]DJM֙IRQswg 9tOnϺU2flL**v3_9~%~A$T3 232rKv G88qJIIyccd.2wDO6EzoKxqRbNw:pyؓ$D,M$Iɖ@с |QIr\.:1ؽ+^O;tnET!qaު{J8SVo}yW>JKf }fIfDhM4&mև/vUe^WVyX# 8Np!,tSuJ')iKTR**DJUZUI;*J<1&C>!&$OK&j; TyrJII33̑9܊5"~P=7rJ)brC~:"JM'9 QDdIBJEM$dII#%IrB7\2H>iBczfiD qfI,I!btI7Ymme,~HsC,X~q}PYJ1/b0g>Fb7ʵUGZ^0Y9c>v?ny$H@  H}ZCވpUZhFz~BN Ľ{sЃAQ0:52 {p8GDp#q$~7⤇22 DIҸer\Ҵsa^bm޴b\;y:?qpb>`9bEi#z[^&=lm~f->XFl,N\&NjJvK(<;Ie2^N91%:'|]˹Kx']]r<\xyjR^L2g Y,OMe#L~v'*ik/,d K(R/OL=y0Q%G-3̶})ӥ KuX{\|| %GՋ8N 5Al wfͿq&7qN\喝i$KG=9yyNtxK$q/Dk 4LVPzl%Jٌ/|TorC I5=&)5Bi3꥖0y7y/IECz8DDDp"LEtF@A+{ʦ#b< a:d~r~MMJTnu#&Ro?ηY*ӞozяٴgHHq Dm^!ςZ;q.ED{dݑNLϓ1R0DPM(E "|̄2ˌRM~,Ƃ` >n%։#8R uOi'$qț}9!b=d̴>*`ӉVKe$p/QX(N/2SGOj$kB4xZ"B svXk0J  PE-@!v"\ª%Pk'c$XU ZGFF܍čefia'^:REEJYx|DGDDDDBݷhץTXNO{țMjkQMjO2I&v,QQ8!G7+(?4nD~X*'$T,JK:KE &x2`(VTI+X*:RONy-^ņa`⑷39=9n4`,^\J0`קDQh\ZTψF2PFIyG*ndY,#'yV&t; GJID&u)MEIwDc@ϻ2 Cx,'OENM 6A)I SRjS4eQB7{3¿k''7x75mRaz="!YٸL)bUF>.l:K1ųG@NY&1lQ>;_)BV-,SƩaEIܢ(\6 #(y4AzzevLZFJ/%j$9EQEOD{l۷:-"TRJn%j/;q敥,YRXƕb ŋĴ#2U%;5 Lez\ptmU^Q%,aBu`4$(Pa"n=xaDaBN(L'<4 tF0-%z>x Ğ ?HHȍVaOKZM>2Ù@\V0VS S ʚk4oC&K TJQO7ydz9o1oFI&$$(XGQ]a4O>[ 2(ΟOJ ˆŤ4=SGZB\yxe{"QIG7{ !~$vV*ܲ-Y=ѿ?#G?fMJmZ|Poҟ] 葺EiB#N2ȷYu90J ̅Mf~G<ŷ#GoD5kgxΚhJ,m'"CCFC~ {A%DM9ɀ‡~Q(GbdH4C$0Ң%ˍ9)m%QoG^qX3>j9"IT3_7],P~q6TI(J $3E\As0(8! &dFzdw"mx!GEq iI !qOB=%h~w2G&dXB%8hѿoiz)A>0 zX'^pa*PRz(ZHn5p$wCG?nJvb`&wE "s\Cn66GDo@M?p 9I ,$כk|өp??&S!ULEc/M.==iچXҌğ(>9~u.V9Uɪ7­?[X\FL^~3y9$e%&OԽ{8C}*EM|؝)B/b H`LP/I.'P|5UY(' ɠԉ1}LDW8)zuĞ$ۄ}'Oď473E0[qTӹy'M޼s+NWnM/˭Snwƞy{s%g@wzio*o<9@EI 8バ$C.#7Xie[YeLeE,-oכĴo2W%-.O7 Jo2bX~-eL;iY%zH?  BX c<13פ.oχ؟?h O&UG2s8Rg80{^7'fL)8g c(B?HΟ|eL$d !q 8:EE*J%g[Fm3eK-%7I׾gZǔ֒@V%s;obImmy\K,| 2ϠZ>$xϨ2g&}խTA=kJm T*MJ܍IIO79dd*O8~Gz 7CIRțY>:cnC>Or-k8X/1[ufs)KR !zsX"s j<0܊"DQE6DZ7yuh~( n76좬rĞ}(f&C,NtgK,d0`ؒMBI[Rܽu-:j$.@\KϠ<-jN~=&i'&L&ȢyAa ㉼ώQbǠ&YaA:4 . QE&tJpdk"檚'NZ?藑sKb)FIqxBNdf2&t`&{Nj(|g⢣(8B>QGhJ% e(QhDZ$z,Qˉr,xvy-m4wvIJgd[kxݼ[<ȈYgݼ<6l ‰Di 4e(7rkcʓFNt2Ld(:\IEx9Dzb䝇*GO-=HPv?9;ݞ?Mzw]w*Ɇʺwh!FHZPKshydYCS,cS!"goeDEkDE.>h%D#{bOItNh,H!dXHoy(;@^XǕ\QhTz"5OUI5dz"|&G`B4 {}`]T |~7A&).ne<!9:ތWQ5Y"8m^n?4xV`<:qLllϻ#~uHk ˋH/q|D2f4x| ]8U4|!=&Xdϩ k}Ded菷OCCpV{3E>SlQ$I=ĉ0L=x&>̝r }vì}bGT8ͱI2rnq$.hOH>F$%!{익a?a L7S>C!21կ;F|5(vgE,yc;g+$ #F"9;"&))"I*)Uh7.l7|<+XO$z(M'"ț@zA{D~y)ϓY1(n'U&C9 +&IO?/]; X~/u/)vMy0W1/#cQʽ^5OMq8ƍθkH &!(og&șxu> RR^2CfGp=:LdͭƵ5!RL|.JUOL$a JS;\>"8&tI Hm&Z>Q5\?FB2Ex'}&Q)mI'EGKo' ˼o eeyя L2ݞW(Ç6mYN:D"alX^bDoe$g?ƅ$N~98io5"iSeFހ4|O<? |!n۳>y4?*Tγ6bD}Ɍh-f}orO~U'8~8,7AOɻ|?C_`&F9; A BNj${P> i\VKKYx z0Q1J7.# dKUak%IRoDӱ̉ЬOTFOύ!dVHՁa#豙!G(X0OmOԈO8pyR4b,LMIaqلA1xyGB&RlHbfDĨw˾E -GH;bD* *7&E''?O~uZAhIJ'bQ#ɉa :/%&I0>\ҘKozԁc&IvRyglIqs7Tg-%Xv}FE#$؏T73R&7QE#.@sCґޏ%/9IMBQ;l 4'm^e,IfB =3m h (MA4Mi(ߌo88GNˆ DfNșJL=cnv$$fH4)7=UOIV?| aA74wc>m'*o;p496K]]iVsy3>4I"?$6!qtL477󚴕*O_kiַ[ߙeۼ#ҵdqØBQHd*O&$x;yOʥOV-ik?Z֤m?32dŏ$Ŷ9-9斞?YOuvXE2z3YM*+VRY',MbOҔ7a-ˣY "(`,b&HĎ6(pBf }EJ)Tm)>ܷk[nܢ?-[[[X}Zm*Rznl&HB}>ِ%o*{}},}%Xb{7[H UU)XDݍ7Bxl 13ĝ9oԎdLd}q83[$ I듈G4 XjzO|>O@'I=>y>OF`+@Gy|=i*2FK9Y@If1}7a(L:4Ěb4B`5IibjL2DILDh>D%M$D4ktZ5g#TFx&tkX&KxNi[6JNJT)*UJ@֑0FA:+UueˮOT~8oC""&JÎ@vJH|!ܒ䦘:gD(.Oz1ę?!;ǂXJ]̇c# C7vAOPdak ow|`xϗszFF (x5u04 xy ÐVJ~ɧiŶܕoВc#D)IG"sZvМ836- {Ŗ p6' &|QFy DI ydٳgi)M͟|\)"Fv|N\J5sĜ`o?vS hLOna8돾b0RJR)F,Fxx"dbZU5R 8y`=1ldFЎP%K,ָ//)Dp D ! `QU/z!p؉ݔQp5༊TTnעHz#֓7;’0I5UE0pi_" 8Id}rOI bIy!@XDgE༓{\M'%L|A>}x'䇏I*;$oAyPOD(tS1 fd '&4E}Q?A=4'LC2#}D&w:QB(L[Zҥ"֭3CpK Q>KJ ˓:Lc%OPz3LL_hh 2T/KKKIrPZqxy;ԓ 1L`;P*?QGf*,BUdl0gPa0I` 4g7p a^Ij(dKQh㳲aT Q"=SN Ě#N:xxcqmߪKwXN,Inu2;V j“3`FoGb3J2x'R*UJIMMM'_lo73crIB0}c]Q47}~<{;q>:JԭJ)MZ}Pߜoo6VBo TmcJj|HF|k%anN(x`vb=3ua >IEb.Kmj Gw+Jy=QEyBX(N"5 =.̓`$لo2nT'yTNPIϓP4p`>f4$~ro2ܻ~adžx76g3ehvd3HPoa̒5#N &I8 (iI?GTYnn*dȟmPQ>y)&S,f$LbFYֵk[ѷ ךTJ~*>'tJdN~P}cG (Օj-V@;q(ə,ŭ3"ю(PFL%IIfZITW6|Ar׃mݦaGfI? %(:{5ŋ;唥xoy$oH(O$x#%2Bϔ3 "DЈ(iA7؎(uc'>=Z|{@O0餄ì&kn$BwcDr1Q %CK5@dxyFz**>!l9|x{ vScwA:a73$'>~RO7y4 6hx_lBsI܇ !9_#T߄e,(3 J%[Yj-eZTR))/&`;hl ܖS]"\fٯQEgÞ폼h)}*Ys68||`OZ"He B{.^ۺ62fRL1M?N=R{VG.|=wXFYCw"8Lc GӍ1'6&?Ѥ( $PPP,\q}eUoE*QNbaj؊3uG>NLLO~d,m QTV=ߪF 6Rt{#-",ёoMkZoۆ #iHxpg]Urqu2b7X?SER[%VIʯP|Q%h%OʄF <0?887RL%!}1K""FQuN=A'',L Ύ~QDk T TRxu>Rzd2%AI`G\)z2L # pB6C> /M^fDžygjђ7<߰z䗇m6##&8H~_b=.^=(wRR^3X%؏?otd_d RSW%=Ja"ЯF|xn$u ҏNOEވ)(Bv\.z;2I>$C֋рņq(b#!ѷѴm })& n1xфgr4FTl)bK\,$A L)$=r.y,' T d>J\]5 S[HRKL[Tڍ3H&Q"%b@{dz;>Dv#̲;0{wZ\_Jqo_Rxb#<%:4Sd VHNjJ}pdXnay? 6v"o϶ EC'LC!'#y(ȟ4(ED7=ϚEC7&9߽6oCسAM'>mɆL#ԓ4F$`>3Ь}ŰUSnj#a6 )au#sSnULh|oi\g f8<8CglDID'-77 SXjFx&9rC(|`Pp <$M*r%TŠ$}pR(Qc v$FN~S O{I4i))Ba7,ÏI&OG*90;",`:yb ^fJ'=SL<5mMnjj~Fm>zRn"}@zQ$  /$0|B#l9ϖ>D\3$"tpsW)jNs$엒fJ;Y"9Z^# wq'- "Ů\n.D(n&P:ydL$ d3x2Ňc.ϰfLKQ&LJ`HqgoZoG8߂Rf/%#AOLv7NPp/v}ՙf`.b1FGiwNt`yL'Le#MQ((l Bz|7JU-SNDZX4~3|{&KĢ҅A%9GlNlK4IȡR¢{K#s%"'f$O;+pX:eެiF(z0uIgɾL ]?{k<đ?J-e,AdrmcX a8St~DEQ243% ҝ(@tZ\>]WR^E-ʔ}JTNb>Ӽ.]ixX4>O_AO6A795uFC>P C}8$kSXV??4h<%4'Ydvq#!a2ũ/BJ1 !h  ĸF\`0JOKn)L` zՋ>ii*IPYk(ӟV~l px(ZY"ɡ#˩TrhBQ7i'FȽr9GOԔIRi%ZKVURԧ-%w}Fg!}qČRC+hJT%:T{BlɀJ' )ʦ]$lqՎaLH &|\NpǓ=1+狻&zR;[y%c cdvQp {ّ䉈LDBd DD0]\LFvwRIM(G~C8Re ('w'>5nB}0~%G`;4Q' (VRN 4rwǯ(QJ&@ UQbͥئZ䣐 "~k6,S=N(GL\Yb&dΜYoJpB2D(턹;3 D"hDG0FLQ:'n-ILY8cd {<4'W%);g~)8 8,Eе 'Z# dcM5hm*SX^Hx'|‰=enN#:Rf92!v0';AG?i=&\`|6c{҈ՓoȒ lSDʇ`W(`U&ĵآ=ͰHrG@x,=Tw{7%UJL& {CŅEiIbhE\.7LGX1u4R)tтx7%Y-~I5DK+ZS\OZUs 2qnG+4JbZ]U+<x'D|$l|B?8L(zbt8Pq!tj8|(J?`xQ=툏8h&,(4p}-r ΕKx`2Js~#2 idsTԟڶ6$c ü#fP=)| &ji)"*}_6D4Dڻ"xK)i$`MWždԔ~Gf<~PgˊAB Y^0Nܼ1$Wb?0&,'%]p;G&V`&X\0pX6G&ad6ghɉ2O>s`c^N/TxgPI2p*3$F\07C\HN9! \B&[W˼i8oor׬rk8LQ7p S98扺y=^2IIID# ǘӢ-ۿSxw"4(&!ovZJE[H~H}sK00QEQEQEQ|aY122 Q~9jrjf(ŵFRTt7jI?J`!J%˥D7j}2{;dd5{JvŜ©ځ)LD4o^"o >zA̓ߗ% %LL7bQE4-'DY'n(3J.hꪤI$`{ TZU*UU<7NT*egIX"J8Y$s’Ov؇GI:IH9S'aikquN<[ǺBvcLxYS JX~g5pq)׍@{'aӻ<0^k<秇xN!߈~Zi--jE 5A-g 3:N?ؗ>x$h4$1}ZKXKPv'La$yW3c:8F ~_LM;0UU{U"e'Z@oihPi+'x0Յ(q#/ ^1d"UI,OE>xL!x`u_3SMRO0RO@O\>wdn2^Є苏HGړwARGx>=3'mduCG&Ak&ѪUx@H1jɴ8{kfh[xxџ/dFLTT{6*z`&zģ0$rb,o,GGB"""")W =^I 1>M| F%a %$y ;`Ϝ0<}6HNAe$ϼ] 0uC ASK yKY&AaeޏȬd20 (GrMI͞hM15DQ^_6]%7Bw%La)ڶ#NMMpb/^K<&@ QaE (i29< Fhy>yȘ`L 0'G3d{C|8">4A8phD ra'%k4jjq/,Q"^i^8qĽbOq~.^Нx/1}9e ެ&aT:ebeTNFN8Mv#'vOt'(F<|P$g0Q?|5NqRQYO 5KaN*$rDyGpJS8Rӝg915,ݱ.Q3_=d*Kai+&br7.mCI 鈸Oa0@K#6$up~Զi[v Pf%ހ`V.eT2daْuw$ DۜP1Mo(U6$pFMUBv2Z-i\xb7cpC3U)UŴ3TI:2a$~On"z+>)\&$mQI(L{0|4Ʉ#7qzrGN>aE :cdPo %&Kx6Ż,gC q?NK^Mō((Ojr\xnnOjTĎq bE"O`.ija,oQ`bnnR04# } N4xPL3jZВz=(t5N%1?pϒA& `LT84\?{sKȑgEgy|4g qJo2 ?Q@:Q>Ǒ)0(Ro3E_Ȫ*ZU:cY9Ǯ`wu)dd|xUW ѝ4d,4 J΀jNL8CqZΝ]U[Ts'ғdRE 82ܽ`&A3X8ݯy3d*L 2P/?R08B\N,GGB~ }[O{~`>o˥Jp]TRei,ggRJnJ=v7>aM &OKkӺlC4TNބ('< ڭD~G]D+GHh"F? =PO4Ӧn-A0䌑BH4. 6Ł‘LTY`|gC'9NrDfogMI&rH`Cnn$;"~އ6>?S9=Nm's.*p 0"y_0 *]B}C^5 (PZ?˜>Dg$AS(G#j DX^HXZ,OvbѐŎ1KV?4dzA>);蝹4`dqnmh'$#I#"NI$N9"NI$L8p2#nɸ0(Pݑ &"=0ps 8息~G4$ ?/!k*ш#}i&DI&i fzHobDrDq"|g қ^wКgƨ'rI$'9$q$ӜGR%)GAj=@G>Bptttts骕U 7?@=xG"(&|0ItN&M&,PP}bg}p@61y:2phh`F&JĞM8ʑN dbx&,KH=Q&$b'JjҞd}l x"=56t1 ZqLthZ(>DrD$OsI$'$K,֦i OaXdX(PB y5 n#:3:RpI&y9; 6s=cxEQϦ5.ӿœȓN=7ě/]U^m$c;q4),EĹwV$œN*M)', ҇Z{q8򆛗={I=zK>ɫq?Ar<\NisDǖ&`Vzí s7#5;2FDד<|BJp".{& l;ꎁCa=Ց ~v-e۠A="s'&;}̦|o }=|7ͰҴҧDM9pu'6LlG^mGFyc2(ю'1!hcEf^K#.,&n%89nğ~NqWN::щC*0TUތql*&W)? /r˜[%ظFS12fDʙS/{F{]4/;8\>1~n14GNIJ%bM̛8,xW}͏Z󏷺x}ˇھOpcg n3*_}{1ZbF npla FH|A/ 68 ##HysR# JGj!=qpdӞR@ѶGjn:"wI>)ǝ4'k8\N&uN=Ua.#z bXJII>2gOl Hшt(z!m*mUu?&,uXUk13z;Q?`BiH4Ė=p'D}RbzTӬ:c>4#:= BĢZ$gygOr6AtbNe,OObg N*V#7?֞}u54C65-خR@gם8ry$ǪFȑͧvBo()\J7Ӕ:U>/Ҫ+TМ9$#ZOLpP ƈ厠N;M{τ=gpQ\mS>"g`M.K'zI%4䞌8םAe&F;i`_Om[>wßlϖ{ˏc;N.94H6&1L17!L 0;QN\p4 ΤS>9ϖzx*eyGp'P^yS3˟*y0&غsE3:pNy 04I̟ p#,vȓNjN9VIY4۪Ud@J`T%:գTϚ!ړ&d(h Gt,%؄@[:Mn|MG+ZP>a'qؓ=_o#:G'bizӍ(N|mVpG6.QFg`eK%)ɸ50CLyvG$<Փ$剻ǐ gdvl4f|_s"J{>F<sRɌ F8Ϊ.&Y$Ҍ PKqIRRKG)D#L~1$Ɣ,0 VHCIu&|D׹3-T?/9FLLII)34a3DWVMbJ&b*g '&‰I0Nu#3 ԛ>]6-"צ&؅pƌҖ.jdH׎grb $댑;\jJy$pd\Ԕpdr/`''D9q9n) *<<h +$LQ'"/I֥$ ӀYK&Qƙ ))&tnDcLhhu"ahx"sC 1%"(i"oD  :5r#% 72u#D#yWoֹ@X"H!9ٜNDC(B1-2@I";@86g\GPtnpd v%yFtŤG #6m)&eDvL .^Z(oj-Ts9iHMp|,*v]&4Kv-8RyxNUj8qNlG%6g \/危G'2}2b!ɡ%!IC ̓Tvd4< ϒKҠd,Pyb½9ɒ ։Fp9L{$t gJ sO2u'xVi4DblΧ#0C,OO.X҅}y I&cJwm J:>mV UV;01&LagUnYlHЗ3ND9IziJM!5^N~'T*8io$=3rN3ҌDQ3NɫP)YJcN<[(&ILl,\pd˒nDӘ &!3yቫ;<Ff݆&N5ӆpzk/.:q5%Ls#<\vg"n*/7Pd6iE4΍9ct2 ЙE:L7i5Faq8s2oNE%"d&(ɹL7鏜k㉹ӫm ,FB0kģng4ihG`,dDS+#|ϜG (㎔xrDn5x %#Rjfa)5dIy9͉̃ڒgt@ϙ|oNKn aGo-)8ix]ԵNgN3s6UÛJh0:QX*5Є뉾#JE&-|6 $ʓ|&6a4hO#>k|M#$cgLog')R6͒YXX9uMmeNr3M"M))%Q8P˭2fן,s#PLLJ34II)8S&k'5QŦzr䪧U74TooD\ymK URRGbKÏ$̆keC4țw,ɒi E2 ʵm=b2F94 Pe޸LoDZ!FՓ.kJbB&28reSDv'.vĽ/&qm^w^z2ta ˣLrh9NQ%$oH:Bdݛ:"gb&Na4c(k^Dx𲨲-j \x\q_.=,W\@o YgPu cX%<8HM֜Az(%ᩙEJ19X\,蓬/SKs$.dAao 8uDg39zx;RpSB^쎠3DI#pIFH凔>ӥ$dGM1BQEjd4sb=u>Y?I(#7o΋L\u䫔 6exqt7nʌ#%Nvd ({1o 2`2i nN:w#,hHJoL\\8.)k7NB)b= LZ *EcfL(;4{ 7㫜ÞHQqܛKdK54:^]vaktx59:ԶFL&5Ż/FeZ`g6 j5F$qi4iȤTԘɨxl(3L''#/1U:2y>6(E%;d23 ''ZI{4'LiM3MXPIN'%tc8@_rߌ c(- cZID\o %SZns^dByR7CugIb5\PLFYRrcZsS[z/X(XY F4cR]sFNG(qڬk^}g׮&%TҌLG( Tnd)4elΘ4DśY#ʖkˍqDк'lM*<+t*()71ˉԛՑJ$±ytGTbN 0oӐ m {&YmX%$os? UI`1I&h'uVUUr8n,Y7eu<.`&5@L )>;4:er2"i-R7 4h)-KqLS5yª6܎8X9 BR&8r(ΝMZZ&&ȱ4&yLz=\,(HL<xG5o6&Id%-TI%JM62dѸ'"_BXl 0~BynqㄡDHg:Q^\1@#1,7pΚda᣽L)d9#(f9~?o$իR*(TZ!HZ~\{R7O*2Z>tZjet89[誼\oQQbꪼ~ԢR\}qBl|;a9R9dr)EڛEKғ$F؜du$w$a&vҒ.#%=juD9&a3 ؓ&a&a''$F(y?!ѿ }ȇxԓ%LMNc7Ǣ MF$X\ R#!QǓ (Mq !D|;r5gS`FQnbN0J&5"Nd!p'&(%ļDF IKDgP!"8؋ƠQ($kɰ&ČD`5kDP"2lDm 4dQIJMQ6j 6䚂n$j 6VғJNyHDMY1Hd)mMj-Q-g]zxQ_|i*6#v 1, $ȁSq~0'l9 ,fXrPq&dL&J^ 2L \PO wR}#OφacIdD}9C_M:gۺi J(08xqitTM;`&Gp%f'KJ\M>p杳۳~1)Rԯжxtޏ~}c:$e';#'yUR%T*S|RpP˜™md$Θv#w56):7 [ƔOKQGv xlԤ(|LDR1D֥%MxIu{RmpObrŨQ !Xʙ##OGOʎGW&N|lbcr e dŊN;QʞI&`6Rn2og;);4d Gt70{G 5gP7DtFC ,eOJ,܉'qh}:Jg (3ML\ޮK'J£Hdͩ*X0'2J(Aa:b{Pq^-aX0*'Ln+y?1>O '&jԹr9&Dq3q6ƄMDC"72"J,,\\*,O!f99uJme3Y$2sⓙM)xQ0O'|dm 9"Df&0Rqpq:z|d#9)4vD|Q<HX6uC|EGb8'#0wqCdR"HK&>?7kUUIk*kZ$}nߒ>`{)RWG?I$)qwʥVfڟ7"eLڪd2V,J/Rϐ%'=p6u骕ZŠ8|gF#hKˢGr|S$;*`\ysoXk`,~0&v%Ę8iG&p7q~MI=A.I Erd +>-vi;pBI/ԍqoizU9>nL8jUE\ߐ]_hJr:bFM\^a&@K$OjF?7v'2j @HCF&K⧡jS40j_êRK JJ*kNLσ  oDOtp'&e?iT" A(VKnc>'&Ia6Ԟ,|6''zHXm >Ȣ5fab(HKBZ>8TMxb.>[VW><2&3nSz^6#DK`QF|Qv7I}ʥ+JMzp;Rxy2{a&D̩< >d3QG@Osx0l Da ï#s^dLcϵUa'vsvO`LF%QiR*,83"1H$JC)!DuD4qRRT,oˍ|=iBE$?=A̙Q'''';x܏zɭI>nD&a><7=TW&ؿfqAB^nVw:&JJaȴK |0bXb3Mq>0:I'D?w^;5$v,5:'"_d &).AޒHN4``zQ,>8qu[qp9o咎$ 733«\*B;BO:$$ '&|М!=f{!F֓4"I퉇YU}UZZ.-THZVtT@M6wp;=n[4Cm[!ov{ x8ER%!acLGشz-ƶǣvhz-c {8;PFbX/\ Ү0D#0cAK0zUUYZYUVԪz $9)8~(h4kR`Gf<*p!~/sArb#;>س2P ГVjrX}HH;ًDǴ*x>>3koQ24M # XTRkKUk)"R24TVKEjPL#AhF:29b6E% bO3)F^ ֟Y814Ȳ)bΜd{bzj*Xzr:d +T֢6j))JuS?kغ^FXJ}#-̏3?KŏOzhO4I~%{2gHF sTWt>QheGnJO-- VʊfdcxDчӾҊ?) G u)Fʫ*Վ߉gavQGBvG\QfI{Χ^y0QC d4QGOOO(yErQK݉S'#[VIOe첐=ִ>w@$7H}1몾Is<>QBa#DU(!`o")*%V&UՊy^y^?nیc{l~x)&)K̞ѢRҧwLqA;Z1n5:gq,%,>˿N ("bDQdlѼ*Lybsd(5ɒ4IR( W8\PC >!'$P&IJVZ.0t^wԱIN$x! X1,q08yb?nNUOP9V^3.8a dZ|@v=ϋZڥJS 8~y4 Ҷ$)PjX77,?"eE4&,[8.fj^l~?F#7 (\RJ bA=qڜԌ隦Q\~9IPRt,T*Q*ZIIcb|-2Oq>p8"8"{pc7IO. Ic~;꜓v 02(N Gz NsU;>gR",L0GK*b{W\(J98moCRW> r}w."`o!xy0pǴ ߉PPkAœG"}q&QQEHQJF2NIcHNԓ?Пx}=J=~z7*c %$Yq%DJZ-˔\:+&o{OL%2UM7=2TTzyϘa좋x9\x>#z367nyp%mq# pce{k>_ ğ>ه:1 zt(gz4Ѧz6mq>KZSQM)R~<I'$H1BoD$oNSj+jB1wa}NH?4I)@d6)tRQ.Նٻٔd -B K^O7vc0 UEX`Kc=Q ӻ |MUZ\n*];{|pAfF %)բKXH07H5ezC:JOP:йz@Td(hǵ"rs`Ǔٸw?ust9G|‰88PT|W9*oj( w ! J؃3 ٬q=#'&7-ߧN1:ѽHGTusEo$nvfǛiUJēQ'.j#RI&g3hIslxƈ摦l%M{&:fLDŽ.>20Xgܱ7GX76Z"xC()4@6p1ן(>Yx\SJ(Qa '$$(R|4QG GWoxe'NT oI23 K>NL7|О$M .i3pi&rhE' DSLC!W"Hd\FTI/A'߈<8;肋R{#򹾨iED6?'rz$IEdV BQ*&G`;щސ&*+ '~&LHzΜm˅6.QFa&O8؏.F?!N $fFMj]teʒ9uD0'{^TUܮ"%Djt(`F-< ϧ&XaՖ7Q27(gT֔ WI nFvNj:{8LDQDYNORU8;11e,R9ѫ#K(J$ۘ`vk6P6lY\_Cn XYogƉ8cJSr$6U Q*O*y>P=kS{ '  ݓ[`o*|SxU'j >ZOܖ$Plj=?95d[P7:5>~A<(xل͡ sg'&НLQ8$7Qmm^AIK}3(p"Iƴ歷oB@c e$ 9JtRۻ9ηrܿ%gQSēSk)Y"tHvV]';[wswy]hn^wnxs.nk;yQo#۳\帩/Ϟ%gFfI_yu|%=a){)#q1%kȽ=? 8b_ gZN8?엓Տz?>Y(D%V.&ϔ:l ֚`TMLԟ;)\Pdk"q\^s2!$"qh))!B&B! *nQG dRM<Ʋwc̃$ٲD$Pi4UU)ObϠNXzj`=:nFb,8c((G}Zޏ0 LLS8~>$nݓ''&BFHE%'ʭ?o{BipND}uZ5z&}%U& N@BQ%d(tl'pK&jƸq|A`4+AIYR,/]K)L%ø)b8TxS|0a-(-8 D zx;f?i>%ŌJy_{{ ϔR/}M[F0#o[4O\`bp,XbId$eEQ, XG\\X~Gv/FCTTQIיLXO0`Ϻa"L,Fz"5)8z5)Wʀ^Y |$؊WD2b<(ۂV"G$Q8@)Jw% N,G 8Xw7ee;MoS779k^D`b/mA,NG"ߏ[%Icv%}gmJ5&H~J B{BPn,_PZ܋ZJj*I_ER//0]Sq_Vc;&aƽEXkT1Ad~E?iF8sȓ h=*&f"({"zonY)϶QFgVb?Кa0ɏ+.UZ5|q02ġA&"d &&!7a4C#IaHњG&N0t)"Hw҅Ix3hԹJ)f%5'ɸs ,劏*f ENK' idpyDލQD7"3LUO48S:=$\oB-1,xt0,jJ>`31m2 2Ks38ѮjQb:rCx ɯ5q_3%JW־-Rߪo⇟9{7o { j0eRnZZ"EJiD%R‘x7Ix0NOC""12 hV9&jf<l7>n7XH`(QD<$l&@'*_ EH8WCo'$٭?7NnzG8?Tvڳ9uheW^O#ۓ̟@}@uX^,¶" ? d>IA?̐j >Aﮬ"&2aMQ &B~Q=A<0J"!6~l;s@߈bF,Ө(~Kڐm x $9p& ̡&+~ZZn!}ROXKk>rȜ;rpӓO[*𞘃(?o  D- yC7kӃT&,LĢ HB0d,f@~ >pvK"Ibɣ3B㾯1-U.]+'2hxTIk5KZewikLxna.47nss##ciGyUkTIfWCoG j׶r)zN } :::ڏLY ҉'r^nuue.)pଟ!rDˊC)3BPI"" I AKPt9D!8shhQI!Rr$yK# www'tOUw+i+JQUTU=ތ xN:6kuIRwrO#{BkML$H2V2ѽ7v5IJEihVJYV%VNo!E (.(X哇^`ZUQqTo,ˑL6Ps(NT6Ss++ lJD[F)G9ִzÄ%'#'O'8c$(oF`H,)Cg#{A&~67 E'%>QG,IE皞bE\YF7whiDA>vYDoLJ?|>Slp#/&8G#>#7spg%Ӊމ=H!c= jY%-7B7w@EU$|cs ַ1SqN#wzh>3$UGXSHϼ2^Fd# QG "DGDێfHǘ{Eo䒛;IS!{. {nBR- 1( #eWQ'kj3ԎÅQyIUQqEt"g82X]A,K*XҤ~aB N`\k֦E]KG9ja)TZk-UedIFIZ`*0MlN4v1Dr6:>#!hR̉2S5g(؎0G'| q NT18A3J"sBԣ%}QWJp!(L"GrI.AB "(!t@0KM G2\z{s\w==xKݥO#괪UJJ =aLx?nBҿpM1z y`cx~~R^=0; {3di&Jr7F|7ʛUUAIÛarA=`О|>Mp|9#ϬiOʗF[JFӉlRRTT:Ml0Dxc@yqpbh{6WmwNu;˫wNS뺹n\ܮwrF17넫'!a&Ĝq(`&QLC/٪WOjR}'T(O@)ΚN b2y0O3a0L'?fAdZtlO"'Hjǫ5ה(Q5P%!#yu,_EZ82G ID$ ାepRyde^J%q^>o+S~xmņuΤۧ[cg$ li_7y-KҏUbVcdb-w|I)>=~%TEIZJjjC=}gxCka_p'&LrM"NLY,$SL3?$d'@C` $? 6c.  a0DY(u.n^~~8OHcI O)~\ROPU&2II8(3bPŏǻ\^h IL~\]v6#TsH?HD::f*T~1766yԩu*(b~ӧ(zP$MaqեMg:yc0F[* (tӉx<#F-<#(QELiOQNt!K Ï4iǍXDjTĤ$J/%iɁ{-jZs>iR^.嗯NU{n)rF,&u~w9y>0X(|6%fX& c搫~3.9J5*Y=\Y0檪VU|&!vHC1U*ŘfL0*F3ћяAJxí''.:\KpFpV*B)K $zP9) ρUW.P< ^ O$;NjH,RC犟 AG:*#(^X/2>i@p>!6 >4K[Yqc0TU2XH*D|% |G@OOON2`yJ~I{!bDoGJ&LK9'%Q>Lΰ :^8ϙgp\N.ʵꄽG'bN M&5!$tHfĸy(L]3bxtQEiOKKQe=/)9]|?8N@Aֈ RQFuI"Ḍ/%qvhq7@=dDtIb%JI_ I |3KNju\EJm=D\3aNȋ%K[{ k\/|XZp5G$o!YؑL_N䰽sXXZR$w{E(d.-T7`I, 4 z Ξ ̳#HOI8b0g_*DNI yV|ZT3>F*8N@lb='?{檩uk&@ZQ4)>q1^s,j(Ac-`?74݉}W54{= " "Iq&%ҁ܁@+FNy~=Ta0T,/Qyfa00,0Ù**54ҍ\M$GHI= 8qz"İn,Fjg8.% K0H5aByPj&SAdG< ULH'#`Q5