From d151f988cf395ba21a4560f5a5c783bf2452a252 Mon Sep 17 00:00:00 2001 From: langens-jonathan Date: Sun, 4 Sep 2016 19:52:40 +0200 Subject: [PATCH] seperated graphs/cleaned up --- ...r-store-or-none-of-this-shit-will-work.txt | 2 + .../query_pre_processor/Scopes/Scope.java | 12 +- .../query_pre_processor/Scopes/ScopeNode.java | 16 +- .../query/SPARQLService.java | 2 +- .../web/RootController.java | 290 +++++++++++++++--- target/SCOPES-ENDPOINT-1.0-SNAPSHOT.war | Bin 20216993 -> 20219689 bytes 6 files changed, 272 insertions(+), 50 deletions(-) diff --git a/insert-this-into-your-store-or-none-of-this-shit-will-work.txt b/insert-this-into-your-store-or-none-of-this-shit-will-work.txt index 3ec2d63..c17cb6b 100644 --- a/insert-this-into-your-store-or-none-of-this-shit-will-work.txt +++ b/insert-this-into-your-store-or-none-of-this-shit-will-work.txt @@ -1,5 +1,6 @@ prefix mu: prefix foaf: +prefix graphs: insert { @@ -16,6 +17,7 @@ a . "personal"; a . + "GRAPH1"; "Graph 1"; "hive"; diff --git a/src/main/java/scopes_service/query_pre_processor/Scopes/Scope.java b/src/main/java/scopes_service/query_pre_processor/Scopes/Scope.java index 76811a1..ec05021 100644 --- a/src/main/java/scopes_service/query_pre_processor/Scopes/Scope.java +++ b/src/main/java/scopes_service/query_pre_processor/Scopes/Scope.java @@ -94,9 +94,9 @@ public String calculateGraphToQuery() } } - String clearMetaInfoQuery = "WITH \n DELETE\n{\n"; - clearMetaInfoQuery += "?user ?uuid .\n"; - clearMetaInfoQuery += "?uuid ?gname .\n}"; + String clearMetaInfoQuery = "WITH \n DELETE\n{\n"; + clearMetaInfoQuery += "?user ?uuid .\n"; + clearMetaInfoQuery += "?uuid ?gname .\n}"; clearMetaInfoQuery += "WHERE\n{\n?user \"" + this.name + "\" .\n}"; try { SPARQLService.getInstance().postSPARQLResponse(SPARQLService.getLocalURL(), clearMetaInfoQuery); @@ -105,9 +105,9 @@ public String calculateGraphToQuery() } String UUID = java.util.UUID.randomUUID().toString(); - String setMetaInfoQuery = "WITH \n INSERT\n{\n"; - setMetaInfoQuery += "?user .\n"; - setMetaInfoQuery += " \"" + instanceGraph + "\".\n}"; + String setMetaInfoQuery = "WITH \n INSERT\n{\n"; + setMetaInfoQuery += "?user .\n"; + setMetaInfoQuery += " \"" + instanceGraph + "\".\n}"; setMetaInfoQuery += "WHERE\n{\n?user \"" + this.name + "\" .\n}"; try { SPARQLService.getInstance().postSPARQLResponse(SPARQLService.getLocalURL(), setMetaInfoQuery); diff --git a/src/main/java/scopes_service/query_pre_processor/Scopes/ScopeNode.java b/src/main/java/scopes_service/query_pre_processor/Scopes/ScopeNode.java index 49c02ca..c26efc2 100644 --- a/src/main/java/scopes_service/query_pre_processor/Scopes/ScopeNode.java +++ b/src/main/java/scopes_service/query_pre_processor/Scopes/ScopeNode.java @@ -1,5 +1,6 @@ package scopes_service.query_pre_processor.Scopes; +import com.tenforce.semtech.SPARQLParser.SPARQL.SPARQLQuery; import org.openrdf.model.vocabulary.SP; import scopes_service.query_pre_processor.query.SPARQLService; @@ -14,7 +15,7 @@ public class ScopeNode { private String name; private String UUID = java.util.UUID.randomUUID().toString(); - private String query = "select * from { ?s ?p ?o .}"; + private String query = ""; private ScopeNode parent; private int scopeNodeType; private List children = new ArrayList(); @@ -103,6 +104,19 @@ public String calculateScopes() } } + // performing the scope's query, if it exists + if(this.query != null && !this.query.isEmpty()) + { + try { + SPARQLQuery query = new SPARQLQuery(this.query); + query.setGraph(instanceGraph); + SPARQLService.getInstance().postSPARQLResponse(SPARQLService.getLocalURL(), query.constructQuery()); + } catch(Exception e) + { + e.printStackTrace(); + } + } + // adding my own inserts String pullInInsertsQuery = "INSERT\n{\n GRAPH <" + instanceGraph + ">\n {\n ?s ?p ?o .\n }\n}"; pullInInsertsQuery += "WHERE\n{\n GRAPH <" + getInsertName(this.getUUID()) + ">\n {\n ?s ?p ?o.\n }\n}"; diff --git a/src/main/java/scopes_service/query_pre_processor/query/SPARQLService.java b/src/main/java/scopes_service/query_pre_processor/query/SPARQLService.java index 81e32d0..f5f3cd2 100644 --- a/src/main/java/scopes_service/query_pre_processor/query/SPARQLService.java +++ b/src/main/java/scopes_service/query_pre_processor/query/SPARQLService.java @@ -353,6 +353,6 @@ public static String getLocalURL() if(System.getenv("SPARQLENDPOINT") != null && !System.getenv("SPARQLENDPOINT").isEmpty()) return System.getenv("SPARQLENDPOINT"); else - return "http://localhost/sparql"; + return "http://localhost:8890/sparql"; } } \ No newline at end of file diff --git a/src/main/java/scopes_service/query_pre_processor/web/RootController.java b/src/main/java/scopes_service/query_pre_processor/web/RootController.java index bdfa844..e468b5b 100644 --- a/src/main/java/scopes_service/query_pre_processor/web/RootController.java +++ b/src/main/java/scopes_service/query_pre_processor/web/RootController.java @@ -6,14 +6,11 @@ import scopes_service.query_pre_processor.Scopes.Scope; import scopes_service.query_pre_processor.Scopes.ScopeNode; import scopes_service.query_pre_processor.callback.CallBackService; -import scopes_service.query_pre_processor.callback.CallBackSetNotFoundException; -import scopes_service.query_pre_processor.query.DifferenceTriples; import scopes_service.query_pre_processor.query.QueryService; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import scopes_service.query_pre_processor.query.Triple; - +import scopes_service.query_pre_processor.query.SPARQLService; import javax.annotation.PostConstruct; import javax.inject.Inject; import javax.servlet.http.HttpServletRequest; @@ -49,6 +46,208 @@ public void init() this.localSPARQLURL = System.getenv("SPARQLENDPOINT"); } + @RequestMapping(value="/users", method = RequestMethod.GET) + public ResponseEntity getGraphUserSettings() + { + Map graphUuids = new HashMap(); + List userUuids = new ArrayList(); + + try + { + String graphsJSON = SPARQLService.getInstance().getSPARQLResponse(SPARQLService.getLocalURL() + + "?query=" + URLEncoder.encode("SELECT ?uuid ?name FROM WHERE {" + + "?uri a . ?uri ?uuid ." + + "?uri ?name .}", "UTF-8")); + + + ObjectMapper mapper = new ObjectMapper(); + Map jsonMap = mapper.readValue(graphsJSON, Map.class); + Map nodeMap = new HashMap(); + + List l = ((List>) ((Map) jsonMap.get("results")).get("bindings")); + + for (Object tripleMap : l) { + Map cTripleMap = (Map) tripleMap; + + Map sMap = (Map) cTripleMap.get("uuid"); + Map nMap = (Map) cTripleMap.get("name"); + graphUuids.put((String) sMap.get("value"), (String) nMap.get("value")); + } + + }catch (Exception e) + { + e.printStackTrace(); + } + + try + { + String graphsJSON = SPARQLService.getInstance().getSPARQLResponse(SPARQLService.getLocalURL() + + "?query=" + URLEncoder.encode("SELECT ?uuid FROM WHERE {" + + "?uri a . ?uri ?uuid .}", "UTF-8")); + + + ObjectMapper mapper = new ObjectMapper(); + Map jsonMap = mapper.readValue(graphsJSON, Map.class); + Map nodeMap = new HashMap(); + + List l = ((List>) ((Map) jsonMap.get("results")).get("bindings")); + + for (Object tripleMap : l) { + Map cTripleMap = (Map) tripleMap; + + Map sMap = (Map) cTripleMap.get("uuid"); + userUuids.add((String) sMap.get("value")); + } + + }catch (Exception e) + { + e.printStackTrace(); + } + + String r = "{\"data\":["; + + for(String userUUID : userUuids) + { + r += "{\"user\":\"" + userUUID + "\", \"graphs\":["; + for(String graphUUID : graphUuids.keySet()) + { + + r += "{\"graph\":\"" + graphUUID + "\", \"name\":\"" + graphUuids.get(graphUUID) + "\", \"access\":\""; + boolean hasAccess = false; + String query = "prefix mu:\n" + + "prefix foaf:\n" + + "prefix graphs:\n" + + "\n" + + "ask\n" + + "{\n" + + "graph \n" + + "{\n" + + "?user graphs:hasAccessToGraph ?graph .\n" + + "?user mu:uuid \"" + userUUID + "\" .\n" + + "?graph mu:uuid \"" + graphUUID + "\" .\n" + + "}\n" + + "}"; + try { + String response = SPARQLService.getInstance().postSPARQLResponse(SPARQLService.getLocalURL(), query); + if(response.toLowerCase().equals("true")) + { + hasAccess = true; + } + }catch(Exception e) + { + e.printStackTrace(); + } + if(hasAccess) + { + r += "\"true\""; + } + else + { + r += "\"false\""; + } + r += "},"; + } + if(graphUuids.keySet().size() > 0) + r = r.substring(0, r.length() - 1); + r += "]},"; + } + if(userUuids.size() > 0) + r = r.substring(0, r.length() - 1); + + r += "]}"; + + return new ResponseEntity(r, HttpStatus.OK); + } + + @RequestMapping(value="/graphs", method = RequestMethod.POST) + public ResponseEntity addGraph(HttpServletRequest request, HttpServletResponse response, @RequestBody String body) + { + try { + ObjectMapper mapper = new ObjectMapper(); + Map jsonMap = mapper.readValue(body, Map.class); + Map nodeMap = new HashMap(); + + Map cTripleMap = (Map) ((Map) jsonMap.get("data")).get("attributes"); + + String name = (String) cTripleMap.get("name"); + String type = (String) cTripleMap.get("type"); + + String uuid = UUID.randomUUID().toString(); + String uri = "http://mu.semte.ch/vocabularies/graphs/Graph/" + uuid; + + String insertQuery = "prefix mu:\n" + + "prefix foaf:\n" + + "prefix graphs:\n" + + "with \n" + + "insert\n" + + "{\n" + + "<" + uri + "> mu:uuid \"" + uuid + "\".\n" + + "<" + uri + "> a graphs:Graph.\n" + + "<" + uri + "> graphs:graphType \"" + type + "\".\n" + + "<" + uri + "> foaf:name \"" + name + "\"\n" + + "}"; + + SPARQLService.getInstance().postSPARQLResponse(SPARQLService.getLocalURL(), insertQuery); + + }catch(Exception e) + { + e.printStackTrace(); + } + + return new ResponseEntity("", HttpStatus.ACCEPTED); + } + + @RequestMapping(value="/graphs", method = RequestMethod.GET) + public ResponseEntity getGraphs() + { + String getAllGraphsQuery = "prefix mu:\n" + + "prefix foaf:\n" + + "prefix graphs:\n" + + "select ?uuid ?name ?type\n" + + "from \n" + + "where\n" + + "{\n" + + "?uri mu:uuid ?uuid .\n" + + "?uri foaf:name ?name .\n" + + "?uri graphs:graphType ?type .\n" + + "?uri a graphs:Graph .\n" + + "}\n"; + + String r = "{\"data\":["; + + try { + String jsonString = this.queryService.sparqlService.getSPARQLResponse(this.localSPARQLURL + "?query=" + URLEncoder.encode(getAllGraphsQuery, "UTF-8")); + + ObjectMapper mapper = new ObjectMapper(); + Map jsonMap = mapper.readValue(jsonString, Map.class); + Map nodeMap = new HashMap(); + + List l = ((List>) ((Map) jsonMap.get("results")).get("bindings")); + + for (Object tripleMap : l) { + Map cTripleMap = (Map) tripleMap; + + Map sMap = (Map) cTripleMap.get("uuid"); + String uuid = (String) sMap.get("value"); + + Map nMap = (Map) cTripleMap.get("name"); + String name = (String) nMap.get("value"); + + Map tMap = (Map) cTripleMap.get("type"); + String type = (String) tMap.get("value"); + r += "{\"type\":\"graph\", \"id\":\"" + uuid + "\", \"attributes\":{"; + r += "\"name\":\"" + name + "\", \"type\":\"" + type + "\"}}"; + } + }catch(Exception e) + { + e.printStackTrace(); + } + + r += "]}"; + + return new ResponseEntity(r, HttpStatus.OK); + } + @RequestMapping(value="/ping") public ResponseEntity ping(HttpServletRequest request, HttpServletResponse response, @RequestBody(required = false) String body) { @@ -98,9 +297,9 @@ public ResponseEntity preProcessQuery(HttpServletRequest request, HttpSe Enumeration hn = request.getHeaderNames(); while(hn.hasMoreElements()) { - if(hn.nextElement().equals("user-uuid")) + if(hn.nextElement().equals("MU-SESSION-ID")) { - userUUID = request.getHeader("user-uuid"); + userUUID = this.getUserUUIDFromSession(request.getHeader("MU-SESSION-ID")); } } @@ -132,10 +331,10 @@ public ResponseEntity preProcessQuery(HttpServletRequest request, HttpSe private String getGraphName(String userUUID) { - String askGraphInstanceName = "WITH SELECT ?instance WHERE { "; + String askGraphInstanceName = "WITH SELECT ?instance WHERE { "; askGraphInstanceName += "?user \"" + userUUID + "\" .\n"; - askGraphInstanceName += "?user ?instanceuri .\n"; - askGraphInstanceName += "?instanceuri ?instance .\n}"; + askGraphInstanceName += "?user ?instanceuri .\n"; + askGraphInstanceName += "?instanceuri ?instance .\n}"; try { String jsonString = this.queryService.sparqlService.getSPARQLResponse(this.localSPARQLURL + "?query=" + URLEncoder.encode(askGraphInstanceName, "UTF-8")); @@ -169,13 +368,46 @@ private String getGraphName(String userUUID) } } + private String getUserUUIDFromSession(String sessionID) + { + String getuseruuid = "\n" + + "select ?user-uuid\n" + + "from \n" + + "where\n" + + "{\n" + + "<" + sessionID + "> ?user-uri .\n" + + "?user-uri mu:uuid ?user-uuid .\n" + + "}"; + + try { + String jsonString = this.queryService.sparqlService.getSPARQLResponse(this.localSPARQLURL + "?query=" + URLEncoder.encode(getuseruuid, "UTF-8")); + ObjectMapper mapper = new ObjectMapper(); + Map jsonMap = mapper.readValue(jsonString, Map.class); + Map nodeMap = new HashMap(); + + List l = ((List>) ((Map) jsonMap.get("results")).get("bindings")); + + for (Object tripleMap : l) { + Map cTripleMap = (Map) tripleMap; + + Map sMap = (Map) cTripleMap.get("user-uuid"); + return (String) sMap.get("value"); + } + }catch (Exception e) + { + e.printStackTrace(); + } + return ""; + } + private Scope buildScopeForUser(String userUUID) { - String getNodeInfo = "WITH SELECT ?node ?graphName ?graphType WHERE { ?user \"" + userUUID; - getNodeInfo += "\" .\n?user ?node .\n"; - getNodeInfo += "?node ?graph .\n"; - getNodeInfo += "?graph ?graphName .\n"; - getNodeInfo += "?graph ?graphType .\n}"; + String getNodeInfo = "WITH SELECT ?node ?graphName ?graphType ?graphQuery WHERE { ?user \"" + userUUID; + getNodeInfo += "\" .\n?user ?node .\n"; + getNodeInfo += "?node ?graph .\n"; + getNodeInfo += "?graph ?graphName .\n"; + getNodeInfo += "?graph ?graphType .\n"; + getNodeInfo += "?graph ?graphQuery .\n}"; Scope scope = new Scope(userUUID); @@ -213,8 +445,8 @@ private Scope buildScopeForUser(String userUUID) } for(String node : nodeMap.keySet()) { - String getNodeParent = "WITH SELECT ?parent WHERE { "; - getNodeParent += "<" + node + "> ?parent .\n}"; + String getNodeParent = "WITH SELECT ?parent WHERE { "; + getNodeParent += "<" + node + "> ?parent .\n}"; String jsonStringP = this.queryService.sparqlService.getSPARQLResponse(this.localSPARQLURL + "?query=" + URLEncoder.encode(getNodeParent, "UTF-8")); ObjectMapper mapperP = new ObjectMapper(); @@ -241,30 +473,4 @@ private Scope buildScopeForUser(String userUUID) } -// @RequestMapping(value = "/wtf") -// public ResponseEntity preTESTWTF(HttpServletRequest request, HttpServletResponse response, @RequestBody(required = false) String body) throws InvalidSPARQLException { -// this.buildScopeForUser("JONATHANUUID"); -// this.getGraphName("JONATHANUUID"); -// -// -// Scope scope = new Scope("test"); -// ScopeNode scopeNode1 = new ScopeNode(); -// scopeNode1.setUUID("1"); -// scopeNode1.setScopeNodeType(1); -// ScopeNode scopeNode2 = new ScopeNode(); -// scopeNode2.setUUID("2"); -// scopeNode2.setParent(scopeNode1); -// scopeNode2.setScopeNodeType(4); -// ScopeNode scopeNode3 = new ScopeNode(); -// scopeNode3.setUUID("3"); -// scopeNode3.setScopeNodeType(4); -// scope.getNodes().add(scopeNode1); -// scope.getNodes().add(scopeNode2); -// scope.getNodes().add(scopeNode3); -// -// return new ResponseEntity(scope.calculateGraphToQuery(), HttpStatus.OK); -// } - - - } diff --git a/target/SCOPES-ENDPOINT-1.0-SNAPSHOT.war b/target/SCOPES-ENDPOINT-1.0-SNAPSHOT.war index 61b478792da97e32a3e5cb6690c7d4f8b7e05ed0..3eac1150f1c158f5c2840deb84507f3ceca58a29 100644 GIT binary patch delta 16089 zcmZwO1ytS8x;AROxVux_-L1I0ySuxy+G52^ad&qq?(XgscefTV+|YCG`1k(rWsK)t zUuH5_!U{x~B=>O!t~6#A4oO)K5(*Ox78Vxl+Ls~@DHjrWsjV%9cz+Gjfeh1u1P4F> z-fJiTGyn$h0RRht1Hc0i0Ehr205SjtfC@kZpaU=fm;fvQHUI~J3%~>50|)?w03rY} zfCNAaAOm~^kOL?HlmIFKHGl>{3!nqg0~i2|044x4fCaz`U<0rNH~^dgE&w-x2fz#9 z1MmX`0D=G^fH2?_Km;HP5Cezy zcmezcyaL`Lf#3aDzd*HqY-h1G`2f=#~z6a5J5Wfe>dyu{d*?W9^5Aye*cn`|= zpn4DL_n>(X+V`M)5Bm3Dcn`++V0sVc_h5Ms*7slo?*fh(;NAQ0$H8pEV|H-*_bOS1 zA_*^B?t~p2C)*cjg#R}?45$>}tFC3B3P$?ZXmrmGuKKTPhvfhl&qna%0LKMQ=)!rc zFZ>Zcv`9@J8SAY%YDNn}fa%>DM5lE+zwIzF(p33wh)@$X>Yj7WL6L`nISMoIZK|B{0i z_|<3DuHN6*LAX^*EHo=8^w&9|A%^P_H$IlrCnI_27V0>SCJ2i-Yp)Q}{L#fV+uqee zh^SwKisW*e_L1Xj@xd)e7E`iq{08eWW4z(*6=EvqTwi@VN1B~{7NeRHh^1w5k1zhz zqJb=%z^814I_;OaYyAi#)fB5w)yS>9kc?+GGdcr{Pwp=zu1CyxCC*0<9j{h*=>1t+ z*K}0j^*v9Nup4hQ=DS(@3l?7c8}#^%yBpP*VT-(xOe!gbnABeuH+WP-3W_Ni94%{m z7Ip3|BlP0g^tTW4h88zEAgXGvNBj6G)bEvT~0UAb-$^Y4JNqL{Ub+C6*?F8*5qHmj5MYDgTh7#~-$m2iAEd>z=4)+PlFXFA| zK8zkH`|C6__H%S{&0wFxQ!2_GWqrmMs-!3G1ywL6NcZowGCP}&_R7e=7F}4g{lZHl zPz=^1&!wHQX26pV1)0r2%}uXT_E_{_eQ|b|DPhDbQQ@wjwMCHps21cPxBi#<-U_6% z5TWtK=6FnG=4`N+*Uh$w{c*nNi!@6s&vZsqSbij{A#S*dhudyK5r*9%#{%0vF-}Zq ze4@M#d2Gs9f*|7}GFOCc-;8pAmz5pO26`}ur~>vR(qP|>J;=+Fn!h(Zkj}xUgmW4* zlCpRpZ^WAc9d4jUvC)1~-Sm|Dh>md@S8jM-oNc30ozvWfhL@fA>?9>fAx&(AVy|a0 zUy@jbAd(rGqE)(XW6FN;aoasBPMjy*aBI%BUU3ggA$J|!q zcS2kS7DEB+eVtXsvMgS+SxbNVg3=Z+1Iok7Fpt4&&F_a>#XMD=LPOXXt9jdb@Z~*+ z$O1Ip0vvGWsm%46<8lSa2mYpuPJa^h2}k~wVbLSaoidE{trmU9IoDjO!XVEnM|?qa zdOS^M9Rf53*Vt4(Y})EyK=jQtRGOw#B0WT|{-TCfes!0lG77PkM7r5hij|255~aVA zfEd20ZP%peg@tM`p4xWmuAkFLKI~o%tVl4@cI_R!eOz z-XNpGlx(yJ8N9iyoYD~Td{B`n2|6J%)mWfRh(5?rgna^ajxLlYn)-@?Ee&oNtvG4F{{0luEG4#w0C?@$?Ga5g}0JG+d-7VQ_SFjca>Mcy%(wkoXJ6QJb)TNYy`0~Xet@!xMPV&x}4De~DtW|0flAUkj zpk_A;Sc@Q%LyJZ@yS-9qFrf?Z;G`Ygw^hMhEL8Iae{AB|N7s~9eVS%F{{f*uK3lRt zaca9&<{WaM%}wYjsm=DZ_4|i?6pfv+4_%z@jE+0^IwZ!FV@dWbo1JWj_Ea9f4fz~6 z=&LE#m(O&c_?6c+3DvU`0hOh&Sx7u{YqA;BxC3 z@eHwL@do|*D^7~Jx#s7aydO*=n`%w2V;|9YB#aWq;i>o%9%1hPD1;9M(Nn(pJ*Y&2 zdWE4$&(2uX1}a5eB1v|K7z4j%2UnFRfGnulJ67}!^aLvl3uOIk3S`+dN1}>CTYv1@ z`|!67(OBa`+D~uk>##X#dZ>Afl+hK`{V*O(9m^?PynvNuX^t?&R#s8fVJi}^T-z;c z)E2-*t)g={7%Zq1bHG=KQu%4i&`iVPIUWaY(m9)CGHxsWn306Hk0J1qFrakH4#F0u zzj=#7`aA_@tN-Aj8*X{+8K}5_ChkR%TJzxZ%ImMWc%0VB(!o~WoNRP;6^Y%|AFKVs z)&;?{u_B4xHCoM^q`(}*7--<{8jzNIH!F^pu!tJHRT1pVA1eQ>P*K0SV{}CTmY`9X zH#8d&QpWh8sjC9dm=wcAyKrVQ4%*>vFB%@3OJ%4NUDNkY> zi!yT^>#teOtX(y#3%zGPv{#;`^VFV0cGYj+FK-(fPXcxPk;aONN4+aOf_n}9>c$D` zHt1$&Hs4i_u}rO!^KcZ+rlj#$HS@D`ADjBSHV=jhzlVE;F$7A<$LZ0bq<{`-4KSl9 zL~RGGBS8~gwGU0Mk3?_83;nd^Qf7OY!QemQss=8vpTXo`A-S+3`x1I6+FO3| z)7IR78364GZ-3%N^@e2;d=j?a+uz>1h%O)VS$^PoaJDE5uah0{j0!ZO{5Z3r3r7zr zMwiLNO+8ljRhBWjmyK1A_5k!_faK80@+Ey4GEe+&+^uNBIyu1 zzR&zIJNEK3nE`1vwFX`w1t(iED-MH&BZKpwN1Ck@eIzt{SBbV0G3n;ETa) zSd)mV&AU&oHUo5E{v-^v-|LbizGzk7T~TAdg}m8bZ$2PJ3S0E`W$S=myaGdyQ#wko zDXSWFUr=6q``+pvHeU({-nOd++WXjGZTgL6$e}&lM$^mF)9vt2##BmhLlcmqBI809 zBpbIx7Pu>JQju2!qA$%Wf5UIGxkl+1jojMmT3T>)sY#G)@up53yZ+FEo14K${O}{j z_(y19Rb2;;@)_o(XY>xJ?qe2(iEjELJ6JD22BuUnJ8vwuAMfVZrfyZ<1qB5p1^L^j zuW+gfk?L(R9}{TeoYUzn)kH^x%o2)2F@L*?u67d_)=+==s_0_OZhpGg-8s}*W?AV@pGREBO{`6!V;a$C5bZv!str5Mjnd4- ztLmpcp2;n9-=b8FHYP$gG?zcBsb%>cMHIG`@*1_uX&u}N2^w^B@&y8dEZrECqJhkl zIY}n)Tl*ud^lgyT3}aXL-{{9^x@~GUJBwp0Xs_J-_dgMeXWP*m@F{<`z{Ho}(Y{>x z5Zd7ORp(pS)oq z9wk?{jDk-i{xe+7gcb1ws*K*+Fs^_7F)XOeN~;NeYAXb6ih_1>ji2@Zp7_69c%@>) zQK8$UHyioZVMmtEZN#jY;T5NE7qmx5juc}`#hvizncbVkT%L9~BZ`bnM-;R>sW!Ru z|Gu7E$owT^cc(4P%kTq3wvHE$*)jaXfKT1lGQUr~7#ML{8%Kj`%X1Eg&on3Pxp(!! zL#t_cHQq;IymC-9Bg#NA^gb=OyCgTV`ppQVzoqoRm-d^8;JnCqq8r7^Hck^gkLBUC zw5TMK+Ohm3-=!=>sa2;YjR*lT& zFsTD}Xw-@n${p=Xvo?f-pP#&}d^}1Fb6Tb_?ua3f&zC?;NIWQcJ%7LF7?u?Jg}kPu zZNd;D=PB}&HK=x3doG;?f0z?PCTw=qD$oT%eLF&`cb zNB8)Z;4UBZ`YE4Vgm6I2ATGxsH*$?n4t`yU;4Tb_yir{}15Wno?c9+@Rfa&-U)5|3 zAeu!y8MVIY6L^-ZOBa!sn4uh~@=|fNpa=s+? zyyTP*$+F)aVGr_bxy&KPe^uiv`8ZUh5qCOuooHVege2NjJ?|J@a`hmncZ|AKcg)>1 zn=5~MByK|#S|tF=n!bAK=JUtoc8Re;W;3F}?JiJYwRG4epJb#RTNelYb8e-p|J z)EDkr>YQ9YB;(4fSY0+8w3zEC{Ni0#k`qQ3pdsk~!Z$iWY~@H=eZfFtTb2J;)hEr= zsqM?1%z2irSMi;KThYbx5E|jK8wOUQl}S5aTSu5>0b|NB!^4TEwa=pC;bJqvWR}q@ zSY}PCEjO8AL}{|2XhFxM)r~E_!#utTi2Umz16Cx-9EE-?S$xdEc(^;1#xnSnXb1#j{8H>hpFLc2Q7;290w6ZVa9PD$iyk;=4YL~T( zMzPMkCNpsIm*fW9bR5SQkg+-7-mC& zYD-vINCK%*pA%hvgyxGmtR{Cj15#pP{!mvHeCq%s>7n|aIDcpaQo(!<<2Qvxt#QjL zBs$8X-=`1c4x>i1D`{-M=PPN&^oY{f+&$BZ5GN+)6LP83*&0;jl}svee1}y646RQr zebchYFrIW}r%X9ebp1mDLzBXsc5M?WU7Y;tR?KqmKM~j%S#QdWl!^#76uTuw8z#@N29SC%{!{hQ>-rE^4i|yhEbTy8LlHl zUjtZg=&}s;q%%Hy{e`$k?GSOwdrSUJZw=YfO*7r{+4Bq!o z(q;3NWpnWK12{|($xm_OtxnsJ?sf1UG8rV(VUE^Xq}3RsAp)3)ea0`_G$_D6T2R(w zhcF@gwS~C%r)kTVq&r+FcpMap@q$!ES^6MbF_mw$rYMY9G@~d?$OJ0P3>5e!P528k zt?A38WVbYXWp2~JC&wFN1@3&hv~bS3H~8=bxkovw)pgU8AY68uopI9Z4JD5x zsugsZpu4%ur_Nn0BwY+zSsYZ0iT@$>w~6hhNN^sD7OtgNwww+A1)A0@1lP`aDB?we z)@-2hQ@%vn+`uJ+4fIbQkJ9`~HeH%ZE*mVl^7X7H6RAoy_yVR@0RPA$G`(SuiDSL=+y9#V*W7J%n=5I=Gr3teBu82{_kl zR4NIiq%e5STL?<=)ThU4fe4{}u)jgYWJuvSn~-XTvP)~mT}ez$J+H{!m;9p`Bv9jU zXE>i7%Wrl>m7PQc?2A4QL_fH(^5{5;-D^J)5`I%sg!;fIWck^Mhy>}oe`T%EyKKyvl~+;SEW-gXengIn{LnpU-@LG_A;CBv8&0OjSBq#M9BdUzRApXwg-&t8X7i z%3U|@qU8HuSJFt9^wygUF^|1uO(ckGAHe#1A?#axo18~NMx|U$*`7+YXIWXa9Q{m0 z_p1Lv7PZ7i8)V8n^Qp@e5^1KA-QY@itjQUnas#S=4TZX~4^<8790XnvfS<+eCE$kr zgDq>pAPd1d(Ko3rrleLTkP8F%d1T)79D*3j78p8_$C2XOApN(IF}Y@mRip}8&}I*h43hO9wefy@qT z9A{3PYeZs*E}Ym_tXH<#$q&5Wt#AY2FGq^40x@ic_Y}@h_MX_*Nn6MD~m;O+a5El!jT%sBpVrmvF3ucHtJh@}vtV6gTqX<2Q3c)+7 zGnEU9)KDD;cdu5JA;YQPp`-OSzJaErO@ZZ!brqF?m#D(PrY*LVwsNUT$Aog{RO(<- zQU#q7`K}Wgf+;|vuS^b9n`MUlVdft=k%-YM9lc$1ZQ&`LC;WW-(xt&~#-`4nY+mKb z)lyA_Ez8S_4puAJv9<5`X{iZJ?Qmz$hgcDmbO<@c3?&|r?syn^Ox&43d@y!|*O}IM zi}jn(NP_u_bM(SWRPBEH)wA@9<*RBke3M#f=0m!(>fEBCG#dZ4*Oov&#v2~TlHyA; zSj}&ntCr4wloV&xgRz>wk^^rB8OfGr9iZyAE^WQb>C+2RnT_w+_|^o6@|yd+czQ%2 z0wdcsZ>!JE3}T!6cu!Ts(_R*#o#nqe%MZ!FR+nBj-4^s9yFPIDWGdh}AM&?#XF@~; zED_QF#wm)zGCA|R(5~&`v9O=!(uM4-s=Rs(c+DejMQ-{^teY zzx2}2{UiJ^NbA0tpVHYf13XmLSYpszUVmoMu~2SMeiTlBy`<982qLRm3e;6&g;EM~ zSZK)<`z!Whe0YGwf3a4RpK}R?u&>WjtuOkhzpJ?G$eqwMrvkfgX9H^#<_ug54_))w z?wyuqI^|&blV^@KktQt7iTTqD_B74h`tx^;5h&aIg1c&q47*tu_0Zh4DDi4hDlM$KLHs(i8d9T$3iRC`Rg&aO%`Z?d-T&l2thx-5#@y&h#UZ=(F375@%uen6g?rFDXJZ|?fq=N1h| z*K^W(YCc;3bLrF;Wn^kmN154O(<=L0gagv=R{Wz7ms=JNw4)-qHFipLY(d8gUNuE}P%NM^O!LElS;pj(7=Oku8Q;HTa! zW9d5I&-5ah6Ar~W3WeELkDKiKjVMXd@tZ%-WtVdu_v>z#I{q3U7;ItUEK@4KpL`MS&+PRG>LmFN0WCxV=X?YBFsqff5v~q1uPl5jIc#uG}o~2_waQl~|J8i8cK6v>{Nxi9r zU+(zvJ$1@HDLDjg4WI;Q2b0*`8X1CKn!a!cXn%cUz3PJ5nB9(Dfo(vmPVg>N53>-e zNN^?jx^o?|6vo+HLINYDYVu9#S++VwDA;+1o_$#^k!&GxnUphh-gn?Kk&lFH*OZcL zWL&m18OFg9k8SPyXRQO=8)UHqe6}h2+khiwaH6_T>5>lEwr=r`oh#oZ%H~W#)f_fm z{b3!m_QR@Ty8dI{STO7QWJ&5-uof3_)g z4#m=c*$(?w|DvLqDBOhrJ#SxG^WdUThkg}Yac5w4Z_8mwuASA7qNs-q9g}b}6@W{Y<;)I&-M^a$G(f^31#Q3^c?zEz+JvotB zE6zZGFl2_JtuBtNoT~jX9*O#6l5v0^m8fQF(7Xo+cI{UwSIwt~9`)57CpJ?Hwvh&Q zoU`NA`Htd_AswmCETmEId}FQK{e#Wr@!5`G2RSy`fwDC-xN>%GHseA+P#>g=oQR@i z?{&wvyL{LBNZpw;L*Ig!re`@P?&Lr{KVgCu7jxz$ZQ%r+*#QNGUc`4Sw)Rr%r6g~j z_+xp?CTh3vqee3{`h8JdqlOaiKuLxCjw2RRwtm1Ei5g*aAVJZvN^iR6i)8z&j z{gj##a}DreR(dmxU)L_SK_@rllcG=AlM|8E*@^;W*L$in&Pib7si98U3Uk^KvkCTw zA^3S4=`kvnmQD=qeWUQ$3U---iDQF1J$KrJjTAd)r?AEI3-RuXM>8YKP)e3gJXvbY z#Tl3Cul&dU)a#cw=9kx)ez`E^Rf2g$L^RbO`AZe9bv6W@Q(}PqHUd{hDB3#;^W3_| z%j@N8YQ>elvzOp@D5JMsV)=PxvQ?X{nU|Z#y0Fr^Nnz&m$TF(K}10_GRE6S z2O70fx@?*5zb}0W23eJxoV1WnU##fyFE|lw+y%EOJ5ro7CQGk5uM?{=b@uj*c~kCT zd6+5L)1XZr%&I$XazgDy!&O<#^S6Bez%Fr}u;^}KqjnpcP5V^0K35oQx2Kgx$TQBB zcU-<_tsCnkwA?uRr_F6eooQ@A(>u6)qJe&Hq;_^tf%T%|8;G*GVm*eL++f=7j$@_- zydwNFX#Dg${}W8* zhXd8@7VC=RC~^jeMR7yw@K>2i$F#^O8*5d~-5KX1)_7243Bm_Am+D^*qf9pUvSGBD zb!+qnMQ3r2YQ6wY!s%bx9 zYE2b=qZ^Xf*vrp3U{Sk>^HXS1+OQcF38^x9GMCH032qeMmgnJ6Lk^dWN3_O38*dfG z=Aw+ipc(@Oix3lM(~8;tsyiKSAAeADEu!s1H>*=v)AAoo=yMgG`h1bEP6hm>7?1vv z#m`iYk4UJhp33dvo7Oi8^w_i?KgiW%)5oMTPiqfU-J}=Cv*%kAY%R~n*u67HrV|>T zSo0M$(=)j8T@$o4mM(}}FH&lxQvwS8%|{_`n4n)kB2P<}{vR|hPS-a^XP?N_Hlh#Z zePVC?t3&7E927_Ud{B&%66cvO*-xPSJxM12sUD^6nvm!Z(6ULcw!uJ5<7PQmT+)eo9Uq@IJqrAI_vXCEEAc^v|?uUDuz86UB1DBk5^lJ`rHdJdS7Gd%JNsrXU zt+VDyljy0GOPax~-sNZK+tyC@{dH3oI&SHce(QSi^k*j}-;cd>_c$|r|CSt2%%LY3 zfz~NT0$7eJa;M;n)o+h7f8>Z%E~y793QsGQdAr8U|!8^p$!H)Vka|^5~rWXpoVWz#H-R@m2jpFvGv|PhGE%iq>b3%auOGLWA2e_6G z<&*ion{zCy$38Gt%!@>mKojrCO;>sr==^f53K;tcS8Ul%#G<8rW%ezUaM1tP)PhWvj0uj)rRk?X zEbYE{y3cs(VYsTc#^ir@s1Yywo^7BKMTxqk)>ohhGA~F`1gCyBK+kJWU8Si0U zuG1avf;W8O2n;PJ(BEI6cS8W@P4?p?9s4b@Z+nwcE;Cm^g+Qo)e~dO6ZI=5vrY4ck z;glm*dEX;VDYd&=^^UsaG`=9<$Gnl*-U|%*Vd=;9vTL{brr-pb^)z@;D<_uwv$9B2 zw0?fM03+hpbSm;itEpF^nTLjnt{xqYt$i0CxY|bvT`9xD^cG)i()_WkuzLYV$L#LB zSBt|M?Q`2F!X)>`r}UwkhK0?Y;)eaopSiJ7xj#J+=_%B?z8JqjY2MwsE$~(dh3UCF zD!lPlASKETW6%)vwZ47_9YWwk?lX~X;q_I%{;?l)CRhtldV5Ix#5+WG2_>rU;x`P7 z3tkQC!@YPQZHbc=p64wF=q{=Y1)#igL4{P_m;c+HXKMBAEY`N*3?sM z2W`}p=!w`dO5+=S{b(Z4qa6^ma-PgnM%6_q)N5TvwnPT;3S~ReMnbZmk&W)D5>Krx z#p|`Tn~^SKBk}?-^(SGaKmHodH852mYp*mV7cC`LEhYmY52VTP!Z#%c2jNN*KT93H zpnKy3-zAgLYJoPj>BJiNY)%%K&MzRo-S$8f)84=1@xmk|!5}Qz9~j%Jj+#7m>+YX+ zxW_9HsYa-=(-4p)P!(+j&y^+e({2UtWP8~S#)GMeeedAPJ5)f(EV~lD=#Vv|UTN3I zR#?$DJd4#<3*=}O6!!KuwY;})vx%r0$#&iM-4}o5QwpRusauWsfy!_HiX=&hPFM%1 z9K9seBTK>`*a8$|=UdCiDH_r&D2GHtdi@@Rmv~DqN8|j+qHn zF0r1cl>ihhOm#);(!jU|=eZbSYIo{axpj2Fz!jemi`duIShZL3z$}k-GpX)GMdU}SvuiLlZ47%mpNcy&8^LmN1 zZZ<)*#Vi$F z_nkKx9|yPwU> zkOSNnv|Jyvu5}IhqC60LWrh{`5FU~3dMmu!k-dw9`FH|0Em;^g^kIlf00%i5Da!ZN zQEuj&9NjNjib?uIytJeMCi;dXv8IZa3O&teMkyDaCW$d0>dP)$&nG?B)7F84qKQO4 zBC|`UP`oL3Uu<3e#EGKs{W3ZCK`sLYSfig zf?M4-+0E!8A9_R>Ay5|*cv0A`X1j5l2erlHUg+s{+x{x@@MY5aGY-$-3=?gh-<~G? zQNY$+gDZhKkR(1vX`{wczm@YebG88^BaG4E*nNVf3N{U7L)YlI5AXJxbMx45(Xp&J zb-ez25&I~%N`U3pX>{wcR1?Xce2TS56t(n%8Hy8Y7;DEan8jE8;IOLP3#@PF{2(Kd zy|Us}IR`}3X-9ELE)({@f8xv|tD|B`p}hqigE!!ghB~{052C+FKaYLWrxlYF+^!^! zI$?%2#)TPuQO%-mXpQ*3BjZG!$*+kTo)j)VCVsaYm{v~pQ4?duFz6deDES%n469Zjd{Z$z4L6k}| zBPj^gi#H2*-avuPK0s6X@y8{?WNs(=aM9Z3S(mZ#MJZA#f*Tt+;(1!BB9e($E#uQ@ z%3hYycBH3WG5FKyqv2wT1#N&NxeTP%&^;;0YwyfC`oFmfUMTz$TgD<)pY%#NQNcb_w(IY>X;DcNB5&bf(Lt2}xoCd$N+4GMe%9%)Yk&U8p zP^{)_H2TA3Lg(A3G#Q@WM)E!wmhn*M1nsCA)~Gt#sM_5WbA%Mre#I2>eCMILB5Zy4xp zx=HxzKFTTkZAPA6ei|PT^p27`!!zv!38~V_a6FYci@1s}${LIOPdO^)JL6z;beAaa z)06N3ltj`rN+Zb*d}_2l=R0(n7~gt?Z3d<~!zeUWD4b>3L00g%<|lkK)4h8NL;J6$ zKQ+ALE}#ts+k(eLZC7y#tR1VM6E`P>ibcd@M3g+hiKPF^wk@#=oxd&UrXc zXJKjWeXl)K=(Y2rk323!$Frb?;Y@CVzYQLnrsPc!EJsz+tCGU6)UnI8_O=LfRN^4K zTtkgi5kk511v-Qu?Rd`HIRo70>bPry-1n{05YBmHW67}d+#SNpKKiRkMy zW}%EN&rB}5wBA&&bA{RDY9hD!LIE{nBMQf0;k*v4H_!P+=Z(;AqNL-j`l4=b|zwyB0YEP1XLRDgCf5=v< zUYiqvnO=6^rQX=LNd2O~et#6YkG+uHJu=LwOwUumgTjZ&DoJ3B30*YIxM>Twu-zY0 zPj+9FOapU|`k^s9Zrgp*Fv`#JI^kUTO5bgU-R;ra^QL=#h66fv`56I(>Kk5WA>v=T z?^%B2E6ED7f~QB+tun@saboCw+Ehv?%H4nE286fw8*$wCMF;B{9s#>OHaU zFSt%8-Uz#V#Dl~zN4Pt?2did$TRem4AQe8LShUR6U&KUytQEU7vwXxo`S2Ty*T@?d z%Zn)yL!+3Cb2Hb(8^!&DhtLvq-QEK-zE1U}$9*%P0K{t*2Z2;YMe3i$KaWxfi0CDT z&W;=%bkYSgGSJ&R*5Cv4b|GKXho+h#g@>5w`cLaici|;HUeLQ#uk47rdNhc-2Eq_g zoN}%_GQcz}DH2Dhii@C&!%HFKd%v9LH|+3x2;|RLIHa1WO@x<;Iw|B9?by*gWX9Mv zkFqp?;vjZug$j1bnF6QqoE%jh_$aog=bQie2P*XVVDj1!teVUI1x9p z%|Bedd<&VJc#pekzIlz{zBl<~k5LdDj7|~(N-gC8l{TJ^(5n^c)g9wSBDYUg@}Ie7 zQl@$9ObrY2p5taz*!mQic{lde{A5C+1!XsUJoP$uIY8nz%eoau5$+NGYpU}0_oiM| z3nQ_DE-77~!RPgU)X9*D_h!azl=l(5FW~o_>GweT5VWn#U`y}~pMIXb*m?ba=}L(x z(7b2&chuW}-;v+0FC<)}JY#Z0EI)C05;1r}e$i;CAjORg)g2NYQW~ zA4Mu%7r#g4K3ztj=M2_<3r8qGRl!c!-|R%LNG^;p@CtUWi$%l0b*YoL=cce3d7z@pYN*H-0+uD0NLF=7(=97o1V6Wl^i*A zy=vG;1WQ+Zoc)%lD^}VjTS{ProdEIDcVknMo}Ow;yD76EElf5RwFl!{eIh~B%8RMSiX(FL`#0vK{ z%1`R6V2_5llqgpBGu`Lx#Lwg=Zw1ujUYFD}eP-A`Ij&5MH)f8i1S-CmY`*)T>RYW> z9K>rAER;?-TPyyU+XWAQCiYK~PX%-?zgj|_-p)(RUxL2C$KiH#7%Z{YgeroH;Aux- z?|tdNwGm_@Xl5XA84oVC;{G;3)KnG|fa>_WR5A{8Oc^!1SwpfV_EcL(1nLvMX6|1m zm19}8!dbSs!#^KmYYu*vQ8Xh+oFc_ifiNOF$4I!LE-{(v$pQIf^!x0=&QOdC#ho_1rQD1A&jic7$4K7(@Q+d|!gnS6^ zv9zslE4U7y{>!I3oHmby-kA~N4fh<<8ErrjV0aW{ALsuo2<*B;KI?*kY@IivPhjG! zyJLiv+sWJeDI4~L$NejC%1%c8|GPyJ&;IMn0sf)OOqK(D6Y~9mxMYJuXuK{%VBj+R z-($wvC(0b)RR128!%*P>7yDP~0G0E5)in-O6{P%pFYoH>4*b@6UgY)0L<%eupA7J&Qz_pOfe_ka?{MUQ& zi2p|y#Ox-Z3;Mq<|GAg`>jMBwlmCw{*eJ?!;1KX&|7V2xe>Npv{eKtww>PshfPG2_ zar&Q)(h$>{|FukxJO?;-cB$IJVEljj X!u?lY3%%^mz+wb2QF}pO28)o6@VH*1E2-a0q6k?07d{4fEmC7Ugqo0C)j>0Dgb~KoB4V5C(_rFb0?aOaW#9bAScF5?}?e2G{^>0d@d;fCIo0 z-~@06xBy%MZUA?H2f!2H1@H#=0DJ*{0DnLL01WsH2m}NHf&n3bP(TnfLXvCU>>jlSOhEqmH{h(Rlpix z9k2n|1Z)Ae0Xu+Qz#iZ?U>|S*I0PI4jsYitQ@|PE9B=`+1Y7~G0XKkKz#qUJ;2!V* zcmzBFo&hg_SHRzB;CDX`@D@;S@oy96t%7}vcW(jr7VvL@@D_+~f%F#0Z-Md_sBeMx z7VqEU!&{)g1;$%oz6I7>e0&S+x4?M|+_%7c3;eercniX}AbJbpw;*{7(zhUc3-Y(1 zcniw6`1BT3Z$bSQG;cxs7Ibex{}v2y!T1(TZ^8T)EN{UI*#n$0AiwXuod!UB^(kz>B2uOXdQ8AS>vyz+R%&f7!QYaI32VF7m&Co)K~^jm^2^{&7C zvwev+xcArj|7I!*%8Su~A0iZj-3$tuu&0C{qa+NmP8SCDkMZ;;4|5Oj@m?AwHf9fX zZ|t*a4-M6PS|YkdH|EOIy7vqB54>XxE~Y*`b{{-fN(fFKhTk~SzDSjF-xSCQ&L86W zNc#n-h%wD5y88uun(y8&1efMU|Ei>Y5h?up{(0{w_$Yppy?(C;Jh0yrD)d)Xtf$EE z@P?-=e>#&#ea8Fpp;_W@<&5J28IN3=g@*Q&HD&B?sBDeM`NA1IALShp_;G_6^%(Y; zXwW?SpK`kcHN|~(Mv1XTHO47xwyM5jrRXuxpGv+J$(8oiVJtpLzuz`~F%oFPa;OJQ ziTl=m)kD|p-3mL$VD@g|9hqdu0pzZtsWyo?TTuQLRJKp(Y*(j}pTo3Qf)#eOsl!LR ziUAr~vDW2b*>=4hbG!wsPQAj?!O^@?IyHk4GXj~+d8t-w6iM<=GvDUbC=x)bo+Vic zd0E|T*6H_@WEQl^by@YB_NpB7EU@3Eoq2i8&Z0^R{8<`Vz(k6R#=IF3rD?P}Xkp>~ z;lWe)!fYmRx@N)rlnGAsE!+gSKXZDVdG@3A{TH!TzjhE3G=n(KR+k!*N0`u1hWaj{ zdmUDyhR}=xH0T4@*0N*tTbs{LY|O75B8Cb*_*I4HzUs^6FhmAKC{N?XWS$=83(OoL zh~oFk+pS`?fC~!FQGHGVt!y$RI#y1QJSfrsq=>Dypx38a3lqd~WtC4iD{|R38CjB1 zrj*#xG05*pi$InXs-LMitNm;WhHlA5=Gd7zMRrT);xk|9+G|ilUmgE87SmM3ZcGSY z^0lCG0}(CVld4KMT-ZVrgU>!rh<45;*7TcqhD)z_3V1B^usYefIONqo^7TVW!P!Be z*P?>%;>*@w$(BW@hjkw*{Y=lE&mxAPb-}rfnkxG(vuRd8xEY)avuvb z9_v#AcL}5ODY`t2E>B79uaR+F@)5aptqj9_y3b&#UsoaF>Rz07ghAF{pi8>^RbB?w zA2u_oV2=`r=rX>ff6kC{OZ;ji1fwIPfVq?yU1BjEE5PZAJ(@M#V2e-$KJBAwjNAIF6C#NqA0`r!Six|M5qJ?*7Q|c7G_psAjZmUu zz#a>xV5AAlmMJY;#7m|rS5rv04^*;7zYf|RLjISDdoSxF^ zAy`SN^C$^1&badN`E779U|xMqQC!Z~vg3)X3{{z@imM%BUn2oqvQ3W`PSyH-P^b=9 za!N@h!hteUk>xx6NB3`R-O?d$efg-Lgsf}8iNdrjetu`&A49mD=CY;8CtJnE)8BVW%Po(~HPWV8fDPB9C?qLLhpUwRpTBaw?%T z(3mTIMcw)n_%u3y@cQy8DP%;gdvH^|6Yn#K1*g8S|96sgmFJA|)BHqi${(WS1)Rgy&K8V*6Q z*G0a;tq5#Y-5FJkFk1E(9^LADgzs8iGJ8+AZ&1(F9yo$K+U7SM&V(loqMY)S^-gW3 z53PE7d5vKn>*@v=d!0GYS*RsMY0uf)z^RU!52(Q#q-trtG`ZtsIdWs0{(e-S=SX7e zl=nK2QC$;z{f!1c7{`RQYV)Sm{5?%3H{D$Q)+_ezF4|?KuA{iL-6a^QCjZ8Trr!lV z&?-Wl9KGZ=c}>1rUe|{fpVhj_#nV+)Q+1C&S*{WdMo~M@L}9aq?S(u>Mt;3J zx7;kZbE)Ib!gHd9J1aR%%VzcZT=;_{2wR9;grzkC$1fgEJrZH|=;&n+s4 zm8;kHy{f#vKB2xG+RvZqWbB$8W{zM^Mj92X`7X`96^X4CTpo?x1s_d{tsn2gv(^K? z3+xD&2klPoPS2PoG>g2bMZ*iMSWHN!)df^=Q)UIR(L2CbS5k++qY`i7p*(~B-J@^w{v z#htyvM^C7)`Sl%F>J0RV+KY%G_>hL0rO?KURp;Vnpm6M0ZGX6Iq2w`Y^llU1#yU!SGL=)QnYOi+-i2=;+>zYE-wcAimk1n z_adc+nifO}Em*K2+eQ(D1q#IuyAZcxc~cpQ4A|hCw9r_fk}C8LVsoN_R~)cYM=B^E zi0s6d8ZTL!f11&s%-cYAA(v_|Nj5!&Oqi#*@3^t{?SV0(_CI%GT0S+;{Oy^lKi)O; zx2<)c%4w9=o64@QIWbf=a8{4F+gakS_H6Qvsp_Cm%h*m=V%bqBv+^Kw4P*$0X5`n9 zMn(+TM;OI@M$$Cvt?tMI_e9UX{FzKrR!_wyhJ_Oo(a+LM;Tvl%V|btb-f9%mIhr?? z{dG+8!}+!hWM>pynH_EXIXSgN3-oYK2ogWL`SOHedyvcDUC6oYr-B=`=7=ioc)68S zvl6-O>=KbPRdnUeU&=pTX7V7K;bI9vl4g4&Kh6oS=x;!WsXx+MhoZgJyQ-np1t@M~xv zLg9TUeI`?KinqJ2KC@)FXUHg6{JM}4IHvezV_7|>s&ro9IrgCPNcgCK@_rV&P9O3m zXZPaiYFAt9nj`>iO(Cm5Fi#K@c-2a9p2?qM|4jE=5e4dnf<+kjpt%;pm%L@E$}qpv zW|H)X3|nof2v2BG?;?0T?^%|S?cx?sD;eiGW&Mu*+WKjiTXx|D#Y;i;J8m|o#6s-M zv+2b=4K1?wB?ElepZy@Z35p~?=$?x{`@vt{z>pmfK)mu?Tz%SNRX7iVxpN_18|FDM z;pwAv6HJ9>f>I{#JygGVAfEBP$cED=g7x83@d&RdZM>nnDNQ>qQ1(GKHIQ=Flc+${ zj-B#7{3QkMKZ5ijFcpt4#J(ze|JhMyV)#e!HSBGG66M!N*FdwJRAE+X?2$Y@ieQ)c zXGqSBtj1R;OMfK`tgzzRFIQ;#kb6=0e+NgXW#HN{OFSQ@81-M|t{$v?QO!JTA9*@MHt|BR(+2nFS zxo(E*y?R`DvZB3u7(#*v(^e9*GqKXx&1+y>eH&ei1E*?h?~iVWLF}%P@L3v*Nf zm}ufA6_X?n&G%S*VDX;SxFrNt1*8Nu6(*U)bhdQVmKWlK%ya_XB(s~KaN{Pqpt^9r ze#)Og$bj{JG9#o5oaLW9fjJXgQBD9;F>Aa-;Skwq+zo#o%e&o}v9t1Dl~#za)X3Qi zcblslMp#XvFN*zTB*{&oz7^T121$sw8_Swc>5rP_KY4BZ$VUymEFkpvGld3ncK9JK zDHdoWoOeiC$~`J4mG$^W;I&!qGZD{3ZM*e(;&VafpNR`shvkm%zqqW?Je+C4U6Mt` za?8+rMO`k77g=(?qB7NT4GO1S&?EEp>ss?ZQlD$ao%CH8*d>ZYuuyW0u7>a-wfy;Tdsd=Tzd4|G13skd0 zVGjWpNY5#s`EkKP+EDs*zI+WNuTtuq@yYt@e0AdARbS6$C}SeSp4vx&@t@gju0(&i zU4MVM>C61(NAw*`>z#|{tjBy&jEKC=gz}vH2V6bAfpf2W+EX>I>1X#^1I4sW2@O8) z7u+<5HoV;;zKp`IeN+ktvtF<>y)K3G`00B-%Tjg+I@(+_ygX|%8C;X*jdkk>g8Myb zFL}CkBf-OWZa2iq_W}WVg~Sy_e`kM78aywCi{D3b{M`c&g7Llj!zu5Hq5s-$$`igO z#R%bF%0z0)xNH6Hm!Y{Mr6#KN^4AJRdNg*TzzVx>s=bLi6otp`WDV|8!&T9byj3xk zs@8lqD8DwwU{o_H{8^RcV?Ak+LfVLe;AI|5>d0nRLweoGx)F|wHA#xpWIbz<&%t@{ z8y`ixh=&3EM<(%)tluK}co;o<(IC~BS$jaMO`}L=UXAu)vbq3)S_zzaa|O|?GNo}+ zW@m#$eY?>Q9b$tdcY&sn@vznHWL?_*hCsIT|zACJ1Uyqv%dH$zXUTfWATQ1 zGm%N3J%&uAvG#V>ln8UvEw7V+=%^n7v>38x4O?OZ=&RE?k@4!kA>0XL#H%*9vXTWn zNRnIbGrwr1%dwvRg!TQ#;c@P8?mVARYuUxRPO`YJ7`$$u4iHl*)5_?CR>2Mx-4D=OoxB;iIYe<;|f`lWcH5ESgR zfrVUxXv5>{8hX3WJQOCfvlbJ^OSriAR=uY+xGHdsS{fNskR3)*P<5>7mhDwRMywoS znJ)EhT_7g}A4X~6$ZN6p-$c{R`tp^Bq_~o&W2#RRcBPz{vqp3d3&}4x^PP4DYLKQK zw*s}ujxwf=nW)%mUFuJI!7mT8fv_bbfwvFUr5G^tUAv2DXb}AZ7qPt{xqa5PeJuTZ`h%_R&xu#n zmTILzxz#ufxsdPz=!8it`s{H^wh<*}98HV<0q&+K!A}xG7_x=XtMOueVlqAZXxBen zE~OmAhww&p=*aqoiDJFz(dW}xoxxhEvD*=m;ZA*Y$MWs^Wor6-xUuMw63NRr^1~9< zO`2!SdkTC*CmEWipe`<)nx~@N zDW3;qnN<6YW!uq!!MR43f>9P#tOx2c?w?5=dqk>d$*q|#Lix670!!0neEAH@To|b1 zNx=nE6wu3JFpZ3fq4JU2Z6jb-Ut40U}wy{hS2FOc_cA4jPeqSl?`&6|r5`1O9rfOy^ z&d`3kLN+jE1yNQ9{Ip7(`&2q!MzEzm*IXH1!%It#ZehqsobJ-oDGCV&e|~Mo-B3t= z@@Z{uXbPB2^4!)|T`%U_s3vvS%fz@+TJKLaqr4sSl_P)+t?B5t6YI=Aug=!}=F#jv z9d@^kt4cIPj*Q4@ia9OIoQPP8He9-S%%z*CB2dTMciC&^GZ4l4Ejm_9pA^p%Yy6|{ z5e~VH7@HrXZW&j5cl1ZFqQ%WO>k?c=nwO|V<6CiraFET+ND`@*U#RTZx)AOhO*kiX z2PdIMl0(--lp)f1sHR^R^R?pqJ|9abany`Ro%bPo_vep#I#bJ7cD(9iq2bj1J8jv^ z@~STi+Oi&FHNre&uo8qj14j%MYrYw^)W3Cz5p?3Zv9cxCrrnId3-|Klnh)D)TeKVd z0;nD@hBO9V%0IgaViIf!o5{Edz0*u2P59oae`~;5<9@Kr@oks8^pzhP_0ToT81c|r z+M+NtdmSmS0i_o=idl@z%^4!E)B5^yE#u?YpSWtzua;aJ-1Y4ub}-XYaF@h%hN(Id zv3Ggv1YK2TQnWjQVYAt9#JAL}iMkZfL1niUw7*6)LlWeFpMOR)-|xj^&l-?Gtr+vn{lq5kYau@*Y$9*ffuAAZ92bY7 z*ivb#LC$(CdA1@+C|zZu&vW$S70JpR^O8f+XM7q57MnU46s@TCBKm<(AY--^Vk;Onymtj0f*v>HxB}totMRN9r0iyEs;y+R-U;tdmvq7^WfR$= zRcRkF72Hp-cfsMpCC>6r-%yrvp#X^=zD>eThINNTHI3`&j>rs z3B{2PX57QYu0%5k$K+KNOtl2Z>_oZL=j)Gxi=%AJ|V zqy38j&ueJRVqxagOv~J%Rr8%R&8XPDoirw{C2)Nf$C$M5o!l(;7rQ#>6Kw0v!YuzU z8$DmR@3C|>kRCL9qjQIuoZN#eJAKR@NJ;ixYTucq3zX=|6S=cnXUv)f7D|)z_q99I zV@`f(Q7N^{{{5k%Q{kEh<6eIB702B_s7dkbqqD?>Ba2H8{d6^6kC?x#RQhand7iGS za4Q%M({1HD`?t}VK9V+LRulg}C+8S3zm}izv(#Y?h*DGEXBrl}@2Y=`th9t={dU6b z^=oVB4+8y>p~uJQxtbCtBWcUZ9&cn>-4})c8Qpaq{KrWg9o^wN5fO6?_&kjtcd2`N#-WK0zgCjLFz<_(Mc5 zzS6w-<%HjQ6U}1d$YR$)7@DjL2f`HjW&|MK8R$8uQZfaMNGbv+b)2iJAR7)>rpg{w*?T zIm1r#0x|n#FIz?PER_Rw1qmQg_SqZIQMz8eyoYL!r;0DSZrpOV>_Yo_-%d(zH%>WEBw4n$} zdAiH(U-Nc4Q#LxA`+fRt>pPDkk@L$>(TP>Jc;vpH5(fB=JHR^%3(^!BTI|j}JLW%q49SWR>v;{s56a5J`R}U zOPKS<%Hppx@m>mB4`Ya6nsb5`Wa3T(h2gS;;D!*J=hCuIWDlaLF5zy(X=(@Jwy$r* zas9!V;2%}$6Wa%j&mUgX7Kuy4yQThmovPhXt=eAb7)&I&<@6eyZm8 zKfVW5?K7J~1;bb$SZh6N91pg1%hakY!Nr|e_O*o*=<78N-Wbg4lcR_JGEeR9m#^e7?#i8vw3kb3S5Jp_X!^9@!uz^y`8M@V&<%~n zMT3B#Ao+i$-nn_eOj|5>EEoidfb{?0Vr2u|OCT-=f^>$Sb;s*z2dXJZ$ei402@qs3 zbe`^D?gvQ_qz(AMVEC-^9x|Y8Tk^g>O8i-DP_g|X_j3K$B~p~1JA_r?bpKAUDMk)b z_|Q8EesF8C)c_@y110)?@-?#jm_RC)&RD+gyxu%RH#kQQEumpk7l@rO<pJhA z{vr)6-_Rz3M(>iadwds4*Sa(s$4E=HA{h+6H)sCLiCV=;7qBh(V`x-$ngb<##B{ zNhyxe%7>laLJ3VX(TBb}mc#p96x*TVm4{#px7<1>~Kmyoc0clVgn<=6y8U zTzS3u=+m1o>++6vfv*P@(0iGjNBP8SKC^LO?U)4Q?7vDRmKEaWwZGtLJ=wk|`WE(0 zlcePw><61rnPbD$%n~8o@d0HqWc+49@+(6(t3VLu=55;tAL2aXCn$^z&Ua*|Oyn-b z$hfy5tv<{ZJtUuvaj36ly>ljyXhou^y0YEQw1g>iKA|&UEX6%p*JMO!$(#A2kOdr| z#@oGzgN~m{4iQr*bAZk7kh(kjEA(R{R@9tM4?L~9p4UGs8_t69S1Lh6>iNtzVmele z&rLSo^mdkBcm!s9@g3gzE=GkQiyL99-tdsVtW}y$2;XXbNQseZc>6*vnZ&yRE_V(V zy`k*R*7PlT5EZ#IYyBQ!8R6xR%0*fuo68}?B7T#`dp>+bp|1(%NmhJ#dB|4=pUDP` zDZ#7D^xdEJJ0-oUpYat(o!c1|2wK_a_fsw)@g%ohtoHFZwGnvq-*qw2gubp5J^F^9 zJF1{sa5WG-k+8335XgpH2MFDR;v&9Q#i=4^estt(m55$hu&Lhz>-ed3*5AL5)$=Br zz>~TR&I{G6_-M)>uFZy6Zi#M1eb2+ey8&}F9P%uu)RE&xHd7UnN+caSJ8l#8)j;IC zbQkh%;6B#O>1jpFfk-e=M!fd(t@p8HzA(xpVd5=8;F}cQ_(yj2u8R~-(z+q6-E`4* zGImP;oqa;M)f_d-Bh;M|&cGWvBRyrLrSG6AJRkg!@k^D`wOk{sw8%SX`pjCUH5!~G z#-sx4oyq!_U*~~SX0u22@fF(o(-!}%8gNB$ zZ(-7J;bMkVa?y37rt&q0wr;|o=k0>AA_SG|Pf9`H&wS2{BUn=vc!=4mt-lpkH#588ry#Out-RK&@&>(8HN$tKC%^y zNZ3g9sz->L)7TRKhV6BGg3h>ua|=W8foK>re>UOo-@af9jFFkri}$x=yXUYR1f>SE zbdH@j4;sXu+zcDT{mi@u=-lI8@!!t4`Rvci=WxIkPW1mdbI z>JCGnxY&{w$cix%7Ui69-n$<6LX7tF;t8_kx@e@$QN8Sp!dC120n2o`WsX&Q@h}I^ z$V}bB;>apCLlwg&QDC+H0$^XEiinb(b){pWigebzPDFsCUe`4!8>ls{k>g{hlZ z-xA-U(R2joO|L2T!;O*joc*@QDlW3pFNvH8wS#nmatxRw)UqsP?c9~|RC-|^Bl)|! zp<>Hde$!T?I*lz`sd_y8I*nb&-?S(Y*gMA>7z9Tq7aRAO+uKt)aF(Z2>@8%j*-CiL ze`1O$Wo0RI*|mKHqlQEYT6%+#6SQZ3MNGQi*p*{LHjt@J}h zMTU}&DVPeDp-Erk{zy?fJ_eJM zB4;-Xuc?yt$ZHOFc*Q{`6^j{g3C$%@hkwqn$zk1*FHJoeXxH;m!IJ-Xo`_#SVAdDWLty~-4E z_Fziw6E7<_C0C5XSu%c$Knu_|Z-!(yRVD-j4NZ0FjN zlHJW76nxna;4BnWOv=$K4ig#j+rzRwfA5Jl`L(N|D(zKtldHDKWbS7#Cob3i9!*H` zaNw31VT%%`j0MA+qOUI9#F1+_8l{KUCP$ZJG+~W?jSlSf6L^fCn)qt}u4MFF; z${zupvkYJFB}mWE@yveSuF&0?XE&g>7uUJh-uRK7;ew)|(d;+F?l)|{SVxOeE~KC{ z)vRKZ#oa%aX6f&&O|*Beby@c){=p2kb*hp}VFS$=bP-Uj4u*F0XF-EuYpzQx4;+*m zmw#!OuWFs4g4$Vti$ROuWyZ6H9oWY1-A3IAd=~yk)XSw)O^jQCKUnUn(!Yb63NQuvwFs}^t2&tID=Y* z5)6W~%*#5d%7|#S2=aI6IyR!N#D{hrGFD!ZF8xn*>tGZ(EuIh7M_pg$-^neI2?#MF z*9gthMes}q+V0$9l+Kz^My^e&FPaAp5SHl*%h+%KnMY8C?%9FftN$!DjMb#9+kD4p zst=OsXLTqW#M2cnFBB<R)|O5>1IBG-_A&l7wXG2*_#R*F zTax)I2M#Uty1~0nQ7F`~;OrXa)OBf5&4}7F+H=`xzs$_pcjWpXSRY?{hz(F!G3;(q zA$Mj)GZ{^;5f{IRoiYU@X5f!S@HbN=vq~4ga~%WARLBUa(-ela(c$}o3&xV}w7#A- zo?nm$lsq`j|L8lg*g1js{gPvjr~mC#Xym*o+Lw-qG+R>o7+(ECnYPE2`5<+dAm*28 zSo~E8yR6lxfL;W>f^0gj(4K>Zjg2~Oa)m_L@F_IOd8k}_iO858X%CqFAKTg<$Vl|z z;>xTJ`(;((5qqSUefOcGnYCmgT!GfKIq$Vs75pB{CXv5hFsi|8=cvNV)`)Z#1@#@9 z;hIb!Inu32JU{&y?m2M1Qr2Nd&!iwKOcr^Hi)I!0L;Utf4<)gPa_Aid1TQev_^%bd zp0{ZREzH|eUeCA|2(sYcKW^l@=z<_W{afG51S-*g)fP}W{TryJ2ZF33`PT^T4}#?V zR|x}^%)crYs0{uMJO`>H$bXHiU=XAU>f4&)|6Og&mHP~WwEfrp4XE&;wBU1{LqL%1 zxo-=M@VS_QAV_Mc+W%~Pmpcx0q31>eU9?dA1phJqU9Rq@xBIFQg5J7R$o{L#325Ym z%BB3T#x5ohBy#Qr(1lF$c4YrK8I$|pmCv^#koLcxm0N>$s5D+lRAV>&^ F{{ummRA>MI