From d67ec8c0ac98daac87c83e670f55dda578e7511f Mon Sep 17 00:00:00 2001 From: Leonid Pershin Date: Sun, 26 Oct 2025 22:56:38 +0300 Subject: [PATCH] Implement progress monitoring for image generation in AIImages mod, enhancing user experience with real-time updates. Add localized strings for new features in English and Russian. Refactor UI components for better organization and clarity. Update AIImages.dll to reflect these changes. --- Assemblies/AIImages.dll | Bin 77312 -> 84480 bytes Languages/English/Keyed/AIImages.xml | 1 + Languages/Russian/Keyed/AIImages.xml | 1 + .../AIImages/Components/PawnPortraitComp.cs | 31 ++ Source/AIImages/Helpers/PawnPortraitHelper.cs | 90 ++++++ Source/AIImages/Models/GenerationRequest.cs | 31 ++ .../AIImages/Patches/PawnPortraitCompPatch.cs | 42 +++ .../Services/AdvancedPromptGenerator.cs | 47 +-- .../Services/IStableDiffusionApiService.cs | 5 + .../Services/StableDiffusionNetAdapter.cs | 36 +++ Source/AIImages/Window_AIImage.cs | 280 +++++++++++++----- 11 files changed, 470 insertions(+), 94 deletions(-) create mode 100644 Source/AIImages/Components/PawnPortraitComp.cs create mode 100644 Source/AIImages/Helpers/PawnPortraitHelper.cs create mode 100644 Source/AIImages/Patches/PawnPortraitCompPatch.cs diff --git a/Assemblies/AIImages.dll b/Assemblies/AIImages.dll index 97454818667d315d7b192d6e849deddd5a3884c7..cf9e1cb2fd9c9030e192bbd22f52f958c75665b9 100644 GIT binary patch literal 84480 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 e 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

