From 9058f61f48a3c801e7817dd10905fc11e57c298c Mon Sep 17 00:00:00 2001 From: Francesco Romani Date: Wed, 24 Feb 2021 12:56:04 +0100 Subject: [PATCH] sriov: add support Add support to report SRIOV devices. Much like GPU devices, support is added using a new top-level package. SRIOV devices are either Physical Functions or Virtual functions. The preferred representation for ghw is Physical Functions, whose dependent devices will be Virtual Functions; however, for the sake of practicality, the API also exposes soft references to Virtual Functions, so consumers of the API can access them directly and not navigating the parent devices. This patch also adds support in `ghwc`, to report the sriov information, and in the `snapshot` package, to make sure to capture all the files in sysfs that ghw cares about. Last but not least, lacking access to suitable non-linux systems, support is provided only on linux OS, even though the API tries hard not to be linux-specific. Resolves: https://github.com/jaypipes/ghw/issues/92 Signed-off-by: Francesco Romani --- README.md | 61 ++++++ alias.go | 9 + cmd/ghwc/commands/sriov.go | 48 +++++ host.go | 41 ++-- pkg/pci/address/address.go | 10 + pkg/pci/address/address_test.go | 8 + pkg/snapshot/clonetree.go | 15 +- pkg/snapshot/clonetree_pci_linux.go | 48 +++++ pkg/sriov/sriov.go | 113 ++++++++++ pkg/sriov/sriov_linux.go | 128 +++++++++++ pkg/sriov/sriov_linux_test.go | 198 ++++++++++++++++++ pkg/sriov/sriov_stub.go | 19 ++ ...64-8581cf3a529e5d8b97ea876eade2f60d.tar.gz | Bin 49461 -> 49927 bytes 13 files changed, 683 insertions(+), 15 deletions(-) create mode 100644 cmd/ghwc/commands/sriov.go create mode 100644 pkg/sriov/sriov.go create mode 100644 pkg/sriov/sriov_linux.go create mode 100644 pkg/sriov/sriov_linux_test.go create mode 100644 pkg/sriov/sriov_stub.go diff --git a/README.md b/README.md index dd534b0f..96ce2ec6 100644 --- a/README.md +++ b/README.md @@ -1115,6 +1115,67 @@ information `ghw.TopologyNode` struct if you'd like to dig deeper into the NUMA/topology subsystem +### SRIOV + +*This API is PROVISIONAL! ghw will try hard to not make breaking changes to this API, but still users are advice this new API is not +declared stable yet. We expect to declare it stable with ghw version 1.0.0* + +SRIOV (Single-Root Input/Output Virtualization) is a class of PCI devices that ghw models explicitly, like gpus. + +```go +package main + +import ( + "fmt" + + "github.com/jaypipes/ghw" +) + +func main() { + sriov, err := ghw.SRIOV() + if err != nil { + fmt.Fprintf(os.Stderr, "Error getting SRIOV info: %v", err) + } + + fmt.Printf("%v\n", sriov) + + for _, dev := range sriov.PhysicalFunctions { + fmt.Printf(" %v\n", dev) + } +} +``` + +ghw discovers the SRIOV devices starting from the Physical Function (PF) and exposes them in the `PhysicalFunctions` slice. +Virtual Function (VF) are exposed as properties of the PF instance with exposes them. +However, in some cases users are interested in the VFs first, so it's clumsy to navigate the PFs to learn about VFs. +To make this easier, ghw also exposes a slice of VF instances. These instances are soft references to the very same VF objects +you can find from the PF objects. + +```go +package main + +import ( + "fmt" + + "github.com/jaypipes/ghw" +) + +func main() { + sriov, err := ghw.SRIOV() + if err != nil { + fmt.Fprintf(os.Stderr, "Error getting SRIOV info: %v", err) + } + + fmt.Printf("%v\n", sriov) + + // you will see the very same VF data data you seen from the previous example + for _, dev := range sriov.VirtualFunctions { + fmt.Printf(" %v\n", dev) + } +} +``` + + ### Chassis The host's chassis information is accessible with the `ghw.Chassis()` function. This diff --git a/alias.go b/alias.go index 2e679a96..7cd9e708 100644 --- a/alias.go +++ b/alias.go @@ -19,6 +19,7 @@ import ( "github.com/jaypipes/ghw/pkg/pci" pciaddress "github.com/jaypipes/ghw/pkg/pci/address" "github.com/jaypipes/ghw/pkg/product" + "github.com/jaypipes/ghw/pkg/sriov" "github.com/jaypipes/ghw/pkg/topology" ) @@ -150,3 +151,11 @@ type GraphicsCard = gpu.GraphicsCard var ( GPU = gpu.New ) + +type SRIOVInfo = sriov.Info +type PhysicalFunction = sriov.PhysicalFunction +type VirtualFunction = sriov.VirtualFunction + +var ( + SRIOV = sriov.New +) diff --git a/cmd/ghwc/commands/sriov.go b/cmd/ghwc/commands/sriov.go new file mode 100644 index 00000000..c6048c8d --- /dev/null +++ b/cmd/ghwc/commands/sriov.go @@ -0,0 +1,48 @@ +// +// Use and distribution licensed under the Apache license version 2. +// +// See the COPYING file in the root project directory for full text. +// + +package commands + +import ( + "fmt" + + "github.com/jaypipes/ghw" + "github.com/pkg/errors" + "github.com/spf13/cobra" +) + +// sriovCmd represents the listing command +var sriovCmd = &cobra.Command{ + Use: "sriov", + Short: "Show SRIOV devices information for the host system", + RunE: showSRIOV, +} + +// showSRIOV show SRIOV physical device information for the host system. +func showSRIOV(cmd *cobra.Command, args []string) error { + sriov, err := ghw.SRIOV() + if err != nil { + return errors.Wrap(err, "error getting SRIOV info") + } + + switch outputFormat { + case outputFormatHuman: + fmt.Printf("%v\n", sriov) + + for _, dev := range sriov.PhysicalFunctions { + fmt.Printf(" %v\n", dev) + } + case outputFormatJSON: + fmt.Printf("%s\n", sriov.JSONString(pretty)) + case outputFormatYAML: + fmt.Printf("%s", sriov.YAMLString()) + } + return nil +} + +func init() { + rootCmd.AddCommand(sriovCmd) +} diff --git a/host.go b/host.go index 5d82a53a..a9905011 100644 --- a/host.go +++ b/host.go @@ -8,6 +8,7 @@ package ghw import ( "fmt" + "strings" "github.com/jaypipes/ghw/pkg/context" @@ -22,6 +23,7 @@ import ( "github.com/jaypipes/ghw/pkg/net" "github.com/jaypipes/ghw/pkg/pci" "github.com/jaypipes/ghw/pkg/product" + "github.com/jaypipes/ghw/pkg/sriov" "github.com/jaypipes/ghw/pkg/topology" ) @@ -40,6 +42,7 @@ type HostInfo struct { Baseboard *baseboard.Info `json:"baseboard"` Product *product.Info `json:"product"` PCI *pci.Info `json:"pci"` + SRIOV *sriov.Info `json:"sriov"` } // Host returns a pointer to a HostInfo struct that contains fields with @@ -91,6 +94,10 @@ func Host(opts ...*WithOption) (*HostInfo, error) { if err != nil { return nil, err } + sriovInfo, err := sriov.New(opts...) + if err != nil { + return nil, err + } return &HostInfo{ ctx: ctx, CPU: cpuInfo, @@ -104,26 +111,32 @@ func Host(opts ...*WithOption) (*HostInfo, error) { Baseboard: baseboardInfo, Product: productInfo, PCI: pciInfo, + SRIOV: sriovInfo, }, nil } // String returns a newline-separated output of the HostInfo's component // structs' String-ified output func (info *HostInfo) String() string { - return fmt.Sprintf( - "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", - info.Block.String(), - info.CPU.String(), - info.GPU.String(), - info.Memory.String(), - info.Network.String(), - info.Topology.String(), - info.Chassis.String(), - info.BIOS.String(), - info.Baseboard.String(), - info.Product.String(), - info.PCI.String(), - ) + var b strings.Builder + for _, s := range []fmt.Stringer{ + info.Block, + info.CPU, + info.GPU, + info.Memory, + info.Network, + info.Topology, + info.Chassis, + info.BIOS, + info.Baseboard, + info.Product, + info.PCI, + info.SRIOV, + } { + b.WriteString(s.String()) + b.WriteString("\n") + } + return b.String() } // YAMLString returns a string with the host information formatted as YAML diff --git a/pkg/pci/address/address.go b/pkg/pci/address/address.go index 6a8a4e45..ad371055 100644 --- a/pkg/pci/address/address.go +++ b/pkg/pci/address/address.go @@ -25,6 +25,16 @@ type Address struct { Function string } +func (addr *Address) Equal(a *Address) bool { + if addr == nil && a == nil { + return true + } + if addr != nil && a != nil { + return addr.Domain == a.Domain && addr.Bus == a.Bus && addr.Device == a.Device && addr.Function == a.Function + } + return false +} + // String() returns the canonical [D]BDF representation of this Address func (addr *Address) String() string { return addr.Domain + ":" + addr.Bus + ":" + addr.Device + "." + addr.Function diff --git a/pkg/pci/address/address_test.go b/pkg/pci/address/address_test.go index daf0eaa6..c3989dd4 100644 --- a/pkg/pci/address/address_test.go +++ b/pkg/pci/address/address_test.go @@ -80,3 +80,11 @@ func TestPCIAddressFromString(t *testing.T) { } } } + +func TestPCIAddressEqual(t *testing.T) { + addr1 := pciaddr.FromString("0000:03:00.A") + addr2 := pciaddr.FromString("03:00.A") + if addr1.Equal(addr2) == false { + t.Fatalf("addr1 %v and addr2 %v should be equal", addr1, addr2) + } +} diff --git a/pkg/snapshot/clonetree.go b/pkg/snapshot/clonetree.go index 97308031..b80a54d8 100644 --- a/pkg/snapshot/clonetree.go +++ b/pkg/snapshot/clonetree.go @@ -100,7 +100,7 @@ func CopyFilesInto(fileSpecs []string, destDir string, opts *CopyFileOptions) er if opts == nil { opts = &CopyFileOptions{ IsSymlinkFn: isSymlink, - ShouldCreateDirFn: isDriversDir, + ShouldCreateDirFn: shouldCreateDir, } } for _, fileSpec := range fileSpecs { @@ -157,6 +157,13 @@ func copyFileTreeInto(paths []string, destDir string, opts *CopyFileOptions) err return nil } +func shouldCreateDir(path string, fi os.FileInfo) bool { + if isDeviceNetworkDir(path, fi) { + return true + } + return isDriversDir(path, fi) +} + func isSymlink(path string, fi os.FileInfo) bool { return fi.Mode()&os.ModeSymlink != 0 } @@ -165,6 +172,12 @@ func isDriversDir(path string, fi os.FileInfo) bool { return strings.Contains(path, "drivers") } +func isDeviceNetworkDir(path string, fi os.FileInfo) bool { + parentDir := filepath.Base(filepath.Dir(path)) + // TODO: the "HasPrefix" check is brutal, but should work on linux + return parentDir == "net" && strings.HasPrefix(path, "/sys/devices") +} + func copyLink(path, targetPath string) error { target, err := os.Readlink(path) if err != nil { diff --git a/pkg/snapshot/clonetree_pci_linux.go b/pkg/snapshot/clonetree_pci_linux.go index dbc3fc83..656ac51a 100644 --- a/pkg/snapshot/clonetree_pci_linux.go +++ b/pkg/snapshot/clonetree_pci_linux.go @@ -70,6 +70,19 @@ func scanPCIDeviceRoot(root string) (fileSpecs []string, pciRoots []string) { "revision", "vendor", } + + perDevEntriesOpt := []string{ + "driver", + "net/*", + "physfn", + "sriov_*", + "virtfn*", + } + + ignoreSet := newKeySet( + "sriov_vf_msix_count", // linux >= 5.14, write-only + ) + entries, err := ioutil.ReadDir(root) if err != nil { return []string{}, []string{} @@ -96,6 +109,25 @@ func scanPCIDeviceRoot(root string) (fileSpecs []string, pciRoots []string) { fileSpecs = append(fileSpecs, filepath.Join(pciEntry, perNetEntry)) } + for _, perNetEntryOpt := range perDevEntriesOpt { + netEntryOptPath := filepath.Join(pciEntry, perNetEntryOpt) + + items, err := filepath.Glob(netEntryOptPath) + if err != nil { + // TODO: we skip silently because we don't have + // a ctx handy, so we can't do ctx.Warn :\ + continue + } + + for _, item := range items { + globbedEntry := filepath.Base(item) + if ignoreSet.Contains(globbedEntry) { + continue + } + fileSpecs = append(fileSpecs, item) + } + } + if isPCIBridge(entryPath) { trace("adding new PCI root %q\n", entryName) pciRoots = append(pciRoots, pciEntry) @@ -149,3 +181,19 @@ func isPCIBridge(entryPath string) bool { } return false } + +// TODO: make this a real package +type keySet map[string]struct{} + +func newKeySet(keys ...string) keySet { + ks := make(map[string]struct{}) + for _, key := range keys { + ks[key] = struct{}{} + } + return ks +} + +func (ks keySet) Contains(key string) bool { + _, ok := ks[key] + return ok +} diff --git a/pkg/sriov/sriov.go b/pkg/sriov/sriov.go new file mode 100644 index 00000000..f29c6d8f --- /dev/null +++ b/pkg/sriov/sriov.go @@ -0,0 +1,113 @@ +// +// Use and distribution licensed under the Apache license version 2. +// +// See the COPYING file in the root project directory for full text. +// + +package sriov + +import ( + "fmt" + + "github.com/jaypipes/ghw/pkg/context" + "github.com/jaypipes/ghw/pkg/marshal" + "github.com/jaypipes/ghw/pkg/option" + "github.com/jaypipes/ghw/pkg/pci" + pciaddr "github.com/jaypipes/ghw/pkg/pci/address" +) + +type Device struct { + Interfaces []string `json:"interfaces"` + // the PCI address where the SRIOV instance can be found + Address *pciaddr.Address `json:"address"` + PCI *pci.Device `json:"pci"` +} + +func (d Device) ToString(devType string) string { + deviceStr := d.Address.String() + nodeStr := "" + if d.PCI != nil { + deviceStr = d.PCI.String() + if d.PCI.Node != nil { + nodeStr = fmt.Sprintf(" [affined to NUMA node %d]", d.PCI.Node.ID) + } + } + return fmt.Sprintf("%s function %s@%s", devType, nodeStr, deviceStr) +} + +type PhysicalFunction struct { + Device + MaxVFNum int `json:"max_vf_num,omitempty"` + VFs []VirtualFunction `json:"vfs,omitempty"` +} + +type VirtualFunction struct { + Device + ID int `json:"id"` + // Address of the (parent) Physical Function this Virtual Function pertains to. + ParentAddress *pciaddr.Address `json:"parent_address,omitempty"` +} + +func (pf *PhysicalFunction) String() string { + return fmt.Sprintf("%s with %d/%d virtual functions", + pf.Device.ToString("physical"), + len(pf.VFs), + pf.MaxVFNum, + ) +} + +func (vf *VirtualFunction) String() string { + return fmt.Sprintf("%s index %d from %s", + vf.Device.ToString("virtual"), + vf.ID, + vf.ParentAddress, + ) +} + +type Info struct { + ctx *context.Context + // All the Physical Functions found in the host system, + PhysicalFunctions []*PhysicalFunction `json:"physical_functions,omitempty"` + // All the Virtual Functions found in the host system, + // This is the very same data found navigating the `PhysicalFunctions`; + // These pointers point back to the corresponding structs in the `PhysicalFunctions` + // slice. + VirtualFunctions []*VirtualFunction `json:"virtual_functions,omitempty"` +} + +// New returns a pointer to an Info struct that contains information about the +// SRIOV devices on the host system. +func New(opts ...*option.Option) (*Info, error) { + ctx := context.New(opts...) + info := &Info{ctx: ctx} + if err := ctx.Do(info.load); err != nil { + return nil, err + } + return info, nil +} + +func (i *Info) String() string { + return fmt.Sprintf( + "sriov (%d phsyical %d virtual devices)", + len(i.PhysicalFunctions), + len(i.VirtualFunctions), + ) +} + +// simple private struct used to encapsulate SRIOV information in a top-level +// "sriov" YAML/JSON map/object key +type sriovPrinter struct { + Info *Info `json:"sriov,omitempty"` +} + +// YAMLString returns a string with the SRIOV information formatted as YAML +// under a top-level "sriov:" key +func (i *Info) YAMLString() string { + return marshal.SafeYAML(i.ctx, sriovPrinter{i}) +} + +// JSONString returns a string with the SRIOV information formatted as JSON +// under a top-level "sriov:" key +func (i *Info) JSONString(indent bool) string { + return marshal.SafeJSON(i.ctx, sriovPrinter{i}, indent) +} diff --git a/pkg/sriov/sriov_linux.go b/pkg/sriov/sriov_linux.go new file mode 100644 index 00000000..0d03596f --- /dev/null +++ b/pkg/sriov/sriov_linux.go @@ -0,0 +1,128 @@ +// Use and distribution licensed under the Apache license version 2. +// +// See the COPYING file in the root project directory for full text. +// + +package sriov + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strconv" + "strings" + + "github.com/jaypipes/ghw/pkg/context" + "github.com/jaypipes/ghw/pkg/linuxpath" + "github.com/jaypipes/ghw/pkg/pci" + pciaddress "github.com/jaypipes/ghw/pkg/pci/address" + "github.com/jaypipes/ghw/pkg/util" +) + +func (info *Info) load() error { + // SRIOV device do not have a specific class (as in "entry in /sys/class"), + // so we need to iterate over all the PCI devices. + pciInfo, err := pci.New(context.WithContext(info.ctx)) + if err != nil { + return err + } + + for _, dev := range pciInfo.Devices { + err := info.scanDevice(pciInfo, dev) + if err != nil { + return err + } + } + + return nil +} + +func (info *Info) scanDevice(pciInfo *pci.Info, dev *pci.Device) error { + paths := linuxpath.New(info.ctx) + devPath := filepath.Join(paths.SysBusPciDevices, dev.Address) + + buf, err := ioutil.ReadFile(filepath.Join(devPath, "sriov_totalvfs")) + if err != nil { + // is not a physfn. Since we will fill virtfn from physfn, we can give up now + return nil + } + + maxVFs, err := strconv.Atoi(strings.TrimSpace(string(buf))) + if err != nil { + info.ctx.Warn("error reading sriov_totalvfn for %q: %v", devPath, err) + return nil + } + + virtFNs := findVFsFromPF(info, pciInfo, dev.Address, devPath) + physFN := PhysicalFunction{ + Device: info.newDevice(dev, devPath), + MaxVFNum: maxVFs, + VFs: virtFNs, + } + + info.PhysicalFunctions = append(info.PhysicalFunctions, &physFN) + for idx := 0; idx < len(virtFNs); idx++ { + info.VirtualFunctions = append(info.VirtualFunctions, &virtFNs[idx]) + } + + return nil +} + +func findVFsFromPF(info *Info, pciInfo *pci.Info, parentAddr, parentPath string) []VirtualFunction { + numVfs := util.SafeIntFromFile(info.ctx, filepath.Join(parentPath, "sriov_numvfs")) + if numVfs == -1 { + return nil + } + + var vfs []VirtualFunction + for vfnIdx := 0; vfnIdx < numVfs; vfnIdx++ { + virtFn := fmt.Sprintf("virtfn%d", vfnIdx) + vfnDest, err := os.Readlink(filepath.Join(parentPath, virtFn)) + if err != nil { + info.ctx.Warn("error reading backing device for virtfn %q physfn %q: %v", virtFn, parentPath, err) + return nil + } + + vfnPath := filepath.Clean(filepath.Join(parentPath, vfnDest)) + vfnAddr := filepath.Base(vfnDest) + vfnDev := pciInfo.GetDevice(vfnAddr) + if vfnDev == nil { + info.ctx.Warn("error finding the PCI device for virtfn %s physfn %s", vfnAddr, parentAddr) + return nil + } + + vfs = append(vfs, VirtualFunction{ + Device: info.newDevice(vfnDev, vfnPath), + ID: vfnIdx, + ParentAddress: pciaddress.FromString(parentAddr), + }) + } + return vfs +} + +func (info *Info) newDevice(dev *pci.Device, devPath string) Device { + // see: https://doc.dpdk.org/guides/linux_gsg/linux_drivers.html + return Device{ + Address: pciaddress.FromString(dev.Address), + Interfaces: findNetworks(info.ctx, devPath), + PCI: dev, + } +} + +func findNetworks(ctx *context.Context, devPath string) []string { + netPath := filepath.Join(devPath, "net") + + netEntries, err := ioutil.ReadDir(netPath) + if err != nil { + ctx.Warn("cannot enumerate network names for %q: %v", devPath, err) + return nil + } + + var networks []string + for _, netEntry := range netEntries { + networks = append(networks, netEntry.Name()) + } + + return networks +} diff --git a/pkg/sriov/sriov_linux_test.go b/pkg/sriov/sriov_linux_test.go new file mode 100644 index 00000000..49f90131 --- /dev/null +++ b/pkg/sriov/sriov_linux_test.go @@ -0,0 +1,198 @@ +// +// Use and distribution licensed under the Apache license version 2. +// +// See the COPYING file in the root project directory for full text. +// + +package sriov_test + +import ( + "os" + "path/filepath" + "strings" + "testing" + + "github.com/jaypipes/ghw/pkg/option" + pciaddr "github.com/jaypipes/ghw/pkg/pci/address" + "github.com/jaypipes/ghw/pkg/sriov" + + "github.com/jaypipes/ghw/testdata" +) + +// nolint: gocyclo +func TestStringify(t *testing.T) { + info := sriovTestSetup(t) + + for _, physFn := range info.PhysicalFunctions { + s := physFn.String() + if s == "" || !strings.Contains(s, "function") || !strings.Contains(s, "physical") { + t.Errorf("Wrong string representation %q", s) + } + } + + for _, virtFn := range info.VirtualFunctions { + s := virtFn.String() + if s == "" || !strings.Contains(s, "function") || !strings.Contains(s, "virtual") { + t.Errorf("Wrong string representation %q", s) + } + } + +} + +// nolint: gocyclo +func TestCountDevices(t *testing.T) { + info := sriovTestSetup(t) + + // Check the content of + // GHW_SNAPSHOT_PATH="/path/to/linux-amd64-intel-xeon-L5640.tar.gz" ghwc sriov + // to verify these magic numbers + expectedPhysDevs := 2 + expectedVirtDevsPerPhys := 4 + numPhysDevs := len(info.PhysicalFunctions) + if numPhysDevs != expectedPhysDevs { + t.Errorf("Expected %d physical devices found %d", expectedPhysDevs, numPhysDevs) + } + numVirtDevs := len(info.VirtualFunctions) + if numPhysDevs*expectedVirtDevsPerPhys != numVirtDevs { + t.Errorf("Expected %d=(%d*%d) virtual devices found %d", numPhysDevs*expectedVirtDevsPerPhys, numPhysDevs, expectedVirtDevsPerPhys, numVirtDevs) + } + + for _, physDev := range info.PhysicalFunctions { + numVFs := len(physDev.VFs) + if numVFs != expectedVirtDevsPerPhys { + t.Errorf("Expected %d virtual devices for PF %s found %d", expectedVirtDevsPerPhys, physDev.Address.String(), numVFs) + } + } +} + +type pfTestCase struct { + addr string + netname string +} + +// nolint: gocyclo +func TestMatchPhysicalFunction(t *testing.T) { + info := sriovTestSetup(t) + + // Check the content of + // GHW_SNAPSHOT_PATH="/path/to/linux-amd64-intel-xeon-L5640.tar.gz" ghwc sriov + // to verify these magic numbers + for _, pfTC := range []pfTestCase{ + { + addr: "0000:05:00.0", + netname: "enp5s0f0", + }, + { + addr: "0000:05:00.1", + netname: "enp5s0f1", + }, + } { + addr := pciaddr.FromString(pfTC.addr) + pf := findPF(info.PhysicalFunctions, addr) + if pf == nil { + t.Fatalf("missing PF at addr %q", addr.String()) + } + if pf.PCI == nil { + t.Errorf("missing PCI device for %q", addr.String()) + } + if pf.PCI.Driver != "igb" { + t.Errorf("unexpected driver for %#v: %q", pf, pf.PCI.Driver) + } + if len(pf.Interfaces) != 1 || pf.Interfaces[0] != pfTC.netname { + t.Errorf("unexpected interfaces for %#v: %v", pf, pf.Interfaces) + } + if pf.MaxVFNum != 7 { + t.Errorf("unexpected MaxVFNum for %#v: %d", pf, pf.MaxVFNum) + } + if len(pf.VFs) != 4 { + t.Errorf("unexpected VF count for %#v: %d", pf, len(pf.VFs)) + } + for _, vfInst := range pf.VFs { + vf := findVF(info.VirtualFunctions, vfInst.Address) + if vf == nil { + t.Errorf("VF %#v from %#v not found among info.VirtualFunctions", vfInst, pf) + } + } + } +} + +func TestMatchVirtualFunction(t *testing.T) { + info := sriovTestSetup(t) + + // Check the content of + // GHW_SNAPSHOT_PATH="/path/to/linux-amd64-intel-xeon-L5640.tar.gz" ghwc sriov + // to verify these magic numbers + + for _, vf := range info.VirtualFunctions { + if vf.PCI == nil { + t.Errorf("missing PCI device for %q", vf.Address.String()) + } + if vf.PCI.Driver != "igbvf" { + t.Errorf("unexpected driver for %#v: %q", vf, vf.PCI.Driver) + } + + pf := findPF(info.PhysicalFunctions, vf.ParentAddress) + if pf == nil { + t.Fatalf("missing parent device for %q", vf.Address.String()) + } + if vf2 := findVFInst(pf.VFs, vf.Address); vf2 == nil { + t.Errorf("VF %#v not included in parent %#v VFs", vf, pf) + } + } +} + +func findPF(pfs []*sriov.PhysicalFunction, addr *pciaddr.Address) *sriov.PhysicalFunction { + for _, pf := range pfs { + if pf.Address.Equal(addr) { + return pf + } + } + return nil +} + +func findVF(vfs []*sriov.VirtualFunction, addr *pciaddr.Address) *sriov.VirtualFunction { + for _, vf := range vfs { + if vf.Address.Equal(addr) { + return vf + } + } + return nil +} + +func findVFInst(vfs []sriov.VirtualFunction, addr *pciaddr.Address) *sriov.VirtualFunction { + for idx := 0; idx < len(vfs); idx++ { + if vfs[idx].Address.Equal(addr) { + return &vfs[idx] + } + } + return nil +} + +func sriovTestSetup(t *testing.T) *sriov.Info { + if _, ok := os.LookupEnv("GHW_TESTING_SKIP_SRIOV"); ok { + t.Skip("Skipping SRIOV tests.") + } + + testdataPath, err := testdata.SnapshotsDirectory() + if err != nil { + t.Fatalf("Expected nil err, but got %v", err) + } + + multiNumaSnapshot := filepath.Join(testdataPath, "linux-amd64-intel-xeon-L5640.tar.gz") + // from now on we use constants reflecting the content of the snapshot we requested, + // which we reviewed beforehand. IOW, you need to know the content of the + // snapshot to fully understand this test. Inspect it using + // GHW_SNAPSHOT_PATH="/path/to/linux-amd64-intel-xeon-L5640.tar.gz" ghwc sriov + + info, err := sriov.New(option.WithSnapshot(option.SnapshotOptions{ + Path: multiNumaSnapshot, + })) + + if err != nil { + t.Fatalf("Expected nil err, but got %v", err) + } + if info == nil { + t.Fatalf("Expected non-nil SRIOVInfo, but got nil") + } + return info +} diff --git a/pkg/sriov/sriov_stub.go b/pkg/sriov/sriov_stub.go new file mode 100644 index 00000000..943a2710 --- /dev/null +++ b/pkg/sriov/sriov_stub.go @@ -0,0 +1,19 @@ +//go:build !linux +// +build !linux + +// Use and distribution licensed under the Apache license version 2. +// +// See the COPYING file in the root project directory for full text. +// + +package sriov + +import ( + "runtime" + + "github.com/pkg/errors" +) + +func (i *Info) load() error { + return errors.New("SRIOV load() not implemented on " + runtime.GOOS) +} diff --git a/testdata/snapshots/linux-amd64-8581cf3a529e5d8b97ea876eade2f60d.tar.gz b/testdata/snapshots/linux-amd64-8581cf3a529e5d8b97ea876eade2f60d.tar.gz index 83cba8a09f622f96e1e736adc0b1d345728922e5..2052b9c7f754c1fba1f5dbce399f6355f260d254 100644 GIT binary patch literal 49927 zcmb@udt8k9`#+rmu*Yz59 zuxS^=e^5`Y@vQtIH1;$3!*{EiJh+p${$XOa{QS}4u;11cUP_sfBHUi1s2@A%`|mzq zc-o&NTa$)oDv;-=fKC#}q#3Uc{R z&o^*v1PR9-J;Dd_w3A(TMJC3(yipBV=b7OAMeta=ZE-$2vN1dSNvd`MBl zx%gVGm`AsSl&zvC=YC!wr{F+iln@#upxT)9txUQ7fHKHwrh4Pj-UH$*cHXDIuTFR2 zp4Q3*u)}|ZY?3;EpmO7CGp?}go>r{otdaE$EF<;Jnff;2y}@5rmQ~*=VF~NDJ3Dei z!%5}FY3t6(S6Oo^wP#~tQ zF{$5*-0Mzc!s)ylHWL)WX6@>>OocLxw4dM}Dkq#piUaDi_iVoPRcH$EusnMZ#3 zfGylf<9suN(yMN@*7psU> zY0s*zcu{fAt)W5>iWH};SFJo-roUA`UN9~w%lmD(eQR};&o*xCf#Ce@wh`*5XUle5 zua7-ZTjxQ!oXBcw^Kh9EYZ1SV>*6xrcU8<5?vgx9?$-Dv-09&VzO0yHKkLX+zgkBz zdwMw6zNIb&!ihWZRcdCPh(p^>;sj?K_qFZIEM8ETv zw~BvX>tFkua)lz`k$qm>L+6DD3UAbW5xl9e#4pS;dw=Uj%7ra#uWjz1GhmBt@hk9H z;rM(m|6&=}-oci$-rhOydS$LG&6!N$4BPo&s7qcfKTLYdOF(~X5hE|7uGd*|E8UaF zgvHFA>ik=jFg!)2cC(*AIG4_(|J7UO6?WDmb#QI~uPs#Rk+}9;n7U2QEv-%n6Bh1V z;^N|eVSsQ8cjqc`+OwaE*U>IH+|ab`Qy(Qqygjw5aMuIv?x`sk9B*l~F$-Q=-P z+12q9;au+0g~8z-l#jiCdsD+}S3%|7?CS$Ac-LDwJ{=xEqjlhEyP-bkPTIA(2K3ui zwI_N~%h2D3x1 zk8ekb4y_6C^({Kva6z?ssPDA4F@t=6&pYsP*&yFOIS0yy`?ifsOe}l%N7R<8p52&KlX)d*PRN-n7LBP6fp7fE55?{krCLbKGt(WOmG}25 zi%Q>RKe4@jkngnC-8D-lwLZC|_7i(}Zq+*|oP$F4N`0S3M!X-@C!}Wzj_M}57`$LY zpP6fqMJ6hT_x4a83QC^PX7_4edU{Y`$eDD*RHc69H)Cf8PY})>V8R}cOS<&g)YrKt z!{u*0!)8i%?eAm1wkPk#WOnpycl#!1apaaT>Am2ALxpN0@G zu~@oE)3Rsgj$PX)#RoJ*@0&M|!>L9qX=l&#jyCglspjf{HdTZS8|F zg-l|hYzWb9v%auA25y@dZdac18c=-Tg--iM>#VAj;Ls8Cdp@hKq}`UD#EmYf^?z3o z{FdbxN-A53P)k+ZaaEbW@{Lo1SApcAB#-kvYj=RUPS})3gw{%evuf0vme5nyjccrq zk%{yzuFVQB8>yUqDw>_SuhxsB*S_JHN8Mpx%H2W6K9#QHc~Wm0gJ$|Ku*i!1J~j2B zMZXY!+E95*VNf{N#ane(@~BBHrG8R;My9OGNpLyO=iH!GEys)I`rFgn{T`^(DChCd zE9%6XBJIL*q&MS>W5jRyA^i2PpCo1f@F;aF>{711=$4e*Gh9@>T`!4%FloE?C%1F! zGjxzVPF)Yd<=1H0+2Yc@59;3yoT?P$Sk$hh`pbsNNYhYGs90F0X%XI2x0hroD5>^{ z?~2p9g5s9g!K&!^B|Z{f-t!=j*PL^eo6;`JFGLnQe^GmhOQ&c=@6_6mLBFYEp85H| zz~_851!a})_6KG@4QOlp%E~8_D&kF;5TkPA1Pq_XdlP(>xNz#Z$me344axgDJae3| zqV&K_O>5yLcz9u41OfXL;o`3qTKPJAPT8UZCS^+PWIx@!c~Z(x)p|uPv7#why6FWk4{^Z}9O0&rGW8pa_^hz0~N&RhmlX8h)O$m>@@8T6EEO(;ydrSm!;k|qt zKWZbFEQ@L8_71quCh8umlLj9p`&+Z`(-GnEuQsO*UKinXV*3G7nW+sc^WpogMh{UD zW3_e7>6qHmOdDBnw4m1CUs^KK&FkEO!3)T^5asc(=35tCoK}W~Z}^v2OmU@5Gd=XA zy|0)j8CT8QMN&5LDTQtYyyXR&O%E^LapGlVD!C5fbC;7Yxk8m~ZTzs&7fOceYqQlF zGg6nDEcf@{C!@C z*9*&pJI*-Wm$`XOy`at$gRQ%p4cN_$auVWFn=fX}1zEKBj4wPCVw z3H`|HU20-@q-4A>D`~yRWykdxOOD8Vom1FVj^o$yn>VETUbxn(xRozcxs~Nyun}nX z2MqH4RW&SL|MJ-x_+q1&JcB93*2yj~J8rlq|0(+MVZ)=+Rf4xww~51HT3(1bv9~qW zMkVs}p)Squ?^)!@ChVQ$BA)wcHl*F7IfCei;jU9|31V)--LkQAQ2Ev++s=#9T1-_D zMZQ}oL4cFLP4-XA;r4Yp`vCtoh!xvj=2~5RMckPIY&j0$BtbK(sTo+I65aEY>k0Ns zIjMejUK!0HiYu~ZM7z^dzbUeWcK&ylziqdnz^0ZHyy<0bNguvIMVGgePt?z~JWlC8 z-`+2JaKN({A2xX3f&+dH^|%hTwI}YLTL*SU!zujRY0}v^+O+KzY&rZOav8gF;6@o# z`-^vUT~@@Re$G-ykHR(ZYDCitDb4J9gdKRIu{T+-rrkLHSrkX58*EGe{k zrWLG*U~iSvlS<=XYsm2La|HM4U6Rpq@&@gYBrLl@A5W$4ly&}Hs}VGWZ>A)%WWODH zwRwM;K#G5|3W=BP3PtZ%k4mN3rG6ikqWsdM2)k_C2MAEMY+J3kPX&1$)YK61*gR=$rBa~VnEUiMPi7WUpf;#2SSC{-!&*1uny7d;>ZIws7|!}FlT9U2|%{n1y=dGN0Jy;{D}aO`Qr z&{wqCGay)OSTW3__?22PQIkoJ?B5s_I1+rDG$=lqMqq0qXXgWv3X%krri58yII#U_ zSYS?zin`+3ClUmqy z<0hG^gLg`T0_&l-$%VkNqYDh9pfyP=nU9%eYC1n=WG^T1&1tLQXIkK=@7NcLB>Vk< zjI2L=EM`{Qbc+tId*nPWB;ceYRj}NJ4BsqQ!jh`9(^sR9;jx^zPsmnE?*@FHA?GF8 zxl#R6*TDR#(~GPIzmjaeO&sx8S-Mx-WNlK-nY#YB%27i{rP4{F$wln+D_YB#%80Ja zW1%XC-8X3UiaqCCr`&`Clt}9(D$`2(#JCQ}$G0WBKs;RbpZh~F zbtsHXT>(BTW)77z?%G-nYoM`s6~xqLE{WCI7i`uiM|j zXKmzA!jg@u%)2KfJN4?*s-QSN{o4?F;WyA9u!x<3D{~&E8rZv<>?I}#mfZkK)h{IfGM(hKhV0=hCvcnW(_Y;Z)Ag3>RQj`u zTrFopke9>sd4XED)0&{T1Ug=-l2+ZCUi8Vqo=PIj3i`Gck@hzygk`6E@@fQ}7Lya} zW5C-!_4cs@hZ*zEYAp2mvoaMLuRh&3xv8{G;M>+e9Ec4JcVj5l-3%{8JLa+Y@#E%kdi ztzCNT#btW_QzauWPH6D0X~){(`#|kFp@uk;rV?CYab?-eQj}WDWBw{Z%CMDT37O|b z6%SiFcl9}--s+G%C`)M@r^>XOxM;#isr`aC7I zC`J|eW_?t=>k+YJMk5@o2-gbgV?FA<*e)>IaT-16H3u-_h7@$O#`BNdO|xb%24zL! zPuIG|5^F+7bH$Q3r7}T5{P3#q8>w`4`ewOWH?nQW$R)p2L9?nl`$n$dnU|h*b|RSO z1Uj8`(?0m>8Tp{yEynegOrm%T>Kvj+_$1xMU#m#FAzxMsEA;Np?h--4lgVIOomp2vX?wGBMhw|iz3F(fFqgBYvZpXt zGDsF5bLCm+9M^AM#!VYJTEi=IJRz*z`KtBvS?zj4cfwgo-3>;0u+Ea1Hyynt zuA6%XAGpiv5Bqgf zw#`d8)uLZe$G!#@xWv=G5Hs%#jG+jPp4CIkN&dBp_z|46yuNL1Fmz}QTzCP~zaFg# zc?oA}iym6``v*9EU&AuvGM-VAk#P|1Ue}@+rGm}iV0KtbQ0W_Wq&Z^B7uw7=jN0sO zYIwCp(+!XN7^wd8eY7-@2UW(!I!!d@^?8D_+JS;{(#q_OSdBk(5 zRFS5wz^vjNH~_oz#k(--h`EZejE)~|)Vlb3_;h3{Jpw{>f{t?!)DsH;choUgvxZ=X z8ug4kN%LAsD@J@qA**4;PA&Q6Lcz-KH6i&h*%h36oYCT8KWk zHe@~>)e2Q~2yYDQyToEi;Fv}B8hG_8l5#%HfWuR|2EZ&?`Ftpuk= z=z%_O8qJb1>Rf|E52RUYG9#{;{P8+x?C<(YiuZP!mM|Ty3aLPxVPWR}_%3HMDqAyI z1G6tf6prfJPP~O)nJyr6Y9;UE0{#U-xQiE%kMmpU*^O}c5FNs7j~QZsSu430rw?9D zJ1qi}LzihM@&_A=2sZ@n+!}H=9?UJ^%!ALm=?oTjnI=!GVdQy}@aZnymoM<9M^fOt z3j}r5bz>x5q#9N%aRWHdQ9Mp49yH1It)MJX5^h7$NEb>}X9J4Zt#@kIi4*2aw))Sg znNi?%+BNeg9^+yVoTLXFSr0qXhWoV&XuXU8%`=$vG!7)+d~W#u90enc78jFe4UuY3?Sv_hqx-CZP2Mg_S6yeR0EZa1)uT7p&|7QB5wso6WA`d;F?T&!mm zrWem@*ARE>;ozYPv16v*Nnx%Qzua-KcQqt!p-0B4qTL5qll%SC{>3r9Eh6t-f^jnR z!sBcXF2ScQR|Ws**DEevLkMeOR=I{_(_1OHc<033y`S`rBxQ*(q~}BO6+S58aGtY! z+(h4|B4smmg4uC5E62~unj(U&pYFC@vy!zh+mry`uof-5$1x6C2RCleLUejO$nmCF z-PB~hqc@E-=7GVj%3X(fu(xRDOr#2Smh4viy7rt*u#wvJht=RhqU0v|@|n#+6?Z8) zz~kgRmD9sI?gg0e(`u6Kanf9+E~yl3p;Jc0(X%V*$=9FJoIyO8)psrVn&!MkEA8|K z%^FLCnWFn_0BIr&UFnV;~G>o2+PAFghgD=D_0 zF(=X<#Vv3MRrO1!Pf#)ox&wPRSwFI`VFZ^Ejqa1c0TM=<7{0C+H=B0ZM}} zyS|Z5kwCBxPX@=^776ZZc+QA3lg~JPoK{7Av`eoxa{GPt596OJC2=&)Ce2+$rQ{!4 z1Li86fZsq##wjJA^p;B~n$sc2tF)uKe9Bvpr+j^%#{cy$+eRfp7)CM?C1_K+D@8MA zUF;XpZ3h3oc5D7j>1VGV$M`EmG}znXpFE zN1NArsj_@`T@M*gM>fbVRg(&ub4*8W8#xW$!VW?)1sv-j6~dCj{4Zd5way(X4;hh) z%h_S6xKG=K$x*Dz5=)`{mr}uC4col9MPQ~Q_kXt=ms%2FSaCSB02yIev5c6~|2*jo z;s`m}i$IXWe>4#UIdnqM_1Q(PV2K6{-c(yz^Gz;S$#u5!LlH#Fvdxd5)l6KoVlybs|kI&Sj zYc0vp(n*^U3mSotkk}wElBAg1Xx_%sLlV}GtsPpg)**j)I3_!5pGk*DIc#}R* z@8ksi5f#s--R5Dq3JNg9InskN!SKt74dp7sz-$bdQgW>eIJ~$@bJS3u2RUoVKM78B zQb&IEw^Dm9*wtosdLyV6p)a)Ypc|4}pe-=0su=tUg*CJiQ~O7fZ6v7-_6uU%woags zT`J-km6BHIeE1p}&0|d7@J%((fYe0HH_;mIQsC>z>G@WN<%*pb@6vrUi)=drC2!r8pyw6tSzxm(X!AczUU{2?Go>l&m*U z@B+T?>x@x;{$Gmi-?i;Rvz9n)u7YH63!*L5aImin`3pSL5Ivp~Mm=qPYd8ix8_M#7 zlFG=D%$aSV&zfgXtOvUE^R~?SY{X0* zLQ}vjT-F~@g}zzJHm<7r&q70~%1A2|8sduH=LD->Rg)zUpEO^iH|e3=FzIa5nb?)1 zHQdYkw6EIrTu(Oy>xX@sj&IQxe)XJ8Y*ByO-;c6*#?g@_EfT-gzbT8qYG3qf_&FJ8 zDfE0U8C#c43Z~L-+cFSIq?Etr51LO88AI}KFp-pVb`5&{9M*mP6vS-ZrHU^eXe4d0 zGxB;p^w=ndb$k;xMeKN6{tP_rQwCq$X*;DCC0O>|85~(OHbVwJ?mjRegO#d_8O#jJ z=9@-BiCw%OJ>;-YTm+0o=+*Oi_Sib5z!xm8!Dol)AouMp+_R&0rfkO`JYRW^;*2z{ zV`oE!o^{w~Vt0hiuQ1(YuogMuya_MyOs)9D7zU&5vnHxwxn}pnF_yw5Ry%dQ7e|uw zsT4K&5M$EIBO-EE`4c9A$ZjIdD1@OT14D5f^q@LDTOI8HZn-g(peF{ISHDydCm>Vz z0Ud@^C?%ax(dj!3x)i(gl}tcA^hJ-9*||stSF=lhXkll;6)@RY3DXcyGPsdI+*p2` z!(0JV_8x?^Y) z)W|k1JCY9i(lF0%U<{Oz$2l5#Im0O!zIXx0X2BereHzQ(TjAMBn^vMP9!4g_A&-K{ zbn=wQu)X*3ILu&FrBZ;2aY~b|Aq%UZ$TQQSWHa*nJ?i>gX?c@W)1o#NjEhHp zY4vI97B1}=oNdPFrX`ql9)`2FWe^l6huh-75ISV4ds7ummSYz49b%y2hFm}L+bnnP(;x7k!wI}s`W=-AN^Pr>93 zNM1b0>Tg%t1YN0k>J;@R=bG=$OPH+e{r=xFL_g z0Vs^f2=#f8sFJZaNYoxZ)R#Yj-ee zxkn>L=Jy$hw>_#0{!!OLoGb)kKFl6*0}9xB3)hR(#3N$D%ifhjKPNbDw$hiDv|akxtw|}_u;j71)bZ|^ zTlvy^np4jvR}+aeQ^`3xY}8I#A+8jx3xNpma*EgTI%_-Ws|LG}Zl19)@;)Cl)qrxw-+G&mmLclkL5erQM0MZkzn<&%DS!7zln|!7OPbE zcK)s|+O%B^jr*vyy9%0Sf3@1--~zIAZ?o$G`*GD-E2hS-#V7ls>tPKq%X2T7V9)lXOHNJSp)svb-8?D$%CO^2IotK(=P|QPB{-Lt!Xlzl5FWy zQ>EvWg%uQvQ#@1}$s_vgnl^a)Vk2c4EDfuTTS9sA^5JmP@>`mnc8?;)2{*?0)^Znf zNP$1CR?r%Wmj^9VlF7AO_2laH6He6To;6?1g9a7(kd`TCfTBlOO9eZ3?-?lBKIL11 z{RC$onJ^i=-eL+ZhUD7OP}q9Fx%92Q?3y*WTRfBM^ znZJhTCnvWG`i|QgvkAN4vJz8Vdx#+QZgrXhj+hqpE5~TFx5ZVP`+yfek6v{#9wzq` z3W-~_<{;g?pW}QgOH6tdk!vz2$%x%)(c$hbgzvtSP5S7vR4_w>tVtOnOhhbo$K20MJLnPNu0Oh8;w^kPJd{eIFMkcEp$<+SSbYe#@4IJn{ z#tts16#g_UD%ZH!luF4p)Pj1lDupI^aIAci+u0+52Ukwdfm^HX%&*%+?P*Xos=>!% z+F7&n0cm?LLiFQTQi+dHNshK2KskFf`%xl3xR%b{%7%z=eeDfC2`$kg%Poay4;!=r-N^z_UJ)yPO1? z+^nO`A#dEa-zjY)`a}ED{S~!jfCz{03!XC|38Upe7agy09TcS1lF58pMy@PK2`bw+ zbwb#X&(0GSVcUO z_yXT6V{T;oZ1?zx%7Z^n&k?+Zw<WnX>1>zwE~?MoMHX z=Z%yqtMiiQk5H#fkvZ_fpAVCoswITkW50GsGnGeEu@qoR(Vt+YL#Y z89Fy*LE($n(ifwDt9Ym1YnlhG?n|8)xkW7vIN78TJYa}4R_Mke2FX~U8?y?pc|7jCKN6M*P+m+k~ zxxVCWi-voEE78;kw!T-09-fpEPkq5%{NJ)Se1VJr%o9}g)Ez6 ze49bakxIq`GH6e5sHOP?Q@M!ul7RFQVw)85+Yj@2LXb`nIFThkPB?VA^GZs#-o?6j zuR2Ibq6Nr&P>}3k034W%=L8NKELt!fC4>-g4kOIn10tQe+?aa~OzDujL3&{ z6^?ecNy|Fo06|`d80?D3Ye=494TlYD@CFM{`WIMM)+dIIwJ1}DYYlsaFf~&}^lW?& zI#VI2LoNstjX*4<6Nm-r2zRP~wtiG6MzvMLkxsF+GbIPar$Ta243hkC$N*n_d(;lX~n|riFDA0;S1}0 zKAAPXLcCMC5L2$R8V2mC#7BMVRBIVUBm9TyOJB zI%ZuBr0ovFau_xc$GvS0C3IN4`4#9@fmNrcRCB)S$28weXc1nqdJDDZObxSRN5dt2 zt9WiGJEu=oz>p0x|NdX{QVt)5pN6jVDGO#2nQP_{;JH&lYY< z{B-e&(NGWjo@>13FP%i8ehSe4zjX(TG6;OULxWbpqj-y^A?wB{VlmY2RSMi7Y_z6e zh#KP2k$hqKWklaI`gka)twzFg->7GVj=1Db=VpGwqnBbPP!D^bBd=n4@um>=-KIE8 zk#U;E*o6t&g*6={9W~5o7MLY5X0iWq>yEkSNI!^v}`I?+K)qC{FJR*&YzWB)^yisF`{d1H`d}@dVR@*D&9Z`(gc{!zNM;Ho4GPBY17jyKq-Bf%ePIXk1v>n z?EzMD(&c1Kcc8v9Lv>+j3aX-$yB@L;>rN+GC&RD?KaNXU~dLF@<5P5H^$d zeuEshR!rKg4=&4Hq9ndmsE0)%!dgi$%cR&=t98ehb;%lP1BD)|$IT0~lpoAyaI>r) zjv(ugFBnjBthq}#sYnpPHm1IQb?AyLY16~=W#`gbV0=)FaIQv_;*s?3@#RB(TF5oy z1Pg;CL!)TDz@M@a&cu{8`3Cq|59cfjl{VEbU(A7qW$N<~4m90fJFr42uygdL*xkfrvh8+S?X0ui z@sL&`!QWlU53j5iMC3FE$5`=U5>&0<{Z=n(8$QYo=7;VAsb3Y-Lr=M zGHpma3U-?3uO;W=yWBw;#%$uu!=hqpDKb%nsZ)Y~OIh2g5$e_*9(R>z%583PRTZhd zkG{L15tNu-o{@cHCPdE=!^?BD$q^2zCx8-*iUQhIVW3qA0<75q*t?<^hY09erN>@G8ZuMC{o^&1I^tqvub``o}{bomf`Nig<;~m8_7G`w;6yaG0haS^BG+;wPmD3l~{k?6cXx{z;@N9DH zGteT?I0JGUjc~ZnOa@EC5Xp2sv0wUs9~W;HjN{RL0>Dz9>JY(4O3Q6 zTOIiwI`m^8O@aYEl^gDecK1D+u=#M5G zq9$+e^P{^P$r_fLjId%lIGV|T=eaFX{&0$?Qp6rJU)SfkQku``he9!Ify9M)zx z5uazO*q!Ud*pcxR%7=}3V365mtg2W9bP#)(qI8}Cl8n9-%jv^${*SG~RRej1wBUap zs2K!`V8d%%ITCFQL}Rq7=?R}Pq;@v;M15cn^{kD2_!YUq_sk;pfc%MBWLQFM9$+zS zX4=t>7u%5*{A<=NmYe@!;E`kAn;%^<&5s4Uh zTFfTwni*R~&K9%bP7`EoRZi-E_&@7Yr@4w41kM;V+CVBD$O!m?LBN^t2R2!JL{($= zhCw9h5QiQU`yDDR-XHF4=>L(t-k${W)>uDeEH(_PTy^X%nY5*3{9&w(35#osc!uLb zD2GUJ$QK5ugn#tUBchBzPkKa&W-^sQcEZ|fk_XLER}98l4AQ;KS7@q+uRa=xpjf%s zd-l-&*hUCbd^wxKXY2RMJ0Jc=COP$~OZTP03@Y@<(73g(VBn%4VmDn&-k5g=3sAPD zdWDKH^6@{kh-k~`aMF;9@hHwB8?4}AM#ntwfzSVh8Aa^hS?4*1r^kGT72Bl{a|@&Q z{j;GU&mRdR(N2aMCd6vN|Ms^22HHO;`XdzEsokh2Lm<%WAX6GaEOcx zty6N*)5d|&EBG>v&+bpg=H8Bn&nXr2vOY05Jbd+tQdEO^H*;zgSoT|NoHbb^k(18< za4N;x|2EZJg8>@HpRC0clu?6es0Pc8YT!<*wQS<0!Lk0&U3J8d&$VpR9;%Q^OvkX| z+Tn&@z~Q)NBG%~Ivf#gmkC2WT4Mn2Aa^;5^0PxgUuo2lmgeBJX&{F!<4MuY>xl^@F z^@rJ%RG*Ung#j1+H(|<1ef~d`=6^r9RjEC%A_n_!bIHlo2A}dD=H`y(*16^ac!B*o zSo|8;Mrz#qy~1bn7A4Rh*=A|YiLtXV5TpHCM3D11Mkj)bNe5v)2fa)|E_9aK{^_}4 zB>TH_^EUZmyaBmj_tr-a^8+~RsO{m(|1$ztka5Vl8(fSbxELaEeJ-f>gls%ag^czJ zrA-b~DsnLJi9yP{RM_V(kRu%=55Wv}ARQt~VtOk&>O2@M5v%w1yw1VZV0CknmNcSV zbSobcRirtpn6Oa^`g23H1QVT+(x4<0jeNeBlUaufQqe^FqrfD1elOVv&#nljqEoJe_M07b``pF z<`quoZp;4za_RITpJ9&C(~#s~SJnT(vr+X>(Hnc23^~QG1OF74P551J{*$=;e}K@& zS}wxT57dOwsUtY&K{`5z#BR$w_v!skY#`ZKNcDH38E-l$P7J$^00aY$j_io+3>^G( zEmx&c-wFBeFppK%l?j#q0Or~K^YC@nKzD>3`Fn7A!~iahC;DG@`a=!*(`*AG`fKQ( z4u8~;u10{DkT4NT45P07NxX=s3^8-m7DM;?|BTarfoHAstTxi%Z99Cxzv0>bkoodG zc2~Yn#t^%!$%%-gnO0>3^upS8P-hDGq7$Pw5!gTGiV)ANbF}1EG)j@4hjsDbq4Q8kT&1;#O`wgPWanw zgb!9|gvcEHJAg$7`a@RpPm+-npZx>aocK?t!t?w4yypZ{)%ag|Pr%iGxT^$%s%-vy zRdKfZQ^JgyxLoid6F1r&X`B&t>Mb@Yy-&K!v65@d`x%dH!_X{PC23>oTYtYpgwOv2 z^w~pY$T0)ae!X?En8yYr~WJGlHuw(OU|}t&&!?XHQJ09nNg+g#iMq{Oml%Y2TAg z+Gu+fHu+F04uCgv!EUk)TdK=vQKF!%riVw{n!j63Q3q(*G}`sX9q^et>^Ih(N0H^) z8E1FvvqxZG#P0p;COofg5=s*#l-wc=*RCJ*+Jy~tmK>;%tqS1 zs7Y(tQ@De;)eq^-vargnOdC*19(nO49DH0NNXCy3*d%>BAS_-k+>-R^vh)lQ*gs>~ z$UH17>K!(xxFi zF{DlOUjPfN99xKQs%JA5lt~11HWI7y-6&4! zlxM^fkZQ4$np66R648(?Q~PCx^Qwh6rF!3Lc7|nvbo(9~=N0kaWOqIKvl3svK$^bO z22zp;5i)@EwILhn_2EoIBlkxbaOgh$6NFU~J+;iSup96~8Vhq0JO$znNNMQnt>hS2 zi|uS9uhCJ1-!H8$#QllJK_^JX@-fYKzgWe72OfCg3jbZDQM`oGQaFo{YWKEzT~}M- z0_&i$9p#QW0c~|BHpb)0$XVYQ#NYyfBVw7^l#;%Qx?uMs8uhNzh?fO}C{B-;T5R>i z!gLMP;Ylr`B*P$twlsCoicd`gT)7xVcvo|#8phw6LR%_ePFx<7A6Xj4&V!M=X-4!Z ztt53C!hDd*OmAIJ)Vfi#B^Mv<^AB&`Rg@6;XtKY<stX28?rsos<78m)wMu2J)JDG^(dgP+Ps2UKNkcXes@!>vt{u z1;Qf+xh+J_@$gkzmRbCJ>d-tzhC6cY4{45AGDu4dY}X6iGg{bwa_$^|y5Nr9cL%1L zk12BRC=sbN=~AauJjC`~ytrU`tYXzEJ23u4+u++>2j_q%UTE!624cJ+kSXr+K%*|v zsC}N(5)@bMymPRmu)2j4h+P=3;j``{NbdEVj2Du<^I(FE77WCzCAf_^im;ZE+-Zo4 zg8S78FDG?lOEYj|`kTD^N~udx|w4#zuvpEMtqh&wjmWgdfct z=!ArJAyN8siy(RZxvU#^yY{sQb)FJ0{-9cII|DDip5;#`P?9HG3^xo5b4xUM7x-8& ze_FUT56|Q%IwCd?W@cDr)G0(KbJvI7qfNKVpYYGHQ7ve1}mD@7pk1q7&>Cf&Ur2E@yNoL^6CPLsd3xcs*LvK2YC<;7Seq zaKpNX2bV8AtDmD4?50@h1KrGe_kHk(QnCfYHYXU~N_ABZK-b26a!Dg_v{SMwWSds( z?(!md8r0C1c=dJNTsU_-J73W}0n44aN@QALM9(wzO+G#kel~cM^1G zq|#w*CI$lFg9ku27I%8p!6^p&L!Z;6?{FLnhCYr7H`fHU3(%?IzlZqH>9i&8%V--D zC{9W^-n}_p5mxK*AaO|St>SZ)2fs7es9}*E-iKOXlc7(sX4*p}Cuz%W?_Jb;qjx-y zH)B3_0CFdz13>=t>Q1=c=>X8s{~sKH?El~ZZ2!{%koQ3-Cyg6MJ}0~xHLOg}sPQGO zpg0zUI_P`bv%5?8mv}hn9h3~eg1(Flqxq6%m?Vx{?g$1-iy0qB~Mg}S5Vp}SbDYqj%}FShq`Ec4hnbL4-vT^ z`Gy?QzY5IVo({qln@IX%GDHIK7EPTVibZDqD-) zxx0al4ql?~dQhuRxuY)`En}QMiJu8>$387=y`Db!a=M=IihwzcVjYnYe!UlmlY&bm zFS?#7Q1aZr*RWUYngCO$LCHxiN&Lqi*n_vU~ZiN0%885-Wz=q#B*=?_C#CdTulJWVIp#uOtQ8NvdR-7XnU20Th;|j1~VuQ9yo!r^kQV0+I3;OMiPy%$TR}v^CF?T z_Xflr+s?$n*dCGS)6m`aoQOTfwGcX_ntgbxzXLVL@>C1^b;n>!GchteIsasFw-pO! z(L-zw-oz%20=OU}&C2d-g15e(w{{Ud-ryv%qKPj$M`aqk(F}d4aD0&uc`8mg-U@nL z2FbrxOCCQ=8m z;9m0JRR!TqQ}HJoBz(?Rx@!|Ha35SncpDuCJn=@yj<^0#jf1FLSyDky85tgr-5sb( z{X=117z~bpw2BVAV277k8N9$_`f9>p? z@o{y6<1)kji+!FWplx;b#494QI42x$7LA;?9I|C(347FSn$CIs)&hz8%a4$zClfS> z@!sCTx@AS|Ly0s7X!K2S5NyPxuk!>CPGj-BNn?pFA*2B^WW>ZKyrhAM^&SY@82_Lq z4>Bu8i&7(j){AkI=shqQE~UA)6xXb%ZJ6(@x@&m&6vs>qeS1Dd%CPq95iqQcoWEa7 zH0eXqXIPW@C+(O|tZLn10HShH)~)g`mj|GIQJnLnX^YmY7`Di?{A);crJ=3olHoyJ z(a4yjVGo6&x+7^Y7^I=qr6b9P_9$oM%r$Z(-hoojHkh^h@vO)v+4Qmvg#k}9F^PKml8piEG+t|Z|Rx8PB(uI={@ zFVK&+L_IjsJ11#nw-(72NV!C6$uZV)a`5Br#>Fx%y-Zq!BEjpQvt3{UCD{dIAAE!C zoOR_3{)IpdC$~Djxqe<~OM=yGn(MJO;x48?roZEF61fGpV6OXFaszz#T1&1c-D+V& zxe|>mhpf3H=&jO-9=0fUEkesvWBmvt6VU~;iv`w(j_o7(a~Avh{{ma~O^v;7Q?cV9 zHhtu8dd%Unp4z5jJc_*f8D*8zMSjL!90w*#H}QBTM^O$=C+o zgTHGFx|0lS&_@qh(*YZ52Qzj&DHHR?Y45WV{MCUq869auPDk4C!jLwsUVv!>dW-+? z0+s*G3p93mfpdT11#JJ*3*b*P{k<1puHAQffew^_D8E4|aO&R(T@EQ3%V#l}MgMM? zJ^d;ZU|)rKX)SER3eW~^(H_$m3!?PhvCAJ-c%bX4iqW&iV;G2o1qcfciO7vjr*k<| z5CH^Hoc+~c{Q!Tzi5L6@k6wyO(O{Sh%pG3p z6N=5={-vQAAb^oQFhUn2dteBD@7aS6fN==f1EV<@*#q zdBON?_y->1NhR06 zK@Vk?$-j6I`(R`COik;>VFEUF;D-%=1_Yx!GKl|^D~RaGApXM@w83L0nr0~3k9z(z z5k#Le$ql9o8)=@J_8x9}_{;7UN_etXE9rZKuALVOg$=)to9Eb@@l)#4c(#nPM(Ir^ zbY*(y!QB2Dmc`MR_Nfv$3WHXiH>41bPi2C>LvI1zh;0bzw~{2c?rdC^X-pxMl8zKY zi#`4buNf+U#OCn17(xSeg7+7GWyp#j#TGjkEfdp_BPfmp-IR@JaRxX@;_u1ifgv0B zp=Y4t)X@r87?7zXdXyyW?0WM&;@MWR0->o@-oU{lwj&rrqd#+rX8F;d1$ynIe;;Ic z@7`ocxQXCg?|l2yK3xu=65_O)AO;trkB9}tyGM<9K(K3%S;1p)#IC)*VuqK~2R+7L z5jMsXU}%Gn6NDP03ODFTd*p(GHVor;+4er@GC$#But99}XY#Q>0Rl`S|2ZJQi{$?X z2*zWM{!Sa!NzyU#Gkh|ben?tSY(+eywIlTSp_q1@YFJM7hb-bfz4@HTcu#NksKVgu zC8BxQ;(d6*cS3jiy|5{>NZ6a4b_pl#I;AIZVgRI+fV6qY1;G(j zK@ds>QA1rKf>0$0PLK#ff{>&VhTJB}L?)A&N#=6SUjN$X%%q{(e&6?h-~ab{^f^gp z&Yan2ueILwzVF_rapDHdzgWq0;ABi8sZAn^ClkRn?U(E%;z3JwcacQgj1-3hP)TE! z2_`JUwF`2n56!R$&6Q^t0`meGI0jL;ZJzXE1o)-_xW$PDS3Boa3%{wV<<`uqDb}$lc_*ab9)CgR?xs6pA^fjfDbWa?%bQZB z?mBKsN2^T6Tj(KP^@z7U=ewXmA5Fj_!ap)=fhF#WMO{>elM~_annLcL*e58@ft>aU z*s0Efh&vXw2B*?f6Z7~+B_m(UwelIA<@C(JM&fd;2FMz=*bCT(d~X4(swX%hKtQTI zJ%kfadDT}~&aip-CK{YoaP?{X zC=SsuG_!GKw_)xqq~;m-ZXXCS*z)3ukzAzU5dZi!;1a#poI`LlcC$HoRJuj9wAuk| zk@Lkg^(ADTme|BvX+dN}Bt5|s@wcQWILfZr%wVy6Wx&a_P0u_`L`k>-TlpjL7jg6rkrJ4jMif*+82u$_JAurej~t>6rbx90x1q}311r+7jk>lj z7Q=a|H-G%x%nJ>0k!`|8JE>T~hoQ)D8&0pmL`9<>7cX66_BLF-FPZKxd1^Cu!gQLy z3$Zyv$8Fr*hNco7t|t|F@L?9$uj@WQ1^`B9a&#LJM1{q}Sa>B_f%Xnli8qxM#GGK46<(y{d<6v+mTFqy@*z z$C)4x?$P&tZVfcEG2rnOOrt}IyAjAQ&_&=p4xUJHDr=oUB8||&%1m)D0gq>orwI#I ztVniy+A@J86IB1+&d$eAs3ha-9#ScfS<`!7etj0tbtj7YMdnz6I|gnQV7-0-Fzv?JN7wWvU~se z8B^v=nKvaXY5#in(Hlnp(szmJvl7KKI7A{(KKefG(pYpb3tX5r1)`@YAm3?m_ym{& zatl|F=PrxqF68}J4TkUzy()+>jwF8(ItMZ1gb#ZJ?zdW;_)*Wn+_KnJIqySMWHLENpiKJnlk@Pkn3L zN~a#jVbMOwHa(!<-+Xv5xN2SFwRc7@#Z7@g6X#XO>W)l=va3}6RNo+PO+y`+Ds>GXD3a60l8cgJ&M0WX93C#P> zvh=%v@wjOV#7rk)4e%Ck*K(MzZh&ovRZ-W%DK}an)0UqzO%nLCOuA zyuLgcN(3FR+@8#EE(^?7S&|}g5wCi}rdym_r7%C77@edD?MF&2@&eXvC*-xIQ;BU? z%3Qx~iCc5y_lVgzA=B9_;1OD_!kfe1w8+D3Z24D3%*Ss*^`;59d#T*ac$~zmJOTAJ z9KQ&A5Wt`PX0+|UYT4nBVS`1EBRr%@$0>Ec^TWBj2kvjyFk8Uy#`X_8G}-uZ!<#TnrUEP98;nArty z(LoW9OXzU~9xLuc$P$Q5*j&xHP3cspVxu_ItdWUChu`!JQSeL~ocnl{jX`b_C!p6| zE))ESTsoQJF0@UtMnl3{wU29pEhY8wvV_U)=dZJ$XHo=*fnig+WOK`d95@*L=PZG;gXK^(N|O5Lb60kC`EpZHgZelm$N$^;U3&xJKoG zKhm#cQLWiXCP;r;S%#91V#uhHJw4yz#ANj&_(?baH7jel0X`o+0l!A0XFWQsOp9v0 zd*|-#KBtsa{y8YRnQA48>T}#(Zvrz%;uJ_i-LYy)Oi|htJEP-(3iF zw$a%bXo74VEPV^p`$Ls-j+GlfVdccf4>EC&0Jd}&><{JDK803!T%E3!a2d1WV4RHy z2tJ6ye71SZR?hgUwk?R##RwIcXcGLZvtnbvYKYrasut$){&XgMR>GaEw=)y=L;Rig zL`ElyVKoU0TG4s?W!SJ{^ZIH<V-w9_|w#ch6DV+1eV$DVB5L6w(E+TD9Ftz>;mrs>4Y35-^^jHgbOxnyn zf>f&r}oN_Biv);cZ$;eURpYGp?*i66&)tx%k**EiWw!K=&&G%)H1SG!}*R7p8Agy$OH z)(6_yaUzP4u1LeW^|jJ0j#r1r?^}cM80)SLp@5Bb@jkRLZ52O-W`x=qF={yBI_fbc z%=tE>x9`GxN!dxcNhj9(wvg{`8THYEikgt0e5T>gA%_M7rU_S51o$UkCMk8w-Vify zr9Jsb*`{6yFG3jZ0MB#GS%w5WT zqTslTA@5$Of=|W?(3^N6P)fu}(Xx~?mMYVKBMHuersZFh`(jcORaan+F}WvvdV$NkK7!)-^ma7J7fd3Nw7hRG;Y!VMQy?9w zi8k3{NF0Tfm5}a?VR3>i56XbYrIm)#!)F`3lMVstylc|}xa^h1BDmNJ)$Os?VEJ!t zg5%XG@jvW4(i&ftv$KK~^Xk77^yv|%O`lpxx2k^Ap0Hj^yfDC74SV2SVi~>8x4eH| z+>0@PRxI~evkTZZe=7HDXvXI-w29os$kJ)ym&W$Xg@sw(Fs3fT6R|K~0WS)877Oye zP#A4fM_c4uG4RzNUFZ7!QSRFg35V3~ICtk0zX5w;2$6T}vX)ySfrO2fknLfVKZ}33 zIZL$}OW#05gnlPeD7rXcP>%q4({{v+K)SC8q{CtS>V5>LsFuUMRqPdtZ%D&dtXAlM z!Q+o=?+m0tD-Q;QIcqlZ*0UGi3LrHSVY#>PmvNh@vQpJ zwQ{2WHvY-HFB`TKLm-@Z)BtG_ji{!HXylcVB``F@NRfqc|8{|{jhH;1z=#)c{(lzu z9)BPBiO(Yb!1>NE<9v$eJA;fUUeBedji$1E-haq2IDudcvkX&(wg`F0!;8}1+@cUc z%1sbqC;~izTUr2Z-E`ow#$M1gSCZPHf|M$~<(%`BZ+cV4q{ zeKUQAl-T03HQANK?~0$ET?PZ7?Noiba!9*xvs$qAGw81dXR2Q4q0?M!F^KnW7I zCGzgHWbTElLR`HK3?9e*3|DQgO>@Ca%Zr9sKL`W?S)!OR9FpjVI&54R9B%J&x!q>75lxf{%AT8Su5LV zRYccjrFvjlxlA6ceZKa)#ExRmE?yyivX1kZ1eKdUhnd%XhHQf1M2JNIbp|3$cG!Tm ze{r#*PC3OOm{k`4U4#GUz<&y(Yc35dW{SX+!10dX4QencMS?VU;q`=%K<=XJqm9sN zyX|m_7Gck~qzeKPtk~5EQCXTc2V&a13OV)vt&)FFVAKD;#ow~z|4WOHS^D2-@&799 zm%#FXeGp~}%P|!lzDTR`!gU4UhSO^F4w`hVZJr(BYXq?8mAx?6+aqlR?__01W#o1FVP2 zFY}oo-Y?k(XWJhEe1uH0&om(`hv{mR`KAhSYx?eE(|4K_3^`OmG%?UtQ1?b-7=29y z8-tuiDrN?RFZkHAm3S7So?67sqRC(!nDP~kb@V9!{xH31%=&MfHpkp!pP3_vKvn=z z;dfqhcWq+hrwI9CQ@GYfb%(uhX1${c5Z{hHQ1-MMEFgYF_=j-7;_n+qJa*>Oiz?!M znwTkZljSo^Na;tLSOu?kJEljBifDE|=-Qqp4~fFc&>?ahf1C*UcGCLw-;?~ zmDqEdfNWf`m`iq=;%F5Xd7fFuxC-1OY62E=%q!U2;8w5Oh`P<#tRSbw8^=Mol|?|_ zCj+Tdf;B61~K8?SYXZPeL#60%yj_H&7#HhK86K9K%Opiv1)E&vl}CR=g^E zKOp|ec259gTI~Fvw-!lFPY3T)!1TIH9mIX#a<`C#Zb4C}uUXsc^- zbvkTPH8aX`LMgjKGd7$g^An!re)hnrl?ArYs0JNAt~)ZzX`3}Y%$n|-!Yf_OusrBK zJY1Hh$IVz}Aw}#=4202JiB`l2z3d#oZEK{+0ibEvuhEFy-kyT`_QcCSAIdWXQ|Zx1bto_S0Mk9it+R}Z zuk7sKVI;fk?B8%(a9@!FXx3fFwY=C8q8p<7X-o&`81JkP?9m>7e!7qho~l=;vn7`^ zA&FgjTd(qVn${oM-eF7nmojM4qT}Ot8Tvn9H|D~u5xK$ztgzNPJu<8^d`(XsgCmoV z`A^$0ak~!A&(^aeFxAmPb)Iyq8cxjJ1zn}eo8`J{S0)>b+uei;imOYvEvcKgv#a3V z41WtVh@U$qh@|FICe@#h#9(a0#8FzV{T;R$rsZ#^n8T3^kCQnC?1hx~eqmj>QLXi*wB8VGw$i&Jsqx;gb+MIVf5N7?5^!*&PUsfo zd|*LFu^WB=Q6qN*s=XkhHl}c`hIOF$sB~GAL~Oed?CbVJ=fzvG)vt{y;ws^+zg;-6 zA7i>LCV2?V3?eX7CW+8zm-zYi94Cqpn|an7>FFAJ1}AIB18kO9}!SokFAZqkFKv+Gy1NRMi{J1JvdpudBydE8-9`A_)#t6~`RfFVpPn^o5E z~&g~OJTe&LiyTVtX*3 zbPKIUGK}`}KNu7)FEkREAx26Wf-(=_Cbr|WAGj{48u02i@9j=JiJ zHm_Leh1=d36pzM0JSr$JaR++hd+o1C!vRI?$VpWk_P;7a>$g5Lv*U5@I*2a{6~xw{ zNP-GdOV0W|trQ835*Tz5QYWBp+R^iqRoJs2IfY$6qCctKcoiqF(7qsrZ3+^GBbxaK z_CQW~If*^!{BnCvk-R0H;y-(j1NQJo-m;2ynea{h8X04iC7q7`U$i&aL$LQKQgD-y zg2?Q-3bIq-M)tPz-Pr=y9_#vT1k_sEVs)^<+8dZ{PTd@x)#T357C|i* zwn*@7Hu~a>v2)y#uf#^%g_t!D|AiRG3qhTt7IXOQmCWIJ@ToGwPm?x4PU>^PWJ^s* z`DHffwr7FYeeieIVF(_9`?1_0EN>=Q?~Hk)7Ht5iGme3o`yd{}-i{EqXVK=ITzGpQ zTL&qW!$Tmscj7^UAZ&+$eVrnN3`7Xm^@>d}y%;3@ZpUBj2to~&RiWJJAZ%Cx55*s<& zBKFdSqu)89WZ16@%DouUNNvC7w`!&!v$8p(FqKIPL54#c4BJ~c%_Qp0plDVNxo6B` zhQg`)oR541!v4?*^n83rWcR&$d7Wx-?vO(leAN7_+QIHq#WwBd%_n08MtX5-0c>oq zV|wvtAL*?b-Z-B$+&7edrwqkLEcq$C+~qc@#+H16*pj(EGygDDk|@^4z{7DqT`=R`j;by+n(0Xxw1yaM`jxfK1wJNJnLJ4ZNuGz zhv!<0F0S9dK4$&g7Bn>-Xqg zBz7~*;-RCbF>aMel>6D(0!j|1h`d5=8-OcjV(g-%E~Ax&5!jDtBk&SQfbDtxe@zU` z1?11PQMl3M^nz>tYwlMoPNh$NDnzc1%mX6{CO)_FnS#yLtlQyy{5d2|cBC)yS~U0V zmzhDl?LkJ;ZJL!Gf$x@h|7Uz)-D-v=a)$?iSJ>6S#l$Zhd?mDugn#Ne$Y_3-Thlr! zsmTZq`CxDO!HV#oQiHsM8YIdxXk&-@R3s?AZcyNR)L$gDdTkZb&RJ>f&05sp_03qv zb_%+G;0D!yuDdK`XRj^#W&Nr3=hshY5#~9u zSM5mu^7)6Fi4@pj5DWPba4HTKI3>JzHoRz&(4;B_HhJ$=p$8^u?;&+hc_|xzDd)*N z<(#hU-cQS6(;$KM*qH}a--fUPsVqNL{0IgVn%E6S$ap~s98Oey5mwe9_k9;h_ym6e zZ8_@8crn+k*Pbt17%-9ga{6IKrG?|~OZv-!KJC91=q>MZb!qba$C7@V;%2n_OoWA= zAMm3@D zQ)CDZ778E^&hGII*oFLif#>3P>#US$z%~#Vh2%!rb48O?i?BXC%vUtADqYjz(MJwY zFP+W8&gm)Y0x4Sm6p@Nd-Us*iE>>oJj}*!}-mxfKFM-aX_tWhhU@M~TfYp9BUszM^ zDI*tYkyB1rqOc4M72J24XeW$*fcQZUKfwQr14KK3H`)O#)U7b=PaGRkeFjA>x)NKR zVs&qksVf7i){8`;QBGAC@%MJ!qK)9^&@CjfgDVD9>Rcp0z%dv~6+J~%$qVj3@mvT8 zcjm{{xc@d<(-(^FKNn0-j z2;+@OC6v(e#gRJ5sShXW9aewmeTBJ7|(!w%|y6+yl4Gzrx2bYy_V zBB(!u!~?DCZG^}jP8n9*ck}Fe!cym2(NZCPxJ_!^w=biuJ0<{~BLO@WRBLXUnM<(O zr19F!Hl8aJ6F{K>-NQdo4N$zh`JaOKZx`Xm=KX97FmBKbxCc!@LNsOu#UhgWjHq%t zfY@v7q>%r9K5U^K3^Koa0QbFnkPn%6`z&%YjY10Dpum1-P3s{^^-7WR#~0k+Y~?)g z){3Bhnn0aB+aYB~wXDs`@z0kCC9QEX85I2y)Z_gYLH)Hv1ohcSUp!#<7^t5v8M=tkl69*nbLijK{qw6^mM_-R?I`(1=QjdLsme_9m$4 zYej#fx0W3Px*HG%f%wb>I-2-oX{m=7|Ma5#FJ9YCiJm@2OESv;+Ma(W|34^J?)X{Nb9HCqbJ`xbrRuUBcVt3S zZ9Ts~T)sP~%l9Jj55*u@f+YR>g1bU^j-2ul@ZV@B>5x2Tsl^xB6pZsg9wQ$n3(po` zIv;a{8t*!8l}vu35f7hGUj++r*%hdiqpaLl>HSEo9*nd>z<#i030F>~K!4v)P~FAA zzirK`f*V^Uz5hRnbM8GCbQ@8Q?jOm0PfTW#@W)=v3fylL0?PvMOCNgr0}bp!S1F`F z7>bbIQ-t)Hs%V7tzpX$>j{;9ROHsQ)u^jXJ65^MN-TH|o^oM2SH4TS_QjY;2jwT=6 zmnkP->_srHF(8*YN;?Jn`NV$^Q8t~>qTvoFL9los6eQZZA4482K8Sozg$-$vqKL&a zcueQ-GeI%0A+llK3+fiUX^$l;Is9eOM9A;6O>+5&k`=mq#{Y?@6Kl@_wpJXaBHD=l zi#Vdresa3z`VIkC&uCX79Xy>q|4{8<8s+IwlcMCz3tA&>X%$8|2=Qwkm|CxDACyVM z0Ts17FVb}4xsaR^xlB7vhhQUJ1RG~xB{*X3pYOOLJpRV0Ya{BRRY8E#qyx)~sOf)J z%+alh9Nj{m%CNXN<1fTK`b-=|^Iz6N^JNm6$5vcK^Jus;i@v_$0z0Ju`A31WPORXJ zBv*vMJz(3QsSmkbnPlWeVXYI$+>m=j1uftNRJNHk7J@*gflk!Ldk|f`dnoJf&tPXj zyY?CduK*pJl<+;q&V`6}nEI%;zs;`gKkPj?*`kOnMmszrv}9`>rjj%$hR(R$5xqOC zR?yGw_)fP5$l_7+Anon(y}_#TxWK@N&8XKXdWYT8a{%r;EIs#-hD0beFb>EJb)!Q% zZi?z#+O)gVroFn6`W+36BPHm@v3n^&SGC^U?c{X@t{E~YM9q#0wUnUqO|i*c zT!aMt1`W z{-*nrq0mvv|FG?26k=jP+y2>$a2M@75^Rs#i>)1s_FOR^c@F{mP8_FeGL*$-8i#Km zFS(p9h@pa7n3iNLAba>0z|cNF(uAx&*RM|HPsDYF!0*( z^%c>!gMOKlELFvOp(<|gi8rBDDAg*u|LvD2s&V#XdB=`+cwC8Og8R5S12LCAq8b5} zox}*mOiamyVc_OiQ6Lq;+P-};3Q;PXdl(|u1V@=tOr}` zd~}8z_E0mF5-TSTg0IfMH zoZ^%xPYz^54x5-#Xwg}s;xVeVGAESakj5YxtITNnbTsW_oIfi7T6ySnx@A&K#DzNe zvV2}qk1*<;M)u6!g?wN>lr+S-jIFBIefBXG?p14Ze_`v3y{jSzIuFNj`C6c9A>m=6 z=Hck?ntr-~WKFfx@TW+(St#2xR#=CuJX-SA%h=`P8{OIvTFHw`g5IXiJx{xH@2Ke9 z`=mQwyEG3DIV?QC;8&EI_G|a-Yjg_5H9ARjjn3K?}|ZzLZq0@M8@34n9N-7CZjJ-a;fmE zLF+v$$ z_NIxIh??~6K}1zxahkl3CVh)aig&DBFM{<@G!KvZ#%ZruJ=kzPwF?%8PVWEtv_@KErBC=LRaH07P6>A7jTt<5M4*7LdwzZ&+UqV$Fn2w zYf+z`=%pKp<(}OG;nbYF4b8a=DcQ~lgOSfe{5RAZH-Ij~%h)pD<(3?EHcSYT&US*9 z?F*xjFU54|mB|jJ0Y6+)(@&Lvq^6G()pT?OO1qcZU2z51;1?^>jfz`#jTSIQ4&eqzbDynhhzi4m6P9OFj((QL0g93(fHXK_^|dcz^|}8*y*;b!1W7WID-lZdPegEUC#UVkTSqy8w1!WVesjvS-Q~%Yjso%A0 z>W3k(MpLIY_FA?(?6t?j%yWZzTyXI3_T)|e#JyF&+>?hPtMMZDMl*0N!`)wSZ>h*T zQJD?Dskr8Dmbm6Ffc7sqCy>yd>4JQMFDRpmA)1z>y;+c4Q^{}B)wX|I$p@fsrVZ}- zsnhmHD!W2bsK8f`28FwVR($a~n-e{Zq1`)0)A_(bx} zAgNa>`evRdI(#$#FJipmt7tca%8m_CQ!^-f_sDxFF#<2q>varvFjB+11)@&~A)+YM z(T02h_*>c8BPK-D$;Naj#pk0Pe_zP&3duNllyyUGq9e8Tz1&P7I!{D(&4Kg(K2>4Dk+_$M* z_0KIi=HLHjOP(RM9_=+Lu71O-=lR5IN6*!&24z^_nMHx^ z(1FkbwNHkX%|5>Pbb(?4amS?tGnahzcwD`U?;nCCYm}cAvh6LZ)i=$mt`H=k>sk{v zQ&7Ewu8fYMe7eszD|3~**~+5G`cd@o@byj(gm9!c(L-d|^dX#Xk+_?W>jK;88%GMV zXHF-(g7zk~9F+neS!BoxSE6&>$nNGNNF1ig?FkR(V1Y ziEU7GMHW~4iB^gy8uh0WWfZVR*e;#O6`jsM!9Co&aS`vo9ZnHkO-V-}`X*8|Z`;R8 z1)GlIH>DN`_7^?^H3jTUnpm09i2u5{6tI_fJ%D7M4!RLrvG&lS5VtC!7ZG$9W>zv* zh7Ri;e6ajo66XoCLnuf&6Yr1LvkOjXe!8y0`_(|` z3Hf)l4;lPiPZN98qPz`TdbDSY*s`UE^j*X&z70zZ%S`^_4O7h^Z4FGXQ7I~mEM($L z{wBQ?#=tzeI8oRJmT6-ldN*9>U0pKt(@DzSz&5Nndg*+GPh22KUnr)C^9JAlyUUnG zF9RpU|J`LE*YyvV@sGoP=)W=SztCa7`**|s58wA=7~UGj6hd3H)ndmUU_qTw3^9z& z8!%kxLg!n6l^NFTi=R+h=rZ|z672|pX z#t0@DkjW(#YM2%7A!%&Oi>;9?3XVwG4SkwanWJ}x@kQ?n*O-e!7;Cmh^}Vkw2yBi| z13_kYOxHYhVR;WS+`NfzoX5NlmZnc<=c%uc;Un&@C+^K*y*XXyG`Uv*Jia**0PGtESI?Yv>}H z;3G}!nU&ec`$YCsIgi$I%mcRBZFXDpYvUT2Yb1buum#je%}IoJ|3b zE3JVO{8^cA$djgm2Bwf7L%7%k+)LO}lA`KAV1P~U3yaQ=hZ1WT+b*cl3N@+d z%qhQU$UJDK(RbRk@+X*i=J$C-qhm79K6B@8saL+U_5`(V9>dz|yUQ1d;v{d+D_omrj0$oRoo#28{>%Ci!* zuCb}VIQQ(pp<;~U2wHQ>CsHXu*IrAId}ZITjQGel9J)X zT#{;vyrwR<_)q5JvZ|xBIZXLVzNzK}csnVWN|gfgNY$a!%U6t}IY-TX!sHc}WJbu(7amu$%Syj9oau2MlsXs~Zy55x8V zk}mm7ykXdAKBK3eS?1n6k7*Bmb!|V_vz`!T3wiTHdXCeEk3Z*CH(~RW`fKqNOu7x< zVCZR4=c-d1(Rb`R9(*(patT}3XK)hRpY+_c1kW%Jn6qB=Gohu1O@9u1pnah@ zP6BiI2#+(L_JmDD?ly5FtSq~ZJ2h#UqW!Wv(D%A5SV~b`^#(H{CpH`x0oE0>7&kv= z13O>?oKmjb`xa&z757?J64zGC?pn0U?4QJv(Al5!DORTHrmlsU)Le6C<*6e~Y}q!h z3qCGL&#ZoSbQbvID$4@)H3{S#u4ti0j8Xk>NKk#O5*h;u40YRKyx*jPPmmsN6+&?tb0NyN|ceso8mVlfpfd zJ*V#dom(t{9wTfOcLS^ZmH79?5m32}?Hj%*L!X*zWuEaq*!XUw`n9$$E?etNQq$PZ z$nrnYMfIZu7)2ucSoQ6D$U>{JUBKh*T179|gu3)x-d%-wNa-Rb9k^;x_s6yTgJ}kW z`v&z+rPefPo}@-#z)Z%p12lJomeAESmLUAGz3 z^v7{IMcH8PoNrOiY_xxnOz7IspuS*?RTPHFK6c;lm#-*P8q{fz`k0=}*`IXG_DAy< z+yl%myJ2xf*xo(x23nY(Yn8=evR(K?3cl8ASVS_^sr20CzE-_2o_cyeBO`RB?^&$R zh~Q_DoGa?`xFYUQRdnmoX>51~UW<{BH;3a(H8JVTuw?_G`(ph-V(h$DF|`*wKgO+N zM$Y|~jNgObC0fHJ-?S(f;E&4}NdLYeIlqo7ha4M|{`mHgr4XOnlq<)j>YE-~h;lvT zhE-!h%HaL~R&<{QT zvwLhF+$OB?y)8-X`()wpd0!;ME&;Ohne`Zan#E6!VTIoNJ48IGzugS)lbk!xm-RfY z%ksI3+Rvaph%x9gR`NmKp>J<5#I3MD7>Jw1beLNIoh;ZA5Jp z?cDMb;BE_Z!s4tN0V?@UM9JjNlQS|slD#@-1KWFGTZj)-5Hf<@u)(a;!0S-Bv>#Ch z#%rVQL~8Gp3sw0kVcH8Ln`c-Q)_%n62egj4Eg6{~KjD@5Nw)5mW* zdOj#wb~?&ONd5)p?}UcvE9sF8Lg};gsMJ#B_7vvu4wGVachu{0a;g;_PRL_-tVT24 zp-}3mBqnTmz*a5@vljMDZHTxq>^=0$)Unv64FOeVU|?3%F7=VSY$MzY?o*(@)ZR(S zG2My25CTfvJa3axRRXckLgLeU_Mg4%n;`({`KJ6iu1ns*1s}eXh-mM5q7073{ncWO z4I(w{dW&nPBZ!Xo!|&4>T}^O zP8!*FzyLqZTvgi2bB+4@?@xdJ`^t%VLvPu<7BA?V&X7^1V`rpuWLrz$0X!}>&0D%b z$bxp2$<5P-1&-PQp{5bn)(}~BgS)%bJ98mnaRC(T*^kXxtW`~NSU#wK%6@?=MepWBj85BKP6VtyG>tc<8b2y4B79+ z8{4HAt{~e^-@2XnXTtaBE4!igX<=n1fa?=>#6D7OKPN=j+ZaiQu*AxK#48%Vt7k^y zLqAN4IwtH{jqC*?+XEx$DBp*hRu-iK=@#HIE_jwkAKywLt!;Aav1QVbZ!9&1{m*{;j?j z6u8hc8VA8Dzw!pOFap{m>seXzw2z^S7Oo&MRp1yn9rLy{i=_*yd)?3eX>LSbe}`H1 z3k*-;6)q33-xmjIKIu$xv3R0T;_<1@g2&ON;Qi8YY`KsftcjWWX2nhM4mg8q&1w8^ z$rH$h&U@oaO1PWn)7j^ZzP%?Hd-kh-o^kx%&;jj!b6u~G**{{G#-@h$J4O>cYM^*iiCV`gy!g=_Y^ZN#+$7S~-K ziQNON%;yl1gxkQJW$oWF8_-tI;zyaGceZ$dqV!;JrTrz&u)eqgieDjJ#8V-xUa8}K z73{}}OG>1vH~cyrN_2y5Mxe1>ioL0Lv-*mba_o3e`4A%saFKABQksB!FdT?|l2j1ix+ad^4xE{T z5PGzh+lO(6p7lDJ1aAurasZ*$bo*UOV=2gyMjhMZ(n0oP)b#1^#SuM+J6%aJ){v$( zdyJKpl`U`m-UXSBZPM|uLD+P6=thCalH1wBWeJPEHa@mohT)@D%*#==S#t0Le7^+8FwD1#LkDoApyYBdDIPzWqsvP0SCn4%j)6BIE9RV#T2%%Y z@c%lUG7fa7bGY9WppH&GZRqo}P&hgGyX%z|M=`xTG=-%^RU0;kb}^|E?vZr9VN>?P zW%f&@58F4KO?mT}FM36|I@yZ|Iz}G$gb#g7@5`EBP$0-$(_m674LbpMDOy#v0@*vw zdC!yI3SoO~il*3r;=~{3oQUQzD?Txcr-jeZ#%V_iv$#9zJwg2R-cEZqqn}ifLgLV7 zN?F0z@$VY&{)lJXws7?RZfvlsm5Dk~JwmOH6Jm#M156l zNatnM$Oy*wyn`Kzu2`7vu1A}-*I7IhOf{+1I<*t-JQNqG_{_jQN<`;&QiXrks8UF+ zw6UWWT!aAdJ2ES6$gdT%cHRf?22N}46IZXKP_!$I(yRJ8?c@0_g=lH7`x-qXyRnW_ zq1DxUA;HZ6FgxOC&|jp$q1DK}Y(vV}Y1I@VW&d*&{-in9+Sv(RvCXALA4uw04wx|e*ASoh7LNpKU0b3&F`+eQeP z=c-4WR*Wa^XiY-}UX+QdaOG+HoJY^?Mru-qga%CJ?REoCwfEJ6oGLq_zpBbTIG}#6 zrQ?|pMT2xg^ptlePsBLgO*waf(X=pvU}Zd|G{$@L3g_n!9vE4hQZv5#a9)P*tMKai za;K$UJtV1x17@k5-aJ^9yCt%=NI7b+^G?eLb&FLQ%FWB(3_kgdU8qWxx6`tz^6<8z z2Z@P|7uJcLBdL^CjC6ONNo2-+=Y8LLRr9J3`%bMpDV$YMe)pEMd1TQ}OWxvH(E)ku zCr4Q*6%{_zI%QEA?XxEL8;dcryt^~Py}uc#%8LyfCRj2iJu9XsU$&-hAoUSY;= zXFrdU&#H4Ybu(2|%CVV;T_X0xnG~#co;k$9>&juz*MmP%R;?VsD~{khIL{3KBs1Wf zb-A;mX}ZP7EB~`A=8?6R-sQ^8)4$m}Il}u{NbN%Bw6XSAA~U@9*brj>5YeoavVc3g zW_})bHQsabI1}E?46pnL=O+r|XIN}8iS!KfR<2H~iA~GN8a2x|%~xo(*>|t%qbu>3 z5?2+1&$4y>aG4deHZ&e*BcBu)_wJe(0bBkc~4 ztY0CT9c3{lzM`!%eX2k_YgF=#28UkqNJ>hzxR!oq5*;E7$jQHCV__n;ALASn;F(0% zRXllMl5_1XbF!qz_(1m$ye|Yli&xCIT=$mVY&#_H1m&w1uduL+4DqyVdRuj?`1pP+ za@X>_fuU3l<)!qttVe^SV^{e_g^C5_o7UIj2Mr5v?#*9x^IC)D?l;5Yi&_TVw{hKj z=B`cad~tV|y>I1jmG8E_+{ojppR8Rl+p>7r{n=l?iMkjaRkQR>)X?attm3E%{U+um zyjE`Aw)arbzKVI<_U<{k@2xC4$}8uZ`R3yE`*sV9`+2<#8S-^;{Kl6mpW^tX@e zGV%WGH8`>?s`Tf(vu9<_*4q_FZOUm-AJIsPTDNZ7e<*0b*8fH8yFnV8($?1#c1_H& zHYpx9VTb*%9>Ikdrxs_WKHiiwq4kL7b&+=KwgZo6J{KgsbgeMSTo9;^%38}y*j!pQ zqsgg0`m*|?S*`iQr#Jar829E<+n27suiM6M^L_lufvI87gRN}$J|JY$!;-Vz;oM-=4S8bKOc6U#+}< zxgq;?+bzYi7i~v|YPQ~r;JN$W&wVhX%Bdjwa_vX68uN!+HThhN5mo&hXKTirZu_;V zfE{FyD(Gs`{l!V+%^h8R?@qPd;63r>db~5%CC9P#NJ3Fj+tzKqhk|_HI!~}l00+sr zZJ||n0|JB3WtzWxYInFerT#(O1gkgwO1C*17TCfLv@gyj=Shx7MaC<;MfKfyy1V-s zN&b9~zKyh%Y;wPw0ysC?26{g>&dAVZkL0DMH2A#ur75;PJde+}g`X4K_O0me&8r)& zU-xP9)HMC;`k0gLlXqZ5>Hq0Q~@}G|JaN5V?Ye=PH6HPYR zy6LQ%sv39mh&MUk?pIBFo7Q-D$N(#0{5DrNQJPLta^U5ISQGUMo^H2;!`Z_bB?(p4 zx-BKoHM^z`rth_8lpHvaBh=3w@yfRKVjqF;yB*eReOJNBqURDu7wgd9oGKGe5UA8X zlNoDbob8J1p${tWH&R~O<{ewYpWlfvjpX+?F(&wx+5-vnYfD?=0!ixq?RZe!5&n+errK#7b^ci0I-R@&dOsXn$%1aI@Df%nF zY_UF?46pA9_vv%$4sRQ%dH!7d!rg@0I(6{dP}>vHzX;~1j(u)RH49a`eXmE~UZ%~? zD!srDf;HqU!X*Ati}F$EsV|SOc2q|APN!!H2Dp!jFRJqL(1bUUr*IxS;Wd-j@d)K;l-zoQnPxM*$M^{vD)JSIfHG8VE zjfSPP78s{Q@Ovltm4)UMc{Ow^s4{v6CFDqFH@}o~ytOC4xu2GhP!&69yx-HS3dihA zW0$y}7wLi@@Z8o6afy#53u51rxy&y0?a>SG%LF!NWaCY{q9;I0UynW~ zhmnaw$j_+sObJWy2rQ8i_1}iX781vo+(wN?d%t&{1U~xL5DRb^C7D5{c)gO)T}h93gIa6}Q{VdZK-f)9VMiTP=3+v!aXxmU*1B zIAL$A*E$QxFpCob$>NDnDWRM!>w{DQ6@?{NSIysW@BB{kR54M?R1COLaX00evqq}* z+;e-#&7lLXR^>nUua4A_BdPqM_L)4XB)jEqJWXbN>|XDsJA7Yn=Cdr%s8pI-7%&Vj z$ecWE20c&C;bY9L&{I~nkAgIOhs9fXwCGSo=xk=MQ9(}Q`hDTXJw9%-XKGz|qQ}(p zo&~yiX=|?Os zuStp|c&baUf-{wygUQl@)yrsM*j}m&i%Y*DK24=-<86|R9>}D&@ z(%AYAc+lA5I{m=rT;wR18QninTax@)**HyloyvjM+({hoW}Ds6w1dUU?($tE8)s zHuXtuzie`Ita=?%2o-i8XNH`Z&IEZy0aRP3(1ba2^O)rQ8I zcIF}3U$hAuo{QFf^5M*tSE-5(LnbOIzVKxBoyKOFyHQAaT^6-`$mSBy$uq>xDksI~ z0^?_QW)Xtifid~H(kh>nnt|~}o2HY~#;s62ve;tP&`5jQM0~P>UzmT*#@bYn7rdq5 zkz(?q9HpiYT^O`Z3UY;A|2BkwU|2Xc%Nc)r4fs3Vsz0Yq-e|h1T zJ?j_0GE2Hd*5xiF%PRbcywkb8>}B7r?Z0|WOT(mDNn^J-XWZK5{qxPaLzgfUx1@Wv z*5xNy&OAZVisUvOQ9z0o@kvbyPZ%#H4`{?qe)_5`DZkODu$W&8Z6#LOLIqFC)N6Rs z10Za>`Z_}dEsYIvD^qopPFm1ru4$A?LGIXELKJvQ6BCF9O`;{nxBivHnF`( ze`*uCg-p{a#X^y;H9=aM!uUyI{B$z0cXlXA(*?o!%FDWy%4#*~w^t|DG>PW=ELp!<lDs{X(GpfR{I zqR9`m`ju|-7^Z;s5^77emMaueX#}J&>$-HRTtQ2OD5_y^(_tc_)xjnQK;1>v}9>S&?;-n zCrht1N$G)lB~MdQ&xc4~X{y8YDYM9vW>>eZii+9;QMt@^&E%YMPv01Y3|zS8$(WhX zLkcRVj{D}$cLnt(^DT(u_NU)|qMdkq;hFzZ55M#f)r42v6}0;6nT4*Gwz@Z@yEnbH z7ah>a$Wrobnr@7?u7uZ=222d8r_+sRkv(49-a62B@{NDyw$t~F11)w*ZBNP*TpYY5 zgG>Sx^w{asKbu_KBp7HOsd)alDvl&3rN-VerzXvAAlfuMll-8G@{D&+O*h^+SI`&{ zSoj)R&rydj$4zYve_A5EBBAD)mZYPS_QWlVVd5?^x_!b}$ZFd5GH=@ULL%-Oq?L}V2gQEVgk6Da z)WSN@sMoEA;-*^PumrE(OdmJ+hh+gD^!+WkGfL7TPg z%x$Kp?R9Wmo2+qZlMvb8+CtY2i}X!Kt8y&WwsGZB$QrZAO$!mwFzCbS2SQ>&rcUTu zFIZSFZC-MR36>E5SwXst+@?26TlfkTTIcdQ_YAdr+nCjmRWCJOMSAEAH@=c)b}c5i z=_Bwya;0A58JfC+xtYQQmX59$#W4FH`)RdwIV^1u1!Pd% zI~~>HR*%4$YWpWL5&JEf!W=%>Ao9{D)JAO5^Mo*Iy}t8S<5yr_q2Q-mWow&mkhd6O zKmzoZj;;qEeZbBJ5u#?p2m5ZX_%`6e&e>6Ie2h3gL=X zutOQN8jwcmepA#h7_=I-P>mOGv{%e5MVtFg#uZXuFDK0=!@WAbY-l`_T*sRT6$;?q zgGv|bIKA#AaU+71dgtP5VBN4svCAQe(j34^$<)TJG{2!$3Wg`+K(m**n%zDf;9J2v zNWFHAOk_lEOcCr?_~_#gib?a^1B5WJeJ%}ZV!{`VaB5R+oK`S!|9;%*IIX{u{4Rb9 z7}wiFg6*vOrbAW4v~SjQ?8{CnxJvEJ)PJ`OmNL%UpXf=0sA1in)xz(fL+&5<1Yn zizUATQmzsRUI`eo-{#;#U=c^?Va)e0iMLvj4{Zmcj|?vfh8nO!!IWo`!y1SzQeCtf4l<$?{Z)`2 zIidBhhm3~yCmp~d3JSoT75q&&t|PUu&WHR`yVWb)LO{NSW@SD6R0wUFuupMOtQ$6$Uui9rvUn$l+-Hy0#Vs?3kBZ5j z!G+|Sa}r(BfDi=!DSHfFfrC#s2$7%E{|rh+(fQ!VZhvf9I; zmkO0R;tt;W3f^rJO0HQli)KK2^H+M|HyWQnQ@!Y3klOCnJw`U)QtLD|vZ;2(&d65j zPQA(FXf+XKJW=BnXsWh4O8MhGAylm*W8nkghX+m7!K12qk6&r+EuP6J#;t2%4Qz~q z^{-bzzSmBNPx3T-&|fCR5=VBZMPu`ntJi%JET`5jIC$?3spYei8BgrmPk&mM3!etT za9r(ZT1z_ht`A9@EyvNm>Z0(&EQf!;BCfqqmRIN{WCRCD+G+V-UA zm8b83|E-(M$|~1o-?UnFYl#z0IY(vT6-h>0KSZ)=-NJO7K(Pq5=U>UVaOXY z4@QiyCzF%EaFH|%$ssC=>?L>!e%^rxMEgN&9==g$ykWmS*o`a^_q{mn4Ou^f@gIH- z^4FiS`nGGRV0@q~tKPjKQ$^&^^U{t#t9OrElH@BA&lC0iwEIHF-F6+Ao~5jc_A${f zCqvKN-Tfnu)k;o`hN^d>z_?|RuvNy0P%~a1DUzHV4bj=dc|(n_ghqR=v-{7rJn~K& zlYC*~WayG>5|k=(8cm79da0JJmVPMACC|qN!xZN*vU|Z?O1Ygny8lY(Co4DJe*LAY zkiS~CPgN)#Y;xJWTS%T!<{5|aGlq|*c>HyhS+eX~jh`OWv`JToEXXAeS&UDQ9lVfn z&RA}3VJ=IOH1i;0{K9aud-WSnS~zGSBRrwlIXQ+5G_8l*&vCTseb&v+A74CsgDzgm z7zyAYN~3}2x?}LuWG3&+AjZ7AR4Y04!{<8a4Oy8%_0T6*y***V#M;j?X2G;g!$Bch z@*<3~TOYT>R2}YjvrSH_fBH!>?WBehY;!8PDksx?^52XY@J!X@2&R))?beArAZyKi z=rghumIZnG7NQhX8gD>}m%b=UHf6nSLt!LgIUj0s&k8?xvGaVl(<2`kRl-@9OJ zTR~cD`Tj?_=NK6&|5nTEQ$yBfvXhyFlZp3b`W=3-=Uv_aStK_eW7P=1yoIiZAKdro z8~@?2C!CobkuG5~8DlYdsBA462I&;9yOzLliD&RL82!KmyU{9RB{@<{^h~J_R+6uo zdB=tn`#txO^Qth6@IKJ03oCSSW$O(0r-_2vnCZVs*!!{jn%x!^|SFgGJ2r2_)cUbv(J##0 zJaEz(Kk{he7k;JWRnit(z=hW=I1R()WIi0arKW|YK`N1xmgj$DG~n%*;KLsnf5XTo zdW)Vmu*m8(?LPwo|~68&_PWm0T=b;r;Tvn{HBKdqKx5Wx)lT` zQH!{ZCAI@kE9jF5!EPz4;5Xo}Bj<6qExTX`JL8z`t`BTF4Q<8YaycYsmMzlLFi>;HXNn2IjGET*w^002#PS zF}w)m1XiIXj-W1D7YGL|W9D6e0Selp`)RF_H3T#e-9v9Tur@s+55BG?aZW$Czd$|fs{#T0s7CtL z8sSj8j+DbrFzGc8uCCYK8~Kdv3Fgsoc+R)bhh5I2vVE?)Y53kg;LmV6d#aK+2I+eK za91^%b_t?CT*%C8Lsk5+8>%R($rIcaX`dS4)PynC^Lw_C?C5@D!TbuonBDf#F)FBY zNN3I6615~vZ5Igx3g8esQCTFJOYyIl>&c$gZ^i_<9NexD6P2_uQArDx?>1RTyHrt{ zIHHCY9%~?ujNMQy9Na`FcrYvP+A;wb%4y?6wMlMomn5ggO>?YIn%?;4uFHN$=cK&b zJ7##LsElXAI8@RN1+XU1$ek7nMU1w7E#wSJSBXC9i!bs-7a%546T8L7nl;gf^Wa$x zId_ueXpHCtnkzdjW5TIcuIT2j-rr@x@fsN3e3QsEXd`OuEEo&^^{APg_73OdiOP!? zal&Ct@ODlmX29X~$;+&2x0Luv-oynaO|N|u>!NdXPJTPMt{F#q3dd{V3s!4T)oETU z^hs=K|G)IN+6SEW*)tP7QPGJ$zKD+HeWSMOYq^=UkoQ%aRPOzyH_o@|6@G_V3F%Io(WRzMc&_aSel7F^}Ws|BlH zp@FjhU#}K$i?IjiS@zSRg`6r2C*LvzrZR`z^&1%bC#}4$9e!)4-iY;8ZE{{EJZT~O z_(;&P{R&4Oa^s>iyMUHxFyCje;Wwu98s?QfCk@W;y_0*2ZZnuwU>g-r^5E!o8EnFr zq8q8kmmcl3O&b{8IciVVJrxXT(niyQum<9T>3W0zMV0CBI*hT7WYraQ@C>A*opL&` zk+qhO4&h+!w#@B{n3jC&xwto&TmIF+4)6mz35LpQBd-6|kdEkEAD}kJx{kY#voDJ#(e%K+;X7z9j&8}vcexzVM zlUi?BSiP82E>12tC^^%)n11YHIv(#(>2}G~!Zj2=X5gJV4Qsv*LIqoevDuf6&7W#H z|Mn+4&w7C>?1-8(5Bhx&;m4|MC9KMW;X9!{c;D(UTolkduxzdt8C1##ejDJq&~loV zEVUiBG#oKddg3w0qWi8L-}c+}wQ#^f#$_zexVZ_Iobdqnp4Br?OehczT*m0n1{)0` zA>F2hcvTf#dvW}gknmG1P3(?>J|TK*&L`L$qZyCHxuVKdF~& z`K$@Pn8g28`71`7X=j3szON?JVbba+dg%yPEiZ>E3xo}U^(9)~#INmpjEOW}yclFZ z{ZuJBs#J7oLIgBMhJK#k+$h}M@lx9T&KWVF<2)xLGrm&t=TSa$cC*0fNngD^8>_xM zMVg7WGSRNS8uE5{pbyip`&|9uHX=wypyO}pr6HFEVCbWHrSNEdT=eS!i$yEGq_T9x zvVl!X@|o+T@BvvFlXz40Jvgk=pd;MU;kGZ+?E@pfBrZtJ17p_sF(y3*k9RP_RYksC zX~l?78|g$XiIDU22rjH?U^pAUF^;l9zISI-oS_x5ig;xv+*eFnJQV!p#N0kFiCl(t zRqfHdjc9@4u{1BM#brLCBF0Eh^nBO0n~Rr+>+yL5T4IdQudLM@+rhk#Pt!&UA`$v^ z*YXV0e5Cu$eR_9JHj$*H&GbqTl-H2MamnVoY$prB)fpa7?1YQ z?e9`!xaDvFUe{x~$Jl-OeoTy8e>3J;u*s!}ywNR0pPqFnvSYm@wnd{GtjmmgLJ)RrlxK3f(= zF4UJZ!Bc!0-jRlQ4)5UvOK~;m)Db&3ljECU?&~^8DXN8?w`&ffaE?I8uLf7bY7?0V z2zI#@9D$7#ZOneS{tSk{r1*o;4Ik1rPF}ScMCD}B z6D0z>T{~irQ(p;Iq^S7wdZ>6%JQc-)R~J9yfCDo*OraKy?3ZCo3n%>N^?Z+WVx^~# zjgZ`^9L#1}s%+nKIer2ab$!SifC7iXGe_;}b@ z&yFh>B^_m zyWH6JUr4X0D{%Q>KUCs|ar z1+bpD&NpS;%1BVF1>-AJqCsn7!NV3N4SRW=+;lojN6t;0Q0O(;bSOVJU~csO+Tbz* zh%V4{yajw2d#i@KAPJDIwzW+z?4BxzQQdu4bXAsKIhH?QfxD-TXn?X?Bj+YkZV26Ov^ zty&2Fbm?YBq8B{H&X9g=l5jT^w%M*d6W}>HZWowO!2x|n?raf8v?@U{<|l8)abVF^ zTZSBYOC(vcpAv*ZKOL`L2hQ6b%S9s+Ulz^SGV0>lfhy5cXRDawg_QktT4*i;alc35 ziCHc6mkViW>Edh8L;YKj*lS8~3~L zlE|~Wvb8arL>nTG{G3YjvN?;aZtBCPtBJi}@4}0j{vTYO=BC~|b0L9atu9!{9H8x!%Sk2W-pg2TuelDj!_-8H z9jJ7kzI#ioC)j29ZvJ6%f_=b!CGUVIncv<6z@%^N?1w*`W3^{T9qFmZ zjF@JS>x>S zGRO7&?V(E-22i0oK|SNWX>rR-4Y_yZ>!(TMs|H?N)4ptepP5687e&vg^_uxg9oXPK zb7B9i)i2lX{rUK=aS$ImMt`=ishx*NQu`#l!MRo`9lg!s#4y+1+m~3ZW+J}Xa%uEx zsp%O;?mT}#rD-N4S#Zk3moZD92UD~!;Uo$pdN&F~>bHKqV01$z_|=InWzy1BaWJpO zdEuKTjdi!BU(cdMJgpFESF6VBI+6X6!Zu=&HbDkY$7ezK?aZ5*u<$E$JMYr4r3qY*dvKQ)n7%xy5JgCsRcFaT4rg&GXw) zdZE`zM1~Hg-{ct^HPOKqNN_7Qt$HfNu;ATS3{RSW+#EIyDYDfb%ky%wU&~BcGA$9t z_1Lw;M=N4STYl0%BwRA>hDvZ#2nvem(@qs4=rxM=ZJZ+IU!4ql^o#&=?hTV9W2RZI z?Q-)gC8<(qB`hM&Rg=A{->5fU;ZL|ki=V|jc7F;7mp_howPUPW$$QJ_SlPOi8A+5h zyQ;3FBrT+{DWG=K{ov=%Ize)Zgxqm%vn!1Fl0zX|Kp7i{axB^u~xKIUu{4 zv7(J#5@FQQ{SfWEulAXGRi2SVZ!EjivS~figZ@ViFxn>=BJWu?!5jm1!vS|5tnG(x z4>4|Yi~aAA@n}@^?z>Wlv>|2q^>W7F;yjEsld8b={yyfg9PR~QWH!(|%qM;W$_%s& zLbASsE=vQ(f)8YkuAK;SrSH;V0^_6m+YIQ~0C|Q;0MQsr<=_^-$4LC1#k63o-xJt7 zg%@^=5syGzj4V(&#)i(DnmP$A7V@%`!;;<14jD^o1{;tUqAd+%7(feR66DZUVHRlM zwb}?4hajz`VEMb9L#XQp6eTg_w;c3Fw0&R8ri~K}BoagZ!|3sul1aO1WcrLhn5$23 zBMiW+dE!qj(OC|ohj246Fl&exGv6u66RNpXhF7zXX%&|X2kg*-_-;g z48VR~8*vWv0;IUsHMNk5tGwoLlls}fOBmk&7PGvL^aAq^j^6mbO4M^VTQ~cG-Z_Kadt*Xd*9 zx*+W(67|}Wq8H|FQe0&u13!FM!4^lJhAZj)61;y!3FH12JkB9cSnSNPV3MC6-B5}A zz})jA0n0xu!i-ut;_z}dne)ucha)?i$knp66pz%?PiI$<^Ho1szJ=PKnpyTcm!z96 zo#|jr+b;~!+oL@-*YY#C8Lo(gKphb-L&MCyH?8r=go7w*%&z?}kRj(^?;Los|3a2u z7$KKtcs$}VqE-#*5g{iOh%n=->KB|wUcu`jCD)S(y~QfQCswewl{_vJ4toHCJfkra zAFSGmk~Vyk0z#xa_c8_L)lvry)e?%u3pr(vgEhjX@Ef$?=o`rJ0As|r{t5!=v|CDI zJg@dwERD>~Ba!5LpqpY!UYb+*e4UDTdX-ve{kaKmm_zhTY>%MGg}HKa z_^M%DuAWb=CRaJ^NM5j;ku<@TbBt9F7rtlDi(&d|(FJ2=QFEK$u${YlW3^-2XL{qF zy+m%U=b_@pAdBhK6whe8ddB&@HI_vtp4br1GtN^fR_A}lfYYrRQ3DXPR)0Lbm+96K zkVVnyKF!(FZs^GPG{$)XCdE5mk~0Sf23b^Rl-(b9EsjJIH~uY{b<>k2@2pq|UF11h z(QI0(B0}d6Mn}4y-W@NY1)=F1Zc|}DkxaoE9l5bg8_Z6}(|6|Q;yj6_=k;7saScSu z7+#;5R$+N1?yrYka}rX}wAtgq=8!J32DrTN3+VTlsVApKj91RL9xRV8c0p%7GGsLd z=`z~hYX5UMcTeD~t|pIHX^p#A^R0BxNe{~h&+HdCz-A^pWW9(IxTY=$WTamX!AJIS zGuTUscI^LhMYYr|7QXxp6W+X*DG@vSUp%X?CQrE+^U^+tiE9WL7dTl<_HlF9ZHiQz z&24OzBqk_EJaRw1#X`PgY=0cO>gz5gi3>J^!1W}=A7hM;@Ya!9$ zEJJY~c(tBV5e;>;xK!dg>60E@aU)yK(p_wz#CnlEmUMlXt86*QgSk2_m-rwGu1D;k zh#fnH-e#FPTKsYodMdkHsf=BMC~a!>e3eCph*^E1nI_PD{F_B9bmT2?=k40@qDoiQ zbB;NhX|rf@I_o4GdJIP1YavstAzuk#QjnP3xW0vDUb=w!WR?ap_~wV;(E^iP6=dnA zEq=h#KT7Z4l{AgZkdKB*1`4PvEqMBCN9t|VOx_985iHjeQAZbZ;RY$3Za=Vb*cjvR zukb63s(4!7};pt&WJaFmiU!uIyUO&gCTp%g@E>v+AfA%-ujz@AT3*lYYGWC>lfhCUS6-_ie}zNq<4SIcTVgn#!Hz{J z(X7YB@ew=Efq5KzfK-$D(H)GPKu2Di%TZJsIAr(|c_<$+F~AyRE-td%m%rN$6>lp9 zhhaQpqbiT%y12R%w=CqH;<{dM=ejKZj_YcKpIMb?Uy5Y#g|PIzWOuQbqwah$B&;uS+AuNSPxBLDQ11v9~X(&kxYJFN6ygl)*w4_3?Au4 z?>8q3PX0z{SR0sURY(P!^3z``2*hfCDOn69K1N^tVa$1~U=iW4g6$mh%NFA9aE^vU zN}zN5Qm_K|exo|ZG~>pc{J+O^y22m#FV^|w-;e3;wjs=vvD^N?W&0IYg1O*!5kCB3 zsE9Sz3KIJ~I`v{bwo$~uDO5+SHKMX-bqaSbZCu)+Y24;uk@M$>8?+sZTq9=cNSr9k zie*As8&a{HS73F3hooF|CuJ%C|A#?*gR=HAaKi@v)WBZ`GyVf{PIthl6G!7l92Jwl zF&2U|mJUE__r;%V6laRQXa$-9*E(VN_*#L8ge7f}=QNlyUPoAVU&}l2UX#dnO`6;K z8|`ITS1XoHeXqT>e`0DowD&3YDEvXfp3KL89#mLMZvD3=YK1VPoc!fzhne~!3horJ z*7(R-uw)rW13zs38-AGg2Yxuq%&^oWEZ6);ks3UhEquf|1|^T<>wTCU=YWfh4OA7C zW9Jy_j^vaD!ZNGeaKC#jdgFgG15T!4DFCkcD-a?ubsCV}D!dvnf@y~_$X zUqFaS>$g~KWSuF#^(U-H&6`q4B?JmL{LNSoIA^<;$>}N=0taf}~MeNO|?TVV|Q1QUIdX!y!Iu_DcyEF*HElk6CgTLKEEpIlbGKL+kWh)#A z>pc^(@W{pqeCr4~s>PNYDtB~ve>WCq7ymGp!4m&@tR{5me>0XGt4AIBxPWg^k#2do zb}kWNRdKC8Si`-KJs#HA;uO<*iAl<} z?@OGF&8)ZD-}r*2qvjX7-k8s+*h9*>g)JwczbHe0vD9GnJ5{0%!~54;hj!W?n6UV7 z@SBgJOhpV@!TeuZ-9PT!78k}|v%j~jf&696A`B9**FkYB9{I4eI8T1YsKpg*|0o8@ zYL?o;ZRaYHtt57ZVg5QdlY@7LO4i9VHaM5VAk0xZ>yI3yL~whQ31-72+stFt3tJd4 zg!Y82_J#?>|3@HQ&Y|2+-UbolAEB%vF8*sMTMU<--^VQSy$!sFm7Bn%Q-LSGWOyIx z-{5X>6VE5~!ZhJ;OxN!5 zzZ>(&za8^)$Y-7Im7{Pwm(T~d_Qmo)Wr4(EJJ5dzk8}hJD}y^=CDMtVAR4=yI#t|| zptRI*2(J%gBqrY{5^Xe=Z`%v=b6HXmBeh&Qoh6d~PL*2z3@iT%xaXrkM=#7JV#rZ; zg7A(+?2k}ZPMiF1NMe`w?<8!9q~uR3ej@yR*FhvCa@`f_2JF=bMpdbh`Q`d1P)-tZ zQY;5&dwD+!m6HHy^alI9Pz?8p1wUsQYUCiYrgZ^eLE~92K)ZYX+1RI!V z{&Rpc5Rl|5Lz20R`51eyI=fJigd7Klr_4c=&L#YRm+)aa@UOEGj`U>H?>{Efh23-KojOlLMxNhfb8-N@!Y2COhe+n#~! zM8t8e1FuT!NP|KC0lxkgt+3h4c}((l`1bz0v7GRVB`d!nO~q-i0cWS}ol~iLIgA zPnj2V+ZJ2^&s928hVl-Qi#FVH&@Bs`0nu29DC9~Pdi&7%NS!vf3f-QthgB~0kC$cF zDpFRpU0=`W$qNgx8+9iwG($RC&a18(&MR3AS1H$J6OVjzj0C}$zF6CM2fIh*0c|4~ zkdC!+PA9^yfFBs4TU{lu0zBC|n9!|~^4E&4m$zYQi(hg~CA|VJRx0;!vZpji9#Dk8 zS@cb&t5N@vdC0y7hLJrhv^XN$K&cINJ3@IciQ7=uChDu_cYmS9;{w=mR|9nmE|7O2 zM^7N9R)`z76+(4bJi+$vW2)d*5+`@$h&FgTH=$gj`wb$gubfv0V~#S$J+z{v>mlSZ z$U*WS|34)cEdlQw2Kz+(%TAy9;Fi-9%DoUAHH5=<#2iQXSykIs_bTc>c0Mo;50e%oOh1BhO}4ByI+(xj;q zF3kipIhk~(-q40!NeQ6~+muU7&!~uAN6S|R+JH*A>H8q@_S~*?7TnIpqiPRzkc6dZ z7;5M#0>?u7ooppPQcd*Rh1!Bzl%nLjQ^EznTieePdcKBw-0OD?&*Pbb z=pF~P3(jEESKBxuX0{PFz1UA-b19S>)|E4dT+D0}=-^;k8{g^46hC z9&dxigF>R@m{K%DFo3#szw1&NL%QOQ7?f4&{hy^+lvWWN8^NEwG)yciDV}z+NyVQY z5Lm9__uTUmswwGg?y$)dO932Sx*8(nBC`Xt8Fj+8N<49o>M176F&&D6ORNdWMeXc2 z>Lece!7kp!mKgkE?QGb5faYE8izsRcx4afM7nrx6v%F#(*t`p_p2VU?@jaUlzO~$~ zG`5BxRbNDtF^bX-GM9-PW46rL5l1roHrrC^0;7qIeGxFnLENAo%Qp%8Uo{d)x@BN$;x zE_=SvcUF|eme9jkER7$!^cbh5l>hKJRzq>TYk1r!jFeQeP0MBlFn{<>>~-C&wVLY_Z6*Yai0E>e^CqYya~-gJ7|~3*_k63L zj{>waIHiv`r-a_>J`Cz~O6VbeYjUMDDRXdv?b-42-a^S1$Ks}$#k(&I8DfK)pdhWm|0m)4yn7?XDAJ~V zc!1{TRnK8tmzdwblJzHg<3ouIx2~0S>{$cXXIJ=Bl9i&c#n=Q8KB+2rBdzC$?gW0% z(^_6{{4qG6NvSQ#4P-FTgy&l@?k2$Ptt~wnj?C(1w%jQy$CadFa$q?3f~o#>2G?>3Dm)D)(aXU zfb=ugW#z%i2f*urmx@k7s=k+*R4#HIcooY+BVI3u2&01$eD-+R=!rYLN%TI6s`Xdwhr9D2*Y%pWH=}~ zco9xsLrTy%)W!!DO(4tl1Ut?Rph%4#wrOBn9oA1+A?#)9d0ntGT&u? zZ{PK^q`2F9Y|q)td@O*+ea!lqeSLAe;wjm{Ugf#JgG_98=KKQsWwHxqjS@sNTXKmb z3DhBb@^g0YaMp5CMw>We5LRj>M3*a>TKCE}8hw{uXts^nahPq$vcN+GTrkF%>%(pF zVLd+zx)@?Q9)4&)H~N%~Sjm21kv9a}g$xctjKRF!L2!P6!ow<?nsUeL)s z*p4k}7-R8)haOEFVGC<=?3h*9tHGLL6dG)f9!4~mif~KtCD>T?g;UW7TMgeB{KH-j zyKuf`dlj#|1FzU9rI#T20hntb(*Ox@QwumqaNZN?bx}}G!JR>OK3aN$TN=7%rFNrU zdQ3;mD{Hh!I#o?<-^muDm(;+>J`&^}7{bbArd;Xv6S5d{PF(yb-1Xz?>Sj0lUX&n&rHT)(E^UYv_8Zb|Ze z$?pD#r!5@^Js}k5ll`A+hjGIw_k3^^6MCY53`O)_e~%l`n&G6cq;W6fVD3*67XFmL z*U`ri1m@_a-{UW11Y~ zD2Ls6R!_Q?9ETcN4qsZz(PZ(6tc{Yd>)HhBI9}$ z3keEYNKh?l#?$@BWym(&s3%plcZkJP5i>o$FY6$Xw!qN7p^QScVBP#i86|v*qxSS= z7NI^IHUNfFB~1Ap|&&1=RAxt?)JaTz7cwKn!SzTxcL7sW`CP;e}ZR(m*P3+sSx*w z%~q^_MySmOWQ5w?aH|Y<1b6_SMe}HGoa2`BN1?IDM^+p?%Y2II6Pcv z82IdhzUbtqZ!QpqM^gO7S3>eD7oSsRSu%`!e-8u(m)-+|Bm*!wk%-~a7Q>U6)|G14 zE{nv2h2~$+z}^czo_9S3Z;ZRNiNRr@2Yc+Etj`?Po(a(ME{qIbk71kK(D}W5D$@Ku z6Bv(~z#}dbsIS5PJRCtpOV%(k`H(ez3I5sxn@)=fF9;r8jnE>La}-l~^jSe+WVe@t z!1*&oZVwR$(5fcF=-O>2OHa;W-M|K>sg+4|>6tR78&2TK<{-+By=@c4zaT#0yGqjK z8YVY+iH1yIdzExodnVAYlm#{`t!62kT6g!B>FChs6)zQ(1^c5cD%xG;;vv?xm3%UyC`@gKn~ydY1e2O+6WneLj<*%`%1w!=qS(xYas81YH89|Se>D5W zcgo2ZkhwnT)$NadU38Pi{IQ(o9kP5i=#vj#R-A%?hI9b)YePDK`lk48I$#L;tS90E zDVtzy)LY>`TKz?|M~gu)+ZpZuX!h>n3+s8gxtBDUEFYKxMuRMJgTcCz8LmJ6p1 zY`$U$r#RV0=-R2*cy#CkJo0Ra@Ys(!`X%{&huJUHvo03Ro;#&kxCF)6nW&)W{6ji` z&e)I+u<2#F#AEN8f%B$!{o3GN5LTx!_$D#=`*8o<5bl37zxUz(1uGcDJ3*K-kF4fT z;~dMC2sS&JcPmeg)S(F{Lkx;D7#1BO9?DOG(6EzYnD@Ua02FW;ynshP#bQRls>1In zfDQoB362o_?$u-NgA~Bj6E!%0#yzPh95Ob|9K0lN(`V!mSraV4!2aX#8~D32lg9-a z6)X}KGa9t$=wmvJV=BbmxuT|W4cock|lxkesR~&Riaw(z-E3u7r)1wjfcY35Z@QQ*zY6$cYlib zct+^|S;QYK#*Rg`J#qsUdCv1~V_mwuL}%uV?vPcdd&(y34>8Zlqy!%!v@w{zwDPIH z(I7)k&{qIo+=^kW#4ugN_F^wYw0n4|Bg+Cr_|8QZAbbh300@}hvjCl@j^(nas^Hm> zfd`d72=(I}zg!d>jQAga|Ah5NXg3JwQAEED_omno>MBw8{3-*ZeHm?H3&$S~a_-f; z&pn??77E))f>Dg5)z|a=lN4h3E7x`%q*m!8y4qv4ZFeQuO9op^C^~Fg} z!6^TS$P978mOE|w7cd{4zTs_XXboGKDM(!=$S9{h)~n8hSQdBvk&B63F2Y4@j{5tB z^6t%1e}gg0?npyAp}k7b9?4fhs9fY!b`zC?#nVMF?<*fVVtYs8(18iqv#D&}ca}T| z5o~Nij_2=izQ><&KALW)U-BmN5sxgxG|7|^PH7?g9;-**v50A3CJIdg95=~H2%lts zmcU^2W{7Cs^8g%@Fz^5f^5z?OfDi>m_PlSlJH+i(gZIsbH`iQ3;+`knm+rn_Kf`*4 zPlsC_!AIgRV-)Kv>ap9#-)S0L?HW6?o>*A zU>30}xbmJXb+FZvOb8f=iHqt&UmEpC>x*nSaWiH(`lHUq0DVoxAC&)Apx;Xb`l#X2 zm4=lF1SzOXSVug*MikI6s6QORAY4y&zCdZP3@%dj2}|%z9Kv`>$&g~y(lJP6ccKE3 z4TGz={?{*}SH1t$3Y(#@C6S%i&tb^cz8k;9X^XI4d&g))1(Np?;^YW!#lPAG9={hb z{cb$4+hCfG;Pr<@b}s35SFOr7I(AfZQ*Yy)C@*2Lq$)aog|=m?03tyZD;AY!rTPX= z7B-y}CAtMPK{q#1A1gm$C1!;673y3_7v%g174*!u^&15bo;=Ag|{$ zL=w2U4+eXhj}@iKguP=#8I6g0o#)dz`Zk`A%{Wp0ehK&o;u;UJ5Xz!pyzNTf=2pMl z(7i9%BR1ss#Nvnbmf(68T(R>BmHLTMuWXPq6Y>btm4c^!;I*F39NcjB{(7Kga|h6R zhY6_rJxK_R5{1C+^a`YckZ2JCCsAgDKcYh5NS_58lyG_0Q3tG^w=SAgBOrtCkgfA_ z*lyrun~UiWvYt1q2v=!p4{kgtWbB)HScvu~+_)_jTKw@V(lwaKVZn(B{(t>P%`!ROoU`w{%Ofml=4 zkb8Fwsx!D$CC<_h9Dx=@Id;-8>tj0_rM)&<)c%i}iatFe*8HuYM)3Ei$fw#rZU0$f zX=^M`b*GxhN9WNc|30H?g9~ArgtXrnTv(PZy(dgfRQhM{@M8?CN67Dg*aR2sFC2cN zmH0IjnONegF2_&%6Nko$Or?L6l%;Q_+TJ#|mqq^rcPkV;5CI^J5Ct=O);A6f+_d1UG+pO?ym*s}OKgU%LDK&mQw8ozISSz3N4{mvw=C4N7*7 z)OAi7c0YUWBKJ*Q-`R5h>mhxno}aX1lK-;&2@l{>7NLFa_Rk_*~N=8h7877qhlYs_5syDp=he6b}S$^P$H(I_!~`n9@w_(hAnv zzKV}#KcZ5vqy|GxfxK4b)Kml zRWSQEv=VD!2!R$L@R#`!;wvR?gsbKB{NMU zD?>?uUvymQvpc~Rf!0Q%iaH754X5)eMN55#O;B{g`K1v4TnXwUgzc~fG(nSug4x2c zL#a?Mu+t;)>XIPAslCb3$Ex22*b7_%A5sqj6a%W@l6g&ZhU&SpUPUE1tbPu**Fito zmt0A-+HaDX;VkTog@TUQR`MG7J8Q4wX09ZGu|yLzLa_T0npT5D^}9l!IiTO|0gs97 zJ7?nPOJp$-MX>Cq@kUIqkqz2B2k-IVX#E^weoJFX`x7U~c#yq||LtE4zvvSxNAK}$ zcQ+9-QU-!^eIuv%*2MTksV;^)ceZMzhwo019`ztxv7<`4wjo~7VzS5?m=^d1DtD0R zmEPT-$G{HnWX~Hgt^7+~nGFx&)7AX+#Y?l{vqS!nY}S0lP4VI9E9-0B=J<2#NHd+> z`aY}0@j9EBttJ=G93gP?gwlk;s|ADvQ{cx~vkN{8?l~X$jHs%tA+TWuOCQcL*jLU@ zkS?{^L$9t0&Z6^=lOtlv`%L>%zwfj)$X2>3-QqR zRwwo<1nT6t=UGgITCRrORqXzakmiKL6}TI4a3en1)q-OYbVfAeoht-vJ~Y8<#QZca z9d;7?OJKeu&M`AXXYKT#*exhsa}9Ye=C>p+74Uh{yNkn1f{qC$%_DBJyxJzgobX_U zSNfHfLvPbRwiBE$CCE$Qg%H`WL>?1S%seoB+EWV-JlFKT*3Hb$0{a}$;Vqp9jso-k z%g`1S9Z0_Oz4KK!Ll6}6BA zHe862845%5I-a}@JHdTZ%{(mwtSuOs9S=j-+89|2eQCbNAz@{>0ZUCs1o`MmUu>jt zo{Dik`0wL91v2)7Ge#EP3Y?U8_7d|(V$WY@hh{U&{G;QJd&YLdY$R~je-Y`a2Da^? zyzpwcOf09tLYdFJ{A>c}QDTBBfdvql^yv(%L@~ThS&AhcC5&$%K3(}Uz?IMR+6Gi% zTUvn)9TjP3WrhUsMisSDIeR#Au*q?Vfu`>K?Tt5VwDPVvvjy{B;8?)xo#9NzH zF}QJxtERq%{g;s;>(3$ySjL;)Lw0%g6XXv~Fo zKOvfqr-^bsJHoNyEI(hK=Pop;xgRLd>P6sFZqBmV>G>LL7|g;0bVe{6_Q< z=CjwTAeol5@Iuz}qGEHVULK(^#hM)(g~vmYpy3r?Coo&CS2lZ*z*P5o zmu-}92$O0yZ%1qPPcZ*1d@(+o{cJ*^st#A^+tRSnj#@82HV=LS=YduQd7GwQcbwdDZpY-d(Y-H*wh6tRe8R~E z(>+0(mF?5kg_(UY*(bs96b9b}5>m;uoD(TNy?r%lRU!^Aq5BX2m(X2n{+|T8>cm?E zUH^{*JqhBRh6pkyOOcj#rsc*>W>7&BlO2ugai+u(^%0E>f-7ebwczYnI}Y4x3wpp? zvHKFSpkv+Us}hZZ9QDwv$G^c{r( zG0?)m4X$#%F|Tet4{J5Uz-8_`NrQS&p3w$TTJi02JFH<`4j(v`DA#4Piw$eNzq(>& zK+c9Ec^$SJ{uZ`lRU|(&tY9R}`R6bbO{d$JGI^Zz2>ltfqpCiQPHjJHLAA$Z#kxF)`E9lEL}caC4R-x^%Gf#_9N2 zEQQg+DtMZOxZ@(}DJ_TI{SxG*us{f`B|4ZBrkE(nM3j#hcd*GzByemrUIo(c{%6__ z?#jIykqC5B$AG+J0}a^U4!!s^H2h*{yReyV5f|pk#EBRM6IYU&(`Iol|D=&p{Na7(ZtRt_ootN-fbJ$JCj>zo1%*JWR zkKClYdPr>{u=a;?!Dr=ll}~!+$b}we)*g6y8Wy@(EXQ9LGx}o9?VpLC27;mx*7y0HLH4F#GU2cF5%xO9&z>Y2Y7Ev;n6ip@J$rtd#N83=q4AnKhYI5 z>rEp1og70d5ya~l6Ktbkcq$~`WRBZyIv+R6hp1A0jdEL>Jd;72EUfnSD7NZ(9TW}l zX^6xU?sun9q>^z*$U4W89-bT zxkbXqMr}Zd5pJ_<&uf+a$r&^*WDI`JiqQQExmPM{WP;9B;a#f>RRb3afdOoRG{-m{U+gPM#b^&bvLazM-7KI8a_7CagACog(!Np@N*!s+ttrd#e;cybT zc2&#~uw9B7pc7PR9qo0hlyc%$UtqoGr?5vWYlwRX$|WV@-d|0pGiCrxed1@_gRLRY z;AeI!Xv#@=QHN}pux)$OJ&W#}+|2AF@fjY{A>jTVMEPT4m7^Aob1wq|M@dWId0GNj zoQG|%!}*0mn7|dvkygwD#XYmax|6VBehQpln1g&HBNtrf>=uED$iu}iErMW1Nhz?iztSnv4UoRrBVi1C^#02 z8Njaal|nBL4})4H6*M1a$#Hn>$O1}-a1$>&yiAIdq#?;uV0Z;QgSNMD`imn(Sbg>p zxAeXVf0eOYz=NH)^}2Ajo-zJB6-q)*$+& zHHiMSgy^R`gWUR{fm3xVie1&c(te;8uoLde4!bY*w4?wxe4hd9H>S)Sp6=xFTnOBh zmJ3x@Ylze3Jmu&hngWIq7n|4uel(^4@AKO^WO0j{Z#;||UZvbL7W1Ofk@B+N^zt!6 z$S@S=_FOl6V&;F*U=AuCH{jfu+hFf&rgcmHv6TZ03e#8^PqoGfHMhZP62W(&TSExV zh~g0ozl76fRZ;}%v98;DbVZ!c=35=YoLj(^6X!9_yEUF+6^XQJjn)01Nzhb?^ylTH zkF_JYs9N1?68pRW&Z$u%Q>G;hZnhEiU`LtNKq^!Ow!x5H&*LF&QdsqEGfIp^j|F#y zSa9tivSAH9Ma=~z2%Jzxo0mcmp`THj5b>;;3wA+p-KurluC*LmqGJ@!S`?DH92%i= zEeyq?cPE0ZuX21AD8y;Wij|q2tIs!RSyR1Bv{b>)W}Rcn3#8AGXLnRqpl*90(IJ^_)or?3O@I@QCA26`P|0FX~Ezl?<^0u{i)1=(oL5P;_ zU=}4IFEx9F8pvVkY(~x|aJnQ&+j<H0+eNuYW1`xqizXo^7I--_YJUL`<3dQUo_l2)vE1! zdDGcDQK45ERd@Z_rr+hhM(`uL5tNq^z~6#1QX-I#fGwu*hS{tUW9V;XJZ#-#g{1Xg zROIgHxq3JW!+J+F9E!rj4x=LqI6t+rC5{}D(_2Qz2guxw+~#5Z`FP~oNcI;TfDnJZ ztOFMQv=6L&@Lr9;*@HSb`L$f>o`CCk0Ur8@EZ7%e?Or2n<8xs)~nk@pqRgI#s9~cKZ-Nl359hMB}sV0@TkgF zMDGc5nC)*3@HwOs3j^YJ^+^bCG4d^-KL>j&r~eZ4dt-u*ui>Z4oM?a7Tn4KR$MBq1_; z!)(=ok9T8)29#oO_4;>H4AU)xrp${^> zkz!Ei<8+|0A)}QZi}C1F;I|Yzt`FJmDJ*8F8nwQxu3C>_ZeZRQ#cxrM%jd419D`wX zcG|oa%TcaxR4HEr=Ohs?&?4eJVCO(uT@jC0p34*bwkp%c&t`{7iRE>6|JG_w6fdhe zs?-0hnoD#V^HI|p0KNYtdjSFkOFtOJaVLMB>NIQ3mB{?{0YQ0XmlkzizD;DoRA;1< z6YQ+hIcyoiQ3=}TA$GQCj1)VIwb=sg#s2kS2=$Goa7fe}EzsW5Ev#+anM9&7&SYm` z*CU!lrhzjRV=IA5^%wquRF7y{lIlrf9jU$%QMLIKyQdOCK5JlImje}PF!m4(*LL7r z3e03VzHGT$@Xx0jKgV8*6q_Q#dquCGawha#)DqYDDe+k-D`>*o4vyAt0Tf%GqH zc?s6?m#j*Z9_!Zf3E-6WrJPKWe?sm%K)|cy z9>M5Kaz6wsUQbNbxJpcyUug=iYCdHT=qb`d@Z%r{O%-~?;Uga<7BmlcNrfDHg*kJt@c{ZoZVe5!qY|3K#O zkJNeu-2-59gICo0?TC%vSkY0q$C`^;Qx243QNt_x`ebQ*GQJC+RsX2i>OzTM0vv+UK1qmwDb~OHdQXn3W^;)j zxHYQNmW$028?Dsu0)xEkT5TlQE@h;*RQ0*dt4Gyn^{Iaa+TRlBZwBqCAO0iIz86B4 z;e)Nk>|KEmG*Kze#QtYeJ#M}BN>2_OIscvaF zp>q9sb5^^n=JYA!kQNu{_NFQQaYP&VouA-^I##i^bNxk)(4<&`Vd8sQiFSp6m14)q zz}e4~+TKfZkfe#K)qQp^6=6jc>M-=GCzw%%8z*7F_Z0_C5g4UZ>YY_#^@O(1E+tW3EW_;9+@7kJs&vxxKV|(1KppdZ?L=jmF zHSN_&9HdwV${oo@S(8id;xj-MpjNv?$tvF}OM>*r3Lyl&uC!%d{Y16>8^J~ePUjF5QyD)(&GAxGUgeKXc~p5L)G$}C zT^-5w8rlFs_2fd@Qb&`X*gSX8G1V{??0g~7$w827@(;koV)i8BC&~wBnH>8-+Y*@E zytB!THnFads{(TbRjK*{Lp8swb(L$qr*CN7^DdZ2SzLChEN*|>6+$FLpI&7_^ut9& zzk^zD@I?D9lzpB^*;`u*y{%ACQ|ObBw&4B0aUSx&wNUoWM<`|APAU7q4HVH2YN3Jm zC*8p&z5cwa2SXyl+_6*F0e6O}vEE!EcKDJPopM^P#bvjUy6jRA(U+5Cj3>uoumG3H zdHf*t>+m^Iy5EgnJN^=zc^jZ(IlFXm?_nF)1&^h~{RX78n)lATt>gkl7^9H9^z9}g1&Cvf{n8%W5mM}*^?~wEQ_}(Vgmw|g3rpW^{Qa1AQ#H@e>RczfL6}aF> zxFKV+u`}ZudL%S#hHG=zNv_|9rn|0iJu}7rc;lOEYg!>m$I($MVUxQ48_Nml6^c=h zGrL~`ZL^^N=FGoPiJi@w^9R?cb5kXC?%Wyl(>lNO)84T7X~&|~^oD4GyAn=5#}>AM zaG#CDz8bmv@_5Q#UJ>hWV+o?kSmfAs-8cQI`zD0CZ<6ebAd-tsVieQ%uj_=mGZ4dHhHi?vICu`);uhHc-d0G=9yI+ z5p2509~Y~-+kN(#5VCd8=n2@9r|p(p~+bnU$W3u_mpcrkH&0=DS&C zSrYVRKKt36YU(_!Tgn~v)WKG#l<%Q3F6JbGyU(HrDS>7kY*?X{)+3HMc5~=G3X=*p z?~tmC%|xtW_bdjNM`&>AD53fPwwA|22Es1{PEr=Ctx}cBmlaC@`xBPBei@t>cki>Y zwpUowRs5gUaw@^^GKCk25`1@b-lQ7tQRj`wSZWIYL<@?*7WTJB$cOxPgOT$CV)hHL>W5*65TISE8WxCty4}{}uk;%qoJ*!?m{|n>2%^Og1qdr>O zmp)pJB|E*;h~J4pSq2X@j6Z2ayDegv^D-%JXb@XO_=`Js zu`4IxGnTBhliz7U9MMcgSvao4=)0%JN{g7du9a4T?I;$a3Xci>k*LBiq55QQfF;VC z@*Fi-)=X4f$sjeV1(j$?7iS`RVRA5c&w`z(=jz$XY31177M-+~_BIt0#p!JkyHBy( zYaH_t6t-IABFqy-uzS8R{`FQ{O}Y?`@zl3#_QT=1NPL2l;#VJlI+1A0A^Yr>?~3da<}XUL93(k_M~*1Ww@6J9aWio>Hu z+8RdDlNj!tg>?_9Gsx-RZoI!%%hMqPBa@m(W>LewD8=vnyIz~E;4GSHMSboqp&n0E zTSc-#aTr?Wm()t}Xh{*J_;#+M6dyFq1QRda1|ferCtUhv{r%`_m`IG==N9|T^CHGv zYrjdsZWT4tVt<%Oy*5RH(WOByH5>i+q5f&zP#^hUhB`XtF|CM>dAs4%F&~60AL!IM zP{`;lj`^(?$NU08zsM{(<{eg9+&9^^?whsHV=lUHG#2-bN9%1IotL7iZVuUr$O+qS zpCL+LZm7gZS!{HqpCu4{3tF=SH{e3 z`)gAO{0Er*`oenUJ7)nZ`-4&9MxTXfnNOi;hS*?#LMBxteD;^_;Jy?K1Tp`LP!ApR zzI-B<@UYsIF|U>L0al4(m>~fc(Fa!cHx^BV)wOI9=W*Ulc=vT}PW(pH=4!Yv)#gr< zSe>PgEWLl!!!fP95{&4Z_|VT^57v z`|NAWV*WqZ^SJ-RdX5%56r$tG@=BMn)0a2KMQB0okV^i$+6)hX!nw+5bEPnZ)EPnZP(J%i# z;u}oy$bNsZ_~nOK{PK=!*7KUhFF!hw`sHs^zkK_cy`7=Wk%QQ6a}c|2sha)RZ5zDT z&<8^X7tJCtr`Nk9Q<0Pdg3ZEiQZ`FSgJNl+&K;4HY;I_A-;COPJ{FCFvZId>EL zSI9Z;bNKghUIY%c^v<#}1_y)y5Ld=T9jp=IEzu-N2^eygwt7v)k(A{xLGixS|EVeH zJ>F2zQLIY(i%6$S%mx$OBSBhXCY4voJ7f9GZQjgNtc1+LEVKUZ>qh0MNTPjC>amI3 z!@v&u-xYMaGNx99qbp-x0UXq~winPc{|+@Nh-4WxIck|lp7xq$Ud&XO+9|md6-sfr z>vQzh{JGiI)HU~;Br3y6X24SGRb_1@mw%lVa5X2Sh^2-?tmG}_yturkv;My?=hQm$ zKdI-bh4Ol$rkhp`i`OBEZG-pbKak-jT2{dQ8}(d%thA%V&T-=?QHH-+E5lb1mtRqa z&#sZ-9dK<7!rm$C_zHXL%lb07ouM<@k zDbvzT7jeSs`Doikf5gN-OGf#K`H9jQagcSjw{5N-S6$^EuKj03T%6|~k5JBahimTg z@_dAIx9O^$Uro5eb%(Slw~k$2q~kR$4NQ0__oD%Mr|6vd&=Z>}xBbtk28I{Gn(M7qWY7} z-W+E!UCb`J+UqW6-;aygSN={HvnQdW8dde64}?HzG5ejyZ!hJK|4Avg{WnWFlY|>X z1;z;_T$A*Hi$2_mW1FR&^9 z?VbtWdr@Gp`)Ix3a&qZRut!Z^n9D|I1YRQ_?Ue&MVVDjRh&Osw{qjshok=4dmyQOu zxa8u8@8$g1OGp^F;dD=Me$F;^$YW3Pju8Y&T;+qGiQ@ruUGEu13W7cpl+RSpH}T;v zXw47KW0-m$+=Xdfkvx%tjz5q^JvJJR@}@0}O1jKtQZY1d6nlyfcYx`*G`HCc7KNj` z2)B}8K?P&tCepM2M3Q+$n-}bT*z<;C=#m6_jM}K``8#}B!8A(Na#KhGE}cV+-&l}4 zpl4~P^kv*(*o|M-{moxCK{`?5p3QAvup^DiO+^NIPna(RN+WmN5B=ej`bMR~L8p2E zpMFN%n!NejLM-2=q~8{R&X!<$vjWiLkAK`8`||`h)c8y~6L&;9h~6vqFdtxq4ll2t zv0PhtK8v^gG|+{OuMO#ubfVxYc55|jZ3v9rEwxWU`YPV#zq=>+@Wdeai+eKN#Kai_2B6iSvBr@cz(u@Ll&N7fVIHzH zvId@kmCxslGg^-Mq9#z1O&B!eQ6|8WNC(&W|SdlrOyq|gFlqn@4=Ze z5f-(BsRsbtWIy(656(5Ai@5{C_&$4pCWBsraxOo97D?dcbVPN(Z4yZv2vgtib)${) z2U75gV@lxBr_aV1eTm*ry>^{!-!X{4s9pozo^3I3@UxErg_{xgoPyI};UQcJ%RXvF z_BKzV#baT#DqAx|w%VMvBJ$%dWz9HrO%F|CkG)sGSZ`A~;Sog*heAiAnQd->!Kmk9 zyGLWAm#0Qn2KsIgLZZflZ4#%L{TMXBtrVP(%AqJaCYYSgd4m4z%#p{J5_i?2ObEW# zg1PAoRW2GRQu=`N(IUr+?%P1E4X9*)++@)AZ;{7t!GgzZF7qyAWW}w>cltF&P>igAw9drQ`b~>o4_xoyqsAb< zXIfU~gpFw*XzgxdCM>24-EUk3HJ;?A>i&k7gDwC%)Pv`fpv~>F&urwgDxwH8GW%Oi zs#AvFEY&-I2(o!;Ik0ceE?ff|$?iHi>#Dcj$Q*n<}T3RU8+2mYV>BE4e|~@4$T<8(!99m@9nt&!GXU=`dAx5-e4GZh!h+&qG2sQ9}|qS9sI{?Z#v)gjq8*W1My_p*O< z@?x`n%rg0wU>g@Gu;O<+o6_{t|cO9lfB zzSpBn)tU-6Q{$fzfL%l8h9QIx%qp$sAV$u>ge4g<=Qv?HxgHa3CgIbZgi!O4$8eb` z;mp&sudXN$D05N9e9JW_QCY>s88TydhFPetc1cjcuWmXoh~ddz76e(QimO`oWP{!@ zpCf^cx4{$l8e+0F*qUCoCR1@Oj=ioD?xwM;fV?Q%!o1)}#_E;P+1^I8U$N`rxJafV zBtw^=VUo9oRb@E}J>rxVYC?+qVn|TX48e>2T~p5>mnmXeENFhtI?k%O&%*MK$9$f1 z>@Qu$ZZK%>soA?ls|kLupV)s-nfo^QnlD(L-E$k8#WXuLJQ%^zpXyT;T4A?|ZvasOC zQwDAi9J|>J1Kpn;sp&XQi_4IM%wFw3;Y0G6E4t68^75yUnALb2{e$3l!+Qez4KR_t z_Tc})R>uWav&HP9_%`620<)jOIXKpKI`23Y)_(&b#B0VREjLPVy!kUshv9t=8q!QA z)lQxA7dG(S+w3qBcouH%fd@kLuC6#hZmgi$!Yj&D3mR(K{-j{vmpu=|r|26FzXO9- z&nHgUyn1@A%L5pi5I%gX!R0nf82u)6{u0(7O^)@&#~i})vw*W1P;?px_bj&~*D3DA6N7=kp}1NJ>|-zWl} zj>q6(8NYUuf$IVT`RR_^*bM(FZjxa;=Fh}Eo`JWyjz#RrC0(`bNV4c|)XrSyF$^eT zX!2}-xon?7-(9feKZFGCKY`z-H|^SS=E$OI#W92pixD=+28;W4U^>GsnodK=<~G^m zqKXVJJO$j#r6VTBI|g+DcNJ}Iy9{VfxzGcJ+H6hGM<(nmQ_vyhq*IkDTs%68uEWEZ zY~x#ctj}oW8}I_!|jb3)2RjXYw@Lh0a>UyuMUtWm846vAF zL@N>k=x@WK!^*P)b`@|sPZeN7F^%!KQEV;?k{R)ww;V@)1bxYJ;_m%pjBut0o>0q2 z&h&cV3Z;rc$07A6Q*R%A;sPAVvW)!V47sTZe!E>|C>>< zVjXcmiksikahG0GMo=1E7RB4bFTLD8;WP3Z3CiI@cMKI}(D!ZQvBRjm*{qXRxeGE6g!Lr2 zlBnQw*oN7lAowdWkeTQnM-47_*k!-F+Cudf0WynZ80e7sa3}tLE->ruCgd{h;g{}C zJ9FVz!j@^3G%i;TSNtm;@c0ssQQN^Lk4;yVRSz`#jBM>7s2+4B-Gmh}NjJW*D_O!-+ zTwMkG%jfYbIcrQ9DEzCDR-+!vx4qE?^y-YP2jt#rmS1itjr9BOkN39~@d`AxeBM`( z*_ZFT_6PFX@v~Rv9=5P||suL?I-g?ISB{i;c>~>Wr zn^~V9a0asC7J9S7GxbL&o_EB3pt6!-eEp~T2b)PGn_U)A8O+VBVv1qEt(n7p>zMO0 za#_`e?aq*MCn2b@JFjUO87Yey@vYN1=TERxx9m$?f0koPbDC}fS%QsTEj;)@Ho=F; zTm)GXRCHxklL{fZ%(O0AY2003NH~ZZ%up~d91YQeA~HJ2Wr3a~PAX=0SE*7BjQxhv zRHOgHBVF(Upz^x+(b9T0#!BTFTxUFu+WX9LE4*=?SBF{h07YF%5nqW|`f?^)ZJZL*^eYOxq$Rr3Lo(FxssJri2XR8pZxZ z=65QFK~PU{bV*CN^rdHudmCL4fPa-3Z8rXP0=@{SQZ?aOTSN(N2@XGbslIA>VaAFl z$Cqt>8ud*^^7ELmr1LSx!v~IBFFxX>$sQcBY_y@8BNvxFUFF%qJMF@8qE^ZK<7T_5 z-CMLau_M}#TI4hTdr_kHz$19*zMLxQ!V|Z;KD=45k@tMqrB!ZbE_heAX zKo`VkG9WC`1D}`{?Uy*AqD4h0NgTAakC`}Cdrt6!PJuTrmk z;;r&My92t;l%4b3lp#=NhiXU z4oCHr7Vgvm_FxeA;z^x#P}l&A+_~Kz(Gx8*5+9lY-aq=GcX8M!P5du5a{=dL#Z^_@ zpi(`v-&CgX7&D_ZwDX|y>pMcgc~@9^GUPD>q-Ve@ZMO={<4A$AMeH{$yqNpA=0^2> z!;MOV257UR&tIBH1Y4M73~u9hu$Le|4^8x(ZMry2oL6)H>)V7=XB#;C+7r7XxP?6R zD3WAx%ATkRXPkq+#C~~p<%0wCDgJ=2S`(d*;{@hYQwRiZOWBgNDr{l=u$+C;010EQ z$&UXb5;p{AgYnHzDq@!AO!W%8CU+|tak2TgHGy*pocqxlN#iv=m&Iv?d*h8l-+&YwXA!dyON^D1G3cAG z4U~zoYl@^V82>AriM0jiDmZ%>r*$Q&HeytyuoV1AC&F%+l>W|`*q>2n#YmJ6%EWCf z#E3gzH{!}Xz73xdW|-W>KkAzqo|81$H=Vl;b_;>UX#7&J4o^IjXA5MYXXlGg(G|Vw z95cAtH|nTwE*64Tc38S-;$j^~WDjtrbr3@`737*U`NPWa6+}=>*iK}&4!P{X#$6lf zxxRvO5Y1H+p`p670XO+r>RKU3ed4)OLG^^vZrq1``g7B1S836%Kviu)?d+6kmd4kduzL`;I zWUKuIS#~^oqOp3HFaa?pIMQFk>Uk3?ewrnmd`tc*Hk)a0Y^{-rtelm+dq zaPK$w@wg*nImZ7q6q)D`(DvOB+i5tCt@sxv8xLHoDwSIL2YVplIJQg+Rj3LwaaJ39 z2?1tENUy|Z*Do6O`gjxA;e{tyZTwB(I#(m$j^0r~phzJ=TpEE8!$2!5tDN1apIBJ| OWL&msYjwAW)&B$85c?ni