From b3f11ae715ca45b5c1b4ab015b0a1fdf19572987 Mon Sep 17 00:00:00 2001 From: Tahseen Fida Date: Thu, 24 Apr 2014 15:34:58 -0700 Subject: [PATCH] Fixed search query creation --- .gitignore | 1 + README.md | 12 +-- pom.xml | 19 +++++ .../AmazonCloudSearchClient.java | 39 +++++---- .../search/AmazonCloudSearchQuery.java | 78 ++++++++++++------ target/amazon-cloudsearch-client-1.1.jar | Bin 16174 -> 16548 bytes 6 files changed, 100 insertions(+), 49 deletions(-) diff --git a/.gitignore b/.gitignore index 539df96..3533ef7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ target/* .classpath .project bin/ +/target diff --git a/README.md b/README.md index af604f8..1a6605b 100644 --- a/README.md +++ b/README.md @@ -89,11 +89,13 @@ Below is a simple example of searching documents. ```java AmazonCloudSearchQuery query = new AmazonCloudSearchQuery(); query.query = "Dining Tables"; -query.returnFields = "title,sku_no,description"; -query.start = 20; -query.size = 20; -query.addExpression("sort_expr","(0.3*popularity)+(0.7*_score)"); -query.sort("sort_expr", "desc"); +query.queryParser = "simple"; +query.start = 0; +query.size = 16; +query.setDefaultOperator("or"); +query.setFields("sku_no^11", "title^10", "description^9", "features^8", "specification^8", "categories^7"); +query.addExpression("sort_expr", "(0.3*popularity)+(0.7*_score)"); +query.addSort("sort_expr", "desc"); AmazonCloudSearchResult result = client.search(query); ``` diff --git a/pom.xml b/pom.xml index 1eafd57..22be305 100644 --- a/pom.xml +++ b/pom.xml @@ -40,4 +40,23 @@ 4.2 + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + diff --git a/src/main/java/aws/services/cloudsearchv2/AmazonCloudSearchClient.java b/src/main/java/aws/services/cloudsearchv2/AmazonCloudSearchClient.java index c989794..6d5b973 100644 --- a/src/main/java/aws/services/cloudsearchv2/AmazonCloudSearchClient.java +++ b/src/main/java/aws/services/cloudsearchv2/AmazonCloudSearchClient.java @@ -184,6 +184,7 @@ public AmazonCloudSearchClient(AWSCredentialsProvider awsCredentialsProvider, Cl public void addDocument(AmazonCloudSearchAddRequest document) throws AmazonCloudSearchRequestException, AmazonCloudSearchInternalServerException, JSONException { JSONArray docs = new JSONArray(); docs.put(toJSON(document)); + updateDocumentRequest(docs.toString()); } /** @@ -200,6 +201,7 @@ public void addDocuments(List documents) throws JSO for(AmazonCloudSearchAddRequest doc : documents) { docs.put(toJSON(doc)); } + updateDocumentRequest(docs.toString()); } @@ -374,7 +376,7 @@ public AmazonCloudSearchResult search(AmazonCloudSearchQuery query) throws Illeg AmazonCloudSearchResult result = null; try { - Response response = Request.Post("https://" + getSearchEndpoint() + "/2013-01-01/search?" + query.build()) + Response response = Request.Get("https://" + getSearchEndpoint() + "/2013-01-01/search?" + query.build()) .useExpectContinue() .version(HttpVersion.HTTP_1_1) .addHeader("Accept", ContentType.APPLICATION_JSON.getMimeType()) @@ -415,25 +417,26 @@ private AmazonCloudSearchResult fromJSON(String responseBody) throws JSONExcepti if(hits != null) { result.found = hits.getInt("found"); result.start = hits.getInt("start"); - - JSONArray hitArray = root.getJSONArray("hit"); - if(hitArray != null) { - for(int i = 0; i < hitArray.length(); i++) { - JSONObject row = hitArray.getJSONObject(i); - Hit hit = new Hit(); - hit.id = row.getString("id"); - JSONObject fields = row.getJSONObject("fields"); - String[] names = JSONObject.getNames(fields); - for(String name : names) { - if(hit.fields == null) { - hit.fields = new HashMap(); + if(result.found > 0) { + JSONArray hitArray = hits.getJSONArray("hit"); + if(hitArray != null) { + for(int i = 0; i < hitArray.length(); i++) { + JSONObject row = hitArray.getJSONObject(i); + Hit hit = new Hit(); + hit.id = row.getString("id"); + JSONObject fields = row.getJSONObject("fields"); + String[] names = JSONObject.getNames(fields); + for(String name : names) { + if(hit.fields == null) { + hit.fields = new HashMap(); + } + hit.fields.put(name, fields.getString(name)); } - hit.fields.put(name, fields.getString(name)); - } - if(result.hits == null) { - result.hits = new ArrayList(); + if(result.hits == null) { + result.hits = new ArrayList(); + } + result.hits.add(hit); } - result.hits.add(hit); } } } diff --git a/src/main/java/aws/services/cloudsearchv2/search/AmazonCloudSearchQuery.java b/src/main/java/aws/services/cloudsearchv2/search/AmazonCloudSearchQuery.java index e0f4d8a..ff88251 100644 --- a/src/main/java/aws/services/cloudsearchv2/search/AmazonCloudSearchQuery.java +++ b/src/main/java/aws/services/cloudsearchv2/search/AmazonCloudSearchQuery.java @@ -1,5 +1,7 @@ package aws.services.cloudsearchv2.search; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -313,11 +315,11 @@ public void setReturnFields(String ... returnFields) { this.returnFields = builder.toString(); } - public String build() { + public String build() throws UnsupportedEncodingException { StringBuilder builder = new StringBuilder(); if(cursor != null) { - builder.append("cursor").append("=").append(cursor); + builder.append("cursor").append("=").append(URLEncoder.encode(cursor, "UTF-8")); } if(expressions.size() > 0) { @@ -325,7 +327,7 @@ public String build() { if(builder.length() > 0) { builder.append("&"); } - builder.append(entry.getKey()).append("=").append(entry.getValue()); + builder.append("expr").append(".").append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "UTF-8")); } } @@ -334,17 +336,23 @@ public String build() { if(builder.length() > 0) { builder.append("&"); } - builder.append("facet").append(".").append(facet.field).append("=").append("{"); + builder.append("facet").append(".").append(facet.field).append("="); + + StringBuilder value = new StringBuilder(); + value.append("{"); if(facet.sort != null) { - builder.append("sort").append(":").append("\"").append(facet.sort).append("\""); + value.append("sort").append(":").append("\"").append(facet.sort).append("\""); } if(facet.buckets != null) { - builder.append("buckets").append(":").append(facet.buckets); + value.append("buckets").append(":").append(facet.buckets); } if(facet.size != null) { - builder.append("size").append(":").append(facet.size); + value.append("size").append(":").append(facet.size); } - builder.append("}"); + + value.append("}"); + + builder.append(URLEncoder.encode(value.toString(), "UTF-8")); } } @@ -361,20 +369,26 @@ public String build() { if(builder.length() > 0) { builder.append("&"); } - builder.append("highlight").append(".").append(highlight.field).append("=").append("{"); + builder.append("highlight").append(".").append(highlight.field).append("="); + + StringBuilder value = new StringBuilder(); + value.append("{"); if(highlight.format != null) { - builder.append("format").append(":").append("'").append(highlight.format).append("'"); + value.append("format").append(":").append("'").append(highlight.format).append("'"); } if(highlight.maxPhrases != null) { - builder.append("max_phrases").append(":").append(highlight.maxPhrases); + value.append("max_phrases").append(":").append(highlight.maxPhrases); } if(highlight.preTag != null) { - builder.append("pre_tag").append(":").append("'").append(highlight.preTag).append("'"); + value.append("pre_tag").append(":").append("'").append(highlight.preTag).append("'"); } if(highlight.postTag != null) { - builder.append("post_tag").append(":").append("'").append(highlight.postTag).append("'"); + value.append("post_tag").append(":").append("'").append(highlight.postTag).append("'"); } - builder.append("}"); + value.append("}"); + + builder.append(URLEncoder.encode(value.toString(), "UTF-8")); + } } @@ -382,75 +396,87 @@ public String build() { if(builder.length() > 0) { builder.append("&"); } - builder.append("partial").append("=").append(partial); + builder.append("partial").append("=").append(URLEncoder.encode(partial + "", "UTF-8")); } if(pretty != null) { if(builder.length() > 0) { builder.append("&"); } - builder.append("pretty").append("=").append(pretty); + builder.append("pretty").append("=").append(URLEncoder.encode(pretty + "", "UTF-8")); } if(query != null) { if(builder.length() > 0) { builder.append("&"); } - builder.append("q").append("=").append(query); + builder.append("q").append("=").append(URLEncoder.encode(query, "UTF-8")); } if(queryOptions.size() > 0) { if(builder.length() > 0) { builder.append("&"); } - builder.append("q").append(".").append("options").append("=").append("{"); + + builder.append("q").append(".").append("options").append("="); + + StringBuilder value = new StringBuilder(); + value.append("{"); for(Map.Entry entry : queryOptions.entrySet()) { - builder.append(entry.getKey()).append(":").append(entry.getValue()); + value.append(entry.getKey()).append(":").append("'").append(entry.getValue()).append("'"); } - builder.append("}"); + value.append("}"); + + builder.append(URLEncoder.encode(value.toString(), "UTF-8")); } if(queryParser != null) { if(builder.length() > 0) { builder.append("&"); } - builder.append("q.parser").append("=").append(queryParser); + builder.append("q.parser").append("=").append(URLEncoder.encode(queryParser, "UTF-8")); } if(returnFields != null) { if(builder.length() > 0) { builder.append("&"); } - builder.append("return").append("=").append(returnFields); + builder.append("return").append("=").append(URLEncoder.encode(returnFields, "UTF-8")); } if(size != null) { if(builder.length() > 0) { builder.append("&"); } - builder.append("size").append("=").append(size); + builder.append("size").append("=").append(URLEncoder.encode(size + "", "UTF-8")); } if(sort.size() > 0) { if(builder.length() > 0) { builder.append("&"); } + builder.append("sort").append("="); + + StringBuilder value = new StringBuilder(); int i = 0; for(Map.Entry entry : sort.entrySet()) { - builder.append(entry.getKey()).append(" ").append(entry.getValue()); + value.append(entry.getKey()).append(" ").append(entry.getValue()); if(i != sort.size() - 1) { - builder.append(","); + value.append(","); } } + + builder.append(URLEncoder.encode(value.toString(), "UTF-8")); } if(start != null) { if(builder.length() > 0) { + builder.append("&"); } - builder.append("start").append("=").append(start); + builder.append("start").append("=").append(URLEncoder.encode(start + "", "UTF-8")); } return builder.toString(); diff --git a/target/amazon-cloudsearch-client-1.1.jar b/target/amazon-cloudsearch-client-1.1.jar index 318a9af590ba769794664977f4f86867fc997116..f03c5e38caaf7883dbf7515d551dad64a05560f7 100644 GIT binary patch delta 9325 zcmZX41#BEjkfmdcIc9cZX2yw`nVFe+Ok}OI1?8(yQ?=3iyPgEC&ON1oiKL@l8OXf`<03=XggzrS?t}5Aueus>6bUqJ;>4 z76LcxAR7N(NdNEySW=JXIuGW-KnH1wqQNU;V8V)h#+2_*_y%ipk((|wx@}H9)t6u0 zV%XdqcHbkRhYV`Uix022W~tWf+_-e~Tyt!-Ydx#!Zdr5n?9_XF>;|yQP;-{uk9-_- z|M7eL>$m0Ob+0r{f>5Vy=vgRSH?m3cI1J8Su2KFO@fT*tnjPQsTszNmi5#q!>!-mv zSLK>*Spy&jk|Xj&!j41F3idjDR?G>?|;dZIrrnxJgjo>%9+SsYk!Xg%XHfSDzvO2(Idd|wOnSRQpQuyM6=od6>y zDvh8GFAW!Tii*%IuG@u?7t@Nh!=cNrr;(@eCCbRI9a@`9mC+D1V&&8F$V+2#xouRA;Q?M)H!3_FO1djc<~A{1%w~LDKU(HstQ{&RnH{2OBSI z$>Rni&vlxh`U$kE4*QGw^HkQ)OMbBE4Jb_XcYfnSzAJ1s)(X4G!gzaHqeIo=GYI)G zS6*IY>MjAuZWp);F{W&L5SS`fq4YyT*Zg+5b*!K6wj1GbYv;;I>;WBN%}5eTk2n9721g4x~726&D93G~2RAWuUHPJU*ZJ^n{t4w#{IRsJ%0n1cBUOT_^Dt_Ls2o-YCVtmTjS7b1-iN#t>7GLu%J(Qk&z*)U5s z6L5F;|mlU^9Z*mWE0*Y8CQib~SjkB&S)v-D> zqIGR0V&c)Qeo41EIkLk#2ekV;c~}$$JMW%)l+3yn)Kfl(^NJ9r;}WnF`Bcu}F@A|_ zf6O>6Ubmi^deoy1NQfD)&F2CXhA{$f%8-9sAUV)h8djhc@Qw1=KQ1j6l}P19z+_U!3^D4G1K zg3PmL7Fa&oHs4U18!_fcgAqyT6@R3ml%$5}*hjPR1UpI6ZGsBcKONj*!cC>bbfJ3DhxrI*KQH6Exf5URMlXP0qlssuA2NiKsa5%SN$R6DA77T#xbDXp?gO zbv(KHjr!qbfeuVeKc>@${)mN_xmfFD=iqp1Yp~?vRpH5N7kymcY4dvnG}AAZ;b}3^ z`JkNpNr}rNH$>`+_BwUQF~%&@vQ~mD|;Zi zHgEVaft*zwmNa#m2^ZE#9Z0BC<$ewF6iB3W{lZaCf(z~m7h@!13quv5&dobs3DYf-TJrpXygZ`Ap3gnvKX!;?iw|WO-yF)TMYhy$j%pMYN1ovM~8Peblgs z+)g)Djifis)b#@o(F-7;BFBgu)693>wy|f8yp&P;tTxbNx>NZ?s21I&C(nCZS(Q?< z*nUCfI{=PJy)EOHx7fky8p|SIbMsd2m4C#He9@ygcPS4udrYUk<3g_8(+l35xf0cC z@yyoB_B7iJZ6V##6#lU5n?oc?_MNOo08=a{wfjG*KBDJdpZIRQ)R_&F7?HOuSv@Z2 zhfl};y-WDHgm-$P@YKR5m>K0kS)+68>IPx?5(9=6^Cn9-LJ~@R+3T!0*g{quUudZ0 z!QH5KfRs0F?MXOi?JI7GdnqZ1!^}EQ`5htLnJj9ZH6Sy7@$QOfskc9jgPU@hBIG$^ zw)_>LgtSL8J*s4L@bSuwuQbIg8LwoaM@po<{1GGIY)OSvJ;~-!CwEOfw((T{Gm}Pz zn-F}?IHdQ~{{0PaK=Es~aw>h{N8J^}YiS;+^@dtd!)S4RwZhJ6hX>a`YKtIj*&Zsg zy(sKTq3R2EFgXS1w8_LArULauv!l13AdIw%y=pEM$JekV#4#%$;4m5!EL(b@}kDRpv|d zcNZhdjH`Q_)ZNO88_(O^mxqTJjY`Q!Rt=5y3rn7wz@~=3FInPFoMq?9Loe>x2Dg4E z?7|VFZ2oXCn6qhE8kBE-j^pln3sOGMwy+q+(R$ zQhvM*5uI3;x5&MDtP+pV3vDGyRD(Z_kHIgAeu8|&v6m&uo%W=xz)VVzc6$tKz~4QU zdjc4?8Ue|BHh7CFPJW+@G!p5u#w_sQlYHj)^i>V_o{GgO_j|dNtllPnGO*gO%nr>Z zmhzhsb6nDUfBs9o194Hs845Ko4TshNzJhu|T}X?6j~@Lp>)Uf_tZI5FFiw7{RfF(6 zVLol4oB<`(JT%0DU9Ik6@K_)pA%QbN%JSp{B_&VkP@5gOMm3$ms^b9V!2w(tq76(r z8N!_9hG$rmuX^0(-q0P|RIBhhUaZLBs<3i+r*HHSwY3T3CA&CkTx@JfHLjeP{Te++ z?yW?1T6?6^@R^x}sbwEpN7VDiJ~+t5Z=bZsw0Z3<#$xW<_`2vUM3PY(n9peCVvPIi z!Q;DlemMmx1Mg5bo=K2ih9vm>AW$!ZgNtV1vI_S=jhdl&C~@KC$Bqewb9qU(-l93{ zx^n4Pw)7qgARG5_jvS-Sya4lM`{2r1z5*?GhQ*G1(Kk3Hy|1D8M4Ky0qmN_#l`1{e zTCAxr-V%*4`U0ePw+g7;N8qLAsO&S}+Q^#?;BSi2PzG_f?>n5s9 zSjw~yja~%kpP$Jr(;vJEf|i!#gyZ^wRnzY)1>=YEg2pm<8T<{|CHsa(YOh*JvdSK9 z&2ubXr5@UIg<&IS{q7((o{x$ISk}6Sm0MKx7g8zx9NF_ zP47}{OKA-{QZaEh3k7FeZgkELjk(z|=;*FDWIEr*t|X5!Cow!x3jmu-a%~o{#{|ts zxquF*fov%JC{~7Bik}+<`)7tkMGpMCsdz?W${8d}@`bEK(P?6+8sr3RN2RuJMuwNe zsX&05KOEn;Oh;+Esv+GXp%lsoCIv% zn--%RKqVv(U5Y&c-&Xp8zl`lLLJuP_>qha@49=na>d-R5;!8qCiUS{&#@)6aJa^X7d^Hoc=xBCTy}q zmi7|&>PS^y45k%E(-v8A$mW%v&nd$IIfVYA2&HqCKbl+kgOz>b*fe}T+Km&2V^mfr zC&xl3$r7xSx!|y9o$~dYoDXq|;2w$vfM&8GS+~ML-h%r7Z=IExudQ3G;c;pTFmdebIvtpTiwChF#9tE zmnrKWCE$`;sFOk@^Y{|v;7sOrL51s3r6;~4g#+wvS@Y%o$}B(OsAw_`5bS!Adb@UJ zn}#2SFjLoF;s`a4P!H4&v60+oYXHUWkwtn54iBd5XjqzZF>_mL7^4alQ`Zbp6^+r> z&6Lep^0pF5paEObwthvEHxK_rE6BGNQoO|_5lh{cu)ip)ELW;5g{;9ocE3UNC6HqZ zIKUHLFYprGfh(Y7Ll9il6(RcQ8KB2*f_{C3vpJ^!s01fRp}1u}TokrpShhTn8kP8* z7t!e=%k z9FA=Cfj|0uzna>sB^ZuBLHAlxg2l96Q-<$6Id2}dqlLb7f)%9Rc{I1PoF(Jg zqp%m*{tnIYJtTjNJM`0IL#8W*J$LCqP2W2s~E{_zDZ^(|xxG#zyCWiC@6< zpyXY#$_a_itiD1Jb<4;KAOvisw}`wZe|#6sC_+mkPuJ8QY8Da+C&pgwqpWCCTNyuw z1aKGb$^`ItKZH+^eldDkYJ5Hez_2^HZq!}Q-v`T}7OF)dl@Ac8#yztOA%x*7!W5g1;cCo2ez7SWxQZ(xtH&w)k5a(9jo@A4}zJXuO8j`|PHCa2; zUA4TT)V8S@h$6#v8e~D%EIoLsMFBN^$vJ*1%z`CO>!_D+X}j)T8n>Tj8TuvJk6rsgi!oS&BN6@^Z=>#wbmj*l37g*U_1H--pA zJZE+3x^B_$<|HJ&nF=r7qBY1og__(WlE6`6$H)pbv0@hZlYw0xI8@pi0C{F8hu99R zIbdBK*D6DHMZQbX!7xYArY2*xu)#*XmRwJnaRcCWF-Ew@4$iJc+JtB&Fcsp|-_kd5 z^^)sJGBiLU_1R*{FO$fD>GpD^K)T3%zX1t@%L4J3p{ThWwa9&-Wafor;uzor;)B%;HKG{k(D&*2>F%gGs4{e?-o|Q9n!p2m=kI*ac!aCdTbDw-fx`$30I~+C_ZEjvXm=QFk12Y2N_( z5S^jCrQAP60gDGwvPe?fD4)9H;|p*qzf9U!H<{vq>wykQMKTFcdN6RpcsbHbHKN1{ zOU#>=ckMQuuh>t398o(<)KTWZksJ>=$g0T7nu-yb7U~EB4v%5KJZ>%0^VJW1PjyH3 zy-bAtJ*fk=qL*k@9G@to{>Rg)C!hK{D1d*&K#EqRr14VW-)mB@ z#CJ@=fs=2BTE#xXq;^**qn~WAKw=TCgJ)zn1SU$ybp}*P-g3FgG(=-v78|ILI2L9W zeSRCEsYk_{tfsQQn-t;%F&49iR&!}I$T)}8L45kH?xt$3gy!(RG#U36s|-DjMvBnQ zL#4XSl||AL>L}YBI!Urf_H_y|e%K-3^@`$;M7`1JQW6Zy2|uX|#^|VM-%QZKr)qZH5n{OXiH-kar_t%Q~_j2Hw_|q%HE@aK(rx1SeTJkR1~v-HjuKQD?%6=9uo&6 zY=cZ^`P|XciY>1|yVAjL0k68OtSm;`&hHBQEDCe0V6nA8Q{1k3IWkUD_qd&-F>~@# zvc5MLe7^28E%3;9#CNpm`bW@pJ6{TlSPVwM8RM7j(O`vXM?K^5l9|T4G9@WE{3K(? zNr$^)>{4C9dO=gXA2O&OM3s)U6mvj25*$di%3e)h6p~qaipMnjMol*SmB$n#XghO- zYsHwb&)JoWOvx#Z(3=rAI@m0Dvqg3tCA7lQMkQz3;WKv_7l-3<@a%?_9s4yq)gA$b zRsG?TLMV&$r!<1-bbhUD>WXym^V@4F5-)PQ=LF}j|Bk`W$WMK1nD&l{*GkKLCm&F` zIoeJHSK?d)D7IvxDoCvn3DVL_{egrC)0`_cos%uKx(OTI4^>KVo)4KxUE~1k zND#&65Cij4yL#NIcswyyUcBH!bx6MvvQ#&?9ejCn5A62PAp$=p4HYYafqSr zH&&{4F~k8mbc^|9u0somfD$vczVkiRY&yDeY_`_A#WCz| z??@-ohvq(6-A&Vk9d9wvloah3PEd03JWtezMGO*kqmu5#bVBsWp}Ai@E_(XC%Ert@ zc)l^=F#n8!v@-dqBQuMveZ}tF^NKu(6*9x(XKKoik8~W0$H5BL77++IjCv==DJ=-# z$;OR2-GRzy&s-xQN2u2AK83Bkvv}r7A#Ir zBR(r&4CY;pvbPIPBqcHF6nS5W6wS|U)I(t^S#weS`S9C1GT2jAwUi7y0vIc2Ct;fc z%qWzp$EywpeYpf{+B#Iy7g(DOr`Y7T8TM*Zc5*Z1_t=NGO41&qm*A`ajtk!UY)1XH5@E?kem5+97eSHY2b z&J4Av84=)H?R5u-Y6`0#?rj4>YkSg4glSAbRf4dVt9efS3`pc&55NE_sMV zjOhoGQELV0^BPF1)w=%sI8*Erf!7m7&EqzPs6Y5|O+((&@FL6i%soD8 zxK2!>w0X3OK7X6e<4K?GI=T%6nnzK-;vfG-w>&zDVR}l1!xF`%kM=6}oRGh5LFTVP z*(NRm#>n6i2l#MQM_QC$o@ksqa07dmn>y9^k^la|(2rW3mUM+-x3GFa|Fh_QDitXXZ#9IL`c6>m8r_a- zOW3v963!_6C^Dagv)PjEqd2m*YDAoZZC>>$^p*j>1%79X9%)BSnHK&-MTHVx!qiz= z;w!cMAcnP?v}sbf->O&2I(_6&RoL~aq$Id{I7YPnJo2pv<8v*2(T(YKMV>DXj08J8 z(6$=p7mlrEio*m>#d&-#INAb7SMdzpd*S-z{9RjzRDoZ+q7mReQmgMIM(OzU%#EQ8 z)7Wb*8JX;R{X2A^gN?3eh&NS!kbTgJOVIdL>07Q|O~N|Gwe6l0^P|BPFwV$o)CJ6P zdBEr0t+o%hzSpIDLtc8ZcYLofz~Hg}mX(4Yvw$W&Ph>qBBH{0F^XN=kZSEAYmVuFZ z4Z&Dr-M^dU1yY0pJ@Gx|cnYd2^)`!@R~D)}wi=vK!01*r#!ePl6ZTW)=qWq2{NaW5 znOpXP(YrbeEn#LZSqBH!#DAVtr~m1{F5eT@e-ayKXfcfrE@5_NY5i#k|FjNGXwSeW zT;NHL@S|!IblKhpR@J^oQO+b>a; zmS)KDGun3(S;OOTW1lOmSccs&O__s)ddmSmmh z&rh3RgxSoX#W1@WR-g%`4F2Taby5)B{tiuv>9b(}1O15)#o?a)gN_IZC!^_aQT6^f zsK32PFL9$*E^)rJaUVR_LiFI%A>W&HC8tBRpT3|@6^z@H0pFK*W5HltSQ5cz#VKSa ztrV2?K;^|IH88fajO;2hqy(ux$z({A-TOz(J&F(h0NUxNMK|L;-x93426tKeW!F%r zzMJ#9AOa6*^tub)>D8j6k2D#B6<5_TplaN15!zl6+EGyoP<5QQd;rW_j+6CUR`GO% zG|{`y(|!&a;(O`(BtO+}r5vJAOoQ8r#RwY^qn&*D#&-Tj`|z&)@XkvtS;&?YD+P#) zE5uS(SV$A+qT5tb^cG65MPB=xQS>N9-MX(-A5VqXm@`qBi%6P71PW!r_Y4{^qYitR zQ$%5Wd=sVIOMS(_+yWoyITvF+=j*wUm@q+md@Kc5wh8(4%Yxgx6V>I_3fyA~N1Qh#**UYL@tfXEkT zvFt@|V+He`#5%hlPehYC(nAyS!z%Z3@C&IRLsAY_F5bC@5)Jr8^khi!&a7C7CMkF% z-FqmQv z8d)%&Y00&`zqc9lufWCgitp{CMbjl<4VTpvu-~^)25G1Ba?mBXnYI-6BicxKs#01} zB+pAk?yIX-HrO!Gk!dGKUQA-1F0qR$Y)&X^0s8c^d%&+N(LZGN9Nx^U)=APdcNGV1 zv-HUV6W*>Pk?0+)Mbg=D-14E z7OowJ@8FooV-!N+TN_HIyjeHgg+xi$5hW`%0l4yzf>(jClo?s1*#+$UOr3^+Rcj)G zJJ|F)T&BW}s%yIDdAz1|4dJ7XmszhGpzaBw1YVovJiQi{!G7fYP|fWL=F$PSyMa<_ zyJNw)LF+tDP3H;yl48fNdqRV=Rf(l`!J-9KX7I*0oEgIMuN$-^iac^=$C@^n8`RmN zXGH+FQtTqM@|erSRh#anjLQ_#g9n=qDer{KiA(eMLXAv?{Ye01?y_2a9(SF)CwG(s;_fYAw!;6Bv5gb z$&8XR>q*x}hr8qI0=ELAzRkmT1#G-hyUjXQwOXhW=~m~+>Bg|zRa4fAWimnj2oLuB zIJm&Kn;d)1Y5Is-Zi$32L_u_id?h-|a*09s%3%6>QiEW$9HMy0U!nh7H~`sVXMl$B zg`jXq{=2Dj7-JsVrHM~|qGri}hJunq_-8^v0t6T#Ke$ODUpQgG8U{{l-?07u)Czm$ zkjZqSOXL(+oQV~?WhU9I=}EBF%Q)0Q@tyd;F&p#oIy82>{1G?;ULts`S~u@a6o?tf z+=MBVPsFumLt^?(k7OnE5KU_c+)yt}uB*i7*BzbbyEVxu|DvYrN z;S(&TV8#ZL1v)?m^YXndE+`@Kl6G>4vif=Lk&j z;!=@UVcys>7zZ07ePf-L&p&WV%2USnt@KNa{Z}?MuKFg} zD|0%&4{t}#uxhBqdh;Arq{n<%;p7>{yun?b$vE?MDWv$;WI%m@V?4(FWxf5+ba|Gx z(RNNnaL@J(I>^{+L3I6*hV6M?XBPPt1I&vdkidNkern}k&NE407Z!0Sq?AAH`t7jL zVUu!RHO0`yUwUI|8nu@r&{A;PSgf$n@7W*S9wd-fi-);sJ?*P9+?05=!Y5FKgt-V@1D?1#1NBDBoJj{8VDmFJ#+-=Kirub;?Kth4MXwI(E!?m@;}&g z9wjnFh@T#Mp6WlzHQl%WpLhR<6z4ydrT|Zx|8)G9h2t5(_@;^fpKB;6^#3-#Kz)4t z=754ykWd$4l2MdoaWL_)aAZ-I`vi>*^Iz(o{|To5AK*`%|5PXMzfbKHAcmIt*J6ak ta}d-2SAfq@|9?UMcLb=WfXe?3`M1221(~30c>W{8l^`#C8t=b;{|nqx<`n<{ delta 8840 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