summaryrefslogtreecommitdiff
path: root/scripts/lib/mic/plugins/source
diff options
context:
space:
mode:
authorTom Zanussi <tom.zanussi@linux.intel.com>2014-08-08 15:53:52 -0500
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-08-11 10:52:19 +0100
commit598b120406dc1d2b7e377bd1ab6f0acbef034b22 (patch)
tree25b51e30cf73935cdf80bd2f9766def49ddbc808 /scripts/lib/mic/plugins/source
parentd39c76f24a50c9359840c0959fb50fc6da0960cd (diff)
downloadopenembedded-core-598b120406dc1d2b7e377bd1ab6f0acbef034b22.tar.gz
openembedded-core-598b120406dc1d2b7e377bd1ab6f0acbef034b22.tar.bz2
openembedded-core-598b120406dc1d2b7e377bd1ab6f0acbef034b22.zip
wic: Rename /mic to /wic
As well as any other stray instances of mic in the codebase that can be removed. We don't really need to carry around legacy naming, and the history is in git. Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Diffstat (limited to 'scripts/lib/mic/plugins/source')
-rw-r--r--scripts/lib/mic/plugins/source/bootimg-efi.py166
-rw-r--r--scripts/lib/mic/plugins/source/bootimg-pcbios.py190
-rw-r--r--scripts/lib/mic/plugins/source/rootfs.py91
3 files changed, 0 insertions, 447 deletions
diff --git a/scripts/lib/mic/plugins/source/bootimg-efi.py b/scripts/lib/mic/plugins/source/bootimg-efi.py
deleted file mode 100644
index 5b1a5332c4..0000000000
--- a/scripts/lib/mic/plugins/source/bootimg-efi.py
+++ /dev/null
@@ -1,166 +0,0 @@
-# ex:ts=4:sw=4:sts=4:et
-# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
-#
-# Copyright (c) 2014, Intel Corporation.
-# All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# DESCRIPTION
-# This implements the 'bootimg-efi' source plugin class for 'wic'
-#
-# AUTHORS
-# Tom Zanussi <tom.zanussi (at] linux.intel.com>
-#
-
-import os
-import shutil
-import re
-import tempfile
-
-from mic import kickstart, msger
-from mic.utils import misc, fs_related, errors, runner, cmdln
-from mic.conf import configmgr
-from mic.plugin import pluginmgr
-import mic.imager.direct as direct
-from mic.pluginbase import SourcePlugin
-from mic.utils.oe.misc import *
-from mic.imager.direct import DirectImageCreator
-
-class BootimgEFIPlugin(SourcePlugin):
- name = 'bootimg-efi'
-
- @classmethod
- def do_configure_partition(self, part, cr, cr_workdir, oe_builddir,
- bootimg_dir, kernel_dir, native_sysroot):
- """
- Called before do_prepare_partition(), creates grubefi config
- """
- hdddir = "%s/hdd/boot" % cr_workdir
- rm_cmd = "rm -rf %s" % cr_workdir
- exec_cmd(rm_cmd)
-
- install_cmd = "install -d %s/EFI/BOOT" % hdddir
- exec_cmd(install_cmd)
-
- splash = os.path.join(cr_workdir, "/EFI/boot/splash.jpg")
- if os.path.exists(splash):
- splashline = "menu background splash.jpg"
- else:
- splashline = ""
-
- (rootdev, root_part_uuid) = cr._get_boot_config()
- options = cr.ks.handler.bootloader.appendLine
-
- grubefi_conf = ""
- grubefi_conf += "serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1\n"
- grubefi_conf += "default=boot\n"
- timeout = kickstart.get_timeout(cr.ks)
- if not timeout:
- timeout = 0
- grubefi_conf += "timeout=%s\n" % timeout
- grubefi_conf += "menuentry 'boot'{\n"
-
- kernel = "/vmlinuz"
-
- if cr._ptable_format == 'msdos':
- rootstr = rootdev
- else:
- raise ImageError("Unsupported partition table format found")
-
- grubefi_conf += "linux %s root=%s rootwait %s\n" \
- % (kernel, rootstr, options)
- grubefi_conf += "}\n"
- if splashline:
- syslinux_conf += "%s\n" % splashline
-
- msger.debug("Writing grubefi config %s/hdd/boot/EFI/BOOT/grub.cfg" \
- % cr_workdir)
- cfg = open("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir, "w")
- cfg.write(grubefi_conf)
- cfg.close()
-
- @classmethod
- def do_prepare_partition(self, part, cr, cr_workdir, oe_builddir, bootimg_dir,
- kernel_dir, rootfs_dir, native_sysroot):
- """
- Called to do the actual content population for a partition i.e. it
- 'prepares' the partition to be incorporated into the image.
- In this case, prepare content for an EFI (grub) boot partition.
- """
- if not bootimg_dir:
- bootimg_dir = get_bitbake_var("HDDDIR")
- if not bootimg_dir:
- msger.error("Couldn't find HDDDIR, exiting\n")
- # just so the result notes display it
- cr.set_bootimg_dir(bootimg_dir)
-
- staging_kernel_dir = kernel_dir
- staging_data_dir = bootimg_dir
-
- hdddir = "%s/hdd/boot" % cr_workdir
-
- install_cmd = "install -m 0644 %s/bzImage %s/bzImage" % \
- (staging_kernel_dir, hdddir)
- exec_cmd(install_cmd)
-
- shutil.copyfile("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir,
- "%s/grub.cfg" % cr_workdir)
-
- cp_cmd = "cp %s/EFI/BOOT/* %s/EFI/BOOT" % (staging_data_dir, hdddir)
- exec_cmd(cp_cmd, True)
-
- shutil.move("%s/grub.cfg" % cr_workdir,
- "%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir)
-
- du_cmd = "du -bks %s" % hdddir
- out = exec_cmd(du_cmd)
- blocks = int(out.split()[0])
-
- extra_blocks = part.get_extra_block_count(blocks)
-
- if extra_blocks < BOOTDD_EXTRA_SPACE:
- extra_blocks = BOOTDD_EXTRA_SPACE
-
- blocks += extra_blocks
-
- msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
- (extra_blocks, part.mountpoint, blocks))
-
- # Ensure total sectors is an integral number of sectors per
- # track or mcopy will complain. Sectors are 512 bytes, and we
- # generate images with 32 sectors per track. This calculation is
- # done in blocks, thus the mod by 16 instead of 32.
- blocks += (16 - (blocks % 16))
-
- # dosfs image, created by mkdosfs
- bootimg = "%s/boot.img" % cr_workdir
-
- dosfs_cmd = "mkdosfs -n efi -C %s %d" % (bootimg, blocks)
- exec_native_cmd(dosfs_cmd, native_sysroot)
-
- mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir)
- exec_native_cmd(mcopy_cmd, native_sysroot)
-
- chmod_cmd = "chmod 644 %s" % bootimg
- exec_cmd(chmod_cmd)
-
- du_cmd = "du -Lbms %s" % bootimg
- out = exec_cmd(du_cmd)
- bootimg_size = out.split()[0]
-
- part.set_size(bootimg_size)
- part.set_source_file(bootimg)
-
-
diff --git a/scripts/lib/mic/plugins/source/bootimg-pcbios.py b/scripts/lib/mic/plugins/source/bootimg-pcbios.py
deleted file mode 100644
index 959cf411bf..0000000000
--- a/scripts/lib/mic/plugins/source/bootimg-pcbios.py
+++ /dev/null
@@ -1,190 +0,0 @@
-# ex:ts=4:sw=4:sts=4:et
-# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
-#
-# Copyright (c) 2014, Intel Corporation.
-# All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# DESCRIPTION
-# This implements the 'bootimg-pcbios' source plugin class for 'wic'
-#
-# AUTHORS
-# Tom Zanussi <tom.zanussi (at] linux.intel.com>
-#
-
-import os
-import shutil
-import re
-import tempfile
-
-from mic import kickstart, msger
-from mic.utils import misc, fs_related, errors, runner, cmdln
-from mic.conf import configmgr
-from mic.plugin import pluginmgr
-import mic.imager.direct as direct
-from mic.pluginbase import SourcePlugin
-from mic.utils.oe.misc import *
-from mic.imager.direct import DirectImageCreator
-
-class BootimgPcbiosPlugin(SourcePlugin):
- name = 'bootimg-pcbios'
-
- @classmethod
- def do_install_disk(self, disk, disk_name, cr, workdir, oe_builddir,
- bootimg_dir, kernel_dir, native_sysroot):
- """
- Called after all partitions have been prepared and assembled into a
- disk image. In this case, we install the MBR.
- """
- mbrfile = "%s/syslinux/" % bootimg_dir
- if cr._ptable_format == 'msdos':
- mbrfile += "mbr.bin"
-
- if not os.path.exists(mbrfile):
- msger.error("Couldn't find %s. If using the -e option, do you have the right MACHINE set in local.conf? If not, is the bootimg_dir path correct?" % mbrfile)
-
- full_path = cr._full_path(workdir, disk_name, "direct")
- msger.debug("Installing MBR on disk %s as %s with size %s bytes" \
- % (disk_name, full_path, disk['min_size']))
-
- rc = runner.show(['dd', 'if=%s' % mbrfile,
- 'of=%s' % full_path, 'conv=notrunc'])
- if rc != 0:
- raise ImageError("Unable to set MBR to %s" % full_path)
-
- @classmethod
- def do_configure_partition(self, part, cr, cr_workdir, oe_builddir,
- bootimg_dir, kernel_dir, native_sysroot):
- """
- Called before do_prepare_partition(), creates syslinux config
- """
- hdddir = "%s/hdd/boot" % cr_workdir
- rm_cmd = "rm -rf " + cr_workdir
- exec_cmd(rm_cmd)
-
- install_cmd = "install -d %s" % hdddir
- exec_cmd(install_cmd)
-
- splash = os.path.join(cr_workdir, "/hdd/boot/splash.jpg")
- if os.path.exists(splash):
- splashline = "menu background splash.jpg"
- else:
- splashline = ""
-
- (rootdev, root_part_uuid) = cr._get_boot_config()
- options = cr.ks.handler.bootloader.appendLine
-
- syslinux_conf = ""
- syslinux_conf += "PROMPT 0\n"
- timeout = kickstart.get_timeout(cr.ks)
- if not timeout:
- timeout = 0
- syslinux_conf += "TIMEOUT " + str(timeout) + "\n"
- syslinux_conf += "\n"
- syslinux_conf += "ALLOWOPTIONS 1\n"
- syslinux_conf += "SERIAL 0 115200\n"
- syslinux_conf += "\n"
- if splashline:
- syslinux_conf += "%s\n" % splashline
- syslinux_conf += "DEFAULT boot\n"
- syslinux_conf += "LABEL boot\n"
-
- kernel = "/vmlinuz"
- syslinux_conf += "KERNEL " + kernel + "\n"
-
- if cr._ptable_format == 'msdos':
- rootstr = rootdev
- else:
- raise ImageError("Unsupported partition table format found")
-
- syslinux_conf += "APPEND label=boot root=%s %s\n" % (rootstr, options)
-
- msger.debug("Writing syslinux config %s/hdd/boot/syslinux.cfg" \
- % cr_workdir)
- cfg = open("%s/hdd/boot/syslinux.cfg" % cr_workdir, "w")
- cfg.write(syslinux_conf)
- cfg.close()
-
- @classmethod
- def do_prepare_partition(self, part, cr, cr_workdir, oe_builddir, bootimg_dir,
- kernel_dir, rootfs_dir, native_sysroot):
- """
- Called to do the actual content population for a partition i.e. it
- 'prepares' the partition to be incorporated into the image.
- In this case, prepare content for legacy bios boot partition.
- """
- if not bootimg_dir:
- bootimg_dir = get_bitbake_var("STAGING_DATADIR")
- if not bootimg_dir:
- msger.error("Couldn't find STAGING_DATADIR, exiting\n")
- # just so the result notes display it
- cr.set_bootimg_dir(bootimg_dir)
-
- staging_kernel_dir = kernel_dir
- staging_data_dir = bootimg_dir
-
- hdddir = "%s/hdd/boot" % cr_workdir
-
- install_cmd = "install -m 0644 %s/bzImage %s/vmlinuz" \
- % (staging_kernel_dir, hdddir)
- exec_cmd(install_cmd)
-
- install_cmd = "install -m 444 %s/syslinux/ldlinux.sys %s/ldlinux.sys" \
- % (staging_data_dir, hdddir)
- exec_cmd(install_cmd)
-
- du_cmd = "du -bks %s" % hdddir
- out = exec_cmd(du_cmd)
- blocks = int(out.split()[0])
-
- extra_blocks = part.get_extra_block_count(blocks)
-
- if extra_blocks < BOOTDD_EXTRA_SPACE:
- extra_blocks = BOOTDD_EXTRA_SPACE
-
- blocks += extra_blocks
-
- msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
- (extra_blocks, part.mountpoint, blocks))
-
- # Ensure total sectors is an integral number of sectors per
- # track or mcopy will complain. Sectors are 512 bytes, and we
- # generate images with 32 sectors per track. This calculation is
- # done in blocks, thus the mod by 16 instead of 32.
- blocks += (16 - (blocks % 16))
-
- # dosfs image, created by mkdosfs
- bootimg = "%s/boot.img" % cr_workdir
-
- dosfs_cmd = "mkdosfs -n boot -S 512 -C %s %d" % (bootimg, blocks)
- exec_native_cmd(dosfs_cmd, native_sysroot)
-
- mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir)
- exec_native_cmd(mcopy_cmd, native_sysroot)
-
- syslinux_cmd = "syslinux %s" % bootimg
- exec_native_cmd(syslinux_cmd, native_sysroot)
-
- chmod_cmd = "chmod 644 %s" % bootimg
- exec_cmd(chmod_cmd)
-
- du_cmd = "du -Lbms %s" % bootimg
- out = exec_cmd(du_cmd)
- bootimg_size = out.split()[0]
-
- part.set_size(bootimg_size)
- part.set_source_file(bootimg)
-
-
diff --git a/scripts/lib/mic/plugins/source/rootfs.py b/scripts/lib/mic/plugins/source/rootfs.py
deleted file mode 100644
index 8ebf62c10b..0000000000
--- a/scripts/lib/mic/plugins/source/rootfs.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# ex:ts=4:sw=4:sts=4:et
-# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
-#
-# Copyright (c) 2014, Intel Corporation.
-# All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# DESCRIPTION
-# This implements the 'rootfs' source plugin class for 'wic'
-#
-# AUTHORS
-# Tom Zanussi <tom.zanussi (at] linux.intel.com>
-# Joao Henrique Ferreira de Freitas <joaohf (at] gmail.com>
-#
-
-import os
-import shutil
-import re
-import tempfile
-
-from mic import kickstart, msger
-from mic.utils import misc, fs_related, errors, runner, cmdln
-from mic.conf import configmgr
-from mic.plugin import pluginmgr
-import mic.imager.direct as direct
-from mic.pluginbase import SourcePlugin
-from mic.utils.oe.misc import *
-from mic.imager.direct import DirectImageCreator
-
-class RootfsPlugin(SourcePlugin):
- name = 'rootfs'
-
- @staticmethod
- def __get_rootfs_dir(rootfs_dir):
- if os.path.isdir(rootfs_dir):
- return rootfs_dir
-
- bitbake_env_lines = find_bitbake_env_lines(rootfs_dir)
- if not bitbake_env_lines:
- msg = "Couldn't get bitbake environment, exiting."
- msger.error(msg)
-
- image_rootfs_dir = find_artifact(bitbake_env_lines, "IMAGE_ROOTFS")
- if not os.path.isdir(image_rootfs_dir):
- msg = "No valid artifact IMAGE_ROOTFS from image named"
- msg += " %s has been found at %s, exiting.\n" % \
- (rootfs_dir, image_rootfs_dir)
- msger.error(msg)
-
- return image_rootfs_dir
-
- @classmethod
- def do_prepare_partition(self, part, cr, cr_workdir, oe_builddir, bootimg_dir,
- kernel_dir, krootfs_dir, native_sysroot):
- """
- Called to do the actual content population for a partition i.e. it
- 'prepares' the partition to be incorporated into the image.
- In this case, prepare content for legacy bios boot partition.
- """
- if part.rootfs is None:
- if not 'ROOTFS_DIR' in krootfs_dir:
- msg = "Couldn't find --rootfs-dir, exiting"
- msger.error(msg)
- rootfs_dir = krootfs_dir['ROOTFS_DIR']
- else:
- if part.rootfs in krootfs_dir:
- rootfs_dir = krootfs_dir[part.rootfs]
- elif part.rootfs:
- rootfs_dir = part.rootfs
- else:
- msg = "Couldn't find --rootfs-dir=%s connection"
- msg += " or it is not a valid path, exiting"
- msger.error(msg % part.rootfs)
-
- real_rootfs_dir = self.__get_rootfs_dir(rootfs_dir)
-
- part.set_rootfs(real_rootfs_dir)
- part.prepare_rootfs(cr_workdir, oe_builddir, real_rootfs_dir, native_sysroot)
-
pw_}֑YX`q\R0렺zP_~s:ya&ս*s}8_|㙩 {8Ӣӧ"#|b/RsIb22\q6 [GaIC_Ջ2D-Ym(/xsvM@vN 5!8֩4J vUG0ה(byM;qAi 8*tңXW?3W( B}6AƤpge>8| Gr{,Oe$D.1O%>by9LdXG #ȪWm }PQ9.Yz&|^O?F (?7)ϱe:[jȂs$2XC aZgA2dS+| wC(#{b7^ g5IYR <.*9O.lുlu矻йӧaZ\ eXtD@!O 9&ݫ3"!@:*90t|k%CLYaW{h!gޟ1.tR9-ejj,9fl4mx?%8X}u ۆEUUPur}E4C3 ;FIs/6<2'**(%Nm kJ㡚k/nqĠq#DxO<3FjŎU߉ '.Ŋxd^*L:[|K,jݜSxjqj >V*I B<@3m!'lLNm#]>Zn9e4!Դ~brߗgl/}҄>3&"&2#S{U8r=$;M o)vnΔQJTE䊗wϴ4r*z|CvϏL]!.%p1#,Շz!12!O;S0b<.I0K27[$U;kԯ+O\0>4u7dx+=c%nXN-I|Z4uR( j9Uohv-EV%彎o]~ܺi =#`54TPx~,~61rpRdFq$Re|Yѳ}$& + 郮Y~2}g/zyzO1 : VL ~{@.0Q: Λl;6 [3?HygQ؜ C,cc+ k_xokTC {6NBa#y0v )Adj- D rof5a6#D!؝8x6mQQ 76>gD-sÄ,UP^!0ճ0XdQYq؛eGvQgJ5xmҜtskSM_)W%d)+|$?QǣY]90hlQ&Ѩ8s偻(-sY]QgLPa?m_;7K~cvozGNRqPsPɬyG0v;r ˝ͯ !4s1;V5;3:=OqS4S &T~$?^A,g [Z|H8FFJ&;#k'bTe>d9Oxt94gZx($Jb ]`=QLx0F aքxV TDSUq}7Ux$@R=!Lj <^(+[tShhNrqz3It,u,EYSX?Te# "Au.NfK'k}Q)sG?<L.d{ז`/..fW5@ P>57c"<K!:Pdq3pICtRl9:`1]Ao4B!6~f1l8rlPH :vb7{o |^7Pb` G2x]逤7IA(,sYV&AcLHԓ2A9cEBd=`'e BX$u~\qW[yaaHRI`⻆Lh\6"RtI$e`{ϱrkkləF!!iMqp}!^f~^8Rx^Uk<r uH]k˖,A""BSdhCũsePZi5o ;f4Uޣ\x iE &>+2+ދȨs;!0G4|IFWx#Nu9 mg:C$y gpa|5]z@,(%w𛫑mZ& EH=C^@A}EQ79CJS| m~\.yX$"E,/Δth9Q5)|P-rFt>)Z\L|â>w l)[^ `*Qps6]7Wg@d$f[>soIƝ6rLUbp+3\%Z1=\{mgU v5mwÛzGf2m[870vYwqύaGl:E j"Yky箰hNpݲK/{rީ߫7NQ:hn] t==`hlG&.m3 -^Ӗ^*Lo>BGY̫y}49UjT`[^@ _HMa)YnCW6_-g9\YM=ِU]PXDcdMwI:#p';"c wrқNp9SxP3|gfI84l* ~Y^#`ɝg_\6-6_T4Cp//Űߣo ( yvU&8ڲzd^HPP%t3@r48 AuQAgwޟ¤hcۇ$~j]! /u{aQzlWȽ2tSCYS̬M0 .>c'[chz8 <U:7gIPҁjD2B AUQZؔLF%_5&\.CO[A={I Խ|oMfX,c !5+\c%EZK4L`Y0x D!H9`뗽;LxrQy /ĆA%_аN<_' -Q^>g*$']O3$o"`6ֿ3Q$&o$ٖ1z mSð=t ַ$Oߎ_>snq]- ;m8:bJ2e|8W<+QwO GARqM4Xj 5t9Q }y8/xD!ܶ;SfZ? D`sgA;#yQHl7Aj1D %FxCýnw~yf&w\W~p/~J>%;n ç6jy- Jg7,Lßke/tIM?cn.#mAa" eJCfˑ)~ݼ61@- y1aJj7pbLцdVl{(=њb'W=fq aG \P YFmfDH 1md=99C O{}xMs^{؈6\}ϛYHX:CUz "ώGkv<ְ\ 75*>DC!9}GI@A W byu>ns2ugnQB¯[_b^L5*Qhiz#Bh?RWlY2*3y2QLDܗ.VAQU(|6:ЍBq003տLgp8UwɃm$-ְW.oeWRմ IIB(eNtyf=XvLbG]ӯ;;Ca`$>FKG@B-BWiUoĨ"n1 $7&"!8nU-<#nJkEݧ zŒ΅c񝕜!fO` r*b ^= #Dģ3K*,U%-QVaU9{Z-WE$kUGvS!\~h R(Ư{no&qӫ%jiw8f$%Q%;nyzc<1*9٢|m|-X(;:UL$T17ҐaL) 4Vbײc60\$y1\l𖢛rC%XBr.!!?D*%'j~׋!}L4ZX]]PEN|8뻏 jF}K˯WGJ2lmyVs,3uQ ܯ[,3΋Y[ &8QV$]Yv:IDgv}=X^t<޳hgV<^8􇇋9م5b4,ۜ%?Wq'+j]- Go w7?`fs02n:ɵ\(`HC=!% Gw qRԤ7# HC*ThPC@!lW>6fKmΏ!6質 aMw _zm@yl.%r}{fɿ/sDV0 Mr j ar߂KhjI:2{yH,ZR2 $a_rCW'.U`#toǛȴ9!l4OVzzCJZ޻ bw]n.8+ѭ6u-Q?9G\e̍v7AAdHC^e'0\WxԬaZ]gV:#E/01Gb{%Iy8\980Ikjw2SF:n+\13BW;.*V۳+]Q\rAشYosF"VbIVds~1hmZ'6던/O˛x!S;w=e 5ck r!fiܣ _#YwRz}o"n`u~v~u޼5'o[WiiXO9cewWXńLET:erEpDƤ0EJIFdk>GT'^:P=w̭D^Q^HH g{en\gըV8;:2:A_s8\HOvPmec Y7ɯ+z/(tvǷj*7΍;%(!ڙV19?'IRNlQ(5䜎iǻ7u^~ocML D B#~*~+F_1SAC1_V\Xf Un+<-bL?3Gx`jN0)%fi=>4si(ڛ3g-{5Y<v Rr 'Q5幒2x5I]î7UV/ߺ{yc᧷~˷'$'ݒC>;C=F =όkmڵgh{@3TuGt05W;d1df{8suRC_և&WXPhK5CLu|&2L]F1 *6ȑEsX*,v7/;~WsEq'{qGSߛ_iqXv\1wS J=YÆd:h*1{1oPOfpAX0V*nƦ죧+;5'';WhQbqRo/bҹ]= L 帙?Lp"-Kco>1r:^AbUu0n=I5c]cԿZTm5&uSn^f tѷxw8T!;*>J<0Ա="*/NK6$*Zy*|pgYfI1MjYdISv3M;{xvst~gހxɰTu=ѱpt*#$IXc]eg7Z371,5;EbF%並Wr0\eEh5-a(LP/tQxSI_=VQc}c &Lƣ0WpWj}<Ϟ\:E7gCW^IU/O戁Q ]E{u~U}Yq~0iX׵EU=#y9߻7g])"e%"HlW`E@u/%&K Ao!y»^Wo w-Vk&9 'Y$@k=ҹ_6ƥ{MUΊ9 ٣͍E %>pxq >4䐝W%0ւGL,@=e雼{ihs'FJʯG@L`Gܠ guW,WӠsF()aƛVUkXhF+cuWʄv!f.**I)pVp`Q,P-T޶$ݑis=/ھ(j[ +?iPn},V 8W}n4$!dGs]텉zqbDNh+ '˿sU:C :t\Xb0|([.=ܬTS_AiS\< ]%1A,apUecXś5s:X2{IJ_(J g a}-Fh,+0#{CySv' nYօB"S[Y^.@]g * 6aQ@C¥|h9 {{B@Gd;F5,s4Ҭ ʇ-w{5]k̵#8A*W]V:ЅpgR˺9X7nQ⏠BO kMH QhO7L,D< l|.%M|uħ8i卌H#kC cމ1Ϲ!TUA9Ytd>ncA3.:?)Q*vcѕҥ^u^\ojK3NOx^8ZS"Rǃ/&ƾ"&V Y[O0ПQz?3Og1qPVyL{h7ymIDTS٪Cv{Lxs, |tlPݯϲ1f8_o\{ܮxZ y\iM>U 3퀘iX.bD<3ݜ`r0VEsԈ_6Y*F{1kban;ɴy5nQ/O\xţޓj:37vsJ%wCBҫ>m/?fk+| W}$V׈ B,fލtpWSBf=uIoW@nr8q "|OU63^Yu*ișx s'8+o ϣ.|+ECjns DWpg&& JȂYO/q2L{e '|vtEdk|TYs.^*ɠ9ɉ8n@0@1bn / 'r !<^mJb:lν۟[b\O>vjh#u?#SX5kC[T'wQcp4ֶΘ fhC*XVdbDÝiRb ^8N(.´еlYސ,]~/͏Y<uQuMzEiت0=#;>KTh6lGѱSfܰl7㻻 ޳0/`;"w5Ij@ QQ'َؖ"/ImK8ҰfVHwE47`'3z^(!pJUhIzJ0₾XP 4>^^oghl)-E.)|g!6w8EØd@ߎ+kb/лHbM9{S]sgkZ!~7l !&@wV6m&7 0}hbf#FP2~ZGK`qԤmhm’oǧD974[^Ԏ04qA[7r MzaѶ79f"cs:u wp`*T);{#Wo>b1}9ΛČЀQ1=*$Rbiwzp]`Y>W  ݼe;bN-qT~wHiʡ\, vw(Ե! lQi:ȾA@1ѯy  R;'V[7y_"@$lGgϠMe^=e#@bܫem$t_vv|~SĆkPYhΤw,c,~`N%FcewҰTU( Aa@. Uda k0e= &-T#c/:4ެkbK{v0)# {'`Q"(U<=C D{9{D-Pk ={b2WT4fXf'm N~U!V;']?lVkg0;(Q}<ʩM|Wl//42=%='H)9Qf>"F<#qIh>3l#EQ{ T< >ogt6!/-Cp0.29GD[?fܸz5A;:p#y;3QA+DrF{Ǵe.YʺYRkyB- &7Tώ by&C |&2wISFW<'"dl<@$DJ֮x?o# '.T m ]vVVuE*OY-]9f趯?Wz=7l:ߵ(qs m>h~}zO/8>IB#PXb.pw~x~t vU{Hڝ%j&<L>`A*  JpIIcr% E(Ѣ16>l/5JD/fi]ϧk!zrP a+`R^_z>h!@oMDX0()( W "bZBJ (("Hl iJDS J#3QxD4 pz󖼛 \'FKPYR_ƧF/.w)ON_Cۀ_"j~=g٣#0JtR#iae̦|9},*15 mT֜B X)?kg9LP0$ )$ Fֈ `D@M"2&HBTLCBdD UU> SBDKMMPN1ZJi"BP fAQ2rh %h !%i2S (hr $2J3rx0H1rFp=~n`h!*z1xKS\!ƈ!78_%-,M7u0yKQ:28v^%>rEz\pU@*IU޾9;{ Q" ' `! -\ϻ ȉL@~)G.E,vwQNcR_!!2V_FK =.O#w^Z\~O6#bC"h)}ՋAZ{ӸGz7gk7t26mw`|BTןTEA+oa?o2s-lFbCK0Ao'B#Qxؾ^%st$̩޾RoxfC /`G;7dCbIgC%H!<ܻb],Vw]mO>3\|BPuPqwz㫠(ltӋpA/#2"BV]t]cN#?[8)>\O//?[ )]EiqwVSx챮>'Kh>@=O8y=6zo*mu =ϧΣԾ(مU s"}dcz/>\YI 7dN>`*;#!t>jIٷnAԩ=ڞw9/ɇ_7FOnǧM"\I(@Ki2HXAC&0 " pi(/% 2C>?`?ACK*1DE'<(Hae'd2c"@  #>5T,W`jNNSELI U,T2 tBwn[sv.P<ʄKXBu'7!h׸\c?D(QwV#n~W?wK6G2 #v" Rty /m Z%ӡ& !7WXdH| #vԥ%߇ed#0 ) $B:" XEDHT@j? "&-l)b5@H9[00.0 I@RQ6ΣDŽl3nV@ Ĉfg0&(bZccp.qɆRqarXqLTLJF"De P(m*)RfG%Mŀj+5%5kɤfAE@aJl;ش%a%UdE=%.fTXCIIM%ŘA,RIPh12NFNT!?ɧvwܑ*O?$|>w @ D'ɻ[wz?OC[G~h?Mq$@챒+B"c~_b!:DV'Ն`ҕl*Llozu(t3 :d57Ɋ4Jb[:5aDPGfh89!1 ( )" u/iM0!]0%,&pxZ' 6l,dBh4iHe,^TZZI]XP}DCc#{ipʲ+UVfU@+Lfv;0և v0" */GHrc]`DL!#wbk0:XHD&I!J9nXDDAҝY^ߦkN`d74]ttweQDW9 O,p JAK+^jcӶNe 9'hr !@0@#y tI&آNVI#MNmkgSh⍆v23T̶ iyu\<\nlL.x\9lC! 9cGzu]f$f e" å9lޠ׾ǘ؎pDeJFG jH b^2:LeǺV)`e,M W,6;eWؓ!DGeأn@lzzsuja42i1>-$0akA#v#R6i?}*F4}s]Uhl>^amc+i%`na_YlL{),I.ݲIvqs.=y[h?>=ai|>N9 xg`‡OQ#ri;B.j&~$aGx$/A|m_΂COK!bDVH".NΪA^VB] Pc&Vr$PhsxO_> m} }yg?U=E4U1 QDTUH, Ig&Տ;z>q"'@FAAD(h,^`"ե]FTQ^//|974ch2)ӽz4^{Cjʨgm`>`5υ/nẉEr)0˜"U4QV:O:ʘ[IVHfmzgrŇ6u;='$O.)P$ ?1ۼy1fVPȍXP<+'x~?-+G9%UUT)-84NTdRS"ĘаÔK}U+?Q~Wn!OJ{|)ʞえ`C?Ti81{т Nt}]Ep7%!`_O"D;H#AD#s)υ1MI?~NV|rBpܜڗ?rptaigs; xP-i_L}m};~o~NQCUzXNa(c~,2*-$H71=1_ݴ,2iie! bL Phe0#rpbgAG'cn``T*[~>K% ǜÓx#?\>xV;[yB'$ϼYuT>.O6ޯO/ï@?Lsg:-Fv9y,Ns'l= # G+}vܺճ@\!Cѩ_hɮ'"=ʞ~aO-w ryvJƩe}$eJxl5 _|8I2o>[|@:5N:DG m|N݌R==|7gG*rXCWyNj~[pg(.l?X,:ux={vO=6?J;ϻWͷt ֟xd&1Obۓ}i05~*Q1Av.MA-o5swKA/x#KL-230X\u'g=/0؛lKa\&BAtW&".A`ֱO^c?D{ݰW( sdcXw+J_'|x/kç.ܪGkuI>܃F#oWZ8xĘq}g:z eɧ|.kqZ-$?w0r)|Ksu H{=A'Duf6(팍wV][sێTǿj>zϞߔ[y%A<.ǻ]9IwzTH8Ʉ:w6yu-ss#@gn!Ԅ Pr{ #Ý=oS/ojwJ|&>ӊ<'FnvS4a! 霸hs|˷J {Yl8uVѭ[/l!s=I$My`,OvZ|h :~.5_L,fʈSX4ŨߥYڲ˓l3_)t!x֪A[$栳k(S6b3H\bxN<]r#4wze?xCv[M؟0@ -pB"|P 03w.j2w~q%`k>QJ@-C f<Œ,Y[9G=LL>B[}Y}ח1;ylm}к=*/72;J-1)((iXS PU"LAf6XCDJA1eڀ) B+L` TD:$0ı$%p$L\Hi"*** PbB***-XCB SA%@ҥ-PIAR.׮i$A\6>嵵_дIե|`j!9Pm[uUnѣy`Lv&@b9+ed`K0l5*NH)isΛ 1X2hba*ƙ$ q#c! Ir!GF2C18% j&\9rF+R.97+J_1#{C7TA> ]YL>~WI#<@8+8^r L"n(bM$`a'iw$kܼ "Fp{/KliazXY(@1[Lj^C:+~>@u{Zav1W [g TLcxʃO\I2e,@aD xG!8nL@"4 B%: 4 'hAuqUrx*!6jZDyeDb]v/iY`7.ZJ./Fv`]ޑ1&҉IO?;Qx挩+F;>ۺ}>gOl/_q1@yDOo_ƾ2:aaFkUs7ڜJI.A!-#yFH}ݼVo_t؋yRv>E42$!,%*ʉUeze}Fȳ(íaS|#2w.ٍ!EI9t;30E f^Rk0伟{ф֔;Jc5K$a3;;wC&@Q˟6Eу cskƶ.H@G%H؁ĸ0SszԞ?[U"7q2uK"~]Eo W GǶm^%,eS?J'pkvTvNn"Ml> AP݋F 5ɼL]6s]bm:œ1ƒ,@xM|$'F^ ?!6 LDQz<&5\盥ca6_UX77D=` :kՋ&Ɛv+40|V5N;g$ P* 4>apƺ=Fb^ʝOZyKʆ7F<1Գ?ӚtIO_y9~{<@f5PFo桗E?CCh9IhPvr^~Dh8ZL2&mʇrۉ7´d\M\Vjz﮳v7KNvNH@ǓY{I3ю*uf܋lf~'w A#W EQ*\oC+w3VwWa.< Ƶ >;VL].L1qa,||G[%$HlvߴF5ݞZZ~o _pC/FUc߷R p[HɴS 8K & >g&`l~=oQ4~og.{#k=y.R7FClG?oyC֣jW,dT͞;*2^7,Ⱦdl R䷶0i! ^p8W*V#Je+ D3̈N}dqմ>nR$e/ۗD %d[H& Ȃ' ΐ Oµn>q5aMvI` Sym!Iehfl2i &:Mr0o"_U1{Eձ8W B;ZNR")X90z+REH!.Mj!u3c׻lUy[:hA.\g0ݕaZ*'4 "!3)saGi80B:\p[:V2Q%dWѾ;]yQpT⣇w\\۪tAufN}IR|g(R]'q8n ,vIͶ(i|D*[7R꣍-QT7Yß@ϑ]Wbؙ{jaFA^Jc v&Ҿ }DQFq D-)cRK>rߟ5q9x`ӜY[|D]ѯAqM%xW1疊0nrѣ VWiƧ"1*4*& S;gzl9p#\S%m޴C8Sl8a_9+pItnXRM jɨ-WSv_1(Q ˠME8"yEay|sEv*P֪ZYe69,%"ynJǣy7yDIhx.^:IwO(AopwpGa.GYpD3+*s'pa awٻPJ .hj'YWdD lk2wVs8R7 .c0QLt*.a H:3 #*K 1}1CBP&6٨@ҳFq5m㬺g(f"F1.'.s VjĨ/9Ǎ8끭34m0P:A]UҞۭQi'C T!jcZ{smD8ɵBgf`wI,[21\ 4p[nBVA '\Knkfw1gy4Frq_]WTrM)̞va٭)k:}j{Gen8F2V"硰cG|d"s]l\ Nqz5^}WTI$ FothBBt4EJ pt.df"8_ElYS1j|I]]sl<2!> to{7]b*#Mb561/ޫG:{nPw*rؐc)ȥm1ڨ5p砮,ċb1EpJVʾ-˒^)Js];B?g=*Ka$g>8w Gc=PARlzލOlZP]&7sR;E㋆ fNk[A8vnp/ΐ2L - |ML){.&qI=uWl,越]pK֨^d~caPނx9i,M7WN:5 uN0iXE`T**jՋ$vnPv ;b8ym!&w  O\ȃ%EremxÎFf V('p6Aٜ~ѴiZ30:beƄ/g&~:rtʜb kBA:kwi[<57ehj墒T\oy|g8O$[{!6nN9Nwc氻g y1WOSv~ш)UU #+3P<˞ȯ+~1]sF'n' n'oicE=Gzz;0rN| Y<.[UDR󪷾Os[˷0GTV?J7[I~.V*S ZL4[A8kuCm=uF;qχ YikWL:sͭԩHbĎDF{FeE[W~yl<+<wP/;onRmB%kP=͸J&%Ϯ~j mURzFվzA l|] ޸I #9RV ɠm^e} oq۬;v\|w%ÖL}*#,t$^`9r8I$Gvg p {.*AN\c,=@RJ!! $27 S