From cdba0d582e233069e6b655083bb87c27d3b0e829 Mon Sep 17 00:00:00 2001 From: Andrey Kurilov Date: Wed, 11 Apr 2018 16:37:43 +0300 Subject: [PATCH] v2.0.0 --- build.gradle | 46 +++++++++++++++--- gradle/wrapper/gradle-wrapper.jar | Bin 54783 -> 54329 bytes gradle/wrapper/gradle-wrapper.properties | 3 +- gradlew | 6 +-- .../concurrent/AsyncRunnableBase.java | 4 +- .../concurrent/ContextAwareThreadFactory.java | 10 ++-- .../akurilov/concurrent/RateThrottle.java | 4 +- .../akurilov/concurrent/WeightThrottle.java | 8 +-- .../concurrent/coroutines/CoroutineBase.java | 2 +- .../coroutines/CoroutinesExecutor.java | 20 +++----- .../coroutines/CoroutinesExecutorTask.java | 2 +- .../coroutines/RoundRobinOutputCoroutine.java | 28 +++++------ .../coroutines/TransferCoroutine.java | 10 ++-- src/main/java/module-info.java | 17 +++++++ .../{ => test}/RateThrottleTest.java | 3 +- .../RoundRobinOutputCoroutineTest.java | 4 +- .../{ => test}/WeightThrottleTest.java | 3 +- 17 files changed, 109 insertions(+), 61 deletions(-) create mode 100644 src/main/java/module-info.java rename src/test/java/com/github/akurilov/concurrent/{ => test}/RateThrottleTest.java (98%) rename src/test/java/com/github/akurilov/concurrent/{coroutines => test}/RoundRobinOutputCoroutineTest.java (96%) rename src/test/java/com/github/akurilov/concurrent/{ => test}/WeightThrottleTest.java (96%) diff --git a/build.gradle b/build.gradle index cf0d743..154c082 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -description = "The library supporting the alternative concurrency model" +description = "The concurrency library which includes the coroutines functionality" buildscript { repositories { @@ -11,32 +11,62 @@ allprojects { apply plugin: "maven" apply plugin: "signing" group = "com.github.akurilov" - version = "1.1.5" + version = "2.0.0" } -tasks.withType(JavaCompile) { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 -} +ext.moduleName = "${group}.concurrent" repositories { mavenCentral() } dependencies { - compile("com.github.akurilov:java-commons:[1.4.7,)") + compile("com.github.akurilov:java-commons:[2.0.0,)") testCompile("junit:junit:4.12") } +compileJava { + sourceCompatibility = JavaVersion.VERSION_1_10 + targetCompatibility = JavaVersion.VERSION_1_10 + inputs.property("moduleName", moduleName) + doFirst { + options.compilerArgs = [ + "--module-path", classpath.asPath, + ] + classpath = files() + } +} + +compileTestJava { + sourceCompatibility = JavaVersion.VERSION_1_10 + targetCompatibility = JavaVersion.VERSION_1_10 + inputs.property("moduleName", moduleName) + doFirst { + options.compilerArgs = [ + "--module-path", classpath.asPath, + "--add-modules", "ALL-MODULE-PATH", + "--add-reads", "${moduleName}.test=junit", + "--patch-module", "$moduleName=" + files(sourceSets.test.java.outputDir).asPath, + ] + classpath = files() + } +} + jar { + inputs.property("moduleName", moduleName) manifest { attributes ( + "Automatic-Module-Name": moduleName, "Implementation-Version": version, "Implementation-Title": rootProject.name, ) } } +javadoc { + options.addStringOption("-module-path", classpath.asPath) +} + task sourcesJar(type: Jar, dependsOn: classes) { classifier = "sources" from sourceSets.main.allSource @@ -137,7 +167,7 @@ uploadArchives { } task wrapper(type: Wrapper) { - gradleVersion = "3.5" + gradleVersion = "4.6" } task printVersion { diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 027bf0082ba262c06a14803bd8027c24205a93e2..f6b961fd5a86aa5fbfe90f707c3138408be7c718 100644 GIT binary patch delta 30484 zcmV(;K-<6ns{^^H1CTcaC{4!rkvmoin&_GFa`AEj0FWB7wDkxLkns`D4-NnTCL90& zA(L?i9)B)lY+-YAommTD6xVe&JaXwCBCr(=TU+jhz2~O;$EpF4+{Woose$qDmx@r1N zKWWnQ-hQ-NZ4{@r_2zx3`1x*eNa;NZ`7GVZ2ns-e+XL~FPlHm@dX2ah(D6eAIs*82EK$pG4QAOGuixk4Mlxf$6pxuOZ=6Fuju$| z1AklbH$ljM8UY=DYvAwj_qF&3yl&th@l_o&a^|1pPG6HVU(@iUe zviT3$d|fvGDHZxJ9sh0M1pY_IH+1~3hHo0!hnIAGi(kRxCWMf^D%wa?8#p2Yx(FH~ zBs5*X(WHyDx@gu!i!Rm~7#Hhx5z)m4 zx$j15B5u;fCS7dS#m%~i>SBv7Zqdb7xxqF~Y}drCnz&5>0_LFO*j|6iN~i6#KzP)1 zFD>+D{8`)alT()OdII&MW5*AV4a8y(_8%D^IVKx&+t2<>mGu<)YOFA=LHn==td+DU>2sF-n?u=)r(?iL$Z##1H&PtmfbT2w7*Gi0* zk#oP$y-6qO?-%H6T}7>xnyj4JF@GTt=ywy;ykRKm*dv*_N!vSVO{UaY+$k$HVR=b8 z&QAvX*(6Q9X*HFpqPwbQ-_3E~=rL}Za-HeqOvbazQJ~CT-71OnL|%-*&8@k89NX_6 z9~;c?nsmDlB~!NAQL_>WsR}W)oRm;W*l9oMM^9#^rzJwF&h$|qCo?x@OWo^uR$9j&vYi=!mcA=s zs^85>Aq4qRQjxx3R-0S_a#7p$%fvDe9D7QtN(HLjj4#kqJkIfqKcDewWZRnKa#fP- z&BfJ0r*u(EThsQqmlW7sW`Efo<<{fzlbUFyBwD!7N++kvy|tsFb5^P>-DFG^$8@kX z;h;0^GC53IX?yps0cT3#`_|S9xTzGajWf2NWAcV=f7YetHk8nL_H>HUx^ru!H*G~+ zpw)6iZ+R{_K6#Ez(#LY{uH)W-<)xC6s=0)!2%7@oo)W^4@*_LzN`E+1?i*4I~%|Q*>#f+Z4Bpou;@$ z+-c$oyv4)^@w6#+iMyD73Q^IgLe@@{#twt7G((gwNfEncvquwmo8lhPW8x!t#>5MF zk%o}!cPh(kVy`Lg75hxFU)*Pk1ENxT5tq$r(QAq`vUk61&a&aY519BF{H#Dw`YLUT2gO4ImrwPM zjSP+)j*h1ZtAFT`lP5=`DnUe-XNahK!S(X4RYclC1x(-^t zbQP1oqw61cd0`n%DDw5jOfvcVFlTTnYwa8-jxq>8AiNrmQRl66P@&(XNt58IF-4& zF68r=nIGlzQ$ubzw=|=<>8@PbG}v1>J-t``x1*$M3SVSMvPw>3 zUa7D;xU{@!wS=~lo0kShf4sfVzNNiZaSd zZzFB{2kmJqlj6OxvE&|FMyK{LOY5}JXl+hSYe@Tt8p-jZG5~`*03K2jKs?(&$zU_O0Sdc@9B5yBc?w_^1 zn6$VvWiKmxdKI;N&rqB8@8U5+?Fu(bjDLwRlcoq~MxM2)tjaoiRO-C862^Gci(b+v zsx_K?a8MFf^PS20sg#?RH4z;co0_#{UeVY;;->vvZSM}K+! zyEhjeCAF{&@D*gmGP$|p0_`pxn-{bFJ1AQaEPYid{SQ>&IkSSNbe9#6iS^%ZjrL7C z7u@rN#61=4d!~ZPD?LA?A^R45`D;l_r4!0`X4~r6VZ6H+Rq&{1cWeJ@K9s0jdW(dn zU2o3v%Z^aNQWcJnr@|H_Fbn}3A%ASZIh1cpe+)(ieOvERfM>pEy>*sjeqS{O54W$ zwxb@mVl8e%1g+SF9ZHv7xgCqTY%c1uSsk-V^*p7E>`AQxoaIX?uhk)?C9pQEUqj6e z)L(}Y7mKL926IW5dd1&C8+4)x-AcBZ9W_SCi1s&8#e?ONPASM%Oy(BAe*REJx$*l|it+Iwm_6S{%0{IoY4ms{#Sg|-kn zBYJgnO&0CXf9su!hxY4?1aCl(1heSsyn(jPEV`e^)}DsS>zZ7TG`#$R!rE(iohEx7 zUsd0n>3^7L0`BIhhkq3J(){~~i~Ypcee~}EI;9tT(Z_%LF^B<-5+N}h#srQq_y!qh zM~SRsM9?rDGJ+>@98Z(#6F7mNrfYtl)Sn~uYl!0uIE^pi48DxB_zE7N7IA!?bKk%j z!MA`2;sIg8Qtp2@HL1rdcn5xf4!r{(#yg2sjS?^82k|aK<$oat_`4b6HI()!<(_9` z#>o3acn@kR@eL5DR11mZ97j;-ct1Ws z%PfISmoNQ1vX4=^gyfd%xINyM#ZJNI4*uQAzg_&hi+{TpvFA$B;336ut|Vl(;6qde zMG+q+C7=Cy5r5C*GtvIG_C?%1()lU^FNE)Dr>rb`o`$I$zn6~h2;X}h`{Ik(AHFY( z18vM&z5Hg;M?{yW5r=xXG}t^%JifF-0t;wEe}{+h2^m{dks!sUr8?_^3)F z1+BMomQUVX8WH;_CB&5{dH((^4i0yO2eLR6K3x479Dm7TaHJ!ARF01YIF460VJODg zojPp}3 zQ%Rl39OJ(+=Df#L@_0lY*+BupvH}^Ol{p0uv_F{~%pJY#_wkM0`eNvf{7c%Ak z6r+Y%l)s1MGx9q)lJ3|UeiJkDa5&C(q~iu|W_)kVdz^uPps^>5)15hwUm-ruEMcxi zT?D)2c&Z02if)n!Vk$$Fl@`xW-~-kw4eQN=fO_^9a!P)|Vpbsv4M6IXFf!*vY{8onveQ#_qN zd1%b$={(HaijcwmUm4(3SVxT41@sl;zZ=Ku2I#q*o8d zYXYJmu&L@fPQeYNf7No-VRFQF?cj(&B3&qCrUc@7uS~`6qV394^~#L&C#@MrDt}(d za;7ZbR{Q2*Jead-C0q3T+3c)ul^vPA=3CXO^s~pVmz;XdzADFTM~;?CvVT?^w_Iyh z`UIM^!UKWPbQFi}WtH4;w5tcUlP!5}sqXvI4YGO5ag@j5OiR?KXRgRnpp41uRoh=+ zh$jfi@k;XoJ0d}sc1v@X>q@5g^J9o(ai4ugGZoU`HPHfURpkH z`$Xm`NIkygmc2?8eAf^ z*I6Q24Qz6TRGF}6T`Q>j)E^(2%&krIk~ zW@O&+YVvH|mVv``^*!_vUPMJFFFQ(0TY<;ckzq6wUfnM>>$&^U?0*|l$_9pT!@zzV zFffP%0!C|S2EK)F3p~F1g&nQiPFeZ}zJu=?_#R#%PllY*yn$EM!4ST0;0L&A;59Y; z5I0%uhc?dDUG*H7lP+*D@70~M>3V@#@}(6>vudd%n&l+|nU_7^RJ1ZL6PIb=N0Fn~ z4V=J9fhQhCC4rcK&40if__2nc82BmPG*HC2hMyVuIesC~IT^JE)4Ob{SboW8Y!XCi zPL|DUmK`wO(EIXBF{3wY23`mzXKMJBfw%CshF=@_4Q^=ot$}xNQo}6+zrzhy>S6RP zVGn+$ZoxOSnu;NVrXpUQ2{RUj+>_3%e#aU`PFWRRZb@g>Yk!$Z<=-t6ReJ69T8${x61I%dQ37cG|U;hS5#Hqcb(nsR#0m70d~2T@M)T z>6FYbb&LL`=r-sVJ2w|tpr0S> zr}!yuLkekRATYpP3_5yM&)~XOwGGa3-VGtk@gR58lxb6+@PRuJ1KU4DY+%QSXnQ|Y zJ`}3OIrekhgAVM)ChWu0JTW6Rd>&tjeglMVM7UCpVt-tJ5nrMd-NedBpbHSsEFwO= zzk$RelGAsfaoOHLN3YJIfzCTHP7U%l7f;0-=(>eNYTon?I@R2L3;m1enQrR#Zl)5Y zdzW+{yDxGHkxMd^Edw7QcGEhniCjmj<1ZLhXMNgRw{dt8Tc-zm`|jZJTq2cd;E7x^ zm24mt3V%NMdn$Ps+foS*G|_hRF1Ek>;1gwHu+{Yr`cy6&*x9>_>-{TW9Jq(w0y#a! z12Z&8RH01*eCQyh|0&nGzD(!+oY5j^+-Ls(iBCm0bJ#65s~Kex6Pa+oU(L+4s@H3* z6-b3Wq=6#BbF9lnR>We_%ao|HdNtPURaWOs)_>=19L8;Y8NWvkf50%_!w4GGTEr+l z9>b?Nj(?$mf3to62Pg3WMG?bkq2UZs92b2ki0wEbcCoqdetuMbAVj z5NH1fP)h>@6aWAS2mk;8K>!4)dfi+C0JEtdpaKo+tZI{{3IG5!7ytk&lW_(XlWZa+ ze{6$nFd_^=055EXk%ZWU)Ugd1WE*T_Vn{*``LIPKosmwAW_2VTNt?EGCfzehCrMk` zjgyehwCPUw-YeaEkN>+n%d&KUfBgkN-TU6R*ZW?c{LjOW0oWimsn~|QRcypd&I&qyiP@x#HzyU<>4Dtyb*6w@MaY? z4)`r9w&Sgm=iB7+cDcMm#eKM6!2=53>BqYy=-n!o<2?%At6~-2r(zk-D0ooC8p-88 zJfz_LetbYh9X_ZciwXHPDVGn)t71^M|!dH9q({E}q!lpkM~jK1Q>R~39s+H$vC zzV62z^7k8ld{f1@@NEU(@#DLa_*+eww`Z`suU8-te>tij*TZo=IT{|YQnBP{n?OZ}nM_-H(i+m^8ABjc zMBdpo*xnuK>df(}c2V~3>+TxNL6^;f77>+hjU{8&Hi7x|4MPIH4s(Rksv@zZ(VIye zHd2H7;kY4{G^2WaNKeJ&-Ua%su~=GQUBpa{hDTHSNZbgYNa^F_Mk>6+f8OqQc0GD5 zNuzuT{t7IvKUi$CEnQEIl3%sQv4HAw-leAmDjkfN8Qva?8$7KXPnkTlVn$j*1eBC% zTAeZCmX7PGw84+n`Fcjwhm6XiX7V^0NrFoY2?kE3EhDifCn}FY z$21vvDCW2oWBfcs+Hywnf9Qz5AYH(gE^_S4Sh09`1}^P%c4O2Tmm|fBj_680kt^%#e{v z+gxgU;-Z3WkpeYbi|aIu;#Li};ARa+aWlKog$hZ- zFYq*7Rp?GehJOnjf70d*F`LJj6dHbsUn%&thTq_~#5pEVax4=w=(A1#M+s{99e%Ij z5BQ^kKWX?g{=%f1DX5)#daOqu*YH>TO~c>u4-IMDso@l!slmcs3jV3#U--AcQV;ia z%f1|sv*0`qJIxcxxT%k@2RJ7uG&~o#OE3Osw%evD_UP7Fe|tJ@B-l|?67RoU=mOMv zAYaX%mbSQ&@fomm+gKsQJf>QHdeB^lvSp?%O1ASA;nPHkDAk0*hzdVd6J@xaZRA>p zJGDljJfB3UqFmBxY!`Fs@rtO>M5U-w!~#t$6aht4YobOhQp93S)QTl^+Ieb{{+`K~ z{!G$}C5+sme^eu=h^3miNb2i5LNhh7Oe`1J)}beprWG17=#B&vAry`4>GU`~8#-d9 zLaw?Y-W;JLDKim@@{&8Or;SkE+H_sZtTgRAeAI|qnph!LN{Jy&tdin_VY`x>Q%)(* z^3iH>F+z3R9HEpNua>TfHDawMf7XdQfy>Cl?KPpK-E2bXaU&W# z5;I0ZvE(`Uw;5D=4H9Pyeti? zSC_+~mNLfUx*SSUX&!8;pHmpU#koyDtw9iY>6-Yu)At1Zpg zf2Cs9sc<0<#jZF%hT{kM%5sJ;KG2G|&YY6pl5?H0myuH>Hv{J;Wan~?v`xIK>ON;^TT<_NE~S;vwBA#E@}8Ub zY~`yx_%RaExG67(#`EXs>_8OWZbe<3!Qt&TebafmjWOBksrrR@=kCIFbHn8Gj1F`E z=Y`iOyJOZnHe#ALX2uzZ`U4F^ScQ$)2Ed0PhOnQ*@HO1cLmBtOd3%-n19|%jf9?<{`%9)*8+exPh%*cVU-vMA3&n*moyaHRzApF$NW z7qpfHOC;^Wpsz8DKx^qFs#}$ye?n;K6l#dFD2v5e)CPI7q}3nvH%}rcH%nW~)=%Q1 zRyC+LPGQ+_uxtv;xdv8DV&w!vQ&=?|^iN>*1TLP!8gg2j#kv{0cOk%aE#171me$c- z4X8yUmZJ%qu^v0og1vOwHP}GkY=S}PNnD28umyLZ6)(b8oW_+ni+0<0f8&mSh?M4VWAVIqMfeSQP~Gs&ft91h|bQcx(Xox|rC z{FJttkFyN9ou*#Laf0zUY0DAl;WuAzZkVIwHIKh_^yC!kh8qL*6KI$O-COH|n({z1 z4ymMKKqsovMVD;1jauxmf5J^v0`}KY+bC7Ogk6D`x_MPjc1_N|GX>ezotItZwqHON zx8zu~yLh#>!da~6Uvr=(5YFO~32Z22*OSMtHph;ybeG-zbe+_DS2Z?fu_=qqSzMaM zWxMY~MPv$FhMOjE#aYT|4YXyk^J5yOsSPj z$~8>vCVDwce_z4)w=sctF?Dw{ZKbu1l+eVCxr1Ji-KrhW!}AGWN$3lh&Vrcb^uP=4 zXr*zdYxf>IiRsbCKv@=h?m>-{w%qK^qF;J{5(6_i;N+=AE(sYdWg*Pu!V0^9BzFsU zx!kw7+$*OrNTwB(FoAuA8Ff=0mr9q5V9`me7yl2lB`pjH4V??QKqM0Y0QM;W03efb z1{RZG$qj#oL=u^}K~F(Be3can_UCC;5o z66;nUR$A?%b+;9FsHIg@5;Q8db=TTjt+v+IXKQ`!t9`F;>3gqlDer$~Zf=Fe1kR*+|hcn)g{pAw?!JU7Ir z@;vD&mgY2t=Z9zxj}LJPmxid8%jC0MnhI$u^SO$v64$_jDOMBSb}96XX^0JTs5a;*}vjo6ia1tybYxAzBVz7^{<}UYZ7>uv#db8{{?8 z)2Q%y3V$xhO+j8O9nB#+hu2B7KE&tq28CNfw1&qAd80fxNmCi(&Adh73lwgZNn1m- zj<mh$?;VZ`P|KyN@FRU4AD+*kj9pYDTQ|_+!La1nVaBVSF9rcYZ8#gqr+O)B8UGsmA z^|c$|%HqKVEvS_wEjAHXv}cbqm7XvuXcPf^%WQv3$@eBJ z$~4|3A2;mkO&c09r7(L+OP9WA>9UqojA>F-RIkq(RQPIiH;wLQT5?<~&l|G}oE70* zZ(13lhILjQ=3C8f`Gzfl6Qf&}B^CYx+=9XOR21gT5_oRONGhdX(c|kfdYRb7Un4x( z;gHXXAtYwG)00Mf$};V~>a~BsB7j(Lb{a`rR(6Qf3o|?#K6qcZb*4NpbtPb$Hb$yd&MMHD*=g9d@yKSwGCTURZM7kh0EQNf(r>JK zW1v%%?b~`I*>0KLuFL!p(}Fq^-4z&*RyUcBo>NCczOQ=-_S&eqXO4g5wo=yaa%E3P zUtO2czB4JlSz0ny+T&`2z*J(c7hprZ-A?II$J2SqM9OM696aY6z1>E;ZA6@rVAO>a zRMWiSkgcj;x2$;xl5L~y=8qb24CI(-@>MKVOlE&Df_@hpMr4DbN8Fs4v?Ga>odKf5dUe8z>9*}m@JEruK&QJ6 z`8dm{>#c-j*HtMq>Qcg47cqaLhU8Dn!%~>2Bva0Q z0eSHiZ0~|%mH}u_-sTzj5h0YDieF|z@j0HclvKY_(3n^$vs z7Y}n;CR|pWw7avTWr)=Blh#%iw>atCMZB7xS0&R_dY*q?Q0W8udzJcWK&7A4FI0M( zo>A!<`a6}brZ1@U2tBIO9=-;QPpZO{MWFFTx=y9tbgja>Rlb(LsPc8ZN8vBY$Cp*U zo^Me3D|`dC=VL21Z=n$Ts>)yEuS11w4H3;PYicV|q$qr&$~W;h5Y^cevSJlP=mmvu zR{0jbRpo!%_;!`=;5(68ylV!9?^5}j{4JI5=DjN4!}m&apUU@(1`nwGAiaZKV0iI{ zRNOXWMkZS`U3{*ikd|F2X!DDc^R-CANNVwft)cw1bu+H%@jgtmu-PUgn^kEI>77@z z6IutdxMuWXlaBUj3p4Zjs!(GL^Iz9?3A$B&i1&Yq!S<{CZQjeY{g^_ec_+alp~XI% z1S&tw-%)8V-J|jW{;ta3gH^c8DYMLWCjo1T4$Vu34jm4PoKhSwj<*7%o^xV)pVp=C zGPE|sh-y`~$>oM)Fs^Yj)kXtd$?$T{EhBn``+@7y>TL~<*`!ra(Pk6aVt4t%U zDm{M=wKXYPH8Tn0SfV2w6OkpFZb7tkHUmZ+cIo9>hn0wFx@KFcq}a~JvHqsMKD#uVlV z{?ZY%sS$}lNhGV{sO?n#5x=4Ek5&E&zp3(1`7Mm~xMiTqZ}ZPoeuv*h4eD9@sPsGj zxx&9t`8`3$FZul;OOL71RQ?rw%)fsY?93ePjCCW5w`tiaIeSR_@PW7mThJfr6NNui z`8Rxx%D?5?kz0?wC!qEn>XDE~^|$EcPsu}`b=;TbGt|mbqn0!_%5(k+UI?IS#1V5O z{fQ-|qi+PJjhd8o#-38*d8*cqry0|Zleq!;OxFnoqr`Sj4jJ`^E71_7Emv32#D9<&ofa*Q8Y-a{!f z*%0ftaXt)mIBD5A#EhZ7ZLE7d^(pj{OztI<=4CLU4=x*HjEuVj#-&KX$x&2>*vXOF zJxROKU)z>UL{qjQ@icOi>_cS$Kl-pmWS{@nLz>~U>|~E_n4??1qH=$)Wb~Sjhh2~3 z%SnBCaxWu*cCI~2$6UDNo5}j2f(;_*5jgYI(w5g3r(eOZb?_Ryl7c1XfNcX2noZR<;^>zc|hN za4%X-9v(_x6G?AS!m)qJxeGe;q>wr0MoIEz=E6p@$NF@s%5>TZnPkNf&fEZ!)Gaqu zn_4pe;m8_T;pBj(L=O@t3XNeN*>gO3D5xNe-gOu~mM$PR(W;f^*>Z4L3%B3(}PFE1qmH5h`tEfQE)_5pC(+9Tq#mMiW#xxRDXTa{fwIa&H2$E& z;d->wDS&n^R%(AVg-(SG^Jq2|&~sdAh*k;{kPuhG}h zBhnnE5Gi=BEbpfYYtc+>E_;H;<7HBfKkVQF4|-$1+f^fUK1?gQ_6;0!Pj@F1L)FE9rkmx(O2H(i!v(x*1eLw1jSf zeSKJ4Mz_)(&};_uyp!(2thqFkzKOR0eG9AoSa~1!&uqLi}srif?~eurL@7JbNE4m_$dzfx_V8D-Y8tHF@E@ewypQhw{V9#0C9y>Xxt~UGui= z4)VUEZ-kY8Djqh=YMO-h0*Kv86KE@-u?;S~kmk^Knok$OP&?>!YJ)iLio8=u)}_&@%wEm}9~YD0nee-wPw<(Rs9#?xTPEDJV*3%z7<703#t{uk3Aq;F$|A2g!$FntGRT?wuS@D{*xC4HB^2RCIK_z`+E4Vb4fB2a5CgI#l* zE1#s(7(SXdNb_3@O8n1IX{)cIZgIUPS3ys z!nL9DMXD>S7@+DJf2E*)!JV`ifLOStV3Fd8Uf$B`N5|rp*4)aL)KFxb)0eq7+yvBh{q|2$S|VubO?Wc4#ckq_HS@vAb>s8yf4 z88sW|DJSR1o8Ujkc^h=%BwMMcp^U54n|MmB)eh2fVEJ?j?lbP7#dy>-S3bMU?^~8z zh-kQvw93NVMKytNpr2OUL25-f@Fbm?LtA#|0?8j#4EtubL-1y(bqjoRE0xe~2Wwx*724_wkl1!etb!P5UtjYT~_|jQ8B0 zL+JT|W7;3$?|FK`O{e@mxa6V#V<74*WmIu(BjP8p;%Fjiy1dHwV`aWo$N)YMOF_tEM>YHl5* zb*(ag{Q#XmKpP}ev|z!;8b!>vskJ8fA{B*|g3T_}!@-t*+Oh?CMH0dV&HHGo%XTYX z^WE1An*qDhZ06fXGnc`Fi|}#~x)&m%_al$U^Ks-67i}uNJb)Pw z(PBh>4d$;x%(o%Jdl2VWBfhUkOz%a+JcuaR4>}LS-jCw_aaj5gVq*|+JOUuT58(X{ zuoB;P1DrjG#uw=&Sp8~jKQGfO;JAlo(W`)B5Zo+!jb4YBYiK9^h~9vgAI97t(@)TM z$a#Cyf%eB4&wormbv!?r-ok(HU5V{Em%x5{!H&ap@nfX-Q(IGc zL3=+%avq>u{{i2DOz0IjJdOZA&(Tz%Z5mJ`8ccO5q8!PJGrLb!kN{}K%JGFZKW zV0aZKdkrb(Xb}__p_YJMF=o9-zl7N15gwAzeOPlE%>OG#J^n27{ z{|H*2psx87D1Cx_`cIBUH^3hAu-$%0zkzMHW1IagRtG@02Vj5x7`BD2G8Vmw{vo}E z+yt5ez#H-9&IC_ZG z`;Ptzu;@iRr$(1^|AO}4q4r-;)ch9;yT3x{|IR=HL^C25L&5!yh{aIxBWIVJCd3?T$BVHf-@Y3nmdL5HO)|=e@oj$frzrL zW_B46{|o&`I#{allv%lwqP$6~?gW=K7XK%79lJPiVvGL@1G$T9(&-@J6e8ZM-Ea?N zv-m|3`mIn|VE~BS|L+Gov#09rQ}1GMto&OyR+e{SQc zs1o@90keKcxgQGQdB!kI1ONc%3X?%-M1NNsRTTbCGGSnta*3oBp%swSgrvj^rL{@X zlu{cF7fl6eYwRQ$!q8+U&P*`;3Ey4IcVF9=QCv$`pZy*F4t1YNNE0T~lqFf5bM~Hn z`S#vt@0maU{_PI{@1r5%5qvk41eQg^+f1svu10C&M*;)W)GA@B~elIaw2D&nqDT+ zNss7V)mF5MT4I>)@ysfkTFc^4(a`s_a@{1z;mB#Q9niKE(;{3v5d$^%%rN(Ad6G6- zuFjHfA|q+B*h~S#9S<7UWT`_d*-S>=)+&j0rIw7IqN#EUR6eGR(YcoX|XtJn~j2+RtP;!+-e6c$N1R>jV}x z?0lpz!y}~CHB*-({}V({KQN^FvF*`od$`)4Bux%_ZMfr-@(_%4ws=;vc*~7+a~KA- z)|jNZ)}_!fK7(E^%~Z*_v}M@bLuY9{jO`bx~SPa<3x%M26tY14ML!Gihxej?=r&Vkt3LCT5BS3Pht9JB!4$b6DUI3j1Lcz;@g~!0-aTTf(Fe9C0wZ90&z|!g!p>v15$;vGX&g zi1LR54uX?HC?Gs>@J8#=KflJGkq5tv`U<5Kl#MWDVv(}&A>|=W_;v}|W5UHFSRq7< zh|w=j=)zdSHC3VojMIl;0`Ix;<=gS)>2vY}H|u$_wnXt=Z`XlymWgwN&H{06;v+YI zx5m=sD@iAwgC(-aZAuHV_zO%p2t7Nawo=RUOPjuy)f8^K`^vviO9KRx-^?1aZRP?B zwC&RY!vz2UHx85VZ!dp$6IB%cCJmW18QKzP({dLIqzP@*T0mMsD7R`aNNX!aglRIS zgVRiyOt^@O_vMn!^bmTcWDmL+sfUQ=(V*@~?j z*;&mVmC!z`7mBJ~u`~&L>vzYhQ$sBlva`0O7Yn1u=%J`qp|YYC?YY|}I&Jcu8aLE( znMbxXu8pOIXFPwem2;NvkdcrG!b^zh#av}cwKPZFFE> zLU`QFYa&&InXarXY1W+B6NJs2YRs#aF6QoH#B{F{())kCi#rS*P}{UfA#5+}%>JHd z6Ryvl$4f#_eQ>7UCD801Eh?8;_gRsLSV6OA)`YVuH4u=_zQ(l{VdKkc`Gl((2_vb1 zUi`A*yw`_NUf$O!4vLl{&sArcRgVk=1qSB+EN2- zz^&fa6mO}Q49#~$(Mh1zU7Sw%`d6Xr*;@OK1og7622P|Jq$kpGDD^+E99hqr6)UHm z(M9w01WpYJR0RidgQBlRIH#7E8AZWP?2>U)!7YF6Rj@}417hX2g7;M#FT=M za92WCV=-iWtl$%T%F@-KC-pMLlWZXe1^cjH!8v@UAcGW>da3rFT~=@gXB8Z%Zq(jR zZhVe$1z+Gx;ro?>uknq7Z$;?c&q`Ds@tLJ-TF!RFFuz9I*_bzVRy;g+@%(9)DEO{O zi0Xgt3&=dzmEQLm(fQPOUX_w)syYRbqnanB?o{xs5b|Kt=4jor zQQNF8vG)wESP&9s7A7QYPmTYVV}vx=F?H-n^fGRDxr(-25hl^1OfjH2*TrdKcFYVvzG8&VEN5!u-CLegY}| z6rqbx(Dn%7^v~Gv2$9-~oLNOw!qmZ4v`e^$Z8TyM{o~W=Ul1N#g~A^&_y76pA<^29 z<+uk?jys8;L??RDgKgx!3!~(8hSmg6JkJwpo)|@(zlQeHGsT@3F-(4Bg_ke_IM#no z93u0>v=x4)%msOa zUqM1nXGA6*c=w7q%L8;yJ5W8klXy@qLU<3u$2` z5}Ti3i(_^tdT3@IBUuZ#m01Q06J<#{S(08}buV)|M6R`D4ZGo^6y+(LCV`N6s$3%1 zITNDn+kOv8!uNiUSf*?DWArU#1_hCaUbr4s0fYz>BuKGWhCl8vd{-cqQw%xXqVS>xh4dzQstR`0txOm56=75T06Bag;kKU| zRC&QyoG!08)6H>M z4JwK8pNWs+Lm21m7AzLJg^>8?%$%7y-d{L99 zjjb(3Ur%egx}=yT)l8E0gr;lOB*SdKyZOHsws^h5E;+Em;GH(sRfaY$$n0#bspfNK ztw@rNw2@beD~hS{eOc(`?lN?yURkO+qnRZux3gA;Wbn`Hx@t}rl~PG1t5H`ULnq-- zf1JMjU&|9xQymFIi=pQ%#k8{9mS*T8rWx8D-nojD7Gb^YPj4u16uGGA1vzJ#nqEj& zO9tFMufirDJc?Q1iL1h+FK5{H*hynA>FyEufmalRz@ zGQ<$7=NyBSGj`0pI-~K530Bz*^7Q!8e}PMW1kf(xsUI_#6*1?>Jf1Q1xMhQ3+|`j6 z`lfE|>L-*y_h~9WuHia&Y>{f$^@4>{;De_rVs+M(Q!~^}m0RvshA&x$k#n_GJux{q zrgjxmJs#6(ilMXj36;Bh71b;P$B61o$>-HlDKr+RDjlw)F$SE@+_AKxyr^vRf2nay zKpk9AEr!0zA(36%Q1jN|*-DX!B^p)7LVI`8c)5Uftei9THt#}Rqpn`GU*{M+wJW@q zd3oynuhd1)f{Gsc%eT>cfCU14pb_VRz~>vy>rUFu(cVMUAC7#25ROFm;rT#&0bR7V zavhsR1Dk`7%_B&%AnC{+mvI%ae>s{=BxATiw>hZq(F8BiRQMx=&+taSph3W0eRF)A zO&f01*tTukwi?^Ey^YO{oiu1{qm6C5vF#>JPQIS^eDCSEf88^4Ju|cWn`dU{y5-4k zVInl`4C2fonpwiUCUv_BTBPpa39@BFE=vkHQ(md}+>?cZGK;pd#Br;m7qwgQpgPlY z+f#&XnUQmFxAm7tqmKShkl;EvXzeaY|Qx?l#wtn8k<;$+rrhD z&t_5rxv2rSfd$ez^a$NNKgB?AgS<`VE>%;MNChJENF40zPo*k|q@qU@f9N-9IipcJ zqd==wy5FFG+xL3CoURsufq>9J{m0vcC4?O4=)(X&@q-=_M>9h)NY`uTE#Ig*j{0zx z>Ua`GO%X>E`a(47<)A5Lt_wTJek^df?g}`}_MNf^y#0Cr7eA2yS8x-gzOR1s&cfxqTA+7+g*&vU13BE3-;dcI|j zofiY}%%f!^*IcLVah)sde-d(Fs zI4MU?ZP~e!>?2*^$K^p~lkUZft}d;-b$<(3(|K$=DF_OD@o@rTQ2rOZOn=dYWFir~?bWK|)EHyAQBp|h) z+Y=?2*fHSXqwDSvu60^3#lz?DjyWkz*VUZqq9xWX(s@*nSmpD~UT_YSHVNEVFLqKBjc>;WlR?{Jco9&_|L+`GW1^$ z*~3JSz+z|RWc=*vR1?y!Bti-rv0(w)lMpc|*+@9?)}JJ#F8GqN!rpLTGK{B6$$rR! z(6j67{?LO?p8b@Bp2W1{5@CS&vC}O)MI{GFFYLjuiDa%Msx@J1+a}%CU(Faq+{6pqc!b-s88RFtg2tks^pp@4j@Ua;P+E266YUnuntAGti={$qE;!c3 z67`a;5m~N@Wg~<0^kPm-LU8+1Is*rQCyl_U`UoxK)+6ttdvHYdRbP>(;$KeN=O-dU zA?pcrO6qcJN=Nyj&tDCl+BG+ieXMp`iNo%@qm;j=$!gGHRLw*%PR#7<9PJ8Dwbo@e z8^~>_=0)tZO$moqmao7c@>;iN-1s<_TE~k>GN+$~_h3RD<1Ck6Aa$vELlu_-8YCYp ztgjR()p}?+PH9Jyj(cu5w`H3u+*^kXP%iUYsQU=NLtX-Yyi+*rP#d5WK&hv18q;H= z@8?JcJc&1zeqVxO?+|enx|gMYgY&ENGJ$%_v%2UDpC`n!wF3pWLjm<5BucbTUWAT! zzCo}QUr4osC)(8;JKe(W1-V}ZFczuu_joYZqP*aAV`0m8LOgCG!J8Me94i&+-_{YK ztcL1E&9Nhsb>8@4^%YM$A7dyczmDv{L3lFXyfBJV)RFN}c1diz<9v$c!X|7S0MhDNYl#d4x^DrvuDXHNJIj)BME~b@Xy|pF~L*?Ad_piySIW> zNzc1VF*KJh<~#Kr-a&uto%BH67XfHWe;^5o#3(anUGrP}TBo$E4Vm(K@=d zvL}o;5~fb{NT_}`KuGK4ss^$Gu{8DQE)#m$hTc;aDoANjrqi00r&N# zx|&`J0t^Cm0*)}Z&%CTwEabBLXklh+1h8RE)o%T_fRR?FPSed6nxxBiaECl6rE*_< zdB~cgsoJ@N?j!DQCqJBF*BLneV=a46zd-@QR>I&JXZ-CZ`-_(#)Lak!DOQGfBzt2- zJ8M*r@tlJ4UrD~*S5b1*c<{f7J5}&riZ5t{4ofBo#$pm;pQYQxcrLVw^-HVo#z8IO zm9CM$CEnHGg9iPI)@QE2fRY51wfl%6==%B(E5Bl~_t_}vAR73o*VIa<^UP0zH**^J0V)q3&Wz)dRt8^bDh3sMbN${u zzO_sy0*@Ds&T__(huP=Ti96&lPW%5h{Sp_r{I=!~s8$x$4nk_4%Vj=h)LTl|Q8#jnXDP~7$fL3Qo( zK2<4ONvCKnlXOGPaIGWra(qG)s`+5$=$bf5W%7{w4f{#Y4}^7b(#H@RhXD>EQV}6y zUCpup@p8#`xS~>kH9ua;aG;vw5PAHtO`T1%mOBa9_%FF_PLCsRunv+p#0ODdtfk&u z4qWGqa=UFz?LCbEu)o)sqaM%qtq&jES`;8-hy>vHKV;H-7w371+YeM~E#;WmS_+F3hGk z>lb~mD4e{9U7V6L#@+_6xbQ=Y&L3+`HxF_WUN{{ToxO!MvR(?kr(pFnwzgrL)>)Z^ zX;+jgoH1Xg>lK#N8#oHIQf*-7TktG81swpibs;)L3Rd@3l1lM~L#rJ68{g7XZBk>? z3@Mb4bdXyQNDHgsov|c_BDBTv(dwLo$W@I#C@k4!vDs?49C_q#W9O&b0Uk|CGUU(6 z1Ltcgg2jT?wvoR)ChDynB}*}vF!-#KcIsu;DmL6jXLj#5+p@HCHmbDE5wL{XPC)^# zHH&T&4w&4A8Cm|BD#NjU4*8`}77G@jh7~Aejf|$L()E^EHV&%I6cMO)T!peG4JJ07 z4-p^gR-;XyjiV*~8cK0ja|fvUXw+sJJel+HN#wL&{pSJ$yQiNFU=!Dy1B&sUK|OC8k;!(d&VAyM`>&Qr~3^dK(x*)}|}U!t@U+A~-vh;peQMQ2l^E5h>_ z)*w_Biz1XY_aoSdH^upGyyn3no7)xp`)o5m2ArF^wp{|LOrYx_u2JioVV!7K$xP|M zyw;IOAG`#UQM+O<2~N1PxFiJN)Er+TJjQdHWLrOQpNHgfnm)RIbON8Z-V=~)R@^Xk znYb9?OcOWiMKnb2N4zVBpLUIcD9cT@Quqf~?&p%ijkRLW~2It4)$vg66>J7_WITtTIj9m5?(5IiVVSRkot} z7Q7sa_FSIsuxfkVlbs!391L;cXp974^#|!18WXF|fpEdRa;X=}NmZZfZbHh3&K-s{ z@HoCiPQjDX)h&}BC*#<_i=1FFM25`dIpEAIQB3HJxqHp@J5ABly2BcoJuH=hX%&fo zEjLf$V6@HGZE_!No)zE)z$F2ZQf9D^_9gR++c*5Rzf5iTv+_QM`jB^-(A!h3=&^Eu zy2P0@ulTw{(p9i-<-pB~DCkq{2AwW-GAj9-2VJ#Z5RDh9YPiv13MmX5Z#<7zRgTKj zB5KofKD;H2r0FVtm1 z5OeWnerj9dF|_fVOykYHEq0KuNjkO84Obr+SQjN2;lKFS=!#bLK$1r-tkCKM?QP5w z^m>K!)Gn#a9MbDFfn4Ntj{LfDe#;EY1<^Mo%fd?ppi9r0-gxf(TG zg)uH)2Y&!}M>`A*uo$mV`6(OcCFgK_`PR>Ju=^z&$JbDJb0bK1PEZyRK+Ydi2(IM? z>7waWa;ZChGKvI1D7$56#1pxGTf3S6t*ymf~2R*Dw}Bm*(tnPnkWMjs?ul#Gzs zri=oxf_mADzUJ=OU_^Hr>X`09X zpw2-f;P~1K$ec)>-op(fs^wPI=ZmS|eSh08ry(k4j=9#)-KmJE73MWd zk5oi-#&qp(N%j*`h6eQi-l4jScD)mR#|hryM~pOd)_4tb-SK=SeRI09p}c!g9ktKT zKQP6@G$C`K%CUs${6;l$vd_VVUP#5HMbPsd#0`3hvd1^@Q~IF~}pg{rEu+02N}S0QO3A z%IHJyo_HIJ7&z1s@$y0SP-gInB>9n(;n-A}M$A2$Sc~JC7nqK4Gf#tDzpVX8BIEk8 z0zib4uh*N$5mMn(DbIOY4qqotSO1W1%Dv@r5I4L@)Z{XmDklmAG~?wBg-HiH>G8Xm z!3Sqvsbo7^M%V${V@z#s3T=Q3=P5JhTv+4Ls0sZgHyq6JxJsT}L!`R6Fd6*pE@_vW^)p5o%W zE9Qf)ChCou!_-rqLPFxpF(0i3)l2$zA61%T$oE$BB+9Oz1QH_}Th{;qgT}URSW5yj z4s>k_Vbp2vDO+`E@WF9M!gd}aZh;R=zmv%p@tv`07g)BSHe4#ba%z z4mfvOCqTlu{1LiZltv6=hQoQ>=~(1*`a?wwJw5iDpO;mmSv|%rH17L;AkUsOTL};0 zfSbqQY4s9-r#Y?sV5J1?5HFeleEXSQGcno5^ST4!fn94o%>F^!5V49{7u$%(Z$CWk zK8I$E<@y-AeaGlP`0NFrVK6y74Mh*rBui$4OKu(U4Q6J9*;+|DdYUc85-MU3P6%a# zibM2(_?FuH!syF~PapZ@?249AoGW=x8hYxCJK-*g8&8PMvnU#%&XFM(vT5Ge9=~c} z#t9V5AJJZB*jw_N1|0qXK)l*7Y+M3!{(`bjMU(~uuiM&#TuPo(1U;h3j1qJi21ALF z{$WEI8sIR-vJyn8%VXihAfDncAg&Tu^WLJQd2t4ZdR7t72G$3X2B~078^TXMW;I<4 zUi+JDgngCP&T*O7{rk0Sd!Y6A!ph5xubF`|{Z`x**ev&GbjIi>SQ@?RvsA~CZaYMO zFW}%`$YmKog?L%Oio={TvH+L!Zojh(wY}D;>TELQMH1(?WJdbp!f&c-2|=VOEm{2# zSVNLah-0N!pE|EVP(O)N2!4qd9am70P9aWf?-d zU!xV=>1D&q0x;Xcv%F{Q?_)yd`#R-_lFXc@nm)JS5bpJDZ{LK{2G<{Rep^X~KWo(G z_{@L6kwr>o-ZFVkiF(%+MfNccrjU>#N-f(l5$$RENu|exPbf0|*RtdXMkKMe_Uj{ew^sIH#F=#K* z;u4_{?()ehOJ~47y1mVOWOwAQ;IKF-4t3Tl*TF<$pgfMFl8ru; z){*~Sq0Ss;s;1FaB-7YUS*v`*B%P1&aQk`s$DM&Dz-79cA^mG`@Fk=j~&5WWV_S@Ttb7!~V@Yqx`p;{|URRK}}X}nyyZMG@pA+1$Elp zGoY=0NFeK6unFjD-se0D(M96!<0;8ZtBEgNx^+@*UoR8=Tx`Z2)O{RAQ_`O+eacYktb!!6YGP(9n*E!kt|0E3KCEInLt7;7U-}(> z+7Pv8W||qfMl?JVZm4RupdU#(HGKvS@YF-na8VtO`>ymGt znkB})|IgiHeoz+B^Krke`nZ2^{b6LCW-tLM>VG!ifQ!W$6;AA$Q9lvqQP>z(VdN<2 zNvl+PBUZ7UA=XT9nWdy=vNw1DwBak5Bx;}Kd#uWL+$nv$Y&%u?=1tcr?@8Cm56br8 zv}Vc>1pQi61eXo=*T7e#2G#>~>2%HEW@1y7!K9#~WvV)QQ;8pW!&)hIlwy`g0PRE0 zM=tCgZ}&72TAmlmKH<={1CNF}%XY^YfoOIyj8Y4&j5<@nfAVHP+Z`W3$zTTXq9$cELrCt4dk zjTZg7K7UO$uVl*)ji;AW!LpC+%Cj8Shnkqy-FIKR$|`h70Z`1}wH5!SdGK*#;Ed2I z<5g&}=-w-QHYM0Tgm8z&fiJm2$79W9snlz@7GYSEva0M5xjHnnE2#}V1hD(2t@YI6 z;MALWS*$$Buk8v7vGSQJi4&`0OGR!Qs4YM+jw!!h9>1R&i5y}}wl~E=^7znyb9bLZ z3YvDuAFr@CRp#*jJ=y?45C8T2njzW+_GpLwP3^(2IIHXB$Fa?!nL)eo2V*t=&3t@L zw=&OR8l(%HqQ8H5#v#H37f|KamXIzeaYhEi0zcOvMZLlmlaLJyf<2%RVJpo5nSI2jG=*wB09jZ-#E5JpyopCp8d`g;^t-ruU+ak;E=iZY8;h->IaK1HRFD+J;u z7Aq-&#wY$p_z3r=h&*CkTlp9Wd1mZau0~t!`VD&ztgrDqXir$Ef#PUHKRz@+mhHsTl%YbN7hPUJMj3O#PO+sGtFqMN4E9G9q^$w0#k_Pj7VZx9#t4ZR$8%Nmh{)k z+v3#kvlK2CB%)jRq0fl{xJqEG2z)-rAq;5%?R|w4Ha%*92U=#_Yje#G3OM$rp0uT- zAO;WI{%tlhhVcQ;4OR~e{FTlGVxOP6aoo>^UWx@zjPk0N4v~p~{fL5i54Cg*WCBg& zqhS;2^dVkIW8_;G?Ey4`Xe|?LKEq!F)w_%5!b6|wPg^5lAT<`9!O>`QS(2F~a(bQ& z0rs{-)e`W4&s~<1j%~z)_Su$F?R^nYDo>k{%{Y?ndJfm%T`rq8D+W179(>b@Q5 zu3fDpQbLSk-_;8uXSqklqG;waliEmpT>H@NRg?4Gr};&D=?RFfCqI+`az_y%6vzIv z;l{APw83yv`>FR`?Xd@)2oiFw`iiJ zekWTt;)}k7UGK&Qvf=qsW&aXqD3K-f>2Meijx0rfY_!7grMX4^=OKo%d8I7qO5ZX~($(4H!2!AT=W zm!8^8^TpYl0(RrVUoSXJx3O3H9sKXL+mHOd^2CT4-@- zlrjbbsfHCzJvy?eY(!C{3{X;@ncN3&v7L@NbSS00O10eZ&qPbAD zajY;X#uT}M)2>U4S}VQ5*u;P-o`L?zJ}E9#0?s^aFYHFG zal{Bcssr9)VJi)u%zc04unO>10H+h(m(g4DG(fDigH(C-f_LIbI23;6d{_E;QxToI zM*BWKPJ)X*+6CH|ywhL*EEHN4XRl^T&A1k~ zPC~*G?q1B96kpRzp)|Pi&L@f^>U!7Ce4-o5sjW*~0UGI*m=xdlcOO8jUDe9>Qkk<* zwx(38LD;DOsr!&l(=F{eOCs#`dp-`Nr`jBviX4&uu2P6jqDxNR@6{uL3(Dep&sUA< zgsJ524m+i`PXx)Lu*c}Bbtc;|eRJLT6{N`=Ovwh{NZm<&!+!=4g;aB=^m5n3XH<0J zEWWu~1jsE~WA-h(Z zW8qO)jHryA3S)iSuD@s z3l(t4CFxmfW2?#~HEtH_@f%=Fphn?c>89tG0l;2Cgn6U#I2Z%Mkn(@nCqE;ndh=2? z&eE(>6gBC#5&+kG31+zybq66XP`mJNTBR~GR!Dc+7_T{2S)@x2Wetrc<~-v99}E@q zF3`uUe9N=Ua>y^6r+O#KMsO?ZN{$f<^fB1k1=vdAOHK{hl{ zDCGVAiP{AJ|H3v!YAd_|8FJ)^Ked#(s;ny;+08#&FlS1$vyiNzjuSq31ctfOv>Y_E z0n>BH0ZWpYe4H-JBVTQHVRCi8=~^MXF!>)3)j((X?1mV5^cF~Io&TEU>%@K(xEHwt ze@O1w7KWe_eO}Gwo_HFMhYmF@AXU0IL1}1sGLThr2Sbq{Bx-Iiz-=R=2n#$!1lu|f z*{w?u(YfyUaUequvC#;UuBh z6lqWPqiBfogjyJ=3`qPFF+pcQ#MHQXRFC8K13faOK5SiDv$vw z&@hB|pI%(!6ci#;d;hqWKK8 zo779bN>CYy?L_d1`txNuq#GZpdYJ<)OKmG_ytyP@1@_o#I2_oIMIS4p%QiBJo_B_k zM^9LgR3xCd)8d@9Ps!@1+81T*Dv98!?NAp2e24pcPtu2E-`M`xlN>&D`9gpGIaTOG;6_6N8GT)ppFvg;|^Og+&gM zlG*OXDnZ>BgO}V(_n8NV?t$VeeY+~9&C7K@whS3Y%7^%M*9)Gl#~jDs8<+A1Z$}wl zK`_UFZOg$e^Sk!bR{PPu{exxhr1;z;GYYH5CEx=2Bv`knK}+ zoS$Dp`1hSY{#PPF)p*m)gdLs4FMCJnjD!lEycUs6!~yr!Wm3W_dnZR&0>s`n1IqC< zHWWg{pUa}rAQI@b=T~Vuo`C4QdPNwKAz&BuA>W@=qtr8+(j#K_Ngr7wQI)GbdL@T`PvILOP5b z(4PN#efLbCIQ^i0os!xHabTB!b;UlyeNDHqxPZ=hAbX*ea_tk_Sqht2omXK~O^(kw z8(9u|?czz)U?t0G=9x5KzVUaQhWg13n&B~><&VI8T@>lv&U2|Hu?!u$xS4pKjyB8n z#n+vfB2Iul!dujaW+oKarNK&vQ{nTESE-7W4&w9IxO&@{&#WaD%3N7pMI-hI?o#98 zhB26&7MIm-27MMq9g8TnCSvT1`fCJie0>`BQrv1;jrL;HCOo6nS_&C+<4)Y|-+A1A zoXEG!<-c-l7)(WBd6uMoJBwIxJQZ_p5U`txd`kfoNK@D8{G_3?Ozt`@%t@WiqiVW4 zw{0=eMK8#A5^L;(cjPc7xzE+Rqx2C?=6^Sxch6QZ_wTZyRViqGZM54QG5w-@^lj3{aPlT!|c$sSzfzw=19}LiE z$8Y96i|8nBgwuMCc%vQ8kZ!K?M+&80Z{XTJR*n$}E{M=QPVL*;Tv{kLVf9@Xu{|en z*Gu~~Z3&2!`cz%199HGrB5kiY`%MX;H*>5yKM{vWN64hzZk3qdXlH^hiImsp&AG~D;6P#;@5A0ad`(Un5lcg<>b*sZyW#CW|Uv`$2jtFo?6cUF%8G#3sE zKJWqTk5=_d3AJZzH@mx)s6zzEZ0)TAy{!f`3qldx-iTxeb$ICO^d&D_(u zug-+E06^Ll`!o$|(c`l1*%aRaDz67nU_Hy*QC8h!^=yaTUAjo}G~!xC7}@sNT)vWU zji`tDVYcA7H25h3b>Z98W$^HRILp`%AMV4QHR>6uQjB;ufOS$>Xv5bUU6a2Q&Af!( zT-cvDcaV4v=g{y0mvL5X-6`1;_IYHsO&vMH)+szKGiH&aGk(Kna6FR&(7u*0{}9^F zL*V&_?my2cNvVOo>p2b zLlN~Djw&z!SAn&N-3ppFvxgVPPa1D?qo9uR0>MW~Q^$=9^N8gsP6oqk#?=^;3lUFkj4>0^B6^NtbKo> zkFg)d&!{wAhIWAJd&Ndco_QtMw9qt96UdG=%++$-YRF}#NS<~JeI@-T|%g4EPV;YC=hK7D3%b9%hRuF?K0E=iKnb&s6;Uk<`t$3lV*1Jr?!>nZrM{Tr^S@l@Chg^t9tDo4s`R)n3mEIBw)ohij$RrU@j-q zu;Hcz0ZZaQQtRc*0hf?xn7TuckON2 z-mhJZ5N+6Trg-|%lHjC$`P~qtfcEoRH-`xCHJkT%7x1db?4v#@9|&V4a7z^mT&MMA z|Hy{4-Ob&UxqYAza6*~UF%o@qqf}(;q1sVMCRV-n+i+c`D&~RzwDgL-df?3V>|4J3 z*|AP!jYd)5=uKkZ<{5L9Q{sAd5*LS9<}WTNmg2dna1#y7UnNDz`SExQ{#WWWUASt#KiPg!AVr8~XGr2WP)LQQXbU=gu5Q+wJX` zH4L#UjhG)xoDlDG!`|x$oxxLnsvvUP1FZ5B*FP1zaS)L%dN=TE4k%uT%ThYk@m;wO zG}H(KIU|0UT8ji^mCax>&ymQ&DmRF=hQAo@tOLfb4c@K~Cco0myJAg@f5pCpc3G3m zZ&BwD%{JbH2{VE>mc50(S)(mCgZ`{b8?N%>G>GenV355>#9Lwl_S4qDosXgWG*<); z)c#Cz+vciAS<9g+zm3?o&KURFNk z5gkB_Bf{G~AiO>TeIQB$&PJr$o2lMgiE>WcEYp!K$8OHYUq&?w;n%BmySI{24+(l= zd&qov0#}e~*lzM=La6wCfVs!CP)sP#-J?9kSRVh(BBGGOX!VkvEQ5@<`#tn1^|#Ji z6XcYrRu^P-8~!puWO(?(U&OG%fyr%ZpSS>J`)~)etb;5nV~wbBwF!Nhjl5G8Zzrgi_z0!UP)^vtLz|*R$d{KZjFFec zk`-DDQf2i6GduY9c^wvQtriO_pUA!ybxj+QFWr;x8pLCpMla%fpTjFQ);3m=ANV=I zi->?bOfdsY&Z0o>AYV6XhHQVCtkkrok(8dVR_TG5w(BT`&Z%xaB%ME^mB06~w9c?Q zHozM+ZM5Pkxige*-?LTY?aS$YO{<7tZ!8ZFy;90cFm;hZzq{o<2^2C*kdTgT?kSg9-O3b(*l+^znWquU|XP{+>#x$0Gj zNBlj{z`Gi72D!FET7!x!K?J1%YUCr2>n%|VhY4XchO!W+1@({^G-p1E^=(qXjt##8 z(;8{N+yqDUxmqhr2*pGS!-CXlXD+W{V$HB`I)(P$M})^3*@eY29_&GDo@I}m_~#d& z1?E&(opJ)^p2`#Q)OnhaGTi=S@S)90?1_=*JI_Nblhq-&v>>m<@x2GCh(Art;Yz=9wzc%FOS}L!JbJD>gyk)I`E*f#_ZNQM2NJ8$ zL#H0RafFjT?xn9sSS%#-;U>ZL+SZ4fBSyAdniEN@))IoDN=;JJdWWVy)Tyc0^j+4e zv7>N(%VrI0;dxr>tt&48`bpc{Z?PI8r^L zua_s}```$bN`Ds1)7N^rYIlpII`Bk$!hAMClUp>4l+-GG(Khz1lfE#`z&G#x9dmpy zS2CIJBIl)U zKw?+?^PI7gsvot|2?JEK*p6{30D9}IUu@}C+~qD$$zc|C&u!7zewpi4&_rEiJN(sD zybm|>{_aW`LO|wt)7Xx&s4186tHkRU+bo(HgO4m4v~ZIKgIjF-uKPTlK}7Y?K{x0D z;t2d&q>n$KSE)Jh5ND9tsuRze)v_yDloV9t?A5re1$eEv^oTRd^8k zz9TK*Gzqx)1E9&OzvkSkvV>FJuEn75 z`*bt$q0IDQ>5btCobQ9{FO8l79oc6JhH08ZcTzXVqqRFnC%61JO^6lH-0d%RNCICg z1$9>R+})Z=Cw2F7T(Ms&qB`YH{5k7?C3Q(VL3FIaGRb0oskw(9CuwZxQ<2zAT)o8a zc!!|h&!`r0BLc|I-o+HRP0Ib~c7|}bFTckZ{nj=LnJ536tDD1UUQ?CULK_O=s1_Sw zaI#DR?r03TNm=y0Z}O4rZo+Xzxig&cl`zfq68ANd&?hhD!E*84P)mTQsK6i6$Ij|e zWmBEA@z5zC6ycok*Rv|#YS&(l$zfC4go6z3YJ5q-Zz}-ms-v-=y22hh#FgXIer~4o7%%f7XOFYn9D+>_X3EdXCZBu-3-@3&f|;m_kEvw`5m*&*R5kZshlqGY-R#q z$htJAGlDNmx8#`UVev*=z*@qVwJ$T5uc{^91eWind3WEBnv5N23+&>nw7`d=y-}i^ zV_fxmSbF&C;&&;M>+*I%T^?LJ=PPzuc!U$oU;0l^HPZ0F_7PezWVt^@c?ATZk{mXWc$5|lSK*&3G~miOGEiL& z8UEkSB-Q>jdZ`ioY2?uU{~IZ_|1>&`K>-c5(SQtNv|wO*|5OQqA_1$%ltCSU?_>O+ zIY9n#ar}P+9DsoE{X52oL~R8W7{>t`SdjyrKIU*djte$n2dtaJ2jbde0l6n=!Au?g z6u(Rm;s5Kp{ES|Eu=--#N)-{1@n!i3x0-MaKUR2@m!01v)-nOxC}KBhCH; z*3LowGx@)W+rNO`xqpDQc|?DJ{}Q+VyHHvRK7guVDGflSE>a-XJTsVm$A`%HXW699 zM=RTa&PMoyvUF?Px2~O;$Eosx%y_>d4kF-sjwr-l9>5(S= z-rGZ~)kbv+=*>I+>;3=t|L;BV`EPydGXQppiv|+7VSiv4FV(R3Y1w>6HZRNO6}kEg zIzDUQ7x7CPe%XM5n+86IUor5j_`Ga>P15|jY<|PQ9e7p4Z)*5015NmC17ZA*f#1dN z$>rad%^&Faf`LE8AIavAW%ES?U&5al_*49uZ2r84s=ln_FAV%8{z}7Fbo{k}t@xWD z)Sr>4j(@Kj_*?v4E&d*_8Tbc$O~;I!`9~?~>vHDn8vaQd^Ut#R7uo!)Z2nC)|1O(v z$mTz!LI0`azYLtjf9v?Bj{ni{Ed%@Ul8$flE4bZ+5VBWAABk!MM@2vvK|_RurVCvY zHFC<(MXfGO4R6y#ogwN)gDx5=RjkoOSQAaUSbwXFW=*u{Vx56;v0fJuU2KqYH_{Su zi!L_lVzVx8)kRbnTXb=oF1AVm+cdFV6Sr$(hX4f3LC3MZ{*;wY+i8LDsOMf@=*{@E zw&N$KEZ_A6>PN>;92pyk#UAQEIzDn-Knx1h^}9~mw;X@MN@eV7=|_RuzVX9{2gV+X z4S${);M9&rfl$hwnXxHl3`TGnYl^ZJ7rC#)Lz^vD>Y$xNjc6>2K?D1 zUA<{FlWC&6s%78Jc3Euktv&&JS++N)(iS$HXjliv~IXRB)caM(^=A|ax z?!(EHtt4tzA|Xv7hL)2ODhWI7C!M_P`sKU~_`u~UdtNS*xv`*g(D7~0u~IZ91-IJds&+HJKugis6B&O#A4Lhbe=t(qPFhb8tF}25f^B++|XNI z3rt9*e&j6`6*;YpGsLfQJP)Ms?rKkx+GQXk9Q*G`~}M zUK9IFai7?4iUZ<)Qydh%n&>k{zc{3c0aF|nM@(^48uo5^z||&Y9e?mL^S+(X#4%GG z7efL~#ne4fgqlF4;DP8RD;+Ii?2>koP40cz6eHqRd7PxY{cWh*EbucG$&HdJdPK!Ln&64zB_}hI zrYky{vRNJ^TRO?)iDrrlV_n3YROfohNAvY)T{+_WGRc%m#!${Y=^bM8qj=5~lX90+ zB4G+!OtYRy-Y%+5b@i!=q=^|*%nDXYW2w}zh?ixxDb9-vd4J@TvTrML)aOdgDK}?R zUR7zq(L~A=bAmevj-NW*Nr1Uxei>bXwW&fC5{Sy#%Uze}QeBftC((7t@-2U1-ew7A z0MtpdW}X84oN0YL61@f1%OzoBJdl!ec8Sb$1-MCvSBOnIdMWA8t`hrXI_kK7G@Y5B zcWFZ+%DDv=jDP5{iD3oVM_9UYN#2!Da+yXvZkA7u<_n#Soo9-)OgL4!x-RDHn3*5t z>r+E+IJY#Tx#_N4*)-T&Hf^a&wsCv9dwV+Cx;?#5{o7g6HH9xSBw3{vBmbN^!8j`xXmTEg{K5NICw3I)6M?RiF;wmZFZbtGAK1{X_P& zl}Yj3*jRE7Eu&L1%+mVE{F7E#9%*vp#=@bqbjJ$KT}ULow7S`yA-;W=SA!DDrEAri z)|Gd=NNeS5(2^~Aer6e+;q;f>F*cN`SawHhsk}l&(ivm+BN<*Cm;Ae9PpsFTOHGJ73ogJb$vvOQ~Nx*yKLdp(s7Qv;6+MFP9!A zcYk4-;48?A*W~7k3-r4TY+lXw|HIgVVi~K#)&F1xp0g`>N~NrLOsxM-YxHl@x#(UX zB<`)?-?J55Ug`NE9oe_w%ior?RNA3@XSS`59p<}xNhObZcDMGg7DI{3rMF0E+V$ov zzibN?JXK)}c`9r{0>con5yA$X#|8FN0Dr15$FWl~b`h3O1op%7m7u!%lzXoY9 z;WFC=j>Zv0fZv+7cG1zf2=Rgv^Qa=MVjG1{_20u@TaFOli|bA~n2((24*AQ&$xP}lHv?aZpp|RacZQCesJAdkN zJJw{Pbw&PgoVvbku>X0^>K)$^1svL~$yaF#Enyj6#lmB8AtejPP8QGWwQ zTr8sYI?N?o>J@(neb9*}bSvFvjxVoU;BmZ()H!EXEBc0xEb6kTKi$^ev51Cpad%SO zUF`2x;-Wd0;#L~)1m3JvG~fz;fPb7n$bNt`W9&a!P*!!ESZJjFI^N`Zg6-GQn8li& z&<%v+H_#NP;30@dNxEOwq&llI`$aesjLx}Whq$e{FMANu&WAA=acC=n9F5lrAHlW&lTc8th6 zP6Q1zAR~ARC-5|>K8}<4X@=(KN&Q(;zlu1%fHU|K&f?2Bhp*s4S`o)LIQLDQ6?_Yb zARZJZEEWDYqmH(`g16v@7|=WMVZ4=C)u{0bei&~fR32u6znv*wLw{|LQSSw2W{kY= zz&lY(jhDH%cTx(WPyi8oc@VLe15uTz#k=tyf^9p#iudAugj7)Ict1Wse=I>vm+$*L zo{v+f1mcz(xFg<{#V*0-PX64*pWXbqn?HLNvG;1x%^}5bz9dn$;6pS8MHL?=B_I2F z70=}B&w;k~Mcgye`F}YCUI^dYPF-2_JPlKYdmqEy5x(yR_Qw}-Abfuo2isVydil+w zk2o$b9uDnr>85!)$iq51G|J%ZXJJ?>WCw~Fcc7SY2k8kY731J)WwLi^F-R?MA;L>mvqqsjQo01e2n<6CiPbQ zD0>0UtjCYxd4C4&Jl&d`dxC-far^{(G3M1zvL_4LQ$_barCiBln0kMTxk4<;--6`p z@LM>N;n)>^1MBc`IL>yY<0fupR&UHloauhBu_uc&owru5S#vEEfQW|u-EPi3^@=hUHPG9j+2SXas4KY!)T`XXgYB%KRCK!b+D=ag{| zO5?&0vF!)*R_qlM(-f+De!idrfU6 zf-qqj!_s2g0IEr8CcpRk;d=eMbFsI)CDLPQ#3jBuZ-Yyjs1`ju+MZ zC3W(W8ZN5gWi?nDX4_F#%ZiR(NS&rGX_#xrypA18d0hxNb(kEr zT{}1~kVqE_nQ4J|-m6ftr)azKY@<3W{gO57NafEfTh6rQ+iKrBj0f{Jtz?UyKbM{J zt%@VFSADBilYaK(wX)Nw+gIec?Z~lmS=Q?lmVax_NuNNIR(K#VmX6}Ey{wWOiFS>^ zcCuy9EjN5$xeVrwewZJB4NR=sj&b5MuPyLC} zQf_0SkAJLEMNTptne90ll*q&h+i?_M+R_oRxXUtIKB_whSDmtN($I@FFTY zd6^_SPhs1!3fKyM`sgSx%L_cRi4lf7<$pE&a;xC`9!}3;rEFjr*9{!PVFN=rEMTmT z-N4uJiom1mpWumx?Np?1;2Zd+fmiV@5^2~eFBtf?IvBlG;5a1vRPSXn0d+bO~pI&5^)F#Cg82VW4gpX`J zS3`9GZuy1o6f9%=o&@NT7OkuZck@6>#0fQ->nc;dgJv*jTQw|X9&FLNZ`Px zPiKuG#qsI_>l(d}=fk#U*8^@l?fR;Y(nG*wvvtpD1ai^}=J_Nx14er~CG*SeWMDbE zEgH(6Ed`jXz+Wte?RD=%t+g8Ls*;rE$r|P_QFo-Q@kOLhD|EZlg{`u;XMfA?LMv>2 z&ibOQd=hp(92~>&r6aAnT!V6Iu^z}OtL9p+r>M^cwV{hJh_KCIfM4^+`K@k43Tb2@ zFvwjDI{H-4;JQz>4bE}i4I|6(2zN7-X;a_$!P^jnyFNf{aQ6pjdp}e@8mh%P4shI$ z4je!?4&n)(n2{Qu#HXSk34fs*5w4V@7}uZ1XDCHCu?iCC0>o2Gh|e5qBC&+z%x!2~ zwl~qyr*mkc^EQmLL%hw!Q}HIcZsMq#yWd5pntN_yUvhE}IL@pt6 zNrtk0@DGUHu#RaW*OBV@E5_7WzxL)W99zPUnW4V^+jumWNF|zhEPt0wC7Vcvg7^QC zO5VZFRDuIdwB5LaUGLrhvobNX+VyVwR4$s>)3=xFLu+6hzKeYVIX%S#Gc-t4p-lpO z;2@>{KG(UqOy|9vu}aXm$Nc{bABrC4ut#iDGb$n`GU5J^nwe=;uh&>BkP7=r14V?V zS(les5sO8yP@=}_)qh#DS6Q7mSf96W47c!E{2Dp@1|#?_M$x3!62|E9BtFC`{2K-Q zhwb~nID`8riWtrb4U3cHy+x%jSN7cNyLt!DPsh7s;3!?$X0k(CD>EKRKR} z2g|(SYJ?s|xcVH9lQ;Wm^Yc7wLt69_$*B5Wi+>W&39_hyzkef-XZU;dB-M=-&2eg; zYSH@>_(I6v0{{8ZX;J-&@D6CdgMsbXU;W(*$CKgtg%Gn5$+Yn4>J!w`e}Qu>d@6rI z*Wg_o6nGEu;`=;~Q?QF}BXj*ogfA;j6`jfNVj{Zna%jGvGTofd;#}*oOyXIU2b>S# zO#L5FO9KQH0JDxCuL2FXiD2uZ3IG5q7ytk&lW_(XlVBnwe>{*4MuZ^<;00C~Nr+8I z9ovAx1H6bK2|47$7LjyDIx(8nk#r<&+R~Y{O?T6DlC+iGI0@-Yo9=Y)z0$q+_`kce zEK7&+uRq}F-uJ%!eee6e$CLkg_%Q&R#1<7haJP!hc!^wIDwmfjIHRISf{XBS1+Vbq zm43WR?q03pe>J$rk9+-it%BF7sE}9{c)dKlPsJPXMg?zDQSE@=tYRnLB6+@5E^m{| z+g03;cPMy3!8`qUmju0A#R|Mf!FyG##`{z($5{mrs#q(z+>eJ8yx)%xsHnvURb((B zzb57KA-O#4$CMwBsPN-axqnQ-ITerN!zw<4kE-|>e?G3_6L>kX&G1?+f)@CMBmY%SN^jO*u2o;dGcMP<4c6GF8`Bb?m z`v*Ha2C~rQv!De;#oMEasI^02VO{-@fUnIQp|pywXu{}8$B!7v0sTnKkV={nJvO8# zqjK*8eb!hsC9uBBOpb;}lln-^2%k*qT=$rCk4tKjHnsj8I2h{Egw&sJhY-lN&cYCk2Se^ zMq<%$n;DPmi4ke+J{yOON+M?B1Q|(!OY;f(Pp2#+zAq~(he6vk8F?t?xD{pmJVe@Z ze@1fXh+dh>V@nq~_NA?8EIb33b~?NUsqAhuPCJWZ=IE$Y_9Cw+blHcbt8gJ5r;JG2 zGKs&|3;)1uEa~=+QxRj@oGN`}B;N-DtLkP)WA;u4R&~TU8n4Vlug{O=B3GMS8I^Sf zXo9>}IKYHqg$MgO`%fn<{Zv+A;`n1se_Q#TO&J$ey3!RhWF%8IM)kCeysLP^L2&K^ zRY@8tGo6eWttsLddR$;}R=3W?c-nHnB-M_jqp^`bBVt6ytt^_&K3B`lbr(*P0`sq$ z7tvffq4wKmIQL~q!G&#-0ySKV>oknwRt>k{W(~)1Gpo^sE|P{{;Ay%l-<^yafB#iF zq#M)3+&IRh(C|zAO2Mx+{06@z&T)aF*HlI=o8_%u-@iZ!7yqQXzrLPOcRw%_R}4D3x>? z%f)ovEXX0Viym9isA1)H#ii37t8h?I z+&MUlJZ94@SkE%kYOIYgzcR$27|b@{k7cFl!H2`bCGcp$&CJJo7y!ALN#*<`k5 zdHt=>>)u1>qI}tee_cN(W3Q$#UHCmuXVrLHfMVEI(DXxI`Qa(T={ufhUVXuqbFt@W zmhXZF50?3Tb~jTcCdZ#D=HP{Az`_i&b5~FD-Z?QZ$?j#dG^`$74u@LO7?0_4C`qPx zu&r)hVe}f?YUf8v^DAbcZL)DVHqttat$-Dv-E`h9Yo>2oe~Ph7My=D~d>o2hIX8ym z2l>i!hA%$Q3b@XklHbzvow1gYQ&)Dr%}&TpbM0!Go(bGNOOj=>=@wwhS$Ju#vj)bJ z=1KX&v%Qncq|*soe`L(C-yX*Cv>v0s7Uz;XEwrWnAQ5=w<2vJbg-0+BdC+(Tavc{ZnfAtj%<@H{4=NZ&}&d|2B&huPKE1fC5r}^YPKkwPfS9$PbBqA|WHiw3} zb98nf^1E9>6=!hR-KIO8r`s5l?VhS%h zMGX@W585b)xfa{NmAHYc<{&`F5&o7Sf)QeoSe&7_Qo473?=nFNFXcl*Jh=$)G04lcml6pnu~ef^xI0xn#p6E^1bTYQq$k4+l%8u!3t~ z3AT)*5!$JQ9)=c2yDXb-@bs4Omv3m~!T-VXf>uG5%-BphoG++f9u@xJz8%@|x zr(J_h^vxC+gr34>xDDHI2b%FBY{wZ~iF0VRe|5t$duN$?XjFI)Rgn z$0=KmKsUendUL}ZA+H7et)(ZYP&?cZsGC6jB1OIId zGzG#LTrz=8`RuxL*wtj&@s;kfyN|Audhe;i<_xxEur-5AGq`N;{V402!nWbY30!fG zGMWP|8En57OC>OHrSDPf7+%=WKZ&a*fAEZRt}?9?xcaOutCGIC+|^_yWdQwz4G}tk zY78=U4ls$X;q5(`^iRT8Sj68U>KbUvpnY${6DYIw z>2Q?T$<*D|)ksZtHwHR0*wejX8e^}-*wDkHu8n7#wTy=#xI5ME^|Wo$RzIA&q5BD*u@bSZQAy$=$+TF86IN_wp$WkZBnuOkglSk8aB0 zQtomQylN8b#s34d9W4w94F+u=njI4W0PHCM03efb1{RY{H4%SQ<+VR2GnqS?Tp$EO z7}gPqWDh$U5DiI?*btDg7!dI$bCX<|CEmG166;nUR$A>w-EGAkYH1af1dWPq-L ztF5)Qw$}Ew_PxHP@4ddIy#Kj(W->`G0w%wF_ug+g>;IhZd|zJq`;*TQ(E|Q3K>h5K zMv=xZO`bG?JT!m#(x~z|E$Wu;{#mEWdW+=a`~)~ zrc#=!e6Hpih3ETufx-)A#-aetp~7u4X={Mi@wNc9@I?x54^XS{ZQ+akyhA=Nk)}#v zEkJGDu5f=xfVOeFpTmCE{oEve%>k1hzJu^I2NEzSQ1SIGBYuT~BZsUI%ro!e+wOv|GM2mIRv|6SS>srn< zu09@1SX#{5tVNR0B#)9g$?h*rl&FB6?j%hn`5R)nb}0 zTaAAkg~sD906E_ZBW74DnJzB<1ie04lM{*hucgW`dB zhZfnanTC9)I=xo60ng2FY;m4&Xs6MYG&ReJ$Cj5l zPB-E;ViR#iNA@^V*-4XvMq#iwjrOE`Z!&))OyeE$G2N=!w4n)8in6D)c54flENx9j znI=X=^@glLg|9((^XP7-#V54#+%c=bSrN_+hM5s+SZCE{zSZcFZ`cwz(R*ZBLgCNB zEg0-bMqu77f#;Ntq*CSWv4j3D8r*E)|0eASJ$E#WthR&p6u)tsOM~3g=lNehepj^F_PO#S-XGBkv$cC_1${M&V=}8N$FT=PpAz7Q;9lWfDN?{ zE2%|nPv<4#NwY(@@tm*s_2?az9=1pP5eHIGE#wY|Y*oFQY0gEEY#VJiZ$yt_Ajd$H z*J^adG%IQ9V_h(sri)3YCUmQ@51_KditBYVY9tZ@WQ5XaYMX^+B7+h1JJ^5F!y9xh z?Bv9R6^k$5}>QZ^k9Nu1XpahZ6QQnlyHTjOZh9 zzAh7d%QGObS2V@I(oFWi_}NneP9j(nkAluP=c7IzjcPGOnTi#0b8W_}Mq-N*!@dNq zJ*8z^piBRbwGR4HrK!p3!&U(>~aH& z&vuQaY)9nkG0W`F_`}G}pa@+YAI}rE;(aYk6!mc_M#exqxO{bng85 z^O>4mx2*L3cFL(Jr*FPA3#3^%%xZzKa^D@(tX%iIOi`02v``4GICVnVMNgX6q7&0P zVQxv&S}e4xPKDOi;l)d2@dYQb_*C<1PT!(oE=z^W@>6zqcC@5PEjwjxWpS&W&K<<7 zsd?2hO{M4Pd6nL$U#ovKK!Ym%jDD`tQ}nb-*U~?zbPat@rHAPemG8Li`EI^PntN5gPc*n+;l7!HzZ@05!ExA54G!hEM#fX9@(%%y@u6YT@tekax)sT zx-|=p9-8M`ZqEz#m~kw$`a`gEzwmO9R+U0pb!r@HhopaK4H*d-#}pmmn6NAfX(mKV zWiw#JW|vwX>NMlgkQTDcWJ2ua6j0ToSSY*F456l~4V5HHV(GLPl5$XnobHUpJ5se> zt?ej~3DwyJ+L!^A9~Lw|qVgerRN==|eq0=XmxNSpHTTp zc^iVy=%;^z2eody$`s9L*sk}a(jD+n_PnU#)rceJNcsh(WutEdrjDAFb;h1t>UydUok%mL z9j9^w@~N&93P*`;pBysk4OgN8%*)&??EZh$WzR^fowRc9^_Wjfon`7=4<P;4Lka8EdTIUG`I-Bb%H!+mHr;Q<({hX-S>8h_BheV`v2Z^0b=qm!KE#ZnzHO{~T=gk( zlT7X<6UOB*p$9G-V~mWuefnic!HH2+((L3&?VO~Y=&x%}#3M;dmv|bvN%o^MfFC{B zBC^l_>mkkXS$2|3H_Xu^UlF-i())i5+ry5>@nxsJJh_(a|!rhEgu#C^eQn%btZEDT@ha+oXxt#-=yRn4he%C9aU}?4qMqbGjxeg$ty0ygGxT!Zr^e8ej0Fxin`>fRG z=nXRyvkJ`UTyy!NJDsc8;IMxi$K2G^WZPiGE!6SwGTDumRKStA7&W&SnO&#TsGrJ+ zD3^kC1zkx@SK%v%uBJjcTjRY@4%+q;M`Zhn^D>^3Fn14q0qqy@bqy$Z@tj*eNO|Q$ z6lg2VpGYqal6siNl~)`lrM&Vm`O2#f)A&O+ha1pNBOls1SQ(}gY&AR4>zGNfRXD8ryil;+98_ORxwD^TRcm>6AS1me{F7&H)kKss0!u| z(2S+tBJW+t{!$st^%OzLnfs4@SUEtmYN6%qwm}NjDxRhOB7c9-_sqRCe-3NTM$M4;AE4!h>IR6RjwFnlz1h~~8wmU^G2vNlg;>k$IF zD~@8c5~*ZgYPf3ju;&S?&Y={5JXruT(Iz0X1<>vSe0qPW9yS;TdP_#r78@9Bza4@_ za3N-YP-;{5xn70I^_8 z;X=h0y`r_vi;hLDZMjvgZN8vaRH@B{(aFua=b5s#A*kwHY` znGpV5h~Iwz?B8g|fDe5tV)04{l8;Du!d?Y|GHN!`lXlLLH^G07{WfIBNw!i?K^aG> zH}I5Ls~e(a!19?A+-KcRi}0vzsd{Fq*RwRY2+?pag{q2j7uNcMz5!Z(JE@gH-xIVV zhqmm_1(M&d9QMsDo8V1Q>t^`o7AmD%5!Sas;9Gy_9Eg<;@KT`temh7fQw2RkN3nh? zaQ>`~y6N!g_wbf0!etb!OZm|cYT~_|jQ5TzjNvHfCxa6V#BOvN* zRNPikxN?xrS<5X$bZ(pPX{u}U6t05n3hUuG_^+XLkQ$x*wi@{jt~>7zIvoj4 z8KQqRFjiCH`2+MBaWozS)I30I_tWYjYH1syb!{?#{UBX1NE;+mv|_==T1Cvasjb%k z0u=|9!p#oUgZ|b5+Oh?CMH0e=E&FMT!*(lP^PSg=S^&GUZ06fXGnc`_i}7*@x)&j$ z4^TUj~Rat(jr8CE#|L6%(o-LdlBc?Aii%vOz%U) zJb)-T06GuB-jCq@FnwuXOi z&|5aNbL28BwQ+96m%x5n;f^D8$)ltVP%F%>PSU>Z*`+3&g>WOYk=HY7b8 zc)65ejGYeLBezqrXi_O3QRp&2F`)F#A&LXyJ#8b#2I;avGEo2oz0#Ek`UZc=61XS# z(>MqC$)Iv{|FN5d=`QK?+iyYt(L>N^J2o)WPU@EZ3?Ls$U35KaqU%R(k?&yiT`GXy zL1;b~I#xowhqptZgD1D54`cIi8G#A_L2lN}* zc00D&-(t0-_`MlB?ggx!jbnc=s0!=~keh!GsvgL&2ORzg+0(hT4dZ_T2Pe1QfIfjp z$wV(|ik6Bh)Dmq=y?4_1$|}2(=-q$p&j3RoqBuFai2E0`{|;sUic;pkP|p1gqW*UV z2q2mfu>@)zuth9^VjtRj+iZKs_5dcu^v`xa&4^gwr@w%@BVr@wc<_Hz$}6y;`G-pp zpG|PO%`oIlp?^&=ROsJQHc=p=Y^IsL1;qbK|B(uj8a!oIt|TUR(yBATA&tfV30=o7 z_MP0~zrjGx;@VUa@Y&^u`)Vi1eHpEMj#i-aKlHzDbi4;ok&(@x#oh zhdqZ}DLF-pKSRk6O3puS?uVV7-P}*dM(*YXe%Og!-I?Rg=9ArdXO=sG70zLgn=#m( z_Hm3sIV`H>a4vn;&bv8CbI#ALJO#A@|39;RNVy*hcqZahU<3dF8Vi#^XheT^8dVhj z4h&2(ndX9_H72b|3>5+mt+r_`G)mLdV97kDmM zOIM%$9sUk=pMfA`u%%hT;#~IGXYX%+`<#9FRkjTg#VJe9X>Qz_V+rcqT*TT`uNqf$}yA~(Bi=m#WJ%>;kLSV=urI^3w* znxQj{ha;JNk-WjT-nz1Z|6Jfb|T^yQOfF(5mr6P4;*w>2%L0IT-FG z7iQ@H#X0bg2*z(cweQd@PCeaC_~xI3{Xzo|CaLv1!XT!=@2#VN^SA&A0xu0tKhx@G zc~3g;VXkGgO4?rPFGhX8!L#F?Z@`<~5vUWg4fxh#4fxk$G!+{d*#6gR00Om>1aykN z=Mf^09KnBd(^?aOGYZjk&_fwyXa=#4>HXt2gh++NG5oCs+ zutI|~3@_oiDNG1~;RZ$)eL>&P7>m(#^ax{KY(K>$&AdTh1Az%4=o20{@K$T-?-#LW z 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ðLt@<6$HVt0f;!20Sp<3m>$F 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 Tivz*Z2ZEoYg9+>VN2C7-xCsBy diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 6492533..bf3de21 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Wed Aug 23 01:05:25 MSK 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-bin.zip diff --git a/gradlew b/gradlew index 4453cce..cccdd3d 100755 --- a/gradlew +++ b/gradlew @@ -33,11 +33,11 @@ DEFAULT_JVM_OPTS="" # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -155,7 +155,7 @@ if $cygwin ; then fi # Escape application args -save ( ) { +save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } diff --git a/src/main/java/com/github/akurilov/concurrent/AsyncRunnableBase.java b/src/main/java/com/github/akurilov/concurrent/AsyncRunnableBase.java index f1f0040..2e70951 100644 --- a/src/main/java/com/github/akurilov/concurrent/AsyncRunnableBase.java +++ b/src/main/java/com/github/akurilov/concurrent/AsyncRunnableBase.java @@ -114,8 +114,8 @@ public final AsyncRunnableBase await() @Override public boolean await(final long timeout, final TimeUnit timeUnit) throws IllegalStateException, InterruptedException { - long t, timeOutMilliSec = timeUnit.toMillis(timeout); - t = System.currentTimeMillis(); + final var timeOutMilliSec = timeUnit.toMillis(timeout); + final var t = System.currentTimeMillis(); while(isStarted() || isShutdown()) { if(System.currentTimeMillis() - t >= timeOutMilliSec) { return false; diff --git a/src/main/java/com/github/akurilov/concurrent/ContextAwareThreadFactory.java b/src/main/java/com/github/akurilov/concurrent/ContextAwareThreadFactory.java index 8406f07..a2b52b1 100644 --- a/src/main/java/com/github/akurilov/concurrent/ContextAwareThreadFactory.java +++ b/src/main/java/com/github/akurilov/concurrent/ContextAwareThreadFactory.java @@ -22,14 +22,17 @@ public class ContextAwareThreadFactory protected final boolean daemonFlag; protected final Map threadContext; - public ContextAwareThreadFactory(final String threadNamePrefix, final Map threadContext) { + public ContextAwareThreadFactory( + final String threadNamePrefix, final Map threadContext + ) { this.threadNamePrefix = threadNamePrefix; this.daemonFlag = false; this.threadContext = threadContext; } public ContextAwareThreadFactory( - final String threadNamePrefix, final boolean daemonFlag, final Map threadContext + final String threadNamePrefix, final boolean daemonFlag, + final Map threadContext ) { this.threadNamePrefix = threadNamePrefix; this.daemonFlag = daemonFlag; @@ -55,7 +58,8 @@ protected ContextAwareThread( @Override public Thread newThread(final Runnable task) { return new ContextAwareThread( - task, threadNamePrefix + "#" + threadNumber.incrementAndGet(), daemonFlag, exceptionHandler, threadContext + task, threadNamePrefix + "#" + threadNumber.incrementAndGet(), daemonFlag, + exceptionHandler, threadContext ); } diff --git a/src/main/java/com/github/akurilov/concurrent/RateThrottle.java b/src/main/java/com/github/akurilov/concurrent/RateThrottle.java index 7f12f25..15e907c 100644 --- a/src/main/java/com/github/akurilov/concurrent/RateThrottle.java +++ b/src/main/java/com/github/akurilov/concurrent/RateThrottle.java @@ -30,7 +30,7 @@ public RateThrottle(final double rateLimit) { public final boolean tryAcquire(final X item) { synchronized(this) { if(startTime > 0) { - final long periodCount = (nanoTime() - startTime) / periodNanos; + final var periodCount = (nanoTime() - startTime) / periodNanos; if(periodCount > acquiredCount) { acquiredCount ++; return true; @@ -49,7 +49,7 @@ public final boolean tryAcquire(final X item) { public final int tryAcquire(final X item, final int requiredCount) { synchronized(this) { if(startTime > 0) { - final int availableCount = (int) ( + final var availableCount = (int) ( (nanoTime() - startTime) / periodNanos - acquiredCount ); if(availableCount > requiredCount) { diff --git a/src/main/java/com/github/akurilov/concurrent/WeightThrottle.java b/src/main/java/com/github/akurilov/concurrent/WeightThrottle.java index ee1a038..172e40a 100644 --- a/src/main/java/com/github/akurilov/concurrent/WeightThrottle.java +++ b/src/main/java/com/github/akurilov/concurrent/WeightThrottle.java @@ -28,13 +28,13 @@ public WeightThrottle(final Int2IntMap weightMap) private void resetRemainingWeights() throws IllegalArgumentException { - for(final int key : weightKeys) { + for(final var key : weightKeys) { remainingWeightMap.put(key, weightMap.get(key)); } } private void ensureRemainingWeights() { - for(final int key : weightKeys) { + for(final var key : weightKeys) { if(remainingWeightMap.get(key) > 0) { return; } @@ -45,7 +45,7 @@ private void ensureRemainingWeights() { public final boolean tryAcquire(final int key) { synchronized(remainingWeightMap) { ensureRemainingWeights(); - final int remainingWeight = remainingWeightMap.get(key); + final var remainingWeight = remainingWeightMap.get(key); if(remainingWeight > 0) { remainingWeightMap.put(key, remainingWeight - 1); return true; @@ -61,7 +61,7 @@ public final int tryAcquire(final int key, final int times) { } synchronized(remainingWeightMap) { ensureRemainingWeights(); - final int remainingWeight = remainingWeightMap.get(key); + final var remainingWeight = remainingWeightMap.get(key); if(times > remainingWeight) { remainingWeightMap.put(key, 0); return remainingWeight; diff --git a/src/main/java/com/github/akurilov/concurrent/coroutines/CoroutineBase.java b/src/main/java/com/github/akurilov/concurrent/coroutines/CoroutineBase.java index 3b38409..f44f290 100644 --- a/src/main/java/com/github/akurilov/concurrent/coroutines/CoroutineBase.java +++ b/src/main/java/com/github/akurilov/concurrent/coroutines/CoroutineBase.java @@ -29,7 +29,7 @@ protected void doStart() { */ @Override public final void invoke() { - long t = System.nanoTime(); + var t = System.nanoTime(); invokeTimed(t); } diff --git a/src/main/java/com/github/akurilov/concurrent/coroutines/CoroutinesExecutor.java b/src/main/java/com/github/akurilov/concurrent/coroutines/CoroutinesExecutor.java index 089e7e2..251f847 100644 --- a/src/main/java/com/github/akurilov/concurrent/coroutines/CoroutinesExecutor.java +++ b/src/main/java/com/github/akurilov/concurrent/coroutines/CoroutinesExecutor.java @@ -31,16 +31,14 @@ public CoroutinesExecutor() { } public CoroutinesExecutor(final boolean backgroundFlag) { - final int svcThreadCount = Runtime.getRuntime().availableProcessors(); + final var svcThreadCount = Runtime.getRuntime().availableProcessors(); executor = new ThreadPoolExecutor( svcThreadCount, svcThreadCount, 0, TimeUnit.DAYS, new ArrayBlockingQueue<>(1), new ContextAwareThreadFactory("coroutine-processor-", true, null) ); this.backgroundFlag = backgroundFlag; - for(int i = 0; i < svcThreadCount; i ++) { - final CoroutinesExecutorTask svcWorkerTask = new CoroutinesExecutorTask( - coroutines, backgroundFlag - ); + for(var i = 0; i < svcThreadCount; i ++) { + final var svcWorkerTask = new CoroutinesExecutorTask(coroutines, backgroundFlag); executor.submit(svcWorkerTask); workers.add(svcWorkerTask); svcWorkerTask.start(); @@ -56,24 +54,22 @@ public void stop(final Coroutine coroutine) { } public void setThreadCount(final int threadCount) { - final int newThreadCount = threadCount > 0 ? + final var newThreadCount = threadCount > 0 ? threadCount : Runtime.getRuntime().availableProcessors(); - final int oldThreadCount = executor.getCorePoolSize(); + final var oldThreadCount = executor.getCorePoolSize(); if(newThreadCount != oldThreadCount) { executor.setCorePoolSize(newThreadCount); executor.setMaximumPoolSize(newThreadCount); if(newThreadCount > oldThreadCount) { - for(int i = oldThreadCount; i < newThreadCount; i ++) { - final CoroutinesExecutorTask execTask = new CoroutinesExecutorTask( - coroutines, backgroundFlag - ); + for(var i = oldThreadCount; i < newThreadCount; i ++) { + final var execTask = new CoroutinesExecutorTask(coroutines, backgroundFlag); executor.submit(execTask); workers.add(execTask); execTask.start(); } } else { // less, remove some active service worker tasks try { - for(int i = oldThreadCount - 1; i >= newThreadCount; i --) { + for(var i = oldThreadCount - 1; i >= newThreadCount; i --) { workers.remove(i).close(); } } catch (final Exception e) { diff --git a/src/main/java/com/github/akurilov/concurrent/coroutines/CoroutinesExecutorTask.java b/src/main/java/com/github/akurilov/concurrent/coroutines/CoroutinesExecutorTask.java index a712f78..9a79617 100644 --- a/src/main/java/com/github/akurilov/concurrent/coroutines/CoroutinesExecutorTask.java +++ b/src/main/java/com/github/akurilov/concurrent/coroutines/CoroutinesExecutorTask.java @@ -33,7 +33,7 @@ public final void run() { break; } } else { - for(final Coroutine nextCoroutine : coroutines) { + for(final var nextCoroutine : coroutines) { try { if(nextCoroutine.isStarted()) { nextCoroutine.invoke(); diff --git a/src/main/java/com/github/akurilov/concurrent/coroutines/RoundRobinOutputCoroutine.java b/src/main/java/com/github/akurilov/concurrent/coroutines/RoundRobinOutputCoroutine.java index 237bbed..234e712 100644 --- a/src/main/java/com/github/akurilov/concurrent/coroutines/RoundRobinOutputCoroutine.java +++ b/src/main/java/com/github/akurilov/concurrent/coroutines/RoundRobinOutputCoroutine.java @@ -41,7 +41,7 @@ public RoundRobinOutputCoroutine( this.outputsCount = outputs.size(); this.buffCapacity = buffCapacity; this.buffs = new HashMap<>(this.outputsCount); - for(int i = 0; i < this.outputsCount; i ++) { + for(var i = 0; i < this.outputsCount; i ++) { this.buffs.put(outputs.get(i), new OptLockArrayBuffer<>(buffCapacity)); } } @@ -60,7 +60,7 @@ public final boolean put(final T ioTask) if(isStopped()) { throw new EOFException(); } - final OptLockBuffer buff = selectBuff(); + final var buff = selectBuff(); if(buff != null && buff.tryLock()) { try { return buff.size() < buffCapacity && buff.add(ioTask); @@ -79,16 +79,16 @@ public final int put(final List srcBuff, final int from, final int to) throw new EOFException(); } OptLockBuffer buff; - final int n = to - from; + final var n = to - from; if(n > outputsCount) { - final int nPerOutput = n / outputsCount; - int nextFrom = from; - for(int i = 0; i < outputsCount; i ++) { + final var nPerOutput = n / outputsCount; + var nextFrom = from; + for(var i = 0; i < outputsCount; i ++) { buff = selectBuff(); if(buff != null && buff.tryLock()) { try { - final int m = Math.min(nPerOutput, buffCapacity - buff.size()); - for(final T item : srcBuff.subList(nextFrom, nextFrom + m)) { + final var m = Math.min(nPerOutput, buffCapacity - buff.size()); + for(final var item : srcBuff.subList(nextFrom, nextFrom + m)) { buff.add(item); } nextFrom += m; @@ -101,8 +101,8 @@ public final int put(final List srcBuff, final int from, final int to) buff = selectBuff(); if(buff != null && buff.tryLock()) { try { - final int m = Math.min(to - nextFrom, buffCapacity - buff.size()); - for(final T item : srcBuff.subList(nextFrom, nextFrom + m)) { + final var m = Math.min(to - nextFrom, buffCapacity - buff.size()); + for(final var item : srcBuff.subList(nextFrom, nextFrom + m)) { buff.add(item); } nextFrom += m; @@ -113,7 +113,7 @@ public final int put(final List srcBuff, final int from, final int to) } return nextFrom - from; } else { - for(int i = from; i < to; i ++) { + for(var i = from; i < to; i ++) { buff = selectBuff(); if(buff != null && buff.tryLock()) { try { @@ -162,7 +162,7 @@ protected final void invokeTimed(final long startTimeNanos) { } } catch(final EOFException | NoSuchObjectException | ConnectException ignored) { } catch(final RemoteException e) { - final Throwable cause = e.getCause(); + final var cause = e.getCause(); if(!(cause instanceof EOFException)) { LOG.log(Level.WARNING, "Invocation failure", e); } @@ -182,8 +182,8 @@ public final Input getInput() { @Override protected final void doClose() throws IOException { - for(final O output : outputs) { - final OptLockBuffer buff = buffs.get(output); + for(final var output : outputs) { + final var buff = buffs.get(output); if(buff != null) { buff.clear(); } diff --git a/src/main/java/com/github/akurilov/concurrent/coroutines/TransferCoroutine.java b/src/main/java/com/github/akurilov/concurrent/coroutines/TransferCoroutine.java index 0120b07..3bd8e12 100644 --- a/src/main/java/com/github/akurilov/concurrent/coroutines/TransferCoroutine.java +++ b/src/main/java/com/github/akurilov/concurrent/coroutines/TransferCoroutine.java @@ -68,21 +68,21 @@ protected final void invokeTimedExclusively(final long startTimeNanos) { return; } - final List items = input.getAll(); + final var items = input.getAll(); if(items != null) { n = items.size(); if(n > 0) { if(n == 1) { - final T item = items.get(0); + final var item = items.get(0); if(!output.put(item)) { deferredItems.add(item); } } else { - final int m = output.put(items, 0, Math.min(n, batchSize)); + final var m = output.put(items, 0, Math.min(n, batchSize)); if(m < n) { // not all items was transferred w/o blocking // defer the remaining items for a future try - for(final T item : items.subList(m, n)) { + for(final var item : items.subList(m, n)) { deferredItems.add(item); } } @@ -98,7 +98,7 @@ protected final void invokeTimedExclusively(final long startTimeNanos) { LOG.log(Level.WARNING, "Failed to close self after EOF", ee); } } catch(final RemoteException e) { - final Throwable cause = e.getCause(); + final var cause = e.getCause(); if(cause instanceof EOFException) { try { close(); diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java new file mode 100644 index 0000000..953853f --- /dev/null +++ b/src/main/java/module-info.java @@ -0,0 +1,17 @@ +module com.github.akurilov.concurrent { + + requires com.github.akurilov.commons; + requires commons.collections4; + requires java.base; + requires java.logging; + requires java.rmi; + + exports com.github.akurilov.concurrent; + exports com.github.akurilov.concurrent.coroutines; + exports it.unimi.dsi.fastutil; + exports it.unimi.dsi.fastutil.booleans; + exports it.unimi.dsi.fastutil.bytes; + exports it.unimi.dsi.fastutil.ints; + exports it.unimi.dsi.fastutil.objects; + exports it.unimi.dsi.fastutil.shorts; +} \ No newline at end of file diff --git a/src/test/java/com/github/akurilov/concurrent/RateThrottleTest.java b/src/test/java/com/github/akurilov/concurrent/test/RateThrottleTest.java similarity index 98% rename from src/test/java/com/github/akurilov/concurrent/RateThrottleTest.java rename to src/test/java/com/github/akurilov/concurrent/test/RateThrottleTest.java index b7a0a72..bcae49a 100644 --- a/src/test/java/com/github/akurilov/concurrent/RateThrottleTest.java +++ b/src/test/java/com/github/akurilov/concurrent/test/RateThrottleTest.java @@ -1,5 +1,6 @@ -package com.github.akurilov.concurrent; +package com.github.akurilov.concurrent.test; +import com.github.akurilov.concurrent.RateThrottle; import org.junit.Test; import static org.junit.Assert.assertEquals; diff --git a/src/test/java/com/github/akurilov/concurrent/coroutines/RoundRobinOutputCoroutineTest.java b/src/test/java/com/github/akurilov/concurrent/test/RoundRobinOutputCoroutineTest.java similarity index 96% rename from src/test/java/com/github/akurilov/concurrent/coroutines/RoundRobinOutputCoroutineTest.java rename to src/test/java/com/github/akurilov/concurrent/test/RoundRobinOutputCoroutineTest.java index 040bd9f..8d8042c 100644 --- a/src/test/java/com/github/akurilov/concurrent/coroutines/RoundRobinOutputCoroutineTest.java +++ b/src/test/java/com/github/akurilov/concurrent/test/RoundRobinOutputCoroutineTest.java @@ -1,10 +1,10 @@ -package com.github.akurilov.concurrent.coroutines; +package com.github.akurilov.concurrent.test; import com.github.akurilov.commons.io.Input; import com.github.akurilov.commons.io.Output; import com.github.akurilov.concurrent.coroutines.CoroutinesExecutor; - +import com.github.akurilov.concurrent.coroutines.RoundRobinOutputCoroutine; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; diff --git a/src/test/java/com/github/akurilov/concurrent/WeightThrottleTest.java b/src/test/java/com/github/akurilov/concurrent/test/WeightThrottleTest.java similarity index 96% rename from src/test/java/com/github/akurilov/concurrent/WeightThrottleTest.java rename to src/test/java/com/github/akurilov/concurrent/test/WeightThrottleTest.java index 9bc9a99..e5b4b9b 100644 --- a/src/test/java/com/github/akurilov/concurrent/WeightThrottleTest.java +++ b/src/test/java/com/github/akurilov/concurrent/test/WeightThrottleTest.java @@ -1,5 +1,6 @@ -package com.github.akurilov.concurrent; +package com.github.akurilov.concurrent.test; +import com.github.akurilov.concurrent.WeightThrottle; import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;