From 1073f82f1f32c71d0f08a8c0924b833f2fe57017 Mon Sep 17 00:00:00 2001 From: David Parsons Date: Sun, 19 Aug 2018 16:58:02 +0100 Subject: [PATCH] New ESXi Unlocker first commit --- esxi/{esxi-smctest.sh => bin/smctest.sh} | 0 esxi/esxi-build.sh | 12 +---- esxi/esxi-config.py | 63 ---------------------- esxi/esxi-install.sh | 21 ++------ esxi/esxi-uninstall.sh | 10 ++-- esxi/local-prefix.sh | 65 ----------------------- esxi/local-suffix.sh | 4 -- esxi/unlocker-esxi-300.tgz | Bin 0 -> 4754 bytes esxi/unlocker.tgz | Bin 0 -> 4187 bytes 9 files changed, 10 insertions(+), 165 deletions(-) rename esxi/{esxi-smctest.sh => bin/smctest.sh} (100%) delete mode 100755 esxi/esxi-config.py delete mode 100755 esxi/local-prefix.sh delete mode 100644 esxi/local-suffix.sh create mode 100644 esxi/unlocker-esxi-300.tgz create mode 100644 esxi/unlocker.tgz diff --git a/esxi/esxi-smctest.sh b/esxi/bin/smctest.sh similarity index 100% rename from esxi/esxi-smctest.sh rename to esxi/bin/smctest.sh diff --git a/esxi/esxi-build.sh b/esxi/esxi-build.sh index e1f5e1d..a081ce3 100755 --- a/esxi/esxi-build.sh +++ b/esxi/esxi-build.sh @@ -1,13 +1,3 @@ #!/bin/sh set -e -#set -x - -# Ensure we only use unmodified commands -export PATH=/bin:/sbin:/usr/bin:/usr/sbin - -# Copy patch to local.sh -rm -fv local.sh -cp local-prefix.sh local.sh -cat unlocker.py >> local.sh -cat local-suffix.sh >> local.sh -chmod +x local.sh +tar czvf unlocker-esxi-300.tgz unlocker.tgz esxi-install.sh esxi-uninstall.sh diff --git a/esxi/esxi-config.py b/esxi/esxi-config.py deleted file mode 100755 index 67634c2..0000000 --- a/esxi/esxi-config.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python -""" -This is a simple method to modify the hostd XML file -Not using XML on ESXi Python as it does not preserve -formatting or comments. - -(This could be sed but cannot find a suitable regex.) - -""" -from __future__ import print_function -import sys - - -def testline(line, test): - sline = line.lstrip() - if sline == test: - return True - else: - return False - - -def main(): - vmsvc = '\n' - sandbox = 'false\n' - - with open('/etc/vmware/hostd/config.xml', 'r+') as f: - data = f.readlines() - - # Search for the relevant XML tags - i = 0 - vmsvcindex = 0 - sandboxindex = 0 - for line in data: - - if testline(line, vmsvc): - vmsvcindex = i - - if testline(line, sandbox): - sandboxindex = i - - # print(line, end='') - i += 1 - - # Simple toggle on or off depending if found - if sandboxindex != 0 and sys.argv[1] == 'off': - print('Removing useVmxSandbox') - del data[sandboxindex] - elif sandboxindex == 0 and sys.argv[1] == 'on': - print('Adding useVmxSandbox') - pad = len(data[vmsvcindex + 1]) - len(data[vmsvcindex + 1].lstrip()) - data.insert(vmsvcindex + 1, (" " * pad) + sandbox) - else: - pass - - # Rewrite the config.xml file - f.seek(0) - f.write(''.join(data)) - f.truncate() - f.close() - - -if __name__ == '__main__': - main() diff --git a/esxi/esxi-install.sh b/esxi/esxi-install.sh index ac79756..356d926 100755 --- a/esxi/esxi-install.sh +++ b/esxi/esxi-install.sh @@ -2,24 +2,13 @@ set -e #set -x -echo VMware Unlocker 2.1.0 +echo VMware Unlocker 3.0.0 echo =============================== -echo Copyright: Dave Parsons 2011-17 +echo Copyright: Dave Parsons 2011-18 # Ensure we only use unmodified commands export PATH=/bin:/sbin:/usr/bin:/usr/sbin -VER=$(uname -r) -if [ "$VER" == "6.0.0" ]; then - echo "Error - ESXi 6.0.0 is not supported!" -elif [ "$VER" == "6.5.0" ]; then - # Copy patch to local.sh - echo Installing local.sh - chmod +x local.sh - cp local.sh /etc/rc.local.d/local.sh - python esxi-config.py on - backup.sh 0 - echo "Success - please now restart the server!" -else - echo "Unknown ESXi version" -fi +echo Installing unlocker.tgz +BootModuleConfig.sh --verbose --add=unlocker.tgz +echo Success - please now restart the server! diff --git a/esxi/esxi-uninstall.sh b/esxi/esxi-uninstall.sh index 753e1d2..bc0e02c 100755 --- a/esxi/esxi-uninstall.sh +++ b/esxi/esxi-uninstall.sh @@ -2,15 +2,13 @@ set -e #set -x -echo VMware Unlocker 2.1.0 +echo VMware Unlocker 3.0.0 echo =============================== -echo Copyright: Dave Parsons 2011-17 +echo Copyright: Dave Parsons 2011-18 # Ensure we only use unmodified commands export PATH=/bin:/sbin:/usr/bin:/usr/sbin -echo Uninstalling local.sh -cp /etc/rc.local.d/.#local.sh /etc/rc.local.d/local.sh -python esxiconfig.py off -backup.sh 0 +echo Uninstalling unlocker.tgz +BootModuleConfig.sh --verbose --remove=unlocker.tgz echo Success - please now restart the server! diff --git a/esxi/local-prefix.sh b/esxi/local-prefix.sh deleted file mode 100755 index 2476135..0000000 --- a/esxi/local-prefix.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/sh -set -e -set -x - -echo VMware ESXi 6.x Unlocker 2.1.0 -echo =============================== -echo Copyright: Dave Parsons 2011-17 - -# Ensure we only use unmodified commands -export PATH=/bin:/sbin:/usr/bin:/usr/sbin - -# Exit if boot option specified -if bootOption -o | grep -q 'nounlocker'; then - logger -t unlocker disabled via nounlocker boot option - exit 0 -fi - -# Make sure working files are removed -if [ -d /unlocker ]; then - logger -t unlocker Removing current patches - rm -rfv /unlocker -fi - -# Create new RAM disk and map to /unlocker -logger -t unlocker Creating RAM disk -mkdir /unlocker -localcli system visorfs ramdisk add -m 200 -M 200 -n unlocker -p 0755 -t /unlocker -logger -t unlocker Stopping hostd daemon -/etc/init.d/hostd stop - -# Copy the vmx files -logger -t unlocker Copying vmx files -mkdir /unlocker/bin -cp /bin/vmx /unlocker/bin/ -cp /bin/vmx-debug /unlocker/bin/ -cp /bin/vmx-stats /unlocker/bin/ - -# Setup symlink from /bin -logger -t unlocker Setup vmx sym links -rm -fv /bin/vmx -ln -s /unlocker/bin/vmx /bin/vmx -rm -fv /bin/vmx-debug -ln -s /unlocker/bin/vmx-debug /bin/vmx-debug -rm -fv /bin/vmx-stats -ln -s /unlocker/bin/vmx-stats /bin/vmx-stats - -# Copy the libvmkctl.so files -logger -t unlocker Copying 32-bit lib files -mkdir /unlocker/lib -cp /lib/libvmkctl.so /unlocker/lib/ -logger -t unlocker Setup 32-bit lib sym links -rm -fv /lib/libvmkctl.so -ln -s /unlocker/lib/libvmkctl.so /lib/libvmkctl.so -if [ -f /lib64/libvmkctl.so ]; then - logger -t unlocker Copying 64-bit lib files - mkdir /unlocker/lib64 - cp /lib64/libvmkctl.so /unlocker/lib64/ - logger -t unlocker Setup 64-bit lib sym links - rm -fv /lib64/libvmkctl.so - ln -s /unlocker/lib64/libvmkctl.so /lib64/libvmkctl.so -fi - -# Patch the vmx files -logger -t unlocker Patching vmx files -python <F>S0*6E-kY*No(L0G6?7_|7$>%?VEF^q4+qQj`0Jyz%Tg%W(|Wp*sd_kk-TWfk?g)XmQPVj zUwcJ1y*X2A<5iH?9!y8>v<9;xj@9lzYO98VDy?@6SVpodt6uf>1Pq)89O&WNQ*l@m zSHC$_biuovPF$fK+xzS@+~cpfH=QlUJ<b_pN~OP1NS#^9!5AO ze5Pob{S+QiXkl1!23$t^eF~Ck ztWF}qNbM^e$ewF6v^25D^V=$Ro^ln+OUAZH$QuY+b@UAP3tkU()C+{zP@F-gr{5M=^5bRY{GYi7BqRFml#@}0tRUAW^wcr`hd~dMikYzqOvIxV3GtjkH zuh!rl&?Jv}0~Ftq^Ke;XrFsd|qYIZ3pOAF;6KABx$%v2f1+LEQSSX1ojaNd^^rQ+* zBv(){dgEuoakY5RfVG&tVXrc_;Ta#>jtDuc3nZO5+BFixGKrTuE8VeZ{`l;B9c2YnZhZRnxn-~ zu!7v|tHX_9a?KM@e{P>}MDZ&FNe8c1m6n*H3@b zPr-}L>B?&XGa;s*@^OV@P6}nD5(~qd@4fcf>Qtz6>Iquy4uxf^P6KHcdfae=u0pvk zKN(HyDo4mi&khUcwhnX0hw3X4vlTo~>nlfQtA>rI+B-liCLZ8AW9D&K-6Fn4F|0ma zmeYN5E8Aqna>esYYHE#m|ia<>-C6jRXs^11fAQSQED5-3`%*V7#flZ z1CweK9)1YrtTD2Htv?2iqi@!|N<5uR&r*+CbqLe<^$c%zZs>X!bkZM{$ayPZ z%vU}1#A&~K-&aVX_i?S&GiQE%dQUY2y?ChJn*vm{5$&*fzvTRYQStQzgE>#(Otm!6 z)SJT!U(ZXd&gznnLmf17jlC6bV-i3I<;gKD69!jCF=F}B7;vGsh=Z|WUg%q@G5>mR4MVMm|PuyCIsRz=$?OOnRlI{ha9zHhBq8Dz^oj}v{KBQ z5|hbN|C6@%$wq(dZZN3Eb(MGda$y{tdJLO0e4*w#0t z=#mOuQU@i4{Z};mT(>LQ@nZ8zkXnpUAW=x%F?fZ4UF+B#F#TiY_pHv(LM5%s) zj6bhEQubrTwFjAk0`q_y-oI6sk}cd3sM`3zQJ)M+qWEok?xz3O>-QIb=tvB-pHumC zSC7~jz%axgf;2W1h=Tg(1D%%j&hJZ}_=e1jPpit%49o+Hq=gb}-v`_B@I@!RiE3h} zzoLek#?!A;@-@3Nnnh4Z4fhYCQYDe(M(PwYzLZu8-RY2fcCupg{NtBo-*U#KrZC(# zp_l5rIq@>dGwW7dg{eGvkqN>!X4rgG8sOqw?xcLDfj0d_ZpFku!dohTcxJxdv5>mn z!!X)8{x?pubJ~0L!YV(pd);S#hb@d)o_tfU$AMq`O7GsDJe~t4+}AYSA%Wfq-!hm0zjU_q?wDYNi)oF-B!EpgIZ@jnO;?8;bV|CDy)FMG}#)7 z&l7O%CbmxYD|6s2V&+sMgXZ+|VTdAK&QS!_48PH=vZTE)wG|Vfv!tN-BKn1sh*M3C z86HtuL&Qp?D>}hAX3CR)oi`tJ(78%<-Ge1)Kh255B`uDRmz#`q`%wQY*=LMFtb!^7 zjfUNWUWRRTze69R`9bC=-TSg?2zzeLyUOKpg*veH`Np;+!_cJLCw-xYrPuiH6dG?I)7Kl-_sr%*jk$UUKZr2;TGhh4b`FlaOm6~0CYuJdh+oJOJ z!;dl&?O28krmXd?BC(zISnjV~2lx9$Z)m+q72zvoJDhKhC(WJ~;9>xzh1h{QxpQ9o z2oX|jdDs6@;d4av*8*&ReAZMm2JjF-XVj1 zS<#;m1D%>p*%Owx_LH45#R>)d3SM6;WV>Cj_}K5jmbD6g{Ul$QCF;0 zH@nNM0w#JsYzY=ae;1gy{Y3M|4&P)ENVrNOywq|Q7T8DAAFMNEQys$WG8OlQwl*qG z3+)){5_@NEn+F$}^qD0^w5sO%=Qi72hr@cc0{|<&w9G8BeM42T zWIMB%XM=d2#9B+-H?=MfEBG3;v9fcm6Vfi#UYmEH-eQL_IfkiiI7|)6*U1-Jd#WVP zz^X;(kkRz~<@8pL$VAR0PByRhn~KE&0vbn(-3%qAYkf>OSb`F37jxI+>09uN_d@wVGiyS7<@}jzl6N&3eFyiBRwXl6 zfH>Pl^T>%NcB;WB_gFWbHOo@_@dMb6maV`V-6TpZOul%v(EIUY7WdTf@Rd49&$CJ# zEf#)`kA?fs&3g}&_re*Ed(Kuz(_?t&TgE?~ILy6TmFOHfa(y%7;BcPw&^Z4f!zyLs z=Ns*+cmj5w4S8?EurloCk9~?Y8sb)sBKT>C=F8qJPkT)G&#U0^PwX=xhOxb_1>sQX zZ7ks6U1V*%{8=uGTs8ULr$OC)mPK}Zua^YOMMjlA(kuI!x zz>4VC!v?Q$27DiH(LbcYWxg^_z6qn7(bt*>e3)|H*>IMKZWmXX8L+~5Ms?FBlyS`P ztC>{pSOuv<=#D;oNs94GT;L2-c8Q7bww9wNb#7f~meJCPY!*sUc|Wm6UR=*&^;{Li zirk{QN8DAb#p>9XA58f@+lRDDGId;EO?mlGMR!)R%XvkS~aNNGcsAN0Ek_$*X zd3)lUrNXzhcq(z6D91?!_xW!epn(d{3Wex2NsslxBPl;~LS<=rfu}pSyls#C-EwDM z#XXjTrxWq!N^El!G!8JfC+=!6tu)yWS6i+SAQ9#V?}{|1rNRf_X7(vnyf-K_iQLV4 zzee7b&F@g#CF!+SN;Ow}aL~pYcks3{9FtjXvUqLbwMF)v<6a`|+#zA1%~QJ6T4Nd4 z!-*fJt!Z9y-OAM!sWK)n565`EtNgb~v+{8EPz>UlRHX^c>wlGAhw5NG5@ z$tTTieP_e-^X}E{?%?M=jQp8H=1sW|iaiblIf%r0qXC0?4B(Q~rNG=9{hlF2tC8Q! zLW$T2g-%~SP$n{miCKOPf!&D~y&uT6&=`z-#`T1k0>%EJ8Dr7gx_44hL-jEPqa7PP zi()j|c)MhPKjwS!pF-_7x<#xqP#ytPaEqrK~v1LHSp{}YJz}3S59DJn%mnr#W-u) zp_y^957>K?SBucu^wXv9tYewmS z*hgE=C7t;cCawg3_fWqrQ-dvs#nRK+E$}`k`>BvX47xMP5}!WM_pr?WMP?c-w`r^( zJpmAM7o=NOc)y{cSg(vRfk>l1EW>`RPG{3~xd}BcbFww~>A)PqlVI4Kpr>9%v3rX) zcIC$kbFQI)%3`)tl6UDXrSbDtwjwRO-u|aR{W+u4tIJmYMcs5<)Z{$3-6MHG>;lUj zn(7`)HpN>B!Xh6Sr99G**g0RN>;A)JL;>o{RjS9#@J{+RN&>aE2BhltyBpq5z+sGy z)}rl+W)G|ZZb~bb)Ac$$Z+btwc;9P_?SgVT3 z%3=RtggU3PX!G;wV)Hri!pB%CJcWO?uyM)%2sql)PS6g4b~Sf&6hhnnDRcbN{lvun zEBy})783#gP5*<4K!9L~Cf>3oxMVgUS91 zSy~wV``HbR68_u8ucp65uKGt#+aYW&hWmGo8=!zhx@sV;+#KPGNQAYW%|+4!1qI#V zC=2Ap%z}dER#vkA>4D!z({;17grm_wL7=lE-2B23f%E{P;J{tDZN{C$6|38EOv-Pk4*PQ-`cK{UJ3F!|1 g|Fj8Qa>*r^Tyn`Jmt1nmCI2t@HK45hb#z-!Sui5 z|B6{f|C_bLYS}zIDnBz!)2x}#zM>?989d z7a`*<&jtauoUMM$EuGncJsZK)55iz+m*{tD@zE!XGx!GxIv7$noCVAaal~GPa4-U` zpuxcyOdJUqJ_e<~{|4{E_dk|On&iF+*z4Jk5_Pwz)DXwPj zRvOQquCKnx#(&ECfAm!UznA~HU37iha*LzVpTqyAX&ly`{QqC@|H8w&TgHp?yYJ=y zig9RGBL5>?1^r(s*UC@p|94vd7XcTGJM)$>zYC|nm)qOh%k`%Wu3CL)J2vwI20A|E zbGb8re#f23Gz8twL)kE^2l&@9oLfr_kFMuDQXU*W$@g^SQx!euoGbacf-vcLr zDdTK-hkb(Og=|!SF=q_?G1%BdOjrRzA1v<<=8R~8KMXC$LrP$Qjl6RR8BUQ*;EzMm za$vgvRuK5MV<9~l`SxOljfWKyzp>-80Q3-*(RvC)%L^tWX1O`X1DcDb;FE&}zjcvRj2t38 z#Kx)s0SyZK7D$hh&#|v@-5gSIP;Q}XBAtLC(dT5)P?;#8kxx^9mes@wa^nT}kR=m1 zBOgsBIDTMuNFxM3_FdQiM5-Xw}w8t)Q(+Vm9JEFc zpS1$KY4tBVulj%x-NtqQEp#rRas3uvw64z!(ERnL+wAqA)6KQ6ZrZITjK;$!2q)o%6Q7IGJ@{x#9O=yah0H;rz; zb@r;==)%pb?oFrHME2)M_PTX_(M2xJtLAmTh+J_Dny>KzdY6rMn^@%eh zo44K8FPD9|?6l9DIC$Db$r`8areuXmowXaSs{))it{T5I1y%>CbaMnIrGqz@O&TJ8 z4gCMC-|AeG8fTsBeit7LsAabwqrPeNngwWdTRk$!MYnTR$dNe_qa%nQ-gQ$_AyY%f zBM3szuX@dxAe=WFZKQ?nxz4x`y}9gNoxvruMvOx*@{jLbQAmRMK_FCdh&l3Ct`BC=XyNabH3({n4dzLWaZl2L_fkjO^- zJ!^(le0YbtaJIzKf%(ablOjBS(R@pV`EB#X^L#Es$6vE#m~bjp6nIKjRFN}O!lQDF zS`p4+$vE7~TBse8R@-C?5U>C!g zzw@+wjK)?@sGGRD=SFNSG!FeKTj}InMSUCpzkyyUfT1AhdLFT=2;D&}ujt+(wUsfH z3?A6qD}L}DPv84eH_E^M4tvG1&u3OhjRoF;P3S@dfyvx}ZQ)e@PdNE}gxogRNjnhA z+zO{UE|O^0f@mfvidQl=KLI!1-= zz&@Dy;%B7h>Xm$~7T~ys|Lp^LNz&Ukt2q2-y#K9UKQP}HF&xoYy7sDnad50{MM1U^ zn)yEBU4DpqIik+l+_h|`54Cq#i*S)1B4GXzOtmjY{kieQ{C)Mi7P%&(UU^@D>V2w5 zK-Kr#Ad*0iEgbm+4K^5J&@U}_fqfO;W}Pa=;UA!z@bk}NS|Qplv-l%We}I2(;L<7U zqfl`IQJMo>_j|os6;7axPrb|jpxbOW@Ua?&l@;1k=8p9-hLt;tBFkf+R8UCr<6^+r zt!_vo&8!KoPA53ZaZT2haWTQMjf*BvfShNM&i1R_dG7-fj6vIH9hQ#8~T(OxE^9VenG^uyx>9d{am^OM@6iVrcy}d+_$}y zScQ~8`N)M>svRoTxPP25-6%xBsbxs{DRS>VBK(*ZJSi45xW%yT_Dj6z@5I7s{CsL1 zqVa)fu1>^#*Z-}6|EAp}s%$Nl@iM04v4^GZg;=8ec4Debbs3#L zinA1PWa41MYK8T9jo%?>KD`vumW$Rx{8a(-9D2C6&Xv1?B&K`XB+xVh4#e0AXeZU+ z6#uWSUTO-J+6J`xV8&*&bvOY-w#+z;CQc74gmWKWdDz-Rr}x4H3MILu#i*aA*cd{e zFR+zO)sQYiik&H1#E)dfA9313jf>od;7E)VMO7YKm$Z<%Ex{@1;_ey4F~2##v!PEEV(u1| zj2FGmhDvWJ!zhKb`b0Jr8&DE!o4BN~*zBJ&)SuP=J)yJmY$U-w7P}|l?kgKfz$I2m z?##WA^BADta({D8^g$EM6Ujxjkay7p-c2p+F-F=aHa(gqJvW3S! zei*Wq?@ktc%<=Z)IGo}j|7hP~iPX3s4$O*nk9AVyW2$P?^hhPU?0~XUlnuE^Kd9rT zdS71}c9(~T;Znv5shyVK|SYumo#H^a~N zbi&zdYyOm3TcY%vWR}$Z!cni00v{&mKY9a(tGVm@^9VQhci0uxeD~siL;SE{Gb{>u?z9%%v19k-ydpuumTvTTCRIKyN9~F zRHsI#dvU8qz0K0%j(DdK0WN2&#APXiDlc6i0omb-jpIIO;ygCRM|Q2)|3)k*t;D+o zdAt#%VEa?-x`58IsTGP|ScpiC-$YJ`V?QyxqDxP)&)t zE|x~t)Z`1OwHjokNhup|><&x?#IsNvY{;U54fvjW2d_=_W-Uz)jhtqwY@Q)@BkC#H z(U1fJ5xg1kRpMCmT_OVZ3GB52WR2*h1hUyP_VTHccMnoyG~z6f@2H@jIZR&nS$-$6 z8+C{lku9kO8aU*k+@D!qfh=!Kk1?iCu4`L7I=~(orT;Epy*O`dl2&TS% zZf@isYDfy3r7*L}j)`O&u}z81Zzr+&EhIKK3i3VSXntKdnj7J0?hZ%uG2v)FG91m# za5T)*YN=YO?UrLBAQ9C-)be9O^5l^YHvcps`K=`W9w8~pt$3|Mi+idZZ z5!>|xre}^4m$O?tboJExUaSl>AuOAI&yxDs{YJSc>Fp#Jdd0NSlSYSzk7y~SFzJp` z^e+^r$X%?j1R$5#p%zW3oL4)OXfzs>d!wO-xQu(uO(aU2ENiaBR1X+{jneu{o6ao9 z)ARL+Lof8_qI(iw_Cvt<(y^tk$p;Wc+j3o96aNqZw;*A0R8ruGtx@aGT=#?yQ)9`` z7MznD@;$s5v~g(UP~!PP5w|b)r??|WIs65;St?lqZp+?Xi~hxf7LB{kuu>K?ct?Mf z(E~pXB3{=DkXm&OC^{r&LFjnt?-T9Cf~3Y4DxA$>xS&_4cl0eG1U4s&3e2GuFsYZ| zfS@JGc!UJwiTJC91RMh{`mk3;1Yt-uWAKDXL5nm`fFs?vf^V23gC`7fAKto+V#mDk z`K_`J=7fz=kBi!J7Fy`b;8p?Ad^q`h4}H+=1xCuOh#*QNi6Y4CLJ~k(wB4MRf>WH= zGx~y3D)EB~Nvfk5_jkZnP7p>fyrXYOoB$&=MLG4>OMWv{oEee2i zA|R8Qb<2=LkY*9h+0!-NxlGj)TOAA;wqo`oY4g)Wx0?ooDLQ3QI?y+zWnE@kA&Ny+ zQKHSg8eP*)ic%>b(7XOPa416534-`{OF%oaxvWT!6cTCOC!`4dLXrh3LDd?On##yo ztA3@NnMk0x(W9D@3WP@~Q>&&=wzjBLs}_<3O|^!bYSFY(>vZ9`a??Bc?9Au%VKF9> zSh|u_ORo&?JQ0uL`{Ed&SS&{0o^6zRsysx~{=6KgPyoltjv!UrTKW^=WPYc`5+e@_ zCO~$HCMh2*;lNHyci?BJ?2<1s-WEA`nQyt*CP2mjm&I$6!Fa l25m5)Ze}o0uNP!%^YqUTpRT9t>H6Qg{srCUk2wHB001uID+K@m literal 0 HcmV?d00001