summaryrefslogtreecommitdiff
path: root/meta/classes/kernel-module-split.bbclass
blob: 0c045c91e9057771ba5e5ecf449f9c8e3c258307 (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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
pkg_postinst_modules () {
if [ -z "$D" ]; then
	depmod -a ${KERNEL_VERSION}
else
	# image.bbclass will call depmodwrapper after everything is installed,
	# no need to do it here as well
	:
fi
}

pkg_postrm_modules () {
if [ -z "$D" ]; then
	depmod -a ${KERNEL_VERSION}
else
	depmodwrapper -a -b $D ${KERNEL_VERSION}
fi
}

autoload_postinst_fragment() {
if [ x"$D" = "x" ]; then
	modprobe %s || true
fi
}

do_install_append() {
	install -d ${D}${sysconfdir}/modules-load.d/ ${D}${sysconfdir}/modprobe.d/
}

PACKAGESPLITFUNCS_prepend = "split_kernel_module_packages "

KERNEL_MODULES_META_PACKAGE ?= "kernel-modules"

python split_kernel_module_packages () {
    import re

    modinfoexp = re.compile("([^=]+)=(.*)")
    kerverrexp = re.compile('^(.*-hh.*)[\.\+].*$')
    depmodpat0 = re.compile("^(.*\.k?o):..*$")
    depmodpat1 = re.compile("^(.*\.k?o):\s*(.*\.k?o)\s*$")
    depmodpat2 = re.compile("^(.*\.k?o):\s*(.*\.k?o)\s*\\\$")
    depmodpat3 = re.compile("^\t(.*\.k?o)\s*\\\$")
    depmodpat4 = re.compile("^\t(.*\.k?o)\s*$")

    def extract_modinfo(file):
        import tempfile, subprocess
        tempfile.tempdir = d.getVar("WORKDIR", True)
        tf = tempfile.mkstemp()
        tmpfile = tf[1]
        cmd = "%sobjcopy -j .modinfo -O binary %s %s" % (d.getVar("HOST_PREFIX", True) or "", file, tmpfile)
        subprocess.call(cmd, shell=True)
        f = open(tmpfile)
        l = f.read().split("\000")
        f.close()
        os.close(tf[0])
        os.unlink(tmpfile)
        vals = {}
        for i in l:
            m = modinfoexp.match(i)
            if not m:
                continue
            vals[m.group(1)] = m.group(2)
        return vals

    def parse_depmod():

        dvar = d.getVar('PKGD', True)

        kernelver = d.getVar('KERNEL_VERSION', True)
        kernelver_stripped = kernelver
        m = kerverrexp.match(kernelver)
        if m:
            kernelver_stripped = m.group(1)
        staging_kernel_dir = d.getVar("STAGING_KERNEL_DIR", True)
        system_map_file = "%s/boot/System.map-%s" % (dvar, kernelver)
        if not os.path.exists(system_map_file):
            system_map_file = "%s/System.map-%s" % (staging_kernel_dir, kernelver)
            if not os.path.exists(system_map_file):
                bb.fatal("System.map-%s does not exist in '%s/boot' nor STAGING_KERNEL_DIR '%s'" % (kernelver, dvar, staging_kernel_dir))

        cmd = "depmod -n -a -b %s -F %s %s" % (dvar, system_map_file, kernelver_stripped)
        f = os.popen(cmd, 'r')

        deps = {}
        line = f.readline()
        while line:
            if not depmodpat0.match(line):
                line = f.readline()
                continue
            m1 = depmodpat1.match(line)
            if m1:
                deps[m1.group(1)] = m1.group(2).split()
            else:
                m2 = depmodpat2.match(line)
                if m2:
                    deps[m2.group(1)] = m2.group(2).split()
                    line = f.readline()
                    m3 = depmodpat3.match(line)
                    while m3:
                        deps[m2.group(1)].extend(m3.group(1).split())
                        line = f.readline()
                        m3 = depmodpat3.match(line)
                    m4 = depmodpat4.match(line)
                    deps[m2.group(1)].extend(m4.group(1).split())
            line = f.readline()
        f.close()
        return deps

    def get_dependencies(file, pattern, format):
        # file no longer includes PKGD
        file = file.replace(d.getVar('PKGD', True) or '', '', 1)
        # instead is prefixed with /lib/modules/${KERNEL_VERSION}
        file = file.replace("/lib/modules/%s/" % d.getVar('KERNEL_VERSION', True) or '', '', 1)

        if file in module_deps:
            dependencies = []
            for i in module_deps[file]:
                m = re.match(pattern, os.path.basename(i))
                if not m:
                    continue
                on = legitimize_package_name(m.group(1))
                dependency_pkg = format % on
                dependencies.append(dependency_pkg)
            return dependencies
        return []

    def frob_metadata(file, pkg, pattern, format, basename):
        vals = extract_modinfo(file)

        dvar = d.getVar('PKGD', True)

        # If autoloading is requested, output /etc/modules-load.d/<name>.conf and append
        # appropriate modprobe commands to the postinst
        autoloadlist = (d.getVar("KERNEL_MODULE_AUTOLOAD", True) or "").split()
        autoload = d.getVar('module_autoload_%s' % basename, True)
        if autoload:
            bb.error("KERNEL_MODULE_AUTOLOAD has replaced module_autoload_%s, please replace it!" % basename)
        if basename in autoloadlist:
            name = '%s/etc/modules-load.d/%s.conf' % (dvar, basename)
            f = open(name, 'w')
            f.write('%s\n' % basename)
            f.close()
            postinst = d.getVar('pkg_postinst_%s' % pkg, True)
            if not postinst:
                bb.fatal("pkg_postinst_%s not defined" % pkg)
            postinst += d.getVar('autoload_postinst_fragment', True) % autoload
            d.setVar('pkg_postinst_%s' % pkg, postinst)

        # Write out any modconf fragment
        modconflist = (d.getVar("KERNEL_MODULE_PROBECONF", True) or "").split()
        modconf = d.getVar('module_conf_%s' % basename, True)
        if modconf and basename in modconflist:
            name = '%s/etc/modprobe.d/%s.conf' % (dvar, basename)
            f = open(name, 'w')
            f.write("%s\n" % modconf)
            f.close()
        elif modconf:
            bb.error("Please ensure module %s is listed in KERNEL_MODULE_PROBECONF since module_conf_%s is set" % (basename, basename))

        files = d.getVar('FILES_%s' % pkg, True)
        files = "%s /etc/modules-load.d/%s.conf /etc/modprobe.d/%s.conf" % (files, basename, basename)
        d.setVar('FILES_%s' % pkg, files)

        if "description" in vals:
            old_desc = d.getVar('DESCRIPTION_' + pkg, True) or ""
            d.setVar('DESCRIPTION_' + pkg, old_desc + "; " + vals["description"])

        rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS_' + pkg, True) or "")
        for dep in get_dependencies(file, pattern, format):
            if not dep in rdepends:
                rdepends[dep] = []
        d.setVar('RDEPENDS_' + pkg, bb.utils.join_deps(rdepends, commasep=False))

    module_deps = parse_depmod()
    module_regex = '^(.*)\.k?o$'
    module_pattern = 'kernel-module-%s'

    postinst = d.getVar('pkg_postinst_modules', True)
    postrm = d.getVar('pkg_postrm_modules', True)

    modules = do_split_packages(d, root='/lib/modules', file_regex=module_regex, output_pattern=module_pattern, description='%s kernel module', postinst=postinst, postrm=postrm, recursive=True, hook=frob_metadata, extra_depends='kernel-%s' % (d.getVar("KERNEL_VERSION", True)))
    if modules:
        metapkg = d.getVar('KERNEL_MODULES_META_PACKAGE', True)
        d.appendVar('RDEPENDS_' + metapkg, ' '+' '.join(modules))

    # If modules-load.d and modprobe.d are empty at this point, remove them to
    # avoid warnings. removedirs only raises an OSError if an empty
    # directory cannot be removed.
    dvar = d.getVar('PKGD', True)
    for dir in ["%s/etc/modprobe.d" % (dvar), "%s/etc/modules-load.d" % (dvar), "%s/etc" % (dvar)]:
        if len(os.listdir(dir)) == 0:
            os.rmdir(dir)
}

do_package[vardeps] += '${@" ".join(map(lambda s: "module_conf_" + s, (d.getVar("KERNEL_MODULE_PROBECONF", True) or "").split()))}'
?SmW)KX]ԮU9X Zq vjϲ>/<ϩW'3y)Ы>D>$PZ(Zc}YO㴴hjJQrb 0ffhh 8{;u_[평ca-1lzRg!'kHd;rãGUPrv(|"bc?ֺE#RIdbsur<ԣ`x^Y:jr؆1#%&Z.RLRqRbG+/;t@wuw(BI% 9 # [hT6(٪Fʼn_|.LLHRF WP `[k4+_@'b%8NzeAV}:Ol4 ÀyPrЌrp3|V0>5U%f Ek@hge`$:ue3K}Z|zcyC629K[,Z MFE*~7`4vD]9; X*  ?Gxg5M7C DaD8Ð `d@m F4әnLxD@,"'2(66(JEsF=SU m"cgI ?Ly fۗTJ˿r`0F!X, Oelh9de!G?enxI(c#NK; 3@4ʝo jYW?MNUnWkJ~ yy eʢP[qXUv5ѡHU^@S=B;Γ?4G4ʸʥ?ر=@ PB齤71Zz=t(vӀ uj8wh~ u,e{#&Foe\rN_3?KLCQ8G.vgmS&CȗBVJf`gs&#--!7iA ؠ U 97kvu-B)b8Fhr(^eų*&ۨ]&,^7 jw?Wq߿$&ԁP6`T )`v*/]Luψ|?$qx&SSs O%9ϟBO΅c4=5ʪmdD_ gu7?̰ w7`a<`huN0m$XYʚ S/m4by*:j@}9\:^j ?`煿Pm&58Wّh72.˦0B{Uh;m7 $;?.6PDx(.y֬ .4XZ1ZP wqx+aS`S嶔;r̈tBr]o`f5,J}pgP{g\}|Ng:F6bՕgR̜1 $Lj@ SRVc8>sr̛A]e9OE|Qw % ^p U lѠqe$@%zC+)rX*H]@`|/zB1sv5?@/S!K>oeE8i9Kvk gG~!l@6r8n 9gp@\&X/o%X5C# NEVx|qHWT;U IqDARaKos|[ iz|8Qљ6w c*#4Ԝܑ J!dK~]|8FGb<Ӫ:52_7:a㓽盾Ub0fdeq .tmk7\"39a{zVh靗ä!e~ |tFs{Ῡx-<΋Q:6}åw0}XWw97TDrQPb ;Qr-"JάȼzX+ŕ.<(F`g^"䌈+R7iؘ)i2P4{zR]g;g po~ O1kC[ jULS%ňh%3ԘCx=(h]nK1B6lO46zRϜʉ.10z*wuPg e(; ~NYLQ@E*`^4Ł7ydHS 1@Kʍu`Fbzo coq2/O<:.@rn6!9xoġx"8 3W;*876͆y7+ĸ2$&Ex-*h&\`` }D HZ!`ڙ>|Ttov-t^^TuE/'J'>mȚe}۶cB*]ye5\ĿGk_Ԭ(׭2pt:'T!N{[Ps*V\Q]deaLmth{Vs5hp pU`~o:cU9C1+'bl~M{SKI5M KoS'Ba*6G( j0R{QR2iQ Ѷ V}uNev!vb%wDoB43<4 "۹O6;Ϡ@z ֭_?yP F>ϋ3v#I0):̜39ꃕcfwp-s\~vanҫIf Uz>K{xyMe7 6ujZFxhΠb;9p~gçq NYd_;ACjң`tE/Sˆlg[:Ǵ"O\WO֢ CSMW^?f@$Cm}W'ɖc&Zp3:AP,0uu;V]8tm&lT.4/Zp쳵6i&粧M0ԓ@OaQxFZGrHC7j H$kTB" s;4 /WidrbG֊$4") xAhP&[:?B즆m!PЍDnοN7[U> ADH6جs O}e[,eYnLslDM~g7 UNj#,BdN$Tv5!amys=HtsʐO9^] OBLZL:X(' $ ףpCs•d)nJGSX +Z)p=iqi0aJUe-_A 5Xg1[ygu. qC}zO).}2xJ Q+'14rUj`jS[ZVc. "[d:1g(@f`G#E}Zve q CpKnXk?E#}KY-:as0̷cLZ+5Q/n3DE(U* Y`u*sq.dwvxy%dZ:QaVgClh8rRgJoM,<;t/뱤n nG.l&άs?zAOHsW>y_yMMHy8ezٝM ٕh>OZ!7Yh 4-8*q`[%j*>߂iByT8AS,N-E0im%gon3nNJqާpHH;9&Kޓ>IQъhpXK y KBpZ$է42ٽZַW:M?Iuo 2Ws )P^')9S#XWC.\ox~A)I6atˁ@tg^|)p A.~l9W~N%"1B 8 `0J! l դ,8aTZ4j ~TZv/@SǑ?]U<ʼ~s9xWkb/o>Tž.sZFhı%ߔ]B/fiO)ɷ8*~]2 ƣ]IdZ 1s|ұ>; aZfǔSu6a[x~ `Tw>68-]O/m6nR`a?˹iS=BXH5*KwBذ]XEC_<ۀVfQuf}eR *Ȓ*%L{l9 YJme$ Mxb{7+ @- SNaͨuWya”7*G»h]O BlC घdOxC|(ߓS4.RըTb^aY},ZsP&(NIFZA∥zhj],6 뤧Id dQIl i"l)]Ft)3%韐*ɶvM+ WhS fU `%;fs:sl 2u(@qкё&iL*`* pz] I;6PPHV/(,uY}tWּ}E1Rp##s.!^jja$wQCLYub-aT[TY~Ԉ)c(ٻ4]Zꊡ2;/H2&))t-Mt p ?841_~XJւg\Zzb@!l2-fe&(Ӥ$@]A+vFR7un40l B 0L Sb0VYXg7g(vOdLbq%XۂtTIg28S|b#!ɡ=n!ykQ7 {H{6Ԕ?#ѥ,੉seKp.|"%x[SAJIη+uʆ󹈩Z\͕DcPR!vW>\#ֹeB빤ٔ; s"uk1dم9\gLhf6D#FXFro7*.mL_3d2 \e0d$+%ȭL&/YZ`lT*A"0׼2NA񍬔33$d*,:mc1w!r+$kmJ<ݾ[.҂ =s&&Yt@ȤnmZ=;W6KOɠV'c,um=q#BK$xsˆr8)fU \(tWbf, $+G\r>96f>HuJ pMY#>gHYisPv% i+T&#W.ի?3a)>A$p0Z5#'Ug }]J~UWn7\o=Squ}e*~͟17F8m7APBZ@lkB[M<|p8 .f^@f5z>0IOp\sBIH!FjɃkl\`bH SP') e<ug$$@(>ofMvjDZJ J_Y1ⶕt54B4mkyI /A>peP`qKrU>{6x@ ( @BEA fǬ@q~ *, xMbM.=\jt赀!{<c_ͽ>,e`U;6,zֲ>쵀YCu.gq3~116-j[Z֖)6? kzth\hk B O 9ܝ2ÐW\ pTYg'J68ddb/TNo8esݞ^7;eyRsk?dY{8wy̳l^gr}m;v'8okg>q a!uwO;@菍 9j3ea?f?Nܡй.7c3ϳwZ7=/= D@pje! ة.EFsxI(P@8:Al}Y eu: #8bd!z{YL~.3zqs.v4ܯvw2Spj:$-8H i3"H1 \]OdPDH4m4303@ E󦀘Ym>nI+l'~S_ރ*{Qz~]Nh0m k%ᩔx9FQ ?@2~KTdB| k-ՄNAZ1=(\t}25^q(3vQc_?4_g!b{!rÜ謊XI(8?wY /VyY%?7P]򿖀@8[*G'#?i8D3ɖ?? wO ߭ =spks9ROĢ~x/o*E6 S/]2vݖ%!L @#L dF *0O6HC^(Pc ᖓ9|ն? P9*6$k $z̐%ueL5ԌA <˓z *12u`'[Y狇1y6[IK..WxMCU]bRtVm;s 8â'[?\Z#)xbwX@N!͇Kۯ3L'J8,2Wg$-$}F5~X~GGq+Ss@u0PT!"4UG@X F_hyS\׽_=橓D*bg&lBƃq05ϳ.%p%$uI<AшD ^߰%o7+>/+<wBzw sဳ1M>Dz:>܁ڔemÒ_өrYjv zӛ7ͬ8[6q:P깅eR$(805x*%_T BY%uLqܪ >Ҿq#< e4Of#˸bfݡXvd2&Fq:kZih,YHVfRFo mUeYb4Nlҧ!$XYv=$pi8x|M"y 5Nuǃ~q!]ݩمWxp t:s$ifJz(D TDb@nR9 nJ`gy6!sdKQ4n K{"ORN e:YGD"Q&C6m" 0]&mgMqjdZ,`a_9; (] 8Α3*6?AB@$3k ElZ>.-sCZ3܈Z'Xd&d!; $52$w.gC=L9E_7~aV |4ݨ\V7\iNpgw:Uem$UlQƺgx\&i7Ysщ`HB0e YiEe/Gȟ2j!UV*^!1te<05K^ZmmQp9$oFzo'f> /Xh#З)K~8-υG;zZ8P2 LdY [$-m,*2Apa¤Y_HK 8 PY|>Ck4@Sh̳T3(i|UzxѴtcc&yAJ!Z%̷KXG+C,{ _GxVK5h)>-K3-fpTX.Oψ%q-MZw)nQjSw?*d/nLeEqne5eMc$al#TClYP !ebe>FiZeLRyyYj0rxiI)Wze``7K'/dW-KN-Hez<k9iӇWT ݟP E B ,'?HUt"0T; WOL&{k:['Ɣ0i+KkQV; G8+R D\nRCޙ>rWaBJ0 |*{U IOʹ]:n1k@1J"_cuQp` c3aY%y8]7>O2>֎ؒ/CsP)d̲<6 CU",F"*Ȣ1b :ڟ59vvm25IsZJWlRn:rFc$;DM(QuH$-g#mUH4w?23ēsW3 #\Yzm%[i>5szU Up) ȔR N]_(3 ^O\lP>a2t|=DM5,?6|8}.yDÅISwL]8Fbou겨_׿|]`{Thn2C_̆r{f" W_F& Ǥ^'lC7j^בQܪ1 jɜONȰ3)}i ꌋa_N[i̸uBߍl~׾Q{~G Ž(TjTT ڭ;z}OPr)s+`PXjaS)XY}?:śvCNʡn2/=LNN>v%׹ǵ^1jtApls刾[:k9&+D :MCHLˤ'9o‰n]IK3%k2lҧE~6EiPTR4vk r2;x:?1Ml^->\x|-ueYmg|KtI*FX"g)@ #mP\L)LxD5B-xVZ%Ae{l@<=!G}8]foh0{TWC`n=ִ0Ybt8~tA :)nNٱ`t5*|r{  3&]y~W Gmfgvע ERP,HUk;v\֧~NN쵯yRح8`DdSiM0OZ%IaN~kkPON$O?J) 썽Ke>F[LgMiMJu?$qw_vڣ4u(YD^suT닃XXm\j!k:r lǯ؅XLIT1CD*@c#"!WȼX\͞ /(jSb!:ƳfMZdt ֻp`Ҳ WUIȷ50jR !r+ߜ-Swm:)]pnz)m1bVMUmH5%R=@_ &ٌN$yoښ͆2fЮϏEY͇ڥg,˭ܙY'۽T6.GkZvAUCoCco/̐5%7nl8p\[K yESIl"󕹙Ρuec~K 4>tDTW=֒#ߛQhذCκHm?;_Jلit$) V|< k \mf#pjHo\wu=~98|oM]_ l:ʦW; u!)!(Zf [O^:&ԉ454(ON:YWj#b 3spymA)[wGCY^}I\?,]~B +Y;6,>='\O3 5)>]sb/X"x1k#Q$޻LFd/MwIltT!!4OZ;Z.9Ȣ?.k2O ݹ9A'7 bgoN% $goc` +*1L4m9^EHߢ7sL'@V8Ȑsl\b@l}TeOO eKt_Om踓wS,“TStG[5ozN!=JGP"\ T.^+j5|:"9.,pK_ṉX2ֵ |;=:$8oぜmt}(#2#" 9h%b c%kV U5m|Dғb0I_'itΨ:0h NB`""'V<}F+k[{{WCLX]TBtQx7sUN OEJt"8@;Brd,[W⻐h0&Jϓ4mk$dH) I!֍55b Z8\ⴒydeNoJ*)']fJ!yd6Hn(q7VөWGtĀ@$= 4NJ,2zXВBwJ븕^-* !~cMK" .b>aBBI3-JαݘYePsUլ>3MWGY|#cڞ~hS.^f5ES9\ .ߑ;x{RK4J4jN7ynvV]W&33/ٖk$9*GQ-2SR\Z4F1ΣvՒF11?$> cP / x d՝U{~<\bWšp>pmo׹6e]<MhHB1E8>~C\ H<6ZzOV[%~7s?nh{hSu&2peRMvBv pJ>߽ΓLMTQ^m(L(Y K8zRup{x3b%<=̗jPBJ0UpTn~u{[mEw_ݏm+͢c&62)|ho>d YTn9{k_xod/Ll]+}SQk4+0PHoHw VB4;DO,DH{ KATz"*y:߅v6TpXW6yCK:O B,Pd[P]a]dD;3pj^}jk.xر@09:mբ v +i*p 啙f#9R7KI gP~S %uо%Q2I:ОV3VU3zXT%'q#:-vPBhrF=(f;+D B ke}knrV8b qs{,]mXd"#8]LA@oSC vY<)Ӻq%(ڍ-z v,XpnnK@9ftNl`UʁQ۔ᢳ HdpA9Ч'w8VpnBC;BG7ө5ʖ΀g֨)*0qFC/t[rR1C[ 9r.,G% [% GUY.甬 .y/Z|(=y2:ǮeB @g\&+gs04Ô<(PU\4V)/NG~vM)T2N1]*_}ԑr~8EKRpĺSs@̅EFX?vP a<ԿaQnPYcU2޹s2u:ʩǿLӤʃ NJ8ab=@*9DAP.y(pE"U#p=gskiE1|'Kzu>݁?*m8P\g !?7;츗&Fy\GR i_@פ߲m\VSEMr f*G|)LS6>U`A1*z?|0:l_z)bWgg輡mn:JfwLlJ]Քrd bA}NnԦهkX#Uu[{-mV,Ö0,+Bܾ6\?؀ C;<(9Y97E+]&/Ou|ZK0H%0h$-xY@;ne E7ӛ>p_=37Ȩ ych~Yz<3ʫgX^\(j0D`j KzC2>~~l>]&7Rxҁ7`駀蜹KV\rP0WLUQ6h# e`<9=:tQUp[]P]?CEhYzmrxOb XW~+i&Iǒ-|W1RP.lh1CE飬F'/˜Rv~N1x, ,V|0OnaQ2JQ0̎S(qej\cT uQǠC{A3t^;L۬Q#f)13g>_WD 1 \f0fab Jʊ7 jQT0FF驊PZ8JhsGZQLi kk+!X*상as]w-QC(6s~ H䨣'a= u3,nNGꑡ/f/8A q޴nu:?()Ф$jD)1^}V.MH_] |o祁9"rС nsgO)s_,˕g 6u΂Zwp9vgJ ɐ-dHbjW*Sԗ@- g]I[pE[ EOXJocLjn@ Ez 'lZ+3qN&y @eMm."D8EetuĠD}X[Th@ 4*4Lb`&A:ZǺMT9d| vq & Va h  #7(*L ;FՃܖ8!>2&-N <٢C65Dx+2D9= &&5(S ͡^ 3+H^J*hS(&ڈKeV3Ƅi?iBl2gnNͼv1䄚 դM)x1]OZU&i._9ai}G A6J*>ToN:T8+I^60?4WLN3"%Si3NW:F[Y)bECњddfJӻ'ƕB+s @eɼB``X7=Nit 9e3f(-{=F) ׆-ghο6(5`pTWKƢ/'WxN%VJhxeO{zz/ 8ZyQ+B#뺼(aS;AJ@W1[uh9GD>T^y\~%ݾ0#U: _AyݔR;&TMqw"!ɣ?tZ&w,Vz_Xix_bxYYKg}:~kAq&[ ϒrϴ}$=zU苹X{U G;BBGG·txE8%d̄ ߲e%s >!zUHqN;9{GhX@󿍿x<1/rҡl8A7vp r oR2/%6ܠй>1|dq;x +$6%?##uUca~e-E퉏v~l=jQCf~>?' ~?D7wDF#~2X(HKge7R%co.uhBWBMnR|Rȟ0/̝|q<YQucl65zgwT=B lꘘ9*l{u-Źq*RĒ9-,E7I|բ]J j(t z1j&f;,fM# Q7M\="?,c]mW=/OO]&xnCM-`7M_>v˖5Dc[OJ|{^K[&"tɮ4?-7FEV *9V]47lJޚ2֡Tsr^u4~FnPI:h[9z$kL8E&h+i }`J?N ĩ6S~g/ ʻFύZv[+p65[dq898"s^im5`m%m6=ayLV؛`6>v+)Kd%F\g?=LJ|30s*_41 ʬHȓ5P$( sI+x(D@09'H0Q\+s }nn՞8tĬSdSTBr8{DH֨D@)Y-/5l{tFtS1IՔhvZʙz (C7k>'9jyifC TmԐA;DF'5"Xa=P}vƐjGBV5!rJ&`{To+{.fLÌX)D86+[>kOp*izͺx%;7_l]iFICp7jm;HLby'ީYJ*r,]UHAZPҤ%}&"i>I HH/19kH\_&gpPΩBh%螬|}˶aZa?^^:5>M}; E;:R^mMØl&)MDXwKm]3hBI*#7xb0],36 rsbiF0!ha^oji=~U‰taׇQb0é' RhYn=!U:[“˗>,Ҙ8H_Skꎛ//8(Jgw#;zZ3PnyFM̕0|}'0+FD&[`$l9a: f}RVd)ؓM:' w"TK雕${$o< N3)>F:scvLz;~0oиwBG{gͽ; |o{|^ tT3yDžy7UZz]du\?bϿ#)>7mxXS2J_YKX2xϭRxN4T b)pvFM5nqqGAp栌="/g,e z|zCJ[AƤVCB' X 1!+Rb+DDAV1V (Nw$Tb1= e g\ (|8FeLGieЯG(G(Q"kԊMLUVw\ fH$!E:*Gh\CG37;:jdo1J JjUDQl 4PHs_g7ZDZ,]ﵟPugJ m^u/f碴<胯_lqFJS(^ۆwdPь=NbX~_ƇP?zԩA6b2:L%5yHebJS')eI{PhoTޘt]3{7Nɞ?!Ucw=*Q8&9uSiYhS̊y!~6tk#;"…"8qxę)txb%={UB.%E=QS_$VCK:ݟcG5O.4F)EYDtB{YYV{QhN/0ピ oի%Q!|)ޘ ZaFI> XSo^RfLpZCct_qMOym{1RDyHՏVokjfD-guqUoTޛv u1JV µV|ĩ9Qwǟ?%9ᆷXVyf /&8zk{]^x[S^ +H#RN VМenﲸgjC7̙:/b25YՍ2 GV' ȏQD$< x*۳\p<[cy p',1F.SQ%S "\Z[}K&Ha{ 1=Ȍ` XŃ1 RDF,UA e)SB{ZZP*fw8sHTz gxv)f ۷59xD7i:sr1'~I+l` X$3T2mFuû+&!DRMIcpԇr,|=t>4Ti#jvM)/k ֵ]aZM[}ϭ_3~߭[ +zGu㊃N#7ׁýfLC3̡Z36/RVqֿ""^D8΄"S:*L(d$w(ePMV)hâfޗ~o6ݓfc(ÖiD絭s{!AR)L#ˬ#1f_{%f{?x^s8Ctaɴ<Ģ1Mp*Wzsu4ijֹOjJ.:K_LS4-]C]ΙrDa;5d(6y,fN uwMjvZC}X+m-D,_3g:L>;GCbKkGM8 Z/'nqԅeʊ}~nmNc*)ܞ[t̝|9Ih\H޼wM$J^gΡYyDiY/fdRaG`Si^f xUM<*R<`Y}i$z Ǫ+^`+Fo]3vN5;;N򰙱WrR\f1v_dM!$]1m{@1Z}T8AMkܱqY4§O}ǿϋtlϻ~\qqؼfG# A>D =6۲wWc!äLJ'[a2n;pv=ɉ9NT^úB.uGuJe}uG5e֞d|PݯI-Ѵv^-vs zʗ4l=67z[ ̿cq2]zv_k.^-2M9P> y,z&|34+'W=(f_ U6i;B G?ڻxO.?ݧӹ! w@ (K=cjvLފuJqGʵv$N.oOMey9u=eG8x ~LW-S2=Q ɪhhLV/{M ~`0z}[L:7?gU$A (m t×DjfHtZ~^i[HJbn:C:ʈ"_!DT~կ= aBmnޫʟ;/T6E><듢ֲYy{oi "AVv ebzYQ`"<)&wh/:ֿV87,7)f}n]pS Pq#kvҲM: oUjn9ِf29@CW4߹>GkH:D摭() ŹC0K2˷x;f8,Q :z'l-uPUJitMM 33kgf[wYl~o5K4J5Xڻh6!!tNdSe?,?0 y ӌ+zF@!ےfD? x?5͙V0>럷: ngJ.>8B()߉wlh(fJ5X"tbSUugpktf "`ogn66egϲsE2"zpae?(RDfIz̤KD40f)Y1 9)ʋdZNEX#AUA" K$`0P4dzWSM5O#zPICXW߽P:":ΪE"O`ha!ACVEN3!X."0x~m^7L]qrebr)tUjS>U;m? w}rP^,f\B4<^=g㐡;5)3+K5(< Q$( 1@?6#GF-ɭqlX VAjPxba `!0P:)/9 +6_Z) y Fi|1`0@ČTⰧ-&U™4U!) "찜fxo)Sz׈ F  5 Q-+3y YP 2, Vp)vђ}ѧ dY.I0|: HEY1TqJOtOBt=65`,e3%:8޾~ t2,TfEm2bvnH$rP|=ze]irt~`&oѷ8hNH(2jxht0Se d/6aC33ircZ(zHט:*b** @(@3 T0XtMh5FHDh! ,{U bx4FEV;+& I TSIdF9N%RWܽZ: >1G`:tHoMkmS[@7yh+ ΋:}3)d7˹s`Hs_DO`n0T@rȠ!B@ٹ~ۄ*N0t 6Q>@`xNB:dGz  [Fm a,|﹄{.dSsVeN twr" \A'@YGMk AYFgc3O"ә <Ё.wi1:P*h!5{.w r?;UZLNJ$ۅ5j#6,潔7/66#[9 P Ŀl| )`5FQnj)eT.k 庠:d-,Fz2Pyq^cOi7ڵ)\]qD#*R%tӁ:tk.]:zT+6)Rw*:8:c714 F9Ɛޔny EO>8qv]=F3hJ"SR$dLR ˈ/O9uS(gB(O{kk" sUS͒Y,K:&>fǞhi1Y "Agu>&X}wFS|PC&=? uEW8PU ,Z0~)^SWC>sjN& ?H3~\T'Fj%nv k/PNTtD|i 1zd96w0"PNQ:@1?}utцnxC*5ѓ<4pM@"I*Z6sɩԲ`R֖p\( `T`ɀT).}4 te 3Uj%Z$HmSN%"vŗ4kR>\oS7N2a[JG a`\[B'Y?|$44ꄰᘍ]ߚ a2! -&SIr!'+gKwykv^: |Yn'Vr@k@!` mTwt<{|%NQcZ54xQrO(ɸDb޷Td]4 ˤrP贽;:2 t}@hCБ1rV%䱖bC^Q5v3Mp4UkzrҕiRL>4Cҥepv{ Z{cEuKFwiZSkL!ڴ~^5 +^<{7ɔO~guut>="˚ kg51luN d D+On B'T8C.a~9~u@ bW1@p1M3ih2bJ'9)\KwsqtN7Pa>(W,!<8Ү1˹vl*6"|U2LˊxEf:%EKV/ 8ZNC:eX Jk  ÂjL]e[!箣m͹bi]ԫRLRCkJg~攌8D\uEFO<^,*Ռ,6f|kђ#;sdWdOPs)X/\}1ԛn[#+g 1O 8^9褥OA>f k7,rRT*HaڕּJqGb-}zjKJ-<d`=<. UcĹF3151^#؎X3vgc };IopM .$~_=Zndoy͓]NjHzYYouZN徑77^vީ;W^O ɺ%0s'6|6ojV89b9\6?}<)Fd<D $ -a2VԢ,j^$r~ >dȱVlg桸r(?:t@Q8PhGMϦrEX(Dvjvyth,j##Ft~w-*}c_ӭC[MmLayr Nj;a?R&MÑ/d&3Yu`*іAɹxZOƆ}dy|!gfm0@( !DpŒ0-NR]r}5fg@rk#'Qo“`k(\#§ӌz:O4QJ-qNuQ5z RK¬K.VsjK[wxȻ%Z]4LUVn:W\7H`TlKISVY@H`AC_AK Z5d%;%% ,9*/ng' *?/z9l}YmsD_B֡; V4Rlk<%V?:&^oeXOd'v҆]6@2[Ƈ[Fv<~ґÀdc'M&&Y.7Ԏ;_ʒ T0L  DhX(s B](P@SS s#h:YOܫفaYcFI͇gA4,aкWY僞ATct꫞TxN#64]T¿kLP6 bw@RWh6 *&e7D2ٗl&;>u$ V//&W  &+ o+v1T[f=YɣF@lǐ{/3/7{{UAN`~M:ЌE`dXM#'*5kIWn_N>}ѻv}%|dTP0-A.I>z(蓇oFKVU-xUJJ*-jŬvCc:ٽP\6N=ʙ@j_zXU2NcJ08Z˯M&նδU "}G%©̒̚U q (]wqyڄ N*t4xo6P#,T˺;폤>NZ , öHtQE MJx-P֑x DuIRm>I}\6?oխSUj[-}t? CMwI9hbNGӸ36Et.uuBhܚtR= LfL`-ܹ^W#dO1u덛6e1ӟdVUY9-쥸o~nYERq锛gלSUOoC^PD|{ VF y{3}^&}KNҁ536 @13$n@L`GzeXx$%gT9f_qx/ZqeuׯӞ9# Y@wG<2l)uietO tN !̷͢T NG i^D?R) ~z[Գ&r¿H<`duc®L]z^ 3dR߇@0$-pV)SRv0j¡ͭUcAS4=bgr⩅4±-i.gH5a#yd䳆Dv¢:u llc.+yի43#˶?R0*IVUH[َ1s%Iiדԫ7&2mʒq uhX0(h6N>ۤ\X&P;::XmpOSY>-/۶ *[T+ sv ]*^^XcA ,k%pu= yq31?(d [0;j#(bn_n.qM+UW3׌; 5|6t1J篟(kZ9Wv3!m.y4FfP T $E1vr.5N:qqVM-*׳s$$)eLY$-' Ykeёۈ^L&rRՌ;;=8^0ÛR>F*dM^* Y~q[H qgʛH=7'<Җls$=9e5[!޹IC ~Wk4z=X*Q=6DO~nKgFطUY.ɔfm[LF7@7̋9=Kww>˳P}/x9ߊ4<:Cp׀j)B]kSGezϹ:J/%0ڠxaFqb5M!m?(. o+ѩ_vEq$zmZ꼞%iZS #Kq[ mevEWSt ]=OB?f+TU GSPhhgiE"DiaO0,H!N͉-}d,'+:{;ymu&I ;@C 0)NJL>\R m{d/OEbSW(WzASVdDU:l5)YkRQاF\`yQѣ82#d\J `[d\ɪA,?éZkJ0Eex_VE+Ч-4imR׉>iHwT#R0;9,.f]כ}U/߾Ƣ2 ynOlkڮ"X$,p{G8@! Y],Aأ<4tZ\']¬)#蓉`Y)y_{w{q೏V hXc;ON–q|_o`:HSeOSC{*S}nNJ{hp~?'ysӔmjZ}b4i۪I;#HUr%[ܙ^5NhV+N *ϊ } Y5z' ULo걾E7{Sk!A>jC6sw]Ew'Hd3 ~~oi;?_lCjz T 6 gqr?:[xiaR~Q]( q@7@- w\Fpx `!RtkY ~C˼B}4o後d!0& ;F7X;`0!HBj i|Fd/I{=55Mk??Οy\Yw9,H]`?Fk X8?`hKx͠_9Yv~{Ώrt7po}֥oYɇo$P0u`dX\7@N::6eaQ,# K6h_ oyCJ seP=U;ؐGZX]Ve,[υZBĤkAD_.Ԗكxpa=:B{~1wjG> 2hBaAEA^׀wuہƮÊ%+PT QvJ#1FAP e x, nܶ"vc@6ULʉDO!8!q,n;c6x훞^9y(%AYqPq } O`Ss[uk7GMFrv+P:Qe!L a2:@,Z6rHU~7Ъ0FW?Y?wvbŸ1.4[l[X6q|ֶ-{> X@!j=#iH? ;^G Ic=qY)XVIڽ%tDQxDr軆mcs`m49D8׸yy$@Տ]Ef\-A}aQthV&~) Y p)LS䨷] яu?GhkV2Qgj kGat."@Q&:"' 2nt2L{\=AZyJ1N_a\3ø5}`#茹G>{:v2a?oXyxOyz'xՀX@CmpVcDգJmY?sIER; ^YBVTQzI ;S̡`kZPϲq0k*ŦADD"5B }Wʣ7ղ~ A(Pg| 2y0GDؙ:>ݸG',U43 "܌qu6:::8v_g$H'4r|]VfJ}<&{3k2)|4qI@;:Ǡ{wa{g,Qņ36,Iag"ZDX#ÇV?iCTsyg)Ujrk8Lɚ)))#?swy)h[G#2rƞk=:4 7a&Z\޷hg#)3s&&Α~3 hfhhP.& fUeyXIBD(xGhjdfk$ٕ^}a:֫Ho.;X'YB%zM Hyng YVXOk<& 7M=į< %3LAl^C9}FF*O,_JމK+9J >Bp(g2,zPy;)erEi63('2  -@P^-x ʮ 9jiG}RG_^pճt09jN,]N<)'ڀhEK :NZ-Ӧ4O!C-@ *\L`9?kfRtrG[1O' =ˬtN8^qLw]o} Sf2q+VPQr 0pBԘc'ƹ7{y gW-P[#|;oK|GZ:ő|#*@$>ş{q )!nԕ kx~?u])/1 ^n41! j< 5o\ ErcGiWRhhd-#+dCOG2G:_W*GQ| *+ DZ(%yfPF$a53Db3X):,yBc50Jf$PPDc&ԈcJ!A]%Ѵ Z ľHw`vWV' vEayY(Eʟ^*t .~w4ٮon⴪J)5ѧ㹅YfPC] {QjoάG6`Ha0>kɨRgSE&UZѬs׈iVVD ʗ;E3}kԓ2 s/\?3= .$7uz;ܪx߆*f 2=rR-L3%J6N v@էpD M|dRxUQ<X<h^EGd`u$dg%vEjeK,H ty@^%q| ЃqξsA~9]6aK#ht>~=,Y: l_Hf;z9U\R#2!Y|PlQK}٣6%_WG2$~n4rmN5]h3zvZ~*5Pn^畚&|ҝw L4oԝQP-\ јS.j c:1NaRjy鑱-pih_yn_Žo>b|\Z.d! N`b1σ00a5N9m04IDIfSkn+9N *}DFH (!BB@4tY1z(Wi@ۼ r\zB{ʛktK'{(er&Qߢ! P&dzlWƀTT2 j|ǠRxA# cTrZD;ZqoQӞ{ } r]6/Y˚ ǠSU^"q;7o(ssiLGt@PYzFYo 4plz0Qu`rk V+(goWN) _F+{M&aQp18=Ҥl=MnVۑeKϷ8˸tN6$~55v{/33ڪy?ܲ*6V\/wyzX Hiy uq^1't? KPx|>wer㡡s@BQ #?h7Y+#g ]U Ѽ%2ӍR/K1'$P8T Ihx?qƝi ! 2p (qsly3A2v?CåW}.mr:;/6~)Sh*b'C[.g;v>FuOVgzX0`}r)1z&c/%Sm'C{H@e2kS :ۓm?4\$$y~ с!4n@\7 *}WG};2- 8${^BZ-DYR)zqϷ⭅`-'ѯ0ĻVz}Qٳ#J S)oaW>%9Y&E{KPTwY2 -{G)5Lw9,];TOg!^w?}9*#/ 1 aB=fp?_=ݻ_1k ?bӧK]b!eK8]-2ߏ=Uf&Q{j\Yo->8CҲجBKy}7~!+>/M ü.oM\)=#~KI$cDa,զ4W J1vSaӜ٫\o1 hZǍXn矉X3bbf+hI1͝T mLM6 Qw?$7w9!j9}'CJxCBaYsjmG@=ܘh'O]>8 ۘ;rRC}tz9C~[}(Ҧ%Ȃա[7a弩9&Y=cz<*]vO:=E>p aOsO%hĩ]T"i̺4(+V@#D]3hkM !`m3Սҥ! %<\r?6BPnBw.}&EHo~xD_K7 ՝--h-EO&WYНȲURIyE&G))٢Ylk58|ɭMe^880xE ,79辐?-o.h#oqRCH%Bl&xD^5n^Ae. wjLLj? {>Zcbt4F å)Xȯ74C瑣ԋ7ֺth^`-2itV-M>&9c OSƅS&oiZ mN-)s.6SyQEX}{q8z}I"kiC{a׾jz>ٻ4$]AȽ_|:. OZ/!9f%D7pdAbɼFkBϕ-&3D.\ Aqk$63- *K-!!!"4}`+7C)dPGn:\đ8DL lyq̇HA|dc$m(qgcr/#3R`j;:җoo$j9gt l?҃=:W[@I!33x,\ΈYu43x%f$2%9ŹeI(0=nСUB F@B%x~dR(+ly[$Z7(xBe]D#d)es#/9oP v mtr¾|;jրvܣGumÔPVwZ(*tb@{9z¢Wb߂9L'Mü9z$%i-/$ 2r:Dsg89w=4좺vLܣ&;?gWn2:;Nn WyvuEVVfAz4׫=-1WKl'߲PBmt, .V(D0@`6R0u%C.Yw)f(TG?`ChvXx<agw/n&v(>5&-&|?fnznR }~a ;_ t[|#yAGaaTlZ9Vm Q\.t6P3KiC)?Kl۬8azG=qMN5F[0=ϼ$:WP3<8#̰K@(أ UW@d$ @tB/>+TyxAT5m(<&n|Q<5jdY 1ιU`+r^w~\Oqf8^yE8{Lh)YµF;YUoԵseF:?J] {,~J\ $r6Wk8+ޫNNm9DoyWېo_#_-YtdnAj6q:ϗocިpjt %=ϻvb2vmݥ]KvÂIp|rPL{vPc=fn-#uyzߦКǽq<_RSp"(=[X_XIzeN;a5ՕSbÏkdj`ku0h&5~6K9X M~?BU4@K 1M]n44d2ȭwbc1/P.޾pǞ/|dnEAfaO7Uq#  d9f=+qpXFpUy%e: ݉ ߫qzB}'\߁8Kɟ[1TPW @?U*mzBn5i'v^kCmd; ?<jFT&m5!DS_뿦xnHj-kԨ-9rd- ;5Aѫg[$=<-bŸY_j7|~a#wŌ'bߖ$%'Tn(!4苋n`^*J%>PrQѳT\D G$xX\;dXÊpd !#Xv& *?RYZmjh< W୆N شo V%b&RPSn :S0m hB7&qi O _۴?ĽV +X!Z5/ ac6JU5%n=y-,* >(ݨN'FU2 CЬw+D6i1iR!/T0,?}Քmw[y307Ք^qkZ M?7w5ӍK٦4L98U= ۤ8Ndef׻|.G;XL{/M!SxPƨ)HW 6 ^bO\ԳeN(n+ % =^KRTe ˒y3aH)LM"~i:}nv.œUc'S{m;9-WPhQXx4lRFIxII]f0(  ^ .}anUU ]l7鸞r]/AfC[c飁@_@< BXqW^<-Lt}ǝ REGb`w- gCJ y HH3HJR[>.O_@1 1s~_끕 jwHGOOA=JzfMB4pۂΖMWŸ1#y/꫒(}B}+n@Py4\x˔-[ijJn}>Gr*·Ĩ{o'n\t>^=#lfj}~.q{KZ*Y-瘣roݎ CiT9(Uvعߤ7PYAɾz{8L HUUC_N y~`™ܴ|9׻HojYZ@ #Ù&UQ7#F=%[+!3$]oT[H'% 4UF5uN~}cΖ3c* d#jw8jJ$;{bcVS=,q30W)+肦;pFWS :\ǥ&QNyaP]jYBA sge 9;Wf0:îD΅osTP(=9`K0Ԙ +|  v-W~^)ijmցp¯kEe[6 e 8n?~1|_OlY}o=~cb(pS֦ LrߓqBC t v#< l?J<,Ԣ۫YӦbs3KBwimܑ-.oY$e5$a,h&;,|[V/[`+wkQwig:œ' ̬$ҫbP*Z]!tCOGpbo\Ӧ~FF!%fQ@apIlˁARtσKw BH!9j0$s|3V6E?jZ@($.OXE jF4bX|4#$El?W4sޣ{!I)$ M% cgOpaFr#y!Si+ .$^FRh%{^ݟaCb 86rEaGIavx2NөQ^\ԓnڽ4֥46z(P ꫍jE( "皝J@mςQja9Z%5񈑕)j_0e>ݩKՈeNB_=c8[D(Ph 2?ma pح\U.:t0,M:xfv8]D$FӃla#5S"\ yl )]L>VA]ئs;\ #ú@I)H Pc ZƯpFqe-*ã}f{1z9᭾PjvUaQEGY} &3HBU/xw:^y )n/-ǦȃQMy#!@["E{}贀]L*])F~F~IRf,0.$ި٭p !4D@ 9۞j~K_Q>KŜ:.n~D_hT.&#f)|Ra q{SK FHs"]/k@b|2f;z+O, %i4#sddtwөm ,Z z5IN[IfaP|*y6ꐟ^j&f{) u2h1ginS[9ZMM}.ŗl;~ YyA5&p,.#5 1Y"Q$bB b!E` @! 2+ `  0)HE@ @TR(U ňF!b+ "@+0DBc |6fp,1$K5l<ݠ%d?_+WѸ7|3X:fa͹.3/hQp7M3)`՚ίڻ-|\yw&Ϻ]TYF<&tB06{tfhr|C)yVM<4@R*b`"ށmG"h\bwUFK^D u5V)6v E+r54aސk)@~Ӱxf^}sn٫yAcvoy:6'`E䧃!pVb $!Ĵ_ '=D:5 L"CO[ʓ~ c(FDͪSOOG$&C2Γ4 RTFw C Sm1)lyF7r@o| ƒY`n r9au#׵}n2i:pV"URx} 5)SR["e!$U Zx0V cIIe~\%/ CnX_0*_h9)EN i1+7ɷ,\LN lur-FD*2 ,'=6OMI5CY 7Ц[1:RXΤfe&:` $OHAGئ