A zsBMLFu9A+_$Ch)V6k0~QjvpPDc9f3t6dftbt=Tn+))`{YF&WNM=crDn?r8@rG}z5N z&;IC69-%gmg@MN7D5;(CxfIW6Q7c8Msbgt%l}7&qXpeXtlwP;C-0Wy^ z!HLUjYS}nGtVQRHc7@wbjXBXe)XjvYyh4t~bY0aF zSwiP`+8BXy#@y*{ z?NtRUJu1nzI1qGwNM#NP4+AhgTF$~^dN_ws+8dW6rmM8-^pc|L#q)zh9G6DdRC}l^ z5p0JTu&-nrZCM%0o_aQW!+8%CBj+=UAM2Qrn6%x*k_v=vvnNs#^I>9Ez&NS1=%??d z+icBhPwX);VhUsWN%0QLr} zr3%upGC_w~6}D24_)zJaT~tPP65s+7XNx8Fa5s;AlQ+U%ll~2{5yDih!h;Fq7&92< zE3@m0K%+BBo`^dfF$v6?&7VE&;UBV!IZ_c{>pXC#q>8#c)V#*4hm>2}niLAe9r=iF zWeUCFs>l+4gtqgV8DGwp0D&4P?)X@In{%LZ(<;UEPWxx;PNP+w{LY|lI!!wtk0s%A z$`d95y`vcE?;IU9iMBMRypzv&I+Bg$rv=YoeI({Mrcx=abph0&O_@Wh)Rn>kU4r9y zJ35869|QNQGaznI%#pC>_7+f{x`jGNw8IW?oDn(XAu`$-(h^#zEpLa|#f%$vG}LKR zn}9L7(e8+QMzEyLq!l78x@)?YP5gCFP3@@CK%bgzcyWe-`|LrZiS{linw zw#SMzrFO(?HPQZxOdRMnk>2zUXk!TF?lgZ5s`Q6Dh9-Fd`%xK4BYB>a57Rq?elBns zXwZh(ve~V%{a6$lMQ%p$F~g0i3-A-7DH-%*7HgB5rVAyMFmta>3Hzj;f!VDXjp9RU zCy3%`hH_=4)@7Ab?&oI8un7_by_O zPpByti{nQdjva-;2E6W>mDOL>-sDwZ`tM&vdHT6J-E7IfCxiV(Vn}-!fsUQ>yYbCM zz^h@YFUmWnpB@Q060~jmU<>z6=o3=XC|UHaIUbZb^{7?$>~SnTYoQx z6!JM?bJbr@&5;}8+G^VZc2^7F*GAkH0iBqchg-Gwd6a(|Jukzm@bDGavf-D-XwYa$ zYwM_~DSs-F<}Ft+@`pqp@>Gv{_*JAdw!8C#$nzLkPNw0JWsHccihTqjlBOcdN z&#So=F6M=Yv!$)JPg}-8;H;<_0zFbLHE|}%_M#^}WJhqi9p}ckKp5IjrGo5O#&`g6 zwWCxrd$m3_z*sBIs_n39<{68{X>ijs=;uNFs3p{^Z#>rAdZ_sbc186uADlV5w9_`Z zC_%oUcHoGsS3%1hrHy%{9XxAabwODlXVf{Ta+r+E!OMWByOp#fc5LklC_TSqZEyR> zOjTp*T7fRlbD2eXlZ$4p+#dBcbk#%cxnPwX!)T2`QZJ(C^o1-eZVpf)bP10VME%CC z5Ncn0Y}%aS?38nxtQ_z>4c^p$3*Z6nEN9`9&Y{M-XoP3b)&@#r8LZrnn)3k;&HYgv z+WBR)^}0^MMLDbeIik|j^>*zwj|+7q*8#Z1NKFv`h=%HZuHe{^+5z?r^t|$|f!eMQ z?P+E`Fm8cyOj|XIc{onCV@r;=Yd<{b-Xt>*smD$J2_FP$k*v0odUyZ8a$yU+d#psx z?ofj1m#FU&oks?)8U{3W6qW$NaUhX@w;i&9}#>mB!SQ z>IpV_ECOkNJ4hin>8ug!JzY`*AE~EL(E1(+vzOYpt>lfwK%8v{YY8~ha#-s`KbTuC zjgqAv>CPVTi<8YJPb}tvH_kx0VWN1@`-y`S9Yxc2-gp6hpyzD+6y22iUsE%*t zgI4?GTer8idTgz|parDwt+-gs#A`EV?VZnD_`Qx#&;0Dvt-iOHwjVW}qlrWh&N(Hz z5Eve2G$p}P-J?z-{SJww-+>ZNa(8-bJCUw;j^dNNNZ8Z8JN*>mSVxka5dbskXSx9* zz4Z}7au^=o9_~syPI{;>*_A$!-iP2kTS(7#9ZujQ_MLr+^notpq*AF)gVq5#l{B4* zrWBKfjwEnOI;h&&o!&0=n2tmWcc(L%NI#iG#@3GvFQD2$a6TxM0)^VXGetjU8BIO2iW1( zJ=%fmz`e<2dh2}-y8Pql=TADjhqrz@kxHevey(q{3k8O^-j6CayMG8|kjQ;_7e*rW zoujy!SItq=7ciaA9cD>$N_&~bV2Bs@V`6Rk#|PU62AF<1;LM6G@DNl^X)`WvU?zv0?a-Hz<~G-fO*)kl-qiLSF!^w_a?hJ&;yPmqPb_! zo)jg?GJ-RZ1S$7HM0+9RTYriHarzC!WqA85LyUJ*uqb}r%p$9Gq*8nK05~Jbj=i{d z;)GNOMz3dY2dI!rQM;rDl3mI~COfxi+0CK60exm*=(vidNY`xk8`Nvqk3gQ4z z&+yjQp)i0rbV0Hc7^bARXv9%PkxD}wrG(wnTi?Wgu3fK4GtFmXPq4du!07-$*m&XjZx zR0qbrs$+-mB$5z|5i^qL6*gsWM1gK6h6ea=0DNUB2pSHggqhKMP2`vgeTS2~!eT=2 z?@0EguRHj!N;19O%m4Y|?LlhtJ6)vio!-uF5SH;lUWO?S+X)7D^Kx&mYCZ%@L5pb~yU0Dn#Zf38;me;({hX62nM@LPizXsCN! z*r^`I9z($C?&<9#CM>8`zvx%x-7lA(Cni_4B-3HO(p$gh03AS~J~qJF9Rh*3UbJaQ zAab{RAVl|p;?HxeZaZ>Kr6BYu{HeXr3ZH_@ViJ41DCP;+Mluw0SaQ@6mb?R3XzP;$ zB94^I^wx7E&?p@ME1MYi9=IYsRC_&2#ZAF$6KLLf4gfv{T|QzU?C8uZLbENoen}|z zB?*67!e4$vGTB49`Y5Oit24ay1#zrkOI`w5K|`>NI1e8M5vdJWu{F?|dmuWXGW6w37UG9@ zCA)lVk@f58dAKfuB%r>;k?w-CC~Z0YK3*(0n(XgMKjGuK{Xlx_W5fbg(%TQEw;$%H zI2aCkX+1q)zr-LfeZrqVg0WUQpyKv8k+D&~SKAK^S{exK9$&SjXdCbRBn%jOk=ol8 z>BqF z2_EyGY@0tn6m1jg>!tp%#S}!|qM90twnh+bK)-B3zrVT0%V`W{`kKH@ zZ=ZtZp+67d`oN%%1X3f^K4qzWDx@}R!C@bidcO+Yh}KjdUhD)Y3R`M#svmBt@Z;yw z^Oli5H-bcIdxW0Z=fT^;lMjrH%+#vs`LwM@woY$-36&!3{H24*9)$`x@a?6{m+jynArfRwJA}vy zh7e)fx&ldWeYxk?p1$_@y+^H z>EXqgpPPD9^VBl#QMxn_Fmn|q+=JLRg$S35S7k}nE}8HocVj_NbqK#Xs`~dL;No{3 zzcr}3txxgt8K-*?2`BM8gWsb`HT8Gd` z35gb9`C};sic*p*MEVN+`K#N|xam3nEn7c&#gTMwk?r09V@#4!hF0%sc%956|g8Gu?&ACL)3`ccg4k@;x) z0B1JP+V_A%(+9M>(dz)Rhv5BFL||}%jN3)?^j@k4w+9Z>){7u}_o&WROd`FHFdfXR z_ay~%dLN@bdK=JG%+U9#f(Nw-X)Ot>k-nZ@LlY_gdL8B?m4a>3=HU(Y1>ro)4Hx0J zVOEpq#BG3+ZA_Ga(RJboFmB2kohQ;uKytvU#A^~!gGB%GrD4CI-%q6Uj*@n-!kr{~ zCwV!;%cFn{x-ob_g6J#~wjV(XTo7dL?PBJVWG-P$(oev&FGNz-52MB5B3s04NzA=vt<-l6C1^M$j!T!gKXAe@ zTYJ+`0^U?y77D^mn}-XhYy!he5BYZ5Pf0(9E?X0HwAnP|y`QbpFRqvoETgrUYY=DvhUm?h`iu2$R)d^R@t=mI|v zdaIg1xg@o>SxA^YV;5(ag71SK@V^iD$jzf;C&nfKB=v?MlV3l>>yP17L6QF;MIcj z`iYh?ebcl3;Pn18_O;oPJ;`qcvDU;1V@@W_k+#(q@Lp@Yo!Ne|AgqYD4$ddcOikNRUS*23qdP3fUgb6x1Fxc?>}=km(BWuiSM&jtK%oLhxea3 z)ACWpv&#^Svw34KCUDfviiQo`72+v@*!bbk09=y@7Ht=61s5v?2LuZt&%o|HDo0 z3cuv5AC@toNWV`LV^*i`{Dny@ERr<0@%#Msg!%lGr5Sb*kT!zfTku_!(W{*{>mE;KKe`Vd~ouWj_$9r#?0w!_}GoRexa~jaVwkG@XZ@{-QC!z zUd!S8oaNHB%Y}9M8pt(#d8B&HEgUSYyQ^OHTBcmbrzx&kcDPnve&;n&-a*pXMt<33 z<|ZeO9XEc{=FNW7?B1C}|LS?u^~&7FfBmx;e->S^e;;Ld)W#a`AB>d4GgG`G864br9EYGTBQ$R=;q8N2+%MvA%_S-MQs-a&jgBr`;Gf>#su9kOL|pu+ z+-7i104fhhp2Id9H>T&YfypCs{Ckts(xcXVcGe!Q=QgMQeWiVJ z#sqq8{~g7VDbN5%KYNkR%}Q>I^RUP!dc+MzPrx_Nex2g9Hv9LxVneov%psQ zJ$+o}b@oUsVUJ_$)V|Y?_?s56u$jS|E!oB;Kb;h0X^SIcN{zd%_|NnpaFx6Gn)z#J2 z)yM01aN=oKlZ%Ml`2F+~(H5lq*C6nhK?kxkN}tG}%_*;xZ!spkQa<&Z)=1exD}1)q zG{0hKp|gzO>V+Z68&X zr5gQ-Y78P%b9amZUIu(NQlc!umA0E1wiwZRuUl@8%W(0Z{ zvLg=t>o6z{yrrWJntEv7FVSU0zNCB~=y6GO-}aWp?Vw+*g1yL-w%T?(VqnkiYelTN zV2Ew7Q93G!H0iGa-PPA>X$wP;Z6(+&KBzlPZd6h+LGNI{;*V`pXBVZqMgTKGU>@+|7HoPyaPEpi1t(5j@J!E~U6_CON8 z6yF(?iWHRw$SQ|oe+aICPhE68_-Jqd4GyuqD3V6|O{dYR-nu?y9f5M@p^dg~19w>+ zN)`m`xja{x)88O;BqDeS$AY8VU3*$-XJjAjtyZyxFr?ZQvyg}m z4=sZZjLiU=m%&)1KWoW0D!?ZJnG_rV9`N;zGXSq26C4OyU4$mNy#>KRT%YL;50=#B z4ra0*(-jQZX}+Bn*=ez);Uic+h&~qwa(hOhN-x{846Skp(bH&8-9S=HOPC%Cx`T7n z(y}-W+d(6&?0l4Wvwt}5jzV~0jKlBNJ?xHQP=E$>JZtTD$ly`ng^vcPQOIg&WasksqJ-1idlAxBsmC@%EY9U-j0}&06vjd>)SeBsc5OYR24yw< zT#+1iz+IQ=6bkm#@~$949zm_$AojzLdK~;r9tS=8r_vz!H3fc+e1!sj(-rGr zrz`80E)|+lW=9JFq$}&wlQ^MF>y<9j`MJ5_(c-3Ie}n@mG6qDNT>>p~2NmWD%noR8 z9r>()*~K5lx$F|6+}wiv$XFB&9|wREQJAO=VI^Tqqy8Ls==f}Ra6F@)$k!0aF$1O< zyBGo#Faw_0a$vrICt!A(-yl13JVbx42533~+4aBKo0;wI%tw6o2qW_S^d1E#AoWE~ z1Pq_VECeR|Q_)sBHOs&_;c@JtO!!m&lr_z17FvTiy~QDaCQdN}p;L6HIYFnaubfg= zr56iRlt<4Mr=jzLC&P+vgP29;ah)Rp@<)d!La;T)+~jyxRzE0|ab&fK>QYwS{EMnt z#L@gkqiBvXuZv<=Fvn>J#^6YHRxQSGD*X+Pf#U*^Z;{WjwgN>FYZo|%h-b_wvzJx_ zbmn88QQ=7_mK0MP*}pob=rtAyPKH2m3P5-&Kze9KN;nV5U7VTYj{FnV<#+-fGj<7A zh+uHXRs!>JC&z0Dcsk90LGl+PBqfYK^4H(CH!o!oJZf;X)%gOZ9VXpH38W-WW>d@a z1hY6!+_Lw>8pHG1Z=B|LKQF0eJTK~5se@6Wvnek8&_=ho)*_tJi}1$!X0fn%aUcQxZ*G)j7#{Z7%n8h1?KuuLAV3U3-J3!S)~a9EWC#b)Q-0Li2(A-cx6r&_@(+& zy}JI9T)KlxcVMyO(wpu2S>Tyb)+AAnyfV12i$E>x&*^W{ETq^h1PIIMbTrL19motI z8Qg>~8Y2UNy9){mvW?C>^i&UT5F?e>y%1%1Jkl{4o(y-a9IniC=|zxxG_%WscOh>^ zu>8oT1XJ!|^Ei(sL@HsC4@5qN0FR~frF*Ovv_b~8J(idqMU1#1A-OnQBF#7q#V9)Qr28YqWg)7H%ygi zOOf6%G1_GvuzvHO%U31JGs@)?YX*vr7!;7**CVe{!2#OM647 z-b`?rk>NA6So9DvTrYGdw(}6NKHZ8XnXIgzoFYH(vKnZy_n3@ga^Y*WdbAVEL?H4H zJ9d{M&s4D(62ji)3yzdCVZL=lD%uFQm^FG{(q*wt2}BM`SruExWnHn0?6P0R%bt-a z`wUr2K&c>RHNQ)sTVQZD7&3b-YXWBPTxRRoq>$qd66qs-!w z;ywb0j9}R7hhI`Rv{xFo9tA~g!$oSuqF|% zL|cG#U~YDNb{q6zs}WH7F)TxFWj%}r#V|v=mB_|WnS(-3M<>OwfVov}@GNLUSh-?Y zINhosb~b1v=WvoAYt_lQnmJEXZAgNcuuZ=*!?4DTVY+bxhb}XQ?qeK!%ow@@HDgF% zsT_p}X&M7CZcJo8G}PWrN=2n)luC< zswh?fT-UqcEqE^j8O#WWS;!`;>s>V=Gq{jhwWH$AwM{EgVnHp(pot?jR8P5oK|#fQ7^#y9~k@6TjjlFLo&> zOPPnw5W*s)i6EwAf9*+VL=Z)-M>*u*X9KWjQFILSdZmrsJF&8h6P5KA7asF5&Su3wi!e}`GXka{@_In;_AwvPE2uX4|X75YAS1-?srUjWl!43(^4Jk82=wf zoR;QLzuxi9@YB+>buXD-u$M!HIYS>41l++o_GGrln=;+>9h&RmBMtGhhgQHh*uw-c z;Kd{XPAzi$pn`oNEs9-gDGycCK7bI})Py_B8olV@0WbtP`ryKGPo%3;c`KJTYI>^e z)Gnj!6x5dHODOuHaYpcB=u8)-Ni`rNMY_xvT*3bHrijG!>8VH$wMDy_>s{D5{lByM zvH#xYQ(-e-;U8{wj;9;510Jy(-6V!P2Qs{lZo~k=^zFo|isItKof}+<2Ff+eEL^!d zE`D)z@Dk>Gv$>0>1GV!4UOqIUhSR5mF#~*adcYg-N*@M%T4xY51Y$10EJjwHpXwUYDSx9*LldkqAk15j!F$t)jv6ZznoGvwSOgp~%ecV?+)5C#40PCVR zcm=AJ%W7)S>tdoF+h05iMSo%}CY;$_-6ztfGPF$ zI-b_$geiGpZ#Z3h`bsuGVRDzDgK{tGOJ!?V+$0H|;8iFVl(P03>!Ky7sVFgTadff; zht2G%CQmq+xh{qdVC#A6VQEauk{(uy=higo$ZkrFLmg&%h*B`rWN*}gw3zLPj6^xV z!rc_?ZUWd~oQ+0=(VaNRNDG~*`Czui#ydE{^){%=#yAq}0CocU!ccop2l~yHZK549G!qUM7&YTen1#d*R^9AKvr1_n0JzjGm zbq=JG$1C6HjpCxnZC@oDOy?(Ph1seUFrHzG`*Bo47S{yHxZYD#L0HmBC`i_dhYWo-VFPZlgj7_P{K=g*`SC z*?ikpd~h=pXasAt9m4%N7?aXmWZ@72BQwpELjk*_^*fM>@rFs3a zUKO?r`z}Wb%ED-{^Wv;ZW_=7+SA(mVomK?)K!CWxxUP3wkAPE;a6>feII_!CfMWQH*A945q{Gq3YqwWO>jHIZ`%aBDEypFuw%lz zm`IBG9k7%ClmvsmldR9CSgVpwkFgy}Iy%Ny*fG{4fno)8xR}h{s1xIsSm3_4*DkKrZH)!HEFr zX3F6LsA?SYctwt@<14}fT)(;x7su&Y_&!!Ro(o|)ju%P`q)8!9_k}ibq2sv_ZWqQ2 z@ns>`)J;M)h|Jm0={)X8nr@Ey=lS{J?(NsbRQo3B>S z^H_9v2amBNy=PkQC3?VW>fv;aE6g35=1cV+>qZG)9hCjcLK-SDtxw{@p)Avy(9-a5Oholi|CC zYdx1F;SP>DT;S`3fYrAbEp&%pfRNtJ$i7YMv&Kl?Zq93VZi(AkUZ@ zt-X?FS>H-y@VnB*@ zQk>70!y$1Q z>J`YMhjCzXTawBQ9)X0K(-1Z zSp2vz8T}2?=mP*b?qwMNe4ywFKgcvczF?w{QukI83Ooc}{VqKHqB`?a6HmWbHKLrn z&NDAnG-8f(-_<48YgjyNyHL)yi}zpFSQO214-H@}Tg|{D52Fsht4A;ma{TOFC{=b^ zX?PxRGn?cY$}x_km&e3FJwajBF~eKAGvtimx18k*_;7XN@G*~=SYx~ad!7$?B@neQ zSqkbB6DltnRTS_lCxbgl%N|ltL}0VYH=%72U%;#9t(mYxY<(QaQR9C4=_mNk)0v-< z@SR@he6qLfrepPe?BnQJ(|LwS(dlSER$)8~cs?BF$3-ZnUk{i(^_uoC7bzxi3iZV~ zMPE$A5S57|Jyd2|=at8)Y}5Kvf^yrZ8a%(Ai{c0e^qY)H?6iFn;%T92F289tRv<=s z-&zpdg64s933KiM2%;;P@gOrK;_uUpM;(SOAv3!SZkfaI#42VLXa9T|VuJr7Pk>i# zJ;`OC2M9mOGSyaTB^ZMM9LCMecsPksR0T#ofFp4UGj2#?{KSmR>V!lXxOGty<5OmQ zlf-DM0b?G3qx5BFypzNj)*FoR0FJ~4W;~q42n4~X25=-UXU26&j6XBuZ*fKkI>H@! ziXD+JP7gmVPAIUZ^nn&l6k4w&h$3r9Z9J#gx;#Pju(Cq&oSxQ&38I(vQGzJ3#?(1t z9U)W?6Xd$)1f-yG&6-Ww2Bw8)*c5NYO>2urbh_mnB9(mn)D<=~p>mTSy)x5%-r!W` zV0KB-D;V!RAb`Qg*Gr1Ng5EmO8+{g8D!L7Dx{7Y+1hL%Ea5|3aZdyBIWTyu+8{#q5 zx*H~@4Mjl6;bVi&!NihkJtsLEB&DQ3l>L66!Qyw~+vJtgBPK27YfGkEUtS$!p=oNb0@*k;+~`m8aM z;j@}0#j&0E71J=^=ReG^d|(Z~vK1MQU%f*+*m~_+d*R_8Sj#=YwWnAYLphd*JTKoA z8QH0%Zm)HfuyqlS&ndzaUW&Dj^E{zEpHqZ)yI$*FVe@lwDY9^*$1p9` zDiL;>uysgFJPj6him+$?dKCMaO-r>#NyZm&fU0=lxTg3JuqH|dHps}3n9+ThYMm(= z7&XX{D09nIQ>wLCGVYR$EhV0jc3-AiD<$I!$=H8kE@$xdlFzz|GeYOH9)!4Cu6BIZ zox+{1Dn6eyl)2oEKI;MD9*b)7UeD;q)=qI+4Zr#%=2Al=b^S;B zUA8=566&t+DTQDPW&jRj-S7Q{s~04@-}yQ4SqjIg-0!Y>S8fQ8N$F8^TV!_vSF?RN_Qbf0tALa}`{NOFuCtzdCg^Ll) z*c3s_&FX*|#c7B?Dy_iI5Up@nV)`RCEBqFu92bc&_HiQIB}d9&`k{;eT3Z!#o_=JeX<4`}1brH)ar0g!|sMN7gkBf`Xq+mQ; zB~H7o1EIlE61Fu3GX4f6^W>-`$75Pm{qZ)9=a+Oypu+@Nw$6hQXQGI09ghJCn{E}@ zHgK@R23}(0HZV^vsB(Nb6Ji^D-KyXimgXKhKI#gRGGt81b&_-bv;=ncQrLLyg>Kzj z`?$)4f0GsKF?Bx#a{QsnY`=my)QH1gmvxLHiB{)|`7??by z>OatzKV8O?G+b__>UQ5o72EZ-Bi|3I#*8#b+HE}rYuw=v*_wn;`Oz01+Gt%RxvU+K zF@qnm3|1xk0jQ+jbIX*2u!P@&kpEhA@&pzB3(J4peIcG(+~IctJKdOHPsI5fv*u~u zJid|t;;7SFbKEWqcWz-N=jvxBrIesJM4ZL!*$lea#FJgpg)1*`b*Mtv2n+0@UDj;q zg+IG(l^i7aYii?{Pq@E>jij6J^Ypb-Y=+zraK!{cMt|AS^ZGpj;o^ml?Tart#>Enj zx0bF)rIEkFx(iW|3#bTAyUZ9XSNyVz8Dsq_IFGy8x)S_id?xbZlg8O8Cd{k@Ep;bJBV*|#igYCRbmul61DPYlmS`Qc!vYoRcc@(miX^)VVk~JbM&)*8(81Tm*C5SK_Lp;Hg)8#s zAT2j~B3Lrvw&15o+`-QPV;H}I(iHu#Dds4gUjJ zQQ0RhpkDwD9|VXEV9PQFV@6GOhS;a%p5l?PFQN=QieLu6I4PGHmq|eCwZ}LoGfJt=*$tFOeA!=2)#;2L#Mu{SuOW`^j*km>nilCgWr^d z-=2hTO2U7egg=*rzng@Ao`ho{#Pw$<;dM#)s3iQfB>em&{H7%Qi6s2JB>dwz?u`4StT%o)4mf;C4Ngoe9Cn4+xYC<-8d~ z&Y2HbM&^Sm73Fc2n5Pb%4_K1tR7`4mE)@g}%q*HA2pAZCnjr`nLmY-6U?A|dgdkub zYBfU;Fc5N@AqW_V7tIg^jNuML5HK*yX$c##Pt%Yy!pRW?jFApQ5HK1Xh9F=xIt)R; z809bo;d#Nu&lwSFM;x!k#890dzKUn;Y8A%#cW!#JT&SyDL0s-?k$3TfLMZ1BV=}SJ zC9h_qovH1OekDham_UCp!#5z?kST1Oa1` z!w>|F$qqvhFfhn;ErNhC)nNz%#x#c^$i*u7EG*3L&(Fzqj0|O};M1VzY4*I+yKF8_ zaf%88U8gz>LBN>qFa!Z(hQkm9jME&3AYh#CFa!Z(ro#{fj58dDAYh#7Fa!Z(mctMP zjM)xD5WSY2k67ftcxRQC1YeY%Lesx!2)-nE86T$y_t-d=-{7l)%TyhFP2)Uu1>X=n zFZiaU1$=ReUY8TLAl3)Q`LT%LF2-xM4H$L2CkaIGl0f|Z1ysgs$}60>VyKQ6lb1PJ z%2`-Ua%C}LLchi!=P$fAV^{|worp8%U5KB6Ll+rH@Yx4W+%aqj{7~uQWGPEPWuB;H z!d59d5fcO(0}(f59i3RGStsthvQ952?idzYzv+qLV9amg-9xl5Gz#^pC};c4(tr2Gt#h-WuL`BnUaty%2xaf#8J65wgv;l~+I6yslhRJnia5~M zJ9&5%lb0)kZv9>a<~Un7?&~1%I1u3&F`Ggup^VVtq2moasN;YC6eM_{L(Giqg@mp# zD)mOsL$MgQ8A2)=1`;){I*vJ`OZ1Ygqj8!!dfsf;J)yELSTmTDrlKKlLOPPn^ zj=HcjXF?D6xLwfW=o`!W&=+xipR)!P`x_^Du>+heWghgwBIsk{5PfmQXz<0zj&=a3 z=yJdq#{SPV_!5>}A(AUu67zw(wr}Kn__AXa<8igCTw#ga0#{h#HPaRD8l?$QKL7g{ z#wzv}7`vB34Yr*M&$!IN_1&*P%Ijp&3*dxfhp~4v`=Z0xFEbk*b%>Hzn2o+Ug#9~aqu&l;zs~IcIgI^# zW?v?3`TUL?ErihqlVVqLv$TsaR)Hol*yCXwf&0VQftX?30rIEe?q)gC`q3)C+ApsZ zDqrjxE}5?MyM-#-73_fsrT2e82dF4#rm3Zzbmk#+d#F68B$QQh*Z!Kzt0*V2s~FGK ztSA#n^avq_8l8FH`wrsVu5(*Qkg?3*MkaevQtvrXL<5*45xCt$sDjFT*^g z-wr$qSn`X!6gtMP)_T!VWOXuz?Ml*HjD!EXhPRny?5o#jV^w;4Yy!tp;ZupQv-#t(rc z@=4RZJoAIg4E|mi=A3I`rakARqb1ja&N= zd{^a05M<3kXQ(LSiEa#5aj)m6!tJt25=~My4o>lq8Qh-7Zcp&NL45HGem77%zY((P zcB;)5Uwi5KJygtiSATiv6gLsB?%=PRP`lqOIFcu6?A4;Tg4PaG(RIM};X01=)^p^b z5oYT9CQ8Gddbj5d`G+2ljvaaqccS&Gw24cG7egq&bfDHFRJb234dT03{_p?*>&T;^ z^Bx{h66-255M0cy@#0~8cnQzA*qjTYFpSq;5}c*XIU<>ZA#JvWk4$EDun_KVCyHT} zG{ZxaIV+hnESZBf&zhigGRjj+4&35+|snD6};~TkK9&prV|_ z)-#@~Sy3kJ+l;|ckgUs7!V5Fuyb|HOD1&|-!F{0nwJ%qmB&|Ox5X5%|{jm*Phjl&+ z6JY}`dATm(;G+}(m;Q&G;%G1XE|JM+dtrz|jB81H_MgF3Pvg0(8jwI>}9 ztEe6z z>cRtj$Wl?plg4!)QF(oLS-OgcSWAiuq{QwPEl-Ik7OAYL%mn9ui@`MHHl&{7$}%nVOr6^{T5H9!d?;mOQ;6d3B)#hD0C0lT_B z4Lc_xr-IZ6(Y%XcmR%g)_18bTw+Oq0T+QMuKG7WD=zb64Okrh{z~d@p#z{OlZcp@5 zd+OeCdTX;;%B+(zj2{~B(q3K>Wg{Xk5}#rtG7YxcD`JB04dOsR$KeF{13uZ0-z5C7 zzVLgp@xPwHW`nmBzrMiHLSQ<6?f`Zlem@sKZOB7BBYu7ho0H<_36O`y4>NWAoC@1i zbSt-WI(vEs0LRa1NbUGxg@~VLIYIn9j#T2OOyY;98^zBCa{O@8nTPpGZ#<+Vl${P` zv8TDbigFTrlJQ*4((&^YbE3?*0UV`5!-4^pB)pnEx|<$yup;Pttw)3<$C+ zM(_m1cv4@=q^hFgo_3ycogNjVrIlTKG{JXzv~e)^j=c9upCiSo8{b>)(r?%f5SHU# z>^Fo3`fVHROX|1hKpxg_%+&oh6E0QJo!q7~fOgk!tPuUSn-lcgcBIm8r+HVQ||6l#a_nWUHq7%_?cy|9x_@6(6Gz%$$7YAkN#;M3)Mi>Ly zpW5@vDHzLmN*L$23vaJ3Q2Zp0`}XQWt4rlfLKfGgeE7AI8jR4Ly?E9-wJRO_W-$8~BcPJN4a;S>3+@W5zxre&eI#--2 zwR49g6_#B|7ejDmTA0pT5b=w+BPIC~G{LqnL8%b~od2@$i{Q5czmfPIY0vKte+PKn z%H(+;+g;)dnnIi3b>Dz*QX=nU>02!1xG5l)mEa}%wuQU(ECy%WeR~d4dv51K=-XCK z(6{FzmA-}hvAIQLqi;DAealH_9yV!uZkLki+<9Qfu=@BhM{p9G&-hYCJM;RmbaVl5 zIZ?y<%(>w(05mUULJM^bj)mYK9vlho&j-hOtoiWZ;G$iEgXInn4&nYxa7gVsIO2tW zAvnZ6;?FL@kzhOL6G^dw-3DP^J1jPs??P7`8XGIYyBxotiw%X%#zct?3(f5=HX`hX zpNkDHgxF~31hKIQsl-N=#Kyf68=Q&Q;3O$Fq@)uY=W}@#`Wcjd#X%!XWWk6wJU$W;PF;joYne=?e+4hP6yUG}mZ)UKkfk)rQh1F`F3Nqp={MydjMt-Dw9cNhxDv$WXPjVP z^D!4Pa1v21afwSIc$qU1mz*RWgh@##tAn!Gr(9k|If;G3c$A?$fmw=Y#&}H~hV@6D z3S8Edv=W7|`ldB>$!<)_cJ`4{nON8Lh%&)F_?HJL4iYxom{e?yVzGHI)z7cpG`kZ}4L?DUJ^A9i|2 z!s%Qaoc;|baQf$5h@D;|PJbLTjf!$6oX$ySUSDUSkdjcgoSpt9mse3vVt;2mSF^Nf zY>$dEKh{Ig|H5Ddu{JozjYAo+_*gl)k$Q2u*~Mgc++=s$WIomD)@HZ1`71U>MLCK6 zgYn#$u##^LjHs&hIO%W7td9jGbV+UC<$`D`akO#=|xkl-$L(3%< z<8wqjYLQ&4^tx1{<@g-UL=a(6z3~f!s$Y(m_gvzjTqktw-jD`LNa7?<4PV)^6hLoe{kRaeFya)GywAh{|^vtfOi6~ z#L&t*3g6@G3w%nu)wC zAWQy#j3T6N{4j3ums-Sp?tp*fepqf&V;;kMb5@t*i#HX_ACo&E-^2qcRmCQ4$z`}m z;I#rXh5yGK<~QeX*=czri%hz{hT+vYBa8g>W!iykKY0odWSjIrkC8JSVFmd?gsv$`Vjbi*^Lz@eN_5kc?I3k z5S$Z=*phq1ws!>vV4+Fp!v7{cna_SsD_~3R&EtBv<}qF)HeXf4_&3tJ#V(foQyFuP zgb)4nSv|v$x@x;~Mf`fVNedu~4W%g8<~b3+xw ze?yO-epSxics{_nN29Etme#VjpGTb3&~@-Re3i|)Ydr_DYiLLPfj}{RkjDDg7d+ze zQ;S&sZ)uBy&RTjsb6>Awx~lHUs$%+E)st0dQ3<#7ngHwHCB5*X$p1~?C%wi0BJ-wr zqhAGc-WU8&^^CtFZT~l*Nk@w(uL1Pa&PwL|v+fa(NppKW;whoRlDB%B^r`s#s#1=t zphW4QJ}lp}n6;&dKVKEU{is-j0d0M0YZ1rTu!50AC3Ips_kJwIE!`eqn3Ki&p8>yw z`era30SNsl%Om+>4?~%)@F>&doOdgah*N*WXktp?mqnkYWmhx;cgg&*wj{e^8fJ!6 zP+62!ps6&WZu4j=UCOyLvn!s*GdJaux4Ue2(KO6L{UmQwP*X<=^+CnXiof7ZfCizO z%AYHrhU56rQZ7G(sXAP{Zh$R&(x1cFtfOf{O++43(}lXx&O2SSd;*Hg%@*phQcbl8 z^@C6YXn{~WLcXeLIFDN_)YCzxM$nZ)z3pLYG~Farqsi2X*!QwudRH=a3hk7=*vnbI zs$oVGzG=>WdAoF6%`}<^$_0w&PNwz>wFcxgtOfgoIzjTzr%#2tUGgrV&xC4{yd^j@ zWG#FJKaDQL|Fpr>6_U3U&!RJRyHLyMpimbG)q!`iIqy{|x17EfYK!Eppl^lxQ1VvN zKgm^|MN6>0PNP-yo#dT~9pp5+lztTI9V`aZ=vw+os9S})iIl-LxDiX!=sxlYRWHxFuk@`XAPTi$8(7b+6! z2%!#8Post&F6!kA&=VPf^m5u&nwK7+3yO;X=atmC12jwE1%L+q(6a;=h=y4KcuHjr zV6V(tz&-h&D1%n@W|{Xg`a#c6>4O1RWDEs-G<`T^Sf@dA1U?w(^psO`O#^bbRy3rW zG`Y6UZPM04hNYzpXA7KF#kt$68RkOXqzTo%d?r1e*@+oocLC#zgADh08IB5Z*)K)g zn_1%^zo>vY$5efyOq$e-p;7;d8bIHsO-LU=6M9dBRfBw=sB(JS$2L>SP;j2|4F|qB zbrxW#&s@Okphrs@^kpjJ{xpWyruM=`#OW!W9)r&IGybk{{^{r3ERnq1$NUF{voV!@ zb-C{x)N)J;%S;gd@o8<~+$Wqr`zM(O1yi`xK*=4Ix)8aGB=>uPX9#CU>Ox5F@-IT} zjUu^Ca+eAIj^K0CmLWGJ@&&?Qn#P)M6j&>*_U3m9ML<=)wv!4Y*#4%^eC_EO+0(2oXv6TAYsUjP~+W71}k zT&UK7^OfsHz4lt-wd?@Cd;3yzDB8KuI~VQxjB~3 zakCB22<+uyewC*a@MMoG!=NP|t=R|sdslWwqAdl$54Xpssvvo#s{tCC+>Af&?hE*e zdnlmOu4DeAo;)=H^0(T07{AW;$<+T?wo1xA{4-@22V`6)^~l|36Lc~kBT?!0CbyJ( z?QYWqTv?L~s3nh3o6tvJxfo8jZM!x#;h#fGJy|v!W!DrQ`@hogTID>n{a*(6@>ec~ z%T#hN>xfzi8J}XG?~+yzb2Glu%_HJ#!Fzd_Gfv<#wJ2j^8I}WDRk#HE5`$*MDc+T| z33a{iri_cB_hzB4@!ga0KcMcg^WLhsGDFd3oBBifwV<{M#X9i>9$ktlk!Tm?_P!1K zmwRpMwYt^V!ECdsZ?RW)Q(*;5UQ>8c`G=rJ3w1r+Tz5l;n`YWnZtr{1N1td(x}y4# zj1(G*lR}iEyvi*Ze!9BKrh4tnNT+?(ni^TTGb59JluM~=aH+L3BY;nV=sY*_a%hiD z-BYtOBafcyqw`+qxhJE5dgIEHYiNaJ35~O<-q2D;GebJ>Xi)gLPMxN1f@Br-uh-Nn zP&HJDYfaWNrudzVAWgNYFAMf%)Y6qUb#CS-8FlouO?^@G4}9|BN1M9G>&+ZQ_`(8f z5icD{6NF-4=Vl&B{}gJM@5a31%pv6K&yvgOL|oAfp}|7!qGzys9YV{6T19X7%!TB& zn(}?vvn+Ect+ORP_*B7A`Hulu%Y)`|uA$U6KL}TYK~3KsF{>`Je_M(>nfOP*AzWcmIcZ6Hg!UN7Vh8gv8jjhSK|%fFKlX^P`P}| zh*r@hLT%ENjIjx{N2pzNBzk264M#IrvbyrL%n9_7rfkX0qd4zlV_Iky@-7{tDNpF^ z%#*0@SWT_(IVHFtr8#kmz0@41*h?*O>OpgJ=Gk#-Uj5F@);Kkx z>b1;yaq9l+*D~kFsegkCQ^O=?d~C2~=h0JBG{u%#RCtP}*s=&^oyyd5sxSH=vz;2J zGo@$R^XYg^`94bjJo9{-Y*XiC90YZmO*N%|3u=x~%Y6&ee*iVl&U>rE$hv^qHO27) zYLBMq60G%$Y48lGk1k5@=UzncO+@|&*ZxuajQ-4O@DtghTYOD9C|Do4xYH+nd|3mNC z)U}x};p%C>P2H9mFfOIfZ0fFpJ?b+0(xx87f!t;EgG~(&?oq!Y*O}agRlehb2K|cC zY|2}@nl7hYo60H80@cf=#vtzss*wl!E)wrr$V^b3fvOwKpQ#XVPvR2bwHg!j+C#Z*nx}L7juE<(LZ`;(X z!C=;Pqz9{x@*Am8hVClghbVO;mD$wiSy`a^*wmH#YSRtiFT(ZBqs;yMxTxx^IV| z+?|wRQ)5u>PAagebhPL$Dz&L{l)H<9HWjM3vhJq-HZ`O^25Oj1orKojLya~y9j(2G zj<=~n@cg|r*`^xd`FrVfo9d|Fqc+l9oBDOVK^v*frfx;vebjDK4_if4w0$Suo`o*5pZberOt;bF?NDV`Y~rV^Xt znc)$tu_>Mz9-)3V#WTaBG{mNOW_XkuY>H=w%{0!YcxKp4lbmu{mt{RhGi>UGtgApZ zYf3!$Tlz$(>*-x{P1bK|uq=;E-I2A0E{#*qWIair+tk6{A7*W%K643wdKB-V!9uOT zvq>iHpiAR<2B`Tl<< z- zciMR@`65j`KOy-dO%_T^?xvY`9!u^f-{OSiZt@GIC10Xkp;pjbd`bBwdMqjLW!h$! zV=XV!)fXnTyiC^$rM2v#b#@+0?x9Uf6Ow!A0im?yE40PVW64)2_o9U4E0iykmVA}U z>^zoyl{z{SlCRRmLTSn0(G_+cOa6{%WkM1ZuEl?an};~j!D)3N>QYO`TQSD z@VPU?uLNrEaa(ZiEKuv`8WsH$Z84->O4{YJITN7Y$$dIAfe(kb72OZ$NG^g09Lb$! ztnHM1hL{Mz*L7)_%sB(O2DN50)cB{;mha(bgWk_#I48hxljux_IyPoWOBq+xS;UgM z)yXiq#=~uRGnAF3a7xH!C)fV(@Z?%Fe!jF<+pjIuHJ&Mbr}eY144h8>@9IjnO>6$Y zfV%H69O2K?V5bXqvbFygb^TxKyxU|CFP8YZTUxZTCJV3D9L{;NEGx^6)5)wXjBAk} z2;3=)|Jn#1z<2Ed<@Lb-07umQvSb>*eG|Z0Q8ungbEpBoC3p`JcU^Jq*AsI}PoZNJ zq{r~Z?#FOP@-aN?`WWshK87#-K88D)k5Pa82H-akzd`t=(2{a21b`;q*jR$+0r~)D zL5ATlfsF#k3!EfyhQKC3zCK=3o<|!5-woIUcf^*ISI|4cIY@jB{T=ZhCyg>|2Ltbm zUCejDhvENsol-uAQj96stpp6#HVLqTW(eLY>vOBDwy%S88kMUh<+JcMD@$GjJPX&% zd~Uj&9;l4bT6IV7OKF2TDgP?KMVVLOs%^Mj$&E-~Ex9*<|8&_^kmvK&<-{kc82-gg-RfeT%I#J!rQy!CI==2hXmHW-%#$tX82E%X|@)t>?ZV}o%@aXvWZ^=05(*(+eIRcF-K7#meC zYA-jAsH;Qn>)sRbdMUSVzuH;XWDI}}=Yeyhca2d6Uu`hz#D|xm?T-Lwuco+i3%3|W zt|jHq7y;Lf-j|^HzTU4x+vmOhXlx|5YAb!8`K@uDT2awy3~;fxUsoSwr>kMEYkK9X z-D*qk3bmFlt>czH1h`!tQ8z+Wi6vE1d%5wU_i{BHoJWjC*CoOG)Oc6VoQKs$)xY*Z z{2vhKSM7rQCAE71tBPJzMaBia{-7>{{rdr5@O%QewI{=a*$fxfG2E5Oa8>aqkY7@M z063qwt~IVNWXO?onZf6(DXvxJ|57tth1H#EjM%VW-4e`lHMuqf`nZ-Gc{zgsF9;0- z>{EE0tJM{$J>9ikU0OKDwVg72^IRK@tMgV9TYjF4Enke>Nre}?)>1pJrCME+gR4b; zt!s(vjQSm}VXkFGdtA$1w`RZL`VO}J3AxLBA3*cavID|-m9BB!QTL^5t!rfoBFc4d z+4ta&%Q4(*RVe)cZ8frU%G_Ix>v2uF)p)#D9q`H348Oz`+FJG3f_{*^ulF$mk9BW! zEv}vc{HeM#0WU3Tc2`j>GwR+bz3{NBs_+u`ZiCN3cf%e;h`G__i5>YcHq7E8n{&Ak|t~t1$(=0k? zN_258S$HRWRc6ey+x1@PDo>k~YS&}gIHUeSPrFFI?y5|G(ZjG48rZ^SM9v$Y34%`$ z{5#_r&qto`jBCm}0W%61USM{5wo{;ftht>&%sRpR)O88`vz?}wOakW*C8wANT}`+) z-S2A6KHc2!;?s)#u5a?rGPk>~!o9@(E|H~7Ig0@~ z!q-rr!b`pDgtJaK>x6TsaPAb&ox)in^-dN4w+Y;2L%yfFN$$>VlDl)8 z+vwg@^d@q96(8%{Dl%&&=GPh%i+m}2=!??)ls9QAv@JJ|@dbguhySVa8pt%HYd~b5$!4Wt{^w$}D zHy9k;8Ll(Ia4&u6b&<_EO3;aDP?C$shI}fF}_S) zo@vrdTLVXLvuJJ;d)mdGcI_ovME9rp=u%@D;1$LSz^jc*0oNE;0^Vp`3%Jg>0dT#s zE-f1?JWJkbYyiC1xEq{};AGRo0=Ej>4wylo8V`YgP&nTSG!#pw2n+yb(EI8wmITbE zZ-oDy@c%7*kL#1P-q`h3;lB__rE3FyvGcnbum?Q>SV=np@xLQv_r;E`6!2(#n4&M9 z0UH8%g7BvRj>iAwvLbCX_KPdh<_bR7#^=(SygTr;*NU{Ac#G@FybdEu^RhdP72q_v z4$vieb6s3^x!@}V-yrxMg6|agp+J|LB`XDv7C2Yn3W0YB+$r!wf#i9a)@76D_bBD^ zNLhiS1S-xEGa={w~Zxp;q@Fu~R3%*?N4T5hFe7oS=1>Z0De!&f&==X_! z!OI126ueRJCc&EoUoQA^!8ZuLLGbN@Zx?*O;QIwPQbd1>=oh?P@J7KK1#c3(N$}-@ zFBg1+;2Q+rF8FrA_Y1yXaKkV9{i0v+a={w~Zxp;q@Fu~R3%*?N4T5hFe7oS=1>Z0D ze!-1Y(Vr^%1uqx8QSe5=n*?tXe7WGu1>Yd}2En%rzFqMBg6|jHNE7{Otbe`W+XU_t zNa>tgCU9T+%k=x~ed!#rl<_k4%ApL#%Ye7$lnLGd{L!2S!Dj>iDQC9eg!{OV6xbke zw!jX7>jiETxKAKuiM+rDfwKj62wX34o4|bnDIoF!8wAc4xL)8kf%^nfwnz$W5I9?4 zhrsm$w+U>>VaeG7I|Qy5xJ}?bfs`xS1U3kqEwDr2dV$*n?h{CPA}_E(;B0{%0@n-N zCy??*QecC?*#bKRt{1pX;68y=Ao2nm1kM)NA#lCGZ36cRq(YXTEwDr2dV$*n?h{Bw zqEldlz}W&j1g;mjP2fI(R4noW8wAc4*dcJez-?-xL)8kf%^pFX&uN=$;=3w5 zU_&``)(dQ?5L_TtGCo`2Hi2j1N#MJ1pXzDc&-g2SL4%CFhN*g}K5C+xudY*fs_p7M z?4aviC%P_kt#^6d8SZ@dVD|*~WcLF1?e2Tr@3{Zs{>ts~q;2IC4{xn+sxRt$!1svn9p7HxXTEQJ z(^4)^>Epl6|2!K2*W*lk~oTZ5e|A z?@b>H_;BShfGwd>fawCqR*wa~IrDhHXA2mgA7nVVlw~#ue8J0{J%!9!Rl~JZm?r_A zk;$Bi1q}CurT|_OV0==^bU@1FQnRy}(_VHa;6quApCU3>3+IEHW^leNw;D*8{8 z+;M_e3qHPn336{2`C~=fMR4?EcQYr8#pu&||Iq(=D|Ia~{z%K$+)Pev1(ZC5%HSmiO5eD8} z?+tt<&c6(tr}Y883cD(PJ_6tC!gCSzz%K(-c)Ee#3Ah|k;i-fHz^?*Sc(z~=@T&n8 zPM-LEglhp6tww7M?A(U{zYeW2@bu3x;5X6Hz;6argliGtw*V^KMIQm_#=P{_fe++-wdd5GB^$RZvhoOPNxFj0*E^(Gz0h(fQp{PE)vgf11ii0 zX8?Z&P|>qA3-~rbh3ohxz@0P~oaX=)?wj#D4Z8pp?tYyO{6#>8yH>5haTWvoW$Z?A zzX4F;p3!{ZuL3IE>j?vY4N%eR_>!GLZvZO#J@&0Q83$DK7WVQ6{Q*$XAL#<%Zv!g& z2+^VFW5h*I+F?`zK4(+|zG(CYe97noxW@ik2h=v2NLrhFJZZhu2RnE=I=X%n8glB|jg6B5RJ)U2gtIem) zh29&z_j|wd4)&eyd(M}UQkHUF%HouFQa(tT<)81r%74B8b^rVR`KgOiFHZec>O-lI zroNT>_tep8C#ShP_{2H+FB|uP+)0eKwD~vzXDO3zuBtgsXWf7^?L+^L!d(|W{pY#Y z`FjB;+K2v461lE*=r??D*C(m$GThx^TU1=ZqO^OuskfpVeU_As7Zl_?k;DI6jJ`E7 zPk8bF2YWF`c&QA(a{MartHiGgziRwy@av6rB#2)h%t847$I#C?=#d=sYYyH%EJmLe zqc4lmhsEf-a`YJ-h`-tNl!wzfcKW!X>8(hQ#awea%{LBEmFpnRB#$=c8%G=0xQ{lj z!*4Bqx4JRAcrK^Ko)%-V=WP5grws33jf=g1Gj8*KWjv1GPW*o7JxHJ8SLQoN$NS3F zT3;o82k9gHzVIEZ2Bn;;E=pOh4&YbjzfDE)`xL((smH2`_}z@(`}n1#9ji`HgSo>; z%$+rBOlxFeTho%!ZB3C#|5^RP95!p#zyXY%+Pa`Qe8IGZ%}wnsBjz~VLkkU(LWgJ? zFt}Up5#4czbjKVpv|H}5?zqC75N>L2Y-<~9h37XeY-MxNf~hT$c2J|k3l_A@ZEp=P zu=!)GrVARa_9^X4+FHg~;e}{sa@L9A=9ac@_*0tZFKlbEy33h+PD}Hm!}G?rS}lzW zn#YE%vs>Ej$|r^+?Ps+vwyDXB7BohdESNi@SuA!kHFc=3;no3%ciVs?y5kP%jya5( zP3JeYwl&RZYZ-CGET-pkb0anp(QS;APQx6A)e>3M)@}@b7zoDLMGNL4IcZUw*bH?1u?rT>Z?U)q zpe9-^&8>40qQIv%Mdl%Cl)h$!J+Sc4+Ap;T7-m;*5EFxTJmTA18 zskL1wr-Jq{%Z{JW8foWra!XV5$qU++*!1WrRl~VSZQ;31Z4vI5`Lkw0V^dq(5>Usr zEP##eE#v1mo!t`e;(-Hc{DSsD18F!MxiGvSBAozII^m?I`7PpTFzk-#!g4yJ3p1(1 zP;5cV*-c%$1WerpK-l-3!1n{SX9v=lR&iI8wPf}{ItAk-Y(b=z%^uU#-o%}U#p&$U z3+IPzJmT0Pwj$F?bT}wo8xXDy$yu#!Eo?ED#sOg>f2hjbOR=K&E#7K5H zPiQ${<9Laj$ds1$c76pPtSL((?Je{Bjz5{E(&XbtO%0EmatbwvN4JF|Ez{}zrnW^b zvu4r6rVAD{E?n5sWHl|AD_uy(E^fD)=3*-B!fonGVuqR}RdTOWqze^~2B^ZI*IJ>j z$-+d*;*(p>LcgBFbqn3h%yCWD{O|&dmpL>)GB<3s0g23k59T^e869qG(=&6VuXK1T zvRdZ1VyLxY)PZWp$mA)2y>iHSinC;N(L{JjW6l&pr&<`%SQSPsX>W<>JaoA3=Q!!~ zW`Ys#GtFvlIjaeC-k6riTpB*Sn}udXGx*)FHOOMWj$UM0m~T#OT7Xg2JoOw4Q^|Og z8qqduR_g-Hp-pXZW@B?Rjc#dcn{rN5b4xQdE^7aO+WXqrwyre2L+XQ+CD9@kH=Bu- zFgxRp1KWz_uhm%d(OR=|5 z*(A^Bd*1V&_w$@X-fGSxl@>Rydmf7jF^8lql1(6Yso7{$E99kXg*Eg57z)B#^}fr? z64&R*7pxXIJ6JNCrjX_~tF;D}r3$rbfK&C};s$*LEPB!8i!LR~@>Zo@*zj&t=Aiwz zyoQCcSntkXA^H5;*RZrjLlbx2ohSheyFZGQiDVzn$^Rcn3Q&6XktnXlEVwI#1!$Ab2vFt<_4!74=5EELK$ z@jH4uIgg~bMzm)SWiERg(G^QDJ2kLW-v&gYZ{@YZu2);x-HAZ{Qnk1nU6U)^^@^g7 zd(gaHE<#K96gwn)YlK^Si$!dEi>(&wt-!*~BZ`~r>)^EBij^8%mWc8NuUy(}^tQKtTF+Ws?{pe^>fx1!{k)!f=kWDZ zyxN4Y!}#`8TyDaDQ^VX-w^X?Qh-z`-%+2!lZ5R}&s9Je@z5-QO-QF(XlQs??^z6*7 zTKN@zI#UV`LVJ*GrMgr_nvNV4O+ME^&qA$e#O72=e*UJ1*l67|i*>r6H)^*xVNY^9 zEE3(>fTjXKwxHTwsfr%6ibR?OdPei=S>K(6=t2S%sv@RyDx16g6b*^iHPYrSN zmO%_{yDTA)R&T@4Hu9krmN{AFFX^x~5a1mJSn7K@m0{NjM*e1@0t{9PcfdWByFgwb zIm;nX{EXO4u!&!=ZVe3XmlsMU@=G`@GK*@mr5xT+qrB}=Z!dt)(ekR-V2-h}Ey+O) zP;mvGx?r(VZXk6Fp2_ZfrBtqX(~C=RO~G^US3An*;3z~ClUO%J0RwVGy-*oZ*j=wi z9=9zdloIPGSopS5h!Nyu6>a#gOX)HNm#8ze7a%l|(nu2QYAv4>x-`q3MRH~2yza8O zEw2Ev5yR`_=<@6kGOeZAN86LcY=sR}^IgMYnX82z`GitjV?MNyW>K74=$MALR9N3+H4IWm9+DSSUaz9X zjSVu4VC1_8LcbtKY@L4~Reom8dJV?LFJu{m0mDk}y4RSN@+;VzKqw^sA(@EjkmTL8 zQ8UASiF+K-5XVnje-*lZcezljdx&cJzEOp0SS~bKKpzy7vV=F{(x2qmhEy7zYAnK2AFT-K*B_1Qo8=LKy_91mzApY8tKz?VC?6SGichQf-Tj6t?=d zg7(-bm*7WGmI5G%M01Er8oM{4s_H?xE`>C{>1`G6ODa_F28R_ZHW4fLU_}6h%5G3$ z6|0mt%IeJowVO?<9mZ{55$uK>*z2m-(Db?ngqpc4)nM)F)?F2{MU4q_<+nZKL>>YN zMRQ}LtH3xpLnQ(>s9PqiS1jVmyj4qPQ$2q&co`Ax26dEhaIVqZ0BCHeY&en9h!g-7 ztSh$Dp0*3adRVjDg<6Hld-jvYDTx64=rE&;(eI z8v~lzl2+A&YH9cNwuRm&*$`y0T zgKK4erHVJ9owvcAm*%!+Z!(6n`SNOf4eHRM;DiDN!Umyyy#Ui{ z+iK{P*KKo|#}(`r5{$Lj(5ZHt4y(tA*X4RPy-al{4{d;G5xv#D&#l+cK|@FsBH{>V zcWT~U?2OI9g47C2Rq1zSt6FF*d6ni3*}xHu=I^h2njdc%2D5mjqng%)<3 zSV5QT)kdzlvxEJvFd(oeS3hVrTPoEUABT%-C7eK18jK2qh9Gg+r3otF-g9Mq6oVRg zUO{HoLJdk58jT$rTL*~3fozpMK!+>}ZY90BdsRi*Z(1FD759bn3UZnLBd$`$VMON=9@85`(v9i-jG80cNFot$Giiq{_8I9mW}(!IHbNvAiW2 zM!B<BNW_P7~L69pmEv#arJ z@h-QaimJgN9U5ktY04?yw)RFd{I}9 zRF*(zJuq}0yNgEs#u}wT_Nnp$XaYpMjJgXpP^p51$$+sMWi;=ychpd#I_uLeN=F;) zFRpocEDdf1n1Z``VDlhukg|Klh!b=cE&vd077BGgpSLkafbg_q0Xu!=2cJ5?%5NY? zf_{!%#vrSsKsH=0h!q4X9ag=grCn3_I({*pDgc*4j4NrVn42*aVuZ?uSOgXP2>oRpDkpJtVv8bHh1P z`!s(aS2nbbn+f)Zz-y)ER-uM-X*dBL)gd{@`E<#kx9?=3wOO*Z`I@U~r<^Ks%-~jdbzJ zYmG-pnEVnzMo7QdRwffo3dv|H7zG5!71aihppjC zqvz~RonMn*7bh5T{@rq|T4CsCxLaRzAzKvn1jX`tn2MdQg^f(2`Z}kAlz&9C#}2_+ zKB9kkm~hhzFP+He*L8~$2M;0~#vKCBGhTNq!h_5CN^ysBfqj)AjZn)kM?jzrz&iOW z0EcjA8@pUc$f&&jWyC(nO)%$O+l*5>nq>!-GT}U%WNGIiw$yeNts$=ODzbdkT`Z$? z9D3_$okfJ_sA3Uu@Vbg21>C-XnxKT@9R+vcM#=o?V=w@dt2a_&V}2Rar8^EmM2B<; zftJ+tA|Bm%XcvLS>o{B0ipws*uaqq=o*Y%1l+-4@mBq>qGB-VLm1ugYdKYB5?`sAk z5V~Vz{9PJ|1p*oF>bzF=?&+>pC@*VMy=Mw*^=fTRV9(+hp;A;WCrI8`1MP3O>J?dW z7I<;ZD_+`_cDrV_hAj@*%OcGA#%yKR9JgVj9|p`p>y!}S8S7B`c|F_lV{+N1wd(}} zEPz7n#qGbFUIQskc)r3Er(mJUnz*#?=(`+r+5B62;X(9T1&e`wpT@4bCIyHfoEwIG@FJ#ZBbvNY#<5;_Dh)0?YN>M2{W(^8gFK==^Fw9CB#UkP)!ABk=Cp zv5NTQ$W=hd;)_ECq_<@J^Y}`bx%F3t2=+BKz~<~ZvOsOU+YfA*SiK}68JZv-$p#vp6mmAc1|K~|ju?MdA`NOK(sbqnxIWXwZLz=dp8HGDoxS=gIYDu;x{ z6#CI)0l3uAlB>qG+(Ev9u{a8aLxq5%L&53KCFUII5EjsBS;4SqOhb%!0EsIb;+3nv zXwMa3UB%qVbvwpmyvQ54VCWDa~My|^N?cp@m36nQG( zTjA1Qje^j`_^Kkpy(v{;%pSY`vwNBK3UH!=R4JnTgy_E~x?KaU3c&0N=0?uel{7Ex zWpvd%9#+cC?WO&7j1cr8w~)VyF?n!rFdV)CoH}qX1AEfJ?1|^DVm#F~fg3m&u`+mKpPtY*xMd+VdRv?%se`t3<#m#v)b zV9to$F=9w!Z|r5{M?vV~x5d4{yM)sSwJU0Sj5IJn8R2P@zpT}ST{phiO4 z6P0dYHJs1UL!~`In8mu#3yIPfd(#p*@MRS~5_K%snl@PFY7yxT)a}hOsb}Ju1@xzm zqK^UpcTe){`YsDKAy;2?)+kEj)A?0%RQ>V~!awVoQKk}z&wg}1YY)hKmL*HxoTm!DK zQnS7AY3~>e&|7jCsfQEDWoXn0o2n4lpJP0tZ-icnrVZ_6KiS8GsX_Vg<-K(<{ zHY3903+sYM%rJtdJA0CAcfkFZL^>%8h$$j$OXo`71Z6jbz6|NivEEgT8bv)@^8$5j z*jvqF)HOe@VU$CExMJfX&R+e!ZjUW1(qBPK4ME9MS-faDXeZ5=s22jyKajj$NYozm z&Z#5ClPvTfwKI%uimuK=o2=m9GB6;dAfH2e2PMR@3XJJT%LtQOlBZuly(ZogEanN= z(`ndEea*mQn1NkAf&7fvSwteOKj@E~Bc75ZaJ*HZT_9KhQo-;HK8pB9fni8WS9l3! zcZ8q}S6LH;L~e8)tAI(lV782fq%r`K`M~+eg0LhL_X%{7_}+jr@bHf@ySh}wgQ|sj zx<=}fb99c+@IjrY6LgyjVQ1wt8KKn89F3g);pqyTjXCHJsh&ii&5 zpGO({kS^i5>wX5~II`kB)N+LGI3QpOZX?k*B{WL8+U=~cmTp#=-JFa>3-(!Hs(8}3 z%;MKbnzEj>f6z5~`sUoTAq74Ic5nUTYnDiqBR7yLw(fs_>Eh#l@6nZW=bFL;(3ix@Rw>rZ&E{Ym-wMh(ZXd~P<11CC*7def4x2hPa z7Q#WGZjP#8tMXOD%ROd_eRuHpi;vn1iR{;Bl;vAGmn| zR=3;zI1hK^EF6#H#ys7165dA7T*lLv?+*Hu+#!I;nYw(q7px0^L&q_8viT*n4X zplVEd9sJU^giN7?hIelE$9lhpQm3+%o*ZQwbM!3kl9m? z$R%}@AQTxQt#JLUt36A(z5&g2%RD$=QWy>{j<)`KmrAD5dY6s?WnA?p3sswL2&bx_ zt(@cdL5-Q4zjLzK)5Er!QjoqpH86f)L%5Dcl777N`8#XPI`tE&&rSV`^dQ%%D@VvY znqXhb9FK1lPp%c^%ay23RKK2eZ0+EgtF$gOd}=Ewy9${r#F0C5CEf20FB zDWk*ZwsaAdOgZZtI2xhar*ohOPey|>=OmlSPL0VHW;}2|vz$MjLQ*NB{%O_TlqU_hLVd@ng|!}sGY6>Uxp7HP ziBd(0HdxK7w7SPNcrKiy#-v>9!Hhjd7!69zA!1AY#L>3^ml}rpM|TBOy3Mod&~Epu zpW;fn&3pPnw1MOgLNRH^{9H56od?6_EpiUS2t5KP@2MBW)lpth9Z0&WR^!SNL$0LK zQ>Bw04yD+W8hVM5RtfOJ_k;#+#cKG5iP*(5T69ZW`T2nq%q0 z)j&+$72xuN7-iOx$yN0}YBB+IT@LOdaj628%YBG7Svo3i5}s|y78uFnNL*MII7fUE zk{FP6NUBaH-jD2Rv`QF{J+^!ZX72AI_V3(%&Et1jX91s#i0>;PcN;j+8Rgi_uYj70 zPoBTLIdvGnGFpIwdK(u{o(DXh6(2KyM{=>zFTh33;&&Tyx-^i7l34}bc>L7JD*^*z z@rGX3AbZv^s$K-)>~(KJ_o|~=o2|I3NhYG2RfhB+V#2zUmxP{F6Qn)qWlF@H%*UM% ziaJkOsNfYAA=QK-`;SOLC!aayrdX2)bw|*u7 z9B)vJC^mXA#tDZCu~VUJtKt|b@{`LJ2KiJCy17kvuX|*5Rh5ET*Q-E?p`IS_RtuFO zxz*9lq}@rAKT?TY?Hu{;RaJU0aHK-*Ph|}*xEih{6%7qL<&V5+@bqxj-$hQOGtZj) z7+LfEVTaehbKN-CUYb~b!n4^ac@B3|=6<1S1}eV(<8k$MOs<>qi=!V$)a@I^L?Lxz zWkxSyTs0)-4qNl|jLrf1n5z-R1-fp|5#s95ToBLj*j&x9>Fwa+k=y7+(_r${yPUmS zjWGWbZmH=MZ1rIwBBLoTCk;3!deaHb6t%aJP1gCTdQYsp@8&S+P7+|*eU?&GMYyh4sf zxUOo6ETQq84o0Ain0uWM)@U0J)QNn5N2Yre5{3RNH)Rceo3L}FsJJ*NBjRLPVnUNe zLXv5T51E*!X-+suxPTE%nb+gC&^Caks*14GA15wuLDcDrYD-bqT|*s-YMtuT(Z=M- zY!o~luP#{WHAId@_ND7XDw73xT+i}wI|qy9K@6j`HwCVk?v<+3ONy!&&&Nq{T{>M; zouTeTa2#U5xsq*kWMwFKqu5LZaSs(E;~B+|eavJ;*#Tln1;Vj86KRQfn3$EZPU|gTw@+vb(B8Ki-t7`6C&$F*at0rn4?@%niR(VG$4F&HOy$x z+UzIfU`CA1=|a70&PguT+yaf?1RP9l1%uRIS2`3FH_v z9_A~v|CT_bGfAF^x+F3S%(~6rw7HHRi|8R2m?AE0MEAN1oGGcIE??;0y*2MbKnDS0O-|I?twx1I`{r!=MD@jVFpw~4}hc;yaqf%E2 z2Mh_0GyUik^nMlGtImM9K@pd>y2o2Wd+HYI9MKMY!11!kA+LGS&XAVSLVbBVz%F9l zaH6438>N-szA$(CT_4X0meiTFLWD(kP4}{izn-b79aS3Ww^XRrqrZ}2*87d+?!c%E z?#5I{XN< z!OTaNamFXq6pO|6qYcN2!gvQ>PtMEkuWE1ds+Im{m(iYnu7;aE^-tz-zDNvd4@1y# zQvN8uxej;@Z1shC$2{Mw&#nUI+rYL8eamY}+~tMG5}{kdEu9sh4kKqOubMC30!>~J zO~Lyv>igDF(mC$lFVWJDGtA^yhG-SI@fLM`U9C6eLwyQTk=HoGTIkdCbEg8dw$Zep z=II{q3Pz`X7R~X3o=GXz+)Qf#qj_M++0?M2Ive$&aMJaqP8#tdTlB2B&849}eL)$k z?|1y7ATVC&hCpA9n=p*AIIHj-2sta8>!-b+P&y1NX-n5TU*)9rra zb*~Hc3!_VJTv3XmujVUc?hCk--pS?MK+jvB4b*;f=ub0e*LkqQHSLu~^L&(CM7Esi zH-2z^x>FX-A@$?PKfxCO=t+eo*4*d^_t93zabXXoYA?bmKz|so# zeqY{9QD^p*m&pi-^Zj70VBXaC8vjtL=q+^11GN}(s!uP3F5hGR z7ljk1z3Cf6TmuH=P&cPApX#n(C+CGVbMNZ)S`}-PzPy)N&~7n0Q(PQo;-?s>;+H>u z{a=6h@;~}F@BY`5|M}JbUGt?gA|B67>`M$~j%E%cxyTVR z^FzmDc$DGbzF6ico~W8ir3MW~2jo=33?iFSOqK=`z$p<&*TLaT`;DX-h^6ouA56qD zZzNFB`X}inbQ?=#2V-OWGlQ}8(nPxT_4HDF0MCE~ggAi5Q^~|o3ggG)!zPw){WOJ- z6h23?1L-Avj-`n9*ocWE!}_5t@Ja$Zd<Sj|Cx1`w!#8XcPx?3?~LM1@s{O z{*`hrma#zI{uw?eCt~qu$j;x0$;Z#|K?W^=ixjVK3h+Np9FN6f6VI3-RJOi31jcW@ zKb}aC>ZBTQ1j4}h`$-eWA|sDBS_;Hd%3+)as7;<7NeqL`Dg46<;vH*&ZmH)IPaq>8 z<9Nsa_*g(~Og#=rV4Dx{pB=}>bi7RaN8kYhcH=)3d|Ka5fVY7l1^{}khccUoV1O~O zb^^pX3^^Ntq_+Ny&_@k;KHdK51oOj`4$9CltKxBy(t`&NVhX9$!GlAI0ThD3Q}`Uj z)t3RRMsjKZ7^YHG6&PShSpx0A*<{|guwIanLDDkyjEO@=l6Z}Q=;8W`miK1vtU#dwO-YJHT1Fk_WI+Lssx zpk%uBF{B@eL$DKrz%V7V#vpN(`cww0B_+(8X?=qKsFBtF#0fVN6iHN3FZ~&L=;r|R z`NSxOk%?wj?R+hq)yyiYFaz?`>I9gL6dF@R z?4TG2fbobb%yj$b39$L3nT(AHGjcYf4OPU|>a?M+!?WS?wueR&2~G+e7FYX#kwp1Wh+%DZ$>Vqzjgm@1Gq73a z!D(0se4Mi%Nvs5NN$4aH=74Ci?_eR@PsK7TBiPzwYEl)*cSIAlsrRMbx1j7%tNivY zDf;fH6e&LmAAVQL-;?xvlK!5gzn4rX7p15HSES|#QuBimsre)D8aa!fT(3VK$ErZr z;*A(2nVUr-KAarcM^J32U4Ll1^3%4xbLf(3AIh|!htp)@7>XWAGD$aOoNxPt5@k?VaYx7Y3_6ke zz@ z7XW%X)B3JbFY{nGW2for0AyUSa0TO?T`fMY7N9_XIF#+v9I4I3=ORXhr}ds2^PP$C zn2_`jMuQPkkQhu|;HM_SqY*?O(BE^Q+uc3B2dPJ;vfjIcU_h)$EH#xHh4&;x`ax#V z(d!43D3swR=}r6*SShopGB;`H?)lQDJm)w~q>os`pjnK400YAiNj6mJ92m|l9w2?R zIY#**dJ#j8!*mA(7HHSZV#akNM`l_dqEm99FMb_~0$#7< z^(M4R>&JZi6Xed~bpfxJ6Kc;=1H^D@=KAc@MCGe_xVLwP<4Zp$3iX@%d%P(1-3mFy1h56BdT z=&paAVqTziKTH^Lgl>lu0xENu*`$7qX(@uh!>U(71@?RsE2a!&} zB2O;UGR34Z#1WWAQq10+>R|>H3w-GS+y^X6fjBkhU2+6_ku* zNuH13*ASz#e7nH6mjMi0ghJ9!{P1cOQ=}dy&$F#%dTDFZ7(89%h;V74#KcpO=r8rTi5RU?pfl+az_UQS z@P&yOy!@ytX#qvoo>vxtRpU(ky^2f|W5uzwBtq+bC>XFG-j4EZVd$`|{b8*Az+qV3 z!_?tiQ|My zrVdb1cam;G+; z=>XGRzkDA&C88gwQ^vd!Ggm$pq`AJ&YX3#B>i!jaeVF^F#|mV&ztxHd{@I^UC#)BR zcNRX?3_D=CA2XI`$9J!={Q>pq+29EtM=s#u4U)Gj4BkBE5C7N>GjHP8V?JG%6YTP8 z%v|$FaS8mCwmfI!*5VO7!abk2a)HOz)ax^6^T&@o;vwkfdJGp+9A~=3BO#s>h@HtY2DDjM-+6Jb}(j9S#><1YvP=l?LVrDY;{AFn^1i7Vy zc<@ePyRfrUUtPyTzN(c~_uS-FJe8roS|}eYZx>2leN~^EyXqEZwYv7zRncO8(ezGn z&EytlPn@nj5&#n#bpL{Nl)}o>Bno8=vv&VZ;bIABfU9F8DCa>L4?uY>U>7sup_C`!yTd9Lo|isuj6PS6&@QU) zaX2xso_40MNs#5P)DiX!t^~N>1S5Xu%{bbVB6`hEzYrT>*geKH4%>MBhJWzT(Dxd~ z;5Re2WS0C5xZqN`fw&p`CLG7OVarKDwstr&r_^}VSV~8|62-$?9^nUAM$_T}E?~v% zH7eJqn<4={j+ir;318>1YDI9!X>$^^;`f=>P;v_SQ%Ijd-3)%rgjdGS;on*OE24A* zZO@<$+w&JpVVCiDR@P${oW%=9{AmUK)>nT#xIX`n{=FPCV?gbP6xYA``~Qvt{}+r7 BNCancelling generation... Generation error Image saved to: {0} + Loaded saved portrait No image generated yet.\nClick "Generate Image" to start. API Settings diff --git a/Languages/Russian/Keyed/AIImages.xml b/Languages/Russian/Keyed/AIImages.xml index 3a753e5..c1f9852 100644 --- a/Languages/Russian/Keyed/AIImages.xml +++ b/Languages/Russian/Keyed/AIImages.xml @@ -42,6 +42,7 @@ Отмена генерации... Ошибка генерации Изображение сохранено в: {0} + Загружен сохраненный портрет Изображение еще не сгенерировано.\nНажмите "Сгенерировать изображение" для начала. Настройки API diff --git a/Source/AIImages/Components/PawnPortraitComp.cs b/Source/AIImages/Components/PawnPortraitComp.cs new file mode 100644 index 0000000..f159a8a --- /dev/null +++ b/Source/AIImages/Components/PawnPortraitComp.cs @@ -0,0 +1,31 @@ +using Verse; + +namespace AIImages.Components +{ + ///

