Bug 961335 - ICODecoder Robocop tests; r?ahunt draft
authorBenjamin Dahse <ronoueb@gmail.com>
Sun, 04 Sep 2016 13:37:57 +0200
changeset 409693 8015e1a2cbf44af95dd6029b1c1ba097654dfb43
parent 409680 401ea746b1a9d515032b66d1368510d09e4e5a8e
child 530382 8c961faaa99d79cec67a9f2295f23dd087792ba0
push id28514
push userbmo:ronoueb@gmail.com
push dateSun, 04 Sep 2016 11:44:18 +0000
reviewersahunt
bugs961335
milestone51.0a1
Bug 961335 - ICODecoder Robocop tests; r?ahunt MozReview-Commit-ID: 9jtcfZCjAbd
mobile/android/base/java/org/mozilla/gecko/icons/decoders/ICODecoder.java
mobile/android/base/java/org/mozilla/gecko/icons/decoders/IconDirectoryEntry.java
mobile/android/tests/browser/robocop/assets/ico_decoder_favicons/golem_favicon.ico
mobile/android/tests/browser/robocop/assets/ico_decoder_favicons/microsoft_favicon.ico
mobile/android/tests/browser/robocop/assets/ico_decoder_favicons/nvidia_favicon.ico
mobile/android/tests/browser/robocop/robocop.ini
mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testICODecoder.java
--- a/mobile/android/base/java/org/mozilla/gecko/icons/decoders/ICODecoder.java
+++ b/mobile/android/base/java/org/mozilla/gecko/icons/decoders/ICODecoder.java
@@ -1,21 +1,23 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.icons.decoders;
 
 import android.content.Context;
 import android.graphics.Bitmap;
