From b547c043035ac6c8a464c691bd702c4bb0cf9c10 Mon Sep 17 00:00:00 2001 From: Nick Alexander Date: Fri, 14 Nov 2014 13:14:36 -0800 Subject: [PATCH 01/29] Backed out changeset 19fdbc7ad829 (bug 1098239) --HG-- extra : rebase_source : e932299bc61e56e811e0187ddc65ab8b62b7a32b --- mobile/android/gradle/build.gradle | 2 +- .../gradle/gradle/wrapper/gradle-wrapper.jar | Bin 51017 -> 49896 bytes .../gradle/wrapper/gradle-wrapper.properties | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mobile/android/gradle/build.gradle b/mobile/android/gradle/build.gradle index 9cfdaeaa4535..577a0e7ded92 100644 --- a/mobile/android/gradle/build.gradle +++ b/mobile/android/gradle/build.gradle @@ -14,7 +14,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:0.14.1' + classpath 'com.android.tools.build:gradle:0.12.2' } } diff --git a/mobile/android/gradle/gradle/wrapper/gradle-wrapper.jar b/mobile/android/gradle/gradle/wrapper/gradle-wrapper.jar index 3d0dee6e8edfecc92e04653ec780de06f7b34f8b..8c0fb64a8698b08ecc4158d828ca593c4928e9dd 100644 GIT binary patch delta 42496 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%0A$#o6WfPc2U@ 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
    G$9-3O@w*JGCZ~kHa^laDM&(RI3)d{c z5_N=|r|vp(HsLyCB+?176Ir+l7z#+!!|%AhWC8%)`kL-H}dgxlHP_xZIB)^&z7B=zAKVTm9zvpf}SO#qbytLP2N3_^tRD7J#X7sg*|s_ylnP&Qej%@#0I# zYr*W-T7zgx95wG__ERTM67!rH_W%Rn6?sD5`Q)5mGDW$(fS;uW911eXcF`q{!n%co zzMB*7yEGSFU5t3PvVKRHICRgY$FnXj-5OgDeR0pI>L5-Jk<-nh+RN8cjw((WV|~>2 zy;11_7Y=#;P4PYU-*-)9)>_i6EmM`tCpo?_8T1vlBoNXp9SIvs6Z2Vz#NVPmodxiq zThn|EJ{gJ_737&F2{dpg*229<2Pko-Z3X7>&{fI<@L(BZF;}jN3}Op)XBLcyGMVQ6F~W+8JHU3<8E%a`^Q zojj!(ZsJ+8sg2JvHp*qT1&84np#`HcXOgL2G{K1ei=8jN!p#cEp01{#&-1?p-S z)O@XWJBT!zqd>S`U3p<`!S5dy((|~Y!k(r1Zi+>u;I-q9Efg20$i3?+@{(=9tE|8$ zD)y?-gV(UtBV{4Ht3NL2iUyC^pp(j>K857BmZ;pWO#FPB{N$I;7*A#79*| zA#`XR=ckJ#YsFUPv}x3isb-v!+UU#V)Zt-3W>J>+$_J7=Fm9%|s8^?#nG3|hw9j2w zx%9b)m2%TceMBRVnga~%VMUXW1!>w_rcq>qcD}k%WcKczt~P(GOn2>dRZMQ`O!5-9 zr^Y=+Gv_N$a_x7k{k2YVK3}pp#MoVRi8eIf9KWK2>PEeWuQsxm;^|T(RB*Vt1~lq1 z)?xE3a|DuJ*2#>rd~oN(l@a#t>Mm9yUK>E1lmGFXX{Vu#W1_FF{mjn- zJp}_wm<(_)N!Sm+9gQob73oXQ99~9Pr1}{(RV zHEd$*?X52_-*_JSKp$SU-xGH**l7D|vA6%8yR>G!d`(khjSBOq0*YvKO~;|hpocxT zp^PD^y$X$NhUZ7J`Y`SNw;AvXfseE7JQBjW`&nBkm>-&yvEb3TNV7Kd(K287^%0z7ZGLlv<`=LdfM;!ju zJ-z3ZMoy%2CmMj4lFTIBDfj$;{YJ zw4Y|QP5c#X05a7M4msb6w(agQ!AHxD?)}^jvBbbRBrF`%zMil?$@eFRn6)y&hJHrQN})vkMLpr`zfO zIh^isA{>;}hSvsu=c9y&steA(fqA6AjE(*_32?{m`4O;p%cQ^3Up+3Q<)~%y&v9hPgzt=I8rJ`v>{4vZk z4U+XI)1}vPzJC3Z=2Gmwb#(vx=N+QIX9ay+9~zoq?U}ViK~4rS9Y+xrqGW$P0v;EW z1rH5-iK(%4Je8hHhBEMIS~1y-Gb+V!f`J>ZdeI`!!XRYO(8I#_9K#}sYD@G}+kqj4 zD?ybJ1C7_HGt0yC-riD2k0zh0o?N?@cQ(AVutJpTxD6Z!Q6-JtwYR&8CU&d*^1j9Zu<4G5_msr$v zApjTs`imD7#Hq``Lk0AOhJKB&aa0d%mZfXtu!MBIIzmD##^AGd$}H7&JlpSo zM6-E>EV7=neb(G9+EXh@JJ%n*Xgla3HToWbV<_ER$aeoZNqBeO?&?EUw(SejlBfw1 z^%8eWxL)V}09XCz!qWMwRK?`U|a`#g~gpwCfmu<^KxJH>9sS0lx%v_3}Ce_M@M<*ZW8US%49 z$rc9Gt4XhOSWqgD&=}5dus6x-<{BB` z05`kHv)&~3jh}Lp#`o1%W-P(aq*aV(%pl2ZOypYlwRUOz-Rrkc8&!HZIlyBCAj`*| z3}it^Rv{)(Oq$=FZ|#A870CnbHNe4*{Tyl? zo$9RQ(2^SGrTzQnVq*Q1Lle5J@kC74@xe*G_bra zdMFUhpK@_GL!ztcb}D{#^tlpQjYws2sX&?oq7iXw3w%SU`Rb%GfFP2@5w0AQ8HL%%e@6O===SjVrjtUj8-dD2xTT8r#7B(5; zBk8Tgy+kH+Hq#2}?_^oEhOtM|%o|!N^;=T;q7!mIV;WB!Wh6Hi0}bA_jx+H1ax##F z=IPCs=~vsrWt`Ix9qxs{BxaxxYYm_B#19ppVwfv4-=>&vv3B(N%Dxe^q+4$Vs?Hkz z4*L_4M@uVOq3pFmi`uZOesNo=`!yZ9-%J_OuHf&9Ph4a#A~w*!!>4ayC~LGMI0%s2 zfS6XIoD6xJQvtF8&_DpjiUN~o-Akd}EpN_e>Gf6?MEUIpW^t$%y-XVE;iRNTT}r6U zc$vN7fhKLAox-R*sfqfxT2UHL;RjPt-p`qYd&qzILEd4SdKKk5>tU4|8~uFPw`dY52oTtJDr(rRjhJ`#4j8?x5daQpl~$ zGuDORnG~o^(^kv2<9TEG#~rWWS5x+SllaOJ+cBLbpNnd<9;24)3Ah~xxr=0Xj)oa1lwK^T)m8Aq;rg~j*0?WCP$Fh)dsdfXp z`#kg7-8q8!-1_W~JB;hjKIP0lX6lPvlqsPo_@Ml@sUeJ<50@8LUa=N@;8``}h<;!Q z8@|dx_XF3cuSd?plxeh)B!z*5ztJG#8te>SXu@{bbe6vFVQ6G6|<^(zIf|er%!tTvebR#=L zk(IFRInwii@fgqtl%a5BzKI+1ro`%)G{T)?T(?4kzkgKCEBA^IpG$k7EGif5 zK$1+sFjx|c&Wy*FTzQAkvF#dosymcd6}O>PGPxMsqwBNVYFE0mqp<;>P-A?Y9jUl_ zEfJGxT=+u3hVLb^9$OoVJTlKDi{%;;b3mp*%!9WCsQe zRJ}kgAP(=PfikMM=Rtv0p7fkSvGCE+ihs=Q_7Np@o37tkaAp7K5<{|GkT+qZm18lR zqd8Wf-fAZ^?42(A1(F9c(0$HX_e>^k`3`!Wgc-r^-l85fGW0Q91xB|DhK@^|1A*zI zlGs9~xz&yZ<4>}!Sp)VAjxRFU30-{)#76;yj$|07Kf)L!U&YAI9;AO9J+`+H()hv< zz+yEtD!-U1ts)fhl#5q1@5a)sbb#0G(akZR)FslGBwX-t%t{|@nF8hIM^m{uhc1@E1NFD`OF{6ilJ*Upw?aIf}y{=WD^WNtd zI%TLd)@V5QBsSheV7OeZI9sTrVpom-q9GTPL|3Z65X^wIhm%Th_%9f8B%mDobjI6h z3CfZ2tjTCY8q1+_Puhgh^7z7zk5snhj9MD_Zwhh=oodN-cxKuL*=P3c?yEy+jaffN zUa@j`B;1zujQ7Bw8;~%+Kh-oI2KD7k);ash^J;dmp$LCB3T^DO)!?AhDtK+tsQo?; zFd0?MD8tD{fP$hI&3{YCj}8o5yRg7ujg?pSqyZ?mBy*VeD!olFt3sCJtY2vJ#bZ?N z@tV)j2d#|6w^eLX6HTc$7`7QsZXb9O@!tGMjwV$xBqH|}SgNHjQIJq1FrVpYx5ptk ziGv30Tb`|E^+xLTuX+(|Dn_vd0Rr^Da)cB4ejZ{1F;%C=aArVflLL|cGC@Bi%l&1s z={RU#>-PZ2xm*RzgG|0m#9J=36u-3{Ocb-EO$t_Q`a+gbu<)+!bt8Ul3HM2M%W)B~z*p zW@8m4(#rKoiH9N$#0R{Y=BLg@|H?=wsj?d+r|L48VUJt#vG{N1b!H#g3kBG>4xJz&UHp%Ed?}GBw zva%*hs7Nm!AjEz3Ue23f!Pej-*B?dyUx3VdPTv0wkf~Km1t<5| z+4HL9LVNrGQ^?CG3Xa3132Le3QG0v>{sINA;~^Kgp8wB<33Vr)4*vXjo|>v6Gz=~* z_>eUuB&ferp#GBp>M=zJNUVYs->b%b#B0i@6%H7PvM zcpWL_BVDY)MGQVz14poQssGYJLDdI9!9ajwFdU$f761gieW2@71_mvH|EQmUJ>bA# zd{8qSI>@f+4;Zf0YsnDItOjOgeF8RxhcK&tLJ-q(F?W`GYj3Xf_O0zZ$LD5tCN3_2 z=a_WOXt5u>O#BvX1gP^?DYFdS=xDEw8~6F~J9hJe5d+4gp@H5`&Bz{-~$s zOJ=VAo8x4)+0{Pp`fxT z!5#T06b58qASp<<5gP*h_bB?m6^mf`Bdd`P0(^3o^ApBY4hZnJkqQF*`{ccUu=N2{ zFCakGPtPF0e-BXkyT~GCz(5+7zpV`kl@IR6X@gr5{(oq}_xgZMB?$9f0~%;pfe=LY zpK^W@n*B+FqnD5bV&F*a7ERa?V?tuf`Zqlq(?T1R+QdQmIPmdz1lfOB>I1H|LAywj7_l2E3iYoc*2%#08XR;5eW%n2nGd#UGy=?+CNu)K&~-} zqmvEP(n1OWLSo2)EvpCybNqt>-|GXSOh5sJq#*Ry1fZ5S00jJZ=(d0G^#Rmo5Pi!` zNI{hCf54DnFJRV1u%3MXAR)|BwqO+)L9y1DAk~gP;3si2o`5aD0Xe~zkZWUtsPI1_ z1)%7j01KTU`c}0OLV%FXtKf_k|38=Ua)*e=X#Z0>|J_iD3H2AFyC+Dgog2ayDb8c( z17<@7vk5*CyXgYKZR@`0iCwvfD5oW5TZ77#~)|2U z&PUga%?Ib28bsFh$BzGw|NZSrNktGl`gKu5(M76B?NgJ y1#$E|mXLPsf9y&8|9)bRZK*7n>#-%Ic*1$m0Q%U&h|UhKoqNIl;@J53-~R(ULG9N7 diff --git a/mobile/android/gradle/gradle/wrapper/gradle-wrapper.properties b/mobile/android/gradle/gradle/wrapper/gradle-wrapper.properties index fccfe002227a..1e61d1fd3a9b 100644 --- a/mobile/android/gradle/gradle/wrapper/gradle-wrapper.properties +++ b/mobile/android/gradle/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Nov 13 14:57:51 PST 2014 +#Wed Apr 10 15:27:10 PDT 2013 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.1-bin.zip +distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip From 5a28817554662e73fc2a1f718bbb731023ca481e Mon Sep 17 00:00:00 2001 From: Nick Alexander Date: Fri, 14 Nov 2014 13:15:17 -0800 Subject: [PATCH 02/29] Bug 1096627 - Fail Fennec build if GeckoView library depends on more of Fennec. r=gps Notes: * The Classycle definition file was built by hand via a process of trial and error. * The Classycle JAR file is used only at build time. I don't want to land it near code because it shouldn't be included in any build. In particular, landing in mobile/android/base can foul up IDE configurations. * The Classycle license requires redistributing the README.txt with the binary assets. * Even when Proguard is "disabled", the target still runs, so this is a good place to put a build step that the built JARs, as a collective, are healthy. --HG-- extra : rebase_source : 7df8aa0fd0537ec7cb32eb02259797523f5ba97d --- mobile/android/base/Makefile.in | 15 +++- mobile/android/base/geckoview.ddf | 73 ++++++++++++++++++ mobile/android/build/classycle/LICENSE.txt | 22 ++++++ .../build/classycle/classycle-1.4.1.jar | Bin 0 -> 124106 bytes 4 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 mobile/android/base/geckoview.ddf create mode 100644 mobile/android/build/classycle/LICENSE.txt create mode 100644 mobile/android/build/classycle/classycle-1.4.1.jar diff --git a/mobile/android/base/Makefile.in b/mobile/android/base/Makefile.in index 9a354904fe38..5d980c429f4e 100644 --- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -134,11 +134,24 @@ else endif endif +# This stanza ensures that the set of GeckoView classes does not depend on too +# much of Fennec, where "too much" is defined as the set of potentially +# non-GeckoView classes that GeckoView already depended on at a certain point in +# time. The idea is to set a high-water mark that is not to be crossed. +classycle_jar := $(topsrcdir)/mobile/android/build/classycle/classycle-1.4.1.jar +.geckoview.deps: geckoview.ddf $(classycle_jar) $(ALL_JARS) + java -cp $(classycle_jar) \ + classycle.dependency.DependencyChecker \ + -mergeInnerClasses \ + -dependencies=@$< \ + $(ALL_JARS) + @$(TOUCH) $@ + # We touch the target file before invoking Proguard so that Proguard's # outputs are fresher than the target, preventing a subsequent # invocation from thinking Proguard's outputs are stale. This is safe # because Make removes the target file if any recipe command fails. -.proguard.deps: $(ALL_JARS) +.proguard.deps: .geckoview.deps $(ALL_JARS) $(REPORT_BUILD) @$(TOUCH) $@ java \ diff --git a/mobile/android/base/geckoview.ddf b/mobile/android/base/geckoview.ddf new file mode 100644 index 000000000000..1c3bb98a5989 --- /dev/null +++ b/mobile/android/base/geckoview.ddf @@ -0,0 +1,73 @@ +# This is a Classycle dependency definition file that asserts that the contents +# of the GeckoView library (Classycle set [lib]) is a dependency (but does not +# depend) on Fennec (Classycle set [main]). The additional Classycle set +# [middle] consists of classes referenced by GeckoView that probably should not +# be referenced. We want this middle set to shrink over time. + +show allResults + +[lib] = \ + org.mozilla.gecko.gfx.* \ + org.mozilla.gecko.mozglue.* \ + org.mozilla.gecko.sqlite.* \ + org.mozilla.gecko.util.* \ + org.mozilla.gecko.AndroidGamepadManager \ + org.mozilla.gecko.AppConstants \ + org.mozilla.gecko.BaseGeckoInterface \ + org.mozilla.gecko.ContextGetter \ + org.mozilla.gecko.CrashHandler \ + org.mozilla.gecko.EventDispatcher \ + org.mozilla.gecko.GeckoAccessibility \ + org.mozilla.gecko.GeckoAppShell \ + org.mozilla.gecko.GeckoBatteryManager \ + org.mozilla.gecko.GeckoEditable \ + org.mozilla.gecko.GeckoEditableClient \ + org.mozilla.gecko.GeckoEditableListener \ + org.mozilla.gecko.GeckoEvent \ + org.mozilla.gecko.GeckoInputConnection \ + org.mozilla.gecko.GeckoJavaSampler \ + org.mozilla.gecko.GeckoNetworkManager \ + org.mozilla.gecko.GeckoProfile \ + org.mozilla.gecko.GeckoScreenOrientation \ + org.mozilla.gecko.GeckoSharedPrefs \ + org.mozilla.gecko.GeckoThread \ + org.mozilla.gecko.GeckoView \ + org.mozilla.gecko.GlobalHistory \ + org.mozilla.gecko.InputMethods \ + org.mozilla.gecko.NSSBridge \ + org.mozilla.gecko.NotificationClient \ + org.mozilla.gecko.NotificationHandler \ + org.mozilla.gecko.PrefsHelper \ + org.mozilla.gecko.SmsManager \ + org.mozilla.gecko.SurfaceBits \ + org.mozilla.gecko.TouchEventInterceptor \ + org.mozilla.gecko.ZoomConstraints + +[middle] = \ + org.mozilla.gecko.prompts.* \ + org.mozilla.gecko.AlertNotification \ + org.mozilla.gecko.FormAssistPopup \ + org.mozilla.gecko.GeckoActivity \ + org.mozilla.gecko.GeckoApp \ + org.mozilla.gecko.GeckoProfileDirectories \ + org.mozilla.gecko.GuestSession \ + org.mozilla.gecko.R \ + org.mozilla.gecko.Tab \ + org.mozilla.gecko.Tabs \ + org.mozilla.gecko.Telemetry \ + org.mozilla.gecko.TelemetryContract \ + org.mozilla.gecko.ThumbnailHelper \ + org.mozilla.gecko.db.BrowserDB \ + org.mozilla.gecko.db.LocalBrowserDB \ + org.mozilla.gecko.distribution.Distribution \ + org.mozilla.gecko.favicons.Favicons \ + org.mozilla.gecko.favicons.OnFaviconLoadedListener + +[main] = org.mozilla.gecko.* excluding [lib] [middle] + +check sets [lib] [middle] [main] + +check [lib] directlyIndependentOf [main] + +# This fails; if this passed, GeckoView would be ready to extract from Fennec. +# check [lib] independentOf [middle] diff --git a/mobile/android/build/classycle/LICENSE.txt b/mobile/android/build/classycle/LICENSE.txt new file mode 100644 index 000000000000..c50c58104483 --- /dev/null +++ b/mobile/android/build/classycle/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2003-2008, Franz-Josef Elmer, All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +- Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/mobile/android/build/classycle/classycle-1.4.1.jar b/mobile/android/build/classycle/classycle-1.4.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..bc8f2ddaac38df5e5eb22e2033546e04aa0d656f GIT binary patch literal 124106 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%0D3nE33 zH}>ZG+fOub=EvpN?namckLkLk20^OvjKs|**DY?^)dQAbJ1&4Wd-P8P?f~w0c>JM3 zqAs?J_r&BJn@_dmOQR&^)!~F^zGT!e0zu)N$mRp_r5IA%9$e{>sS^9h_UqsXFE85% z&Y^az|G-64!@zDjm^av;dMMy@f+=kz)9_y@vAqm$wf=hYVPZn$J^qc6aov(GL^3g5 zEb@GKS55h!{6Q~a?%Qck5pObRr#?}_YK1;9*xJVafrl`X`4OV`6z*_bfG_`|H~2SK zCV9kOUtbzxXJ-SLopVd+Xqp54zx&cUyyz@Dq1kF_9LYN(T5*Q6HX?M;zYTjf01Wm|K*m+2$fW{|V6j}KN z6WqBW6tNku37dE8uZ__|szZde5P&hBtCz7AmC7$$z-$C(I7#{qzm{x7;9Hhx+jbaf zSa$t)yq3kyXvz^1)t5-VCQTZtn6syP zx3&S@N{A|8nP$Lh7M<=q--vX4ko8K;9cc(V1~%e|E*6#&7mhK{4Gvh54I4+n=yAy}U@WZmK36aqdDPpj#)3#1mrfW(qCB1ulLr}`Gu*$cZFfZo71h=t zFP%n$9;0iX)k2q!lgW?+Z~|5IN}e>4)`_baBt3_e(E+i6=Z+sTK5I8MUy^{ry@O)7 zGV(Betox&?G)+hPSVStOQo=1=aSj~Ijb2npLhp+@aa4e?IPT(p7K-HR;(PCmTt(fV z>^IAn^+DtsBhf4}If+Is4S&~ZWdhx^>K#Qjnf-=(VLo4_uI@Ird;W=2<%kixWx@ao z>Z>K+d*mc|!2DdGF?J0>egT3UHoagPCpPXLMS?~v(;As}p-kl#-j>e7Tv!VTDzBLW zj`nfW{4Krp$;pq6QjX}aoHJLj5J%5oN=)ms)}R?DPd{3x&0!^MoxSkrnp+r;sRY9b zt_w%AAD&b?2KLTAC&{4@-ORumqwBcj&Gg%HC4%Z_r1U^DeU0VIC6b$S$CJpSDNzF8 zlEb^$^mFqtfOiJ3iqcH;aZr(R<&x;mBUHy~=0a`KT7ndeT3KS6V*SvWN3LoZYPW}s zAm;-2Y2A1|QnZ=jBu&{NCcCu-%p;np70<%J_6h7h%fH~Y-P zYx@Iaj;CsfxEp6%bt0PL6ur&SQjumvd<5a>qr2tq>Uh>49x%2QL4yVOPpO2Pu^%I5 zqK_W3tSBsj%tJ~8W|mvD#>&PUOco&XM~*J2CU+o>L`Rrr`$LtlX16czV+V-i<`W{o zIkUtE83I>abtY%rqPgOCvIv$PktiE|Yq2iGY&tGgZqOcD9kLpwy8s-T~UcGD+#K9mSvV zIgM#SGbw?Q$hI((QI^uM1syVMJEM5X3i*JYV|dZwesTxikupzZk7EalNz|&%6GU8# za8#hB5|@DJMWca#6DTlD&vy*gcSdTpj@wr2p|gsvu#vZmg=vJBdJXnO3qHh`;(gnR zy9=pBAhAs*N$$C3*W1M~w8byJEsDn<&m^R5gn58ej8>rR+hDy$4BM-GYk9v^ohpsP zPS4A-vG}3%=p6zpPbC}4s&!V?F8>|8Gwp{AP~<89`<`aIh6`Mv!u#JNpO0>!g}i_C znoK{`SDODt*Rr=UFmiCPvHy?D;6HtfJ1+Ux#)Slt|5B`5`%!4qmEpsO2`j|<;sfB? zss-1pI%hO!D0qk0bieEekO0addHeE?vze$t$_2jFIv5)tKY2Bn_w+{2SnonXchjsJO+33?G90p&@?U|r zJz0C7vK8aSYC5cHAi>Y9xn8tN(-HHf?KeM8kEc+#4DQX_Ndz@mOf4^goGOWe!oGfk zYZ3LR!=fgUi=oy}0Inn11OTf?L`&Q+WjV#yR6a6zaD-=DC8bcGl5yIb_azV1PJ)uu zjXiUZy>Q477@H~dIdG{geM9B&mCJ|V#lFLJ0!lIX6VuJZyZb#+PvqPaQD?2IawTY? zh&D`kbDAg-Y-TAEc3{qOE&01Q_9`AdcuUNeTOOJK+KkktxY3lO)E`UrBN6pu`F%m1 zowQE;rE*g;TTl>@TJ!>4I|!Eps!D|))#=?Dqd=uPO;9wm0=?Sn_CrMnoo_YFMPqg3 zqPzJ~x1n(4&5RuWy_B>5sXAUrwl-@4RDzd<@5$}3BF7_x{DT;E>j#&B87X798f|2^#6(hEf`Kh@JCAEV)vxiPNld*$XNzOD{fcIbcMIsb%AW)s4|!^+G0P5p zO14d;ZHewvD6+LBw_0Td)Kb*S}ZxLh;-YD{wB`P_k$O!V_Zo(_z@gS(yzy1?& z9o<1ub~1}*RKbp8$IBXs6~?*eq|}f1>c;M-r+LxFqRHicCSfMc5BilU6Akq-lH3lb z>^0X&ZPECKhUiQ5p^dQEW-t*P$+kIqwHeYQKvazA-=1CA=u!cu5786(yir%V6Yt3> z!n7U*O})Gw_dPoHaK9%1@bKaJM`ER99}+uZ=HBa$unSYZ3ZzXmdIXYP{@VHge0l?p zLlWdIAE!i4Xar;o%p9t%G+)*SRsjfN6h}cU;b*INUgi2z8RZno!{`#(3LHt%8<{^N z*C{1`m-tiMamEhdT#@v|?p#DkX@0hm7RWUQ`OJfy<7ArmNN@Hfvji`}gT`NA!{kUd z#?6pBajr3ff4tt{#W6)P_qhOQV>^WawfeE&h@tO<#Tg;o{RJiWL7hZzt>V}v_lo10 z{4^RPW@Y&RFVLW)=zKd;t;IHrwb!zg5${V*V)m6<=3>H(wc@0iBLvDFBgC&rP*A#v zm$E+pMQHyIxPiS9jP&_~<$po^_jrK+Czk(LFQX!5D}^6rv$yp&3vI-FXm~!nWl|@e zT!a@w`4Ew+geX}Y*?PKl{BKoFmb9tj0^XueAn#K!j)h*yv|F$T0Ux=Nr_Bs>(|TfO zj)6^&r|kR8`%H(Nt($k9o-P1es3g4MSlC@?27NWu37|Sp;^Yv>Zdm@la9p*z8j4X6 z1pe(9X5MauqjrCPTW&~wu~Dxvy)YZea(&z7Jhm}N~{^p z#_K{;rgo6xCd&+MjwC7WspN^t_rKei1abxOleKnP1`M0^O{b13!ut}aHCWrrmYFt= zlH2h7E!xX47}&^sS#}OdxL?F!rnapaB)K`04JPI>H^zuNx+_$|H|t*|#`kEJbm(eJ zfYleJwz?-~L$ftqLtSzo@v-!UKxN9ci{dh;&q!vPoF_Kj3zJ~z3oX0yF@&b(ha8?~ z4Q$RAHz(^lm9}?{lQNQ2#vErfkEfFL6cWA)^4?;EQQ27NZCrE-K{P5lRhKa96FXO= z+RZ@}3>A#J(n{>w3g|IY+lMau<-+SsCr{S}kefCuF!FNoTh2&()kCHnnOGhG1+Y=C z*Bj2WJPp!`!u95eOk64mS7 zrNC&{xiQZVoOWWAEom4(!gkfhg@z+`o1kBo5Kv5jjzg>LNLYM}#?xNQY6U}xoN)FQ zCH%!J5^m@Gjh&dx_G|_d7h8OQd}HG>azn&XT2Y<sQRPKsMtSy1U zOa6n!5P9ok@&^zs8vBWZ4DeA$7jd54y7>$$Sl zkPrMsskvu>4>kHuT>5x$uqOo14@|}oaEOvhyf;qY_H^)=SQi#gbKDZ4ReWJqq=G&# zPg~y`Z5al%FmPFXNTqo3DCF{msY_jm;6l{A){F<65wupyqPXjL#khWMPcfz-CP3TI zunEZIz|iXn9EE?i>-fhhGF@PvOY+k+Uw%#!f&cmX_n#JwM9M$C)5ulH`iJ)ZV>4~| zZ~XUvZ=^-?QZ|Tk$lNwO=(?p)c%0P`KhMJLmCAKZC=_u2`$Z5(uE*-N-~yJ~zxl`{z9h!KBc z{=^UQbk6G2ooz+yrdo;gI?6S+A zj~|d+By;Owk#cHs>h@-vItIdFs|*gJCZwEEk=_=!!POVKd{kajkXo?@;hIXQ4Bm)9L@jYKKTy&j8r_o0Ae(@2 z7FR{B9}u;yy(q4Na22(hA^A%P3$qIxOJ_jwB*Zv^iIo2PU&MF+D8ns<3*(5NMh1rR zzd|AZS%&|tI2AKT#X}75ZZ&%oYin>|FmyclWoZ&W)7mmAI*>FV*XR(iY-fv=k-II?}yCn19qJ7+2bxoLxa)5 z1NO0&?)Uf39gpLsdr}#o(ji`_#XVd2>mdY;tE9aJ22bJOcSqQqq@`oSm(F0?lUchS z%kI)W2@dfaqcu;V0U%7AMS3VWGq!RA7Fe(wCF~z-=U?5$dkEO~wyo%lw@%m*H!v98 zYLN!6iUS6iIA}sLqhGDTfzd;*@`hYRdm0?s!!1sgy^NUINw1uk(!e*F(PY^xw_2Te z6@M^-nV=)aug8vrFr>$y++YYXwdZZc_rkT3FIB-@iV;s06*y32*fhz|r^*tISc#`3 zhsViYGFWtW91Hl>CV1|B)e@K#w3w};vqYVk$r58}4^qiZQqnFOkRP}=*Q7HJV;yd( zsp;e9aV6B5y`%}!4mQj=qK!&013MYx7!uU(c29)$xCc=GU?b31#Ng;}%PA1Pl2pp)_^UH(ZRr8ZW9g zi*_xy#70E`E7Wy*8Z+g-&JsLETu}&HnxYZ~n zPQ)$0Q5#mGe1l;i)179+AK4pQ>Fvw>AEnz#5hlvbN;4_o>DGBmnS6Cn!7yZ$Bs!Q)yWav5wQTn76BO3LM6tG5K>{viJMXBUF^n0UWo}X zuCFGApVI>wNtU^Xv;}|R(x&+JTe1Q}QkI0n8?ll2k;_XQKx~AwSC=m<#>2~Xs2!+f zZ;oY#r4pChw^pT{Os$s%%&+e9jEih_-&O`MSOPuti)HEpc zb6&@9oNxZdbn@pWh)>b5k$7ICw=m%E%t|SNSAk0KL-pM0Z8BxL0l=sh2=JRSWw8aa zX0m1EfM(JQ@H+=Ni6C*CGncs$D9oa-g*`{9&bkVy<rX>|UF6MA8QJ z_D_NNK;~teaQs6j!MluN+WX1w|R zp?u=Q+7~X-XSVC~k)4!?8xUw#xet*)w{h;(R?8$^Xgwr8>_7rkEw6U!SL<1yD`LEkF=`&QGhJ5ZvQ1NJc z*No&HK8%n$iN~BQIjssoLmll}nkY#X+X7nK<^gS^LkAVZzjcBL0Kx&SIyDE<|8P~ep9Y3gcp0}y#SQmoxx+>4&d2^d-&bhzg z8ISKUQYw+rJ3_TFaChavy>h~i4ConJNdgnC z2XIVWt9g)*jF$V_VOCqJ!(x8KkWOoinupcG0D-ePtN@hVf-qYvl67cfFH~l{%rukH znE_FnMVPupA4%Dq81&=63xC9vJT+By=DE$`GdiQS`#`Tm?J%mNp)(jHf~r3H46lve z#{~(#0#<$&u(x~4v8ADcMFD#{GK&No9By$QWh=Mpig3^E3eMT-M67234t4g!E#zm6 z&Lg)B6c4Vg?M{@J7$~CIlB*<|8G8J%<$IanHa#wXfJQZ91tN~zlmHsSx~{?L+mEgl z#t>f20*?x}?e!23O>wmal?bV`1fPgGV6oA{LxyjqL)#Fp%_pS70TJ+1mlhIGRpW_# zUIZHvbU&o1e3izZ-i)+M1>quVuk1e*Gl_SO2-=N5~c^Vn>?Yr^Pnbz}V@70rUcQ)#qb}j%Hf} zdBD>I5we8(P|C7-?Qal@84W+Pys61N`8*&PvS}EkNC(de zAyIQ}vCqb9JuMFhZd?)R?W6+j@C?&4l@ga5Ik!A>+1nicuDYtO@3=Sf zCK9XQo@4L7MD2_ROZBx`RYz~v2lu{$JqV~CDU|p0dNM`dXn6L?EYGv(ktVk0#0ML! zn(^2=0++3++%Hdmibd@rCva;nQ?tTU*CxeW*myD>E^wYCG;L26Yte34qDzj?yoOQL zXtP0E4z?`wZsh>mD(|n2XBxM(@3yo*HTRuU(dVh2hQsTRGgRV1cS#a~3)e*rBJ>~^ zA83b@Kke}LFW#6N{HENwTAm&pCkO`V?Pbu>p8lz=?gS!^hvq7WT%?Ej6Fnh0g!RH;~qMH+J}U6Ro1Lovow!ALBXy z1u-XlLd<{2kk76Pw#f?!DA?p0(2KWFDF%W>POEo8bcetjsRL^B&)C|u;-6DIr-X&3 z`X0}MnKDy!B+aF;bWJ8We@tAik-a=@PHuiNsm2jQuf-zUfgoIk#Esr#OyP%9x=BtP zi~umYPg*3;GE{9d3OOw93>u8mU6tA`xTVkp5x<8XQe|q4#1c+UwV0#PUZ~)7S9@Ha z##JRYtBhHDM46-B;zNsuw%N>6KyHpV{o2nY$D#g}o+Kf~w4T@@+oCcfYK1NCs2Unc zo051;%N(e5Yz-K4{PBIrTUx4IE$V@SaFaT=ph*wAy?z{5>BNt52RD_jS6OGrO95@6 zvpT{;Hu5ltBL-4>)q{Mb(bA()si6K%Wc%qgGQbgC?dNssghRh!vXqXyVkvkFu7I=M?w(04}{3u-#R_^Hgb*o%gAz)(++plKFnH*Zv*b3H5Ga5^9 zqQ^y3B0doaks)ND79!?6`40=ni->t?0O>^UxCI0<$mV#?ucNPmN4=0ed|nOo)+6$}zwn4Py`oKeitV8=0_a&4rM-sd5O-L65CFhE zbo=p`;3R}x_E5AD4g@lpB3n+r80GL>l)~splUR4*u&3e9DLYEw8Ci-TVWmd$*}g zgJld8%@Y+cEMp6VfLbV}s1R&e!myG@sP2ig>Jb#588?vedD{8$eFc0lc;d6EO~n+- zX=LuY&A`zd-x8aQ+7d(fVKPFs%Il6v$KCLo;v3A=M0*-U$2;p5` zOBknJz8f{+@3qEfA@Rb2vB0=7SOUkt7&=fYX(`k13syM78fX`Ps)jbFhoNUu92+rN z14l;2BJ+YEEYg=0(iIZm#~wa5?xlhZ3=ZBcN!O+Nsl=J*yu#*K;niq-P{;1H%2w_f z%>O1H%1p^cmn2V2003!>R2Qw0XFB&+K{M0XCb33|^jsM#8maICtXmt6wVS5}c{(g- z%DSo&iC13P*EYhNuClw87$UIL!ANbXpYKcLv1HW6t1wqyYsX}M12rMS-si1vC~w62 zCiZG7kVpWWN4eZ5vv07&< zjA*AN)G+9cnkPTkav%C_88!9-%wZ$~Bx}nZ(1l6_;-(c)*i7>Zt)YX~NF-uh^o#6%AG#0vH z$I+sK{G2r1Gr@jUJ-K{J-ki-@Ek_Stt=|L!*l80+d+wLt^E%GVzNK55j6KQ4@p}cC zQyXhDk}^M35`GVN+7Sa0;e*?*#<$(J=8M`%#@ENW-sRXpi&d20?FHF`5KCq|G? zON^~`+|PWCD_KvA?e;tvG;co*1_hd{#!JSs;w!X|ZkY!JgmA(@O8v^Z-T2YbSe8S**K#%q)AJkl?F_!@$tTL&d>`DR%jJiSzghAa`YW)MESVf z#E-k&HBAE5(JdL{-ZGMzhNwnkOL}xPmxXHNXOz)OuROzYjbrdd(eJQ@CHP{GDl=dF zM2jJYM)t{N_!G-#>q0UzozL#d4ep`NiOmeK_m8-mxAgI&CWM63Ot-@_lY_Xh6isr3 zu}yMBg-&R=<;-^lnOB8gkG^Ui6`?wFgyM1p@w~=BdGeS<9E6o{m6?IuV|=s z%YB0NbDCLFzNB;oeG9vs!Wdh51!$F``N{2Io3Cm>(Bc-SaZ-O!NMwxWT_ETg0v&t4 z{_e)j5)RE2?Ze}!FztE?8F1p_`%TWwx9(~O$0aY|i#7pHhWJ%jyUY_^tKOCniXH0a z4i=umyI&*Uw4i_T-UtXE^W+wfphLp@gkss0i@A+Ify#lWoAete_(Y2Fl4 zX8782&;#d>FPT2uvsZp@elc!Qj`Y=$>&J(8M{$d;sE-~%mjzy;Pq@Die=aeT(t^%= z4Itn3h1lDQ+YkC@Hg+a+<+lc8ey@oaGG@t_^qPuSok@@503^gbfAiFI6z5V1niSf~ zk?&eQ+@Q25AWmW6lt>i%xe2*sCQL%^XuWY z?T({DxdZ<&$p-UxT;kg5T$0~6Y<4$wgL~m{z*w1L3x1o~$q66+sPmm7;Pl)=b%*1C z#E_=$J(;LAkOBK?oE==o){ z8(OAbls;m^ZJQZ$mmNB%k4U0!`HAPy^YF#wU@@y|^Gm`tK@{a$x**IlhYg|WmJ1Hz zngl_#|3)1Q3hWxIyg^9EkzGOHC1XBy)M(o}@*t{P zg*Q{ZykW>$BeuVOArX(lIqrPWNBW|UW=dH-?!`hg{cq1|3#twjTZ3Ql-&@JTh`e_S&!D$#+?@V!b;UpJro7@H!4ntq)-l&HhBvgwh zTnqEsJSRRlH=zH65@`T^J+ll0Bb59B)m4{gJ43*PasC25nD8gPGTakmlgY`>HZ3J|t7jWG8$kFgEG6!NO1$CYXNc zxn%wOvFq9A96O5fu}8^>m>zd8P_%*FVo{kK7tsj3kPZ2vJJKf>B@hl~c=3Lg~O~ZMU{ZWa@sUz_J4Tkam%g=Med0E~295 zJJ4x_#-vTqM5pG{5JgL5_Y6_v+BN}ww%Gn&f_jl$NSYn0w-t38GooP2K9jyN1IW?2 z&Fp!KC0nBg)>a5$%l$4YgjrEp{dRmZY}kdS0C5w1<|$KkNcl3KzbOvJc(GK6eijIF zKNsmg6$<`6VgJwAT_mCgs)qq1@Un_k0UdWu$C+{K3!`^Z(DJ>W9?3sGFf}+eLFiNd+Ew=33L8)?Fn=3dy;RyxpVb%Lf2{}q4|_@+ zGx)F)1v7yirw|3J+JyU3o~nMp_L_+zu8V8{Q{2E9T)zsJ`YqW}69 zULX18b9+c^qF|z6WMBw-MqjZeyMPQBtAQlQz}Wus)BkXccq`5+TA!sT-Oq%P>VN;~ zpB~Xk|8wl#znDmo3FD5lswn-Fbw<>&s9Yq3`OZM*PjNp%luo=?>Cf_n&tyK7L+TNn3(m}XJ!CxmIMh8p z4&VIvVh5Ha4U=QGg^Ub|@?!rbtMD3=H>rt!?_3I)G=AFw%PW~xo-tNbL9{b2uMTV? zWyoNntKAROZ|_0o7cL}>s%;BjOOWgyJG6?ZB+whH5071*>=7i2N8#wa$E9OT z)D>HM_BQD6@gCNyb#u`ID7B&y?=3OZuj3O{5J$HaV9vEFd{=a?-rB!=PA@FtV{V9JURxuj_S8MM~PLaamgGQZU>PoTaBy)?5LZRLn!3ZsgLdhNNNj9`egM72 zj(BIeKB0e!5*)POc2rKZuYUQ@i$qDpl^KzgMoM_*tPR>hF=L;5U6U7yZmL_BB>E&}9Tc(WJp=MA-R z3QsPK>{dRJUR}S(FD9|w*@clG(seD@FBpyvT1T6Hly>kE=iRu3-YkSlIffY#CdZ&}Q3 z;&tAtDrwG*4Dy&+&C%PGrs;ZGLu<|P1T){;hBney2DW%gz$8jw|E#wL}i& zmy8ng+-lE=B*<`+Lx-P_oWB-@5@CYJxcQa)MF+Z7u3SXaKJWhhAs~g#Sxxv9AKvy95Q~`D9bEHC*<@MZFI`jFQ`>a_+PYwjl-}gmDyxEVI3W+l3 zYp>if8iVLNTH6y_=^D&_kTY35-IF*(vaG@g`Q5Mntim#*DZwxo|6#QUifTa!-(2ly z&YS?%pH=c}9_fcJ$Tww{Q{v%j#m8_xF3lgI2bZJr7|zxz+0k_Ont<9Yme{$c%{eDD zQpn2CB;%z=W2>fG_0B!^wc8dOH&n|68+pf8qzStLc3P4lpqT=(>bP6qK3sRm{5%Z8YW@tV zBXa855)zyc%(@|G4elO_B${<%`xn`*f$j#m@nP9IAw@HmEQ9iK%3G8JP}`c-;>j&o|BL9Aun05& z1*YsuuNZP11F_faiy;PjFEAswG6Ug(7!;XGt1MI%C1^CNG;_Um+B4y1J)6_&fxDy1 zBx8L!&XMhJ;c2#7$Zz6IECmq}C9D11rpa7BT>Dmattk@uXYKkXan#41aaxqhiBTkx)p;`l`uZ%Y($OyuS_f(&lC@zqh?iRoqi}USv=REQOaYG*vk>;cI z&O%1>8lxYq$B2^z`-*|jDf5y=(~aq@LJY>I$Lw>!wG4BO2?8Tj2eY2b2tg+;*=PYk zWjWAl#k~`$$0fQ;$Ec$oA1*JJBlrLB14TU6MbuuEK_ka2i1f1z0YRXZ=^pn0|^*aU!mBE?(L3D zOI%DUh)=qU&`6mXvP26}^9YGTuRGI9i08QQa|Q_nn`luV^1?M;r&@izj~25$Ev{K8 zGXe?IE?|6igIJtt2@;FvF|;rmHExi!WweGSHcf}AmnTqXBVrV~nR{O8=Z6s{jl4go zB*V!C)()0zKPXlIxHf?-3AI}d61@=Hj=kXYlA2lB^>=x5L{Iqd+WZ|zrIJ%b-AN-G z%*sH)+ST|1l*<9lG)0HekCB^M1@!B1lChzGi9Y{`abnj_w1ikq|&?sYptQfh>b62pf9sPcteHHfqDnrP6#e zKz==-B@GgZ&h1OT!-bKTxm>9Xp-Fc?mcqR0`u=b_Ne}*|kRe_GOUS(5P(3^rM$}#h znk#@C>e+d$uQ?Q(j0|IjI_||%+hLeN@ut)UaVPv1#wLvnm zQgN$g-dGLFD>_o5fskTzJ68|N&a7uvEgFdUdp}EinHQ^_UcTmpiL=xM& zTBVZnTi9$h60s88$;>Xi$XpV!imX|45DpHshC13eyMaC#==kJXJLo1EX|3jfHne9( z{&<^p4#0#79CTUQ8nM#ma61{f{;4@!h5=(S2>q3iK+*x-l=Mf9%HX|mbRG z0>o?3@2A#$wT8zB&zEymL(2qpwcL|2iQ@|d%6$MSq9P@6J@O!zd;~Z$BTIRR<(+Mz zz^tDi-MZ(qdz;h8v2+Yiuxy;^@qIc1xZ+Q$fb94yf7;nU+9R^#7itD`4myV!lah!G`_zb|pkD~inPs{3u zU!CT&yelqwENRoYRQhr4oJV;bPsr>1^mMyW8G8>5(F(P?1;t+ZMf$J4-JQrG$GG9~ zDTPYpsq@o(#0~I{57isWcPz*v=5z6pUd$F{qOk8^|CvuY>?4w7e_HbB=OXz>i~dgu zdg};As2+Y4;lshB(jYe=OKa_FSO_*%f4!~&i*-+f9uwraND{TWt1ozx(pWWiVfuO- zW2bL!KudZ=1Rw(--LR)CjQVZuIQ0rD^A^2KbSn1oTuG*(ypG4skg9yneW0r$6*l{! zWh>3T46wJYbM11{4{XpG4(T<{r^@T7`q!?n1rWEH@uJJ>cvX~^>_iCMcSKnXzMJGQ zTn`M-f6Gg3g`L+*K7*e3&wKli*{`y(o6}#@svrd&sa1Il?+p@bmQl3Dc^eD%irZWn zeSyRNt{Pa7sxbebJ?*h9Jk4f_5hS?JS?zWVh%VcoLRP~Yj;R`UUu`#T(~}NQ?QAaJ z*S;)ur3OKzqLsSwj2=bejFPEJ*GrcpQHiy1j6ybSgnrCE5b=GE{c*<{7}NrJqu?Z+ zBK%Zti|Bnt*6)1dt6?U1gQ(C& zc+zme6Yjwd#V5iG<=}XLYo6{L8c^sYEh+t;NAe&KW?7qyX!67J=p4>9V>lktPu|vb zWW)G(yggP(hP;b?q5UPvA|SFA$JTmGZvhZQ9=I=-igZvY@S_(Q@yen^`A)9O8r5nMa7_$CDI%(bJ@G zUfDsJRny2^a+p(z-SefqOG65Q+{?j_iH1sPfTe4|r6`)99+FPYRh7+4$>i4>a{53j)Q$kBy*1K;~It{*?_muQMC zl)8#VtdWKmfhE2_^J$^@JZKV@U=nRYr|IGp-|o%GGeexwtvO3K2_2gjjHc>j6iHvO zoDA}M!6=7ErcnKW>OtWX=ZioBq|2{FuAu1}uJ$0|X)#<6^)OMD@9vC&Kq)bO*W$TR z@|)3qZAzZNAoC(KqhAr=KkNpDJLjC4RI^(NHl9AWKsMf}hpCc6)6B^}09m@7YLCSF z7#+H`^vi4VTv$HLU>AZgb%hvj@$+Vt)Yebi7v5qIv#L-?AEa8yZnVe6j%T9#@jKDJ zGDqhf{QVZ5gZb;}5{|L;HslXrPVRjeyTXC%N9KWxzhGQ{oP7W2ZcFFq$@hPr{6F?W z{SPPqul(j;4J1NIHtMP+sNJ>-)O4$T{?p_zya*D~XsmizUTd;d#`YPkbz0(2D$jc2 zEZg8$c@YndGSXJCZNq14oGpiI(JhYeFNc`EMGyxJ;j4J1&AU65!B7`1>h|`V{lK6U zk5!R`Z5adZvMquQ9O5?vt%3;V-C*AeRFgX6j^m~S7J}E!qHnx4&mawkZI}*44B`x= zax_xw7gX&U>*y$HghO-K-{^5`FLz}}#Cb-X(i;uahTLJk#U%@>GYJ|7AeY@0%e&zT z2VX0!NgB>to};rdc8oV1GhNbn88l9loK3RC7?BM@ZFnyL}8?D{#P2$>@TvgxJsJfAElW$06Ny+Mhp~p|c=onjI z=7rt~8poI4rZnk<_d(;Y~q*4fxq}q;c!XYBti|Kj_nQlF!_;%9FB>t?clhI5l zsew{s5$7x2GJyF)fsfeLDJUV&Mhi%Q)3Qsypmi_81`|8Zx8cMxGFR1R(@`%cjHCtz zUjbWH+w_s+dYxJ1HFQTNnk_#aXUqhD>Fik~*o_8y&^1q{Np@oWAT2Z@wVd{eCb!{j zn}T{2w?-|FriP{LxH|Xb}L%;|~$hUKWoMd`0zMnCAjHNVDdzSXw#D2Mk7VHyyU+(9C)iY{Hu* zZSZc@_rd=9XIbEr3{yCO6-ra&ki0O_x}=*SW6KD0ZPamT!layj1k|((A!>NDWKr7e zuW)S5pph4#&jcUPcbGx~(z38aMte9yQbGlr;^~<E@S8%j$J|Tn(rblJW z<)Sb=&(M8Y0;I^RB2q)>PjRY{=8nP;p8QDoB?EHGo2H**BgJ#c<2djQ)WLCe`F-+# zvsl41JSL%~SQ(%XPf4J(3 z7kUZ85TZ^WXRsWQ9@WC|Iuu--zG%k`16yZt8{|QAq^>*&y6-48823$AHFfpdMW8+U zgVWmLH9w|L30yc9-U)+q!dzv!G&L5UxjG`o*g@6i5IPz3@{=cH+9b_d@~$es5$L_C zh083XwdrtqV}6#j7m!EITx}`pG6F}O7Bl;p(R{sHT)1p+ty*DwUKtRNh({tm^xY3p z+QHJ95Gp(XS_SH=lO`;soyVcOh1y)1`7;cP);;lPV`^EgU>iV*LE`%wDg-)i%dxa7 zRjuF}igkLuFCT9$3Bu4E70B_pM&nr1f>f;ngOrK|QH$nsIb8~@)cNX&Z=D4z=GDEn z&B-s4$a3pZ(LxKhv^Z0AM`Kc6N;TtJqSKj5@wV4bK|0W7E0qk;0`sAP5*wH}_{6<1 zY>T&09AneNQDz)WU zr@}qy@TwDvE%L-PF3TnEnLyyX#BICg>Zrb5EswgVj0X-^)=^L-_ZPh;Gz*%Mwdsw@ zJHal?>1uN@>D?NBy|$QQXq2oqExM65L!z^#%eyr-w|O-b0+y(nk%Km4K7TS60KQ7tTXP(`qPj6Ey~B|)sfizwCNm~IiJiWRqZ+=bn2@Won)vWk0yFKKZyrT)?_yTsXp zi|3zx)@*$Mt!m%y_z9KQt`&VN2(v>WyG61YSlo(t%}ZqAp`EfT_*P9l__)8fZq=48H|0kZTP>gcrRZZEq;?B|1&6vN_b@h(xez1tv!Y&yYJ zI`PIFdM2e+S_5>-A*7(k80WcXQwJH>))IH*!5u>&@Jw1~NAXw1nM)J3IPSRM4%NsXD0E_uH$NzSLS94T zHfhrp>4#X;Cd^mxE2ttC=|K3|6U|`vNRAQe6FJ=5A$-`%cV9o*@Wfw;JI8!JE|~7l z9)Y^$I}nTU>ZjQ+91-ysZPVv*g7DoBVIL&#L|!?St!$5=l_Sb(W?CHgN=2AFpCeSP zN1W-k@sppORzINBM0kfZ!%Vr-#hT_xmX38}=2Pw0Yb)OlNpc)+VpI3j@%Q!Gvi^#V z{}Dh!`;L^YeY#0b^#7%>`2V=dKZAw}bx2Q?dCU*F+O%b900|vQbGiV7O)cbCAax*7 zLJ&v*f4r}-LhCZjaF+>tMuvQ`wKcT$xqd^~Qa##FNu||Nd3|6-)N=CNhQ|Bs2V?pl zOR8n6*&po8%hCjdWqgmuo9#~<51lVqQJJ1ch+pdL1iK3!%OfT!hq@w}crSa2K=IZ{ zc1=K;I=6ahcihYTEv(SnR{Ls&2F`(QL@;@Fo=7pjqfK)4-Js&LJyt6T&|RPmxjxx7 zxh?Pas(CewS-Bo=SssmdFWOhBcM|TV@p_I1zo4u|gQG}yBd7-sns+(Tc7N#C{16_fUt|q>+2R zN`RLebrT&>fE-EP{~g}?+bqpQT>jL6alAMbfDB1X_!SAL;djHRC3fl}ZKaOJYISpC zPNA`mq4jL(vkBz;Gwim^c9wR#WC;Mn}OSreK5UC+V6K&wbu zs^uapE4@`?h{TX)_MlUprl3i+Q3HsaOnYRr`)?0v%cBdc`G^BMOJ!u5ome|3=cTFs zHsHHt+;0WY3u1xUT0{yJxiY6S2G*K1wFUmqEEb^`#mf`~02BFQ#`DycnW=?aRTX9da?9%aumfT8FNMLPi^)ueNlCVD9`IAu8PUBz8Vk-y$va*wBx8j4W~^b+4!4 z%%Ese63pME59Gpw2Q5monYUL#q~|U+Uz5_vUWLJ@Z>pz|tSgd|s^W6MrFSl(yId!I zG4r(CD1f1t<_@r*wR0!GjANi`s9v+do10h3?Hb2wnI@w)1*4R!qmF}}d?9mf6Tl;g zKCIvdwt7sYrK}xQV5Mp<`AuodCt85R{|nGL=)!MTt1tG~FGvIM*-2vG>W4(ZtXp)h zkg0V0ps5yiuu%EB6jAy5r0R!5j779H$hUjykz@&MO@L(vUw~Z8)Om*$hu4@JWYN%3 z`FfN0Oxw}mQTci&HGU|+0{t@js(4L}qjqii zY7)~BTyE$O;MhMygm$%H@-EwPee4M1+cHM=>B};D)#(3zrG^$bE5Ulz!@sR|9ft61 z+v9H7X1H=dM{8hVy-&IC?04(>D%8(+T^i=ItpaI$nXe83{-M=Bcx8|J(QSDgyg_4s z>x}w=`mMu{U8Ox}w|tT6om|)(n_kI_r!h0*8#^jfs(znFXxQv-_k|Oh54_%f7H?F{ z{?GC!s%G9v7GFM>$`pkciK*imqQ?mfN&`$;qYE+D)}s zcExb@go2?F#lkEYRufTcvNPm|vRigZzeQFV=v(%%a42Raeh1D}JL4sf6YWXg3IQI7 zA;Xbj#ZI>&Ol`D@9Ay#6um)<2t;+{Jl@vYsjXdEpaU8d|#>hs=fg-ZFL=L@7bIx68 z%#-!VRzn_5*&T;y8jZunoqnBXhR{X`j$p4ZVF9Lr%pD&f^l}zB;Z0>gH+X-u?_U^* z*_%Ji;0PeFvtD_6vKhc*x@y}YVigJTHFN583IhZ0lgH=6v~+Sa!0FuwH)J?%i?TyrGa(i9UX&3c^xG}Xh;=t3J~s$KIT^M`Dn zGuwf>mPQ78&;&nH*>;7Y_(`AAydW@Xijz3Xg^4FRR}YI2aEa)VZk!?{8*cZGuXnly zIM+<^I?;vc5U0}Qq}7ZNGOor7aDvE%Z>|QH&jvM5lLp2i8L(D5Q3y*A#!pHF6Eul? zUD49tnv&-vBnCalC?y7tY!-hl4XOvVqefkc;$8y)o$-HZ($WsIlB5hJ*N4>{B2QCS z+qO^~Ldc8kbyrTC=i+-U_{caozRUx{baJTIBO%03u^c z!0#i0RLS%`Bp{PI5(r*GmEee=RN096016+Q^L_YIcrAOdR_@Cl3Vk>NssVaKrwjn0 zB;BGNlFa1@4KMZlx`_y4o+RJpiqTCX8Aky-ZMj;Tzo9hPSNSmKa*Z%>tv;aPf7`qv z_VYrF7q5%uOaStpi5)K=@?PQiZE8B018(aZPM<1HkBnQg?512Oe!mWfATzHCrY$Y3 z9qz>73j!e8q)e2WD1R+1e0m^5y0k1upQqP^jIuE=Kyk{5((zI@Zy@ZF z_^xQiR0Cl~AcPtVKX1_RPy%8+V$yUF4CZB$emYSpbgH?KF^MdJ9Dp+Kg~ViNiA2IS zPkI1+ga1A)L8aNL4mlxONj7EjB!(}+!93->^9GD=wv1bwy0kr*A+LaY3zFg3MAaCy zRx*XYF3u^|@DxUkfLDS}ZhAqE88Nfl4aa!i0}Yj9K+h8{Y0G^yQObIPa#Xp9MoDJW zim)F@b0?tQmCRhaK!#UZOSW6sGmwk^cz@f&b8aStxj0XO)t>1LiLp%tg7feW={mP; zje_zbtXD_fv`pv}Z3gN1yD;)t#YFlk<(2eW5TkS#kQ@?vou1V#!Vw-^w?gQ3&L;%QdA+3m&)e{6%i=qpC((+7qyAB3LfRV_Ma<7g8!t}1tsffb*tNa zH!(H+V-DcirjPeK(AAd*nS>fPKP0P^iqW$u7*}JngslX-X#Gkqn8%`kC_{+H(cO}K%osX+OXy!a8ZhcB4}Ef006+Fb(_o~2yKL_2KUQ2qigl+KDWEiW zD3J6VXa*xpzIqX5TC|Dn%pX;g`!}^8Di{}@KeQ}v`%zy?D1^hU#pp8z&+|FG)D)5h z3=b+{piRtnWrGu;APUvc{r)7)a#=^0?zyLYn@L;3%uj9P<|Q%z&9iTsZL^;f;p$QG=jaekqPgtC-0we6kaD4bReD@zvJ%5yKPC5TeHn&Ing4^E|e zazaW_SP&J}-g7%D<6Q0JHL&WD9L4NrZVo{UCAGMTGg8a9vJ;vB2}qQp<3^d^KpFA( z&y>j(8QE7ttdsKPx#Bfnam$4Fw}{p)?78T+nX+rKOhO|h*ddQCPxPH8R*EQA?ir!T zr>vk_VFrGEWz7Y{i#rj^zhU%CQ(l!1C{HHB?6X6?h3v>1@LP(?@xqVCEPW&aT^QT~ z)t2f?3)Sz<{Fp2&DW!*)m3(3u;Dx18jK*mX+{YpGP#qf8CZul8Bp059au-ToXAWG; zzN7%(978oQ3Thukb)fzp5{r71$$&qB;J}4gTgveJ*T1V8e{ddSRmVQkK8@|-a}oTH zM(5;UZs6?n-{X+}%?Y&mBsseL!FHq*1)JC!yKC=@o5}qo0`z zUv6K1x-#}(xQ}D zPXD<(ofs)8U`CXnNoz~fmFFX95S?agcDQEe{W1}G5NI3if@>z3l#)23{O4KiN8ne5 z9T{ACli2jV%*#Epr|0)a5IcYUK;1y^z^{a|%W{#wp#{BII?3wu?W!`Rw;^yfzGMBY zGnG0TzVKJ8_0~I$G$Di&+a1Ktpgi1g8j!GihtCI6UR@0Okz_M=ouUP@da!rz3%p7G|;^HP$M`y2=SZo^f;03)x9 zmX9LuH={t6ohzt7u#H%jJx}MvDs8*ky~4%}tg!eFwO(U?UPwk4V)+rmg`9-sna+$W zpEp%_=ymy!;V8%V_E-(Chb2X|601B7rqeH?ZNNBe6V`9+QnZw6VhQL+b*ZXtMjNog zSOiTys0iDqg8)HB=KN~hl9~jBi&;i=dCt8WcQ0gECLLQTJg@p(1JKa<~)) zav@kFE~r$dy7ZEMrLb!(bf}1NCaRL6c?K;61!9@<4YJgvjH{7SjmD<_<&sm*2D=Ra zfD>j(7h;LP#rtOh0SGCBWXPYf?E}Z zmK}LxIWvU6&Jm-Y#bF*e0#V_@^*9UD9YC-wp&M3DfGgP<>?S7qMTaDN^J0SJ0JSORFY%mpr z<;agLCr+EBnAD(6dQ0kP5K6RKvV~PTmM5GmS!{qfG0>kO<1DZA3mC#JEzw@Q@hOe* zk(`JNxnM9vIIt6*V8{kAkmBR@o6SZ{QOrW9N^%J+_$-MQnnA#iBiR#=a=3;l)#w*= zx+!nRXk=u)c)I3jG;V@B8i0884&wC~?yWT`FKi-WDJD@kcrpI%Jfrj*+hZw&rp%Wis6Jme)Jx%c1dfdl10h0LG#A>;F*{!gCxpZ7u9*2dJ> z(Me6;%JTo-ivL>$j+e3he6j(XGBeGLvX2B z6e~K-KTJ|%m2IH6+QkegKY6y-Ptvd32IG$U)$C{29`fBO0|3K=SjLR!>47ex)>jiz ziekSP-1*If0@W0nvH^pMbr}&R9F`A-{Oz_eWaHL_f20E7RH4rFCr{G2ku` z5NefYM^Rb4i-j2TvAQn6hQN^TZUbWeCoV7-8qS#}gMF_*=!lJ%Q%+%6NU>6E4#ZCp zTGy^>Zccn?*J^1Qw$*FKrM!J+8ky3p90uq(U;Glw-3$2~Nz8>X{6e-b4OXqizo0Ya z7ehj|2f@~J-7O|@lC4i=artKx^S*bHN!#e_rbClBJ=yf7e5X{wP_9r2bu`yq61 zd9(2T#MFHl!tEM#M)7!u#qoikKIm0Wdh5f(_G5cuY$s z0ZSOF1#I3z!cVWU*MNu^Cx#?F;}iGp*V#xP1IgUce&4}Yl#!_ey&B*LG*;6GKcsn+V z15auR8CS%!WSbhdgW@=O&>zsxk!kU$*~<>2#}F1p+^&)K(s_kxFq>!y`hZE4GOYqQ zD%V1TL6=G-Mssmx3u+o;x30ZQ)Q(>*TdUjqVHN?Vg=Qa-AT9B*QZG_@a=oHjx%W+F z8+@|)?WW`~wdX;He$q~2ptjlijY6<)Um3H~m~90^H3&UK&Ap^VNdp5+R)mqn(zz2; z!JbFah1C(w&`OSn`7UcBnPEL6^%R0!uX!3w3yNFP{vJZmjYnDjN*b_Q1mKfWW!XxU znN8d>1{3weEXdG?YJPIaTvVPe$(rlUQ~$~D2D6S@TJ~#RbA~tmMWCCHES}KELuVp> zH?Hk8Wha(2jn7Uop1kP^kKGP+5ysPB4wgoLxeH1amb=#x*isx@eb5m=7&^ARR&o&5 zNL#u_=Qh8N3&rv|Oo|Hu;j^qk0;X!TvG_5{ z@EXYEt#6d9QSdC`lSaeOg1Nv^ zJjZD8FbMV|u*=}r>7$DRLxElJyTrVdN<*h8T;DfIc-&@LLut%lM)5oaZ~_q$eiWf* z%x^yBS7xp_3QGpSOdWtcc;CC2Z&!n*eHJte@!Mi z!J*qCcG^wMm7B-KzT+9vOE5DG#1cwu&%+oL#yGO|IL&t#0oBC7F1ogH^4)QM2Qif9 z?eiAZoLIqz!6WK)3F%w;>SW$JWqC&25?u+b{pw|4fWJP{@Y1h!7id5%d4}Kx=j}>MtSXeVt}=yM$xUH(uOMOn9w&^Ek0}#${tFd;E;%vtayI( z2)@X=R`@H;sBN}*AI5z+?37A`${=4uSf^raR?Q=)fZc<*6Az7EQijLk5~o8#ndwK! z2I~sJWk-L(ZUS`-x^_I%a<(+!{2~V3PTV{=;rJ};=tqFtJ^bCRb9 zYQrgy!7d$jtkT?K^I~SB?_i!=OemUzudq#Ccz5TrIPL-;j6xTo=x*0a0F~1n`-ahM zUg+-%w~C|CYxizbj(I{Gx1>5pcE3i6<>rpXSb1+mVfGVuZ>NtscH3O|c6y21WYF#n za?c|TU4?rr3?xt6?6odb%TGRFPGmVSZiaYZFeMj2H<;7sfw9QXaNA_Zs@+lJ>|(jF zUIGp0>Zd|mZl5{v3xy!$a4&(+nGy*yLJxvaVhl#w!0Sp1O<_dIam1q9E+Jd@mzS}D zYz^=pq>mUd!qiNS4KS&(F4ELR0`zxpT0jgU34JzV((||+WBPs!|MJdOJ-Qk5GsrC> z(4Mg#o$p(AF2^Qq*D)s^{oBt*FB>mH0#DiXuy&4pCb*?Rdv~&T9<)#^INXHLv zR-qH;Qw^2*7)Z|Y* zd!I$Ki%dK7ii$X@8MciwJu%!l{d9BM;ur%lz;(3YJmzWf?$P6*&-;D!dHvR{_u<*_ z0Z%mwRC^)}P{F72tH zNvrLZRih;0f11!du2pC?<%STF&%Po>>@t6Ynn8EAO4>lY4rCcLo`l5ANH|DfksD1k zHM(1-$m~BfdQOizboSI0IuoB}gqB@#aM^PdYBW4_#8N#UHu^t|onw$@YqO@iY}>Z& z>auNDmu;gzrFimT1{ca#~1jfeOq#-jdgX! zN3@5Xd*@Wby_=ZT;x*se-d((<%dLU)pz^{(XRwx_W4h`^jXlvMImWCgC$=gfj0=sk zQXPwbf>2+mFbYPln6dL9B_u~=>d-_a#L%SkG{3c4YzjGYc{-qg;D%*sIwsvr!SBZ& zt0w-IvNTl{gs$BfovOTDA)lyVom&tzlzQLFGWTOvk%>eKj`7vzF>umGp3=!t1a%GomnQ;0+sKsXWYWEHNa-Dcs?mQe4+Rc{Ok1|vSiOB(s$Z?@X z$8!5YFV}Oi8q-P6lXyq0gO^eBXL$i3?S;&;-+h$g;&nTotZ6@Ygn3meJK{lS9KCX* zYuqh&)@o}R9h*#9rvqioWU$mCSU`D6Cp5~Ls&!IjcYc&jhex!H?~-54Gnj3Ic+Pb9 zEn98V!(yU$=Ye+mGl6DyThGpQC)ue8j%BQ~T@&gsUNaU#dxDt2c%tYsT?cDDIWe4I z&3Y;VZ^hD7ZS&%6v0me(Guh%QVy0fnnVeKIe$%N%IA6h{7=?!u)m_VOg?P)=@>>zi z+LoDOa2o5>ErQK$RR6T)FDoO{6m?}&gEu^sh~}IAw4yKy&%NAlLW3l=Fu>yAT@s>j zxLb6c$Ijh!T?2e8smVN8_?`Y5^hTB*)1HB~qB9(gq#S=vId*A`>G%c=hgP1OjmT?_ zX7z|d)JcYt;yKB1fqhk89|lB-MqFxgzEY+@&TfoUX{)K5^^8fOX7I9y+NG#+3+Dga z!nPqiYo-g7uCpKGQ=A^_mGnW3Xu%8()WFG|>se}rgM578nJvgWmpE0iv z0->>EzCO(5At&`+H*&+YAJ?d_<5Id4=6^q#FpRJ4q6DK?1Ef=_u#dGr)1N^Ek~{|x z8k%(}7}jAj5n<9Gdf)qYmJYFbo40pppv++>7d%aS`m(xJo~oUbVNbNuq=<`hx&lIn z3gugt&YnQnf_8KEAE4Ny!-F`RC}ARYEP_F8VKv#q(gl@s8PZb+W5d*@W|*NHu?poI zI1r=yOX;!;8L*?Y1{7S@YDc1-Zx+u==2_-VpHcLes=0lziVwa>2AFC(uq0Pt=XMd4 z^pNemAga0<7-=Ps9qPTXx#SJuaq=1X>14b6#V_kAeyhB+hj|sa)k3WW4``fsf3&lO zgQB*}+DnVEoq%~F!u{f6DA|>Uv$ydfyPL21^UN*ehNG&b9z}PSQ=U`{>TjLPKScX! zaYa;;cg0ig7S#%=S)_WYwb|Xg4^m7X?UhQ zPt`BTyW3E(L7^VoV;F7P>97K3jk5xiURXjmUCxxARS-sp=$~{lioD_l3Z|B;2)Pe# zMAh7wRLB}54=5Q8u@&+gm(L6@yWUS$kq9k2$Wy<7N6mdfqId`BI5p8Tsp*l5^YSPP zE_P_?r(DpF8I<-e;pPU4mDv_L{!!*=Yb;VBjX7oVroL#kO($*hh zr7kblE^h7cOXdjfcmNlqrx<$DZ*-U&=yxl3T6G+8cQoOK28=2+^(Le7xfKpAW`mEM z%8p)Q9$x*q&j#~*gsC@3M&E?KC>zl*Fz+hP3Kqq2m$iaK=U7R=KBW-6np1226zV?4 zIBNbDmRQqpu~Z3KQSLEH{RK4nnPG0L&GI6{77{*S)lrEvH|A?G340Bj@O~$Ek~8TF zyASF0g$lsC(qbL{g^JiagxlH&maGIgeT=mwvpv}wV4LZYF~h^DQGr&$WnQO9b{v4XJ~UGW5$_D@_(n{_C8ucKnPu_oD|-d+#`p z;@9z_ey_JeY{d5?_&I4I-ckk2Hp%5(BsN>dT^nAg)C< zu3;q~v(%(NrOG~glWwc}Uu?$TyO55&x5eL)P!EQ#>3+sSh)hN7^GGSP#WGwv6RmVB z(Fil13C27Sr96~QE9l?sr;8bnoyu#Wn26j0y?|cKZ3CM^-MP$C>{d-?s4pK3o z@w;D2^X>1%{ttb1MMwMZE|H*(m934nk+mbSsF978k)yra-|xr?-$gr;3Az`nC?cxw z55mv|cjz2H<+W09RCxrDiojifwPt^o@}( zXQjY+=q1DHQ-%OX^f|^eJ*^}TqEw8pKLrH^0eT`O z6oGmH@(S=0M$mJq^4a0!;6+katK=vsLJD(%iE}g?O4G^TA7&+~;~e8GXM=PeTfL@+ z%?M*{N1n*cX`bNh@IFhK;VC2{?L*9rqY4%3(VTh*n}K;9QwO3%)*04u+_AgHZkoty zHFU^j8gYE1l1v(teZji8;@Ez%ET)UlN_y&Sm`X#mt;&dFoN*43$YwPt^7EcH5+tBt zfEgxhB&OSkB?VhS+TN;CV(hXhL4^?+^IUWX5wsc;s6l_=17KBmI$nLSb*bUV%c&S| zRhnS0Xd~F7oTP>^K^6w(zA=p`+rF%He4fKgGNuV^{= zD86j-EH1v-rjUbO1toe`{gn^{a=Am2q~PrAEZb1MI+@2sIM1Ov*TsNFs>+pqSbmDg z#QYExWMg?pN@=_VY@UX4hGXYsDv4%tYfe$c=_sV(3T69VZ6K5)U1F_PxvqBJUEP?| zDk>eDhRT?U`_zgxEBw~FPRTh7r+^fygt5j?vtW<1G9{0Geql7k@`?mlTxMx2omI5~ zmG%lkT0t__GFQn!8piX%Lwf6y=7^8}Gi@x&L;9-hJY$m5@9j8B=U*o1PfDJVZ&O}R-jR3z1lx`)>)MewoOj4Acro`Z+kww3 zEST~c=pjt*x2tbpmKK1lD#&^9`Y?h5H5m8hdI@DuD_YHDP}pS}&rlZ|p7KVyMo1nb znWz;np1S~YWDgrZ_LD#RF$9Ae&@PEU`#Wgx5V(~UB<6-~rMt?GU18z*JI~n0R14iq zhtHr;xf#F?@LTTW*4E0$JJ-3Cn7EV6<9n#Fym-WN8@g5Ib39(+C+fY|+pv|T={6>u zL|hMZn*7n$@R{WbG?cE%Aq>`}%IeT^Gnx8uZ&ejwIb5Hm4M`F zD~)xlx@>C^m1CFl@nC>;m^9liy%m~uj8P#%+S(Y3HI^G7{a7(+3(5>&7@Ta(wzVod z%d~llV!ORNwuy>^Ierl=oUS|wo4n_N5*WNZ|V8^f&9~S;9LKTPm0@c(l&z42Ls+%l_e>V zzkT$Nsaj>gd7%~BqhSvw2iMH>gU?tLXK}6U#4n;^$<_6t4Cwfarnyfgj-OSwI%b&h zvSos8TPFcxe#mUx!a;8UA*w9=`SymuNX@2rZX=Cd<3k!6L0<~d2ET>A{x(0;G?JoV zf&TF$6#bt^k$=kt|6BK|3gN1>fbw}|X~QUmD34YDVbfRT&2{%$Q@WLtw@3334_RzQVeYsSr0 zyo`P_Ml0%~+Ls~Ns?%Ylr{C_?UMAdsBRsSwcp5(KU~H8ghVx&ibATH*EsM4i@FI7B zGgq_X*?^Dt4f40d3(&bYTi)pfKA*p?hKdvFf;dh}5cNM&A&4?xJ`jMwjf>h~bk`b= z>W?Su_s4^BQ|QAb%e2?Se1v=nL6YUV35R~-xKW(hF_Gb>+WNV44TW~N%>grIv0N2h zrxxXSd~+P=cH_!i-%3?EguL#wQ;n-VjT=0$&t#z7gc}j$$2eJ{i**dE=aO{2kmhBhtN#0TD!_J43u+8X);WdQ=o?wa)B;WTM}Tkl#d?w z^w8OfH%fN_7ozE;#?>MFH%`$hGPZ-jj$FG+&ncCeLN!freKbcKFY;oNlT-O(-Vv}$ z(^;+#F}kS@q>$ikMsoeYl7I25zn(kuU>>(Ae|{bl;$oj2W$aqvkhCvMg|v8{8@bc) zc4`Te(aWg>?KkT|xhuzyZ&(=HNAntgvT?Kuz2J9ehXXorTtdvHw%kZrT4t-M4}&uNd2-NUx0T2CCm zF%V*RQ1>Pi%e!xD;~5N=;#r0nYk+2{`9_xDY7dBwx4&z>S>e3_JZwV^5TGw+ZxBS$ z(#}@S`sP*6Q@RG6=X?+W+ej)5jP4NfP^`wyMrnBWM@=VtjOxHyiXh9nYX!Qg3(8#- zw@{T(zXEKLV}V-M5JSvrfdllWZOV`mns9{U9?7>WGhccfKlzNg3Z89XAJFmJQtOP*yOB_md;|NT=M7b!otXf z4M` zYKEBg#XNk}6V@{ilOjCuFqP`ap@YQ&IX2G|@w>l6)HEojW8zL;kec7QJ9oORbYL?w z+?z=de4>2p0%~I#v+&=*DzW6leCsoHoz`=nC!d}KX|Dbhz^TAmVXrpz)l4im&o3L3e2|LlnD6g^Qtu_Lt%ri9 z4>TbX%LZ5YF)pTm25lb)IO{4z_9b^w7 zP3=n#N6)k{OUT#=I0&qIp3-X3#;BNI1Xv8yCe_%ZdAD1M#~ewFI_z*$v+Za6JZ63% zINt|*e0`%Y-TXF-eNynIV{{Ru85=2WOt^6GS2k!;;o^?0)lRGFH=w#>FXfI5#Tl+_ zbi2R}YUt6ZaAQ`_IJa}HUyGreyH!GO$8-~AyEio->-NP3Gt+HZ+6-ejz}2L)A3Ydf z*9kwsIOw=mvdDK^khyDDgkiw7LSh{Iz-|56g|;`mouF=VdM+M#{CgKBZ6{&@UG(+G z_bQXv&tNU?{%31Z1n;{{Ki>2}oaBfMsj{Gx5HGD^JF2DC8}!`eiOFp{txz&Ml*erm z?f|Z8w5MIO%WuS}2m4+5&Vh_XRRA0nIu*=7d_yb|n0s>T;W6d-fJykm89fl1?LKl8 z*{=Q&lG?!BO2CdhaB)*WtF%SN$1!BOt&@%^SSg-51m5CQ&4A+WY+X}N zPD<83i^$nTtZ?S#H3PB@v*FGnPYXse+U%dcM`mYU?$;o$*MyME3^MwCYJo|%lv{PS zKH0aB1}@Pvt_htyd~_W?){TBi)e!A|JlhYJ09QQ(8V{gMJ5J|&s}8Pf!$DODx`p(9 z#=PbGOD)a8EUaL2NDfePlhAS0c5{ zb_NOGqw&X2A<&hSIBl(l>DCSrTJ^XUeR~+=F+@WgVb;4mIUHf!IUzx|9{eM4#`si5 zK5=KJ7--b$lzO~CVVuA@*TS?F;$uC(J9pmmf(gss4Q^Ft>a!u@-m880Gp&)b)n3BE zih12(X3BM6+4Fv6s#Fi^@Y$T%9P$Hs%4IOF8{ENKl+5v_tc_~dC0SgwInM$;BUYYe zqaQz~BwYK%KO+L!Kxx=aKxwA@0}{iGPJzF{L?vi+C8)8_=@KXC89cgMDFDI3*;z1+N_MbD@ic%kS2cp=jfIwu zwwFhQD0f_Aw7jMh*m(SuNYs4W)+HrFaVVI+_Zn8yu3BhGnZS&`Y0h}gS)S`B>PfTTO=GQHIcH|EmqegcNh_P5I#{q)SN z&6ZcU%dF);dg83q&S$KaZ?R3m46umDVk?$fFR!f@H`=3R!Cae1Ki~1l!VLS^cT+zg zDeD`c)G`yQh*51<3K|?uGuv;)VM#XbpXV1!vzqshSg4_{*|UzEpj_>De+8tP^&O+= zD~AoFR!0IuV%agg@QM+$)`JCB7uU^=A0y8Tax#`IiTv~Jn-n20x;<;lAxU^eAFocd zA@Q;$n{8SdNC(x7+d~YaOR&}tm#l8gsLfBIO1g$1cH% zR#JRZT@t76IWVk%q@WRcZYXJo0?>o3o?14JTGPTh6UF`x zGEY+BA;-I{EH3f1E%rLsvrNMZ+sV3uRY1weq8(FxSgUlMBhl~@QF>})4_Skg_?caf!NG z?-L^nSBT;q1RWL9@qD`6mM{g@io@;E4~FG_^O0uAWl(xt6(Gkh;XN_1;e_<+X!GV9 zdixYhoy*t8o$56Dsc6c}Vxy{)SGIreK`D(3MuUD!MZ~^mXEgus9u&W|o~4_^|JlpU zP}Wq%Qbzuiu?Fh1t>7=KK?Y6>gAWZ>re*O#W(F~b&sVlXm+70PA4!#J-S6nir|Vp7 z09IN&{X?fc<~@@&12%9ar7(+#oJd9WmcC+gWurUUWb*m`_Ehvk=7KzBo^b>I5W4th1yR%{&FWwhm@&*ta3R*) zO7&ILR zionrRs&UrR^zCmPO2x||{f$F46%LHJ>}zViDEp8%HEUXlD+?z_*HeGkud0l2b3y&?ui>RB-y*^A{GG?w~HR}yqv>ZWV zk5=fq>I)1kCYdV0EIlh$Q4gbeT3RPvb9Zk0VZWf>xu87+pjBLbnfrLDjxC^$ofOQP z&*yHbd{^cWzVHa{wQ6=X>?c)N20jl81LLcFsfIC*2h%_|dyRabh1-g_RiQm2l)oh< z=&o2-=)puinp_bvB!1K$7REb0_8*0uX9<&O2UaR$xaiNIXP}pqc5qwf&y(Fx%hT6? z0FcrEmuSU=d?Vc*5?NjH2Q*JPhSc%VpG=6oRB0|W6%y@d9V;$4)@bh7od^9p7&ViI zvlOGTGg${p-J#y`p_KPdf6#8IqO)QND#&XJD;d;Hv%3}z75V}Kt_s%4#YjGZw4w+Q zi4VUonGVKFpd`8wW%6v)--t-($_MClhUIy>fz1>w_iOVZjOva+S37-vYIk;kl*|db zC8Tnk0%|?%69_RjM0HPfYSS5E&G_(tw@5Mij`tK@7BH`J@UC5e!Ut1&-i~!^6w{Zt$ za`QPnN4S3wtf#My;TE8JvU)Rxlo?cz#WSEp!BWTO=6h2kXGc9OG@wR=5haSU6V`(k z=>t0s5A+gVvS~){U(NeQ#XrB~{W!oI&DQA$e*^TQV)3Gcp{}VJquz!^nqufe3AbN2 z;kY={Vk=ID?+ z=gI_W+Mnwnui^Hsw~p`Uts~{2;EUTEwOinQ>`wxF{w^r)}9QY%@ z-b-{SoQIshV6B@%w;hV?$STc#RPb?BXlxOPr&Kot$8$5bCm~u^f06x-nWsp%iLxgx znh`t2c6_m`NcT~|gL=z+9%0UIJy@9VmOl59Kvnq^6#HHep(ps6?16PYJ0wrhFU&4UY!hl?Xz>d|K^+$E=@ul-ZHL3zwad4(M{ zE=WIaBMMC=na|nu8MyL6`WE^5yQ@!w_6=1=+RyCt{hoiF@;h|J%o+v)LWW8N>c|Ky zXidlrjBpVq`L&BFY;xw&P!F&+>}w!8#EPrZyBUV0^5W+~S~oinqPQxcDhYo;qDB;d zY8Z3SY(U$avE8dQCJzKzAFWLE=GHlkVDPWKIyS6KBxgAmRnp*CIA?a@WignWvxgyv zTNt?OUjQ-XC3^};0i@(+Xt5EiR&XLS=AH?cA`9yoyNuVipvO@=pvLiTSEoLnjzl`G z5T3zM)oqAv@AQuoUWVVJ*!S6{exhxl57+A*e2Gq(i@c_X-aS@Z?amu_y*?x>qm+#n zHyRNoT@^d2;YEsm4AK<(TdazG@aV43Rb!x`fATx13!*I6V1vpk!C=`!l~rVQ%13=S zJ}_BxHTo#a7poyyFc*JS1k&y1hSHfmGt!zigFTtMBA~H&3U{mCu)xsm7{TbGUBjGD zUrTE#+|a;m4Z1M5`$=MUhFwu4^GYbOcC44w98^F)>n0dRVdzPBm8(JJx4@t=zPBM*~qu#G+CO_12#(MdDt)XO;+ z<=ygxKvEGm2i-fgHYMf+`$oVKcYn+sYukp^(5w=65(Mi>+mloYZ_tM}(qmIUedZg^ zjZbQhgQCgT!dD6(AE2eb{h!vtS&|v%7}@z3=9BYd`6M7xo(~ucb=QqIauq~_C=@I6 zTQwrJee0cQz1jOquwx0>()H$xQ)^&w5Xuy}>7l*ArO7cCbwr8B!J8iz7kR@>pf7I2 zjT6B+3GK!*!32qQOp>{knh8uDmu>v?en+#(j!&kpi7~3IlrQv+j$PeZcQ-qyoCqW* z+j0NeEW2X7Gi#3QCw0%YXa131kx=I_rjHBz3o^= zYb(*;45qUY<)d`M*2cp(vPhPA5bFo8VI38vs0&xoVhH}}<|^%#gd!6Qx+HjdnXPp% zZrKg}siQWMMb3dvhm@d}IIie%pcUx%!1_tbn?7{%QQ^rRIQO>pY>STM64Qv$;P13P zu)Pf-cgh7b-~y^1QM7aH8)wQola5;~q%E|;bNyWSi2oE%V+*x|oC>lIP3CP9F3jx%uNK2V$BZ$73Iv`RbjEa_I*C~Bq zyqOY5P^pleor0mpjn=wvhEj6hIhz3*342Z+iBYe`KC1deBSb?dW3NQfQVO3Qnz>xrv!Yn$>_qX*_cqUk0Dr2JM69xu%W~nAZ(4QCAv1&V z8b%!s^B3%RevG8qFB<9f5v5?Nu(-kkZ8Or}MH!vO^@wA+@gnH$JK5!HGa}<5J{kMv zRBENU8Qu=!Omht0JO{Rtl!x_kQ}KJnKmQP-9@cBz5cy(7>bW7NdEpN1!&es3bBU+% zYZTOJaktAu_MK5*4M>4CW;DCYLk3<>oj$FA!RbXWI^*LJxZ0teagUCM)Ra(vdn|dK z>uEd|eCR|0o;QBn)IMD9TZvmpa-!0l)L)7fD8J)E4WYPNb#X0f1&*HObiPjB+9ydC zO7b!=_^!}p7lWl5D91RCtyqI=$3rpS>z$d70NZIgc&AxjvOPQrA>a+ksH&{Y^@23qPkq zFWSAJgw+~AY*ua;9N>xrMsXoKUXCw1V9dJxG?^dgId}tY#XM_*iWV#hByeDUl{MVMka?yB9 zc*CD_5c*2UqAz(NhxM=j=1};T1~VEO%clo`O9iJ z;~-JtQopp~(9fUHT$7gOm*#YRF+O6EIa7I|)^0R)+XJL>r#Z zk&%yx zvf(smh=zA|--uSMup8=RL;aZ|%0&_1k*uCUp}`?I=dfoSsC1@(bHccd4AN;SBj95B z%C0|vmQ`r-k|>lqA;Egam(HZtl1K?g+J0C)M{hxq^35QY=7N>^S@aNIBYzXelb#2S zYhJ581k;Gsh;5%$f~q8WO_awQBSMK^LGPU`7b_?6Cy_zYch&(>gCaDy@HRA4GC{V* z9=s&EiJfa_9q2*p>IF2Xb9wY5Y^Kf5Sa7>^Fvr+m`cDO||tpVB-Ie1boqsYoMEpLIX z5DV9Z{J?lW?x|$>6~Aq zprY7B8CIzb&u~jxWSbFrGJ_+fSce=@hvfR)%J~ALLWHDJtCx|3;zEheoBmMQooml3 ziCNP%#H?HfdjGwds8%iT-pIi# zKko8VwfdlPOw*26?`rek#sgP=v+d&-u9S-jxdqY7XdM#KteN4&pivii#$sL@do|1j zPRUat%O*mm`vvjP9H7`70ZYv_?x-^EsIMkuDr72wQ;+RrbmgFzcy{FLp|^)0H3_qETN#884iGx!slWK!=D8>Fz}B9Nwas&c zVkH{=O-co~uClR9(ZP3c#vy?YhHPQ4Lft-p{;ON|m&%+bLTxbeJ8IT_zyGu_{Ext; zf2~7*FGBw(_T_S1ziBqTemp&W9$5s`4Ce3q&L7qDxv}$*7XKGP1tHkq!AnQNSlrkv zQ%6N#osj4cxATXs(KqP@Kj4)k#O>tuQ(V1dgv2r&IviRG8oztEces1}AE7CKr325a zEeY@M_Fv|A`|sZ+X!b^bY2}UV>G<^>9PRZC9RF6h|2v=|L3!dkRiJ-$5U)rl798aH z4idtIvhFC>NU!+}_!I~OnevCs1Sy?`D|WEw znb>5uyFTn67d(3)NxX=Sxh@}VJpJ~Xdb;bJqJz8o`tb|h2xf?(aEB#dDV(i02m+>R zY(f|Yl9c2qmN#Vlyj{Tp{1ANJNBUcnmx}MkZ&bWtAY-JO&XMPC$p8S zQZ$7J>P8eUpJb8(7kCKW^-xAMeM%^&7qI1^@La2Qs(m_6xf&vPN|XTnF)y=(Z(zAR zoU8b3hfYPS2&*i?7z(==-!C$afd+{K>D>KRI9Ge1R<&ZXQ?0N-7&xRVj%sQZoXzD# zVJtYTi%#o8GNQPVk$(Nic9Pi!-bRCC&XJv`wggmYEa?fwG-pT^8cD|7hQRa12f`8S z+1=M)S4O^vL(V2lXNe4#s5{^H6BQ{G+Lnj(ovy6XfR*r)SClD?(q>V31=`05ZgDx* zaMDVTHZs@BRjxMADe;JN3;Yz+RmxMtAD8EqwBeA?R91#(OxY7Rbvt9&v6QIX0?!gq zt!%9DOf`dmDLBSPBz*KMF|0?+Ug&!|`=6TI-c+^RaT~ADHr`b!7nNsus|6Wz3yOzz%&{eNcyq;T)3MQCz zkJ#mPACWJ5JPcsCrfeV>1dQ72)w56wn4zP$sqk{Bx ztzrj>5eE*>f(91#5{Iqi4f;lX2kfK$;=nC(;xLK{{@;FsQ6jg56Djo1)>>UbD^jP( zddv4|a1fs>5Ff_I4P$B=QGB*?crE^@>#u@u1+eX8|2pwsd1-rnQhoP(tF9C5#}BIS zQ~wLw^rs zmxrj8cVGtsVQ{7BO+c%UXyV-; z7=QndD}HhiLSLI&Fh9S}fK$lNgkSOlFd;Ujnk`Tia?4gvGWon8wli6Bq)P0(U-~~)5fwnW1P=N+U zeTY;S6REa~ZWF{Zxt3?^<+el7N4QMqR_L^SQtE6iXP3u?!<@aPP@?QB9;9sLx%*pJ zHMht#@J!`JaLdd%o2$d9+#Yk&RJ}L-&R%@2ha8Oy)T?PUYlw+SbVj4H&!|(W>*f+U zdMqP9nT{!D3>ZwURGUf0kRk^rHto#Xyz`~j8&4S0v9BGb#65YnGihm|yQQ}4~rfxVp+O0)flYypjkku{Pf>OYs za2qDCN1aola#I#AKKhsKP${u+_bx#fMNta%8F=>D>bnXudxl*Z_Fqx71nJG?yh`M}eYC~dg zqO|LrT-+(OG9TX@Fh*fq;*6YF#6^ih%TK|!j?ri0y1&Gp@K<^kk+(18o?_6#Dzd-7 z;*^&fp3IMVDSLeetx6Y!iAuo5jcCzz=!Jgz9q7)$Iq!h~mfBU9ReUrsf|o$sFSF)5!LDI)Tpp*)8>J920zw?Z>lOflGuX6&81YAz^i&+#^(u96Z z9MgWxv+aw1hTJ&4+}#z}-I3t^4#D;y4>2XO1lq{2+Mt_L+}H(L8DdgScJabEob*%u zQ#c8_{Um1DfFF2-BJ=39M3GeU0oYF4n3aUG*N~_uU4CiH0ti3#N9ev7MC`EZ#E1l~ zQu0Z)@Fhs_XziHh{n#~{#gzOlkL(~E@S(cEy#P~8{Q1M% z|7Sn?{W=AFwyz@Y%6Y67ohub0n_W z*@CU0hV`gmR-hLSKeQ?OJbk{NS|1HclheGu&_Ho0@gJM%dMT6S9;A>$jCjM#kYB|z zDT&D%+UoF+*t)~9B+;W7+-Zl66jN;?1L}-W&>0j&V^9H3L{x~4)tTU$%ONS$Y!&K5 zlj>I_MnTx zd9Vea`<0-TX$`B80!>>EMbpXD zc_`QgRfh9tO;oG~qB9+w_Ij_$Y8gN6VV`1XM6OxgUSm5Qa4Fa=MKP@3?ePwlApNA> z^Tk6Fn>pRhLDofc_8yKBhe+v0{*xL%kZ*++R0a!BzhT7vo8! z%Rr>9Z^*47(DFw(1kR!0o!6f|rgqQh&rr2vq) zH-b-CvrsC6AXZpU`JZy$+Kx4mfjt^m(x#l~N0|nz-lZ~NlmnhrgA1!n>EiJ_kW@eE zbjV|3aQPO9uXoTxeP2qm=kU2%b!o!lXev3PC==LUJRO_aY{i~@?5N<;9UU~sJn?Ry z1xZ%#pEVJyLp3z%A7T}5>vkGBaqXZm2=n+7X{H5ss|^0I)VWx0_uDKdY{w3wxP>)R z_4q;_ccTCbCg1T34=`j>Oo+V}hKJdpp&%m3s5>>o$pjqxIfC-;Vgr5dAN#Xtb8GPAdx$kgBbhnY?|erm+kq(I4p4MEvTV5@C1zh;V2P zaIDa5#^c0pM|wtZeCj*dQ3+{UJp;pEhQIWG0EnP|6Fosu;lq4U#26W>0siKsGW~N@Q8Kc!wbXMo63}xnGW>^&NP>!_&0k`YN}f!vOsO={v&0iBe}R!Q zmUvb^1%ZueQT(Vz=Z(UvoBhF*dEB%VyHp{4VU_nk<n7Vz zg%Ub5km%zv7#52Xp!&38k&s(Wx4Qzvn7`zv*ej8s8HqW|6hOu%$mV>HnqPb?ssAu4 zr6NO5eCL2c%7OH2MwLoFGAkmIHA+L8shGFb97HKDUP1eQTD8ufHfTb#NSFE7{z>D( z`YpdecGC~SMhHf_Gz<`6X^QO%c4_#)O_X5-3+rTDHtR;`MwH|zIh|Ep_jkHcX-mjk zUUC#_wCn@0prKt@X7Orh0{=KA3Hp@yJhw>Tdm`$=^7P#|1Dmkc58Cc8n4;@9?lU-^ zgNO6esonKrk%}JWLzKxOAdmAjVFD~xz*s_yp2bJ03&+@#%@u^2ge76qQ+8elZSc8P zDi>Q#O;y;q6abBR(VHjqDFp^F_vqQB=OPx^Lx)HjHkZEm5p|ev@s^Mgn*xbO8!UH8 z14uZx`3ka+PuH%91F@1)*mAWR^Zgp-!=1y9^u^$&m+MAG`D{F4mWx-_iZ`5aN3kbi zHA3-xEeNDCSnWQtzu}wVxi3Y=0+-t@Mo%6P1ae3=VgKwZ{UTW!a$xE$%>3Qv8|q$1 zN85BIrwaW&nHg@oB@|m&7>}8(1Z~h%rA?(UUf|pz)B~T|R#i>AJLk54$zgel^S!+JEn^JO8Daue&eQ#KYfGDROnc z7}C)4fHf$rowYS|D(cX{hq=KA)}adPgPl)Cm=?OpgOFP?WcoY9IZy5w*!02+dhr7} zCM0tx*bDAJo_v-6%v#9oBN=!q7lfjnzwP&eBzq{EZ?rqqkQhk<1!q|)QJteK+2$SU zhiLz6LZ))@RQH=fAtH-G+4O87Vw})BLJ@AK+?aXARQ;}PfX{3W5+*qjq!TWGT1UYFwBsBbI%ZFC)F>pB zq?oPYDTj1?Wa|8H4ZYrD=G<1aj=^@emtrOF zM}n?9IhnrplreVxl$F&5klb5`&xx=I57GO_l#3HyQJ>Jq6+TYP)D=7bEe`)hhH4_* zK7E0{h+ri9;#~OxG70)m3y@bol0th-NV_ez4&qrQ#l&=rB8BFGL`SWB6>`8tcP;cM z$m|G7;HNFo{Jsi>e6;flWkFqx6{v1uD;0XHy^$m{VUz0&u{60VOLNP_MQtlv0&k11 zGr9st-+tuXBE4`g>SASeK*lm+Lh49?+Fs-`NpPw1s1j8}DGBvU`-u=YQ0++({^xH0 zv|S0bH;|7Wt0zE%;oYj&E}{hIEM?ADaGDc;xrc58V-wcV4s_lUVY6p?tN0`i$VfyV zcU4PA4hADI)IzIO@I&pX^1d!6V+s1n@ql8WFI8aKI0cUO@#4%Mcp&ESGcg0-oHu)6 zPE>|+J@Fw%6~}UY{vk|8=#ejMj6S8X;e}ixE9+sZKka%A+P`TQWllsZPnclJhz$)u zSf3gLXvP9D35*IVU@;r<7qQv}tS(=Gq8swbDXx9WS-1C6y3RLfa-b(Q3t0{dEAk#N}2DLd%}d<577 zcM>ng24Qsd6v>w8Ir<6T9UUJHsz7m1IJPgy4x5~F-=jKYr$|Jke5pQaf_Wxhdz0ik zmfh_}O^r+Sfb!wgTaKHC$yf1Rq)R8fYoC>#Fi^*&>l#ffZ z3h869xHwW>?_BroLrqCNzNXPB^)RMo>FSqL?;<5idy;#BpdlUz8ZL;AfCCSHPicE< z>OyDG3r8FGd#go~K<<@c1Qh8u1(~dXYcP+@3_I%UFs&K+9}O3-@cJXeCua)sl(R+L z@xIaIw(vU4{>BQu*aQt?1G(-IRzn)drga%k82SQ%7T*8DfZ{1tZlNob-~xcF&KwHMgBI$fXXf-*JmNQ8`7{ zv3$^tt6bups~@HdfOM?kHOgUcN`TfAu>fSkL%5;gz;6ErdaC{Lt(I z*7qUqkE51&KHNjLe4xP?%0xigV3DB0{i=ZG*j>jvPaT&g=sNQtk&X;z-sF9Ul-FrF zPK!>USXY<;wWn~s;jgqL;P((`?9c{f=I;0A6tIldsK>71UZ=t6Ok-4kh$f;z68t#K zy+_7WTe)8dPk=*KDRSSXLlF-9IRhKW_5ZW>6K zZ@->>$zgOT%znGMpk|C;VP0!8*W7E8u)h8aDyT^$pn=Wb;HA2RECPS;@NShM8HK5F zFPx*>)W|m1M-36NN!s+j&$m^-@Zgzv3yUXO^|0h+klh&GrWYUE&fMJ*a>NmTu`WYq zGOLJ?Yu_5PfjZ7#wY0Hy^qil3G5xiRaUM=05owPYcxZ5@%Of*xa0=JwX`O$v(NpKy z%j2PDyw5=zcRwdoY~)Xr8nm*?@t2e1X76gxAnT*Ckz|hQP0CCY$JN$I_6%u?d%AQC z`aXHnA37~+n(=yZr|wPibN5#RL1XGQZszhU?`?3@(u-|dMN^X**cS?iOdInId{;YN zcgH%d2Qi7b!uWjOZY#~We^@SP#t*KEGI7_TN>IN;(DT6-ztl?w-29LsqLhwy&(BMV z8F6*P6)DEp=2{Hnw6lR`ogxk>X|f4vpGQo3Si(;9W_?kzj+oXpg62qWp986d>jEw$ z5eF}@sWqb`_L=2NYEeomeP=i#n98UFK*)Z!$jp%>*amp9wBwPq^?e`~Hf?)DX-y~A zeUdESg%R?1+A@W54s&d42ZBj4axDhlc$1ZHwlUeXKMc?aBMBP(gLl*N?5o!F`rmtxaJ|gl`{qWA(_-+@_syL zOuKcCLQKE4G`^FXP}~Sb7^#n_iYjwkPdDhDKrz`4(&myu-(4JcX4E|6qFS0Kni#7x zOr`D57UUUm$KrYCZOH;1tgpKgDVoK>`9XsrJ_%SY?#+R!sR0F8XEja?;p}oLuFiFibmw_TkNzEe@6q zVB0Tuc1x6Lw-FDEV!Z0@;6W5Q;UWilLRKGJ-IgH%0ZfYeYp&REVpn2(o<6Gw#WW?i zL67dQWIUxokLSbX#l_PaP3*EoQ03+%8a0etzBGvzDOuB#Fl94#xl?OwyUX~l5A`C| zRTt!EI)?mSb~l8X<2o$1o^2E9RMhwTx7)QmO?q01%2d3!E#)Cs@D*z-OTsDQ<~W}6 z+-0=dFta_L?@!s%ebLt`6XM1xhiF~)yH_LlrCgNzuH_uJM3|-)a}muTRF|5Y&{tL= zR>#$Ki^yq<3K+l6s(8|Y_7JUnO9Nq$oLhxxAVV~~@U5p0CG!-)o?<%J0N{I91s#oY zi(TvL(W;(sJCmTIWedd%bY~wm>=}zMhs%7yZ7pP6sULfS&=j|fOk_zlYr~+KvZDhI@>q|}q`zDI~H`E=6F|yAbzMmbYJB0CH zx!H5F9`|YyDQs6YnhrZHZ17*!(wuL!FdqhI1F{P>-sGQ*(}2J zteVl5MgsZxr}z|KNr=t)lDpyeu}MLUps z9r9b2Z%B0dWEA}>9q<}>9LS({!4MuWyg$aIsk&c%ahLD{7~W22vMM5>!q!V5J(*9k z(2u2>z$`y-jbck#NwO1>^WuBt4w$%Tjpdc zhuge)>f2RY{v+`mb3z4v`ru`4KM>K{wl_#<|tgrz#u_MA-^opjc(WRyjXL4dUer47*t%0pj}nE@Yn$=e?bX_2Lfa-aYAnOq_j%y>X}>WNYn|W z4cESXtM@d*GUio8A{X~ar++KmK8COyZ*A1Oy_XuEiK-Ie%@KsuE&^V%mgToEy#-lR ze~ckloe+(FA&`1`E+H{TX$9YB?S0UL7$TMlD~sA&Q!6S~NzF2H%w=)T)a7Mx zXM}3YO~)NKcQ0+F(6MHxWxQc9w+ae_)2{LHbv!Cze+z4I7u&+Pq04Xl)k<0J#u9uQ zdG^XnhK+}&UWqC3z6~n`}-ztmY$UpE?BHF=T3y6gbxS5o0c|Qp7BGQ8cJL#R zbM{qz+?LGzC73I-$`jSgCUP)NR0P);nsGzdHDhe8I=2l~`CnOOQnNcPa7%33cwSdk zN*Hy0D51At*+aar@5ybki{-}LugoGqL!UY<;Mjm_SJw7sIq303eKLB>5$r&L;^U^S ziu+#QR@CDKHH{XP+|x~-fXz0eD(v|;={5^*r8D=7km8wB^cp=@nL-W5!|wpyP*>A@ zj@hA2ses8PW>eLVGQ8kaZAlCR%Vus4P;J3H*F z9Xc1gV_W78qZRyp4&+=Jj1Gi0kCG=G&BuHwACh02DLVTMe`Iabzp?2;%(CgLE3b)F zt$ueqJ}la#@VIk9w(4lf$bHi@Th?sxns9%%NUm%5xQ~hsej5^g!UD@TSY1o!Rj=US z_usiHz#Gh^^oj0Wbob^p@DjI{Tc2q+sjWh+I{{H7Zp#<*XljRlrn4}3Fnf6Mc_x=4^J;<7-_s4C&4Es$cx}uY>H7v`QWC_k3J*|IB+XX^H0+` zGh9*evRSF5^=N$jd@ttGWQEW^Ay63`E)QF8X7Bjs3GgG*2-)`&bk^TY=^WO6MK(85 zP4FRU!aSrdsR$OmNH2^l^yZG$j36;rkPhvea(Vn)QQc`hNc4$Mqy!^bRh~Tkl+k0C zA#tVG0mcwn8EJV-9!=w`%7DfiCoIj4%WC%*ki=y;`2wz!cKe4O1!(XwewR?`=KAH`9z(;BOQ_W zTq-A!W_6a7;T5l`j$9!>d&9)!m(FY$VQ3y4c7cO z;3ZNDy5M-MR?Roy-pC#t>)vGPO{Shh-Wq>!hFG-Rb&)}nZH{>%l1E=D+xHJ@kT!## zH;Ql#q|&<(sEI7((^rbx?sbXv#AuDa7W^b2S!E!EvTr;g*5lXnmhoV6Pveja>d7<^?ZyBX{Y81LI_NqtIVX z@7mCa7~S59^t$YQrB;x^!TXBHR^J*Gz8&2o&$s#BWi6cu-F6`l;qW$1i$b2XyP$U0 z?(f|^CV*bK0KTVGAP0oIGr%iJ=oNJy?l$%u5{?!?#9`xT1>|pa2e~@_vr8;Y^GAYw ze-aT-@u^aD^gGD3bi68(S@qYnafy+sv@38KHPkSiuf??}7?Co(At`p1n%8w+97RP; zNKg}`96CbyhLrxa3P-yx|8?4dx##=AY=L!(aFcdey(bEAF1Yg%rs9$7jL+x5abdKD zjNLca7}v`8)-E+w`99O~afzAYO7n*pmnh=P5Rb z>!m>VCHr`_MwnfHw7SiqX)jbA4*!%1Z zi!pB}YK`?h#&?==8e~5+!Mm+Y7RPVZQPwF&eLoy6e-To^(wF+QbmHkl6VW;ZoNu*8 z?DYs!4bn4Cn+L-F>83-h-!T|QK4SQ1I|*{LyFKiXAu^>5Dh^_HTq`5elb-ItP9u7F zcg${<^gUt9kz`(-kkobXyp5j2H`hL~Y{H&9s=M@9Ry}*6AK4f%wFY-xP(8SvjWsjO z(&V+nED|T2zEyYWSjA5k2Ek1?3N9AS##RxcA#7wt45M17t`R&?t&6%D)gx`qHd4*Y zrCj;RoTHc%r_ee>CW|xUm1*!^re7iN{ql8%TFDkHT(CA@y828JBYG3oE2K6W12T!| zSu(TdUts5*@I1G^TJ1~qsaUq7Eh>#X>I8tWw`+rX5r5U2%iWa_F6 zMXl2SeWOXUYm89rVwY4;cL{sXs*lbXex0jlr(H6JbcsY)4V8r&-{yEB5!b-l7AzmT zy-f@2A-?z!FPPC7# z>lm|=q|-?C!?7Nf%+DAb59KnoYTmzj*Syg}9hZbM;|dSw*lSe1?TNoeW$MxUeh9zF z7hcw7GQg2Qw56HIC6h-W!Ugk7;cB8AvKXDC$cv9}_adZo#ue24+fB*6q|949?pzKs zEZUEJs5(xBp+i*pAnKBhRClb}Br-GG7;#%?no*GGuy}7H%y{BcWit8QRl$&2VQ?Z1 zZit%uKtva7*{YgIq6qqUC8tTRD1K-`EZTQD0pw>hjCM;7@12n|lhY2zW8wA9z zG}LkzwM+7`h3;V=%Ta4mRd&t`?foci1fPOUg7MZti(>?eMNMg&lXr zsV_0b4xRJ6i-;@!h zh&znL%)W_w6cVb0?20t2P}a1K3hiGrk}6E40jr)klXLxte^qro*QkHF*Q91;lBAu~ zl)6i{48;ZN+RT!ju*l^al-DK1I$(t?Q=0`<9td1t0(ae+eO^Lvg_5ek`C86r^dl_x zuo`piI;|&ZURG9C?;iWKd~?|amUsxSG11oKNW-!4G)8G~-q3XMM{ud4&#&avN+C)S zske)!?~M9Z2NEjXq|m!^KQ?sZmGINr>31}mNFSTf&C?~?1b}2hqimB)7;?w#2jtmC z;i8$ZJGgU=Ue<{jIYTsu# za-i4|suE@>&s^~jy?a=2_2!`}>&C4q3ZY<0CWm?&rS)!jH^LE<6_*im*B7|(_uYm! zuaJVP9CN~w*U)71x;G~!jQ6zy?IeQ1xR$(H&Qdbkoy4}pj%K-3SF4TCmlNnbWxyq? z)Z8hhupWo~SYB*q>3;Y&%5X!fw~#vx>p9Ajo05SInIc?46!ShVKe@-;VC+s2+Qkhi+8KopTL&+W z!V`?t{E?Ys*F$yXu8_EMXP3?6lPTm@O;Q!1SI~ujjZR7JVIE4RL)?qkcbtP`$8I46 z89fDMeOer&B%>N6Wch}|g`(v&D#7<5LeJt=e6I#$!MdZKR<^y|<&}7(qNu>%mIpvq zWNxm94~GMjS;fGI8fsGOhZUYCJh z*UaSQZPoM0ufx-XD7mVbxwwE_RVo62<>7JSQN*$cu%R{o*J}BSZody*z=LE4EVE?( zOEok>E*>C9bI`x%s%SfCl4ui(3A}wk#fqshDv%)Q;F5f;T&srnn&L~1k*z`r>biQz zB!{VH<WgW=xfiKtkOD@hIS?eCVaBIRsGG_U&*R%%r{355l@ zcDtiBe6ZNhTYg@jqfIaylw-cw&Og1@Y=b`lSNS2yqNl`Vu*@62B#9A&S?Xq)bu)>> zg94?d_ltvgigDk}#)(Xl!}wxuO3e-gYUq2CnyaqKbPDC@)|AiT_*GCBnWEmYc_XVc zYwwjuT)N!^7FvP(w*AZnU8K+UO}A8&=;+pE^8RU@s0K0#&z+Kv)bBL$X}hsgJUp8y zF?lJ^0^EJZI~}CU`^bx!S5a=1tW26F16exl^T(*MP{Kgjn(g`RSh>uT{8&}odp(oO zRteX%HZ{z~*Hus=kI*L9pW)PXMC7fdyt7kRUd>$-qMA}I=)>1B&sDAqdh~D;fqzuL zWi{G?1;_7^j707hahmY_=H)gT|3;*+J6JKJJNRtzb9eCwqbaU+#m`O(-TqF%xP7O9 zHb7<;Q%u|X(-Bc6*};Zp}j zK|N)-=nU%@=LK}>4ZcFzE_sY?vK4gcnr`u1E0ZFU39$#IbURd%aM9bsUtY_lQefuA zS$phmN@*KQZogns2T>GA>)kh}T)%@V4PP{~puqbe{#}zba|_zs7V@5UL(pS16IC7UNC}ybOSe1R&CLZY*}!KYn|9q&jrP$DOFDG%Z>OHyTrp0USw|i4rRG9r& zx!d_Q@9Do&CNdsm+I)w((x>y>;{~g4cIo7U%gu%au~V(FQ?C5IzO5J&MriDUpk77P z!({VpID>kP`MrCOHS5z!;u|(5nwvHzcE+MW&DoZNiC@z+KkermNl;GS_f152mc90(kpWM;?Jf+Tc_W= zt+9iHx5A#%V0cImwlXlmAE=P*7spZ`wW2E7~Y~Go&kpEb(6W zauCDd-Hp*K;Y2T^*Xm)fN$%Yh4%DSgnr!$`vHSoe{1G)2pS58uEJEGp6>AGJ2Wz5n z^0T7G2!YFACf#BSBUB5$Z>#FphPj*VD&XFk`@~2-AI%7Mkuac_+5X~@>G@S~gXqZq zi_LT8yN}JDmE(rRl4&S4J{&gyUT_74er{xrPCl$q-%c^rVeuetb>Q7WDNfyxtC!K; z+%8gNVel{`A7|gZ<*RTvMQV70$BszW?pXekEj&0o@vO&3yL1dIq^zngoQPk1geSU7XXi1NYN8x99&=R8J zJ_nB6uQfxhIDiw#Wb_~XF7#z_=K6|&V7mNtzE=6U%Ut;fIrA=Vo ztxH@y3L5PXKRvdbs%$lu1`ZjO03vbvbDV{%2k4v_C`?URvGW>kj>BkakFA}@lCj~@$seK(M8I&;-{ z1}5j`I5^Uhhz->czn<*_XUdQT<(N>&$Z8znK=hUhrM5To|{zyW+f7Yw%;e~Gz zavJTQ3d&2lEd`y$?(}YlETb~0k9vXCsS%iyo-Be{=nC^++#GD$DGgp3j1yTnnA-N? zbm2B=_f=G%$F;j(A||CD7UDOv;{M(2O$cYCs0))v-D?f7Ia_)DB}K%$Y*Js_r_dfb z6|HY8c}JN#N$e>G`4jH;qse@64H5pV&i1muV5p41m*eJ(ODK8;1`6R0Z?ss5U@Jqf zd84m49j4rpup8*TykuHo51PDDu8#NUl{5U_QI9%#M;SpLe%x-r8xoWKY^KU>Wa!aQ z&z(&RUtskW4$A2hsD8wux;FL}Ql_pJP?Jr-1{o(DIoxkOcE0AdL72Tww{x=$7pmY3 zY+P&_QxY(ppIyG5g$XB^y_dvVHU9AydeFNv>9OdFHh2x~Jvt8meC(PM+2IBq+rVpq zk|p0lbV^n;_vY1lhs8e(Wb#-IeQt9b8u)f}a1al>JLd`C6C82#Mi&v5Rmj%-4S4!P z(P!ZeA()(WW(HlKDT6bxT&N;s2X^KPBNYAG2E>X(te@gGWTKiO4qdh`--`8NFTe5J zS$=`xUWDFkv`oPDWnbOT&dQ-rFf&wQ(Mk{zhtRor>VAldR`B)~xung*f@7O$V^U71iRfa>n*@aQ zrF=Y^MHuC2rEex4r1s+vX;CLG7aYpIAmN*)sVKlj5zv-eXPaoATQd^4)Gdvip1DGedz)t}`e)mto3cE+RVpk7hiuhqy!K!{hsQ3J{AL|P zMlY3)(=55{?^6aKyj^^$oVS8(sD3||*@vO|<>eIW@21nQHj2>Zgo#%23Psm;OCpGu z?yDh=);U@r;IY(Rk$1OImr}RFR2I?Q?j6S7yr(O{RrzMEP{;cU%9YyLTh^842?{Pa zcN{J2=nz)lmQqc`34?T~8rPo$Ht0B0>(*&G=q-oYlv6#54=?8J!+x0GGu3p33Pd;& zY=)+X+FfNi!H}lK=Cm%vZClyx^Z2?kpW;)JKCa!EB{PBRSei^KRf->@n9}ey(P+G+ z`nysj?OSQSm}BpF%RO~L+j)76mdoLY2JVX%P8BH#SoL;naSjQ-MA98wVCzaVCoJa? z0>tu6rWl^`jbS+0^DAjv?CBQlt>FhmS+=#*b0Bwl!l&|iQy8>%8-%D(ROk=IwQctM}(%J}Zp|(1cE_V&ZQ%M}$m1OSqS%_(3=QP2&w&J(a3_ zZBNGf>ikw}kE)v_RuZU%T+9b4500^@St3y6igu)=DFQ<TrBzxQ0O zG?0x`QGy-&t|HPLcj0xMQ6b5SSw=0hvYTiIsgtnovzS+s5#hiz7VvVnUIH(0Zn-#; zha0kp+SP4E3DTS0KIEEJtxF~oV`hJ5oJ9oex3c%2<%J1<@09|^(WxM8e6rFWiSu#J z1#YpRiD?^0+LTB_hzbeh9$;9aw{0#GV8BwZJ*-UVd5wW=GY@Pki?BA@7P z^D5iJPlBU1ciZ56){4Hq_rQJy?!c+ztXMFK;GUtdJ_rppk0EgCDxX*ZHs8a-;lcyH z8d#P9S)u^+oWCw)7+{|E$At;A@#8njGFlRB@+z_%-=4z&^AA67MS_9MKuqpmW%CC9 zdo=LD{pY?Pe-{Tq_DlY{RartsURFj^i(OgvgmAWSK%{>!Na16^zfX2t{(c{%=)9)CQy|UoQtYN-C}3_Xz(Q4;UkqS6D=3Hf zJPL4RkAtbBg_4cqztcabf$ZLwHNpX4A^@a-0-6Fpo`@v{*{^&0xS!u)5CdyqD)3ze zW~2lF>w-+K{k)2U=xEQtAZKjKc>hS~;N<$x0QEGlP^hpO5+r2-DS}9T!hrAMAQj*w z>)(X?Q!OEaF{jQgy8~*b17PG(AUN*dL2|C9&eoD1K=1`}{dorVX`!|P^&+nVl{^9} z3CUaZ^C}K{$a@j%Z1sLLrl8+dL15rc0u0<4eqw-cz!Ql6PWo{gDe(Hy$-~wB%(0}u ziwA+yNJmT609BO%s!9a~ExYy%;?IC}+XHd}ZTRad4$6=`2lp$9 zCar|4`T4a@11BKd0Q6T5JVKPec#vAZl>QU(eAlS=)r zIf#)ox(4m)04Ov71^tBLsz9S$fxN>Pna7n!ri;YbFfe7n=n5Z7pnTP{l(UtBNRsRF znxP4hf(>XxXcc`l{hguh=n8UkviAg8s5n`GE|Tb`H23-~p!tM>z6;v;mn<%(os|q? zU5h?)ZLEM~B$rM<;n~)|vw-z^{~8$dLiyiy4&iyU;*dlGI+p?D9NPDR z7D@zo&`zZ%?t+=)k4bsPY`2Lz;ssyJ-;1<*h8mLdvN znE?|L1=DG0E==0EQ;|b7x*p?icLHp zE$!rCW)Hep0T4U&f4=4i0;pg>v(PPHn0!7})&^v6p#ieImp-wvjK&=2M9h3@grk@X$cl-;|pV=t@;%4sw^#^*nUsrLEd*+2m zkgKJsIY=4gZte7UP0Xn&KY+9wL}O8?x+j`X9RN)So(X9C-OW26{BIww<>UMZOM_U%8^hs&OaR>o zprIS@Q^EP@zZx0(GfXZ80O<)lanO&%i{kT<|4ad1Y-Nx~0>v}@Ya5_kqcaU=a`$|y zwwA2m#Y{-$JvAhUe1T{v799qL1FFGH%YSG7Hb(g2U8Nv?+fCCQ*wpO+oKJbaXQ04| z&0_*okO(*(Abk9F6$ddr_!C?c1gy9DBe`!u{8c2-URr>Agno*1>MkPxkXQrc=3#$< zxc8M1GuZ*%76bZ_`6VpGcx{_6fJ%cbO#z;oE65T^m;GBg`2~2_1y~>hipmCtt(-sUz;|&_SjV3W_(xNJ?(MCj zSDwcK+M)&`OXvok>b{WvbFlftjxOp{o|cXaJ%Y#$G_U}a+;s#0mHgMCSmr$@ttj9H zo;CkJ`A~kAQykPb`qx5$7PfJ;akp`DR5OKyr)TvKd1hy3v)Aqc+%LcfI^4?s@Yf=M zxoGQ)8vugW@bpth1xz*?Xawk9B4gt};eTa>Ixm*};dC^xJ1haZ2{8BqMsB~Z;-I~) z|F49z3W7MG_giQ(0l*W$3p6(SFFM3PD-Zt8cXcucxw&05nr+E$fGGsn2>=_~xp@HX zani&6=G;z#NMK;)403h10lA$O9HJPqNifbapn4c!91q>qSsecrevuo3fQO1~^XUPp z4*|FoltwCGVgDxeFTY9q&%jID5in4o3$XZMspr>ZTJwWtG*AmfV3G*B3Air(_X5vn zyMP*-AcJG0GX{!unsSn8Yw@2sZ0{wj?2C@7Ef8Ga?K>HQ~A3CUZeo1r@ z{#QS9R$>T}&-Ec05XHg_0Uu~x+#&ue^53rOd~#xnsEi*#1qL6d#&rQC7m)vC?mTx3Q2-r!!DI>$BFzHL#srA^^C}LSqWB~CVmAxH z-n8eS!w1CWM?CEW8>lY80x`^gx8cO8^|=^8-fw`c&?Y;=cmWZz80Jrwz%K;LTm>Ly z0rf%$D6PyFAc3h4=-`Bw>!RMPyMLhx5;AuKbZFPs!1~|mXCDcOGH_6z>2v^!*asR7 zn*D_RKeM^dXIrSl=)VTsPC4L~p~Ig+uK&yi^z`q{>iLDB-hN&=1r#7eaN1iO^8eRD z&L{Vpu@3M7s;L30Kn-PiI{5`Gd?=xK$x`R>fW`V| z9_|C?P_7E~N`aPzOF zoGb#+MgKCj^Tj@W-oy#p#P=-wq89~_hv9VY^%GL= z?Tbi%2znvbdOG|03DPm>cO)>X|37k}pN{cPrz1WoMGAa=DHkRu{v8d`$?3emCuqL# zbI})N0X_{roh9@Hd=q$aaN-_+Y32v`)Z_B!c;olZD% zLWjw{h%R+DkMwE%oK7ckg7vv`5%xc81tRz9ouelOY~KC7fFJ7u&fiCRTISPR08fxU z6=#s=ZwNe%JiY(w1gTnm26^sotlxc zhJ1FX4)hk6-?@WC4K=aR(4b!u${C%@R8R literal 0 HcmV?d00001 From 41848ac6fac9733af50831d50fb106b7207c3469 Mon Sep 17 00:00:00 2001 From: David Rajchenbach-Teller Date: Mon, 10 Nov 2014 13:58:14 +0100 Subject: [PATCH 03/29] Bug 1044020 - Add duration of shutdown phases to Telemetry. r=froydnj --- browser/installer/package-manifest.in | 3 + build/sanitizers/lsan_suppressions.txt | 2 + toolkit/components/moz.build | 4 +- toolkit/components/telemetry/Histograms.json | 28 ++ toolkit/components/terminator/moz.build | 3 + .../components/terminator/nsTerminator.cpp | 442 +++++++++++++++--- toolkit/components/terminator/nsTerminator.h | 7 + .../terminator/nsTerminatorTelemetry.js | 105 +++++ .../components/terminator/terminator.manifest | 3 + .../tests/xpcshell/test_terminator_record.js | 108 +++++ .../tests/xpcshell/test_terminator_reload.js | 85 ++++ .../terminator/tests/xpcshell/xpcshell.ini | 7 + .../test/unit/test_crash_terminator.js | 4 +- 13 files changed, 746 insertions(+), 55 deletions(-) create mode 100644 toolkit/components/terminator/nsTerminatorTelemetry.js create mode 100644 toolkit/components/terminator/tests/xpcshell/test_terminator_record.js create mode 100644 toolkit/components/terminator/tests/xpcshell/test_terminator_reload.js create mode 100644 toolkit/components/terminator/tests/xpcshell/xpcshell.ini diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index c849027f870e..fe6b4ddcc920 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -914,6 +914,9 @@ bin/libfreebl_32int64_3.so @BINPATH@/components/DataStoreImpl.js @BINPATH@/components/dom_datastore.xpt +; Shutdown Terminator +@BINPATH@/components/nsTerminatorTelemetry.js +@BINPATH@/components/terminator.manifest #ifdef MOZ_ASAN #ifdef CLANG_CXX diff --git a/build/sanitizers/lsan_suppressions.txt b/build/sanitizers/lsan_suppressions.txt index 028bd0a16b13..e432bfe82434 100644 --- a/build/sanitizers/lsan_suppressions.txt +++ b/build/sanitizers/lsan_suppressions.txt @@ -26,6 +26,8 @@ leak:libfontconfig.so leak:GI___strdup # The symbol is really __GI___strdup, but if you have the leading _, it doesn't suppress it. +# Bug 1078015 - If the process terminates during a PR_Sleep, LSAN detects a leak +leak:PR_Sleep ### ### Bug 979928 - WebRTC leaks. m2, m3. diff --git a/toolkit/components/moz.build b/toolkit/components/moz.build index f7e608b22a38..f54634b2fc58 100644 --- a/toolkit/components/moz.build +++ b/toolkit/components/moz.build @@ -45,7 +45,6 @@ DIRS += [ 'startup', 'statusfilter', 'telemetry', - 'terminator', 'thumbnails', 'typeaheadfind', 'urlformatter', @@ -86,6 +85,9 @@ if CONFIG['MOZ_URL_CLASSIFIER']: if CONFIG['MOZ_CAPTIVEDETECT']: DIRS += ['captivedetect'] +if CONFIG['MOZ_WIDGET_TOOLKIT'] != "gonk" and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android': + DIRS += ['terminator'] + DIRS += ['build'] EXTRA_COMPONENTS += [ diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 854e765989b7..678a2fe3ce84 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -6775,6 +6775,34 @@ "n_buckets": 10, "description": "Sidebar showing: seconds that the sidebar has been opened" }, + "SHUTDOWN_PHASE_DURATION_TICKS_QUIT_APPLICATION": { + "expires_in_version": "never", + "kind": "exponential", + "high": 65, + "n_buckets": 10, + "description": "Duration of shutdown phase quit-application, as measured by the shutdown terminator, in seconds of activity" + }, + "SHUTDOWN_PHASE_DURATION_TICKS_PROFILE_CHANGE_TEARDOWN": { + "expires_in_version": "never", + "kind": "exponential", + "high": 65, + "n_buckets": 10, + "description": "Duration of shutdown phase profile-change-teardown, as measured by the shutdown terminator, in seconds of activity" + }, + "SHUTDOWN_PHASE_DURATION_TICKS_XPCOM_WILL_SHUTDOWN": { + "expires_in_version": "never", + "kind": "exponential", + "high": 65, + "n_buckets": 10, + "description": "Duration of shutdown phase xpcom-will-shutdown, as measured by the shutdown terminator, in seconds of activity" + }, + "SHUTDOWN_PHASE_DURATION_TICKS_PROFILE_BEFORE_CHANGE": { + "expires_in_version": "never", + "kind": "exponential", + "high": 65, + "n_buckets": 10, + "description": "Duration of shutdown phase profile-before-change, as measured by the shutdown terminator, in seconds of activity" + }, "BR_9_2_1_SUBJECT_ALT_NAMES": { "expires_in_version": "never", "kind": "enumerated", diff --git a/toolkit/components/terminator/moz.build b/toolkit/components/terminator/moz.build index 04077904743e..999cfd0792ab 100644 --- a/toolkit/components/terminator/moz.build +++ b/toolkit/components/terminator/moz.build @@ -4,6 +4,8 @@ # 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/. +XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell/xpcshell.ini'] + SOURCES += [ 'nsTerminator.cpp', ] @@ -13,6 +15,7 @@ EXPORTS += [ ] EXTRA_COMPONENTS += [ + 'nsTerminatorTelemetry.js', 'terminator.manifest', ] diff --git a/toolkit/components/terminator/nsTerminator.cpp b/toolkit/components/terminator/nsTerminator.cpp index 6c86a3822955..5c91eaeac027 100644 --- a/toolkit/components/terminator/nsTerminator.cpp +++ b/toolkit/components/terminator/nsTerminator.cpp @@ -18,8 +18,14 @@ #include "nsTerminator.h" #include "prthread.h" +#include "prmon.h" +#include "plstr.h" +#include "prio.h" + #include "nsString.h" #include "nsServiceManagerUtils.h" +#include "nsDirectoryServiceUtils.h" +#include "nsAppDirectoryServiceDefs.h" #include "nsIObserverService.h" #include "nsIPrefService.h" @@ -28,11 +34,14 @@ #endif #include "mozilla/ArrayUtils.h" +#include "mozilla/Attributes.h" #include "mozilla/DebugOnly.h" +#include "mozilla/MemoryChecking.h" #include "mozilla/Preferences.h" #include "mozilla/Services.h" #include "mozilla/UniquePtr.h" #include "mozilla/unused.h" +#include "mozilla/Telemetry.h" // Normally, the number of milliseconds that AsyncShutdown waits until // it decides to crash is specified as a preference. We use the @@ -51,29 +60,76 @@ namespace mozilla { namespace { -/** - * Set to `true` by the main thread whenever we pass a shutdown phase, - * which means that the shutdown is still ongoing. Reset to `false` by - * the Terminator thread, once it has acknowledged the progress. - */ -Atomic gProgress(false); +// Utility function: create a thread that is non-joinable, +// does not prevent the process from terminating, is never +// cooperatively scheduled, and uses a default stack size. +PRThread* CreateSystemThread(void (*start)(void* arg), + void* arg) +{ + PRThread* thread = PR_CreateThread( + PR_SYSTEM_THREAD, /* This thread will not prevent the process from terminating */ + start, + arg, + PR_PRIORITY_LOW, + PR_GLOBAL_THREAD /* Make sure that the thread is never cooperatively scheduled */, + PR_UNJOINABLE_THREAD, + 0 /* Use default stack size */ + ); + MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(thread); // This pointer will never be deallocated. + return thread; +} + + +//////////////////////////////////////////// +// +// The watchdog +// +// This nspr thread is in charge of crashing the process if any stage of shutdown +// lasts more than some predefined duration. As a side-effect, it measures the +// duration of each stage of shutdown. +// + +// The heartbeat of the operation. +// +// Main thread: +// +// * Whenever a shutdown step has been completed, the main thread +// swaps gHeartbeat to 0 to mark that the shutdown process is still +// progressing. The value swapped away indicates the number of ticks +// it took for the shutdown step to advance. +// +// Watchdog thread: +// +// * Every tick, the watchdog thread increments gHearbeat atomically. +// +// A note about precision: +// Since gHeartbeat is generally reset to 0 between two ticks, this means +// that gHeartbeat stays at 0 less than one tick. Consequently, values +// extracted from gHeartbeat must be considered rounded up. +Atomic gHeartbeat(0); struct Options { - int32_t crashAfterMS; + /** + * How many ticks before we should crash the process. + */ + uint32_t crashAfterTicks; }; +/** + * Entry point for the watchdog thread + */ void -Run(void* arg) +RunWatchdog(void* arg) { PR_SetCurrentThreadName("Shutdown Hang Terminator"); // Let's copy and deallocate options, that's one less leak to worry // about. UniquePtr options((Options*)arg); - int32_t crashAfterMS = options->crashAfterMS; + uint32_t crashAfterTicks = options->crashAfterTicks; options = nullptr; - int32_t timeToLive = crashAfterMS; + const uint32_t timeToLive = crashAfterTicks; while (true) { // // We do not want to sleep for the entire duration, @@ -86,14 +142,8 @@ Run(void* arg) // more reasonable. // PR_Sleep(TICK_DURATION); - if (gProgress.exchange(false)) { - // We have passed at least one shutdown phase while waiting. - // Shutdown is still alive, reset the countdown. - timeToLive = crashAfterMS; - continue; - } - timeToLive -= TICK_DURATION; - if (timeToLive >= 0) { + + if (gHeartbeat++ < timeToLive) { continue; } @@ -102,20 +152,177 @@ Run(void* arg) } } -} // anonymous namespace +//////////////////////////////////////////// +// +// Writer thread +// +// This nspr thread is in charge of writing to disk statistics produced by the +// watchdog thread and collected by the main thread. Note that we use a nspr +// thread rather than usual XPCOM I/O simply because we outlive XPCOM and its +// threads. +// -static char const *const sObserverTopics[] = { - "quit-application", - "profile-change-teardown", - "profile-before-change", - "xpcom-will-shutdown", - "xpcom-shutdown", +// Utility class, used by UniquePtr<> to close nspr files. +class PR_CloseDelete +{ +public: + MOZ_CONSTEXPR PR_CloseDelete() {} + + PR_CloseDelete(const PR_CloseDelete& aOther) + {} + + void operator()(PRFileDesc* aPtr) const + { + PR_Close(aPtr); + } }; +// +// Communication between the main thread and the writer thread. +// +// Main thread: +// +// * Whenever a shutdown step has been completed, the main thread +// obtains the number of ticks from the watchdog threads, builds +// a string representing all the data gathered so far, places +// this string in `gWriteData`, and wakes up the writer thread +// using `gWriteReady`. If `gWriteData` already contained a non-null +// pointer, this means that the writer thread is lagging behind the +// main thread, and the main thread cleans up the memory. +// +// Writer thread: +// +// * When awake, the writer thread swaps `gWriteData` to nullptr. If +// `gWriteData` contained data to write, the . If so, the writer +// thread writes the data to a file named "ShutdownDuration.json.tmp", +// then moves that file to "ShutdownDuration.json" and cleans up the +// data. If `gWriteData` contains a nullptr, the writer goes to sleep +// until it is awkened using `gWriteReady`. +// +// +// The data written by the writer thread will be read by another +// module upon the next restart and fed to Telemetry. +// +Atomic gWriteData(nullptr); +PRMonitor* gWriteReady = nullptr; + +void RunWriter(void* arg) +{ + PR_SetCurrentThreadName("Shutdown Statistics Writer"); + + MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(arg); + // Shutdown will generally complete before we have a chance to + // deallocate. This is not a leak. + + // Setup destinationPath and tmpFilePath + + nsCString destinationPath(static_cast(arg)); + nsAutoCString tmpFilePath; + tmpFilePath.Append(destinationPath); + tmpFilePath.AppendLiteral(".tmp"); + + // Cleanup any file leftover from a previous run + unused << PR_Delete(tmpFilePath.get()); + unused << PR_Delete(destinationPath.get()); + + while (true) { + // + // Check whether we have received data from the main thread. + // + // We perform the check before waiting on `gWriteReady` as we may + // have received data while we were busy writing. + // + // Also note that gWriteData may have been modified several times + // since we last checked. That's ok, we are not losing any important + // data (since we keep adding data), and we are not leaking memory + // (since the main thread deallocates any data that hasn't been + // consumed by the writer thread). + // + UniquePtr data(gWriteData.exchange(nullptr)); + if (!data) { + // Data is not available yet. + // Wait until the main thread provides it. + PR_EnterMonitor(gWriteReady); + PR_Wait(gWriteReady, PR_INTERVAL_NO_TIMEOUT); + PR_ExitMonitor(gWriteReady); + continue; + } + + MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(data.get()); + // Shutdown may complete before we have a chance to deallocate. + // This is not a leak. + + // + // Write to a temporary file + // + // In case of any error, we simply give up. Since the data is + // hardly critical, we don't want to spend too much effort + // salvaging it. + // + UniquePtr + tmpFileDesc(PR_Open(tmpFilePath.get(), + PR_WRONLY | PR_TRUNCATE | PR_CREATE_FILE, + 00600)); + + // Shutdown may complete before we have a chance to close the file. + // This is not a leak. + MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(tmpFileDesc.get()); + + if (tmpFileDesc == nullptr) { + break; + } + if (PR_Write(tmpFileDesc.get(), data->get(), data->Length()) == -1) { + break; + } + tmpFileDesc.reset(); + + // + // Rename on top of destination file. + // + // This is not sufficient to guarantee that the destination file + // will be written correctly, but, again, we don't care enough + // about the data to make more efforts. + // + if (PR_Rename(tmpFilePath.get(), destinationPath.get()) != PR_SUCCESS) { + break; + } + } +} + +/** + * A step during shutdown. + * + * Shutdown is divided in steps, which all map to an observer + * notification. The duration of a step is defined as the number of + * ticks between the time we receive a notification and the next one. + */ +struct ShutdownStep +{ + char const* const mTopic; + int mTicks; + + MOZ_CONSTEXPR ShutdownStep(const char *const topic) + : mTopic(topic) + , mTicks(-1) + {} + +}; + +static ShutdownStep sShutdownSteps[] = { + ShutdownStep("quit-application"), + ShutdownStep("profile-change-teardown"), + ShutdownStep("profile-before-change"), + ShutdownStep("xpcom-will-shutdown"), + ShutdownStep("xpcom-shutdown"), +}; + +} // anonymous namespace + NS_IMPL_ISUPPORTS(nsTerminator, nsIObserver) nsTerminator::nsTerminator() : mInitialized(false) + , mCurrentStep(-1) { } @@ -128,45 +335,92 @@ nsTerminator::SelfInit() return NS_ERROR_UNEXPECTED; } - for (size_t i = 0; i < ArrayLength(sObserverTopics); ++i) { - DebugOnly rv = os->AddObserver(this, sObserverTopics[i], false); + for (size_t i = 0; i < ArrayLength(sShutdownSteps); ++i) { + DebugOnly rv = os->AddObserver(this, sShutdownSteps[i].mTopic, false); #if defined(DEBUG) NS_WARN_IF(NS_FAILED(rv)); #endif // defined(DEBUG) } + return NS_OK; } -// Actually launch the thread. This takes place at the first sign of shutdown. +// Actually launch these threads. This takes place at the first sign of shutdown. void -nsTerminator::Start() { - // Determine how long we need to wait +nsTerminator::Start() +{ + MOZ_ASSERT(!mInitialized); + StartWatchdog(); + StartWriter(); + mInitialized = true; +} +// Prepare, allocate and start the watchdog thread. +// By design, it will never finish, nor be deallocated. +void +nsTerminator::StartWatchdog() +{ int32_t crashAfterMS = Preferences::GetInt("toolkit.asyncshutdown.crash_timeout", FALLBACK_ASYNCSHUTDOWN_CRASH_AFTER_MS); + // Ignore negative values + if (crashAfterMS <= 0) { + crashAfterMS = FALLBACK_ASYNCSHUTDOWN_CRASH_AFTER_MS; + } // Add a little padding, to ensure that we do not crash before // AsyncShutdown. - crashAfterMS += ADDITIONAL_WAIT_BEFORE_CRASH_MS; + if (crashAfterMS > INT32_MAX - ADDITIONAL_WAIT_BEFORE_CRASH_MS) { + // Defend against overflow + crashAfterMS = INT32_MAX; + } else { + crashAfterMS += ADDITIONAL_WAIT_BEFORE_CRASH_MS; + } UniquePtr options(new Options()); - options->crashAfterMS = crashAfterMS; + options->crashAfterTicks = crashAfterMS / TICK_DURATION; - // Allocate and start the thread. - // By design, it will never finish, nor be deallocated. - DebugOnly thread = PR_CreateThread( - PR_SYSTEM_THREAD, /* This thread will not prevent the process from terminating */ - Run, - options.release(), - PR_PRIORITY_LOW, - PR_GLOBAL_THREAD /* Make sure that the thread is never cooperatively scheduled */, - PR_UNJOINABLE_THREAD, - 0 /* Use default stack size */ - ); + DebugOnly watchdogThread = CreateSystemThread(RunWatchdog, + options.release()); + MOZ_ASSERT(watchdogThread); +} - MOZ_ASSERT(thread); - mInitialized = true; +// Prepare, allocate and start the writer thread. By design, it will never +// finish, nor be deallocated. In case of error, we degrade +// gracefully to not writing Telemetry data. +void +nsTerminator::StartWriter() +{ + + if (!Telemetry::CanRecord()) { + return; + } + nsCOMPtr profLD; + nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_LOCAL_50_DIR, + getter_AddRefs(profLD)); + if (NS_FAILED(rv)) { + return; + } + + rv = profLD->Append(NS_LITERAL_STRING("ShutdownDuration.json")); + if (NS_FAILED(rv)) { + return; + } + + nsAutoString path; + rv = profLD->GetPath(path); + if (NS_FAILED(rv)) { + return; + } + + gWriteReady = PR_NewMonitor(); + MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(gWriteReady); // We will never deallocate this object + PRThread* writerThread = CreateSystemThread(RunWriter, + ToNewUTF8String(path)); + + if (!writerThread) { + return; + } } NS_IMETHODIMP @@ -185,19 +439,101 @@ nsTerminator::Observe(nsISupports *, const char *aTopic, const char16_t *) Start(); } - // Inform the thread that we have advanced by one phase. - gProgress.exchange(true); - -#if defined(MOZ_CRASHREPORTER) - // In case of crash, we wish to know where in shutdown we are - unused << CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ShutdownProgress"), - nsAutoCString(aTopic)); -#endif // defined(MOZ_CRASH_REPORTER) + UpdateHeartbeat(aTopic); + UpdateTelemetry(); + UpdateCrashReport(aTopic); + // Perform a little cleanup nsCOMPtr os = mozilla::services::GetObserverService(); MOZ_RELEASE_ASSERT(os); (void)os->RemoveObserver(this, aTopic); + return NS_OK; } +void +nsTerminator::UpdateHeartbeat(const char* aTopic) +{ + // Reset the clock, find out how long the current phase has lasted. + uint32_t ticks = gHeartbeat.exchange(0); + if (mCurrentStep > 0) { + sShutdownSteps[mCurrentStep].mTicks = ticks; + } + + // Find out where we now are in the current shutdown. + // Don't assume that shutdown takes place in the expected order. + int nextStep = -1; + for (size_t i = 0; i < ArrayLength(sShutdownSteps); ++i) { + if (strcmp(sShutdownSteps[i].mTopic, aTopic) == 0) { + nextStep = i; + break; + } + } + MOZ_ASSERT(nextStep != -1); + mCurrentStep = nextStep; +} + +void +nsTerminator::UpdateTelemetry() +{ + if (!Telemetry::CanRecord() || !gWriteReady) { + return; + } + + // + // We need Telemetry data on the effective duration of each step, + // to be able to tune the time-to-crash of each of both the + // Terminator and AsyncShutdown. However, at this stage, it is too + // late to record such data into Telemetry, so we write it to disk + // and read it upon the next startup. + // + + // Build JSON. + UniquePtr telemetryData(new nsCString()); + telemetryData->AppendLiteral("{"); + size_t fields = 0; + for (size_t i = 0; i < ArrayLength(sShutdownSteps); ++i) { + if (sShutdownSteps[i].mTicks < 0) { + // Ignore this field. + continue; + } + if (fields++ > 0) { + telemetryData->Append(", "); + } + telemetryData->AppendLiteral("\""); + telemetryData->Append(sShutdownSteps[i].mTopic); + telemetryData->AppendLiteral("\": "); + telemetryData->AppendInt(sShutdownSteps[i].mTicks); + } + telemetryData->AppendLiteral("}"); + + if (fields == 0) { + // Nothing to write + return; + } + + // + // Send data to the worker thread. + // + delete gWriteData.exchange(telemetryData.release()); // Clear any data that hasn't been written yet + + // In case the worker thread was sleeping, wake it up. + PR_EnterMonitor(gWriteReady); + PR_Notify(gWriteReady); + PR_ExitMonitor(gWriteReady); +} + +void +nsTerminator::UpdateCrashReport(const char* aTopic) +{ +#if defined(MOZ_CRASHREPORTER) + // In case of crash, we wish to know where in shutdown we are + nsAutoCString report(aTopic); + + unused << CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ShutdownProgress"), + report); +#endif // defined(MOZ_CRASH_REPORTER) +} + + } // namespace mozilla diff --git a/toolkit/components/terminator/nsTerminator.h b/toolkit/components/terminator/nsTerminator.h index 9b43b8c2b473..f343dcc25a81 100644 --- a/toolkit/components/terminator/nsTerminator.h +++ b/toolkit/components/terminator/nsTerminator.h @@ -22,10 +22,17 @@ public: private: nsresult SelfInit(); void Start(); + void StartWatchdog(); + void StartWriter(); + + void UpdateHeartbeat(const char* aTopic); + void UpdateTelemetry(); + void UpdateCrashReport(const char* aTopic); ~nsTerminator() {} bool mInitialized; + int32_t mCurrentStep; }; } diff --git a/toolkit/components/terminator/nsTerminatorTelemetry.js b/toolkit/components/terminator/nsTerminatorTelemetry.js new file mode 100644 index 000000000000..30e2b5670630 --- /dev/null +++ b/toolkit/components/terminator/nsTerminatorTelemetry.js @@ -0,0 +1,105 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */ +/* 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/. */ + +"use strict"; + +/** + * Read the data saved by nsTerminator during shutdown and feed it to the + * relevant telemetry histograms. + */ + +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cu = Components.utils; +const Cr = Components.results; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +XPCOMUtils.defineLazyModuleGetter(this, "OS", + "resource://gre/modules/osfile.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "Promise", + "resource://gre/modules/Promise.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "Task", + "resource://gre/modules/Task.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "setTimeout", + "resource://gre/modules/Timer.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "Services", + "resource://gre/modules/Services.jsm"); + +function nsTerminatorTelemetry() {} + +let HISTOGRAMS = { + "quit-application": "SHUTDOWN_PHASE_DURATION_TICKS_QUIT_APPLICATION", + "profile-change-teardown": "SHUTDOWN_PHASE_DURATION_TICKS_PROFILE_CHANGE_TEARDOWN", + "profile-before-change": "SHUTDOWN_PHASE_DURATION_TICKS_PROFILE_BEFORE_CHANGE", + "xpcom-will-shutdown": "SHUTDOWN_PHASE_DURATION_TICKS_XPCOM_WILL_SHUTDOWN", +}; + +nsTerminatorTelemetry.prototype = { + classID: Components.ID("{3f78ada1-cba2-442a-82dd-d5fb300ddea7}"), + + _xpcom_factory: XPCOMUtils.generateSingletonFactory(nsTerminatorTelemetry), + + ////////////////////////////////////////////////////////////////////////////// + //// nsISupports + + QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]), + + ////////////////////////////////////////////////////////////////////////////// + //// nsIObserver + + observe: function DS_observe(aSubject, aTopic, aData) + { + Task.spawn(function*() { + // + // This data is hardly critical, reading it can wait for a few seconds. + // + yield new Promise(resolve => setTimeout(resolve, 3000)); + + let PATH = OS.Path.join(OS.Constants.Path.localProfileDir, + "ShutdownDuration.json"); + let raw; + try { + raw = yield OS.File.read(PATH, { encoding: "utf-8" }); + } catch (ex if ex.becauseNoSuchFile) { + return; + } + // Let other errors be reported by Promise's error-reporting. + + // Clean up + OS.File.remove(PATH); + OS.File.remove(PATH + ".tmp"); + + let data = JSON.parse(raw); + for (let k of Object.keys(data)) { + let id = HISTOGRAMS[k]; + try { + let histogram = Services.telemetry.getHistogramById(id); + if (!histogram) { + throw new Error("Unknown histogram " + id); + } + + histogram.add(Number.parseInt(data[k])); + } catch (ex) { + // Make sure that the error is reported and causes test failures, + // but otherwise, ignore it. + Promise.reject(ex); + continue; + } + } + + // Inform observers that we are done. + Services.obs.notifyObservers(null, + "shutdown-terminator-telemetry-updated", + ""); + }); + }, +}; + +//////////////////////////////////////////////////////////////////////////////// +//// Module + +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([nsTerminatorTelemetry]); diff --git a/toolkit/components/terminator/terminator.manifest b/toolkit/components/terminator/terminator.manifest index 955b6d0b6645..c1757ba86ab3 100644 --- a/toolkit/components/terminator/terminator.manifest +++ b/toolkit/components/terminator/terminator.manifest @@ -1,2 +1,5 @@ category profile-after-change nsTerminator @mozilla.org/toolkit/shutdown-terminator;1 +component {3f78ada1-cba2-442a-82dd-d5fb300ddea7} nsTerminatorTelemetry.js +contract @mozilla.org/toolkit/shutdown-terminator-telemetry;1 {3f78ada1-cba2-442a-82dd-d5fb300ddea7} +category profile-after-change nsTerminatorTelemetry @mozilla.org/toolkit/shutdown-terminator-telemetry;1 diff --git a/toolkit/components/terminator/tests/xpcshell/test_terminator_record.js b/toolkit/components/terminator/tests/xpcshell/test_terminator_record.js new file mode 100644 index 000000000000..9f6a9cfdb5d5 --- /dev/null +++ b/toolkit/components/terminator/tests/xpcshell/test_terminator_record.js @@ -0,0 +1,108 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + + +// Test that the Shutdown Terminator records durations correctly + +const Cu = Components.utils; +const Cc = Components.classes; +const Ci = Components.interfaces; + +Cu.import("resource://gre/modules/Services.jsm", this); +Cu.import("resource://gre/modules/osfile.jsm", this); +Cu.import("resource://gre/modules/Timer.jsm", this); +Cu.import("resource://gre/modules/Task.jsm", this); + +let {Path, File, Constants} = OS; + +let PATH; +let PATH_TMP; +let terminator; + +add_task(function* init() { + do_get_profile(); + PATH = Path.join(Constants.Path.localProfileDir, "ShutdownDuration.json"); + PATH_TMP = PATH + ".tmp"; + + // Initialize the terminator + // (normally, this is done through the manifest file, but xpcshell + // doesn't take them into account). + do_print("Initializing the Terminator"); + terminator = Cc["@mozilla.org/toolkit/shutdown-terminator;1"]. + createInstance(Ci.nsIObserver); + terminator.observe(null, "profile-after-change", null); +}); + +let promiseShutdownDurationData = Task.async(function*() { + // Wait until PATH exists. + // Timeout if it is never created. + do_print("Waiting for file creation: " + PATH); + while (true) { + if ((yield OS.File.exists(PATH))) { + break; + } + + do_print("The file does not exist yet. Waiting 1 second."); + yield new Promise(resolve => setTimeout(resolve, 1000)); + } + + do_print("The file has been created"); + let raw = yield OS.File.read(PATH, { encoding: "utf-8"} ); + do_print(raw); + return JSON.parse(raw); +}); + +add_task(function* test_record() { + let PHASE0 = "profile-change-teardown"; + let PHASE1 = "profile-before-change"; + let PHASE2 = "xpcom-will-shutdown"; + let t0 = Date.now(); + + do_print("Starting shutdown"); + terminator.observe(null, "profile-change-teardown", null); + + do_print("Moving to next phase"); + terminator.observe(null, PHASE1, null); + + let data = yield promiseShutdownDurationData(); + + let t1 = Date.now(); + + Assert.ok(PHASE0 in data, "The file contains the expected key"); + let duration = data[PHASE0]; + Assert.equal(typeof duration, "number"); + Assert.ok(duration >= 0, "Duration is a non-negative number"); + Assert.ok(duration <= Math.ceil((t1 - t0) / 1000) + 1, + "Duration is reasonable"); + + Assert.equal(Object.keys(data).length, 1, "Data does not contain other durations"); + + do_print("Cleaning up and moving to next phase"); + yield File.remove(PATH); + yield File.remove(PATH_TMP); + + do_print("Waiting at least one tick"); + let WAIT_MS = 2000; + yield new Promise(resolve => setTimeout(resolve, WAIT_MS)); + + terminator.observe(null, PHASE2, null); + data = yield promiseShutdownDurationData(); + + let t2 = Date.now(); + + Assert.equal(Object.keys(data).sort().join(", "), + [PHASE0, PHASE1].sort().join(", "), + "The file contains the expected keys"); + Assert.equal(data[PHASE0], duration, "Duration of phase 0 hasn't changed"); + let duration2 = data[PHASE1]; + Assert.equal(typeof duration2, "number"); + Assert.ok(duration2 >= WAIT_MS / 2000, "We have waited at least " + (WAIT_MS / 2000) + " ticks"); + Assert.ok(duration2 <= Math.ceil((t2 - t1) / 1000) + 1, + "Duration is reasonable"); +}); + +function run_test() { + run_next_test(); +} diff --git a/toolkit/components/terminator/tests/xpcshell/test_terminator_reload.js b/toolkit/components/terminator/tests/xpcshell/test_terminator_reload.js new file mode 100644 index 000000000000..2b5bdc3ca3fd --- /dev/null +++ b/toolkit/components/terminator/tests/xpcshell/test_terminator_reload.js @@ -0,0 +1,85 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + + +// Test that the Shutdown Terminator reloads durations correctly + +const Cu = Components.utils; +const Cc = Components.classes; +const Ci = Components.interfaces; + +Cu.import("resource://gre/modules/Services.jsm", this); +Cu.import("resource://gre/modules/osfile.jsm", this); +Cu.import("resource://gre/modules/Timer.jsm", this); +Cu.import("resource://gre/modules/Task.jsm", this); + +let {Path, File, Constants} = OS; + +let PATH; + +let HISTOGRAMS = { + "quit-application": "SHUTDOWN_PHASE_DURATION_TICKS_QUIT_APPLICATION", + "profile-change-teardown": "SHUTDOWN_PHASE_DURATION_TICKS_PROFILE_CHANGE_TEARDOWN", + "profile-before-change": "SHUTDOWN_PHASE_DURATION_TICKS_PROFILE_BEFORE_CHANGE", + "xpcom-will-shutdown": "SHUTDOWN_PHASE_DURATION_TICKS_XPCOM_WILL_SHUTDOWN", +}; + +add_task(function* init() { + do_get_profile(); + PATH = Path.join(Constants.Path.localProfileDir, "ShutdownDuration.json"); +}); + +add_task(function* test_reload() { + do_print("Forging data"); + let data = {}; + let telemetrySnapshots = Services.telemetry.histogramSnapshots; + let i = 0; + for (let k of Object.keys(HISTOGRAMS)) { + let id = HISTOGRAMS[k]; + data[k] = i++; + Assert.equal(telemetrySnapshots[id] || undefined, undefined, "Histogram " + id + " is empty"); + } + + + yield OS.File.writeAtomic(PATH, JSON.stringify(data)); + + const TOPIC = "shutdown-terminator-telemetry-updated"; + + let wait = new Promise(resolve => + Services.obs.addObserver( + function observer() { + do_print("Telemetry has been updated"); + Services.obs.removeObserver(observer, TOPIC); + resolve(); + }, + TOPIC, + false)); + + do_print("Starting nsTerminatorTelemetry"); + let tt = Cc["@mozilla.org/toolkit/shutdown-terminator-telemetry;1"]. + createInstance(Ci.nsIObserver); + tt.observe(null, "profile-after-change", ""); + + do_print("Waiting until telemetry is updated"); + // Now wait until Telemetry is updated + yield wait; + + telemetrySnapshots = Services.telemetry.histogramSnapshots; + for (let k of Object.keys(HISTOGRAMS)) { + let id = HISTOGRAMS[k]; + do_print("Testing histogram " + id); + let snapshot = telemetrySnapshots[id]; + let count = 0; + for (let x of snapshot.counts) { + count += x; + } + Assert.equal(count, 1, "We have added one item"); + } + +}); + +function run_test() { + run_next_test(); +} diff --git a/toolkit/components/terminator/tests/xpcshell/xpcshell.ini b/toolkit/components/terminator/tests/xpcshell/xpcshell.ini new file mode 100644 index 000000000000..ae5534a58b7f --- /dev/null +++ b/toolkit/components/terminator/tests/xpcshell/xpcshell.ini @@ -0,0 +1,7 @@ +[DEFAULT] +head= +tail= + +[test_terminator_record.js] +[test_terminator_reload.js] +skip-if = (os == "android" || appname == "b2g") diff --git a/toolkit/crashreporter/test/unit/test_crash_terminator.js b/toolkit/crashreporter/test/unit/test_crash_terminator.js index 8d421f88ad59..c81748f2654a 100644 --- a/toolkit/crashreporter/test/unit/test_crash_terminator.js +++ b/toolkit/crashreporter/test/unit/test_crash_terminator.js @@ -21,6 +21,7 @@ function setup_crash() { // Inform the terminator that shutdown has started // Pick an arbitrary notification terminator.observe(null, "xpcom-will-shutdown", null); + terminator.observe(null, "profile-before-change", null); dump("Waiting (actively) for the crash\n"); while(true) { @@ -30,7 +31,8 @@ function setup_crash() { function after_crash(mdump, extra) { - Assert.equal(extra.ShutdownProgress, "xpcom-will-shutdown"); + do_print("Crash signature: " + JSON.stringify(extra, null, "\t")); + Assert.equal(extra.ShutdownProgress, "profile-before-change"); } function run_test() { From 150445534aba86cb7781f0178f6b1dd7edcaccbd Mon Sep 17 00:00:00 2001 From: David Rajchenbach-Teller Date: Sun, 2 Nov 2014 18:35:23 +0100 Subject: [PATCH 04/29] Bug 1044020 - Add libdl.so to lsan_suppressions.txt. r=froydnj --- build/sanitizers/lsan_suppressions.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/build/sanitizers/lsan_suppressions.txt b/build/sanitizers/lsan_suppressions.txt index e432bfe82434..e90728dc2927 100644 --- a/build/sanitizers/lsan_suppressions.txt +++ b/build/sanitizers/lsan_suppressions.txt @@ -94,6 +94,7 @@ leak:processInternalEntity ### leak:libcairo.so +leak:libdl.so leak:libdricore.so leak:libGL.so leak:libglib-2.0.so From 3d6212aad5ee729940d666ab16ce83913c79f3ce Mon Sep 17 00:00:00 2001 From: David Rajchenbach-Teller Date: Mon, 10 Nov 2014 14:55:02 +0100 Subject: [PATCH 05/29] Bug 1044020 - Don't build the Terminator under B2G. r=yoric --- .../components/build/nsToolkitCompsModule.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/toolkit/components/build/nsToolkitCompsModule.cpp b/toolkit/components/build/nsToolkitCompsModule.cpp index aeb982458c63..7b7db74c3f7d 100644 --- a/toolkit/components/build/nsToolkitCompsModule.cpp +++ b/toolkit/components/build/nsToolkitCompsModule.cpp @@ -4,7 +4,6 @@ #include "mozilla/ModuleUtils.h" #include "nsAppStartup.h" -#include "nsTerminator.h" #include "nsUserInfo.h" #include "nsToolkitCompsCID.h" #include "nsFindService.h" @@ -44,12 +43,23 @@ #include "NativeFileWatcherNotSupported.h" #endif // (XP_WIN) +#if !defined(MOZ_WIDGET_GONK) && !defined(MOZ_WIDGET_ANDROID) +#define MOZ_HAS_TERMINATOR +#endif + +#if defined(MOZ_HAS_TERMINATOR) +#include "nsTerminator.h" +#endif + using namespace mozilla; ///////////////////////////////////////////////////////////////////////////// NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsAppStartup, Init) + +#if defined(MOZ_HAS_TERMINATOR) NS_GENERIC_FACTORY_CONSTRUCTOR(nsTerminator) +#endif NS_GENERIC_FACTORY_CONSTRUCTOR(nsUserInfo) NS_GENERIC_FACTORY_CONSTRUCTOR(nsFindService) @@ -105,7 +115,9 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(NativeFileWatcherService, Init) NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(AddonPathService, AddonPathService::GetInstance) NS_DEFINE_NAMED_CID(NS_TOOLKIT_APPSTARTUP_CID); +#if defined(MOZ_HAS_TERMINATOR) NS_DEFINE_NAMED_CID(NS_TOOLKIT_TERMINATOR_CID); +#endif NS_DEFINE_NAMED_CID(NS_USERINFO_CID); NS_DEFINE_NAMED_CID(NS_ALERTSSERVICE_CID); #if !defined(MOZ_DISABLE_PARENTAL_CONTROLS) @@ -134,7 +146,9 @@ NS_DEFINE_NAMED_CID(NATIVE_FILEWATCHER_SERVICE_CID); static const Module::CIDEntry kToolkitCIDs[] = { { &kNS_TOOLKIT_APPSTARTUP_CID, false, nullptr, nsAppStartupConstructor }, +#if defined(MOZ_HAS_TERMINATOR) { &kNS_TOOLKIT_TERMINATOR_CID, false, nullptr, nsTerminatorConstructor }, +#endif { &kNS_USERINFO_CID, false, nullptr, nsUserInfoConstructor }, { &kNS_ALERTSSERVICE_CID, false, nullptr, nsAlertsServiceConstructor }, #if !defined(MOZ_DISABLE_PARENTAL_CONTROLS) @@ -165,7 +179,9 @@ static const Module::CIDEntry kToolkitCIDs[] = { static const Module::ContractIDEntry kToolkitContracts[] = { { NS_APPSTARTUP_CONTRACTID, &kNS_TOOLKIT_APPSTARTUP_CID }, +#if defined(MOZ_HAS_TERMINATOR) { NS_TOOLKIT_TERMINATOR_CONTRACTID, &kNS_TOOLKIT_TERMINATOR_CID }, +#endif { NS_USERINFO_CONTRACTID, &kNS_USERINFO_CID }, { NS_ALERTSERVICE_CONTRACTID, &kNS_ALERTSSERVICE_CID }, #if !defined(MOZ_DISABLE_PARENTAL_CONTROLS) From aeaccd51b90c898a662812d71d455958d6a3b0c8 Mon Sep 17 00:00:00 2001 From: Paul Duguet Date: Fri, 14 Nov 2014 08:07:00 -0500 Subject: [PATCH 06/29] Bug 1088257 - Fix tooltip/label inversion by removing the unnecessary 2 assignments. r=dao --- browser/components/customizableui/CustomizableWidgets.jsm | 2 -- 1 file changed, 2 deletions(-) diff --git a/browser/components/customizableui/CustomizableWidgets.jsm b/browser/components/customizableui/CustomizableWidgets.jsm index 2a36b9f485e3..70579cb49908 100644 --- a/browser/components/customizableui/CustomizableWidgets.jsm +++ b/browser/components/customizableui/CustomizableWidgets.jsm @@ -399,8 +399,6 @@ const CustomizableWidgets = [ } }, { id: "social-share-button", - tooltiptext: "social-share-button.label", - label: "social-share-button.tooltiptext", // custom build our button so we can attach to the share command type: "custom", onBuild: function(aDocument) { From bc52a3e288f7a823919e8bd704e8770d027bc012 Mon Sep 17 00:00:00 2001 From: Sami Jaktholm Date: Fri, 14 Nov 2014 06:57:00 -0500 Subject: [PATCH 07/29] Bug 1092452 - Fix intermittent mochitest-e10s-dt failure in browser_timeline_overview-initial-selection-02.js. r=vporof --- browser/devtools/timeline/timeline.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/browser/devtools/timeline/timeline.js b/browser/devtools/timeline/timeline.js index 2ec2ae555554..f89bbcc731ad 100644 --- a/browser/devtools/timeline/timeline.js +++ b/browser/devtools/timeline/timeline.js @@ -183,7 +183,17 @@ let TimelineController = { * updating the UI as needed. */ _stopRecordingAndDiscardData: function*() { + // Clear the markers before calling async method _stopRecording to properly + // reset the selection if markers were already received. Bug 1092452. + this._markers.length = 0; + this._memory.length = 0; + yield this._stopRecording(); + + // Clear the markers after _stopRecording has finished. It's possible that + // server sent new markers before it received the request to stop sending + // them and client received them while we were waiting for _stopRecording + // to finish. Bug 1067287. this._markers.length = 0; this._memory.length = 0; }, From d2471eea6c0b122531ee978be1188aeff1a897c2 Mon Sep 17 00:00:00 2001 From: Garvan Keeley Date: Thu, 13 Nov 2014 11:54:00 -0500 Subject: [PATCH 08/29] Bug 1095914 - Copy over CellScanner from mozstumbler github. r=nalexander This has a few important changes: 1) Null-check the TelephonyManager availability. 2) The cell scanning code was split to remove wcdma scanning on Fennec due to an older API level on Fennec. This is no longer the case. CellScannerNoWCDMA.java renamed to CellScannerImplementation.java. 3) Remove broadcastsync on the timer thread, have the timer thread message back to the owning class through a handler (guaranteed thread-safe mechanism to notify the owning class that work is done). --- .../service/stumblerthread/Reporter.java | 1 + .../stumblerthread/StumblerService.java | 11 -- .../datahandling/DataStorageManager.java | 4 +- .../stumblerthread/scanners/ScanManager.java | 4 - .../scanners/cellscanner/CellScanner.java | 117 +++++++++++------- ...MA.java => CellScannerImplementation.java} | 99 ++++++++++----- .../stumbler/stumbler_sources.mozbuild | 2 +- 7 files changed, 145 insertions(+), 93 deletions(-) rename mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/cellscanner/{CellScannerNoWCDMA.java => CellScannerImplementation.java} (76%) diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/Reporter.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/Reporter.java index b3edf6285ae0..0faa47c634b3 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/Reporter.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/Reporter.java @@ -32,6 +32,7 @@ import org.mozilla.mozstumbler.service.stumblerthread.scanners.WifiScanner; public final class Reporter extends BroadcastReceiver { private static final String LOG_TAG = AppGlobals.makeLogTag(Reporter.class.getSimpleName()); public static final String ACTION_FLUSH_TO_BUNDLE = AppGlobals.ACTION_NAMESPACE + ".FLUSH"; + public static final String ACTION_NEW_BUNDLE = AppGlobals.ACTION_NAMESPACE + ".NEW_BUNDLE"; private boolean mIsStarted; /* The maximum number of Wi-Fi access points in a single observation. */ diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/StumblerService.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/StumblerService.java index 40b31df3bb4f..0f2648c81ae0 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/StumblerService.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/StumblerService.java @@ -17,7 +17,6 @@ import org.mozilla.mozstumbler.service.stumblerthread.blocklist.WifiBlockListInt import org.mozilla.mozstumbler.service.stumblerthread.datahandling.DataStorageManager; import org.mozilla.mozstumbler.service.stumblerthread.scanners.ScanManager; import org.mozilla.mozstumbler.service.stumblerthread.scanners.cellscanner.CellScanner; -import org.mozilla.mozstumbler.service.stumblerthread.scanners.cellscanner.CellScannerNoWCDMA; import org.mozilla.mozstumbler.service.uploadthread.UploadAlarmReceiver; import org.mozilla.mozstumbler.service.utils.NetworkUtils; import org.mozilla.mozstumbler.service.utils.PersistentIntentService; @@ -109,10 +108,6 @@ public class StumblerService extends PersistentIntentService return mScanManager.getCellInfoCount(); } - public int getCurrentCellInfoCount() { - return mScanManager.getCurrentCellInfoCount(); - } - public boolean isGeofenced () { return mScanManager.isGeofenced(); } @@ -125,10 +120,6 @@ public class StumblerService extends PersistentIntentService NetworkUtils.createGlobalInstance(this); DataStorageManager.createGlobalInstance(this, this); - if (!CellScanner.isCellScannerImplSet()) { - CellScanner.setCellScannerImpl(new CellScannerNoWCDMA(this)); - } - mReporter.startup(this); } @@ -144,8 +135,6 @@ public class StumblerService extends PersistentIntentService public void onDestroy() { super.onDestroy(); - UploadAlarmReceiver.cancelAlarm(this, !mScanManager.isPassiveMode()); - if (!mScanManager.isScanning()) { return; } diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/datahandling/DataStorageManager.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/datahandling/DataStorageManager.java index fc70f9647518..00fa336d0ce5 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/datahandling/DataStorageManager.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/datahandling/DataStorageManager.java @@ -424,8 +424,8 @@ public class DataStorageManager { } mCurrentReports.reports.add(report); - mCurrentReports.wifiCount = wifiCount; - mCurrentReports.cellCount = cellCount; + mCurrentReports.wifiCount += wifiCount; + mCurrentReports.cellCount += cellCount; if (mCurrentReports.reports.size() >= MAX_REPORTS_IN_MEMORY) { // save to disk diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/ScanManager.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/ScanManager.java index 6d8b488b0f8b..5a0b4f25aa23 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/ScanManager.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/ScanManager.java @@ -158,10 +158,6 @@ public class ScanManager { return (mCellScanner == null)? 0 :mCellScanner.getCellInfoCount(); } - public int getCurrentCellInfoCount() { - return (mCellScanner == null)? 0 :mCellScanner.getCurrentCellInfoCount(); - } - public int getLocationCount() { return (mGPSScanner == null)? 0 : mGPSScanner.getLocationCount(); } diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/cellscanner/CellScanner.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/cellscanner/CellScanner.java index 809f6b6c5489..83e7ef95d382 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/cellscanner/CellScanner.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/cellscanner/CellScanner.java @@ -4,21 +4,28 @@ package org.mozilla.mozstumbler.service.stumblerthread.scanners.cellscanner; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; +import android.os.Handler; +import android.os.Message; import android.support.v4.content.LocalBroadcastManager; +import android.telephony.TelephonyManager; import android.util.Log; +import org.mozilla.mozstumbler.service.AppGlobals; +import org.mozilla.mozstumbler.service.AppGlobals.ActiveOrPassiveStumbling; + import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.Timer; import java.util.TimerTask; - -import org.mozilla.mozstumbler.service.AppGlobals; +import java.util.concurrent.atomic.AtomicBoolean; import org.mozilla.mozstumbler.service.AppGlobals.ActiveOrPassiveStumbling; - +import org.mozilla.mozstumbler.service.stumblerthread.Reporter; public class CellScanner { public static final String ACTION_BASE = AppGlobals.ACTION_NAMESPACE + ".CellScanner."; @@ -30,47 +37,30 @@ public class CellScanner { private static final long CELL_MIN_UPDATE_TIME = 1000; // milliseconds private final Context mContext; - private static CellScannerImpl sImpl; private Timer mCellScanTimer; private final Set mCells = new HashSet(); - private int mCurrentCellInfoCount; + private final ReportFlushedReceiver mReportFlushedReceiver = new ReportFlushedReceiver(); + private final AtomicBoolean mReportWasFlushed = new AtomicBoolean(); + private Handler mBroadcastScannedHandler; + private final CellScannerImpl mCellScannerImplementation; public ArrayList sTestingModeCellInfoArray; public interface CellScannerImpl { - public void start(); - - public void stop(); - - public List getCellInfo(); + void start(); + boolean isStarted(); + boolean isSupportedOnThisDevice(); + void stop(); + List getCellInfo(); } public CellScanner(Context context) { mContext = context; - } - - private static synchronized CellScannerImpl getImplementation() { - return sImpl; - } - - public static synchronized boolean isCellScannerImplSet() { - return sImpl != null; - } - - /* Fennec doesn't support the apis needed for full scanning, we have different implementations.*/ - public static synchronized void setCellScannerImpl(CellScannerImpl cellScanner) { - sImpl = cellScanner; + mCellScannerImplementation = new CellScannerImplementation(context); } public void start(final ActiveOrPassiveStumbling stumblingMode) { - if (getImplementation() == null) { - return; - } - - try { - getImplementation().start(); - } catch (UnsupportedOperationException uoe) { - Log.e(LOG_TAG, "Cell scanner probe failed", uoe); + if (!mCellScannerImplementation.isSupportedOnThisDevice()) { return; } @@ -78,58 +68,95 @@ public class CellScanner { return; } + LocalBroadcastManager.getInstance(mContext).registerReceiver(mReportFlushedReceiver, + new IntentFilter(Reporter.ACTION_NEW_BUNDLE)); + + // This is to ensure the broadcast happens from the same thread the CellScanner start() is on + mBroadcastScannedHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + Intent intent = (Intent) msg.obj; + LocalBroadcastManager.getInstance(mContext).sendBroadcastSync(intent); + } + }; + + mCellScannerImplementation.start(); + mCellScanTimer = new Timer(); mCellScanTimer.schedule(new TimerTask() { int mPassiveScanCount; @Override public void run() { - if (getImplementation() == null) { + if (!mCellScannerImplementation.isStarted()) { return; } if (stumblingMode == ActiveOrPassiveStumbling.PASSIVE_STUMBLING && - mPassiveScanCount++ > AppGlobals.PASSIVE_MODE_MAX_SCANS_PER_GPS) + mPassiveScanCount++ > AppGlobals.PASSIVE_MODE_MAX_SCANS_PER_GPS) { mPassiveScanCount = 0; stop(); return; } - //if (SharedConstants.isDebug) Log.d(LOG_TAG, "Cell Scanning Timer fired"); + final long curTime = System.currentTimeMillis(); ArrayList cells = (sTestingModeCellInfoArray != null)? sTestingModeCellInfoArray : - new ArrayList(getImplementation().getCellInfo()); + new ArrayList(mCellScannerImplementation.getCellInfo()); + + if (mReportWasFlushed.getAndSet(false)) { + clearCells(); + } - mCurrentCellInfoCount = cells.size(); if (cells.isEmpty()) { return; } - for (CellInfo cell: cells) mCells.add(cell.getCellIdentity()); + + for (CellInfo cell : cells) { + addToCells(cell.getCellIdentity()); + } Intent intent = new Intent(ACTION_CELLS_SCANNED); intent.putParcelableArrayListExtra(ACTION_CELLS_SCANNED_ARG_CELLS, cells); intent.putExtra(ACTION_CELLS_SCANNED_ARG_TIME, curTime); - LocalBroadcastManager.getInstance(mContext).sendBroadcastSync(intent); + // send to handler, so broadcast is not from timer thread + Message message = new Message(); + message.obj = intent; + mBroadcastScannedHandler.sendMessage(message); + } }, 0, CELL_MIN_UPDATE_TIME); } - public void stop() { + private synchronized void clearCells() { + mCells.clear(); + } + + private synchronized void addToCells(String cell) { + mCells.add(cell); + } + + public synchronized void stop() { + mReportWasFlushed.set(false); + clearCells(); + LocalBroadcastManager.getInstance(mContext).unregisterReceiver(mReportFlushedReceiver); + if (mCellScanTimer != null) { mCellScanTimer.cancel(); mCellScanTimer = null; } - if (getImplementation() != null) { - getImplementation().stop(); - } + mCellScannerImplementation.stop(); } - public int getCellInfoCount() { + public synchronized int getCellInfoCount() { return mCells.size(); } - public int getCurrentCellInfoCount() { - return mCurrentCellInfoCount; + private class ReportFlushedReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context c, Intent i) { + mReportWasFlushed.set(true); + } } } diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/cellscanner/CellScannerNoWCDMA.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/cellscanner/CellScannerImplementation.java similarity index 76% rename from mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/cellscanner/CellScannerNoWCDMA.java rename to mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/cellscanner/CellScannerImplementation.java index b29324664d0b..37f27d8adf89 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/cellscanner/CellScannerNoWCDMA.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/cellscanner/CellScannerImplementation.java @@ -10,35 +10,40 @@ import android.os.Build; import android.telephony.CellIdentityCdma; import android.telephony.CellIdentityGsm; import android.telephony.CellIdentityLte; +import android.telephony.CellIdentityWcdma; import android.telephony.CellInfoCdma; import android.telephony.CellInfoGsm; import android.telephony.CellInfoLte; +import android.telephony.CellInfoWcdma; import android.telephony.CellLocation; import android.telephony.CellSignalStrengthCdma; import android.telephony.CellSignalStrengthGsm; import android.telephony.CellSignalStrengthLte; +import android.telephony.CellSignalStrengthWcdma; import android.telephony.NeighboringCellInfo; import android.telephony.PhoneStateListener; import android.telephony.SignalStrength; import android.telephony.TelephonyManager; import android.util.Log; + import org.mozilla.mozstumbler.service.AppGlobals; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; -/* Fennec does not yet support the api level for WCDMA import */ -public class CellScannerNoWCDMA implements CellScanner.CellScannerImpl { +public class CellScannerImplementation implements CellScanner.CellScannerImpl { - protected static String LOG_TAG = AppGlobals.makeLogTag(CellScannerNoWCDMA.class.getSimpleName()); + protected static String LOG_TAG = AppGlobals.makeLogTag(CellScannerImplementation.class.getSimpleName()); protected GetAllCellInfoScannerImpl mGetAllInfoCellScanner; protected TelephonyManager mTelephonyManager; protected boolean mIsStarted; protected int mPhoneType; protected final Context mContext; - protected volatile int mSignalStrength; - protected volatile int mCdmaDbm; + + protected volatile int mSignalStrength = CellInfo.UNKNOWN_SIGNAL; + protected volatile int mCdmaDbm = CellInfo.UNKNOWN_SIGNAL; private PhoneStateListener mPhoneStateListener; @@ -53,13 +58,28 @@ public class CellScannerNoWCDMA implements CellScanner.CellScannerImpl { List getAllCellInfo(TelephonyManager tm); } - public CellScannerNoWCDMA(Context context) { + public CellScannerImplementation(Context context) { mContext = context; } + public boolean isSupportedOnThisDevice() { + TelephonyManager telephonyManager = mTelephonyManager; + if (telephonyManager == null) { + telephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); + } + return telephonyManager != null && + (telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA || + telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM); + } + @Override - public void start() { - if (mIsStarted) { + public synchronized boolean isStarted() { + return mIsStarted; + } + + @Override + public synchronized void start() { + if (mIsStarted || !isSupportedOnThisDevice()) { return; } mIsStarted = true; @@ -72,23 +92,8 @@ public class CellScannerNoWCDMA implements CellScanner.CellScannerImpl { } mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); - if (mTelephonyManager == null) { - throw new UnsupportedOperationException("TelephonyManager service is not available"); - } - - mPhoneType = mTelephonyManager.getPhoneType(); - - if (mPhoneType != TelephonyManager.PHONE_TYPE_GSM - && mPhoneType != TelephonyManager.PHONE_TYPE_CDMA) { - throw new UnsupportedOperationException("Unexpected Phone Type: " + mPhoneType); - } - mSignalStrength = CellInfo.UNKNOWN_SIGNAL; - mCdmaDbm = CellInfo.UNKNOWN_SIGNAL; } - mSignalStrength = CellInfo.UNKNOWN_SIGNAL; - mCdmaDbm = CellInfo.UNKNOWN_SIGNAL; - mPhoneStateListener = new PhoneStateListener() { @Override public void onSignalStrengthsChanged(SignalStrength ss) { @@ -103,9 +108,9 @@ public class CellScannerNoWCDMA implements CellScanner.CellScannerImpl { } @Override - public void stop() { + public synchronized void stop() { mIsStarted = false; - if (mTelephonyManager != null) { + if (mTelephonyManager != null && mPhoneStateListener != null) { mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); } mSignalStrength = CellInfo.UNKNOWN_SIGNAL; @@ -113,7 +118,7 @@ public class CellScannerNoWCDMA implements CellScanner.CellScannerImpl { } @Override - public List getCellInfo() { + public synchronized List getCellInfo() { List records = new ArrayList(); List allCells = mGetAllInfoCellScanner.getAllCellInfo(mTelephonyManager); @@ -186,10 +191,39 @@ public class CellScannerNoWCDMA implements CellScanner.CellScannerImpl { return records; } + + @TargetApi(18) + protected boolean addWCDMACellToList(List cells, + android.telephony.CellInfo observedCell, + TelephonyManager tm) { + boolean added = false; + if (Build.VERSION.SDK_INT >= 18 && + observedCell instanceof CellInfoWcdma) { + CellIdentityWcdma ident = ((CellInfoWcdma) observedCell).getCellIdentity(); + if (ident.getMnc() != Integer.MAX_VALUE && ident.getMcc() != Integer.MAX_VALUE) { + CellInfo cell = new CellInfo(tm.getPhoneType()); + CellSignalStrengthWcdma strength = ((CellInfoWcdma) observedCell).getCellSignalStrength(); + cell.setWcmdaCellInfo(ident.getMcc(), + ident.getMnc(), + ident.getLac(), + ident.getCid(), + ident.getPsc(), + strength.getAsuLevel()); + cells.add(cell); + added = true; + } + } + return added; + } + @TargetApi(18) protected boolean addCellToList(List cells, - android.telephony.CellInfo observedCell, - TelephonyManager tm) { + android.telephony.CellInfo observedCell, + TelephonyManager tm) { + if (tm.getPhoneType() == 0) { + return false; + } + boolean added = false; if (observedCell instanceof CellInfoGsm) { CellIdentityGsm ident = ((CellInfoGsm) observedCell).getCellIdentity(); @@ -226,10 +260,15 @@ public class CellScannerNoWCDMA implements CellScanner.CellScannerImpl { ident.getTac(), strength.getAsuLevel(), strength.getTimingAdvance()); - cells.add(cell); - added = true; + cells.add(cell); + added = true; } } + + if (!added && Build.VERSION.SDK_INT >= 18) { + added = addWCDMACellToList(cells, observedCell, tm); + } + return added; } diff --git a/mobile/android/stumbler/stumbler_sources.mozbuild b/mobile/android/stumbler/stumbler_sources.mozbuild index e721e9df72dc..af27dc4d147e 100644 --- a/mobile/android/stumbler/stumbler_sources.mozbuild +++ b/mobile/android/stumbler/stumbler_sources.mozbuild @@ -17,7 +17,7 @@ stumbler_sources = [ 'java/org/mozilla/mozstumbler/service/stumblerthread/Reporter.java', 'java/org/mozilla/mozstumbler/service/stumblerthread/scanners/cellscanner/CellInfo.java', 'java/org/mozilla/mozstumbler/service/stumblerthread/scanners/cellscanner/CellScanner.java', - 'java/org/mozilla/mozstumbler/service/stumblerthread/scanners/cellscanner/CellScannerNoWCDMA.java', + 'java/org/mozilla/mozstumbler/service/stumblerthread/scanners/cellscanner/CellScannerImplementation.java', 'java/org/mozilla/mozstumbler/service/stumblerthread/scanners/GPSScanner.java', 'java/org/mozilla/mozstumbler/service/stumblerthread/scanners/LocationBlockList.java', 'java/org/mozilla/mozstumbler/service/stumblerthread/scanners/ScanManager.java', From 53995c07d75b73c444def5ce3fc7852134281ef2 Mon Sep 17 00:00:00 2001 From: Garvan Keeley Date: Sat, 8 Nov 2014 09:06:00 -0500 Subject: [PATCH 09/29] Bug 1095914 - Fix NPE in WifiScanner. r=vng https://github.com/mozilla/MozStumbler/pull/1192 1169: ACRA Report: NPE WifiScanner.java:98 --- .../stumblerthread/scanners/WifiScanner.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/WifiScanner.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/WifiScanner.java index f1a543390eaa..9d5e8d416221 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/WifiScanner.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/WifiScanner.java @@ -65,7 +65,11 @@ public class WifiScanner extends BroadcastReceiver { } private List getScanResults() { - return (sIsTestMode)? mTestModeFakeScanResults : getWifiManager().getScanResults(); + WifiManager manager = getWifiManager(); + if (manager == null) { + return null; + } + return getWifiManager().getScanResults(); } @@ -105,8 +109,12 @@ public class WifiScanner extends BroadcastReceiver { deactivatePeriodicScan(); } } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) { - ArrayList scanResults = new ArrayList(); - for (ScanResult scanResult : getScanResults()) { + final List scanResultList = getScanResults(); + if (scanResultList == null) { + return; + } + final ArrayList scanResults = new ArrayList(); + for (ScanResult scanResult : scanResultList) { scanResult.BSSID = BSSIDBlockList.canonicalizeBSSID(scanResult.BSSID); if (shouldLog(scanResult)) { scanResults.add(scanResult); From 4e4b118fd84234279d86545827134eae0e819080 Mon Sep 17 00:00:00 2001 From: Garvan Keeley Date: Sat, 8 Nov 2014 09:08:00 -0500 Subject: [PATCH 10/29] Bug 1095914 - Fix NPE due to no telephony manager. r=vng https://github.com/mozilla/MozStumbler/pull/1194 1185 NPE Reporter.startup (no telephony manager) --- .../mozstumbler/service/stumblerthread/Reporter.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/Reporter.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/Reporter.java index 0faa47c634b3..f84f0c25c459 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/Reporter.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/Reporter.java @@ -63,7 +63,12 @@ public final class Reporter extends BroadcastReceiver { mContext = context.getApplicationContext(); TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); - mPhoneType = tm.getPhoneType(); + if (tm != null) { + mPhoneType = tm.getPhoneType(); + } else { + Log.d(LOG_TAG, "No telephony manager."); + mPhoneType = TelephonyManager.PHONE_TYPE_NONE; + } mIsStarted = true; From 5c9fd6b65dd8ed78d4d9c4f09a873f72f7bfadd9 Mon Sep 17 00:00:00 2001 From: Garvan Keeley Date: Sat, 8 Nov 2014 09:09:00 -0500 Subject: [PATCH 11/29] Bug 1095914 - Fix NPE from no app context. r=vng https://github.com/mozilla/MozStumbler/pull/1195 1187 - NPE - Appears to be from no app context --- .../service/stumblerthread/scanners/ScanManager.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/ScanManager.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/ScanManager.java index 5a0b4f25aa23..60d7c8f1c3f9 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/ScanManager.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/ScanManager.java @@ -98,6 +98,11 @@ public class ScanManager { } mContext = context.getApplicationContext(); + if (mContext == null) { + Log.w(LOG_TAG, "No app context available."); + return; + } + if (mGPSScanner == null) { mGPSScanner = new GPSScanner(context, this); mWifiScanner = new WifiScanner(context); From 5e88160aab48efc061e63b9746779db16d339478 Mon Sep 17 00:00:00 2001 From: Garvan Keeley Date: Sat, 8 Nov 2014 09:09:00 -0500 Subject: [PATCH 12/29] Bug 1095914 - Fix crash if GPS not available. r=vng https://github.com/mozilla/MozStumbler/pull/1206 --- .../stumblerthread/scanners/GPSScanner.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/GPSScanner.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/GPSScanner.java index e72bbfeefa8c..6d4a61131c56 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/GPSScanner.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/GPSScanner.java @@ -65,8 +65,23 @@ public class GPSScanner implements LocationListener { } } + private boolean isGpsAvailable(LocationManager locationManager) { + if (locationManager == null || + locationManager.getProvider(LocationManager.GPS_PROVIDER) == null) { + String msg = "No GPS available, scanning not started."; + Log.d(LOG_TAG, msg); + AppGlobals.guiLogError(msg); + return false; + } + return true; + } + private void startPassiveMode() { LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); + if (!isGpsAvailable(locationManager)) { + return; + } + locationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, this); @@ -74,6 +89,10 @@ public class GPSScanner implements LocationListener { private void startActiveMode() { LocationManager lm = getLocationManager(); + if (!isGpsAvailable(lm)) { + return; + } + lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, ACTIVE_MODE_GPS_MIN_UPDATE_TIME_MS, ACTIVE_MODE_GPS_MIN_UPDATE_DISTANCE_M, From 32a317d0333bce412752363befa8916a2f2a284c Mon Sep 17 00:00:00 2001 From: Matthew Noorenberghe Date: Thu, 13 Nov 2014 20:25:45 +0100 Subject: [PATCH 13/29] Bug 1098482 - UITour: addNavBarWidget logging references an undefined variable. r=dolske --HG-- extra : transplant_source : %23%9C%95rJ%E8%02%5Cj%E8%9E%F3%D8%10%BD%CEH%7B%15I --- browser/modules/UITour.jsm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/browser/modules/UITour.jsm b/browser/modules/UITour.jsm index 397e971e62c7..e826532fedfa 100644 --- a/browser/modules/UITour.jsm +++ b/browser/modules/UITour.jsm @@ -1303,15 +1303,15 @@ this.UITour = { addNavBarWidget: function (aTarget, aMessageManager, aCallbackID) { if (aTarget.node) { - log.error("UITour: can't add a widget already present: " + data.target); + log.error("addNavBarWidget: can't add a widget already present:", aTarget); return; } if (!aTarget.allowAdd) { - log.error("UITour: not allowed to add this widget: " + data.target); + log.error("addNavBarWidget: not allowed to add this widget:", aTarget); return; } if (!aTarget.widgetName) { - log.error("UITour: can't add a widget without a widgetName property: " + data.target); + log.error("addNavBarWidget: can't add a widget without a widgetName property:", aTarget); return; } From 63dc7b1baef1218bbbaa81ad4dab7cf5e8d32b8c Mon Sep 17 00:00:00 2001 From: Gavin Sharp Date: Thu, 30 Oct 2014 09:00:53 -0700 Subject: [PATCH 14/29] Bug 1083990: fix bug that caused deletion of history autocomplete items to temporarily mess up the suggestions dropdown display, r=MattN --HG-- extra : transplant_source : %02%96%05%2C%CC8%06%B0j%2C%FA%81%F7m%5B%F2%F6%15Y. --- toolkit/components/search/nsSearchSuggestions.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/toolkit/components/search/nsSearchSuggestions.js b/toolkit/components/search/nsSearchSuggestions.js index 69970119c914..c0a9ba6bbdaf 100644 --- a/toolkit/components/search/nsSearchSuggestions.js +++ b/toolkit/components/search/nsSearchSuggestions.js @@ -86,13 +86,17 @@ SuggestAutoComplete.prototype = { */ onResultsReady: function(searchString, results, comments, formHistoryResult) { if (this._listener) { + // Create a copy of the results array to use as labels, since + // FormAutoCompleteResult doesn't like being passed the same array + // for both. + let labels = results.slice(); let result = new FormAutoCompleteResult( searchString, Ci.nsIAutoCompleteResult.RESULT_SUCCESS, 0, "", results, - results, + labels, comments, formHistoryResult); From cd759c6735ac06c247fe5c3bd4cb9f16d0cb7f63 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Fri, 14 Nov 2014 13:35:54 -0800 Subject: [PATCH 15/29] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/7ed8854b26c0 Author: Michael Henretty Desc: Merge pull request #25819 from mikehenrty/bug-1090152-fix-icon-visibility Bug 1090152 - Make sure we display statusbar icons on lockscreen even wi... ======== https://hg.mozilla.org/integration/gaia-central/rev/9c649cf34014 Author: Michael Henretty Desc: Bug 1090152 - Make sure we display statusbar icons on lockscreen even with fullscreen apps --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index c24a10eb1bcb..ef2d306332c8 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "1f41a654b3311705e7d71ff9b2137d3340c6c272", + "revision": "7ed8854b26c09af7ccccf73ded4bda054da6157b", "repo_path": "integration/gaia-central" } From 4d0ece55c07db3bb4a2beb1c9586f1aaa0cc9311 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Fri, 14 Nov 2014 13:37:56 -0800 Subject: [PATCH 16/29] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 334d5af19a05..eed86d258c8b 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 2e6e46274dc1..c05dbae4dc8e 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 3d0f3fe39d3f..563f8b271217 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 3608ebee91a7..e46b64a6d6b2 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 2e6e46274dc1..c05dbae4dc8e 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index be7c84790d77..a8aef3222344 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 406408290cc0..c6f1bc8186b0 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 58568a895cd3..8f573b66dcd8 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index e68ef550723b..c28e2fa4ced8 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 4351b1fcf14d..bf9532e5509a 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index ee2f4c216912..4b8d1e5f5044 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From 16dbfeb526dac8c0bb7328409ab91f70d9503d7f Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Fri, 14 Nov 2014 15:10:52 -0800 Subject: [PATCH 17/29] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/80fccbc45163 Author: Ryan VanderMeulen Desc: Merge pull request #25291 from anrao91/840790 Bug 840790 - [B2G][First Time User]Wrong or Modified names for various locations ======== https://hg.mozilla.org/integration/gaia-central/rev/7828ffaf65fc Author: Anusha Rao Desc: Bug 840790 - [B2G][First Time User]Wrong or Modified names for various locations --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index ef2d306332c8..19bfac8f1c52 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "7ed8854b26c09af7ccccf73ded4bda054da6157b", + "revision": "80fccbc45163de816ecebc6ea2f57e4506a86166", "repo_path": "integration/gaia-central" } From 6c8374ace9525772d3958b8be9cd64b57785daaf Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Fri, 14 Nov 2014 15:17:24 -0800 Subject: [PATCH 18/29] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index eed86d258c8b..abc3e9a32fea 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index c05dbae4dc8e..a89493c627d1 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 563f8b271217..9b0585ec7964 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index e46b64a6d6b2..b21952a92621 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index c05dbae4dc8e..a89493c627d1 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index a8aef3222344..7275ad99ec10 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index c6f1bc8186b0..3287b4b587ca 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 8f573b66dcd8..eaa7d0c07b65 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index c28e2fa4ced8..fd6b6d400372 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index bf9532e5509a..69848133e2c2 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index 4b8d1e5f5044..76d685689f17 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From 4dfc964db9643f10c01a1d32fbf6504f822c923b Mon Sep 17 00:00:00 2001 From: Nick Alexander Date: Fri, 14 Nov 2014 15:51:50 -0800 Subject: [PATCH 19/29] Bug 1093401 - Only set MOZ_DATA_REPORTING in configure. r=rnewman For all applications, MOZ_DATA_REPORTING is set in configure if any of MOZ_TELEMETRY_REPORTING, MOZ_SERVICES_HEALTHREPORT, or MOZ_CRASHREPORTER is set. For mobile/android, we *also* set MOZ_DATA_REPORTING when we're not in a release (Beta/Release) build. Geo/stumbler data is build-time enabled by MOZ_ANDROID_MLS_STUMBLER but does not automatically upload data: the user must manually enable uploading geo/stumbler data. That is, this is an explicit opt-in rather than an explicit opt-out; and geo/stumbler data should not be covered by the data reporting notification at this time. In the past, I believe that geo/stumbler data was uploaded based on the feature being build time enabled, which corresponded to !RELEASE_BUILD, so the logic being removed was reasonable. --- mobile/android/confvars.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/mobile/android/confvars.sh b/mobile/android/confvars.sh index d09e2ed71f79..3e14df27b6d0 100644 --- a/mobile/android/confvars.sh +++ b/mobile/android/confvars.sh @@ -55,11 +55,6 @@ MOZ_PAY=1 # Enable UI for healthreporter MOZ_SERVICES_HEALTHREPORT=1 -# Wifi-AP/cell tower data reporting is enabled on non-release builds. -if test ! "$RELEASE_BUILD"; then -MOZ_DATA_REPORTING=1 -fi - # Enable runtime locale switching. MOZ_LOCALE_SWITCHER=1 From ffc244bbadca03c4b70035d9d3072b0846edf04f Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Fri, 14 Nov 2014 15:55:54 -0800 Subject: [PATCH 20/29] Bumping gaia.json for 1 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/d671a244ca98 Author: Dale Harvey Desc: Bug 1030045 - Define MOZ_DISABLE_NONLOCAL_CONNECTIONS for integration tests. r=jlal --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 19bfac8f1c52..37ee76d72a55 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "80fccbc45163de816ecebc6ea2f57e4506a86166", + "revision": "d671a244ca9804da1fb7874701967afff1f017ea", "repo_path": "integration/gaia-central" } From 2e16284a33073fbb0c306f8eaffceeac768283ac Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Fri, 14 Nov 2014 16:02:19 -0800 Subject: [PATCH 21/29] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index abc3e9a32fea..b3f3c7ab1774 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index a89493c627d1..b60c597ae083 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 9b0585ec7964..3c7b9324c969 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index b21952a92621..23a5c1634b74 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index a89493c627d1..b60c597ae083 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 7275ad99ec10..a51ea0af9f8d 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 3287b4b587ca..cd6a1e233d6b 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index eaa7d0c07b65..da219ee6845c 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index fd6b6d400372..4e2c63b0e904 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 69848133e2c2..ce7ada04a855 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index 76d685689f17..fd27d6cf1229 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From a2a53064df9a4c371121a36b0a9ae4ae163d0c20 Mon Sep 17 00:00:00 2001 From: Mike Habicher Date: Fri, 14 Nov 2014 20:56:59 -0500 Subject: [PATCH 22/29] Bug 1098660 - fix the (complex) requirements for video mode preview size, r=aosmond --- dom/camera/CameraControlImpl.cpp | 2 +- dom/camera/GonkCameraControl.cpp | 367 ++++++++++++++++++++-------- dom/camera/GonkCameraControl.h | 7 +- dom/camera/GonkCameraParameters.cpp | 2 + dom/camera/ICameraControl.h | 1 + 5 files changed, 273 insertions(+), 106 deletions(-) diff --git a/dom/camera/CameraControlImpl.cpp b/dom/camera/CameraControlImpl.cpp index 7e63473bd741..bec91b9b2ae8 100644 --- a/dom/camera/CameraControlImpl.cpp +++ b/dom/camera/CameraControlImpl.cpp @@ -84,7 +84,7 @@ CameraControlImpl::OnHardwareStateChange(CameraControlListener::HardwareState aN } #ifdef PR_LOGGING - const char* state[] = { "open", "closed", "failed" }; + const char* state[] = { "closed", "open", "failed" }; MOZ_ASSERT(aNewState >= 0); if (static_cast(aNewState) < sizeof(state) / sizeof(state[0])) { DOM_CAMERA_LOGI("New hardware state is '%s'\n", state[aNewState]); diff --git a/dom/camera/GonkCameraControl.cpp b/dom/camera/GonkCameraControl.cpp index 9fd95e68d2bf..b4f24d99a27e 100644 --- a/dom/camera/GonkCameraControl.cpp +++ b/dom/camera/GonkCameraControl.cpp @@ -313,22 +313,114 @@ nsGonkCameraControl::SetConfigurationImpl(const Configuration& aConfig) return StartPreviewImpl(); } +nsresult +nsGonkCameraControl::MaybeAdjustVideoSize() +{ + MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread); + MOZ_ASSERT(mSeparateVideoAndPreviewSizesSupported); + + const Size& preview = mCurrentConfiguration.mPreviewSize; + + // Some camera drivers will ignore our preview size if it's larger + // than the currently set video recording size, so in picture mode, we + // give preview size priority, and bump up the video size just in case. + // This is done on a best-effort basis. + + if (preview.width <= mLastRecorderSize.width && + preview.height <= mLastRecorderSize.height) { + DOM_CAMERA_LOGI("Video size %ux%u is suitable for preview size %ux%u\n", + mLastRecorderSize.width, mLastRecorderSize.height, + preview.width, preview.height); + return NS_OK; + } + + nsTArray sizes; + nsresult rv = Get(CAMERA_PARAM_SUPPORTED_VIDEOSIZES, sizes); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + const uint32_t previewArea = preview.width * preview.height; + uint32_t bestDelta = UINT32_MAX; + bool foundBest = false; + SizeIndex best; + + for (SizeIndex i = 0; i < sizes.Length(); ++i) { + const Size& s = sizes[i]; + if (s.width < preview.width || s.height < preview.height) { + continue; + } + + const uint32_t area = s.width * s.height; + const uint32_t delta = area - previewArea; + if (delta < bestDelta) { + bestDelta = delta; + best = i; + foundBest = true; + } + } + + if (!foundBest) { + // If no candidate was found, the driver will be fine with a video size + // smaller than the chosen preview size. + DOM_CAMERA_LOGI("No video size candidate for preview size %ux%u (0x%x)\n", + preview.width, preview.height, rv); + return NS_OK; + } + + DOM_CAMERA_LOGI("Adjusting video size upwards to %ux%u\n", + sizes[best].width, sizes[best].height); + rv = Set(CAMERA_PARAM_VIDEOSIZE, sizes[best]); + if (NS_FAILED(rv)) { + DOM_CAMERA_LOGW("Failed to adjust video size for preview size %ux%u (0x%x)\n", + preview.width, preview.height, rv); + return rv; + } + + mLastRecorderSize = preview; + return NS_OK; +} + nsresult nsGonkCameraControl::SetPictureConfiguration(const Configuration& aConfig) { DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__); + MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread); - nsresult rv = SetPreviewSize(aConfig.mPreviewSize); + nsTArray sizes; + nsresult rv = Get(CAMERA_PARAM_SUPPORTED_PREVIEWSIZES, sizes); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } + Size preview; + rv = GetSupportedSize(aConfig.mPreviewSize, sizes, preview); + if (NS_FAILED(rv)) { + DOM_CAMERA_LOGE( + "Failed to find a supported preview size, requested size %ux%u (0x%x)", + aConfig.mPreviewSize.width, aConfig.mPreviewSize.height, rv); + return rv; + } + + rv = Set(CAMERA_PARAM_PREVIEWSIZE, preview); + if (NS_FAILED(rv)) { + DOM_CAMERA_LOGE("Failed to set supported preview size %ux%u (0x%x)", + preview.width, preview.height, rv); + return rv; + } + + mCurrentConfiguration.mPreviewSize = preview; + + if (mSeparateVideoAndPreviewSizesSupported) { + MaybeAdjustVideoSize(); + } + mParams.Get(CAMERA_PARAM_PREVIEWFRAMERATE, mPreviewFps); DOM_CAMERA_LOGI("picture mode preview: wanted %ux%u, got %ux%u (%u fps)\n", - aConfig.mPreviewSize.width, aConfig.mPreviewSize.height, - mCurrentConfiguration.mPreviewSize.width, mCurrentConfiguration.mPreviewSize.height, - mPreviewFps); + aConfig.mPreviewSize.width, aConfig.mPreviewSize.height, + preview.width, preview.height, + mPreviewFps); return NS_OK; } @@ -695,11 +787,10 @@ nsGonkCameraControl::SetThumbnailSizeImpl(const Size& aSize) int area = supportedSizes[i].width * supportedSizes[i].height; int delta = abs(area - targetArea); - if (area != 0 - && delta < smallestDelta - && supportedSizes[i].width * mLastPictureSize.height / - supportedSizes[i].height == mLastPictureSize.width - ) { + if (area != 0 && + delta < smallestDelta && + supportedSizes[i].width * mLastPictureSize.height == + mLastPictureSize.width * supportedSizes[i].height) { smallestDelta = delta; smallestDeltaIndex = i; } @@ -1249,71 +1340,9 @@ nsGonkCameraControl::OnTakePictureError() NS_ERROR_FAILURE); } -nsresult -nsGonkCameraControl::SetPreviewSize(const Size& aSize) -{ - MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread); - - nsTArray previewSizes; - nsresult rv = Get(CAMERA_PARAM_SUPPORTED_PREVIEWSIZES, previewSizes); - if (NS_FAILED(rv)) { - DOM_CAMERA_LOGE("Camera failed to return any preview sizes (0x%x)\n", rv); - return rv; - } - - Size best; - rv = GetSupportedSize(aSize, previewSizes, best); - if (NS_FAILED(rv)) { - DOM_CAMERA_LOGE("Failed to find a supported preview size, requested size %dx%d", - aSize.width, aSize.height); - return rv; - } - - if (mSeparateVideoAndPreviewSizesSupported) { - // Some camera drivers will ignore our preview size if it's larger - // than the currently set video recording size, so we need to set - // the video size here as well, just in case. - if (best.width > mLastRecorderSize.width || best.height > mLastRecorderSize.height) { - SetVideoSize(best); - } - } else { - mLastRecorderSize = best; - } - mCurrentConfiguration.mPreviewSize = best; - return Set(CAMERA_PARAM_PREVIEWSIZE, best); -} - -nsresult -nsGonkCameraControl::SetVideoSize(const Size& aSize) -{ - MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread); - - if (!mSeparateVideoAndPreviewSizesSupported) { - DOM_CAMERA_LOGE("Camera does not support setting separate video size\n"); - return NS_ERROR_NOT_AVAILABLE; - } - - nsTArray videoSizes; - nsresult rv = Get(CAMERA_PARAM_SUPPORTED_VIDEOSIZES, videoSizes); - if (NS_FAILED(rv)) { - DOM_CAMERA_LOGE("Camera failed to return any video sizes (0x%x)\n", rv); - return rv; - } - - Size best; - rv = GetSupportedSize(aSize, videoSizes, best); - if (NS_FAILED(rv)) { - DOM_CAMERA_LOGE("Failed to find a supported video size, requested size %dx%d", - aSize.width, aSize.height); - return rv; - } - mLastRecorderSize = best; - return Set(CAMERA_PARAM_VIDEOSIZE, best); -} - nsresult nsGonkCameraControl::GetSupportedSize(const Size& aSize, - const nsTArray& supportedSizes, + const nsTArray& aSupportedSizes, Size& best) { nsresult rv = NS_ERROR_INVALID_ARG; @@ -1323,24 +1352,25 @@ nsGonkCameraControl::GetSupportedSize(const Size& aSize, if (!aSize.width && !aSize.height) { // no size specified, take the first supported size - best = supportedSizes[0]; + best = aSupportedSizes[0]; return NS_OK; } else if (aSize.width && aSize.height) { // both height and width specified, find the supported size closest to // the requested size, looking for an exact match first - for (nsTArray::index_type i = 0; i < supportedSizes.Length(); i++) { - Size size = supportedSizes[i]; + for (SizeIndex i = 0; i < aSupportedSizes.Length(); ++i) { + Size size = aSupportedSizes[i]; if (size.width == aSize.width && size.height == aSize.height) { best = size; return NS_OK; } } - // no exact matches--look for a match closest in area - uint32_t targetArea = aSize.width * aSize.height; - for (nsTArray::index_type i = 0; i < supportedSizes.Length(); i++) { - Size size = supportedSizes[i]; - uint32_t delta = abs((long int)(size.width * size.height - targetArea)); + // no exact match on dimensions--look for a match closest in area + const uint32_t targetArea = aSize.width * aSize.height; + for (SizeIndex i = 0; i < aSupportedSizes.Length(); i++) { + Size size = aSupportedSizes[i]; + uint32_t delta = + abs(static_cast(size.width * size.height - targetArea)); if (delta < minSizeDelta) { minSizeDelta = delta; best = size; @@ -1349,9 +1379,9 @@ nsGonkCameraControl::GetSupportedSize(const Size& aSize, } } else if (!aSize.width) { // width not specified, find closest height match - for (nsTArray::index_type i = 0; i < supportedSizes.Length(); i++) { - Size size = supportedSizes[i]; - delta = abs((long int)(size.height - aSize.height)); + for (SizeIndex i = 0; i < aSupportedSizes.Length(); i++) { + Size size = aSupportedSizes[i]; + delta = abs(static_cast(size.height - aSize.height)); if (delta < minSizeDelta) { minSizeDelta = delta; best = size; @@ -1360,9 +1390,9 @@ nsGonkCameraControl::GetSupportedSize(const Size& aSize, } } else if (!aSize.height) { // height not specified, find closest width match - for (nsTArray::index_type i = 0; i < supportedSizes.Length(); i++) { - Size size = supportedSizes[i]; - delta = abs((long int)(size.width - aSize.width)); + for (SizeIndex i = 0; i < aSupportedSizes.Length(); i++) { + Size size = aSupportedSizes[i]; + delta = abs(static_cast(size.width - aSize.width)); if (delta < minSizeDelta) { minSizeDelta = delta; best = size; @@ -1370,9 +1400,147 @@ nsGonkCameraControl::GetSupportedSize(const Size& aSize, } } } + return rv; } +nsresult +nsGonkCameraControl::SetVideoAndPreviewSize(const Size& aPreviewSize, const Size& aVideoSize) +{ + MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread); + MOZ_ASSERT(mSeparateVideoAndPreviewSizesSupported); + + DOM_CAMERA_LOGI("Setting video size to %ux%u, preview size to %ux%u\n", + aVideoSize.width, aVideoSize.height, + aPreviewSize.width, aPreviewSize.height); + + Size oldSize; + nsresult rv = Get(CAMERA_PARAM_PREVIEWSIZE, oldSize); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + rv = Set(CAMERA_PARAM_PREVIEWSIZE, aPreviewSize); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + rv = Set(CAMERA_PARAM_VIDEOSIZE, aVideoSize); + if (NS_WARN_IF(NS_FAILED(rv))) { + Set(CAMERA_PARAM_VIDEOSIZE, oldSize); // error, try to restore the original preview size + return rv; + } + + mCurrentConfiguration.mPreviewSize = aPreviewSize; + mLastRecorderSize = aVideoSize; + + return NS_OK; +} + +nsresult +nsGonkCameraControl::SelectVideoAndPreviewSize(const Configuration& aConfig, const Size& aVideoSize) +{ + MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread); + MOZ_ASSERT(mSeparateVideoAndPreviewSizesSupported); + + nsTArray sizes; + + nsresult rv = Get(CAMERA_PARAM_SUPPORTED_VIDEOSIZES, sizes); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + Size video; + rv = GetSupportedSize(aVideoSize, sizes, video); + if (NS_FAILED(rv)) { + DOM_CAMERA_LOGE("Failed to find a supported video size, requested size %ux%u", + aVideoSize.width, aVideoSize.height); + return rv; + } + + rv = Get(CAMERA_PARAM_SUPPORTED_PREVIEWSIZES, sizes); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + Size preview; + rv = GetSupportedSize(aConfig.mPreviewSize, sizes, preview); + if (NS_FAILED(rv)) { + DOM_CAMERA_LOGE("Failed to find a supported preview size, requested size %ux%u", + aConfig.mPreviewSize.width, aConfig.mPreviewSize.height); + return rv; + } + + Size preferred; + rv = Get(CAMERA_PARAM_PREFERRED_PREVIEWSIZE_FOR_VIDEO, preferred); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + // If the requested preview size has the same aspect ratio as the + // requested video size, *and* is the same size or smaller than + // the preferred video size, then we're done. + const uint32_t preferredArea = preferred.width * preferred.height; + if (video.width * aConfig.mPreviewSize.height == aConfig.mPreviewSize.width * video.height && + preview.width * preview.height <= preferredArea) { + // We're done: set the video and preview sizes and return... + return SetVideoAndPreviewSize(preview, video); + } + + // Otherwise, if the requested preview size is larger than the preferred + // size, or there is an aspect ratio mismatch, then we need to set the + // preview size to the closest size smaller than the preferred size, + // preferably with the same aspect ratio as the requested video size. + + SizeIndex bestSizeMatch; + SizeIndex bestSizeMatchWithAspectRatio; + bool foundSizeMatch = false; + bool foundSizeMatchWithAspectRatio = false; + + uint32_t bestAreaDelta = UINT32_MAX; + uint32_t bestAreaDeltaWithAspect = UINT32_MAX; + + for (SizeIndex i = 0; i < sizes.Length(); ++i) { + const Size& s = sizes[i]; + const uint32_t area = s.width * s.height; + if (area > preferredArea) { + continue; + } + + const uint32_t delta = preferredArea - area; + if (s.width * video.height == video.width * s.height) { + if (delta == 0) { + // exact match, including aspect ratio--we can stop now + bestSizeMatchWithAspectRatio = i; + foundSizeMatchWithAspectRatio = true; + break; + } else if (delta < bestAreaDeltaWithAspect) { + // aspect ratio match + bestAreaDeltaWithAspect = delta; + bestSizeMatchWithAspectRatio = i; + foundSizeMatchWithAspectRatio = true; + } + } else if (delta < bestAreaDelta) { + bestAreaDelta = delta; + bestSizeMatch = i; + foundSizeMatch = true; + } + } + + if (foundSizeMatchWithAspectRatio) { + preview = sizes[bestSizeMatchWithAspectRatio]; + } else if (foundSizeMatch) { + DOM_CAMERA_LOGW("Unable to match a preview size with aspect ratio of video size %ux%u\n", + video.width, video.height); + preview = sizes[bestSizeMatch]; + } else { + DOM_CAMERA_LOGE("Unable to find a preview size for video size %ux%u\n", + video.width, video.height); + return NS_ERROR_INVALID_ARG; + } + + return SetVideoAndPreviewSize(preview, video); +} + nsresult nsGonkCameraControl::SetVideoConfiguration(const Configuration& aConfig) { @@ -1392,12 +1560,11 @@ nsGonkCameraControl::SetVideoConfiguration(const Configuration& aConfig) return NS_ERROR_INVALID_ARG; } - mCurrentConfiguration.mRecorderProfile = aConfig.mRecorderProfile; const RecorderProfile::Video& video(profile->GetVideo()); const Size& size = video.GetSize(); - int fps = video.GetFramesPerSecond(); - if (fps <= 0 || size.width <= 0 || size.height <= 0) { - DOM_CAMERA_LOGE("Can't configure video with fps=%d, width=%d, height=%d\n", + const uint32_t fps = video.GetFramesPerSecond(); + if (fps == 0 || fps > INT_MAX || size.width == 0 || size.height == 0) { + DOM_CAMERA_LOGE("Can't configure video with fps=%u, width=%u, height=%u\n", fps, size.width, size.height); return NS_ERROR_FAILURE; } @@ -1410,32 +1577,26 @@ nsGonkCameraControl::SetVideoConfiguration(const Configuration& aConfig) if (mSeparateVideoAndPreviewSizesSupported) { // The camera supports two video streams: a low(er) resolution preview - // stream and and a potentially high(er) resolution stream for encoding. - rv = SetVideoSize(size); + // stream and and a potentially high(er) resolution stream for encoding. + rv = SelectVideoAndPreviewSize(aConfig, size); if (NS_FAILED(rv)) { - DOM_CAMERA_LOGE("Failed to set video mode video size (0x%x)\n", rv); - return rv; - } - - // The video size must be set first, before the preview size, because - // some platforms have a dependency between the two. - rv = SetPreviewSize(aConfig.mPreviewSize); - if (NS_FAILED(rv)) { - DOM_CAMERA_LOGE("Failed to set video mode preview size (0x%x)\n", rv); + DOM_CAMERA_LOGE("Failed to set video and preview sizes (0x%x)\n", rv); return rv; } } else { // The camera only supports a single video stream: in this case, we set // the preview size to be the desired video recording size, and ignore // the specified preview size. - rv = SetPreviewSize(size); + rv = Set(CAMERA_PARAM_PREVIEWSIZE, size); if (NS_FAILED(rv)) { DOM_CAMERA_LOGE("Failed to set video mode preview size (0x%x)\n", rv); return rv; } + + mCurrentConfiguration.mPreviewSize = size; } - rv = Set(CAMERA_PARAM_PREVIEWFRAMERATE, fps); + rv = Set(CAMERA_PARAM_PREVIEWFRAMERATE, static_cast(fps)); if (NS_FAILED(rv)) { DOM_CAMERA_LOGE("Failed to set video mode frame rate (0x%x)\n", rv); return rv; diff --git a/dom/camera/GonkCameraControl.h b/dom/camera/GonkCameraControl.h index b7508080374f..0fe82967ab96 100644 --- a/dom/camera/GonkCameraControl.h +++ b/dom/camera/GonkCameraControl.h @@ -98,6 +98,8 @@ protected: using CameraControlImpl::OnConfigurationChange; using CameraControlImpl::OnUserError; + typedef nsTArray::index_type SizeIndex; + virtual void BeginBatchParameterSet() MOZ_OVERRIDE; virtual void EndBatchParameterSet() MOZ_OVERRIDE; @@ -130,8 +132,9 @@ protected: nsresult SetupRecording(int aFd, int aRotation, uint64_t aMaxFileSizeBytes, uint64_t aMaxVideoLengthMs); nsresult SetupRecordingFlash(bool aAutoEnableLowLightTorch); - nsresult SetPreviewSize(const Size& aSize); - nsresult SetVideoSize(const Size& aSize); + nsresult SelectVideoAndPreviewSize(const Configuration& aConfig, const Size& aVideoSize); + nsresult SetVideoAndPreviewSize(const Size& aPreviewSize, const Size& aVideoSize); + nsresult MaybeAdjustVideoSize(); nsresult PausePreview(); nsresult GetSupportedSize(const Size& aSize, const nsTArray& supportedSizes, Size& best); diff --git a/dom/camera/GonkCameraParameters.cpp b/dom/camera/GonkCameraParameters.cpp index 07e9cb848bb2..848a15aef3f9 100644 --- a/dom/camera/GonkCameraParameters.cpp +++ b/dom/camera/GonkCameraParameters.cpp @@ -117,6 +117,8 @@ GonkCameraParameters::Parameters::GetTextKey(uint32_t aKey) return KEY_RECORDING_HINT; case CAMERA_PARAM_PICTURE_QUALITY: return KEY_JPEG_QUALITY; + case CAMERA_PARAM_PREFERRED_PREVIEWSIZE_FOR_VIDEO: + return KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO; case CAMERA_PARAM_SUPPORTED_PREVIEWSIZES: return KEY_SUPPORTED_PREVIEW_SIZES; diff --git a/dom/camera/ICameraControl.h b/dom/camera/ICameraControl.h index 1b1407c34c2b..da1d9a36e2e3 100644 --- a/dom/camera/ICameraControl.h +++ b/dom/camera/ICameraControl.h @@ -54,6 +54,7 @@ enum { CAMERA_PARAM_LUMINANCE, CAMERA_PARAM_SCENEMODE_HDR_RETURNNORMALPICTURE, CAMERA_PARAM_RECORDINGHINT, + CAMERA_PARAM_PREFERRED_PREVIEWSIZE_FOR_VIDEO, // supported features CAMERA_PARAM_SUPPORTED_PREVIEWSIZES, From 178c35845016da80d9855e88c12e269b74174327 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Fri, 14 Nov 2014 21:00:52 -0800 Subject: [PATCH 23/29] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/eba399d3ba97 Author: Min-Zhong "John" Lu Desc: Merge pull request #26132 from mnjul/bug_1098955_remove_inputwindow_getdpx Bug 1098955 - Remove InputWindow._getDpx(); use Object.defineProperty to mock window.devicePixelRatio. r=timdream ======== https://hg.mozilla.org/integration/gaia-central/rev/494be473cbc2 Author: John Lu [:mnjul] Desc: Bug 1098955 - Remove InputWindow._getDpx(); use Object.defineProperty to mock window.devicePixelRatio --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 37ee76d72a55..ef09b516a637 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "d671a244ca9804da1fb7874701967afff1f017ea", + "revision": "eba399d3ba9724c77e073adccc0dfe9f8169dceb", "repo_path": "integration/gaia-central" } From 0618323144dfc4e86aa9194bd6c5e3ce254e3c82 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Fri, 14 Nov 2014 21:07:18 -0800 Subject: [PATCH 24/29] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index b3f3c7ab1774..5b23699feb40 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index b60c597ae083..b29991dc6c61 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 3c7b9324c969..1a95065bc0a7 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 23a5c1634b74..56d50af5650d 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index b60c597ae083..b29991dc6c61 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index a51ea0af9f8d..cdc1fb941cfb 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index cd6a1e233d6b..330ca3afcf89 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index da219ee6845c..244b32c5b5bf 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 4e2c63b0e904..11167fe7dfca 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index ce7ada04a855..0347b4b08895 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index fd27d6cf1229..8881cecf9583 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From 1ffd463d9d1b512eac4a3121af4b69f7cdc83f2a Mon Sep 17 00:00:00 2001 From: ffxbld Date: Sat, 15 Nov 2014 03:21:16 -0800 Subject: [PATCH 25/29] No bug, Automated HSTS preload list update from host b-linux64-ix-0011 - a=hsts-update --- .../manager/boot/src/nsSTSPreloadList.errors | 15 ++++-- .../manager/boot/src/nsSTSPreloadList.inc | 46 +++++++++++++++++-- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/security/manager/boot/src/nsSTSPreloadList.errors b/security/manager/boot/src/nsSTSPreloadList.errors index 58e84563b17f..a2ed86ddeb0b 100644 --- a/security/manager/boot/src/nsSTSPreloadList.errors +++ b/security/manager/boot/src/nsSTSPreloadList.errors @@ -16,7 +16,6 @@ at.search.yahoo.com: did not receive HSTS header au.search.yahoo.com: did not receive HSTS header az.search.yahoo.com: did not receive HSTS header azprep.us: did not receive HSTS header -bassh.net: did not receive HSTS header bccx.com: could not connect to host be.search.yahoo.com: did not receive HSTS header bedeta.de: could not connect to host @@ -89,12 +88,13 @@ facebook.com: did not receive HSTS header fatzebra.com.au: did not receive HSTS header fi.search.yahoo.com: did not receive HSTS header filedir.com: did not receive HSTS header -fixingdns.com: could not connect to host +fixingdns.com: did not receive HSTS header fj.search.yahoo.com: did not receive HSTS header fr.search.yahoo.com: did not receive HSTS header gamesdepartment.co.uk: did not receive HSTS header get.zenpayroll.com: did not receive HSTS header getlantern.org: did not receive HSTS header +gizzo.sk: could not connect to host gl.search.yahoo.com: did not receive HSTS header glass.google.com: did not receive HSTS header (error ignored - included regardless) gm.search.yahoo.com: did not receive HSTS header @@ -108,6 +108,7 @@ gr.search.yahoo.com: did not receive HSTS header greplin.com: could not connect to host groups.google.com: did not receive HSTS header (error ignored - included regardless) hackerone-user-content.com: could not connect to host +haste.ch: could not connect to host history.google.com: did not receive HSTS header (error ignored - included regardless) hk.search.yahoo.com: did not receive HSTS header hn.search.yahoo.com: did not receive HSTS header @@ -121,6 +122,7 @@ id.search.yahoo.com: did not receive HSTS header ie.search.yahoo.com: did not receive HSTS header ilmconpm.de: did not receive HSTS header in.search.yahoo.com: did not receive HSTS header +inertianetworks.com: did not receive HSTS header intercom.io: did not receive HSTS header iop.intuit.com: max-age too low: 86400 irccloud.com: did not receive HSTS header @@ -139,14 +141,13 @@ li.search.yahoo.com: did not receive HSTS header liberty.lavabit.com: could not connect to host lifeguard.aecom.com: max-age too low: 86400 lists.mayfirst.org: did not receive HSTS header -logentries.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no] login.corp.google.com: max-age too low: 7776000 (error ignored - included regardless) logotype.se: did not receive HSTS header lovelycorral.com: did not receive HSTS header lt.search.yahoo.com: did not receive HSTS header lu.search.yahoo.com: did not receive HSTS header lumi.do: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no] -luxus-russen.de: did not receive HSTS header +luxus-russen.de: could not connect to host lv.search.yahoo.com: did not receive HSTS header m.facebook.com: did not receive HSTS header m.gparent.org: could not connect to host @@ -161,6 +162,7 @@ megaxchange.com: did not receive HSTS header minikneet.nl: did not receive HSTS header mobilethreat.net: could not connect to host mobilethreatnetwork.net: could not connect to host +mocloud.eu: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no] mt.search.yahoo.com: did not receive HSTS header mtouch.facebook.com: did not receive HSTS header mu.search.yahoo.com: did not receive HSTS header @@ -216,6 +218,7 @@ ru.search.yahoo.com: did not receive HSTS header rw.search.yahoo.com: did not receive HSTS header sah3.net: could not connect to host saturngames.co.uk: did not receive HSTS header +schreiber-netzwerk.eu: max-age too low: 0 script.google.com: did not receive HSTS header (error ignored - included regardless) se.search.yahoo.com: did not receive HSTS header search.yahoo.com: did not receive HSTS header @@ -235,10 +238,13 @@ sol.io: could not connect to host souyar.de: could not connect to host souyar.net: could not connect to host souyar.us: could not connect to host +spdysync.com: did not receive HSTS header +spongepowered.org: did not receive HSTS header spreadsheets.google.com: did not receive HSTS header (error ignored - included regardless) square.com: did not receive HSTS header ssl.google-analytics.com: did not receive HSTS header (error ignored - included regardless) ssl.panoramio.com: did not receive HSTS header +staticanime.net: did not receive HSTS header stocktrade.de: could not connect to host sunshinepress.org: could not connect to host surfeasy.com: did not receive HSTS header @@ -252,7 +258,6 @@ tektoria.de: did not receive HSTS header temehu.com: did not receive HSTS header terrax.berlin: could not connect to host th.search.yahoo.com: did not receive HSTS header -tonerjet.co.uk: could not connect to host touch.facebook.com: did not receive HSTS header tr.search.yahoo.com: did not receive HSTS header translate.googleapis.com: did not receive HSTS header (error ignored - included regardless) diff --git a/security/manager/boot/src/nsSTSPreloadList.inc b/security/manager/boot/src/nsSTSPreloadList.inc index fa4e535e1f9f..dfc92b250be4 100644 --- a/security/manager/boot/src/nsSTSPreloadList.inc +++ b/security/manager/boot/src/nsSTSPreloadList.inc @@ -8,7 +8,7 @@ /*****************************************************************************/ #include -const PRTime gPreloadListExpirationTime = INT64_C(1426331489992000); +const PRTime gPreloadListExpirationTime = INT64_C(1426936177225000); class nsSTSPreload { @@ -36,6 +36,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "aiticon.com", true }, { "aladdinschools.appspot.com", false }, { "alexsexton.com", true }, + { "alexyang.me", true }, { "alpha.irccloud.com", false }, { "andreasbreitenlohner.de", true }, { "anetaben.nl", true }, @@ -73,10 +74,12 @@ static const nsSTSPreload kSTSPreloadList[] = { { "barslecht.com", true }, { "barslecht.nl", true }, { "baruch.me", true }, + { "bassh.net", true }, { "bautied.de", true }, { "bayrisch-fuer-anfaenger.de", true }, { "bccx.com", true }, { "bcrook.com", false }, + { "beamitapp.com", true }, { "beastowner.com", true }, { "beastowner.li", true }, { "bedeta.de", true }, @@ -102,6 +105,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "blog.torproject.org", false }, { "bodo-wolff.de", true }, { "bohramt.de", true }, + { "bonigo.de", true }, { "boxcryptor.com", true }, { "brunosouza.org", true }, { "buddhistische-weisheiten.org", true }, @@ -119,15 +123,19 @@ static const nsSTSPreload kSTSPreloadList[] = { { "cdnb.co", true }, { "celltek-server.de", false }, { "certible.com", true }, + { "certly.io", true }, { "chainmonitor.com", true }, { "check.torproject.org", false }, { "checkout.google.com", true }, + { "chontalpa.pw", true }, { "chrisjean.com", true }, { "chrome-devtools-frontend.appspot.com", true }, { "chrome.google.com", true }, { "chromiumcodereview.appspot.com", false }, { "chulado.com", true }, + { "cktennis.com", true }, { "clapping-rhymes.com", true }, + { "clintwilson.technology", true }, { "cloud.google.com", true }, { "cloudcert.org", true }, { "cloudns.com.au", true }, @@ -151,6 +159,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "crowdjuris.com", true }, { "crypto.cat", false }, { "cryptopartyatx.org", true }, + { "cspbuilder.info", true }, { "cube.de", true }, { "cujanovic.com", true }, { "cupcake.io", true }, @@ -171,14 +180,17 @@ static const nsSTSPreload kSTSPreloadList[] = { { "debtkit.co.uk", true }, { "dedimax.de", true }, { "denh.am", true }, + { "depechemode-live.com", true }, { "derevtsov.com", false }, { "derhil.de", true }, + { "destinationbijoux.fr", true }, { "detectify.com", false }, { "developer.mydigipass.com", false }, { "devh.de", true }, { "diamante.ro", true }, { "die-besten-weisheiten.de", true }, { "dillonkorman.com", true }, + { "dinamoelektrik.com", true }, { "dist.torproject.org", false }, { "dl.google.com", true }, { "dlc.viasinc.com", true }, @@ -211,22 +223,24 @@ static const nsSTSPreload kSTSPreloadList[] = { { "errors.zenpayroll.com", false }, { "esec.rs", true }, { "espra.com", true }, + { "ethack.org", true }, { "ethitter.com", true }, { "eurotramp.com", true }, { "everhome.de", true }, { "evstatus.com", true }, { "explodie.org", true }, { "f-droid.org", true }, + { "fabianfischer.de", true }, { "factor.cc", false }, { "fairbill.com", true }, { "faq.lookout.com", false }, + { "fastcomcorp.net", true }, { "fedorapeople.org", true }, { "feedbin.com", false }, { "ferienhaus-polchow-ruegen.de", false }, { "fiken.no", true }, { "firemail.io", true }, { "fischer-its.com", true }, - { "fixingdns.com", true }, { "fj.simple.com", false }, { "flamer-scene.com", true }, { "fleximus.org", false }, @@ -313,13 +327,15 @@ static const nsSTSPreload kSTSPreloadList[] = { { "imouto.my", false }, { "in.xero.com", false }, { "inbox.google.com", true }, - { "inertianetworks.com", true }, + { "inkbunny.net", true }, { "inleaked.com", true }, { "insouciant.org", true }, { "irische-segenswuensche.info", true }, { "ironfistdesign.com", true }, { "isitchristmas.com", true }, { "it-schwerin.de", true }, + { "itsamurai.ru", true }, + { "itshost.ru", true }, { "jackyyf.com", false }, { "janoberst.com", true }, { "janus-engineering.de", true }, @@ -327,16 +343,19 @@ static const nsSTSPreload kSTSPreloadList[] = { { "jelmer.uk", true }, { "jfreitag.de", true }, { "jitsi.org", false }, + { "jmedved.com", true }, { "jonas-keidel.de", true }, { "jonaswitmer.ch", true }, { "jonnybarnes.uk", true }, { "julian-kipka.de", true }, + { "jwilsson.com", true }, { "jwilsson.me", true }, { "k-dev.de", true }, { "kaheim.de", true }, { "kardize24.pl", true }, { "kartonmodellbau.org", true }, { "kdex.de", true }, + { "keepclean.me", true }, { "keeperapp.com", true }, { "keepersecurity.com", true }, { "kernel-error.de", true }, @@ -349,6 +368,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "kinsights.com", false }, { "kitsta.com", true }, { "klatschreime.de", true }, + { "klausbrinch.dk", true }, { "klaxn.com", true }, { "kleidertauschpartys.de", true }, { "knowledgehook.com", true }, @@ -364,6 +384,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "launchkey.com", true }, { "lavalite.de", true }, { "lb-toner.de", true }, + { "leonardcamacho.me", true }, { "library.linode.com", false }, { "liebel.org", true }, { "limpid.nl", true }, @@ -407,6 +428,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "mattmccutchen.net", true }, { "mbp.banking.co.at", false }, { "md5file.com", true }, + { "mdfnet.se", true }, { "mediacru.sh", true }, { "medium.com", true }, { "meetfinch.com", true }, @@ -415,7 +437,9 @@ static const nsSTSPreload kSTSPreloadList[] = { { "members.mayfirst.org", false }, { "members.nearlyfreespeech.net", false }, { "miasarafina.de", true }, + { "michalspacek.cz", true }, { "mig5.net", true }, + { "mike-bland.com", true }, { "mikewest.org", true }, { "miku.hatsune.my", true }, { "minez-nightswatch.com", true }, @@ -458,11 +482,13 @@ static const nsSTSPreload kSTSPreloadList[] = { { "nmctest.net", true }, { "nos-oignons.net", true }, { "npw.net", true }, + { "oakslighting.co.uk", true }, { "okmx.de", true }, { "omitech.co.uk", true }, { "onedot.nl", true }, { "onedrive.com", true }, { "onedrive.live.com", false }, + { "onsitemassageco.com", true }, { "oplop.appspot.com", true }, { "opsmate.com", false }, { "optimus.io", true }, @@ -513,6 +539,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "prefontaine.name", true }, { "profiles.google.com", true }, { "projektzentrisch.de", true }, + { "propagandism.org", true }, { "prowhisky.de", true }, { "pubkey.is", true }, { "publications.qld.gov.au", false }, @@ -550,7 +577,6 @@ static const nsSTSPreload kSTSPreloadList[] = { { "sandbox.mydigipass.com", false }, { "schachburg.de", true }, { "schokokeks.org", false }, - { "schreiber-netzwerk.eu", true }, { "schwarzer.it", true }, { "sciencex.com", true }, { "scotthelme.co.uk", true }, @@ -582,12 +608,13 @@ static const nsSTSPreload kSTSPreloadList[] = { { "sites.google.com", true }, { "skydrive.live.com", false }, { "slattery.co", true }, + { "slevomat.cz", true }, { "slidebatch.com", true }, { "smartcoin.com.br", true }, { "smartship.co.jp", true }, + { "sour.is", true }, { "southside-crew.com", true }, { "spartantheatre.org", true }, - { "spdysync.com", true }, { "spencerbaer.com", true }, { "spideroak.com", true }, { "spreadsheets.google.com", true }, @@ -611,10 +638,12 @@ static const nsSTSPreload kSTSPreloadList[] = { { "studydrive.net", true }, { "subrosa.io", true }, { "suite73.org", true }, + { "sunjaydhama.com", true }, { "supplies24.at", true }, { "supplies24.es", true }, { "support.mayfirst.org", false }, { "surkatty.org", true }, + { "swehack.org", true }, { "sylaps.com", true }, { "sysctl.se", true }, { "syss.de", true }, @@ -634,6 +663,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "therapynotes.com", false }, { "theshadestore.com", true }, { "thorncreek.net", false }, + { "thusoy.com", true }, { "tickopa.co.uk", true }, { "timtaubert.de", true }, { "tinfoilsecurity.com", false }, @@ -641,6 +671,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "tintenfix.net", true }, { "tipps-fuer-den-haushalt.de", true }, { "tittelbach.at", true }, + { "tls.li", true }, { "tno.io", true }, { "tobias-kluge.de", true }, { "tollmanz.com", true }, @@ -681,6 +712,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "usaa.com", false }, { "uzstyle.com", false }, { "vaddder.com", true }, + { "vhost.co.id", true }, { "viasinc.com", false }, { "viennan.net", true }, { "vmoagents.com", false }, @@ -692,6 +724,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "warrencreative.com", false }, { "watsonhall.uk", true }, { "webandmore.de", false }, + { "webandwords.com.au", true }, { "webcollect.org.uk", true }, { "webfilings-eu-mirror.appspot.com", true }, { "webfilings-eu.appspot.com", true }, @@ -702,6 +735,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "webmail.onlime.ch", false }, { "webmail.schokokeks.org", false }, { "websenat.de", true }, + { "webtiles.co.uk", true }, { "weggeweest.nl", true }, { "welches-kinderfahrrad.de", true }, { "wepay.com", false }, @@ -773,11 +807,13 @@ static const nsSTSPreload kSTSPreloadList[] = { { "xn--maraa-rta.org", true }, { "xps2pdf.co.uk", true }, { "y-o-w.com", true }, + { "yoursecondphone.co", true }, { "ypart.eu", true }, { "z.ai", true }, { "zenpayroll.com", false }, { "zeplin.io", false }, { "zeropush.com", true }, { "zixiao.wang", true }, + { "zlavomat.sk", true }, { "zotero.org", true }, }; From 4bccbd33d3f2c7def96b1da9f0452b314e9952a0 Mon Sep 17 00:00:00 2001 From: ffxbld Date: Sat, 15 Nov 2014 03:21:19 -0800 Subject: [PATCH 26/29] No bug, Automated HPKP preload list update from host b-linux64-ix-0011 - a=hpkp-update --- security/manager/boot/src/StaticHPKPins.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/manager/boot/src/StaticHPKPins.h b/security/manager/boot/src/StaticHPKPins.h index 4151b10cb041..0cdc9ebb44a0 100644 --- a/security/manager/boot/src/StaticHPKPins.h +++ b/security/manager/boot/src/StaticHPKPins.h @@ -1125,4 +1125,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = { static const int32_t kUnknownId = -1; -static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1423912295636000); +static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1424516980930000); From d2233af98c99f25b35a2582505c7a51fb59d2d43 Mon Sep 17 00:00:00 2001 From: ffxbld Date: Sat, 15 Nov 2014 03:21:24 -0800 Subject: [PATCH 27/29] No bug, Automated blocklist update from host b-linux64-ix-0011 - a=blocklist-update --- browser/app/blocklist.xml | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/browser/app/blocklist.xml b/browser/app/blocklist.xml index 0458e972a708..1e06f9b07657 100644 --- a/browser/app/blocklist.xml +++ b/browser/app/blocklist.xml @@ -1,5 +1,5 @@ - + @@ -533,6 +533,12 @@ + + + + + + @@ -886,6 +892,12 @@ + + + + + + @@ -1542,6 +1554,12 @@ + + + + + + From f9ef31db91bfa01f1b33836207cfbb662531c185 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Sat, 15 Nov 2014 09:48:03 -0800 Subject: [PATCH 28/29] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 5b23699feb40..3b614532ff8c 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -23,7 +23,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index b29991dc6c61..4bb838410f9e 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -25,7 +25,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 1a95065bc0a7..e3f347cbd03d 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -20,7 +20,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 56d50af5650d..2709420f9183 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -23,7 +23,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index b29991dc6c61..4bb838410f9e 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -25,7 +25,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index cdc1fb941cfb..375b8de3fc75 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -23,7 +23,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 330ca3afcf89..8a2bd3ef388d 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -20,7 +20,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 244b32c5b5bf..b6e91cd5264e 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -21,7 +21,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 0347b4b08895..a172ea472e03 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -20,7 +20,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index 8881cecf9583..265b0d9cafb9 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -22,7 +22,7 @@ - + From 0e4e95561639c62d07c1939e326564397fc8caf6 Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Sat, 15 Nov 2014 22:40:00 +0000 Subject: [PATCH 29/29] Backout changesets fad675db4598 and 618d8f44d9e2 (bug 1090168 pt 1 and 2) for Nightly crashiness. a=backout --- dom/canvas/CanvasRenderingContext2D.cpp | 71 +++++++------------------ 1 file changed, 19 insertions(+), 52 deletions(-) diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index fdbef56e9aae..d247b188f3e6 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -1469,25 +1469,6 @@ CanvasRenderingContext2D::ClearTarget() state->colorStyles[Style::FILL] = NS_RGB(0,0,0); state->colorStyles[Style::STROKE] = NS_RGB(0,0,0); state->shadowColor = NS_RGBA(0,0,0,0); - - // For vertical writing-mode, unless text-orientation is sideways, - // we'll modify the initial value of textBaseline to 'middle'. - nsRefPtr canvasStyle; - if (mCanvasElement && mCanvasElement->IsInDoc()) { - nsCOMPtr presShell = GetPresShell(); - if (presShell) { - canvasStyle = - nsComputedDOMStyle::GetStyleContextForElement(mCanvasElement, - nullptr, - presShell); - if (canvasStyle) { - WritingMode wm(canvasStyle); - if (wm.IsVertical() && !wm.IsSideways()) { - state->textBaseline = TextBaseline::MIDDLE; - } - } - } - } } NS_IMETHODIMP @@ -3284,7 +3265,6 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess gfxPoint point = mPt; bool rtl = mTextRun->IsRightToLeft(); bool verticalRun = mTextRun->IsVertical(); - bool centerBaseline = mTextRun->UseCenterBaseline(); gfxFloat& inlineCoord = verticalRun ? point.y : point.x; inlineCoord += xOffset; @@ -3353,27 +3333,20 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess if (runs[c].mOrientation == gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_RIGHT) { sidewaysRestore.Init(mCtx->mTarget); + // TODO: The baseline adjustment here is kinda ad-hoc; eventually + // perhaps we should check for horizontal and vertical baseline data + // in the font, and adjust accordingly. + // (The same will be true for HTML text layout.) const gfxFont::Metrics& metrics = mTextRun->GetFontGroup()-> GetFirstValidFont()->GetMetrics(gfxFont::eHorizontal); - - gfx::Matrix mat = mCtx->mTarget->GetTransform().Copy(). + mCtx->mTarget->SetTransform(mCtx->mTarget->GetTransform().Copy(). PreTranslate(baselineOrigin). // translate origin for rotation PreRotate(gfx::Float(M_PI / 2.0)). // turn 90deg clockwise - PreTranslate(-baselineOrigin); // undo the translation - - if (centerBaseline) { - // TODO: The baseline adjustment here is kinda ad hoc; eventually - // perhaps we should check for horizontal and vertical baseline data - // in the font, and adjust accordingly. - // (The same will be true for HTML text layout.) - float offset = (metrics.emAscent - metrics.emDescent) / 2; - mat = mat.PreTranslate(Point(0, offset)); - // offset the (alphabetic) baseline of the + PreTranslate(-baselineOrigin). // undo the translation + PreTranslate(Point(0, (metrics.emAscent - metrics.emDescent) / 2))); + // and offset the (alphabetic) baseline of the // horizontally-shaped text from the (centered) // default baseline used for vertical - } - - mCtx->mTarget->SetTransform(mat); } RefPtr renderingOptions = font->GetGlyphRenderingOptions(); @@ -3665,45 +3638,39 @@ CanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText, processor.mPt.x -= anchorX * totalWidth; - // offset pt.y (or pt.x, for vertical text) based on text baseline + // offset pt.y based on text baseline processor.mFontgrp->UpdateUserFonts(); // ensure user font generation is current const gfxFont::Metrics& fontMetrics = - processor.mFontgrp->GetFirstValidFont()->GetMetrics(gfxFont::eHorizontal); + processor.mFontgrp->GetFirstValidFont()->GetMetrics( + ((processor.mTextRunFlags & gfxTextRunFactory::TEXT_ORIENT_MASK) == + gfxTextRunFactory::TEXT_ORIENT_HORIZONTAL) + ? gfxFont::eHorizontal : gfxFont::eVertical); - gfxFloat baselineAnchor; + gfxFloat anchorY; switch (state.textBaseline) { case TextBaseline::HANGING: // fall through; best we can do with the information available case TextBaseline::TOP: - baselineAnchor = fontMetrics.emAscent; + anchorY = fontMetrics.emAscent; break; case TextBaseline::MIDDLE: - baselineAnchor = (fontMetrics.emAscent - fontMetrics.emDescent) * .5f; + anchorY = (fontMetrics.emAscent - fontMetrics.emDescent) * .5f; break; case TextBaseline::IDEOGRAPHIC: // fall through; best we can do with the information available case TextBaseline::ALPHABETIC: - baselineAnchor = 0; + anchorY = 0; break; case TextBaseline::BOTTOM: - baselineAnchor = -fontMetrics.emDescent; + anchorY = -fontMetrics.emDescent; break; default: MOZ_CRASH("unexpected TextBaseline"); } - if (processor.mTextRun->IsVertical()) { - if (processor.mTextRun->UseCenterBaseline()) { - // Adjust to account for mTextRun being shaped using center baseline - // rather than alphabetic. - baselineAnchor -= (fontMetrics.emAscent - fontMetrics.emDescent) * .5f; - } - processor.mPt.x -= baselineAnchor; - } else { - processor.mPt.y += baselineAnchor; - } + processor.mPt.y += anchorY; // correct bounding box to get it to be the correct size/position processor.mBoundingBox.width = totalWidth;