aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/develop/check_flash_bbcodes.php
blob: 5946f685b8acdb39c39ea50c02f05d55cf3d7af1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
<?php
/**
*
* @package phpBB3
* @copyright (c) 2009, 2010 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
* This script will check your database for potentially dangerous flash BBCode tags
*
*/

//
// Security message:
//
// This script is potentially dangerous.
// Remove or comment the next line (die(".... ) to enable this script.
// Do NOT FORGET to either remove this script or disable it after you have used it.
//
die("Please read the first lines of this script for instructions on how to enable it\n");

/**
*/
define('IN_PHPBB', true);
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);

if (php_sapi_name() != 'cli')
{
	header('Content-Type: text/plain');
}

check_table_flash_bbcodes(POSTS_TABLE, 'post_id', 'post_text', 'bbcode_uid', 'bbcode_bitfield');
check_table_flash_bbcodes(PRIVMSGS_TABLE, 'msg_id', 'message_text', 'bbcode_uid', 'bbcode_bitfield');
check_table_flash_bbcodes(USERS_TABLE, 'user_id', 'user_sig', 'user_sig_bbcode_uid', 'user_sig_bbcode_bitfield');
check_table_flash_bbcodes(FORUMS_TABLE, 'forum_id', 'forum_desc', 'forum_desc_uid', 'forum_desc_bitfield');
check_table_flash_bbcodes(FORUMS_TABLE, 'forum_id', 'forum_rules', 'forum_rules_uid', 'forum_rules_bitfield');
check_table_flash_bbcodes(GROUPS_TABLE, 'group_id', 'group_desc', 'group_desc_uid', 'group_desc_bitfield');

echo "If potentially dangerous flash bbcodes were found, please reparse the posts using the Support Toolkit (http://www.phpbb.com/support/stk/) and/or file a ticket in the Incident Tracker (http://www.phpbb.com/incidents/).\n";

function check_table_flash_bbcodes($table_name, $id_field, $content_field, $uid_field, $bitfield_field)
{
	echo "Checking $content_field on $table_name\n";

	$ids = get_table_flash_bbcode_pkids($table_name, $id_field, $content_field, $uid_field, $bitfield_field);

	$size = sizeof($ids);
	if ($size)
	{
		echo "Found $size potentially dangerous flash bbcodes.\n";
		echo "$id_field: " . implode(', ', $ids) . "\n";
	}
	else
	{
		echo "No potentially dangerous flash bbcodes found.\n";
	}

	echo "\n";
}

function get_table_flash_bbcode_pkids($table_name, $id_field, $content_field, $uid_field, $bitfield_field)
{
	global $db;

	$ids = array();

	$sql = "SELECT $id_field, $content_field, $uid_field, $bitfield_field
		FROM $table_name
		WHERE $content_field LIKE '%[/flash:%'
			AND $bitfield_field <> ''";

	$result = $db->sql_query($sql);
	while ($row = $db->sql_fetchrow($result))
	{
		$uid = $row[$uid_field];

		// thanks support toolkit
		$content = html_entity_decode_utf8($row[$content_field]);
		set_var($content, $content, 'string', true);
		$content = utf8_normalize_nfc($content);

		$bitfield_data = $row[$bitfield_field];

		if (!is_valid_flash_bbcode($content, $uid) && has_flash_enabled($bitfield_data))
		{
			$ids[] = (int) $row[$id_field];
		}
	}
	$db->sql_freeresult($result);

	return $ids;
}

function get_flash_regex($uid)
{
	return "#\[flash=([0-9]+),([0-9]+):$uid\](.*?)\[/flash:$uid\]#";
}

// extract all valid flash bbcodes
// check if the bbcode content is a valid URL for each match
function is_valid_flash_bbcode($cleaned_content, $uid)
{
	$regex = get_flash_regex($uid);

	$url_regex = get_preg_expression('url');
	$www_url_regex = get_preg_expression('www_url');

	if (preg_match_all($regex, $cleaned_content, $matches))
	{
		foreach ($matches[3] as $flash_url)
		{
			if (!preg_match("#^($url_regex|$www_url_regex)$#i", $flash_url))
			{
				return false;
			}
		}
	}

	return true;
}

