From aa89a43c12feb46c5e6989054d193a3f38ac867d Mon Sep 17 00:00:00 2001 From: ferricles Date: Mon, 15 Mar 2021 22:40:05 -0700 Subject: [PATCH] map guild functionality complete --- atlas.js | 17 + items.js | 1 - load.js | 1 - load_ing.js | 2 +- load_map.js | 123 + map-narrow.css | 62 +- map-wide.css | 62 +- map.html | 84 +- map.js | 406 +- media/icons/Chest.png | Bin 0 -> 18006 bytes media/icons/Crops.png | Bin 0 -> 2212 bytes media/icons/Emeralds.png | Bin 0 -> 478 bytes media/icons/Fish.png | Bin 0 -> 1705 bytes media/icons/Gears.png | Bin 0 -> 1146 bytes media/icons/Ore.png | Bin 0 -> 470 bytes media/icons/Wood.png | Bin 0 -> 1903 bytes media/memes/agony.png | Bin 0 -> 19590 bytes media/memes/doom.png | Bin 0 -> 22970 bytes media/memes/enraged.png | Bin 0 -> 10517 bytes media/memes/lmoa.png | Bin 0 -> 8116 bytes media/memes/sunglaso.png | Bin 0 -> 4053 bytes media/memes/thonk.png | Bin 0 -> 29334 bytes terrs.json | 1 + terrs.py | 53 + terrs_clean.json | 10727 +++++++++++++++++++++++++++++++++++++ terrs_clean_backup.json | 4062 ++++++++++++++ terrs_compress.json | 1 + utils.js | 73 + 28 files changed, 15638 insertions(+), 37 deletions(-) create mode 100644 load_map.js create mode 100644 media/icons/Chest.png create mode 100644 media/icons/Crops.png create mode 100644 media/icons/Emeralds.png create mode 100644 media/icons/Fish.png create mode 100644 media/icons/Gears.png create mode 100644 media/icons/Ore.png create mode 100644 media/icons/Wood.png create mode 100644 media/memes/agony.png create mode 100644 media/memes/doom.png create mode 100644 media/memes/enraged.png create mode 100644 media/memes/lmoa.png create mode 100644 media/memes/sunglaso.png create mode 100644 media/memes/thonk.png create mode 100644 terrs.json create mode 100644 terrs.py create mode 100644 terrs_clean.json create mode 100644 terrs_clean_backup.json create mode 100644 terrs_compress.json diff --git a/atlas.js b/atlas.js index 005a059..34dc4a4 100644 --- a/atlas.js +++ b/atlas.js @@ -34,8 +34,25 @@ function atlasClick() { atlas_img.src = "favicon.png"; atlas_img.style.width = "100%"; atlas_img.style.height = "100%"; + atlas_img.style.maxWidth = "48px"; + atlas_img.style.maxHeight = "48px"; atlas_img.style.zIndex = 1; atlas.classList.add("atlas"); + let roll = Math.random(); + let rollchance = 0.03; + if (roll < rollchance) { + atlas_img.src = "/media/memes/lmoa.png"; + } else if (roll < 2*rollchance) { + atlas_img.src = "/media/memes/doom.png"; + } else if (roll < 3*rollchance) { + atlas_img.src = "/media/memes/agony.png"; + } else if (roll < 4*rollchance) { + atlas_img.src = "/media/memes/enraged.png"; + } else if (roll < 5*rollchance) { + atlas_img.src = "/media/memes/sunglaso.png"; + } else if (roll < 6*rollchance) { + atlas_img.src = "/media/memes/thonk.png"; + } atlas.appendChild(atlas_img); atlas.style = "background-image: radial-gradient(closest-side, #" + Math.round(255*Math.random()).toString(16)+Math.round(255*Math.random()).toString(16)+Math.round(255*Math.random()).toString(16) + " 0%," + "#121516 120%);"; diff --git a/items.js b/items.js index 61edcc1..943d21f 100644 --- a/items.js +++ b/items.js @@ -115,7 +115,6 @@ for (let x in special_mappings) { itemFilters.appendChild(el); } -let itemTypes = [ "helmet", "chestplate", "leggings", "boots", "ring", "bracelet", "necklace", "wand", "spear", "bow", "dagger", "relik" ]; let itemCategories = [ "armor", "accessory", "weapon" ]; function applyQuery(items, query) { diff --git a/load.js b/load.js index d2e7a81..c5d2d5b 100644 --- a/load.js +++ b/load.js @@ -8,7 +8,6 @@ let sets; let itemMap; let idMap; let redirectMap; -let itemTypes = armorTypes.concat(accessoryTypes).concat(weaponTypes); let itemLists = new Map(); /* * Load item set from local DB. Calls init() on success. diff --git a/load_ing.js b/load_ing.js index 5ef2dc9..35abeda 100644 --- a/load_ing.js +++ b/load_ing.js @@ -61,7 +61,7 @@ async function load_ings(init_func) { let getUrl = window.location; let baseUrl = getUrl.protocol + "//" + getUrl.host + "/" + getUrl.pathname.split('/')[1]; let url = baseUrl + "/ingreds_compress.json"; - url = url.replace("/crafter.html", ""); //JANK + url = url.replace(/\w+.html/, "") ; let result = await (await fetch(url)).json(); result = await (await fetch(url)).json(); diff --git a/load_map.js b/load_map.js new file mode 100644 index 0000000..cc87bf0 --- /dev/null +++ b/load_map.js @@ -0,0 +1,123 @@ +const MAP_DB_VERSION = 1; + +// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.js + +let mdb; +let mreload = false; +var terrs = new Map(); //terr name : location: rectangle def {startX, startY, endX, endY +var claims = new Map(); //terr name: guild name +var neighbors = new Map(); //terr name: [neighbor names] +var resources = new Map(); //terr name: Map({emeralds: bool, doubleemeralds: bool, doubleresource: bool, resources: [], storage: []}) +var terrdata; + +/* + * Load item set from local DB. Calls init() on success. + */ +async function map_load_local(init_func) { + let get_tx = mdb.transaction(['map_db'], 'readonly'); + let map_store = get_tx.objectStore('map_db'); + let request5 = map_store.getAll(); + request5.onerror = function(event) { + console.log("Could not read local map db..."); + } + request5.onsuccess = function(event) { + console.log("Successfully read local map db."); + terrdata = request5.result; + init_map_maps(); + init_func(); + } + await get_tx.complete; + mdb.close(); +} + + +/* + * Load item set from remote DB (aka a big json file). Calls init() on success. + */ +async function load_map(init_func) { + + let getUrl = window.location; + let baseUrl = getUrl.protocol + "//" + getUrl.host + "/" + getUrl.pathname.split('/')[1]; + let url = baseUrl + "/terrs_compress.json"; + url = url.replace(/\w+.html/, "") ; + let result = await (await fetch(url)).json(); + + result = await (await fetch(url)).json(); + terrdata = result; + console.log(terrdata); + + + // https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/clear + /*let clear_tx2 = db.transaction(['ing_db'], 'readwrite'); + let clear_ings = clear_tx2.objectStore('ing_db'); + let clear_tx3 = db.transaction(['recipe_db'], 'readwrite'); + let clear_recipes = clear_tx3.objectStore('recipe_db'); + await clear_ings.clear(); + await clear_recipes.clear(); + await clear_tx2.complete; + await clear_tx3.complete;*/ + let add_promises = []; + let add_tx2 = mdb.transaction(['map_db'], 'readwrite'); + let map_store = add_tx2.objectStore('map_db'); + console.log(map_store); + for (const terr of Object.entries(terrdata)) { + add_promises.push(map_store.add(terr[1],terr[0])); //WHY? WHY WOULD YOU STORE AS VALUE, KEY? WHY NOT KEEP THE NORMAL KEY, VALUE CONVENTION? + } + add_promises.push(add_tx2.complete); + + Promise.all(add_promises).then((values) => { + mdb.close(); + init_map_maps(); + init_func(); + }); +} + +function load_map_init(init_func) { + //uncomment below line to force reload + //window.indexedDB.deleteDatabase("map_db", MAP_DB_VERSION) + let request = window.indexedDB.open("map_db", MAP_DB_VERSION) + request.onerror = function() { + console.log("DB failed to open..."); + } + + request.onsuccess = function() { + mdb = request.result; + if (!mreload) { + console.log("Using stored data...") + map_load_local(init_func); + } + else { + console.log("Using new data...") + load_map(init_func); + } + } + + request.onupgradeneeded = function(e) { + mreload = true; + + let mdb = e.target.result; + + try { + mdb.deleteObjectStore('map_db'); + } + catch (error) { + console.log("Could not delete map DB. This is probably fine"); + } + + mdb.createObjectStore('map_db'); + + console.log("DB setup complete..."); + } +} + +function init_map_maps() { + for (const [terr,data] of Object.entries(terrdata)) { + terrs.set(data.territory,data.location); + claims.set(data.territory,data.guild); + if (!guilds.includes(data.guild)) { + guilds.push(data.guild); + } + neighbors.set(data.territory,data.neighbors); + resources.set(data.territory,{"resources":data.resources,"storage":data.storage,"emeralds":data.emeralds,"doubleemeralds":data.doubleemeralds,"doubleresource":data.doubleresource}); + } +} \ No newline at end of file diff --git a/map-narrow.css b/map-narrow.css index b0ef0cc..05b42e5 100644 --- a/map-narrow.css +++ b/map-narrow.css @@ -1,6 +1,10 @@ .mapdiv{ - height: 100vh; + height: 99vh; background: #121516; + width: 90vw; +} +.overall-container{ + margin-bottom: 10px; } .container{ width: 95%; @@ -12,5 +16,59 @@ display: grid; grid-template-columns: 1fr 1fr 1fr; grid-column-gap: 5px; - grid-auto-rows: minmax(60px, auto); + grid-auto-rows: minmax(32px, auto); +} +.leaflet-tooltip.labelp { + font-family: 'Nunito', sans-serif; + white-space: nowrap; + border: 0; + margin: 0; + padding: 0; + border-radius: 0; + border: rgba(0,0,0,0); + background-color: rgba(0,0,0,0); + display: block; + box-sizing: border-box; + box-shadow: none; + text-align: center; + text-shadow: 1px 1px 0 #000, -1px 1px 0 #000, -1px -1px 0 #000, 1px -1px 0 #000, 0 0 1px #000; +} +.labelp { + position: relative; + word-break: break-word; + overflow-wrap: break-word; +} +.leaflet-tooltip-left { + border-left-color: transparent; +} +.leaflet-tooltip-right{ + border-right-color: transparent; +} +.Emeralds{ + border:2px solid #4ae024; +} +.Ore{ + border:2px solid #7d7b74; +} +.Wood{ + border:2px solid #855E42; +} +.Crops{ + border:2px solid #e3cea6; +} +.Fish{ + border:2px solid #a6d8e3; +} + + +.resourceimg { + border-radius: 2px; + z-index: 20000000; +} +.marker { + z-index: 200000000; +} +.nomargin{ + margin-top: 2px; + margin-bottom: 2px; } \ No newline at end of file diff --git a/map-wide.css b/map-wide.css index 283d2b1..68b6326 100644 --- a/map-wide.css +++ b/map-wide.css @@ -1,5 +1,5 @@ .mapdiv{ - height: 100vh; + height: 99vh; background: #121516; } .overall-container { @@ -7,16 +7,70 @@ grid-template-columns: 80% 20%; grid-column-gap: 5px; grid-auto-rows: minmax(60px, auto); + margin-bottom: 10px; } .coord-container { display: grid; grid-template-columns: 30% 30% 30%; grid-column-gap: 5px; - grid-auto-rows: minmax(60px, auto); + grid-auto-rows: minmax(32px, auto); } .container{ width: 95%; border: 3px solid #BCBCBC; - border-radius: 3px; - + border-radius: 3px; +} +.leaflet-tooltip.labelp { + font-family: 'Nunito', sans-serif; + font-size: 1.1em; + white-space: nowrap; + border: 0; + margin: 0; + padding: 0; + border-radius: 0; + border: rgba(0,0,0,0); + background-color: rgba(0,0,0,0); + box-sizing: border-box; + box-shadow: none; + text-align: center; + text-shadow: 1px 1px 0 #000, -1px 1px 0 #000, -1px -1px 0 #000, 1px -1px 0 #000, 0 0 1px #000; +} +.labelp { + position: relative; + overflow-wrap: break-word; +} +.leaflet-tooltip-left { + border-left-color: transparent; +} +.leaflet-tooltip-right{ + border-right-color: transparent; +} +.Emeralds{ + border:2px solid #4ae024; +} +.Ore{ + border:2px solid #7d7b74; +} +.Wood{ + border:2px solid #855E42; +} +.Crops{ + border:2px solid #e3cea6; +} +.Fish{ + border:2px solid #a6d8e3; +} + + +.resourceimg { + border-radius: 2px; + z-index: 20000000; +} + +.marker{ + z-index: 200000000; +} +.nomargin{ + margin-top: 2px; + margin-bottom: 2px; } \ No newline at end of file diff --git a/map.html b/map.html index ef070e8..d2ed4b1 100644 --- a/map.html +++ b/map.html @@ -11,9 +11,9 @@ - - - + + + @@ -74,27 +74,75 @@
-
-

Options

-
-
X
-
-
Z
-
-
+

+

Options

+

+

X

+

+

Z

+

+

-

-
-
-
+

+

+

+

-

-
+

+

+
+
+ + + + + + +

Do NOT refresh too often.

+
+
+
+
+
+

All Keys

+
+ + + + + +
+ + + +
+ + + +
+ + + diff --git a/map.js b/map.js index 4df8378..e02e5fa 100644 --- a/map.js +++ b/map.js @@ -27,18 +27,39 @@ setTitle(); var map; var image; -let terrs = []; -let claims = []; + + var marker; -let markers = []; +var guilds = []; +var guildTags = new Map(); //guild name : guild tag. Ex: Atlas Inc : AIn +var guildColors = new Map(); + +let terrObjs = []; +let claimObjs = []; +//let guildObjs = []; +let routeObjs = []; +let resourceObjs = []; + +let drawterrs = false; +let drawclaims = false; +let drawroutes = false; +let drawresources = false; +let drawmerchants = false; //latitude, longitude is y, x!!!! const bounds = [[0,0], [6484, 4090]]; +const resourceColors = new Map([ + ["Emeralds","#4ae024"], + ["Ore","#7d7b74"], + ["Wood","#855E42"], + ["Crops","#e3cea6"], + ["Fish","#a6d8e3"] +]); /** Thanks to kristofbolyai's github page for showing me how to do all of this. * */ -function init(){ +function init(){ //async just in case we need async stuff map_elem = document.getElementById("mapdiv"); let coordx_elem = document.getElementById("coord-x"); let coordz_elem = document.getElementById("coord-z"); @@ -85,9 +106,25 @@ function init(){ } }); - - map_elem.style.background = "#121516"; + + try { + pullguilds(); + } catch (error) { + console.log(error); + let header = document.getElementsById("header"); + let warning = document.createElement("p"); + warning.classList.add("center"); + warning.style.color = "red"; + warning.textContent = ""; + header.append(warning); + } + console.log("Territory locations:", terrs); + console.log("Claims:", claims); + console.log("Territory Neighbors:", neighbors); + console.log("Territory Resources", resources); + console.log("List of guilds on the map:", guilds); + console.log("Guilds and their guild tags:", guildTags); } /** Places the marker at x, y. @@ -108,17 +145,18 @@ function placeMarker(lat, lng) { shadowUrl: '/media/icons/shadow.png', shadowSize: [1,1], shadowAnchor: [16, 32], + className: "marker" })}); let mcdx = document.getElementById("marker-coord-x"); mcdx.textContent = coords[0]; mcdx.style.display = "grid-item-7"; let mcdi = document.getElementById("marker-coord-img"); - mcdx.style.display = "grid-item-8"; + mcdi.style.display = "grid-item-8"; let mcdz = document.getElementById("marker-coord-z"); mcdz.textContent = coords[1]; - mcdx.style.display = "grid-item-9"; - location.hash = coords[0] + "," + coords[1] + mcdz.style.display = "grid-item-9"; + location.hash = coords[0] + "," + coords[1]; marker.addTo(map); } @@ -134,4 +172,352 @@ function latlngtoxy(lat, lng) { return [lng-2392, -lat-123]; //x, y } -init(); \ No newline at end of file +/** Toggles a button on and off + * + * @param {String} elemID - element ID of button + */ +function toggleButton(elemID) { + let elem = document.getElementById(elemID); + if (elem.classList.contains("toggleOn")) { + elem.classList.remove("toggleOn"); + elem.textContent = elem.textContent.replace("Hide","Show"); + } else { + elem.classList.add("toggleOn"); + elem.textContent = elem.textContent.replace("Show","Hide"); + } + +} + + + +/** Pulls data from the API and overrides all of the current stuff with it. Do NOT call this too often. Called once, upon initialization. + * + */ +async function refreshData() { //async just in case we need async stuff + terrs = new Map(); + claims = new Map(); + guilds = []; + + + const url='https://api.wynncraft.com/public_api.php?action=territoryList'; + fetch(url) + .then(data => {return data.json()}) + .then(res => { //success + terrdata = Object.entries(res['territories']); + console.log(terrdata); + for (const terr of terrdata) { + //terrs.set(terr[0], terr[1].location) //bounds shouldnt change + claims.set(terr[0], terr[1].guild) + if (!guilds.includes(terr[1].guild)) { + guilds.push(terr[1].guild); + } + } + pullguilds(); + console.log("Succesfully pulled and loaded territory data.") + }) + .catch(error => { //failure + console.log(error) + console.log("Something went wrong pulling and loading territory data. Attempting to load from file...") + /* @hpp could we eventually get something that writes to local cache on success and attempts to pull from local cache if fails + */ + }) +} + + +function pullguilds() { + let guild_url_base = "https://api.wynncraft.com/public_api.php?action=guildStats&command="; + for (const guild of guilds) { + fetch(guild_url_base + guild.replaceAll(" ", "%20")) + .then(data => {return data.json()}) + .then(res => { + guildTags.set(guild, res.prefix); + guildColors.set(guild, randomColorHSL([0,1],[0,1],[0.4,1])); + console.log("Succesfully pulled guild data for " + guild + "."); + }) + .catch(error => { + console.log(error); + console.log("Something went wrong pulling guild data for " + guild + "."); + }) + } +} + + + +/** These functions toggle drawing of their related objects + * + */ + +function toggleTerritories() { + function drawTerritories() { + for (const [terr,terrbounds] of terrs) { + let coords = [xytolatlng(terrbounds.startX,terrbounds.startY), xytolatlng(terrbounds.startX,terrbounds.endY), xytolatlng(terrbounds.endX,terrbounds.endY), xytolatlng(terrbounds.endX,terrbounds.startY)]; + let terrObj = L.polygon(coords, {color: '#f6c328'}).on('mouseover',function(e){displayTerritoryStats(terr)}).on('mouseoff',function(e){eraseTerritoryStats()}).addTo(map); + terrObj.bindTooltip(`

${terr}

`, {sticky: true, className:"labelp", interactive: false, permanent: true, direction: 'center'}); + terrObjs.push(terrObj); + } + console.log("Drew all territories"); + } + function deleteTerritories() { + for (const terr of terrObjs) { + map.removeLayer(terr); + } + terrObjs = []; + console.log("Erased all territories"); + } + + drawterrs = !drawterrs; + + if (drawterrs) {drawTerritories()} + else {deleteTerritories()} +} + +function toggleClaims() { + if(drawterrs) {toggleTerritories(); toggleButton("territories-button")} + let guildkey = document.getElementById("guild-key"); + let guildkeylist = document.getElementById("guildkeylist"); + + function drawClaims() { + for (const [terr,terrbounds] of terrs) { + let guild = claims.get(terr); + let coords = [xytolatlng(terrbounds.startX,terrbounds.startY), xytolatlng(terrbounds.startX,terrbounds.endY), xytolatlng(terrbounds.endX,terrbounds.endY), xytolatlng(terrbounds.endX,terrbounds.startY)]; + let claimObj = L.polygon(coords, {color: `${guildColors.get(guild)}`}).on('mouseover',function(e){displayTerritoryStats(terr)}).on('mouseoff',function(e){eraseTerritoryStats()}).addTo(map); + claimObj.bindTooltip(`

${terr}
${guildTags.get(guild)}

`, {sticky: true, className:"labelp", interactive: false, permanent: true, direction: 'center'}); + + claimObjs.push(claimObj); + } + guildkey.style.display = ""; + for (const guild of guilds) { + let guildLI = document.createElement("li"); + guildLI.style.color = guildColors.get(guild); + guildLI.textContent = guildTags.get(guild) + " | " + guild; + guildkeylist.appendChild(guildLI); + } + console.log("Drew all claims") + } + function deleteClaims() { + for (const claim of claimObjs) { + map.removeLayer(claim); + } + claimObjs = []; + guildkeylist.innerHTML = ""; + guildkey.style.display = "none"; + console.log("Erased all claims"); + } + + drawclaims = !drawclaims; + if (drawclaims) {drawClaims()} + else {deleteClaims()} +} + +function toggleRoutes() { + function drawRoutes() { + let drawnRoutes = []; + for (const [terr,terrbounds] of terrs) { + for (const neighbor of neighbors.get(terr)) { + if (!drawnRoutes.includes([neighbor,terr])) { + let coords = [xytolatlng( (terrbounds.startX + terrbounds.endX)/2,(terrbounds.startY + terrbounds.endY)/2 ),xytolatlng( (terrs.get(neighbor).startX + terrs.get(neighbor).endX)/2, (terrs.get(neighbor).startY + terrs.get(neighbor).endY)/2)]; + let routeObj = L.polyline(coords, {color: '#990000'}).addTo(map); + drawnRoutes.push([terr,neighbor]); + routeObjs.push(routeObj); + } + } + } + console.log("Drew all territories"); + } + function deleteRoutes() { + for (const route of routeObjs) { + map.removeLayer(route); + } + routeObjs = []; + console.log("Erased all routes"); + } + + drawroutes = !drawroutes; + if (!drawterrs && !drawclaims && drawroutes) { + toggleTerritories(); + toggleButton("territories-button"); + } else if (drawterrs && drawclaims && drawroutes) { //this shouldn't happen + toggleClaims(); + toggleButton("claims-button"); + } + + if (drawroutes) {drawRoutes()} + else {deleteRoutes()} +} + +function toggleResources() { + let resourcekeyelem = document.getElementById("resources-key"); + function drawResources() { + + for (const terr of terrs.keys()) { + //get resources of territory, dupe if doubleresources + let terr_resources = resources.get(terr).resources.slice(); + let terr_storage = resources.get(terr).storage.slice(); + if (resources.get(terr).doubleresource) { + let temp = []; + for (const resource of terr_resources) { + temp.push(resource); + temp.push(resource); + } + terr_resources = temp.slice(); + } + if (resources.get(terr).emeralds) { + terr_resources.push("Emeralds"); + if (resources.get(terr).doubleemeralds) { + terr_resources.push("Emeralds"); + } + } + + //territory bounds from bottom left to top right + let bounds = [ [terrs.get(terr).startX, terrs.get(terr).startY], [terrs.get(terr).endX, terrs.get(terr).endY] ]; + if (bounds[0][0] > bounds[1][0]) { + let temp = bounds[1][0]; + bounds[1][0] = bounds[0][0]; + bounds[0][0] = temp; + } + if (bounds[0][1] < bounds[1][1]) { + let temp = bounds[1][1]; + bounds[1][1] = bounds[0][1]; + bounds[0][1] = temp; + } + let TRcorner = bounds[1]; + let DRcorner = [bounds[1][0],bounds[0][1]]; + let gap = 3; + + //draw resource generation + for (const n in terr_resources) { + let resource = terr_resources[n]; + + let imgBounds = [ [ TRcorner[0]-(16*n)-20-gap*n,TRcorner[1]+4], [ TRcorner[0]-(16*n)-4-gap*n,TRcorner[1]+20] ]; + imgBounds = [xytolatlng(imgBounds[0][0],imgBounds[0][1]), xytolatlng(imgBounds[1][0],imgBounds[1][1])]; + + let resourceObj = L.imageOverlay("/media/icons/"+resource+".png", imgBounds, {className: `${resource} resourceimg`}).addTo(map); + resourceObjs.push(resourceObj); + } + let gearObj = L.imageOverlay("/media/icons/Gears.png", [xytolatlng(TRcorner[0]-(16*terr_resources.length)-20-gap*terr_resources.length,TRcorner[1]+4), xytolatlng(TRcorner[0]-(16*terr_resources.length)-4-gap*terr_resources.length,TRcorner[1]+20)], {className: `Ore resourceimg`}).addTo(map); + resourceObjs.push(gearObj); + //draw resource storage + for (const n in terr_storage) { + let storage = terr_storage[n]; + + let imgBounds = [ [ DRcorner[0]-(16*n)-20-gap*n,DRcorner[1]-20], [ DRcorner[0]-(16*n)-4-gap*n,DRcorner[1]-4] ]; + imgBounds = [xytolatlng(imgBounds[0][0],imgBounds[0][1]), xytolatlng(imgBounds[1][0],imgBounds[1][1])]; + + let resourceObj = L.imageOverlay("/media/icons/"+storage+".png", imgBounds, {alt: `${storage}`, className: `${storage} resourceimg`}).addTo(map); + resourceObjs.push(resourceObj); + } + let chestObj = L.imageOverlay("/media/icons/Chest.png", [xytolatlng(DRcorner[0]-(16*terr_storage.length)-20-gap*terr_storage.length,DRcorner[1]-20), xytolatlng(DRcorner[0]-(16*terr_storage.length)-4-gap*terr_storage.length,DRcorner[1]-4)], {className: `Wood resourceimg`}).addTo(map); + resourceObjs.push(chestObj); + } + + resourcekeyelem.style.display = ""; + console.log("Drew all resources"); + } + function deleteResources() { + for (const resourceObj of resourceObjs) { + console.log(resourceObj); + map.removeLayer(resourceObj); + } + resourceObjs = []; + resourcekeyelem.style.display = "none"; + console.log("Erased all resources") + } + + drawresources = !drawresources; + if (!drawterrs && !drawclaims && drawresources) { + toggleTerritories(); + toggleButton("territories-button"); + } else if (drawterrs && drawclaims && drawresources) { //this shouldn't happen + toggleClaims(); + toggleButton("claims-button"); + } + + if (drawresources) {drawResources()} + else {deleteResources()} +} + +/** Displays the territory stats in the territory stats div. + * + * @param {String} terr - the territory name + */ +function displayTerritoryStats(terr) { + let terr_stats_elem = document.getElementById("territory-stats"); + terr_stats_elem.innerHTML = ""; //jank + + let terr_resource_stats = resources.get(terr); + let terr_resources = terr_resource_stats.resources.slice(); + let terr_storage = terr_resource_stats.storage.slice(); + let doubleemeralds = terr_resource_stats.doubleemeralds; + let emeralds = terr_resource_stats.emeralds; + let doubleresource = terr_resource_stats.doubleresource; + + if (drawterrs || drawclaims || drawresources) { + let stats_title = document.createElement("p"); + stats_title.classList.add("smalltitle"); + stats_title.style.maxWidth = "95%"; + stats_title.style.wordBreak = "break-word"; + stats_title.textContent = terr; + terr_stats_elem.appendChild(stats_title); + + let bounds = terrs.get(terr); + let p = document.createElement("p"); + p.classList.add("left"); + p.textContent = "(" + bounds.startX + ", " + bounds.startY + ") \u279C (" + bounds.endX + ", " + bounds.endY + ")"; + terr_stats_elem.appendChild(p); + + p = document.createElement("p"); + p.classList.add("left"); + p.textContent = claims.get(terr) + " (" + guildTags.get(claims.get(terr)) + ")"; + terr_stats_elem.appendChild(p); + + let neighbors_elem = document.createElement("p"); + neighbors_elem.classList.add("left"); + neighbors_elem.style.maxWidth = "95%"; + neighbors_elem.style.wordBreak = "break-word"; + neighbors_elem.textContent = "Neighbors: " + for (const neighbor of neighbors.get(terr)) { + neighbors_elem.textContent += neighbor + ", " + } + neighbors_elem.textContent = neighbors_elem.textContent.slice(0,-2); + terr_stats_elem.appendChild(neighbors_elem); + + let produce_elem = document.createElement("p"); + produce_elem.classList.add("left"); + produce_elem.style.maxWidth = "95%"; + produce_elem.style.wordBreak = "break-word"; + produce_elem.textContent = "Produces: " + for (const resource of terr_resources) { + produce_elem.textContent += resource + (doubleresource ? " x2" : "") + ", "; + } + if (emeralds) { + produce_elem.textContent += "Emeralds" + (doubleemeralds ? " x2" : "") + ", "; + } + produce_elem.textContent = produce_elem.textContent.slice(0,-2); + terr_stats_elem.appendChild(produce_elem); + + let storage_elem = document.createElement("p"); + storage_elem.classList.add("left"); + storage_elem.style.maxWidth = "95%"; + storage_elem.style.wordBreak = "break-word"; + storage_elem.textContent = "Stores: " + for (const resource of terr_storage) { + storage_elem.textContent += resource + ", "; + } + storage_elem.textContent = storage_elem.textContent.slice(0,-2); + terr_stats_elem.appendChild(storage_elem); + + } +} +function eraseTerritoryStats() { + let terr_stats_elem = document.getElementById("territory-stats"); + terr_stats_elem.innerHTML = ""; //jank +} + +/** Toggles all merchant icons/markers on the map. TODO. + * + */ +function toggleMerchants() { + +} + +load_map_init(init); \ No newline at end of file diff --git a/media/icons/Chest.png b/media/icons/Chest.png new file mode 100644 index 0000000000000000000000000000000000000000..846faa9fdffa204cc17ea408b1642ffb6f7b0d1c GIT binary patch literal 18006 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 literal 0 HcmV?d00001 diff --git a/media/icons/Crops.png b/media/icons/Crops.png new file mode 100644 index 0000000000000000000000000000000000000000..d978b29377fba0a23753de6fc499b1baa8f56fcb GIT binary patch literal 2212 zcmb_ee{2&~9KXR}104>~3?{_$02zVn{pj__9qWFz8*QXp?TSndgX`UEd#=4JcQ@KC zNX8VM3Tl7|>Oh$Ov58_xgkVHxL=tpj5DB18V?+@_1SQ}^QQviKGn8KvFS)yS?|t6) z`~7^spZDH9?yH?sFuHg&f*=JRx62RTg~pvf5_l{GHuz*2TO*fzQe3{64wCI?n&I7Az~ zKGdnG0JWH`xIi&9YGX~5m1JpV7D|(pjUa6VWyVR0Bdwg7Mbj4sy{Te|^Sf%&zTlSw zi|BfsBZx#IVM>@yiW(*;mSqW&CTJRm2wZECbv}v9+LVk17tjP%itCahqlQI3s5I*i z3`ROgAr{Y?m9=!5V8VzbA15diX;4Z5MInoeH>=TJlgvjL7T!HNm35g%mZ$L%LFo4+A1DhcPspM9!&16%{&$(V2(# zdz?<6s)VE{9MJr8s!&h0(@L>cD^8oJRJdL*=aDs?mj&Q)IWU+SlO%~82n8*Ckf(4) z;8|Q?83wmoXbQK{WYB751(LLY%zT$3G#diQ%opK&Gb{46MTBh4LJ(4BXxwf$)3`Zg zvxP)!&`yfM%=|i4f(ww3-mo2GSsKdW+>!=s+LB&4^^uGt5PN@*#;`Gzo-z#7CNXc;-9ihjSbmuVG&bZa1S?{*~0^VWRD*p!z`)ra0%wmJ&zzcT^?6u zz`kl#{cQJc->r@r8-}&J?-|~;=b*ejzvti{dD){+Rppg$T4R5+q-%^n?}xiOzCp2_ z2S4fQesV;Qvr^i;X8HY(42-HOocz%FcUB)^E-u))Yu5{jvR{u?FIu^I-oVtNlP8d} z-nQwd=65gq{=vM`vAH|KzgNyY^}x857iK){Y^(SX-G3ObT0OP#Y_fD|oz^YyUQoB8!au!mRn2CpI52O; ztiFyH*9}bSz76}W=IO6%yz8I!?0cj3L{U#^N54LN?T`2~7d|*-A2x*->50p_eI*U= zuMsXToi=^ToM|Vu&qEc9E}na??vHK0c78&q`*8Ed+{XUCFMeu&X~Yx3Z5_7ZlU&-F zyGhg!jYs2!^d5YU#`SjfBT=$nR sFJ4;EDc@|{(f{fQziD>l?$16d&p%plq4NN?)A*0@RM)z;RxN7(8w_pjs{jB1 literal 0 HcmV?d00001 diff --git a/media/icons/Emeralds.png b/media/icons/Emeralds.png new file mode 100644 index 0000000000000000000000000000000000000000..8ba65343009c3d14433a9155a95d3743ddab43cd GIT binary patch literal 478 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP~2csy9!lU_XRsw}&GeaUuobz*YQ}arITm}Z`qSVBa z)D(sC%#sWRcTeAd6une-1_nkaPZ!4!i_@)>cY85AinQ%F_1wJTtKKxRTNRo|4juB^ z;*qYb8S+6;$7f=k%G#;@3LUMjtqDRbf>%1EgnSakQw4O35@*HAcJJ^$R(Oq>xp>Cs zzt4?~CnSW1E?afVQ_;e+AmwaX@7t5H%5EHvR-EU4S$>T#@^#QWDmzs|?;7`+Wy^Vs zDwA~Y@&8qw`?dJhno5oXwLezO{rl~**^fQJk5*ph-&dy3Fhf4pWKyQ+kA3+EB)893 zo}eiIDOP%c+Jnk@TGzP4EH*g`E^hJ;Ty$;2;q!@yGaP3-UO2?HJztf<{U>vaKwntn z^UA^nB9k22*xpp>P5r|hADnyqR+GqIowbvT-xuEE<;Itb({Rb>geAo zZb8qA|70HgmBapU`r~<}9Z{7lTjh*jKh`1Fw1%^IosxT R@E<6cJzf1=);T3K0RWO6y-5H7 literal 0 HcmV?d00001 diff --git a/media/icons/Fish.png b/media/icons/Fish.png new file mode 100644 index 0000000000000000000000000000000000000000..1a797a9564fdf7060fe93b507fbaea05bea78b54 GIT binary patch literal 1705 zcmbVNe{2&~9KQ)0gZ*IsB4vskM;1YLy}Mq2-MMq?+I20i+cFv$3F@wQukE?s5AUvP zH)Gn36hv-f-}MxVlqfb2pVxwG|YeY2O$%LM4j)twiyN`a>={* z?!C|Ze1Cs$UvGD3-I~TV2!hmwLxDaxH&~;(3cfckEb?$#t%Y_Q2vYN~H7bw;hinK^ z`H&RtH~S-9tf0zvUQ}bio|QF-Mv#`)ti}t2z(ivpAt@Yo?TfE4R1!ICmn%X>G(Sj6 zp%ESI80n4*BZC4XVy(}hEm;;4$iU>$tejE|Hp^iJUKXycZ306J5Oa{je3n48Khlf( zRUM!%yBilMrvvpccFIjM4rep!ASn+)dI*ZfNs1-iEX|QPlq zl>*gUQW^F8(Ji|qMN~7!)@5)I;7!0`FlJtybm24=rD)dWU>$Cpbh0G51dXVo6dzs= zg~zl7buuu#cR*pnh`h<)6D$gBT-9YBnk&hC0uY*#z|gW2S-+Z6bto8WM=#$G`~AJT z8kbV=!0792N5dU{H^sQ!xWi5r)Qv>guwt0JB7ks!!=P*Ik|eSohII2TH;>18uYe04 zCyB>AJdKM?jCRo;5c7(j(*1xcq^$%f-53Ao{T^L{1<0rFo5w0kD|6V8WWbmX7Yk%fu+zo zgqUa0%ij}+9^AdK_tT?SUTn(`xR4{ZmFs%u^XsQI^ICnCQn4vN^W@r`ys8m-QxH$h zbv0aYeg4|asIzr4y`lN$jnhx(k7m?gZca_SL)fOLn@-xMtN8IF^NIQ~syei7V(iPa z)!SFS-{3ZXyR}w-s*65{j(_d>wurVcXR`o&=iWZ~am{n}k=nPx(G)Y83RCt{2o#AflAPh#`tNXZloV;)LV{1pUB!mQGgU^vFO==5SFt&j&t_T1C z0000000000000000001t!^`>t3Rp7l_w>KGp_iMs%=3KufoYmV`uTs{@Xz`Jz!nT3 zIRB0NPviQY`_9Gvqt73Og53Mzu)GnUxc(ErMSibm5fRD7{UdhT+v^V_5WAc3C#g#Y z?e@TLIcpOm_{QP}WHb6!UZwN1pMxXAxawx+r)YQq>&=L(RlTyt zu$kpGs)V`9S4Is1xd%UPJs47{y(bTuR7Eohv^D@R1_KC=bq-L1#R=Q+wG4Xl0H^f< z46kcNZ?z11GJw{&+6NHPF#l-o*;vU2XHm(@C4`7o*6wWX+qXAs2u`c@8ryjAruTw z$XW&(As~d3CZ*?E1};m**5ava78$>m0Xu=mgs5fEbQzeVwvxtp8R$Ka5D~o_bJxXH zcbx@oSM9SVy{UrTSw4FK$C&Q}I9Jk`&;B=_MWLfAXug?aKs-$r<^S6wy3G~8i znx^ckq%|6000TJYFx0$_qo#r6+Vh+PM8#7rgWF&Lc~*n68H~rFBKiKR&4d1`(_5ub zD?X>3@^>&^A}fhnjamk0{Z$16xK3^$R$9l3?WsZt2u=+v3#p_zp{rWKH9|m0CCynM zX+B_h9hWc-0X-{eGIUYPKt$<5OOf%FG^3!U2`r{JCCw;!Tn2j2BZdM|XmHpE2#y;~ zpcZ(6bB5Ohq6a+3Toc#|Ji$J0_5n0u@Q-P_3UK)Tft|qMU;x4K<}SNY(f|Me0000000000006k>3o)WP?$_IMIsgCw M07*qoM6N<$f`d*61poj5 literal 0 HcmV?d00001 diff --git a/media/icons/Ore.png b/media/icons/Ore.png new file mode 100644 index 0000000000000000000000000000000000000000..d96b00d26eae6cc02bd08b38bc6369ca3957f741 GIT binary patch literal 470 zcmV;{0V)28P) zDY7he<~?UnmWZM;vMj|u-(t1N88FLWoy@UYELd^yQT+wb}o7 zszK!mQV7pL2AIW(NiuPp%V?;avGCzE$JND!$`fl%aDjIRy14WQAgY=4nj%BIPWoK( z{=oHK6xy^vq$|gO(Kc(%1(n#ptv%DX2^NO}FOO5)U*A+G81gDqP@!UC`_CY%P+^_S z9jwt%wH}hsOEk+ibI#qIyB?Ai7l#5WRP8C)Q5rUy#fh|ARcP+QAFwOnU@V7Q)c^nh M07*qoM6N<$f&h8PL;wH) literal 0 HcmV?d00001 diff --git a/media/icons/Wood.png b/media/icons/Wood.png new file mode 100644 index 0000000000000000000000000000000000000000..7ec4e60771ea9cb3619ff20a7d964fc2a02ac436 GIT binary patch literal 1903 zcmbVN4{Q@v81F>D%`IE9MaRVCI26%vy+6IS>$$p(c5D@IE~AElf$jC~wLRC~op-mj zTSyH4TL_zjp}5Q{WI=_npi!eHGZ@DZahRFGVqyZ05N8MxnVO6#1mAUSGi6NllDm8N z-tT?i@B4n=`))^FZFOEwNsh&0$@A5C>(RTwyzjaLJ$LO6JJ2gzt=XhoEO!^0cb26u zQEag+J|p=Xj0XM*PEev&ASwZ9jYn04wphx_<0=rEp@9WpNRr+7FN2@sm?XOKjdq^m zRSyhHHSHSQ&|d2o+M5NJh?hTxmBl$^APNnD#iJ2f=i+WWX_rG|bDG4lB*bWT0w2F`W$|s%Ff}dMZsQVPqVrByFY4kdi=A$l%l#Es}ID3M7ocD3lEyVd)H34J(GC zhm~8H&Mg1U0ZJ{;XMD`dB^u4R(2c5A6h}D(BH4 zFci(ND3P>Kb!p0&$AhijD9NG{(;uD#hhAVnH;yzbB`7;#qy4mvvojon#A7*%nuYR; zCnB!c-iL8 z`#hdHO$ka7w4m2luf=>-9tZ7mI0(i{CyDYr=aY2<$O80v-8f2$Rgy%`CX_OE$gqT9 zqgcXbXGJ0qWB>tR&?W?EmW2XL@AoP~iz$72zlin=rS^d65S>IofGlCBSV*{BHkNQw z4z|?J0?{dyruRRoN$BW-$p5xu9!RrhxEe`EYPO}0%m(;uY7~*MWSMY4Fw5VK3#RT+ z#8cDKJQ=vX2xiU3!VnoVRB~-jYf8gWzcYuKMvFc&ts2V6w1yh-G5>Yc!?P-V z-b(-KQNHJF?NCL*OP6w9b-bOG_dv;epH11f<@|7CX!y<-`o`*VdasV>uZn#C&E;ze zJs4EZZEgJZheh2$yd6+?dI1T zPjybg8;8F-(Q%sWxPEjgH>HCUV0iRn;knJ@`O~l6v*+E@iQWU2n##p12M4BG7QNA0 zJmDlR?k&n)p4i^>P|<~fQ^c{}qRrW3OS|I@pW-WC1m)lDFK)V8_Wnpk-;ZxCyRy5Z z7^vzyJ63%8;P9>jV&~)gmpnZ=G4-|O<&uQw!1=;Q&onxnTc)c!X2MvPxc>Eh`UeBW zU4;dI_HExbvxomZyLU-X&+>y6{NQghxw-oqyN3FYZ@=HR_1ySR*1Uf5-YXM_4v+ap tBEF*^ohJ_6*BO82ig!`slT(h#{JM+RI@veBC^LVFzN%X9k+n_F{{`Mpi;e&Q literal 0 HcmV?d00001 diff --git a/media/memes/agony.png b/media/memes/agony.png new file mode 100644 index 0000000000000000000000000000000000000000..aa91fd0e3048827d9a3182bf57b3c96cc8f3259b GIT binary patch literal 19590 zcmV)HK)t_-P)}p@>w8?SchG#qQN>$8r@fmMdP%6%oY(qJjzt z(otHJ-a;q|A%TSSo=m2<@Bj0>`|M#7K!JD_fB$?wZ}w@k&p!Kk*Lv4_R(Z|-1^(S; zM|d<(8~32uhn{V-+wPlWo47GCz%vWkF(JW|R?S242EJ&E*_qOoSC!OaK3ZU4rKw6Q)~=J9ZmpPO-M zEX{wIaiSTAn{k{O$5@Q%W{fwZ#S%0`%6L}99IyhnfQ56Im%(CbER*#|B!Xu~%8cqz zl<~zHrZu(QIkVcS<3Ea@D>+Zcet|qd3_t$FRl9SJRi=FqK*VqbfJcqj* zjO~pnI%39pGgg@KWXRYyCB^M#tn&=&+UQ6Z*^nu5j~C_Mwnl!G3iB~D-ebmRQdvG4 zDewjhbA*MNB!DbTO`=51(nKtWg|k>BiN)erEQ%$QgyL~ZxjYFovXvoltFl?l3=136 zrcLV@92~sM%+3IP?EmNgCRADD`bUoV{OTtTe;htF%&vFP`^anI*$=|{uds5KajzLW zBL-1}hB~&Gu_IT_+DM!&VPhyAXNMVGagV3WSldwGsi{p|Rps$Rso~ZZ?r5LM74?%j zH`C0UEW~6p>dh!wlzb#lDxSk)Ni6DNF%OG|-AE;p#LcKnq-n_&$%Q?N>9hkhSEvAM zhW?q^#^&bcuWa17vG)IWu>R;rRzJ1TzRUV!H?!%KAv)d+I~T(0qxtFUjGydpT;6Id zsW*1i8k7u*#NvC=xty05ILPN%sDO3E% zlKSdu_qeO8YlG)`XPH^~|9N29J-?RjnV({K<{Gw5=6_}xJbEasK7#k;jPs5)u0PY@ zp-HgnXt-|y+`o{k1?2Befn$vO%-A*2SmGILvPNH>u~YA73|bOw(BmeL4N0S;Cc^GQ zl5G}Ylcjk!*Tj{Pq*KL5n>k5sb}HCkD`W8x7JCj*3mFkJC#3>Y(kcn9E7zd+9IzFD z1-_oAQYi`SkeNMTW^XmK#Q$r+hB`NYu7xyT`$*b27S%&gu&B!xZi^v`*ZUt#@ST{>p#c!uQe`gFs@1%%&+H3Gy2UK44YHG zy)kpDd6OB#DT7p+PK&YJj9;4Zc{BcNYO^z*W|%S7j2f+z5hEfA_56`8WGIzNWMT#U|KWgled)Q4dI zfiq9ldXoq0;Hff~A7F6niLmzVaBV#doD6Gcz@`IW^C7VH7}#($ESU{E&VZ*s!dd#8 z`~M3T|B$MXw?5q zeSN*2Z!ojZgKVsS&41BU%1+s^_LH~6ncZ79)H2u=qj#eKZG--q@Yrm)3EwK2{+`Djj=&_G^mYQhKr z4ODB$!VXx08?2$DRqhKtP9zc|Aouq64n`u8yUlFOzZ9hK?c~D`zy3>b_SVf?j{**6 z=gu&Ygsu>DjpLcivi$Dt#xD;x-f6~9=7soBwK3O>ITfFAilvzwAIDg$q0LH+cO%Pq zOETU(4zd`BnsK}tcO7*QmxPUnt5R&N%h6qzr7LOlg?&{lb=((8uq#z!Nj%MkW_-bn z8yjo+mKpDm)b2OIoln+pRon<^jSN?Yg)uiqfw|Wj`a*z)LLr)(n*0f1h9ueZybfUD zzk~|jxbf}j&0FSPI(e$~-}|7^HQdNBwe0MYWEP>X7S_(@7pEBqnK2__l%qy2Y$QA* z5;MXn!xBcO(Xe>MKnWYku#pRySQ}@VNvrK9!+QYQzpZ;i5U0iGTfO<@zb#J!>NR}tu!LK; z;vpj};L`p`wa2g;!!m|d8CEi^0&qBCB;vj`S`h0KH`=2ynsn1D7VF7oeAJ95YHL{I zT$va|q6|f%ba)=C<1v<|Q!Fi1v9eUdGf|JtwN*S&E^tM2wPTiKBx#~(@;LP>DHWh2 zqXMRTeNRhwZz&xOrq)(TsEjPBV&I8PCUeBA64Z`u=ggll&Q>rqei&L{Ak2!D0x?M^ zM)$BDXJAJ?tUZPE53O;kRjz;~!dN6qB2z;=T1ChTB&>#rWypAW;uacVYf2TvMF5Tq z8DlI=(c;dXkmT-Pq5Ym5Glt#S0(}vW;b?@uRFv)MFwdmIJe`cPC6=Z$o@JXzig<*l ziy7`}uH_8#HAibj3&>@0k{A}C9;RcUhF=1pa$yAW`0?Z2QI>B2dLoe+jz*(TnAz-C z4XC=1+FCodxA!d@SFK3Wz1iq^R^YV)-_y}7x0o0*;TPX|>O&^2_?duzv7&&I7yz&Jp`h>3Ks z&e6T0iT>V+Y}%Qtyq<*}3D|rn|2^BcR?Cig@km?90VZEiYhyzNKuK^|sxOwp;?pS`xg_hG>bR^X%Qq%8I>JFLl86K+p$^CjpcNn00sA-BQ2{3q1)S8cRBiBFDmatL z5RbvY>RMnnTXz*5pue2>nk?&RxjN5h ze!kaK#mYhr8h)1)S3BMkH+1H>F2zuG|W#UfuZDnz{AwkEsGXTPD&I zFF_;=#j<0NwpLVYpBG`f2>gh#C6;6`Rs&v{4Hl&<+rXA|E$a&ntZ8iL6K1@z!udLW zR|Z->j5l_?TjxtwOT>Kg;H7~2LZ6Y*rIAUc-7%NT4FP}Y?Cjj{9|dZpHfLwUf?-LV z6I2Q7i;fJPodPkV@FA;L>v0ljX4wNCA34#OR}3N_Mt#hX1uFwb>Q~0k7&8~ooKUeo z#l23>`R~1VW`ktY_S-4 z_4Gt*7|t{}9$4TrZZ;b;bzI@a9q&6!V2b0F#huI&w-N=b!rMnc)UoNTPxo}3+`n^Mtq;_&RPA2_G+Y5xW_p3{Zga!=q|Af+UdI)0 z%5s94^8v*IiCmD6s^GLF?>p_r)raM|`875CXrgiD5qWMnv4yir#`#l|d?#s+yjPS( z($_0M(rGAV9BJPdGf0NOGloOPP}t}WR|x%d9uhga%!5pkZVR(Ze;+UNtcBTGp2Dv! z#s!o2a}1T%e8oiT<258KPUI!3+!vBgy%tEQ9*af{)>l2>wQJW?)?~^5Gf?3d@9yt8 zy%%1?P`?bIW{|4=tAK{+>oYe%{%L{UUSpHU`3-RxI2C@@%H<1<@69*9cZl)r1C8&` zF)p5GTs+a>&!2%moXHg;=5PEI{OokN?HsuMJ8;tlaPoZC7NYd!QV@?qI!1pc>(FvIm#^wig~y}pqrGgUmCtm8a0uAXurXSYq} zh;STfi26v(8BETtc?oOiivb$85Y?rsU=5{MR3?QFZf9pF+qQ4J&df4@cTnNtmep&H z+yV=D=wYeN!`QJk2}6>+zb2u2KkcM)=T7}y+zo-ua2mQ=VaH_HG6Oar2)j;%?zh9{ z(_raI@YJbr^Py~gtHBQ^v*}oayZ;?7TFCNA#i z{?fh+D|~+btb=U$iB-m~{s>)t0;HYZZhhHbSGl`)8$&|^QN)5&Zp5ivt)-oga3}+1 zddaX3tNJb$MiM8(^(ik0@fY~Pb`3YPvn|0#;ubKuKg@sMMY7>)B4dBJdc4) zlGR0zXIe5Ws|)c&#@L~lXqB-&X*_JkeI;Y_0md`+#?E?$-pp~oyIV4>oz}*e%sA7G zkC?|tEz3EvCf;o}BB64zqKe4;4L>vh>&1@6s**d0Nc>zb=YSNuBvq`DPNrC~>`7wb z$RI=f&px9$e!RukY@EIP>GitF*t$aiW$5ko;BOj5HEiE*Y}{!0(ix~{k3Ni@ z7|REYr5Kxu(L<44r0CFjyOOZ87M^b4g8dB^9|=F23^%@$Yf8q_@y6p}^!Li7rqg0_y}D43Ha8#pfTdC+$Ta2 zeqhG0TH5(W%~&p&zJSZ;z1|sVBJULp$cS7}AbcMIwQ$ItLu$5AC^$eBKb5g0b*|A= zTjyLl2I+0BZJ57Lpmy~i@~)ntG4zt9U&H_*h6o{-<)yhT0f5gx>O8%e<9Y?`4hL|E zZmDDWu^m;grk=}BGPrXlH?KAbhTx%d;Ex}G3*W?WQ^h)t#(30>WfS)2cjNcx zEA2Bm#!@bjARwojN41O~@wjqhbleA{$V~`MieOaE6#y#VT;xjDi*xEp3!$s;5i^Uv zB2eMI(Vn5!C;Q1TK!PDWH+(P!swDOKK)tNjhIO70{eTufn=0j^(}nTj8l}`8wxw}LMpasG3rxAVq%H@ zUJ@Dr85}FFj3hGvv)cK+iqWQF0P)(Vy&^yd1|}WbPoAO5O&%V~;Kp#GBBA>Ts92=| zF-s8`iZL{tVrV!E169yj3tOAv(K5d~)VQ>4Y(CsrT5UYxnM=?7T*Y^7F{8Z_K2s*& zY%|^x&-1_K$=p-ikJUDob(WwF99tN{8l=}Mt+AsAQbLSiw&eBVfp`j}1t%jWqu(BRD zFM#E5-~uxqYBq)rnZkXR&0T8MWh>iBmvR;H%HnE8GRXk3(^ z@q6X#%4%NpVOAe!++8%DDf_QK(-w0Qs_gq?tBoebWfh;*5L2Xd&v2SZEMMVsU!mF! zKpcIn02)ZAe$S+)HV5X^hBjVz$dUSe!>xvrsKS0to>o{|1zm4|n-7Plzr{}!O=(EGT%aQ>gucRR#e|Wo z%VR0kr1(i+AGRpBM4Nd`v%65|SfXWm{OC7f(fi@9_rZ;)b5q{vo?{G+GZyLnL)v+) zVBAoX;v0F7V=BC{&g){L;+sQ~(C6ZtFDivEw#EiP260tA-wV)OBwmRHhh6sml$s_N zxEPxMI!sF3X$-|rlfb-V9Ik(($ZfF{^Mg3WHk*i~7t zU3TE6BJ7w8_s`{mX5+ErJRV=r$af;fcgK$7&7lNSD$c%(ipZTvgUYan3U9UA}Du#MioTSv^Dj#=4!x0JRL!Lbp;-C_ul_x89&9 z2fN2Z{{nh99?a0r*VDW8J)HgN2-R_;CgO+H=9G-rHmT0j=TUWI-``f`e-3Ep7qeRV z`S=?CE1Trh3N5Fbp0zMd;WP(W%tdmp&Q;MdsfBeZ9VFg_ab(^|yg%9_?tMn%0v`~Z9a(7qf;gF0$W72zO>m2p(# zrKk%f-GowTu{o0ISLVQr$|zj+F?ioD*q@%R4Es`pb6)~Z0ZpWsI-%I zRzD;+M%jMVY<$od+NI~?*h+#2)*4-uS+`xU)wz5lR#gFKaNiA6IC7>@7dM*HMk(a4 z6YW)THzTVpNlUm$jd?DkL8&1s2|O_FXS@sGw|K^BsTfCjS=uc|&Z6YZa~TI(M;|`? zaDHdTmU?4T(b&*zaN&V0on+iI*63Jh+%?VMnt$Wg`NogOD6`&p>I)}x@2B6$&rUs@ zFC00Cj~zarg%c++C7PkmqWcV}2m~kL0iXhNRL)X7?I)RuTu_>h)UGtd#CVCLr_9#( zt9IrE|ApB7trZ(q?MH97Zn!`i=Nm);pvv6S&^juhhca}!&{&AIiw$-ZVP_jWD&l=6 z4A!#SWh)d|*JlhN-gXKbR>x7H5<5G;H2W9hpFJwGE&3HuW^x9+D@J2;$ z&fu0g2ETtZHy@(4^-NfQ2|W5^zJF-W#bxJJ&aFWE#7M+Vs-lHSo98OLU$M#!z|`?Y z0QC}aMO@s(2>_MKot&=W_?ZXk^-EvS+CA&^1FGQL^z4{}(l9%A8U1~dN*O|)uVzO8 zmG3B3EVbMU0&SbXIubS>#&-^r+C3DWNVxZQI#8R~O@=KUb?n@{Kky0KC5@g@S2PMK zBOWn46$^#^taWjkkx-1VMe!^`A{?d=SD~(D~tm=6p%8uW@ z6TSq)bDi4Uw$12P=u0HI^F?J0RU}jrE6caHib1V~!%eWH9v(k}OXip}F3y)V+IJ!_ zjh=PJ5?QKDqI+;Y3r{o}JpTseB1S$FB`PW{WMm3?(uFE4EH)-uIgZMOjTqsGxzCSO ziABPMLrJ1uH5RYK(sh{5QA`jYnY8a&2_ZW+$EbYNNKKo&~<)5;H~XYcO}L^gD>=NmezHs%ymJ zQlFK`#;7vCkt{rA&V`j!R=`su46hMO)MMEamWw;ePV0_hnrAl|Ec)(lOJ>_Al^XyV9QOh< z8uxRK0_G@f5em*e2)S#M!4wLGmh6!!I9n-pL+5Ow<8WXyg9Ap#Zlj}1>z+@ZyA(}< zDJ!=x1zpXsV;nplWzh$X8|B+w{U+|8WUM^USbBtU;dp~*rUKJh{h0C2cNyt|F=Lvj zI*+>eY(FK_CQ?;9kE(h-mvrX*eh1Mg;e6t`ifVDH${B&DM|(S2-1^1nqb* zIidwDuJzQIllKdnzFsiySrF%Ejm8fq8Rws1%*^?;;q1xH&XN>(E#*AbdG%iK)m<#E z2_q6ANiv6((7>|>X@=GK% zeJge4Tz)*)xM`m8z#QX_I%8>@@t{cW8{Pwdc{}Xi_B!WYj}_Yf7s`fFvvCK9q~ z6(FU;6s^}x^Q*g*b31ytAM1<=<-zK6IYO3p)}PiA-{K8B*Cy+7dVLm0RNa1N{Ch0R zRWoNHP`ULoPLg`{eCaf)?UA8Uhf%}Tv{Wk3bfYUbSW+|Mass&%vN7N_Cb)kZGwKqJk0^wIcyA~Ooar)lFZ>K{i<78VeoJb zKUpY}`*i*=)_8E5agQAGpS%_x`Yc>_0<1U-u05G^-(-wS8d;I&1>F<@(ncbrh7$#6 zDeB^Mp_+B0XQ5_dFdNkbDq=}O4oppgjJv6NUy>#(R7bfw!Hp5vsw8{8#rTM&`CK%| zZxinZe@OtpM zAi-?Ok|ln!*>B%u5mwCX5}ClRFug9ROSLE&w)Ppj28>}mx?S3d)=jx2jjmqxN2{u6m;-=HNyV2-B!T3|T5@)>gOn!8NEriUU001BWNkl>QW1r=)FH;-H&YX<;*>+JhTB3dmrxjlMozubU9B6jYsm6p7%Zbrhg~4agD6 z*5}Q5+uPpePpoHtUnsD73Ut@dvB6vdm!sz>u-m0vip@#0TO|yA5qL_LVjLcw#{W!F zuY-@lm8Y{#1ou@(v-|+#-r2@QW5k7i)Fn;J@z0E0sC0gTu;ocbGrn4__?}+ah=uk9 zQ-B7b#+*NzbY+H;Qmtc-gjbw0NC(jkQVq&T{4z`_lX33H!t!*ENVZUKVUjX(5^-O> z25YpA0hpttMK?Ck8viGNj{e>XK%>FbV<(wnczHlYz_n8sp3)jazB_4Kb{3E-^az`L`9;n{SR33 z3D*m#C2f@JRg)sWGEFE_ARCpNQMovQQTb7l)<9BymMBczB$-+hwSHEH(m*6xl|o^c zu%#cX^8|n@%RoiKsif;1HZRla=(?h1F)xXgivBtFmXc9mO0@+yH;~c*TpdSlc5u^Q z&QSmb-~;33Qg1!o%Vv2SSB-z%Va_O5gkOp1kq#0JlV8vM2 za2i+4G_F%8u)AN+vV)ClW#!&>2yA;7+_?aDe%-BIInRjZV_3rTFC;9MC`r-e|Eag0 zq)t?yzzJwIA5gzzX2qq6$R`XWvvM2-XtkxOHc?}qA9$Afj)o|Cew1cEFE`Q(&fSFI zCRT2wFO8#nDOA98fL6eCfa*Fm1g`I91vgbkN!Uvn?r-&*WL@j%CXxTQfm#m?FP+a_ zpR`Y4#6`p8v}{xWb^Qi=hz<6-0JVsC1+=r!SA@YLO4?e!MpD~G_ijZ~qOi6OdQRdu z2N}PfXk4|QVu$bI*$KwIDmD1?fv{m7+!lka??I7@!y~N}txO>|o^ZWL15s;j)LJ{9 z0CYFBA`y;x(K;DOLa=VC$hIPR`cWDJ#Hk*+GoE9g1g4@Oj;fP%$?yq>X{fGsk~$`l zbCDWFYnl=wCPujml7i90snm)Oy2oPy?W_4cKktJfsnU5zgCbz|9*)=#>wd_-sE`+x zr9;M-Z$tPNzW&yM>a>q0K!xkBlpqG6+AcM;K(2{WDr3--_j6(e?2vMCRcusGuZoM5 zjTNu6snW^}d)dc81xdA5T$`9{4kh*d+|1WnHzrf%{8U9v#M{bemG$fZeWl+& z8hkyj-1Gp@(EtY4@#xolKn14SyNZ3%i zu=V{6UiB^~rR`ZGBz2kdb6kr#b-?t2c-cT!0ML!oEDrK*^w_B_bydmA0`}FR%KSgv zJe%Vz<|dbX&}>7}cWor)uM|-I-Dprp0UCfBNb254z3-%4Kt^O&JSU-gPrwHfs-vF! ze={0Te*)}r{Vw-M`9J+Ke3avpfIdI@OT>JKD>PE`<_0$1Bao)Ut~bL)6S=n4xP7Xz zNRoNwTi}|L;p!uK`Xu9#(-e0+5!QW-ub*KQ<3`=MO2Ts1NHkQ|z)_3(9vAi!ZnA!$ zVxW0vy{f&9)RL@T8DIW)=|;}55Wk+gkRMdfcGYC+>1TD79!OHzFX6jh>Stcc+UcuK zO$IF?NgvFx)@Z45A2?mNKnx^X&z}P{=<)DEfXae(R&3=cV26A{UUetpaywioEe{(! z*mVHh&<5v?;mL!IC9{m%$BJM$2(E8ru`*y4S`u%4|P6)7l5kcbAVPPTWU90$4B2kx?<2B^QBY34*4}J0#Xg5 z#P6<<|0yeXcnsX0;j%f#qWz5P%f_!{2;F%gOHVhhQ#Qbp3wdz5vHVcuLgnqOp9cen z@a)nBPD&O1@YL&F-9)OixbFj?x*<{D`mDAntrm8%O&L4^ov8IvCH~)vH*ib)VVrGw zPERC#+D{W}A2fu(3vPY@ssl6tQ0ERtV8{i}gQElSxpgo&j{x0!=skbJ=<}ltvys;g zV|Nz1v~DV)I^yD=0yC%vTi+{#Nj0EN&@&!Z><23r!h>h9NJ&+j-U*Mi^TQL3Yu|00 zt9s2pzmLn4#v`h>UNZwWG(+cUeEm4}Ob9W{>Z!GYbMXDZad4q8^C*|cHJnP4u;?B} zkD@PXNh2%!{TAkzg*I+!oXJ-$%BM30x1m5m9P;R!@iHF=UVR4qLUT<8l z6prgohI`L|Kg@=;C%~c-Hr^llWppo-wlI(GvK1=n2OcmSJ zZl;}%4r6n-v2I9|UxBqKbe3a_%du^RHFfZp8ZJK292@l1F~;4^#+GTu+G)lO0`Jn- zvFWfBw?~YX^~SwgTUXA3tz-G3*rR19@Z*Ebm9;B_P8YA4xaY;b^yi-QIg_L#1+0|w z*W|nrj{7lCfq8GfnV$On8ETlzW8p@AAFp-msG2;gQcXAVm43f&_-N@G0YHES5-FD| zpT^6}nhgLCx!9$Czb2ntDQOd>z^J8gz5i=KEgdJ6(pv9>5J~Bi2hig~5RPrJ8KH79KK>hZX)cR|IuN%;S+4DH#%$0HRtc0P{U>F1$3No#{}cU z`0FR}9a+6UpA8S4>*_@2nCEhSUg-_hOjpT6*8IF9#Zza6jB{$^JXzPsaIulTaGKuQ z25!$L+{OWKGh@-Q$8+w|keNjOBJFP?Hyz++Ds2P-_`kG+l7})e$mzsIkWMj<~a!?lfcG&GqElh%aWK3PR?Xzb11mKnE8fkmb;f;DjTK5N%V%A}mSb&R zq1qFenQ+L>W)%{Bv#QLprYUUpif)S!wYt&vTElZDaem1-cUG-S4pUbA1?8#yY{qNc zMA(-JB`{wU(6FJrT7jZTS7l)uv^kzdm}NOmiPZ4Jmg)R{@*J)@@MwN{*m0aY|0v!& zc@}fhRcL{TSow+2jMr5pYmWTu!Yn;fArm1vT%5|z%=diAbZ?xS%yTuto z+I;8i184C%i@GugtyQn|`va9LKsCACd9;R(kOuy1dSBAnU{S_8J~_`DYp3$n84I|1 z-m(0zWs%lUCZZC;^?PLXwx_BPppL|si}sQL#gYtookI$fZL8)yS*2@Ffj_^M$D53< zI-@TZ_FJ#bJP38F6p%EhT%Xwv-7{ER&PSpDcAJu^t@l%Ex>6?<5E6%{8&NNP)T-nlh#uB=P)a8;a5 z)iGzJZ3~+Nw!56*{*v*ZmCh*Y5cZa2)TMXIx>U}S)S$RvNs`p311A8c;x`6Xs(=ix zOP|%)1JF@!hPK~Qz+JA0&L61TLo!W#bn1LQ=oOuDrfc%I$c&(bHhoT$P15cAn}OQ( zuk8h;Q`Zd^VmP&y)dg;Pw{e*`*vmf5R+XoFMpxMH(53ckgK48bVXj-HYsVIeLO2GA zwCj4Qc55rs#*&h8SB>%51ml@0#+8}?cbpD?JO-AX%x{#3^w11=Y#}El3`IXgu;)`s z>r}4pREn7?u8u@E*lmmxSdJ0(#`8-LRc&^RB=h(f-1nG&V4P$aC_Vktno6GnH+=u#i|Z~~$NybfX$*=#M` zW;woZDYu@f@9j(_FsURj>#uc6Y?d_s_CH%$FY0jZm*J7KIenV1UR)ln3XGKaKR;V z4g9Bt9Cs>0Tr)kOv(y+$b(RZqJ|(BEI3!&^esdWf_&%RGwwAQkDMddN052I~l}&_= z+K9mRh+93y$OKZBW>PxB0_}Bn``ci{0sP`9 zRpP4x(8pYDOaB@>fIr4yHb?w6$eaG>0kxW z79-!{Q+Um3Ut$t&`;VfNp0<$j9u*utdmJoFLT3}K+>fhkjh*`$9b^4oL*G_Ld1WiD z&&`<6e;s%@7cDr3n-(0!Z;RD@){Hl}>-8M{CSO*@i)-#5>;mD^LR4_9Nu?a&=dYiC zbxr%nsp4TX`?v#i_X?}M?NbI{%dtvzlT<or6dYLQxQq5o4FsZUxXT3v)-zuX2_( zrkf!tlyk2(q+hcHS6d5 z<6Q~Ts)b4UVCwu?%TS8N9H6Zct|o3$*?+ZT{0!j+0){Dz*F4O_^uh( zhqEk;)H7I`POsMjrHO14Yg1F>T%I*CbJpg{*#)kfIm;O%$~I7Pb+)<5uStm-jb(og z)s4=@Jkn7=m1RuU*m2hZ&^42Fb_=WNM!A^-4cnO~Ps?eNveoUQTtT0yOEje>3$X(q=#E@!%5#QoC-WJE`V>oCN-@ z@4D4&RDXIF&)spSijTf{7_@ngVIh(6H>-(+>Ggbfr90{as(rB46?4g$EQ=SQUzKo36XP$ZsYk`SRqf(<}+)1iRR36iZdgBwWcx-evEnT&}OWs_X@**8Nux zpkLpkET2U)?z#6kxd0z`JI_lZ$zYQ0No>BMd-@hAv|3-N59dOS{@W^poF~hievN?C=BjeOz#CN2XB`*U+ zKx)*v&C8<{YU-SuFg|a5WI;8oKaX7--@(Ss$Fg?q(XjJv(D!Lr_93|OeelO~Sl?=_ zj2e%7#$&B@Ts5tk57ry)5p%s4WO%tv=296fq3yO*)SJW-Mbg=NVy1KzC2#Kus3SUF zU4WkK)NSw|o8R%Z8xJ-f&<5u7irk@XCd7kUm?4YM8;;Nui8v4itN_+)-H|xmk)#{i zooHuVz#7jMjHhahCmW4FXN@QKGwxR-jq4ABhZn$&&0OX}adWu;1mkT)M}1YiPQnH8jCqWfD4QX4yReJ*8j;9{+bX9_eQt zY<9a61ri#kHuSeZ467S_j`*y=T~J5;8}N(`CQbyQo$!}t<3 z8TZH?+TXak+PJXJxJkK5*S^8|ka8cUTb6|OHM40{XJ+A9&Vi+kU_)9v)j=h0eEh^l zJ~`7kB_#gSV}|9JXrA+Z=XjoLNh2^_qo@k7daluAX&OzHXiYR)jq{Zyv6=v)D2fE#qiI8Bp4`N|U6&$yiloJT=aE zV4QL51mjmzt6ZK@t(7Qc4#C3vW7bH@%ek98u56^j#+agU&bym<>?a3v>FbT3Pcr^c zYb+i!gGa_q=Z?B&eiMuHnTnsgP}?%M#W^kMXa9-N5b2>-af-Ugg;64zq*szGU}aG| zcO)7jlJtv_6zvd6EI8Dhb_*qrJO`cD*H!`0ZT!-)e-lEB9MtWV0UYa$EFDPD$v~!a$zkc zY~@`CltwHwo7`y_y^5HuHyx1%8_F_u#%@>Lk84a~A(GeHtgVH8Qb~ zA`|tujt-?{{R%XZ@^Y(2)u0Ay_n!~wfSG+Fz;KTvcfEZjE5F4<1wWuoN}R1R-~i3h z9nLvG`vX7)s(_D}+tRUD8`{MEO>cI`e2aK667u&V(?)Xfn3GcNd_*eB%B;WX&D%0Q z=j$@%#^kVa*tG&rWPORzIyo_9oKOzK(jUXp54j3*Zf%D9PKWQl1`hC>7H`y2kqFV9 z$um?QM_2V&HsBEaB8(mGtaMF;=vfE3sB3Iz4e1RRYlvBC# zOZ%hZbd8~?zv*gk%#if$O8CIaXH}$zM8a+P=r);)#-UJxu*Zr_m`i44IUwYRjWT6F zYtQky>H}Ezd-@4b@xsTYLVS68lpjttu9##zxW934ow0s`v2Coez1A404$~EnvcY0( zwQ4q7J)5FUtc%t0bUepXsVGmC!aP}HENY6mKtixvlCmeXmO2ATjW|Tk%aV2Oi63o| zI)0TgL_c}n`Z)sVQMQ0*zutGlf&T78)QFt-SX;s;Z z_$M_i>(>oQwi*p5;ttdfZE!Ad^%-SBn6bP%&S%FO(`$W6jOgYCmEMvL6$VHAJRBJ` zTJQdSOrG-&XyT_c^ZdHOSl$+AQ*DIxr5J1TNuJH*SedTo$xI`Q^KINyZ0C-;sa)4E zg`XCi_@YG}?WYX_R%+u|X#+K~)G=sdqYj!ZfzgwZ1@6`-MDP1P|xGKMTf zcd!Md=RqRsCV*7+@}?ZedCCj&Eljx|NiRgiHP=v$r;$qe^q&I2@;znLh?f;-tSG|2egJh4^$suNuq{8#;v1Kx28({K3bP|^_r3lNr)riLuo?lrKhT91+-Ni7WOmB z1%ill0U{Nw$FfjGu*=sBx@d}UP~27T>u;PItq>GWh3cG&?8HMAb^7WCwW><(2@FYV z0H)jI4$c~l-3va32cln@ZL1#>2_X6}lw?iDk6QePnV%@uGTS9EZz*Mw@go)MjHed> zRcco2@K7YmK*V!9(#ws}xVt*>YY@Tya=t9rO689 zT{q2oEMCU)HCR?0tKSM-`8Mh#El1y?87y6?!gjkJg|KoQtBzxtN~VFDOC%DN7OmoF z1D-a6rE*vzGg4$b>P9_J?fo;~tMu>Nqq$TjlOYm`$oKU2#_k25!)+c9U4P$_N}zj3 zO*MaRt>qk%16~VVApx4@UW>CM9`PkqQu;!GdSUv#C>`Mln=Rs^FuO`MY^$kbQEQu1 zjdBy}EJ?i;TyqVP3YKlbs_L-nDl8Fmu}E3FYFp#71Jebpn8WIdSRsL>)dNXQGNQh! zP9%wB)FCA3SfXQ^uw{vPMPkt^qS1Za8R;Lq{zf7ZH`#!p&d$zvz94un_Tta0Y|^f= zrJLbo$G0|kL8U2AVAerN?Jnerq)y7X7%fP zG3;LK^$>Sl{QYJ1#yu(H&iW945iQs@lZzC@wlu%iE`jl+Z{dyxa@1o&AqK-9ofcu6 zd2Em8*_5o}K{K~^nGBaiRDdR2&)cF^kxevVxf(2$bV*v0U@=KDd}Qe=$HNVS9%ah1&HaZeV%osnps4E zEZm^rRxXMXrAH6vvQ!#&I2P#D?Y2ysG${c39#A-VAO5*0%tPP1S($p;WcALRv3|-V z&NE}xp+`7tx3}2nZ{=9s0L5CjsX3XrtA9aTC5O#{Ea~mBIDOF~1F1%qwoGsYfvi`7 zsT33KYc1(fm6p`2NQ56uoyvQZzclv%N2JU5)ce^`#QmMX-6IMj#wh?&eFW7PP(v)# z=%M#sT|w#qxRImwy@#asUqC`z zT3Q6^XU#0~94h|TmPb=iJ#`G`F*s&O_t=@mPxFwX=Gcmis9O7 zS0pqX^Z8o`XvpVviKXbUC_5~{%IYQ-9eynD9Xp14NsdxD)Bc7$$HY^7qoJKYO`XqI zRDV(^IQmZYEMkAumq?N=>sR244GQW)q`m`*9lb`5UQ7Q~*3gR4q-{K2e2=qNf~~e1 z{MM08w|qHk$RIkeSmvU-@vd-I&+n}t$HO&sJY8L)udUJ5lPXL$obaPDeIY~jnhJDx zCld5#OROu8;rhnuygySo!3S#qeIv!pY!7&n@S&(W|j|!(VOx0JZ%x<)f0tE7FJK?oD_@a(K+Nl(ws6o@>CeS$CeMiqC2% zRivryvIHtit&!-Z>hH2ZWKxwjk11M<16#<3AiI!S@tOscTJ49-#9k4YtN9SeKOTFg zZ{r-3Q<>tvO9aoyTxEj1lg{B-B7yfsFqtw{PAPLq7aRk>y9xXfi{NKFj!Dl`%~@X% zQEiu*I#Dq!h@~sWJk1HFRgh=&lGTs#Z97#GELW$Jvy_FJiFlF?36?muOj%H6)>ucL zW)F`(S=tAcb$FAioNE9oD}k_&(6DykZ^UXFcwV?I@p(@ zFO-$EL1}j~8l%2LC5GFxDyilt5veL6Ds{cJxCGCcBpcYJ{*nA3u4dM+Czwrhr$eih zoM7${LEN)txA-C&joz{Sdps;DmBt)lO8_Uax*4(-i^aC2m3|v zRc-?gY6-llC2+tiW3ShXF^MXo78|Roa~6CdKP{RaC}U6cUd? zGb31Z|gNS_H9}1mHm(c533(ktZH_bTQ48gjC*7C~_FE_BB*jwHjtAIA(I$DuK5P?7+4IY8VF1leea( zrV?S{5z08IB8dg;ON-3XW78WaXucN9YbrvNtr;=EuJ;UP=Ty7Mwaw{i*%I3U?sTKk zV7uk;e6*pUxikocInWr*7E&igmp`fS=v01mLCR(CYC*;(n}9Al%2~hePn##L9YFl+ zm>1iV0iU+@9gD>xSLHbSr-V8G?HkLM9?8mKy&S#J)M%;MGNi@K?6`)!=Yr{ft2A@e2>Fs5gV!_s}TUFtWple`2At41b9*-}Wrn#F{GTR40dq&p8mWR%xUZ=y| z*_eiwi}(dG0$wb&-Y(a0gU*0_55_J@x8(T}!vLjHNnO+4tk>&5&d<-^+cC2w44kLt zr@RHsf24e{1d`wu=w}sJ4qbEI59;9H;6Hwt#bQwbOmI!poUc}^2Sj9h7<1b3G3bP7 z%*~Ekx}53BrIeRQ@q4-;xV+j961eS#hK8D;2Kgr9XZP(E+DTn<*{ zB7kXK*Xi|f))AD;UzMwN3EUmD&qQQS^^;x$8gO8GT>L`|Ocd3GRpdN?gCcVOx(0GN ztj()fCX*RCdi3b0g+hT!MN`@6^ttQ0${fk(^Cu1+I`mYzT;9pHjUp0lKK=hEm!1It zQC-&`6p>S%1~O25ip3%eRP13*18VM;vTPOjBz z^Q4rs(lmWx7ZQF-1_t^W7#u_Z#@W15F72H+fA;plp}wDN+OqZja$I@nqaS_mqvxLc z#^&^ouU@@c-hA`T``qV$ju$p0pr-%ef(tHKK6B>GYkGQmJ{!mJjyR5;5W?XnyYsSm zt&n$KLI}IxdmP||5Z#xQ(oX+O_zpAu{iRaD=}5a`spy7g4D1*f==c`p8E)vJ|r?iWSN{!B(k=-n|m zICxeZ$Dh!V-m%~A?g;xO5%ddv34vv5G5Cd0F1Zs=I(ElvUw7#zu7Bt1v!*}K>eZ|F zS=9eI{OAh(h8u3^kK_2ND2{GbO6@Q3eRkZDzV_M0QtZF0U!sK|teCn-7blS$80>S$ z9J}P!-}=4xUFDqX?>u8z1pnbjcPFe~y}EDa%$Xl9m&;qGsr8OZKO%ukDV-GICH?D2 zh1+@m{x2b3*g}|o-}4vFb!VS*`j)r6?N>hRoa+nEF23-EFZ_pG1Om{Vf6Sdb_rs-9 zaqBdpcX!Z%Ucorq=XJ360xl^euBWHs1_t}x!o~C5`~`E}>^U=BrKjYgI69(*@j|pj zcz^dft2Opj`7uva>%~9~PxTqrd=d)(bx_ESS^uHQoF0|GXel8Do zUqT3k5QO(WXIy>l>$vcum1KENb+SehMfCRfFn8`e3P}RMz~BJwb{lIfV`F198V%Ak zW%H&j7-Pw@ls&t5V~u5We2njY=N7UwJK%jdXL0WE4;EnmuPG$Dero4}SYY zANb=du6X@z;E#fvZ@zi|7{bdsewxDX`08favSsr(Z{GZ0j4|)B)++qY=mc-}{g4m{ zDR9=|!b}&63G)}sLm*hT{3zzknL|%sFXx?i9s~XTzlnFF^`P|G)ro6wz$8sMczzAPga;|EzUL zB@jrmEbL$>5W;!g>>Nr;taC^qvDPAlppeAg=&+8lu@Qt&)EhN+@7~4u_ykWq^(437 z{zFW*??O13R@(phoO1?{#Zn?pSaIyObI(2F_x|>;KJ__(FMQz(>Wy!F(^Jqn)H(oB`cjEB$4fcJgQEmKHP`L-(?cmjK zsa)d1i&k>n@yBuU$tP1OSIE+wM!gQ;ccTDf4LEQ(BCYA|=|M`3Ilv^lpvDmblN*$h zVS#vCqTOy|t;0D>o@c~yLYk&%tx-y2Ope1*h+~Y+$&De)Qlt=Q9s32;PEpFM{Pi2w z^2Fm$aR2=evVPsheV)@D!a5AU&xJrQUAmarb7%h6oj&=oV(m3b5O@IX{aMtf^rM#``tRspg#%7Fr^tTnXTEsS#r97$3jiR12WCj8$C zymoL7r4&)5vDOCl4|$%EWf|5Q%H;}5DY7ib7(;Gyl+;-3-{TxqdU_Bz(ljN_Qt~Xv zT8ndzI4O89!Wx{*$c@36oI+B>I>TLe-_2+K`E!iy9R&nZ9{MN<$ACegU-hc<*8K6u z{^Y82Prqp0OKk_dl)_hlnLmI2veD7e+Zv6=0`^n$ez$w~YGAOBtFF45^Uq&NfBzuu zb^|FDplff{3iVb&Qg7-v&IvDPA$L@R|--l?$8Vq8w1 z_MtQfh#gO86aDZkd$w zHf!wx1>bqtSHF4{uf6h0q!bJf4P&h#4ZgM3dY@ep$1#N@!CJ7^kfkY7DUu|{If6hP z&JlzjwtN`YI*c(m99k)ybyzG;IB)d}fzk>kC3$L*LZY;{N3Au%9uP#4>OMoGQKi{x zVRDPoI=G6En;es8Bn6GLUP~YZtyY`9zJ7G1x#ymH`N8eCasRy!9@Zf2*a4+dL7#To zNn4LOX3@o;`qa%Y*#dYegx?YTQNV4$!tiee`&zt75_A5_^LhK*-a#BEY}l}#*|TQ( z^A~@{BK&8x^1D$ANg+v)O5w1yS}DdF;wU1HqOMyeguocny;jG~>bPBL+NRY`iKEE- z{Svg+KB|}J;2Z+swSyaufLgX};g;Y0&0o9tgCG2_>tBim@M493SiyI8 z`{`$%$~CXQmU(mL(`q%b)>14MvBpQ+bfl2MD#tmL)<_|UqL?I!{jDl5;5^F_K$0Zh z&qpAo?5g!V_qKsI#=N>u(>ASE8|xg7oH$k}rNjAckkT7&Qb>f*Byj;LRj}}LumWRp zlvd<6qghWed4^OvEEF(#j*cRn$;q7o=Wx#8oS@ZilBOBf7@TuR?by6&6JPw|SJ|{- z>vIg?eT3wHXQUMB#1+SFdB=O-eDMc={lzbU7bAQL*o6xhF5R(X$L(2`?IZZkYMwE3 zh>I`1nAco(8CoV}xy3nyF$O6WE*N1^9HS#mmZsnwT5E)q#Boeg@CILJVHjg@))GbD z)xud2Uii*AgqT`*LP&%Vj@kA9RFA&BFILQ+Di$ZG^AylbgDc7#DlL7WsQmXdCu z$l=ghq7)PgF-a2Pgz!g-&*7k?CXTh&1i>>=N+G2}YlRe=@v%CC1H-)YU2o@_YhO#8 zg!hVr?n&jqtY5cf;p0!NyM26o^U{xg6!${mVlQOpcMvyurBb@RUTwoZ}zJNunr5N$CX(J}ZVG(z^T5Li#gYDFp)R?H0vC5h*|k5qvl&oQ|niZnum*uQW@aqNvc<3RZP$+MiK;029y2qlT5 zm^?Ey8V#&-=t$y(!Q?q{oZzgWUT=Ei&{|BEq9UI-!a17FtowXYN`!#4-KL$kky6lX zHA#|)?c1N_|Nfs(Fgh}EP&*(fzdVj3ebll=KX`J@x{Jcxcd&*>JYL9(kzVkXPuFUV zeFX1)UCYIjJ(xV_ z)KgF6{lEF^^z@dxF^T<0I1zN3X8DtA)?GL_Jn(6zvZBvhkk4l*z(i4WeWTHMEBm=~ z#u(1I;9OpJ_3Lpqrrpkn;sS*vrkEr|ae@rS5kexQSA*WF7etXJjwAoj!u#m4R%q@0 zbZacFw1tp@{@y;6(%${c{CS?|hN%d>_q`*nyP?`noFU6I(!51(GY}T3KuCvD0u{vw zsZlBdA;^sXZX8IZ5DKDLA%z2HFe1uTT z7%3!CTtMlFl`Ajg-S2q^L&N>u4C6tD7DD8c6V*Be;tEo2w|%S|3arY=~%e)l@SSc|icX7C1* zLPD`n0P8byN-0FxJxXb`Rw2q3ju7V%Qlhm+O3}3+wAS5VkaKuV5JyCjp4wd!bfj_C zhQ*WxL()%v6luz(68(Msl#68|9V3-S1Z`)H!32XYiZoFO9w8u#W2B0a(rXzZBnag_ z1+9pph*GJ~GyK?19 zeZV)r2;mFBz5Cto)|)nM`ed4>F8oY%{OVO#T*^Cs?VYrnDOyLg+bPvrl|3W7aabQn z2|*TPZ1BbHR5HeSb#AOhD?dq5q`M18DsTB~B}uckchQU?O}!uOzt7NawaBv6f44E1 z+-rtLvk?q0zaWI`1cLqJ2`9oa;cW+#=cHLX*eD@vEWAOO=Q-AbkP2s9Hx=yj1zzQ= zDC&N$vpG7S?|36Puie`16l?rK+q-v!Mx)7s`HT3i4}XAp^XFj9fscTW3|g(W+q8Du zC*S?<)Ab#9+|iNEOD22?n9qOy^PkAF>}Uc2qa*lhR$s+sueky#6b_#$%k!LOt4X`v z4uKix)x1*v;idA?v5q7pX)>;!OA1SjT53jY~^;z!Y?|GJ!21AN|R?E9psE(Bshmw8i$V_ z`oNDjS|jZji(tyAbk34xZPK)bF&Wl*_?T9LN~M=1E>J9%m@|7WAO7tRvUthDLmdH1 z2w_|8*3tLf-}(eoP`H;w_zEyb9kuvP&1Um$;mcLW?KyG9iCnw-jSLJ7QL8s`!AA$^ z?;oVEZ-7Rc(rRW{E6H<*6p+LbaqQh8uljsY2j|F42(0)E5$lLzAwfxnR*EEwz~O@~ zQU!tgn@tJ{#bPno4u0o>BhpcK^0ZbIk^(9ifz}!yLkfndQW9rB|;d4$Z?pU0ijx} zv3u7Z=FXYNhkok=^!4{0!VPrFS!cFvdG>8@x&HNU0?d)X!w)BX0l4||=NGqa+wnJ9 zmRUfEkd>M*1KZH64bp20@X+rEOIFW z_SH{fAudubmx-gqdlP^Y4ir8{@BCSt=a~--;S)DfN~BU4lhbau$g+0VAT!3GgFES? zf&wXox5fpec^k`=_Ap`B8S6ERH6WZo2^I1K5`n}yi4+=ZA#1mNs8?%xdwVEV%9Khm zS_!1~fvG%e13pCTfH*0jBaL-llf{Jsdq+p;>Fwo)xBV)mQlT3z-$(QTJ2E;lZomKC zJN{<%>ea=YZ@&4k>i=-Umw+7~AOF*KyFCjJN0!by7A%^_d*A;a1_uX83Nfa8emgRg zc@-zYV(3I|vpmOGi^b>VjWZy_S&Kg_qbT-KvY_r&_?eI%ykVTfID^Ay&`_YX#^PN% z?^=0eP8=l^iUo?L66H#TBuTpQ1MvCv4xGz6i^)wlf#j1-8EKZ0nH(n^#v0Px8>LEV zbQB}dXyq4hq++5t!Z|@ZH8h(oYPA~eb{ijnk|^CtJ$r3|@b~YWKnYD8$5`R8!Xc!i zR4O76yn59tE`9aI2Xz61tlaKhBeQP3_4|K{Kbj9I-$VUU0%mx4_~>S{`2oO+5Ft@o z@%lHfX5NB@j80Cnd+&%hbRvI_i|`)VLCgq2J4?y3tZVpWHuq>+DKXZcy*^Z`ky4T6 z0cuV?T+>z(j@9?lAvn(SEs9c<+TCLG+w(uo#!e`x_MFycw4~Li#UCd36 zkPszNFr_+5$aU=qFc@bLLJ>zX#bS|Su|ly}CQhQR{nEh-8e;dk#$0vy+A67Lc$L2mDBjr?Z!#d|DG>$y_CH&jsf?D>U zN#d9!PAC-%L{UVfBcH<$Q9I$J&$|nOj$}6p<5RB|95kCv(k!K3uj8B}%`$J9J7_gq zR3~e+S}Ar~;>QLTQiYg&nzqSvpMX&UL{P!aMhkFAAy86u^ZdqGCaYB+Le6r(34%4> zapRDZI4)2q6i5mMq?Y7))?HA}IjnP-pc!=#tg(hxquC8h4-F3S+rRT$oO;?xU1ZRH zLjbPb&eX$?JoU-L6^9#m^ktHeSz~a^{{|C2^1T4qc{4zL6x;~+U*pfyqji?MM_Pf zP@vUnky~GhmD@HBgAkT9Z}|+K6}aHi0bzl9??no*d4>@9xe-3Ngn&}1gw_#KMRcN= zxyf-t5@`+2QLoq8vUM9*U3CS!cJ5;P_FV@`1S#j7-Ms19^ZWYxRsr8-D*L+6IM~j2 z&N)%5)&9sBfA!5oI-*`{03Hy5aYWL)W?CsCrMz_>f)gEhm2=)-x51tA zIeKVihBVD+wOZ6e1x=RaWVw%?HJVN8%_fazgGRkUntC^{*=%8qUyxdB`ui*BNTRjE z*o;QAM!jC8UagX6?ciqRcqiYdXgdaBwN@p~(vWAcoS@&1UnD!tOs{%>O`YK>?<>xA)bxTJ1a5S}UcL z);Zq%tJiVSt1hA0^a&1Q3`!|t?N_S`VOl8#T51|;+h<}CU7!X5)*K}>!~f!pV?LlL+B( z7OZioNMJ3rT1_8$G#Oe+e)Quz`R3QZ&EU`g1N{RmSU8W~zCkWrc@c#|(LV+`S(=ij z83GY}c}1~MqF%4zuoTOQj|2ugr&gOJ&vPFi2;pBBjuowy-}O#*H_GJX1bOCRW4%4S zWbGCYJ@N>%XU}D5#xNT;tmEVV=O4S!w*7{cQp!rDa@pkM<4YUhJI*7)ig zr4%L3!||bb^wGz->7V|YEt|G*#cMC;o$q=Z#d5)W6!