From 3b6246f25650c296d2f9ce0daa53aa6030b9deac Mon Sep 17 00:00:00 2001 From: Tao Chen <42793494+IamTaoChen@users.noreply.github.com> Date: Fri, 30 Jan 2026 00:40:28 +0800 Subject: [PATCH] [Template] SSH Linux - Add support for deploying Coder on existing Linux systems (bare-metal installation) (#605) ## Description A draft that allow user connect existing linux system though coder by ssh ## Type of Change - [ ] New module - [x] New template - [ ] Bug fix - [ ] Feature/enhancement - [x] Documentation - [ ] Other ## Template Information **Path:** `registry/IamTaoChen/templates/ssh-linux` ## Testing & Validation - [ ] Tests pass (`bun test`) - [x] Code formatted (`bun fmt`) - [x] Changes tested locally ## Related Issues --------- Co-authored-by: DevCats --- .icons/linux.svg | 438 ++++++++++++++++++ registry/IamTaoChen/.images/avatar.png | Bin 0 -> 55432 bytes registry/IamTaoChen/README.md | 16 + .../IamTaoChen/templates/ssh-linux/README.md | 58 +++ .../IamTaoChen/templates/ssh-linux/main.tf | 319 +++++++++++++ 5 files changed, 831 insertions(+) create mode 100644 .icons/linux.svg create mode 100644 registry/IamTaoChen/.images/avatar.png create mode 100644 registry/IamTaoChen/README.md create mode 100644 registry/IamTaoChen/templates/ssh-linux/README.md create mode 100644 registry/IamTaoChen/templates/ssh-linux/main.tf diff --git a/.icons/linux.svg b/.icons/linux.svg new file mode 100644 index 00000000..6b558e7b --- /dev/null +++ b/.icons/linux.svg @@ -0,0 +1,438 @@ + + + Tux + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/registry/IamTaoChen/.images/avatar.png b/registry/IamTaoChen/.images/avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..f14100c4a7e280c29ea6416127e94e611046d678 GIT binary patch literal 55432 zcmeFZS6Guz*EbqOKtOttjsgNwrAa3sQWcQiiHOo7(t8Pth*G6X?@daicLLIT2LV?~s!H)9|nEl9S#2 z=gmJ~^52)jjIsAiw3vi2ufRKjZrU$@@=acBa*uyjX z-;LlF;cX&f5PR^cQ-afv5{sCd1!aqlR`5Kv!n3SB7`aLZ@zo4+FxTLh~M@?;AeM4hYbIY&p zp5DIxfx)4v>6zKN`QLvQ*48&Rx3+h7_x6z|r)TFEm#C}jf8-(n5dODV`2PPA07CQ z4*W+4{%_F%Qo^#_Tao<#lOB;1%uL*x)HF9O>m{lwERh5d-~L9WTj&23yT69JA7qb` zKwu*Qqcv^|4?gp@tL^*PyJfusI z`}qCmHn=6W4Cnx)a9UZop6`d=>2|#VD2{)rgrQp2Fs3&EB3A6zAnE)Yz%Mo6A$hKK zKH~n*8M_pX8$hUi@`Q&Ggsk~^h88dg9XsZLboFy0^u{ByALews-ivgNJj>CWPEJt0 z0az;x73D*^Mu0zw;6yB-Xwy*zI}NHh%vZIES%Kq&oPy4e;uH^Fwd?qC{sN)+a}K^D zm#3bf0+Fz1Xsf10JMXgo+c$vABUPJJPh{$vdYs(__W8Pc1U;x%s;_|FtN&oTQRD5@ zH}OVQ8zZ2L-kwni>=Vr!=7Kl6U-t6 zf1myQE#NFXYIUe25afxfM@IDQ^sLZh{2}Y)$A^SIQ_hXz&mRop`1nTp=WJ$27vUBO znq~fC@iZMexdNHj{A+qmWx6@`7sV$7-j{q=vsyGGmbW+v`Wc1|DxCzac8%=V8`J5<8xOsgEIiVz_igq5Jv4yknEgVTmEQH9@KflD^Ss<`|vAxe&W2! zajdOwTfS`4P$N0#?%%(fJYWz1Gm@*>dPG6nD|X4osW}M@eEu+qC)?z>md$4zzaGV5 z-HsrzB~oWLOL245gqU5APKkZ?_J`cl``$po`&=qF02jde&o=KLL8?trXrKwwrMqPC zWWWRH3sM_ji}F?IzBVOAa<3%?w3lnq16;E9wm% z8$ANn1m5dhK|Q)WEJG`SC-#@AP=D6tht1rGVzBc$)PyLAeCO`L1JR6v1%kxZyfNf<^RR%H+*L`TsZ^zcwO^W1 zmwu}1C1jNk!={F&3bJahM_fj|m&zgEPk1fOQuO&gC1mjsWDz8cEde^*0HQ9O{1LDX z)6eH?{6pP#WokT4HvrF&8^9DS`8kwoU(BOiH0u*E_6lf|%n%6{W zoEd!wJW{JUm&5SzC^zpV_6_Zjqj1}D0@rRlXqB=Ww>14h=Bj1>)DA6i1L$%Fx&r_7 zY1XyE*sW3JIs>=ZyOruNyF_yk7nxkx{xyEHYu|AjD}{1FocND$Jc3R^9L z-MInS0wanqd+xdIcks1Ej7$Z|Q>=`OVkK9wV>6D{GIELf8jTnuR4)P#Ry*NG7*C{N zpGkmy>U+&}^J6lX{+W~D@DRt4MF_%uC#;R#^9M!}n<7~qSk}FTO$EW8awm=)eZ2v| z*|uR~HvnhRMU9JWY)hMy?|M!okh-4g;F2b3BCq+;-M4c7?%3`bobj-q^xAnSNMOw~ z+uXQ79tK?%9O<=7e&o?}`Lo#|;WB;^<9Gx3_zkxRtE*}iDOo>`mP39tfUJXD{b-kI zZU8UVq4$ERdVCvsPYm59G(CDcrunewJ)8LwKTEA7frp<|UHz5puDmKmQRu-VwFjQCe zIsxjnYsH}qC$-tpMD7;2sE3(Flj3?IGtQpICL(?iV?&ZZTL6a{li|HRo~N4qw@vA8 zPd`&xs*BvKV|V-BR<;O?G4K`Uelm5UL)T-g_29WXNEP#NPG{`PH^~U$0cducv3;+4 zexyfDNb)|6@ErLlb{--?Lf?=)7AZ1SeK0Y2{~amoY5B_p^@CI62M@l}ELV14g72#D zysDC)dtXnI<-+5T$57mvEM;*b#^s`jDld7%SAE(aduBAHpm$OCl;9oGBKvOksuhue zPhzHh15VI!;;(DEZSsD19mb|aMwtDuPwluD zI<~OifUE1E1=rPvYL{G$d&_hisIWi0JsWrOtkrn0k8YSP;1tBO52A8-kx0CjUB28r z>e-dJxILwjgtrP6zHs7BT1z+Byc~$RMZ--!uVt~(u+<-+8qi^0o>R;kh^e;-+!7k( z7iiqEC`&pIJ5~!;uPu00HlTP1y2+|MQ-2Hq7xXAG!kVVfnGml!K5jKu$$9@{G}wYr zqI!p7Xc_B2ew^#sg$kx?mO_HvWt+>qGCdxgu6jf5WHRaAdiNMobz?HUf%()P5^6z< zXcjzvK7%=kE*f@SwDkWPr?;#s-%|HxzvX7)*YCy+$KT7)g6|&&*IVfH>_)R>r%~|_ z=`*I$Gr5~@4Da*jM*{xc^oZ%3_#-Fj2kd^idPYHi@MbwRwjRfU>ju{1N|4~b$K_Vl zj*>27@0A0G8`<%wq_A-VFz0)}qyv%4sdGJii`2NNM9o8x&(}*Lbq;5bN-fxrf(m6f zhINr~N2YD~2?~L%=4T6Ii*5j5m%ufW@N>V^?htCHcXgBOb13L1kC0OcH0{2UO-L5} zbjuq)6(-&5J~k1+ve9d-@5Hf8LRmI#kh0Ubi&Kh~rN?A?JpfnY0k%ipZHO%HSI7GX zB+BZU`z^%$k!G2SdExm;nmQ!amvwZd}o0?JZ^E^~pm1Tfl^aXK?ymf$2-&^=G zNYc+?9r~?1cn|}h2$Dr=FYoe8yqTA1RIM~FX;ln%y>HhX!CPdR;UQKx&sTz~=6mKQ zBk&mPJZx+}!IKA1AkMClysv`PQZfRP_K=enj-VD&i?JeBVz7s6nL zO|%5t%Lr&N7(B_dNFFb&crX1cmP8+JdRRs3Qg~T0%J6LAjR9d!lJRd-O4*Ibp_Y~x zN4mR{KGC_aohzoF$&8w%<K?ajEBba;->&DO>}%1?VJyh@w8HOG8rPKW7~Y2N zc$a>wNQ(JiPxp%k`wg|W3fx|X7*)<-9oZdkFMZB30K&3tPMa%z_e^xe>KT z(k9i(ZvGpU9;pj&+%;>OnoOQPxh*619Pbf(T6?)maUG4Z{N^``seo81u^^=*+Q9iL z>maIqpUVc*>ae>%tx0Ls6a!4vW13Y7=3p6AC_YyVBliX#n>U7CDgAPKq_giMqC4!Ji5ZMjDDK6qk4xJL6UkkgXUh^mM8X1u^w!Xcb zB~3X~sCI?3FjWpTB8xX5beF&Q>HcfO%%Fm>vy$`5*!%zP@C}p_3saH>9!#PcFq)_l z5efHvKa;fzmU~@j)&8wKjzUcpjNoG7n6BVP4obw45J&m|Iaw)!utQ|O0-lawt7P^R zqlyzt6OSOg%Y4YHqV*j5WmJhtlfMQ0<*-C%;vhLL_=ohjVxz>b!Oa|AE(7{u~aGnsm&T zPXAjp+eLkwX^rEZt4|FC$0&vLjB~EwpS29;urj!2Tm2Y}nLM7rQ<$7M&gQVY%(H5679A zn#`>f5nI2o$I{~q&}(9_J&n@~$g!BtZK-u2Bjuj2x8-l|z2nI{o)x53RPl0y^>sj%|&R&cKuWp1ZDRB(GQNdaaz++Ufj1)d7ldrI1Z9e(LD;=kA(;Zq}eh`UHzx~WJyt2!K1RtKsoKlpNr~NBNrXFa*TOu+Cl-8bZX?j`0 z`_tPgbd0r#QQ*1i2UK_nqm!xceTa5H3gX4vJRo}ot5ij@VCOD2g!@+ZjFjlDC9ACC zSZ@H8Bx$~fNnj58r6$t4l=Es_o8^MG4>=kU#%vHpzBx-bnR?YF4eG!dj9m~Yj~szX^V zB)^FH7@~A&mil9s|Z9lToBIig}2>vQ%zzkR~IsGY9r8==C zRQ}_#gtU{1xQv-8yAD<3&l|cW+^x`BQ`zfiVe{#JUAU&Ar+K!0*HkjEP$y$cuCCUn!dUh9){(^2rlH5jwJ zKp)STMy2-!%f=EQBTni3bUeHbBtGz=Dv1jvK`r}V_6k*n5aRH1M%rl5W`)1fzIrGVShgR|r+sOWQM@MOOv;21+%A?*)f(85I z;VpShhy|COt*Wmj_KCv%H-M_P(>0DNA&lIIMIL^f@l1auws1>bZnAn;zg)ZTbCE1x zKyyWwy4_|9U%if}cgM=Z=891Zj|QUMi_)|);az`{J_@)hR!j0( zpwIHWDr9-jGt?P#PuoqxB2Z@0lf&B!H>16wkERv0N1YigWsfaelv>?y zzkd3gK2X4Zs9rS*bpu#)QX1v?=50E_)dVA1YL1lP$?;K^g&H9T!z`z=oj83|IE(xl zp`l_FWuZ%?%N5EZ~f=!GN8!cMVZa)~F< zIX2nbtg}BwZ%yN(!r=pRRS=k)6aEO&K(HrFDjz;sFEz<6WnmdBkv@`Wwwi?%sB7uE z0c0n){*J0SpV5WAsD8jFnpHeh4Fm3fU5*ju2_~f9uy0olwy2rvBI?bfYR*@LCY>1zO;P20B4h zXcvrV{dE0O$QY1m5AmpFx_5wfB-CzW=e^!w~<&4v;Pt3<267L*IZ@`}nZqTiN=cXMB}DtW%v`za9eTdn z>q0@c>z9dLX+b4D^}jw}r`7BkeX7hh|Fz8_A0^){oy|Ars+OD_O=q)jIC=vRngX6D zqe$^^9)Xvu-LK#x6Ip-!D<_;~bQBtXcA1p6Zbi}kW%C7uJ-FZoK*AofEQ*j{&1yUt zT?J7)r)2XWLpTE46%pUM*T^*4Oy$Q*tH=`3Pi=aqtx6& zt<^f9h$wLH=&%@jT8zJOMn_50Pv2KgCt|Z-FcO0K=loJh9Vu2dZ zH80GTb>cBRm^A1slpvZl$N_cI={VHs!7F9iRU#G1$;#BNb9`zq*ydTT&1{k{wk%4642X5a6Tr@%a0@jnBa~c!OQb+p>q? zdz4<9o|QvUFx8stZ}{rbC+hB1xbNb`FpgnsW^{(LDb9kKJE3iSr#a*vM#sImg9S`} zCKyjepCCM+MmwCjyPL1N}E+?fP?`{;&+K7jX*1+ z*2mP^5Q<+!@%hbjXiA4Tq>C8G41SWD;0Jh;CFK9=^^0gMh4;&`$H`u0jM2_-rXnwy zubvn0Th9Bx7xy0pSu2NyL*_cZpeFHI(g18ej!Es|TomvkyqwlZbihri{I&C8>w*5D^mAv73DY{Ew0aJbsHF=-I9LwKV@1(PGYk))YcCDo;^(^YA3DAo(IvY z6aSGte@W!8SXK3t|LG||ZmnU&Zufk0m*ucLd`SZB04#b}A3(v|DBl|MLdW*Pwl$@S z){J)8JS&o;nW3Gy2I}^OmD}5HKb1K6^&6uSdv&g<>SaGqBhp*8tz;_=b8-ND?hX8D z^7w_jKv=AxiLidyhxD)97PZL+77DmT)88BA zZe*FZJ0?@9!2IDcr+dO*e0(2_I0G)mh(1cONC5;?VPyMIq+3? zw*A&v;U+bOe)ewdo9c=`QoZCK1=`Y^L&D&_qOT^Jw;e})+(KOE$_BkUw?Oemi!Vhe zbp=H0v;L5j#g{5pCYmTL;`LoF!!{$ULGziU>W$b2yJ3hP@=_}0E%Y$-O_62R#e?D6<1}|L&vL2 zWntvpFlv!MUJ6`|=4_ZNKy%^duO-tz=efG9foPZLXNy}qes>rp5TeJgod!~1MOX>L zFr%MgM%CXHOlf+BUQnvU^r=8Mly=P9V$W?x4r9k$AJggDQpiNbXWomywxz`6DVfuM}PSAT=0n5{Xr2|h$VqJQ;jYF=wQoL*m< z=wC^m93n`c#8p=+8^7`%-wvJP4982)VO$RcE?CS*SQ#XR$LK+9u11$0zW5==E6_#V z(goDBN10>G)i};(@SHwz_y%Bwspf&iusS>GvK?UX-s#7rkm+n8Y%>HbN{@N@`FiV& zv^ZX}Remui`E|6v&m`qi=XIRLNfuRSi%*7VhE&62Pq?9pB$*t@WYMJeXMy$UE* zGL8gM*}O?8t1ut-HRs8LK~B9-g#|i1_PT@bDrjUXbe`^I4Wjv^N-AtVncTN?+-?uM zpui?VfsRxxR4jh!!-I&?OsqSuW?%0LzaR~elR1l1v8FgX4wrHDPl`pl=Iqi35@-r% z5W_ja#yC4kgq8>%HHU90E5XKK&lLz)L3jP`>FNNLCvsmlb&*HLb%l`CBRXOwgE=HW zFVK_UR%R?Q7au0cEfPYADWRA4Q#{~{K@miLDGf?c~(8fmO=X_HgI@2zk~Fd%k%A-_d0 zl2MNWCC1kt9UXMDkCRbva8z$xZNo|k)>_S}M&!=NwYLmgO zJUOw~657ykGMnK8P=slBEOY;P$923{%P`1E9p<@n11PkctOQm*>??lgDR;(=`hYXm zF0|Pzf@eL%59!)sz;V^zBm0ugz9U+HEbE5-t- zcq(Sj%US=QNOFi@h_?VLQjPWd2j%ANI5jy0@MQW1z>y1%n!&G0NBKBpP1Jj1E7z}U z{J!wJ@1CRCF&quRom|ZRo4F56rzATz?wrxAiY66&QJJf+^helcsZ^~kgx+Z7pcv%Q zHWGcu{Zc)asCYMW*s8!^n+G5IS2)8tW`brZ>-Jwh9_0Gw{Bp}I%=8mWq>zy z500a_Xug+&cuo~zK+~Ck_kpyFpj*BsGh40luiGAM?GizZa}X-9+xX22c z4oXzxaC#lKpn5Si+d=0PQ0ThGNiM%Px5qwyG&X=~{lKgECII(INh(O=C(0ZV*8`zF zH~(nqc&#(K`6&}p9+!K0Dh3*WeDTiG=*^+=#s&mVf%NBG-!FL1q&;ND0!pEx4xf|a zGzgz(=S?~mZmI_mesez@mD`#bA$>1{b&~u_M-eI$2i!20;(RQJ6*W@hapXm8Tcftp6PG|+_IRV4NeN*{slhLN`sIjn;2 zIKiD*|w**8;Mf4HF;z|KG++- z{_6uRlSF$ywo)e+iw-m$vNzt|m&wuiSU|$KyrWvI{8Ef^hdcAKGFY7Jll#@2NVW*I z3&}#GWS5fZ8C3l7yL0aRYABiJm^g{{Y+V$Y%y#LYz7Ybcau;U68`G!7lW&Lli)EN_ z0)OgbRVc}*hD!J1WtDwy01VE*YKS^5T5H9sHKfzNwZqkKf7>8mnaa~#sgj>X)5pUi z+5rmc%50tnU37wMzHkE}olKf*qseC^Hrp-SI&^$*p2&P)wlyq#CDI8CzZ2>vVEh6h z_?)eBUwuf=Y8Kp1rPpE5Xd*U1Wfg4?&8Jl9RFX;>YsrKmsqDvR{fSIy8O!7`;#u1%Xd`jwc^Vss={jf`M`ez>#vcWA*$aS2~DLmBq< z{N84WAU;ZhyF*w8{ElOoJ9eo~fbG7DL~_#Mo#?wjr$d$t)wOnysV!3lE3*#0Gw80M zbJJBt?RhEa#q{{dwI2p-;k~2tx9b)E!+c-{7L2>ojt1|gxCFYc$%p`OhjV}Db5Mym z(n_>F>fPfe)N_Acxho+SSc%h_BJYcc>HA7sU{*ua+tnpYLH{+l!_xfa>y{KHYkg6I z7dW$Xd~Kx0#W%zTO=S?zJU3w(s^`WCy%+_#EpJx}XD|~G{;=M=e-AWE+=!OI z2*N0~QMy8nXl{lboG><0i2@bF(FgBJw_!yiG;+3dWmCO8XNPU2?5?5&1u_r&tMTX$ zH((th%r01Dz!C-Fld2yTa3eTbT4o%R)6oGX2iq;GQfQ`qR3{xdXkR-#hqly^y+ zoZ!G+=E6MJUm4%Hb7*?62f)u-9%Ze*;YZmM?0n|?Cf6P^SL3dkESQy5++@Qw*6$qo zJfqK1S}=3qF)=v3Zk8~V&=#;cR~5Qr(thu*UObh)wz#n70Y;2$FF^Ub2#XDfeIH1T zYFVC%kz07}8>{JDQs(z-Xn9#Pm1!}&*S*|lO6%clH|_JF=3?v7;VgIaNO{lSbLs`9 zL;d1|$=5S37g0Fj4W8?b$lntRblz?X*k`l_+0HXvNlNUyHDDNZo#F#7F8M5*C7;+3 zRX!98Zc2&DPeKC)Ms#=QP)SY|Q?RNw*4$|qW7F@0DCs~rI5?&yv&cO^uNXb~x{5iBY>+UcqU@$w7qrNw`bcyf9rN=HG{hxU!F^2Ks z=*TnZAHLNV%qvvCldbRj(L$$k_PPAE5Riaq^9=w3+^Y1SOHBd9?o;i6ydhmmN(`c( zarb~xu3pvb7p=GqX71$1D6EmqAI0+RYN;$C#gv`tw{?a+r<_`j0mdzhPaD34zkONy zLxx8EG0E0-`tF(0J3H4Mb0yBq{3=w#n!DwKcFc(TZ26XRqlHfG?iIJrA6Ay2ps){v zRbkIRF|v{MPZvB)B`NZfd*OHWHD9b6>}fJ}|1p3ej||Yu6q5lyFbx z*g~wDy1*(d^8MF)IMwHDlb{=c7vU%+ayhQCV=US4{C~q39 zQqJfrQ=UXz(SLr(O~RQhns%t{p$ot|-Xe+7W1zG2mXEOl8x9iZ$CG{Jzm?dN)@5O* z{y~?XEO{nzDnq5<_jnU6ttlUa$@5npPw!#{byFv5R zS`wYWt>9jlzXQ=`M7v<6EvC&dGjm>7XCGM#aF?8JanEymOW;A|8paZ>gmSeG-$;G_ z^#jRf!VEP;?mUfo{sD;j*gW;n$I`7;F@Vh3Aa+DQdixv`7Y1{rLh-B|ppj4ImvrG> z@#fawl(YL*hPuwzI{?^1$Z8ajrHu%pREzKZs3Qj-^D0E|!LJy77hu{71FVU_*!yDpc9P2 zj|4|XWQP#cd8MGZp~$lKKHvV=pm4=&&G9)|s*OlYCAIS@#VE}Vy07C1e~kwzC&CyS zG52K27QE9B`;&)1bmP4kni2azWQSM$(d0W^h2c@8#WTDq-0r#aFDjGhU>nf<{sz`e)Q1w zP6j>oip}b z5V@Vg!zvz24Q>=j7GG*6hgC-f7cDq0vqY%Gp3k~D^tSN=0!q9oH6*Ydv zSVJ~qw9Ry~K4N2OyDLtRLZFn8Ow%PCM_(UjU3y?kQ#>O`1orvisuKN{}_T#~kvlD0^M%GRR>Z`4THH9SSk%0Q@X!7oz zmm|(NEyklt)=Xcmc|QHi(feD&L`ujdG1OV!eu%{qlKz5h>D{YKVP(_2vIm^)_*@K! zYN)f9jI+VSe$;HAlJ+G3D_`j+;p@N(QaabKVoLb*YM+L}jmM zS;N_odnyea`K{tBTXxxfwNh^6cTJKv0Gp5S@Kq@9o#!~(l2k=5o;=Rbg)zqaBYKfI z#^%X3{SrnIo`oX+FN1$MW|zj?Dm04hY-C$Lj6c=mt<6#j$h;ID5|0zK;EcHeG`b#e zi*}CFS)oc)!g0NAOErBF!wItTad-^bDupIjLK?l$p001-G{blJ`@omA7avht#TX-m z_i~gc*roktloPvWqaSut1J~jU?Sn93u{)=E9wyj^LtMK;SDz+Uy9bw#?wNUL4_z;V-@ z%kjsB*DrkDNdJgD*OSb1S)uYM7G`l?u>SHK6?=C_rqjjpM$fhr&{9fX*%31 z&BZ(8tG5srhbcrIiKR>9{d#9w+&6&9 zy>8+Vz?iQ2htxxxgm85k->iE96drn%-rlVTpHb^>o7%pEcLI=er_ zM5~jthJ6~xN-~^9L>$JF+f9&dC=fWffWeIM;1Z%pYM;`>E&h{;ZSbTQYmjmwltc!j(d)MOO<$jV?c_m^%jz50S#>o$j=BCYVWES! ztng5eiXxmu)37t-ugPe6_?543#q?AA-mk-i7C$_hD=Os$avMufbA@jncPgsA%-+sU zyQG?`yAMar*?;%FyHW4B7`#7`QJ^l86K)-G6vCj+krQt5iS|23l5kha>#dAT8k0)p zl|*CVzPbK-^Di5CM|-Z1%44GMNYRM~d7tT6N8_&CR39*KRP0^?oJ?j^bOH9Kl+moS z>sBW3r)+nXG|>gT)0S)f(Y+35G=bpMc6&?-D+1`Xe;IQkk3H0X8?5#qUV}N8lsxuV z+~aE_8wd2$Z$O1cxH6SAVZ8CycZYOH1_yov%S|x5w3E#x9@-$`DnGJ{CQC3kB;n0H zy;sTiliKR>Rr9gAFSj_(IKW9oNO3=U_3G1lGskvfO#WLaGafurm=rF`EAH52>DVtd ztW1667t~5idE1rkUMhLF#d4F#j5GX==eJQ`J2pDL-_UHx{tG~*|8$mOcSKR5$LCVU>3yer zpT^a8qXOTCE43eaubgj;!UL$5gLlb3jif8#>t|vEJY&If8;fz;8|PSnlQieM8s@JV z$qe>mX6eH|?unydU8{<;W%pWO#rSXTi!XK9A2$Fy7$C^Iw$)UwFM`ghJi8|M_YNW% zC}i64OzZ1&?*)lS41Ny}1BEE4BDpUf&nVF}X0&!LjJPwzyWRTReYc5Y1#$|Vc?Do% z7hDe8{^&4l8u!qNOPfExwC7)Ut|1<`mrJ!(j-%wN=fjcpB1!nL-r?zxP5$z1d?dgM z1H>aTEh=oisOMV-SY}>t`m0UCkZ&{Rvk^#)7YN}_?t&lo6SXPUe{^sII5RTd1O0UE z9!EXB0XRUZGQQ-Q%y7FreX35bCe)6{_T1PG2Zfx6#K9?Q;n?-$@e&0h(qS34*oZxw zxPpZbuiHG-+(K@Dx`V6VOSf(k6EfQ;flqaaUvql0I#T~mCP+%xF$7IuB;Ge>KbU=8 z+c-FK`UC(K!xrO<5{W~`ulX(>x1rzH1Fye7K;u&w^V%r+^@u}Rr0M!xrSQs^^RE^Y z)h7oJT$lJS7*;-a>CsU-m2;2x+dnQ)GLx@8KBmSkzyKHqKO`*L00CuvryMl7Cc1cf z@g7Nm_z7XG4{HQ~@@&AT`~%i)zo-;eS+d2+?^=3d_b9xD8lp@T0@8{C3ocAMak7Y< zD6Z#FQdHFxmh;<#CR(;&!G?x(oq|BMY>er8<3}71YNJy+uGA0MW9lPP5|e7*5sAWk ztwai_u2oR=A_^&dj`o)k@9zl>7EEcd)R*u53-8{Z2++g|*MIvE-oIulTrzw&`+R-n z)(zkt=p&F>m?ArB{rjO*0x_C3mFBThCQjr(3dd}*FjbHNYCr#;^ke~f6F`~N^>5^)t;Mi{6I zdRGrz@{tXxJxKZr=nn{gZ*@`RPp&C0KTQMX_m_OD=uBB=CCD{&-=xj z=4<;rpBLwtM{I8#+)Lf)x6(r&zHarPPK3^m#7oDOI>`am+F&Ao?oa1JfB6Yij zL}^xXDsP;tY+UZ6vU6`Cm|vEwXc|Cu-$V_`%!gpe^W>N1I8XCg(sPcmHx>x07?{a% zl;K;bakwuit8h_CVX&=;7Ms4B^FALD_z2VvGkkKKym|r_IZ|bjc&~sE)LvibqGAX0 z;?|#}4(VTNNK(8v6(=|q+ir%?_oa^(^?v%nZ26Jt4UOfzAus;?dIk9v^$X4SCFvv& zgQ@ymV{KS6x*$w#s(HHA;Sn#Jjn&>~zuJlYJNJU3*|^;lSQOBBIK5V`$a;}98~OXt zJYlkn5Xv^6{Os16avzEI^*j2%Kg%RG#gY`WAJy3N-0v!VsQhPORCmRVfi}e?UJjQzyxmFl4)O28@l5f;IJMoRulcE$L#zPyMWBXa^j2;rs zsk$wezFycrsm72u@-L~}p(QcY&rTl2JV$P)BBs0K8e=gk-ZkUe(_76+l%&7KWih+t zPrT_(*I_-JC|SY{Y)P!Qyl6Otv`tnikzyzHy|Um&ZsHX?|_RL+G*1zl7b*ekBaQ^7r|h;)wRe8-Cb zisVquiv0SRBrocIrntDF4mE7)4Zx8Vx&XSEYR1-JKqXEl99${eGg-o}Z{tZ)x2_=9 zBCXcs7i+VUT%w%6=A>A0!D{6+f7EMQiRIpY2KR-}bUi7bvk~*i1_Bqtoo+@K7 zEyqfaLnb+EL5GTnkNE1p*|?r47mf>~ueqrv)ndhGkSB6T#2?*<&o6&YT(kJkQA}TIf%&1OG{rO5<MfGQibrAX^aC_VTWY7(6`yGHf*P zoeJzZbG^!0`3h-fHnVAfB~cLJ5;)=;7s|b*ym?-3VMep2JofkKqO2ZEXMxc9o6;dN zCF+$`p-SrV!cS=fLn%<185JjfOEV)?X;wQwrT_Ns+$ZQmJN3EijTcRpSzK#}Zw-?Z z_!hd63}?p&NId?EqXrQL1Nbv?v6eVm7j{inj!TI?AiTul%6#5wF+q7R-N-*tn4DT8 zuhN0!YfQ%Pg%qwzz5*avi4ZppB8NB%6Dg>!LK!TzjR{hEXc&4lnojV}6u#yTZd#zC zSg;groq5eFWV%*@FLm+@>y(>?e#LPA`1{9sQby39n(vgIBIIMpzzV`hn67{2Eh-o} zYtV0)ZM*5r5ApSbT*P0`Cr1qns2VQ)vKIiSXe|CDS^#E0^5yp+GOU4V+1)lS9jZ&? zMpm&}s!p_@^So@@Q{@+)O7-C9QxuSHRrW!@yd@FTzkLkXf?=U^1^)EaJX5Y93qUFa z4XPCAUbKw50{|i5bX`3}UWB(n4Li@y@JOjL$@1+d< zRe&2W0z=2Nv(M?L-na#%ceP41WVBQhjpRC{kF}<`IS2k}I2t@QH}z%a>u_d|bm6sM zp_h=zbT^ltdO(t04>5>0)?6Cgu7;hZU1Y70Is<&qaBW2GM@8uKkFHz+~voo8boars7FU%gX$i}N%jgZ?Cjjb(EktK zzWg2P|NUMsl_Z2@H$q9a3fWC6WSt`WGRba8vJJ*eQFbPTP^OZQWwP%hJBcC7SYj;M zw;9VAX6gHU{}JEM4}NgDuEEUX`MA%0&biP107LaMe1N2+`(1{^CH(w%&M`B#L8OPK z=qdg|-R)H0jQPJVx0&mU``EH}3lrAUh&)X!&E$@e#I6x#q3TLT-Fe}1h=eU(HA_2N zhQFcR8drbHF7%+3(;Ge6$3`TT)D5;xT(P~t)Dwq66>9Z)Z)?r%#->6G-xN;>H7+y*j`Ic*7lGo< zh}RXS3st{dWcHEh&d+ZQN~a$Jz5OS`5XTF3?5C(|UR~GoMpw{~&YB}&%K20&qb8VB=Eu}Zn}2Lp;88p!LdU=*^rzgwk`WVNC|i*4;Z2=ysIDD{ zQ=_H-wQ*>8tX^lwwiBlcP0Es%ylGolW#2W?E)JG>?A>%k28J_HcRzj&;&z52H6|z7<8XWBmj&v^7f*;V?MyDX843bsTGYYlqtULhl+)Ucw{{K%L_xZe;gq#? zgu)kQFNOudMy~1tb1YK>zpZELg6dPQDwQ9EihE`+nXDl4Y_{pO<&8uNFXK%xF-M8T zC;Y)d9YI>1zF~5I9N&qFM=DZtKlB$&o zW&@;+1?X$-+m$O%F_PLhF*I)_A%@&0k$d{vscBbsX%zlULwPcL5^Hee^`84Dsi18 znvz92msqfl1mgy()iLJdrHJ;(=B8-T*i~tK4YGh5;YbK-o?Xi+9sg!Teokvo)vn&rz=r({moj= z(%Yize)QritfCPKBxnNWd+3W`cDFHI@%7MfmBG$9&m_Tj49&A7e=!6%<2%YjWJe1a z)M0Nnn&0OfEG|e_Z2<3dEuRY=WLa(mjJH54g^-Fz=FgQb(t5xba&+Oksp~uLBUoP_ ze!TfGW3*6izOc}5a4gs5YeT?=O}r*h-P%!cV2%UJFVr3*uSd0)G6bHz4F|?nGNE^E zT^%c2DF3Ce%pBT`9xH9d&MEP&1$wpe(ItY41YHV7Q!yHFwFs=HiI}~LSsxwh} z0TeCVdC$1%_pPSW0(X>Y#cao|?bXS?*5XEwV)4fY7Wq-dI~I8i?o)d&+6>jjl&7$F z#smCrO!9jh?!;;L*&*dgv5B~g>yS_I_V)X32Hm@%idun2AJ>W8Yk)ZP)>cy-^% zD^6SPug&kTNoTb9uwVHhqnd)ayL>LgzjM^Dq$*F@)=8}VN>Y}*!-?XHAv67$!K#>| zY-SLrJ_O(p$LzCrb-Vv4pI(Wy(@$<7qPrWY!T&){m+KdaH7ML}0J%QC7R5HLxqo4| z^u~J(B)m7>-gb*~5iq)aTZjGipK@TH?Z~H#lU0};B&8VnV26J25j&&u@GrU_NDZ(t z=lU}G@cp`F0adj4ID0bo>3(ZgOR&ll3u}c=S!IrRuMgw;2GH5lfszv)&j>p^N z9~UX9KW|f1m%~@KhG{m`tNeWaqv+J642#%4D)AG@9XpIj~4}aVA7Im#ReF5KfH;s6{#uxA{#wU$|AAIv> zlo=Db4-P@~oZ+$HwV}mYsXflyhYzny5KXAIWM~`(BY;#e%=}JGERWJrmEG{X$0z}C zvw|Q;6F4zE$4^~kC!QJn!L+vY_}%b8@vR-u#x~gXFHFuf9rYfNT!H_~>OuMgqnr2M zfR2|UpjpoRz$wT=j^IS5g~+@<37YY?QAA7U=Z za@G^cpwjVI_PV?E4btbimnXjo$j=yIMX36;a3&rjh!xNu(S9JWDl6hu-6F!O_R*jD z9c$q&?--UaftN^3ikC~N(HMedi#;n5F3FKEEB;dvvQlW=TmPoXRd>0}xj$3OkY$lv zN{e~?MZB=gutrm=L@LDMPtM?&*qJt+YtwJk_e)#!_eMwe982=m9%f1`Ua6?jddIS1 zuUXQ0-Drh>a6^EH>%io>r*$uVlYu)x)iQtEfAa*p#Y}R~b7wni|2n-YTL?V=2lz^6Y0~Ras$26D-zYz{a8H z9fahtU#+|qv={5+R zZ9(6Om#MW2Igw_2E@TeroY76!9sXSNTOnv)klWSY$1q=3h;CF)F#L}Ls#I@%G7=TL zzuc_-sG&r8rUN^(8vM}2&nscPB4!RzC~7gVU@N7i=x)KtFq)Ff6ENf9nen-ILu^j2 zv0+CT2!INkgPXv6I>#G*QG0`SFFffRCvzuOmlL4PTE*Ido;)YqlfyO}n89-JnX^fz zI^XZ_?_<-og8{55z`&?*P=vvh%%V9u&J4SaUyw`00dG~g*9|_#2hz{yYL5;8zX6V}dZUfY7fg34at@H+XDSp&S;2^2Lykw+&KJ@3O6ddf?R}trldAe z4tQAbW#M%lJ25C0-4V|PIWSkZbd*%^g{!#7sS&YI&ZLi5CS@DCHC9G5E5Df8aT}JSXwDPm z_l3G7H?GSL$|0X@@fDf5unexJB20t>8XIKk`sZNnl+r}3(492DzRwnwZ2YeN3#g=n zCe(jEWZMQl)wg+uI*ZtDjK~H~a*XcqZC$guV7nl5*Jxrg@M?$#eeamC@w8;{IR@;#-i_2LrfWk|?oh zh-_PP(W3rM656;@DdX)^#3<0O>R#n}MUD8DbUgK>bdt_aCBUC!xRn?&x3SO5eC+M= zwDKSB%ZkjgDPEV&e;A)KEK#0-r+89n2p05w3kh$wWgh~qG~7C~!Zx2Vd@S5Q{oBc) z$SRUc`p*x@@voJs^k1*eDWQBeYS5Fpi+M4D!6f1%NAZwpj|x>VFz(A!y%|~3Cj8lN zqY09RsVn#+F8*!RokQQUdD}evYL|Mn@Rs)ny|voEd(=mkeZ}_ZD?w=>inEkeZbYsA zB49oAIa{EvlO%reTd2ZaDTn$z_K-U7^9%QZSB6?3`!J-3exV(_4hS7;b(Wf@WvcsE zAJf2VMnfl<$eP`_%eHmz*qK+ll}+z(uKw4~h1uvW53k6NkAAh_cbDfHzmmCg;iigx z6w#j1IE4CStlbODnC1bp1Kv2w#_^(z?!m4hoo|Hl&4DUORazV{@%yKb^$B>#<0dEw~VA4YjxW_$NC{zK2cB%+1HfHu4Jt_QWe@xpyw8 zRLuLHuQ@D3PCT~iW)193c&g(p_SviVIiq7&wCUXqGv;%9dq|IJhxhfbzs4>LbkBIL zg9PX%a3fvMI4l>0q0;a_5{g5i`-HB05LjR*fUMlfL1glBpc%4~^?hO!pm&5Ri^`4% z`?`jFOj2iS+AWEvIxx+3c>emBvWn?#SG&e)Qg{7HWYFxghk1+gb#<8*lmU?hQ`+qJ zC!r`88>wA7)t`43u3#y|Tdw_g1+RT5IohPkl5)HLv54T5ss8hZQPp+LV>JUlgB_+X zmG{EZdPI^av<2G@njj-rmlI&P!l^Rz{?WRE-%~i0I9IL5Z^)axzAUwJWK$g7(G+pF zy=&l3{>xSGLwyBFlDbOGY}m{HqdW|5*Ci-b_9GAVZd-4QVIoio{&FPHw}1kJq2|y! zK$XFaD0@FYdzwl0ZjXiTZ_o69EVr@4V5;o5^m#nn3-Gf08`R$qUC1Y>w#Nr08~(46 z{G`q2Ksmnal;-gu{LI#AZU()9A-A+Aj5zuNf`L4cqyedV9q}}Q{0?;(h~>X(C%#=-%P;SklE-mAl{nV zJ;m~;JLRXjHrNYMv;%0N6qDVbL;%`fLCH~V%Y|Y9q=<}OW~T_M>?qzZ1n(1=IfUuf zlYk1#J&B*o#CUs>>gGLCVUj047@M5myK%601zY)(RPPyW=}`4I(0JmTZL)I`{n|Ld zGGl5Kb4eu+sQrtWQ+*%dfkxo9y>)P7+P%b|K$pRGjGx_R%!D~7k_HJj(!a3O1V%RS z5pThBV35~1PO3ZqZkTXNp>)>IB5*|2&t1SqRvzGs9dMbuJRBr+z@H=<^rQT}Ny*Q* z&awPL24;Kfkq$HEs_ozFO<7pjjuKGD5)CC45;Dy{d zXW?Wxj32pT%_d@H4-B9Lv>DGRM{I8-u_6l z!N2O;H@(Bv$gd)5MJ0D`)!+lGN5)N7Q}^j{<5qFk2Y>uyK>}FB^a~c>5R`1w1{Rh{ z8y{a%XjWQaznn@QNG@w3;MF190pqO()slqcTPOu5l@N;nmbIs`^&`f!mnV#I^9nyTx7v%JQHs?^Z>? zGWRtr7H%anL#}C9@r@F;mQ!7$v@3n^Z7>YR&u* zK%c)W7L4Hr&wVCdXjbzY2v``$I~x-?Xc%$)R0CV995)$y#-=2jGV{jz|$fW zIQgYs@WSiiepElMz-6hGLC0PR3%RBECpJ=h@sx$^Y|nSyZxx(%w=Zo)ac?}VEqj_D z@b(0dl&d%3?v0Znjh6{V^4a_@A4=L0I07I3LVEZNy>w^%H9Hwgs{k=Imc}8h@rDI> zy^_83{xW@u9};NOgK~chLXH8=Z)^Wn$TJKv>`xeq9^QaOLxt%gfQ46{n%jA3yZCcN z0;sN8;Jtn((Eaq=!RENd5P^)(C~t25cfL}Mqm;W8VuiPn?ENjEJ+)C{D5IGBfeCZ`ga&IFMr`H*Z~j(pIl+#JcU#|9bL&EZ<2F zC-X#=lPsWZjlj1rBI~|x;8;hypODSId^}89;zDV_poYH{6xnZuN45;2MvrWKP#H)R z_oNi1mPD3ZoO91uzO+KqvXD6j0&1u;b9O9bXa{#fp4g3C=+&MG=^<=36RT^Nu99cT zPZ~vq!8FpT#SVXwDcD$SdHuzRfC)zoqsX-+Q&VdCoDLDZ-#Gxy!wE6!bg#pM#|4qM zd?>aOVa}I_=QSutB$V-iKL@JK2zTwrqd!J-VgZKMe#R!U=pl`6n2>wM;qH-BhbH2w4^R#R8}Qw{!o zWUAWh1DeY>2cL1gPsb(KmbkhsCLQTgpg4H$$+fOXkHnc=n!FgC z7Q2Mm;-d)y(d2B(KFZ#)HorYJ)F=-E09xE1^coISW0pJ5v^-ipu+;-<4pm-CK{W42 z6+e4#f*lFn#2P4_FTC5o20lHP{FbNwMSS%I!M&zbfurMakU@+FLRELKyK~8$eK4~H zpQ7RfdqCQ5V2iJgh>6+mT8ucwChnLjdenIg0w|9$@GJ0nUtL**$}m0Rs~Jv!*3t;p*x)Ad>({%Tz)++4OA{^1W^)ZJkuXX&7+>{k~CYYsy>r8rJ>~&|R9iNV!8~k_Z~Vai!ccF)DEG#| z9+(Lggb~>~RVS~7Ebx#yl&zF2SZiuOy@+09m&Q=WTg~+@K~#6zeN+}NpmVzVb4o|SB$l9P(qeH|H!bEPI^vv{6E+m$KX zivjI4SE4o#qUVVx5+Q=?hif6=5vBNEF<2-CI=+c8q1}L6`Of|~^)xHE@H-7aQ8>HOvU7CX7bkGg9Nb_Eh}I0vPb?SIdp# z1gXVk`DVN!Kb1WP@H2<1ZEI5(5_aSxZIj*yQ}{=`8=tRHhI@pj@O?edPv!Jmmqxl| zEwwk>lSQ56re}0Lfy-kGZWg>jj6HsF>0|WP@b*D^@>iS;nL7%BJzec5xUmK;CRTI* zaN?t+QT<_aAfAC*Gez1~PS9UWrrt#A0AgTKX+mZZ6z%ur#hUeTP28a8?}}DHekqxO zua4J2viEjQ2+Qt*PJ*KZJkFus{jW_fY&t&#NKHi5eMmBr)0rChAVSQ>AZ;j`?%B`K zZd?Yy?Ad3^+Wwo!Zjpa1`a4+T4_@jZow$6>K<$S}&{SmJgNowC7g)RRblu57Ark{s zZqj$v?Zo-3p4Az@SW|N6rfm?Mq;wjR{K&psxrg62N&l>RL`IDH&fn)C5;jwb^G6+} zEhObRa7P|?Kqs7ZuK~wMGl-ak_e^4ESJ; z=d}aoV67jiV@`bIQHTM^MmnxX^cCvwqyJjf znWrZ}Li9*dOkVqQuKK5a`}cbRTJQKW@NjU9w9dan3LqS*5$>-1X+FZEji}h4j9J^4>(52KWp@R27hv}u%^B{YDwyS!2q=w@`3sn)QG-&^^C_<>u^YwS z<9YX59Sx-P09RPnG&)f+VeYkq75#NM64Q9*)zgU;{#~BV!K4qZ%3GPj$@gjGhP^C+ zOPxz1a;f@_(3Pk!i@kqoB$=94pgWC#10!jZMXh48_t663##3f|?Kyd|iyYFRdZlN@ zSH)uo&?x3TI&A06fsyN_)OW7+mFT1KW@pU+H+k%GJ(xmMV!l4yxbG>LJEe4>aYM+O zH>BDZX%541wfX=8W==E|-ZT$NK!5{8=CLaJ@7jANx0-*UyBn2a0hfPI7oL+iefJx} zXLR#ffELW&HuDa-Yx#bjRc8S5Jz?DuDObrR9Jzr7cf4!e6%vtaL;0Jr%?I~vb^xvC zd1_(X)ahb)j$<@Lsjy4_>+XJ!pD6B0@&e>WBcbe7ccjO+SBIYIP{oYXM^}F9o@IQ* z-GFZ__9Slo%99hW$WYj4sOUZY@BX31(Q|!K6bg8!^J*wPZJ1Z~hMSBzb-KWbT8w?m z8)sP7_(pU@*fTI(Cm+qU>tSM(2>nnJL@9O%zDP;0CYyh{pah%OQQF#&;*xB7=3BO; zla%_#jj~&^#pyvA+rIoZ4s`PI%QbtCcd@UEucDcopvSv}hS?+iBSf~AO7WjJWC>l~|xN(JZK5z3-%;YZBa`Ckr8PWkc=ktkqG+OP&4vt5wcEB-A z_DNvD#T@|!wRYQmxhBj}Jltp9L8ox^cm@*UX#iOfv) z02-3&4{7jIGb61eEQ9m{|w)hqTS8i?pI9B*#1X>Xb8HZlj z>K0rh*U>B#kH8yQxtE=;jqQ|ZUC()F5n*aJyGS{* ze0h>59_<@FfbM6myoC+mWRSmFtFpQtEcUdX+V`jrqjwZ}Qv%wVo`*e?_n^T~iZLU@9OKchTD&eV={Ay}?AVXBt=yWP|mlLTP@? zfmVT1Ycb^oe@f(t|F7`m!nB{RTQ3=$a6%`9Dh+8nnleGZLh;e>&THV`S*f}UjKh}q z#o<}MK!@A7FftG`TSe)lK2yZfmA-n<-mI+N6B4-H%BfOeL^qJxjXPMmVD)2ZqBX_{ zT>s6snZWvG;cpY>GXc!0%S-J>ZBY>#pZ`?JPR(_aU4QN=w^keu+}u^EyMH-qea7{6 zqNMD6dl2hX>$Mg;qlVI zrlxmVxSMvH|4K4hxsAxUSv|iz0b@ZjJeHRl3Yy*HztXu{9$wunsrsvXL`cRdT3(8;3KLiMM(jC$qDS={hA|*XTOk8 zwD4zV;;2DQCIm27*$VxAr`3Q0C1pMD3avHeP>&ZdNOMe^y5QzuR z8YmxQ23vK2pP?ry&?)eoDj|APX;#6Ub1DXN)mLe%HVo+j-pG8?jT!^sIx>k#sP#gg z+$c=q@kQ-Exkd%j5QanEzdske1r_V$_cReP>S;K9uVu`?yJlcgd=yOrQR>J5N!3MG zav%wygGiq|K%^{h%PGOc`>DPr@8bWld_^@$11lm>p2S2j3sS=_AE88cG(!APUW>V1 zbuUsImyYCL1l6J1AhE4H^7|!tp4Fxrje^?Rm}7o`^Z;P8od6>cn{lu+nMjGHYQVK0 zlE$43?W-yfS3VUwy&WynqOadHI6Zbr+;p%DlhkUhd`U`>}3jcRs9skw4@&NS*~^j~wXRwn&!q zN@{Uv)8!{~7FUpEqBnOIFv)4t_iTW)95((H z&bZUahsJ&(A38DJO+^Ml>CL(7*XFO9(S~(hn}Pq-iOwFMyq$~nx$Z{(uc8d#r5=Ca zGaMPndyO6N`wN^Ylk=#8NP!>fl1klQ4BC3Z8M1^7+uf?GOZ$9{*1EoclY&Q&L|Yic zbmA}ioc9^>M(v)fj8Kw01dwIP8q}COE+jLNnLGdCGY_c$)HXdV_)#LJW}D{rg*EjI zKadf!8RR5Mvu)kIR8{$E*3k@1uZjWBnkX@ zFDNHnh19~_yO?}BzvQEiG-Im_huSD;cx!_}wcTQhE5?(g9LRr$wz9f}s~8_99w$az z{Tro9zpQj6;wWPdTnp|Z@*xSJ>ccpk#FXtVAO{7uR=7F@$v*WyU?wupGI<=2tpqL}lP5BKSk(OEt6upt7j8hX@D74|6C^x@Ocofo5VI(e$EFWU=-|0AQz) zz6*T{tcp?PRLMBc&pO_!f|@I0UM92BBb?42oAu{=ag0$%wC+PdgXJXIvin{B+MCYVD;3)ztt zv0U#znch(wF3<+z@(!HnuDF#eCy{g>74H6qH{zI3h)V^<2GNp%?OdC{%n&d#WxT=+ zD?FZpH~g&CDBpTd)sWZaRh;!aK}Id0J9b`)i!+A_J6qj|L4|)T<0djB8Q_Y;zCnbM z4=JCiG}S+-v(0jWUsfAo#;SLEE{?NOIa=vey34pUMpml}G43A=$&x#zjLg@0XyiR- zCS#d7<$vRzq@5%!(+G340c-@5F0W#q9hQk^@^}jyZo){Ac58c^n9bB+PGhZmJTa#s z3Q_?3ZX^S0-jkc@-#vb+fOkT(T^|hK4=|PkF2>ST6dwXoIGqgbZhSqg6A&T6_yd&! ze1>0Z_Osgksh8B~7hnsAFBi#_=y~{lv?fQ%8C5aw#rh^RX!j=(+*kr-p|j6zu`blT zrr%v$-Rg-Y*pCc;qM#3u_Ul?iCesi))csN>R@)?ha=q~~qx9IJaGEz#`D5I7#uWH# zfD`>KPSBtyR~raP9GhL)O(mPO{bQ-I*&HT|Z_GoJwQb66;n7B;`sIbLs=rzr;oXKi zsHHE@d1%Ej&o)q9;g$=Dx$nfyJ5c<2V2{)8bJ|TEY7$`9sq-|_iIm7Z zdo*unKhB-VJl|aF`r?orAf#I_xVQ@2guFtD;KUI&!_!?LF1ib>_|65vIogwKHsDNP zLCHvyN&2N~@;S*{F@j2uj^1>j|NMO0cmZ^Q$pKFxI+Cz){=nofRHM$q6+8lremPq0 z_G&!unymWW=4rLo65_daF?pfP{JQw;?y1CLkY9PC0rl1ICmQZMldau2UPdlzt^h~~{*MtqxtaZ|_t-dLK0-$$v=No%%G+)#z2j8x~>KL*1Ep0!;F4}ptU1rI~B8(6S`zmC^Z!1Kn0>C`#WYYlDFR-gHxI>7j9VN z!S4)8o_Hjoeq27{o-_Q8O#=J)Q)LX$pWp^4;9ys&5T<=EH8hMhpSt`jP4=ZOtxFrz zLL_b;5l3nwJ9}5_uRhayQaP#SqYzmqk^Y_wK;x|~a&=0-O0K<6Qx9l}6s|5Ow9I%R z&ER0`@lwxp2NFK+@5uHYcGJWlm#MU#T{Mm6+yY1i=mlm{#aiCgI<(VwmJ_P0yI(j) zqEKaF_%7^8dq7WLTtvrM$3Kn#x-pgXfc)Z8*kQL}_5DDqjY6}b;KOGi@r(oBPg}*z z-LpMCmYw5m<35~)NCvu|DS~hs!pVDu3J<2jmK1QMzS2(ftzk>uM{_})QRVA5Unft5 zi`uZ#WU1aNN->(quRkw}8GB=G4{sv3uc8-Hv1?9{1l7A=r)SpXQNwdl5uc3!e``SG zG4*}$wP$5sQv33aHTLf=UrX7ff|+MIuxkWVwd%f!`!nkf)4H0sD=&6E7QlUSD>DX8 zKer8^zzV3CMIFN)%=uvOg>@U>wc>TYUU!!tH|Go>j6kXWu4j$;%(Xof;U9|u_>b|i z=>?q+g8CS(q|y%_zgq@Crw}@1LqPnFw>NCxIW;lx%_pb)6F+*Qw6qQn%2fl5<{Lds z_I#QU6+#haq-x8OL^^7($X0J$QY`P}Ste=_rL(mUS@)J(`A~D?&h9TJ|jQ;RxfAH+w+cx;@@lJ7w3U1g-Bz<(ce=Q5(y)Zx$AwA2fq6 zk>xI4{S?k!z;Ez>w0k1$*{h**Wau>H7pSVcF^pE*0BmpE;t9(jZ{hMq)|&Wae&aS7 zpXistDM$`@bi473n%Qg#s~+S8LvD|7zlG~m;>=t;RD#ll@Z{5@-G_YkoPAb3(mp8m z6dt;DH;{t4XzN9;b^b%#qUgFLgLaGQd|tJm)qk{qIx_sEv9ec=TGag*tb`V@9-MyN ze7_zLc+-yFmB+RdIRDB=@5rSeoCGaF6`V?Dl-Ip_CUxBG$%M@&5_r+?%LBx1Qj&nh zz3b`sW*z(X;bdn%vMZBaY(Yy_z?P~-mK5pgb19_0S^&=gpy)Kb9-JAuvAW^+bYZ4W zW$WcoaoGT<`|#O$i^XRmnizTJ4zq!tu{y78OtQ`_+9TUt;o$vKR(!NME5>L>xoeGl ztBcWg_-t>Whp`yiDad1EZ9UdF1KuGRQ?St>k~3&Z>PP0zJW*_NikfrvySP>=B_cy? z9+1aT*N&HTC5}22&LEC|N&=$C!y|9USTv3WIe-$_no^2Govu!dO)vX(tN%itH}DAM zF819d6x`M9Q1kvlT6YUBZu*_81%1^@a@?8B?Y@?^DhN446Xv<0@7Dudm`OHJ-*K!ohR9vwlY`PrE|CA zuvA*gbgT?F?V&w8>y{SgO6Ff=ssWJ03ps&1<z7I(H#=0`>UuGj*dWhTPbr@_xJLpqVHh56j-mC0vsC&%fr%6=*oapeiKZ^nms^0HRdj(8%4ZT_;=yi&gX0V8x@mG{TCQr0 zpa_3uHu^$!NsQH#w^yoFJI0H!TYO;ec=%Rw;gzqkG*nVJnC(wF!5G-%%FXAVc zr+@m*|NR|2RKH8xYCvQ9RYy^s`lvH)e{@f;e+0la_m(X%-4al$s0jAhATUo54(KzO&Xr&ti#Tv7wVZd=obzmOq{FTa~ZFEcpJvSAX6@2IR91z~k z)XQz=fdx0L^V}WDBJ*s~rJqxJOkc7VW}$D+A-BEVSihvX?Hn^z*Foo0ZnZS(x;_36 z(7KoTGs3q`{IYtFH(NOmd^I7VB|2L3&Iz@RPcA~5HL&-G<}Ou6%4LwY>Z@w+_k83Z zT~m%a&28x%sTLA67V0r1V#)gQ;ZLFNagml{tOn~2GUFsc-EwcC@mzylY`OQ8FKu8e zPGVn`3Y_&*ryqV}PBV2!GU^;S?SST~HDr89I+zx{$nI>Wv&+~Z)ln+W5o`U?dO%;) z-uEV$xiwG|(I9^TW*nKiw4%VU(>w576Ntiz8GfPq-ya%ppZ3G07Iw20W_&&J|HqOV zXoHlY%ahr%}m+mimD#k&R#3yc?u9ezZxDIYrLWGRUrlO@qFOMOQ5<7 zA1a+f$PMA}T&+cS^t+lo)&H?rw%pRiA8te`*UI)CDwmulCCF83;wJ$fI`kEem40)G zDFT>i!u!^Y@;|S2 zagKkx!J3R0Bof&_cFZN#p*C~))pQ(cM&{6_M(xtAEi-{`#| z!YM1;1lS_?>+kDRwt34_f4JqJp<<_+`k}0L&_5D2)p0IAqzH^}+lad)$_zsLQrfKc zQ6vNvzPqszXIK(L(d}Lt5GHQwk^h^X+k}GX8uQtT&6idfd42{nb%|Ownz4c)~v z8~c`R?gH_RC^F_pefD;3)0FwZj=5>zrKbDFdFWlv- zs6Ers8o8xOHF}K^gkBAB>SMc}TL-`xQ%csniW=r3%5xf)i$B+XS1lIVwQQEp^<^4! z6pp4R1?dEI43`+D_ACclzWrVwYn?lmLb}yDj{>bmcjgJVa(hY~fl9PO=Dod30_nEjC>EACig6&S4@Rya+4 zDOFcHybWHy1ay0siCp{eG9WT7<1xaKpvaU*c##DX9Lz(+CCGlGUqauRL|}gPB+!)g zhVw~>v713U*I63fZdI&Jtew06`ah%rE>XQ_w9Vy{+0)^9_lBUrbBF>zMe7lSP66De zJ;a&6)}q**x2zG%P)_vR!-_I$5P+-aj7^*0^Ddc5-Qo!Tn4Cv@@w#DW4o<0KpWqsE zY;3X(Y=HJblS*TrWnBbsp)Pvmu}7ICXNEs(Y`6`dk$z`Ni|az*ICA;p57A${%muZT zo5gID0Z00<8m@kEzuZo?k3RrvgU~KC=bx2XU9JlR^)}=ptztT zX+PLQ@J3C^qyoKvx@hr#i2MlCn8?f~RKaSkM>y+jl!BLn^O*a64u`N$)WEw5IydiG z6vzKeVwVE#kL*O#HwK%{7Kt2`}IH(RJ{2~j+J+E_%cuTtA>M+IYR4|?r>fOf1 z2m~(0&5g-cckI+H%E%)?A5`up(8ix=$4|Ur4eU|f-HFqc_YV2d6%d9uuNgEX2Y-GC zDVX(*kjijZmtep|FW#yZuOtLI;@Mwy&5K^<3`bdm?a~~J+SYGgv)_YG5__ysd`!+& z^yQSJkIYv0?P7D?;4axwZy|WRds>9B_Y|;(UvYDY2*AQ zC9mU{uzXOgK2Gsmzc7U*35VnfXU=Uu=Cp@$4#x4Sb36|}OB_-t`wN0RbaH;}$%2iwu`@3F{OfPvHwXW2dl7PK1Uhtd-Tz3fteM#< zpDn3aijP3npV@AutO)FtkYUe%#L^5bZ%8F~1c$0&IP7-6Cvg{eI?`oEKb`EkIKL_P z$)@hEnt2Tl{G$&dkjqe?-Uu)XN^VOzHgbzY-_f)YSOfzlmEuBuBRtXrI-w%hgG3Db zSG+tBIp=2M9x)$jY3f=d%_1IMpkEuL^<`xD_QnRVnH1MIBYIF|SuAej+M()Cy zY6f2@Yub)xr_lI)_Z$uPL{XFK+)H$bC<%DndMI+#AnT)M?y!YPUif7r?Yl+&n#)Q@ z?n~faixvUrQD+^UAT+1f_>@krqOb@m^+I?UoLN)yET@Gj|G4(;x#QQM42buf!|uJT zz3zZf)Oq^G+3eTemP?76*KN1HHstXYk}CHY(bS(b@5 z)qyqp*ROaK%9>qS9>2F9czvk#=vjnK_O;3^OTq`~$>}xw=srR5Q2UwRJ9(lvFbCyw z#-lEAN#$}rI`$J1tO-Gk&)0*3HOIy>$l1ltlymOor?vJRJMCYYHbswG_=xoBr!`(! zPN0O`Wy<(O1a&a-{%mbPJ_;07FtC2IV zpr5Vs0I>yg@t3jhEjr`$h>gW!v_nJF;7U8vmF5HgcbQ5vZT)J5ar}1<4I{ zToFn6kM{Z;M#&5^f{opB#kP4aIB-ZB6o|Df=LL>y_~Ay=Pz3Nb+#Aw1Vd(a=)2?^l zhx0%`U`R&bshsH^99uQxJ>5w?GNR+w3Qfv=(4%pLd;3=e2s6_S4iowtIC8pG-*+j- zc1-gA#Xsi)bb=P2A!;--V?VquUx_tpF*_k@!6Nno?{nAPmoAF=F*>X*!lEzAbzi9P z+{IpXv4*ba-JCv?BS8dQSZFu*#NOOWw}WS*)o@PxvT0_0g_at~LT(A598e@vbV3eG zvwv*kTl;;vpXJ)ck3v`uuq}y-vyPtQAHx*eq_(2o*~i z))Ss+lQX}#SDL~GE(@~k3e`!xd(+=?%+^itf7KtL#Yq*-wiU*yf5W0#66LL>nF{0! z*`TR(EUo^(CTnl=>*hMp1LDlOWHO1B{C2Kwx64;gKS^;%@M;GO9g1|y>VPW#(vaekYPr~5Idm^_s8q9 zo~^%ZL*8)dl>F>kn0FQ}aUE`Rf73y*3O~^He?V$l9UQnkdtaOE96&QbJOq%SAx#%v z*FDa+sfmmaS)JR%$n;x_f3>^rdJKfNq?-u%DV~2XOx0qZ-CCsWaL_M}=!)9nEBysv zH;G$pm zA46EZhjA0HdT7{%HMmR2@r#W$-Dv+XzmEXEI;Z}taFfK8_)FM9 zM`Kf7&Z%#8$_cT4R9|kDX`PD)aiFT2b&BaG;|k`%etHB5{4{uY^YeKF-5BUBcR}Pl zIeL+i^`e?}d0i%ejXf`;BgY!p%kHDYm6XqwA7zobV~M3!kbmR#zWZ-+8ja=m@gxEc zGAtQFX=)+tICtDNYO}1q3EprHT)+xYi3_uJa?^OF$!t9Sdr|_C1o;t`a{@4~N=Jo? zn}wxV_#SM2P6{FulWTH6?9Mu#pUEBwapoDV>8h1|J|Z@A`%0sk+}yE)WN&Q*1Tnr< z_o7^WhTly>l+JCNoS3xo7s=``&9^>$k3DRK-B_O>9|)?fV<--7YlW0#}0~vw;Rlv$bD@v*QOz z11KNU{o9SJX+*_zr!<5OmY{Xn{m~&OX0H9;U`a>)S)b13tG8MiEfdp8>1le!>LvZz z3>)Ci=_7(S(yK|cUwZKE*{7APT;IX2T?4s)F;(?=`0nhVRHq%9*PT7jEd(7oDMzY^M58eX?yvOFqbol?vLV-R+Q~A&|GT!gXLMpHu~$g}LYJQL<0=uN zCn!B+j`99)jR*xF;y2Dxc#=IuHS&&}`Z&LUtKZkYq zv?6wB?=K~s=iwawJns|otw~;)fXj*9=!UP0;aR~*@u8@LDsY4^8p@= znbELMF@=HecuB?Z!-I!aH+Y9@FI{eQvHm$@6}*CZe5BE*@OI}0vRb*W}uU52K zYB?yJ>^BqBj)D)TD`Fj)#d~gGkc)SA>70dqMY$~d+4R(J8;!>arcET7a9RBIJ<1+a zuFAn^t(%==)LV_<)m|}u6Vg&*e8sifCKA&Q)+M}2!HN)%(2Z;}@57lf9u3D`PSa@W zo7N32^rG(DPui)IXH4JUs`9O5+*chm-&|+t zW{3na!L0$bPXVyfkVhxteTC#@<5qxOQ{UrzVj%&>P zltXbtcK7s~EU`a zN)r1o7?#fn%;`8i?AorC8&;D03E@0wuXbzg$G00e`16-GpxDrc{D?35qb-k}ZTBV- zF#mS`c&)&asZ14{Fm%kHQE4EvNbC_Nh?mSR&i0FPM6Lz6oFsxp#ceKK(Hxh~yrfiC zATn62UPp6PoH(4Yq%~R(bJz3klU-ix(M@BAhyU^zXOk#RGRvhU=I~~94zs8REK470 zIp1OVGuGfVY~38c^>nt9gmVh7XAJH5yE!-c>0|1eKt>>Ee?uA>%#~DIc>gx%L#NkI zhHKbLQX+1njH@5LJ|@>IbXTDX^vV0;mOWD$AsOmgCCMX*T_n*!u-5Qsc+Ey-f#E#0 zGxS;BKV){ZPdtk~zXbvM9sK$rEE_gu!Lpn`;(jK^2K}|LWS8kUAvl zloqU21hxlV2ZzYs+zwRebZJQJeI{jdb(n8Mi z7w4etUqnxcfIa2#V1_}j^^R)A-MU~+PMXYzeSmN6>}B`wTqrN8JJKW~*g~6&0w{u7 zBZm7%1}@t!)-A{(w={~(%A1`AeMFZYa`06y*`V23PT>R=hMrAL?2D)x=ES8iJ9zNN zVY&P5TEc^XV$&oDX#Li0kuy=f;2HX{pi=3XEjDU+iSj_>3&zZ3>@DzmUX?En6?AQ$ zORxyR#tkZ4B_icc+HmqCym&^8s0ya~wR4rDq()qstzX*PWIx5MMrkahhUsdDXich?)IK6WzM>%CF z@P2M~>`Mj({`OtTTW@N=U999_NMU#EET8S04SmcD3OLgny_z`4V; zL`N@C@Bq|siTc;4-~g+qX%um>V9zcNh$|M~*EUj9qB>M^fzXiLUuU*+;no;b)a9mL zWpxZ6#h3`VSbS{LkIzP?M4Y{s>PNBQNj|;4&C&16W6uK>1!nzk|BktQX+N1hqz$5h zGtheB(Jr4bVt^%Q(YM&?ck7H{JBgN|zW{ziAf*?vIkdv^sh2ZVXxyZMB8%iFzS~A! z`|kSZXTKHMsm8g`3HUVrI{c>1L12)NW{#pUusp3u5VN4o^o5o!p#@LMlK zdU&F$q}H*>^lX?xiwVWu$1>$GcIQqgTyh!u$nWZJt`JN+=f1anxXpv+Mr4!nDd3BP z8soqJ6ym4&FmEkv&`Z*6jJaLBEl;GHc+h$(u&1P8FLI5=mx}T@!(-PdIrQoGFt2wy z?+rTbQBIHB$9&J#_<~Br8UjpgUggfEebDGcQBll|zxrw_s@|OSwftLRVX?1+$@_N- zJkw?6J`pu{^IioX8%vqxlIwxoAxu52#~M_3L%3h&eoZstgPN^aa3)>8otsJTv|^RA z93~t~fX;8VCSqQE+}kv9sf!5KfJR+v=lWBu%EQD=hUYTmgX@k2r(pC1>mQRfMGs>3 z)qY;3o1~A;oU!fsdx27(3IkJcoRwc{X#W7_FPVdvQCy`Zhv`W>keab(U9OU6_a)wR zrZ;RE`;1uX&t>2qe2SCg_lATM}8ShA2?y!@z^Aga!J zoyDFR?MQ2C{ay{|F&5cV2V{dnTo(Qrp;DZu4AXK3N%~`5O-q}!qB`ZCJM+A?SVR}u z(Xd3EiUUkX5>y^Axfy;a_APRZjnT$Yq9<6GGTeYw1N2utB-T~@4<5PfQc<$A{oc<- zLU5*Wye#G557@^*H43pcvrxLcMA!g72bBXD{77p#we|@e6xr~Qr83<%^1qb z^kzj`00mZtZ=`D3l_n4)RJ8HOLaSagNVQ86vW@%s*IyR7Y^;lljzv9qkMR#E*B`!u z2hQlLNr2#~@1B;@X=c*B!0>f>zN-6nw0ukc(E;B-WG1I5K`fYX>kv19@m7#!Cb*0= zJ35baWxmj9NT%jAY}+jS#upvj=KB&=EiV*Ee#vEloB0DK#g<=RZ~plDmgR@va)|Y@ z7FDBi|E)G|P0ne>TS^jm^V?dN?4!RJ?5 zCj5m-H<&I}p)bAbCrSLf*v`B3&dqX#Wxuk9`9^`06;Fa3mV-;6L6<_pquR0eu5$jc9c5MIi$6>9kbVLXh+S2|Q*Wj@O{uXooEewOYW^eCLhLOA~8{bumrT0Galk%F!QVC zcwt=D=)qUm_Jp%-{ny}1<`!53&*U!%7^8uhZF+MJH%Qb zf_9d@meOrx86DQXy$fWCt~vJ_vuzG9-1_=qWpM_%)b^pQ=P;V!m*2N`10`wO5S<6J zxEMawQ9Xh$HWG@FICWy1n3OakB25VhR37VUn?-HM>bvmbREW*BcX9Jd9T%)A>+nDA zgG>SD_P~GI+wrSCF}{=wP~*6d0Xl;)Z!Kn@ui_%6lDatQ>WU%DaWB^$nlCjHcg{ot zOrE$hfg6t6Zz+J(iIfmhFOnjCxi56KcY&|!QRyyBFS=B=caX^@ol?YHWLW;p)$Ner;N@H>5T|Z1B`Bmm==zLqlxDG0!^;58VCVX$do8QBp;YxKS0f{X+|=z; zZC-@>s}tQc{7FNJX8=;pC`bUhnGUrEkU`|9G${v|NF7_cd=BfDjZl2>g&wFH-XTl@ zWvNWpz&JB~PxP;N|1-lazzjSI1bA(ymG64a=L!@^PrS_7x`e0;J^Qt!V@@|;s3Q2~ zhPuY%R1b2c5R_ZF+LH?1mA69Hs|5c_zs%1s%~p{fXi7vo< z4mn!sIRtR4u&irVDdY6{z1-eZ`TE@TKdD$%9K&^OeAyqg!^4$x;us)b>8=>`IQkIZO~LmvIl9a8UHprWeaK-QOeYXaqy5Z69vb~$->mpQ8zS|CdLBHI z4J{B(>Qi;zZG6Gg`K68~P?1qVTJ@mzvo;_r=@Wq881TBT z-6A7630^AZp_HX2{%n2?w<_4Ho2a=o$xpM2p2h$<+344GS(enNI+}_B8?6jab4h5? zlMLntjQ1MC9K#SJ|3<K!9)-4?$|A_b%S9z!v%HQagco#o)Eq_%*pi`t$REmDO>^t_! zzUe2!(BobWNdJS;#b?QbS6!|Eo^>eHjF6}1kPIYzQaYewj!a{eEW_QY8jsX&`Y1Q| zYf($XS>(lB(}VwaupHUDj@l;q{G>oUCH@)SoIPZ zi!wgwAVD`zEo;1300f#Ud8XC zq1@O7R(+wM*o!*Ix-buHaN!wd;;;yBe)J~BYyHudU~)AUg&+ud;56RMcni3jBpDjF z*_h;>2y5a;abcBiqcP zC%UZj!)b2K!X=K~wUeLfWZqS;HwV4ad1@^i1< z$OD_xT~oUcp9USvGB&x+3qfP~_Ho(+K6b9%SsW7J?`6b%oV|uXf=T;Ut&5qhXJUn? z1WUiu&=1FP=Gu7aL_b>{b944PA{~IpLFT;CAY)KEkg`+te zb+z)lKc-dV8G4|Oz>}Q|QkYNJ{Csn-em1@t9wlC({@F0qb2p*gjt|ysAXvPp#vI2y zh*ZxY6(IaKM@6%+^hI?~nVPaznvc5;;-rGVr)KWQ2E9YaoccDjSl(XeXBpV>Hoo6`L}|r zKPs=8ZrMTTG4D~zRZGqcym)nbuiLVWqkoDjudXZ7z4sUH z>L12MX?>v=5ge5k|K0~-M7mixt$9m|wghl;Y9iLALk7?@an^$65Zxab*AHGGTzFM? zmciwz(+YlT#v9@3uK!64Xsa!Gb^#OLZmZPlxQu&E)r(*;436LN;>StfVmP(dlpZF% z*wYA{esA&ERe&0LbMfL>`p}6(`&T|Evh@)xBp`a3!VMI?gyMPhr)%kF`4M%d|N0%^LUF z&*2u&K>38;*NbVBak(k@;>+icCX2MB|8$=x@&wa6fyAR2>tHqMmEHCr?a`fem6^f@sL`gUcQ=D82I~>gSsCR&AW^ElK`+Ehy=FCPCJXbi>>$?yiBy7b`ug;NS0B3P<2&I$K8g| za1n!nN5L^_7Ucd6EBVN787Up$S^Lp$W!|xs=PU2@?ZS&T(o6G5o(c}_F9O2;OQliW zdZ#6dkcDW!0MInbf@Vvq3@T zRUNAONh@gE4=grF##>bL! z^a*67ndwp-&)UbpnnKNs&vyd4!dwaz9$L#il(zZ^DmVIx*>Bdq?qaRZa8M{N%peb& zA}Rtny5I5uYy53xUhQXNEy%7wJztM9?NwLFn4`F7nn(c7`C&DIwpd2-1V>zD3#nvD z&u6JD^I#h}vGrsVn4<|u(7IoGTN6u}TzE5a$fJp?NB0{S)6aw*0S#2JhFF@kWs;U+ z$XVGIAEE$mTz{i0!?i@cS79yTEj>6>|EHy4#`r+VcTj(+sbt1+jB7ES+2=~_aM3BB zwUOM+-u$0XTQ>rw%`RUtE$FnuUaHzh9aWa!j9Ieb-c139I6Laa<0?Wx&$VI^v*D zr$I+z-@Kz9T6Rs4_2PDqsUR)Q->C}u#9LKoW!#$k`n~|qVeC;F^p&Gmvd$VGe;)TE z4#~cw5P**L!6{yHF(kX@@q{*NvF(0j`^Eu#^=qTKOJ{;dg(tw|u}LDtR0!#M++(Jb%8H(nD{`Xeul8;w7l&CzVbwma+v=03~FEwP1e zCJi)c8~*YdYt6=_gnc&dEuhGt-T2uyz1R*Za2S=D&!%Oz0U#3PahJXQh_1SqO9m_| z`d$q?IuQ>Q2bu6*U0X4{%9zrrdQRL>??^=;XD+1Tekc>pId+wA>Sa>*;w|Z5N6ckM zorTN9DfkpT_X)5C0t}#*D`J>8qlKMLa><{a`gT5w% z_F5&{M&SnoZ{1~o{JIDBA;mKJ25nB`0n9ATX8lve-U*i^nUa$!eQHk3i5B0#p|D2w zzt(u!2RtAszWu8vT?VyV2INt;5$d}WV%tJ?@3@#AfGfZP1nMb*R2gv36qor^y{*i2 z6Pq{oPvbyyFwWnA$^0CI%dvA|C)Utw3L% zT$~%&H-F;tdNTJVCik(_O%4*RDpBL+l zY{fY2dN^%Y}ZF|BOa72|qO$R4pA;tRGBQhe20eB3-a;ksTsRk??LY4NCHa?}8r>0bq882tny z$;Q&fO8R=+6gtBcHjcb`Z&IW16QBT()DtR`XRQq;Ef~GkjBMH7qdg7+P@+>}LND}m zZAxB~Q&rZ1F7>o?`OAkUuNxjq3CEwkprz&9ev3Tq+)@Jo+}#=sy0=_a+N@*sb_QV8 zumM*QOu_Q+^(@f^`3xo5d%1aP%GV9)sQ*L8dvfJx8zb~89`Rk(q6^8CYgxE%_U3Oa zgQ~0e+eVz*9@4-cj0>IId*f(+=jlQpacNnZ0F2y|LR|M>c;;7t4+&U<_vJ;CQ4tB~ z&5W$a#2i^3=nU$^@}y87$YK1@=5qpRX%ho9Iw0#L9iP;}_$r%zc)}-#?berwUIrXP z!n&NP(lYu14#9XpToYEA=O(3<&TIS~)NjC`rsKzjS`Trqzge(2AXLdFkt|5Q(2m&s7M%S_C9X>O+Aj3^ZL4vILp2?61f-zexNOO!<&=D!N2 zhiqm_;li*iUqV-eJU8UcKmCjVXZpZ+h!rP;@}Gon%@~EW*arP5*DI0#W?5Dvqb2ai zjKO>*_Q`%9s@!%9CW3K`y$9%CrBn%#zRK;JTavnYQ!XsZkkJG*k-lC-H0*0J=jd*| zv1yKpQOsu`=pX2W-z-Osm^kgRG*Sx=SWR?sHC{L_1(H5Pfl5f&*;Y`bf!O5?~=>7xRJ=W&X+p{O*Qvk(W z6*UA$?`iy1OHZb*_p#g=`{C(lGgUa@_RWxN@>A*JFE$S<=CqMk$hW}B4&iVp<4nWg zJ0l!RLJ6t(IiJWQ@jw2b%o(qgc_56F(?6zb6{{Ke-;sNa=y4|rVDINdD%-6E0s0Cv zzVok%*zHJ-fQs6{qhCj?65@5NQKAzoWgA(MFQRLy2j@~=|6b7WLK{$yCd>T>mpee% zVxl}=ZZxzQ$J+o$+?X=~8jT3rKK73#U5b46CF~GIWV7LAwP-a-19_}I0 zA=+nBx`dufNqnE?8IV{_1mk&Lpv#pW7Dwj~4L>jNpk)aXgEB6~$tnIA+1t1g_e(Tp zwgH>}#Ws577mfwk2|ztp6Z!_TPi#STAU}S-{VeGo#AqQC`(=AeP^tq^+0+60QFjW~ zx7rpx^VrxG43`Q0nU0C&T**>GY*rcbgp1C#dY|VD^60v)FmMpGv1X`H7?1IAfRE^2 z{8gO}EyAg%AYfPo7`YjYkfT3Tr@aDI`_ZBXyE@?gG`w#?L3M^<8di64ETEfNy|)*u)nb@`S3-f zjk2uu%S-tHpv^S_cZw?b*dsrcjHb~q$IArdjX`v_wWcR@z?m{^+G*6V0d|3{p^B)u z0@2G3yq7u96E1J+9RA{tz4$cHGy~90_EN~{Hr%%cv~yWb-3V0MwsmZb^8BjSk-5T2 zy!!9>EVBT&(Arz99DZJL<);8~nx-8`gZnf>ye(9$TEHXvVaJ$d+OIdz9g;nMU<8tC zGyvt83B350#bCTu^Q}81G|(V9(B34^ywdbw+a%5BFZfCDv1w$&%c})}-sJ-v?21|| zk7Pnl5m9A1qXoPb0X^Pj{VpGeAN*{KGLClP|NVYbd?GJDBsQzIM@LAsBB}8yK|lYu z7hBr5)%<|^k2RM~FFBWarTuz>#Bkg90@OuKaV^WckmgP+DopNK-N+P9I%fPGoABBn zPo+X9lhm@m0czJbQ7otx;Yf4>Tf+}G;j8HT0R{L%HLnNb51DnkCp5>!^YyA0=*Kr7 zs0HaBHddd4qa?2tbJS0I&jtXbGi`E5wN@>*XFe(5g)bl1(s4|4me>z#j%8V(iQVUs zZlV}2!9LSJ1>jh1%4`RgQm+My!TFCWRCjT&FcD20HNkI=IxeqQtg#a)gHFta$FBFg zdn~4Xfuscwsg|k3=f%@&d-er|a+-zkV@wd_( z@9gnbS|O`Ad_^pjeel=#vAHyc9#!M+b6sq_2Hq|>FD->BKFvV|-VL$;5U&x4`~Wxw zo0Ao4kMCCixLsCG$v&l$rl76=V&rKl(O%2U_y#1W3b6V_yZCTYA5Wx68N#6}E$0N` z<%toHX5C2ncSd0zbHU%Wahzi^s>*xies*mU5C_##>BghHKmLq~ZqLZC@+kPW(qpS; z?)^3YrJBW@G}hqz91GjWaQM@0?>S|hVf%!?F?Ky#dsnpq(Tx#NvzgQ^xlfsJBxO1I z=+yKXJy5EwS>$Rd0f{9FxZ$rv%SN!@gSgO(jO7{LP89UMv+t zu42|J;Q$hgCTMs(d~Aqtp7d17#uan63SwI__r2=+7l3sY_%&NpKh01TsJ7RIe*%t>;*Dtvh)@u6MLu5)KOOPk|j9}RhCVcykQ z@j)l!wBJ9QmKEG`CN^=kF@ag-cdtHskb@cehVl;8CL4gb zB{`gRBpCJd{>a*z!FCjZ5n!lkUgyq`MvyFG)XnEA!OzEV=&}%?zmjl_N1L048>XFI z^0R`uRWrHG3n#!BEv;!Ld15MzuDyKuuZwuF=EK>y3-G{7C8U7xQ}{3#dy2|)pkaLT zu$_X8e!^g0H#Gc~(&p*TP_5ESA6f>@nh$!n-oyf7-xI3rT#6C>)Q{`g>^D@&D1b1S zEa$)Jb%%$JoxS&APKYdE-4z-Q`z@)oua9}BA$ePGiepwH7IE$ zB(7o;tjKJhWV0EI>(0QAH=vlrJC5Ia#iJ@u8t6qPS*SrWcrRn4?|QT%*XZedE_kvT zU%D#z_l5Y3b4AXmc>SOY&nkj#6C`2!TNgZeb}ma82?-PeU5p!$4`fY{;D+ zQwXO}TBHfFZ)D1}oLd^};DSqcdnzQbijJrAYMd|zCFW!uEXO%oC94JG zuFjzy(quFFo|@)-w%ugOG!(C#)~tOWK$p^GrYMu6Lhm&M5Or)JPi#6w5dBTn1$Uf- zQ(`ACWke`Bjy#5$bEz5{lY+iUGK4MMV(*KWL>uKhexkT4Vk5DyUiKj|Q$y zsOsKUV9dNyMsHcVLW{=6*vYre#3dU?V34!9nTM>s%Yi$49V8ErTrsp7&mCXNNKQ#4 zub?s6zUsokFI!Om-TPF!5%t!UoLGs9J!h_2YlY9Qp56oyus8 zvalRy71Sn)#@v5l@#sC_W7)vIhK)_7mX>iOWWSVDLllVX%~|3qP-?N`^HzHE$c=mM zv+wb)5&BFXER5{UX==GUbbnZe(st2Ig_nS;-_=TfINC2*)L4GfFUs{D&bjH6>13x< z^*ne-!*yMkXuFQ6^^zPaWml(eqw!UAsjsBZFR`qCx%%TlgBe7Ra-g!0~m}HPJns%rDE&sKubsFW-jI0O9!`)MLkcSr@?guLaF8 zP?g69wJv$crakz0s?8D#&URd27}>9(<6(F*Hgo55-w$$T4}=qTQ_kaC3 zJ_WM>+Zsxy=pKeBSuT9>vfv`6e?<>pb!&LvBj;O+V0EA2S|4%l2TAX^Okyh#K(std zfpY@XOa#{RxbqC@a7lNN4bn_d7{~xrX60Ajz30wf$#MZx z@NvdttPb+m%;Fs9g$Y$89XFM<7mAdofh)Ly|f}Hl7@0P-y9T(qIY}Rdwn!b`= z100`>evUm!J{bJ*`W!9&G{;?6@pF2Z%o7f?5FyS`v1X{ti9fk2Cx`8I;7dZ<^>NW8cl_nEXJkI279nJjvZwguZ6mR+6XsRR|hk zpMS6DS3l0M&z62SQS-7;Hxv^p>b^h+_+ctc>nHNr>_rN1@ zl#50nfU7FZxxUDW@#*iRtd*(?lwT}sdy%V~)l1sB_}Vus`-WCoA3Up64&RApo|n8Z z&TuaL<80sZ+CwDvE4+J(wY;VzcnyT-(BMYqVbW<4>NI#DTeT2M&#o6jO~UTyUPnO=5F3>XszfNpJ_IVW1Y$788+4{Q`_}muu`sf6^m!c`G=r89 z^!|cfb*&tj-mJ%adn0@|d!LelhHAT=u06A`_|PFot@Q^#=WD0SrbE2eaZ~Tfbf%~X2hU$S9X0~X5P{Fzc;ql^ zL@+$t$wqBr&-Gp=-`%@ELAzumh6{W158okgpHDnxA3l?N-wLohp+IWfA?{3g?dXS1 zUmE(t+w5*Pd2;E~OYk%$2Rc34l%~Xm*mPZP8^y2OE;4b5c^hR4CqF}d?6W({jq@zb z)2iusf3v4)Z`c{Y#A#@m&e2MFP6@V_=r3EahY4St2Ge8@5j%IS&tQ|Q~ zb1`C$uObtQY$xvV^4PB$2^U3f!Bs;cQ@k8KYQ>^(d(EE9;#uD{XiSKc@-=45 zDd)7XQm(dZrE_M_q3w$i$_>tDjZF)esV61XJ3{yNG{^ZH3;KBLo|hODXI|UC zV;r0E582K;UD9?z@$(ZApIo{@I*V>zk5}vQuodKn18}pz?f||3ZIuLy<>Ev2Rb%)|I5&SSe58VOn_T1hFMe@gzpPU zzbH@&E@@=g=k~;PQ`@@{3nYk?L4T!dCqumeyvEh%dj9VX==>#cpLXzwxkV-?K;?+v zy;FrxwNieKWsnYTN`XwZ)Ng;DLCr_*HgT?7q>_-j-YBb?W-TE+`* zJB;SPK|VJ4b55%$Qun|hohQmO4DbXW@r)$f`d`9%PR#!n(f=ENe^im{SorqU&6Xce zGZ<3Q?QNL14EXzY_1$$TD~0VX_t?eDD2ld6>SSl*wJ6RFw#Yfy#ikUlzq07BEPuoD zy?+Ss7pb^aD8{g9ehPJ5qVv0?>PGm?|NImQEU4hrShe2`fY|fa$t#hDF1MzR`6rfy{ z*yKs#fp>7~JDT~_(!aomCE%K6u0tvkrD-nYZRjhT^D%DMr=m&cqqz(=Hl;33JV1uJ zI(cK42EJa@SFp2=>{bcA-nXg^j&@;qU=FJxCeg(wZ<<6Qkw@Z4kMb=2_Yx-+u;Xsr zjwpJp$_;Ad+_1@YF^*HYR;U(GAqTo=4y%m|TFFO9czT!)<*%~y{=S;F=_Aagl&syB zX>Tc+Dc4hUc$9~HCNZqKd5T~ar0e$>TF`u1VZ7UOceJ@Fk@}bVBWd)DVth?=p9^7D ztN(*b_3^mg?tt=L)!K*UnuVrV-Cy~%sjD2rs_UoR0W*JBj-bFzX5-i@a0(8!_|dm- za;Z2UoYc8UcaS(_b-Ayk-LC{%1|Y!FlNUHw;8=b{xPhUZM|~na)9_oNGYh%aa~{eY zyWF>JK13x@`si3sx_^3zGd>Y4Mk0p|z`23!0nB8$)y5#r?c?L(-wua}R~l;bUvwV8 zCrK<9!I$^o9bB;M&_|WBck%UBplI=wqt32}-M&pPd!>-&!5^03QCXCDza0LkX2#_r zv7fwT*Y}+J>18w0w#Mej40&n~bp{^3Eh@YK3B?WySlijib<9N!{HM(^B~WoiFKg3Sb z(lC2piT^MT)<*g@$gr16cfm$TchQ%wXey{NNQk`-ctSc;#^SXV7<_|e2fn^gt@N{y1M#fpzD>~nH zew2W9SY)()ac|7zw@NhK!rO}Y*_Hb!ia~3wvp84_0Wi-AwSoPDbFL(uA|o-|FA{Bu zO|O74R(>|U+N4K-2Z|l=2^#-`sXrD_27KlXVg5Zyg1tXasPgfkKRzQdXDX|&DPjn7 z3Xg^sWj%jK;l`6OvAwck)nG{SL9HV34+{6sF{IO)CWZ*fcodg?`n=@%eHE%7$DWXM zi)nt`U+o*DVOhaXpyOG!U5=VSGs?vrKq9hbS`?G9(f zpZEf8bJ1A-whP)~b+>5}AU#W|v zViB(5M|7I3iqFz+FX~2_*|3 z1cK#d-wSS`!rCyez*K){6<+kVecTW7>r&%MIP*e-nm5lm7dY$!q{Q4;M5V=E>LW|t9aXD18*ze63pjd#xDvgm2JW&$(rN_VRFw>e;rDc0ZX2I zPwd(Uw;z{y(6V*iCJg^Zg}^a#T8OL%liw$0Mg3d*UXRiD`j>%&JOV(bv;Z6>^Wzk^ zxd+sruMQDYTFD)!yd1M=Tuk(F7l~tK^{%%hz{CheGBojL1jU6mBkR5s=Jj_ zbMxOt$^QSYqr>uU=aED9)uZvt8fObtzWh4XK-jU~ruJYcgmVH=D4w5_JVD%ZsD z816l~jyOn5jCmZohZq3O=l@;!a`CY0=3uO*#>@@6{4giv^CY)5Ul}yW&Afco/debug.log` on the remote host. +- **Agent Not Starting**: Inspect the log file at `~/.coder//coder.log` on the remote host for errors. +- **App Not Appearing**: Ensure the app is selected in parameters and the workspace is restarted if changes are made. +- **Validation Errors**: Parameters like host and port have built-in validations—ensure inputs match the requirements. + +For more advanced customization, refer to the [Coder Terraform provider documentation](https://registry.terraform.io/providers/coder/coder/latest/docs). diff --git a/registry/IamTaoChen/templates/ssh-linux/main.tf b/registry/IamTaoChen/templates/ssh-linux/main.tf new file mode 100644 index 00000000..42df9dce --- /dev/null +++ b/registry/IamTaoChen/templates/ssh-linux/main.tf @@ -0,0 +1,319 @@ +terraform { + required_providers { + coder = { + source = "coder/coder" + version = ">= 2.4.0" + } + random = { + source = "hashicorp/random" + version = ">= 3.6" + } + } +} + +provider "coder" {} +data "coder_workspace" "me" {} +data "coder_workspace_owner" "me" {} + + +data "coder_parameter" "host" { + description = "Remote Host or IP" + display_name = "Host" + name = "host" + type = "string" + default = "192.168.1.1" + mutable = false + order = 1 + validation { + regex = "^[a-zA-Z0-9:.%\\-]+$" + error = "Please enter a valid hostname, IPv4, or IPv6 address. Examples: example.com, 192.168.1.1, or fe80::1" + } +} + +data "coder_parameter" "username" { + default = data.coder_workspace_owner.me.name + description = "SSH Username" + display_name = "Username" + name = "username" + mutable = false + order = 2 +} + +data "coder_parameter" "auth_type" { + name = "auth_type" + display_name = "SSH Auth Type" + description = "Authentication method for SSH" + type = "string" + + form_type = "dropdown" + default = "password" + mutable = true + order = 3 + option { + name = "password" + value = "password" + } + + option { + name = "SSH Key Manual" + value = "ssh_key" + } + + option { + name = "SSH Key from Coder" + value = "ssh_key_coder" + } + +} + +data "coder_parameter" "ssh_password" { + count = data.coder_parameter.auth_type.value == "password" ? 1 : 0 + name = "ssh_password" + display_name = "SSH Password" + description = "Password for SSH login" + type = "string" + mutable = true + styling = jsonencode({ + mask_input = true + }) + order = 4 +} + +data "coder_parameter" "ssh_key" { + count = data.coder_parameter.auth_type.value == "ssh_key" ? 1 : 0 + name = "ssh_key" + display_name = "SSH Private Key" + description = "Paste SSH private key" + type = "string" + mutable = true + form_type = "textarea" + styling = jsonencode({ + mask_input = true + }) + order = 4 +} + +data "coder_parameter" "ssh_key_coder" { + count = data.coder_parameter.auth_type.value == "ssh_key_coder" ? 1 : 0 + name = "ssh_key_coder" + display_name = "Public Key From Coder" + description = "Add this public key to your remote server's authorized_keys: \n\n${data.coder_workspace_owner.me.ssh_public_key}" + default = "********************" + styling = jsonencode({ + disabled = true + mask_input = true + }) + order = 4 +} + + +data "coder_parameter" "port" { + default = 22 + description = "SSH Port" + display_name = "Port" + name = "port" + type = "number" + mutable = true + order = 5 + validation { + min = 1 + max = 65535 + error = "Port must be between 1 and 65535" + } +} + +data "coder_parameter" "apps" { + name = "apps" + display_name = "Choose any APPs for your workspace." + type = "list(string)" + form_type = "multi-select" + mutable = true + default = jsonencode(["VS Code Desktop"]) + dynamic "option" { + for_each = local.apps_candidate + content { + name = option.value + value = option.value + } + } +} + +locals { + username = data.coder_parameter.username.value + home_dir = "/home/${lower(local.username)}" + coder_cache_dir = "${local.home_dir}/.coder/${data.coder_workspace.me.id}" + agent_id_file = "${local.coder_cache_dir}/agent.id" + use_password = data.coder_parameter.auth_type.value == "password" + use_key = contains(["ssh_key", "ssh_key_coder"], data.coder_parameter.auth_type.value) + ssh_password = local.use_password ? data.coder_parameter.ssh_password[0].value : null + ssh_private_key = data.coder_parameter.auth_type.value == "ssh_key_coder" ? data.coder_workspace_owner.me.ssh_private_key : (length(data.coder_parameter.ssh_key) > 0 ? data.coder_parameter.ssh_key[0].value : null) + apps_candidate = ["VS Code Desktop", "VS Code Web", "Cursor"] + apps_selected = (can(data.coder_parameter.apps.value) && data.coder_parameter.apps.value != "") ? jsondecode(data.coder_parameter.apps.value) : [] +} + +resource "random_integer" "vs_code_port" { + min = 54000 + max = 55999 +} + +resource "coder_agent" "main" { + os = "linux" + arch = "amd64" + + startup_script = <<-EOT + #!/bin/bash + set -euo pipefail + EOT + + env = { + GIT_AUTHOR_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) + GIT_AUTHOR_EMAIL = "${data.coder_workspace_owner.me.email}" + GIT_COMMITTER_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) + GIT_COMMITTER_EMAIL = "${data.coder_workspace_owner.me.email}" + } + + display_apps { + port_forwarding_helper = true + vscode = contains(local.apps_selected, "VS Code Desktop") + vscode_insiders = false + web_terminal = true + ssh_helper = true + } + + metadata { + key = "cpu" + display_name = "CPU Usage" + interval = 5 + timeout = 5 + script = "coder stat cpu" + } + metadata { + key = "memory" + display_name = "Memory Usage" + interval = 5 + timeout = 5 + script = "coder stat mem" + } + metadata { + key = "disk" + display_name = "Home Disk Usage" + interval = 600 + timeout = 30 + script = "coder stat disk --path ${lower(local.home_dir)}" + } +} + +resource "null_resource" "deploy_coder_agent" { + count = data.coder_workspace.me.start_count + + triggers = { + init_script = sha256(coder_agent.main.init_script) + token = coder_agent.main.token + } + + connection { + type = "ssh" + host = data.coder_parameter.host.value + user = data.coder_parameter.username.value + port = data.coder_parameter.port.value + password = local.ssh_password + private_key = local.ssh_private_key + timeout = "5m" + } + + provisioner "remote-exec" { + inline = [ + "mkdir -p ${local.coder_cache_dir}", + "coder_sh=${local.coder_cache_dir}/coder.sh", + "log_file=${local.coder_cache_dir}/coder.log", + "cat > $coder_sh << 'EOF'", + "${coder_agent.main.init_script}", + "EOF", + "chmod +x $coder_sh", + "echo \"$(date) : create $coder_sh\" >> ${local.coder_cache_dir}/debug.log", + "nohup env CODER_AGENT_TOKEN='${coder_agent.main.token}' $coder_sh > $log_file 2>&1 &", + "echo $! > ${local.agent_id_file}", + "echo \"$(date) : run $coder_sh and log at $log_file\" >> ${local.coder_cache_dir}/debug.log", + ] + } +} + +resource "null_resource" "coder_stop" { + count = (try(data.coder_workspace.me.start_count, 1) > 0 ? 0 : 1) + + connection { + type = "ssh" + host = data.coder_parameter.host.value + user = data.coder_parameter.username.value + port = data.coder_parameter.port.value + password = local.ssh_password + private_key = local.ssh_private_key + timeout = "5m" + } + + provisioner "remote-exec" { + inline = [ + "set -u", + "PID_FILE=${local.agent_id_file}", + # Only proceed if PID file exists + "if [ -f \"$PID_FILE\" ]; then", + " PID=$(cat \"$PID_FILE\")", + # Check if it's actually a number and process exists + " if [ -n \"$PID\" ] && echo \"$PID\" | grep -q '^[0-9][0-9]*$' && kill -0 \"$PID\" 2>/dev/null; then", + " echo \"Gracefully stopping process $PID...\"", + # First try graceful termination + " kill -TERM \"$PID\" 2>/dev/null || true", + # Wait and check repeatedly (up to ~15 seconds total) + " for i in $(seq 1 15); do", + " sleep 1", + " if ! kill -0 \"$PID\" 2>/dev/null; then", + " echo \"Process $PID terminated gracefully\"", + " break", + " fi", + # Show we're still waiting (every 5 seconds) + " expr $i % 5 = 0 >/dev/null && echo \"Still waiting... ($i/15 seconds)\"", + " done", + # Final check - only kill -9 if still alive" + " if kill -0 \"$PID\" 2>/dev/null; then", + " echo \"Process $PID did not terminate in time - sending SIGKILL\"", + " kill -KILL \"$PID\" 2>/dev/null || true", + " fi", + " else", + " echo \"No running process found for PID $PID (or invalid PID)\"", + " fi", + " ", + # Clean lean up regardless of whether kill succeeded + " rm -f \"$PID_FILE\"", + " rm -rf ${local.coder_cache_dir} 2>/dev/null || true", + "else", + " echo \"PID file not found: $PID_FILE - nothing to clean up\"", + "fi", + "sync 2>/dev/null || true", + ] + } +} + + +module "coder-login" { + count = data.coder_workspace.me.start_count + source = "registry.coder.com/coder/coder-login/coder" + version = "1.1.1" + agent_id = coder_agent.main.id +} + +module "cursor" { + count = contains(local.apps_selected, "Cursor") ? data.coder_workspace.me.start_count : 0 + source = "registry.coder.com/coder/cursor/coder" + version = "1.4.0" + agent_id = coder_agent.main.id +} + +module "vscode-web" { + count = contains(local.apps_selected, "VS Code Web") ? data.coder_workspace.me.start_count : 0 + source = "registry.coder.com/coder/vscode-web/coder" + version = "1.4.3" + agent_id = coder_agent.main.id + folder = local.home_dir + port = random_integer.vs_code_port.result + accept_license = true +}