From 7663b9b9f1c85152f3ec500d5ca3e3d7715e8a26 Mon Sep 17 00:00:00 2001 From: Brandon McAnsh Date: Fri, 3 Jul 2026 09:11:45 -0400 Subject: [PATCH] fix(accesskey): fall back to raster logo when vector rasterization fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rasterizing the vector access-key logo via Drawable.toBitmap crashes on some budget OEM devices (e.g. Infinix X693, Vortex JK68) with "width and height must be > 0". The failure originates inside VectorDrawable's internal cache-bitmap allocation, not our dimensions — the values we pass (92x132) are valid, so it's a device-level defect in the vector->bitmap path. Add a pre-rasterized PNG fallback: try the vector first, and on failure retry with a BitmapDrawable (ic_flipcash_logo_raster), which goes through the far more robust decode/scale path and sidesteps the VectorDrawable cache entirely. If even that fails, render the recovery image without the logo instead of dropping the whole image, and report a non-fatal. Also removes the !! on the logo drawable, which was a latent NPE. Refs Bugsnag 6a47a1e0. --- .../app/accesskey/BaseAccessKeyViewModel.kt | 38 +++++++++++++----- .../ic_flipcash_logo_raster.png | Bin 0 -> 9580 bytes 2 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 apps/flipcash/shared/accesskey/src/main/res/drawable-nodpi/ic_flipcash_logo_raster.png diff --git a/apps/flipcash/shared/accesskey/src/main/kotlin/com/flipcash/app/accesskey/BaseAccessKeyViewModel.kt b/apps/flipcash/shared/accesskey/src/main/kotlin/com/flipcash/app/accesskey/BaseAccessKeyViewModel.kt index 7ff1e6b7c..d51fb8b3e 100644 --- a/apps/flipcash/shared/accesskey/src/main/kotlin/com/flipcash/app/accesskey/BaseAccessKeyViewModel.kt +++ b/apps/flipcash/shared/accesskey/src/main/kotlin/com/flipcash/app/accesskey/BaseAccessKeyViewModel.kt @@ -158,6 +158,9 @@ abstract class BaseAccessKeyViewModel( } } + private fun renderLogo(resId: Int): Bitmap? = + resources.getDrawable(resId)?.toBitmap(logoWidth.roundToInt(), logoHeight) + private fun createBitmapForExport( drawBackground: Boolean = true, words: List, @@ -168,9 +171,24 @@ abstract class BaseAccessKeyViewModel( val spec = Flipcash2ColorSpec.accessKey val accessKeyBg = createGlowBitmap(spec, 812, 1353) - val imageLogo = - resources.getDrawable(R.drawable.ic_flipcash_logo) - ?.toBitmap(logoWidth.roundToInt(), logoHeight)!! + // Rasterizing the vector logo can fail on some budget OEM devices with + // "width and height must be > 0" — the failure originates inside + // VectorDrawable's internal cache-bitmap allocation, not our dimensions. + // Fall back to a pre-rasterized PNG, which goes through the far more + // robust BitmapDrawable decode/scale path; if even that fails, render the + // recovery image without the logo. Refs Bugsnag 6a47a1e0. + val imageLogo: Bitmap? = runCatching { renderLogo(R.drawable.ic_flipcash_logo) } + .recoverCatching { renderLogo(R.drawable.ic_flipcash_logo_raster) } + .onFailure { error -> + if (error is kotlin.coroutines.cancellation.CancellationException) throw error + trace( + tag = "access-key", + message = "Failed to render access key logo; rendering without it", + error = error, + type = TraceType.Error, + ) + } + .getOrNull() val imageOut = createBitmap(targetWidth, targetHeight).applyCanvas { val accessBgActualWidth = @@ -227,12 +245,14 @@ abstract class BaseAccessKeyViewModel( drawRoundRect(borderRect, cornerRadius, cornerRadius, borderPaint) } - drawBitmap( - imageLogo, - ((targetWidth - logoWidth) / 2), - logoTopOffset.toFloat(), - null - ) + imageLogo?.let { logo -> + drawBitmap( + logo, + ((targetWidth - logoWidth) / 2), + logoTopOffset.toFloat(), + null + ) + } getQrCode(entropyB64)?.let { bitmap -> drawBitmap( diff --git a/apps/flipcash/shared/accesskey/src/main/res/drawable-nodpi/ic_flipcash_logo_raster.png b/apps/flipcash/shared/accesskey/src/main/res/drawable-nodpi/ic_flipcash_logo_raster.png new file mode 100644 index 0000000000000000000000000000000000000000..5f03fe63b3e0f6d6be3ff566dd971a8e7a0fd74a GIT binary patch literal 9580 zcmb7J_d8o*`#*MVO060-g4m;|y-Pyvy#+xjrFQL7BSuB6D$+J-QCn(LRcbVrOo@XTj3+s>)Y!! z+b1UDJAc(eO>GZ@O~;kj;uf|ZyIQVdP%6kXe);0{U3o?%4vR^FJb#AszTk-;YIPvQ zASaC4#_-$gN4j8;X6-#fM$vG&MKqNkTTZ4%M??%eBwLcV9TF9BZK&yemq>i1A#yvb zKNMM$6Vi(LvJ~{bXkPR0C-AYdhWYCjt4F(iDJzLNTmpM#LOc>g8OW*8j57gFd)8X1 z;Ta$KTVl!SA{ny-IkAPT6&4}xSvtKL#wYuBP=MlYVO4W2f=BN-5Pl*{1$+^oYwx90 zs!l`zxEw40eR^4h{{GwtJ3=$)+*ST`caG1{H+aehF)knk2C-+p7UH=%F+kRSE%lvp z56QCLeKn`sa#Gyv&=VYHY*z1wUj6obdtNF;f|6`WsMcbc8kD<-XsBTb&+JkAC-|1vSh>zg}BO)In+ z5Z(%vSkV}DZQs=~6Hs0DT`YR|U_pp@nEb3oL9T$8GQKOwyhy5wjXmGgFzQ25HRDLP z%?y2mbrZBygcyV5wZ8`WT1(dbBe~D{-I^+k0x97$y;^fsd*Swht0~4(0New zO@0zPXZKbu!p&j-2Si!A6HRAk_D|tc<1)P~rb5;9vPDvf5IYbcp3)bZpS)TjB?iWZ zw>{JQ=MDp1jNJ$dvVfKzsY3|6yOMF1WN~Cbo#@cUj$f?v^XbDUVF{FCqLFJB(CoCi ze=N(H&rT@HztEpxG0XVPP3`odZl_Wd;W<;Tpil`POs9$*t)Vnf`=taFBZv*raca(G z{>$BkPAYEv7;Zw~L^k=7Cjn?)xY5D#iKa64AmJ4(#{LzI48PKGkFdy=toR)Te7{%I zayT_KSV}R}hc&9Md9Pj72LZs`SjP55)k zWGwuz1x1z>o$G%9dpW{JXZTBlX)M#YSmH-BDmn;wjnV9K2?w)R7n=H)6GlQ?W|&gI z?Vv&P;!ZDK%E_NLNk2{7<%BzXB&l$P#tz_+l;GVydGXw0uT9Riq61CRV5dE>zEVxa z02Xs2al1`S8m)VWF}?fC`=j5&Nouj0F2O!Ijskc+V&$|GDASlNwQ@2g;9Npwbn;S& z&sY0~MEAcw%k5lTHYRjGG}duomDnrYC2h>NBn&Jk_f0r9mvWCcs?#$&q9I5n_edQ) zNl$uwK8{q>JZKu+KAcnJ#>ii<9`^DbIP+Y*g7-QrI4MFFAk< znphj|Y|wC)M9uXoMtzLB1vdu^0vx^#3c>F%ouK)jrciP0*e8`Bl4C&#uco#!aO>u+ z0Ia_V@jbr~%f5rCdr1gvMs+~`XO$=dyw7-Vks4|q-Vkml%8+0O{050WZnf!69ZP$YjQpS>Y{OYIgbM?FK#eip zo!-z%w13rXQHFwQ_Nz&10Iw_c@xz$q0K92I0b@z-aZXj5Q3z=9eVncaMUqs>Py5=5 zjbv2I840D#wy(yZmuj>I+jKcu=SAD*W65rvQ=`e8B5#DdWYw&|D6&m z0@QIxbQC=hbdvK+^YmMZAK3n}4Rpf>qkdMqD{&A$m08uhaQ&_q8hj_&8MH0 zQp^5ZvHKfE&<#FY;Ws~Qsv=njWWqc<|BR|U_70sE=Q3ZbF$RG1&*n#iiA$WkDgUni zl+i?{fuJZLBl^p!be{4^gv4!bK&8R&V(Dc)D3%m3V!*?-r)zfUf%w?z38S4(m9YJ; zxEp|*2b^}M35oOQh)=$%@@nFP@;;>l>Lf%Psp1n7&_H+hz`M+}5}>=G$oYW;@nZE7 z3~+=;zpoFk?vgES%%=kK@lK}G*h^|4KC{^BQmzS;O@el9@P4GrhT7Z%010ce32*IV z`^7lYtJAbw1!#v9>OnDdSBE*Xp~MAbj9%XSZ~I1H(3`{VFQ2JU#>du`d!Ir?D6xy; z#D;&uMZAEWguQePGQ>++`Oo9NKOR@NAYV;^hs6cB{)iSaW?vEozDcivdj)L=T_lK2 z5%l5|0NW=$JMh{`?(|@SM*4SrKtYK18B-7|V3(@K@vwx-(-PXqGt15R^+f4w>YAM> zP{%a==gt^j?TdU7g_kg#JI;s@*pop56lPcPxk?pVeZj+fwpvwAb*i)|<0-0gOKCE#}-WSCv? zdWIRNlJkVV1W2i#5*V0B>o@8WCl>!)$4AN)_Zpm0^=Qsm60+5sGq9upy>?`NQ3>bv z*B5C2B?7BWIu+cs4@wgMw9tta){qlQkbh!n2W~ey$-z*`Fwwbf7BOf?wiT7k<4nGb z|8}qg+d@y;KMUvp9Imp*7Sggs&7XxD)GwxV2p^1Ql&jd}G=XLPbRET!GYuQ0?f1v? zGs1|}$LYFNTf44TFjcJUWS2}Q(={=8I*eCs9A>KzJ^e`W&aKfm*W%;_hMhHz8@O9W zY+3jqO&pwdpnl>3xdO_vln7ft2;-+i5)N@&?)-U~bI;KhBf`FpFW$U=S4jO1K7hx z{;b%G0c52M;#PIRFHJ|Jl2?xfiO=6Vbdyg!^2LN5OgLl6z0Wn(T?x!cwd#y=0EZxc zOQ7c$F0-#Jq{F!S=N#`|fW09znVXDS;sf>$*=fAK@J0KqLLVmDa~h+*_6{DdF{%nn z5}%a9e>xvNQSu9OeINSCbc6Bxh0Ya?(cn`pHVP*}*908K#zeI&naMkc8+qYKscfZRflTfscFMtrZLWbzP?e8(2Bk*vVE1*{ z#IJ)d>Diq0>^@DZVNjwra)B$mnk(|*-BMDCvIdgpapysh9r?zaLl2W|Qmxxlzr1NO zZ@6TG1hlpch)S@rv%w?)qwJiOwMzk_-pCJpmke6st4>v=H4}|8ySWK?OOlvL?>_j3 z%Z64fa0r>2cRa(Eset$D@slGtnqx}iSS$BHAjo*>{!4KQf z#&Jif1qtFBa-#25r{6IC!{k=mA1%Mojg`t9DBgTTC`+M~<_CMng_{{l6HFP$0afpc zs_n(9JAS9br-!>Yt6-Dmb3n|CFONP>%}{s>k$dG(QKO@(yb?*S#K-^id?URZ7E9k4 ziKdo+Xj3{t1NBfN&V9KU(RmGZR|9|L%$g|@Bq_EJI!(1BRbn7g-&6==<+|EBRg4jaZ_o){ACEf zCmKqh-3o`QTAR1x-nW@i;YE68|0aFSt~@(L z#hKs>53_FGXMY-^ttg2^5k7%B^$7JyUgxvlA>2P)!kOc5sNSR9m~<||*MefK3H`&H zn@iE#w9tQ892=pec3NZ@;h6BU+hvHd*BUk;+M$V4T?<9y6@LBtejd%-QB>>Wn!o@ zgYWuww4~$+Q|^5G)YVv#%FXSS+!hbb@Fr3b0rjSa?FsjiySdq^b-X&mp$LkXL9Oo} z-G6duX;Eeo1wDv;XpLP3x_=a=cW)BmM;%QzV^TgZJ+XAFY6?k70r!C?UUGV?t=kky zN;0y+Y|tEmi?!d!Dso_{`1ED4sZ3)TiZ;MeS~R(k8%z{WrS49b=W&T2p;VDMDK~Cj zSOq(kND7toR=USqy9)%&of<{y&wUfQ%l{PFPuihyH|As##}C*=3iljF#zBdHXHbVk zF{XOA!A2F0?fnP(R~)oTjg2>fvF#L*`VzMUU+@!|58PKeFo8I-d5{5ahc&~TkgkY_ z%`G2orNv4jt61V#q(7;UaL}+#F8tC66At(@zW7~r-%dnBwSQI_Rszr|D#_?-b<~yA05vYF#zc3dsqwM`Pe19+O}Q3Y%xDk>Y&y}sCMRDt z3<+g!C4f~zU*>#4SBH>GvCoraWcZ#agi$bz)QrBQ<>LpnW`q?jIY?C)nfTc#k!DbrO!1mG z&W`!EsKzC|BQtwH+vqqPVEXo9cvF6eR-uJ8`v{N$9t(QF>+)`PS+&4=8&c1aHe?sC zQa=^tqoeRtc*rJ;YO*aCkTE*q=DixU;Xz~*m+ftp)4rxk9`g8m(B0;|gYt;#%0GIg zq`!+w`qw6(c9;U+iYw{kC3sc)3`f`5`AE7YTvp!9(3mx%)dXm!uhho(dm>HQnOnx0 zs%x!V>)#mwMgGT3j7DH}nRW9jMeXUw1E(YaLJ*Ns5V1KGQO%`2s7eVO=Dt$Eg!k5_ zONgo}m6B<7;(I69_iaMwze+N2@5KUImsYL$-WyyovcPYMN$FykxNYI(X}i`m1$znL`gK~Xn>G|_hYsIwaR7L6(b(z*vv+7G`IU1ZzAvX3 zJrDMc*>$i^Y>;X~Es%Y`mtHMm5s)o=XPkP-x?bN5SQqX)65FA2o>eHOSoKD3OG0-^ z&?XlCaU8QIp}Ay&4lm|;uex)QXey}Gfs0T*C5Aw%X|n*g*M4D@6C3Yu7hFg-Ss!}> zG6uXXo3bN*g0~z?(0JBFIqPCmO5hP*&v1!Ue%5UH{S5fm>nOLQw|yWw*oc3pjAT;2mLRjc=PPX$Qr;w+Vj>7PZ&X;8As)$1}#u zdZ{#d7fug@vE2Jrwq^pe%dth?Q5WywH^@2URot=BPI+U*-7`UjHyGgaGhz!{+%4i+ z3(>S$#|-a36mCZ-LdF_DWJA*!6BeHqTOMY1Ibx<>(d=~Udy4{gG4Lg>!{Srl_l_dY z6d;R%l7S;PEI^mds&x2wV(Jugvom-)0Q;|vw~96Xr=!T*=8q~wu&6sWV&M_<8^DAx<@E8YLn7SMn=cyHJe-z@HKeJyEA(U(!UG59*JW^ zP{nTUSSuwAr(06*3MqtYbwTfa{&cv<#~TQK;avF94G15D?8ieAyH*mH{@(rX!m^_< z!Tz89t^fWVMMF&CB>df4SKxBEkKa5{q<|T*ja%|t5ylCN2Z(4G=Pqk}0%9;l$5?n) zRCryf*}2z}pAKKA4oPBj5EnMOFUT&AbhheHT;(D6CCSelwHF~il;1b+wx-u`r7;S#*0FMOGRY4~ z6mosp0k3PPk|Dr?i!r*xn+;8r?!^*sM<0a6xv-RACXzI#?k7{&>B}B}GQXbdMGY;4 zx2j!^BNteSqo{ zLE`SiUDNYUs~yY67|Hm&?GDUa$M7x!#8BimxUDO5Gld$xXb+MSUPR*JQqvrFs-+wp z>BQyu6h@#7?#G3gbD@|<(XoE|M01Ze4$gJ)r;DEO5t+t!ODY@{Km4R^qUlXIqoLsA zhRqN8I6uM6&knbI#N{)K_bZSKUT|9j%I`DZZ~3-X4JA9BWPz~{ggPZF{hBlRwC&K< zHTT$%`=HKQJiPy377Q98TUF`xtDL;zOJ z;EM7w_{>r4X+J-N)VsLdAQwuGM+q!t&V2ZtTnuk&nvGQ3rkk%$C2KHeRl^?mK%@`) zERjcB1Xfjp@5Q9@2Y<<``D>NMCrcG5gb=BW?WY}%Ab6PV&zXqs8~ot%U!?e+C7AiI zbxUaW0cZiqfH>Hf+Q+mvE~?~Th)WoD9pi1Keu5Xvl2TuQh_56BOhT;o$;sC2h7&EW zuP+h>q!^#!iZL-l>LvsaL5g!Th$D0+y5%v0^vFc2OBM=9n8jWzS*PF)q9a6 zZG01=P2`uVD2U|TEvOb!m#BI%??Ef`IK8(u)<`W@a!`NS#`TF}_ItIPrrLUU4b7mz zFU{N=j#xS4^-C?45rqb^0=Je0L=j9}iH$Nl6&C*9A3mS_Ph#W$i{o>64sPgn;Rdu_ zD_Xt2v2+*GKnu(<8j8Vit;SsMGP(5YZh910{#(v{g4o+&UscGg;SBhx)6S@e-HA1F z8=*bjY~&CK|2v|D=1Cy&X+^Kl&fwp0)dqrmr6H!MgFBGy92^3}15z&^`MW>Ml<#VI zQiS1yo^)Zv@tgUdFN^!qv}b?^OsKlM!cgY4$)lWu+mICKj8gAwcKOv?n^L!(-vqR* z23KGnfntmZ4)X1_?#z<2shZ2s<)6kO z$2T<#LP{}~Le9^eF?9}V<%l|f&e80-4$>m{%knWYE9bzq?V4eegiTbL_p)&P0~-7) z(&R9u$eHsr^Qx3K+#|g(Npn#ZdoYS3oZw_{T0qBq{~7mp;aO|vugn{NsISStGxcOc z((e0AyD4XfE?{gn7PVb%rpI=@AOnHF+z^n^4F{3jW&7}G4IzO&I0a)F!KYb=NlT~*7Nv+7ahHlEm#LhhNlT-WZZ0^;MwX7PGH9${p>#~ne}ad%$BmqO zT_iYNvoop9yc#f;3>4!)2oPLfkYJ132`HN5Cyv8^aq?f8v_DgFJa0*vk~=jPM!3&R zCl_YCdfaGt)@j<`(>H=eE%2}nIZe>Iq3TGeTo)yY>iWv6$u7IH$v0Of2H)a0S9hnG ztCDkiC`E-upeKzj4~GsF{-`$e9YsQFW#nsH^sU@H>%7t-BBXV^(#mgI+|Wulg{spi zQVa~+ln`=!T)2|e79o4%3+3KkY1Up(_laKb&}W$1)sc)snv80+9x&0jQY*ycI2Y<3 zR7LH#jZUq=f3{`1!J(=RZcq+4zZv!v9X6XfjBNsp{=G^uNolzi`8mgYbcj zJ-m`c>+jF2I9T|>`pEjfw5 zAURG3A9TqjYaf~Lw`xR_HId;PjS9k$`LTFnfj(0{bZY!jOeyz9%o)dz6D{$&%rLp{RoRT1r~7xmKWf|AI^DQ3K0 z>cQRRAq7v-4+R*r{WIryN)7@KMC`z3;w4fOX=S|zpQ$rK<(woEe+FQ=`TCz`FycPx zfZ2djLE;bCC>LE^$%wS>O5BDt468NH2IUvdMts&}fLWM+_GS;{Ov@vE5EQvL+5dTx z4pT`R9`3^IIu^&a9u_IU(H>bfJ^kb#B=6(2Yx}GR{KMXI@+{f=QLs0&QIr_WBJ|;r zcAt;!oOyYc$tMftS9ZHJp*h*3jj%7WiT5e`*wLX&p2PFgXsJC}Wf?5anf#l58lClM z+NMc5N+{WXs~i$E`TgToLgj#8*bA~HKV#y_lg1SKNKGJ$1}aA0=e}#->B;VWIfa}_ zsVuBkN~6>`WvkULS@GCUO?@r2Bx=T@9J|yB3(uasb})|MyQ%3is~5HSlM)zzW_ow0 zxn93MfP5X)-x8gc^l3No{y-wKnq^7kFgH8Ldj+UuMX7rr&^W3rPAhTIc7{kz^rc7B zBY()gZm7tbt_MQXMe~^BL7Bx&qA}xlQPEO`hfJuWI&0iId3ohQ?7m$e%~sD_T8)S) zRg!Nwvop+`Mybb3+*`K3KvHg{@`i)bZWq;`E!x&*Ueo{?nKns$LJrj{7FA!7t6dW_ z#T9$$Z(?um1eh(~Uv3wgXB`1|)|Rp656(y42KUq7N4)$u&oDzVoQHPM-jyw2@EtfA zw81!vgv*st-DgGJeA>bH?E`v_d$|4@UMDnhuaSR;>OfjlGg~r|^h$y#)UU4iGunR6 z_n^G`T4gT8eyfh%lRYu_AH-{4-7hppsxyeE*T{65QYH(?nO#YL8a-|4Wsci>k=pz$<>H(dYT(aej_s9t) zJ<9bS5jB$=iHYrGhxZsV?hMVlV_OQ%CY<>qug#ivQYQbS{%-izU8PK0^~wFgiGd=x zBF_YkR$d}f64~f+Lp;DVX2oL<8h}HCa@CLX31an9iF*LV_6kk$_Xz`^`m;Y>Mbf_T$u}sqLX)Rdm9N2U zt@n>u_!VE^K6#5}_1WqepK$~^p>ME38P2v?FHYFzV;P=a*Hj+Be`VC>k0m{H6b)K? z^k_!4B}OhODK|XAxL;O9wYN8$zMrhpi{;B}MBbiOB2Ks2gh8=!zs>|5rbyiqR&O!1 z7i|}_u`-)VjZ3bn&*_0imSf@ya5rp*%*gw)M=Xao1*%wl$eb;ElJkN)F&{oc?L&io z&%K#hd|1>QmCSRO66L`}i`oRy=qNj73$ewp!(9=#7crISKK8#408_6~S@4JUuRo0$QzwEu|#!3Nd*Kk=0tH&7p zIH@Xsx7_&VZ)R7$oya$_tMDUfWBH5Y{M)!3%qb$5k8)?7I}mQGZ^q5e;_#pRBNp}+ zB|N-IgM%4U!nRYuXv z?w+vLE=9k=+|)I$vpQkPT}vutN=nXg8}vFb-~9DzZ~2MXzs%w%{@QWm2an$O)&SE{%;)8U#Kzsxa_XjwDc{~jGKr- z?C21)Y{C^ji>K&XshK@4#$1XKJ%UIwAJYyNMHqjMuX$TE-NxiL$IYQkIgx&g^nK&} zJbp72nUxzd!qIR2CjEIycyUp`almV7i3~Zi9e5dHvFHBr2vP$?O#69}@#$G*QAF*9 zMrYEh<)- zw1>coRJDZen1I#qENtkt!~q_kDog(Gi#5XIpjXtiHYX$z!*kPlK~-{SPLyAkk0;20q+&fs|A$}D}snGWG) zpLdeHYbS9jX)$cN4x?`whrR3gaD4go;|l%;QbUl)%ICs+y0iG#?KaPZTNP(zw(FZh z#3VybNC@k|vDh!<3;v;+QS^~!v)4f4H~*fPc8s*qNusoLDg?Mjt@T7K@u_-}m!D}n zR0T?KNAk|Ueu{PEYP02jGff+=;eKVetMUu6e;!)z2+U<>>=7U-zh?&RiTM+-V@dyU zH{kTtz#t+V5mtaZkH45zef_0FDZ^odbV<-|c=O_Otn&9<0H<%(hAW;kbmC&eOCiG~ zd;6MMb{&-bK6~(P*Eosz#^9VD@*n3F&Cjh~YUu%Ywawa6jfyN>a)iI?Q{GoB)$tOK cKUumYBP+2sOyIbd@*k}L(Kpen(Q!-sKPbZg5&!@I literal 0 HcmV?d00001