+import android.support.annotation.VisibleForTesting;
 import android.util.SparseArray;
 
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
+import org.mozilla.gecko.annotation.RobocopTarget;
 import org.mozilla.gecko.gfx.BitmapUtils;
 import org.mozilla.gecko.R;
 
 /**
  * Utility class for determining the region of a provided array which contains the largest bitmap,
  * assuming the provided array is a valid ICO and the bitmap desired is square, and for pruning
  * unwanted entries from ICO files, if desired.
  *
@@ -346,16 +348,28 @@ public class ICODecoder implements Itera
         result.faviconBytes = decodand;
         result.offset = offset;
         result.length = len;
         result.isICO = true;
 
         return result;
     }
 
+    @VisibleForTesting
+    @RobocopTarget
+    public IconDirectoryEntry[] getIconDirectory() {
+        return iconDirectory;
+    }
+
+    @VisibleForTesting
+    @RobocopTarget
+    public int getLargestFaviconSize() {
+        return largestFaviconSize;
+    }
+
     /**
      * Inner class to iterate over the elements in the ICO represented by the enclosing instance.
      */
     private class ICOIterator implements Iterator<Bitmap> {
         private int mIndex;
 
         @Override
         public boolean hasNext() {
--- a/mobile/android/base/java/org/mozilla/gecko/icons/decoders/IconDirectoryEntry.java
+++ b/mobile/android/base/java/org/mozilla/gecko/icons/decoders/IconDirectoryEntry.java
@@ -1,14 +1,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.icons.decoders;
 
+import android.support.annotation.VisibleForTesting;
+
+import org.mozilla.gecko.annotation.RobocopTarget;
+
 /**
  * Representation of an ICO file ICONDIRENTRY structure.
  */
 public class IconDirectoryEntry implements Comparable<IconDirectoryEntry> {
 
     public static int maxBPP;
 
     int width;
@@ -18,16 +22,17 @@ public class IconDirectoryEntry implemen
     int payloadSize;
     int payloadOffset;
     boolean payloadIsPNG;
 
     // Tracks the index in the Icon Directory of this entry. Useful only for pruning.
     int index;
     boolean isErroneous;
 
+    @RobocopTarget
     public IconDirectoryEntry(int width, int height, int paletteSize, int bitsPerPixel, int payloadSize, int payloadOffset, boolean payloadIsPNG) {
         this.width = width;
         this.height = height;
         this.paletteSize = paletteSize;
         this.bitsPerPixel = bitsPerPixel;
         this.payloadSize = payloadSize;
         this.payloadOffset = payloadOffset;
         this.payloadIsPNG = payloadIsPNG;
@@ -180,16 +185,22 @@ public class IconDirectoryEntry implemen
 
         return 0;
     }
 
     public static void setMaxBPP(int maxBPP) {
         IconDirectoryEntry.maxBPP = maxBPP;
     }
 
+    @VisibleForTesting
+    @RobocopTarget
+    public int getWidth() {
+        return width;
+    }
+
     @Override
     public String toString() {
         return "IconDirectoryEntry{" +
                 "\nwidth=" + width +
                 ", \nheight=" + height +
                 ", \npaletteSize=" + paletteSize +
                 ", \nbitsPerPixel=" + bitsPerPixel +
                 ", \npayloadSize=" + payloadSize +
new file mode 100644
index 0000000000000000000000000000000000000000..e5f6fd86f4772870038e4a8de2ac45eabf419f51
GIT binary patch
literal 40648
zc%1BeWmg?f@aDzcf(CbY2(G~i!Gl{MSP1U!?gV#t3liM@;_lAH^<JC{Y<~OSeYYQB
z=bSk+J=5ozs_CkFy82WD05AXqz<&n}fD+KJ0|03KyXWNmpSBe}06?S*08mo?Pn!`3
z00{8^_l)R&+N~%6KzRZHfQ|is`ojYNCYb<0q^hzU1}ZV?KPU_Zd1>|k-u`zYBmTP>
zIF(!cg9Io@OKN(+To@t+;0?{O=b|FZ5wy~jNpXKj_6f)z4Wwo^p+;tAWXz`)!KGB-
z1c>#*M^Gx_;YyClr7|k)$ji0ECB~pWd;9xt&UZB8x;;1qZg#M@=49qxX6Bw&{=1x>
zDiu>|l)}W^@AVikD^Pqw;zgPxLrR6<-W4t^uz55n?cH#jXAX|U!7htu!ezpp<iJ@z
z!I1PJ|0q<-xL%^j*viup&pQk_48TH4S^*>nzzB?v4f(R4;7-C!2FCOTF1_!TEdcXy
zGWEoZ4g+%FVod<NR+v_pKa?;xN--pce|fwvWWoi(tpThgXGlkTNoNo#;rP4#Tqa>`
z0Zr)tI+|cw!6gKe7>l<b2Jiv&5P6ZfIgy%RMtfuHC=8t?NC0gA<ocNY58=no@N#^u
zU_M4b>c5YpPy9pRcGy3YTmA<sF&=Ozf%qT7$JU#>BAb7p`Q{SNlyLtL0?;=epJzY)
z1D)Z{7fcBJhaiDy=kt1;`JY%H|G!xOPqFM4SR+U=4}dAr<o-~{_7?Lm%zD*CIik*~
zm}H8DSKaTqrOG+Px4|OM$3=J)6e>ee1V!0xPILFR>(-#kl-u2K3dFBPo{+-@Xzror
zA5)pq#Ar+kA!!KVMA^xF*?gPxQBY|SkC8Fvf3~JxXODlo8N4fz!u-vu4~me?V~P0z
z!vf0avwm-TJ4zE@FDY=KSnC7=^17YtRBHZ78vTu`7zDtqs2&Wj@D0Cj@_ljBCg%M7
zoBnH|Q1clP?_<JG?C-a%EdF&yqSk#u2(`Soq4m4HPPTwrDgD8rp~wz;T3UG52MHj@
zVp<67a+PuXRIaE^k$#LfdaLmiso>D3Dlm(_!{vtV&&A4=BAfuQ|J@>KrA|SRWH443
z*jovZ2X{4B;yfdpFP})QSuC%%*5(|3DT+L0)R+hILf^@}$t;(8xp#p+IzHcoQw$m_
zDxz+BUv<IQa9)gC*V_A)Kxf(uWuj;F?YltoSoUucKrFpc9*=8mIbs#jyQU8C05%aY
ze!o1isC8;?Mc~7}G~?Ut36Irc<sz@|8t+=WD@oUl?0W!c<M`yZ>A$gSf}BSwZn$sz
z-rg|esj^Ek<#Y5}Uh_K}z^&3aQ2W@AdspcEDcq~6^t%po9iZ@h#F;Xl2*+!GyE|RN
zwYIbOlf)L9Xggi1k$N2FhueDN=z1*tr>zHobTFPQ9+()s_ScpL-1-_rA)fnlxt7gJ
z0aZFD&*L)@ObfS=Xw!f8+5~kexnHxX^GuQb89Rz5dOBOwVbhk%rk|dy<W{$tY+Q=l
zY&F{-ZuIJP2kJ`bo8dJ_KB!RQ-%nv4bA**a4)z5kj>Loa+kx}dtD=Q5^D0?<w&gya
zZ^<Tl;BH378zc%J)mzML;7QYr(?6AG!1F13_<m?`#h3Dl+8$rX7u|zRhoZglq?ifv
zqWmet)WcvElJ;1&rwqgnIOjN=GQj!OA}JC0EyMtH(kPLJxwzKiK<1CG;EK>Il=gSA
zrwMZ+!e!s+<HoAqe@;^itC1t0E9g9|_LTUr(??rI&Ha@Lu_^jpq>`?AR#lp&YGOxe
zd`9^{EhrhSiOjzVS-?*?9CPM58v^#0gT`4}k1GlodKiDa?!wxci<~TRKZ_jv_ooh6
zUFiitkm;u&JlhIkBcD@E182mE8<wwXKpU(41vx2wk>zys!`sPv+jTz2N-&W-fy?H#
zZE8g?nef3v{wPH;_-aSZmp@(5hJHJ*LKhwJm_pDgWU1EhOiQyYJmFsu2ua9zlgA(z
zNtbJDQ7rlNF$kaKgVpFvL9I+rILr=I(KB>uPw8hZ<58Dv@?e}Ki}o{dz(1Fr&1kfg
zR?|g~Vqjt#%=QZ_!y%l=yV58d*nrb%_WES`aDdk;B84x*_TwYmd!VK820-ymJugia
z1ExauqX3TU+0tT7x-u3QlAVcMJ`7c9#h9SO&Roft5Vfn~;^4j0%T4d&&4;a$Zr>N7
zgM0e#%HrCW8!q0H>w>eY+)_3o%$7n|vt3AZ^z>dRL@Qfe-Y0KMH3%5~KrD5saP)#j
z8=Y0Qdb1JCT;Mrn%97-+j2n&b-XO|t+wq-FM7py3<%Yu9QjPg~BJ<(9KlDb<>j@;*
zWWOz@!5(WQgGp;GmtQryshUL2Z%5h}s@=ss39NHqd?z&a+x61F{oF3Lxk%Yp$^P!_
z#}W7Rn0r2UglN0|w<z(dtE{q5W^q$ecF$(1x}YrAOI`S`m5a+~F73AiLYQ#<8=5z{
z2>7_D;+*xj*YiZi!h9KMyJEgfqv!RqW8wLZ1peE**WFo}-9{7B-C(4#MtpP+ZpBD^
zp1fhtce9_6!yC!ja-9nG(+S;1jd)VQOfQ{RGO?s~-;t?>EsjoXJPbDb?*-1|E?AU4
z)s8ct0?p#V4FfH0;_v?a{{jht`E+059?1U^Dk!&X+|s~IcG)2lg-1|!G@ZxbLv0no
zh<V%$z*#hCZ^(oz00kJKVe9$*{Fw=tI0Pe#L8N<8VpAoEt&X`tr2g|HS;sCnY`~P9
zb)Rjjw#{<2>MF~=r{wAp%lWVmHuX;Ie#K0)#0j50NfCubYi8r>Xl}_?KbQ_D$%kJC
zlrQoJBuyr9J$Q&gRgk4cO*9g)?O&tU%!I^29%SF!?t11ic5|Mu0NPoM{+h*Cux{TI
zj7rGPYC%rGVWbpI$Uz<R#p-$*MilutPkf<33d!ps$6X}YZZxjVNy+nj+*^s5uN5$v
zN!}5mx_IE0IKH>49}xpjp#=ZDHJC}P%oVCEZC^3Wa*Qs}Cg>60cFq-AVVY)H{sZ#T
z%9|U6bpCX8g?4295L40Q{Y>bRabp9ca$VVTly}91N8txR4WJP9N`C(1KiHnPRPkfP
z>>sOGugrYMOQBITNc%y{#`vypk5N?D^S1V<S{aXYCOF^?9tQZ1!m%6L04HJ!Jd#b4
z_ieY))}{e~!nF<QSP?(K$9OuUb?4AL4?>v5{AKf9I@mR9o$dQc4464)jR~h_yFcO{
zr=b+7$!L#G+CzuU#7ZXARt2%_*i$GFC35msJHiRvuZU-mf5b%<uIHXh%j}=3#T^G3
zyio{sn&Mxizu}ksdd`@B9k8kEQqB=_{g6=&<iJ%c(mdUI)zxdVN~HO-biTmrGRm2V
z^>G4dKOBxlF=flMni!^Bd}|Mw@%<M(Xg8<T?DAufu*i#NuX<F9<X*IiT<#vuSBq%B
zlt<2aH3l&4RvDK4b+~Ir#ZTV8n6zI3uv5qOry2VwOpCn4q=X36y{&a<RzFD%e`4eS
zjQGQ+^7<3llAfP`i{O9X{B7~{&CeX!Z?iLz;NGDY&Muk%FZw5Pv5>+-2#M>X+%2^O
zhN~{u0hwZU2X<MUYLymSoH1ig3Y1A4HBa0<_wv`=%AsmV?OT7S(ZJ3ZBsv63QP~3L
zBL=J2=eyP&)L4>j1>fgRB`z+m!cW~V_rhLBIXEY;Jf@!Q?g&N$Z)cO4pNgt=8yh5w
zKcK@-!HlOh(j=pGzFc-_ru3}BsH^#gD&lMO6OxgA<*}SpAKQzte}jQTVunQ|GjO^@
zF!7_v^;t5KP%_}DT=~k>V)%4}IL!Zg#Uyv~YmY<BwO66p$oC{QN+&MHvcBgj1-zdw
zN}qW`J8zBTZaVW*=+qYYt-8Jl9PD<}DwN#dNn$837I)6~cs&r$=>G;SWLuCKlG2>s
zi7Eei$eO|QCAGRKXhd=1di%ZmGYI${J-AW9=GPAOP?%Y^2@DdeYw*jZ%}^fN0O%;9
z8h+F3tVXlNNHo*dT7#b$Co?y>))Gd@^<4g2l@`A3J_}>T?eJM0n%T~h!^6jd_8>LC
znSVUoU20qnNrR`<`dltbZTBTjySh(Awb~$UOMufOWt(!?+5_$j<9cmypeNR&LA@V@
zB{c0;6~`KH;g7u35wgtC-l@hGH=SXMaZ24vZAuF)J-Q8aJdML%O|K6b5A^QV$>e{e
zU!d@to_eh1Ya;D<mbX>!joSl~2Lx{LRrH&DNy8s=&tHdJ{xURgdhL9Gp)bkU7zZqj
zvS<)|bJA=*oIEt@vYW6!s40b!F0M5mfA++Re^{{}wRFjC#GW$lHX=d*eFo-0w08Ab
zH3_C_b-(QQfu{p~wI6(bokgz=N|Ydmd)3%lx2%j1q-hd;p?q+W9UbukIGKy)xSge&
zYBM-EJZW9R=Q{l}m&FIzc+;X%VCK_ROtkO~$>tP^L4|H3z06H|*j~>B8#7Gu&xLZT
zxRW~uLlOXQ<_A3gR*n77ldbiw#dsT8KfYSt?9%=@&`M4aKL&mgDlA5`L++$K!S}-@
z%Xb^P`{tK%L}3;%qn=)oIldovx^cuvJy=F;hM+|(tp@d^^d@a+aDu|L7FyPpb#)33
z&9fV9e0>r<IShhLdwBR8eIU+=@)O*krf4KQeL1BZunOx)Q51u(a-|V@vIbz)|2r{%
zNFKP4w-Ye~flOc0EGdZSAYY?q_(NIiT3Y-%80hFE$t7jTSX&*3XnmICMHpWnLK_Q7
zoxX&+YWW$wk8{VmXIP^6ByUJb&2q<ufoZNPq{*Q!0UD9sq7^@{XZ0Bbks}~zV+<ls
z6QdkGqc<oj`q$1R*)V$%SKPq#6O+st|BmtvrJR$`k?~~0r5}9bI^3^H&E!D;=F&yV
zB>Z-_V|iQ3bImZll-rhhzVvuTpRzx66B>Id5W%F_iBbo}`%{^nn5cS6ACRNrz(WF5
zBeRF&3HjlTl5pDU=chM3o!K-alC+@_!U&pg!H}LmDWbnyv)Jh=?(E@}fblQcE1g5K
zNGRbSv`~bMK;cwLSovOXk4g&JM`Q*3xS#9eL(yVC!m?X9AV#o=9i0jO8}T&f7jSpf
zdn=`5;O@jc-<LFY$wC%%qU*5E9@>+>o|m|su15}0srEdCfRQapKU}k03XK49XU$x4
zQLmYn>`SZ}VUMKcrtwv{0~cI@%dZaF6p*zga=?_Mu?i=aR4?r(u|LQg#}9IiNb9Eh
z%~SN3#UF04W-v1BO+$Z|q<ml=8p!fDd?&OO1ssGGsU)_BP098aLRF9P?a@t)1JL%A
z4=IYx#}ac;H3!o}8o}?Wt?^oMj{$F2VB^C=a-a9N*N_=dALDysk(||zMC~|eJQpnC
zcCjXNvDREPk<oaa(PrrIjj4NZ`bN`qyPM-BXG-eIMDT$C0veZN@E2AX^Le`&q4<L}
zIzpM0OQqlq`)qBbwEtSagLF@kKw_}6&8Pm<;d&;^?UKgxr)>kb+%n`)7Ly7}02;Za
zK>tm05XGi~G2+ACeUp>yuN$xILhqQS?-)gL|92BvfbpH#t#*}v*%ye;U%uGL@{L>e
zIRz%@yW&<;ir+bZa_orAve!;O9F~a0Kv)-@%km_)Nu<+A99c+%FwOw)&R}F7ac&56
zxZ%^b$G$7-0-S0I&kon?3k)<%c8Fc<xFHoJxNB+}vJL&4*bQ~CZl2Q6zj_)XG>)L1
zfLM+J?b&{Vi`KEqinWb>7xgBNpmP<!o8Hf?T}~EI+Nr(}Jkx;c(;vhIu59$y-|2>P
zdK~c+e_(dGI(K)Tb6~T0!xDhxuuL!3uMjo;W`x`AijEJBm6Qu`h27M+r(f*z-Y{z3
z9U9KEj2GeLVi2IW^C~VQWbX2WHizM>*u4m?Hp^uvy@7Ctrecp{zZpE`3chI;N-O+9
zlu+e-L?w+A|3_RU7$i_(z!UbQ2SYm&_OGlWev{ngcRzNHz1``^CO|2{P;KY%l<4|j
zyM2kQs$Y4S)&&_$od{Lm%G7TrJ*CBmAqs%9JY$QAgT9XBrlgnUr|~qF=`BAeqj!;b
z99E+SooWPmwC}fw|AH5j7aU`Y%Zd70*LoL!GQrx3$d%J8O2U-Bj(F~200ri80Ht4g
z5r;Kqu{UP%nRTzrw%0SvC!{wzBo~PU|FPaCylDcB5T_xngC0~Dr+H$d)<zB1qpxVO
zx5@nezqpw3wPV3)Y>H{q@5(*&<b}Q{StkZy`;!x{foI*hSEAmt&SNArZ_Wq?#7Iwe
ztfKp10a?G#pZh;qlQQ~%a$m<tN2Rs|QZOOhTQx;n6RKg9Uo`oCazQ<r)oWNAB?SdM
z<FhPTOF=~z2EYIIecicw|Hqx`17R4ep7P3c#n(~tN*Bsm_a(*@K{i@rRnA4X!pO)-
z*`b~D=y(+Q$;LZi>2m|f!n{iKS)d;_5UmlQQw`T*JOQheBlJm?i<w|smazwY@B7px
z{-d+E`&_2q=JCS;%^`Z6N8|^(a_#9{mvvjGzNzJHAE|$nLh#w*v2;1hyhKb$Hfa<~
z;sZ?fAo*{LW$QBT0{LLD`|~Lo@Iy+<n5QSDDC#UHx9xTm+pX<(d{8@GDumB&LuUdu
z+pJ~V{QQY<boL95-)<<O?h^%0nc~ypr);yd63Jjh;0pHX=V!rE6*%k|a1qA$bMd@q
zLD7p5WRp`nv8$RRyjdhQACE@N<yPo1m_N6v_j_QR;q~;zYbb$h=W?CZ-Ra_&bD-HI
zeEfj&c|5k#V^yZ>*&HwC?{Ckk`qe)|)_ITN;RH=lRVUePndFrGrgDMG62ewzx1KIc
z3Ai&We*b%+;%6iz6UEtjGQ_iXQIfO|1(#m+*Le+f{52i+aE{eO?j~>kJBbKc>w2>f
zB}g0L_wU~ozAqyuurG?mJjniXl$|GHJGOt?omSXbcW##RD;=Nf^ZfrM_Jb8Zt6wS-
zx`d5MMd9I(T-FWDPLk;2fLPxrjq?GY%C`gP{e;vu*N$}BwEcnle==1vwMTtpC6+p$
zR@#mjy&+==JgJ{u-d`W)%W!k9;M_rn4;xZw9z0XYcn@t*XeX&VzVHs7dC?*Kjw|`4
zU|^j1D4~9mo<DaCsut@2;tm0D%s;d;t<2Q5a&9ZM$}lGoRhvVuxntBL<TSP}&Zygi
zPzaw@Kf*6_ud^0#H?S3~48)R3h=0<}2(Ej3+{fb6HcgI=WRjK&Lq|A0x$oFr^=xzK
z)(77(>^miHUm%S~QTTU?x?XOC5<38Ne<eHh^_8sEKwagrt^z2JFWJ9udq^MHj-t!B
zr1Ech&`{>(dS40>z(nBr>5vjRs{8G8H~T{!^Z6uNwofLpfJuC6C5kD>8J6c%O?FX0
zYt-Em`4?u<V@8DDKdRX-5o&FdBh&OMe0ggQx0;BzSN31{8PJJ@Q&E46TPQc|iayN)
zd>)WujjyH*J!aJI(#8YqnKWW5n`|!inm+r8YJB`gkgeIO{j_VEO*b;BNspNra~@#V
zlLh7xg!yA`c49<RADz-q6Ti~&dZ+>j9d}bMc|5!!<);i!iJ2DM$jb95<oVWBL%e9Y
ze5E4(syRq}J%(q&@Ld#RB{A6Pb3II@WWpg9_5lq8kVx<9n-3FyQd~cRxi%G-_nU%b
z!c&)kG=GZTU`zcs6gdCx{E&@To$|h%Zkd=y*;ryVWxo#iAT8+EE3DH+boN#RFA}>1
zj=%7m>ZS0;e>o68XMov=cXp5k&A?AYA`V#oMl=zo!=ChQovjk9{c%m#lN`=G7_*cD
zD>t&SKg3uP8_ezRMw9bt5M<_f9VC~M$;a&$-gfx3e4I0WtrnF_!nylB7P;2c$_(=6
ztNU>d#RzjL5TP#yG<*_SoiH~iNDM@ZKQN_Gk%dc~_3X6wmKr2Qn9^H%*kC<qEqmR_
zI@IS*w)}=B$nyJ+yv<MyCjqMpW;2<>{(^M&sro?asC)X-*8)x4BPYl+F)=a#Y3QNn
zcRx)q+olFEIz44oo4r^m!kA7js9fnmz1~b)eOMW^RvO}p1=uvQ*;m4x!Ph$HVG(dJ
z78<1^!CU66yn>fci)Ds*-}HXI_l_c-Z9(SOxb41?P<x}Aym;BJu+vWZ3vy6b9fI1r
zf!A|`Wna5sBqTJM&in9546huyZ|aX$Z#J~VBAlba6l=-H@>oT$L9RZFrPqZ8KJzuw
z(u0=CpOQ(J@!8jPKXC195idb>c|Z##%)vM55@<u!ytQ|pIwXMV?Ycg$_3qsYb|p2}
zley3>Qr=OHc+QsTbxUXRA{cX<2<|y-fO+Ds%j$i_0p0{$8|Na!7&49qtt~9SeXVaX
zv4&R<1503dP(JmRIHav##m>#BEzI(vEV-No-~&dAKIFJ|Uv-|`{sk-h#IKYNQuDx5
z2gV<*aBsenJAl<hRHx6KZyCj{lG4=#I;|<}zQZZq!N4;0tS?wl%ZaL^avT$dNkm0I
z;@6lXNA{`>Q*=(>kY2Z#L+CTdhV#FqG4%UlC-koY0#=bHZg!-w)aE-b3&&vGcGO~d
z+$M+unGr@J3Dbae@Hk&D`10a!Z98q#@K7b^=pA%sANs;6Mx#@=4RPfn@k%IL8Q_gj
zx`ak<>@hc+Er)-gAzWEsZFO}qu%{zSUOHinNj<-&#a(}}^baT*<LrDhc@4?9<xzQp
zS!kp}?A@cvo0<K3S#=%vYwhc!#`Kl*t(u<$ltS;*o17z78N~$Tsy|A+qRPi)Fz9Nx
zqW7xjeX2shckG4`k5P&;s)H!#337;7GSO%;S)41HSH@-bMyTocE&R+?DGetO`|hZ=
z<FYge0S&p^D<#id`fo!LekM>uVc#Qj7Q@2-4xftGwJ!+4_A?^r>c#*|$Z;>k%(3;^
zR3mPKbOLVfq!cQ@{dk{sdv=Hs=aSHBK2E@e;f1C0pbIl!bS>xLy<P$Je|utJ1L>v^
zh;Zjd_Y~9s!V4{PeU~!NJ^Va2wbnjy1l}|J%HM=&%`~(y%qqBnFyLQ4{8f!y!)Iis
zxU?sdLIQ1zxr@^I^onwd2QYODxt>Nb3DMI@e1v5bFGTr{xsAdp8txbph0j6^dfX|5
z5<WWb4-t9`D>Deq#^pB^yPToM<oMQ8P#gwPSpgV8SBIRT4BYyDoVFpee(2oP&sUWx
zRmTJIVoe85Vl`lB72bMn(b41)j!!M&7Bow)M+WKW>8hIrm|l4H1civ@21Ixx(<Bfa
zk9yPh;;M!!4tRW_gi9iLegj)Xwr3FE`6Mtmmk${t69xK9yAgf9iR5An)KYQqf6=#Y
z`Q^#+y_6PJHa5#^wV|XxbUAbSgmgW5$V>%^5G3bOuWfX~AOf2Ml=D~vyVw9U2Rgw(
zmRo`8qpAooP6U<@S~IO!!%rCdCBX30h+K&bJ~Br4Ri`kjolzl_=#V{qny0YS++Ae`
zOC=+&>AVySSl$N%Fq5Lv%9QL*yp7(!*+7-X`rnHc&$5CMY|{N)xb{~b3#IsoS|~m@
z>nlkB%a0iLQo#fqfqb~2A0b*x)8&FY!-4gA2o6;qvMM7j9f*^G{^No5_wa)fM&b7t
zOmWNBaP|6FrT*QoQ=UIZB0sL=T^W(n{#<Q97!F5P^XSQY>3Vz{VQ!a)MR)nmRKE%$
zoDT5xR)Rsy>>g<BcL+ed=K}cSo8aQJq6{lZ$cA{3@6>43Wd0Eq7>@iP-HAMifJ|@-
z>F4}~Kw-$KH@eo{6?r>=g=TeSbQP!AH`lK9)bECkz3%*Qyk&R|6Lt2n1oT@fJgNNa
z`d^qLuqmMarEyd6mUlx|QtE9dfUUJ%bUs$A)*y1w29aoJgaUv{5;I4ARh~%W>DR`f
zs_jweY}tbvv*<T2U|OqZyeo|yw)3`BGcQuLBhB(*Zs&u@c@0i=6M~FuNkoJ(75nvN
zuyee4@6xsJ>PX?w#r2SE;G98_B|*UZXcfyyED3I0aOCd4v{?u0I82S2hnUDv$TpQL
zD(BAMvA&4x^SB#+o4&H9%NL~kG%273oeUi@2K1hGr?*;!e0r;=9YYb1N-%<n@?@7f
zVYoTvl+NLT>wKt3+}`Fj;sn-NwSNpWNj9Dhz_I$l`d7_**Jpz4cl0%qz;7QdD1wGD
z<9pd}dNdgsKMGx36zb4Jj&zlQFib~U6wvz*s5CG)XIY*Im4lmkBVpC|<sQX2h*O`O
z)DICr)oH}TH+F4}9h|u3rhsqrIDX>?(duRH=ID7$`u)lxu1ET^_^nob)&7^?cDY!3
z3u5t{eb#b>yqN!uLAN-z^F`-a=z136R-CE;15JRPxakLYv`1P-wT9wYf-R`l{(ij0
z6`@hST2V1WQIF62y<Tm)NQiiE!Pl30X?7Ml{GX3Md@C1gOSzhv$)f*GtSh6*vKNSR
z7&w)LH@`GmOcyXRvIoakN5UuWDfpk&6!7}L`6Mnwd7Kukmic?sbjYlxvR5~7iEP;Y
zx^Aws5Im+<$j8eh4<b!cZ<iBdHJYrrFndjm$KQee#=D(?DHQO|*GG~)-LLSrWfYA5
zciP)rh0h)-6u0&jTG4y|c-LmC3I$)Zv+o~$d)9}1^vniqpIO6fAZ<Tb1mGw{gNuIU
zzx0<E$iWSO@3IBSM`$6waJyf<Hsv<EPvzp{d^6v33oQ>jl@QF#VDTXa_WXO2S>PhW
zUUaVK|62=CIi#J>Fx-51;QV<{zX@6INv(SxH^=tJ_2kvkg|^-m{-)+zlNaUr9vpP!
zUUQj?DlXVhA|P1J&m8#@)YA2l^H{shiEhZh`@jM@hQ+7xS;S!<UiB9|L^FR2%E<J(
z@?NlE4n*M)PZ{wFDeOIC$8H62VLc)g7Ss+5OryuL=8+xR*a;va->mK+s(LMa3`1}Y
zq3Uf!M7zuDjQ;tz>d4bMxU8+nc{Z4aoUU^fPI8gpTe(MbVJ^5qRI{U4UFn=nvnKQt
zeQ?@OgJ1#2JsKPN#31w0_*UlYAOuwP4DLThurc2d{57?=8Cgyuaf8D+j9S=(3PZ3$
zQeb+sX38WxH+a{Etgtn_Y7M$SBlX=GVOB$}qM}lY#ao+o?JA5$aHmyJ(siFwBpGqG
z*Yp;gFI6H%GSK1efASQ|6ik2?D2o)od?C~PNV<86^}IxmfZo#lW}&Cm=@d;&4*CS)
zb$792UY~i>wPZ79pIX^Z(ARH{z0(n^ZE8+G5)l#_)?RWLl6gu=+HdSbH&;wc<c(<v
z1hIdsX5yM}-SW`+2)MyOj|OHZ+fwNe<6REO7tv*t!0&~TjDE1#2uI8-FBem+SC!xE
zE~sjdA#5P%Ds(<03b+%|DJ)aTyC3r^aq)>rSKc^oE6IxTnlY$8ZooMg`3C2eJApYm
zDcBGJuC&dL<3AcbS5>DU^MF-HF3xV<4=ay&$w2X%qiSq5fj$mR!uJEPSm5eYkOqqP
zyjwr2K4H<*J=Lq(t(+`TTG7~%&we%{?U)dPL3~Iyp=$XJF3Q%M*pr4s`!!_<-8@NB
zAx=hOd8<w!C{Z{6%__3m@6+|cA*)b2r~cOpdbzhA0WO(}$na2(r<YH>w~2=9G|!l&
zh;7l@s26k}n#bI6;jxjvod#q^=ttp~4z0@kiPriINu8uNOdVj`IGD<cTMcjss^<pi
z3}+>~sB(T#N;+$b9lmi|HN#8zVK^SIc5MRZ$tcB{M(8Ub=>%K2zsEim6veIjX2wDQ
z=Nif-Sxwx;oJ>u?I2sPL6f>;@{2N-XZ-R_XSuhg0Mx=Rw`7}60bZn1(;VVs<V4+&#
zp3&KSauub5O_a_lalo&Pj#%e%w?7n)wvY{Dg9=KA7(Aw%vxsq)R*ZR5KOGwOI=$vO
z#_)BIlno5=>F-0@5WAUO`0s>RlqWM(ICJ_4*4Wi4Y;=$G-pEO-I*a_jRyaw-aV{&I
zj~J9<&3Gec3k#b9?Lh$)qA?jrEL69E20~`j>Z6B?dzw1bus=5!fw$hMTUJx`A^eQi
z<K(eVkORjFz?HC4hak+>R*pwKMnO+74C4iE>dG7TMiO*0H}wx-5MiZxyocKK`GXkT
z*-{P7AhA3eH1(Dx=ZoOip{lfE5}rn)2CC4#=~Lm@w{EDrgt}$Y^v#C&i$(IJJ<*3c
z90?oy+>YN`N~;HomK@$E-|@tayM4m4<pUE6Ef{$e8+)m22d}^L!8x2RFySz@im1qp
zI~4}dU^3?^XZMP@@+&g>#!@kzqX$GSBFa%#oSQ_>3LvIAt~^7uymtDKj_2rJ3^-t2
zD5rX&mTa^<c;Z}N$=2K*FpdL-^ER5|3T^oFvmhYCJJn6!66jfYCr~t?7jnD5<)6n5
zp;WJEFlQ>m$s`%Zw4Zrz7%3#l@9@nodeo7-&jHieLmoY{@~N-5wHCZHKhX%(!ow03
z?+%0`0q^VT_HBDCfT(Li_B?E)%>i!gYvjq`Dv~S36_#WQ*&TX5>V)6o98d)odi!F}
zA~<gkcHM^b%U^RLWpJRKTs)47>pgOEkpK9i*=?G!oBHIseOad`IO>Ij`ZPG0+N~mU
z6p?a*lIfRWAkMV!qyE6EaaVdg6(G3GPb|fd<K@|P3#N#xi{Ir~wbG!XVW&g)Y4&0y
ziy{xbPvYjVX2`|(a>a>saGy12<rbID3AxVLaPJX8iigc}VVKg62I2u}@!NqJafElJ
zNX{9+iG#*24NzkEK)!yXHI3u?!#N{87THr;F-5d`HM{TGUgqgMy>5hU0#Z55op1eP
zrt_o?U%Z-YOnV{h!n^e?4CniInU;6RGy|G(WPo(7Zy4yi4FHcr&#5Vu`Md(DmjsuD
z53#B#N)`l6VanZ(IhM~q?|gz7xWlTO_un8R@X3MuNGSXt59KuTO<)iKFD%JB)36AS
zhZK`tc>de3%=TU)g_a?nzDihovB6g_P3(JtT#^wDLC5BQsxQ`C(w3@q$)?Ux{o$~u
zHs)RDNh2IEL-JT0LU=T_jh!hA1+cZ|18{}}4Rt32UH+?{n3JSAm75`LRma@$C_$)`
z5v*PuncHF}T@%)>&4!mNXxpAHsW4W;@S?0Y>hiihriqU-^x1{<crE^1`|C?WWz_r6
z4uZYVrEhCiKp&Ym@=;Vk-=B`fUEHq7g*dNl)<j>U^R14R3XUX}%2_q9c9}K1hH8=-
zh&4PbT=+mDw%Hw7TFUFg8bN8n?M#RO3ZHU}6pL-YYPrA`BUCvASzZcsL_|0uz@QPH
z&bdZ|CR4k|4eZ5whYC6@yTPLwCvEMQ+$tfofKWl5U8I1cltr1vi^xCqKi)b$YxSM;
zK%by1N$bXxSTntNI|CQw1TAVB0U`q9y*<$P=4Ioec(G^s;?~!}zh@GQxmPsoFYTF%
zBl$eu?(=JXuO}`6wnZDqWuM4+VA4OZeh+~J6(#i4bZ#6EFv&j=^yUz61ts#rsWy0h
z_ww;@HWKvsJ%WQATe)`pVFWf^kTKAWmbUGWMDez>iu38#z97(Ii;oQQuC6MuGeNMG
z^yb<#>r<&&q4<h~UVOgV;EWLy^m&lB+ke}SnAa-c`si9e!^Z#SbP~4ne$9ruKKw`V
zkHK^<vx@0)^^A?&PYGZ&#UxVE`&MsWib2e3OV%zIbw35_6r-b9DzWF4RpjJ|p1eyB
zS5ECk79I6opDtLA2ID7aT>PwgF2og1sqOn@kKR`Fi9GxU(U90(IuH#p|4}Cxi#!8{
z+|yy)Rqu<*6cQ;S{1?xfswY*7LHtevNr?&9s5mzHS#z`qMlmMuxEGAQ0^s+GtKa*V
z?%({(;T=dfcS(d&Jrwcp1V29+`?b}n>)KgJF)MvWbP-oMa=mzNQqgr)Z+EdK7QU3a
z`Ru6fhb{L!6is*%sZ1s_Es^3Xl)ASiRio#+B6uNCW7r{^><lC<Y^pK?T$(ZDe&n$r
zg5H|{T&^{=MztRSAs%OnKOYwb6(qT4&s$;dQ$__<90{=Mq*Q+Ul?S&nWI6F3^9rM;
z^OhDudY$>nW<?CiE($2gX322?>RlDJ$7cYgP2XUVrN4{Td=!z-)$_ag>l!_D#6g^p
zfqr=TDuWmVyFDz)2G=#z@@tE=z0G3H0;(qi+b^o$wUuNST{pNQUWjU`F*VnecBHCU
z2+^{k#(kG~`l1zm(}YI6Qhj>};eje}R^R>lw%{zC_Bzf{rol%;jUBScVod(cLj6M?
zw>kIMj9(AU=^`L!=7jAPKFozs9~4DCpV_@oUT~MYs4FK8GSmHORUKr`<+1ZxG-L3p
z$M`@-o5p%`t@*IJV6bkAmvZZEE?rSJ{YKl!bMX%5+5%1MsqZ*j&>09Ni1J;ngqv|`
zZBaujl03ktt-KZUJ?~0NV!OoBd!q6w$!x){?cN(srRa35vA0bbGUlaBL6YlydWAX0
zI^NzkCct4ret;n52W}}+2B-ydDZCz02n~$K&k8G`@%l6b#)E^yALIOgNVE7gS~}8&
zw)ocrIjk+pqA;S@j$O}J#(Ka~0y-YWG1#Ir&ypmu9hcq0Rv@Gt`eE|le4n#ts+Q5j
zfbk-ate$UAMw<Bn8~bw=8$Dk;m>U7gFE<5+s>7y3=dlIkg^KuFBPtFXCY=}~=E`^{
zA4VwiKJMJ>7hB;ZPTP3=_^9x0myyn~jFByrWW(CC>e1~5B$`Oi@|$U1Jh|*wbsID6
zNY*;3-+F2wE-VvPG8;C=42CpPbQCNMx&oz8K1@+*3<|J!NPuXd;L^Az^kEW<yz&!4
z+dn_5Hj*}PBxB)aJ+UTi$~)+J!STi-h->EPXRaxHVWcCRJf?Q{Vbj0=b)I-?BT}U)
z3m{p26KLJ{Ku-+(XRBu3rLd&7$8mbiGUQB++~U{2L~0$bx@vxze@=1uhTgkWBOd+i
ziJw4We9g3YC6SLl37SJzQZvAD>GY`0?%o~{^!zJvz1B+MFy<{QA~1I#m=uM_KGD;?
z!=m#qGa7_ACF`=l<Hn((9;kR;Z<3=2#PxJ?()LN%mF{DyYBL1mvHH$T;pa$g^jAY4
z@p=Wdp4x(EBeJJkV$YA9_SN_R<`;<hN*Uar5hcEkBD}Zm`^XsF)_m(b4&s(H;NxC#
z*hi$!`EhGv%&jSLZaVqEFTZ19(J4Kal=`7SxQiJPu>GjGJG38-^jqcOX`!OFdHb(z
z))yM&R1e}l3uIP2P|l<F8<Ox>0ZYDC7O<zFZ4osBs{lxDOCvIpfSB}U`$P6XYM(sv
z?Zu_mROY3<1XsG`XBN>i=a%;N65-jEoP=XF6HmjN49~wO5gIrenTD%1!xBv5bMcpd
zuwXAif0Hh-8a{sxiD})H#nd1}*NjNbrv-Y0BV80o_>%-<d<d8s;__6f$F$Rf7_tVj
z9HdXG5VVH?F&}xtke*8;gt9PT(BVoCHzcGXI9T@evnC+|&V4QR>z7iPv%XVcZexm4
zXWb$Jnxwx1{MS!t1dlVlV;O^n(5jFRunb6*oz|pS0UfUZIv+yM%N5i<_<iK!^wvw2
zKZ~Nl1x4UzVLiAg0npGJoJH@4J&6bYBV#^4{5)ovd$8yD2AQAsE!~yi$!^PD$DNgy
z-^RWRSO!vqkn5CPgsDKKiljzCGls-poOpk=eI$h>Mt4da@whk2{Nd)TkE_8RA?DHE
zavM)l(&E0a=lznzCNUw$7#}WR?R!&?TaFNK2)`y#zoK!Oo#E+HP1bgl8HRYO5h^)R
z47So;u>Uc(Ez-@pInG<k`%||>41Lfy?p-vGeI%CiT&@%Zj9yQSpGF|dzB@+o7zt*w
z?WPQN+D27ffW1tMl{j;iJ}0&-8IU3Z5sX-fJCRI-uEiOJ9$Kf>)gECPU?rgyoPT=h
zHYoodPDVe^K8u?`;>AkV6V^@KIa3oMzn$TbfWJmk$(8_qcYOO`t5PrQ^GX@horIL&
zHXN%NCw|j7NoX=j%x4<r5#d8_FgNgtHqux&uCefHyT`a#$3F~%>{t8nf`E7_<_Ofj
zY1;!|OUPQZr!r2$x&|F=cEV2m3J_6p?b{uM0ITjzh-IP)O6WQ>5QmW_Fen`yv}OiW
zn8U5~CXGz)af}Wswjgxv%@+g1BqJ}W4b1N#G(s!85e8BWz%f9!`++?E_CASWm;;YQ
z5zQPGQ7lJbmH=X$;=GO{Z>TMYu4vjjWnB%3!ZOD!Z7Dc5j5ix<-COYUz|~jjeLf6_
z|9YAwv7ScZT74K0Xx~tW{JEdxCp&^P5Pe^k*-*egu-*OY@OTumVirGN1P%YJ-r&IE
zNj=^5I71aYxY2E99y2KXbFnaqu9#t0MZBh?5;)yrK<<VUD9xKU5YE^gYS4q#E$}hO
z^PFjAzl|Jm-3M#s!jfsE!hT3YL$?u}ob(G$%qvrRN7(IrXV`mzs}h@$zE1zE8W&eG
z!{3-P{+(hdT8Frt<!{U<t$wF_xGSviPcO$f)gVv9UxShL`n|yjgGeFU5=*SQ(myCd
zo`VP}W8~|%0$Sg1Pv(apG!sN`sz|q(Cem}nYb-16;oRGG3Z1XoK!i%7qfNqpu1c(b
zhgyoI_eGzey=6QM;|yiDbK%)H8UF+Ifea8e`F)ZfX{G)B)bp>Syx{pq)do##nn>%>
zLLYWyl*}TzE;$x0+H%v{ks`VHxj3?Ql*B(XaIL@uJU3CmUGFgpIvIDeyFSQTEV#fb
zSE|}-Kn}gkdcL%xx>oKM-pK2O?kAGF$!~C;Sy@KB_*1&r(*f?EPw6Z$`=4i9!!+BR
z34!{la&aFy$pLje1LK0(_&q5(?QgPbzO7NDjCfgTmtGCb(-6WNM$u&d7w|xn>9gHh
z%UF+8VkL3m(?+bI@75w=gGD+F&M?}n4|Wn8wn-d?D2&oc27D^Ev(s9d1`6E9cjWPb
zB><zv_n%ejbQ2#TVt(gO;h`ed2tKHq<vM*Dza}$3k&Cb)n?4utUoVG7$I-l57nDH4
zQsGJ}@v*y_e6xZzyvjNTYP3BO$#?AUSXM`IYdh0Bkn;JXVY)fPuK5AqCqxWCO$N#z
z^@87}pK*_$Z7{7c4Fr+;?XYK_867Tc=ZYgEuCqdsdV&lG>`R0H1hk7_tX3|*7G`<e
zZ|E)uiaQI&T9RU#II6ZefjryW$w6aT;cx9ePf>`woNfs2+te~Epq!(`Kg!fGR6a;B
zyZhp)X;@O8L-{eJsvyaZ#@pF&irI)3Irsycp{Nuq?C{pwfj4AR(pg??f#2FJ-Lvnp
z`G_!ZTk@6>I+zkS6#kuXb^cZtAECkZ5{I1q;&%`xQd|?8-XrgW*^%-^-<rXPo`g@T
zCI{N&NJQeh`&Dg)944F4AIQ^O0Vb&s(@OYgt$Oq&l=>xa-ny2ND9I{tk$HmK!6?p8
z$c&WBW5lM~V5G%T5W-1n7{)PpZ2NdHsYF@VWzBU*q9iQTvoGF&!;$rd*H+(;wOmi)
zNv`viJ%w2p^^|%1x-Tl8^ogBK@AxvG*JZ^)P?ZfB6r<@UgB@n_+{EE|c#4*RC)TrT
z3Bd002Ocm5$rMs4DanxB_#;O4hPIfEU{Vi3gN+6XL!+V0J)_fXjb=y6KbOw!oE=Fp
zhd6|P(i*bUF6UeB;ag<9KV`k?b%nWga`&bhGZ>Iynj}u+(zK3~=X_Oyt9*K&XCk!j
zAGh(q2!M=BE?(Md`BfV<Gk3PKODido3|_PywF^JPiri^xw?A~hB+EOgb%4iTO6K$j
z!oYk#`(Av@y^My;9tB}1v$-^?bFhk`R+-%9ifAfgXRW>Y{77o9ZW{QLNRaV-2hTA0
z)$=FF(NS*i_qDOGUX*-jiN&>_tDuuSl^G~JzXbfS>F;6foQT-W^pxePEaN+e{e|-q
zWVdi$)9vD&_E)pS5be2V+<*3l>>fc{41r8pF_}@a%j=%j<Bp0}hgRT9Km-vKxtq_@
zb*BCr&Y}@Z@Q3<K!<Sof8&Agf#(iRqxK3T4WD2$%wo}<kNA2&=<`*bJ@9T6nYL0Pq
zJGSe8rM>{qd>lp;e4^O(4%X3nv;FhZj0yVbDmW490#>i}?YmOC-!Jt?o(;+di|aEH
zdIR$AvWy+Ixri>zhqL(OA9l&wq5p7FJYgAo7)L$Vnyk;H27H3}#o^%;u{b0gc?nSZ
zsE+OVJ`b&L*|YCOZ1Z$dq{Q0O0{2n4<u;Y>yxdHrcJ%#6`b(vK?oHy_#gQ(1w<V33
z5Q7u60$4bMVkp(s%9L~F^q|H^;b3w8C&@}2<5W1GdIrO0tDg`((#`cME!8IdyV~JE
zDZ3`7o>PR4iDmL*wpY1qWa@yjj(!roUrEi1tXT+;<|bkEU$dBR4t~4?<DEQKM_u17
zn3oB$Sm0DEoaj~=>4%+R-+1H)qqHk^X2XLWh(CA+Y5E=f%bfmVVYmjhyc>tE2*<zx
z-ziGbOCE>=HI-k&QN?D|@f}4DquCU=7MVSgDW(hI@8Z~}&ag>Q9I3aU76C=cpC)}a
zG2}k};t5*`&@oF$ZHC(M&L?dhjAgnwYg(`e4QZP88eISN>p<P$iTGe`C+=z1pmFlE
zh3F!HAlW~v?375KjRO=rb|^nwG-0r?iJf0QN_h!LGv?U|4HZU1{eTjY#;T^CjGUHN
z&kew~IIc0R?DOu^l-p2sBH@|OhZa_&k)c2CdK)u||D;dZet66?;BF1AA(#DJaEdRA
zT4z;G;|2RpkWFw8Uuga9k);6VnEb6at(JTsEd?B$_W{WmjK~S_TmdlB$@vX^DKqOP
zvV5aP%u8mHat__da9l8=jS@yCRiIC3gX?)xTVgRC7FBYoWgyl<lz9FUEJ-jtuCeVB
zTx7}G2>2-?QJ(>cpb<Dn5}#;<QO-{`?0)i1F*4MUD+4oMv<$+<6w)V!y_P#6iU|!7
zB3rz6r*KmPs=oQ_ARJ3C>(M74mHh?*at`vepSr?&U+oypjtX$?@ePG*aL>1|5;5tI
zqG@{M@!Zt~OkcBL?7A(6Fe981Tam(XLsDQ8`b2a%MKDb5;gxsK_OyB9T-n6Yd)<sc
zM=HDK)(S|E@ty7+xTLvUS$0Y(hJKo;LE-E@AM{+IW{vNjduCZ~Gymu=w<T3Kz(4m-
z@5xfFHM0wUG9k;0*WD%At)c{v8lxy*eQ%~8)X-){KwB0b%q;Twf>n2Sgz<^5<gsRI
z>ub+k-Vuj0IYWtDG_Xf}>Rl!>%g?#E+3Qms2+3i|B>5e-ZlbXk^nmzag4$XFAk5~W
zL`!`P`%ij+nb_O0*(zlN2EshNyNr}0;%_j;A%NP{x+=72f5e}9oNCjgb967j?BqHG
zWuFbNv#jDA9=1;t7|#MWAh-XK*&*k@$F>vnI&)<!G$snu2)<HTkvJQfc4OMjjREy|
zf)DXgNtN=k`4u^-`{3UlSl;dD_@_3ds!FRu4UItW)!TFVqx4D-VR$?cO)K6OvANW*
z;>U_MRMTh12LhOVjN;Na;~e5Gv!7cp;gIf`5)aPaQv6pN=(G<EtvVc$ar>P<?IaC-
z5s+@+3OdVg+Itf0Ix+m}dBNLrLAKNNAgjL4XWOcP?oa@ki{_Y{(B=8YK4Lb>!7#TS
zS|kdLR)OW^^Fj*W@<~e~taD&JO4cdY^Gx)4>c9Ghos`}1qnsE05fqtPb#!kpmRoA+
ze|vYTS%pxj<n0ZMYRvzD>?=0vKV7Yy)7~k(K*C6^r%9!5@q_xh*+v^OciR`|$}*-b
z9gK(tGRa%b#t5WxPp>)Ies6Z*0qh<j0oeUtCznM=jKfTyRCp12a47vFuMg$$DEL8g
zM({hMeHua6NDik6JCpCHEOqdjeltRRFC@Tz!(M|>v*XhDAB7|<D$sYg%hHSK9>ubj
z*C1BOfv4o(AwAnFPwwg{nI<8YgKxeL8-2!l-}OIp=P17A*zG31Wj}Ei1px9bPu3kf
ztll2GV8;61%}5@uvD?|553`cr(1fu0M%P=mCw3iv6&YCP2s&r-*>4SIHE8lvzh!#C
zgn<WaTt|2K2fjYtC@Fkjg;U)ahRyZ9Yzt@pqascW7btS*3>7;U!ehl_QV(f&Ir)sw
zY|^fpiA@x)+h}p(3h3kJ$~hW{k@!vTu4cZK25avWfzthu#;W_{<?>-9YB=_)SopGh
zh?g^V%#qr&*M4=5j=Dd-$7%Uy4P4I$SWe`6Udn{~7zigsE+K1W{u+}BXGe<Mp$lk<
zI(7MPbM4H3`}t-dni>nF5k#09L|mV``lG0YzGU%XIfkTCC&6M}pRcq9(>J^e@4;BL
zijlSo%2`yd7Sev>mbn%6J*Te8^A6ZKc4m{rgyk#IV`b6VMZyx7hBa#NNc>|q-CRA{
z+@;-44u8Jw4{-I{Loqwg`)C735SX41u*dY$m_URd0QYwW9vixE$_P3g;58y$A3uZA
zn!dtRzWj&;%BHPg?I;#V{GtM8?pxf4y#y=Ml6R<cFV`5*ZPmW)F5BGv?9K|&z?Yri
ziCmKpuex)_n#)$xN6Gc+laMrO`c|ea3Y_{<3uEKaNO;C)WaolC^-@umTbd<9Yb^NX
z$Apk`qGsGdW89X%{|^D>-8NBmy}9`-)?S9Zn6eJt@8-V?*+j*R#XR!Fe68-!b^S8_
zTf&M=ai%;h=zp~QEnf6rrOU00X$^Z#`R8b_WF8?7W?Co=pNg?`RvE{=x4-KjtGl^{
zy}R%>k-}~HqcmrxGOL@>D=U?L<&=v|@-N>w1}{5~hKxD+!@%yuTfOByw~J}HKB|5J
zys+N<?}}!*x=iZOSC@->^v!J``P3Q7JzWOSTTSovVX`S7D(ZbN+sIASv$qpXA>t9>
z^#C>uwJyc&^Y9RYebo>9>sgK=3Yp+(P{43z&%(PnSNkrjF{J-mRcFz`d~>}!aIzat
zfdk%U8XFAIuF*>wP)I5Dgd8GPJB{y7tASof!1`EK^Tl9`@14>YsL3q!6c=9}S2<!=
zS``;84m6VKn5)V}j(>n4VE1nY|5Q8iFl{g<J~bU+Aek8$peQVz<|`J$TFxhF+!z%G
zBN7sPo$Ynnx*y1zC94_Ncy&uDcZnrh>tV{+S=mQCz84p+W!g-C5+BZ@xLmOMXbc*0
z{*F(9-fu)`?6<K$MEIiW<AXM3+f+Nt-l}!E<fIuwBSlBcI#Pi#b3q~CfW7JQ+l7*Q
zFa*N&DLA{|`Dlt}iREhLvID0k*6M&RL|X!z;jQbjKN?!&rwRR<&M6u4<OH--9)SHg
z8y42!y*^LF{Q2oyhH_4>YWegZts1?B_B*%)xQNhBi@vL0P7K0{ymw5NqJ3FCn!)Sn
z-&;Crv?A(c@bv{oXaQ_QQ67Gf=qLx#;<-oitota!;a)HMGtWjNceMfbJHa}G=sY@R
zv`?q%X?i_=@t>;BJjadh$`#UxmEa6LuIW+~9VOz+MutdipgGY?ztp0}DI>yPvM8GH
zCd07OoahHDzEx_LlzyEZaJC~Xrk;WW3&5-?xxUn(azL^$VARG_N$*(z$ve$&_C2rU
zlj%?RzCzZhn|?23Fp386<KIQm02~t2aV;BHi+WiA0FmQ=wE&9l+nX`&MP$cmHu%h%
zls<J?+qaAXEnQU1V!%2t7-eY+kKP_IOH_@1iyQN$f>aAdkS&274`yK9R_z~#9{fmK
zoyb@Tf;_Og!U75JHv^7!)monVRPCcSGbgngw@(-d5N0Yo@ZZNMJhCifb5~Idkk<l;
zzq|QOV0v8a^^;z*BU|)N&Rfd%iwI>B+bLpHP40AJ?t6q7V?Xrpoe16y7X6V*iW7+S
zaV(WB%iT8$S5o;5;v~*&R2Y)Lao}H}VjKsn*-Pi{K^xu-lW^HF!T1|Y9aSeTA<yaT
zcOV1D?9d<Dr}|N8q(3xDLi$Hk0)wRp(g@lulHg+&1!~pSF9RB^+Bwu@rUON4ZFF}@
znU6oz%nMjmO&1hOL2-$Rj)~(aCV+!ipOpXA&X>Sb*?f-^p|WPFkbRe(uKivivdf+|
zOUk~L?AI2Nt)i4rgd|#Ml}lwwg-}Y1h@_Ie?DN0#^gjOHrS<#v{l4$#*L*(b^UQN+
z&YUx6&YU@OX6|GEYA(*Pk%Hyn2AAWh#k3!sPVTAA@)Bz`^`SM3)8jD<A0wMkO_2~k
zZxz0rN%oDK`zmLqy-_l54lSFrbkaqZNl8`ba7#*aUl1gS^oM9PNSqFh4Uym~p&?;;
zHz_28iL!h<bSLmhX5le;f*U>iF&`%L0rL$tLIlB-in9akOC(}B<i>hL^w||gQ<ZY5
zt2bHksc7Cgw&yC((95It;n6u#Q2|9+2KCq``%&e@6I)dsaV<1weY9RxgpbXLR7#U4
zl(MM^<;Q^~S_XR?3di|6we$0f(&JKB?0md5?p@Kk@Z?w5$<y`brrmchB{^q~EupF2
zx2Em-^5!HT7L!14+H%$C<}0q(JWcXW)!{aZCXZ<*vP`uY3G&!Bq~4zu-<>;9J$75r
z*L9>YrnA4Hambrq(pMovnbLgz*`2^s#Y!A>UW&J(10uFCS&Hzs9{5O}9bsrNo1`_{
zY_)xNQs<s4?@tdKaH?w@D;EZ*da>*|OHIN!DwqbNJXVqxGJDbVaEp&LliFn`DnFg2
zxcovuVR`=D1K1hUmd(-^!{-cR2tIp=Yu;<pr~ZaA!I6{`({!u3h8=c&ICf8T&h%Pw
z9gg>MHx+F+x&N!s+Kv4smAA;lmKr?oetKn0cGtVrg+1Bj6^sO@r>FVM`|8=eUyk=>
z&zh6_&&6Q|8E?NCEP5@xWz$jG;dOYRt;jX}_=5eBeRzwhe(LG8HVG^5!QJygU7F*R
z{bnD{>uJV5_{nlkY^zumdm!b_?V{78LA{wbm{snQ%)W9Y(ZJEgyk0pNHM%nG43DqI
zNKHU4WA$x8u|`64;7MAhCilnZPqydH$jG|Cq7LpK>>huw#GB={)_liS0*32y?BThi
z81G%jiZA#D^h+oW)KGHv$UR>@kny5mc6SJ2r0%WA(dLoXle*=8eLC50359p9sJCpm
zn15JpDkr2gZe;z4@EiY8_nxg%AMJBXhEzYq;PXmmPYbTgUF$zb5MCLSO)x!Xnb0VB
z=*Wgm2TwRmdv6&!HU6=W5cd9UfM0jJW@pv*RZ0wVx0|#N?U=doZ2Va~e}J==!^`8Z
zk6|Y$J#EYFvwE`Q`>-HdzuZGQSmZt45HGD<6jxMre%^20238q4@yNW;i-yx)C;SNt
zhNANm9WI@heR*qrO`QrWW{u|W=RMDRcI{Y*rqMQrH`j2auIdiKW4wMX4QWF`jzU+l
z-1mnF_Rc}i)asMhjvW%SDUA(O#z)-bze}NaY&!Po+6MPGVZo%5>js}-Ia<y-q@E4=
z$kATDi7}yvlrYxcoY=g__hnt{{XDJc(rvMmou+xVydv~>E-;nMhA>`iEf}~nIr#p$
z=f#y}?Dk1so|XoBQ*%Mxbe$JwS9K~5xw>CGt3pty*Kc?7AQRbaPLrj>8&9+&H2ZG$
zM_;_(c_lJvg+#R$N6^0L;C5#BDG9sF+V1jE&4=tmxov{yq?S~Xc+;|Oh<`(t_mY7z
zaWq14#|g`hp%n8NJ6%FHemngnpyO1HlFXqqx=s?hMeoSCaM*{(uB7SqOzl|iK9YU7
zo4ZaHF#wl4zR|g74n_<Wn8=2-8z`Qy50jM2Pv7b|*r}o?wmX}Xg47)MVQBX~s=yiS
zTmTQHy$bys>pd&3k9(3Z9g>o>EVWVC*_dWE7kEi!jhx>D1*3v3s`uIC&-b&(EuFbJ
zaTF9=#CRK}VKR*yBSt&y$->9%6BTXyLY%3|e9|+EZoAWJh)@P-<Z62=*m~cKH1gpp
zDI`@N!5`TJKjflB=@mf8FB77zey}Q0%Zo6#%g)s(UTZ#OuWt;$E=%GX(sYRyh9~M6
zx2K2Q9$vO}es*@Niudh`gN4PrC`DLD-}b%KNeg((pS`kDLy3`={CYmdH2pRQbM0xV
zp@P<vI%7@OmTm`CVLZ!+Zp30K!d6f}t?43c?h|3Zn}?_BJ$H<9=;0aL19lz5l=qH0
zNEf`tbJa+48D$G7PhgxIj1m%Vl&9|~j`zJBUN!O1y0l3kVLf$2Lt0)@a1tvQH*TLC
zoBY0NJn3BYdVx!I&vfqZ>6*{%l_?LI%FaEuJ9knnxZ|To9e3EWeD#)splbs&Y3`41
z*9X0~RY_6ID7C})Pjny1(WzhAJly(>QH^rsa*l<S>iq7I#->Pl<(Kd8(!DsG7culK
zaQl;sXWp16YYByy*<D|2F=6YB#V@N=XWCazVL|&^4QKIiICf^pTR)nTZmXVKv1|5f
zM>ipfM#B8`X%F%$Qa3UoFgd~~bkV~~b0gIiwbtmN#~0$R?h0!xV~9@{)ArOVKmPQ7
z<%>=9skAbO9wi0V6xEiyyx;X??%uKo)&~nI?XI;Q_O7o~;<(Wvx9aVbR^Z{A*GVrA
zDyknpA5=6(wK~lsOYI?PxzVnshMa-IE1Q~@CYdtaiVjMAVx4a9%rJ1Pl2hBgqr^Ag
zh2~YaC!PP3{8sRs^Gp(+mr~PlnwrWn+)j_QYP?mqhi0~Cg+!WV&z&{l^N$H*)L9X#
za{(*+4;~R;dUxOHYxyhJ$5>ts5T5(M7CIkB8cyZq9nL+wpRe!Up+lp6*J3jy>|g0t
z%ZsjN(_dR(QCL)Iq=+|FX7_FkB}-2fRd+RM+N^Wp0yg6Io7jPK-S_51utm=gDln#(
za_GDF%SUA3rmm%2JK)zlA#RwlC+3pQOB|;eYhC=a;ADa9r3!2gYk_~Wio~NghEr+B
zH%=UpjhMHYep^Neea+?7m3rKJ&5o+&-g4xD?Zx-l{K<E{oVcP^r?3p*xxhuS0==m$
z#emn^3YS;VMT(jh(a&A#5^c}Zq9f$zgk4m!$B0(0(K5~w?bc;xh);E+2pz+Cv}>oS
zc@cKs$q*A3C`iqWq4dV|aP!7f?jL@b@e#v06me!vU$WXzHEp13P@Lw}Rvby=T8p3_
zhT2=N`tZk24r<8vF)-YrQ`dTqA%qH*sRh5AaC`UuG<CW}X8n^(s~#_v@Y!^hy!nKW
z#Qr40kafjXdmCw>Jo?&6T4vP;)@`wOMz^Vx2<A8(Uox{KW`=d%A&38P=s++FiFZgh
zi8JGQ)9%hhk{qv=7~VOO$|VIpX(FxnI#}i0){P#GkbEIH&J>WJpLnNKp3#FmdTV6Q
zgG9Dx;Wj?z;ZI5HaznFheaCL~zKB<miYk8WAk?RIWJ^5nz^pp6!mb?V<zr6>Mjqk@
zA4HUV#;%;OKe@HMLcYfHlHW-Yn;Rv=+t@WVoYp98uFbGD-%#P+aek!h3Ck{Z{NU9k
zq$j5Kt(oEWelaD$iOr4cET=K$v$Zkopumw&(~ml{NK4pNRdy(~bRJnfKDL}W@uV^J
z61Q42)p7B=MnZeS=GWLTKd0Z7R?o#+%lpz?$oTr<v|jru-@@fIgA}+A%PVz6(@n*y
z&WU0l3Om#!GmF%A2bBb5HJ_GUw_U7>f@{m@5(|&Po=vy-(<4X68mgGRs;nO9UySX+
zCR4CYZFdu_(>=Iu2mecd@w|_{t9A&@w5WR~&GChuKY8syfG5ej4coS#vzoLyV!C`k
zcfv*~?K65>+)Bxs8@9<u%(MF~+ltYVe`$B(RS%2u+0oON%1(0SY)NlV8TI#Sxsv&E
z?s1KdV9S;Cs2c5>l`_ep`wgWZL|NaC_g4aD>nmQVZ(|h05yndJSez^;{z{1;PdXur
zAzaLs4ZoB9nms;MP<YGcCV4)L=xG9ugSc#_X(l<+8<k~u`nFtPB{|2}?r&|pEKgD3
zsjexNz2Et;H3K6m^|6~fnID(p4b)WTl~Z=8q+{@-t~Vx3>j$q&J?KA~_xf>416fzN
z=({JEI1fz{;)E##rnpVQM&^W^NIjl*yBw_$WAbcC3%qfVtAJ&WG%D<HI_G3fe)N1o
zexmz8CyB%T=B%=+^Hf<(satREdCc_i>50P+{Z~n+w~2=828nkqKim~Z)x$YY7V0xZ
z6Ej?cUuR!svrTsHy-u|<L2iG_g`P8+Rkfy@Pu$)sI6$p6GV<|WN>(OyU-PZW4}Ec|
zy<|@^IQs_FDmM*&{P01wx5A~3cJg5DGRJYJQ>7$yx_ms3o$AkNUSiHzXYN09SKli2
z!eJj?V;jfN>%k0`%QBl7s>${&A?d64xVvWpo9UNtD9f`XYL@Mx#I~&p!Q)hYy`%)*
z(5DsdtLmdUSNnLap6a~lsbwWkAD@?+N&cQaZ~{CjE4!DAJKjxcbY-*42-QQ(zF_fm
zRhLF*zr@|+)~&+D0Tv2|hB)ElRwED3k9yl4ENYl$m(sH5F1;+|y>?iA<AqUBQ?sFf
z&aR$x<9u@*g@HlgtigjJKaLefJGZFLk$Bo1_7F{s;f+f%3iZD=O8JQSc~*E<*Er`s
zHus|x%03QQxtH<xF?$cs?@umFTAe0~%RW|Nc}goe81q7~I#b4V`^bsda+f>XvV*e(
zeT)qHQxCqUAz`I&oSo?KpB!?(f4M$+DXpyU)Tqmr>%q)&?hmt)@L6LYs4_QAaeI}`
zUg8Wn<LQ4eUC!M+F>S6gXe_8yG*&C>1_8{6Fzl>5a62l?nG7E^zw$xiaHtZ7t*fJC
zcK28_Tg8pdjUfq^;XzI(sCcJVng*Smo%|s9p?Bth>g%doyW2wUh`!Tk4U%e3@p*=E
zsiELB!c0-Jd(S`43pal3S>IM@n21|j@wVM~TH=n(vQw8=M)uIMPwsK*SQ}0nPj5yD
zCu5*#XcK4Yqg2sYs^ctp+JPkC9QEWnwrJ`lYi^R*>~P9f4%$!L-`6rY=?u?Svfqz8
zED~wmTs13E)pB&b$D<b?SuVIXvvl0axc-2pfckpO?aJCmLM-h#qS2)Bzu2lt`*vwR
zr^d(}|5na>p)V;rUyZ)Pv^~vC<umAhoyTNRHFbRURLP_M9ic;g0Upge{H54v1#`^o
zIrGN|wkHUe5Ba=r&v`c&7?U^Y6O*Ue<Q*=<K>jACrsVGY43Ebp%_(2c7kJF;qMUoy
z%~=Zi*6Y1_V!Y~ENn{gbxk3f&=zQo?xT7i0F{VZgY5QN7=E~0RSVI2z&81OulO#6G
zs1QhB*HhDvv$0WMFW_gOs-R%yVe7J1nfknrMV1)dM{<!mW|tJgl9<7(`#)wmV&`9$
z^QzH?+DUbb3RxDL3MW6hb)D3_YXy6g`?ISRC*o3BHuLLd^u}&+E5(|vYuBka4sE@0
z1Q#^11&?EI?U18vm4biV4tRQb`o1jX5<f0mLo$lc;A3k3T+#kGO7gvur18ng$K4(j
z8_U))>^|#0^jt%V$Lo29NDFVxv&(kZr%fe~%uNLKzMC9j;&^8x+`~pL;$CGJr|x@5
z+;$6f756UHZOX}<fnBR_*_glVt|3*STFo&?f0o6lv+3A1BR0Eyo{iU%PEoxus>-Zn
zquF3d8I`<NX|KM?+14hmd|FwTMpws;JoHJ5JKv7J)8cH*cxE|LpKjzdd{`H}&P$1D
zGvrd7p5EDy=OC|quTQVBG<O!vbXkg+6ztQVdQeVIT@y7mrm*3@kwrq-%m+s65?!(=
zk3F5N%jCJ%SzPimyw*xzqr9cUoIjSqxG|+Ml7fBb^u*xHkrIFY0tp*$+I*s`&~fzU
zs~IO&dY#GM1BS-#w0mRa$B(Y}6p&v#6&*>|mH))+w7|hTCBx>GvTRiHV;+wk11al{
zf=EgZ+3hd9cJ<ZQDhG`YKMiG?SzmI=Y?=3bsUbE`M^Oa3QZ3Ks%BWgU+q2u}SZe6l
zrPjtz&EdjlE+!1bi1y(>kX_!~bh3i|)x4nLe3sLSjcU!7hPNd6M=_xvU2}Zr=980>
zPVQwC^xc(d&m@;_QQmGAN?Y!+CWW1&T7@v_$Qt-~@L9M}Nq*!zyGr%AdXKKLoUrw^
z*OU*fu<DxCmYQF&rB%IErL=2IC8X_G;PX?K+(XTLb+d+XBOBap$XeR)9r)WlEW7Vm
zrE?}&6a=hcc+`4^gNF6i(lfIyd_oE~&iC-7gmNJ)(>1SW!P{1vCh&d?e)x*=_^c#(
z{F8o)^xa`G2S#}#`o#?!J+D4p{&qao7iUPeXJ7jKvf6sK6%KmQfo~pI<fK2PX_>Gf
zi9X&aWW$~m5bNapoZ79tYpf|F_IO@TlBa=%_fDb8HOjJAQX9#ZMD2;R99hCn+CU>>
zR$9UldqGmu%JK!KD@)9Qgbs66QN@#;$oY<!9nAeKql3A#uL3YVcF%^3INt74^2+1&
z=1G4*_x||nE5~D379JgI@Zd3Stt*>tUK%-^!xpbQdKJTFVxif7|4gL;-7?AmIxapB
zYCUJo8-8h<8n1ItYH!_J-?$!Ay*jdGc~ige+ZeX;RKeK(iF-aHJwbUT4ZZO*BD;!*
zX(Ze5Wq5CnO)G9G8#>jTJJC!dX~HGcaAV(*^qgql{I0b@&n*3HTPsK}Z}i~AhAST<
zRCC|lXOWc}QrBHAGd*WqT49-%%2j%5R$hdC6}dQlN^om&x@cNYWP0U^`$GA&q4ye^
z$(8x_C*M5S_<}aN@!^@u<!NNWczk7{#%%YaWA!v=Uu%gSuOlg}VG+pIX>-+UGl}=w
zx577gPdp{PW40~B6_dj7mxIL*H;?qxs@R2!n)9`^9FHC_+HX_vRzsejKh`U{KZmMl
zM=$=yVd<l;R00v}_dc}ddF-%_>&W$aovj`?rtz{_cgraTY|ZjR5}-DOy}h@$x-p_h
zV|fzCpw}bZj9_xRf15sLWS6_<E$IQqcbf8H)3VdSO%@NW-;SNWNvcA#d*>wUmg2)I
zlYX7lQi*s>{?XAPeLbdYD-@osm3<yQW1I4}w0&#z{ubB0HyK{{9qPXIvQoyV?74(d
zn?T^2o%BmR<r}M}8zW-XQ%!6GwmkB|DJ_ZBH<>&|#U5KV^MS3{s48l_OUv#8w?pWM
zcUC1YZrUD8z>)dB_q%YwU|{pGP`M~De=asq(P6jKEd1#%vB0+%Tv8mha;(j?NYahL
z4yB>~k4;Z_%SWTFy6LV`($9PLTB~0sbFw42J$Q0!lGO1LcfcA|=BTB516#RMj=Xtt
zDT4F(6GBc(&611##b(#mw+U%39bJ|0`Q%b7Y4UiqcL)u`P15TuT#iR{EKL2m#@So4
z@yGj56%;AZD?rUnYcs!EaD<GzAHSZ2+x3*dr{5{K{5o|yi1mN_G~ferIZB>5vQ82W
z1M7h!ZnQC3@N<4yCy(U5!u9&#*zgTIL~Tv(MW(`IqSOnfjP304?6lj-=oLIqx)&?Z
z`@y_lhFjDTvb39|o+LblX9D!)C^s|_^BbBr>l^uV`N`+f;Cjo`OHaMRHNdZrHdqxe
zbEDOur7S0n&$`$u_kf*BftaUK(3MlW7unEFWcU~Je>d|*3TKy6yl^Nw<rWOTz{^k*
z>4GsT(967B{82+==T3h3&E5^Qk<kZ_Oy8x^^Aux?Tp3!K1dy-n=10(Gb!&MvMF>lh
z;JqJFy`bVvWsawS$A<y8BVA@qQ-+^JtjIRlu0l_mDc$$VNpxP6yJ;fj75)`2xSQnp
z^qusc({a-gspbX#9nH#(@GHohGz~OLH#kHI!LJ|_!Qr<rBY!TDl9EUgp^ONGe<64i
zp_&NbUktza|Hc0={{Ox3i~nEz|4;c>Q^NsnZZ5#UKo1B60s=6fl9GbtrKBXm)~yam
z-q_d(!NK9MNS%KI|JBviz}MFY;S)`;Ps78*NFJ8KIxw9*dltcgWw1~G1pXHT<O%W%
z^HA0>59JK|hR5TPar$5D59Fn+tPGJc<Si#BXMtw{tPl{@l|=G_dNM#g!46Qft^^dc
z%YcxJHu8jhfcU5`LHvk_h@Z+o<P|2E&&|z6@=zzx-_f$rhA<G=@QD|Xh8VD|Ar45n
zXaWhBjlleNG7xszgp31BFJ8R(9X^x=d`D&RGvyC?hq?l3LY+=cO-0Itv4Q|&i9zzB
zdQw0)!5YxAG5{JPh!gt&<^Lu8pCx}t)5phq!DhgBw2X<B7A&WsMDojMs1W#4Tc|EA
zC+Zb^M{O56XB-^t{}%qyIS2Eo{ebUKZm3;>We2Xgf*lD4NItsK8|*6Ef#fChB!IfF
zHj-x+SOfGkT#&p%xFs+n>XLk-Gx9z(G=#Jd^NZ~l?AJHgsL%2bWrErZIKD7J`M}>G
zJ#-9gd{uxnmKVvJ_^JU_OW9BOtaM<tz-lB<MH~}$8Ez!ci4_IbxAy@7E7gUzQCYOK
zv>>+iJM7dq@&Dg~AE5bJ{=2%m5Sc?c!#RfPjJO0HxOPJVY~9X>)Z6N#2)G287Ibd$
z-1r>GIIAObnvysdj4Jm4F~7|Vy7WhyU(un@@{g{cP!|{TFDXF_E?p7_&f9sAdWM$k
z0QVyPVg0Z1zurY1P!e^Dl4cn&JQo5)U9^8k6SYx`=h^r2562OeC2E_0w*LG8&EN44
zaZ&wiZf-`#6TUB=zv@^v&{Ssy{Cs4PdW+Xm=(9mU^y)XC?XUba4rwlAPO}l`w0&g+
z(9iSvB2D-X?f2LCU%Zx}V+rvWkEMepKWMA70Lgn*5Z+)t)XqZt0oPTSN9jYEpgs^v
z$M%ptpl78=);PC@Sfmes)F0RuN)zSb@6aDQnxz0E%?#LBSNttH!-o|{*62Udg!%8)
zpTz+60O|(h9n}TcHss&iNf-zVeA0`+z#TwINp?Y(P#h>X6z7j^^GI_n<Yg@70Sj?`
z`zx9-{}p@oS^gKVg^Sl;1!*SGQ)dKxoP`(aJ$!KccfQ!-JnA>2b`bg+i4B2(RbUnJ
z9?}pFj1w&XL=);EivJ`0Lp(SiP+7n{Dht>LI1cDMMSq9BDT;&cTfVj)tReOT^_d_|
z*v4Pc{9gVS1Drp2e8j?BM146_mo%`fNIe}LjRl<*73BlQo3;Mb)(WEhb)6Ley8z2V
z+bEB49{~3Q-?6v+qW^}j9e?G&!MvZd5TZ-Z>OQTXQ<Gy0dx6%riwn9SCc_F&*KbF7
zxAs*9N9%onPlow|&Olr9NBx2HzrnBmCiz32QC)ztL3LVGfDRO=D<l1Y^_(0n5P*3j
zLltn~z$d#%O+$h70p{hfJRm4zGf>hKLEcgO2=kC%RR8`{`F{>z+l%7|sILq2Ygv~A
z_TTKPtn@0NtIPA3Z9se!XEFW{z&Gz7p)EvZ1QV1KYG>e@3Cr5A>Vl@L`k(ZNxW?VB
z+X7@{Rsl0h5l~sb74Ql$BJzd_`iF~S7U-P)&b`<-@ek#L+A%oRFhM%-cerMv`kS>E
z1Mog#NdD{zO;CGvGhii-2Nt^)>`B-FR<lws;6pp}M|>!c?~JSbt??5m!@nsm^<U#3
z>I167P>)dm3;JTH|AgusI)<n%{wMGcc|(0fG(q0b^%Gr(P@O?^>$kb{PvCzs{L%mV
zFYF)w&&QvC@&Akee=+>x{}=!N37q{0@bJU%*^5EH(y#Ol3Enf~A_9)&tM|<C|6^VM
zMgJH5e+7N+-(sC`uL$>&uCCjVy_cV#FY*q{AaH+Q%;dZ2qw!0WK76A0F8)sXXsiv5
zJwv+iDIhBVl$?qCYGpy7m*E0<Hc0`+1V_LjCybOs`M@W{`-XGB&(cTZXXx1{y4TgT
zPy=>{?0|%^404x1+(s3cUylLumRbw(BQ$oxy=brbz4RgfXbb`J!OThv1f<!KIQQZ>
zJp?9!HOQGEl*1aF_(JRz;-lwA-%207n*tNu>%;y)P}LIxyE06G1eOoD9kN2sk)a$Q
zj`1O9uvSS3Y`MJ;C?+~B;6Qxz-1sy5>_5?mF=)tpK!87@TfF?VKu&ShH|Z0j04pK~
z78yRUf^{W=4*|WW@HP5q+z*W_!!ax@kOF5bWPk#e6FB)Qev!V4uP$*cSb-T)A0+&Y
z7h)x7dw(H=KlQ(?tQ1&UT7dZYIAkp3q*;(S-FM6>z^5$*RtmBr_^=(=9&GnZ{fBc#
zUtjM}{jV(51<iF<$h<=Dmn=SuSsWWQORxZIB{`9^JH12O{?z}lu+W9OTA%BGVqzjt
zRaF5ycLo3(8*8u;%L<HjxfbR!7Z)dRc6M6OmA~r0w50;z!HO)5KWq=S`?c{$<F=4T
zXj5S<7sgJD(p5n6zEJS)ZSR5|C@3gEo>0bU{|$ZBk@F`g2U#Ky5FfUK;{1gz_#J)p
z-VSUpJ3E^=cJWB;9G(ZD^BFxe(ACxX(>W3&(MG^0w+tt8jtcQ%J7}!#FJh>Fl0UQ^
zupZ<a#wuYP5XSeQ9PVG$1MWMvfVS3pfLSjBIvzD5^mpym0+LFc;Ap)!F!RMB^&uYG
z|L>XqsJ({#LY;&BK!9f<kOyTYS#a<`Ji=pUW&-jQmstb2_!vQOhB0#f0sH&uZ0rA@
zn|)>-_^ka!Z77rhDhJpXdyDm;kf;xqCcMaby{0A?NKV%Vau^Y$9M*&N;kg28yT343
zze*p@K?ty2XiFh|C<jgAyvR*g1JaT#ATB`-p%2SpJy;*T2lu1&{|M+=J!}v54eH<G
zCpu2w8K?gt{|6>GpJ9rK2w#YyL-@}4`M<{h`$hj3{ht6h(oeCr{{@`=X#t3TNrG{b
z)g+((lSlgHILXjY)PbMb_WwCReT~2A92WuT_gPt4BI{g9Ny&mg4S)O5|2v>}I-w5@
z+t<?B2$Y?%KvEY2WQluRHBWOOr-WH3|K4*_)CYrp9Q45~tjvI#iz-lZQA6&DO1fwQ
zOGlf9@~`+Q3jk#+At8?VS}rcmh`+NfOasVi3WAN!O2}P#P8lwsOx%l!SgHV>v!O`)
zFirv!^jEmQ5EFo9+`rw6#9(9)zlw#G2Du~j$GY%-A0u&}C4!Lz{GtK~&ez5s_P3&<
z0^w!5i#*6YA_g?|_`xb74OD+nABv9X!^69r>-`LfeKSLF&YwU3$34{V0Qx}C?}t8_
ztJ6l19It|m1(X@QUjXHd-c5t|%ium?Q-U>6ve<~=L`O#<ZG3KT1@~kSV4aO>V!+;#
zf8jqP@Co-?5MW){J_E6R8RA|@829PkJ;YsnH||UFad$C9?m^YwybMy36Oi8^kLaCG
zxZmNE;Q)r=2Ecrq<$`=Zb0-u5C<i!3hYue@@{kWtM=78|><jF(si{5!@a{9G05jNN
zA%(~c_9-_v2ibpqO@Cm!=pGIB75eKYx`IgmZEf^`o0~Op%msiPmK%5_=q=1|h@+yS
z{7o@5G~NdH?Qp*lAG;fo)xo_=03Rj~($cknw~s3#FDTRR{Qt^AUr?VP_8;EQ+N=j<
zB~BbiJ*1!L9^*f;cd#EYMgh~+t5+BH%TQPTPCNPwei{t_%(j1~5B4Jo`fc<ipU${Q
zzu>nKQ#BF5kAk_m8G;Yx@FUN^n?9WDhK7cqySp2?(+g8bNC-H0?i|rBa($7$uC6YE
z<G0%j812voSZ7tB=!^qe?wf&6Z~#)~<m3dXsHpx#AN?=k@c2t$?6e;2K4uHJggJnQ
zod%FL#Q^_1NnmH_ZiF8<H@Dx>mz0!5a3Q$3X#h<FQ9wt>umCHWn1Gy>A~5!{TBwJ`
zVi)N9`uhGBXNUl`^|nAzm<?E%TM>D62Aj0?kT#6`4S<HL)<Qk#oBY;~>h0UNFSNVE
zNfbzkvjb-$E_{bih%c(Z5A=6zTBzsY;jutpNJwa*-Pe!efu)H6h}#p3y!-p_1dL3K
zAo2V*VB=-FP|w}n?RWAwGBQGb4-57NKF(sm&QcI4DsTdf0v9l~lLXe=H-ONv5TuTY
ziOFA%zqYparx<Q%0C@LgKX7-J1TFWxfxDMJn4XzHaG`JdCH;ds0(tTA@mc6=KtKTU
c8!Y>$>3?i&Y!UJKf}fx7#g9Bm{=@YD09Y=c(EtDd
new file mode 100644
index 0000000000000000000000000000000000000000..bfe873eb228f98720fe0ed18c638daa13906958f
GIT binary patch
literal 17174
zc%1EAF;Buk7<~nT6A2>|Hn=d7m^f*Ii35WnUEH0Bqq`w?baZt$4o*%c8U}uWzroQ7
z6EPB}de<v($WdAZDezvn-1qLjM{4i#efL2Tu#ko8<{@!b1{$KT)f9ir0WV^#QVHg>
zz~dfZ+rfMaC>{WXLclE`TLtoY#mj<s4n;3)R}NV6m4TXs5uWGa{Z<%H9`JmLlJjA9
zG@uj;8%Xblf_mzyr=EK1si&TL>Zzxmdg?bpAGy#b7J`#dI6&qo6x35sJ@wR6Pd)Y2
zQ%^nh)Kk9+`k;*7dL1pR$;ruAkb4Wpvj0AEa`O3c`AA_+v}+8XGjww>Vy@2_0@J^X
zp$~oNL!SisL=JfWgt3wjm|i2&hd%V7Pl9}8EZf)O8tr7*df^|%PQo?Q9=BzkR}t+L
z+V9D-Fk()1o}D(ItvJr{*ym_1dpH?$Zs9n`#W})q)s9)MzMnvci8LA46}Ojp#ulv#
z?eoMGj2Ou?tqW`)fBU(ncLzW3bVXmRe_^NoiLUf(HN|+-*9I}AogR%dYr}68&imYa
z2Zy*<a55c*hQdScN@3l&zujhRgX8KS-b3#50@Rsmu+Oas`#k1(N{7m#{&uJ=%hs<)
zMPEPcR+nY_!7^_}ZgKtPI?MmeU~B8#p0GZ@*ST2l&9cUJaL;4)+L}1QJ&M)K+hSRh
H+qC%~TjON0
new file mode 100644
index 0000000000000000000000000000000000000000..424df87200c706460f9ad1c7722ef0d35f286f2b
GIT binary patch
literal 25214
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
MRMstU<nLDhAMvgeSpWb4
--- a/mobile/android/tests/browser/robocop/robocop.ini
+++ b/mobile/android/tests/browser/robocop/robocop.ini
@@ -109,8 +109,9 @@ skip-if = android_version == "18"
 
 [src/org/mozilla/gecko/tests/testAccessibleCarets.java]
 
 # testStumblerSetting disabled on Android 4.3, bug 1145846
 [src/org/mozilla/gecko/tests/testStumblerSetting.java]
 skip-if = android_version == "18"
 
 [src/org/mozilla/gecko/tests/testLoginsProvider.java]
+[src/org/mozilla/gecko/tests/testICODecoder.java]
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testICODecoder.java
@@ -0,0 +1,238 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.gecko.tests;
+
+import android.graphics.Bitmap;
+
+import org.mozilla.gecko.icons.decoders.ICODecoder;
+import org.mozilla.gecko.icons.decoders.IconDirectoryEntry;
+import org.mozilla.gecko.icons.decoders.LoadFaviconResult;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+import static org.mozilla.gecko.tests.helpers.AssertionHelper.fAssertEquals;
+import static org.mozilla.gecko.tests.helpers.AssertionHelper.fAssertNull;
+import static org.mozilla.gecko.tests.helpers.AssertionHelper.fAssertNotNull;
+import static org.mozilla.gecko.tests.helpers.AssertionHelper.fAssertTrue;
+
+public class testICODecoder extends UITest {
+
+    private int mGolemNumIconDirEntries;
+
+    public void testICODecoder() throws Exception {
+        testMicrosoftFavicon();
+        testNvidiaFavicon();
+        testGolemFavicon();
+        testMissingHeader();
+        testCorruptIconDirectory();
+    }
+
+    /**
+     * Decode and verify a Microsoft favicon with six different sizes:
+     * 128x128, 72x72, 48x48, 32x32, 24x24, 16x16
+     * Each of the six BMPs supposedly has zero colour depth.
+     */
+    private void testMicrosoftFavicon() throws Exception {
+        byte[] icoBytes = readICO("microsoft_favicon.ico");
+        fAssertEquals("Expecting Microsoft favicon to be 17174 bytes.", 17174, icoBytes.length);
+
+        ICODecoder decoder = new ICODecoder(getInstrumentation().getTargetContext(), icoBytes, 0,
+                                            icoBytes.length);
+        LoadFaviconResult result = decoder.decode();
+        fAssertNotNull("Expecting Microsoft favicon to not fail decoding.", result);
+
+        int largestBitmap = Integer.MAX_VALUE;
+
+        int[] possibleSizes = {16, 24, 32, 48, 72, 128};
+        for (int i = 0; i < possibleSizes.length; i++) {
+            if (possibleSizes[i] > decoder.getLargestFaviconSize()) {
+                largestBitmap = possibleSizes[i];
+
+                // Verify that all bitmaps but the smallest larger than Favicons.largestFaviconSize
+                // have been discarded.
+                for (int j = i + 1; j < possibleSizes.length; j++) {
+                    Bitmap selectedBitmap = result.getBestBitmap(possibleSizes[j]);
+                    fAssertNotNull("Expecting a best bitmap to be found for " +
+                                   possibleSizes[j] + "x" + possibleSizes[j], selectedBitmap);
+
+                    fAssertEquals("Expecting best bitmap to have width " + possibleSizes[i],
+                                  possibleSizes[i], selectedBitmap.getWidth());
+                    fAssertEquals("Expecting best bitmap to have height " + possibleSizes[i],
+                            possibleSizes[i], selectedBitmap.getHeight());
+
+                    // Reset the result's bitmap iterator.
+                    result = decoder.decode();
+                }
+
+                break;
+            }
+        }
+
+        int[] expectedSizes = {
+                // If we request a 33x33 we should get a 48x48.
+                33, 48,
+                // If we request a 24x24 we should get a 24x24.
+                24, 24,
+                // If we request a 8x8 we should get a 16x16.
+                8, 16,
+        };
+
+        for (int i = 0; i < expectedSizes.length - 1; i += 2) {
+            if (expectedSizes[i + 1] > largestBitmap) {
+                // This bitmap has been discarded.
+                continue;
+            }
+
+            Bitmap selectedBitmap = result.getBestBitmap(expectedSizes[i]);
+            fAssertNotNull("Expecting a best bitmap to have been found for " +
+                           expectedSizes[i] + "x" + expectedSizes[i], selectedBitmap);
+
+            fAssertEquals("Expecting best bitmap to have width " + expectedSizes[i + 1],
+                          expectedSizes[i + 1], selectedBitmap.getWidth());
+            fAssertEquals("Expecting best bitmap to have height " + expectedSizes[i + 1],
+                          expectedSizes[i + 1], selectedBitmap.getHeight());
+
+            // Reset the result's bitmap iterator.
+            result = decoder.decode();
+        }
+    }
+
+    /**
+     * Decode and verify a NVIDIA favicon with three different colour depths,
+     * and three different sizes for each colour depth. All payloads are BMP.
+     */
+    private void testNvidiaFavicon() throws Exception {
+        byte[] icoBytes = readICO("nvidia_favicon.ico");
+        fAssertEquals("Expecting NVIDIA favicon to be 25214 bytes.", 25214, icoBytes.length);
+
+        ICODecoder decoder = new ICODecoder(getInstrumentation().getTargetContext(), icoBytes, 0,
+                                            icoBytes.length);
+        fAssertNotNull("Expecting NVIDIA favicon to not fail decoding.", decoder.decode());
+
+        // Verify the best entry is correctly chosen for each width.
+        // We expect 32 bpp in all cases even if 32 bpp exceeds IconDirectoryEntry.maxBPP.
+        // This is okay because IconDirectoryEntry.maxBPP is a "desired bpp" not the absolute max.
+        // This was chosen because we think it gives better results to select a higher bpp and let
+        // Android downscale the bpp, rather than showing a bitmap of potentially significantly
+        // lower color depth.
+        IconDirectoryEntry[] expectedEntries = {
+                new IconDirectoryEntry(16, 16, 0, 32, 1128, 24086, false),
+                new IconDirectoryEntry(32, 32, 0, 32, 4264, 19822, false),
+                new IconDirectoryEntry(48, 48, 0, 32, 9640, 10182, false)
+        };
+
+        IconDirectoryEntry[] directory = decoder.getIconDirectory();
+        fAssertTrue("NVIDIA icon directory must contain at least one entry.", directory.length > 0);
+        for (int i = 0; i < directory.length; i++) {
+            if (expectedEntries[i].getWidth() > directory[directory.length - 1].getWidth()) {
+                // This test-case has been discarded due to being over-sized. Next.
+                // All subsequent cases will be too.
+                fAssertTrue("At least one test-case should not have been discarded.", i > 0);
+                break;
+            }
+
+            // Verify the actual Icon Directory entry was as expected.
+            fAssertEquals(directory[i] + " is expected to be equal to " + expectedEntries[i],
+                          0, directory[i].compareTo(expectedEntries[i]));
+        }
+    }
+
+    /**
+     * Decode and verify a Golem.de favicon with five bitmaps: 256x256, 48x48, 32x32, 24x24, 16x16
+     * Only the 256x256 is a PNG payload. All others are BMP.
+     */
+    private void testGolemFavicon() throws Exception {
+        byte[] icoBytes = readICO("golem_favicon.ico");
+        fAssertEquals("Expecting Golem favicon to be 40648 bytes.", 40648, icoBytes.length);
+
+        ICODecoder decoder = new ICODecoder(getInstrumentation().getTargetContext(), icoBytes, 0,
+                                            icoBytes.length);
+        fAssertNotNull("Expecting Golem favicon to not fail decoding.", decoder.decode());
+
+        // Verify the five entries were correctly identified.
+        IconDirectoryEntry[] expectedEntries = {
+                new IconDirectoryEntry(16, 16, 0, 32, 1128, 39250, false),
+                new IconDirectoryEntry(24, 24, 0, 32, 2488, 37032, false),
+                new IconDirectoryEntry(32, 32, 0, 32, 4392, 32640, false),
+                new IconDirectoryEntry(48, 48, 0, 32, 9832, 22808, false),
+                new IconDirectoryEntry(256, 256, 0, 32, 22722, 86, true)
+        };
+
+        IconDirectoryEntry[] directory = decoder.getIconDirectory();
+        fAssertTrue("Golem icon directory must contain at least one entry.", directory.length > 0);
+        for (int i = 0; i < directory.length; i++) {
+            if (expectedEntries[i].getWidth() > directory[directory.length - 1].getWidth()) {
+                // This test-case has been discarded due to being over-sized.
+                // All subsequent cases will be too.
+                fAssertTrue("At least one test-case should not have been discarded.", i > 0);
+                break;
+            }
+
+            // Verify the actual Icon Directory entry was as expected.
+            fAssertEquals(directory[i] + " is expected to be equal to " + expectedEntries[i],
+                          0, directory[i].compareTo(expectedEntries[i]));
+        }
+
+        // How many icon directory entries in the non-maimed favicon?
+        mGolemNumIconDirEntries = directory.length;
+    }
+
+    /**
+     * Verify that deleting the header will make decoding fail.
+     */
+    private void testMissingHeader() throws Exception {
+        byte[] icoBytes = readICO("microsoft_favicon.ico");
+        fAssertEquals("Expecting Microsoft favicon to be 17174 bytes.", 17174, icoBytes.length);
+
+        int offsetNoHeader = ICODecoder.ICO_HEADER_LENGTH_BYTES;
+        int lenNoHeader = icoBytes.length - ICODecoder.ICO_HEADER_LENGTH_BYTES;
+        ICODecoder decoder = new ICODecoder(getInstrumentation().getTargetContext(), icoBytes,
+                                            offsetNoHeader, lenNoHeader);
+        fAssertNull("Expecting Microsoft favicon to fail decoding.", decoder.decode());
+    }
+
+    /**
+     * Verify that decoding does not fail if the number of icon directory entries is smaller than
+     * the number given in the header.
+     */
+    private void testCorruptIconDirectory() throws Exception {
+        byte[] icoBytes = readICO("golem_favicon.ico");
+        fAssertEquals("Expecting Golem favicon to be 40648 bytes.", 40648, icoBytes.length);
+
+        byte[] icoMaimed = new byte[icoBytes.length - ICODecoder.ICO_ICONDIRENTRY_LENGTH_BYTES];
+        // Copy the header and first four icon directory entries into icoMaimed.
+        System.arraycopy(icoBytes, 0, icoMaimed, 0,
+                         ICODecoder.ICO_HEADER_LENGTH_BYTES + 4 * ICODecoder.ICO_ICONDIRENTRY_LENGTH_BYTES);
+        // Skip the last icon directory entry.
+        System.arraycopy(icoBytes,
+                         ICODecoder.ICO_HEADER_LENGTH_BYTES + 5 * ICODecoder.ICO_ICONDIRENTRY_LENGTH_BYTES,
+                         icoMaimed,
+                         ICODecoder.ICO_HEADER_LENGTH_BYTES + 4 * ICODecoder.ICO_ICONDIRENTRY_LENGTH_BYTES,
+                         icoBytes.length - ICODecoder.ICO_HEADER_LENGTH_BYTES - 5 * ICODecoder.ICO_ICONDIRENTRY_LENGTH_BYTES);
+
+        ICODecoder decoder = new ICODecoder(getInstrumentation().getTargetContext(), icoMaimed, 0,
+                                            icoMaimed.length);
+        fAssertNotNull("Expecting Golem favicon to not fail decoding.", decoder.decode());
+        fAssertEquals("Expecting Golem favicon icon directory to contain one less bitmap.",
+                      mGolemNumIconDirEntries - 1, decoder.getIconDirectory().length);
+    }
+
+    private byte[] readICO(String fileName) throws IOException {
+        String filePath = "ico_decoder_favicons" + File.separator + fileName;
+        InputStream icoStream = getInstrumentation().getContext().getAssets().open(filePath);
+        ByteArrayOutputStream byteStream = new ByteArrayOutputStream(icoStream.available());
+
+        int readByte;
+        while ((readByte = icoStream.read()) != -1) {
+            byteStream.write(readByte);
+        }
+
+        return byteStream.toByteArray();
+    }
+}
+