// check if a bitfield includes flash
// 11 = flash bit
function has_flash_enabled($bitfield_data)
{
	$bitfield = new bitfield($bitfield_data);
	return $bitfield->get(11);
}

// taken from support toolkit
function html_entity_decode_utf8($string)
{
	static $trans_tbl;

	// replace numeric entities
	$string = preg_replace('~&#x([0-9a-f]+);~ei', 'code2utf8(hexdec("\\1"))', $string);
	$string = preg_replace('~&#([0-9]+);~e', 'code2utf8(\\1)', $string);

	// replace literal entities
	if (!isset($trans_tbl))
	{
		$trans_tbl = array();

		foreach (get_html_translation_table(HTML_ENTITIES) as $val=>$key)
			$trans_tbl[$key] = utf8_encode($val);
	}
	return strtr($string, $trans_tbl);
}

// taken from support toolkit
// Returns the utf string corresponding to the unicode value (from php.net, courtesy - romans@void.lv)
function code2utf8($num)
{
	if ($num < 128) return chr($num);
	if ($num < 2048) return chr(($num >> 6) + 192) . chr(($num & 63) + 128);
	if ($num < 65536) return chr(($num >> 12) + 224) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
	if ($num < 2097152) return chr(($num >> 18) + 240) . chr((($num >> 12) & 63) + 128) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
	return '';
}
̈ 1!t&jkYtv*2.FGHCc G)pjb͊ qO.I9 xBdybo 1ܙI.d;7FlRQ|3B<3 }rа= [& [Yfb'T㨭swH"FYD(m@ t%tK?rXbQC P'ܦ7l7_. P^5IwÄ́Jy]- LUoM+= ^/0)-B)Nڒ9kI " SA5yxX1d?eQF ibYͽpb^F+[XArP3.r.^5A0 {;Ahn.dM*̜pĜ9Ak O=ԭBe&ͭih5cEeBtFΚ/ ݉{I?{E.#w(o# ڵo}SEϓݯÊ"ͣXU+`ѴwrPW#^E֟ 8t=s oF+zq{"WJ]=XN8$[Cl癳T$_TÂR3Fd7斀dr%/myœcUnF򛷻ERw7E~EUy2e2 |1X8Q85r kEI7RLt 3+r ^שskؿkM5Os*Q9LzȀrŚ o= XHg˔rѢ^ChKenCR꛽+zMiDدv!&b\U<auPE O'ts/!o- W&z x ϳۏ͏ 1F"` ެ<:|A?Lj ?RNų.EFZ0'՝ל~HV+-Uk ]>! 璁t 8=Nv`aq*WSx8ö.QK; TI9&; lƠs#9z朥|MQ*TQ.Mt2/L6UqlX0)% }VcOەcI CKRG؄ryuٷ;›/T5;#+2BrV./6*6`p}78fʤ(^ u!م8O8ް閌 8 6qQzn[5>?kQރszQ-6xys`'(rdPrŪ?ڷJu65aaZkAʆ 6ώ Hz"7EnEb+o$- Bw錐$;R7H9Ϙ$»q IKX' +l:vlyޜq'hʭU?eG pgϷc~71Cs㫆HThɜ7V k=WQ%@A-لA!,c(9'G | aa×ot; wDiZ̛q2ʡ'kðOFO2tC4v_zbЗ#OpqwzЭVͯBOyeЇ8n mr¥=VKBx1ia5 B&8-@;E$[+\M҂y)e+Ut4λ}h8v&!7ޏ9*62[ZƤؔE%4#&wNzαf?d/Du4AQ|4nfKk$^l jAz -!dӉƕ/h."= "Tk q,T66*Z ]xu1YpZڛ!~n8E z@uB]+uVngIu<TxČ'3Z^. m[eT3HԼX2_.N4,m.E+_`;T',{ǒԹfCbr:ŕ7.0db3&&|3╦Ctn])j y+z+)l_o ~*IL;p[Bӧ9wdwPx;efp-X.:4yLfx$`1 f.(6伔,eW:>{)7e`Gr鞔 fu 𵹅TdEJ,S_MPk03Zr:DKiñhI?J\J|Q9.ǝ tlƧӉJb^yκ-r6u˃Le_RT# $RCw'ic0{e݇ɷ>4Rb,'{ngpT~1 u]SZ=|]{:<SӱSl);5Cn2Hl<(}AA :~UЉ",äq%Q/p Kr˿mrr=H]\K@\71_ mHI>䢯Uet<=ߙg1P_-m GtoNN 1"S@=='gcBFw8'Hz`<!{Y>Qr >^h^@A\~*oJӫ&nRT} |fx`Xd6IUk<f\q vQJ7Hz]722cݨrP7QH@j4%ƒk$.joOZ`d7 d5yͳ;]k緄̺T{<mG!~ >zUh a>mgH\)]5_P&ǾS@_0hEN˨fXqǟXc:)%ZA \/$`.G ῷzX55 `2Wg]Q~N5UD?UurLSݓ#P6e՗^X eHu#1AFUsyϨ[MOrkf|:svF["sd< "mV5/c7c;wlN>d03S=eo-leME+m>{xgDeYJCkynXucӳ5 ڇp\p-=Rj}]Dú7J }*7_7rMҮ2]>!DS$g3b&'}{,0yQp ! Tb|W=`OI»#';gŹ z= f5-_}݄͵;ȟ4=#& sWD.ez 8#"DQ#Z+7-y&(`caV;z*f5o8J0EJm #X(Z~ 9~dnƸ'G&0#YYB0=`G,4f *74$@8Lト$f„DGMtIǪ!>9o9e׀vM sQ*9ħݠ !ojap UD'Wy1mEц[W7;9zѢHRn'*.7P+c_Mu?[g(lℋ C"ʺf ]W {g~6|pFq9θ[{tC>gD^`6 ._F<+Ng-<ŁV,o;w=]Ҫ4S~W/ dπ[QooN sVSc^DmO2_~q qȂ'+mG*4Q\7GteTĸݼ# BolRF7FH4;e7&zKĹ4辇LfNl4ZTFڀKǯrP ΐ+O&l4ۜ>TY5(/Y[q ĵp'jwIͮivja0ۺԶk[ WpiS6"ca|q|c .[ `CypZWh f x[2!%2}erWjh Do A;2o1zf<8ߡ;zzܚT4C? ˡl1&ξ VXTm3M LSukxfkݵLvidrטoՅ@ |51c<՛9U9G+fl<מ|[מ -Sl72J?+χi FBǏcȩ}X|\$je`'8W(*[*\k c0NV\O',BgJԍSȲD#DځAh틨^s4`L.q plwyjt+6By&+usfHAA a۟jt`4uә`LĚWMCc#3fѵQp/>ϟ*7U;80+ocWB+:0~1Tۂ`Xب.J@yĤ2&s:x3ipP])wresC5j~A_Q hڗHjMdyut孲0ET cX'yCGıÏ`ݫѦq븄pڴrY$` 8% e~MEeˌt 4jLKϷ 1 D _sCv ǽÈ {y4zH;ybK.}x@Iq n䌒H?2i嚿٥ d˽ZA_ڳ͐\7x֒+ְǍ"Xg$.ZRd1=81h&b6 ~L6=8wý rU lvbiob˜"jhA"ݟl.%-Iat4^bYO}#NoyǗUKa.{m ;VYL3ͽ@[ȸhώʻºR[ؤRP|/KdfoGk,̱Lff%Ž-S+nԲ\vfj*1̦G4zS VӚ)Kx/Z&Q@s3Q̍GZSIww0h1`t(@:c+ =r*=ftٵdI (ِ>l^}yYh}қ+o>*vA[HZxn$B8!š}o ܹTvmB-#j˾@I.V'2L"s!]L.Aem>'ea;y#]]Lc.8RF:qG`u$XzbtӏEG-Jƺϊ۶|ⓒE3jͧL 92 Dž f,~`]&b{T{:]4ײhʨ!EV27l` !e'Ir 8cKq<֨B+y4*]إ㇁nXOͦm mHF9OVAp߾Z2d.c ͳSB+w⼽Z9rʔGrMx4ixE`LFND@.KE#Bdvf[SGC X+*y~uPvPIc|.qh% " !{S}z~kc7[[: ܩ[;Y7Η&qUn͎~fMaٌ@%n Ch=]]dl_uӿpaK%did+B..0M*~;Ef4&-;{^mC4 0xdňPuo| C Egc]'MgIbo] x?9RCrB@[YG[ڶ(u}䠸.tϕqB@Z@<:o*^\"6 nS0 ]T xHIO0 ƸE!>Z#wޤ7YJƝVd^Aټ+iFN|Qps#+Rz \:wmU2@/Ѹ qmPy8h[=%wL+(<XsDh87zc+:~cW8x2 K04"THۓccӪ_܈_8t%XpЕD܇ly'HLZ!fga(k~`-+=Y:d!r冶ĥQCmSі,{u`Hzu!xo~+M:06|Uo%ӣlf=Y2\|{GnM+&[!>3\hCY5C lRU0aGxd9Rbnf[Zoz}fXgjY??QqRh"qe'xx+A6dG%Ƒ3xRW7}恵\y{"ILec)Bmlz""k[Xw `G` W/jZ.zyEnz:+]ӟ%p/FGTʧ7nꗶdu"w"֫m)Tnѣ앁l|αdkI S*a#th=:fѰ``kώ}q$" *ؾ w 9M_Mn78{)hEqC/v61ߐ,b/»n(GTWJ'9kzrq泿Ц/uIobY卖Q)ҭ22ga+mZQ|o(K S68:ƃwA"kB*fsriKr0 T]0:Mb2 0r x$ Cy܍"vF&Ԕa9=7yȡ53B3\\)u\vyG[^W 2f]JC !#2.S58s} V4&ߟHC bXnd9E!є S80/% 1Ei3* VGh7<_TRVɔ`fe}o! me&=k4Blh9mPʮ>It2S0#UCرkM{EoqQ)=3ZqA7.,,ҿt1 ỌDG\E^.ɴ\M Lۦ-Or:3dva1?]qDk 5/oAf.. ܠP;۫J9qΆ>D+Wz'W"Z6J%VȃT}doQ| EV>dZ]ɣF` w/ͩ^ AdÀC'0NÊ7-Mzؼzg}{N'46`DA9k%O/#+SvzY">B|5ݩ5b7҉L$]~f")5ۇ0 ѻ,H)"a$xɒG S%A9upa vܢjRuQ\7W{Q/<[E`\7 !ނZtkV;j]V.H;EMJlJ@!)\MHvɄI4#pU+T=+ xlRQ8 zYS>>~f]Ktz1)ɸoV Nۏ3M+ [RcwAJv-ISMaN~.oр D9N;>ݏ!!z U$ nU5Kzme\{ P*_39\ 'e᠑Nk К!ylc\}̿.YW,!%" ݤSh 0~;707@oW lR%Ê?,<&aHw9 vBOs C*UeR2$6Ukw4EcM?CEV9Q$T)&gYQh9䧸* \=?މPID"n5̶+v7ڞ XZ?sizg2~Yb0Bո)EBƄ_  "`ؤvד3Xa9V6I]'LpsS3BLpcy Rw: 5I oxgn.pnRxv V@M*QJ+c uWO7kMkzo&]pW ezj_PQ*xKP0U|7eЏ5Y"3-uGX% 2roÿKv1WanZdaTC)G}A\RweB!gBZ/:q'(yYjxU3 ZVQ%GgX*;::l(&})ev[e FKfBݨCE|xBYQ2NwȕYeñcRhʛ+zʗq b!fő?g١TG8ԦkϱZb$Akwy@ BUefߐ>rcqLD@ѕ;0 Kvٿ˿[qhaj"Qkq = 8 7([RE[5u{;~;?h~ȱsNWP`T;ұ Sʧ^~(xdUY˟H!4(|`ܴf8W0ZVYjj9sp#},oG%/5e? Xŝr-w :v1)pJF:-+ }e]cp&׿Tf7OPy`Б4d-NbNY2هPhm@X>2<"Qxֳ']6S30rU=x`@Y׻@>즷z _)`# sv㄄TCJRC3ASXUH5́GhBXasɡR]JZ*o: cc0Z̦YhP^½ќ LgXOPf@#v>Lœ՝Z 9 nz֏dž,- B翦uaW)So^ĊeFs*:nj#ORz'w@"bTfy dk,scfD<2ALEsFZV %)K.ɿxHbj6+ZO96`z9 )a / jzȻf{,&On5 슴"bL8os/z 2N:3صriTI'ot9M:/g̔?PʡjԜU*kRUԋ{786,0 ]J|zA?jobJU<\@cdv)ߌ)dmel$.Qͫ&{ 9' F1yF*ӫ+JEâO]Y*զFvrfӮ6LTvy<Ґ>RIr\`o<==uE$ͰԄ[q#ZII͢q2@ͣ]+Vd-C5Lb-o#yp]tS+QwQP@u[<}oK0gc)& G:&x4hr(2ЩീsY|R- DfNK8R.~]+Kb e Xq^冽1Hx'|P*b)  pﶜٛ`)4vS+;ܿƣr,>1sθ3tS͟ش§s-0HyRa,ͼ# q[&;AѡjT ]8S-ʘvDbCY?Sz tjxautPx=0l,b,% :t*Vg6wל2}0Tɻ*.9qwQ,{"Scb }*q-vQǤTp/=NMdxDCqj}pMqsUƳLußF`AQ& T[KB#!SA_w,DO, FekzB2T#!1, ߇Z\9ҤddȳdcTvԹ~XЮu27lE"R p^{~u]'? ynp]`݅](2G#=:m{uScjVJvJj`e/lm଒$XSGBGq\;,,nI~%P|ZDymG\U`Ž՟$wc4/֋kn?.Yٟ]a;-&o)EX47s;2nd{"3"j1E~f7TU/zrj9 ćHɥ2d[*x=YL;s_`F,G+P*bnmm%3 cI~՗MX^a #EƘ /(nK^}R|uYDK@ (^@Ópfeq1N,{ /~yv)DKFe,JRsKLD⃁'MABfp=hh|NFG6EGȈd՗Vx*,I1YirhlmtE5vC+덣8>|E*tΰ!n5lUٹڋ#T-ׁ)~h"Q$P£N`,Wj/NWXz;Q6ӣ1?զ?Ggy^qʹA{?7`k7J-f"A{u05"&CG^B+(axJ\(, AU Ѷ%B{Wk-6 um5rM+L~aQUZ=)>w ]@سVS$YƌKecc8P55&$ J`65&_iG碦'q*EA0cWuGOBq=QUe ‹Fo)δfSP5ғD5WԉnzjSTo2"fWAeq2 w߹BN\(ߩm|X{dO{,)= Ojro~z(N#!Vq}+/|e!t)m\OOϧ"jDŽ- i =^&{o7` O컻B {K?/6% AR𴚒XC ߛƂ:|YGq/gYF`#Kpiyp)YDqWmTod&Mؾ~ou xjO咘$~ ); [6NLiX@ze*c' ں  Q 6ؤe+\>œUv1TfH]qIyvNg㯥 "lQy ֣"=Q OKQOzg܅I~)&#WIݏm8!/yFٟW , eҥ D~ 7MV`) (ڜ_dJ!{;Jk*`/ Ŧq-^YrurV9m➨iK%] ~O] k^N{\R1vWFٯFqmllmkXUUvFG`+ .ٍ1 p+9F:+߼NZ`ӿq?b N :Qb~$|b(ϊ ?Ij4{S- vZ;_iDg 7IeG74EV]#EaLrԲ7$](6Vsw6 f>#F/E#0+E!v[dre)3u6R%|Uv xQЂNd\zn_*Mt2L[y`?^;GGВo Ae٢ dV;z/ h|!Tǻ/vI:ټt bs6#n%9IjpضtԨaZkO-}fqe< jp^ݮ-~KMʷ"#>hA]EK,7°8g<? C[] f+,Jqlda`{;Dkz[ 22Ȧvebi*tp &:haRq*` RB瘏1J-yg)5;N33qsMn7;%6xĊV\rAi,a6Yݏk. +lH44O5_\wnzH{flyѰ$@:SrHmvM_ڔKPg$(Hbfg kwGu־jY!%27tR{`#$oȉȂ c({zLnXwynAy SԝeOF<#{RtCv+v#4@*wҮ9Z㸕+DѸƥpKPAٚ:<:&f2bI>u9oT)Fx/$1i.{ҺX8Zx/'.XgK%t{wUS>quKeNI4/U!jQZ_PziR.\ۮ=RSoc]?wQMM/m\|Xǎ\35Q[4Ct1i3L?}u n+.D׭Nf0ٓy s?"kU33c=#@n,z1LqMP3Gss1DR|zIGZHb; ':Efa!)ظ*֜[e5ʕ1@)ƕqp7G/U]37r S{t9(u9q -6'1RLA*ESR}e P@ws="߁a/E M]B&LЃȤ=Hrnf[~{٩f&,߻ofP$p)"Yյ-%aB5 5d"aإ^&eeqwsje0PUc#9~f޸p 6|ded&fOhb 0Z;?ЋԲ|0 Nي 6EgL1ow@MEC.Y3\Ʋv2t:fO_b ,rf픀A1]К_!,VPQ"b~LAt_UezbYoaF8ǚ##Y>3}p)Y|0)bO]!0`9];@H igfDЋ/i21_S `l;"`%ܰ[0)~d#K ӸdNg}Z7ˤػJuaNo5h{tc$;$Woة,}T <4*Zty|9j LgTk7ha)pBoK"Q|et{i mui Ԥ3ūWg1Ziv,y+;EdG.G5:veiP$UI5ܞd=-8 r(muYWFWR=WW8Fɷt%嘋JT1dȭ\k#ĴOz;e%THGhƟٓn>i1~0m6{j{͵x<|rxٷYZV<с~:jn(}|Fad#D2 u ۿp\T8 # "XӅ1 -;Lk) 7ZgyCXN樂>W`9v%pJOf|h61Q~ronǐ|VPθATmtB#n[˪ @˪1Uc(שrŬy91'_ĺ'UƜLK9a=4Lg39%EI_&VD`t `N }?KehIKS'X$el,feԾ r<'CXo/%}e1/N8m(vmPĴڧL`"Wnbhͻl>ԋ6f7y9ۉʔj;HG[8:)xD]( \\S&5Wǵ0ٌ zhѪ.%Yc8uX-1Clj+u]˙ MfB{n+0E)s31N\k3J^6mIu"#N*od @!A ڦ I;Pn,8gmNi!\bvSgdӧ'L*Z.ٶ@b|Eqkp's E%0+3Pz4rdyotɅ=G[.epuw, >>:XLL$9LW8ͱG@ bR.Ҧ:G#er͕h&p L*&{pܸVŴ's] o \ :y^AG:tg۩Yn4fE+Wʻ+31^4 kXNnU_?Ny!lyԛUADEN1yQ~6B֯AOZYEa}؉lxbdGQ6i+m ׎ޚusDWTvʢ[dƳꅆ_@ ]BZ 8nW&[ՙ [$PI!e,- ؉ɏs8kgn ɄRyJ=y/I%Wk8n2:$8HĄY?kiplI2hx*8;4DPKA`;ɴDw$,4 әAEzHOA  @,+S ѳ0t\Jakp> `X58>쿌}X:4FdnVW gЃ[)+|o'Q3cP[Dc$A`MaVyUoo:-y$;MD v"ĜpGe,W'vڇv7f!R?clZ0 'ˎm#>̈́[ر# |E+Ϫ%_/AM"d7N14 Td:Պ&aa[&a :LYG)¥L]iTBܺ®bFlC#u-e*s*g a *Þ@RWd^w(Q2kD0Ah$36 W&5]YnPmc &$.'i"R$Chw`<{-_1Lkr:-f;ڤo1-H¯JcHx {Mq?&'CaxDSdE!ׁ W6=|{rp4b+Hr@ޕfL=>}64~-S"7L1/O^pgᶗ-UN|WOIڃĝe1Di/U]lDF$l?/cK#"قZW4"sQom=` YzHi9WS`$mfzÙz`KRgu#/<:pDvC8%}i)J]t6y589em}a[@A}NcgyIpZS$ru6;xWMveI`e~cB9͠.;S n3]{FӆnwLc{4["O)EI%5)9݈u}W23A=/⭾E~ wXmEWrmZë>t%:dyd9-6Fb6eDAv?\=GΠϢ ˼-wVft1.ʼn?fwXPy; jO1Bjs#7ׁ }TE p Ѻ7Y} Cd\H۸>-28J]tD6Ond!ov($<R(ȵ &n'0fANr< o٨ %w#o)2+Wk| Ns(^@9/m}!A`H6Z|xvac ]`Q!yҦK`JwŶN2gUSr7X4RKn=cW+'mJH1 OD#i%4x[B3W?K;[T(ʓ?0G<tߑQ}euiPpϹ u]2 c1~ZB&nFGT@4KDPf?<6Z!3ɯ@ d[id T1N3rח> ߍ^} KD^?~ݙc +bt0unES'd܅T{Sdž_xVU_9,W/@7\ZkQ. q8gP~0)-jlu_7A9r٠mR*g47<b΃9\v+wAۀst@-j>+<lj\]$^70=Yn+> k9]EfIÆ{huaOܵ>K:ჩwT[ qlu45EoJqRr̞r;k7wtفO38 :0ΨS$91\&+me 닙_*K1d.ԯʭb~`=q}Vfh& L:]ʫ\X.{wAل@Ldl!N'ڗйuV]*XAw-:qԎۂSY`|SaX Ȕw%pX2X!mJ->KŦ= Cџ P&JEC#kϯO)s[$36֦1!2k O?+ q}؉eI@ a|ڮ~\-۰|QCBu{zO̪c謹cp?bfxMЎVu'xMx@{7mݶ Q俐ZdPoEA4M|ՔK1gμ}׳,FɆS(5ɮAs/8\F8t!T&aSpGNZqqCa{'NnS%ծ;UaR9,2n;b,JerAM,?/~퇚'WsG¡%O%OMlQ#0$TsUHi'eM2шK_ŊPXU$ot6!"n5]XTPhY)Bj54%MttV؀.h?)TNH2߷Z#8 xu$ <" .5>)l|Uu:TV^/_9!zb_}REf)|.Հ$5y%v= %9x`geoVA\MޕXtE*KG9Y('l @Tœ?nGNn0 NN?yKhY*hŇD /lSk"gb.\|r"`>I^ޡY|袆{hA*61Hp$4W*QDake6O^iK}`)كq"QE|g[* =ʦ m- nWZ,`R:G.{jBPe\J+ uio{{JCO1V5gCEۍ?p֑4j.GXǗS`('|?Ge=[Љx?*&+[,5t8I'iԬ[Lu&6El)-[,qi- H*yg74RFW7Ey=y:"';a:~)%w&DƣI| _f ?N ,#SKuHi'-U^́ox -)}tEs~ J@'(չZk[&q5ƧJ<;&C& /$ţ %B0?H Ó[cf?QC9B[vDAK'  @I1=OuI44)]4 9<;|ACGIev:.D ܹ٦[zoT;20\%h=HsrW 3^*9q&7|CE*8O,)TdpF/}9lJStnsaR\d4DM-Q*87ًyg[1}(+u3GRs6I5Ü]ww(fN'C樷?d