beepcore-java-commits Mailing List for Java BEEP Core (Page 9)
Status: Beta
Brought to you by:
huston
You can subscribe to this list here.
| 2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(22) |
Aug
(1) |
Sep
|
Oct
(16) |
Nov
(60) |
Dec
(2) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2002 |
Jan
(3) |
Feb
|
Mar
(4) |
Apr
(2) |
May
(13) |
Jun
|
Jul
|
Aug
(10) |
Sep
(34) |
Oct
(27) |
Nov
(2) |
Dec
(2) |
| 2003 |
Jan
|
Feb
|
Mar
(3) |
Apr
(15) |
May
(11) |
Jun
(14) |
Jul
(5) |
Aug
(1) |
Sep
(24) |
Oct
(4) |
Nov
(26) |
Dec
(1) |
| 2004 |
Jan
(3) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2006 |
Jan
|
Feb
(3) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Huston F. <hu...@us...> - 2002-03-30 16:19:45
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core
In directory usw-pr-cvs1:/tmp/cvs-serv16992/src/org/beepcore/beep/core
Modified Files:
Channel.java
Log Message:
start of new listener threading
Index: Channel.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/Channel.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -C2 -r1.20 -r1.21
*** Channel.java 15 Dec 2001 00:07:19 -0000 1.20
--- Channel.java 30 Mar 2002 16:19:42 -0000 1.21
***************
*** 23,26 ****
--- 23,28 ----
import java.util.*;
+ import edu.oswego.cs.dl.util.concurrent.PooledExecutor;
+
import org.beepcore.beep.util.BufferSegment;
import org.beepcore.beep.util.Log;
***************
*** 118,121 ****
--- 120,125 ----
private Object applicationData = null;
+ private static final PooledExecutor callbackQueue = new PooledExecutor();
+
// in shutting down the session
// something for waiting synchronous messages (semaphores or something)
***************
*** 412,415 ****
--- 416,420 ----
if (frame.getMessageType() == Message.MESSAGE_TYPE_MSG) {
MessageMSG m = null;
+ boolean notify = false;
synchronized (recvMSGQueue) {
***************
*** 427,448 ****
recvMSGQueue.addLast(m);
}
- }
! Iterator i = frame.getPayload();
! while (i.hasNext()) {
! m.getDataStream().add((BufferSegment)i.next());
! }
! if (frame.isLast()) {
! m.getDataStream().setComplete();
! }
! // The MessageListener interface only allows one message
! // up to be processed at a time so if this is not the
! // first message on the queue just return.
! // Question, so how do we EVER catch up? If something
! // gets stuck here. I suspect it isn't getting taken off.
! synchronized (recvMSGQueue) {
if (m != recvMSGQueue.getFirst()) {
return;
--- 432,452 ----
recvMSGQueue.addLast(m);
+ notify = true;
}
! Iterator i = frame.getPayload();
! synchronized (m) {
! while (i.hasNext()) {
! m.getDataStream().add((BufferSegment)i.next());
! }
! if (frame.isLast()) {
! m.getDataStream().setComplete();
! }
! }
! // The MessageListener interface only allows one message
! // up to be processed at a time so if this is not the
! // first message on the queue just return.
if (m != recvMSGQueue.getFirst()) {
return;
***************
*** 450,473 ****
if (frame.isLast()) {
! recvMSGQueue.remove(m);
}
}
! // notify message listener if this message has not been
! // notified before and notifyOnFirstFrame is set, the
! // window is full, this is the last frame.
! synchronized (m) {
! if (m.isNotified()
! || ((this.notifyOnFirstFrame == false)
! && (recvSequence - prevAckno) !=
! (recvWindowSize - prevWindowUsed)
! && (frame.isLast() == false))) {
! return;
}
-
- m.setNotified();
}
-
- ((MessageListener) this.listener).receiveMSG(m);
return;
--- 454,501 ----
if (frame.isLast()) {
! synchronized (m) {
! if (m.isNotified()) {
! recvMSGQueue.remove(m);
! }
! }
}
}
! if (notify) {
! try {
! callbackQueue.execute(new Runnable() {
! public void run() {
! MessageMSG m;
! synchronized (recvMSGQueue) {
! m = (MessageMSG)recvMSGQueue.getFirst();
! synchronized (m) {
! if (m.getDataStream().isComplete()) {
! recvMSGQueue.remove(m);
! }
! m.setNotified();
! }
! }
!
! try {
! listener.receiveMSG(m);
! } catch (BEEPError e) {
! try {
! m.sendERR(e);
! } catch (BEEPException e2) {
! Log.logEntry(Log.SEV_ERROR, e2);
! }
! } catch (AbortChannelException e) {
! try {
! Channel.this.close();
! } catch (BEEPException e2) {
! Log.logEntry(Log.SEV_ERROR, e2);
! }
! }
! }
! });
! } catch (InterruptedException e) {
! throw new BEEPException(e);
}
}
return;
|
|
From: Huston F. <hu...@us...> - 2002-03-30 16:19:45
|
Update of /cvsroot/beepcore-java/beepcore-java
In directory usw-pr-cvs1:/tmp/cvs-serv16992
Modified Files:
build.xml
Log Message:
start of new listener threading
Index: build.xml
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/build.xml,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -r1.14 -r1.15
*** build.xml 31 Oct 2001 00:04:22 -0000 1.14
--- build.xml 30 Mar 2002 16:19:42 -0000 1.15
***************
*** 28,32 ****
<property name="sasl.doc.dir" value="${release.dir}/doc/sasl"/>
<property name="sasl.jar.name" value="beepsasl.jar"/>
- <property name="sasl.packages" value="org.beepcore.beep.profile.sasl.*"/>
<property name="sasl.src.dir" value="src"/>
--- 28,31 ----
***************
*** 62,65 ****
--- 61,69 ----
<include name="**/transport/**/*.java"/>
<include name="**/util/*.java"/>
+ <classpath>
+ <pathelement path="${java.class.path}"/>
+ <pathelement location="${beepcore.home}/lib/concurrent.jar"/>
+ <pathelement location="${release.dir}/lib/${core.jar.name}"/>
+ </classpath>
</javac>
</target>
***************
*** 68,74 ****
<mkdir dir="${release.dir}/lib"/>
<jar jarfile="${release.dir}/lib/${core.jar.name}"
! basedir="${core.build.dir}">
! <include name="**/*.class"/>
! </jar>
</target>
--- 72,76 ----
<mkdir dir="${release.dir}/lib"/>
<jar jarfile="${release.dir}/lib/${core.jar.name}"
! basedir="${core.build.dir}"/>
</target>
***************
*** 86,89 ****
--- 88,92 ----
<classpath>
<pathelement path="${java.class.path}"/>
+ <pathelement location="${beepcore.home}/lib/concurrent.jar"/>
<pathelement location="${release.dir}/lib/${core.jar.name}"/>
</classpath>
***************
*** 124,128 ****
<mkdir dir="${example.build.dir}"/>
<javac srcdir="${example.src.dir}/" destdir="${example.build.dir}" >
- <include name="**/*.java"/>
<exclude name="**/util/Log4JLog.java"/>
<classpath>
--- 127,130 ----
***************
*** 179,190 ****
<mkdir dir="${release.dir}/lib"/>
<jar jarfile="${release.dir}/lib/${sasl.jar.name}"
! basedir="${sasl.build.dir}">
! <include name="**"/>
! </jar>
</target>
<target name="sasl-doc" depends="sasl">
<mkdir dir="${sasl.doc.dir}"/>
! <javadoc packagenames="${sasl.packages}"
sourcepath="${sasl.src.dir}/"
destdir="${sasl.doc.dir}"
--- 181,190 ----
<mkdir dir="${release.dir}/lib"/>
<jar jarfile="${release.dir}/lib/${sasl.jar.name}"
! basedir="${sasl.build.dir}"/>
</target>
<target name="sasl-doc" depends="sasl">
<mkdir dir="${sasl.doc.dir}"/>
! <javadoc packagenames="org.beepcore.beep.profile.sasl.*"
sourcepath="${sasl.src.dir}/"
destdir="${sasl.doc.dir}"
***************
*** 262,268 ****
<mkdir dir="${release.dir}/lib"/>
<jar jarfile="${release.dir}/lib/${tls-ptls.jar.name}"
! basedir="${tls-ptls.build.dir}">
! <include name="**"/>
! </jar>
</target>
--- 262,266 ----
<mkdir dir="${release.dir}/lib"/>
<jar jarfile="${release.dir}/lib/${tls-ptls.jar.name}"
! basedir="${tls-ptls.build.dir}"/>
</target>
|
|
From: Huston F. <hu...@us...> - 2002-03-30 16:19:45
|
Update of /cvsroot/beepcore-java/beepcore-java/lib
In directory usw-pr-cvs1:/tmp/cvs-serv16992/lib
Added Files:
concurrent.jar
Log Message:
start of new listener threading
--- NEW FILE: concurrent.jar ---
PK
órñr
4+óÚùFÁ ¸v£m!þgÄ©~ØoH>>»xÃyRaÝG»õ7ÚK·×^X³Üu'é2F#«utL¬æË¼6QØKã
@0X1ÈÑ
æU,!ø:NãqmùO=Æh8³²¹yqäÑOXæèD^ON§pl.Ön õ|Ø´ò¬û'Ò1.¡4pÀ7zÌXÌt&¶[ywý ZÇ'(Á7Ê|õ²`ÖÖ5Y]Õu¶.¼RÐ,¡
x<wÕ5ß
Â]Ñ^õ
gáÑ«f¡ÎÐWÂfÊÍðP60_5W5XżkxZCZuòÛ ZHèÓ6&¾Ràx$ê"ýoC[«ÚøZh¿Ô3ãQM-<
õoäÌÝöá.Ê@δ&kꦩçÞrÛÝÓr
qQo¤;¸¯Ý*³Tqp%ù)õææfLa÷«m4NÀdü¨*èD)ö}ìý~VÙKdÞ+2È"¬3übá«lØ×=$$ëÜ¥ÑuàyøsúÅK>.xÉ®
RC±dàC÷1ìaßOÍÇ
?
[T`sÂ4V¨ÀNT°4QA`zY'é(3#CØã¼mÎee.aµYýfÂIæÒNOK½ùÆéV90ïçMF%§ÿj[×rjå<I«S(f->ð6ÂÛ-l 3÷3ÙG¿/Nö¬úTì¼Ü|÷4ÜB¥Ã|éJz³CÐ(nÕÉGê[(kàH¨r@G×Ìâ&Î_ÿ@×þ.&ê"]9ÍÐ(OS ³´Ñc ¶'ÉQqÓ!4e0s¹ãåï9lÍòS,b]ù÷BZe|¿ÎsõÏÜwPÞRX×¢Lak
"N5×6O_ë¹!¬+[X;oëÂÐûÔ¹:úTFâþÀ.>S(n-¦öÛÅó-Êõ>böN\"ºý°õ%\¶µÓ
v¬¦ þìÂ%Z¿ÊμÆÚ^gÞ ×eFyÿoÆ·qç¯àöâ]\áê½¼®lãH9]ù"KoG~'¤n3ZªÛtª½úò䣿¹©-ã²³ìâ´Uqr½à-LþZm½Ì÷ùH?`AÒê*=>¢ÇÇ,éºÊöÁ}¸ÆÎdìëÀþ+Kæùe°{u¿Ú|þjÁ,R«àÏçÖ³äi$Ïa®v)s,ôQhïcÌU6NRáí!¬
2 ¥ÏShq[/eî+ü5WßÐú[ð?n×9÷ßÓëF¹nüȹÿÿ:äÏ|¿ÁèÙ¼<ÏuZÿPK$ÏJ
Â0Dç·µ©u#xºé¿àÊ
'I¨-!6Q¼à¡Äܸr1Ù¼a^ïÇ@
@!0(
©Úp'¤ÕzO(>öÊìZk«N½=Kç;y6:²n¦ñ¬Öch-+ïTì{ãÿjå$²®áé3*ª¿#_;'1éx2BÙÔL >PKï¨
wiæ¶N'$Ã4QÍ
àCwPF¥òóݸy{y0ÁqÃG11Fí2xQr¹RJeòj¾"íOÓ;ÞôYSésg×1Æ·XP%0þ¥÷W ô7ÀÕÒSÛfÿ
Þ¸Pi:Ï
¿Ô?{PÖÔ¼@BYnýDK'õZfF©Õ¡ªÈzùÅtãíëà½×âͦ[U|¢'?¦ë©ªBé)ûn]W@ Å£¿ qÑå,æSÄë'Ûè5ôÉ.öÉ>3àýç>
{*áâïÂÐBSN|¨»Q5³Iÿ$v¿ñbpPKª¶»Æ
ÕMÍ÷I6ÍI
Ê»_HÓ¶Içä(J)lo꿯¥7Je.8v+3³¶(ß«*1¸f:3>nfjî£Õß|p\÷Ô´
[7»4°ûì¥×4úR)s"êÈNä§HÕ°
<D=øÐH0´hÀØ£;ã8(ÛAy@ó¢` ¢hÑ1i
ã
»Ö!KÛf6¶Íä:Tñ)1áKÓòrÑÀQ¹ôQþÐû½7{
ÿÕªó|<6ɶ÷µè2Çãù]´X£¢kÂ$¼ém_îfii²¬x>0ÂÑJϲ©Éjk--4¼·ì
zÃs¶9¥°bÄ2cV*e:¥_z¿ùöp`@a7thR.Î2M*FY-|qä~GjÂG6e³#+hϲr
ñíÜ/¡ìÜ
ÜBÉ(å\kZÀµ
°c°?ÇXvÔw ¸¬bò0ÊÁðm4çQ&U°@bÐø¨Eµ _ºÅÓYª(EqÌh-(åz§ßßÁ6¼íX"a¾KÂ|p©³Â|V·iÕº
/C)ðExEp±Ðm!®¯©M@\¼ªÎé¬ë>sM,
¯üÞ$Jh?c)?~Aí_rü¡üð~C«ßÒË[èÂïiý|Àüñï3Yâ-+ùñÞ ¤ÄîÖ¨æ×w·¹w{??Ý;ÏMÔµéÅÀÃwà«qËzýÚßëÕ¸Q¿ª5ºi¶¹gï¾uãe!¢>ÑôIÄüàY#b
ุäÈBÄDZëññ_ñ_ñߨýw»·I×°,ï0Ú¢ÿ¢õ¿ùì]+2JCVyÖE_-"b2üªÀdmWBì0¡íV^+UãȨJº2 «2«rìPÜáGèÚ¦caÇag*iI$AÎKé¡2éyÐ*\ÊÖ÷¸ÜZÇ-~B$AhõÖ]DUÚ*åGªC£ªç'')bÇ PÚ·ì@6xgmäl*sq
W«ÇïfV¶{æÚté¯äªF'ÓlÁ3á¼×ktÚÝý«µ´hW:'©ÔTêKÜEiÔC£L*ÉV4GNm±Wðc:N¼Ì8úðaG^Ágù2¾àȽlö«ÎùÇy_uäUNÿ««ùgAu2ß]Ìwöª'P}8¨úѦD»@:5êFÔ0Ϊæù4ÿ]yi5¼:+êY¼¤Æð)Çg/©óø²ðªÄk*µ¡läBoQ²{аqlß®ÍBsµWvÎÉè.|4ü¨§n=¹_¿ñS®¦Ù}Q¯²Üíän ºþPK;o
DпÀâJüf"ÄÄ4½ßcî9ß=çûöóóW
/ÆW*)Éõ"Deaå#?8´.ê¥d¹ªád9UZ&ö:´ÒºÝè!¶¤ýXßFSÞáP=fÌÐýYB\£]8س©J ½õÿPæ©ò¦ïTv!ÌÓ;ÔcoE#Ló;
§Ö}IùãBª\/,5Io þ®Ò¡5T¥Å"J<´i;D¢KÒR]§Cñ¡7¾7?ôJÞ3R©WNr^Ò~C-¤Øó¤Û=óã8L?Z¸åǾ¾'wIç=ªï#AûjÄCB?B'ú 9ýØáÐçÄÇKb\×Âb}G~¿'æ¹Ì°ò
1[EEÀ\ÞìÛ}3oÞÓþøùí;Öë¨bµm¸dÃ+>®
xÇQj@kxG2ô¡|2:Rqy_ÀÕêMIØÉÆ, kòÍ4*
Uܪ±YñZf2.ä8¦LRg:6y®t)_DI¹+õÔ(£6¬
E½83ªb[ ú ÑIùP Ýý·ï9[o´nvÌd¤ò½hòfáeèRå^(¥{ݹìl÷è"Î&²9Eæo]ßÍL«ÄÎÔú£j` N
¿BbJXÂ ûS¸yÏá[ä
é.Þ*Ò`DçéWËùv
cÁPÔ+.¢¸#8û4eγ+8%47Ñ%ñ3j8.ÊqlÇPk¦±Åç<
ÆJ¬)já
Îè$sÌ#(:ß%xz/Â;%DÝû|»+Zb¸?/ª
u*ÕíJQ5,¿{Íùî#>'ìW&ày×P§Q6T¿gߣÐgNç#Öúgfÿ
üÃò3#3R¤UhBMG±ÕÁØÄ8è`N6^´ÀI.ði.ñ
þ3G/ð>~Ûð3O󤾼>¼$^§Pgñ&Îâ-¼sXI
§r]^¸(y}ü21^JT1©B5:r¨µ#h¸r²zϬ¬Q׬®nÃãzw*$?zí^áw&d¸ÞGáKÊ,Ãåw^¿{V¤cw%Q-dxWäî5¼b%6ʵTÑë¸u4
ÄìC/±O8Sq/Í
¼bPÏóÌú| >Æ&|¬1Þzã¼Ý&`b¸D»}FÝ/ãYLá®PÅi¼/y_ÎQTÐyEù{,rì_IE(í]¥³G½X42sýVC~¸8~ž&Á7ÜÚoQï
H×à<é)ι[$cWxÞïÙstÕè$7)y®\Wøj~Ú¯X5gßÚæj«özç¬üÀ~Ä"üDA~f?¿P_y¯³ßXûwpøÂþYÐW`öÜ)·ØòдtNS>M`Éís\Ê5±æMV)`ªçä
qÉLÊùB*Q]£L(T!î@îºÁ9M6ëé½þ_7;nÖèæWŨc\éÎ
na½q°ÿÑnb7s0·®mXÌGÅ¢>±¢Õ¢uÂõ¢
Íb)¶jtex\ÔÀ+1(ê«qB¬ÁSBʸLE<
w52Ëú.Tÿ
PK_V3Âm
ݪ9ï/DöÚ\op/<L6îyAT«ù"äN¥Æ
%:©á2Ã,w"ÓóUß´Ó©þÔ¶}ÎJ°y\ãÅÊb)ò4[åJÇE±j§w4·¡·Qk^ÿ¯d0J÷RåºeGé⪲©4êô«äí¢Ù5"Û=0cj)c`Ê;Z¢;K¶p(O¡*ÏUã²Cnô$ 0Éï¡Ð:ئ¾$þu]## åÙÞzÜ2®MÆ=ùKÈ+²}8ÌÐ'¢±_nc,Qܲú½ú¶¼ôÒ2±d'=j¢£Ëå
:©$º|G´Ô&-ÕY>Öi} ~K´RÒ²æÈÔÑá¤[ïØ";¡Ià}hQËaý
ì0Q
:õú+ÙÑÓßÈ{f)áR\;ý9Ða_DîPK9°k
8åÇô 8@?ÎØÙ
1ÀôÈ8/#)ã"Óv¥hÓZÜuô|<¥ÛNÒáæV?Cnäø,¥%|ΤnwtɸÄH¤oeÜ Í $
[¼fÛÜfNñ7í~ßgíx._ÎFÖµ,n8ñYK·,ÝáC¥Í UI*ìÏÌÎ$wô,>£º3À0Ùºt2zAJ9ÎÐÒ
>îNMpëº6§<©Ùã|6åDïP¢Q"ÑÒå5ã~<=ñgEu}ÅâÓºéÒ¾k¡_Ð¥£#!:¼úßå¨ÏâSæ4/.SC^S¦ÈßU«Z.Gg1]+ËÇtÑhËFûìlûÑ¥
a»Ñª
Ë
ÆÑ*#à
®*Ø
GpTÁ5pDe¯aÜ̸ÙÉÑ<¢SÍò£Bö$*1Á8¼Úð
ÃvÓrx.]¢ü
!³Õ¿nÍð·C·?Eæ-Î0¸Õ¶èräz7çL2ϼw¯øïwoJ®_þ
µFÑêZ²õGíôrh£w!azï[èÖ¡µv_
¥pÜX.,zI»nW$ªÀiäóE¡QÔ¿ÑÑ^®kÙ³x\ͼÈ×2
pzy{òä^ÐKS
&|Hø0hÜÈ1豤^ÐRåçË9Y^ãJgö©}6cqã¹Óóz6SÒf<ç6IGKø,¬fë*þD=a£;4¯Hÿ<Üp×çgR3¹É4ÄdH§©=7^n¾/I§¯g¥aO*"ªk¤ëÙl9ÖêJgWq¯:|:G:¸ç²Õft-O£gTVqC.<Q±®øàWqgUËa~þjø¾r³5¿ñ2«Û®æ"QÈi/ÓåR:3Ê
\±Æ«³ê5W2õÂJ¬Ïk¼¸Ë:PEN¼+8Çêky¬HÎOUÇýIöqIÅ(ÆT\Á¸«S0w¨²ª6ÑP}?ÉÀ:ÅØl\û¿Q$äÈ^2¬³×%3-Ùê*GÆnÏ>ãµöÈÉúºV`}É9е"Ek˳ÑnKɰWd}ÖûE%±áØ23|0jre»ãÍ~>಺9ë5mW,¶3
È<¿hG{^£ÎØ{qmQÛláhϵçDîs¾
O¶Ñ^ÁUpI¹ÊªDø{.Ú¨¤
}íD`ò[Ft,·p2"{01qv=Æù]¤<*bܲvà> -ÎÃ%.0øE§Q1ËôbWdHÄAëqfl¡3Ü
mDDp×#ì°ä¡Aj<¸¶SÃFva'1(¦¸;ËûÊ+ò ùPäÙõþÙ
Ùðí,$YL]µáÛåA#|mbp;|*Ð?VnÞK)¡÷õûEÚu½?áOkòX¤£XbÙ
vßÀ!yÝ·¡iÜ$ôMܶ¬Mè,ZI(AB·Hè6ºDýb!¸H#&î %îÒûê~º¿'I2bÿnOªl-ÀFÄAã°5¨¬"|fY× ÿ%AÌ×}êð:, O<_,²!*Ó3Â6§{L¬Ô¤¯Ft/·Ñ3;²Ü¨
ÓT^ËÖ
óñÛr;¬àÿÀ})ÌÜÞ
Ó¸±¼ueQê!¥ºb¼
$á¸cÙÚ÷"OR+$õâè«HgôbÂlrßÑO
2ýQÕx?ªô.V5òZã6úì"Ù°ÓfáÅÁßuËÖ²ùlÉ÷¨KüÆRyIñ;Ï\£GýOYÉlâ£:ÍSyªbPKÛy
mgif¦í$Ó6LÒériÚöÌt:sÂ|÷¾'Ùbz&3ÇÇïÝwïýÿÿû÷{õ½_0o wxa`¯
}¥¸w©ÇÝ¥øîQ{½ÜpÅ~5º_=îRÑjô=láZøØ«¦>ïÅ<æÅA²°Hí<lá
ǽ½<¡ÞOªÇS<ÞG½àõØ«PóâY|A=úÔã^| _V¯¨G¿âx·_õâkøºÇ=ø
o¢Þøññ¼Räy¥,xÑ^ôbNZxÉÂ)ïÒÖÕm½:{2¾Æd2^ÚïéIôr1HÇ3©´;NÇwo¨ZÛtK|G¼¾+ÜRߺéD{fK/øk§]7¦:åMÉDKï¶Môªø¦.θçw&;3Úé7
jmêÞLgWýÒTWÉ;SÉyjmTmÖjÁÝêÞÝSlGc£ÚcötîIh)VgϲmÝÝúû&O{*w&{EdܤH]/±L§/GíUd¯^(¥õ3YQ®ö®T¨«k§3ªI-¶Í^[Ô4E=alIdEY=juZmcvE÷Ç;::Åö+ϤÛR;¨A©=XÉu~¹jm§ºqóâM=$¥f½°¸«ë:£Äæ¦÷q¬ôØG~d^E£6m"®ãZÍêPL 7/Ýh¿8w¦;3 [KñΣxko¦»7ÓI'âÛ´¼Ëvµ'º¯ßRÌñ,ù¸BòÆäpj/3<3)Nt&·F=K7¸Û{ã]_ÏÖxÏV;×<¹ä¥Òºet¾.fþPÍÛ×4l{¹)¶jõdËHµrnÁFnð¶¥zÓíå*ëK±ÉÕÊ:Õ¦Æa˰\ ¢0¦,úp-|Ø=Nûp«}x->4b
W}x
¯û°K|¸m>ìÄu>Ü F7bµÀìDGo}ªggbKª¾½§¾£ËÆÈÈkïM§5õÅ L²TådK*ÓÖÛÝJg9÷
ÚÖ¤qñ®eét*í÷qÖÂ9¾£Þßõá{ø+¶aÀ¤á4*ñ{3¤z=Ã8*ôúÞÍô¥æNðá¯ñ7êñ·t}lBËìÅeÍïûÐë,¼áÃßa¹ð!Xø¡?R3ÿ¨ÌV6k-¼éÃ[ø'ÀFä;ÔÛp»
û°M?Y'ë0
äO}dFNS|~Ê.Uà/»ÙTgS-îwuî±§«²ÓÃ,>a8öDº|¹òʰ-ÕÅ
@åŹÆLìb YLÐ=Ým»{2m¬eºªn&)Ö".ÕÝ<,ê$É«zÙW^0Eñ$µÆIfVíîNäEo:±Y©SïôÒdbgc²'O¶sßÔÚ$ï&îxww"É«½¸j]\ÈìÎ+5ÅVýÅÑc/]éÄæxoWfõðÚíѼQõ
³V²hsWçKiëÃʺ¥j¼f\Q;â]½ Õà§W¬À*^xé³¢Gy~mÓGJ&R¨áQÒà_=æbö©ºÌ³sUuåÌR~
ù|»"ÏCç@à/øtëÉu|²;[ë õlYädÄxÆßÈ ,`L´ÃMzµCz×L¾4iô$Lc@³±°
Bx!b'áhãË8tá½!ááóVòêÂHß1¬c¢Ýñ=ÛµÜkrMÎBÑÁx
!ïâ¦Ý¼&crH¯KC®¤!
Ï¿B÷Ö½¨Â}ess8sLëÀ;Ø_`ÛGølF³w³·{KÁ2û`
$óÉà\éØt´bß\ïðEÄ6Æ/P>âü"g¯ÇJI½Ã¤<I!ñ$¦åpº);Ä=ñs*g+ÜO'CO_ø}B¶g¹0²ÃÖ~+Dàåó52{%l´å8K÷¾m
¾(mdzÙúUû ÀÍ÷
¾¥n°ÁÃP«u~±¸ý®þ}.áwùMìC^¬ªU
(oÃ{Ã0Í¢ªÀÛTü<1½2¼Kÿáö/·wù_2µ~
__ò?cÙ
ý7
øwZöи×!¾
Ì|Û^¹ð>í
ãªÅß]dÛÉîJE#;Çaa`²01C¸0ã+
¥ñgm{!¸ø^¢mK»5Ú®¦¶«Ù¿Ï¼à7\ø ãõ²ªµjnù7ðÌ@)£ñcP"(c1Jàx²#"Æa¶9/5¤âÏÁ'e°:
§ù\~ͱè FLegté;Þt
kN ê´ÎÉüé@«FÄ¡ebÅ×c¢IñsÇÇsuq®#n§¥4SFV@N¥Jå'1üмQ->¦ù¬qø´;|.×a
EUt
A«¢ ZÓ^fæÚ£>Î5uè >Q`Ô>
þjd}WÁ%çÂ#ç¡BΧô(b2Ç3ä"csNâsçÉ&¸ÖQPC
_MQ7׬$qe*àhËEÛyÝSÔv£Å<XPV¾yt¬Éfl!ÈV+Q-Û0Z®BXÞ@7èjÌá÷b¹åNnÀZ¹q§[þO
üÿQ
l£I*ÐM¶S4è¡è¥i*°
ÜFn§ ¤[Ñé(ð>(QÇ6ûà ¥>»
¥
Vê
¹§N¥ã!ð\~·©Õ
xÚÔN#ß÷»5_?.Ë:#à1tb\ªªçUdtmáÁò³°ä~Æò¨b|!ùÆËG1M~ùy\.`¡|q}«8·^>|
)ù4vË£¸S>ûä1ê~Kîò4Ź<\|qòª+
OIùUÜó÷£ÙÚr¹èúP~ÇQÝÖ1L"u
¸ì»ÔEu4ÿL&OPé©ôKL¡SÊoQÙQ/1[ÆR¾ä¬¯j]Âß;}ò#ôÌVªÁôvûíê²5riØ4Ü~÷¨²©åq£v^Ì £Á£tu÷ áÄJÛ>ð{ôq>på+»wbȰZýåòGôä'ßÂùc\+Õò§X'ßfäÇvùÏôæ;ø|ûù> ÇåÏYR·åÊ¿ÔakF0tôϨR½àú(ù>ùoÉ-É[¬Ô¼opî
ÍT¡ëV¬çÜãzrÚû=b=UQ5ïmÌ˹mÑñÁuç(¤í9{ãüìo/ïûó#ËXi¬ãÖá5Öc¤±8qîÚ=¹rgÚ¿gBÃ¼Æ \Yðó¡ÊÈm¸ýC²G|"w'4k²sàùËøbièd_}0ý(Æ~û~ÆÉTìA*õ0ËÝ'ñ)GܵÎýcZî°gó¡cCç¼S³gò¸ªàhünã?|b^ü'}ñ\ø4èsèïùð¡ï
ðý7PKS
¥ÅNGä?|ÑÄg^æ
DÔh" ¼ù~?à¸ÚºWÏÞ{í½ÎÞçûï/ß
íçE{$Ôî7[Åvü?¹æZ¨S¾0sRö¾ÐhT|Õ´ÙkySB]¹Þ½,ÆlDZóg¤4d® ÒõûÅÚuÇA
î1 ÅWçELÒ_zÚ:ékôOtýäì&b7èH-¥WhfjHZ"ÊÄÌgÄß"õOHné£íu(úG~ ¿ßýÙYGÅXf§gkz´£´tEXjÐ
v*qmîà8±ÃÐ1£v/[Â1FJ~RXÑ;$a¼w;êT| Þ»Ó/¶T¾áIHð(¶dQX¬§Q¹2®[MWM¦$îþR¤µÞãÚeÔSò[·¡'B£N@D¸
v¤±·Kß9¹ÌËE»°[:¥0UÜ¡b@²Þí3 íZÓô§íi߬6Ìk6CÇ5«¾Wmí
æäWÝÏçc
Ü5æäO
(ã~ÍØ\v<ûX³^±VÅ¥%a¶P aúgªölèø^C@º]ë¸ÜD~7iÏr髾U«Z
úôI¿TíÃÄ3Æ}¯vÒ
g¬§-[Ño`®Sq§»°W`@:L×ò¦Í#^hAs6´kW÷Uq·µO{¤¢ý _ŽÆp8hàúrÿKÄjU½ÝíWfìj¸ÎtâÀ¶ji§[ZÄ
ϾóØPÛµ¹P:Ü%=?t£Çª>Õtz6¦¬íw}._ÞXïZ»Zƺ*'ç¡]زÂ{:긮Ójè\¯Sëì|Èu1Èíes/y%8ßÊÀ6®
q
{Ivê"Ôô£Ô©]íâJ©cÅÝíyô´°·¤Ì#QÚ¥D|$ÙB¼¦ ´.©
mÿ¼-yÚ2ôE¤Ï'ÄMÈòY)<HoR¾Ë=îaïR²E¤>8ÕLDQ-ÎæòqÞ$ÒÛÂ;Èã]6é3/à0.2{ b0
ð(.£6fp"I\ùÝH¤armÐóâz:âc
Qºdµ³¯a`ƾD!»Mõ%ììÙW¡*-(ñ±RBI´3ÊJÄuF]c-%YKµKZ|DßÈZZ¡¬é]Ö´ío¶,b%öá8~GºG;E}
v¤gñÇmSü´}ÌÈO¸úHñ÷9ûæø¸_ùkRö
Êø9ßé{ÔñÑ~Ä~"â/x¿â9üçñ;^Àÿ¢q7³«:Ý8H-dJº¨Ë1lÿÏðáI«´ÐCöPKét w
E_î{gιçÞ;¿.¿ÿ
M×m?Uò¤®¾ÈÂ:H²4{qß)q¥¼Ò¹yÌßq³¸Å°ÉUäøRK7²ºû!§:NiÌØhà»h2<þßóZsÏÿû»^ôµÊccð±B[µhÛÜÃlZÊdM¡«ÆEQ§doS´HÛ}¡Ã²µ"Ù$²æÊ§Ï&Ï6Z0qJoêϯ0Zç{s
ý´©ö:ÅDA3*)À$Ø9joÔ{:ɾ¶VáÌÞ¬êß`ÜÔ¸D¶U´8ÿPK)4Ø
ó1¢ ¥à CgÓ¹²zBäÃN-¯éäP²oÓP!«JX=¬åÕTyfR-IOæhi%O¥Ï¦ã¹t~*~pòÑwûªsõÍ^kA%¨3
ÏP2Ù7A{é\ú-¡a5[JçÔ©B<Sgsñ²®åâB>S.Õ¼Íg¦
¼öMæ)D>·ÏÕÂ\gUkmOg³\¥ò¤^LghpÍsºv&7Ë=dµ³x!g^Jë\x¸«39+4ÏP[¡Èåbt4]T$øB
^X¼úB9+ÝÃïéN¦kyté
Q½¨å§$´úêÜkÖÜÏh¡\̨{5äÖ%ï½Qxѧ¼èB·XöbG¼xõbÛ½x!/¶!$aS³©qQǼÇq§©ø±tQ«µGëâ«
)¬×Õs
¼Z³²YÆî>Ú¹Bæ4ÛsírXBK]
gKº:C×5}v¿ö¥ ]ðy¡lP ôò¬`C`¯|óè¶sÝCLÂ}|
·qöoB
®ÃvOîç¸
vÝìÛèÁf\Q]Þ½a`ôÁC5¢¶fà±À¾y82ÏÉ6©+©H56GV
á-thÁ:c®Q:9qìjÞNÎ=äpD
ªAc+ýr´ê+ G´êwÔXÛ৯¹ð[¬mÜ"°è6x±MÝA´Û®©LÑÀ&Ò;S±ùy|²½_öÉá
)êû±ªÏQI8cU¿³¦ºLà?fÌõªCDws½YÝKtÑ¢¦êSèæüt$|ü7 TÂ#Tô\1þ? §¢×àNÈ~y>v
ÃïÆ¢ô½üaýN¿£ê«>g%¡¥2pñÙïcâ?@8d̰Q<smÃà(k9ÆÕ1hi:Îæ`:aÔ³dz;q'fd̪ù0_FÔ<ÈÔyEÍ3
òÉëËJïc{]oÌõݤ=EëiZ76d^i1gb.Õi-Ó·+EL©Ì«Ds æ±çÁhµ³`ù廹˸_&zÖWhÝÔ{µÅmû5¢¯ÓúæÃ
¹[,îé&¹ß$úoÓº¹!÷;×$÷;Dߥõ=Z±*yQ²É½VTR3Ì
.vó(ëòZ#ú#¢xm\&ò1G-þQ³SºÉ·nßv¡±@Ûüws½À¢WyO|BäS"[¬ä5ÓK¾VÁ8o
,ËÏD×2Ï~A/Ü&ÒßPÂgI¼Ú¼Ä¢ßPâ["ßÙÚP¢Í¸Ð¼ÄD¤ÄOD~&²ÍØb~:üâz>b»Á
Â0ÿè´:¼yó¬û
Ùæ_s©ss»`L~Ô¼iV+¾øÒJ`yoS¼*uÔFÙguÆ&̹ÒV7>Y©*Yh|©¥²FçØxùãÿÁíñÌʦÿÑÚxv.\<¿ºBMPBh#ÜÔÔnLûzoPKéwØÏ±
£{%4W
-ìÃþ0A«J]¸öR&CèA
á0Cäá¸ÞdÆb¨Ñf3W3ª±¦Õ¾ee²¦èc(÷f·6wi"ç«¶» ¦mUwÕ©úaªºmé¾ãËSÏÛ¶)r#B÷=Û!çpúåÍÏШ߰oa,¾e¦ÍBk¿È²s!ªHùù¬p&¥!àøa\n¤mßÑŨ!
Õ;%±ZÔ+¨F)ØúºÁQǤæ8ºÐ#·D¯>ô24G6nyÂqüyOÒëbÞ3lKA?N1toñ[/ÙÎp(ikeܲ3df\W¸UëÇËÎ
Ýcý#u3¦E±#jãí·Dh$5<9>Ka䩦y?/IÒÆuAmÄÆ¥:³øZ1Ö²3htʵX'ònb£#o¡aÛ¢Eß;g5Ô,h¡Ë ¬3ݦ,:évB~F-vÑz7ÍÚh M|K$Á˼'Ca9IðÔ/«N¿:HòVâ#ZòÆdH°Ëä«ÐC¾2-ùåoÑ(rÈZƶ9\@397VÒFJ¢âͯK¨. ^[R@ÍÄÊ:¾§T+Øþb1LA@!
I(`¥ù¢,ýÃ(%ü6Êøù]Dù=ÔñháçÐÃã43ü)Fù3hü9Rü>¦øþ&
ü5¥ª¡ÀFz ±WÒ[sÁ¿PK>i$¸
hâPâOB.Ýìm¥ùÎFÁ8b϶ü}|¾½cVc§ÆaÖyµOâÎlî5ïÖæÙ°7aÅ%Óy9=Y
håª÷B8xPõâ._Ŭq>fj´kq
5½ÈJÙ&vKî=[
¶Ä(!óïäÑùæÿfnLp^â@ò§ÓÞ ñÂ$öﻵØLàRTÂcѰ
é0M°ý¡7ojìVíPK¨Ð\Ñ
Bß²a7kd¢ö?õ¡RüýQ¥wVQT|H ÷Ìý<3ó÷ßÕ5U,x(!¨`Ãx.&]L»a(nÕß2¼kÉ(ç:»ÍEÆ£ç&N¸ÐJäi*áûZ'2Ú¼"7:]c¨~Q¦+M,hÐXÅfá}£ð¤¥cÁ¦$Cµ+¹µez¶´-NeôQX+ÉF«< UäJÙ²µ¥ÏÞ¡ÎS!·bÛ6ñcÕöøðPóábÈÅ7¨¹gX/¸oXOºRmÜ,Æ0ú8àï(%ÓffÌÆîÞk÷¤0rÞξñIíPELIg3
+lðT-J¥9IÉ.zB%ÐeÓX +°CÃäûä-ïzË¿ÁW~ÁùNÝ%YÛçÙQToëë¶~håè-|½«ölÜù²óNc}¦q¼&ú¯0E¶L8[öÿPKÉÎ
#×¥%Ê}ÇV^?Sq²ÌPX#UG¨Ð'¢¡ÕMëÎÐLµ'F3ÃX+âaö¢-
¯ÑM±ÅþsÜöUK²ÓÚñ^znäÉm÷q&¥-×2Xëqøân¨Ã&~ϱ clļQØ&®ØpP3Q·ÑÀUCÒU©Dd]¥Ã}ÑÕyM\³i¶®EÌ3ܲÅꦪÍwúÍP£ÝØ«R¤yi*RÒaAkíá+{Ãfp÷}êâ¾'H$4Ä~É9zîF:ݶµõ¡~¼
.çí_PK sÅ
î¦`£c3ÿäÆ
.ÜàGw´ .È=97ç>rÉÛûÓ39ûpÑW@e=0ämS%Só5¦Ü$×òÌpð0â©UF4¥¶üÀH7R¤ÖÄK
ú¶Mi DËJ+»Â°Xm;Óô1»nBÉÐSSZî¥
<¥FdÄ
W
UF3WkçÁUÀ£@ñÃTëL¶4}Êà×M¹¥²°þ5æ²"
¨çaaÍ>§6T"8<iJ½öÕCù/gqWk¯GAÈ¡÷»áýƹa»ÝÚÜ_±è01Íãß\5,o³&è¸`è ]ÎEØl9ä/À'ÞEl¸CèÏ<ÍÌ>À¹'F''óB¶î¾Bé÷îîü=ù{1DX¦Sý¤z£ùâPKô6%q
¢¬vw²WâÈê!øbºí,[¬SÒN½üÿ/¾àü>xÅx ¢Û¦çôÌù¾sf¾ùôëÃG
ÃÕ6Rñ>Cz&ô8CwÕüNò¸Î£E§ÐH¾î#î]u¥
A«ºâ<qìÀËö½D6]|À`,Iäò¾Z¶'ÇZc¢eyté8iâ&tØ&&Q1qgtL82ÃÈ6Ã<U©°\¾ªÐqÎÄy\0qQe϶Ùïøu?vÈ«åRk-2í=eÎ Á£Àc3ôlX«¯pW2Üj·öfL}Í:ÂxD{¼çLÊRe·ÉÄÐÙ$Z£ñ¡ôo}ÌP¶àIÌúß\RÐjë·æÕ¿7:ÂFCu0`íWòéÝ-+ê7JÄÍ^lFÜ¡ãÈ·ø·â>ëOÖÍQuEü-ý`êÒAÒ׫DH¾êÑ&eîÛ]P^À(½+ß@{M)l<´ÏdûÐßÊç´:E¾RZ¶TvéZQÂ4^ [^Gá%ÛïÑùÙô+,è-øa"ö]ÚWjßPоÃÒ~ÀÖ~RI¥âù^ú3(ÿ8äKó7PKÆÊuZ
')Óhfu{é\
WÆCS64|Gàä¢u¿éÇáÐFoÈ4#¹ÝáH¿ü¸`}ë÷¶ö®k:Ü;<Û:¶lÞܾճ«U@x
Z¡hÌm÷ãæTjOçTj!çO·µ¶nq·{¶·vy:¤¨MZkçú.÷Ö6ö=Þ½^WÐêutÈ»;h®=àÝl [××È@(c«°ß4ÝÁÀ^³+0 7òúhÓæ~:ÚMÜî3{Ã._ÔåºhuÐå|ñHÄÅ\-¤AªË¤ÐvºÅSmÞ½ÇôÅ&Zób}ÓëòsVÖÜá$aÙîì^&±çì¤m¼áHÕ"F5¹MtF¬Y@®Ù.`k ûM '2;ã»ÍHt$ª=ò¼®úܽ!éëg@o)(î5cé!³°1m£Y,úôx&)37í¤\å{ýþ.ËýÌ¿êl¹#ÑøH3ÑÄbf$¹Ag´/ó÷
Ü=ÜÞ ûÌh4êmI<pEÜþ.o´2rüo DÕ5SÞÊôMmSsÑ2>;:íÀV½IbÔ÷Yn}8ĽUçàïÜHÜYË\Ú%JÒ p÷IoÝï3eÑIÆbÐFï\FÒ
St_f*ög)ieþ3VDÍ´ÔÐkyM¾`òè[ÃñÏÜI^:¼zéKÎjÕÖ!__$
Ç£Éä6p-¼rè1Ð
vÛä°W0²UÂÀNì2p¤èÆ7Z&se£7ÚÇ"aàj¼K`Á$¿'4{½Aw¤7>@©P ,{{Y!×À÷ð¤§<g4<kà9|ßÀ¤AAôèÃ
;Ô`<&°¼zú{gúNM¶GQ_ÈÝ+l,ei½±%̺æÞ'mI¶}ð
T®;§¬7s½W¤Öy° ¿×ËîjÍÛ¬Ù&{,çÙI5{«u~u^"{¨µÏ¦À¹2Ù©9îæÊAͬd(tØyJ±z¶aù³>:uC\qÅçOòÕ'(à«ÈÂvq«Åf&ÙªlygVE·A·[=IÈ!%u@£XA®Ã6ÍQ¼èTo§zcHxVè¨ÎÌrÇlñ´xçMjªçgC°nèbf](>ÌýX,Ã)îÂÅâÅQ¬wÝ?fgé®Ç#Ƚ?%2Wnû8Rj AÒÔ⣰D qÊQAxP
¥iâºiEâ8w÷dU¥eª:ű?ª#骴LUÏPÕ³TõwYUfªzÃOôj®l/vì$íZºü$Jw:'pA]^V;rt^mÝ(.TÑ]w@.¤\èúQ"^Á<ñ*]þ\âuR1Ôt'MÊy¬®V°VÚÊm§©¥sîEáÍpÐms_nB¹5ÚWæp.Ï9u³*æTÜ3þTåý4~6s¶òjá²æ\fÍ T& Ä[PÄÆlñT¿b®øâ¨ÿÂJÿ&Ç{R÷çzÎò¿fVKxíÎÓÒîQÚQ\Ä»;":d¾ÀXÐI?,äªJàðø[NÕWÚcå¶SÃ4U#K)èR¬°æ¬¹ÜMÑèÖ<,Tò±ß+v4)¤¤ ÜÆÀÈÒ4 ¥ð0ïCÝŤc28Ç¥Ö¼çXí)ÎzF±Xt<j¦!ºr*r¾y¢KȰ$ñÖY%
¹(Sæ¡BEJÅX¥T2XÝM&Î
µé$j¡:G(òGáTÑY÷$r¥»è¥Ú¡ñ7;mMCã¯WB~Yí1
*`YÐÀe5¥º²0Ö¡RiÁ<¥UÊ:k#uJ.SÚYùrN¥½J{ýô´WºIºû¤U(×1E'£j)^ä(»iÝ\¤¿&iíÚÓÛâ â%t×Ê`tÖÕ%`.UUÖPP*³Ké¡{Q¤ôѶ
6RX³°a¡l¡Â;ñ2¤kõ;L+ô$C¡ã+yizRwE/ $¯ä°û¨¥ðjµÎ@<Õç×F©Ò¬ÿ'Ì&}íʶÌ(Oà¶pãP¿ÜFR7³í ¾eaá\zÑPöCîFܸý»¡rÖRÅüßä3ù LOJóaçB)©["MrÕH7fh,¶Ce¾H¤ññâ¿A: ®¢£,OÙyF>{8{£D'»dáüR«HS3ÿ@êþhôë}Ê+ãV±IÞ&4uàü
Ê
Ö
âÚݨwÓîVäÚç ía(B\ô³}ÅÐê
;æ~x/>·Bn»<[¾gÅA ¼O)î2È{çDû©Zý!ÝömÁï:8oû"è}*z(fÝôkó«ÏïOü»]ûzæÇ%:NrÒT÷<AshÞ¡1Î'à½,T²;¿];ñÃ]ÓðÓþPXªô?dú7ôF.R´&Ãh×ïÝo.GH½ ý4frst(_Ar¢>¡ô®f<#}llØx!äÓäËX¹üFäqqdW)K(`²JUdh_PKº²XUl
Â@
ßø¨(ÀBÜ6 UܰìB6«àÑ,<±q÷á=¾¹?®7
V.>Áæ»÷ëØZjÍÙ\EÖ²%t¿#ÿàzBåPPEØ*¨¿ÔCXx2ã#ð'PK£ûc¾
ºÒN>0R
Ò:<dÑ1£ÛæL ÛN&?ýaéíÍÄÝIylgö8¥yõHñFÜÌ 'yVÅ£:NH'¥}ëù¬õêZÓåËÉÍstV¢¿£|æ!¬¹±Î&9HjÊñ¬ýÃm¶}M׺¸ÂLJ-a'¯Qu
§ynx~rd?¶X¶m³Ë±ñÿ_¿<Ù¹12£n&g,©?ûæ%ÔF
ÜÒþõ9Ä'Pñ[Z¹TGò§0òªÖoÝ÷/[iF~ûÂüÞÕr*ø
ÉòiKç¹bZ-OºOùdûr ¦*ã¹õ¼¶2×Ìò"¦Fý$¨gEã(~?óªùÊù9þÄÝG Þk#d¢D.¥:
¥þ,Ê'QƾÔ)£~Ñ2rczOý©qT¢Ò¨ÿáQTÍ28ðg3¾J¼øËðnÆçWó×Xo¸
qÜK¤
èÆ(ßbD9RËùi¯¾î;Nö2ûÿ¥wãr SbZÂHíÝiH©/ü;Y{\oú^ïC[Ît8Ï,ÎèEFp Æ0/ËE^z?z)²-ÑK-S½z!
sse¬e>mÂ->
B5ñO$àG¶»Â?ñÆ~F
þEø#~ÁrüÊk±ÃË4x˲seF´XÃó×&M±Þÿ.â¨
,iÇ<d(@
ã>²3YÌ?»Ø¯É
£0¯vGBÞ÷Byö1h9+Í^
`$Ô½º+B%md?<¤ó¬n-ÇÑXÖÞé¸ÿyÂvj°U®ãSÓsa ³,!/''½|,¿PK².òG
¶=êØ °ËPÏI¬ÔjRI{ÅPF§®u&:c©Ä½[Ì&³*ýh4~L'jÎ'ÖH5¿ðp¢IÅô¬ÞT.vöæ%Kï2ôêØk¡À£Ã¹È׫g1×<]ñ,çÎʧZ¥Î¡,ÿ?aÿ×ýNYa[Zý!#¿N/Ú´&éU:C×ïA¨D¸Å~1Êô0^Åo(½ì&ÅvÑ9¢ ÇÄ?)tÝõ*ñ`òFáDæTÝ*ÛßPKüw{f
|ÉÔÿÅb^(h1m1V^Τ1kñ$dä>*wêàÇ9±èE»$]W,,ºL§fxàK%Q= bÀcóðI§NËNN\2%ft\ÛuÛ)æ®õÈT5ÄpHC/h8z5ôá´ÖZ!C¶+§¼èün*Î «¡_Å¡Îi@»<I°Zð ãRY(Vdn+Ôçô|9S,-B1+eòV¦ìV&W´seÇa¾=Y+h®_9jÑù¿ËvnOhµ;
êÍZuhÔ´a;jçÎÁdj¿¾úäA»è.ïAX.±M
ì bÔ´,iIþlÂuL»ÐB;°Aü²!R¿ì mçì×ùt>î&}
®<@y
ÂÈc
î(àZWs%í)ÉÃ
=¯·$È¡dïÉÕ$4Nêy-UZMk
Y5#§-\Q×ÕxNÍ/ŧÓ+ZÆ%Íäê%£(öJ@gÕUgg(ì] ¿¸¡®IMjÙRÜ(nhKF<Sgsñ©çâ#)
ZÞÏlæ3Ë#¯¬e9C¥+¯f³ÜÅRÚ,¨"»WK9S_ËmÒ[V_×Eèº]SÚ¬aG2þ¿=ÒÒª4ù.í£+¾@¹ºÕâ²]KnÓ1z~IBk¨÷Íà1J
Ôr§Oøpã>E@ìÞöa>t¢KÁ)ôùp} *áêé1Ó>¼¨w}x3®
iN-èöд¦9buÅf·aç¼fsY§¹|gÎÈ<äÐ9)Ðt¤ES[%Ã7uss¬ÚÆC-+Y
ÎãysX7ÏUº¥X×ezQ¬Ñ8¼¶mhGN4·ºûsèàú2OaÊëH½á§ÂÁßP÷+O^áÚ
ͬ8[,jCºH8WQjÚ.Ò.b8§¢TÒ
¥gPÛå3Z8mÔ6+û
á]©ØAP¸ùö(òdG¿ìÁî¦W¿ÜïýÎí+V¸l·¿(sEº¡ô6[3ÊÞ¡´*n÷YCéýHøgâïAÙ OERÑgpÇø=
§¢»ð$ä|Û
7á8¢±(u÷PÏß]a6è
8˹ÜîÚI(b«ì'Ü<ÜûlDî'èf÷JÐKÃu·¨ðUVc3ïr7ÏÝc8E÷)Véÿ >¤¥JË4-/W;b2"åó¬OtêkL/°hÉh¹g'Ávd»`~ü:,zt R#wÜPMìªØ§Ä.QºNîÑ[»¡½rJìO(ýÜÏÈ
×Än¬bçOý9¥_û%¹|[+ØÛÙ!`´;øÝc(u[hèÁuppåí*×z
È
ÊÓà G¬j:4±oã7zßIõ?Ѽ3ÇÕ¿çÇ«õáúÅÈßèü
æG8+¢µêÛvlKù1êñ#ßȽÂÑ´ñÄû"¼XWåZ{Âõ5¼^[»õcÚ[\¯Ö¡ÿ?PKd\E
kk±¬ì2/0|ô¼½W£Z8ܤ媳¶#?ÇòËëÛ/m.z«rÞ«V½æT͢Ϭ'ä«cÏùSªÜ;Ô Pwêáÿ,ÎñÞÍÓ$íÜÏX;ÖÐ6VrIë3ROvÞFæ=µä³âZa´cäÔ\AaKp?g}@ò-qK|VGõÔ¯ÞCk§5pyßb>cèkd,p¬æýF=ÀÂ|l³§ý
´ÔRÉÉî7µ¡{ë«Ä ¦ö
j°[!xSv©Ã°êøaæNÎm"=ôe¾)7ÿJ¼§FÔ,³¤8û5ÓÔÞ£tû¢õ©wÓ"üz¤®fƧ۹:¶ÇÑèLÝ¥¤?ØCûBþç;hú2Ñ~W¥I^¿E:¹µ«2z¨ër4mu¦ë8qCÛDû)mk¬m®¶/cúÿåéϳãVÞiìÍD:æ:ÏÊË´*S»¸¯ÂxNåÛÄ9©üHÿPKÕ¹¸W
:&uLmá4¬].Á\!×|'DDÐ7öÎÅa¡*Fâ0´ÝÈnøv{¾íH)Ø®¬W¶jâÔ9;
¥X"´Êw0æ~¨NÖeÿz¯ÒVq
Aè¨zØLNëBî8u+¹éÅ¢º'¢Ulߢîõ"3ja"]Qñ¯_PÃØ{ãsÇDº åßùWªimh',7%ýôçéGQ¤è$,þDèT.lß íú±pãfÌ|ahÖz?VskðI½TÜE.8¯c¯
oi¯òÄ9Íu1Ç>òç|éTz@j߸Cúgö¹½
~Í
Ä
C09\Ͱ©Và?PKM6¨
Â@çiÌ_%Â4ÙØ[SX¯GH»°Ù5x5à¡Ä,baå4óñÍóu
=8ìHÞPK._¸
~5*6*RQìlwve»+û¡þG¾Vh|ðµà%Yj0ORÉ˹wv~÷Ìaþúþ@·ëÐq¹
®¨°XCW
\7pS ²/]ÿ@íd/sKsE2énÊÔÀ²@UnÅ>×GÒÏ8ý$÷bÇK?tò,/¼<Id9Æßîý81ºõó37ÙXïQ=(·;¯´~Ñ¥1
"¹ìÊ仲¢Q*L`³=ª!?gëºÑîLé\õí8O<9èæ`8x1ÞÐ}ï~tMGÃÓÄ
+0
Üèý³ÿ¬¥²¿.mf"7ÐXûÿ ô§`¯3¢ÅݳMàÎY»cO[ç{/ASær¦)99£çev_
ë%QR¡ü%9Æ&?î1ÞG
¸U͸p
xάÄqÅ:Bù³eï@Ð&¬ÙÇÐ,{¹@qÀC
[Ã<z¸Çü¤y\<å¾%Uq;dNPj2²ì#hJeQbmÍ>ã1ö)yl¹Á§µU](¹ÄU`踪fBýÎÑ¥
%-Áü
PKA;î
Ö
lpìp^ßqYÞ(¡5HS÷^¢`höd*ËsݽôÆDý,¦®ÎP¦âJM'"¿å*æ(Sy$BY%Ne:SþüåÂâ/¡'bdÅ«xȨâ$P¥L(K#ç"-UwácZج`Á_ÎáäOAýF<'Ñ\ol`¡=7w¸¬S÷W~VÏïôÿ8N«£ÛBФ̣ºFl~ÝÏÐØA{«ÛV M4`á"âlÄE´R4©ºEÖÛºõPKÞ=
EBÀD£±èº4
MU[UÍcFãc¥&º2FIt1aÃd'.ƽ{ÿÿ WâwæâbWúTî¹çüê;çª?þùí!>ÜH¡×0С̳jÙB2)t#«=:zSx}ÊÊÓ¯ãy/è:nA@¼/ ¹r3Ô1 |þ·Ê²,)×þDÑ
T«9ÏæÎä´Ë¦lÈgæÓ.åÐ)yÏÍ}_º¡1ìy¹fV<_vr;N0cã:á¸@<ÓýeLDôºÇsåµ%é/XKEzSpbG¹5¶·à¬I[2V360©Éͼ,
粺íã¯SâSó^ÙÏËÜt!¢oÕZ·¤ÑlàÔ¨Çc^D³ACÖ1bà%CN MÅEË-Sn(}¿\
¥}ªWÇËÆñWqÍÿÃÔ=ø¥UgCF¯f[]/t·ú/Káú2¿"ó ¼~ù3ù¯S~®Àù k
©Y§XthЦ9ÑHhiuÂçRV|iÙµ'©uS¦{æbç<é"®ñ]åã
BA Ñ]ìUpäÑÙ~
à£{ å½}ÌìÞ}|¾½`§mõ[çW$\hMf¨,£ÌÇ@ÍfÇiÄÉêq¬ãüDÀíõo¼ambMãb1%s¦uF&8ï(*d=Ñ,a&£DyÈ0Õaaé\ÂÑêá>5Ôý¦û-|dÅ|zÎ
ô¬×_
«@c&¤ÓØÝùÕ2«G ºmÃÿK
´,LÉËéìÃ%¬ pðWoÿ½=.<»øø¶Ë(+û¯/쬰Á;ÏCUq
M8hvÆ6{68pÁPK¹{-
ÌËXP CFF4Yáx««Qp·Es§mã®p^±ANÁîÁû2ÈX±ÂýÖ°¼Ç>÷9ºjÛÜÉU×å.CøÅ³ï²ynúzÍ}ÁË5½äêfE÷=«¢jvÉwn{znyÕ¨oÕ8Ffz³my·î&?´6³Á åj&ÉÈ[6/øÕ§ÜY7VhD6JÏ|Ë¡^8)û/K¼îY5ÛÇ«uâk3ß1Dê/mñÒ;
ÈÇvDd,YV>Foâ_NFðÕ2÷VÙ6*NäåäÌ© án¸¼µ4±ðbÍwJü%ª2ÒÅHÿ`<7TÄ1«â\±ªb
3Ä^1ì²¾j{ÜqüºÇÍã¤pÍpWñ
*¾Æ#ñDEiWE³.]<¡ÊV6*NÙ¯Rc]Cð¬ç|ÊhO
ߨÐ`}_Úÿp^øðZ0vÖ·¾åpÃdYâÓÁ1kÂaîý7bFì
Y[ỆlQn|
é/Q1r4Jç¼M§· î Li¤i¼{³×%f@+YEÝ3ÛÆÜ£yQå}ÑwÍáÑC½.Õ5qvZ1¦ãÛ?½{Û½³aOèûIÈçdð&!ú'cBRég|¾úPKÕ¾
,wÎä¹ôÔÿ¸wFm
öCÚg+ÕtKÉ8nÖNr-Ó'¥N¨é(õ(:=Å7¥ÃÆ64:ö°îaÃæ-²U'-:¦È
TªWvG6uÅkóËÞs©®I¢^®n±«ÝspØ.£
éå1¯wyÏàÞ/PK0tMQö
>æ\S8b9VpTË\ (¸%¡`kÑrÄD¸8+¼)cÖæ>zÃÀr_AWz¬¸`\3r¶ásÛðý|æ~/jxOôK
ÚW)¥3¦úÖMúJX/¼@ú¸97» Ì /QhâFà&-:ÓVº#
âîÜðlßÀÍx
2¿ë"?ÙØ)¼ä>½Bl[
rÿëð:¥þ¦ w24çÏ`Þm&§ ·i1)è%ÑîrãXÔüIãºMSø~Äd iâ9¹ÐÛ5׬¹2¼²"ÖìÙm¬H)¦¦ÏòF[z¥Íc'
ifï^h.kþPz¦µ"è®ï
69âz½p`Mþܨ
´ðÀ¯%6¾æ^§æ=aèÚjÖ]Íý©æÕÐòJó-_Î ÎÎ%u7_ÂðC§ì
¾Ã²=(UÙb:õ¬}>É{¹áÚFË.Aéý£mz ±ålï#¨ÙÇO÷Þ^Bâ´Ú"Y·?äû8ö ÁqÝ¿mØ. ó4ÿwdX
dÈý?òF9·aHõw$§c?ó¡ªbÓ°ÜIMÇsè]ÂæÉáx¶[íW±åOÄ «©ÕÔ ©N¬¨#H³L8FDÇtHOñÄëÅ)~.òGàL
ùâl£6ÍL² Aq9ôQ*ñì/Pï¯HÔ6®î®¥$iÚ^ÅÖÏ×O©ª|LH*ö×u¶>¡Qæþj2õ+¶Ý«®Y¦cg³UtÖtýÍgëÛ]ËkôÑåöFàýü³Èׯ&µ{s´)ÓÊ"½zü½Ã
H·(N9òdH»ªxîâ±ûQ`êýaµ¬[]¦Ût{x0À*v
bg<o±
^`_OfKê- Ò"?2¹LqDXì§ÓÒªãS(-©ù¹äR+Å©Õäz2Mæ£3K«jª8(<¬Ëjc lÖ*AÒÖÖ2ü¶õ¹p7yGÂ
À.EµÂ]uY¦
Ñt6Z*f²ÑKòy5WÎnäR+y-y_MjZVMæ
w²ê÷P-KK°hyNߣS ɼ:§A\ùbôõêëvõÝR2[xÊFéXIVD2/ôpµÙb>[Ðè;äd¬ò`³Z)RÇ3"×mu"êNnø1áíbvÅ×0éF7zL¹1¨Ïâ97ÂHø/¾ý
nÌળGâOæ3F·´qL¯±Ü|h9«åTc9J2¹nËj©ÛìVϰÆC©Ü(Õ5.eÒ+Sܨ¡±6áý̼#tëT=¼D°àÚÀn9ç
mäÜü
·Ðº ý?Âò¿$tq<+Ç.z%~'M¿½Ú?µ®ã°!
¿4SÈÌÕé.f
e»«axt¢öô*ÛDúªýp9í!ß3¢¯Ó W:Ëqö
O6$ÚôëÐNêöÑ"¡DdH°®Ä±ªÄ½£Klý÷|H$TWâxU⣣KÜ'ú1%>!ò)¾¨¦ÄyyÛDwøÙÍÖm¸;¶XÊU&þ8|Æ>×úMóÙpCz»5¸7õ}{ôÉí¿ iÚí_q<ÍíÍí=¡ßÐúM[8!B5._Ùz@c<9ЯùF=äê¼dÒcº&Á1äç}õ4oÃæi©=ç·<çw\ÀYÓU<z">ý>÷û¸Ëc´ûPKyÚ¬
Ù4Á¡t¯¬XZì:ÿá
^s³¢$ìÎÿà/ðx%BL¼èù~ÞsÎsúý÷o
BT¤F"Hü~í/)=³¶ Ñ*ÊܹwÎ=sÏõþøÀf¨Ã6ÛCãe9ìÐÑa@Ã+r±S©»dàn9Û£c¯Û¼}:öh0È¡S4Ð
n9ëÑqHÇaÚÈäN+Hô\9/£ùd¶Ì9ɲg;ÉlÞÍEázÉ>Û¹t>'v)¨/½¾|vGWõÍË$;<:|Vd=ú5'Sòèl<±=ÛíÎ2ã;
³wÛ®ííUhk?©@í$(cA¤ËñÃw¶[EOÁÚ¶åIäI]\ð,#Ö´µ?G<]²¢àÙy·DjùQT~foû¤ã)MAq¦°K]ï¢OVzyÇzÐÌYÑmKþM+²Ø,M´ Êý¥M¬C³gñë(!ñ6xëåÐ+#èC³
;Í8û£å Ô*¢£ßD<÷H°ëb±\ðD®hâyël2qQ&á¸\*ÿGÖ~-´=1¼s,ãºV]Ì^pó=B´sGB<RÄ¡±"ÛXA½Àeï-¼XòÄÕ$Cöè·Ç.ùêöòe=V¾:(x*ÿX]¾Ê5R"ZUÚ·T6Ä8ʱ«ÜWhÛc· Äî îí±ÀT®µSÊ-g ÇbÓÐgPÁÔã:9î"ŧ» wvÚ°{¬}5Åu Ó%B ?~WZMs]R#ê]9IÌ ãPQç'ÑÒh#Ú]ê5òè,8]F*çn2Ií:-¾Õq=´=l©ÑèíD#"üª´¢³x
Ãôö²©4û¥JüÖT^q¼zuWéiÒ{XFCµj´õxJµæ#êTJ³$oÕkä^òm
Ì&
ÀZÐ;ÀÙ1¬Äq¬Å «9DYNÀk~Ñ/r^ç9H[Gµî£áLjôÔÜm¬¸*W\5ÍŬY¬\Ðf¼ÅïëÛD>Mä3Ô¾ØüogQ*Ø]´2¶õ Øê%àYç.>²Üâ%+àQzv| à,?ÂÖ=hÖTµ'b§¨³z=7ÉÞ«ºWWvsܵÒñùÄT¥VO>ü;½àª¶Fb.¥²/Ô9¦²¶¤eårLß1ßVè`
k³XÛÂãa]mòá¶LtÖ/eÈ3¬ã
u5Ú.kw¸\»]®ò_sö
eÿU¸Fß÷|ó?ðKð#?\?a?~¦ä¿ðiþJÉ'òä:§ð!n²ò¿uzQlá¼[ÿPKÖ¡ ;
ÏZ¬lÁrÏd:+ì`§ee×.XθÈXç_".3(òå¬WzEñ²v)/dËSÈÚk}_¸AvX[Å1ÏôÐ Ýï»`9ëTAéÍåÅð\1T¨é»× z¨Çh}^^(X:è¸âhyüðG$_ÁÛ*Z¶\
ý$:nIøæ+®q1ð-©
8G0)æwð¢-ã¹%ùÉ+¤ëEzÞ I+;FG¨Å2ÇòÞP(½Ó§
/áb:G|Ø+û¶8äÈR¾äÚc¾çzåRß庢°YÒL´aUH)È=t',6Üò#×µáH7GL¬Æk±FAúÿÖDd,[X
V¤LîoÖÄQä1yáYsØ~ùåb òµfx31ÏKÞl4±l{xjôJAö¡¬ý^ÙÍ|¡qÐre|QV30,û|ÙñC-àâ4:¯ø1_Xyɪß{÷ùY¹qç^°O1Î1hr¤|ýI(×VeKU¶ßëçð\ÏC¦B¹#}JZE]ú:Ôñ«Ðf»OשR_28õÄIfQ?C²vüÍ
¦Ð(µu,®uǦ`æôÓ¨7Ç&Ð7UíÖ%ù.íÖõÉ#¯Ð§°n
9#¥Ý2rZ³>q÷ëvzJ»¡L§+hÌI>ñIi¦
§ôi&d3Lz/^ÀËaͲ(7\º×ü,ðM¢ÞB#Þ¦õ2§û9ï5Á½Äv¼>Àn|H/W8â#úûg¹CÃg(âʸø¯â^ÃmF¸CÏ_Íëùõ|SuQÛÒ]¬Y°ßrq¿ïçM`Km ߣr/ÔÉ|)4GÍOª½lnÔ"Á÷NÝýµeâ^27¥5¹Ýa´UÛNÿî¡Ïì
eÏVfüÀ¯?Rû Ëñ3Ñ/dýÆõù?ÕlÞ_Ø¿±ÿ¹zTn#h+d¹ÑBÄÔ+aÑÚÜCkEE½¢!©èhRyí{R>LlÿPKЬ´°
R¸,Ìá^&-Cq¡¹ÊmÛ_fh-óO+XyÈÔãp¯`¾Ï}©§enºë¿ä«®^õuÓÖÃÀ²õªëTCÏãN B
¯Ï×\§þàM0Ä×cò
JÆJ9g9Vg¦3Hפ´meËásáú
÷"Íãs/ @&#Ãî\mÓýôñÅÕ6å5`©:gB!óÀ3ªî^zøT¨JÅ
½*/Zâ8=<Ëõ¬àUcSæñÂPÑ.:CîtV¡¢ME;:d©GVÅuÜPÑ*HʸÉ0}l#E¦êßZ¤ãHLÆ-;ÿ®Cá$gÈLCvqºm8«úâÇ
ÄÁÒºßMýð÷*ºÜUÔu¨õ2µvöäú2ôäxð çÜ-®f¸y£4£~UMA^ÆqmLkW¾"òQÍm¢Kûhâ"K;hª¼f,!»o÷¾§MgÉöA&;I ,Z1Að<z1Eÿ<ÆpâÔ`éf(YÆÁOhÞ,Ìl#¤©ô1-IÉñ
cªÁ
1õPK
.
Ý:NËY4DtìÊ ¢:ÎÈÙYyú C}ù1Z'5aË)/¾YÑû,KØ= #dét~]Òµ±1¯ÿ_³,$ÖPÙ#6-+ðĺ)gêºòRA å¶#{íädTLg)ÙÀ±"&Ëe%¤ jDiÿÄ:á]ãÛ6üÓn Òëy2?ÓäùJê6uæ_ #ÓrÉ44æe®
d»°yaæx"ÁyÏ-¬Ï¤øL¯[1'Å H)7ùýÙç{µl;¡`òQRÞùñ°Wò¥R¯¢ö
øüÁÐ
(ÁÐ'(X ªàEÀ¢Ç$àgJåù(ÿ6Ô§nÀ³¬DM+ÁE,¡è
ögP\]Ø1¢¦Õ
̽¿¢ÙosV3ðu¨M«êrh
¥ro¾%øC˲}ûå.´²'Ú WÂ+³Aö¢ãUàÊð:O¿=xè·P·Æ;D¾KKïáÞÇQ|n|(®³|g±ç°DèKq5¼nVJÉOy6p=Â@µÐ7X*A!Ç[ØÛàS6«½9¸CÉ(ÙNì2ÇZìË«sµ«×·
v¨êJ÷µ«¨ÈFQÚæ©TWw{æ×ù®¶É¥¢ùví&ÊÚ½2m åTtø×i¯ôG3hÍ%
(¿Dùçk x
h×Ý»³ ÈÀß¡SVêË9j^§y¹pa÷±-¸
HBêUjx#*nhC½W0¢á¦%ä0¤I
Mr1
i
·äîW5Ì`VBæÂmñ¬rÊ_h ËöhZÏf³t³Àsf]ÒÓ½·þ¯[n$î¡<sK6{&Ì<±nɹtÃ
EI¨Í:ºí¸1;³2%Ö<À¦
!ûe{pþ$F6i-þ:ÃÙ¦NüVÆ1ïnp"2ö;\£a¢ÀÓw6Tx¯¬DX
lk/4Ì£à(y:O°>»å{J¨|ærÎ\f:mfÝê{÷wÍü>VPÿ*y+YÖB~|üXòUåõ9^]DP4¶Æ¢h\Oý,¯x¬C=o/YúXP¼ÐgP^ßïÑÉÇÑ(Úÿ>bÛ(îAõ%ðwîn?ýaÊSØìLò¦ÃmÃr{riдØÁ.GÚ^ô±¬A&øØ^~¤À´+½@Ç9GàkáTà[Þýð=£D+~B?3òöô+®â7~~Ç(þàÇãO~EþÂ<Þ¢",Â8ðyäþ9m§§J/Ò$«ÆöPg«Å<UQB%¨
ÄÈDv1 U>ìéá1{ãMÛ
j,#ÚA¾^Oàë<(Þáð\&06lq*1¹r9W®ã¾+·ð+=2ÝôËPFåÌ_ÂT:ªBªÑG5¦0®S-Æè,ÁÇT;TÏ
k &d¨ëtïQÞ§V|@p.ãCêÀÇÔ
O(Ô}¬ÈE|Àc®°<Ç5¬rãUøúÄ0¬(üÇ!ƦüPKjéS]
- ¡à64ÔM©Z¨Ðf=¸[µ´¶kàÊ/qç¸ráJ5 ¸"ñG!¾Ùµ×ÔqZ¤äòÞÎÌû¾÷ͼ7cÿýÏï(bÝÀ.f1Kʼ¡Ì¢2K:Þ4Ʋ¼¥ã²l4xÛ yÇ@ WÔ×UeVt¼«ãUãvà5eP®» «¾/RÍi4dkH§éxO »áU}§VÀ¨ã6½2h|" 0MF{®|ßyàØ5ǯÚ7ï]k;^Óó«}ho&©\gæèzYVZv½ÑÕºí6ìJÍn5½íÖ}·ÒoÚôý@~*9vC]á¢8ÙßóçÚñ»~äN/y¾×\Hæo h¥zEreÏkMÜt6kɶ{xùÂü³5l|á»äϨs`S®C-,FåöÏsÈB¤géêí^~H!¦4ÕË~ÑdVúÖqGúQÝÿôUù'aÒtéW"åÿsO¯HÜ¥êÀHÜݱQo®\ñTfJQTmkbs&ÇQÓÈ8¦¾fpT`õÀúQ%¹n⼸Ö~'8&Î`AGÙÄ
¬8OÈÀòþò÷oõúæ}é6Ïäà¸vPE(öÙ1ê®>U|κèÞø0{s×|Q'ÀÇﯦÚ
Oµ¦:&ôǺãÐV=D?J»ö$Gqþ¼õ+í aêKS&eýô.êdøUßF¹G ¢EvD§øp ^Â!(ëS,à\ì4g£3ô*eÊzÜNL'´
¡¡ÁP!óñFæ
gsÖÇÐIý
Hj°¦vvö»3ëì,HôGÒëöÓÄ'_ì "©I7)&þ!ýôQúÝÙ»4ÍÍÜsϹç;?¾{æÙË?þÐOtà=¯á÷ñ>*Jm28¶[Í6«ý°¤íxÃÖØ4ÐpRA˲íåk
1*îç#
Ô¾±£(>óóBÁÁq×bN3v®@f;7*nÀS¼O:go:¢º¾Wa(¥°æ
(»LocÚ¯8çÊ =ZSð1-viÁDÿ¢½d§p])tâu
¦ðN"/¬íÍ[ç=bJ)ùWÉ%¤;
Lá´T>F·¡Î`XZº|ÅòËËbÞ·²/XÐ-Xï9
Ö¦Àü_psk£Ü
@ØyI·QwÄùÙWA±ö
M¹EáHåñm<?tçVv¹L¯É´¶zî·(&ÜBÁ-G¡ÇpOÝÁibI$O É+÷7¨eçfú1SØzäþ&÷ÑÕiBÎÀ TðºÓªR[ßCò ÔÙÇHTÍñÌ_æZøÅV×ÐjÎn@3Ä#híu©Ä9 nnb½t}umçEín1y2äÉ `¢É¾ä±êdf;[eÞS¸Ê¥¢&Q_Eò*J¬Õ?Vî#ìãSz~EÎÑû<#|ÉÆ1 Z'qkSpó¸ë¸ÌHWó(ÑÆÛµîkhA7Oöt?ݧêÝwÈò÷Ëò÷«jv»C}ÖWC2^×láÀ`"=¨Ib:µMdVRônjÚä©MÐצ ëL1¨uj¼ó´á¯»é»9ìÒ«CFv»Ë¨²
)Üç4f±Ávó¡7"ʾäwXä}lE²Fkó|MZ¿!Ò&E9Òê-øçͽ/°Hb¯3iø¤¶D¯( Àʼ[XÆ]ÜÄ=¬0Ã÷ø?`?2ÓOM´÷ru×§Õ¦d=µKâÚeO{'ö§õgoGàG}àeJ|H}ÀÉg^ÃíM¯þºó|o¬;uüBë;Ôcx÷PKbÅ©z
H`Õ5é#Á-ùSÂȨxPÇCxXÇ#ÈèØYé¬ýö¦Y`ÖDtÛs{Í<»ºv®°ë[Ø`ÛS,õ=æYN_µ5Qö÷ê¡ã(y%'ÝSLì:0Ì)âP}Ê2lµlÛ
Ço9û³£¹(ûlHMîPËÙNTBÁR¾ Ð(äðQQäx+',X[ÊúeÁ í§\ÁÓDPÅU5ÄÄÛÜ
\Oã
pª$4Â5m¡ÊDÄ'¡È]´iÕgë:n4D\ÑÆû £+è°K?wÔ²óõ(2
n\´bâã»FÙi[Ù©n²ÕXImoU,ÖwO3ÿg áY2W2qIDÉÙsÞ@g!t#ÍHíÂ0«þ*ÌÊ 5.ó
6F#Ý/R¾Ä÷eÌÅ+lÁ«¼MãÆÇ§;r¡Uå(V5"QTO¿}}éÔÜÕ¨,øi@RÇ*˯¯FHSÍU¹&BI®Qd¡¢æôþ¤2ñS¨=CEa Î
5Tau¥6Õ"DvélجÓÍ ?Þ
øãMÑÔxmÉIëûÇÐ0N|tMÄ)$BItÄ;âGj¢ñ(;¥éh2zuú|Îż«OʺGß@,©Ðïå÷i¶1fñÆ8C¸üæÕ!°2;ãoã±ja5pÏQ/ø}Éïë+ÖòkjÏq¾aUϣߢߡßÓÊ|XÂ
dqÕcìµ@áPïâ>41
ùr¶79%ð8[%p-Ó6¿ùH~ójÿ,T¿íǰß#pÐúfá¼íÜkº±(À7Heo¤ò¯óépÔYò¸gùæP)[a½
Ç]>õÕD|,[Èæû>Ü!_ ×¢ò]ëàdûmêùjðð]êyN¦#ÞâïQg[Açj´Sv-©ÓÖ¦N¡1äUå¨Wmí
ä?fà¹uzR^Õweîý2l6ÃÃö²ylîÍ}>~Ê£ù¶ã=¸û¬?Ç!üø%µÝ"3é·1Ûåû&4²T§}Zqiòªê6û¼v5fMÙ[{'íÂk÷]ûS\%óÔdÁør(ÎÚ°í¯é×÷Qß¡¿ÐÆÁÑ?£ãQü
#ø;²øwo¥9[fÒh°ÈË"âïPÔwr!Xí¿ ãËnÁXYÐ}4Üc®YTD¬¹Ð*O4¨w§àé°S6Øo3¨fhÖòÅ{êÔ±!<táD
p£VxðÐy³U`¨ÂQ¢=¢§DD=w¶ý¨~hD3Ð Ññ8h¥[hÄ6ÑN#$ýö[,s¬ÊOb5Ð=8¥Æåç]#çÅa8Dnq¢#¼¹b7 £ú"ÓÝÒÆ7Akï¡&oxmÞöÅÚÚì6¥UAFgàð*°B4xëÊÜ_,BÜZ7
ÞÇM¬ècÇåo%ÌÂסÉÕWáôF29Ú¶6×ê^WkfaNÁÞát ¯Ëë¼6÷aãö4íp²J?<Æ<r'NÃ@=^Åe\E}ÞýrãPÄ3p>,'éågá§°]Ø)bØ+LtRèC8-â0D
/,¾.ÆñªÀeqWŸÆþâ%LW¨Qeaéz»r^Å~þ»&Ïe}ð*éO±áy
^¿ô@0DÓé
£ª`DB¼*q ëĵèÝyèCpYÐ}«.cýÞM¬êóÍbµ«(Ë£ß]ÜÁ£âÝô=E_#Ñ¥$zcyôßý·Dÿ =l8×FyòÝ2"%rÊ@.Âå\ü¸ÿbø~bk,ÂçS.7//'ýÈ·.Á£¶©¡»^õzàܹ¼ö0`9d¿^ÑÝAkÜÁqÇõÜÝ¡
î6h·bk¯[wY5XWñKn¢aRî¡z)мâ~¸¥ªR ]©BRMâ5ؤÔbâE»R=Ê
t*+yËícÄä\ #¥¶×:Û®)UÌ#9ñ¬¿e
¿aR>ËÐ+s¿
é»SÙHMp)ͨRüð)ld¿UÙL-7 ö<ü9Ø$Bá50GòþàØY¥Ï6öukî¯%¯eÊVÚÛJe;ê)×*±?I=^âBÿ
PKîn¹W
åÀbfvùzçëûã@iy»ä¬1MNO s[3a¼h_û§ÝCYµBbç
!»·Þi¾lÚ»õì¹¾xeí{ëUù\æØDBqíí^xiîTÝ*ß7ÒÖhï^÷Í äWư·e×qGª-ÍRÝT+Ö=aúî¼1AÉQ¢].ÄDüRyH¤@NßAo+Fââ·~K÷,þ+
·1
[ÑPKÚnGä÷
§
ëà6g³èÂÑç¸ÀÐÚn86ÅP¶D+2ýp]¬ø¦-Ïë/(TæB$"Ñ}.HùA
!]!U[(×!¢ë®tÕ4Ãü
÷RU¿%z-WZô¤)Ýô("I6¯Aº¸éêÜï,«ö3£Ñc ÏQ@Ñ@cjéÙrÅ\¤ÔìÎäB£Ãûy©DDkJpÄr}ÉqI£®pÀ1ªgùþñëRUÏC2ôí¾Ó\b0X
4xªËÅKPmÛÔG*æÿK")û1½|¾`ýÙ/³µú-X¿µÞ°©¿.©Eö!ëxÂí@Ø-Ðêr0ZRJ+H¾ú@d=çQä3Åw`ÅÒ6Ñ:í&ÔÈ?ñãûÀRåâ[Hî Åð ]Vé
º_¡G§SÛ0:,}Á@i¨Akm¼üñm¹¬
ðr·7Ð5ñ±¦Oß"ó:¹ÓW04ùiÌÁlìç`Å~¯½«4°$)®ÓwØ qîb÷iUÀÄÊt^Á#bX¦6eàXüÇq^NlYº;Ô.PKQùM
×]Ì1gmAhn>ð3îCåê÷Ri 7·$æ\ÃÊÛü¬mX®c'ß7©Å&KGÜíqdÌè
a¾ë,¤&ÅÌ ?/zɪv3BAm:ëÉàÝYáMËLÄ,[^]H^f2Y'ëRp$±ól$PõDÎ7=¿D(Z[UPzk£7,±èg]ÒY,èÐ;¾ðÎ{®%r¹¬37cßÌg?mæèÝñßÞÒ©&Ý%ÖzÀ²iiSnàYb,+౬ÝR¬6´ë8.pPÁñÿù8ãCxVAï¶gÜÀÉßhAdBBïÖñ:t\Æ«*^Ó1+*^×ñTg KÅ:ÞÂUOc¿örµÇÇ})¬Pjo#¡ÃàYX:úÐ¥ g·ùõ(c0ǶEä[qÌ´èóRNÜTзÝ(*쟿>,çñèö4rƺwàÜ:b©8yÇd«Y®ÛlSPU»ÄNÇ£¾Ð´>ì¹ÙkÂòÃzì)øD³Å^â·dѵm =ü'½Úʯ¼'QÅ<çßÿ°5¹ÈNæÞ(§*Ü9Ü5Ú#AT§6îl/T¥¾r²ÑR\«Cc?è*¸v Z«SÊ2û%_và4%ÒÂ*ø÷S¼iN"ê\FEê!*gxªZFu_O?Àç ëhÂRÈS@EW'\YEÍ*¢£¿>`bF 5Q@=F7íìKqñ¯z
zÌC^¯`Ïf9"XÉY³[¼9Äw²6µ8Ñk¨ LgdàSÒ|Æß·q§JÞ=A}½%}
4¤±?¯o¯$üu!åhéoP¿ûÅùÊm$Y¯ò.ÓúêéûJô!é{SËÐò1wøä®¡±ÿúãßé¬zg)X;ÿa
°6ØÇµ9×ü
PKæ5ÝX>
V¾·ô)ÙN~§
¡RÁÎJhI¶÷2'ÍtÎ̦+ÚÄÏä¼Um9eeJ4Íâ~Çõÿ~ÊÑLÖgÅjykÔ,Ù4o&ÀJPíü¤U(2<0sF^æÒ³nIöÝEÌÃå=nqÕ²ö¤µ²=ÏrqÆ'Ì5ìH&6²ý +dV.uÚ5sÅ~'*~\cfq¬2,ì<CC[ÈXlq
·u
Vâî"£$ÑÁ*´FC«½úà{Ü'-"°G°k8Äi KëÈ¢--Ø*D¦êâ$¬¸êSWüyZ¯óÕ¶²
¶³Ï·¦sVØ\8Ôç¼R.ϰU|
+ü¾W -BGWv÷Hh,×X.z
÷ñ×ýô`!§®Bú*@ñt-êZWí£dë|×KÑÀ5E}\zj`úmrbÞ%*_w
5ªðG?®¡éª®]GÀ§¢rTùa*Âã3 Á忤®yº¯ç¬F@
t
{GQß
ʱS#³®·ã=a8ÕµïÓXÙå4EZ9*{øhØË«ß,»Í×¥Y6Pé6¥·É©RúHUUºYÎuýÙ`Êcüú:-¾Ä2´DhÛ¤I¡'öÿð""_`L-£nQ.Í©ÄO.cû"¬õoóGÙ(å7¹ÚXhA#7ñ¬]üêÅN%^
ÒN xeìXf*»Izwè¬z´QK!DÞ½^µ¨Ý}Çq¾ÒöG¸'á.¡ñL®¬%4QmS¾{ÿ§Ôüéc ©ôûê ,1E3ýþ¢²_Bó<¬WhGøøJ®´åЦ30Såp]é
¨$Ë
ëÙt.0m4&r×bÎYÔSÊê&iqý=ÅdÕÏÌgÜíB7HnçéÀÅ
´NátÖï¤eP?¯ZíÉ÷8"^ÂÎë6ÐY}=úëè.}èÏ#²7¼ÔFTþ$¨¦x¤ôúö]¦Uyfxéz¹ßG뫸@Ã$Ç!¾|ÃôÊmàyõ¨ðü£Êó
[Çô%Hj$_ÂÒÒÄ:¸W_XífÙð
»6¡yb
)&6T*÷p)Ü&5N[§Ì¤/E>qDdÉ#sùE¼ôKIfáGuصÄQ2¥^Y{¾o÷ÛÎÇÿyÀÂï:.ã«®é8ït¤ð½c¸®an_âF7uzÞÒ¡á6{~ÐpGÇîj(gqOG°ùÍOlæ5,høYCU`(öCõ§ÀLU6:v?ÍÐvc»áÛåù¶n'd ì:!ç.»¾Ç&ÁÍÜtc³á7wáfe¾²X-§½FR`¬úÈyìØ¾4í2G PÃõgZÊs27¼ÀS·R³ÅérØ V®ê²ÖiÈhÉYñÉjwÀøì@¸ÅGÒUsLÓï?ue[yakx@å
««28
½O.LB×É] KÉõ(cÆpCp´vÍë=Y® :Õ8cré4å¹»Ö¥Þ¸?Ç)w3ÿjî»UCèªcÁ7]ôc®þ@+rðÚh
[z=)¨ü¿PKøåï.
/q|ã
äøÇ)üÇG9>FáÇ9>ÁñI
âøÇ§)|ã3¥ðG9>Gáç9¾@ã9¾Dgôe¯ÐñW9¾Æñu
¿ÁñMoQømïp|Âïq|ãþãG?¦ð'?åø
?çøÇ/)üǯ9~Các¿åø
¿çøÇ)üÇ9þBá_9þF«ú÷
E½@Ì1í¿ös
fôìNu¦óÛÊiûA±Ð=F\,tÝ@"æRãº9B!,7µµ]©¬1)ÖwóµgU"3Y×ÖïòúÌhÎeK»¸p[éDv;C[ÛÌ-0ãÊQÙ.wèiùÖXÒ®6rfLïKÐ*,,·ÐrÐÃþ½8cm4ÜkÈÀÔpÌ
®6 mU6a
ëßÜÛìJâ °2|\Nد&JkSî8`¸õ¼Xª&¬³ó¨>[R@7£mÇr¶av¥,p»]`D¨c»+ÊTè¶+ô
½XÉv-ñBgÝý¡®¼ÿÑKÐ5Ö0XêÚs¨«o}@$|2[o¡á!Ô56޹Ρá4*EÆ'¦R;|È/y¯&4ùR! Y¨f4ÛH¥DYh!d±BZ$Òb#´ZXBÈe
Y"%6Â%²ÔÂ2B.WÈ2,³zUéIBÄ,WLH2!Q¥la1mY!£jµ[³R1aɦJ2VQÌ*ɬr d:-¬&æ
ŬÌj©ÌkY§µYë0dÖ[Ø@ÌFÅlÌ©Ì&]ÄlVLdº¦V2[,l%fb¶Jf«ÃÔIf»
Ä\©Ùá0õ¹ÊB71=éL·ßo¡Ò;UºW¦{/¢O¤p׬ÂÝîWéÝ2½[ ¥pϬ½Pé½2½W çJáÕ³
)½O¥ezP çIáþY
(=¤Òdú6Iáð¬ÂJ_£Ò#2=¢ó¥ðà¬ÂQJ?E¥GezT Há¡òB
1J_«Òc2=¦ÍRx
ÃD<U%qعÖ%s½
#ÄDsD2GfdÆ-Ä+&&ôHF·0A̤b&$3á0%sÔBcIH&¡s8^ú¢Ø
:¶ÇÿçàE";/ÆI1Aÿ5pNÿPKÜãÒv,
$.Ô
T©E¢Jtç8ëÊA~àSø¶ @âØóþq')%@VX¹wfÎs}æ¾ûñú-5\¶`¡VDuKXÖÙig,äqV/VtvÎÄyM!½¾ Ìmíy<7òdà¶Ó8ÁuBAfý® Ô"BzÝHôÇÆ°·'5øF(Ãô&36ZÍmëªÇij[¡·<}`"ÝøÅ5ßhNd³1ÐBcFk̤*"qÌ5ô®ÕVYìÍP«-¶I7V2|쥡°/â5Mg£5áØXÅEG`Êÿiè%³(Ùì°KؽÌUÉC(×OÜ^äfi¹¾~ÇB¦n?L|wöJg7^¯%ï).u|a·¤ñzä%H¥ßeÜéî ?%\ûYÖº¥£Fo«}o5'=¹ÑØÑÚÝÑo{Q&¾î`{ÇâË¡¤}⬤ÍþØ
eÌ[³M^Oq¬;û §:ÀS}
Ü
ÏA8Îó·%è=ú"}D>¡FYwÏF5Ä1ï¼ùìðjAoÒÀÉhŵ|ÁYýCfýÊØET°W¹TM[V¦¹_bú Lã)ÜßuZ¾¡Bß9«òÎN¡1<!öh 0ýPKc»
é¤ý
¬ýäA{å/ð,¬FP'ÙÄ?AO)ÈÃ4Ú§N1Gª²û7.¢"$HY·gÏÞÁÚ,0Ï×2ýÿ
PK>ÁðÀÐ
Ä@âÀB\oiO«¥\ßû{ìãoß¿|°n
c¤¶|ªrÁ +&&Óê]lU¦j*Í.ñì)ì3çÑ<Dýî1ÃÂ~HÆ@iù²¤Æ£Ôý
ÛúZ·Êa=ijǧËã~Qn9pù®#²Ây¨A뢦;!Ä2Ú!B,
¨!ð±â>ØF.çòGê<a
eÛTWhnô>õÃë£òΫ«4ÃkSlâÚ/PD G~ÀBï#*?áÊ_DàÖ¼MÔ½-ÊVË×q¯âßÏÑÂ&:XüPKï°¯Ì
1P¢§²ÒÎîÌÎÌ÷´ß|ý`}5¬×áá5·¹ãã.îù¸
º2Ô¬,chÇGÉqrÊ©ù NÆ"Ûa¨ß+3F¦U
6 ÇLeÑ}°IÉóâDæ<-ø$ã¥OsZeøL)§FéTçJ~HÌÕHÎ&ê®TÒ<g
ÿÓè¢é½w/F,Ø/gc¡GÉ8£HElhüa^êT¼öaý"mÛ?À*:hðq%ÀU\óð(Àcz"l §Ñ}Ê
íè3X´5õç¨Ds¸aUkÒ '&»Îy¥k£hFg×ýO¨.«|å¼BÃÙ§ÛöM<X¼½Å4ø PKÏÔÒ
FÀ2ÎVøABM¶3³=svæôÏß¿ã~=èDo>\ Ðç
ú
PÁuû¸áìM·|Ô}4*vYåÃÓMJ(Ë×i)d%iTXF2Ó²0´Z*Ñü¦Ë&ÓêClU¦TÌCÞ·ËddÌi¥}$ðxä$ õ7í3YB]M¥éEÑZ$³/¦n'.ó÷iQ"08Ò\×â(^·9è'eʬóK°`>+¤gÊôVsÜ!8ÑgÐåc,ÄmûBLàN»=þ¥(·ódåÌç`ÎiMf&órG¡;Ä=L
·Jc½ÍiKÆ«Ù
I«6Äã4}NS8»_çåâ
I+ÐhC*·Ä\ÚF\[¿4÷ rVàkÐL/GÞ?GÉÓ,K)Ö¬ÝÉããÛ/-{ð%/c-)e]æ66öà`k{º,;ûºÐÚ ¸Ôct²!þ}CDW·
ÜãñbAp|½k» ±Ñýonø]aoßqi/_¡ml§ßàý@ÛÚ¿¢êÚÂó~¡òÖÙ]ø;8½
Îçÿ¿ÛRCcèØ+ÑËEàm êm¢æ}DÝû1ï3&½/L«VÒ½Ì$Á=ÎíÃUö;ËàPKÖB¤E
ªJ/"Ê©±ç¬¼^%
eðÎUA(ËA¢YëU
Tàq̹@j^`!×HÐÍK¡O¥@Ò¤¶JQÙ]jëiËg½ £ù¹Òº»é:îrhS^LM5³VÂ$òèQ ô9¦#ØèFÁF'θmc&&mÜÁÀòéë.S¬V(
(æT
vQJªnSlã.¦MÜÓ36f1ó³qÜÑ+iUW®9E©(
Eþò¶GÈÆô]6% ÎC§«ëä)þc»[
bE½@SN÷xæôÐÜ×ó(æq,pª±áù¿ó¡ùðJ®äA<W¿F*íÁ+¬¤m^gÑß~-0~²\øb9ÂI}Rô¢@»F/W"rý}øÅY,êkí©£CÛ{°né<O¤Ô{®Y¤hA~Úy¤:øtéJ©þ>Ý8ÇòyæXÖ+¿ýcz{øßÊÆ{þ÷âÂ}ÈÚ&¦ù]?ÐTGóWLjáZ^jªÏ.Zë0÷¹3Ìí!Sõ
mµ®{Ãe1)´õð{ ã²ÆGL0e|Ƽñ
ëK¾kL»káÇtùlZþPK½p
°+(¾g2åL¤'
é´²þú
î~%Vz|ñIT*'§NUòüòø`
K 0QA?&La:ÆL¹_}×äµuí&µåÔɤÎe;
7©ÔÕ
sd½ì\ËãßVw]fÍò&³'¦GnK Âqß%o4snküÀný3¤ßNú÷²6 5¥E¯EîDµÒQ: Èe®Gmåzó\](©.½¤@ý£ì¿$K³Âi:0`î½k¡óUıPÅ"æ¹;¯£¶!
m³Ç±É
E¥¾Ý¦g6õ6\EÓ6lö°°5vröÒ'ÈÉÉ9_¾ó$¿ÿüü`[ æÐ¬¡å±ãIµOæýX»Öý>
»+:Ï¥rrÉÂëLªÜ¨ÂZ2^NµSòäÚ¨±Í¾I½ÎÍ©}-Pã¸×9÷µÑþÀÛöÿvÕ^>"ž6tXLdOÓa"©
Èc²s;¥ÀV»?I/S^yIú ¼~Iä
Uô^µY5÷C Öë±ãYØäÛ¹¨0l/K#'Ð(µf©9Gà )/°1S~_;O|R ÒM¼º¿~%G¾7&uÁ
ªí³Î
Å\Û¢VUD%¤¨Cog ¦¯d{ÚU~qàôGU¯¸pK¶Ç3oÞ¼±ý÷ßå¶, UG<ÂãOb¬ÅXXôSív÷4)dîÎé4ÊÉI&¯3©r£
kÉx9ÓNÉáW£¦67ú[êunFzFöµ@ý~J^+æ<ÐFû7oÛ÷!íTûùVÚÐb6&;JÇYð¤* ?=Éí&[íÁY:Oezî%Íõ»rì,æ
Uô^µÛjöC 5£c£M<çÛ¹{»/ Ð82l?K#'Ð,µf©9Çg¤¼ÀæòÚyâLJ;4ñêîJøùþÔVPmîc?ÅË[äÙ
=ó^GÏt¶vø\zº¿ º{?}Ghk×ýXÆÊ5þÅ5¾Þ½@TùÊ
< è7jѶe©U<-#,«,ÿPKIóë¸
cîy6W6vMé
øµÜø]\Ëq×sÜÀÍ9n¡'ðxv9½û\dä;ÖR=,÷äYGK¹d òÕdtX?AÅÈø@ëG-g'Â
PZ÷Ì)
ÓõèÿàcÏ+IYþ/fÁ1uíª*hKñû³À?\ å¹»Æ{8]ä|>ËÖ&£'|Üýäb?ÎññH~ðºåñ}Þc|>øä+æ>cþÍ1"wÉOt_l´¯b½½Ì¨PKÜ®
&ľ@t^G#/
Âáè>ÝzÄôfTÚõ¿·È4CÚ¥¢ n=µÔª¿SFyå_# Ê¡ 5oX¦ïfQ±Ó×}Cû èaÐL!M÷9:Ð]K¬â[°bé
×@fhñÖ8õS¿ý]`©4Aìâk«íaff®<Aâù?¯5ÏH_0k|EÆøF¾¢NãöJÉ(*ü
ò¾ðh,ýÞÝàI0±±[&ª68j&¶lÔqÛÄwqáÑé±olÕÀ`·|_ÍE""Ð1¾áå/ºÂUù ·e¤ù1E
|åw´0,öÒbG(Ü1µùbiFä¯Ôè,y+×ò=1³´J÷åÞ3Âõ6¼+Âݸ½õ?É%VQ!NO/kDjXM¼¡êkÿZÁýÅV©
5zr5ì,%=;´/@ ZdI^¤Ó:ÉZc?+ø
&Ä©@t^WL"/MÒßÑ}uðx4Ñý¨¼ÛnY´[E<<z©]CkçÕØ[¾ö¯íPÐ/6KMäéËYT°4uïÐ~ zÄh¦¦û
t׫ü ¬\ùØ Â
?
6Ù¹3wî¹sϳûíûç/
B§IO$K¯Âïó(Ù{ ÷ÞW2àëõãÂyO&ß]O#W²·¡ê
%=êʤPgXýÏ<õºqÊw®N·%{"¦UJµÆð¦xD'fSzÁv"_07e(ö{mo¹í<9©D¯¥\%®vÏ0[ln»»;Î×
=æ²ZQ?öÄ¦Ôøéãj¬i¼ l#gÃÆ²
ªtOzw';2ìðÇNÔkGëÑ®[¨à6êX2±lã6î0Ü?}§
KÝC;$Z¹!¹Èògímá)cø6eBB1QÔ¬§þÖPzÙ¥;èëL±tÔÅß7I
9B8ß}±;<¥Ápïôtéb\ëõ³¬ôoðNøÏÅkbU?)X'¸p¨¸_.e¥ô§>ú,ýÎ!
¼ÍÏC?y³«½äc¸@³EZdÇËÁÊ=¤ÊÕ=ï¡ÅqÆYhÄ¥CC4ÙùÊ>Ò_1ò¤ºÌZùR`1f÷1úò(I^1j<±9ás/«ÂY]yvX~
®2ÜøwêÅ¥ë`pÜ0¤¡^eä"˶·¯òGðmÊXÂ1X%ÃzæW=aÈv
6fKî°¯ùRyÔÅ7i¶B:DÇ
;bo
.RùÏè>^¿G¼¯¥h*µM¼KF]2i5Rÿ[É[véÁ¤èA1C93eZùrfð?¬ýYò1 ÕÙé©Ê°Êâ>ê>¬·0Ó:Ir4¬$§qê;è&A¤óH~ÆØêÆ×ÞÁ®¼U¨`âé(@ε^bÂz
Ië5æ¬7óô°\"mªN
kÃ7PK5lA
½^Pñ®L<NX¯G¡|á*
Û²+âU³&C©Öîÿ'ÐSyÊ®G¾`È5d(¶zÝ·ÝV@+yâÕm*WzÇ
ÛÂg+7vݾËÝ=ÅE_GwèÌ==ZÕ±¬fÔ=±)5~ö¸¤5·1ò6lL¨ÚXÀ"ôÞðdOmþ u[ÑF4°q
5ÜÆM¬Ø¸·ÿziùl'I°ÀM-X~H. ²üQkWx¡xßL QÖ¬g~ÕɶPzÚ
;êk±\uñÇMÒ6O£á;¡/Ã,t*F÷ÉÖ}ó§+ɰòû2jά¨¥¿ÅP .;ÞKÞà ¤0¥
¦ñIèoJkÿ}¢ÖNÑhæù\õ
Xua©êâ>Ð&!ãÙiùºC4ùâÂÒ0öpñ
©%ÏìíÌ̳ûîËë7
½^Pñ®L<NX¯G¡|æ*
Û²+â5³.C©6nþ'ÐS~Ì®G¾`È6d(¶zÝ·ÝV@+9©D·©\%ê#b>ÃB©±ëö]î}Ý¡3wôhMDzQ/öÄ¦Ôø¹£Ö4ÞÆÊ6²ÈÙ°1i¢bc U½;äÉ@m~¯u[Ñíhhã2j&¸e¬XµqWnü;õâÊu0ØN`$Z°Ü\@dùÖ®ðCá¾
(A8£¤YÏþª'Sm¡ô´)
wÐ×B©|ØÅ7IÛ!ï¾²ÐE*ÿÝG[wIÌïñ¡+©©þþ¢6JgVTËòßb¨ÖDM²C/%C/áRÈk¡i|úËkíÌRôOÑà -ÒÜ ¼«,í!U©îÁx-Ø4Ùqò0ÞÁÉo I/,í#ýc÷«ûßx³òÆBmOäõQã&4>aÞøL9O*Å%òºę̂6|PKþ¦Ù9
=9Î(ʱ%{²À¿Ñ q@ùG¬âMØ,ùm3ßÛçý×7oÔp=$VH`U\g7q69Kà<.$qLL¬(2¤WhK'jôé!¶g3$ZÏ|ÕJºóª'£Ba«):D#Ñ
¸ñÇJzÜ
|wÂW¼/#Öí
/;Jþ®ìpülI_ªmÛÅÿq´g0ÄAGPúMéA¿-Â]§í%-è·£D£çø]ÑaÈûÎÐáÎHq1ÔÞmºsWKÚW²BWÜ¿rTÐÆ[È d!
´&Ê*¨2,éÓ1FÒïò ßîcWP3Á-Ô±nbÃÂU\c¸ùï¥Öo0Á²}_
Ï"=°ô´8åÚûÂU¹#êmÊH Â1E]õò¯zÂé
¥ÕðÈÝa_sÅÒ¬?ÒlÓ84íwÄx
©ôgå>Þ¹O3Õ{ȰñûíuGS@ýo1`$Ævɦ Ãp1dõtI>ýeõÀh1ú3dc8AÒéñTù5X¹rX¹z
1RXò<vçof¾~ûô@ÜA,aÓ
زQt°m;(Ù¸i£lã6ÃæÄÊýäèHDmïçK}Ò
Ò1Cê°Ãé(=Zúz$ãò=½®$<§br?æ'ZÜDPeìsÂú£(Tò§e¨äXD-ʳ'Ôû*ÿè°S}Í`µÃ`Èv¥/q_D^? ÔbÜÓí§bÀP¬t½Ç½©æbb²w(橱Z&ÓÈϤÁo^öhÓà]äpÇÅUd]\kc×EUUs;ãñTª!ÞÇýðq8sQCÝFÃÅ]4þ;åò}j>ÜR4°Àc3¨ÜT@$ù«þ±ð5Cá]kA8tÅ°ÝøS/VB·'JwÞÏB¥zѽß/i¦9BAG
Älþ
-пÒ}"¼$ÐfJJ?×ð± R¬
%Úä1wBÞ4ìe/oæðËKÑÃ
ùy²vÉOÎÖ>Õê§HÕ§H¿iâ5¤am¼Õ ,Òëõ3X_°ð¢qÅýÚ{¤Í°/Àyf±dmcÙÚÁU"èÚ¼uÜ"íPäÒ¼.|PKE«Þ¦
T¼6Ò2\ô ¡Ó¦bb1ái»;ilgÝ) ÿJ#5ñÁøì2~SÄãmï2sÎwùúíÓg
úq,á=°A7ÖJ¾õÔjÄkij.4[¥ÿ!Úo_185
¦Tb·ßkxÏoGäÉI#z-ãQëúª#B¹RóÀ?ô¹d¸8´ìu:óÔjk+ÛÒý8;Òâg.
ºhñ&Qö0ã.*ªX`²»Ç<9ªÃ5Ýkëm}ìá]pKXv±âaÿ{éÅe0xu¥D\ü$±Ë
¨Xþ¢} ÃP¸ Þ¦L Cºd«þUO&;ÂX³%"¢;ík¡T>ïâÏ4Û!N"¬«P£ÔÊVîËÝgîÙUdXýý9oZu(å¿Q xN©QnÐÉÐb¸òvĤ_ýòvê?¬ýäc¸BÚ<Ùi`ê R
¤ßÁê*£$álÐ:
kg M8$Õ/y¾0ÀèÆ{¸HÏñÆ^äíQgcÎ;[u¶)æõa&Ó¸OÒfæïPKt7/
_YÝ(V1úfqÖs4[¢ud¦|
V^>A¬;Aü3ôºE$Dp¹ó -
!-Ë_ûÄwL|8E2k"U|ô
¢ UËñrµà[@¿Ô4 ~Ü^7tñØ3w{Eý3þ5"F?Ê8Û0DMïÃÜÎdæ¹gf¹ï?¾|°{y8u09sºbÌÕ<¸æà:nØ(9°1ïÀÃEK6úBè «28mÍuJBm·ù+?9jÏTã
®1äë¯n -*Ö-Ëë5ÑLý(9{$~3ôS-C?TƱPÚ?IàSmÐ#%ßp-#µ#DL}ëRIý¡^êè,ÂóO¬¨)kRÍô !âÞ)SE¶d"I«eênU)oÐxAÓØí
Y±RY?{N=Jã@<ÏäYÅ˦ÎÅ0F\0ébc.1dÃwQÆM+Xe¸ßÅËÆmwp·G°
ÃáíºÝjì@3¶S¥º°ôoßÙiÅ7é&y e[ø¿_Ì)GѬ*Mc/ÿo
ÉdOèXhQ6zUCÕHnêwEÔÝ%©¥ÜTíè
¨q-bRíÏÙ¸1³ò$Wdé7@ª ;jÄB±s@Ç#Áx&«óäÓinÄ;FÆ[8BÖ[<ó²G°ÞìÁÙ!cmaÈÚĽ.`òBa
7Á=m=Á°µUǬõýÂØÊ¥5DðØ»Ò>$Ý^2¸Ô±q±ÓgfÑ}ìîë'PK(ô^
ry<6ì£ûUâ:äòxRr*ºÐ G%
©¨ÀyÒ+ï=-û$ׯà wTÅSPð:aÚkdÃÀâeÀrÓ¶H¦HrÓ¦ÓØÊЩu^YÝpôTFϹfF7²³ma¹ú´éúð9ËHÛYË|=éYkÄvCänZ¸¦AݦeºÅm:ÁÀ{³)Á°9aZb 7=.ìäx$Ç%xÐÎY´Æ$¯gs¶!úM ^{¯K-SɳI
;Óð0¶k¢^CêhÄq
ÏcHÁ°¼ àqRÃ)ix /+8á^ÑĸCnR-÷çF¿4¤)&lÜùÆAKÇePnsZܲÝ+ËD8ÒÇÝ&Ö`bJëÈhÆCIZzÜr
mçf\ê5Äo%£E¡¯¥QÃÂ6¨º~S±öþàø0ÈôÊ5ÑPβüêX§7âU:þ?Ï®î«cM»µ¨Ká·Í¬mºç¨üb^¡tnܪÝÕfëMgMCz£Fì/2>"Õëwué;ÅðÈ+¢CÖ?AQ)ó]èóÂòãrr4È!§q_+
âý¿/¯Ý)ª>2«õAïP·O
×ëùøùmÿ»ùCbâͧ;wWßrúÎíÜ´Çâ÷éÉêLéZËá¢øwKzü̳®WRñÔì¶ä<èÈʤKD¿w}Ȱ¹:è9a¥Ö¶Ó·é+JÃ>Ïr~Îv@þé'vѾ¸Ð¨n^kÞs
æà5å¯áü}ù(ç¢ä¡ì^ÂïDJú{ ÌÊeBùP>¡GóQ¤wk J
5/wÓìä¡,¿w¢y½0GØD
_Ä1FÛH%ÒÒÁ¥| j¥|^+ ì:Ê;C{·òÚP/¢F|F#زÊóæá_BU°ç<cÞ£CT[@U´êQßüÜ_oÌ#2] 2¹yÏa[§2P²ÒY"uxèrÉUr]Áä±ègX!7óøÊ£+¸áQ?H§QCAú
NãyláØÁÑÈ¡óëØÏ¿F7ÿGù
òo1οÃYþÞä?â-þ.ðñ6¿wù-\á¿ ÏÅçü7¬ðßqÿAj¢WhÆa¢u^¹´á)âk>K´è(JþPK7r×þV
ÃÓ¶¹Å
îQ<5ÄJq,<dxqñ52ÌOÁÝqÄw?дÀÓV
í³íYgWÎ0h7Ðb XõJ¿ÍÂ-êcª·0óOÇéD°~GhñÞ"ÿûXX¡WbÓ/!¢¹Éó0_Ññ ¿Ò¯tô$ñ|ó+Xsíæú `rh8ÒU¢×P%=§$²¢Öüäg¤&H©À2ÂÙS"RP^D)½jzÒ«ÓNjä5 ÐÄesÓñPK×qVÛ
OM yö+ÙnÓ¨-Ç4êÙomFӤϴNºCó´ÿÌ_î`Èí ç¯t÷ËùÏde%¦Î[ÂëíLûiþä>Á£)_îµ
§»é(|8ï0î¼ÇóÎG¢¹7sǦè¿qäb6~PK·^ù6
U[¬ÚE»W[kwkíN]¨Òÿ¾, J Ï)çpÿåÞû¿ÿþ;Ã3ï>ú8¶QA'.±c.Ëeb¹\Á¸R,WÙ±WÛ±×ȸVìO*Äù`ïØu
®Ç
»QÁM¸YƧº÷UKdܪ ÂnË.·+/(ø"îq§©¸KÁÝø3ðe
{ܯÈè±[A!î³ã«¸_`_Sð
Ê0ÞÙG<A;}ä1ßPP%½l¿
ü¦
Oø¤
O M¾e÷<hÃÓ~GÁ3xVxÎï
Î÷lø¾?°áy_°á
~lø± bÃOü
?÷~¡àE¼$ÌñKa_e,¾i1ÄÅ
&ñk¡ð+bù8ÿ[¿ñ{aú?Èø£ î²áO2^UÐ?+¾&ÿEÆë2þ&ãïÁpÌßÖÃÀüx¡ÚRxG(VXÆPS¯µ%JõØVm³^¶
KñP¸4¨G ÃÐ"ñÒ®P,XÚ´-ì0ôHèâ@<¤GC]QÍ`'~¼C$³& ÅÏfXâP¿Ö:kÞ¦18ëCmu¢«U3aâHF"B«WRôÔÄçxÒJ¶º*bèQÅE*ºQ¡#"ã*þ©ø7Éø7ñ·UÆ\â^Oilk(²¹tU} U«xïª8 2Æ,*UeeÈLVÙU¦°L©Èb(
PWeædXqê+¬
F%ÒòÒhF]8i±±hW·-ÓBÈ,[eKe9ÌŰpzVÌc+3·ÊòX>ÃlaðÒpÌmhía-/õGºõ`êZÀجÅõµhÊTÑ#3Ê&áÊ&³)*J^d§©ìtaúYcSníêcvS³×ëzT¨] ³i*Îf¨¬!³*;S¼Á{bvÈaâ±}U'-Uæe³ÊÆv©±nXYVÄfçM)F¬¼Ì0t
i
X¼ #ÐhÝZ¤ bæZÞ^.ÓÄý²2ئø¯`sòF5Å
JÚD{;
Çæ«¬UQá)ÈK³EXa>FµÃâ'¬F`R}¡ÙÙ2[$¾°X]Büæ5į54#u&Z'Ð¥¦ZòÅ2uÄYnn%t
@¹¿µÀGÄJæÙ*#Q/ò´-Ùja*;UYkVÙy¬¡êF®5ôN-Ná d8mÄþH\3D4®µÚu Ê3Ê#wóëôH,n$ÌRP0¼±h6_8o½ÊÎgù*kajÇ!nMDÅ cÙ#¯YÓº
²6]:S¬µH$UµGk6ã!+ýÁ!:×;«þØSäÅÌo4Bºo£¶à5»Ãòq¼B(®µ
¤EÉÁ¡òèß86úôß©K¢\3´X"7ß
6n¬?ª5Õé]Q=BBèCYT$ë¶Ùв¨kÈ¢Tzô°.:vfh$6Í>JAÊõe¦³ÚRV&¶shd¨ëÐCAaËF$@XáÜ2¢ãêõ³N|yäÖæ7yâ2xÌz&YÆ|ì(õ+>rõ×jí'>Ý965R&¯PlØeó¼þ1¾dhà¨.H×Þ¯Õ"Ç$&Ú
h¹
}ØÝ8ó
Õêú÷[¦FóÄzÉÅC"³B4tjK"më!rn¾÷ýâRs7ÅÁÎfzûÑÕ¨i¥j
¼Ö#¤dGÕáz=ØIYt<ÓsJKRÎc¬#ælm«d"âKÕ@Ôå«?ü£Ã¾Cp5ïã*ÕôtkT×i¶)?ñ·é hZ07«-Yh¬8*Ø=ÉPzb)P5%?ØÉ[M@¢Y½Äë2©&,ÕÂÚæ8PìC21Çÿ«cÇp>5¤ÄIaÎ|²êñýæ©IѼ1TËE!
¸VÄI BºÍ;{Tõ%¿;õ®^Úª0]$Ô tiGô³éÉhTÍyÎñ¬òVj¤¦{©%¿ÿîQÂÒEê«A(/DÂQÞVJ¶ÅÕ`þ#]LÌ=9Iõºiò¾döòUÂ*«>èQCoK5#¥¦*j{¢k´¶±±ÌûKµö
ÏNb¸|ò7÷ÈIäwéDnK?Ü>Û òZÜܺÉcëG¾Ï>g/&úZ=¾ÌALj)*îÇäLé
çzÔ$N#¡§ïA póLódÄJÄôáË*½(¦(lñdyÙá±÷ã_öÌôbg&áÝá`nß}äù^ì÷dfù²H£»PRäsxôÞÙÓâ¡×{)i$7«%>§è¤#¥$²ÝnΣ»5²Wy?*ö#\é*½X;,5Û-Ôá¯N0åbs=ÙÃò'ù.!ß%¥äxú[;Ìít;î>ò@ÊÜó¿îAå ªÈÀÈg%ásUÓâ&׸&<q¶ka{°¼%øKLª6MÕÔÒ$%±ÜµÂ¤V¦÷ü&µ*McRõiª¨¬ès£1½q®IMSMD%ÑÄyõÉ^dúrzrö{ìI¬[^mI¬¯"W¸3:®©ræeíÌÅù¹ØÐçÜ©5aâ\P#'V)m rLe^EïǸp7ô"èãÖݨêE/ÃZCDënÙ¿Ovi£+.@Û
¦2{72<îý¾¼Éùho)rç{¬ýØ<@¦Ã=t_^¸}Ø©8h¹Ár3¥òÍ[D¹åå06 (qLèFåðI%´_z6àJ^eyS@ËaÉ" Ä% ÝÒlHsÍsfö³éXIÙÿdëØ9u.a6·¢ÛQÍ4pëyÜgã*îÂN]Ü;yîåôñìåÓ1Èg`??ùL<ǽxϼ¯ðÙxÏÁ»¼ÙyËãå¬W°|.+ãóX%Ïùv!÷±v^Í¢|!ëæØ¥|1»/a×óZv+_Êâ+ÙcÜϦ½øö2o´ìä,·qÍrßl¹,÷ó-y§å)¶<Ë#xÔò*¿ÈrÇ-y·åß*q¾M²ó%'¿Dróˤ)ür©_!y9YoªùÕÒ9ü:i-¿^ÚÈo¤*ºÍ¬ãETs±
Rÿñö4ÜBü¿ÜNð
ØþPK%0 û§
¿4=D&ÌÂg¸ M
],&IÙþªAÖ±¼&,¢,)4)t)²¸p8¾êÅÃ(W
A}LðïmþD±Zg¶}oçV|æIïÒÏ(-ÝB©¿IûÑ
dP© §Ñ@Fzh Ø
¨Ì3ÌѼ4Ô 1&KcÓ}eP¹ JÏ&ÑX©ÈÝgÐx.ë<â¡
&°¹ëôÎD&°%g²ASL¸uo8SeXÔM¸SæÔR¥¦eNã¢I·¦§[3ÒCÓÃÒéVUºUnÍJ·f§[sÒ¹®
èð1ª1áY|ÞCóĦóe¸{hAMxQä*½´êdÍp±ê
ZbÂ4VFôÐRLxË2Èo»´,µ|©'ÕÐS
˳ó»ÑO<t´AÇð9GX© pARèRx¤ð J<ÔhPÐï¨ÉC¶A«LDjaV{hA!³øX5(l¢×?bPÔÄ\§§ÅCÇ31LS"%kÛÐ>t¹á7àZgÐzÐ!´Ñ¤ãéN4ñ
jÒiô37Iqº !}gtΦs<t®P?ϤóéÙzèçâz¼Õ.2èbcQÄ^bÇVM$bǪÃxÜt ÷Tb±[j¶c]`ÊÔz;ãÔÅBD}"KÈÈhª¬tBÌ´9¾W¯LËk©ªvQõüÍÜ[ÄHbi ÜjkÊ@`-©Y0{ÑKÔ<éCo|c$¸ Ú$¤¼ugW×Ô×,Z(&M¤eA8|yÝÔZ¯·WGËñò¦pyk".F#ÁÖXÌ$ÊCñ`y=S\FBÇ¡hD)=¬C«iLw
·íØâèzæÕª£áÖæî9 È4mg¦¥Úé!+fÇ[Ã%Ò¹¡xùòÚcëÊãëCÕåóª£Í-ÑÅs#ö²aMÓ\ñút¨a³ÜB¤qQTÌë6+`7GYò±?L²:
®uæOÅ£w³z.Ñb{¨F[âuìYì$L¤¯\]ßÈ.Ó¼¨ÝirÏÈVE£a; ÒqñÇx"ÚÂt3-[ÕH8*$ïÂÖæF;¶b,ЩEtêµF"Lq'+/Æ9ãÃÂÃÀ°ÃÄÃ-*/§D+X0µÀL×ËÃ5v"D¨ì áºÖÆp(ØA|JOgÃ÷³~¶Wx+Ü©=µÑÈj
:©G³?ºx=bi7+¤=AjhI¡Mè ÚЪ¨ÂêÙ:ÆBÑX(±ñGIº 5aoè9ÚbÙÜ=÷Å
iÌC{ÄPEʺ½ª
ùÝ9:áÎèwnÆøéD G+[½&éïÕ"kí¦#ZíV{ßFÎm»hûjªhk¤ÉnúQ,]ܪÖU«ìX¨zi
mZϸ¥<Þµl±ëÃÑľ[%uRD[ã²z;0½'êÍ
Åì`bö;ØÆzìjÙÓì¦Ô®îke¦Ö=Úmιß
B$¨³5_o8uè_º¼Ó)Vàtpõ´Ky¼33>ÖÙmçUÙç>Í<À½ÊçsiÍÈ=)ð´ÆP Þ1Íl©è¬Æ IÏDy˺¥ë¤³#·%bNËøàwr¯ºòþ¥#3ÕÏØFÜvdΫ©Ì ')5´Réòò¬ê5vpm\è/®ìCBPb
\6¹©\Õ
º²å¯1ZÝÀ[bÑ¦Ö «ÏÄ)äU·6ïÑÛ1NMB ;wAɲTÓlty䨼VÛ
2ÄÔN0Ðò^tP$G¶&ÐW%Uâí'ZYßýJ3U¨
4²å¡89Jß)ÜiÎâ,æ¬IìçL½!h·Ü|׸a;ÒFË"AQÏaÜùÒËó:ÃÙ+#/íÆ»I²Ì@/ ñaãÆCHöârÀälêÊ0^dH´ü/rñÿ ÿsþN6â?Iø×÷÷ù~Åä޳ث?»,¦C{§ó»¡Ä¬¶ÆöD¢î0ÆLÞ[øü¥
+Á£±ÁÂåøÁ6á
®°èJÜPÒe_,&æÈÞC:¦,ªI³ìUΤX,³è*ÚláUt5B~ÕçÄ9hñ;VÃ%¡HIs(Æm6BïÜCzq-
tzl²°½3Ç#,íîÞ9Ñ$>ªyW"r[ë
¥ÉpVKJ]Â^¸ÇÁ&6Ï 0zGl*¹ÿ+´æ/OÚì%òÆÉW¯Þzã,z^âóaf0Zg¸êNhgáõx
7H±E¥¸I¥¸E[¥¸Zk¥¸Nx
áÅ{DP÷bÂç\a
ó°Ú³ñ^=Ò+}ÆôE¯òæ¦×èuÞSç¥Ì®ô+,zSFNµ{âö$í? ɱûF¡ `KDù³EoÑÛr~¿P0¼¤ãêV_pn·½M
øwÅïYxP¬r/'sÅiª[V¯xM^ï³+²Í- 5Öîõúd>+ïW"÷ÙN´Ýl/ÉO±èC!? ¤9°!µþô§Zô9±Î5è¥-úÈÔÛ/%J³FÆ{G¿bAÃ<)nùW>%Í ¸Ùno©'ùÄÂ7éoý]ø|ÚK*û?>£Ï-ú¾4è+þA_ôEÿ¼æ[úEÿ¦/-ú¾·4ÀËSé®JsÒ7CCK#MãMÒñQÒÔ*û°Äy¨4Ù*nhYMW³ü ×'¢-¾µ¼¡ªz¡Yúícn/tþ^ÛˤÓË^ÒIît¥äÜÆÅZ[vç;gß.×R>wVEcÕ}Ò\m'ð
;°Òn_ý
»{âÛt^ ©©!i®¯
±<±Îî\¹ØëTÞ1C!öa¦ÕNSÇ¡B@Hæv¾×¤{4æ0ª´3JêãîÈî:Ù»Zrß4ãvbi(RÏÙ;Âv÷^êÜ
uô¼uîI¤ßTûtLOrbÈyÝX!ý¦Z±¯[V£ÓTßðÕc)çàY¥Î;ª<:wQ§ÃNß@××µ}'û£lͬõkBröÕfÈs/SbÃItä
_ÚuPÌ]9+?s1RûucEGô>ÌdA(jnm®ç¿cjÆmVqòñTùÂÅ>n79åMÙ¹çwBçÉ<¢¼<¿;«÷ïF$õÜ|X¯ÞjR[c¦JQþÓÖÈ¡6Ò rMï~aÑ!¦9îá¼&p¸È|cvßQ%BVcXm\eÚZ×þ
ÈÑé|`¼¥Ýía5´¤÷]ÞÄç ÙâÎõRÉDC _sBuѵvm !Z«oöÒ-ÃR{MHçð¬zN gOÖv=Ô¬¾¼Ì5 »¹cKöXäÎãλH#÷Í(êã'õ¹·>ËæX½ÆÙ)Ak8
á[
z5s¦[©1Ì*§ç ÄgE[S^fIÜõâZï°÷ÕS½2ÔgÂÌÞɦ\Ôrn»V~CÃ+«¾øÔÙ±ªTêÚ7õ§/ýÊÃtçyqÊòe¯
´îWÒj÷X¼ó mñ^j¥yBÏ>È1ÅÇ÷IÜqÞÈyÿÏ
GO½Ë`(àd
½>3<Ù+ÕMßÿÉSdðp~yçÞ"oUòkwll¼rqäá,ýn¶Ú,ýÃ0á%~¦àc0
3ðqX¿åÜnÄ'á$|ñ/Ä»w-;ê^7°" ãPq{]¶üàßãÿ/Â
!2aL¬Õ¦o
ò²Aí05T_6¨¢&ûytÞSpð «ÀâÞíPi æï)Óá!ÛaºL̨ÔÛáPþaÏjYíPå÷ú|mP]-@lv £fùóg·ÁJOGl6שç*+ 5Ì`V¡yêXr~.K±¢Ð«7M6Û¡VäWhVÜXÊ
9E9í°È?ªÐlº$QSÅNUÏ]R3& G:ĽE9õe
Þ¢$,mØäÅB¯£×uúds+<Th2«aµ
sÓQUdµ9å´Á²$,r,VdÕY¢ÄOêh®é1¢¬A®hËdû(ôuñsúÖõqW:U+
\1`Q_µ
-^ÆpÃ&-ÿ¢ý*¹ùo¬/Ùe¿ýðì¦_ÃüFþX
fâ¿àpü7,Æïa%ûb3!@A:OYp)eÃÕdÀ-ä;É{)î#¦\xúÁ»T
÷ç}î-îm%Ü;? Ü
ʸ=Qûfòá0_G¨Ó9Ϲ²=áÊvÏL
%ÎV6ï¥ãr6C¹G9w\Ë·w»ç)ÝòY7Þx;±_·ûN7`º^
`d?»
p@+VÅujK«QÄAýpp÷:¼Î:Q:ì¯Ö§¤,ç=ª{=FÃh}
LÔõJ8B
Ü^©Of}6¬×çÀú\FÙ·¹zLe-$Ð(6.à}r%qDCÇu£ÌÓ©/ýôå@ò\
é<&T÷ì$4};%q¤0£:Ȩ§>=ýX諯
zÅý:ßÎäîHßCÊ#x¢ed1å6§GHwÝF9Ëùç`êv][öKÄ1[aèíXîÚ»cKNâx¶v+ÊÞVöðVð,,{xÌîm
_§Ær=*Ö(WuLRµ#Á0Xuo
a»¨Ùçж=0ÒkÆ}
><Ö0qxáÂI¦<L{x)PY×Fç¦Ú_ÃÃP%¡ÙWc½Öw6ÒFÚÚЧ¢»G¶ãÖʶ0l\¿6¢Míf·Lt`S£¿¹NMGwÉ®8ù
7zÈ4r¯IiËw8Ãè+øó¸ZáAɪxdÉ~ܽ¾aìXGéYbÏ|!]6rÿ;$Þ´½Ó
Ãú@9ïÖF²+@òÖtLàÃò@¡uLb6`êuLcFÇ]ÜÓ±ûÙ^ö^T¸1äûjvΰÝíÉÿFÖÕ(JÈ<zÊùá#Oö+å\î<éîS«ýûé
Z`@®Ñ£Ã$1%ÓOoJf´"Â$ýÔä5K³YBF¨,6Á~Ðá*)iT>Ò8G¢×ëDMfZHH~?ç^GºÊoÛµÊÉ&R-¨å&Ò
©¡Ñl¸½}#'ËyæÙ7½sÌ4OV>cBù9å+å
dKày$pã1týHÿPKlïTE
U«¾ö¿¡7Tµ*é]$ÆÒÎ9s.ßóí¬xt÷8Þ
âyÄèD">lb¶°
ÛåF¿íðc Hò%©IÉjP÷SØ]rØ--_à ^Á^9þ öcXzËWåËÕ >éHÅÃr:ªâc*Ƹ5ìhCßÈyûÌ't;É%KèyS/Z0Äaëqa;#ù|a!06k:Yá:ÅÙi³akìYug¨ÊgChÄ0ÅhqjBXãéiVXEÆ4
å.
¹ÑJÉõ¬7«iÇÈãÆ°âÓÓ6 Wê×ð:«8¡á
TqJÃiÑpç4¼óÛmÜC×íx&hãhãmü¨eä-ÃSÇFhHcB+T\Ð0¬5\BNÃLy
Lk°¤Æ£¢(åI
%Ä+Ñ0+ñ\
ÐðÞfØñÔêíµò¹7mY°öÏè¢ ÏϰN>KéË*yl áôR;ÑÍ`ÐR¦)¬¡\Ú¶
ÍдêÈÄE¡;áEÕ±¢izÝë®-Uzofû¨°*'cØòt&-@dèеï>Ä®Iá¸K1Ä<jÁ2¦ÒÖ,CoħÓN?%uëɰ*Ö=²X=WII]N¢3êÅêv4ÊÑÅQ3º+{ÖÇì9aN> ÓÅt
UùåÄØ£üòÎ)ÃPþ¥<Ä;Ê¿ø@y|Ê/¹»ã[®â{ļ?ñüÌñáÙ?äaÆø*æãÍÌÏ[X¯¦Fµ²¾õ𵬷±-¼
ð¶w²aÞÅNó
ÄÆ.K7á5ÉKBÚéý£ùPK)<
âÇø1è(o~*3Îè8þÔs7-¥éÉ9÷ãß½÷÷;÷î×Ï_л°[F4a2
6â¡(6àaaö
³O^aö+xDë Gñ0D·OLæÓ2(Hàq21½qÝ5]Y³XM;ÞfÉI^ºXNW}«6Û¨º®iûéåé¡ÜÑ^yµ*º;ÅÀ-ßt=6 FÑv6Öïêo9¶Õ]×2Ýû¦²eªgPr´êù¥µ{!2f¹o'öeÝó¬c&
/Y,'fr3)6<áZkùSy³B'ehÍÒ×ÓeÝ.¥ûX,?eûã¦oÄß~˶üç;Ö@àÿzȵ×9Ì õ9Ea]Ö²Í\µ2jº}´L#ßôü¬ãL0lè輡ªm¢#\ça[ÇMyßµìRoçmøSòNÕ5Ì~K¬ÐFdã®c[/êâ
ÿ
×øïøÿëüùUàÒ.º°½.+$¢!Ù´s7¶ü/R|}ðÝÞD~}ê]°sÙtÍCZ
-j¥j-ôÁC4ÕB" %HªT´µÚþVzú[çô/(½wvv`Ρ99{ß¹ïï½w&7ÿ{å*(¾á0¾ïÇü8BÁBXX°/1õ#/3ø1£~Âà¯2xÁO¼ÂøSÇgðs¿`{¿dêW~àdxÁS|t:0Þ`êLoâ-íûk?Þ¡ï°Àoü8;
sq|×GYààíÛ·XÕçÅ·Xó=çÙä
Ý´UKJµY¥ZŪM$kY©vL©6¥YJmGû %ã.y
+ ÕÐîUmM¡ðiºf¯à©«ßL7²Æ¹¨UÓÝÚmïHr6¦j©tCÞºfèê>·ãHÒ{T{].3
´®~©ru¡!5Íjùñ!ÅË=7ÕMu_íÚz¿Û·aäqÃmáp§i:Ý¿OnàÃÂ÷h:gOËz99ç¹Øîï³Ó65êºúIêX¦$Ýj:©¨ë5®]ùXÏÆ9+n3Êú~\1g%ÔÜa®Ý°×=/
ª1vÃZ«îÌ
¦aʸdôâ:MÆÃØ(ã)ÊøVÉØÄìãL=ÂÔV¦:ÚÆT'SÛzYÍÇ
2ÚÐ.cìÇoeta#õÈX8 a¢FÝ£ê5´xl-Tk5éÜT6L¡#d|q")ßÂ*?>ñ uJc7-»ã1e/yJÅõ[üOqößX]ç>ñWîsöñ${û.³*vJ¨'oѬ·¨bEÉ({y²·(
gøFçOusrl¿°`Ê+ÿ £o¥þÿ+³ï$ eÎfÄ:US'©aé/×Î,fÇud3IÛêø-º£«iNwf{a®Mµ¬8|Y]ýWgìiÏMÞfgç4gwQó4:÷[¶¢ç&ËÖ¦%yjºbª):¥u_w÷í«ã0dæ;SÂÉvÐd/S¡"zãVov¯Î¬kDu3?hì·¾ÓÇÒ
|å
X «éK¢
a¬`= Ë
~
êõ.¦÷P.ΣZ\ÀÑOA^ßn
cnÞ}g$Fà×0]|2qê1J®?& ©Àq½ÓÇ1j"øzkÃ0j»©¥îÄkÛÖø Q'a¬EJ9Tñ)|â&Uú3Jêsª èTM¿ö¸i&VÙ®_Þ@`Eeº¡àleø|Þ³³y«3¹
Ädõ?¡Düï/(Ã^ìsím!kÜhV!ròúzï>âݾ³ØÛb:nÔèÑî¼ÒoøÔíÿT_=`¢}ðVË{+äÅ_ÉËß÷zé~RðòûÎÁôÊs¤ÊwI²áóQ6óÇL >ÿ øt~:Ãs¢.Ü!zàÁ¼ÕÙ®Õ NfùÔªô&u¯«/àK\t¾unª«wÔGú+ ÈÝ|/ß¿ýOìdIñ-§»n ¨tá%|£{
2â5<'^ÇQq'HVÂsÎf?ô?PK×¶u`
¦Ì*c¨¿¡å:
gÚ¶2.l¶À]5ݬp
»YÃéìe88!2^Òrn%+©;ÉL.é¹F.©[¦îÙ¶0ÝdÞpôäôÈpÜ Ë*ú¨aîC|ëð
ÄYê+#b)&½ü¢°ç´ÅYªlÏ$NÑY˳u1fÈZ(z=k[¦qKs
Ë3òÂÝÐT$Уbâ*:ñUżsøHÁó¸ à¢K¸¬à
*tdW±¤"+-®)Xü²ò*Kn$«3ã*L
ë°U8¸ðTÜä&Vþ÷ÈaÛZæ°fÛ°O®è¢ Óeè¹&s¹L®°m¯à̦UôP?·ÚÎ>0¨iÓöHNsá04¼¼ljñÐ]ƦÏ4v½â7µ
a¨+_´¡o'&^÷¢ªu;mm¸«4ñ´ìx¢²è©Ø4;Áv¹TÍòË!ª"ÅÑ»UMçpýMWÞ5~à´W
NV³©·ÂM³5]öBïÙ!¬9£ìY<1J«í¸FSYÜ(c¬ê9C/¾¢HþyÛF^³©óÝæM=§ÂbE§m[¢"#fËŧ÷.(¥ÜFSäº*È#ð¥ëËm¢ÕBùñ+Ôí¼t§%Nìß×Î+Kë_¾ÈÆ
;é»d7íáÐ(1÷ú}£|Ù6µý'ÐEz7IûH¯"ëú¬«ûB]mPõ
}kOVÚý÷âà0'|¯4Æc¨ÏѾ-TÛÚ3ý#gþ$|=V®ãy1¦q?FfÕÚõ®7¸JâÉâJÜõ2ç*÷ªýC§åpñ¿^?âU¿iQ÷¨}G´!-k
s~jô6çGxéaÔûì}m®Açrº¶þt±L¥IpZg¸õ~t-²´á60lb>x¥àEfI÷Òc×è¾¢~®cêó57 Á+Ï_f°e$/iúç'PKVæ-¹
ùþÖæÆ:Év3°{nI%³ÛÆinÓÝ] ùTb3O"Ã;Íí
Tu2 R1ÐËÞ8xøq FþáXÙzó.C¥¯ó4w¤I^é?SáãT+ù<ȤV´cò<Ì£æá<=\ÁUÇqÂÃ5Ônù(ÈDW'I "
Ã
1T¨\©=IµÚïT1õö]Äv{tóȤ1DV˼E^t:=¸s(£U#¾ÆÑKÖÃ"¡-²ÕÖ[°V{V«½{ÎkbIñÁø'8ü3ÊüùWò,¡¶_£Nk½µÒA&7<ÿFû2NîGoP5ìZûø}Jq®Ózñ%kö½BÉÙ³C-|GÿÀÿUþ<§ÈcáôPKÃzjÜ
í¦ <!ë*,Í7¯´8÷Vׯn©¾ôª!*
$VRHÀfþiÓ0ºka5
5¬%í¿½/ýz EÈÂù=Cilõ¹a´
0ñ!ºÒáHâAé:¥IzÙpO:sþI¤ÈNQ´Iq¼]+÷ÜRDrGül¯ú-ÄÂ,ÒOïy@l_ 7²3#²ìPKs¡b
*¡ ÐæZôR=ìÌÎ0gÎÌ×·§
æ¾!õãiÂ/)ËDڲ׿^gª¬P²0Ýí?S׳rÄ¥#L¹e¤&]2î3ǪMÔ¥ßvÉÓÔëºc¤ÇÈaÎVÏ.ÂÊ7PKâà«o
)¢#dkï!uâ8CñLHÞ½!öÐ¥L2ä[]ÅZ2â´ÝJ²ËPøÍ]GvD
½ïÇÃO
×úÒ¹
|)ìHør <´ïì{Û@ºMl(bÙ@
yöù(¶üðßøZ#×#áZ/8¸,OuìºÓî½ÃÁÿ4çñÐÎ,;«^302£9¾7å¸mú²,ÔJÑ¡A@·:EF1m¾½Ð
Á ̨¤VÂò1£6¤M5³ùÄ"·L\r?oµ}EòyZ!êÊ|]HQó¦iN =Af±{p^ ¬ý
»*H1Üû°DÑQ±ÆU(F]%cZ,ñ;©â&¦²b7Ä2Í0Ã0+!jk¾ÏÝà¹<·jWÝç%Ï(V
Ë1jíEÏmÂ+·¸ç{®ý[yÏ--KPVl×Ö$Èzúкgq íyÛå[µò.÷·Í],räÖs³Ýû®él
#1sÚ.l+C-x5¿ÈïÛÞÓLm¶çnÛeîg/M
ÝHJùoñæÐ/ؽ:ÑE¢E8Ã1ݱáûO¶¼éNãísKoi¸-h}bÇEÜaXÒ°^ ÍÅ}üZ%àÖÆAWl
+XÕ°&U\¶«EãÞºCbmmJHÿãqùAPàÜÐçª
oSãDä¨>+zåJM\4¡¡l'¬çré§âMööÏM
®:W$´6_Ø»ôtþ*$j_Ô)Ê
3aEÕé¢ZHktCN@gæRæ-;'úðÑ9í:mÖëGBìèAo#À0ùÈõÊN#òí§ÐlðÔ¾>E/D$d>!\GôãtÐòÞ¼(íâÖJÜZ×!gêPBd¨Ø"Â$CI¥í=BGodi ïÃÙϤÒÿöÅ Z[ ½8ϾSÜi¡eºÓ¬óh¥¬#Ù(6GM éèaiL°t6Iox
,e6u6KìAb·`è7PK#3/¥
¶ûÀFyÂ|04<ÐbôÉ,»:¦!ÛY¿þ&²Müþ(½P%áExØ3÷ã{ïÜÙ?'?XEàÁÇó|ÞõPÀ½*&°ÀÖ"CÓ#waá¾.VªQ¥©ÔöÀZG&YhFdßñ(LafÕ Âî¿OV_eÒ1ºÿL ü\ie7Vûµ@ñI¤ÀTGi¹
÷eÚöqFÒRºµÍ¬ ¥Lu4Øâ )·jc{IdIáuMÆrS±|î¢udÑ=5éêècäc
Ó¯=¼euÃÇ$j>êxä£Å±mvëh<ùoí¡Åç
¸òîÎ@ûj¢3nEË϶+er¾!ÚÓç͸±dV¢IæÓS4xV²ôÑÅ)r¬5ÈêÁDð
·ÇpP<Déûl°p×QtbO¾Ý¸À2å(/øÒbò]K»/O{óôSqÃ
ós¸ß.±7}ëßx+ä1{2ÕÞå/ oWÀÜ)PK9Ve¿±
8®%^A¼ôQÈ-H<!×^
EÎmnÿ´Hí;
\Ú9sf´?}?Ð
ïÂŲm`E_oh¸©aÕÆ-6mܶqÁIxÊQÁ_2¬õyRYþ³0ÎÃ$
ËB¤aɸTË"<¶ï34)¦ßyÎ`g géÉåh«Ýh/¥L3çÅFÕ¡ë¡Öm'Ëïú34©zì°GË7ÉXÄü½Îæúå÷Æm,¸QºãÛ³ªÄÝÉJó-¡'ZØù ãW*âcTLîWÝ×ÑÛÈÃ9´<4áy¸Ë®`ÖÃÎÍc¶£IaÉa¸©T¦înã
$4CçÔ+°Úô\z4¨¶EC¹¤ÌE
.àbU·Du`í¯V³7±ªç¯¸têSÁWkÔ-BÚREmWv¦}û°>ÕØçþoWÂ{ªnã1áüIÚºvV´«lS³À~q飻OìkÿjÀ~Bìë¾ÿÏ.ÒÍÀÒoPK5âôØ
V±¦`6L#« <²{ãÅ5ytkvÇsý6%]î
Z¹>^y÷ÃÞ&Íöírå~ÊØbè#60M«2¢Tj¬úÈUÑ
µTø¹¥¡Tú?zbH7Lh0z
(-?F_p
n2lâëï jä÷(âŬúHÑC÷¨n+ÅÊ߬(ÙØAr'½£["ÝYËì{PæÂש"úºØEr"
ͤBëà+h6Më
ñòëçß«àÜD+/ [è¦ýù[hõ`wÐæ<q¤2U(´âU¨¤6W±åÔwV3C÷êÌ;lb[lµÖL
a(wÒ¯ûïîN÷ýóñ ÇQ,Ã^-ì'è$8`/¥vÀu{3ö.¡3Æ®óÊwÒvFÐPs<yQâÁh%_+µÊLþX<gT:®gZh.^VÜYYq¡pƲüÖYZf9dÈ7"µlÄw7¾a8ÿ®¼¦
¥r
ö»£h .z3 íùô×zÝöÿ v¿Bk
è}½µã5³äÍkê]»¿PK(gV/÷
ò0Hný彤¿vuG8Bà~è99ÜtìØeíÞØC¼DcæÇªmËaèÑ»ÃØ±¶ÿ
>%îöê|Ã73ß03?¿ß
(gÑmîÈc/Fó0±O/ïÔÞ]q`´£9 ½»uô{s¸÷ksPÇisX#QVdâÀ£ô4<ûÉÇöUT=4½ö¢ZðL»mÖf8
Óö\;ô}åfMYõyß T
G ¤;®Ø_¼ÞÃ¥9Ôq¯®6WWUÃæåÏZgÜÉXöS¡ã«@²¨3s'ÎÙª8Û^ÎÁUç(ivAÑOº$7ã
¾N:±0ókõ=×yÖÒ0³NSù£OXO[°ËÀvÜb`ãÇÇÄ 'uä40)Ó0°SïUôÞiìØ¡1Ìå.n |?lª+Q5ð6ð>WÃ!íÍâQóª¢5¶mÖæµdµê)6éÚNT½è¾Ñv3YL
^_¨µÏõe·T,]½É1|M²ÓJ-ZN »ÂB§t T³Å~¦S¥Ç²]Eu@8´ÒW
eµyjËz#fÏêª6uòÖÖ}¼ÁÆ,uÖG<Ûk¶B=>WU[ucëûùDÒóB/M
S~òs_ðÿÓò+"Ü=G|6
»;E÷m(zp©×¢
,ðY«a;Çòk¶ø¶ø[lß±ï±SþÀÛÙË/t¤©ÄÒÜt
4ùε7ÇÊlû·2ç[ËëR¦ñ+ùÊüLe~¡2¿²ªß¨ÌïTæì¢áHdøÏ$0Ib"Óé$B þPKôz|ÿ
iið¸Ý,ºìÂ&Qô<|
ÓÉÿfÉ/1$+?Kç8@n×£¤¥I{äáÑÞÀ®è,á½|ÿZ'õÛ^o4$×ÁÆPKväÂÿ
r'¬{F51Äæ\Ï
æ"fö%Ctɯ dÙõÄZØØrÃÞ¬ÓH,lÖì}Ý¥#ºj´oýçlKßs?Ûë{nCÈü[ûͰ"j¡å·vÄo9-«V·ÂÀ[ï9¡Â¬ ¶T¥ùB7~8¢"ìÚáXÙwÞ¸¼KEã
îcÂ@´¢H1d¼U·½-ëGÓʰÚh*fÌbÎÀ#5Ï<°hà1¦gn¸-çÔy¥Z'µë¥Õr»¢`ϱGÿlŬ:"n;ïCWêiX¡ð¸à5[eèT¶(¿¨Cþb$-)?
³fölAÕ3¤3|."&E]Ø-ê¶ÓÝØV¢]ÇÜv"ÿ³H+î¶;æsüF3T5W³´WÚÝøN{a ËÒõtУ&$¼BEû öjûìRÎpP'6x ¡k'U_©*Jßr¼ÛCÞÎÜ7ÄJÚ8Ãâ_XûÄÝ\ÿºJ
»<@Ï GosH+49UªX~ìbÝäb|1>Hò,Ò<>>#Ï'Pà,òI,ó)<çEáúáûþPKÎË Üf
â+Ï1ä¼ÉÌt¯ü`»NÁ6_èìdÕÜÎ0G¥áciøiHb@C
ÞÇ
n¿1}³d¤Ï¤«aOSWp«1ûÓÉk¸
Û>Åg*¶5 þzêä-Ø®t¯HͲÈ&*¤ä5ìbÈ»TqQi×Ñ3;¯ÂÔp#Âg°4|/4ì+ ¨á9F¨êfܱ¤áRp£Ê®îø¥D¨ÁáÈÚê&sÃ%Ö2çújy]ÜlµZå-gï5ÌôlÞ|#.÷¤Á¢óQÈx´±î:Qçîh¸¨ÕFau%/êÆk¯ËWw©S¥´Hµ÷ÄΫJ)ôY+£F¢ª%Aí\dÇa2Ô¼§[ÚÞ£
ðÃÒWBW0Õ
ÑM
¾BSÝ6Êøbtiº×ig¯M©_Ðôó9ÕiR¥A¨RJ¬zTC¯Ñ:Ft#UZàhIZhE
c xÍ1IÏe hôËÊfDß&cßÐÂâ_Ñ^Æ[/}7-hG[ÖÁ×"ÖÐ"ÖÑ.¡K<Æ
Fâ?D/cFä5ú)¸
®Ð-°ä õjtÉ5 ³çH¡»wFø uGü¨Ê¸öe¼;yl5À#$F"Ý2zÑ»ÑÑWÁ?{ò³Ú¤1ßæï¦IýI "$¶éò
$DbÃbwy±Â¦°±%ØÏaÂÅq@(£ÂØPKírmÓU
(ÛXqAÙ
U¹?³fcÝÆAþPBd;WÖrRG¼\õýA`^Üãg"1ÕÞcÈnů
ûbÌUëÖ¿ó=¸(ìñaLetÏG²kP&C+ÅCMÇ"bô"Í]vÏ=lbþ˶
âL>pk©<TQ#ØO7r5S vÓL1âºÍ>òµÙG«ÑI×ðÉ|Þ/>¯68¶Íb®Y¸qÇÈÔSæ'2×Sd'°ÌÀ~AK&V`Î3,ç%ç5çÍdM&Ò/PK°?
#&ë³àÙ¬g²{Õr=^ÉEC)_ª£Sýò¿KqR_K\¶G}#µÜr¤RÎH«MjÀneR!Ñ"9@Jªéö¶16>ÀÔGç¥, è/Hé¯Èëo(éïÒ3+= ÌýPK±Ák
_ÁÍN{;Ò±ëʬOmïb7Buà¥*
ª-ãú7ï»ç !{=µU"ܺ(Ñû¸ùÞÁsÌ9xAóxÁà>ðÏ,,8xET^g3Ñ«A>(§ÙÈf é[È/¥Õ+÷¥«AlÃÔÀà·zÙð»z|)ÛiÍÝXz~Â`}õ±ûäFoPê!²úo¶~+ÒÊà·iT
`®CaÒôE9©Ýh¦YyÚ9Xí¹/çÈwP¨¡¯þÓ.:Bã
5ÕŤî*¨îNÐÏDP?B!1Áð£Ä[$*¨`}O×½çÜç·ï_ìàNMôÜl¡~!ny³â«3ha-Àz
P)²s^¾F-|
6!Ã
JxbÖãSÔ>ü4¼3|Cæ¿¢î^Q»ú
úgVz |Nø¼Kä`ùPK¶i¤
sÄ÷1±`#³©½¶¦HðÎ-TÛ:L·Nì8kô%mÝSn52Õ0á½Ê·Åwud¹,xÞåÁë.ÖÈà2÷t!ù¶%ʼå
óG¡^F3ù5,FÊOϦlw¹Ê·î_kÃÚÿbæúl¼r.ûPÔ,b334êËÍ';4
·ÿWIüB~
Ú)!¡£DtÃòæhg´4ú`Wä0ÔÈVc0='Kb$®£Lü
ÒÁ»>Ê;>*+׸Fõ;
a/0þÀPúé%)^¡üÑûKýPK£.ü
¨(¢m»!Ê)áÅB4/·³²ÝMöŤ?pfÞ°ÝlÎÌóÎ;{Îü¹<ÿ
º &r¨ÂdÂÎxlÂ@¥'ÖÙSÏÌ0äW)^oH7±èÜ
lÙ®g'±òlø" CéÇv«JÇî;8+ÊWñ*C¾ZûHZk+JÊI·-ÃÓöh¯ïz¥¹$¡ëJÏOmø¢¾úæÄ*ð[ª+ÃÆ³ïX(aáͽ®º*öVÒöHÅ>l¾·090laÏû>/ðÒB5ål6þW!/Y6OÙ;ÌP$ã·Ò»NL©Q½¿8©±M]ßèeÃokªñWý6b0vAìÑè5J4BVÿÖoDÚüÞAµ~ÌÐ¥°èÚ0Lê>¡,G9µÅ4j"O0Q?«_ ÷ùù
õô0ø+EËË(
Óf4Ì2dÄàkMáD
.EGY<°×BéZ\y<ò}á
Ö¡R®pv)=
ß`ÈmJO[éå"m+G0ÒQ¯-üÝvéFßäîW¦q¬"=ßO_{¼ë+OÞØ¡T^Kö_?³/l&ÖÿýSOÜ:Ú®ä ìè`ßÄæM(X@ECÕÄ"
ÒþI@jÎ`Ê?B ÂáR©õåÿû0HÛË¿yÉËW{Õõ
í4»sªUÚ<í£¡þ"FAvN
¤Éʵ>Xí©Ó>ÒÈÔî}Dî6É!èÑû(êO(éÏùU ÝA»GöWúÙÑäõ±OPKjå|
´I}ÑaÎö8v9Kµþ
r*bȪX¶2írÖ!^Ø$Íf¨P±E>Ò|&ËÝmr¹½âë\
z5ìF=ØË©.olVièG^Ã~i0¨a4Ä!
ÃÒ7Q:¨êrʳ¢¼«Ãï¶((DAòptÛpz¿ÏK´U9rZúÃó!Uü¼ùN;¥jo·§3ïÏ®V)¤µRHjhL,4t`ì0F"0¾¡ú˨þÿöIía©ñKÌËðéô3$KãêùIÃ
¤ÈMzLºÇ ¡é-¥òRïqj9Ò¾åkÛ^þ-°.â
ºø©l <-4Ûx´×½ý ±¯/!>ÄTÓJ¶àWà×PϯB?¤¬åèVzCbôMe/"¹9ù
Âç°-ôÙHþðèM²a%Ð)$dQì4Rd³hεÍÇA
èmÓ¨Ä.J§C\=uäY4E®hZ7Es±Xk#Wý8ûêA¯PÙN½ßBÏBã·±ßAÿëø/Èñ»Ðù=lå¿¢ÿnþ;öñ?0ÌÿÄQ~ë)>Ay6Ðø¸ÒÈjC6gTvÉZèO¢1GÎ¥3X/÷sóÕsr4N@-7²VMßÛo°ÍÒÛþbüoÔðhâæåcbùX>%ÏÐÇÿù»4ÍcȼPK¨Ñün
Kʸ¬£``
4zt/9'=Þ¡¸ÌÔ¯äü¢ÐÐXJ"Xµ7\ZÚ¤§á|fê½âÛ)KÃÄ Ô1]IéUD@ä`¦tmo³U*tñ2l¯Ve
ØÑ`¬øQà©öÆÑå¶lÏî´ºdÂã95G
pÃÄU\Ó0|ZL\Ç´_akèoó/Q¥ïØÀ
¦¬)s>ü@ÃPRü0íø^%"'L+×w©câcdZ¤È¦B©j±
¦t1
¤·öˬSÈòmOO´ò L|/M¼ÀM¾Ë¡x/ACÆÙCǦ-HÛ*sïb¦sás;¸uºÐÞák¤éȹv¥²ì~äé4L®@Ú®üݯâèSQ,¿²+6}Ë©XE×BéZLªðB«$+Õúøf?xiEìòï
ïº-·Å¸
÷Wô{úLA»ËTLí쬲pűÒ&ÅÈᦫÖÞQG#Í£]»Eí5ô4]¯nÃB9S¬±?Ú85+§S6ÞÝ£l5¸Àï×~GüceÆ+çÕñÌ6঺ã'ÜEhççÉ& e_£mý
?BOAÓzG1»Àãc^Gs5Å9mSB[H4kªàVôüQö^Ð>F/¹W ×BkL
5kc:F¶ô7özrXQHf5`ÂøPKüâM
yT1à@\B*ÑûÆ^'Înå_r¬T@å
>1ô©b8)S%Àigð¸'0(ÔÄçbuVì=%Ô«sbïñ©h+MÇ%pÐ+aDF£BP0&£ã ÒÉ´³¬$ÒmÜj*ÅSþ55ÞkÅ9w«És[b<[©I°ÂZ*7ÂiG7ÂejiÛæ¦>JDuFm®ÆI§"6¦WÃj&Âî&ûí¬Q:ß½43bXÚxTåÙó>ŵ´Ã»=Á¬W3ª:¼£À*©ê°Á;
6ûǸæÆq¯¸2¦¼7=1Ìí!ÌP>Çq¸å:ÍÐìy`ðª~?·u+®kªa!´8ahQOSMUÁÿ7¡$¸
*Ce°i±PhWí9¡â PlrTçO¦¨5iÒÒäSxs½ZÖ«Ì¥ð¹S7ug?|ÊJÛ?¬`H·
/v= ¦I]xVAB
lìQ°R
P*7äÑm<¡]v"=AÐCSO:ºe
@§Ò
ÎU3¶*Ä´JVðð}QÁ%!ö¢^ÃËxEÁe±zUøs¯)x]ì½+
ÞÄ[
Þ{ïà
CmG&%N:<>ï
æ*- ï*xïÇ?`Øù0µ#t?dغ]Kgsì°ª9=}:ÅmÒû«2O$¬>ÁÝLìa...
[truncated message content] |
|
From: Huston F. <hu...@us...> - 2002-03-30 16:17:13
|
Update of /cvsroot/beepcore-java/beepcore-java/lib In directory usw-pr-cvs1:/tmp/cvs-serv16781/lib Log Message: Directory /cvsroot/beepcore-java/beepcore-java/lib added to the repository |
|
From: Huston F. <hu...@us...> - 2002-01-23 18:40:33
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/profile/echo
In directory usw-pr-cvs1:/tmp/cvs-serv26942/src/org/beepcore/beep/profile/echo
Modified Files:
EchoProfile.java
Log Message:
fix bad check-in
Index: EchoProfile.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/profile/echo/EchoProfile.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -r1.13 -r1.14
*** EchoProfile.java 2002/01/15 16:14:38 1.13
--- EchoProfile.java 2002/01/23 18:40:29 1.14
***************
*** 69,142 ****
public void receiveMSG(Message message) throws BEEPError
{
! OutputDataStream data = new OutputDataStream();
! InputDataStream ds = message.getDataStream();
! while (true) {
! try {
! BufferSegment b = ds.waitForNextSegment();
! if (b == null) {
! break;
}
- data.add(b);
- } catch (InterruptedException e) {
- throw new BEEPError(BEEPError.CODE_REQUESTED_ACTION_ABORTED,
- "Error reading request");
}
- }
! data.setComplete();
- try {
- message.sendRPY(data);
- } catch (BEEPException e) {
try {
! throw new BEEPError(BEEPError.CODE_REQUESTED_ACTION_ABORTED,
"Error sending RPY");
! } catch (BEEPException x) {
! message.getChannel().getSession().terminate(x.getMessage());
}
- return;
}
}
-
- // public void receiveMSG(Message message) throws BEEPError
- // {
- // new ReplyThread(message).start();
- // }
-
- // private class ReplyThread extends Thread {
- // private Message message;
-
- // ReplyThread(Message message) {
- // this.message = message;
- // }
-
- // public void run() {
- // OutputDataStream data = new OutputDataStream();
- // InputDataStream ds = message.getDataStream();
-
- // while (ds.isComplete() == false || ds.availableSegment()) {
- // try {
- // data.add(ds.waitForNextSegment());
- // } catch (InterruptedException e) {
- // message.getChannel().getSession().terminate(e.getMessage());
- // return;
- // }
- // }
-
- // data.setComplete();
-
- // try {
- // message.sendRPY(data);
- // } catch (BEEPException e) {
- // try {
- // message.sendERR(BEEPError.CODE_REQUESTED_ACTION_ABORTED,
- // "Error sending RPY");
- // } catch (BEEPException x) {
- // message.getChannel().getSession().terminate(x.getMessage());
- // }
- // return;
- // }
- // }
- // }
}
--- 69,113 ----
public void receiveMSG(Message message) throws BEEPError
{
! new ReplyThread(message).start();
! }
! private class ReplyThread extends Thread {
! private Message message;
!
! ReplyThread(Message message) {
! this.message = message;
! }
!
! public void run() {
! OutputDataStream data = new OutputDataStream();
! InputDataStream ds = message.getDataStream();
!
! while (true) {
! try {
! BufferSegment b = ds.waitForNextSegment();
! if (b == null) {
! break;
! }
! data.add(b);
! } catch (InterruptedException e) {
! message.getChannel().getSession().terminate(e.getMessage());
! return;
}
}
! data.setComplete();
try {
! message.sendRPY(data);
! } catch (BEEPException e) {
! try {
! message.sendERR(BEEPError.CODE_REQUESTED_ACTION_ABORTED,
"Error sending RPY");
! } catch (BEEPException x) {
! message.getChannel().getSession().terminate(x.getMessage());
! }
! return;
}
}
}
}
|
|
From: Huston F. <hu...@us...> - 2002-01-15 16:14:41
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/profile/echo
In directory usw-pr-cvs1:/tmp/cvs-serv11346/src/org/beepcore/beep/profile/echo
Modified Files:
EchoProfile.java
Log Message:
fixed to match new semantics of waitForNextSegment
Index: EchoProfile.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/profile/echo/EchoProfile.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -C2 -r1.12 -r1.13
*** EchoProfile.java 2001/11/25 08:38:42 1.12
--- EchoProfile.java 2002/01/15 16:14:38 1.13
***************
*** 69,109 ****
public void receiveMSG(Message message) throws BEEPError
{
! new ReplyThread(message).start();
! }
!
! private class ReplyThread extends Thread {
! private Message message;
!
! ReplyThread(Message message) {
! this.message = message;
! }
! public void run() {
! OutputDataStream data = new OutputDataStream();
! InputDataStream ds = message.getDataStream();
!
! while (ds.isComplete() == false || ds.availableSegment()) {
! try {
! data.add(ds.waitForNextSegment());
! } catch (InterruptedException e) {
! message.getChannel().getSession().terminate(e.getMessage());
! return;
}
}
! data.setComplete();
try {
! message.sendRPY(data);
! } catch (BEEPException e) {
! try {
! message.sendERR(BEEPError.CODE_REQUESTED_ACTION_ABORTED,
"Error sending RPY");
! } catch (BEEPException x) {
! message.getChannel().getSession().terminate(x.getMessage());
! }
! return;
}
}
}
}
--- 69,142 ----
public void receiveMSG(Message message) throws BEEPError
{
! OutputDataStream data = new OutputDataStream();
! InputDataStream ds = message.getDataStream();
! while (true) {
! try {
! BufferSegment b = ds.waitForNextSegment();
! if (b == null) {
! break;
}
+ data.add(b);
+ } catch (InterruptedException e) {
+ throw new BEEPError(BEEPError.CODE_REQUESTED_ACTION_ABORTED,
+ "Error reading request");
}
+ }
! data.setComplete();
+ try {
+ message.sendRPY(data);
+ } catch (BEEPException e) {
try {
! throw new BEEPError(BEEPError.CODE_REQUESTED_ACTION_ABORTED,
"Error sending RPY");
! } catch (BEEPException x) {
! message.getChannel().getSession().terminate(x.getMessage());
}
+ return;
}
}
+
+ // public void receiveMSG(Message message) throws BEEPError
+ // {
+ // new ReplyThread(message).start();
+ // }
+
+ // private class ReplyThread extends Thread {
+ // private Message message;
+
+ // ReplyThread(Message message) {
+ // this.message = message;
+ // }
+
+ // public void run() {
+ // OutputDataStream data = new OutputDataStream();
+ // InputDataStream ds = message.getDataStream();
+
+ // while (ds.isComplete() == false || ds.availableSegment()) {
+ // try {
+ // data.add(ds.waitForNextSegment());
+ // } catch (InterruptedException e) {
+ // message.getChannel().getSession().terminate(e.getMessage());
+ // return;
+ // }
+ // }
+
+ // data.setComplete();
+
+ // try {
+ // message.sendRPY(data);
+ // } catch (BEEPException e) {
+ // try {
+ // message.sendERR(BEEPError.CODE_REQUESTED_ACTION_ABORTED,
+ // "Error sending RPY");
+ // } catch (BEEPException x) {
+ // message.getChannel().getSession().terminate(x.getMessage());
+ // }
+ // return;
+ // }
+ // }
+ // }
}
|
|
From: Huston F. <hu...@us...> - 2002-01-15 16:03:02
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core
In directory usw-pr-cvs1:/tmp/cvs-serv6703/src/org/beepcore/beep/core
Modified Files:
InputDataStream.java
Log Message:
Fixed bug with setComplete being called after waitForNextSegment
Index: InputDataStream.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/InputDataStream.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** InputDataStream.java 2001/11/08 05:51:34 1.2
--- InputDataStream.java 2002/01/15 16:02:59 1.3
***************
*** 161,167 ****
}
public BufferSegment waitForNextSegment() throws InterruptedException {
synchronized (buffers) {
! if (availableSegment() == false) {
buffers.wait();
}
--- 161,174 ----
}
+ /**
+ *
+ * @returns null if isComplete() is true.
+ */
public BufferSegment waitForNextSegment() throws InterruptedException {
synchronized (buffers) {
! while (availableSegment() == false) {
! if (isComplete() == true) {
! return null;
! }
buffers.wait();
}
***************
*** 185,189 ****
void setComplete() {
this.complete = true;
! // @todo notify objects waiting for more buffers.
}
--- 192,198 ----
void setComplete() {
this.complete = true;
! synchronized (this.buffers) {
! this.buffers.notify();
! }
}
***************
*** 195,258 ****
private InputDataStreamAdapter stream = null;
}
- /**
- * Returns the content type of a <code>InputDataStrea</code>. If
- * the <code>BufferSegment</code> containing the content type
- * hasn't been received yet, the method blocks until it is
- * received.
- *
- * @return Content type.
- *
- * @throws BEEPException
- * @deprecated
- */
- // public String getContentType() throws BEEPException
- // {
- // return this.getInputStream().getContentType();
- // }
-
- /**
- * Returns the value of the MIME entity header which corresponds
- * to the given <code>name</code>. If the <code>BufferSegment</code>
- * containing the content type hasn't been received yet, the
- * method blocks until it is received.
- *
- * @param name Name of the entity header.
- * @return String Value of the entity header.
- *
- * @throws BEEPException
- * @deprecated
- */
- // public String getHeaderValue(String name) throws BEEPException
- // {
- // return this.getInputStream().getHeaderValue(name);
- // }
-
- /**
- * Returns an <code>Enumeration</code> of all the MIME entity
- * header names belonging to this <code>InputDataStream</code>.
- * If the <code>BufferSegment</code> containing the content type
- * hasn't been received yet, the method blocks until it is
- * received.
- *
- * @throws BEEPException
- * @deprecated
- */
- // public Enumeration getHeaderNames() throws BEEPException
- // {
- // return this.getInputStream().getHeaderNames();
- // }
-
- /**
- * Returns the transfer encoding of a <code>InputDataStrea</code>.
- * If the <code>BufferSegment</code> containing the content type
- * hasn't been received yet, the method blocks until it is
- * received.
- *
- * @throws BEEPException
- * @deprecated
- */
- // public String getTransferEncoding() throws BEEPException
- // {
- // return this.getInputStream().getTransferEncoding();
- // }
-
--- 204,205 ----
|
|
From: Huston F. <hu...@us...> - 2001-12-16 01:02:17
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core
In directory usw-pr-cvs1:/tmp/cvs-serv3300/src/org/beepcore/beep/core
Modified Files:
BEEPException.java
Log Message:
added basic exception chaining
Index: BEEPException.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/BEEPException.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** BEEPException.java 2001/11/08 05:51:34 1.2
--- BEEPException.java 2001/12/16 01:02:13 1.3
***************
*** 1,7 ****
-
/*
! * BEEPException.java $Revision$ $Date$
*
! * Copyright (c) 2001 Invisible Worlds, Inc. All rights reserved.
*
* The contents of this file are subject to the Blocks Public License (the
--- 1,6 ----
/*
! * BEEPException.java $Revision$ $Date$
*
! * Copyright (c) 2001 Huston Franklin. All rights reserved.
*
* The contents of this file are subject to the Blocks Public License (the
***************
*** 20,45 ****
/**
! * A subclass of java.lang.Exception that we provide so users of the
! * library can differentiate between BEEP exceptions, and JVM exceptions.
! *
*
- * @author Eric Dixon
* @author Huston Franklin
! * @author Jay Kint
! * @author Scott Pead
! * @version $Revision, $Date$
*/
public class BEEPException extends Exception {
/**
! * Constructor BEEPException
*
! *
! * @param s
*
*/
! public BEEPException(String s)
! {
! super(s);
}
}
--- 19,124 ----
/**
! * An exception for representing BEEP related errors.
! * <code>BEEPException</code> adds support for exception chaining
! * similar to what is available in JDK 1.4.
*
* @author Huston Franklin
! * @version $Revision$, $Date$
*/
public class BEEPException extends Exception {
+ private final Throwable cause;
+
/**
! * Constructs a new <code>BEEPException</code> with the specified
! * detail message.
*
! * @param message the detailed message which is saved for later
! * retrieval by the <code>getMessage()</code> method.
! */
! public BEEPException(String message) {
! super(message);
! cause = null;
! }
!
! /**
! * Constructs a new <code>BEEPException</code> with the specified
! * cause and a detailed message of
! * <code>(cause == null ? null : cause.toString())</code>.
*
+ * @param cause the cause which is saved for later retrieval by
+ * the <code>getCause()</code> method.
+ */
+ public BEEPException(Throwable cause) {
+ super(cause == null ? null : cause.toString());
+ this.cause = cause;
+ }
+
+ /*
+ * requests to fill in the stack trace we will have to ignore.
+ * We can't throw an exception here, because this method is
+ * called by the constructor of Throwable
+ */
+ public Throwable fillInStackTrace() {
+ return this;
+ }
+
+ /**
+ * Returns the cause of this <code>BEEPException</code>.
*/
! public Throwable getCause() {
! return cause;
! }
!
! public String getLocalizedMessage() {
! if (cause == null) {
! return super.getLocalizedMessage();
! }
! return cause.getLocalizedMessage();
! }
!
! /**
! * Prints this <code>BEEPException</code> and its backtrace to the
! * standard error stream. If this <code>BEEPException</code> was
! * initialized with a <code>Throwable</code> the backtrace for it
! * will be printed as well.
! */
! public void printStackTrace() {
! printStackTrace(System.err);
! }
!
! /**
! * Prints this <code>BEEPException</code> and its backtrace to the
! * specified print stream.
! */
! public void printStackTrace(java.io.PrintStream s) {
! synchronized (s) {
! super.printStackTrace(s);
! if (cause != null) {
! s.print("Caused by: ");
! cause.printStackTrace(s);
! }
! }
! }
!
! /**
! * Prints this <code>BEEPException</code> and its backtrace to the
! * specified print writer.
! */
! public void printStackTrace(java.io.PrintWriter s) {
! synchronized (s) {
! super.printStackTrace(s);
! if (cause != null) {
! s.print("Caused by: ");
! cause.printStackTrace(s);
! }
! }
! }
!
! public String toString() {
! if (cause == null) {
! return super.toString();
! }
! return super.toString() + cause.toString();
}
}
|
|
From: Huston F. <hu...@us...> - 2001-12-15 00:07:22
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core
In directory usw-pr-cvs1:/tmp/cvs-serv1446/src/org/beepcore/beep/core
Modified Files:
Channel.java
Log Message:
more cleanup
Index: Channel.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/Channel.java,v
retrieving revision 1.19
retrieving revision 1.20
diff -C2 -r1.19 -r1.20
*** Channel.java 2001/11/12 16:12:41 1.19
--- Channel.java 2001/12/15 00:07:19 1.20
***************
*** 46,64 ****
static final int STATE_CLOSED = 4;
static final int STATE_ERROR = 5;
- private static final String ERR_CHANNEL_MESSAGE_NUMBER_PREFIX =
- "Incorrect message number: was ";
- private static final String ERR_CHANNEL_MIDDLE = "; expecting ";
- private static final String ERR_CHANNEL_SEQUENCE_NUMBER_PREFIX =
- "Incorrect sequence number: was ";
- private static final String ERR_CHANNEL_ERROR_STATE =
- "Channel in currently experiencing technical difficulties.";
- private static final String ERR_CHANNEL_UNINITIALISED_STATE =
- "Channel is uninitialised.";
- private static final String ERR_CHANNEL_UNKNOWN_STATE =
- "Channel is in an unknown state.";
- private static final String ERR_CHANNEL_INCONSISTENT_FRAME_TYPE_PREFIX =
- "Incorrect message type: was ";
- private static final String ERR_REPLY_RECEIVED_FOR_NO_MESSAGE =
- "Reply received for a message never sent.";
private static final BufferSegment zeroLengthSegment =
new BufferSegment(new byte[0]);
--- 46,49 ----
***************
*** 287,291 ****
// in the buffer right now.
if (size < recvWindowUsed) {
! throw new BEEPException("Size must be less than what is currently in use.");
}
--- 272,277 ----
// in the buffer right now.
if (size < recvWindowUsed) {
! throw new BEEPException("Size must be less than what is " +
! "currently in use.");
}
***************
*** 364,372 ****
switch (state) {
case STATE_ERROR :
! throw new BEEPException(ERR_CHANNEL_ERROR_STATE);
case STATE_UNINITIALISED :
! throw new BEEPException(ERR_CHANNEL_UNINITIALISED_STATE);
default :
! throw new BEEPException(ERR_CHANNEL_UNKNOWN_STATE);
}
}
--- 350,359 ----
switch (state) {
case STATE_ERROR :
! throw new BEEPException("Channel in currently experiencing " +
! "technical difficulties.");
case STATE_UNINITIALISED :
! throw new BEEPException("Channel is uninitialised.");
default :
! throw new BEEPException("Channel is in an unknown state.");
}
}
***************
*** 686,692 ****
if (previousFrame != null) {
if (frame.getMsgno() != previousFrame.getMsgno()) {
! throw new BEEPException(ERR_CHANNEL_MESSAGE_NUMBER_PREFIX
+ frame.getMsgno()
! + ERR_CHANNEL_MIDDLE
+ previousFrame.getMsgno());
}
--- 673,679 ----
if (previousFrame != null) {
if (frame.getMsgno() != previousFrame.getMsgno()) {
! throw new BEEPException("Incorrect message number: was "
+ frame.getMsgno()
! + "; expecting "
+ previousFrame.getMsgno());
}
***************
*** 720,726 ****
if (frame.getMsgno() != mstatus.getMsgno()) {
! throw new BEEPException(ERR_CHANNEL_MESSAGE_NUMBER_PREFIX
+ frame.getMsgno()
! + ERR_CHANNEL_MIDDLE
+ mstatus.getMsgno());
}
--- 707,713 ----
if (frame.getMsgno() != mstatus.getMsgno()) {
! throw new BEEPException("Incorrect message number: was "
+ frame.getMsgno()
! + "; expecting "
+ mstatus.getMsgno());
}
***************
*** 729,736 ****
// is the sequence number correct?
if (frame.getSeqno() != recvSequence) {
! throw new BEEPException(ERR_CHANNEL_SEQUENCE_NUMBER_PREFIX
! + frame.getSeqno()
! + ERR_CHANNEL_MIDDLE
! + recvSequence);
}
--- 716,722 ----
// is the sequence number correct?
if (frame.getSeqno() != recvSequence) {
! throw new BEEPException("Incorrect sequence number: was "
! + frame.getSeqno() + "; expecting "
! + recvSequence);
}
***************
*** 739,746 ****
&& (previousFrame.getMessageType()
!= frame.getMessageType())) {
! throw new BEEPException(ERR_CHANNEL_INCONSISTENT_FRAME_TYPE_PREFIX
! + frame.getMessageTypeString()
! + ERR_CHANNEL_MIDDLE
! + previousFrame.getMessageTypeString());
}
}
--- 725,732 ----
&& (previousFrame.getMessageType()
!= frame.getMessageType())) {
! throw new BEEPException("Incorrect message type: was "
! + frame.getMessageTypeString()
! + "; expecting "
! + previousFrame.getMessageTypeString());
}
}
***************
*** 797,805 ****
switch (state) {
case STATE_ERROR :
! throw new BEEPException(ERR_CHANNEL_ERROR_STATE);
case STATE_UNINITIALISED :
! throw new BEEPException(ERR_CHANNEL_UNINITIALISED_STATE);
default :
! throw new BEEPException(ERR_CHANNEL_UNKNOWN_STATE);
}
}
--- 783,792 ----
switch (state) {
case STATE_ERROR :
! throw new BEEPException("Channel in currently experiencing " +
! "technical difficulties.");
case STATE_UNINITIALISED :
! throw new BEEPException("Channel is uninitialised.");
default :
! throw new BEEPException("Channel is in an unknown state.");
}
}
|
|
From: Huston F. <hu...@us...> - 2001-11-29 04:00:03
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/profile/sasl/anonymous
In directory usw-pr-cvs1:/tmp/cvs-serv29433/src/org/beepcore/beep/profile/sasl/anonymous
Modified Files:
SASLAnonymousProfile.java
Log Message:
First pass cleanup
Index: SASLAnonymousProfile.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/profile/sasl/anonymous/SASLAnonymousProfile.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -r1.5 -r1.6
*** SASLAnonymousProfile.java 2001/11/08 05:51:34 1.5
--- SASLAnonymousProfile.java 2001/11/29 04:00:00 1.6
***************
*** 215,219 ****
if ((ch.getStartData() != null)
! && (ch.getStartData().indexOf(FRAGMENT_ERROR_PREFIX) != -1)) {
throw new BEEPException(ch.getStartData());
}
--- 215,219 ----
if ((ch.getStartData() != null)
! && (ch.getStartData().indexOf("<error ") != -1)) {
throw new BEEPException(ch.getStartData());
}
|
|
From: Huston F. <hu...@us...> - 2001-11-29 04:00:03
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/profile/sasl
In directory usw-pr-cvs1:/tmp/cvs-serv29433/src/org/beepcore/beep/profile/sasl
Modified Files:
Blob.java SASLProfile.java
Log Message:
First pass cleanup
Index: Blob.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/profile/sasl/Blob.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -r1.4 -r1.5
*** Blob.java 2001/11/08 05:51:34 1.4
--- Blob.java 2001/11/29 04:00:00 1.5
***************
*** 61,83 ****
public final static int DEFAULT_BLOB_SIZE = 1024;
// Error Constants
! public final static String ERR_INVALID_STATUS_VALUE = "Invalid SASL Status for Blob";
! public final static String ERR_MEANINGLESS_BLOB = "No valid data in blob";
! public final static String ERR_BASE64 = "Base64 encode or decode failure";
! public final static String ERR_XML_PARSE_FAILURE = "Failed to parse xml";
// XML Fragment Constants
- public final static String FRAGMENT_ANGLE_SUFFIX = ">";
- public final static String FRAGMENT_BLOB_PREFIX = "<blob ";
- public final static String FRAGMENT_BLOB_SUFFIX = "</blob>";
- public final static String FRAGMENT_CDATA_PREFIX = "<![CDATA[";
- public final static String FRAGMENT_CDATA_SUFFIX = "]]>";
- public static final String FRAGMENT_ERROR_PREFIX = "<error ";
- public static final String FRAGMENT_ERROR_SUFFIX = "</error>";
- public static final String FRAGMENT_QUOTE_SUFFIX = "'";
- public static final String FRAGMENT_QUOTE_ANGLE_SUFFIX = "'>";
- public static final String FRAGMENT_QUOTE_SLASH_ANGLE_SUFFIX = "'/>";
- public static final String FRAGMENT_SLASH_ANGLE_SUFFIX = "/>";
- public final static String FRAGMENT_STATUS_PREFIX = "status='";
- public static final String TAG_BLOB = "blob";
- public static final String TAG_STATUS = "status";
--- 61,68 ----
public final static int DEFAULT_BLOB_SIZE = 1024;
// Error Constants
! private final static String ERR_INVALID_STATUS_VALUE =
! "Invalid SASL Status for Blob";
! private final static String ERR_XML_PARSE_FAILURE = "Failed to parse xml";
// XML Fragment Constants
***************
*** 120,137 ****
StringBuffer buff = new StringBuffer(DEFAULT_BLOB_SIZE);
! buff.append(FRAGMENT_BLOB_PREFIX);
if (status != STATUS_NONE) {
! buff.append(FRAGMENT_STATUS_PREFIX);
buff.append(statusMappings[status]);
! buff.append(FRAGMENT_QUOTE_SUFFIX);
}
if (blobData == null) {
! buff.append(FRAGMENT_SLASH_ANGLE_SUFFIX);
} else {
! buff.append(FRAGMENT_ANGLE_SUFFIX);
buff.append(blobData);
! buff.append(FRAGMENT_BLOB_SUFFIX);
}
--- 105,122 ----
StringBuffer buff = new StringBuffer(DEFAULT_BLOB_SIZE);
! buff.append("<blob ");
if (status != STATUS_NONE) {
! buff.append("status='");
buff.append(statusMappings[status]);
! buff.append('\'');
}
if (blobData == null) {
! buff.append("/>");
} else {
! buff.append(">");
buff.append(blobData);
! buff.append("</blob>");
}
***************
*** 175,192 ****
StringBuffer buff = new StringBuffer(DEFAULT_BLOB_SIZE);
! buff.append(FRAGMENT_BLOB_PREFIX);
if (status != STATUS_NONE) {
! buff.append(FRAGMENT_STATUS_PREFIX);
buff.append(statusMappings[status]);
! buff.append(FRAGMENT_QUOTE_SUFFIX);
}
if (blobData == null) {
! buff.append(FRAGMENT_SLASH_ANGLE_SUFFIX);
} else {
! buff.append(FRAGMENT_ANGLE_SUFFIX);
buff.append(blobData);
! buff.append(FRAGMENT_BLOB_SUFFIX);
}
--- 160,177 ----
StringBuffer buff = new StringBuffer(DEFAULT_BLOB_SIZE);
! buff.append("<blob ");
if (status != STATUS_NONE) {
! buff.append("status='");
buff.append(statusMappings[status]);
! buff.append('\'');
}
if (blobData == null) {
! buff.append("/>");
} else {
! buff.append(">");
buff.append(blobData);
! buff.append("</blob>");
}
***************
*** 223,240 ****
StringBuffer buff = new StringBuffer(DEFAULT_BLOB_SIZE);
! buff.append(FRAGMENT_BLOB_PREFIX);
if (status != STATUS_NONE) {
! buff.append(FRAGMENT_STATUS_PREFIX);
buff.append(statusMappings[status]);
! buff.append(FRAGMENT_QUOTE_SUFFIX);
}
if (blobData == null) {
! buff.append(FRAGMENT_SLASH_ANGLE_SUFFIX);
} else {
! buff.append(FRAGMENT_ANGLE_SUFFIX);
buff.append(blobData);
! buff.append(FRAGMENT_BLOB_SUFFIX);
}
--- 208,225 ----
StringBuffer buff = new StringBuffer(DEFAULT_BLOB_SIZE);
! buff.append("<blob ");
if (status != STATUS_NONE) {
! buff.append("status='");
buff.append(statusMappings[status]);
! buff.append('\'');
}
if (blobData == null) {
! buff.append("/>");
} else {
! buff.append(">");
buff.append(blobData);
! buff.append("</blob>");
}
***************
*** 285,289 ****
if (status == STATUS_NONE && blobData == null) {
! throw new SASLException(ERR_MEANINGLESS_BLOB);
}
--- 270,274 ----
if (status == STATUS_NONE && blobData == null) {
! throw new SASLException("No valid data in blob");
}
***************
*** 422,426 ****
throws SASLException
{
! if ((blob == null) || (blob.indexOf(FRAGMENT_BLOB_PREFIX) == -1)) {
return null;
}
--- 407,411 ----
throws SASLException
{
! if ((blob == null) || (blob.indexOf("<blob ") == -1)) {
return null;
}
***************
*** 428,436 ****
Element top = processMessage(blob);
! if (!top.getTagName().equals(TAG_BLOB)) {
throw new SASLException(ERR_XML_PARSE_FAILURE);
}
! return top.getAttribute(TAG_STATUS);
}
--- 413,421 ----
Element top = processMessage(blob);
! if (!top.getTagName().equals("blob")) {
throw new SASLException(ERR_XML_PARSE_FAILURE);
}
! return top.getAttribute("status");
}
***************
*** 454,458 ****
Element top = processMessage(blob);
! if (!top.getTagName().equals(TAG_BLOB)) {
throw new SASLException(ERR_XML_PARSE_FAILURE);
}
--- 439,443 ----
Element top = processMessage(blob);
! if (!top.getTagName().equals("blob")) {
throw new SASLException(ERR_XML_PARSE_FAILURE);
}
***************
*** 484,488 ****
return new String(encoder.encodeBuffer(data.getBytes()));
} catch (Exception x) {
! throw new SASLException(ERR_BASE64);
}
}
--- 469,473 ----
return new String(encoder.encodeBuffer(data.getBytes()));
} catch (Exception x) {
! throw new SASLException("Base64 encode or decode failure");
}
}
Index: SASLProfile.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/profile/sasl/SASLProfile.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -r1.6 -r1.7
*** SASLProfile.java 2001/11/08 05:51:34 1.6
--- SASLProfile.java 2001/11/29 04:00:00 1.7
***************
*** 50,59 ****
// Constants
public static final String COMPLETE = "<blob status='complete'>";
- public final static String ERR_INVALID_SASL_STATUS =
- "Invalid SASL Status attribute value employed";
public static final String ENCODING_NONE = "none";
public static final String ENCODING_BASE64 = "base64";
public static final String ENCODING_DEFAULT = ENCODING_NONE;
- public static final String FRAGMENT_ERROR_PREFIX = "<error ";
public static final String LOCALIZE_DEFAULT = "i-default";
public final static String SASL = "sasl";
--- 50,56 ----
|
|
From: Huston F. <hu...@us...> - 2001-11-29 04:00:03
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core
In directory usw-pr-cvs1:/tmp/cvs-serv29433/src/org/beepcore/beep/core
Modified Files:
BEEPError.java ProfileRegistry.java Session.java
Log Message:
First pass cleanup
Index: BEEPError.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/BEEPError.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -r1.5 -r1.6
*** BEEPError.java 2001/11/08 05:51:34 1.5
--- BEEPError.java 2001/11/29 04:00:00 1.6
***************
*** 42,61 ****
private static final String ERR_MALFORMED_XML_MSG = "Malformed XML";
- private static final String ERR_UNKNOWN_OPERATION_ELEMENT_MSG =
- "Unknown operation element";
- private static final String ERR_PCDATA_TOO_BIG_MSG =
- "Element's PCDATA exceeds the maximum size";
-
- private static final String FRAGMENT_ANGLE_SUFFIX = ">";
- private static final String FRAGMENT_CODE_PREFIX = "code='";
- private static final String FRAGMENT_ERROR_PREFIX = "<error ";
- private static final String FRAGMENT_ERROR_SUFFIX = "</error>";
- private static final String FRAGMENT_QUOTE_SLASH_ANGLE_SUFFIX = "' />";
- private static final String FRAGMENT_QUOTE_SUFFIX = "' ";
- private static final String FRAGMENT_XML_LANG_PREFIX = "xml:lang='";
-
- private static final String TAG_CODE = "code";
- private static final String TAG_ERROR = "error";
- private static final String TAG_XML_LANG = "xml:lang";
private int code;
--- 42,45 ----
***************
*** 187,207 ****
StringBuffer sb = new StringBuffer(128);
! sb.append(FRAGMENT_ERROR_PREFIX);
! sb.append(FRAGMENT_CODE_PREFIX);
sb.append(code);
if (xmlLang != null) {
! sb.append(FRAGMENT_QUOTE_SUFFIX);
! sb.append(FRAGMENT_XML_LANG_PREFIX);
sb.append(xmlLang);
}
if (diagnostic != null) {
! sb.append(FRAGMENT_QUOTE_SUFFIX);
! sb.append(FRAGMENT_ANGLE_SUFFIX);
sb.append(diagnostic);
! sb.append(FRAGMENT_ERROR_SUFFIX);
} else {
! sb.append(FRAGMENT_QUOTE_SLASH_ANGLE_SUFFIX);
}
--- 171,188 ----
StringBuffer sb = new StringBuffer(128);
! sb.append("<error code='");
sb.append(code);
if (xmlLang != null) {
! sb.append("' xml:lang='");
sb.append(xmlLang);
}
if (diagnostic != null) {
! sb.append("' >");
sb.append(diagnostic);
! sb.append("</error>");
} else {
! sb.append("' />");
}
***************
*** 258,266 ****
if (elementName == null) {
throw new BEEPException(ERR_MALFORMED_XML_MSG);
! } else if (!elementName.equals(TAG_ERROR)) {
! throw new BEEPException(ERR_UNKNOWN_OPERATION_ELEMENT_MSG);
}
! String code = topElement.getAttribute(TAG_CODE);
if (code == null) {
--- 239,247 ----
if (elementName == null) {
throw new BEEPException(ERR_MALFORMED_XML_MSG);
! } else if (!elementName.equals("error")) {
! throw new BEEPException("Unknown operation element");
}
! String code = topElement.getAttribute("code");
if (code == null) {
***************
*** 269,273 ****
// this attribute is implied
! String xmlLang = topElement.getAttribute(TAG_XML_LANG);
Node dataNode = topElement.getFirstChild();
String data = null;
--- 250,254 ----
// this attribute is implied
! String xmlLang = topElement.getAttribute("xml:lang");
Node dataNode = topElement.getFirstChild();
String data = null;
Index: ProfileRegistry.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/ProfileRegistry.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -C2 -r1.10 -r1.11
*** ProfileRegistry.java 2001/11/27 17:37:22 1.10
--- ProfileRegistry.java 2001/11/29 04:00:00 1.11
***************
*** 39,61 ****
public class ProfileRegistry implements Cloneable {
- private static final String SPACE = " ";
- private static final String FRAGMENT_ANGLE_SUFFIX = ">";
- private static final String FRAGMENT_FEATURES_PREFIX = "features='";
- private static final String FRAGMENT_GREETING_PREFIX = "<greeting";
- private static final String FRAGMENT_GREETING_SUFFIX = "</greeting>";
- private static final String FRAGMENT_LOCALIZE_PREFIX = "localize='";
- private static final String FRAGMENT_PROFILE_PREFIX = "<profile ";
- private static final String FRAGMENT_QUOTE_ANGLE_SUFFIX = "'>";
- private static final String FRAGMENT_QUOTE_SLASH_ANGLE_SUFFIX = "' />";
- private static final String FRAGMENT_QUOTE_SUFFIX = "' ";
- private static final String FRAGMENT_URI_PREFIX = "uri='";
- private static final int FRAGMENT_GREETING_LENGTH =
- FRAGMENT_GREETING_PREFIX.length()
- + FRAGMENT_QUOTE_ANGLE_SUFFIX.length()
- + FRAGMENT_GREETING_SUFFIX.length();
- private static final int FRAGMENT_PROFILE_LENGTH =
- FRAGMENT_PROFILE_PREFIX.length()
- + FRAGMENT_QUOTE_ANGLE_SUFFIX.length();
-
// Instance Data
private class InternalProfile {
--- 39,42 ----
***************
*** 65,71 ****
private Hashtable profileListeners;
- String greeting;
String localize;
- String features;
// Constructors
--- 46,50 ----
***************
*** 78,92 ****
public ProfileRegistry()
{
- this.greeting = null;
- this.features = null;
this.localize = Constants.LOCALIZE_DEFAULT;
this.profileListeners = new Hashtable();
}
! private ProfileRegistry(String greeting, String localize,
! String features, Hashtable profiles)
{
- this.greeting = greeting;
- this.features = features;
this.localize = localize;
this.profileListeners = profiles;
--- 57,66 ----
public ProfileRegistry()
{
this.localize = Constants.LOCALIZE_DEFAULT;
this.profileListeners = new Hashtable();
}
! private ProfileRegistry(String localize, Hashtable profiles)
{
this.localize = localize;
this.profileListeners = profiles;
***************
*** 95,100 ****
public Object clone()
{
! return new ProfileRegistry(this.greeting, this.localize,
! this.features,
(Hashtable) this.profileListeners.clone());
}
--- 69,73 ----
public Object clone()
{
! return new ProfileRegistry(this.localize,
(Hashtable) this.profileListeners.clone());
}
***************
*** 240,247 ****
return this.localize;
}
! byte[] getGreeting(Session session)
{
! int bufferSize = FRAGMENT_GREETING_LENGTH;
int profileCount = 0;
--- 213,224 ----
return this.localize;
}
+
+ byte[] getGreeting(Session session) {
+ return getGreeting(session, null);
+ }
! byte[] getGreeting(Session session, String features)
{
! int bufferSize = "<greeting></greeting>".length();
int profileCount = 0;
***************
*** 252,256 ****
while (e.hasMoreElements()) {
bufferSize += ((String) e.nextElement()).length()
! + FRAGMENT_PROFILE_LENGTH;
}
--- 229,233 ----
while (e.hasMoreElements()) {
bufferSize += ((String) e.nextElement()).length()
! + "<profile>".length();
}
***************
*** 263,283 ****
Enumeration f = profileListeners.keys();
! sb.append(FRAGMENT_GREETING_PREFIX);
if ((localize != null)
&&!localize.equals(Constants.LOCALIZE_DEFAULT)) {
! sb.append(this.SPACE);
! sb.append(FRAGMENT_LOCALIZE_PREFIX);
sb.append(localize);
! sb.append(FRAGMENT_QUOTE_SUFFIX);
}
if (features != null) {
! sb.append(FRAGMENT_FEATURES_PREFIX);
sb.append(features);
! sb.append(FRAGMENT_QUOTE_SUFFIX);
}
! sb.append(FRAGMENT_ANGLE_SUFFIX);
while (f.hasMoreElements()) {
--- 240,259 ----
Enumeration f = profileListeners.keys();
! sb.append("<greeting");
if ((localize != null)
&&!localize.equals(Constants.LOCALIZE_DEFAULT)) {
! sb.append(" localize='");
sb.append(localize);
! sb.append("' ");
}
if (features != null) {
! sb.append("features='");
sb.append(features);
! sb.append("' ");
}
! sb.append('>');
while (f.hasMoreElements()) {
***************
*** 309,316 ****
profile.listener.advertiseProfile(session)))
{
! sb.append(FRAGMENT_PROFILE_PREFIX);
! sb.append(FRAGMENT_URI_PREFIX);
! sb.append((String) profileName);
! sb.append(FRAGMENT_QUOTE_SLASH_ANGLE_SUFFIX);
}
} catch (BEEPException x) {
--- 285,291 ----
profile.listener.advertiseProfile(session)))
{
! sb.append("<profile uri='");
! sb.append(profileName);
! sb.append("' />");
}
} catch (BEEPException x) {
***************
*** 321,325 ****
}
! sb.append(FRAGMENT_GREETING_SUFFIX);
return StringUtil.stringBufferToAscii(sb);
--- 296,300 ----
}
! sb.append("</greeting>");
return StringUtil.stringBufferToAscii(sb);
Index: Session.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/Session.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -C2 -r1.21 -r1.22
*** Session.java 2001/11/27 17:37:22 1.21
--- Session.java 2001/11/29 04:00:00 1.22
***************
*** 83,87 ****
/** @todo check this */
- private static final int MAX_PAYLOAD_SIZE = 4096;
private static final int MAX_PCDATA_SIZE = 4096;
private static final int MAX_START_CHANNEL_WAIT = 60000;
--- 83,86 ----
***************
*** 90,148 ****
private static final String CHANNEL_ZERO = "0";
- private static final String ERR_GREETING_FAILED =
- "Greeting exchange failed";
- private static final String ERR_ILLEGAL_SHUTDOWN =
- "Illegal state for shutdown";
- private static final String ERR_PROFILES_UNAVAILABLE =
- "all requested profiles are unsupported";
- private static final String ERR_NONEXISTENT_CHANNEL =
- "Session call on nonexistent channel.";
- private static final String ERR_STATE_CHANGE =
- "Illegal session state transition";
private static final String ERR_MALFORMED_XML_MSG = "Malformed XML";
- private static final String ERR_PCDATA_TOO_BIG_MSG =
- "Element's PCDATA exceeds the maximum size";
private static final String ERR_UNKNOWN_OPERATION_ELEMENT_MSG =
"Unknown operation element";
- private static final String ERR_MALFORMED_PROFILE_MSG =
- "Malformed profile";
! private static final String FRAGMENT_ANGLE_SUFFIX = ">";
! private static final String FRAGMENT_CDATA_PREFIX = "<![CDATA[";
! private static final String FRAGMENT_CDATA_SUFFIX = "]]>";
! private static final String FRAGMENT_CLOSE_PREFIX = "<close ";
! private static final String FRAGMENT_CODE_PREFIX = "code='";
! private static final String FRAGMENT_ENCODING_PREFIX = "encoding='";
! private static final String FRAGMENT_NUMBER_PREFIX = "number='";
! private static final String FRAGMENT_OK = "<ok />";
! private static final String FRAGMENT_PROFILE_PREFIX = "<profile ";
! private static final String FRAGMENT_PROFILE_SUFFIX = "</profile>";
! private static final String FRAGMENT_QUOTE_ANGLE_SUFFIX = "'>";
! private static final String FRAGMENT_QUOTE_SLASH_ANGLE_SUFFIX = "' />";
! private static final String FRAGMENT_QUOTE_SUFFIX = "' ";
! private static final String FRAGMENT_SERVERNAME_PREFIX = "serverName='";
! private static final String FRAGMENT_SLASH_ANGLE_SUFFIX = " />";
! private static final String FRAGMENT_START_PREFIX = "<start ";
! private static final String FRAGMENT_START_SUFFIX = "</start>";
! private static final String FRAGMENT_URI_PREFIX = "uri='";
! private static final String FRAGMENT_XML_LANG_PREFIX = "xml:lang='";
!
! private static final String TAG_CLOSE = "close";
! private static final String TAG_CODE = "code";
! private static final String TAG_ENCODING = "encoding";
! private static final String TAG_FEATURES = "features";
! private static final String TAG_GREETING = "greeting";
! private static final String TAG_LOCALIZE = "localize";
! private static final String TAG_NUMBER = "number";
! private static final String TAG_OK = "ok";
! private static final String TAG_PROFILE = "profile";
! private static final String TAG_START = "start";
! private static final String TAG_SERVER_NAME = "serverName";
! private static final String TAG_URI = "uri";
! private static final String TAG_XML_LANG = "xml:lang";
// Instance Data
private int state;
- private long messageNumber;
private long nextChannelNumber = 0;
private Channel zero;
--- 89,101 ----
private static final String CHANNEL_ZERO = "0";
private static final String ERR_MALFORMED_XML_MSG = "Malformed XML";
private static final String ERR_UNKNOWN_OPERATION_ELEMENT_MSG =
"Unknown operation element";
! private static final byte[] OK_ELEMENT =
! StringUtil.stringToAscii("<ok />");
// Instance Data
private int state;
private long nextChannelNumber = 0;
private Channel zero;
***************
*** 248,252 ****
// check the channel state and return the appropriate exception
if (zero.getState() == Channel.STATE_ERROR) {
! throw new BEEPException(ERR_GREETING_FAILED);
}
}
--- 201,205 ----
// check the channel state and return the appropriate exception
if (zero.getState() == Channel.STATE_ERROR) {
! throw new BEEPException("Greeting exchange failed");
}
}
***************
*** 557,564 ****
StringBuffer startBuffer = new StringBuffer();
! startBuffer.append(FRAGMENT_START_PREFIX);
! startBuffer.append(FRAGMENT_NUMBER_PREFIX);
startBuffer.append(channelNumber);
! startBuffer.append(FRAGMENT_QUOTE_ANGLE_SUFFIX);
Iterator i = profiles.iterator();
--- 510,516 ----
StringBuffer startBuffer = new StringBuffer();
! startBuffer.append("<start number='");
startBuffer.append(channelNumber);
! startBuffer.append("'>");
Iterator i = profiles.iterator();
***************
*** 568,578 ****
// @todo maybe we should check these against peerSupportedProfiles
! startBuffer.append(FRAGMENT_PROFILE_PREFIX);
! startBuffer.append(FRAGMENT_URI_PREFIX);
startBuffer.append(p.uri);
! startBuffer.append(FRAGMENT_QUOTE_SUFFIX);
if (p.data == null) {
! startBuffer.append(FRAGMENT_SLASH_ANGLE_SUFFIX);
} else {
if (p.base64Encoding) {
--- 520,529 ----
// @todo maybe we should check these against peerSupportedProfiles
! startBuffer.append("<profile uri='");
startBuffer.append(p.uri);
! startBuffer.append("' ");
if (p.data == null) {
! startBuffer.append(" />");
} else {
if (p.base64Encoding) {
***************
*** 580,592 ****
}
! startBuffer.append(FRAGMENT_ANGLE_SUFFIX);
! startBuffer.append(FRAGMENT_CDATA_PREFIX);
startBuffer.append(p.data);
! startBuffer.append(FRAGMENT_CDATA_SUFFIX);
! startBuffer.append(FRAGMENT_PROFILE_SUFFIX);
}
}
! startBuffer.append(FRAGMENT_START_SUFFIX);
// @todo handle the data element
--- 531,541 ----
}
! startBuffer.append("><![CDATA[");
startBuffer.append(p.data);
! startBuffer.append("]]></profile>");
}
}
! startBuffer.append("</start>");
// @todo handle the data element
***************
*** 666,670 ****
&&!((newState == SESSION_STATE_INITIALIZED)
|| (newState == SESSION_STATE_CLOSED))) {
! throw new BEEPException(ERR_STATE_CHANGE);
}
--- 615,619 ----
&&!((newState == SESSION_STATE_INITIALIZED)
|| (newState == SESSION_STATE_CLOSED))) {
! throw new BEEPException("Illegal session state transition");
}
***************
*** 673,677 ****
|| (newState == SESSION_STATE_GREETING_RECEIVED)
|| (newState == SESSION_STATE_CLOSED))) {
! throw new BEEPException(ERR_STATE_CHANGE);
}
--- 622,626 ----
|| (newState == SESSION_STATE_GREETING_RECEIVED)
|| (newState == SESSION_STATE_CLOSED))) {
! throw new BEEPException("Illegal session state transition");
}
***************
*** 680,684 ****
&& (newState != SESSION_STATE_TERMINATING)
&& (newState != SESSION_STATE_CLOSING)) {
! throw new BEEPException(ERR_STATE_CHANGE);
}
--- 629,633 ----
&& (newState != SESSION_STATE_TERMINATING)
&& (newState != SESSION_STATE_CLOSING)) {
! throw new BEEPException("Illegal session state transition");
}
***************
*** 745,749 ****
if (ch == null) {
! throw new BEEPException(ERR_NONEXISTENT_CHANNEL);
}
--- 694,698 ----
if (ch == null) {
! throw new BEEPException("Session call on nonexistent channel.");
}
***************
*** 967,984 ****
StringBuffer closeBuffer = new StringBuffer();
! closeBuffer.append(FRAGMENT_CLOSE_PREFIX);
! closeBuffer.append(FRAGMENT_NUMBER_PREFIX);
closeBuffer.append(channel.getNumberAsString());
! closeBuffer.append(FRAGMENT_QUOTE_SUFFIX);
! closeBuffer.append(FRAGMENT_CODE_PREFIX);
closeBuffer.append(code);
if (xmlLang != null) {
! closeBuffer.append(FRAGMENT_QUOTE_SUFFIX);
! closeBuffer.append(FRAGMENT_XML_LANG_PREFIX);
closeBuffer.append(xmlLang);
}
! closeBuffer.append(FRAGMENT_QUOTE_SLASH_ANGLE_SUFFIX);
// Lock necessary because we have to know the msgNo
--- 916,930 ----
StringBuffer closeBuffer = new StringBuffer();
! closeBuffer.append("<close number='");
closeBuffer.append(channel.getNumberAsString());
! closeBuffer.append("' code='");
closeBuffer.append(code);
if (xmlLang != null) {
! closeBuffer.append("' xml:lang='");
closeBuffer.append(xmlLang);
}
! closeBuffer.append("' />");
// Lock necessary because we have to know the msgNo
***************
*** 1023,1027 ****
if (ch == null) {
! throw new BEEPException(ERR_NONEXISTENT_CHANNEL);
}
--- 969,973 ----
if (ch == null) {
! throw new BEEPException("Session call on nonexistent channel.");
}
***************
*** 1036,1051 ****
StringBuffer sb = new StringBuffer();
! sb.append(FRAGMENT_PROFILE_PREFIX);
! sb.append(FRAGMENT_URI_PREFIX);
sb.append(uri);
if (datum != null) {
! sb.append(FRAGMENT_QUOTE_ANGLE_SUFFIX);
! sb.append(FRAGMENT_CDATA_PREFIX);
sb.append(datum);
! sb.append(FRAGMENT_CDATA_SUFFIX);
! sb.append(FRAGMENT_PROFILE_SUFFIX);
} else {
! sb.append(FRAGMENT_QUOTE_SLASH_ANGLE_SUFFIX);
}
--- 982,994 ----
StringBuffer sb = new StringBuffer();
! sb.append("<profile uri='");
sb.append(uri);
if (datum != null) {
! sb.append("'><![CDATA[");
sb.append(datum);
! sb.append("]]></profile>");
} else {
! sb.append("' />");
}
***************
*** 1166,1170 ****
OutputDataStream sds =
new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
! StringUtil.stringToAscii(FRAGMENT_OK));
try {
--- 1109,1113 ----
OutputDataStream sds =
new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
! OK_ELEMENT);
try {
***************
*** 1192,1196 ****
// @todo got consecutive shutdowns... now what... log it?
! // Utility.assert(ERR_ILLEGAL_SHUTDOWN, -1);
}
} catch (BEEPException e) {
--- 1135,1139 ----
// @todo got consecutive shutdowns... now what... log it?
! // Utility.assert("Illegal state for shutdown", -1);
}
} catch (BEEPException e) {
***************
*** 1244,1248 ****
OutputDataStream sds =
new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
! StringUtil.stringToAscii(FRAGMENT_OK));
try {
--- 1187,1191 ----
OutputDataStream sds =
new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
! OK_ELEMENT);
try {
***************
*** 1357,1361 ****
try {
! ((Message)zero.getAppData()).sendERR(BEEPError.CODE_REQUESTED_ACTION_NOT_TAKEN2, ERR_PROFILES_UNAVAILABLE);
} catch (Exception x) {
terminate("Error sending error. " + x.getMessage());
--- 1300,1304 ----
try {
! ((Message)zero.getAppData()).sendERR(BEEPError.CODE_REQUESTED_ACTION_NOT_TAKEN2, "all requested profiles are unsupported");
} catch (Exception x) {
terminate("Error sending error. " + x.getMessage());
***************
*** 1446,1454 ****
// is this MSG a <start>
! if (elementName.equals(TAG_START)) {
Log.logEntry(Log.SEV_DEBUG, CORE,
"Received a start channel request");
! String channelNumber = topElement.getAttribute(TAG_NUMBER);
if (channelNumber == null) {
--- 1389,1397 ----
// is this MSG a <start>
! if (elementName.equals("start")) {
Log.logEntry(Log.SEV_DEBUG, CORE,
"Received a start channel request");
! String channelNumber = topElement.getAttribute("number");
if (channelNumber == null) {
***************
*** 1458,1464 ****
// this attribute is implied
! String serverName = topElement.getAttribute(TAG_SERVER_NAME);
NodeList profiles =
! topElement.getElementsByTagName(TAG_PROFILE);
if (profiles == null) {
--- 1401,1407 ----
// this attribute is implied
! String serverName = topElement.getAttribute("serverName");
NodeList profiles =
! topElement.getElementsByTagName("profile");
if (profiles == null) {
***************
*** 1471,1475 ****
for (int i = 0; i < profiles.getLength(); i++) {
Element profile = (Element) profiles.item(i);
! String uri = profile.getAttribute(TAG_URI);
if (uri == null) {
--- 1414,1418 ----
for (int i = 0; i < profiles.getLength(); i++) {
Element profile = (Element) profiles.item(i);
! String uri = profile.getAttribute("uri");
if (uri == null) {
***************
*** 1478,1482 ****
}
! String encoding = profile.getAttribute(TAG_ENCODING);
boolean b64;
--- 1421,1425 ----
}
! String encoding = profile.getAttribute("encoding");
boolean b64;
***************
*** 1500,1504 ****
if (data.length() > MAX_PCDATA_SIZE) {
throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
! ERR_PCDATA_TOO_BIG_MSG);
}
}
--- 1443,1448 ----
if (data.length() > MAX_PCDATA_SIZE) {
throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
! "Element's PCDATA exceeds " +
! "the maximum size");
}
}
***************
*** 1512,1520 ****
// is this MSG a <close>
! else if (elementName.equals(TAG_CLOSE)) {
Log.logEntry(Log.SEV_DEBUG, CORE,
"Received a channel close request");
! String channelNumber = topElement.getAttribute(TAG_NUMBER);
if (channelNumber == null) {
--- 1456,1464 ----
// is this MSG a <close>
! else if (elementName.equals("close")) {
Log.logEntry(Log.SEV_DEBUG, CORE,
"Received a channel close request");
! String channelNumber = topElement.getAttribute("number");
if (channelNumber == null) {
***************
*** 1523,1527 ****
}
! String code = topElement.getAttribute(TAG_CODE);
if (code == null) {
--- 1467,1471 ----
}
! String code = topElement.getAttribute("code");
if (code == null) {
***************
*** 1531,1535 ****
// this attribute is implied
! String xmlLang = topElement.getAttribute(TAG_XML_LANG);
String data = null;
Node dataNode = topElement.getFirstChild();
--- 1475,1479 ----
// this attribute is implied
! String xmlLang = topElement.getAttribute("xml:lang");
String data = null;
Node dataNode = topElement.getFirstChild();
***************
*** 1540,1544 ****
if (data.length() > MAX_PCDATA_SIZE) {
throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
! ERR_PCDATA_TOO_BIG_MSG);
}
}
--- 1484,1489 ----
if (data.length() > MAX_PCDATA_SIZE) {
throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
! "Element's PCDATA exceeds " +
! "the maximum size");
}
}
***************
*** 1566,1570 ****
if (elementName == null) {
throw new BEEPException(ERR_MALFORMED_XML_MSG);
! } else if (!elementName.equals(TAG_GREETING)) {
throw new BEEPException(ERR_UNKNOWN_OPERATION_ELEMENT_MSG);
}
--- 1511,1515 ----
if (elementName == null) {
throw new BEEPException(ERR_MALFORMED_XML_MSG);
! } else if (!elementName.equals("greeting")) {
throw new BEEPException(ERR_UNKNOWN_OPERATION_ELEMENT_MSG);
}
***************
*** 1573,1580 ****
// this attribute is implied
! String features = topElement.getAttribute(TAG_FEATURES);
// This attribute has a default value
! String localize = topElement.getAttribute(TAG_LOCALIZE);
if (localize == null) {
--- 1518,1525 ----
// this attribute is implied
! String features = topElement.getAttribute("features");
// This attribute has a default value
! String localize = topElement.getAttribute("localize");
if (localize == null) {
***************
*** 1585,1589 ****
// with 0 profiles
NodeList profiles =
! topElement.getElementsByTagName(TAG_PROFILE);
if (profiles.getLength() > 0) {
--- 1530,1534 ----
// with 0 profiles
NodeList profiles =
! topElement.getElementsByTagName("profile");
if (profiles.getLength() > 0) {
***************
*** 1592,1602 ****
for (int i = 0; i < profiles.getLength(); i++) {
Element profile = (Element) profiles.item(i);
! String uri = profile.getAttribute(TAG_URI);
if (uri == null) {
! throw new BEEPException(ERR_MALFORMED_PROFILE_MSG);
}
! String encoding = profile.getAttribute(TAG_ENCODING);
// encoding is not allowed in greetings
--- 1537,1547 ----
for (int i = 0; i < profiles.getLength(); i++) {
Element profile = (Element) profiles.item(i);
! String uri = profile.getAttribute("uri");
if (uri == null) {
! throw new BEEPException("Malformed profile");
}
! String encoding = profile.getAttribute("encoding");
// encoding is not allowed in greetings
***************
*** 1668,1681 ****
// is this RPY a <profile>
! } else if (elementName.equals(TAG_PROFILE)) {
try {
! String uri = topElement.getAttribute(TAG_URI);
if (uri == null) {
! throw new BEEPException(ERR_MALFORMED_PROFILE_MSG);
}
String encoding =
! topElement.getAttribute(TAG_ENCODING);
if (encoding == null) {
--- 1613,1626 ----
// is this RPY a <profile>
! } else if (elementName.equals("profile")) {
try {
! String uri = topElement.getAttribute("uri");
if (uri == null) {
! throw new BEEPException("Malformed profile");
}
String encoding =
! topElement.getAttribute("encoding");
if (encoding == null) {
***************
*** 1691,1695 ****
if (data.length() > MAX_PCDATA_SIZE) {
! throw new BEEPException(ERR_PCDATA_TOO_BIG_MSG);
}
}
--- 1636,1642 ----
if (data.length() > MAX_PCDATA_SIZE) {
! throw new BEEPException("Element's PCDATA " +
! "exceeds the " +
! "maximum size");
}
}
***************
*** 1792,1796 ****
// is this RPY an <ok> (the positive response to a
// channel close)
! } else if (elementName.equals(TAG_OK)) {
Log.logEntry(Log.SEV_DEBUG, CORE,
"Received an OK for channel close");
--- 1739,1743 ----
// is this RPY an <ok> (the positive response to a
// channel close)
! } else if (elementName.equals("ok")) {
Log.logEntry(Log.SEV_DEBUG, CORE,
"Received an OK for channel close");
|
|
From: Huston F. <hu...@us...> - 2001-11-27 17:37:25
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/util In directory usw-pr-cvs1:/tmp/cvs-serv6472/src/org/beepcore/beep/util Added Files: StringUtil.java Log Message: Added utility methods for String to ASCII --- NEW FILE: StringUtil.java --- /* * StringUtil.java $Revision: 1.1 $ $Date: 2001/11/27 17:37:22 $ * * Copyright (c) 2001 Huston Franklin. All rights reserved. * * The contents of this file are subject to the Blocks Public License (the * "License"); You may not use this file except in compliance with the License. * * You may obtain a copy of the License at http://www.beepcore.org/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * */ package org.beepcore.beep.util; /** * * @author Huston Franklin * @version $Revision: 1.1 $, $Date: 2001/11/27 17:37:22 $ */ public class StringUtil { private StringUtil() {} public static String asciiToString(byte[] b, int off, int len) { char[] c = new char[len]; for (int i=0; i<len; ++i) { c[i] = (char)(b[off + i] & 0xff); } return new String(c); } public static byte[] stringToAscii(String s) { byte[] b = new byte[s.length()]; for (int i=0; i<b.length; ++i) { b[i] = (byte)s.charAt(i); } return b; } public static byte[] stringBufferToAscii(StringBuffer s) { byte[] b = new byte[s.length()]; for (int i=0; i<b.length; ++i) { b[i] = (byte)s.charAt(i); } return b; } } |
|
From: Huston F. <hu...@us...> - 2001-11-27 17:37:25
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core
In directory usw-pr-cvs1:/tmp/cvs-serv6472/src/org/beepcore/beep/core
Modified Files:
Frame.java ProfileRegistry.java Session.java
Log Message:
Added utility methods for String to ASCII
Index: Frame.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/Frame.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -C2 -r1.15 -r1.16
*** Frame.java 2001/11/27 16:04:58 1.15
--- Frame.java 2001/11/27 17:37:22 1.16
***************
*** 19,24 ****
- import java.io.UnsupportedEncodingException;
-
import java.util.Iterator;
import java.util.LinkedList;
--- 19,22 ----
***************
*** 28,31 ****
--- 26,30 ----
import org.beepcore.beep.util.HeaderParser;
import org.beepcore.beep.util.Log;
+ import org.beepcore.beep.util.StringUtil;
/**
***************
*** 281,291 ****
header.append(this.CRLF);
! Log.logEntry(Log.SEV_DEBUG, header.toString());
! try {
! return header.toString().getBytes("UTF-8");
! } catch (UnsupportedEncodingException e) {
! throw new RuntimeException("UnsupportedEncodingException" +
! e.getMessage());
}
}
--- 280,287 ----
header.append(this.CRLF);
! if (Log.isLogged(Log.SEV_DEBUG)) {
! Log.logEntry(Log.SEV_DEBUG, header.toString());
}
+ return StringUtil.stringBufferToAscii(header);
}
***************
*** 360,365 ****
}
! Log.logEntry(Log.SEV_DEBUG_VERBOSE,
! "getMessageType=" + types[ret] + " (" + ret + ")");
return ret;
--- 356,363 ----
}
! if (Log.isLogged(Log.SEV_DEBUG_VERBOSE)) {
! Log.logEntry(Log.SEV_DEBUG_VERBOSE, "getMessageType=" +
! types[ret] + " (" + ret + ")");
! }
return ret;
Index: ProfileRegistry.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/ProfileRegistry.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -r1.9 -r1.10
*** ProfileRegistry.java 2001/11/09 19:12:25 1.9
--- ProfileRegistry.java 2001/11/27 17:37:22 1.10
***************
*** 3,6 ****
--- 3,7 ----
*
* Copyright (c) 2001 Invisible Worlds, Inc. All rights reserved.
+ * Copyright (c) 2001 Huston Franklin. All rights reserved.
*
* The contents of this file are subject to the Blocks Public License (the
***************
*** 20,31 ****
import java.util.Enumeration;
import java.util.Hashtable;
import org.beepcore.beep.util.Log;
/**
! * This class is used to save pointers in Sessions - if the peer is using
! * the same set of profile and associated StartChannelListener for all
! * sessions then they should create one of these helpers and use them in
! * the corresponding factory methods.
*
* @author Eric Dixon
--- 21,33 ----
import java.util.Enumeration;
import java.util.Hashtable;
+
import org.beepcore.beep.util.Log;
+ import org.beepcore.beep.util.StringUtil;
/**
! * Maintains a set of associations between URIs and
! * <code>StartChannelListener</code>s. This set is used to generate
! * the <code>greeting</code> and to demux <code>start</code> requests.
*
* @author Eric Dixon
***************
*** 33,37 ****
* @author Jay Kint
* @author Scott Pead
! * @version $Revision, $Date$
*/
public class ProfileRegistry implements Cloneable {
--- 35,39 ----
* @author Jay Kint
* @author Scott Pead
! * @version $Revision$, $Date$
*/
public class ProfileRegistry implements Cloneable {
***************
*** 117,122 ****
*
*/
! public StartChannelListener getStartChannelListener(SessionTuningProperties tuning,
! String uri)
{
--- 119,125 ----
*
*/
! public StartChannelListener
! getStartChannelListener(SessionTuningProperties tuning,
! String uri)
{
***************
*** 173,178 ****
*
*/
! public synchronized StartChannelListener addStartChannelListener(String profile,
! StartChannelListener listener, SessionTuningProperties tuning)
{
--- 176,183 ----
*
*/
! public synchronized StartChannelListener
! addStartChannelListener(String profile,
! StartChannelListener listener,
! SessionTuningProperties tuning)
{
***************
*** 205,209 ****
*
*/
! public synchronized StartChannelListener removeStartChannelListener(String profile)
{
InternalProfile temp =
--- 210,215 ----
*
*/
! public synchronized StartChannelListener
! removeStartChannelListener(String profile)
{
InternalProfile temp =
***************
*** 316,323 ****
sb.append(FRAGMENT_GREETING_SUFFIX);
-
- greeting = sb.toString();
! return greeting.getBytes();
}
}
--- 322,327 ----
sb.append(FRAGMENT_GREETING_SUFFIX);
! return StringUtil.stringBufferToAscii(sb);
}
}
Index: Session.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/Session.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -C2 -r1.20 -r1.21
*** Session.java 2001/11/22 15:25:29 1.20
--- Session.java 2001/11/27 17:37:22 1.21
***************
*** 40,43 ****
--- 40,44 ----
import org.beepcore.beep.core.event.SessionListener;
import org.beepcore.beep.util.Log;
+ import org.beepcore.beep.util.StringUtil;
***************
*** 141,146 ****
private static final String TAG_XML_LANG = "xml:lang";
- private static final String DEFAULT_STRING_ENCODING = "UTF-8";
-
// Instance Data
private int state;
--- 142,145 ----
***************
*** 597,602 ****
// Make a message
OutputDataStream ds =
! new StringOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
! startBuffer.toString());
// Tell Channel Zero to start us up
--- 596,601 ----
// Make a message
OutputDataStream ds =
! new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
! StringUtil.stringBufferToAscii(startBuffer));
// Tell Channel Zero to start us up
***************
*** 989,994 ****
synchronized (reply) {
OutputDataStream ds =
! new StringOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
! closeBuffer.toString());
this.zero.sendMSG(ds,
--- 988,993 ----
synchronized (reply) {
OutputDataStream ds =
! new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
! StringUtil.stringBufferToAscii(closeBuffer));
this.zero.sendMSG(ds,
***************
*** 1051,1062 ****
}
! StringOutputDataStream sds =
! new StringOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
! sb.toString());
// Store the Channel
ch.setState(Channel.STATE_OK);
channels.put(ch.getNumberAsString(), ch);
! ((Message)zero.getAppData()).sendRPY(sds);
}
--- 1050,1061 ----
}
! OutputDataStream ds =
! new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
! StringUtil.stringBufferToAscii(sb));
// Store the Channel
ch.setState(Channel.STATE_OK);
channels.put(ch.getNumberAsString(), ch);
! ((Message)zero.getAppData()).sendRPY(ds);
}
***************
*** 1165,1171 ****
// Send an ok
! StringOutputDataStream sds =
! new StringOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
! FRAGMENT_OK);
try {
--- 1164,1170 ----
// Send an ok
! OutputDataStream sds =
! new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
! StringUtil.stringToAscii(FRAGMENT_OK));
try {
***************
*** 1243,1249 ****
}
! StringOutputDataStream sds =
! new StringOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
! FRAGMENT_OK);
try {
--- 1242,1248 ----
}
! OutputDataStream sds =
! new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
! StringUtil.stringToAscii(FRAGMENT_OK));
try {
|
|
From: Huston F. <hu...@us...> - 2001-11-27 17:37:25
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/transport/tcp
In directory usw-pr-cvs1:/tmp/cvs-serv6472/src/org/beepcore/beep/transport/tcp
Modified Files:
TCPSession.java
Log Message:
Added utility methods for String to ASCII
Index: TCPSession.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/transport/tcp/TCPSession.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -C2 -r1.20 -r1.21
*** TCPSession.java 2001/11/27 16:04:59 1.20
--- TCPSession.java 2001/11/27 17:37:22 1.21
***************
*** 41,44 ****
--- 41,45 ----
import org.beepcore.beep.util.HeaderParser;
import org.beepcore.beep.util.Log;
+ import org.beepcore.beep.util.StringUtil;
***************
*** 404,408 ****
synchronized (writerLock) {
! os.write(sb.toString().getBytes("UTF-8"));
os.flush();
}
--- 405,409 ----
synchronized (writerLock) {
! os.write(StringUtil.stringBufferToAscii(sb));
os.flush();
}
|
|
From: Huston F. <hu...@us...> - 2001-11-27 16:05:03
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/util In directory usw-pr-cvs1:/tmp/cvs-serv14355/src/org/beepcore/beep/util Added Files: HeaderParser.java Log Message: Improved header parsing --- NEW FILE: HeaderParser.java --- /* * HeaderParser.java $Revision: 1.1 $ $Date: 2001/11/27 16:04:59 $ * * Copyright (c) 2001 Huston Franklin. All rights reserved. * * The contents of this file are subject to the Blocks Public License (the * "License"); You may not use this file except in compliance with the License. * * You may obtain a copy of the License at http://www.beepcore.org/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * */ package org.beepcore.beep.util; import org.beepcore.beep.core.BEEPException; /** * * @author Huston Franklin * @version $Revision: 1.1 $, $Date: 2001/11/27 16:04:59 $ */ public class HeaderParser { static final int MAX_INT_STRING_LENGTH = 10; static final long UNSIGNED_INT_MAX_VALUE = 4294967295L; private byte[] buf; private int off = 0; private int len; public HeaderParser(byte[] buf, int len) { this.buf = buf; this.len = len; } public boolean hasMoreTokens() { return off < len; } public boolean parseLast() throws BEEPException { if (hasMoreTokens() == false) { throw new BEEPException("Malformed BEEP Header"); } int tl = tokenLength(); if (tl != 1) { throw new BEEPException("Malformed BEEP Header"); } char c = (char)(buf[off] & 0x7f); if (c != '*' && c != '.') { throw new BEEPException("Malformed BEEP Header"); } findNextToken(tl); return c == '.'; } public int parseInt() throws BEEPException { if (hasMoreTokens() == false) { throw new BEEPException("Malformed BEEP Header"); } int tl = tokenLength(); int i = atoi(buf, off, tl); findNextToken(tl); return i; } public long parseUnsignedInt() throws BEEPException { if (hasMoreTokens() == false) { throw new BEEPException("Malformed BEEP Header"); } int tl = tokenLength(); long l = atoui(buf, off, tl); findNextToken(tl); return l; } public char[] parseType() throws BEEPException { if (hasMoreTokens() == false) { throw new BEEPException("Malformed BEEP Header"); } int tl = tokenLength(); if (tl != 3) { throw new BEEPException("Malformed BEEP Header"); } char[] c = new char[3]; c[0] = (char) (buf[off] & 0xff); c[1] = (char) (buf[off+1] & 0xff); c[2] = (char) (buf[off+2] & 0xff); findNextToken(tl); return c; } private void findNextToken(int previousLength) throws BEEPException { off += previousLength + 1; if (off > len) return; if (off == len || buf[off - 1] != ' ' || buf[off] == ' ') { throw new BEEPException("Malformed BEEP Header"); } } private int tokenLength() { for (int i=off; i<len; ++i) { if ((buf[i] & 0xff) == ' ') { return i - off; } } return len - off; } private static int atoi(byte[] b, int off, int len) throws NumberFormatException { long res = atoui(b, off, len); if (res > Integer.MAX_VALUE) { throw new NumberFormatException(); } return (int) res; } private static long atoui(byte[] b, int off, int len) throws NumberFormatException { if (len > MAX_INT_STRING_LENGTH) { throw new NumberFormatException(); } long res = 0; for (int i=off; i<len + off; ++i) { if (b[i] < (byte) '0' || b[i] > (byte) '9') { System.out.println("b[" + i + "] = " + b[i]); throw new NumberFormatException(); } res *= 10; res += (b[i] - (byte) '0'); } if (res > UNSIGNED_INT_MAX_VALUE) { throw new NumberFormatException(); } return res; } } |
|
From: Huston F. <hu...@us...> - 2001-11-27 16:05:02
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/transport/tcp
In directory usw-pr-cvs1:/tmp/cvs-serv14355/src/org/beepcore/beep/transport/tcp
Modified Files:
TCPSession.java
Log Message:
Improved header parsing
Index: TCPSession.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/transport/tcp/TCPSession.java,v
retrieving revision 1.19
retrieving revision 1.20
diff -C2 -r1.19 -r1.20
*** TCPSession.java 2001/11/27 07:31:21 1.19
--- TCPSession.java 2001/11/27 16:04:59 1.20
***************
*** 39,42 ****
--- 39,43 ----
import org.beepcore.beep.core.SessionTuningProperties;
import org.beepcore.beep.util.BufferSegment;
+ import org.beepcore.beep.util.HeaderParser;
import org.beepcore.beep.util.Log;
***************
*** 54,67 ****
// Constants
! private static final String ERR_SEND_FRAME_FAILED =
! "Unable to send a frame";
! private static final String ERR_TCP_BUFFER_TOO_LARGE = "";
! private static final String SEQ_PREFIX = "SEQ ";
! private static final char NEWLINE_CHAR = '\n';
! private static final int DEFAULT_PROPERTIES_SIZE = 4;
! private static final int DEFAULT_RECEIVE_BUFFER_SIZE = 4 * 1024;
private static final int MAX_RECEIVE_BUFFER_SIZE = 64 * 1024;
- private static final int MIN_RECEIVE_BUFFER_SIZE = 4 * 1024;
- private static final int SEQ_LENGTH = SEQ_PREFIX.length();
private static final String TCP_MAPPING = "TCP Mapping";
private static final String CRLF = "\r\n";
--- 55,60 ----
// Constants
! private static final char[] MESSAGE_TYPE_SEQ = new char[] {'S', 'E', 'Q'};
private static final int MAX_RECEIVE_BUFFER_SIZE = 64 * 1024;
private static final String TCP_MAPPING = "TCP Mapping";
private static final String CRLF = "\r\n";
***************
*** 80,87 ****
// Instance Data
- // @todo had these per stack, but have
- // since changed my tune, since we'll be thread/session
- // for probably a while yet...this'll help on performance.
- // reusing fixed size buffers.
private byte headerBuffer[] = new byte[Frame.MAX_HEADER_SIZE];
private byte[] outputBuf = new byte[0];
--- 73,76 ----
***************
*** 397,401 ****
StringBuffer sb = new StringBuffer(Frame.MAX_HEADER_SIZE);
! sb.append(SEQ_PREFIX);
sb.append(this.getChannelNumberAsString(channel));
sb.append(' ');
--- 386,391 ----
StringBuffer sb = new StringBuffer(Frame.MAX_HEADER_SIZE);
! sb.append(MESSAGE_TYPE_SEQ);
! sb.append(' ');
sb.append(this.getChannelNumberAsString(channel));
sb.append(' ');
***************
*** 466,470 ****
}
! if (headerBuffer[0] == (byte) SEQ_PREFIX.charAt(0)) {
processSEQFrame(headerBuffer, amountRead, is);
continue;
--- 456,460 ----
}
! if (headerBuffer[0] == (byte) MESSAGE_TYPE_SEQ[0]) {
processSEQFrame(headerBuffer, amountRead, is);
continue;
***************
*** 665,692 ****
// Process the header
! StringTokenizer st = new StringTokenizer(new String(headerBuffer, 0,
! headerLength));
!
! if (st.countTokens() != 4) {
!
! // This should just shut the session down.
! Log.logEntry(Log.SEV_ERROR, TCP_MAPPING, "Malformed BEEP header");
!
throw new BEEPException("Malformed BEEP header");
}
! // Skip the SEQ
! if (st.nextToken().equals("SEQ") == false) {
! throw new BEEPException("Malformed BEEP header");
! }
!
! // Read the Channel Number
! int channelNum = Integer.parseInt(st.nextToken());
! // Read the Ack Number
! long ackNum = Long.parseLong(st.nextToken());
!
! // Read the Window Number
! int window = Integer.parseInt(st.nextToken());
// update the channel with the new receive window size
--- 655,673 ----
// Process the header
! HeaderParser header = new HeaderParser(headerBuffer,
! headerLength - CRLF.length());
!
! char[] type = header.parseType();
! if (java.util.Arrays.equals(type, MESSAGE_TYPE_SEQ) == false) {
throw new BEEPException("Malformed BEEP header");
}
! int channelNum = header.parseInt();
! long ackNum = header.parseUnsignedInt();
! int window = header.parseInt();
! if (header.hasMoreTokens()) {
! throw new BEEPException("Malformed BEEP Header");
! }
// update the channel with the new receive window size
|
|
From: Huston F. <hu...@us...> - 2001-11-27 16:05:02
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core
In directory usw-pr-cvs1:/tmp/cvs-serv14355/src/org/beepcore/beep/core
Modified Files:
Frame.java
Log Message:
Improved header parsing
Index: Frame.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/Frame.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -r1.14 -r1.15
*** Frame.java 2001/11/27 07:31:21 1.14
--- Frame.java 2001/11/27 16:04:58 1.15
***************
*** 3,6 ****
--- 3,7 ----
*
* Copyright (c) 2001 Invisible Worlds, Inc. All rights reserved.
+ * Copyright (c) 2001 Huston Franklin. All rights reserved.
*
* The contents of this file are subject to the Blocks Public License (the
***************
*** 25,28 ****
--- 26,30 ----
import org.beepcore.beep.util.BufferSegment;
+ import org.beepcore.beep.util.HeaderParser;
import org.beepcore.beep.util.Log;
***************
*** 293,357 ****
Log.logEntry(Log.SEV_DEBUG_VERBOSE, "Processing normal BEEP frame");
! int limit = length;
! StringTokenizer st;
! try {
! st = new StringTokenizer(new String(headerBuffer, 0, length,
! "UTF-8"));
! } catch (UnsupportedEncodingException e) {
! throw new RuntimeException("UnsupportedEncodingException" +
! e.getMessage());
! }
!
! int count = st.countTokens();
!
! if (!(count == 6 || count == 7)) {
! Log.logEntry(Log.SEV_DEBUG,
! "Illegal header tokens=" + count + "\n"
! + new String(headerBuffer));
!
! throw new BEEPException("Malformed BEEP Header");
! }
! // Get Message Type
! // Kick out if we've maxed, or if the type gets set.
! int msgType = MessageType.getMessageType(st.nextToken());
!
! // Read the Channel Number
! int channelNum = Integer.parseInt(st.nextToken());
!
! // Read the Message Number
! int msgNum = Integer.parseInt(st.nextToken());
!
! // Read the more flag
! char isLast = st.nextToken().charAt(0);
!
! boolean last;
! if (isLast == '*') {
! last = false;
! } else if (isLast == '.') {
! last = true;
! } else {
!
! Log.logEntry(Log.SEV_DEBUG, "lastFrame=" + isLast);
!
! throw new BEEPException("Malformed BEEP Header");
}
-
- // Sequence Number
- long seqNum = Long.parseLong(st.nextToken());
! // Size
! int size = Integer.parseInt(st.nextToken());
!
! if (size < 0) {
throw new BEEPException("Malformed BEEP Header");
- }
-
- int ansNum = -1;
- if (count == 7) {
-
- // AnsNo
- ansNum = Integer.parseInt(st.nextToken());
}
--- 295,315 ----
Log.logEntry(Log.SEV_DEBUG_VERBOSE, "Processing normal BEEP frame");
! HeaderParser header = new HeaderParser(headerBuffer, length);
! int msgType =
! MessageType.getMessageType(new String(header.parseType()));
! int channelNum = header.parseInt();
! int msgNum = header.parseInt();
! boolean last = header.parseLast();
! long seqNum = header.parseUnsignedInt();
! int size = header.parseInt();
! int ansNum = -1;
! if (header.hasMoreTokens()) {
! ansNum = header.parseInt();
}
! if (header.hasMoreTokens()) {
throw new BEEPException("Malformed BEEP Header");
}
|
|
From: Huston F. <hu...@us...> - 2001-11-27 07:31:24
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/transport/tcp
In directory usw-pr-cvs1:/tmp/cvs-serv9482/src/org/beepcore/beep/transport/tcp
Modified Files:
TCPSession.java
Log Message:
reduced the number of calls to read()
Index: TCPSession.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/transport/tcp/TCPSession.java,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -r1.18 -r1.19
*** TCPSession.java 2001/11/27 02:39:03 1.18
--- TCPSession.java 2001/11/27 07:31:21 1.19
***************
*** 66,69 ****
--- 66,77 ----
private static final String TCP_MAPPING = "TCP Mapping";
private static final String CRLF = "\r\n";
+ private static final int MIN_SEQ_HEADER_SIZE = (3 // msg type
+ + 1 // space
+ + 1 // channel number
+ + 1 // space
+ + 1 // acknum
+ + 1 // space
+ + 1 // window
+ + CRLF.length());
private static final int CHANNEL_START_ODD = 1;
***************
*** 227,231 ****
}
! thread = new Thread(new SessionThread(), threadName);
thread.setDaemon(true);
--- 235,244 ----
}
! thread = new Thread(threadName)
! {
! public void run() {
! processNextFrame();
! }
! };
thread.setDaemon(true);
***************
*** 411,452 ****
}
- // Lame hack for J++
- private boolean modState(int i) throws BEEPException
- {
- return super.changeState(i);
- }
-
- /**
- * This specialization is designed to process Frames unique
- * to the TCP mapping (e.g. SEQ frames). If the Frame is
- * not an SEQ frame, it calls the regular TCPSession
- * processNextFrame( int ) with an integer that simply
- * indicates how far it's read ahead into the stream.
- * @exception Throws an exception if it encounters a poorly
- * formed header or an IOException in the underlying socket
- * stream.
- *
- * @throws BEEPException
- */
private void processNextFrame()
- throws BEEPException, IOException, SessionAbortedException
{
! if (Log.isLogged(Log.SEV_DEBUG_VERBOSE)) {
! Log.logEntry(Log.SEV_DEBUG_VERBOSE, TCP_MAPPING,
! "Processing next frame");
}
! int length = 0;
! InputStream is = socket.getInputStream();
while (true) {
try {
! int b = is.read();
! if (b == -1) {
throw new SessionAbortedException();
}
! headerBuffer[length] = (byte) b;
} catch (java.net.SocketException e) {
--- 424,517 ----
}
private void processNextFrame()
{
! running = true;
!
! try {
! InputStream is = socket.getInputStream();
!
! while (running) {
! if (getState() == SESSION_STATE_CLOSING ||
! getState() == SESSION_STATE_TERMINATING ||
! getState() == SESSION_STATE_CLOSED)
! {
! break;
! }
!
! if (Log.isLogged(Log.SEV_DEBUG_VERBOSE)) {
! Log.logEntry(Log.SEV_DEBUG_VERBOSE, TCP_MAPPING,
! "Processing next frame");
! }
!
! int amountRead;
!
! try {
! do {
! amountRead =
! is.read(headerBuffer, 0, MIN_SEQ_HEADER_SIZE);
!
! if (amountRead == -1) {
! throw new SessionAbortedException();
! }
! } while (amountRead == 0);
!
! } catch (java.net.SocketException e) {
! if (getState() == SESSION_STATE_ACTIVE) {
! throw e;
! }
!
! // socket closed intentionally (session closing)
! // so just return
! return;
! }
!
! if (headerBuffer[0] == (byte) SEQ_PREFIX.charAt(0)) {
! processSEQFrame(headerBuffer, amountRead, is);
! continue;
! } else {
! processCoreFrame(headerBuffer, amountRead, is);
! }
! }
! } catch (IOException e) {
! Log.logEntry(Log.SEV_ERROR, TCP_MAPPING, e);
!
! socket = null;
!
! terminate(e.getMessage());
! } catch (SessionAbortedException e) {
! terminate("Session aborted by remote peer.");
! } catch (Throwable e) {
! Log.logEntry(Log.SEV_ERROR, TCP_MAPPING, e);
! terminate(e.getMessage());
}
! Log.logEntry(Log.SEV_DEBUG, TCP_MAPPING,
! "Session listener thread exiting. State = "
! + TCPSession.this.getState());
! }
+ private void processCoreFrame(byte[] headerBuffer, int amountRead,
+ InputStream is)
+ throws SessionAbortedException, BEEPException, IOException
+ {
+ int headerLength = 0;
+ int amountToRead = Frame.MIN_FRAME_SIZE - amountRead;
+
+ headerFound:
while (true) {
+ int tokenCount = 6;
+
try {
! int n = is.read(headerBuffer, amountRead, amountToRead);
! if (n == -1) {
throw new SessionAbortedException();
}
+
+ if (n == 0) {
+ continue;
+ }
! amountRead += n;
} catch (java.net.SocketException e) {
***************
*** 455,526 ****
}
! // socket closed intentionally (session closing) so just return
return;
}
! if (headerBuffer[length] == '\n') {
! if ((length == 0) || (headerBuffer[length - 1] != '\r')) {
! throw new BEEPException("Malformed BEEP header");
}
! --length;
! break;
}
-
- ++length;
! if (length == Frame.MAX_HEADER_SIZE) {
throw new BEEPException("Malformed BEEP header, no CRLF");
}
}
! if (Log.isLogged(Log.SEV_DEBUG)) {
! Log.logEntry(Log.SEV_DEBUG, TCP_MAPPING,
! "Processing: "
! + new String(headerBuffer, 0, length));
}
! // If this is not a SEQ frame build a <code>Frame</code> and
! // read in the payload and verify the TRAILER.
! if (headerBuffer[0] != (byte) SEQ_PREFIX.charAt(0)) {
! Frame f = super.createFrame(headerBuffer, length);
! byte[] payload = new byte[f.getSize()];
! for (int count = 0; count < payload.length; ) {
! int n = is.read(payload, count, payload.length - count);
! if (n == -1) {
! throw new SessionAbortedException();
}
! count += n;
}
! if (Log.isLogged(Log.SEV_DEBUG_VERBOSE)) {
! Log.logEntry(Log.SEV_DEBUG_VERBOSE, TCP_MAPPING,
! new String(payload));
}
! for (int i = 0; i < Frame.TRAILER.length(); ++i) {
! int b = is.read();
! if (b == -1) {
throw new SessionAbortedException();
}
! if (((byte) b) != ((byte) Frame.TRAILER.charAt(i))) {
! throw new BEEPException("Malformed BEEP frame, "
! + "invalid trailer");
}
- }
! f.addPayload(new BufferSegment(payload));
! super.postFrame(f);
! return;
}
// Process the header
StringTokenizer st = new StringTokenizer(new String(headerBuffer, 0,
! length));
if (st.countTokens() != 4) {
--- 520,670 ----
}
! // socket closed intentionally (session closing)
! // so just return
! running = false;
return;
}
! while (headerLength < amountRead) {
! if (headerBuffer[headerLength] == '\n') {
! if (headerLength == 0 ||
! headerBuffer[headerLength - 1] != '\r')
! {
! throw new BEEPException("Malformed BEEP header");
! }
!
! ++headerLength;
! break headerFound;
}
! if (headerBuffer[headerLength] == ' ') {
! if (tokenCount > 1) { // This is for ANS frames
! --tokenCount;
! }
! }
! ++headerLength;
}
! if (headerLength > Frame.MAX_HEADER_SIZE) {
throw new BEEPException("Malformed BEEP header, no CRLF");
}
+
+ /* 2 = 1 for the min token size and 1 is for the separator ' '
+ * or "\r\n"
+ */
+ amountToRead = (tokenCount * 2) + Frame.TRAILER.length();
}
! if (Log.isLogged(Log.SEV_DEBUG_VERBOSE)) {
! Log.logEntry(Log.SEV_DEBUG_VERBOSE, TCP_MAPPING,
! new String(headerBuffer, 0, headerLength));
}
! Frame f = super.createFrame(headerBuffer,
! headerLength - CRLF.length());
! byte[] payload = new byte[f.getSize()];
! int count = amountRead - headerLength;
! System.arraycopy(headerBuffer, headerLength, payload, 0, count);
!
! while (count < payload.length) {
! int n = is.read(payload, count, payload.length - count);
! if (n == -1) {
! throw new SessionAbortedException();
! }
! count += n;
! }
!
! if (Log.isLogged(Log.SEV_DEBUG_VERBOSE)) {
! Log.logEntry(Log.SEV_DEBUG_VERBOSE, TCP_MAPPING,
! new String(payload));
! }
!
! for (int i = 0; i < Frame.TRAILER.length(); ++i) {
! int b = is.read();
!
! if (b == -1) {
! throw new SessionAbortedException();
! }
!
! if (((byte) b) != ((byte) Frame.TRAILER.charAt(i))) {
! throw new BEEPException("Malformed BEEP frame, "
! + "invalid trailer");
! }
! }
!
! f.addPayload(new BufferSegment(payload));
! super.postFrame(f);
! }
!
! private void processSEQFrame(byte[] headerBuffer, int amountRead,
! InputStream is)
! throws BEEPException, IOException, SessionAbortedException
! {
! int headerLength = 0;
! int tokenCount = 4;
!
! headerFound:
! while (true) {
!
! while (headerLength < amountRead) {
! if (headerBuffer[headerLength] == '\n') {
! if (headerLength == 0 ||
! headerBuffer[headerLength - 1] != '\r')
! {
! throw new BEEPException("Malformed BEEP header");
! }
!
! ++headerLength;
! break headerFound;
}
!
! if (headerBuffer[headerLength] == ' ') {
! if (tokenCount > 1) {
! --tokenCount;
! }
! }
!
! ++headerLength;
}
! if (headerLength > Frame.MAX_HEADER_SIZE) {
! throw new BEEPException("Malformed BEEP header, no CRLF");
}
! int amountToRead = headerBuffer[headerLength - 1] == '\r' ? 1 :
! tokenCount * 2;
! try {
! /* 2 = 1 for the min token size and 1 is for the separator ' '
! * or "\r\n"
! */
! int n = is.read(headerBuffer, amountRead, amountToRead);
! if (n == -1) {
throw new SessionAbortedException();
}
! if (n == 0) {
! continue;
}
! amountRead += n;
!
! } catch (java.net.SocketException e) {
! if (getState() == SESSION_STATE_ACTIVE) {
! throw e;
! }
! // socket closed intentionally (session closing)
! // so just return
! running = false;
! return;
! }
}
// Process the header
StringTokenizer st = new StringTokenizer(new String(headerBuffer, 0,
! headerLength));
if (st.countTokens() != 4) {
***************
*** 549,588 ****
this.updatePeerReceiveBufferSize(channelNum, ackNum, window);
}
!
! private class SessionThread implements Runnable {
!
! public void run()
! {
! try {
! running = true;
!
! // Listen for and post the Greeting Frame
! while ((getState() != SESSION_STATE_ACTIVE) && running) {
! processNextFrame();
! }
!
! // Keep processing frames as long as we're active
! while ((getState() == SESSION_STATE_ACTIVE) && running) {
! processNextFrame();
! }
! } catch (IOException e) {
! Log.logEntry(Log.SEV_ERROR, TCP_MAPPING, e);
!
! socket = null;
!
! terminate(e.getMessage());
! } catch (SessionAbortedException e) {
! terminate("Session aborted by remote peer.");
! } catch (Throwable e) {
! Log.logEntry(Log.SEV_ERROR, TCP_MAPPING, e);
! terminate(e.getMessage());
! }
!
! Log.logEntry(Log.SEV_DEBUG, TCP_MAPPING,
! "Session listener thread exiting. State = "
! + TCPSession.this.getState());
! }
! }
!
private static class SessionAbortedException extends Exception {
}
--- 693,697 ----
this.updatePeerReceiveBufferSize(channelNum, ackNum, window);
}
!
private static class SessionAbortedException extends Exception {
}
|
|
From: Huston F. <hu...@us...> - 2001-11-27 07:31:24
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core
In directory usw-pr-cvs1:/tmp/cvs-serv9482/src/org/beepcore/beep/core
Modified Files:
Frame.java
Log Message:
reduced the number of calls to read()
Index: Frame.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/Frame.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -r1.13 -r1.14
*** Frame.java 2001/11/27 02:41:25 1.13
--- Frame.java 2001/11/27 07:31:21 1.14
***************
*** 45,48 ****
--- 45,50 ----
public class Frame {
+ private static final String CRLF = "\r\n";
+
public static final String TRAILER = "END\r\n";
public static final int MAX_HEADER_SIZE = (3 // msg type
***************
*** 59,63 ****
+ 1 // space
+ 10 // ansno
! + 2); // CRLF
public static final int MAX_ANS_NUMBER = Integer.MAX_VALUE; // 2147483647;
public static final int MAX_CHANNEL_NUMBER = Integer.MAX_VALUE;
--- 61,79 ----
+ 1 // space
+ 10 // ansno
! + CRLF.length());
! public static final int MIN_HEADER_SIZE = (3 // msg type
! + 1 // space
! + 1 // channel number
! + 1 // space
! + 1 // msgno
! + 1 // space
! + 1 // more
! + 1 // space
! + 1 // seqno
! + 1 // space
! + 1 // size
! + CRLF.length());
! public static final int MIN_FRAME_SIZE = MIN_HEADER_SIZE +
! Frame.TRAILER.length();
public static final int MAX_ANS_NUMBER = Integer.MAX_VALUE; // 2147483647;
public static final int MAX_CHANNEL_NUMBER = Integer.MAX_VALUE;
***************
*** 66,70 ****
public static final int MAX_SIZE = Integer.MAX_VALUE;
- private static final String CRLF = "\r\n";
private static final BufferSegment trailerBufferSegment =
new BufferSegment(TRAILER.getBytes());
--- 82,85 ----
|
|
From: Huston F. <hu...@us...> - 2001-11-27 02:41:27
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core
In directory usw-pr-cvs1:/tmp/cvs-serv18022/src/org/beepcore/beep/core
Modified Files:
Frame.java
Log Message:
a bit clearer
Index: Frame.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/Frame.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -C2 -r1.12 -r1.13
*** Frame.java 2001/11/27 02:39:03 1.12
--- Frame.java 2001/11/27 02:41:25 1.13
***************
*** 145,149 ****
b[0] = new BufferSegment(buildHeader());
! b[b.length-1] = trailerBufferSegment;
return b;
--- 145,149 ----
b[0] = new BufferSegment(buildHeader());
! b[j] = trailerBufferSegment;
return b;
|
|
From: Huston F. <hu...@us...> - 2001-11-27 02:39:06
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/transport/tcp
In directory usw-pr-cvs1:/tmp/cvs-serv17443/src/org/beepcore/beep/transport/tcp
Modified Files:
TCPSession.java
Log Message:
changed to make a single call to write
Index: TCPSession.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/transport/tcp/TCPSession.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -C2 -r1.17 -r1.18
*** TCPSession.java 2001/11/23 04:24:04 1.17
--- TCPSession.java 2001/11/27 02:39:03 1.18
***************
*** 77,80 ****
--- 77,81 ----
// reusing fixed size buffers.
private byte headerBuffer[] = new byte[Frame.MAX_HEADER_SIZE];
+ private byte[] outputBuf = new byte[0];
private Object writerLock;
private Socket socket;
***************
*** 258,288 ****
try {
- // @todo consider the costs of colliding these into one
- // buffer and one write..test to see if it's faster
- // this way or faster copying.
OutputStream os = socket.getOutputStream();
- byte[] header = null;
synchronized (writerLock) {
! if (Log.isLogged(Log.SEV_DEBUG_VERBOSE)) {
! Log.logEntry(Log.SEV_DEBUG_VERBOSE, TCP_MAPPING,
! "Wrote the following\n");
}
! Iterator i = f.getBytes();
! while (i.hasNext()) {
! BufferSegment b = (BufferSegment) i.next();
! os.write(b.getData(), b.getOffset(), b.getLength());
! if (Log.isLogged(Log.SEV_DEBUG_VERBOSE)) {
! Log.logEntry(Log.SEV_DEBUG_VERBOSE, TCP_MAPPING,
! new String(b.getData(), b.getOffset(),
! b.getLength()));
! }
}
os.flush();
}
} catch (IOException e) {
--- 259,297 ----
try {
OutputStream os = socket.getOutputStream();
synchronized (writerLock) {
! /* Inspite of the extra data copy if is faster to have
! * a single call to write() (at least with the JVMs we
! * have tested with).
! */
! BufferSegment[] bs = f.getBytes();
!
! int n = 0;
! for (int i=0; i<bs.length; ++i) {
! n += bs[i].getLength();
}
! if (n > outputBuf.length) {
! outputBuf = new byte[n];
! }
! int off = 0;
! for (int i=0; i<bs.length; ++i) {
! System.arraycopy(bs[i].getData(), bs[i].getOffset(),
! outputBuf, off, bs[i].getLength());
! off += bs[i].getLength();
}
+ os.write(outputBuf, 0, n);
os.flush();
+
+ if (Log.isLogged(Log.SEV_DEBUG_VERBOSE)) {
+ Log.logEntry(Log.SEV_DEBUG_VERBOSE, TCP_MAPPING,
+ "Wrote the following\n" +
+ new String(outputBuf));
+ }
}
} catch (IOException e) {
|
|
From: Huston F. <hu...@us...> - 2001-11-27 02:39:05
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core
In directory usw-pr-cvs1:/tmp/cvs-serv17443/src/org/beepcore/beep/core
Modified Files:
Frame.java
Log Message:
changed to make a single call to write
Index: Frame.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/Frame.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -r1.11 -r1.12
*** Frame.java 2001/11/08 05:51:34 1.11
--- Frame.java 2001/11/27 02:39:03 1.12
***************
*** 67,70 ****
--- 67,72 ----
private static final String CRLF = "\r\n";
+ private static final BufferSegment trailerBufferSegment =
+ new BufferSegment(TRAILER.getBytes());
/** BEEP message type of <code>Frame</code>. */
***************
*** 103,135 ****
private LinkedList payload = new LinkedList();
- /**
- * Initializes a new <code>Frame</code> representing a BEEP ANS frame.
- *
- * @param messageType indicates whether a <code>Frame</code> is a MSG,
- * RPY, ERR, ANS or NUL.
- * @param channel <code>Channel</code> on which the <code>Frame</code> was
- * sent.
- * @param msgno Message number of the <code>Frame</code>.
- * @param seqno Sequence number of the <code>Frame</code>.
- * @param ansno Answer number of the <code>Frame</code>.
- * @param payload Payload of the <code>Frame</code>.
- * @param last Indicates if this is the last <code>Frame</code> sent in a
- * sequence of frames.
- *
- * @see BufferSegment
- */
- // Frame(int messageType, Channel channel, int msgno, boolean last,
- // long seqno, int ansno, BufferSegment payload)
- // {
- // this.messageType = messageType;
- // this.channel = channel;
- // this.msgno = msgno;
- // this.seqno = seqno;
- // this.ansno = ansno;
- // this.payload.add(payload);
- // this.size = payload.getLength() - payload.getOffset();
- // this.last = last;
- // }
-
Frame(int messageType, Channel channel, int msgno, boolean last,
long seqno, int size, int ansno)
--- 105,108 ----
***************
*** 142,146 ****
this.size = size;
this.ansno = ansno;
- // this.payload = null;
}
--- 115,118 ----
***************
*** 159,174 ****
*
*/
! public Iterator getBytes()
{
this.size = 0;
Iterator i = this.payload.iterator();
while (i.hasNext()) {
! this.size += ((BufferSegment) i.next()).getLength();
}
! this.payload.addFirst(new BufferSegment(buildHeader()));
! this.payload.addLast(new BufferSegment(TRAILER.getBytes()));
! return this.payload.iterator();
}
--- 131,151 ----
*
*/
! public BufferSegment[] getBytes()
{
+ BufferSegment[] b = new BufferSegment[this.payload.size() + 2];
this.size = 0;
+ int j=1;
Iterator i = this.payload.iterator();
while (i.hasNext()) {
! b[j] = (BufferSegment) i.next();
! this.size += b[j].getLength();
! ++j;
}
+
+ b[0] = new BufferSegment(buildHeader());
+ b[b.length-1] = trailerBufferSegment;
! return b;
}
|
|
From: Huston F. <hu...@us...> - 2001-11-25 08:38:45
|
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/profile/echo
In directory usw-pr-cvs1:/tmp/cvs-serv31642/src/org/beepcore/beep/profile/echo
Modified Files:
EchoProfile.java
Log Message:
removed unnecessary call to setAppData
Index: EchoProfile.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/profile/echo/EchoProfile.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -r1.11 -r1.12
*** EchoProfile.java 2001/11/08 05:51:34 1.11
--- EchoProfile.java 2001/11/25 08:38:42 1.12
***************
*** 60,64 ****
Log.logEntry(Log.SEV_DEBUG, "EchoCCL CloseChannel Callback");
channel.setMessageListener(null);
- channel.setAppData(null);
}
--- 60,63 ----
|
|
From: Huston F. <hu...@us...> - 2001-11-25 08:00:31
|
Update of /cvsroot/beepcore-java/beepcore-java/example/org/beepcore/beep/example
In directory usw-pr-cvs1:/tmp/cvs-serv26746/example/org/beepcore/beep/example
Modified Files:
Bing.java
Log Message:
Clarified usage of InputDataStream
Index: Bing.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/example/org/beepcore/beep/example/Bing.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -r1.9 -r1.10
*** Bing.java 2001/11/10 21:33:28 1.9
--- Bing.java 2001/11/25 08:00:28 1.10
***************
*** 25,29 ****
import org.beepcore.beep.core.BEEPInterruptedException;
import org.beepcore.beep.core.Channel;
- import org.beepcore.beep.core.InputDataStream;
import org.beepcore.beep.core.ProfileRegistry;
import org.beepcore.beep.core.Session;
--- 25,28 ----
***************
*** 125,134 ****
try {
// Get the reply to the request
! InputDataStream ds = reply.getNextReply().getDataStream();
! InputStream is = ds.getInputStream();
// Read the data in the reply
! while (ds.isComplete() == false || is.available() > 0) {
! is.read();
++replyLength;
}
--- 124,132 ----
try {
// Get the reply to the request
! InputStream is =
! reply.getNextReply().getDataStream().getInputStream();
// Read the data in the reply
! while (is.read() != -1) {
++replyLength;
}
|