From 8b34429c3e9dba4cebe3470278c41621709a636e Mon Sep 17 00:00:00 2001 From: Leshana Date: Fri, 19 May 2017 15:15:46 -0400 Subject: [PATCH] Initial implementation of holomaps! --- code/__defines/holomap.dm | 49 +++++ code/_onclick/hud/hud.dm | 16 +- code/modules/holomap/generate_holomap.dm | 204 +++++++++++++++++++ code/modules/holomap/holomap_area.dm | 78 +++++++ code/modules/holomap/holomap_datum.dm | 40 ++++ code/modules/holomap/holomap_zlevel.dm | 44 ++++ code/modules/holomap/station_holomap.dm | 246 +++++++++++++++++++++++ icons/480x480_vr.dmi | Bin 0 -> 43773 bytes icons/effects/64x64_vr.dmi | Bin 0 -> 6122 bytes icons/holomap_markers_vr.dmi | Bin 0 -> 9371 bytes icons/obj/machines/stationmap_vr.dmi | Bin 0 -> 3988 bytes maps/tether/tether_defines.dm | 24 +++ vorestation.dme | 6 + 13 files changed, 706 insertions(+), 1 deletion(-) create mode 100644 code/__defines/holomap.dm create mode 100644 code/modules/holomap/generate_holomap.dm create mode 100644 code/modules/holomap/holomap_area.dm create mode 100644 code/modules/holomap/holomap_datum.dm create mode 100644 code/modules/holomap/holomap_zlevel.dm create mode 100644 code/modules/holomap/station_holomap.dm create mode 100644 icons/480x480_vr.dmi create mode 100644 icons/effects/64x64_vr.dmi create mode 100644 icons/holomap_markers_vr.dmi create mode 100644 icons/obj/machines/stationmap_vr.dmi diff --git a/code/__defines/holomap.dm b/code/__defines/holomap.dm new file mode 100644 index 0000000000..6bcb601b44 --- /dev/null +++ b/code/__defines/holomap.dm @@ -0,0 +1,49 @@ +// +// Constants and standard colors for the holomap +// + +#define WORLD_ICON_SIZE 32 // Size of a standard tile in pixels (world.icon_size) +#define PIXEL_MULTIPLIER WORLD_ICON_SIZE/32 // Convert from normal icon size of 32 to whatever insane thing this server is using. +#define HOLOMAP_ICON 'icons/480x480_vr.dmi' // Icon file to start with when drawing holomaps (to get a 480x480 canvas). +#define ui_holomap "CENTER-7, CENTER-7" // Screen location of the holomap "hud" + +// Holomap colors +#define HOLOMAP_OBSTACLE "#FFFFFFDD" // Color of walls and barriers +#define HOLOMAP_PATH "#66666699" // Color of floors +#define HOLOMAP_ROCK "#66666644" // Color of mineral walls +#define HOLOMAP_HOLOFIER "#79FF79" // Whole map is multiplied by this to give it a green holoish look + +#define HOLOMAP_AREACOLOR_COMMAND "#0000F099" +#define HOLOMAP_AREACOLOR_SECURITY "#AE121299" +#define HOLOMAP_AREACOLOR_MEDICAL "#447FC299" +#define HOLOMAP_AREACOLOR_SCIENCE "#A154A699" +#define HOLOMAP_AREACOLOR_ENGINEERING "#F1C23199" +#define HOLOMAP_AREACOLOR_CARGO "#E06F0099" +#define HOLOMAP_AREACOLOR_HALLWAYS "#FFFFFF66" +#define HOLOMAP_AREACOLOR_ARRIVALS "#0000FFCC" +#define HOLOMAP_AREACOLOR_ESCAPE "#FF0000CC" +#define HOLOMAP_AREACOLOR_DORMS "#CCCC0099" + +// Handy defines to lookup the pixel offsets for this Z-level. Cache these if you use them in a loop tho. +#define HOLOMAP_PIXEL_OFFSET_X(zLevel) ((using_map.holomap_offset_x.len >= zLevel) ? using_map.holomap_offset_x[zLevel] : 0) +#define HOLOMAP_PIXEL_OFFSET_Y(zLevel) ((using_map.holomap_offset_y.len >= zLevel) ? using_map.holomap_offset_y[zLevel] : 0) +#define HOLOMAP_LEGEND_X(zLevel) ((using_map.holomap_legend_x.len >= zLevel) ? using_map.holomap_legend_x[zLevel] : 96) +#define HOLOMAP_LEGEND_Y(zLevel) ((using_map.holomap_legend_y.len >= zLevel) ? using_map.holomap_legend_y[zLevel] : 96) + +// VG stuff we probably won't use +// #define HOLOMAP_FILTER_DEATHSQUAD 1 +// #define HOLOMAP_FILTER_ERT 2 +// #define HOLOMAP_FILTER_NUKEOPS 4 +// #define HOLOMAP_FILTER_ELITESYNDICATE 8 +// #define HOLOMAP_FILTER_VOX 16 +// #define HOLOMAP_FILTER_STATIONMAP 32 +// #define HOLOMAP_FILTER_STATIONMAP_STRATEGIC 64//features markers over the captain's office, the armory, the SMES + +// #define HOLOMAP_MARKER_SMES "smes" +// #define HOLOMAP_MARKER_DISK "diskspawn" +// #define HOLOMAP_MARKER_SKIPJACK "skipjack" +// #define HOLOMAP_MARKER_SYNDISHUTTLE "syndishuttle" + +#define HOLOMAP_EXTRA_STATIONMAP "stationmapformatted" +#define HOLOMAP_EXTRA_STATIONMAPAREAS "stationareas" +#define HOLOMAP_EXTRA_STATIONMAPSMALL "stationmapsmall" \ No newline at end of file diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 45c6f7e277..7a7d82d175 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -12,7 +12,8 @@ var/list/global_huds = list( global_hud.nvg, global_hud.thermal, global_hud.meson, - global_hud.science + global_hud.science, + global_hud.holomap ) /datum/hud/var/obj/screen/grab_intent @@ -30,6 +31,7 @@ var/list/global_huds = list( var/obj/screen/thermal var/obj/screen/meson var/obj/screen/science + var/obj/screen/holomap /datum/global_hud/proc/setup_overlay(var/icon_state) var/obj/screen/screen = new /obj/screen() @@ -69,6 +71,18 @@ var/list/global_huds = list( meson = setup_overlay("meson_hud") science = setup_overlay("science_hud") + // The holomap screen object is actually totally invisible. + // Station maps work by setting it as an images location before sending to client, not + // actually changing the icon or icon state of the screen object itself! + // Why do they work this way? I don't know really, that is how /vg designed them, but since they DO + // work this way, we can take advantage of their immutability by making them part of + // the global_hud (something we have and /vg doesn't) instead of an instance per mob. + holomap = new /obj/screen() + holomap.name = "holomap" + holomap.icon = null + holomap.screen_loc = ui_holomap + holomap.mouse_opacity = 0 + var/obj/screen/O var/i //that nasty looking dither you get when you're short-sighted diff --git a/code/modules/holomap/generate_holomap.dm b/code/modules/holomap/generate_holomap.dm new file mode 100644 index 0000000000..9783fee656 --- /dev/null +++ b/code/modules/holomap/generate_holomap.dm @@ -0,0 +1,204 @@ +// +// Holomap generation. +// Based on /vg/station but trimmed down (without antag stuff) and massively optimized (you should have seen it before!) ~Leshana +// + +// Define what criteria makes a turf a path or not + +// Hack because we don't have catwalks +/obj/structure/catwalk + name = "catwalk" +// End hack + +// Turfs that will be colored as HOLOMAP_ROCK +#define IS_ROCK(tile) (istype(tile, /turf/simulated/mineral) && tile.density) + +// Turfs that will be colored as HOLOMAP_OBSTACLE +#define IS_OBSTACLE(tile) ((!istype(tile, /turf/space) && istype(tile.loc, /area/mine/unexplored)) \ + || istype(tile, /turf/simulated/wall) \ + || istype(tile, /turf/unsimulated/mineral) \ + || (istype(tile, /turf/unsimulated/wall) && !istype(tile, /turf/unsimulated/wall/planetary)) \ + /*|| istype(tile, /turf/simulated/shuttle/wall)*/ \ + || (locate(/obj/structure/grille) in tile) \ + /*|| (locate(/obj/structure/window/full) in tile)*/) + +// Turfs that will be colored as HOLOMAP_PATH +#define IS_PATH(tile) ((istype(tile, /turf/simulated/floor) && !istype(tile, /turf/simulated/floor/outdoors)) \ + || istype(tile, /turf/unsimulated/floor) \ + /*|| istype(tile, /turf/simulated/shuttle/floor)*/ \ + || (locate(/obj/structure/catwalk) in tile)) + + +// WARNING - TOTAL HACK - HOOKING INIT +/datum/controller/game_controller/setup_objects() + ..() + generateHoloMinimaps() + +/// Generates all the holo minimaps, initializing it all nicely, probably. +// TODO - This should be a subsystem ~Leshana +var/global/holomaps_initialized = FALSE +var/global/list/holoMiniMaps = list() +var/global/list/extraMiniMaps = list() +/proc/generateHoloMinimaps() + var/start_time = world.timeofday + // Build the base map for each z level + for (var/z = 1 to world.maxz) + global.holoMiniMaps |= z // hack, todo fix + global.holoMiniMaps[z] = generateHoloMinimap(z) + + // Generate the area overlays, small maps, etc for the station levels. + for (var/z in using_map.station_levels) + generateStationMinimap(z) + + if(using_map.holomap_smoosh) + for(var/smoosh_list in using_map.holomap_smoosh) + smooshTetherHolomaps(smoosh_list) + + global.holomaps_initialized = TRUE + admin_notice("Holomaps initialized in [round(0.1*(world.timeofday-start_time),0.1)] seconds.", R_DEBUG) + + // TODO - Check - They had a delayed init perhaps? + for (var/obj/machinery/station_map/S in station_holomaps) + S.initialize() + +// Generates the "base" holomap for one z-level, showing only the physical structure of walls and paths. +/proc/generateHoloMinimap(var/zLevel = 1) + //log_debug("Generating base minimap for z=[zLevel]") + // Save these values now to avoid a bazillion array lookups + var/offset_x = HOLOMAP_PIXEL_OFFSET_X(zLevel) + var/offset_y = HOLOMAP_PIXEL_OFFSET_Y(zLevel) + + // Sanity checks - Better to generate a helpful error message now than have DrawBox() runtime + var/icon/canvas = icon(HOLOMAP_ICON, "blank") + if(world.maxx + offset_x > canvas.Width()) + crash_with("Minimap for z=[zLevel] : world.maxx ([world.maxx]) + holomap_offset_x ([offset_x]) must be <= [canvas.Width()]") + if(world.maxy + offset_y > canvas.Height()) + crash_with("Minimap for z=[zLevel] : world.maxy ([world.maxy]) + holomap_offset_y ([offset_y]) must be <= [canvas.Height()]") + + for(var/x = 1 to world.maxx) + for(var/y = 1 to world.maxy) + var/turf/tile = locate(x, y, zLevel) + if(tile && tile.loc:holomapAlwaysDraw()) + if(IS_ROCK(tile)) + canvas.DrawBox(HOLOMAP_ROCK, x + offset_x, y + offset_y) + if(IS_OBSTACLE(tile)) + canvas.DrawBox(HOLOMAP_OBSTACLE, x + offset_x, y + offset_y) + else if(IS_PATH(tile)) + canvas.DrawBox(HOLOMAP_PATH, x + offset_x, y + offset_y) + // Check sleeping after each row to avoid *completely* destroying the server + if(world.tick_usage >= 80) sleep(world.tick_lag * 0.2) + return canvas + +// Okay, what does this one do? +// This seems to do the drawing thing, but draws only the areas, having nothing to do with the tiles. +// Leshana: I'm guessing this map will get overlayed on top of the base map at runtime? We'll see. +// Wait, seems we actually blend the area map on top of it right now! Huh. +// It does a bunch of other stuff too tho, lets check what that is. +/proc/generateStationMinimap(var/zLevel) + //log_debug("Generating station minimap for z=[zLevel]") + // Save these values now to avoid a bazillion array lookups + var/offset_x = HOLOMAP_PIXEL_OFFSET_X(zLevel) + var/offset_y = HOLOMAP_PIXEL_OFFSET_Y(zLevel) + + // Sanity checks - Better to generate a helpful error message now than have DrawBox() runtime + var/icon/canvas = icon(HOLOMAP_ICON, "blank") + if(world.maxx + offset_x > canvas.Width()) + crash_with("Minimap for z=[zLevel] : world.maxx ([world.maxx]) + holomap_offset_x ([offset_x]) must be <= [canvas.Width()]") + if(world.maxy + offset_y > canvas.Height()) + crash_with("Minimap for z=[zLevel] : world.maxy ([world.maxy]) + holomap_offset_y ([offset_y]) must be <= [canvas.Height()]") + + for(var/x = 1 to world.maxx) + for(var/y = 1 to world.maxy) + var/turf/tile = locate(x, y, zLevel) + if(tile && tile.loc) + var/area/areaToPaint = tile.loc + if(areaToPaint.holomap_color) + canvas.DrawBox(areaToPaint.holomap_color, x + offset_x, y + offset_y) + + // Save this nice area-colored canvas in case we want to layer it or something I guess + extraMiniMaps["[HOLOMAP_EXTRA_STATIONMAPAREAS]_[zLevel]"] = canvas + + var/icon/map_base = icon(holoMiniMaps[zLevel]) + map_base.Blend(HOLOMAP_HOLOFIER, ICON_MULTIPLY) + + // Generate the full sized map by blending the base and areas onto the backdrop + var/icon/big_map = icon(HOLOMAP_ICON, "stationmap") + big_map.Blend(map_base, ICON_OVERLAY) + big_map.Blend(canvas, ICON_OVERLAY) + extraMiniMaps["[HOLOMAP_EXTRA_STATIONMAP]_[zLevel]"] = big_map + + // Generate the "small" map (I presume for putting on wall map things?) + var/icon/small_map = icon(HOLOMAP_ICON, "blank") + small_map.Blend(map_base, ICON_OVERLAY) + small_map.Blend(canvas, ICON_OVERLAY) + small_map.Scale(WORLD_ICON_SIZE, WORLD_ICON_SIZE) + + // And rotate it in every direction of course! + var/icon/actual_small_map = icon(small_map) + actual_small_map.Insert(new_icon = small_map, dir = SOUTH) + actual_small_map.Insert(new_icon = turn(small_map, 90), dir = WEST) + actual_small_map.Insert(new_icon = turn(small_map, 180), dir = NORTH) + actual_small_map.Insert(new_icon = turn(small_map, 270), dir = EAST) + extraMiniMaps["[HOLOMAP_EXTRA_STATIONMAPSMALL]_[zLevel]"] = actual_small_map + +// For tiny multi-z maps like the tether, we want to smoosh em together into a nice big one! +/proc/smooshTetherHolomaps(var/list/zlevels) + var/icon/big_map = icon(HOLOMAP_ICON, "stationmap") + var/icon/small_map = icon(HOLOMAP_ICON, "blank") + // For each zlevel in turn, overlay them on top of each other + for(var/zLevel in zlevels) + var/icon/z_terrain = icon(holoMiniMaps[zLevel]) + z_terrain.Blend(HOLOMAP_HOLOFIER, ICON_MULTIPLY) + big_map.Blend(z_terrain, ICON_OVERLAY) + small_map.Blend(z_terrain, ICON_OVERLAY) + var/icon/z_areas = extraMiniMaps["[HOLOMAP_EXTRA_STATIONMAPAREAS]_[zLevel]"] + big_map.Blend(z_areas, ICON_OVERLAY) + small_map.Blend(z_areas, ICON_OVERLAY) + + // Then scale and rotate to make the actual small map we will use + small_map.Scale(WORLD_ICON_SIZE, WORLD_ICON_SIZE) + var/icon/actual_small_map = icon(small_map) + actual_small_map.Insert(new_icon = small_map, dir = SOUTH) + actual_small_map.Insert(new_icon = turn(small_map, 90), dir = WEST) + actual_small_map.Insert(new_icon = turn(small_map, 180), dir = NORTH) + actual_small_map.Insert(new_icon = turn(small_map, 270), dir = EAST) + + // Then assign this icon as the icon for all those levels! + for(var/zLevel in zlevels) + extraMiniMaps["[HOLOMAP_EXTRA_STATIONMAP]_[zLevel]"] = big_map + extraMiniMaps["[HOLOMAP_EXTRA_STATIONMAPSMALL]_[zLevel]"] = actual_small_map + +// +// ## Debugging and Testing ## +// + +/client/verb/debug_map() + set category = "Debug" + set name = "Debug Map Datum" + debug_variables(using_map) + +// TODO - Holomap Markers! +// /proc/generateMinimapMarkers(var/zLevel) +// // Save these values now to avoid a bazillion array lookups +// var/offset_x = HOLOMAP_PIXEL_OFFSET_X(zLevel) +// var/offset_y = HOLOMAP_PIXEL_OFFSET_Y(zLevel) + +// // TODO - Holomap markers +// for(var/filter in list(HOLOMAP_FILTER_STATIONMAP)) +// var/icon/canvas = icon(HOLOMAP_ICON, "blank") +// for(/datum/holomap_marker/holomarker in holomap_markers) +// if(holomarker.z == zLevel && holomarker.filter & filter) +// canvas.Blend(icon(holomarker.icon, holomarker.icon_state), ICON_OVERLAY, holomarker.x + offset_x, holomarker.y + offset_y) +// extraMiniMaps["[HOLOMAP_EXTRA_MARKERS]_[filter]_[zLevel]"] = canvas + +// /datum/holomap_marker +// var/x +// var/y +// var/z +// var/filter +// var/icon = 'icons/holomap_markers.dmi' +// var/icon_state + +#undef IS_ROCK +#undef IS_OBSTACLE +#undef IS_PATH diff --git a/code/modules/holomap/holomap_area.dm b/code/modules/holomap/holomap_area.dm new file mode 100644 index 0000000000..7ea09dcd21 --- /dev/null +++ b/code/modules/holomap/holomap_area.dm @@ -0,0 +1,78 @@ +/* +** Holomap vars and procs on /area +*/ + +/area + var/holomap_color = null // Color of this area on station holomap + +/area/rnd + holomap_color = HOLOMAP_AREACOLOR_SCIENCE +/area/outpost/research + holomap_color = HOLOMAP_AREACOLOR_SCIENCE +/area/server + holomap_color = HOLOMAP_AREACOLOR_SCIENCE +/area/assembly + holomap_color = HOLOMAP_AREACOLOR_SCIENCE + +/area/bridge + holomap_color = HOLOMAP_AREACOLOR_COMMAND +/area/teleporter + holomap_color = HOLOMAP_AREACOLOR_COMMAND +/area/teleporter/departing + holomap_color = null + +/area/security + holomap_color = HOLOMAP_AREACOLOR_SECURITY +/area/tether/surfacebase/security + holomap_color = HOLOMAP_AREACOLOR_SECURITY + +/area/medical + holomap_color = HOLOMAP_AREACOLOR_MEDICAL +/area/tether/surfacebase/medical + holomap_color = HOLOMAP_AREACOLOR_MEDICAL + +/area/engineering + holomap_color = HOLOMAP_AREACOLOR_ENGINEERING +/area/maintenance/substation/engineering + holomap_color = HOLOMAP_AREACOLOR_ENGINEERING +/area/storage/tech + holomap_color = HOLOMAP_AREACOLOR_ENGINEERING + +/area/quartermaster + holomap_color = HOLOMAP_AREACOLOR_CARGO +/area/tether/surfacebase/mining_main + holomap_color = HOLOMAP_AREACOLOR_CARGO + +/area/hallway + holomap_color = HOLOMAP_AREACOLOR_HALLWAYS +/area/bridge/hallway + holomap_color = HOLOMAP_AREACOLOR_HALLWAYS + +/area/crew_quarters/sleep + holomap_color = HOLOMAP_AREACOLOR_DORMS +/area/crew_quarters/sleep/cryo + holomap_color = null + +// Heads +/area/crew_quarters/captain + holomap_color = HOLOMAP_AREACOLOR_COMMAND +/area/crew_quarters/heads/hop + holomap_color = HOLOMAP_AREACOLOR_COMMAND +/area/crew_quarters/heads/hor + holomap_color = HOLOMAP_AREACOLOR_SCIENCE +/area/crew_quarters/heads/chief + holomap_color = HOLOMAP_AREACOLOR_ENGINEERING +/area/crew_quarters/heads/hos + holomap_color = HOLOMAP_AREACOLOR_SECURITY +/area/crew_quarters/heads/cmo + holomap_color = HOLOMAP_AREACOLOR_MEDICAL +/area/crew_quarters/medbreak + holomap_color = HOLOMAP_AREACOLOR_MEDICAL + + +// ### PROCS ### +// Whether the turfs in the area should be drawn onto the "base" holomap. +/area/proc/holomapAlwaysDraw() + return TRUE +/area/shuttle/holomapAlwaysDraw() + return FALSE \ No newline at end of file diff --git a/code/modules/holomap/holomap_datum.dm b/code/modules/holomap/holomap_datum.dm new file mode 100644 index 0000000000..67a1ee0bc9 --- /dev/null +++ b/code/modules/holomap/holomap_datum.dm @@ -0,0 +1,40 @@ +// Simple datum to keep track of a running holomap. Each machine capable of displaying the holomap will have one. +/datum/station_holomap + var/image/station_map + var/image/cursor + var/image/legend + +/datum/station_holomap/proc/initialize_holomap(var/turf/T, var/isAI = null, var/mob/user = null, var/reinit = FALSE) + if(!station_map || reinit) + station_map = image(extraMiniMaps["[HOLOMAP_EXTRA_STATIONMAP]_[T.z]"]) + if(!cursor || reinit) + cursor = image('icons/holomap_markers_vr.dmi', "you") + if(!legend || reinit) + legend = image('icons/effects/64x64_vr.dmi', "legend") + + if(isAI) + T = get_turf(user.client.eye) + cursor.pixel_x = (T.x - 6 + HOLOMAP_PIXEL_OFFSET_X(T.z)) * PIXEL_MULTIPLIER + cursor.pixel_y = (T.y - 6 + HOLOMAP_PIXEL_OFFSET_Y(T.z)) * PIXEL_MULTIPLIER + + legend.pixel_x = HOLOMAP_LEGEND_X(T.z) + legend.pixel_y = HOLOMAP_LEGEND_Y(T.z) + + station_map.overlays |= cursor + station_map.overlays |= legend + +/datum/station_holomap/proc/initialize_holomap_bogus() + station_map = image('icons/480x480_vr.dmi', "stationmap") + legend = image('icons/effects/64x64_vr.dmi', "notfound") + legend.pixel_x = 7 * WORLD_ICON_SIZE + legend.pixel_y = 7 * WORLD_ICON_SIZE + station_map.overlays |= legend + +// TODO - Strategic Holomap support +// /datum/station_holomap/strategic/initialize_holomap(var/turf/T, var/isAI=null, var/mob/user=null) +// ..() +// station_map = image(extraMiniMaps[HOLOMAP_EXTRA_STATIONMAP_STRATEGIC]) +// legend = image('icons/effects/64x64.dmi', "strategic") +// legend.pixel_x = 3*WORLD_ICON_SIZE +// legend.pixel_y = 3*WORLD_ICON_SIZE +// station_map.overlays |= legend diff --git a/code/modules/holomap/holomap_zlevel.dm b/code/modules/holomap/holomap_zlevel.dm new file mode 100644 index 0000000000..8f76ced3d7 --- /dev/null +++ b/code/modules/holomap/holomap_zlevel.dm @@ -0,0 +1,44 @@ +// +// An enhancement to /datum/map to store more and better meta-info about Z-levels +// + +// Structure to hold zlevel info together in one nice convenient package. +// Wouldn't this be nicer than having to do those dumb arrays? +/datum/map_z_level + var/name // Friendly name of the zlevel + var/z = -1 // Actual z-index of the zlevel. This had better be right! + var/holomap_offset_x = 0 // Number of pixels to offset right (for centering) + var/holomap_offset_y = 0 // Number of pixels to offset up (for centering) + var/holomap_legend_x = 96 // x position of the holomap legend for this z + var/holomap_legend_y = 96 // y position of the holomap legend for this z + +/datum/map_z_level/New(z, name, holomap_zoom = initial(holomap_zoom), holomap_offset_x = initial(holomap_offset_x), holomap_offset_y = initial(holomap_offset_y)) + src.z = z + src.name = name + src.holomap_offset_x = holomap_offset_x + src.holomap_offset_y = holomap_offset_y + +// Map datum stuff we need +// TODO - Put this into ~map_system/maps.dm +/datum/map + var/list/zlevels = list() + +// LEGACY - This is how /vg does it, and how the code uses it. I'm in transition to use my new way (above) +// but for now lets just initialize this stuff so the code works. +/datum/map + var/list/holomap_smoosh // List of lists of zlevels to smoosh into single icons + var/list/holomap_offset_x = list() + var/list/holomap_offset_y = list() + var/list/holomap_legend_x = list() + var/list/holomap_legend_y = list() + +/datum/map/New() + ..() + // Auto-calculate any missing holomap offsets to center them, assuming they are full sized maps. + for(var/i in (holomap_offset_x.len + 1) to world.maxx) + holomap_offset_x += ((480 - world.maxx) / 2) + for(var/i in (holomap_offset_y.len + 1) to world.maxy) + holomap_offset_y += ((480 - world.maxy) / 2) + for(var/z in 1 to world.maxz) + holomap_legend_x += 96 + holomap_legend_y += 96 diff --git a/code/modules/holomap/station_holomap.dm b/code/modules/holomap/station_holomap.dm new file mode 100644 index 0000000000..2c2a0ad3e7 --- /dev/null +++ b/code/modules/holomap/station_holomap.dm @@ -0,0 +1,246 @@ +var/global/list/station_holomaps = list() + +/obj/machinery/station_map + name = "station holomap" + desc = "A virtual map of the surrounding station." + icon = 'icons/obj/machines/stationmap_vr.dmi' + icon_state = "station_map" + anchored = 1 + density = 0 + use_power = 1 + idle_power_usage = 10 + active_power_usage = 500 + auto_init = 0 // We handle our own special initialization needs. // TODO - Make this not ~Leshana + circuit = /obj/item/weapon/circuitboard/station_map + + // TODO - Port use_auto_lights from /vg - for now declare here + var/use_auto_lights = 1 + var/light_power_on = 1 + var/light_range_on = 2 + light_color = "#64C864" + + layer = ABOVE_WINDOW_LAYER + + var/mob/watching_mob = null + var/image/small_station_map = null + var/image/floor_markings = null + var/image/panel = null + + var/original_zLevel = 1 // zLevel on which the station map was initialized. + var/bogus = TRUE // set to 0 when you initialize the station map on a zLevel that has its own icon formatted for use by station holomaps. + var/datum/station_holomap/holomap_datum + +/obj/machinery/station_map/New() + ..() + holomap_datum = new() + original_zLevel = loc.z + station_holomaps += src + flags |= ON_BORDER // Why? It doesn't help if its not density + if(ticker && holomaps_initialized) + spawn(1) // Tragically we need to spawn this in order to give the frame construcing us time to set pixel_x/y + initialize() + +/obj/machinery/station_map/Destroy() + station_holomaps -= src + stopWatching() + holomap_datum = null + ..() + +/obj/machinery/station_map/initialize() + bogus = FALSE + var/turf/T = get_turf(src) + original_zLevel = T.z + if(!("[HOLOMAP_EXTRA_STATIONMAP]_[original_zLevel]" in extraMiniMaps)) + bogus = TRUE + holomap_datum.initialize_holomap_bogus() + update_icon() + return + + holomap_datum.initialize_holomap(T, reinit = TRUE) + + small_station_map = image(extraMiniMaps["[HOLOMAP_EXTRA_STATIONMAPSMALL]_[original_zLevel]"], dir = dir) + // small_station_map.plane = LIGHTING_PLANE // Not until we do planes ~Leshana + // small_station_map.layer = LIGHTING_LAYER+1 // Weird things will happen! + + floor_markings = image('icons/obj/machines/stationmap_vr.dmi', "decal_station_map") + floor_markings.dir = src.dir + // floor_markings.plane = ABOVE_TURF_PLANE // Not until we do planes ~Leshana + // floor_markings.layer = DECAL_LAYER + update_icon() + +/obj/machinery/station_map/attack_hand(var/mob/user) + if(watching_mob && (watching_mob != user)) + to_chat(user, "Someone else is currently watching the holomap.") + return + if(user.loc != loc) + to_chat(user, "You need to stand in front of \the [src].") + return + startWatching(user) + +// Let people bump up against it to watch +/obj/machinery/station_map/Bumped(var/atom/movable/AM) + if(!watching_mob && isliving(AM) && AM.loc == loc) + startWatching(AM) + +// In order to actually get Bumped() we need to block movement. We're (visually) on a wall, so people +// couldn't really walk into us anyway. But in reality we are on the turf in front of the wall, so bumping +// against where we seem is actually trying to *exit* our real loc +/obj/machinery/station_map/CheckExit(atom/movable/mover as mob|obj, turf/target as turf) + // log_debug("[src] (dir=[dir]) CheckExit([mover], [target]) get_dir() = [get_dir(target, loc)]") + if(get_dir(target, loc) == dir) // Opposite of "normal" since we are visually in the next turf over + return FALSE + else + return TRUE + +/obj/machinery/station_map/proc/startWatching(var/mob/user) + // Okay, does this belong on a screen thing or what? + // One argument is that this is an "in game" object becuase its in the world. + // But I think it actually isn't. The map isn't holo projected into the whole room, (maybe strat one is!) + // But for this, the on screen object just represents you leaning in and looking at it closely. + // So it SHOULD be a screen object. + // But it is not QUITE a hud either. So I think it shouldn't go in /datum/hud + // Okay? Yeah. Lets use screen objects but manage them manually here in the item. + // That might be a mistake... I'd rather they be managed by some central hud management system. + // But the /vg code, while the screen obj is managed, its still adding and removing image, so this is + // just as good. + + // EH JUST HACK IT FOR NOW SO WE CAN SEE HOW IT LOOKS! STOP OBSESSING, ITS BEEN AN HOUR NOW! + + // TODO - This part!! ~Leshana + if(isliving(user) && anchored && !(stat & (NOPOWER|BROKEN))) + if(user.client) + holomap_datum.station_map.loc = global_hud.holomap // Put the image on the holomap hud + holomap_datum.station_map.alpha = 0 // Set to transparent so we can fade in + animate(holomap_datum.station_map, alpha = 255, time = 5, easing = LINEAR_EASING) + flick("station_map_activate", src) + // Wait, if wea re not modifying the holomap_obj... can't it be part of the global hud? + user.client.screen |= global_hud.holomap // TODO - HACK! This should be there permenently really. + user.client.images |= holomap_datum.station_map + + watching_mob = user + moved_event.register(watching_mob, src, /obj/machinery/station_map/proc/checkPosition) + dir_set_event.register(watching_mob, src, /obj/machinery/station_map/proc/checkPosition) + destroyed_event.register(watching_mob, src, /obj/machinery/station_map/proc/stopWatching) + update_use_power(2) + + if(bogus) + to_chat(user, "The holomap failed to initialize. This area of space cannot be mapped.") + else + to_chat(user, "A hologram of the station appears before your eyes.") + +/obj/machinery/station_map/attack_ai(var/mob/living/silicon/robot/user) + return // TODO - Implement for AI ~Leshana + // user.station_holomap.toggleHolomap(user, isAI(user)) + +/obj/machinery/station_map/process() + if((stat & (NOPOWER|BROKEN)) || !anchored) + stopWatching() + +/obj/machinery/station_map/proc/checkPosition() + if(!watching_mob || (watching_mob.loc != loc) || (dir != watching_mob.dir)) + stopWatching() + +/obj/machinery/station_map/proc/stopWatching() + if(watching_mob) + if(watching_mob.client) + animate(holomap_datum.station_map, alpha = 0, time = 5, easing = LINEAR_EASING) + var/mob/M = watching_mob + spawn(5) //we give it time to fade out + M.client.images -= holomap_datum.station_map + moved_event.unregister(watching_mob, src) + dir_set_event.unregister(watching_mob, src) + destroyed_event.unregister(watching_mob, src) + watching_mob = null + update_use_power(1) + +/obj/machinery/station_map/power_change() + . = ..() + update_icon() + // TODO - Port use_auto_lights from /vg - For now implement it manually here + if(stat & NOPOWER) + set_light(0) + else + set_light(light_range_on, light_power_on) + +/obj/machinery/station_map/proc/set_broken() + stat |= BROKEN + update_icon() + +/obj/machinery/station_map/update_icon() + overlays.Cut() + if(stat & BROKEN) + icon_state = "station_mapb" + else if((stat & NOPOWER) || !anchored) + icon_state = "station_map0" + else + icon_state = "station_map" + + if(bogus) + holomap_datum.initialize_holomap_bogus() + else + small_station_map.icon = extraMiniMaps["[HOLOMAP_EXTRA_STATIONMAPSMALL]_[original_zLevel]"] + overlays |= small_station_map + holomap_datum.initialize_holomap(get_turf(src)) + + // Put the little "map" overlay down where it looks nice + if(floor_markings) + floor_markings.dir = src.dir + floor_markings.pixel_x = -src.pixel_x + floor_markings.pixel_y = -src.pixel_y + overlays += floor_markings + + if(panel_open) + overlays += "station_map-panel" + else + overlays -= "station_map-panel" + +/obj/machinery/station_map/attackby(obj/item/weapon/W as obj, mob/user as mob) + src.add_fingerprint(user) + if(default_deconstruction_screwdriver(user, W)) + return + if(default_deconstruction_crowbar(user, W)) + return + return ..() + +/obj/machinery/station_map/ex_act(severity) + switch(severity) + if(1) + qdel(src) + if(2) + if (prob(50)) + qdel(src) + else + set_broken() + if(3) + if (prob(25)) + set_broken() + +/datum/frame/frame_types/station_map + name = "Station Map Frame" + frame_class = "display" + frame_size = 3 + frame_style = "wall" + x_offset = WORLD_ICON_SIZE + y_offset = WORLD_ICON_SIZE + circuit = /obj/item/weapon/circuitboard/station_map + icon_override = 'icons/obj/machines/stationmap_vr.dmi' + +/datum/frame/frame_types/station_map/get_icon_state(var/state) + return "station_map_frame_[state]" + +/obj/structure/frame + layer = ABOVE_WINDOW_LAYER + +/obj/item/weapon/circuitboard/station_map + name = T_BOARD("Station Map") + board_type = new /datum/frame/frame_types/station_map + build_path = /obj/machinery/station_map + origin_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 2) + req_components = list() + +// TODO +// //Portable holomaps, currently AI/Borg/MoMMI only + +// TODO +// OHHHH YEAH - STRATEGIC HOLOMAP! NICE! +// It will need to wait until later tho. diff --git a/icons/480x480_vr.dmi b/icons/480x480_vr.dmi new file mode 100644 index 0000000000000000000000000000000000000000..d175026af1f02a6029dd184710c8d525358748b0 GIT binary patch literal 43773 zcmeFZX;_oz);63liWq36Y6XGaT4c9wq*fsy5VW>-yD88X9093yK&B)Jaz{c2oY+>u zr@AXGVbH3ifD9^-K*)fo)GCC*7$n0TLAp@?&10N`##6JnTGv|VI@h_@?b)xQzQ8PYUyMSbFx&t9**7SZt-$)T$N{`!c={Ft{5qQxyF2T% zLzxGTCKI!g33wEWRC4GfrP49;=}hp^x0~3>Dkx$Ipgw+U+R!6 z?6ZpkcY?b`MEWxI3PegAd*_v>#jS6zM2ZBOmj;k!2evHh1#vaKyU4z77< zzdY`fqE&~f`dupBTIB{`)7oPZ>vSG*dxh*$Qs4D;MpKXaH z4NS<+@u3|Q?-}^Zq>8@g?4?~-$G-Hf_$X8v`fLB@YZpI@nLP8^S0_(kH?M#H!#}+I ziZ>_i@o%sJH0o%_s+y-M7|fDD=D5XVw?ypCx|!=J~&S z+yCnW|MI5))m2}=30(hQ-u~ae`afU%&nNPKovCx3{+qM>%VBOt>3r<|txvr<{r>;S z_5O4I|5u;?0$%)|#kk;qI{W_#b}0XY^Zk1`d*gcl0iOSc^8Y^yHO+ru=kMwJKmPu2 zGtfWy&A+59)c;q|`JXc0e_-c7u=5|H{daWwUxndS%KX~`R`QXt>pU+SZZ_(|)J#c>gHq^F%eQx)y-NNh3>F9qv-;HMX+BU8SpSSxK z{qAPea(V&yV>QZIfU>DarJV|beN9&2VoCG%Y zuUEC(c8UA9-~!g~c--tNSh1;Jefz_l*)hItSMwd&8s~fSZ?&#D>3XAyAu38zLp>d^S#cwB`5Tk*y4xUZB(moSUANN`M%-4) zx;#^I`a5(#*xh;?O$B$z6b z&YACB?^^BhHeHyF!l^1CMr2=gmA_2zjOexZg^G1|VT-k`sN9OJ$o3{KQzSQwM2QYj z50e{z^L@6seDLEprdDvqvmr+3ge8HJ=TMs_Nh^kAOPv?4uo_i<3)MRQ0Ai?W9Wece zBU;C|y*B($YuBUdx}JMO^3TUP$$jMB$X+d$1vAY3F29-1E%d#m<8HgU(&wjs!~NH!w)8B?dQ2}{8mF^-swP!I$N}^DDd8R!(GP4yGae0*UmeW zdkT)srm%WuE;qDFQjSIx|7y8r_|&DumC^KwvGLyc#&$`{DX|2DW4-sW*r69N*pGn9`Mu!fA&g35UlBJV zuP#;uiClz@cO_}3u+K2KmunUdthO7K`^z9Cu0bw7z~XbT>7>kb^(McGMv=IqKR~qW zWdiA#Hef|(?Wo2!j@%jd#p~_tLG3FY z?n2fT!XKyEwX+TL0S!Cikw;qG)I7r|x5LmHKg)ZC#asA{w{g)~)z-;?UWiXn@NR4@1O zDs~B$9h4~#&Ta@6ZvrdJjLeX_Lv=8{>z>-(jR?C_R`(7vigUg6QVMTAEE1{{hZfQ8 zH0eNT5|MYTjBuVA_k4dyYr`^m!`thgVdM#JZ(wI7fyx|!Ba2}l>uEyCeQ|Pi1w-1b z8x0T@Y5MnT58;$o4Dj-L&lus}v1jqUYlHz0Dle0gH?-nc#}7CV?l|G@U%L9*ujM8= zQfoa5sA{qlPiDr+N3$VbPie{leO2AXN2cEIcGc{2TJdy~@ZKh&Ja#<(>AT9f=d;8Y zOF5gb(p=mbBwLgpa`#5M=E*)yOQdF{#Bm-je{x<*7ap35yN!gf#u)=s1<}V`^yHXy zLJpHfIIbL!Rjy%OuL--!`)j^S70u9pW2`)jQCnm7rJwswBK%@(<@xfyi#v~31(&6s z&Fmzy{Yz3#4}}eCo{T)9YNU8gFISP-{dd2T=~&li{hsL)dJV(6+)QS$QXOY6Fns`(tTiMWwdBjN7$4!mT1r_;VP@oHtQFPTcLqT@Sr4hi z?H;XJ{v@Mufqj6)+M~lBdp^~qqr`A{&0+A9LIRbABYeXxMVzb_Ibv1SVpZ7IPTC}uk)TNR1r&Ypp!6Hx)|Ly;5vv^$`QKa2uw{rIaj z`c*f|nqLhcuiD}jc)t&m(X!Hub+`S}b*B5^#lWCe?9AdL3s5^;;-DyH@tLx@VI8HY zf#*|z#7e*hGBE_{SX4k$1~vfxJfW+l!T>+{CSPRnQMB$=ZV1;d=?tSa>yB3ibOqes zzqKSKKVt7-^EP$^rcC0D3yIX6ZJH+o%`<4ylnxrJh3iegp(>(C>(VJPA-u{5Seb5k zuROM$fj<_5!ShO6RyE@f@(nG`e&lL#TXSP)(tFyQ1?3&h+k)X$`H>k_??tiNM|TFn zi(H{oMGbA0T!l}hCf+&z=qJ-FQ}gB%{|$RZLL=XY8CDd?uXHP8?uDOh@5+#P1o8%P z1nH{^cRBl6X$mod(SLI69Cf63OuI*1TkH5qMOo=g@Y?h;ru&P^ilDT=4jm4Xd${ON zw{Hu=ZE0!1M3uh7ZE%Vzb)j_aT}U&*N$8o+ByhUQba^Ac@={rhk$0#Dsh`9|XO^Xs zhbma9$NN^{uI_-b)2i1#JtR;QDyGf&p(sp4}?j)JTF$q zYz0aB7JtpNCDDy{EBmeuZDU`@bgAq+d_N-$*!jyGarc+cvxgN}6oEQ6)k5a`bQ08f zc=RcjuVhG&NR>7_(z;0x`J-psuy{frM&wcGxziHo>=~Ol1DsD*-(5g-@iUhAA3yV4 z>7N_OEPfeJ4oy1;{6p%J-$_hK3=%JjRyisM6qO+-i#E1J=<|ev%IJK<#5Wq^;_mPbJA$xHv(GM+S5IbQ zWt)|Z7rAjIDSvIxChb{Uf6eRn{Axdxz}it{;jN+?vk3m{U^r8r9z%03w=VY22LIaX|5xLD?U^#&v?YZL;30Icn{7l%65dCoQL(#aw}OK5e`R` zm70HMq?UHnWbmxe+J2Z#I6YJf(kQ6~BfsucHsDkkov)UUkE?CVU#(lHok}KAx! zqjG}OJglR(bEq7LtEn_*F?^$jz#fkqFhm9L_DdM}9QflD5_7LCBQpelbKQ=_0W#K; zldVm?@3M=}`)!Msb}VT8GPSlSbi?4C<+ziXHAkz0T_n%h?-fc0*((e6r(+6;$sQ#G zn0+lPN>Wa=L!_}nMI}X{(HHs{1-`2mSaXl9riH_=)Ili-R6A=rtxK#NhAus2wN922 za{4d`=GsoE|Hbg$feKMemBFU$b|U4ht7=E0eZKs*58-s?w{hkA!OVBUlbV$o(oZjV zyogPeV(+(~A@#dNW7~ZSG{fl{wo{kNj#;db;xvJK6`pFFc?R(KzN3am_1;V#R%#7Noizaz1?Prm7>Y7BeHWf#q(c6YP#eeIH$ zWh`*yguzYe7LeZBqeV?8xNm%P;8Ky z*F7`(1y2UcXFCJ=3Qcc2Tv5sK3j{ z(pO^rr?Z3FFH_6Q0SAyIU|`Y6oT1S&(2e zL)tQZw{{o>KFm*rGEDAY7MyS0QPjSpuclg5NX2|qw<3%It!EQ&$eMUPSlo<0kEYfP z4g;T+uS&0K1N8kS7VpK5J)L(H`C~Ra$G2op1nyD6?W7N=ycQ+CYDZT}{;xyX zr2ZuxHALwmW%jA|z#uuMP=6w#Sdp%>CET$u3x9j>eBErPaKp_8r_qMEaIBGYeb!TL z8fL(i6qqQ6YPF>x0Me2A(N1hDAu_OKs3}lPxhjn*lL#Ys& zlim~V7<=Y{?XGk<-tX?pcwT9xN>KrK2d(M4MB;1>K8a)5re%hbhJ}puE}C@Q=%G&X zOQ%IdQ@on^5yi0ix>Cv`zP`3?p^e)9TEBTsg=YW6AAIuys+P}u}Yr(NRY zwX%XZSr#KCEoDeIUT^pY4*vD-W`wnZeXak7$Z_!T?pMzebYD&jznMAzQliYb6q zHz}fmwgy_h><~Vj33d-p%`leWFAzKe04&a2{&GVo{&YV1Zu7R8f(_}KnZJ#wc~;h! z=1t{`v2tx^Bd^^gXHRxE za#`E_2ryU2TiYE(#@D|u1I%o-2H7XUvIz17i4lrHWl z&=8|ZRTvlOWCyvea!pX9TYUB>S$x-$P0Mmt_z`Ew!dJ`RND&*P<_CIHg^oG}mcXz^ zj@UQqIB)%cwjd53ECd{=KqAlWldxL%bBuXkGK_6!m+NX*gVNC0dSS^#9j0?JSpT73o4}n6FOjGJ;SnvpfS*~Xc7;7Zw24bf?%BEMrDv8SYwBRq$-Avl; zDWZ^-dgP3e+uQ{8TM0|O%oE$PpX`C%>m8ikZ1@BYzRA-lDWRj^9@E?C1uMTY|J+GY zGs}L|{JgllG4@VL$^~N+sefrcCIfZ>%N#5tiWgnbpB#r`p>MLp4*BFZ8F?M6g=I1Z#0 zDnc$y;4*fy+!|-@DO);6qH?oo0iGMb?8l(CroFUVI3j-*McV3Ghr; zBX{UBD3B`lN@us}cmk$_ZYTfF4<-?F@JYHk*c|&o?%|3!Wh}V_|2?Q$bJwm4yvy>D zD9oll#G%9Yb7iq&I!ZIXTy5)$IF_a4iDmX`s`ptBMXmMsrqi#3V%;|=dA2n?$D8tnk*#py+h@gD3!f1piMT~ zJ?Ys7e62a=YC9*deK{MqET`7qg@*JeIJXvv-UH(8gOa-?Toc@^W2Mru1e!6Xyxm9z zxgMOfxeU&l@{p@SqE*w^^ki{{0iM)&oUp;$ui;-B&}NDv8nQ-)%M{Z%%@dQr z$4|3KZ^PUR%Ah=@yF#|W9D?=end{LsIo?Q)ylwJCO!ALGvXswyV)@9XO?i!}RAYiw zWRoHo517aV!XNTzW2@d*BF#-Teyg}DXg`gMJ4nzjDk<(2CeJEyxgdc5C|kpf8!~Rd zOi~^K&bY{$4+7aR#;a^;Y3d1MsbZ!~;c-}(*TMXhP;HNcnOo-d_)h}_k`|->`T#t` zgQaq0QzwD;`&7-dr%?ZlJRl{v9Ta8LXZ#S;*LOkyZA@3yuMGK>H?8*y&OWY%&aJBT z@|%9QB!zb`|z6^mzfX1*6uVfVqd=Lb=wcq+ImV ztbuG&=Nmz2QYwb1o>uxmmNP0srk=nvsnm1n1F*D|FRK)amjO19P#VXMm&bD*eA%~PuFUE&mdT(^b%S=$eKF@5DswHcVH)|=guPD{M}%w&4`SdGLQ z8FHg4Dz^}sEd|Ucgff%>XN-HOXLLqxq*clus?gs#o2~CTyPTEUfm<;%cglA|*+786O#jV783BUH8>dfR;Fr*(Zc5TdHLSIZGC zhuRmC7qHM@YTZOI^2b^Hxhu;JgXx0gpW36z%Ydmc#2ybxqj20xI|>Lb zD$1XFUI7jnWA(d>rhUEpm;E6p@iEC|9bKyA&>W5mw@U*7POv`&C4I-5y@UH#OUqYz zHnp|O6eRy3k)0U1`6R4Oh9jD~JP=!cv#D?WI7^@n*_4*Y=)2P4M`St1$K|+BZz2o& z^yr1Ed)ZQYG-SaZ(-UNGonnSVDgtDfS_2-(GG$rk0h>Zh5A<_@2bg#SKmefJm;!=S z_aG9vbT%8CmX%pEvBFjuIrGikB4-n>E6vg|&+-35JKd(2hNa(4K#9NBVqFs6l&XY9MuzMNFrcSR`oS`hNnQMiXD z_y%Ob511c7=4=QS^LkkH9lU0WFcP$xp!P(xr18UK7+<%#7+AF^hvNLEu(wZD<; z?;Uc}=3c9E1qmIsdo(H2e8&stF}UFp;Zk|zMv$xKp8UEps`0Lta|M38i`6!{kH~XU zBTi}%xCciDaYQIw!v>J@Gowi`E_KQ^>*nz;^Ye{@45J5Pc^ZD}f`?+XuUv_kRRi#_ z8g4OBI-l#Xty8RUZE!2Xk{B`3xh}|Tq_vQ;7M8XT!(eKM{?^$hY})am1Xpn0u1c8DUv#sY{G29(}w_yq9~{J z3mbUPLy?YHDxzpzGE*GZX>e5NDB^SQ9<`NbQG@FZU}GgAcPx`;wX{dsj1;6^JQc+A zFYOfAcnPRdN=buNyTy~sw>PwA+%dj9JKU7~`?_6;GabC8vnjoUW1k1Hj+T#4Drs}) z&ohQ&Q&(Z{XN1f>{&iUt_U?r>x|2hJGv*`yGj2bxVRL+gLRW5*I;z!<78ph?4n zC2qbrct`hKppj>C5@w7Wk32DC7ktH*Fy`qr{#c(M9{!2asC|B_&L@FuIQhP@x~~1~ zhn9G%-+{3`BV|QdlF+n*q02K7Ut8g6u$HKw3;!V~AO{fD)))g>GqzY0$Nq z1e2BBK7K^QK1IaC<)k9!mO75(Dzle9A}(anBkM$f@&i=)oS8r}WTseHFVryG#EmtT zR-FE0Dy;)DyF^o55M#QIiX36UoWkNChs)r>E&^|s^2b}_A)!6Z&n8vwpcKF`=A zS;jR0to-bWmXF@aTDNPX&(8 z?+!lf0kFUIQX~-+0aCZQ!E4Y?+9%VFzZmlXymmmgMJz%77l@*AIY}L*c;ZD=%}t=^ z=|#MQBE19^cFaO(wMc-pDY5tko0Q(AR;Xn3cT%x}R3R!t!RK8m6-ia$#Oc zWeoD>Wu-D=zeD&+l|y)7pItt4EA1E4r4J!TqX5FpJ8>x?kEsU8ajUbu;kc@Y0|7{b zxQ;i`R>8+kA=+M!;ue_TT0kEyg@{>JZT|B<*!+}}0;XL|)em*7klA3FndhHEL(&+3 zyRb%WQ0b_klxQEu%Jq~_ZjF01@j#J1^>Y(wm-S%?{lgXRw+P;xmc@&%nm*cn6Co2% zJhj{`4A;XhUpD>*|8(T9?T3T#r^}-!7ImZ(bN5bb{x-sM@+xu?;H3V}ss&#y6ZPfuB?gBLQNXo^~R(J;}o6VSS|{ONkd_MTRrh zY(n+xdqv$K8IHm>z~@^3HmM(6^*g0(NJ!!B?`nKN*&3Rb57wV%?Zn_u8f6OR7vwfj zEQWX*@^qf>AhvL6*s@KqO}_7^9eNx7t@J#?kvPTp1$pyisbG8pT}SpN>Wy8a<#y@T zBEwmXBD7fIEbq`Bn)u^oW+`kUAK=^pt0v&1H&P;A)|@5N`T&(31JvgM69*RsP0qI6 zOBPlR>qixz_19}vI{TpqP`|E=)e4s#$>a=A+z`P2N3~is~f9$YucURLNas6Os0QK-3^tO{!%fckO9C)1R(F;^MO+0PuiSb{;WK+Cy3>$ZWP zJ?)Yn)nkbR8QT!0=(4rZ7>gx@^Og0+z>Ui$;R z$JqpV{38!m%jji*FMkC1()PaUf@0NQXl423v(367(b9Ysk+%%*J{a#IRn3=kQN-L$ z(?su?yl=fpE%t@cr@Z9Ob6rjLR7uamM#@4lEfU*Wm@D%lLhjQQWWnI}ZY|>JOJ3SA zKRFiPjcVn%U192IsR_oowa+Y(rRG)UtIZ&*a&&s^37vlUiivyZ7ZZ2w5n2qOd1SsU z0kmY0J7*K%6-%uxL_OmgXbh-_2PE}j#%niCBG;wV-7m&O;q=nArqBx9qnL72Y4w;g69DHGfF0!YWmFC zOdRcK)>vi=f)&qYLq-=pCB~XPjRjvyfR;aW1_FUwe9PO88bnN3_VH8w>LBzuZQGF0 zsM+%y>$jmM(1bL;_Is%-nCNKdDw2GQ6_Ys4OzcRs7bu~loa6axIm=078%K`m=nMz; zGg}uA#W6iS+Va5>YtX>LHAN}VJS5p=)A7`m46ApFe*Hn43x0*#_S;3 z;^=_8`+=s5@d|94bn2N5YXj?xcMg@>N5Rf>W!IqZrtptpr&VPRvewKx|9)HQ%SmG> z-?7zn>B<`}|Fv!FIkzk0<#Ws^`o1KKzTUu0-g|a$y!3cVb~oWG^^R8Dv4~iLf2tiR87CdD;GHJwrp^x$(6+~ z_eX@Lo#`Ooo83l|IzXJZd0}ksvEtwe(K`sYY!g0@k)R-dqPKzkG-L_1e=JI2-Z)|? z9Vm53;HQp5>K3wKa(j1ULaANN8!T^%rkADC+ug2k!s^s^BRP&Y3G~GEnKoG|7X2}2 z9W5WSsCUt(33Z0mbnUu$*i1c=g%I`_B{Hi@SxTT9tsNF@8U-jWFyPgM+Ck62W?=B> zrRJ}HsNO|e60*y1{7c&9h~k%7ajTlzhYruUUMkSkW7N>eM?gl$5ozH>+DFsC19uO&Ya~lr9H{rqhX5SXz3|EI6Ai*|%ZJ1Mw(WK0ZJ~7{eIGsX| zer`8XVWRBmF%$aM{cXY`-`HqpvR5tjXHh%*-Pb032f%U({cjT zfy7Qp5SIrvgjTC082)%;Yx7QQTA#T`aBPQQHyk}^chj=6ARLM5e8u*O3TPkN$tIi{ z3S^Ucpr}$_>${q76to-jBH|S4&qiDw{WJs?!qY@4AVAt}t32Y$riK)$(EPLp z$J}pxw=BpG7)_KKwJ+Od`cYCeeII0j%+pHOSib!2M!t81)acQ~cl|X6E1tZNq^dJJO~gM;y7hx$Rnf*rqfKCxi>W^y0h-@y zW@bmq6iE{3FKpMj&-Ob@WzKWAuGpKuGIkj^w*hKBbb*Y3OrzMpS|+^oDk8IeYGdvLk_d8OLcH8J7TaY~I~qHZe!g%ZhUsLdY9#$?AjN1*sYOWta~7Nixz?0H;pGs z?K<@KwDc{`B@%me)G71ho{;L}5al+dNXAuc9Jw8)Fyj<>*O`w2PINx@(qu=UkjoQZ zH$bl1YLaE>)@i#DyoD8v-Xyhfc`^(4J+cKMS|E~Pie$m^jCx*nQEjuHmAvaO*))EC zAhwbV*A+yO%Lr8EUYIu-8Ni)V;o;hZUH0c2Xb#Fh8#3dcegNhJq>EiW27&HIIFa~$ zv0`wv+Z5K;PEqW44&_@9U)su1M@XIGkGfAwy)+nAd22JZ-ced=CsU!z?``jvaGe+A zopo6#95;lnzvd7`vB_eA)Qpl%Sh9UL^QnOK=|9lX+I3jq2{AuLM>p`J531)p%M9`I zxojhE|9FUK#{5CgH0Vsko(oA6nfK(;_9+qtPJf*J)8*U>YggYoT9C1}1a$O(MCiOO z^#o7_nQ8~>cfZ)1vy3i}0M@F}5Oa$^Y)dr(xautL9*sVs*3p?!C)CvNpmJz|-k*0= zyo6AMUR1vC<_-*zYZL_te0(=UMm}&~Q0^U)nL*ee@&o*T)>^?#nM8H2fY)smCDNK? z&CZA^L2jiJvJY?VpJEK?BO7_3M<~-(fcY)mMEQmI+7lhEG$-G0&3Aq>EGY_nFnR`X zxR?SB8&ifq!BFyG$9;A7YAaFRuH{rxzYrl+hEh>0rO zua1a5QA=|j(a~ctMAbo$g%O1c2R$-=_DeT;8d zoktdVV;+~9TX&g$xN91_usqPW=4s@kYiDI}hLHgqO*_f%6HuJLPgITz=y*THif7De z6@#TIc*{!%^RkKlmh#TZHNo&(pow1fb`;Cn9Fsb!%PfNryN4)>c;{7WoA3c1!wZ+Q zD*(AUo!s5YQP=7=j@%#%2#a-e+DnoviF@fv;^i=>91jTnMmMc-AdT6LR63C2Ae0dJ z2x8$)0uRQa4fTdkuoMfDUrlSe07`<%vwh{>i=$}NKOLc!7bnyDm^fEG6|_1=DKJ|b z8NkZ`^C3`CAWOWX?b>7E{*K}B{0J~+6H}6Ux}yNpDi`!8X#W-Dxv9~r-iC>6!k0A& zF4!}-g#RrJ1GEGY(o$hx*5W!-`tZ_~aVQO1nq^X#hB)PjAvDByjr>Qt`y8X$1fj%D znU0znyOEYdKZTHZ(N7FL!;Kl!bNh5xP$ANRB7g>uD!Zn*li3emgy zhUJIw0lUE64;C9L2IM#V)Iw)dYX7Z^!ol8QQtdJ?R$IHAUK1yzY;;<-qL+(~WV`!_~*>o3jQw0sQ&rX2{< z>8OB~jCNfeR^wZLV4NB_6?wGQvkOdSc@EZMtg>MC3BI?=s-c#r!@-F`_&jCw$$d$# z>|m!&Qrog{Cxd3@gAvU-MdhU{nGiZ30|dBLSOJr^VqV=^_oZ#?3l{|&?GjA~tWB#% zc~Jw#qUiX&`NJR?7Xah71izeay4G}!Z-GY51dv0-W@^TMqmkQ_0K_i>D53DVpeJ9| z+&Pjr6}-W^JUQC&MzS5U`e3PgWsOx0%NW?xjg8Yd)6%A;@-rmsMhqF zOIH|B25o5;j7q%IlOWh{D^;QE`cTZh-(svQyoQ$lir#nBkq9a#>imhiBU8V6U9id`1I(!4!JuAmGi08_NZOg1x zCtVqJVxMvyFxS4E74;5Q(e-V5^iA}>Y)4HFhWOA^FkUi$uF4aA<>hBVwBU}=5^tIf zu0XmTJS&{E>MEc|o-q{HtF9<|RKw#a&AD_VZRU9oG4yJE&gQStd7n{8)0-7p%dQ@3}uG{L0hrbm2(JeHL|vruxg zEi8_al}sE<;1RqUH|^S$i09}a(yPoW6PUpoE(UAt4B%B>W?lcAwrc6%<(-0ivC ztqhe=UQx`mV7XQj)tpRotqvau;_0zzv<2z^Q8B#VI;N+LlV=%q1ZPu7|J7dM;B6h~ z8UeG;=Nv#ahm3ig1tk~6wlMkx4;k^qQkG5w_W#oFq!kQP zrtk^bD~SClrP^kJBMpCv6=WI;_KqzK3otOE_Zsd@W z53s@F5>3Mwmp>DR^{D%`h!2|snXkI{-yAY?)>{GDqy~-R+ zxyIT(O^zi1Ou8O#?`FvDb3bG|&+Kr6&{zx+TA^8k0ZQ+ilmc3Drc1gT;L*)gkFG^1 ze@dovLg<+o&9tWg)T+i1dQq7*(@<*-+J|jsf}o(M;rHuk zza(68W`7_9n=HG48$*+i7Z}N46 zw&$@K$?P!lBezcd2vTKHBfp&sgSo{jZD|U*Xk#mF--sp8^CQ!$b;)PJI8<|Bkj&0i zp9h3bP~!7@c?Vj;6w0M!!3A$_busj`T@^Bsrz;J_Ikg;jeBisKNMq!nhv5)s?3hXMCJ`S&Lf&E(?*i8*+^!4UPAjP+=> z8dXahfJ;%ODb_>bIIux*e$2L=F${%RNzIsx0#uNLo`OT5VAs*cJzGJ+J`2zcTnGf^ zn6-Zdlmsw&G}^>!z0Zw5ePL-`f{EP!^BYH3N)(`r(c)AXrzl^uS3&!)WUG4T8hw&V z9rPkT+};f~0g`3R8{g5kC0MoJiCVBWn<%WHb9*=Q8Om~IL7Q2LCV?XMg}b82*F#}; zQGhcsTtV|Pw%CS3jv9^K2-s3Io%&1qo?*4669^!X<*5pB9ni6KLnAMgQZ)he@CU4O z_xRokGr9k2WbyNhl)+fHRcia9CP55GV9|{HjFef16Et6df(l40l}37>?-mH7(R?s+ zn?qN6C_GL&%xIqhQ#l8TQ2h7>;Fy9@fTjYw%Ir=7=DPMWp6(CU7ztn`itZI?H6Vl` zk}L#nwHPZHGQmLa@b*G1!w@Z>i7RU2_jMw<pN@)-2Z`inr$Wr7Ixn;Gfyf>}2{BgyvUL^zwdrhxrURxm6nlVmpk+-|G}XDTjf7e$lG)lh{*5^c&F`L@z|rUWJ|!^H{YMaXaYq1UW~@$X$qYY69wjl z3@!@b0~L{ba%{44El9-A4nd6;4>`cOxsp_x<=`)-(iCc64YHF=7Gj#e3&e=2&R;^PWY9s!R)-QR)Y&+52wD);$U{K=<;0~Z)Uzwl? z$Hyr^k|4RxklVa8*a7JGbKv*f_U;T@X{+QphaMi<;>9dY-5=<12g883$ zF;MD79K$IPKsGzQH0Rp3cPH4+NqacIQhfuE3SqR|UWygy0Y@;D_QUpba$V{12=ez- z9vUAt2;8%?(libj^WAgvENi{;I=VJ`T$*m1Yr2A#$8m4H8gBZL6rmj_?Bw&(pP-N$ z{5f|8rz$ag=|+Lf6VS+bz!?FQ5gd$sIIh*g2%ilWnZbb8x?~DA8M3UN=w9PDc`=am z5C?LXGV0X67RNd6x2`1h2O}3b02qPsW)7%AG__lRnb!i|Y>G;k*ASB7MglHJ54iHU z7*E&lqNO*X)&Gz#KopJ}-67yL%z`r*%@(cC#5dYQH}O7W?5Yj zq&*(32ff*ZyeY`WUuGLsZdcmk90a4nd&|Cqf#E{bm$ul>{csH$tVdf-11ea9Y@qc3 zO*K*)$0xTtu&G!;BE5H_0dN4!eWSW`furypX?9>6M~$1ncKghrEUYt(^#%yYqFogg zXr7vlme=ukAfM}Z@dJ(k?%{8Am>B}jo&%w7vKeMQ!ekee!5)Bv< zjfhKBty@v!v#-}7T4fvED4665Ix|}j0=QT@Exr(a0xu7c0bLtHTT1UG2=omIufn=C zK*)wmXUm>Du#fu!Kt85Q5EOxe%23Lyww_NAo(^>9J+`f{Z%qQTNZRP`OpxmO^vA$% zn5G!(5g=pkij!k?V}XOkWBj9Huye~h5$=liu}AU!D6D=T5Y0PIIKuKy_;Z}u)FKhm zFf7xBfCHEWVRPJ92MpPDGy23jz|B30Ie9cwFX6g&d=j$6x# z9#r{5hnX`!JIr{dlP9gQ2m4Z#v*B&~M2wDyhK(=9s&pZWFzMF+A%jFVt{DAok znV(sMG!4itb|DQlhe@>Bc@|jzNKqUn7#ZfDT4DaXlJphYxNt2)UPJs)M z=#2v8r(`;ze~)cEyt-~)Q$Fv&HZa+-l+j{59qwsbfdu2}K#hSYwsV7H<>S}D@}TNO zZ-C{%RKjvp7|RlO)Q|}#gAo&;29gxA#SI`?@!)8nb=tGazDwpLEq4fGIfjBt?_q*~ zVjItYR16IO)P(au#{b7k(tw>NYr)}p9iOlN4r~Nyi}@J*)H}Q>dVB_<6@YhsaiAZd z8W#*;8hq!#NjFySaseNFr>7o`+s$3qgW^{j#u-(7{rDHE&nSs6+s1~sfIX%juWt!^ zhVs6tu9bRh6qJL#jgvPrmcN{QXcfz*S!<%`Y9N|AkXkJv6g^?Pks&dH29+ckO5_-X z^&2FqXFJk0U_h^2*dPEw2+XUDK4IQD`~eVBW+tyeyE3h%1`Q-yBrHdN!$TpFaOmw0 zGsC)d3RVL$07Q4O6;KKRiWtBkAQ+FqrP2Ls_N_lcPX+E9`MS6}XRB$lZf+{WHr_H# z?METefr4E-5)1D-uxD*ED7LM;D9!Fz0ijA7YvLw`r}*ls{gc6fbK`#7Ir*4avH_!! zi4tM!E}h&J!Y04phc01=0Nn|ZQna)jCBq6Pox11eF(bgR+(YYqE^#U~?TqKZ&WMtf zlT4tFPW=pO71x=>0=2aU-b7oWVSNIjqXPsNSV*nV0i#Je;V>h=1|y3T{zC0VYeLs1FHG+3w!Mjdin<1VQt7W-G1eDS={@r= zEX>Z?w(hrGRfgg=0HR|^WTEn_`PBC@nzk|9A45RAwu?Hz8h9W~0GYko6n4BJJ!UL~ zUS36|w4}$CRZ~qzwc}GA5DE~oTt_0!CQI$20M)2$`|WU{+!6w&w|v7dFyKS!ggp`Z z#BcMTrk@4s`}9LFSD~4~Dau!r*_HA@j!im`*wn)70fQB?kSoeUxm7eg{sqN6Qo4iB zDTeyDszLxGN2+t5kI2NWwj76f48+T`_12ub|DlyHPMS&(D_YtNjZi$*+z`Dsp+RVqcCnr5~?-_444eSPL@PBd_!S3;@#l88C18^^E=Bh8kuh32C|33j44io%E~UBC%RkwGQiy^AuC(1 z+nf771NSUig%_;v7Rw)koD4T~p08B8QULh=O-PAS0(EDqLPke*p4wSmsrHD`h5Rdp zc?_eW{21K;FcaAPf494Ue+u0ByL;v%x!&R3`AA;4*Wz_pp9i76Fq!c9cp9Bk{!{s3 z+uR*mk#8DZUtJfJVB5+v{P@g@gfvPEj>t=eyampJ6PIT7+30<@h!J`P+MFRlSw22OXIN#chpa-m zUuVeheO>9)r$(2YT8eL2AMct00Dpd1t`vnu*cHI_DG9c@N!=(uVnw^Fot&%|@Z!Tr z5D(Suz%z;#3g=8f9@W0Xp!P|OGjRY~)Ekh200EF9YMQNo^k#oWIX>>Lu<8y)2-@mU)D*P6KV5e|GZk&SJNa6c)VaHI1=m ziJRz!cPcS0m_<&fU>P=gu{x=h1qb1mP)h3hxHwd@b6HH%844_k^qg1!o;^BRF+v=ahO3 zBnsKn)*+mTH+2T&7Ch*xvA`-iL$m~M?tyVg)mWVvlB0i$C=3ZD)(=5qRAQBU4&)mX z`Q!r2UIDIte=PjK9^2gi0+isUSzZS&K^BRB;*LGq)Avnl*bzFRz+K_G#$6G;6DMj~ z?fMx;bKpnc@7)!qu}7m+txsceDi7qFf7<%>bQ&$^$s*OR#P5wjeF0kscVPF z-**2!>n!-*!mIPdWA*F&^BT1lwBCQlwD~0c`U9`|$^RbaBF_HZa~E9J;qRPg0TaQ0 zAOv2qe$)E-XYVe2w{_0r->{&Cx4ialYYY8t5@(x=cA6IY3$X~qet>aE_KYaP#ABawWef4M5*LG+$=H1Po*?f29 zJv;BO|GK{7n|rY@qsIgE#hJqO9qv=No>EIFU9;wIuKAxG?%6>uyrVRgtY32)wOX*~ zW1BA*y?2U;-bR1>Tf3h=wLZR!UUTZLPv5dW*+&0x{;?V5_UWScz?;v5&%87L7*BV4 z@6=oK|N8c~i|0QN-g4>>{||fb9o2O9^$QaqARyQ%qaaq4A~4EGkv0~_5d@_P5}FmI z1r10~0;njCI->$A5fr7Dpa`L*ASx;)h!A=bLEFgRAxR&!G^-WAF0V=}@Lyy9Sk-@P@a2c7FFyk;Z&?ce zd0>;}X}SN9g>+!8|17CB|30wFui#0^|9M%hQ0Z)zR{jfQ`RUT7|4&BOUlOu()yofY zSQ3qN+m^+@yhTd`Usd_fTeLzt@EfRf8-H$*{J#x6wxj?{+xC~t^0E;Bt^ofpqyMk= ze);>QfrtOg9{r!8dH+e}|F7!(kBa}lRrL&(75o1m)qD8gveGf8;=jz$@yP#ZhyN=} z_%{^%KM6$sWAgtOL;mG?{+r(G|6<7hcK6k?F3@X4o)_^4`WQ>h%z3QBUZ4ck*^@br zmk6urP7h=P&aGg#`EBIxn~l;Vaj!(7?#mG2OjezJ&XbF6f@;1d2$JVjtft@ffLaO@eqZ8PudwpH-M>KWIz{!N5IekpajXp* zQy_4=QX{xL_TcNE+;hgtY`vQ@o4ymisX}>U<#))DXA1=P9xAi(enYhFq)ki$Mt6$v zV!>zbeyt3uRIrCB&%3}Kt@fh#G{_Q%q2oCXD@2_}pRwt(L^H>vW+yhva82bQ9#ONy zBF!gAAHy!rEk%!|^~Gi&PoKekhtI!)t!i41FpcWON_FRV6-EHfL-ZVM!ten8;9-S%Ao)k-j z2eEtXCnnZo_mZPI2fR#`A;@=J);09RHxcJx|xy=ilitmJ*qz%~sYO%)oRPRFcZ zc>JQ5e+3pD(l2QK6y(=}%_BXHio0`@CC=jtp&0=7QYj1Xfi|Gzc&f8*UIw@ zXozgK?YJxLK7kqEB}WJn-DaJN=4Wfl^E7F5;TR4{pA;}-dzk~YK)h9U7YFBnF3Y*J z6h9=(99v6&N^+Oy{mI??)_`g zi;;1cUkldusj%gSa%eNG(0vf(Yr&kLGTQRVdz~r50|kg(f8xohcVpKUVWh+Lrd2b> zbbS)vnC_ochC{nU)n?BcMTngPVaXvIFkZtK9gn(xDIPWJT{wxv@upeqDO!VgA?Vlc z0H!MaDREde(3mu=N+)<-wLk~3@!x7|feL?7VXp(bKM~&<9b{X~^5l}^yi7^UOU^h+ zM&Plmr2S~(*Z6M}&|Z$vLEd`;eoF>sKeGD2AHVf&)1up-ERsoe?r=l<EnL1#@$bXj7)R!DbuD0zk=LpcyIQJlVt`B79qJI26>KdE-Op+dBu(%5{#W15Tz@e;Cc1^ZZnX)HyB{e{pYe7cpyU8F|gR?`Qr z$)Lh0f=~z{fnw$k5erLk3$_biDzlk!Sk1tm=KvOUO@OAv7?7re(CUF)v)mn|IJw{c zXEAJz3`+}Q_lol|O(x*iFSoYAw8&5%n-Z`BLdY*+?vYJMMOm0Bv;QfBFLL)jk+B~X zEq<63wds>YFw&+0zV#fihDb*^1co3HAFD)o(4+q_jEL3kr35-%rTHDF=?D99!t*~( zSYrgDrawiAJ3rHqVy>6-9C21^3M*+cSMYiSh)|9eubaimCG1R$rabq>-U9~yh}M6zs4T))C!AUb7UXZ&?w+%`4eO(u%>?#Fzk;HjUno#?_l9f`6eh zq%J@c`~-YCs-y%Se=fGBKa#FKKtW?ViODY4&L0Wv!(U4|Z;&`5QHh z{SwC&5yzKS61MGiUSkHh&iN_9wX1Go=xBGB7aS>;uH^7{mOYt#DNHUB_%xpG43`kp zK#%`$H^?@RWqeHFzfPXFn|4cg0snn~;B^Ed&Szab2mqYESBma0H0dgavciw)fJj&+ zFS{{gSsnG>wSh&XGf>|1p`P@6GOSQhpD%hy^RxST3F~vMOwKFLO;_237-r`o^eVV0 zZ#A8HO@`JliX8}r1+S)WgQ12*u~=F$(8b1Sa;mU(=*&>g-Ds5Eqds|2!l`wU7u9&i z2(=n7I!;@|(teeVe~OdgUu)g7p4L~--*KhQ4#IDV31#zM?Gi%wZxZW48BxM{x%vA9 zu8ld!vGOkR5xeQl>szN4}R6+*9e- zqXu@7Uo3Aaw0Q+SbhLMp&LH#Gf`r%E0HuiIfllZ=*}EEaZlt9Ao^-b|l4a_#hww6+ zo~W?n>rG*2e(3XcxhA&B1lq}-;r z`yg_x{d>!ZpY5Yq72e_-7%9(+j@twDayM13-5}zkZcM2{rqoND?~g`wTK|#ggdiI8 z1=XDaRuaL95g`^S$6IXGCLQBb=N_^gRxMKJ!)PVb9K6vAc26R_-g5<;gMeJIbybd_ znVE)b(g}cY+3jQYC9>@Lh~LFQM(gP8xesgUY(ywV=0|RdzD9O3I9;iSix?mbRz{9SJSiV_m#`@OeA;CA3<|qB;%~7Fa{dcH@_po z)RpM2jLA{decl+h$L7RMgW%w9`xN7xbFjoY1knxE6dMvN@CrwTKa!Ne(G<8$raUkE zlyV&bjfgFlsn1c`3sJKVSn?=WRoH(h zRg`oqvx{y@_v8)WN$=y*d7)m6C`pz5rWNcf+&mKvdWmS^%Vv^Abd;|W+s|*veGMH6 zxBxxFxuXn0stW6HOF|W>*Zj81=8qKE*_cuQd0oMaE2|SSj5)?_BC-ERz>kP+<8Xlx zo+uZ&nqC3fXG%(B)j27#XHH@PUn^r>0~+Q32ngGqoWca(Iqh#=z5fsMvXbQgf@EX?f!<1K_Mm9PF~DCIH1o!hQQhv7TE=14EgOn@OS! z4`UK)#4~Ton2v-oD<3&`Od&|$&Bp^u!a97GCV4PL%k^~HW1m|I=CE$uxoL|6;_MWy zXpR^sH(xoY+7Skqp|Rpm7?Kj<*3gS^Vx5Y`scqAGf0c0IM{b>2n9+Tf>j= zZMSSGP1fH7?Kc%FVm(?39Aut=RSo66J|dfNmZ`jj)VvnBim3ZBD!ms!N+}{{UXxw3 zwBwX4k{dWn_bg;BriXs+-b|?ckz7 zt>t&5f7=z_ z67Cld^k+LUj)`zVAqH}$76ant=2cG1MJ}q+%^`#)?rY$78MRa`D9?yskq;ofkeP>< z$zjG%T8VMtcIj*A8{N@<@J#RxszfH$0{veWGzs-KWKS!xmGWh{m8Y#B;+oa;FNasK z&&ffqumb*oWWXT>vc4!4@9^a8J&HQG{kS$+oPNdLb-VOxJb`;^xS{Ue^&nUTPG>)R z%@kE2^y|J|5b4ply@T_1RO3z1u;?W;xXDN5m^eEo;BN>j5#dzsy9C0Di`7T3&ArRi?P{@#vkDq7rZ9m z;Al&vIC@fHd{7%$ZM{PSBw?sjQ323}k`pCI23kP9CBEO5_@0goq*~ouxx#~f0-~1nbcpt~0Dzv4hgV`QK?B>_ZlOI%)O)* zgOMGmBv~nyU#!r3<8!TQB~E#_LzvsioMD>RYcH~3tjofbINC=u7nPAEcBfh;)o}D3 zxD0rRTrcMX!Rx&R+Rt<bXvet`3XAnWoOxPDDp;Xk>+B|-P2N3}`&0TSGM z3G5?$RNfLx{87sDR;ox)sqsV)#oqz(Ox21Ad+Q7>I&z^^iT!AZI5OFHrBk1j!yRxU z_KN1-4cP}6Qf067&t!Jv&@l7;T-kMF=$zFEQY{zVY`|vw(I3mh5RKnqjaF-PKe1UV zj+her<6X)n9E7ECWv2a{)r>PEabOgj@XQKFhJT?A3y7!0+?)T*5ov`4$Yk6pb-L-I zf9y*wy2^R{Z!02bXUN%{K~2CE8XSNNxF&9_7pu}Y13rG_mQ0AqSSbQ2&is+ZHvD5n$o=7gtnpG}-U`{DK>x3AMPQAD68qXC8PT$1eA|%QBTL0ez)#Prc@q_VsS2XpxOKh#D@1YUjUxS$Q#bgo9Y(F; zd-e?b^u--@Z7F(Zmqm2vm}<;ab>U2iO=VF1nyigA=4EMF@MNQ-NG%iBshl ze08SZlO>v{^Vx!w^16c|&clozP1+CB;lpL?AlA5i|7NpB;I)ZJsI(jGfgm+m^QwDi{ zKx3w@h;k+%$qhgS&_4pC;UOS^o7~V<;;sMT zIm^KJekWxosfnR$fSe*sN!AC@$L3^x<3QVRay3=9+I)Wjf+X58UTsA`{8op3|GoLR zITU1h_N&33J(tZKOEOlX02Mq{^u~CfuwC9ZzwjKTi<~dUNUHS-)qJ1XtQ^4<2i%$< zUX&N9&JmBLEz%Ab&k>tcJ48ZwtlVp)Tn$YoObImI4ymv&9zaK*$M0)^3~nU>r86K6 zGg8$9%ZNXD>qQXp#iYs9zXEylcm}FjLa3Et&}7BqlN&$sx-Y!Mpx=>quXnR`C2toIm*L9l0AgmZ{f4Y$OsZX^ zX+o-z)ysrL)`q7&`;?>yF=>N0V}8&+-%s5RI-^tCV4Tgyic;QU2EVd2v~}Cww{NQ!PP0 z*-85NgHyM^X0;3Y&4^80BxewdT$=F&1GVWflf@R%I)zxO%ti(ZX8!x#Sl~sb`?UdF zHj!`sD$$m&`Aq^_7sw3KUc#fzq>~Uee?MLP{Vby6OLU!|~QL1ro;9+Eak!mEi|F-k7DgCVNzH!Jeq zWUO43?tQ}WeJx+rq3qd2jsw%oSKKOj^%P&t>z^ZF&z(o2c6{T$Tda+?{hcWFXzkzO zv4TpDm{qe#8&dz)m*)IKED$w)qS%Etip z#C7i&U-dBSX^PCry;a%h$6yxK?n2CRT{xK_ibU2c^g zuRBd4^AOM2^d#~4KFqqW_kLka&VB{K=^XOa`OuZ;GlphddEhqs0FcH#iy*4Vexa66en9N(*lAUIh{9EVP=D6!2S6 z@^g8{Z@rqs4a%#o#T33RJAKqO>%;=X8%ddC><@;!B!qFwTCjV$*3KwDRuLQpsMxs$ z0nsZeDo+cr0cy;pSCD>A2O$$#cS>&l^P((!U1;TJ0L$~r-(6RbNq$?e{uGA83b1aL7|jN(kd0Gn)b7tU9A8?gBHAAI9+|Nyy~3y1Uu_=N}1j}xCY14tH{v3E4X;HvUlMTB@2`KNjuM?n~LGRcP8`8 zXj)mLIF`n-;x_VK9yK=zh2Y26v;1&8|0^TEqngQ*F+c-kZ3bm*!CYU;+Kj2vU;RjC zEQp{nC*hDx`IuH1=`!%&Pz;!>(;=eLzE%j+xnqQZMhrY%#+_(!ppuJq?a zSW`!6d)T#UMpDSy!Q9586{|dXo34c(*;sCH$w`!)OF4ck;g2umdK(o!=IY$@cQ}W{ zFJa`kk-52RWn@>BfVzdlJtbLSMXwdz9>`&}hNE_U@WMsaMd7SE*@GiWBNYw8WDZ%*Us~Umi8x743CC2^jtN zX?sb1&Piy_`17hQ0893H;F4X0&Ie*jq+lq9-U$m&w$ z4}zFTjtQk4^a(<_i>h$;&5N`_0nvDlxTxB3SsdN{A9mumhHe0dfC9lZToRJ?bVMhD zf9tY41KngkjvVIaouUFYGgU;Bnmv?T9%OyKY&*5ik z0|!Dc&M@Vy$~{kJ7zA5&^J8Dzw=9y8mYaNH-KV+{gg6TB1%d4O%?qB0?Bf2NYFJ6M z5~UC15cfTlOvTei=cdSK#!v!U9U#|--w9bC(-&zqV0R;UPoAE`Lw8D zYNFw?0Hgks0Ivt>IbzH3MLfcVLe^YL7`a*~CbhuBr@4*ahG{KJI%*U-+D~ z3&z&!Fp@c;5iVC#4RxfD*y31)%vdwxb=216KQz*=C6A1Z`@?_F3$I|fb3%^i1h@z( z(Qq5_@<`=guE02t7;Q0*1+&~h9N9b$4-+6-1jK^#3{;Eu(__EjA#t`pC%6Dgy2o~? zuzQ_5Kv8gT$M~;`I`TD9YQ5i6_9`}f5f%GCl%sw}UNc?d;{|Y8u5!X_n2x(Uh*jGS zzzs>bq^a0Ir{tz9)m2gJB_L=b`ma8EIb1i+gZukx8IYU}1vlvkgTxzHNkd2oH zm+V{wDQ?~TYb*K}p$_}|Tv*2`wU`=JzU)iYx>C|5O>crqLP?Ki0V#TA^?}q_P_x}M z`)M2QV8Mn^vO>rjWd7zR`-MFkSG|p1Qcjn>uM=nIE(DI+k@*PtliN8fh7*wygctMI zU%m5c=le_u#v3-heMG|u^IKPFK~V= zsRE39kECAkFV)GD!Jd)UV`_xD5m?gqc+zNC2S}o3$QEcn8>yGpvL1?T*k$i+B1{{> z55?aFB%fqI+tAP(8I_I4Hf$Ak{eI1Ty~+0okFUq~SIq|7;KgpHk%g`OE`D+bO^l}z3I?a*k75Kv(@0JqCl?8>BmG)0MPj&w zQZ4loY%$A)Bck;SS+6X9SA_VBgr-Z4%4Y+V*?TPZ*DK35jO&034p-rv>6!u!+(%qo3Bv$dC?C6Hs@!CMAl&TdlV3NI*;UN48+suEyKHJcemh4-i zr5}8|d!hEV-IqMG&16R#`=Z(4@7?_+?|R&5!wukuPE01Peh-4!%s>!}#Gj&3PJAPp z*!I|WR)hdSL<~z>X_6>>&8T#$SV3Q4nqKl>XHX2SxU5;yIkE;eX zb4CVPVSu~z#ENV)V!6?U#9ACGWFV(W2yP}ov4 z?gaabe+lxzpEJjAAvmFDY!3rvppegr%uL8vZH)Lj*XHz=N#G|{vQOej16vIASXp!9g5O5lQ2I$mPC1W(z-*@KfKAD3VYUK zKlZd*%qR14e|{&DVT$(B=7 z))_-PDenRqWqo#pre&g5Ob~Mqc01~`XfCr7_ACY52$zIdn*fqDz!P6K_YP0HGmu-Q zY+roVo5?Q1K*$2l0d<#8BYb3HF_LtC{ij75C;X=*VUX-s zN_9Xt<5z)*New|d2(@#ISyxj^YKl%WUD)^a#kb4E-JDO2C&ugKY3D;zDH}?0hwL{W z`ZN5Nni+`poHk}0C{6bcp1FT>17kiW)FCXtu)F7LPS2*odqGY6zzM83f`^u=K5?Ue zVF#y6gA!TmM86laA_fr7$W&Mk7Q^|qr-h$=P z2xlscbJ``Bm!(@KV;Z7Xv!GjXKgl263{MGn4`lk$$?;G^N6800KfmJY0|DRnj(U4} zWv$gYpUk;(!6_xRvXOi45YPI$a={+V1pE1c+}G+T+O6)9^?Q-In?D+JLJF+){ZlNcP%LE)T>mw`HQdZ2J$M|h4+RI|222c0RC{Q?IL_1V<1Nq37i~l zz+sbBcmpTv6BZ+wia%k`WyYPv615g}qZ>;Z96YPx>lmX>d}lzsi-9^QiMCgHAud1t zFJRDu#%x58rs2XSVb2;=df1SHpF14@!`>p&^v0Im%AsM`blc@x+B#-#2O2ki_hoN1 z8~O*9n+GC>UAR9A424hs-ci=H%IL{GH{p%7XJB`lJ&J+dW&35w}@)Bc!w0z!thPfuK|C-M{qJ*4evyHMou46S7Ge1$*p24FUnAc6%e~rwT8`BOD=5))lGDTa@NPajY9I%}l1x*7`YUn(y2nZpGoXOq z1+6|0F66UB}XX$xYggmv_{ZHsaFy==yKICscS0$FE%P5@o6J zRq?9b5o7Tkw-Lp3|52mj%VoOxg?@$AI6a?Ry$Ia3lvhuyWr zQQS3n52kx~aZo#3SNePy9Z`=G4<_jHBDhCyBy6hL-WX?MIkdWLuQyq7V5^QazVS#6 z(<2=F?os^yRqkf{zq`+-^$+Y7{>4Q6ZEZSZlUG-g-gA%o6n}2!HbNR%Ti6!N5n>me z!3~LT5~h1NHIdWcjk3f70bVKRVJWc+hiVQ*Q70DzmL0urgA8k0r-G_5#NPqhcErx~ z-O7_=N#qY;gBeL90#dA!3r&fF0Nq!kp%vMy2+pm5jf8%TFnoJZFT*DR>o$VXJyryF z?K0`k&GAdr{dRJFc3w>T^zQakhWP3QYW5nMCDYm?z?P*=TP$l~Y5i488_XgGwZ?t> zMWhOsD2T!m1<{iWj5f@V5P$NPigZ7l!&7wUcCcTmd&8yMh&xh|u+#F-2z#y4z25B# z^%gep6I&BXiU7&TQ!79;MJvU2x+UDzDkhqDTY9Cggc4lQaSrf}^h%sSICvbeCTc9R;sLNEGV@}X@+4gTbswFxg5T_P~xUCfrPfD)?>#v2=|?(kSiyu^|QgQK+;@uRuMu9+m2T>wdi?j50tvWi;=tl);h*IVKy#hFw7^ zBl+VVSHWa|-5L6^f-=1MEl%Z}vRlI86MvPZA>Kz9KN_LbW#wLZ`99%9Y7VD=@$X!1 z$L!h|HMq7u));SLFokbiO$$lq`KNmZ^rUn~BMUyT){kX@5ULJT^NW~8<+$nV;<0Lb zMM!vez*6mKShk@GHt;k>7JO)V(eEFHhCfntp((Z>0avF-?9=k?q@OteXm5b&AzsM( z^>_A#s$4q$bwJhFrQ4hNvi#W&_bw_{$PlS{29Ud^5JOehmRQ9lLXRe>DmJHqhBsO*MiLQCg7<;?gEGbms2cp>9arERytIo* z<*%j1432;lXEuL4nPc53@{Kr|GMd0Xezi%^Sgq^?kR#z%Pu{b&EorBBb;lGoyBm21 zrTL(Y#a0x?SM!6B62s^9&E1b0`u?UqTlmCH7`?){!ohodWL=vRzZeBCR$BaPVi4O! z>j+2@*HH&@iRH;+li3BBn8 z64Bk}qdyH0;{5mHaug}y|H-Kq2pUBJgErIC=%N2{v zvIK*f?P)gd2m5ZnDM`0*ggeJ$J-)`jYk*(isKT-Zu{4!?u{3`q+4vI{KXa16&7$#3 zfqSKDO0n)vH?55-UOpGv7p+BqEORVzUCc@4U5unBhrD6WMr|q*Hd*d$texth__B|u zjD$w)+hl`Tqg%{QKXBc6qup5d2e+>w_&t6WS|i5~TDfTS73;ScbM~h7qk|=_V|LuU z%B|!FHX%)jm^LBiQze*U>w;QUwB<;Ng$=Bdfaj|*5)lL0bF*0lE&#jhW#sbCT3Yuw zs|$zf`Bl=gbY!&;H0*z3prf6VIJ?;Kb*N|$I+y&d(G!GN8g=J%do#cW@1iM{hp-n@ zoIe)JdNk7d+t$ zPK!3jNPPd8lMWZwWowLbBf(XqbyHS5iIjL^6%d<6s-5lV5KU9m4VO%JE(9&RQzTvn zo+jH88@O|2ZCOW=JSv852U?^q?XX;$BWRWINwE(JP0QFCTEup60CVFhZ~0^YP2%L< zBOxzOj1)G%x_-|luROm{wfLR=7d~bs`7^up8seAsJe!gkp?@|e42UljOYwI~7#SdB z@O|b8b9bFH} z(=}$7&TXxGHovICa8rRF_cz98EPN_!-=9!s1!_*fRTT-dGty~n3YNYp1`{V8Jc$f8>z4ZV2@QqwZd=c}2f{QyF8ct<%h3Cxd>)kR$xR zm?g{z6ISK*Q2cF2va|s8$nv7OrwgZ7N>hFzcy0*;SrDG+e@$F|QDC;5maz{&kJ9p4 z)lz+GjtyM2i#U>;Y6i%5Ab!g}Y-5n}8oQlqhHG~3^E?H+p1M!x8gHwqgHM|2Os@L7 zn8Nob{IZLT9y>9$9KsIVUR=o_?_U&tsMKuFvCAB8xISk@etlv|Om+VE(pXk=g!}FM z>{IQ6>(1oaC$zy{+mq&=Z^@( z#)a$ScjIk8!*Z(>atsdD^nl#JC?>-B`g64a{kMM_Ui$lV*}H>Q85$ZVdouMWWYQDW zO3m)u2Wahll{FE51f&nGF)ZhIJ&)(Ay1<*?br^}9d#$O4Z-c@%?4qr#cCc(;k?9em-;|*iK=0PqpSk9k{`!}K%NVV1 zMNtM0VS&bsxia!?J1~~MwS>0NJ&~2g4f}^Ce9sULVkrTA zP28J5RMmV^wxLA1;lnQWR@k!vz20mkwGESmH>!-}yXLJ5s7_|fdZ>n-^|mIr)aR=Q zfQovD%pAYtZcFHR@U19a`8S8K6UHNE;ZHWkR?jk6!rDonI%{<*f|0n{6ew!;KR4j9 z6z+H+6_-i7KPED@n6v%^SrD4&&zfX)a+ZC@Ds5n>Aja_~ ztQ#zDjB}qqe)Sl(I3j@I5ou}oQt#cX7aLkOC|@ojbojbHH3*&yZVl?Y*YEp%E^n{b z3B!7ZYI{{#1EW=N@JM`&yc>dEUVVl1`t~9_;;`?k^k{t`bf2$Aj08XEO!tHljceQ{pnQvN zea{#iWEsv!x50nX9TqfZuk<*a5xchx=$Z>7$z6%Ul5bJ{O!18@Mrblc~o zGT5``u`SQgdg=jED2I*h%$~oua;TobjD5NY zVCVGh#n1wul9DTguO}Y_dF0R{%15k@NyQ&ERrS`Q5UU z*8EU6od=)IFuVgd685whXTcL!t2cZ?8aY zywO;I@eV4ERLGmS-pSa9i7so%n9uKrY0`F2Xn%_?=4X7vMNQ*4ZM5%MIm=gy_@bjv zCc$tAT4L!hvz{?o@}NsRZ~gEykkhj18h*Aq^;KT4+la?qL|Vh2M}~3>ow4VT3!K^w z+17#t$3E4)>eOem`JE+IIP;PEP|n77;hjF7Zu)0A$V`&eS89kkfhe+p?^pj26y5=Oc#KvvmfaicXCzQ zynCbz$Xqi|4i7d&bPPAFX5BbREPR*o3oNcwqt6hQVUTvuEhOD8D9_A*TyFCP%zC)$ zftM2&Gu18a4(YtkxW}(1%z@szGc`kmj^;y7)HNSe?M7V_(0aE;GSJY!4Dd4fX_kiLh8<^gN5J96vd@X8F6@&E=VSSflt2KCeQQuqUX4zVL8@#SM512JVswGq=TkVC5o+ z+PObcF1B$H>Yvc?CyLoy8>?#Rj}=xiQszJjdw7*W-e+m!%>A_n)vqnVQPj=MPq+3s zxW>Nh-fM%%GczQ=vKh%>kEL^)<_M=R!cQiAv7)`4C}AXmu-0%43F^bkI;{u})L_aw zS~BQQ8(ntJUmxGSVbJi+UXALpYh|^koNiR9I~ki4T`Ib>GPKw~b*CuWwd;KM14;Qy zhEvY5*eeJIOd0MHn=)U00e*{j$29=|-Rc8&vNmfQF{I~5Zbkv*->xW8)upaCb8n5q z)seqIlTz$@@zcz#hSg4bE_u9d*EJJgZ~d_IoI`DuW3hv4d|5swsq;~=)&1F(EtO$U zL>@86bmmtXfJ{uk8Nq5M%#${l&q&-wEX!OTWQ7*}3KZ}!T_b7KkylIa%mPmCb@rNS z4{!LLYV$usK#ttk?X=ThRXQ!748C;TO9rFhGZO7e%?iOQh>wO0b%RLA%L!ihIkpfV z_a0Y0-1nH%1`gYY#)tny%itm{ynl#H8wsJVQ?~I;PEl}r@}UjdV*EJ+z)eaE@MsZP zD+>-_3};gJ_&mrw<5#pDM>!1Q2MVw9_&%6%kbCyI*!PIUr`tj5rtKCyydBiI1~Y;} zs1_gKk6>S#=J$)*w%BdSM#*f%_>c&-Q_Jaidi1DRc?v-g(6S)_O}lz3&>cTf!aCK_^Wyi zVVzk$)J_ciA|=|DW*ACd$+%`&@HXR@ zmd?jrh9A`(ZkKePtZY9&Wdq(DjjRm%klmS!Kl9eBg!RyvY&=J>THIJU6MOI{e>rSI z3c<_c4B3WyHTjKu*OZsAw;T+-z7L~yy6EjeW0RYgie6Y&Wt=cd>%Y5qH1w!d3SVax zc~Qw>*w_eO*Jf3K-#b%Q#Ht&O&KyG)_#&6pJ$_uaVP=lxz8#zcyQ=}10PL){%B8He z1E)hjzVzIin5!S0(B1wd>O=@*pwrJO2A1aqkJ2?Foau`0o2|cv_|blDLaH}g1vJ2E zL&M57;jX6)nu^pmeHwT6IPG++<#fWE70%&htB!X;ii;R$g^#)zJ~;wk)Zez-r*^Q` zm*HDhgHmCSDN+0RPcy#)@fYaD{3VZdOMxA#c>!uVJ(1qZmz>j#cej6kSzfopUA^i; zdVApXAf>&2dey7w2M=)D0V}D#!K&-V`5`SPW`DqWiWdEL2L0uR&^Cq4u@ol|p8;N- zr^dM2d++Nr%}s_kI<8dixNBhSp&oTSc;eBc%YSgJHf8e@$baJ<7BKhbGhX+srGZ@z zqW~8;{pyG2fZ}BP`EiHsU?+^{K#zQRQN*p4j0ctl?~G5|R9!yp;HvoSL{xdHS?Cjv z531q?E+0rg?9m+PQx|OfH`3JgB&Zw}MAoo0}kxuOIVUr#lA>l=3uaJs`M)mSgQ`|IwsK_9F1+`<&!TbQCEM(>2u z36?%*!%*h?V3zvK#u9?y=ntLrMfaFCx}Q%exKW|kbS4rs^I|mbx{f#)?sQX+`a7hX zVG>O(qjq$%L;vnmXM! zNb~Wl!VC@8!l$(Lri^dGFM>Cs5b{paYTp8(0Mmn43koBgZ#cO%9JR{V55{+2&UdmsbrfE7k+tV-^cv34xgUA}7H^#y z=(I-jGu;3v`jYf&cDy_DttRh8*-7=PO(CBVJ(sHs=2w<*y={y0aNTbKbcrU#_@8SZ zhQ{2^q<6PMP2I0L0m8%f-U4Q9+`ZKmz?D~jhR+|XD&m~VS5+;%1ahB`rP-o>>L56@ z|K2xQtDAmeO}OXqJz!xmYYhC;O@O5)VvsT`8 zpEhVPce>X6VR@m-(uGzQk52aRn|qOGIj?;sFpmU_Ly0|6KgR?0_Q$4;Uw(@z1=mbi z?rb^}RpXG>{NYkanNz9$#OCfj?dL-_J?sy%JpC)Dgam)354EiwgLmo{HaO8&ops ze217mL*FmM_g0%8yyaEa3bqs*mBY;Ncc1Wd7tkW7`~>f!Elhq67YU)}IkCSQ+IU`v zrGrf=xpyWlcOm@t_w`lc$_uCx4q3H+etPVO9le3Zn3<6Ds=N=Sz&vU^uSYxGFi7if z*zmJ@o$g#~>IrK9yTnfAl**iggxqJx`(q zUzg#~iljwXtyzKdyAF$tIq7KQdAGUim%RYwtEyTn@x|gV{SqI+casI7D!=xy^o}|c zl6C?l{PUf2#q6z)4K5B~TN2~yO@^N2;&)z#EVn)YNjhl_U())z+pxiLJ=GZe(!??D zRciTxxaNy2N$*uEA<3R4eHvKST|YF;^KAN_23Xor*RGstCA{CY`RotS<(@(C3q-%G z1%7GGpV;}}ys4|8GJhfOr3l`{=PF1r+m;)c6E8z_pX+Dkzg2gbB0uiWtohL#S0l4& zyoEh~Yv$F9U!3#xyRLlpd5sE-fK#{G4=fMQL;IospDpj=ndK9>;_afNa7$-!e{_qR zQXV}S7|1IZOi)q=|HRlE~$#1y#iQY=eiX_eGCj1(6NTVBf)k;tv<1DH^ckQ z-5=B9mI2MkE>-w--|qKJS4a?o;wo4KW*zX5#A1*+fg<9N)mj`6nSf)*i!?xnLL&8v z1CXT>EaF*+fAGAn%6{|9Ik06b2Qi~EZ=N?rWP^sd#T8Kt{1 zUp>xVf7BJk&2Y3u*d*Mar3T$^6i|6P{w!)~%SJNImYTijJoJ-m{M_-jTG>ZBm(#PX z6XiX%dnMgYnMz6UzL+LeOB9?^l;<1=AD4g8J*UidrUm>WLTnFrDc*6gK2ctD8fE>u z1~K+xVHs+-D4kMQZd4ST?SjP^H3-$cyqL141~KcUS3EUl6p_82*Ce_zM zVD%v-`!^|gM+Q;mesuxe-o8GC?sfpHbL{W-xo{j<{`$)52%H=3 zE;1k9=&$Dk&Uh^~dTt1JvvYQ7mk$<{)u%ZslI({i6~OGHPr0PY?>Dgr&^<#Q98kN= z=$P8P2C$EE)KwKg>h;PDrKSPUV~*&+ej!4~N(PPld`R01B|F{T#}`lcW2 zy<&}rrJiVBsD0xJrB(JGsSetC6ATTUG6>UYpYqAz#w{nzUB?-cq_`^U<13FIXUlw^ zB$$44eYQ6U_G&0Z4f!BntV=P(&(R~w9m80K0IJ1*3xnVfP~xrtcac~ZVuL>TnpjxU zacA$>$ZEtJuOAE=Ik;XgSOPHnhG3h$G|zz;ceZwWx^;k#ssyQjQFuK#->(5+obYK) zNLN0(aw@T7Spi7xfMxS&!Um?Nd}iu!hX1 z76!)A(3NJq&bG+CaQv!_|D)Z{jv)03h1cOI^maq*_Zg0PWI65h+k;S=f6-b`8jy>p zy12#)XY(9qXDdb|{LqaBD_G!pptKb?T1bpa?emM3BF( z-;A?x?!%Lwi_pc|LQTNo9~!p`Sp8{Il}30uH6uCE3+E0{)!14A@%q-S4%Hx-gEY_z z5Zu_`g8Zv^>^PdysM+6J9eH3`2|&U)InCG}zB~1@__T4NJBw47BP1OZ?O(&AsnU$L zqz@g`B>-1Bg;1OgTOHT3GQa}?S*_mr@<0LzaS}WOV=0prw!-+k5A>QJZqp)xyL!Pb zO#5W`Sb$Vrg9x84n0tj!aPnQo=g*&CWwjmta@12G4f2RztDuJ^7k8290o?y#lAYBz z@KksN#`nw79S|CO=KOgKf-C*RW}KPLIW*u5$b-4l z)Fc3UJf+7EdU4FTq&VrM1pGz|z*JdsMJoaGWY{aeCdPdgmbU9Iju4=a6o|(`Ch5`+ z=A5^MAwcxak+WATDO(e>L4rL`FP0K{DmaW;gU(*xFb9UdYJ z3|NAmbZqhi4Bxm#b)zLDrn43BzQQS_P1&+6_b~oUdpX3i(fDT=8L$?l=!OQoq=|^> zVRgiB%7MAx6i{G{)tW1yE-J0?pL_4B6F`|##6Q6b;6fe=pv>p=Yng|9tSGenzVVOE zzfXY?JS=$^rsuedIj$&&wE|t|XwHw_aVjUl+``k3_j>+u!yB{&@a+ocPjv{;Aj3ij z#Et=Ati17Mj}ypLVK)XEvDK`#?Gy~X$&auhj;70)vdn~{$d;9;svdDEi z>+gyS13Af4Un%0F8jywl=`R)q=EP1 z^5cz*;Q;TlFsPKxjfU8f0)8H0gLAA;6}RoSFoAGEtgL>9gR?q&RbiPaQ#ll+vC|~UZ{92Bqwz-Gw)dLtB*-TnG+Y!y+Rtv~ z^C$Izy8fIQm+szsL%M_z0GHaTn0+b|y?0t-l!4Jt9IUDPd#+4lX{_ds_H)oyQ3CKz zUjT&_2?ceD<#m2bvP`i*1~As`53vLYbDX{KuO@X3>6_qhZz)ul4M{lkuO~1#(3pP_ z=vn9ZB}(~yXJGYH)tz7M`VXFsnB-HvO{MF4?Hq$H=4k>w6C7QqfANFvM+8%R*7oBu z=NTCZ52a1MsjRR(%`X(^Z0G}Nbq;5C&fT(I`ec#yOS7rJ#{2yVM8Oh{pB0`K-~{2T zsF$bl4ZkK?h^$*NN6`%!x@7LxJMX$;hCq#;Y5!J(-QK2GiDPmzSk^)oAj*Of*Ur@8 zREe&9&N@^<&&0D7%FYeu>H%5>*r?-SZ@{v$Wj0g|K9VOu(UqlyKn=9Msc{Z%`~H2~ z8`PD2T-^9;3*enVp{8~7-G`PG)HM;^SfVIZ(6w|oH!>q7tj3i<0Imvi??`wA}ORAV5_j8%}7uLfG3YT07y(fnunB9_-znVXy4M|Ui_*%{iY<;XaRLq#la-8UOHMK5||7QP|)6M^X-uG_}!&xD| z;Jw`=8RP|Y@uQwUj0%|) zQ2=V;(61SoapGehm3RV=k&}}%m)?0FP^Aa&@Tzb%dJN_IqC337~mRm%Ux&fm>&?-9Ir6oF5xn zofe+H>uF__`Y=2f@-W2^gWO*Gu1(X1e!2N37kit5W>xuj25p(narEemSJGB0y@Ec} zFNQRSD+jNC5)vzi75?L>bu_&e?61S+<08ZSkc+LSTLGpq3u$iW)6US-T=B_TZeB@e z%PfU+u@@NVS}}1TtZ|_fV8LxPkJX~n&3^+{aI?ECcy7rv)a=$l>7j%+eKDQMjM%gR z4?>iU>BMT?r>jP1)Mzd-sx+6f_dm{)QmK9mmytT?P^TT$Nak}}te%Orb9dAYskgzC zP%Z{))5VikW3snni)E9w3HP5b^-I}Dx=frPwlt!XRLb`?cLKBa$NKPxkoH^hpB`}j z&f>y_ZW$+!cFIF%EFtkx#~SD`tJA@zZQe3ygZlNo^|GqUarcF%V_UysLW;;ibp&J+ zp%&SPozs276b8cnL#!C?8YB|61Nj8#Gc(si5heu&TFS$*&8M? z9k3x0EF`oP0?tN#-4lpW=wfeX4;VF<`(Oyl&cb$lsh*JuW9V?_?LU%K%{-1{u3dy+X#O>L#9{gB11FmwY@`wsTrPWpRW?=CHtJkn_U#<90;o^ zd1ZdMvBt&mDet~H&2hk+- zQkVsBot`qR!I}Jp^}IvNbN!6WIwR+3Q*_z#4(0s$YO}WF;m>-43JLpcXUY~-DMrWQ z-SubU$e^TO*kn3cT^u;;IYn_i?7|;}+5gj|O|Qp~@nfzWCOpfG7|C7c?ZR3wmu74J%<-oPSOpxul}U*)I7cKUrrwjRcKyN;BSTI<)-LR{?~Jgqci~{X|+_t02bd zu#gpjyM-;8J%uJEPE?g@@&nFp%UI@fM{F}l?$hk&Wb|RWDjp6Cbq(BCt~Ti-a*ZmR zBA+9gB5R`cfMScQrHQ- zTc_zX)FIR<`L#ramx`rKr>d5z$ygr*&RGFZ9O;sg-A~7)`sxRny*!cdt^Ki*6AUW~ z{@*6}zheo1RHGdthz1|5RTgG0nm*WY~bkxNkv$!BLaRWqQI(-E9I0$0DfVX#s= zANo5u*w3RRm*OPh>>y-ID&TdnM+@FrW0jOihoI8d!ghK6Tl^2NiH^j&)q&Z~N%XU6 zcbYJnG_1VziS3mklJ9!(nk!WUUrykfPdWtt5#CO^S0bJFT>uj!5&p#rR>M%sgQ#J~@u$O?#p$=h zEf-v9qspc?U3^jnmBqX9~%1l^%;a20)^H;F9!Xz@1yeDhFX#Zle|CL$z z){L2#-vw_Oxk(Luh*6)42!K9!?q=AUw3E{{sVDh=I(u5Ct)b4HlQ+XN_EJd&`I>=$ zUdf(WOx(PVj|#}3mUC3fO|P^EK&fo`?i~Q_fUbP>Xz(I&$A;7n|HxGY0g)V<3B?kx zZ`CP*Z^BBIdtY1{y*zwf@QHT0p_Y|F8!G3jM41r~Q0j>zv|F7|s|o4t*CHcE*l>a~ z9L={K!_7ZjUuSzB=N)lU&ZTjwE9){uUthVrynMBfZ1$mEPe1&9Mn=W{-DGFV?o-vZ z;M4$ySLXFR{$)k6&6|?<)nsbKM4-h-;Be}NJokpOzukqR2wnisBG z8C2{{w1fA6lcnd|8*-9+Nx2?QlU;>^M!VK18d2p0rGzwn;>7AshecK3!qC>X6>)FD zZn@keu$Nugh3q4fM!WC!37nPF`jb0sVW)()tDv=n#ct{!J-YonR?XD3FolLXKOl%K z=WICj3RANF4AF5r-oN}pNv$ecH~%~f)YR&CAxDqu`p>++xZZWymqEAp8mtZWK>1kv zzxE$%15S7G{dqn>)taM0h)r-BXlkx#5bxD!6pEC2&5NTX8R0L8>4Y-7`?yRJZ;{q# zy-9dQ!Zu;{gGZMno6M!V3mnq0I@zWIu|nlsAcyN5##zlPv?%hUw+kTv$Q1aL*5Em+ zY!j$MHP>@!|vzhU?pc-oN~@hTZA5E-9dK>y_#1&IuQl-*ZL*$!a^ciB6TRh&f*Kow z?5cmb#(3T>&LmLxk_L5p!gspW{f6u|Dlz2)k1T4YK)t1$4Kh;t^RA8k^XFU?3J@ub zoWaWImS0Bu3tIw!cggO2O-+ib4XScSxf~Y1c@Jfaclh8|FL$su=NS0e7ORyhV`BmD z4{P`SMklQ|*nhd{Fj&Y4s;N8o53iEYJ906F&~T@-Jh4?dxe`O!QL2_PP*1&*ee13K z3j_l3QMyficaj4HtUvC%bb}4ALU|yYf$1|Kb>+u-4;Uc}Pw%+96i-pxzDNP_+T#2P zwmFt@Ib^&MjVjxcD0`>;UoePr8WBKDl2G6dRh`SOWVpn02nQO;+A$nXsp$Luj(3E%K>!?{GDzC=6Mc3}2P)?K#*Rr;P z%;W&EcMvLj;HiEd2y0{ze9W3uE+ea3kTI@7>n%zy69n_%Al?T|hwB&*QZk+ZK$3MkhmUV3z26|1JBbbXDSvvnylHaA2Bdy0KI>~*9pTNO$MIHG)||oj zu%_y#G|HXCZKeb$$jPk?2#Kt@X2vaq#UWw0JSZwQ;i;R#sjOM3y}dm;x`oNq!)mPm zQThGH6BaG()KE+iS=vaoprD|PNK}>EJsf8DW@|an zT60kEW6Yo9r0OtLZ+)ir>Qv1JIQjy_m^j&#om&5@u!M9T?5`Q1Kj$DaE{28mYDPtCbn#iQ>E3``+Wh?YIM)u^W& zRsORHu6va`lRxTr{kF-8iA8K{YreBRr&I9w8G^N0+l>|- z)IcTS223NDj>gP)3W|!dn#W9c@b-#YWw?ZOK$xUqtyW!iwUX~npgvkC_g#RjrUkh) zw~?#_6qlge+HW#*ZrO8gHFC+UPmx|kbloY}j@a?_$xeUd=V+>`-xgL%>|BW$;eIHq zX%G>Z-F>DyQQl_4Wcf1w@p+-4{%Z*VYW20Ca;Kf&m(!bR>?a=@07GmENZCR|sQb)K z2ZFf}yXjNgmSz{EN66hWVeVIDekm2cDeGg~20b sfQ%r}YgvxWvm+eFz#tBM+qGKte)kP(VsTkVYB->5h{I$&)(b z?*8}te?I$m_U*p6?>n=z`(|c0(Lhgwgph#{0059^X{s7wXyktv{$otuuV_C80ARU< zm{|C$I{P`kb@TCe^Y#J&!1>S*4etF)#Br}-#!RCO+G}xMHrgs9?>nQ9jXl%z!w-Z> zBJN4!q@E|ECgLXVxDed+$l*U{JyKIR!>Xz{F$!Q!q&P^8Vk z9)>U-x%y?QEO9@ySa)ZV)F}@Vs|Q@TJWHR;R-36MaDL2>NiRl)CAdRTe9IS2*}q#F zvVUJUWRpI7=HxUo@?K132%nzQ3HRB!RU}mt4clzsWteDa%MVh4c>`NvqF zfnNZgDelHKi$vS4O-|^79 zqO-|ya0U{J0kFT1OeYu7D%OxtX^f4E^ek8WN7UoPHMT^sd{pz? zp(4=ntm{*|saPF!aNQ$+rK92OBbO=HP>0rE9`?xT6|ukvqqLX?iyqOwjCTg_V*m<| zt$QOQ@vo3&6`>(6?V%yKOMM6ClJm3ScdPr0`!{lv-bH>~YKC-~)#eo4u8)Rxl0T?+ z0N9C4(e(%_z70Gg_W1K85wA``75IG?V!MYyZA4|>)7cs1_e0poiMkj^;gDtfV-Jk= znoWcIUEB?L<~bPB6Bo3J-@ZAkP=dHeT0J4}gNNMmpb+%~t5`&1P0;S$!Nhy-^hF zo1id#ba``=>38pL)&=LdWoB-k$R8bR-Ow5Kuztk{(K?rrsgVtnjwu4BrKYClS}1Iq zg(L9*x>^@L?!Bxuds*+(!PTNb#5@ck1rV2~XS%rw_d>v{wB#H8Ng<;zoLyD0qu~6{ zGbwYA^L}yaxXfmLqKXxJsWPH+h2f?RB_;chX71-neq+N%R#sM1ON)Jdo4|w7V)Wyg z!bFw?8Bu*(YE6wGjg23(@r-=U?Z&L0==1U4W$5um$I%-WBs&J_%T_So^78V31alX5 zHqB}i_)t?9=w<0Ar*<(cR`#@jK6W;*TeP55FwuHpP1(gfl!~VY7vYbREElvLJ(Oc{ z+DE_v$GCbhI2+&g@P(T`*?CJXcHMczJ?;5Dvb?-p^rhA4?`Us#L_Sm8g;!Lx_tuSE zWOT-d4{GM-v?o!pZvp)tH8w$V+v%gfekCQw8dPnvhQuxw!3I5HmOpW`=~Kyd8k?F9 zkB@iy$u=C1&TQyL0?rwfygHj06g zXbL`R^YLSIetiz09@LYZkwH**4kZb7J&+^N-89duK$uNZbZ1I^9Sa!=GJN-Ng>B69g=0N$Fy&Rnp~Bqoc)tH!Bh{COW8(d|R8{4^_9zva zulo!9M*RHW_t)WU+qOtaK-6nUWDo3YiJD5qOrdqnBkkr!F7VOB31CV)YCzv+@jMEE zjDU>S6_cyH>e8FMJuKOdTYUMwJeJ)3>Hh23)XB5AP+KI_n-d*O3;R2r-+S|c`VDfO z$ahmA6g99ID#?2;Vtq&`;#8t|XTYZg%zpcCR(Y<(o??hsbTD)LHb~KB`+`+{S)}I4 zfzZEZICXb^Y=)y@p^)_Pa;7*Js7 zNCnz~4hDUysJ4PQ3q5rIYrmDw&T~a7UUGxIE)F-=h_QcJP|iZCWG?#9I0rmYL-);EP}&*u_nQ~RtXRM)$om!Gx|T#)MB zbv)rkt|w%o(j6qQW8crq@z?Fow+CUCYIE|fOfnXL5?QN}I*m$KlY@-hk%VH%;X8TG zuh5!dSU$a_mxN6Rh&e76%V#;GZB@h*T5O`PoL$YZ zGyN+5jcm!J=tK81Ih{{__yY17*wgFF z^_>kSgL?PyQ2CdA980~AH-7U7=6F)@;pJ>_0$(Q2wpQMFmR4rlmkV-_vl=I}E=lT2 zUK?v`#)?qu!;_P;)>e_fJ)T>5l-}iF1-Lp>Pu0rI8Tx!OhB-9)bM^iM>Kd6rzjCD5G$3f-3Hb@u7pnCr)ns+)IYTAaO#e6uJ98i{$mAJ01YnK%2yY{jNl9&zt_k?_vBawwibSP~a$ zOwttJ>Zi6sQ*}f~=Xlj$j*lNd*1(hWDYhaFV}_D%_>%m4O=3`sZ3k(fZrPvS$-rde z2N#@IdYuI*GlUNw9aa$&-^D*dOAwrr29FS{7I#V3(2tOpS5(IuB2XS*^x9~LFqH3{ zlUgBYdGIVNRD@fx@Z3krVB~KZq+_H|f8#+}SIQeRWV$~NX&$1ch8YX9M)O1OUr5>h zAaA<&-x?q=GB(zN@b1(ifpK-K0Tq`a5Gak zhQ-lTg!jXcxSrLFO)H2-ClL~YQes6TMaUTK(Lp~&h{MWJ({GC3&(Ei=EAv>vC%}o_ zG0H6uMWFW6_zla3{QLovZL8s_#9Sm~ibBlM_148J%(G{Oc-z{Ji>0LG(MzB-J;Dy(uAAH4qJR0+_6Ti!Mg@WekV4B!>`qsw zrUEKqZ#~1;I1Pi$1cATT>0k+~JGkvX#JVkm)(QH~#V96gI!%Y#)(TWQSPtoV_($Zedro0O`;Qm$IIOy=IA_n`{?n9(w5>zHt)6$6tlwcc zFAx1F>#2|$wKyrG`<#yc=cdArq&^>#ckck^6h)r&=v-9YRT@9mB^K0kwUr*kOEbp* z@8JQv#dFo`A>X1#a~e;g#e3D|p~gaR72#a6pv7?Lpg2?pVWz-HBR36xP+y!byyqx? zw@^UCEYW+{!K?Dm}jC&Ci{9+!ya-` zr&nnoSqjC(qp1bVV!}}-Mn-*guR2~{EVqDj!djR&gjhjedP0#x74Z;y1VRkCe&~%< z9-$t1Z9Rl(@Ian`@Y_@nZ&ne*mqDM=OE;LmN6Pe1OeWK7Dx3|&Nr{yC}k1V4uZTV3J9We_N?b*BxBt6K?=YZCafUYT&y zaC-rQaUhC_Z914z$<44;f2RR;1QiuIIipEsr*0VObm=Af){cSi)6|?Wxc|S)S5Da0}Qw-I3#O;_G;ke<942(=}*hQH1t>U+fxe zeh{*|Gf>;Ztw@TjJ#V;NBmsG@NB}Z2GiChtbS*5(Ik{9MicYxnY+Ep{2jda)Q%)cm zE;hzorjv_W8g=bM+knoe#AJ;3)G2}Tz4k;$f8gMe@$vGC3cMaz{R!$rp;yP& z5786py@Xav-?h%|T*?ivL0( zut;h}m(#?lo-Ks$Uzc&Z29zN}`YLU}HWf)BxZIn(*);LI(sJ3-KOm6a9)1dZ|KY<6 zbMx2utoso-%a)e@fw5a@L3t|zhG_6$HfcAN<8=D=k?;1anxi8wuSK2~D4K8)22BYk z^Z77F$Na!e!%ps(EnFXmYukNMMN6546OX7f;=4 z(6>)oOlNZPnSr!qqz{`H>*AUtDngeuGbVKA14m&5xNg0?p!9|ujcPhseej{Vff8$PR~B-cKv*mUHy(P)6e8i@kFP*-*X`hjiF{MQ#N1rQgD0dwbTE9$JMuKsfx&@$)&wc#Pz_;j6C(=_VW8=_IXRo-^v!p-Q9huSPsFN`Zzf9%NL&h^AJ0Vn`pR-sd4YnCo;|x;p4*BTxK>oi(_|YD+iFaXlW$a%#Wet| zZe+BikVAQgEpQ|w8LpCA#-SSI{oc~@qu)9O4?(5o?iN4` z*#Spx8J7zwlsx-fBMpVdcP!CLt4-eeU1HRtyO&Rj<+QX$dPm7RBm`rnmp@f>(>ZHE zz`KSGsET%ssSa3^bldJ;>YDSpids z(1+ww-czZCxas>pynY)eoheQg3vo+>1uBiW+v)eXP}A%Jl1eo(36v_`PLDU`2X=Gg z^T(y^D2tz&F&gKN;q3lC$l%S-o_{V>y8!>BgD;Ti|ITzwzO!?9axC;k1f}k34h-H)P6riu2)<5P_wwOKO`i?)zj_sRI&>qY5bdyIbwl^5dN6N z_6e~2^LJ{IshJgRwJ#kA3}=bzB^0_Fren?7%VVMMigK%eheehmxY+MZ-;pKsIrcd6 z;T9<2oA$6%)H_V#9dt!~>EvMvJr>i62HmXrHM71U3ys(L^$6dxvQ(vbj&BIu93f%b zI!I(mU5c$%Ma1((9b3(&wSP>dl3K-};wfejXS9k(j=VN-rcUt1zQkE};n9#KQZEd$< zQ>X$IqgzABhR?8K-b*Sj@2ZTF7g{tb3`^Rfl+36DNnUf;*W%!_S5KC2OhjW0emDi+ z$o(-Hrwzw$UULWd-1xQPDhjm6K_HhC4)|c&1GD5(dmapl^QmdmegCBgQSu`V48<**ptY$&H*^n(eWDz#OS1d!R^OvPWY zRSTL>M_+YRz|-Xm_=yDE$&z82G2~y%Q2HkETM%vhfG&V{A`SYE2Rx&WR%Lhk5AM~G zEiru5#L#+`jNRD<@K?H(^Hqz zwKfA%l3J37v_=msM7W0lhM$BG50>t4Q)7+JLGkBVvr|(HsUiXz2_ZVjuGrYME#13xQ4OXEiVu``lj0N*FeAn68ekhH$=d^pP7~V0GpQ$#P zE}W5ime$AWvFZS=7bakUI3akyCPxpk(knK!1mYR&rs}7D$y_$H)}cN{xK`sy%mI~T z1g%?A6hf~>U;k#BnVoghDHuktQFiiC&&;OHXkYHll8{^}waIl3Zp>eikYsHOM^xjz zS!!WDoqhYKXv1TBWtmbMRF>Pfb}`q=+dJS!wO3eiG3#Ilk%$PTG}xkG71H;FO;V=F zqj1&WTHn9R5pP?4mV7P zTia#(OW!li#9}Z zul4j#L!bC1M*o`y`6+Rj=Zlo5E#P%)7eg~^H*fX_5fhLSDqJr)W&{7fI<~SlGk;pZi_JgBTU}+Y08)n#eJ7I@bUNGU zN;Mw8RA$%c?57f6ro(C;mU|&Kix=C;oh$?wdckU7yx+Oy3VojsPeKA8HHu-ora_Dd zc*jdIUyzOZAWaXeQMIX)WIb^TWJb>`0^3($)nuEFeulZHOizf!s2C{!yV54LE~D1MzIk`4dY7_ZVoL(dl1>Z8J?# zTFQt29B-LOEhkGev}gK2Qhi_P>gMg6!_u!&$+aqqY5cA=g!oBb4;r8ckAtn7p^LDV zfgss=pU1-L+Xlcjh*t(;h0}eF@~t(g{EOcr11&bV3x5ZS0^gR+46;!mc6=9Qs=&{-0eBY{l}@d2LeM! zR?uhufq`)g5yXlfCT3WiDB^pHk#ir;{(dNzrqzap--Pz*2pMwWC1qDZs&G4;BFWq3 z{sx9?hsn4~5H1utUeLVf8cB=Lq7FMO%+8L}>(`l=^!2)|NQR}%I|Y(vI$I`ZFQAO{?^-qE(f89|K_5F`0V0gOv4gb2u(QR!**e1>2sKt%P2$Nd0qB z2la>d+XJ62#_5nf!4WXc!p}#3Vn%2Q|DqXfY$P3x`4sqOysiw>8E$q*e3!8e`BKR-=!RzCqke^>JNer17b#E`2O@!8;ISfsdr zoEB)1KBd4<4%C$|ZAF1XRCVNP3Gs7A`2RS_MC%O7jzbG#aGLu7XcVk&a+$#Xv((^dK9M71o0TGq2cW~R z+Y7ju0M4$hg_+8!Sl&YUm7XKza(365nR{Onr^Wnk#&D2bc#rk*(P>4 zqm|GYig`8tH@v=%2_yR{b71FP;8%i~w+O(mUySo(o475cY-5e>fhShmVHbN7b%(lI z8M)H-Dke+Ie)|Td^Kco3CYPUk6XYrPai6^Y4@#^+Dcd>V>hHXSlvTZFd)V#U7O!>p zL=k}=L*!`?OUbfJg%2!%qw1qeePu3533M!Xh&=m}K;3f{JP9{NPd+A{JBLKS(z=*$>OKm|5HI`J=)b>`+%zN>_K_NGu zr=2%8Z0ezZ@Ybmy&LzHI7g$NUeq}7lo~^abURwm5EjobyaFo|Ps7r44<3Dp3%lXdW z;~!~m8&2Kg8EtOMJl!9#eZ;LK7~IjeEOq?Fj_;2)iYb5O76oJX3<2G>N3R9%7f47* zSg@=o6wYeQJa(;wXz&Yo6W8vdWty=BnS1vyv_1j7Nt>(!0s>wtMB#)|4PR)|9~|0q z`0RJxG=|=Iks`qyu&_hfz{fdX%PJGrJA#Z&Oa^+DE>o=lw;i(5`2`~{3Z8cs6pY+m z^@=5aWP}y(6NQl9|P={Z?-h+K^m(^ld->F z*~?d`cFEOn`R0~S12X;OH_IJ&K?2vDEof`o(oAxchp zG|NO_On|v8RW9h%f1QZ#q!#i@_*UutdclfL_BDiu%hn-gEF*K>f x?!N^@Hj5$s#>OkWj)$I_6yO+#EZsrlKpDjboF@2wU=AGtwAA!e>s0LC{SOnE!8`x} literal 0 HcmV?d00001 diff --git a/icons/obj/machines/stationmap_vr.dmi b/icons/obj/machines/stationmap_vr.dmi new file mode 100644 index 0000000000000000000000000000000000000000..f57bf08913e7599511193a02e37f3484868961f7 GIT binary patch literal 3988 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 dt4Y`)XSh(H?$