From 7a2b1598eb6c7f0c4cea02e904d5f67fdba29e06 Mon Sep 17 00:00:00 2001 From: fescen9 Date: Sat, 11 Dec 2010 04:56:06 +0000 Subject: [PATCH] - Markers are now known as "Signs" - map-markerpath is now map-signspath (YOU MUST SET THIS TO YOUR CURRENT FILE IF YOU HAVE ONE) - Commands have been renamed to: /addsign, /removesign, /listsigns, /tpsign (Update groups.txt if required) - New map-showmarkers server.property (comma separated list of options spawn,homes,warps,signs,players or you can set it to all or none; yes, can even hide players but still show warps, spawns, etc...) - map-showmarkers directly affects what output via the "up" directory so what you include in your options is included in the data, and ultimately the map - Internally, signs are now Warp based so no longer owner based - index.html updated to add divs around checkboxes - map.js updated to consolidate both players and markers into a single if statement - checkboxes dynamically show/hide from the map based on the number of items on the map (will hide if there are none, especially based on map-showmarkers) - Player list shows/hides based on number of players (or map-showmarkers setting) --- MapListener.java | 35 +++-- MapManager.java | 280 +++++++++++++++++++++-------------- MapMarker.java | 4 - WebServerRequest.java | 45 +++--- dist/DynamicMap.rar | Bin 37889 -> 39090 bytes map.java | 8 +- readme.txt | 13 +- web/index.html | 26 ++-- web/map.js | 69 ++++----- web/{marker.png => sign.png} | Bin 10 files changed, 281 insertions(+), 199 deletions(-) delete mode 100644 MapMarker.java rename web/{marker.png => sign.png} (100%) diff --git a/MapListener.java b/MapListener.java index cb8e75d3..7ecf94c5 100644 --- a/MapListener.java +++ b/MapListener.java @@ -6,8 +6,7 @@ import java.util.logging.Logger; public class MapListener extends PluginListener { private static final Logger log = Logger.getLogger("Minecraft"); private MapManager mgr; - private ArrayList markers; - + public MapListener(MapManager mgr) { this.mgr = mgr; @@ -76,58 +75,58 @@ public class MapListener extends PluginListener { return true; } - if(split[0].equals("/addmarker")) { + if(split[0].equals("/addsign")) { if(split.length < 2) { - player.sendMessage("Map> " + Colors.Red + "Usage: /map_addmarker [name]"); + player.sendMessage("Map> " + Colors.Red + "Usage: /addsign [name]"); } else { - if (mgr.addMapMarker(player, split[1], player.getX(), player.getY(), player.getZ())) + if (mgr.addSign(player, split[1], player.getX(), player.getY(), player.getZ())) { - player.sendMessage("Map> " + Colors.White + "Marker \"" + split[1] + "\" added successfully"); + player.sendMessage("Map> " + Colors.White + "Sign \"" + split[1] + "\" added successfully"); } } return true; } - if(split[0].equals("/removemarker")) { + if(split[0].equals("/removesign")) { if(split.length < 2) { - player.sendMessage("Map> " + Colors.Red + "Usage: /map_removemarker [name]"); + player.sendMessage("Map> " + Colors.Red + "Usage: /removesign [name]"); } else { - if (mgr.removeMapMarker(player, split[1])) + if (mgr.removeSign(player, split[1])) { - player.sendMessage("Map> " + Colors.White + "Marker \"" + split[1] + "\" removed successfully"); + player.sendMessage("Map> " + Colors.White + "Sign \"" + split[1] + "\" removed successfully"); } } return true; } - if(split[0].equals("/listmarkers")) { + if(split[0].equals("/listsigns")) { String msg = ""; - Collection values = mgr.markers.values(); - Iterator it = values.iterator(); + Collection values = mgr.signs.values(); + Iterator it = values.iterator(); while(it.hasNext()) { - MapMarker marker = it.next(); - String line = " - " + marker.name + " (" + marker.owner + ")\t"; + Warp sign = it.next(); + String line = " - " + sign.Name + "\t"; msg += line; } player.sendMessage("" + Colors.White + msg); return true; } - if(split[0].equals("/tpmarker")) { + if(split[0].equals("/tpsign")) { if(split.length < 2) { - player.sendMessage("Map> " + Colors.Red + "Usage: /map_tpmarker [name]"); + player.sendMessage("Map> " + Colors.Red + "Usage: /tpsign [name]"); } else { - if (mgr.teleportToMapMarker(player, split[1])) + if (mgr.teleportToSign(player, split[1])) { //player.sendMessage("Map> " + Colors.White + ""); } diff --git a/MapManager.java b/MapManager.java index ebaeb411..7a1acbb6 100644 --- a/MapManager.java +++ b/MapManager.java @@ -1,6 +1,5 @@ import java.awt.Color; import java.awt.Graphics2D; -import java.util.List; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.awt.image.WritableRaster; @@ -18,6 +17,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; +import java.util.List; import java.util.ListIterator; import java.util.NoSuchElementException; import java.util.Scanner; @@ -65,8 +65,8 @@ public class MapManager extends Thread { /* path to image tile directory */ public String tilepath = "tiles/"; - /* path to markers file */ - public String markerpath = "markers.txt"; + /* path to signs file */ + public String signspath = "signs.txt"; /* port to run web server on */ public int serverport = 8123; @@ -83,14 +83,27 @@ public class MapManager extends Thread { /* map debugging mode (send debugging messages to this player) */ public String debugPlayer = null; - /* hashmap of markers */ - public HashMap markers = null; + /* hashmap of signs */ + public HashMap signs = null; /* cache this many zoomed-out tiles */ public static final int zoomCacheSize = 64; /* zoomed-out tile cache */ public Cache zoomCache; + + /* data source */ + public String datasource = "flatfile"; + + /* which markers to show (spawn,homes,warps,signs,players,all,none) */ + public String showmarkers = "all"; + + /* booleans designating what to show on the map */ + public Boolean showSpawn = false; + public Boolean showHomes = false; + public Boolean showWarps = false; + public Boolean showSigns = false; + public Boolean showPlayers = false; public void debug(String msg) { @@ -110,8 +123,10 @@ public class MapManager extends Thread { try { tilepath = properties.getString("map-tilepath", "tiles/"); colorsetpath = properties.getString("map-colorsetpath", "colors.txt"); - markerpath = properties.getString("map-markerpath", "markers.txt"); + signspath = properties.getString("map-signspath", "signs.txt"); serverport = Integer.parseInt(properties.getString("map-serverport", "8123")); + datasource = properties.getString("data-source", "flatfile"); + showmarkers = properties.getString("map-showmarkers", "all"); } catch(Exception ex) { log.log(Level.SEVERE, "Exception while reading properties for dynamic map", ex); } @@ -121,7 +136,9 @@ public class MapManager extends Thread { tileUpdates = new LinkedList(); zoomCache = new Cache(zoomCacheSize); - markers = new HashMap(); + signs = new HashMap(); + + loadShowOptions(); } /* tile X for position x */ @@ -169,7 +186,7 @@ public class MapManager extends Thread { /* load colorset */ File cfile = new File(colorsetpath); - loadMapMarkers(); + loadSigns(); try { Scanner scanner = new Scanner(cfile); @@ -566,116 +583,124 @@ public class MapManager extends Thread { return good; } - /* adds a marker to the map */ - public boolean addMapMarker(Player player, String name, double px, double py, double pz) + /* adds a sign to the map */ + public boolean addSign(Player player, String name, double px, double py, double pz) { - if (markers.containsKey(name)) + if (signs.containsKey(name)) { - player.sendMessage("Map> " + Colors.Red + "Marker \"" + name + "\" already exists."); + player.sendMessage("Map> " + Colors.Red + "Sign \"" + name + "\" already exists."); return false; } - MapMarker marker = new MapMarker(); - marker.name = name; - marker.owner = player.getName(); - marker.px = px; - marker.py = py; - marker.pz = pz; - markers.put(name, marker); + Warp sign = new Warp(); + sign.Name = name; + sign.Location = new Location(px,py,pz); + signs.put(name, sign); try { - saveMapMarkers(); + saveSigns(); return true; } catch(IOException e) { - log.log(Level.SEVERE, "Failed to save markers.txt", e); + log.log(Level.SEVERE, "Failed to save signs.txt", e); } return false; } - /* removes a marker from the map */ - public boolean removeMapMarker(Player player, String name) + /* removes a sign from the map */ + public boolean removeSign(Player player, String name) { - if (markers.containsKey(name)) + if (signs.containsKey(name)) { - MapMarker marker = markers.get(name); - if (marker.owner.equalsIgnoreCase(player.getName())) - { - markers.remove(name); - - try - { - saveMapMarkers(); - return true; - } - catch(IOException e) - { - log.log(Level.SEVERE, "Failed to save markers.txt", e); - } - } - else - { - player.sendMessage("Map> " + Colors.Red + "Marker \"" + name + "\" does not belong to you."); - } - } - else - { - player.sendMessage("Map> " + Colors.Red + "Marker \"" + name + "\" does not exist."); - } - - return false; - } - - /* teleports a user to a marker */ - public boolean teleportToMapMarker(Player player, String name) - { - if (markers.containsKey(name)) - { - MapMarker marker = markers.get(name); + Warp sign = signs.get(name); - player.teleportTo(marker.px, marker.py, marker.pz, 0, 0); + signs.remove(name); + + try + { + saveSigns(); + return true; + } + catch(IOException e) + { + log.log(Level.SEVERE, "Failed to save signs.txt", e); + } } else { - player.sendMessage("Map> " + Colors.Red + "Marker \"" + name + "\" does not exist."); + player.sendMessage("Map> " + Colors.Red + "Sign \"" + name + "\" does not exist."); } return false; } - /* load the map marker file */ - private void loadMapMarkers() + /* teleports a user to a sign */ + public boolean teleportToSign(Player player, String name) + { + if (signs.containsKey(name)) + { + Warp sign = signs.get(name); + + player.teleportTo(sign.Location.x, sign.Location.y, sign.Location.z, 0, 0); + } + else + { + player.sendMessage("Map> " + Colors.Red + "Sign \"" + name + "\" does not exist."); + } + + return false; + } + + /* load the map sign file */ + private void loadSigns() { Scanner scanner = null; try { - scanner = new Scanner(new FileInputStream(markerpath), "UTF-8"); + scanner = new Scanner(new FileInputStream(signspath), "UTF-8"); while (scanner.hasNextLine()) { String line = scanner.nextLine(); String[] values = line.split(":"); + String name = ""; + Double x = 0.0,y = 0.0,z = 0.0; + // If user has old style of file (CSV) - if (values.length != 5) + if (values.length == 1) { values = line.split(","); } + // If user has old style of file (owners) if (values.length == 5) { - MapMarker marker = new MapMarker(); - marker.name = values[0]; - marker.owner = values[1]; - marker.px = Double.parseDouble(values[2]); - marker.py = Double.parseDouble(values[3]); - marker.pz = Double.parseDouble(values[4]); - markers.put(marker.name, marker); + name = values[0]; + x = Double.parseDouble(values[2]); + y = Double.parseDouble(values[3]); + z = Double.parseDouble(values[4]); + } + else if (values.length == 4) + { + name = values[0]; + x = Double.parseDouble(values[1]); + y = Double.parseDouble(values[2]); + z = Double.parseDouble(values[3]); } else { - log.log(Level.INFO, "Failed to load marker: " + values[0]); + log.log(Level.INFO, "Failed to load sign: " + values[0]); + } + + // If a sign was loaded, add it to the hash + if (name.isEmpty() == false && x != 0.0 && y != 0.0 && z != 0.0) + { + Warp sign = new Warp(); + sign.Name = name; + sign.Location = new Location(x, y, z); + signs.put(sign.Name, sign); } } } @@ -689,19 +714,19 @@ public class MapManager extends Thread { } } - /* save the map marker file */ - private void saveMapMarkers() throws IOException + /* save the map sign file */ + private void saveSigns() throws IOException { Writer out = null; try { - out = new OutputStreamWriter(new FileOutputStream(markerpath), "UTF-8"); - Collection values = markers.values(); - Iterator it = values.iterator(); + out = new OutputStreamWriter(new FileOutputStream(signspath), "UTF-8"); + Collection values = signs.values(); + Iterator it = values.iterator(); while(it.hasNext()) { - MapMarker marker = it.next(); - String line = marker.name + ":" + marker.owner + ":" + marker.px + ":" + marker.py + ":" + marker.pz + "\n"; + Warp sign = it.next(); + String line = sign.Name + ":" + sign.Location.x + ":" + sign.Location.y + ":" + sign.Location.z + "\n"; out.write(line); } } @@ -711,7 +736,7 @@ public class MapManager extends Thread { } catch(FileNotFoundException e) { - log.log(Level.SEVERE, "markers.txt not found", e); + log.log(Level.SEVERE, "signs.txt not found", e); } finally { @@ -723,23 +748,19 @@ public class MapManager extends Thread { protected List loadWarps() { - PropertiesFile props = new PropertiesFile("server.properties"); - List warps = null; - if (props.getString("data-source").equals("flatfile")) { - DMFlatFileSource dataSource = new DMFlatFileSource(); - dataSource.initialize(); - dataSource.loadWarps(); - dataSource.loadHomes(); - warps = dataSource.getAllWarps(); + if (datasource.equals("flatfile")) { + DMFlatFileSource ds = new DMFlatFileSource(); + ds.initialize(); + ds.loadWarps(); + warps = ds.getAllWarps(); } - else if (props.getString("data-source").equals("mysql")) { - DMMySQLSource dataSource = new DMMySQLSource(); - dataSource.initialize(); - dataSource.loadWarps(); - dataSource.loadHomes(); - warps = dataSource.getAllWarps(); + else if (datasource.equals("mysql")) { + DMMySQLSource ds = new DMMySQLSource(); + ds.initialize(); + ds.loadWarps(); + warps = ds.getAllWarps(); } return warps; @@ -747,25 +768,68 @@ public class MapManager extends Thread { protected List loadHomes() { - PropertiesFile props = new PropertiesFile("server.properties"); - List homes = null; - if (props.getString("data-source").equals("flatfile")) { - DMFlatFileSource dataSource = new DMFlatFileSource(); - dataSource.initialize(); - dataSource.loadWarps(); - dataSource.loadHomes(); - homes = dataSource.getAllHomes(); + if (datasource.equals("flatfile")) { + DMFlatFileSource ds = new DMFlatFileSource(); + ds.initialize(); + ds.loadHomes(); + homes = ds.getAllHomes(); } - else if (props.getString("data-source").equals("mysql")) { - DMMySQLSource dataSource = new DMMySQLSource(); - dataSource.initialize(); - dataSource.loadWarps(); - dataSource.loadHomes(); - homes = dataSource.getAllHomes(); + else if (datasource.equals("mysql")) { + DMMySQLSource ds = new DMMySQLSource(); + ds.initialize(); + ds.loadHomes(); + homes = ds.getAllHomes(); } return homes; } + + private void loadShowOptions() + { + String[] values = showmarkers.split(","); + + for (int i = 0; i < values.length; i++) + { + String opt = values[i]; + + if (opt.equals("all")) + { + showSpawn = true; + showHomes = true; + showWarps = true; + showSigns = true; + showPlayers = true; + } + else if (opt.equals("none")) + { + showSpawn = false; + showHomes = false; + showWarps = false; + showSigns = false; + showPlayers = false; + } + else if (opt.equals("spawn")) + { + showSpawn = true; + } + else if (opt.equals("homes")) + { + showHomes = true; + } + else if (opt.equals("warps")) + { + showWarps = true; + } + else if (opt.equals("signs")) + { + showSigns = true; + } + else if (opt.equals("players")) + { + showPlayers = true; + } + } + } } diff --git a/MapMarker.java b/MapMarker.java deleted file mode 100644 index f1dab5c2..00000000 --- a/MapMarker.java +++ /dev/null @@ -1,4 +0,0 @@ -public class MapMarker { - public double px, py, pz; - public String name, owner; -} diff --git a/WebServerRequest.java b/WebServerRequest.java index 464ad0b0..bcf2f6d5 100644 --- a/WebServerRequest.java +++ b/WebServerRequest.java @@ -72,33 +72,44 @@ public class WebServerRequest extends Thread { StringBuilder sb = new StringBuilder(); sb.append(current + "\n"); - for(Player player : etc.getServer().getPlayerList()) { - sb.append(player.getName() + " " + player.getX() + " " + player.getY() + " " + player.getZ() + "\n"); + if (mgr.showPlayers) { + for(Player player : etc.getServer().getPlayerList()) { + sb.append(player.getName() + " player " + player.getX() + " " + player.getY() + " " + player.getZ() + "\n"); + } } - for(MapMarker marker : mgr.markers.values()) - { - sb.append(marker.name + " marker " + marker.owner + " " + marker.px + " " + marker.py + " " + marker.pz + "\n"); + if (mgr.showSigns) { + for(Warp sign : mgr.signs.values()) + { + sb.append(sign.Name + " sign " + sign.Location.x + " " + sign.Location.y + " " + sign.Location.z + "\n"); + } } - List warps = mgr.loadWarps(); - List homes = mgr.loadHomes(); - - Location spawnLocation = etc.getServer().getSpawnLocation(); - - if (warps != null) { - for(Warp warp : warps) { - sb.append(warp.Name + " warp unknown " + warp.Location.x + " " + warp.Location.y + " " + warp.Location.z + "\n"); + if (mgr.showWarps) { + List warps = mgr.loadWarps(); + + if (warps != null) { + for(Warp warp : warps) { + sb.append(warp.Name + " warp " + warp.Location.x + " " + warp.Location.y + " " + warp.Location.z + "\n"); + } } } - if (homes != null) { - for(Warp warp : homes) { - sb.append(warp.Name + " home " + warp.Name + " " + warp.Location.x + " " + warp.Location.y + " " + warp.Location.z + "\n"); + if (mgr.showHomes) { + List homes = mgr.loadHomes(); + + if (homes != null) { + for(Warp warp : homes) { + sb.append(warp.Name + " home " + warp.Location.x + " " + warp.Location.y + " " + warp.Location.z + "\n"); + } } } - sb.append("Spawn spawn none " + spawnLocation.x + " " + spawnLocation.y + " " + spawnLocation.z + "\n"); + if (mgr.showSpawn) { + Location spawnLocation = etc.getServer().getSpawnLocation(); + + sb.append("Spawn spawn " + spawnLocation.x + " " + spawnLocation.y + " " + spawnLocation.z + "\n"); + } synchronized(mgr.lock) { for(TileUpdate tu : mgr.tileUpdates) { diff --git a/dist/DynamicMap.rar b/dist/DynamicMap.rar index ad5247fb346250f1ff8c47c60aff6dfdd4900dc6..e836ce7ed000fc76298ffefd77f5f5002c776105 100644 GIT binary patch delta 24995 zcmV(tKAdoZwJ6Qk#9bEtb0u_xCVa}$CJsmX<03ZMW0B~$| zXK8M8Ty0@+E^1+N0I)@~;U?2#}h(*as$mSmyzrX^4e=G?K|5-qv??FTV`Css$U-7^QNy$j)%4&t+ z5&J-6<0hsT7v=~5*jJN}m0qM{o@uwh;$D^jwI~K-r7$pDuNd9<=-E>^G^gOJ$&{RD zfMr->QiJd?Snv2If8}WGaqDpd|IL}<$J-*2`w1VkOQoGiexa$W!123vU z-4K?Mlp}!ollT~S7}f%S)j8gcWm6I+*g3nV{cR5Me=)xuLp8W&X3Rr+3UsmdLyn_M zdCa%j4w%v-WTHpg2-4eHUP`6eD8CrVsoR8?#?_LcH}wDH=*Cl0?0I_0_U1JRr|xdy zD=Z>O5{~rZAxR*B#x2W=Q9PnHOvHirDov1>VDOh}`f|j_G@=ddZW;`0bq=OB0|#g$ zs1Z4Ue}la(a16y+6(TPz-QI)xwH8xv>jeB$&nrnDD4UHQfgu%cD_f59t7ym4U$y7z3HgH^W_gl%!~GZHcK z*kt>0W0t3P6@D~SHrB16Kw&BYTZ;y0&bj@bVkj9^i*lv^Onp|atS>qm(N zBK*3rv{P48DNZZG;T>eqdB3c1ItipOy(%# z)ofKqpef^3Ddaqdt}a+EHGS*unGLkD%b{bsqVxs^vb?%m(_NXISvg?UTcs=De@NfU zDcdXVaDy$})4pUr@xwRhdpGSF$XTod_qn4GCIqYIOCQI^J-S`h0rBW?aP{e@Kv+*FqT2 zpz55XU)p9tu)$jiLUDYHQLx?qyjUe!lPt0y@33q zsUuNoA<6eGsK$IJ#ge7$e;%Y=ExW}FsKc0&`6#~NkJC4$B^4B9lNivCZ(@bQO{FnX z3p@q3Ut#bkxM&2E9-Fj99;PEjh9;If-J#sX5!!{L`pIQ5K{&`sKVM?qa1`9{LtOCc zIegl;OYED(MiM%~eRZz_8t1$n`9HbS@vs2MbvevX|2S*hkud(tf6Ra9CX%qq-Lbbc zS-hqx#cPxJx##UBNR9;xt=oeS1_CGbuU`bw{lP}`B7^cI8pjx1m8fAX6Y0484`i9Sdg{Xj6SQ`nWe^=Q1-ZJSV$CH0A1DtBAxP}NW+ zB^-KLivwOjpk0uYWR3|XY+p=EVLf)%&98KjfkoEx-(Dk+n^*_6yy^C3k=i0j6`y>x z?mi8tU1jzXkj*}Hw&lNtIc4vwMe1pchoLG{YAwpRrme&8f3Xn;1m;;--TO@`A{*rM zEiPI%Pi4Tp;fcP>IJdun-dEy1>&`->4ZDF}SjuL;A;aZhRF~<7<`=no8(S3H3_tst znrNK5K}?lDyHiu5pAO7U2pjYeFKb+A-Q}hZf%-=85cSLY>CWb`*2H@saGl*UO7j8o zwE+SeIBzQ1f49YsnyP137H_s9&e!^A&PNz)LcqX)uYmt%75%IO!kUV2|Hhi1`((qI zti=VE3}rUm;@2(Y29%5ePU#rAEcXherL1{8duX@jN)7|~vK_d=Mqv106F1WWJ1<6^ zzJ31ydtpa{2Rb~Imzq_LtXJ41@H!Hds(_&t`PU4zf0Hb3&=aG0s*7UM5!iKmswiTv z#kuYg`uF~O(l?zhchJ5?T>|N3_X-Khw`via=P^pL!mp0sT(KJyaiD9Z-W^0(*+EuB zXVT1?1>Nbf2vZEkMSPJ97%-6AC{pVK=DGZgwSBnVgghy{VO6YPp2w?!KVIYrQ2|uh zfm)>te>90@AHYj;`JrDCG95VZq1$@`r6Z8lSiLZOW?Bplu7mM2Dz5LuajW$s>)(ipB(8<_-oTP@bD~%WmO<8Nk zQjTPo*P;c)O_i3g`dSur1$0_nd519WaUCD}e{H{Qpl@~hve7hsG-MpEeR=(EBrd-` z{^{UHoo-MUZ|5W!NI?q$5TirG1|pbj3it^ifPp`}QR`v*Waa})nNcvU?b1WB1=wy{ zU4{JRm-7<>{@3`7iiDvpKVq_db&$V>B`;lVS0m%nPWy_JeE)Df`5i4rdvRS5G{B*pV421=065OdncB?we_+*z;Mg2)X$>`k^%vn=D zDabu6=7nQf(%Eu)TeiR0v`nC%oJpW>f43vq;lxlXk%%)s1A-3p81la!JFxY5m{)EzaU{cSW#J{dU83tzleyZh0_(t;4u zW`}T4P|e#L(`$dNo}R|AXUrf4f7#8|kBNnM=J$zah|>wkw4HhX|-E2?Vp4x6X)L%x*q zOTN;yqTC$_IO{IpnW7N;OB)w2UK{(8l2P|_+LS&_xIQU*SE*{9t-i)^@q$MYXIh@NNS#)fT1lVI9{7sBz2O=g{-5 zRcECzF4d6~Q`kVvKwt9$M0b5KnyDoycykF)R%}ppoqk^88L^ry2|}^P;h_0NYD1eI ziCV>}h4XI~w5E$0YZ#=RlymeF`QN4w4GhhBRt#b^(-w*IZT<1+vf8mAe-gF}WVr*9 zXQ;i>_^sTpKIRFP+qrS^x88t8up`?Mw(UvYV~@9Sk9}t<{K+(_dJ0d{mbR{VMXy+@ zHHTvBy)o%k##=FWWEwRYBX7o%D^&4qM1oZQ|*MF^_{Bz|@S z$%T?v@SnCuaF1Zj20fb!pu)%F6%S!+QoAT?5P1GTY=2bn{S=zce-pcJFHg&h3>nH^ zmaSr7A)kki_Ln_jq~Tzkr$Qx6zG2l0@=X{b>&UJNh%(NJy0z2J=tlpu)u|LE@Db)gGk`#j1Gy&Y+3eLEd3)rw{)@2tCHY0gJvgK>2nwA^J zE*>$maN!B~3#dun8X2deV)oL=gy&3gy2)o_p9p1yE?MDye;2hgj6=?c%pk`KDueYr zR0lH^qHB;}uOo*iT;ueUOR-Q8q94b6YdsD0V|1vtb(PN{T`+-Dy-_~h{w_obO{p!v zYvOzo033pPG2GELnHZHpPerN){R;gj!JaL%Y-+lIU`!E;sCJi9A03kaBbX9x|`q;Ss58ODj!Hja=y{A@-Pco7SJ zX$xn)Z+FgIdv|@!M<6R+znD?O1F(?mfL{P(TyJlWp55nI6mKkZ_xc z@y7B3y4Wz@fqQ;I!G*Mr31mGb-e4PyZ{(jdKP}#kiNa%hf)yZ?>ropakn3c1Xbs7D zf3O=X9|A(-4%S}GC5y^*g``4zsu-4nMz3VGR?8XXz5Zu)GQn_^B+v6TPf&>Mu}5a_ z2^YW7!Fy6YMZtMSIBi?V_k@kmPeNmsE-tHkQoFI5LXmT-nmK?r7jjz)zeBbL8}Dp? z1Xbj37Fct6DIjuQM_0BioM>B2_Uiavf5=MawR$!WmAg>^)3$UFl<82m_Zf>!^;pOgHStfS#{ABU_K9R#+ek=Lg=NI~L{ZWY~j@-wN3EWoG8 zEp?4w<`KZk%|6LSY|VY~X*A%aCy1cz`c8h%oYan2J1&Ncc%SD^M!~J4A!~^EfBW_I z_7w4!lbhV(W0*B6RHhQlY>L)XQ=*rxsi3K5uSR!RNOCErB>=E)=OxIUmEfQR`v1M% za`Rq6qyZx#kW+rme%~B#qtq?)8fPZc|I0GSB-b(PDkViB9hp}Gp{le^u<(tbBvTff6QXIYNM-^ zab_-HMw)L->3pDXv+&#&rYIr(EubH^=EDuxBVZgiO+>&^VeQUJkpbEIl^&9x zA^c~0$9N_r0i`s{MC7C+f2%RYr8ouB<={|S5}CW5S#v9+WqZMfHcIk?jvQz>WDjF< zQ0^O1k2@vZ8c~hv20xbysf#8NiC1C@>=03bppzky)0RXB%f*+llQSBgQ|CHOLc6%v zv9n5*$YrnHTk3Z*L5~)2Ip4i-U71oO8g6x>x zvju9cTg9}jBJNXu4Elm^mqd&yDKB(ZnDtlx-4NWmEfG`WuQ)Z+Es}hz*&NvUTv>fzg zNgbhIfiT5v%g}z+3*8QlM{LbZtfOZ5MyI zIxY}WkI~iz0=g|}c$f;Ovdnt&03&El2y@%?zljG1+Q{SBd47*C4d$wlHj;z}p%M;` zKs|7IolZbEFl0WMrhMo=HDr%u=IG+h8+`~8=sr+Afto*2z@Jf;zU}Xda-23K6El^D zcC^YuxfKf&f4cz(d?=qO?+fsyi1Sp>jZA|)sug%u#b2qY<^l1jpm~N&{vk$uyc)@5 zp&eaO$}TXa&4BhR6G5%LK`kI<;J#uQRqams29_-RQ`6HY8_2rk9?(7muvP}G=xyYM zrmYRqo?SWA%#<*i5b&buPGfoE#IhA$Sun}U7=&*2e>D6He5Tqf!^f4Y$IR{_{J;x{ zP~X-Z-cUATwtFD;hqq7fMSGGM!NaoO;uWNP{?*#Asl3(MGkI(@^XvoQ(O&@tS0O%} zZSlctI8>)r;w~iE9XfIqYoXA)#UvfHWtl9!!H@9$Mwri{DN{}fgWd>^wV5*MdoycX zcyK)lf2AeOY?|8L6Z?SK1y8h2tI@N~Wg>+Gc3FUI;Q1W!XAvvN%$FODtw|T&NS9J6 zb#5Sbv@_n)FOs+O0e@S;B7w3Tp5p?LtS|JRc}B&tYzxeZVi8?=rgc zA%lN(V}b}Y%&fo@Y&mVF8LyM`-Vo7+1|7U5e>9C@Ck}N2XmvPE@FFenIWy)9(`yJ= z@I4;zD{W?^gE!Xm;y8zxZJbQ$N8ZoW6@{vVxpv!WA5uDrEjWZ2+k501U>)ekVsNd zb~YL`KvTf78|Tx1XD%-Q&D+>{1;@2*_0s8o!abI$7Wr zj6IA$>`j($RvA|d1r4=bZ7du7Qpl>&w&XPzbeYrk1FK);t$?-K(L$GhNGa!2Vm1kn zLDzjQtxi*AaYebwmVlbpr3ptHgYJxrv(xo;lrfg4ZHEb-&lpaxbGErE9r$s5f0+_q z??&Drb_yC-CA?>}nJ(Ni!o3rmB>mERUWYrtd&W1+u00a-he5X|UCeQ^&8YJtU%6|d z5&Rrf>wE-F>8P4T<@i+bI}9+TK^gm(TwP)D|6Sa$z7%rr+`83s5*EATNev_(mT9`p zGlOhu_1J7^bx2TBX{|5tCvvv!f3P5)RID}~Cktf=b#qh{?je__Tw8LerHTcNr2uuJ zbSjYm*&jZb6yOk&FAn&jxJ-u!N`GN`=0oY)1ld|Xto6iQH`G2UVG0)Wl_X`7BClPJ zht0hPGnQJ_F*ESb;zG8R2>8Bu|DJzAf+ZF1_tqbJZ3eZ!V*=p^z`Xbqe+lp%Yede5 z2mO$J#7TSH7a;@WGRhu3ZTcWn`vYc;_aD~xnYgEtNf_Q!y~#GKL{;%Z@TKt@UgV84YPA&szA5w}#8WN!lOe~*)6Jor$O583&}1dIP9XBH9UQK>#YrvCC| zK54Pgc~K?&?OXf!B!zoxX7e6!(gL{J4af(lYUJwp>e}nAzTLV4tj4HRCoa zds}XgT-FWvie``dv!;uW+9X>kFR$&1m2Kt)`NQ8Cpnc5Wl>eI4+aV1X{a@rRa9y^n z$#pk}52T8=fNkc?hy0`m#2FXG2({6lo1_lc^pFV+sQ2~Zf8T2?PMKd}-ama10)G=T z57|K~X+NJ<`6%Boncs-Uk7AFC@n_>NErms!=jkoe;kS*btq_n-`Q5)ci;Z5poI)H+ zy{aE2cy#b?A`p+spt{rJPg6B_0J%TqFr5NZbTq2wM{=)U*w})9emGzjwMj_jeJ>TFm|0Kmn#qS6RE~>TFe4g&^k&dDfXxYv6qL>R~q5NCD5$ z>M)0Sij(2y*eafTXpu(Buk@jT>bvwq>>?+Mm9wdOfA$HINqi)_j-P5=5Z`Ph+^(9ZE?PS*E&{iqk<**aSZriW{W8D=H6rNj^F*M1JO^B)b(L zVkSeTbvp|^T_eSEGbFsdSj7b?SxCkL^7+j+uk%*h6$0ct%CWvjH8SIMTAA59PBzHz z57LyPf7sL%hMEI#i#-%jCT>a$q8Pa7N~Iaalm{wyzv45MHjMNZKczL53jk#QCo5A2 zg3r)|rgqLiMJNx13^O{HL~53Cr_l$=50Q06{cM|@Wn|=^yqahMGDLc z4zp*W@f#DC=S4dPIoEU=3ZN=^U_<}yU?X8gx)oD-U^CS`Sz040tg{5TL27(rqIY;AHc3U z&=LdaWQ`Y@=bmB=F&AaAx&7DoyzsJ6w&JBe)727d{nz zY-$QcMOUATBakL=A^^0qh~DXis*RBTe**E=h+5#;Pp_}4Lu5oXXh6M*kV)L`t(lJ0Oi4YoJ4GX~izG2-O2ZXnCVh7i1DTS3)yl5gI-f3U{l@ z{$^dSHLI2=&b&e`??9JVWL;T0Y}*Ps0>ctdBX3Ry?%O>~IG6UVK2ceUt3<+Cc<{XD(UO$`*xLqR<2xtcCC34VZ$L$2C8%5*m?W z0SkCn+}tY<^v6D{G)KX2OT(>U_Dn>m{YGe~6j3+#;hKM?23Tb0R(^}we^_hsDW1f1$tl{T|K={T(=C@Q*py8HtGc(6ZmA1H zlBzntlP9Z4zZnDRT!CLdN;V;jy5M?2rvAw<`SZzBEwNacW~J@W2RR9owT%rfH`A~= zfg3zXxME6UV!z!j$%LlB*}kC|dY~C}h0Nmv`!+ZTJ~URVL*9Lue_SSrjI@nHeoa-F z`=YFI#F={SeQ7hkpCrY~g8J8SX|{g0a;y}X;|v9J@jpeJ@&=IGB#C$p!k=A58a1rZ zf)SXo#t%~G`z_g7`z-rC3KZ3YJsoSxJY@*+T&%xxRF03at8ca^_2lt*s7Q3*%z4ZE zaB$aBv^^v!>9lNPf8HSc<3EG?(G7DD)cpT*Yb-01+n(_R7e8@4$8C63r^Ml{q&~pc zL)NwycBl|jynMy#Mvlx&$Cg$e*z+CR(TQK6x!b$V_?u; zf>scn>*!llY}Q&!BL-Zxf;~OdYJ9LcphNx*x#vbMzls$`^eY6Mth^x$<5+%8e&7PM zTrt=FnPnVY9f|T~0J7t`=(aR8iO zl=SwbRl_Bf3K0#0FJDL7U<1j93^vNsHb0vi=buU1t9#wg5@)ee`se$F7fHOJs%lb@ zU$7@o4F2sT`L2~CJ=HVZNX`yCg2y~VzE*|SnRDNyeg6TP-2`wwqwQh5waZd^R2gB9cZIl< z)uWoM^8H_0JqGh1DZ0*4WUmO;GYLg&pdYr5e922kx%AI{Dw^Dq>QWs9$mJvHaX^qO zL)n7`y_%XAmEq#XpNkx*4SFS8=cI6m1OZsu&0$yDL~^GO+er-^oTi z5Ka3YD)8A*y*D>5vVwj7O5kQ3rbC+Eihu6#qLVPzDF_#ZeYcg;-I%U*!E`23ASV!@ zDGTmUf{0P%3y|UrapwX%xzTz|p$ZJ9neX$xhgcV;5oZw&eD=vwCgkxLh2KFC=tM~Q ze>2`K&1K4tp`jUJB#Rp-b^*ExYRK-0se35>~g%g4oDQ|r{d-xcDNP3A9ewN;Ye_D}0%oKkpDP)&EQ)ELSdZ$%`U3U}gAyRfw zhnl3MSFRR1Fr=&`!g10Dyy7~&wUhRX_9Z$&TxTfN^yQJDK}lJMxGGa{_}pSk-yh+g z`0QH4CdmT$xw$z2SkbF$FWaRNd=m*|=%`b%#O`que5g#N&8S-8sF#t}xt3#Ae`22Q zu1~81Eq&JC1p7r&yjXm%FY9^@uCL<8s+ML%Cj{-DSv$Z{UGmF&>0RX7Twvy3!If zAW|GMn58@ePdXZ3&-e1B2NWyefAM4v{eT#$2>o%YZw4htc-w3bj*i5|cH@2aE63~yyg0hp*QVKPzYz7l z>&gB31va@<52-%M@WTx{z=)zoHZ~@Ih8L6q0DPeHc!gY*gLZDQf9wCp!33x? zD~>oHcW;IHsb}U_mMe;U9knq{1@MwpypG4$mcC z_0R-+r;aiH+U4Vs*d|8d_!oo>oz83~w7&!!B5Uwhq4azvxC3m#3rpkwO7kxo^=Iyu zg0JbB*7XXHzhk;T8(T`?f2g9A8wdGjA=Llti0KUOzH2VGxTPI7=euG(Av2IpJl_Q< z*S}J)^h|q9thJ^4{mQBV&q#i$E=C6u12lZaBqX!dhQz-Liq{!Qzhv=yvEW-{N$!=p zUbkRC7Mk{40BjGtwX6#r+N+}BUN$`Pr?Q_^8F(ARdfDGU;HRZZf93UA6k+l~Z!}(B z0A?qGkuQND`rM%cGSsoNPx|XoAUgfGD6$|1!Gjzmz58|Rzm?=hpjKryEb9#iBr@Xf zayZ1<;xX$Jws|FTL+XpM3Rc78`Y1IL<$Pni1_!AfW^JZmAPG@ef#!`}uzEjBE<(V)U7*@58!EoKz)!{Nb4!MOUA zKb`zNWi2GOKuHuFp_<;Vqq`pWLo*uVz=5Djs)G6>yF+Vge{GfL^_5&pWKQgdvcD!Q z9DBM*6C}KL)3$L+0h8edHGU7h5Rkc`>2qT+3B+rvOh8ecH&tv5)tKAhu3Jor1J1Z` zb)jGEu)s3(n@$Q2>kF={1k~%^W;v_22c963^itp)WbayKMeui%r6Admb3)aj^(@AfH0R92~6r8ZHNfYu(?ZZ@AsZ74i z!Jgu8>{vS~>b%4Z`ajQ22g3(-*B){L8TM?LNjI@pf5Wcd4*ZM0)EwRA7d90y*T0z^ z0J@j@R&QmhYk&;OETC5Cw#@F*lnvHq1<^_A(q|YJL#R6U%WReB`tO5Rm$E;o zM)TnkLqtCN9lyg1g(7j%0^zoSax-*Q(EC=a3r*7J_j(=TRsoiROoDGMo8(k)e+C+0 zJ%tXPf4T`3R|#fI+;hdTl3WfBr8;OuqbcGdQ2niN`KPnyW#ZU(BUZ{*u_y$VF8HWi zjC51CigC%MYf@#llq|0(LMGs!FuMG>x;=tCB;!7ZK<`+Kn|f%C0QT^;0EzyD7^OW- zeG|XtF9Ht1W-%U}lt56*?=|P5l#ivlm0++ae`)LwhF;htV{nfE!Owz@$pGUHk|#UN zs^E>AQ}M)7zd_RhgjGRVPjpXX8?I;hUd-z?fkNe(rdbB|CW~N>ubkCuKTP-`9R6CL z5ZwhBMEd6cUmL4wLn5zC^m^i_A=ND;MhLr}bGlDP`SX}$xUN}lvLL9a0||KvHfftF ze?;wsP5{0q@hmO*oWFOD@0Yx+J7LoDVIqvsY_!T9DXbZrIo}3aZX3vln?VFr=sKbu z9(E;!5ju$Y3KdgWj!Ibl756gY>NIf00bh$T0nJeEZXEB`;Cl!oIjfFhXUStZ(hgyM z8t@C3Kq~U+dx_T*pMkT|9LcIW%H4Bxe=9xudjPF|e6FBWqyR;bDdzq{*SeDH@x@8) zHc$BgUwD_6{*HMWX@CPb)oqHm-V1vS`eX+a;l@DXThs%kQ4P90L-*?lCme6c?#G*b zKccOp^Cm|U4i#Y(I6#*N6bx)?bx0~>5Zw?I4}h4TOkonni@!5}y9`u3`ZTKoe+%~S z>DH(Wpxig8y}4eJ)Hci44`CUx7yzk&cunP^zyx;>YKnc;NpCN$#ACtMA5V%efJFq zwk!ar@_Ni&7n0KK98rrADXtY2e|b$7)J#ndJ=WbTQr(KdQ5_* z*Oun=SAA4z&URQ37=*5WC?hpVYTFS4c^TdG^Bf*N)>RMvZwEAt-mCJhmBKr?kWR3S zX2+i{=m+^EI@1th25Vfcc~^xyz*u2{afTPjh@c`zC8cRf04vYXOaB3 z$rOEqSZS&w*O@eY$0J#JtRgf2qz{=Sx?zS}+sv~|gHBEOndHLk|9^3y_8RtWPjO-m z%5(J@!?}&d1pgM1>?Y6P5#%Nlv1+Py0e?$tt%uP1&p8M~I&IvO-die-+ssqYv3VGW z=`Z8uZQOsfibB)8IFa}he;jP;7J;MeU>s=bu)a0B+v8r&r#_r5d2yrSkUZTEfloAG zf;3^GNfR+F6J|BPk+KiWL7;C4pc3!VT(BOVrH{Ncv1g55BNP#x7qUr5zLEN$k-+=` z$b1VFb($c(fy&i^_mc;sJ)TDhG${aam9YrQ77S&;V!u9yFKx%@e~tliOnCzzQs!~s ze@{)+jcZ&bQ(xnmiZ}2)vM=`H*G8w5l(w1)mD0>c?_tkR5-&?yrB_)=c$%R$;G)Xc z0Mrt8-EJR61j@y@3%@7kPeqe8H;KsFvtO?mX=POrqw2T(fU2bQUc|$`S^)1Kg>K3+ zT=1%gUqLEZ9nkAOe|y&_llhF28&XJZ`c(^m>c|K5&BQtznReI;C2O+ngz+2@dl3fT zv~Ap~NFkV>`;={{bS1F-Jc}SO?2KTw0I^mrFHpUFY`Jdubu=kr=uBpe05;esh1s*$ z89e~ipUZJcP({Rm`UqKs@KPIK^$a!W{)S-rf6P^I@vr^Rnr+5FTbiY}WrMN0~B6)&@De*(8M=i>~hN9BbNNi-KU2-9rQ~Ve8Q9SG}XRgWq4WdFZ-PHPiSHW)w zc%`*vNSrSFe;sqKXf-^6@<4Qow-cs!8b3St*5bAlNECahq|*wFDWv|^TmBVp^U1Oa zpBqqgL=M?xuG)V|Y%hi&Y(TdUlw0~pD=&Z_FpCm9bWJ>8)XIG01y>6GR!k{Bhjj!} zGKgEsWY;E)w1F}QZTTGr&(G*nz~NbUAxarq`b?iVf9hX9jP5A;3ZDl%T$`8?z$#gD6@lpL33--$OrdI-5q@3NPPJX3*Vq&(%KEkO5LgeVxnbH()P^DwOsZEl3lJIF8EfSR31cvbncbR4m|vI~20)!<1*D z;X7P%HV{&zTw5Kf;}pBv|6OIO-v+jFHrL2?jiIi0_QBgyg0#4c59zMMQfHCp{J$%! z%kZWa2Lw(p2KYZMa&m+gsCXwZl$?|}w3!eRe-4Mh`kS&Re?yC|bq*ue zk(Xi)*G6RRBn;=Xm~)E<{gk!QhET!d<}J}!txBtpTatE9?LwypdT3KIRLx^d5vQ&U ze=s;tdX?-8U8j4#@LGkm7iza_&*IAbg=Dtst_-e%TcK1gAtj@R`6IkQ+bN>HN2>Z> zYL|mIv&I@Jv4pOWMPb!i9}VuJG%VyeW5fBU;z^~?@bmQ(Ao2o>4)OpwHK4+5m4-+P zUP2@b@kOH{wt$xk37{U%g`2_I?NqvXf5`d((qrPV{&>-K@?Iz#T#GGz=gn@L4i;3~ z#+=lir2az(3%%D?jtc0n3nvSKgqsRYzGbV+BP*XcS%yc8T&_v%Zkh`-5|ZM9?IC&Z zQ03@LCs~?$B+eAFs;}buWLXKt4>GhX9S@5J_D!95O8DN!N6b1L184Cjjx(uifA#uC ze4}<|Rk&-z0lSuZ-}8K?jrFmk@P~Z|beOBShPQ+K9oe#_Z{nT9^}+L9tuq$3(c7T& z?C)ZmU`K8T+k1pRg0}zXOzgAShDQ&mmN^XJ-$epD=##hN6`VBz57pfBpM-}s%H9Qc z@iLR{>zJ+Va?RG;uf^itM(of4e_}em6k$mm!ptui+1%^+VN9s*+=KMp4`XK6+;YYf zznH!qqlym<2jw>i<~qtoC6n0TrkHZ79Z_?W-EeizRYR(-GN?euUk7k>kccDwQ~)v}6v>x(gCI54Ny zGx{DqF7)#a$(X-}lOMO7Che6<-RFMu-~Og$@Jyu=Gyxs1(V2W6oYlA3$v)3lF^BJ_ ze{*&p0sQc9n-VU9e-P)ve?j&P-eiZd(e?826?5;`TJ2l8+u(5Q{{3|S9{b34R`gF^ z(dbE-N40N*Z_gH#0U}9J@lU7eIc-y4?Tt^telHvFqxGxM!`sEl&Epr!JG-T=7Cw*# zz#+l_R8Q)u14Bl{nPW<_+zwe3>1uWQO(LtC!k(%mRib!BywsT@e?5dTNVqSHF2h;6 zR;+1CZdWQ;uQ^b8Ll`VuDZn0HiG8{rOz_spNV~~97je$-A+6X&=Nw# zS%*3|XQgxFK!hmDUh#jT7Q~qMg29Gr2y)Wue@|a`6TPkRQfe#ipcE3pNq+tajWp^@jg5J#pM;*Uo{lj$-i82?EM(Yl$ zRR5*v?r6>o#d!ZGlq5rcK@NMNar0ic>k&@-NbMRm8fxq{E;$+VHi}GH<083)D6Q zUZay~0h!gxc3!n3X@W+Yt1Z9~O<2DB@lz9St(|vDw;zx|ioF!A>BJ}%!{;)v|8L%I zIF`=VT^n@_6{C*T*V7~gZth=wja@#EFTLZiegH)VRF!;nAl@5SCR+yt(pQ! z$Zw>KtXaf)`>0)Ws<;?}Xv2;CGk2bu?9unrB&aBt%sJc}OdYkGp;r&}(QrmJ4l7wu`$85ZQIM6C6o6&ItJMWCAdppQSEbZWB(RJ`ey4Ppnb*bvM!r}jDD z%)J|CeYK1UheEzJscki)XhZv_8KtNCcQs8oL&8u zCE)&YkN(AzktK*-nhtib_c3Q_Krq31y*#tFR%3W1@qrbw16O~X7gfB?Tv%;(Eblvtwsb#M!<#ELQ^_1D+#c#k4|k2upl0Byj|e80f&&>Imr6 ze~<+M^r-Jj785G7Q1NeZ)SYxEc=utYmK)axin1ay? z(HnTC^v($_s~<+vnKf07_~Ic^O2o?`S!n)rriIw|0<6xTy3Ilk)PVT4CnrCh?rL3e8_gf9lx} zF=lMM9}~EdqVJrA9=_RxndsL^y$BkVdqv*s$lUZNv?>m9YMf#mO{MOBDCH9)9<2S6 zcK2*H=BIN+Bfpyy}k&hib3=hTZjXcsaa zQ_S)nGcNXLkj{NA0F|0t>_6+;hQNuoCjVU_Xe%q%OtpEMn%Yj*&QyiQ&qox$Ol%k( z{qY608y(;3-&@seN$LB}%!*bL&Ie5GWegL|0W4-#LU%X0Fmzn8Vi1o|m*L@iFBr?w@P= z?0}xKN41X)^6L^I<3e3;3w6c}Cgr%Z(f=W_y}W~rIrH|D6G4@&f00hQs9>PXm(Laj zBqlpsaFQ^PN8~=2d_R2A6MUaT7A9+$;0OWQCWFo_R+mJ|6D7}mPT`2QrPx_RO+_SR z?jMXXAgObtX(G(&I*25ARh|`#%}32O#ko`&Am4noyjxT;!kD}ITwu9 zMy__eXzB-CwDG>6=6!1(ZSJYTO*V9=`Tt%`I!FIrR{}5~E`$Hsga7izqN77!{`ljy zD$fh@90Pxwh3LMN&dU%P&$<2AZRtWYkmHMu=x^YegbMhoe=?|PH(97G?J?+RLJpV@ z1Tzh=>B?P(PYqV^x87H7ZzBHwMe-dcUwp{9j;GC^C-|9;aj2!CX1hJ_ zp1D5sD_>)%>#F@60p~TKtF|YUbOPo(^_*98wzGhXsb!?0Gwnv%_&Z5#CiO!oSC@w(0@!G4^|GPv>5}c|I6Gr`2daf1kJXiXM8+i=*l_Za-qeuQ_MJ zBj%IqQ+4!aGn(G(I|s_IRxrcz`^1ccrtV>tzuwE}Ke|8S#k-WPr3TZXwo{e0Gw09e z15kJ;0q$_(1PW>4&7!my)bp{hlgIR9EPzcR{=uE$D>TWrY04H4WFAYs)F>y zQ&65*NGh-!y8pH~x|K+yyBrVJQ}-{8URjelQ8_^Ts1y6_43V2OEFjtoZ!^Nw{CCe~WElO*{WN`I|Ftp4}5xZWX^1m2%~DM zXU`{K&8mA1zX|330g`QX1!Eo9U)?N!(;LU5I+zY;k8mgl-5xd8EQ~t>bD!CWDk=n9(UD{q;wAAB(%W}dUF)jdN z3S{OsJ=Tt6%wJ3#%$`BbsP?f9% zwjGF6?Gh!ZGoyq4cS(p4$+KU#_g}y3&_Uwl(s7-9UND$}vmTV@P_id3P=|v)4!55| zva{efDncFb<4Zz#llc7fjUzJD=Zq!wv`q}UUQ zY8XE#$5j+?Y|;fb&6nk1*kg*Wt;aWdhBfq2O*)~Lu9MQEH=vk#_Mexxa`Hz5wu!4J zs6>C1^AMZBNV5$Iaf!l~i1m@g43H>E%R*Y9D|t}VECr-JaV*_W3((>;$5yrxq~zOI zRq!egF65pu>QGS%Qh(#!TkbkvMkyEzmjQ?(V@{OB)LMvE1KA?HdY<2aU~fS}XF6YY z&Xb$O$3ykAb`4@nu)Jw9v~^F3D@|SX;77E&>K6K~k;(JGz)aXc7O9R)*!MVFbjjG2 zBhT6W94|9z{Ub;G@cWlL53wY;HN+KYjN|u(xi5<2UD(X6b$?(UQMGdjx~1c6$OJF} zD+oEhvWL2wKeTz-aLRP?JnBkGn<36!=iLp`TEkABhOaSOuD2=Ugp-dhQkJ)#uXtsiHLvL;MYbM;moPN$y4~Q&vsjihE zF-5j{glum@=Wdlzk<;I*#PgI=)fBk@>V|~MgZc?1PR}HwNiG>`=$C9xPGvQ``C8`( zMH$3a@cI@?p0!nTHhaxQX~#x4_YUv73H;Gom$@((2!FKYB;MGYxS(23ZS{hxXcfnmUt!cRLYk| zehae#G=JO>MkG-WI!d@6Ig9kVy=(7)Jv zmMMi4;=C%YGy-xmGcwtb5a?qs(a->75(`z5Ce;&al#?$q!b8`?qq`9HcgVDS)-4a2 zN*>(LBcq$ve#tIGtBL1{yKQ-%>_7kZUmdE-S|wwkrB3 zR1tS|N)7qr2ss>H!ZZIM2G3!W6=)$^pB>c_L=yyUFw>fDRTAxBrzeqTNfn(7b~Vab zGk<2ltVv_M#Mbmb2p)NQoCBXftIvbqbWTBhwoe<9I(2P_mEwy0Z6tkpGt9h(#lNJs zs%k&n^>Y|+jGYdD;GYBH03_VX zS8dE^6vTE1rkiG6Pa*?h6{Kr0JGtDovst;u0hqG5fmN;DNvm-oIy9$V0d)G$!w>wf z0^p;cuLUxdG+=Q*o&}6;s!NJ)8Vt)h@MO%i@b%QOlZk_mvaR(bsc-F{){@=<#AR^G z=Q`GMUSNc)D90L|%EeU;Va9u2l)s(dQq%oS$~CxDxaB*IC?yVV5q5tx z*-}_J`@4r56J$Y?yA;;vG)4Ud(b3J33uA(Muq0@YhbVCpLD=EUi$UOW;5}U<8bO3st#>>EgYQ-YXSG2~Y>5WPeLkL6(H! z60dkR>XO*lt6OwO;vn7qBZLr0d@wHvW0H{>Jp^Vq_i%80h z^&e$@hd+uGKsnp|d!xOM#(#M?`vfEQ|4aCxWnHz6fJgVCQdBTDn-qTA_Hl)*a3B=; zle{s4%aVwT72Tr06Hx-c%%m@o^VVH~)u;??ucNc}GuYcJihij)rOtP|4M8+`^nM^J z(=rU)oW#3cmIbLDhit{|hs7~=vFy(2~esT7Uk-WMDg7PkY$k zx-$A^ThNI_x7O!vW;u7QkZx9b8mUPp9xp8eIyT^a6rZ;x1|T*Nk=czU{v=k4Jw~^h zkC?z;TVYvqadb{f3q$HbMK0$RJ&deFR=LL~3Ow+P!8;}tU|kUEgMD$usCl5HL3myT zO;0H;)9C&(m?HmqhksA^$KyZt@9dC%lE`)yQ0?wt|GEIK6=bDclQJ|}kO=DkWNcm$ zR7vQ!kZo8T8oD~haxefX73=Z-SYQO8P;CcmfKwQCH?SDFFe1g1rWXVea2soR! zm47i6+>XNfL;#J8tD3v>ikjQa?ZY0tFv*jxhb9H4B70?NR#8R8;$?^|#;NO5H!AWz zQt)f$TvdU69E8p?G$6GZiikghp;v1Q@96aE@jgyZsr9STC?~?@!RSm5uSE!lzCehGdMMYNC|bg!rE^gJgIqR zJN2=#8IqwdX1=j>atk#T!-t#2%rEVT2R(P$v!3} zA7pn7!G9?>6o&qFT7S>q$EUq8AouEG1dLIUdecveIx&Y>@H8S9n4F+j=H%y0P%KJq ztH=43)MBn^;f3?Fd)NU`1Og$dkBtD=x6gucNEFoc{WzaprVHOFwq{M|TMx9vW860T zQ8awi{c79&76o@fsi9_@5F_pvij`)j&vwOcrhh_-2^yT(7&q17Wo_ibKbzx3R_HuV ze;9}Fw}h~|Z0?-DX>Ph9!jq}wt4Iz`4k3%&D%Sb4LK?c>^K8$wtNG$bo0L)e=Op>^ zvt68SSR)=?`h62X&;sDdFW(Q&rDzgRHM&OA15vi=o9Pq>-9R$s{bat4Dm+69Y9zna z6n}t{nrPqZ2+^b4z{5LSsej^h%5Y{(zgIS#VR5sPus}=t;*j0CCU<0PoJ3-N*QQ?_ z&st_*=A*(NC?UkskBHyyZY35i@kHAa>W=54j6^)xYz_5!m>`xuobV{NjVByMCCJQD z2???)J4bHSIBA?cuRUA}4>3`XLEG?CpeeVz=!r_OCab58u_zEeD_)M?T zuM)~B?b#x|p=P9H)758I=MQfaqMDPbZnS-h#bmUb34~?_nU-wY9C|k&3Ov^%R1t0QAQu8hOtL6Eq|(P zMpcYBKdOd4jz?GUG!2a3LhkUdW3WOq{@qhay80EW2X1i=;3NC9URoM-R>URyUsrhZ zeaG<4eW$hz0BhbN(*tM0VPTARf2QA(oqvGGTQ$RWt(W8fbZ>vFr#&OF zGk_fj2CE_flaIAjm1#bMT~xPZ)(14>J`4u!`)t$|XpUCuSEH7GT1WcR*MzGiLljD~ z!RL4GsnJO7CXgQki@fXqqI<$>VUNOpK@0VsB@&2EO^Tw=tBS|f=-H55Mt{-+)9ImF zvv5hA>_+4tgw~KGIeiuhL^9^A;(M831!R5{YyIk|NCV!5DTubv$VueLdSFEW}@ys>br`cA0NFQok(rs0Vp=RF6NmR;fj z?xIaJK!0hC4>&kjF6m=8DwI1H>)H8e2jVA>S8Qv0lqY(HEW`|8+K{_3r!b5h3IAgG zdPLALQQRIxg!MaEQ7uUk8tn_yP0tu;-y{4W@Df}?vT!mQhe}vu+hetCqg9N^J({o!3;U}?k<4trR$F5S0S{r&1!;2aG1h(N-FlW@6x#9rP-mImJx(1BM@eFGJjKU?V ztX3akDjDl<*A_j`%W)^yVm?uY@~Dl!7)WUwr`P^n2A5}*CqDe%Jc}o0O0r2H9EDVVP61}j%9Hid4p~S za>`6dB=U)(kVyVq}%#4*JR3VGPC&&a{URdoPT9LSf@!bh z(v_%iSYKl=)gr(Sv`dFxml!=$JjR^|bSE}UmYdi($R6)6z;?7_@Me^keWXU65|rPK zb4lDnS%0EE6v>;tlc%OonBo{~llA`6+ka%w6?|{Evq|R1aZs*SZnwhhbAleh?h+pv zmwbq*mc@i$fzZpn%8sQ~2&Wr|AFoLrOq3CK!E1RmV$RtO0fIgXZVyCY#LP|$@l)!; zDz>qadV}=Qn_N17axSB}O(Nw*sqP)g@u7d#V}G7q-X8gzzLM9`>C(tAwu%NMV_!Vv zH<~0@tjCj0*Hjfg0==)(e0LHyM7V`ktX<~`x^{4VCZz%CN6@N1$5^?hm{BE>(3xgN z9yQ6ST41e)$esm9nAbrt$Ohx46-iv}9OViYDWu~sCfQ&VgEHMI8>%(Qq$?^?ZBT~0cXuzB84%*Z|32xm#Ue;jLh~!$iTuIp91w>*flHr=b7GRm~V^9M9^7pe9z>p!`XZ2QufUrGswDv zj-Jzk1VgrmogaE>2#+f;V$R^CH8iorN2zU+x`s%qBMTdL_ZB*i6H$&wx~^=6c7KZB zA(-KDSb<}@z0q>2GIs$xgov#6@K)?W?Id=lwj@EWM z-{IzoN0@_Xy<1<7^;%=3wg~(n)PGuowB~L=I;<$Ts$A8oaV;~^A+Vve9D=Wr@pgr# zyDzuCKL%rV5#-~BV=w2y!_k)9vCfEC@o_YqIaoU7Dihp)t6UgVRr@#1$(lfIQ(U7Z zq`N*4<0v?;2Q@nw9Qx8Q*-o{*+HJ+VsdzIGG-G&`VU~r(j%7142abGULJ8K)>qIV!rxw%(`<$ zQ@LS@U3qmnc1>$TOCi)u?sM6Ykvz!yGS59XP#E4tu?lz2__XIp3x7m*G>v=pwF>Nw z!+lBSewScS1YHItI&j%zat~l1&kl%Lex3HfejNqH?Pf|HFv|$B(LE#Qs{61Et5YUW zYNQ$z&M*zU=rW9L$!F%3hje`1vquQ89%OZNhpujOh+@6~?H62mI^tE>fiHd#T{^zf zJw3sZ_Hq9LweMhL>3@lS{&)2r-LjJTgc;*XZajz^y}HLHK|W}}2Fi4Z4J_PJB?P9- z6d405PUpYBg2c#Dt}o&pA&|#iWH`RVjx0}{>)j`&MR_hiXK$pkZEa0Hr)MyH&iC#; zjb=JL^4?RmDbb!M-20|d3|n|ddxH789xhKH-#sePu+r6vJbygG*dbsJ7W9lV{y1{! z7k7Qu>_g-xhdR4`^JRjoJCs?&{wcuNiJVU}#Mp-LubnK}kj?{xebufR@{=w@=#;%3)e-F>A z%W=&LVw)h}kAG(Wrxq-64|wfH$6mEO^IV)mj^tRK3%4yny~b@~mAWH}u#JJw9O`v@ zGtO$c&goF_cX>E%RQZGn=Wh zr99Ov-x3}$*S}IoQ8|KmU}KWORO{EEJ9lFqwS0AV(q#GJcz2MzYk4c6`8;CNJvf`O zwYb#|LAM;nXqJH9DvZ!E1rYei(Pn7TWYJhjKf((a1aWCHg@jkTV3!R4z=qR-yGPsO zvtV_>$A8 z4x#Gx0ab)u$xT!JeP@x^-CHOlhP3Wh1G}G_(lkr&R&GQ;ZfDBg;*%y^Mg!DE$gBUS zD#W#_Bb7w5($s+N_x1wV=pCT)AEV>*=oOwre}9NHMY7i!2v+?x8qt;;#kdZwd%Y@? zXPb^I@m~L(gM2j4$fr=LWS`Bucz#3S>WJYNA{mFSEGH(Qd{kw)^76X(R1c#L0&~>|n3y-`5AMNHCl3sf_=ins4Tj)*=)~_hh?Y(n&e_r`=(4M!xRA z*Z3lT{&8JkZU}ztaR>Q}$o%7az)L@#HM~#$fONk8>)*%i{nt<(bdT$d>$gOE?wO(f zSN?xLU!8Wbznsg^PxEg_-`#q($Uf|^k2dAdoizssR81`2zp|0=!0fIE811n|({M3cW}38;E{Fa`n21INS}%;<`%a(wwzmc9M(?->V6rna&wd*>mI+_hU>ng$ipH6t)t6)$ zRzKH3N43Dfp})ct{@t-%iHvmD{L)|;&x9?aUI>wi97*3HOkC4iqWu3G~xVwj!wMV5BP8^oVdx*f#4A-<74 z;ovy~tx0;Zo8l}wLhaso^S!Ks_VlbE8*~V2SU8VNb-Ee1#T=qbrZTt$^n0f$g@I+t z6>&;;2tm;E;b*uNwfN2xgr+N!{h&MkdNVig&V2tc$q=4*d4bT&Yy_?qK?$=VUR?zj z!Tod~kUIc70ssJ01^@s8eG>QfyrYVfm17|T@IGv_xnrsUfB!^KR&iB$_&rt(Tn1yW z0As=^_%I}(#*541VjUb5r*)$-z;2YoHfE^z?r582-O4;>tv8Kie{3qX%jZ^mJnYR} z6xx~pvK3x;e)PMW0fF&7rwWqyd^MC!?*GwECL;jm;tkA2ef^yvxX&%Q9GsKOql>zX zIZC_msqqL>2@;>-w>D41y9~3}Wk~}!!{~G%kT(G57XSd?Y5)KN%}aI`eWr>%9W@dF zAOHXWaBOvFX>M~|cV%K+ZDDXOYI6YaFzb`ES83J~f4VnAu_`jry`GN{c$CKv?@p@QLI^f{9kFgUL*F zlQAflJ+vVZw{lY;OhUc2QLxdB1W|=3)BIA#HLEFsi)%z+u6mYESlQtQJ%#zx#(U z>YYC6xtNzcB^xAI4kuI3%59qV?8izL_}F$xvs6GzM`HZFYLp;x(BO6^f6dTI`(Uq2qT^&~2B(~aqu?v7PYqlo zvqyVUicim;hN!Nk7R*`+z*2=>r9{LU<6PUuO)ApMHwIg$A}}*;L%)6-deKdC7Vt7%z4BcKa*%*9m9WNvq4TrOim6j! zih8n_{Yy!zq1;}353im+TgKNyv{}1}v#{N%V-fg@TblFqiA8@=2ngQ=g9-SG&My6Q z!3lrO`-drEHYGpyBGJhlj1rM(b0A(Lf3mWzrih)UGuen80UhZ@_Bv{yb-z90JT!=V z?gCh46_9w7Bk2OKKB7z+JBA7qz>Xaw92PfmHCbIqAsP+}ojF$6B<`pqUtL~E$Os3p zF+2wAwo_;?lof6M!4)^w5CB;tfwXeD>z&IsML3+I#??i0-y8Gd%w?r{OVg@zf9`iF zy&9~h1Cb4>tMv}!{~Vf~R@!^X?3^9UrWH0wlNgVuNx%KsD6G;%8;n^c7hxmy4l&fd z({%rBZHcGODb8T6WVt6WC}M4O2YSv&w_`KW*@ttcNnF5W)Q-a`2Vcj-!5g~bBt|8j zmY5AFrmYxfMZ-n`$La|3fu7N(e@_ao!>>eKb8jRmJfJt3%)071Dh?XT6CX|xokxC- z1|>^kL`e(Jkwo=F%o;6~eh4CA1idsDO2QypOK)heohu;dys!bXObR&^)`7-p!LxTy z)G`K^^G>%a&1&2sMkmdoKV8g#NA-h>A}NXJ{wL^he^jl(tL!s5c+mIF>AyxM zXAgBXOyKU0?UPC;F^=DJf3T$+#m~O{e@6cVkebY-?+(XZhVjTD-O3ShDIM^l+xT~# zl@eRQsI#Eq7mZ)#2Y9MizILtwlbeBbuvxlhyl2F}oEA$tm-37f+;3+^6r&=FrM()G z3Y~63thJJbl7}P@rgJvfA~s>CnPK>?xPeY!X-*jTx7Z7!EM|BV{xWj$i40Dk(X5tD@CNaWi=?O>otj?eXCm<81gmEytqjk+}; zr8OZbD$s_=Aqc7261hTJKI5fK!j4D}J+x$-94-K}-+&tv7ooOvAdoo#sR951sR951 y0(eM?Km47FldxeG4RdK{ZZ2?cX8^De$aj+=U=x#Qj}Ws)frbJH#65ceKnDP#%4-+^ delta 24483 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 GKnDO?>YgD0 diff --git a/map.java b/map.java index 84ed9ef2..ca34b426 100644 --- a/map.java +++ b/map.java @@ -48,9 +48,9 @@ public class map extends Plugin { etc.getInstance().addCommand("/map_regen", " - regenerate entire map"); etc.getInstance().addCommand("/map_debug", " - send map debugging messages"); etc.getInstance().addCommand("/map_nodebug", " - disable map debugging messages"); - etc.getInstance().addCommand("/addmarker", " [name] - adds a named marker to the map"); - etc.getInstance().addCommand("/removemarker", " [name] - removes a named marker to the map"); - etc.getInstance().addCommand("/listmarkers", " - list all named markers"); - etc.getInstance().addCommand("/tpmarker", " [name] - teleport to a named marker"); + etc.getInstance().addCommand("/addsign", " [name] - adds a named sign to the map"); + etc.getInstance().addCommand("/removesign", " [name] - removes a named sign to the map"); + etc.getInstance().addCommand("/listsigns", " - list all named signs"); + etc.getInstance().addCommand("/tpsign", " [name] - teleport to a named sign"); } } diff --git a/readme.txt b/readme.txt index 04950052..64ea26a6 100644 --- a/readme.txt +++ b/readme.txt @@ -7,14 +7,15 @@ Commands /map_nodebug - disable map debugging messages /map_regenzoom - regenerates zoom-out tiles -/addmarker [name] - adds a named marker to the map -/removemarker [name] - removes a named marker to the map -/listmarkers - list all named markers -/tpmarker [name] - teleport to a named marker +/addsign [name] - adds a named sign to the map +/removesign [name] - removes a named sign to the map +/listsigns - list all named signs +/tpsign [name] - teleport to a named sign server.properties -------------------------------------------------- map-colorsetpath - point to colors.txt map-tilepath - point to web/tiles folder -map-markerpath - point to markers.csv file (do not need to create the file, one will be created when you create a marker) -map-serverport - the port the web server runs on (default is 8123) \ No newline at end of file +map-signspath - point to signs.txt file (do not need to create the file, one will be created when you create a sign) +map-serverport - the port the web server runs on (default is 8123) +map-showmarkers - a list of which markers to show on the map, comma separated if multiple (spawn, homes, warps, signs, players, all, none) \ No newline at end of file diff --git a/web/index.html b/web/index.html index dff45480..7d78421c 100644 --- a/web/index.html +++ b/web/index.html @@ -20,15 +20,23 @@
[Connecting]
-
- Warps -
- Markers -
- Homes -
- Spawn -
+ +
+ Warps + +
+
+ Signs +
+
+
+ Homes +
+
+
+ Spawn +
+
diff --git a/web/map.js b/web/map.js index 5d014da4..0c30fcfc 100644 --- a/web/map.js +++ b/web/map.js @@ -565,7 +565,7 @@ function makeRequest(url, func, type, fail, post, contenttype) var rows = res.split('\n'); var loggedin = new Array(); var showWarps = document.getElementById('showWarps').checked; - var showMarkers = document.getElementById('showMarkers').checked; + var showSigns = document.getElementById('showSigns').checked; var showHomes = document.getElementById('showHomes').checked; var showSpawn = document.getElementById('showSpawn').checked; @@ -573,55 +573,49 @@ function makeRequest(url, func, type, fail, post, contenttype) delete rows[0]; var playerlst = '' + var numwarps = 0; + var numsigns = 0; + var numhomes = 0; + var numspawns = 0; + var numplayers = 0; for(var line in rows) { var p = rows[line].split(' '); - // Hack to keep duplicate markers/warps/players from conflicting with eachother - if(p.length == 6) { + if(p[0] == '') continue; + + // Hack to keep duplicate markers from conflicting with eachother + if (p[1] != 'player') { p[0] = p[0] + '' + p[1] + ''; } loggedin[p[0]] = 1; - if(p[0] == '') continue; - - if(p.length == 4) { + + if (p[1] == 'player') { if(playerlst != '') playerlst += '
'; playerlst += '
' + p[0] + ''; + } - if(p[0] == followPlayer) { - map.setCenter(fromWorldToLatLng(p[1], p[2], p[3])); - } - - if(p[0] in markers) { - var m = markers[p[0]]; - var converted = fromWorldToLatLng(p[1], p[2], p[3]); - m.setPosition(converted); - } else { - var converted = fromWorldToLatLng(p[1], p[2], p[3]); - var marker = new MarkerWithLabel({ - position: converted, - map: map, - labelContent: p[0], - labelAnchor: new google.maps.Point(-14, 10), - labelClass: "labels", - clickable: false, - flat: true, - icon: new google.maps.MarkerImage('player.png', new google.maps.Size(28, 28), new google.maps.Point(0, 0), new google.maps.Point(14, 14)) - }); - - markers[p[0]] = marker; - } - } else if(p.length == 6) { + if(p.length == 5) { var image = p[1] + '.png'; + if (p[1] == 'warp') numwarps++; + if (p[1] == 'sign') numsigns++; + if (p[1] == 'home') numhomes++; + if (p[1] == 'spawn') numspawns++; + if (p[1] == 'player') numplayers++; + var hideMarker = ( (p[1] == 'warp' && showWarps == false) || - (p[1] == 'marker' && showMarkers == false) || + (p[1] == 'sign' && showSigns == false) || (p[1] == 'home' && showHomes == false) || (p[1] == 'spawn' && showSpawn == false) ); + if(p[0] == followPlayer) { + map.panTo(fromWorldToLatLng(p[2], p[3], p[4])); + } + if(p[0] in markers) { var m = markers[p[0]]; @@ -633,14 +627,14 @@ function makeRequest(url, func, type, fail, post, contenttype) m.setMap(map); } - var converted = fromWorldToLatLng(p[3], p[4], p[5]); + var converted = fromWorldToLatLng(p[2], p[3], p[4]); m.setPosition(converted); } else { if (hideMarker) { continue; } - var converted = fromWorldToLatLng(p[3], p[4], p[5]); + var converted = fromWorldToLatLng(p[2], p[3], p[4]); var marker = new MarkerWithLabel({ position: converted, map: map, @@ -674,6 +668,15 @@ function makeRequest(url, func, type, fail, post, contenttype) delete markers[m]; } } + + document.getElementById('warpsDiv').style.display = (numwarps == 0)?'none':''; + document.getElementById('signsDiv').style.display = (numsigns == 0)?'none':''; + document.getElementById('homesDiv').style.display = (numhomes == 0)?'none':''; + document.getElementById('spawnsDiv').style.display = (numspawns == 0)?'none':''; + + document.getElementById('plist').style.display = (numplayers == 0)?'none':''; + + document.getElementById('controls').style.display = ((numwarps + numsigns + numhomes + numspawns) == 0)?'none':''; setTimeout(mapUpdate, config.updateRate); }, 'text', function() { alert('failed to get update data'); } ); diff --git a/web/marker.png b/web/sign.png similarity index 100% rename from web/marker.png rename to web/sign.png