+ /// Компонент для хранения данных AI-сгенерированного портрета пешки + /// + public class PawnPortraitComp : ThingComp + { + /// + /// Путь к сохраненному портрету + /// + public string PortraitPath { get; set; } + + /// + /// Есть ли сохраненный портрет + /// + public bool HasPortrait => !string.IsNullOrEmpty(PortraitPath); + + /// + /// Сохранение/загрузка данных + /// + public override void PostExposeData() + { + base.PostExposeData(); + string portraitPath = PortraitPath; + Scribe_Values.Look(ref portraitPath, "aiPortraitPath", null); + PortraitPath = portraitPath; + } + } +} diff --git a/Source/AIImages/Helpers/PawnPortraitHelper.cs b/Source/AIImages/Helpers/PawnPortraitHelper.cs new file mode 100644 index 0000000..39b3240 --- /dev/null +++ b/Source/AIImages/Helpers/PawnPortraitHelper.cs @@ -0,0 +1,90 @@ +using System.IO; +using AIImages.Components; +using UnityEngine; +using Verse; + +namespace AIImages.Helpers +{ + /// + /// Вспомогательный класс для работы с портретами персонажей + /// + public static class PawnPortraitHelper + { + /// + /// Получить компонент портрета пешки + /// + public static PawnPortraitComp GetPortraitComp(Pawn pawn) + { + return pawn?.TryGetComp(); + } + + /// + /// Сохранить путь к портрету на пешке + /// + public static void SavePortraitPath(Pawn pawn, string path) + { + var comp = GetPortraitComp(pawn); + if (comp != null) + { + comp.PortraitPath = path; + Log.Message($"[AI Images] Saved portrait path for {pawn.Name}: {path}"); + } + } + + /// + /// Получить путь к портрету пешки + /// + public static string GetPortraitPath(Pawn pawn) + { + var comp = GetPortraitComp(pawn); + return comp?.PortraitPath; + } + + /// + /// Есть ли у пешки сохраненный портрет + /// + public static bool HasPortrait(Pawn pawn) + { + var comp = GetPortraitComp(pawn); + return comp != null && comp.HasPortrait; + } + + /// + /// Загрузить портрет пешки как текстуру + /// + public static Texture2D LoadPortrait(Pawn pawn) + { + string path = GetPortraitPath(pawn); + + if (string.IsNullOrEmpty(path) || !File.Exists(path)) + { + return null; + } + + try + { + byte[] imageData = File.ReadAllBytes(path); + Texture2D texture = new Texture2D(2, 2); + texture.LoadImage(imageData); + return texture; + } + catch (System.Exception ex) + { + Log.Warning($"[AI Images] Failed to load portrait for {pawn.Name}: {ex.Message}"); + return null; + } + } + + /// + /// Очистить портрет пешки + /// + public static void ClearPortrait(Pawn pawn) + { + var comp = GetPortraitComp(pawn); + if (comp != null) + { + comp.PortraitPath = null; + } + } + } +} diff --git a/Source/AIImages/Models/GenerationRequest.cs b/Source/AIImages/Models/GenerationRequest.cs index 057949d..eec40e2 100644 --- a/Source/AIImages/Models/GenerationRequest.cs +++ b/Source/AIImages/Models/GenerationRequest.cs @@ -48,4 +48,35 @@ namespace AIImages.Models }; } } + + /// + /// Прогресс генерации изображения + /// + public class GenerationProgress + { + /// + /// Процент завершения (0.0 - 1.0) + /// + public double Progress { get; set; } + + /// + /// Текущий шаг + /// + public int CurrentStep { get; set; } + + /// + /// Общее количество шагов + /// + public int TotalSteps { get; set; } + + /// + /// Оставшееся время в секундах (приблизительно) + /// + public double EtaRelative { get; set; } + + /// + /// Идет ли генерация в данный момент + /// + public bool IsActive { get; set; } + } } diff --git a/Source/AIImages/Patches/PawnPortraitCompPatch.cs b/Source/AIImages/Patches/PawnPortraitCompPatch.cs new file mode 100644 index 0000000..261faf3 --- /dev/null +++ b/Source/AIImages/Patches/PawnPortraitCompPatch.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using System.Reflection; +using AIImages.Components; +using HarmonyLib; +using Verse; + +namespace AIImages.Patches +{ + /// + /// Патч для добавления PawnPortraitComp ко всем пешкам + /// + [HarmonyPatch(typeof(ThingWithComps), nameof(ThingWithComps.InitializeComps))] + public static class PawnPortraitCompPatch + { + private static FieldInfo allCompsField = AccessTools.Field(typeof(ThingWithComps), "comps"); + + [HarmonyPostfix] + public static void AddPortraitComp(ThingWithComps __instance) + { + // Проверяем, является ли объект пешкой-гуманоидом и нет ли уже компонента + if ( + __instance is Pawn pawn + && pawn.RaceProps?.Humanlike == true + && pawn.GetComp() == null + ) + { + // Создаем компонент + var comp = new PawnPortraitComp { parent = pawn }; + + // Инициализируем компонент + comp.Initialize(null); + + // Получаем список компонентов через рефлексию и добавляем наш + var compsList = allCompsField.GetValue(pawn) as List; + if (compsList != null) + { + compsList.Add(comp); + } + } + } + } +} diff --git a/Source/AIImages/Services/AdvancedPromptGenerator.cs b/Source/AIImages/Services/AdvancedPromptGenerator.cs index b927114..8e3d90a 100644 --- a/Source/AIImages/Services/AdvancedPromptGenerator.cs +++ b/Source/AIImages/Services/AdvancedPromptGenerator.cs @@ -63,7 +63,14 @@ namespace AIImages.Services StringBuilder prompt = new StringBuilder(); - // 1. Художественный стиль + // 1. Базовый пользовательский промпт (если указан) - идет первым + if (!string.IsNullOrEmpty(settings.PositivePrompt)) + { + prompt.Append(settings.PositivePrompt); + prompt.Append(", "); + } + + // 2. Художественный стиль if ( ArtStylePrompts.TryGetValue(settings.ArtStyle, out string stylePrompt) && !string.IsNullOrEmpty(stylePrompt) @@ -73,14 +80,14 @@ namespace AIImages.Services prompt.Append(", "); } - // 2. Тип кадра - автоматически добавляем "portrait" для генерации персонажей + // 3. Тип кадра - автоматически добавляем "portrait" для генерации персонажей prompt.Append("portrait, head and shoulders of "); - // 3. Базовое описание (возраст и пол) + // 4. Базовое описание (возраст и пол) prompt.Append(GetAgeAndGenderDescription(appearanceData)); prompt.Append(", "); - // 4. Тип тела + // 5. Тип тела string bodyType = GetBodyTypeDescription(appearanceData.BodyType); if (!string.IsNullOrEmpty(bodyType)) { @@ -88,14 +95,14 @@ namespace AIImages.Services prompt.Append(", "); } - // 5. Цвет кожи + // 6. Цвет кожи string skinTone = ColorDescriptionService.GetSkinToneDescription( appearanceData.SkinColor ); prompt.Append(skinTone); prompt.Append(", "); - // 6. Волосы + // 7. Волосы string hairDescription = GetHairDescription(appearanceData); if (!string.IsNullOrEmpty(hairDescription)) { @@ -103,7 +110,7 @@ namespace AIImages.Services prompt.Append(", "); } - // 7. Настроение и выражение на основе черт характера + // 8. Настроение и выражение на основе черт характера string moodDescription = GetMoodFromTraits(appearanceData.Traits); if (!string.IsNullOrEmpty(moodDescription)) { @@ -111,7 +118,7 @@ namespace AIImages.Services prompt.Append(", "); } - // 8. Одежда + // 9. Одежда string apparelDescription = GetApparelDescription(appearanceData.Apparel); if (!string.IsNullOrEmpty(apparelDescription)) { @@ -119,13 +126,6 @@ namespace AIImages.Services prompt.Append(", "); } - // 9. Базовый пользовательский промпт (если указан) - if (!string.IsNullOrEmpty(settings.PositivePrompt)) - { - prompt.Append(settings.PositivePrompt); - prompt.Append(", "); - } - // 10. Качественные теги prompt.Append(GetQualityTags(settings.ArtStyle)); @@ -136,7 +136,14 @@ namespace AIImages.Services { StringBuilder negativePrompt = new StringBuilder(); - // Базовые негативные промпты + // 1. Пользовательский негативный промпт (если указан) - идет первым + if (!string.IsNullOrEmpty(settings.NegativePrompt)) + { + negativePrompt.Append(settings.NegativePrompt); + negativePrompt.Append(", "); + } + + // 2. Базовые негативные промпты negativePrompt.Append( "ugly, deformed, low quality, blurry, bad anatomy, worst quality, " ); @@ -144,7 +151,7 @@ namespace AIImages.Services "mutated, disfigured, bad proportions, extra limbs, missing limbs, " ); - // Специфичные для стиля негативы + // 3. Специфичные для стиля негативы switch (settings.ArtStyle) { case ArtStyle.Realistic: @@ -159,12 +166,6 @@ namespace AIImages.Services break; } - // Пользовательский негативный промпт - if (!string.IsNullOrEmpty(settings.NegativePrompt)) - { - negativePrompt.Append(settings.NegativePrompt); - } - return negativePrompt.ToString().Trim().TrimEnd(','); } diff --git a/Source/AIImages/Services/IStableDiffusionApiService.cs b/Source/AIImages/Services/IStableDiffusionApiService.cs index e47ef7f..6d77d3c 100644 --- a/Source/AIImages/Services/IStableDiffusionApiService.cs +++ b/Source/AIImages/Services/IStableDiffusionApiService.cs @@ -18,6 +18,11 @@ namespace AIImages.Services CancellationToken cancellationToken = default ); + /// + /// Получает прогресс текущей генерации + /// + Task GetProgressAsync(CancellationToken cancellationToken = default); + /// /// Проверяет доступность API /// diff --git a/Source/AIImages/Services/StableDiffusionNetAdapter.cs b/Source/AIImages/Services/StableDiffusionNetAdapter.cs index 3a89d04..cd8fc8c 100644 --- a/Source/AIImages/Services/StableDiffusionNetAdapter.cs +++ b/Source/AIImages/Services/StableDiffusionNetAdapter.cs @@ -137,6 +137,42 @@ namespace AIImages.Services } } + public async Task GetProgressAsync( + CancellationToken cancellationToken = default + ) + { + ThrowIfDisposed(); + + try + { + // Используем Progress сервис библиотеки + var progress = await _client.Progress.GetProgressAsync(cancellationToken); + + // Маппируем на наш тип + return new GenerationProgress + { + Progress = progress.Progress, + CurrentStep = progress.State?.SamplingStep ?? 0, + TotalSteps = progress.State?.SamplingSteps ?? 0, + EtaRelative = progress.EtaRelative, + IsActive = progress.Progress > 0 && progress.Progress < 1.0, + }; + } + catch (Exception ex) + { + Log.Warning($"[AI Images] Failed to get progress: {ex.Message}"); + // Возвращаем пустой прогресс при ошибке + return new GenerationProgress + { + Progress = 0, + CurrentStep = 0, + TotalSteps = 0, + EtaRelative = 0, + IsActive = false, + }; + } + } + public async Task CheckApiAvailability( string apiEndpoint, CancellationToken cancellationToken = default diff --git a/Source/AIImages/Window_AIImage.cs b/Source/AIImages/Window_AIImage.cs index 68093a3..2aaee78 100644 --- a/Source/AIImages/Window_AIImage.cs +++ b/Source/AIImages/Window_AIImage.cs @@ -36,6 +36,12 @@ namespace AIImages private string generationStatus = ""; private CancellationTokenSource cancellationTokenSource; + // Прогресс генерации + private double generationProgress = 0.0; + private int currentStep = 0; + private int totalSteps = 0; + private double etaSeconds = 0.0; + // Сервисы (получаем через DI) private readonly IPawnDescriptionService pawnDescriptionService; private readonly IPromptGeneratorService promptGeneratorService; @@ -74,6 +80,24 @@ namespace AIImages { appearanceData = pawnDescriptionService.ExtractAppearanceData(pawn); generationSettings = AIImagesMod.Settings.ToStableDiffusionSettings(); + + // Загружаем сохраненный портрет, если есть + LoadSavedPortrait(); + } + + /// + /// Загружает сохраненный портрет персонажа + /// + private void LoadSavedPortrait() + { + if (PawnPortraitHelper.HasPortrait(pawn)) + { + generatedImage = PawnPortraitHelper.LoadPortrait(pawn); + if (generatedImage != null) + { + generationStatus = "AIImages.Generation.LoadedFromSave".Translate(); + } + } } /// @@ -100,6 +124,11 @@ namespace AIImages { this.pawn = newPawn; RefreshPawnData(); + + // Очищаем старое изображение при смене персонажа + generatedImage = null; + generationStatus = ""; + generationProgress = 0.0; } /// @@ -146,6 +175,9 @@ namespace AIImages isGenerating = true; generationStatus = "AIImages.Generation.InProgress".Translate(); + generationProgress = 0.0; + currentStep = 0; + totalSteps = generationSettings.Steps; try { @@ -173,18 +205,41 @@ namespace AIImages Model = AIImagesMod.Settings.apiEndpoint, }; + // Создаем отдельный CancellationTokenSource для мониторинга прогресса + var progressCts = new CancellationTokenSource(); + var progressTask = MonitorProgressAsync(progressCts.Token); + // Генерируем изображение с поддержкой отмены var result = await apiService.GenerateImageAsync( request, cancellationTokenSource.Token ); + // Останавливаем мониторинг прогресса + progressCts.Cancel(); + try + { + await progressTask; + } + catch (OperationCanceledException) + { + // Ожидаемое исключение при остановке мониторинга + } + finally + { + progressCts.Dispose(); + } + if (result.Success) { // Загружаем текстуру generatedImage = new Texture2D(2, 2); generatedImage.LoadImage(result.ImageData); generationStatus = "AIImages.Generation.Success".Translate(); + generationProgress = 1.0; + + // Сохраняем путь к портрету на персонаже + PawnPortraitHelper.SavePortraitPath(pawn, result.SavedPath); Messages.Message( "AIImages.Generation.SavedTo".Translate(result.SavedPath), @@ -218,6 +273,45 @@ namespace AIImages } } + /// + /// Мониторит прогресс генерации и обновляет UI + /// + private async System.Threading.Tasks.Task MonitorProgressAsync( + CancellationToken cancellationToken + ) + { + try + { + while (!cancellationToken.IsCancellationRequested) + { + var progress = await apiService.GetProgressAsync(cancellationToken); + + if (progress != null && progress.IsActive) + { + generationProgress = progress.Progress; + currentStep = progress.CurrentStep; + totalSteps = progress.TotalSteps; + etaSeconds = progress.EtaRelative; + + Log.Message( + $"[AI Images] Progress: {progress.Progress:P} - Step {progress.CurrentStep}/{progress.TotalSteps} - ETA: {progress.EtaRelative:F1}s" + ); + } + + // Обновляем каждые 500ms + await System.Threading.Tasks.Task.Delay(500, cancellationToken); + } + } + catch (OperationCanceledException) + { + // Ожидаемое исключение при остановке + } + catch (Exception ex) + { + Log.Warning($"[AI Images] Progress monitoring error: {ex.Message}"); + } + } + /// /// Запускает генерацию изображения (обертка для безопасного fire-and-forget) /// @@ -288,6 +382,20 @@ namespace AIImages float contentY = 0f; + // Портрет персонажа (если есть) + if (generatedImage != null) + { + float portraitSize = Mathf.Min(scrollViewRect.width - 20f, 200f); + Rect portraitRect = new Rect( + (scrollViewRect.width - portraitSize) / 2f, + contentY, + portraitSize, + portraitSize + ); + GUI.DrawTexture(portraitRect, generatedImage); + contentY += portraitSize + 15f; + } + // Секция "Внешность" Text.Font = GameFont.Medium; Widgets.Label( @@ -332,77 +440,10 @@ namespace AIImages { float curY = 0f; - // Превью изображения - if (generatedImage != null) - { - float imageSize = Mathf.Min(rect.width, 400f); - Rect imageRect = new Rect( - rect.x + (rect.width - imageSize) / 2f, - rect.y + curY, - imageSize, - imageSize - ); - GUI.DrawTexture(imageRect, generatedImage); - curY += imageSize + 10f; - } - else - { - // Placeholder для изображения - float placeholderSize = Mathf.Min(rect.width, 300f); - Rect placeholderRect = new Rect( - rect.x + (rect.width - placeholderSize) / 2f, - rect.y + curY, - placeholderSize, - placeholderSize - ); - Widgets.DrawBoxSolid(placeholderRect, new Color(0.2f, 0.2f, 0.2f)); - Text.Anchor = TextAnchor.MiddleCenter; - Widgets.Label(placeholderRect, "AIImages.Generation.NoImage".Translate()); - Text.Anchor = TextAnchor.UpperLeft; - curY += placeholderSize + 10f; - } - - // Статус генерации - if (!string.IsNullOrEmpty(generationStatus)) - { - Text.Font = GameFont.Small; - float statusHeight = Text.CalcHeight(generationStatus, rect.width); - Widgets.Label( - new Rect(rect.x, rect.y + curY, rect.width, statusHeight), - generationStatus - ); - curY += statusHeight + 10f; - } - - // Кнопка генерации/отмены - Text.Font = GameFont.Small; - if (isGenerating) - { - // Показываем кнопку отмены во время генерации - if ( - Widgets.ButtonText( - new Rect(rect.x, rect.y + curY, rect.width, 35f), - "AIImages.Generation.Cancel".Translate() - ) - ) - { - CancelGeneration(); - } - } - else - { - // Показываем кнопку генерации - if ( - Widgets.ButtonText( - new Rect(rect.x, rect.y + curY, rect.width, 35f), - "AIImages.Generation.Generate".Translate() - ) - ) - { - StartGeneration(); - } - } - curY += 40f; + curY = DrawImagePreview(rect, curY); + curY = DrawGenerationStatus(rect, curY); + curY = DrawProgressBar(rect, curY); + curY = DrawGenerationButton(rect, curY); // Промпт секция Text.Font = GameFont.Medium; @@ -488,6 +529,13 @@ namespace AIImages { float height = 0f; + // Портрет персонажа (если есть) + if (generatedImage != null) + { + float portraitSize = Mathf.Min(400f, 200f); + height += portraitSize + 15f; + } + // Заголовок "Внешность" height += 35f; @@ -510,5 +558,95 @@ namespace AIImages return height; } + + private float DrawImagePreview(Rect rect, float curY) + { + if (generatedImage != null) + { + float imageSize = Mathf.Min(rect.width, 400f); + Rect imageRect = new Rect( + rect.x + (rect.width - imageSize) / 2f, + rect.y + curY, + imageSize, + imageSize + ); + GUI.DrawTexture(imageRect, generatedImage); + return curY + imageSize + 10f; + } + + float placeholderSize = Mathf.Min(rect.width, 300f); + Rect placeholderRect = new Rect( + rect.x + (rect.width - placeholderSize) / 2f, + rect.y + curY, + placeholderSize, + placeholderSize + ); + Widgets.DrawBoxSolid(placeholderRect, new Color(0.2f, 0.2f, 0.2f)); + Text.Anchor = TextAnchor.MiddleCenter; + Widgets.Label(placeholderRect, "AIImages.Generation.NoImage".Translate()); + Text.Anchor = TextAnchor.UpperLeft; + return curY + placeholderSize + 10f; + } + + private float DrawGenerationStatus(Rect rect, float curY) + { + if (string.IsNullOrEmpty(generationStatus)) + return curY; + + Text.Font = GameFont.Small; + float statusHeight = Text.CalcHeight(generationStatus, rect.width); + Widgets.Label( + new Rect(rect.x, rect.y + curY, rect.width, statusHeight), + generationStatus + ); + return curY + statusHeight + 10f; + } + + private float DrawProgressBar(Rect rect, float curY) + { + if (!isGenerating || generationProgress <= 0.0) + return curY; + + Rect progressBarRect = new Rect(rect.x, rect.y + curY, rect.width, 24f); + + string progressText; + if (totalSteps > 0) + { + progressText = + $"{(generationProgress * 100):F1}% - Step {currentStep}/{totalSteps}"; + if (etaSeconds > 0) + { + progressText += $" - ETA: {etaSeconds:F0}s"; + } + } + else + { + progressText = $"{(generationProgress * 100):F1}%"; + } + + Widgets.FillableBar(progressBarRect, (float)generationProgress); + Text.Font = GameFont.Tiny; + Text.Anchor = TextAnchor.MiddleCenter; + Widgets.Label(progressBarRect, progressText); + Text.Anchor = TextAnchor.UpperLeft; + return curY + 30f; + } + + private float DrawGenerationButton(Rect rect, float curY) + { + Text.Font = GameFont.Small; + string buttonLabel = isGenerating + ? "AIImages.Generation.Cancel".Translate() + : "AIImages.Generation.Generate".Translate(); + + if (Widgets.ButtonText(new Rect(rect.x, rect.y + curY, rect.width, 35f), buttonLabel)) + { + if (isGenerating) + CancelGeneration(); + else + StartGeneration(); + } + return curY + 40f; + } } }