diff --git a/bindings/python/wscript b/bindings/python/wscript --- a/bindings/python/wscript +++ b/bindings/python/wscript @@ -6,25 +6,17 @@ import shutil import sys -import Task -import Options -import Configure -import TaskGen -import Logs -import Build -import Utils +from waflib import Task, Options, Configure, TaskGen, Logs, Build, Utils, Errors +from waflib.Errors import WafError -from waflib.Errors import WafError +feature = TaskGen.feature +after = TaskGen.after ## https://launchpad.net/pybindgen/ REQUIRED_PYBINDGEN_VERSION = (0, 15, 0, 809) REQUIRED_PYGCCXML_VERSION = (0, 9, 5) -from TaskGen import feature, after -import Task - - def add_to_python_path(path): if os.environ.get('PYTHONPATH', ''): @@ -38,7 +30,7 @@ def options(opt): - opt.tool_options('python') + opt.load('python') opt.add_option('--disable-python', help=("Don't build Python bindings."), action="store_true", default=False, @@ -76,7 +68,7 @@ available_modules.sort() all_modules_enabled = (enabled_modules == available_modules) - conf.check_tool('misc', tooldir=['waf-tools']) + conf.load('misc', tooldir=['waf-tools']) if sys.platform == 'cygwin': conf.report_optional_feature("python", "Python Bindings", False, @@ -91,20 +83,20 @@ conf.env.PYTHON = Options.options.with_python try: - conf.check_tool('python') - except Configure.ConfigurationError, ex: + conf.load('python') + except Errors.ConfigurationError, ex: conf.report_optional_feature("python", "Python Bindings", False, "The python interpreter was not found") return try: conf.check_python_version((2,3)) - except Configure.ConfigurationError, ex: + except Errors.ConfigurationError, ex: conf.report_optional_feature("python", "Python Bindings", False, "The python found version is too low (2.3 required)") return try: conf.check_python_headers() - except Configure.ConfigurationError, ex: + except Errors.ConfigurationError, ex: conf.report_optional_feature("python", "Python Bindings", False, "Python library or headers missing") return @@ -161,7 +153,7 @@ try: conf.check_python_module('pybindgen') - except Configure.ConfigurationError: + except Errors.ConfigurationError: Logs.warn("pybindgen missing => no python bindings") conf.report_optional_feature("python", "Python Bindings", False, "PyBindGen missing") @@ -197,9 +189,9 @@ try: ret = conf.run_c_code(code=test_program, - env=conf.env.copy(), compile_filename='test.cc', + env=conf.env.derive(), compile_filename='test.cc', features='cxx cprogram', execute=False) - except Configure.ConfigurationError: + except Errors.ConfigurationError: ret = 1 conf.msg('Checking for types %s and %s equivalence' % (t1, t2), (ret and 'no' or 'yes')) return not ret @@ -250,7 +242,7 @@ ## Check for pygccxml try: conf.check_python_module('pygccxml') - except Configure.ConfigurationError: + except Errors.ConfigurationError: conf.report_optional_feature("pygccxml", "Python API Scanning Support", False, "Missing 'pygccxml' Python module") return @@ -322,7 +314,7 @@ """Uses gccxml to scan the file 'everything.h' and extract API definitions. """ after = 'gen_ns3_module_header ns3header' - before = 'cc cxx command' + before = 'cxx command' color = "BLUE" def __init__(self, curdirnode, env, bld, target, cflags, module): self.bld = bld @@ -393,7 +385,7 @@ """Tasks that waits for the python-scan-* tasks to complete and then signals WAF to exit """ after = 'apiscan' - before = 'cc cxx' + before = 'cxx' color = "BLUE" def __init__(self, curdirnode, env, bld): self.bld = bld @@ -415,7 +407,7 @@ class gen_ns3_compat_pymod_task(Task.Task): """Generates a 'ns3.py' compatibility module.""" - before = 'cc cxx' + before = 'cxx' color = 'BLUE' def run(self): @@ -437,8 +429,6 @@ return env = bld.env - curdir = bld.path.abspath() - set_pybindgen_pythonpath(env) if Options.options.apiscan: @@ -489,9 +479,7 @@ grp = bld.get_group(bld.current_group) grp.append(task) - bld.new_task_gen(features='copy', - source="ns__init__.py", - target='ns/__init__.py') + bld(features='copy', source="ns__init__.py", target='ns/__init__.py') bld.install_as('${PYTHONARCHDIR}/ns/__init__.py', 'ns__init__.py') diff --git a/src/antenna/wscript b/src/antenna/wscript --- a/src/antenna/wscript +++ b/src/antenna/wscript @@ -21,7 +21,7 @@ 'test/test-parabolic-antenna.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'antenna' headers.source = [ 'model/angles.h', diff --git a/src/aodv/wscript b/src/aodv/wscript --- a/src/aodv/wscript +++ b/src/aodv/wscript @@ -23,7 +23,7 @@ 'test/loopback.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'aodv' headers.source = [ 'model/aodv-id-cache.h', @@ -37,6 +37,6 @@ ] if bld.env['ENABLE_EXAMPLES']: - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/applications/wscript b/src/applications/wscript --- a/src/applications/wscript +++ b/src/applications/wscript @@ -32,7 +32,7 @@ 'test/udp-client-server-test.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'applications' headers.source = [ 'model/bulk-send-application.h', diff --git a/src/bridge/wscript b/src/bridge/wscript --- a/src/bridge/wscript +++ b/src/bridge/wscript @@ -7,7 +7,7 @@ 'model/bridge-channel.cc', 'helper/bridge-helper.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'bridge' headers.source = [ 'model/bridge-net-device.h', @@ -16,6 +16,6 @@ ] if bld.env['ENABLE_EXAMPLES']: - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/brite/wscript b/src/brite/wscript --- a/src/brite/wscript +++ b/src/brite/wscript @@ -1,6 +1,8 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- + import os -import Options + +from waflib import Options def options(opt): @@ -89,7 +91,7 @@ if bld.env['BRITE'] and bld.env['DL']: module.uselib = 'BRITE DL' - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'brite' headers.source = [ ] @@ -100,4 +102,4 @@ module_test.source.append('test/brite-test-topology.cc') if bld.env['ENABLE_EXAMPLES'] and bld.env['ENABLE_BRITE']: - bld.add_subdirs('examples') + bld.recurse('examples') diff --git a/src/buildings/wscript b/src/buildings/wscript --- a/src/buildings/wscript +++ b/src/buildings/wscript @@ -25,7 +25,7 @@ 'test/buildings-shadowing-test.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'buildings' headers.source = [ 'model/building.h', @@ -42,7 +42,7 @@ ] if (bld.env['ENABLE_EXAMPLES']): - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/click/wscript b/src/click/wscript --- a/src/click/wscript +++ b/src/click/wscript @@ -1,7 +1,8 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- import os -import Options + +from waflib import Options def options(opt): @@ -107,7 +108,7 @@ module.use.extend(['NSCLICK', 'DL']) module_test.use.extend(['NSCLICK', 'DL']) - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'click' headers.source = [ 'model/ipv4-click-routing.h', @@ -116,6 +117,6 @@ ] if bld.env['ENABLE_EXAMPLES']: - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/config-store/wscript b/src/config-store/wscript --- a/src/config-store/wscript +++ b/src/config-store/wscript @@ -11,25 +11,29 @@ def configure(conf): if Options.options.disable_gtk: - conf.env['ENABLE_GTK_CONFIG_STORE'] = False + conf.env['ENABLE_GTK2'] = False conf.report_optional_feature("GtkConfigStore", "GtkConfigStore", - conf.env['ENABLE_GTK_CONFIG_STORE'], + conf.env['ENABLE_GTK2'], "--disable-gtk option given") else: - have_gtk = conf.pkg_check_modules('GTK_CONFIG_STORE', 'gtk+-2.0 >= 2.12', mandatory=False) - conf.env['ENABLE_GTK_CONFIG_STORE'] = have_gtk + have_gtk2 = conf.check_cfg(package='gtk+-2.0', atleast_version='2.12', + args=['--cflags', '--libs'], uselib_store='GTK2', + mandatory=False) + + conf.env['ENABLE_GTK2'] = have_gtk2 conf.report_optional_feature("GtkConfigStore", "GtkConfigStore", - conf.env['ENABLE_GTK_CONFIG_STORE'], + conf.env['ENABLE_GTK2'], "library 'gtk+-2.0 >= 2.12' not found") - have_libxml2 = conf.pkg_check_modules('LIBXML2', 'libxml-2.0 >= 2.6', mandatory=False) - if have_libxml2: - conf.define('HAVE_LIBXML2', 1) + have_libxml2 = conf.check_cfg(package='libxml-2.0', atleast_version='2.7', + args=['--cflags', '--libs'], uselib_store='LIBXML2', + mandatory=False) conf.env['ENABLE_LIBXML2'] = have_libxml2 conf.report_optional_feature("XmlIo", "XmlIo", conf.env['ENABLE_LIBXML2'], "library 'libxml-2.0 >= 2.7' not found") + conf.write_config_header('ns3/config-store-config.h', top=True) @@ -45,27 +49,27 @@ 'model/raw-text-config.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'config-store' headers.source = [ 'model/file-config.h', 'model/config-store.h', ] - if bld.env['ENABLE_GTK_CONFIG_STORE']: + if bld.env['ENABLE_GTK2']: headers.source.append ('model/gtk-config-store.h') module.source.extend (['model/gtk-config-store.cc', 'model/model-node-creator.cc', 'model/model-typeid-creator.cc', 'model/display-functions.cc', ]) - module.use.append('GTK_CONFIG_STORE') + module.use.append('GTK2') if bld.env['ENABLE_LIBXML2']: module.source.append ('model/xml-config.cc') module.use.append('LIBXML2') if bld.env['ENABLE_EXAMPLES']: - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/core/wscript b/src/core/wscript --- a/src/core/wscript +++ b/src/core/wscript @@ -1,8 +1,7 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- import sys -import Options - +from waflib import Options import wutils def options(opt): @@ -49,7 +48,7 @@ conf.check_nonfatal(header_name='signal.h', define_name='HAVE_SIGNAL_H') # Check for POSIX threads - test_env = conf.env.copy() + test_env = conf.env.derive() if Options.platform != 'darwin' and Options.platform != 'cygwin': test_env.append_value('LINKFLAGS', '-pthread') test_env.append_value('CXXFLAGS', '-pthread') @@ -173,7 +172,7 @@ 'test/watchdog-test-suite.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'core' headers.source = [ 'model/nstime.h', @@ -309,7 +308,7 @@ core_test.source.extend(['test/rng-test-suite.cc']) if (bld.env['ENABLE_EXAMPLES']): - bld.add_subdirs('examples') + bld.recurse('examples') pymod = bld.ns3_python_bindings() if pymod is not None: diff --git a/src/csma-layout/wscript b/src/csma-layout/wscript --- a/src/csma-layout/wscript +++ b/src/csma-layout/wscript @@ -5,14 +5,14 @@ obj.source = [ 'model/csma-star-helper.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'csma-layout' headers.source = [ 'model/csma-star-helper.h', ] if bld.env['ENABLE_EXAMPLES']: - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/csma/wscript b/src/csma/wscript --- a/src/csma/wscript +++ b/src/csma/wscript @@ -8,7 +8,7 @@ 'model/csma-channel.cc', 'helper/csma-helper.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'csma' headers.source = [ 'model/backoff.h', @@ -18,6 +18,6 @@ ] if bld.env['ENABLE_EXAMPLES']: - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/dsdv/wscript b/src/dsdv/wscript --- a/src/dsdv/wscript +++ b/src/dsdv/wscript @@ -16,7 +16,7 @@ 'test/dsdv-testcase.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'dsdv' headers.source = [ 'model/dsdv-rtable.h', @@ -26,6 +26,6 @@ 'helper/dsdv-helper.h', ] if (bld.env['ENABLE_EXAMPLES']): - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/dsr/wscript b/src/dsr/wscript --- a/src/dsr/wscript +++ b/src/dsr/wscript @@ -24,7 +24,7 @@ 'test/dsr-test-suite.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'dsr' headers.source = [ 'model/dsr-routing.h', @@ -43,6 +43,6 @@ ] if (bld.env['ENABLE_EXAMPLES']): - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/emu/wscript b/src/emu/wscript --- a/src/emu/wscript +++ b/src/emu/wscript @@ -36,7 +36,7 @@ 'helper/emu-helper.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'emu' headers.source = [ 'model/emu-net-device.h', @@ -52,6 +52,6 @@ module.env.append_value("DEFINES", "EMU_SOCK_CREATOR=\"%s\"" % (creator.target,)) if bld.env['ENABLE_EXAMPLES']: - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/energy/wscript b/src/energy/wscript --- a/src/energy/wscript +++ b/src/energy/wscript @@ -25,7 +25,7 @@ 'test/li-ion-energy-source-test.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'energy' headers.source = [ 'model/wifi-radio-energy-model.h', @@ -44,6 +44,6 @@ ] if (bld.env['ENABLE_EXAMPLES']): - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/flow-monitor/wscript b/src/flow-monitor/wscript --- a/src/flow-monitor/wscript +++ b/src/flow-monitor/wscript @@ -17,7 +17,7 @@ 'test/histogram-test-suite.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'flow-monitor' headers.source = ["model/%s" % s for s in [ 'flow-monitor.h', @@ -30,6 +30,6 @@ headers.source.append("helper/flow-monitor-helper.h") if bld.env['ENABLE_EXAMPLES']: - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/internet/wscript b/src/internet/wscript --- a/src/internet/wscript +++ b/src/internet/wscript @@ -2,10 +2,8 @@ import os import sys -import Options -import Logs -import Utils -import Task +from waflib import Options, Logs, Utils, Task + # Required NSC version NSC_RELEASE_NAME = "nsc-0.5.3" @@ -210,7 +208,7 @@ 'test/ipv6-address-helper-test-suite.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'internet' headers.source = [ 'model/udp-header.h', @@ -294,7 +292,7 @@ internet_test.use.append('DL') if (bld.env['ENABLE_EXAMPLES']): - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/lte/wscript b/src/lte/wscript --- a/src/lte/wscript +++ b/src/lte/wscript @@ -114,7 +114,7 @@ 'test/lte-test-mimo.cc' ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'lte' headers.source = [ 'model/lte-common.h', @@ -190,6 +190,6 @@ ] if (bld.env['ENABLE_EXAMPLES']): - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/mesh/wscript b/src/mesh/wscript --- a/src/mesh/wscript +++ b/src/mesh/wscript @@ -53,7 +53,7 @@ 'test/flame/regression.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'mesh' headers.source = [ 'model/mesh-information-element.h', @@ -90,6 +90,6 @@ ] if bld.env['ENABLE_EXAMPLES']: - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/mobility/wscript b/src/mobility/wscript --- a/src/mobility/wscript +++ b/src/mobility/wscript @@ -31,7 +31,7 @@ 'test/waypoint-mobility-model-test.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'mobility' headers.source = [ 'model/box.h', @@ -55,6 +55,6 @@ ] if (bld.env['ENABLE_EXAMPLES']): - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/mpi/wscript b/src/mpi/wscript --- a/src/mpi/wscript +++ b/src/mpi/wscript @@ -1,7 +1,8 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- import sys import subprocess -import Options + +from waflib import Options from waflib.Errors import WafError def configure(conf): @@ -39,7 +40,7 @@ 'model/mpi-receiver.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'mpi' headers.source = [ 'model/distributed-simulator-impl.h', @@ -51,6 +52,6 @@ sim.use.append('MPI') if bld.env['ENABLE_EXAMPLES']: - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/netanim/wscript b/src/netanim/wscript --- a/src/netanim/wscript +++ b/src/netanim/wscript @@ -18,7 +18,7 @@ 'test/netanim-test.cc', ] - headers = bld.new_task_gen (features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'netanim' headers.source = [ 'model/animation-interface.h', @@ -26,5 +26,5 @@ ] if (bld.env['ENABLE_EXAMPLES']) : - bld.add_subdirs ('examples') + bld.recurse('examples') diff --git a/src/network/wscript b/src/network/wscript --- a/src/network/wscript +++ b/src/network/wscript @@ -71,7 +71,7 @@ 'test/sequence-number-test-suite.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'network' headers.source = [ 'model/address.h', @@ -135,6 +135,6 @@ ] if (bld.env['ENABLE_EXAMPLES']): - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/nix-vector-routing/wscript b/src/nix-vector-routing/wscript --- a/src/nix-vector-routing/wscript +++ b/src/nix-vector-routing/wscript @@ -8,7 +8,7 @@ 'helper/ipv4-nix-vector-helper.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'nix-vector-routing' headers.source = [ 'model/ipv4-nix-vector-routing.h', @@ -16,6 +16,6 @@ ] if bld.env['ENABLE_EXAMPLES']: - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/olsr/wscript b/src/olsr/wscript --- a/src/olsr/wscript +++ b/src/olsr/wscript @@ -20,7 +20,7 @@ 'test/tc-regression-test.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'olsr' headers.source = [ 'model/olsr-routing-protocol.h', @@ -32,6 +32,6 @@ if bld.env['ENABLE_EXAMPLES']: - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/openflow/wscript b/src/openflow/wscript --- a/src/openflow/wscript +++ b/src/openflow/wscript @@ -1,25 +1,32 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- import os -import Options +from waflib import Logs, Options from waflib.Errors import WafError def options(opt): opt.add_option('--with-openflow', help=('Path to OFSID source for NS-3 OpenFlow Integration support'), default='', dest='with_openflow') - opt.tool_options('boost', tooldir=["waf-tools"]) + +REQUIRED_BOOST_LIBS = ['system', 'signals', 'filesystem'] + +def required_boost_libs(conf): + conf.env.REQUIRED_BOOST_LIBS += REQUIRED_BOOST_LIBS def configure(conf): - try: - conf.check_tool('boost') - conf.check_boost(lib='signals filesystem') - if not conf.env.LIB_BOOST: - conf.check_boost(lib='signals filesystem', libpath="/usr/lib64") - except WafError: - conf.env['LIB_BOOST'] = [] + if not conf.env.LIB_BOOST: + conf.report_optional_feature("openflow", "NS-3 OpenFlow Integration", False, + "Required boost libraries not found") - if not conf.env.LIB_BOOST: + # Add this module to the list of modules that won't be built + # if they are enabled. + conf.env['MODULES_NOT_BUILT'].append('openflow') + + return + + missing = [lib for lib in REQUIRED_BOOST_LIBS if lib not in conf.env.BOOST_FOUND_LIBS] + if missing != []: conf.report_optional_feature("openflow", "NS-3 OpenFlow Integration", False, "Required boost libraries not found") @@ -142,7 +149,7 @@ obj.use.extend('OPENFLOW DL XML2'.split()) obj_test.use.extend('OPENFLOW DL XML2'.split()) - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'openflow' headers.source = [ ] @@ -160,4 +167,4 @@ headers.source.append('helper/openflow-switch-helper.h') if bld.env['ENABLE_EXAMPLES'] and bld.env['ENABLE_OPENFLOW']: - bld.add_subdirs('examples') + bld.recurse('examples') diff --git a/src/point-to-point-layout/wscript b/src/point-to-point-layout/wscript --- a/src/point-to-point-layout/wscript +++ b/src/point-to-point-layout/wscript @@ -9,7 +9,7 @@ 'model/point-to-point-star.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'point-to-point-layout' headers.source = [ 'model/point-to-point-dumbbell.h', diff --git a/src/point-to-point/wscript b/src/point-to-point/wscript --- a/src/point-to-point/wscript +++ b/src/point-to-point/wscript @@ -16,7 +16,7 @@ 'test/point-to-point-test.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'point-to-point' headers.source = [ 'model/point-to-point-net-device.h', @@ -27,6 +27,6 @@ ] if (bld.env['ENABLE_EXAMPLES']): - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/propagation/wscript b/src/propagation/wscript --- a/src/propagation/wscript +++ b/src/propagation/wscript @@ -24,7 +24,7 @@ 'test/itu-r-1411-nlos-over-rooftop-test-suite.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'propagation' headers.source = [ 'model/propagation-delay-model.h', @@ -41,6 +41,6 @@ ] if (bld.env['ENABLE_EXAMPLES']): - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/spectrum/wscript b/src/spectrum/wscript --- a/src/spectrum/wscript +++ b/src/spectrum/wscript @@ -41,7 +41,7 @@ 'test/spectrum-ideal-phy-test.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'spectrum' headers.source = [ 'model/spectrum-model.h', @@ -76,7 +76,7 @@ ] if (bld.env['ENABLE_EXAMPLES']): - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/stats/wscript b/src/stats/wscript --- a/src/stats/wscript +++ b/src/stats/wscript @@ -1,13 +1,14 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- def configure(conf): - conf.env['SQLITE_STATS'] = conf.check_nonfatal(lib='sqlite3', define_name='SQLITE3', uselib_store='SQLITE3') - if not conf.env['SQLITE_STATS']: - conf.env['SQLITE_STATS'] = conf.pkg_check_modules('SQLITE3', 'sqlite3', mandatory=False) - conf.report_optional_feature("SqliteDataOutput", "SQlite stats data output", - conf.env['SQLITE_STATS'], - "library 'sqlite3' not found") + have_sqlite3 = conf.check_cfg(package='sqlite3', uselib_store='SQLITE3', + args=['--cflags', '--libs'], + mandatory=False) + conf.env['SQLITE_STATS'] = have_sqlite3 + conf.report_optional_feature("SqliteDataOutput", "SQlite stats data output", + conf.env['SQLITE_STATS'], + "library 'sqlite3' not found") def build(bld): obj = bld.create_ns3_module('stats', ['network']) @@ -25,7 +26,7 @@ 'test/basic-data-calculators-test-suite.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'stats' headers.source = [ 'model/data-calculator.h', diff --git a/src/tap-bridge/wscript b/src/tap-bridge/wscript --- a/src/tap-bridge/wscript +++ b/src/tap-bridge/wscript @@ -34,7 +34,7 @@ 'model/tap-encode-decode.cc', 'helper/tap-bridge-helper.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'tap-bridge' headers.source = [ 'model/tap-bridge.h', @@ -52,6 +52,6 @@ module.env.append_value("DEFINES", "TAP_CREATOR=\"%s\"" % (tap_creator.target,)) if bld.env['ENABLE_EXAMPLES']: - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/test/wscript b/src/test/wscript --- a/src/test/wscript +++ b/src/test/wscript @@ -16,7 +16,7 @@ return test = bld.create_ns3_module('test', ['internet', 'mobility', 'applications', 'csma', 'bridge', 'config-store', 'tools', 'point-to-point', 'csma-layout', 'flow-monitor', 'wifi']) - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'test' test_test = bld.create_ns3_module_test_library('test') diff --git a/src/tools/wscript b/src/tools/wscript --- a/src/tools/wscript +++ b/src/tools/wscript @@ -15,7 +15,7 @@ 'test/event-garbage-collector-test-suite.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'tools' headers.source = [ 'model/average.h', @@ -25,6 +25,6 @@ ] if (bld.env['ENABLE_EXAMPLES']): - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/topology-read/wscript b/src/topology-read/wscript --- a/src/topology-read/wscript +++ b/src/topology-read/wscript @@ -15,7 +15,7 @@ 'test/rocketfuel-topology-reader-test-suite.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'topology-read' headers.source = [ 'model/topology-reader.h', @@ -26,6 +26,6 @@ ] if bld.env['ENABLE_EXAMPLES']: - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/uan/wscript b/src/uan/wscript --- a/src/uan/wscript +++ b/src/uan/wscript @@ -34,7 +34,7 @@ 'test/uan-test.cc', 'test/uan-energy-model-test.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'uan' headers.source = [ 'model/uan-channel.h', @@ -64,6 +64,6 @@ ] if (bld.env['ENABLE_EXAMPLES']): - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/virtual-net-device/wscript b/src/virtual-net-device/wscript --- a/src/virtual-net-device/wscript +++ b/src/virtual-net-device/wscript @@ -6,13 +6,13 @@ module.source = [ 'model/virtual-net-device.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'virtual-net-device' headers.source = [ 'model/virtual-net-device.h', ] if bld.env['ENABLE_EXAMPLES']: - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/visualizer/wscript b/src/visualizer/wscript --- a/src/visualizer/wscript +++ b/src/visualizer/wscript @@ -1,5 +1,5 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- -import Options +from waflib import Options required_python_modules = [ 'gtk', @@ -38,7 +38,7 @@ def build(bld): module = bld.create_ns3_module('visualizer', ['internet', 'wifi', 'point-to-point']) - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'visualizer' # Don't do anything more for this module if Python was explicitly @@ -61,7 +61,7 @@ 'model/dummy-file-for-static-builds.cc', ] - module.features.append('pyembed') + module.features += ' pyembed' #module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS']) #module.includes = '.' diff --git a/src/wifi/wscript b/src/wifi/wscript --- a/src/wifi/wscript +++ b/src/wifi/wscript @@ -75,7 +75,7 @@ 'test/wifi-test.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'wifi' headers.source = [ 'model/wifi-information-element.h', @@ -144,7 +144,7 @@ obj_test.use.extend(['GSL', 'GSLCBLAS', 'M']) if (bld.env['ENABLE_EXAMPLES']): - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/wimax/wscript b/src/wimax/wscript --- a/src/wimax/wscript +++ b/src/wimax/wscript @@ -63,7 +63,7 @@ 'test/wimax-fragmentation-test.cc', ] - headers = bld.new_task_gen(features=['ns3header']) + headers = bld(features='ns3header') headers.module = 'wimax' headers.source = [ 'model/wimax-channel.h', @@ -113,6 +113,6 @@ ] if bld.env['ENABLE_EXAMPLES']: - bld.add_subdirs('examples') + bld.recurse('examples') bld.ns3_python_bindings() diff --git a/src/wscript b/src/wscript --- a/src/wscript +++ b/src/wscript @@ -6,14 +6,8 @@ import types import warnings +from waflib import TaskGen, Task, Options, Build, Utils from waflib.Errors import WafError - -import TaskGen -import Task -import Options -import Build -import Utils - import wutils try: @@ -47,13 +41,27 @@ help=("Build only these modules (and dependencies)"), dest='enable_modules') + opt.load('boost', tooldir=['waf-tools']) + for module in all_modules: - opt.sub_options(module, mandatory=False) - + opt.recurse(module, mandatory=False) def configure(conf): + conf.env.REQUIRED_BOOST_LIBS = [] for module in all_modules: - conf.sub_config(module, mandatory=False) + conf.recurse (module, name="required_boost_libs", mandatory=False) + + if conf.env.REQUIRED_BOOST_LIBS is not []: + try: + conf.load('boost') + conf.check_boost(lib=' '.join (conf.env.REQUIRED_BOOST_LIBS), require_all=False) + if not conf.env.LIB_BOOST: + conf.check_boost(lib=' '.join (conf.env.REQUIRED_BOOST_LIBS), libpath="/usr/lib64", require_all=False) + except WafError: + conf.env['LIB_BOOST'] = [] + + for module in all_modules: + conf.recurse(module, mandatory=False) blddir = os.path.abspath(os.path.join(conf.bldnode.abspath(), conf.variant)) conf.env.append_value('NS3_MODULE_PATH', blddir) @@ -75,10 +83,10 @@ static = bool(bld.env.ENABLE_STATIC_NS3) # Create a separate library for this module. if static: - module = bld.new_task_gen(features=['cxx', 'cxxstlib', 'ns3module']) + module = bld(features='cxx cxxstlib ns3module') else: - module = bld.new_task_gen(features=['cxx', 'cxxshlib', 'ns3module']) - module.target = '%s/ns%s-%s%s' % (bld.srcnode.relpath_gen(module.path), wutils.VERSION, + module = bld(features='cxx cxxshlib ns3module') + module.target = '%s/ns%s-%s%s' % (bld.srcnode.path_from(module.path), wutils.VERSION, name, bld.env.BUILD_SUFFIX) linkflags = [] cxxflags = [] @@ -119,7 +127,7 @@ module.use = ['ns3-' + dep for dep in dependencies] module.test = test module.is_ns3_module = True - module.ns3_dir_location = bld.path.relpath_gen(bld.srcnode) + module.ns3_dir_location = bld.path.path_from(bld.srcnode) module.env.append_value("INCLUDES", '#') @@ -133,7 +141,7 @@ def apply_incpaths_ns3testlib(self): if not self.source: return - testdir = self.source[-1].parent.relpath_gen(self.bld.srcnode) + testdir = self.source[-1].parent.path_from(self.bld.srcnode) self.env.append_value("DEFINES", 'NS_TEST_SOURCEDIR="%s"' % (testdir,)) @@ -142,7 +150,7 @@ # the module being tested. library_name = name + "-test" library = bld.create_ns3_module(library_name, [name], test=True) - library.features.append("ns3testlib") + library.features += " ns3testlib" # Modify attributes for the test library that are different from a # normal module. @@ -154,7 +162,7 @@ bld.env.append_value('NS3_MODULES_WITH_TEST_LIBRARIES', [(library.module_name, library.name)]) # Set the include path from the build directory to modules. - relative_path_from_build_to_here = bld.path.relpath_gen(bld.bldnode) + relative_path_from_build_to_here = bld.path.path_from(bld.bldnode) include_flag = '-I' + relative_path_from_build_to_here library.env.append_value('CXXFLAGS', include_flag) library.env.append_value('CCFLAGS', include_flag) @@ -162,9 +170,9 @@ return library def create_obj(bld, *args): - warnings.warn("(in %s) Use bld.new_task_gen(...) now, instead of bld.create_obj(...)" % str(bld.path), + warnings.warn("(in %s) Use bld(...) call now, instead of bld.create_obj(...)" % str(bld.path), DeprecationWarning, stacklevel=2) - return bld.new_task_gen(*args) + return bld(*args) def ns3_python_bindings(bld): @@ -197,23 +205,24 @@ #debug = ('PYBINDGEN_DEBUG' in os.environ) debug = True # XXX - source = [bld.srcnode.find_resource('bindings/python/ns3modulegen-modular.py').relpath_gen(bld.path), - "bindings/modulegen__%s.py" % apidefs] + source = [bld.srcnode.find_resource('bindings/python/ns3modulegen-modular.py'), + bld.path.find_resource("bindings/modulegen__%s.py" % apidefs)] - if bindings_dir.find_resource("modulegen_customizations.py") is not None: - source.append("bindings/modulegen_customizations.py") + modulegen_customizations = bindings_dir.find_resource("modulegen_customizations.py") + if modulegen_customizations is not None: + source.append(modulegen_customizations) + modulegen_local = bld.path.find_resource("bindings/modulegen_local.py") # the local customization file may or not exist - if bld.path.find_resource("bindings/modulegen_local.py"): + if modulegen_local is not None: source.append("bindings/modulegen_local.py") module_py_name = module.replace('-', '_') - module_target_dir = bld.srcnode.find_dir("bindings/python/ns").relpath_gen(bld.path) + module_target_dir = bld.srcnode.find_dir("bindings/python/ns").path_from(bld.path) # if bindings/.py exists, it becomes the module frontend, and the C extension befomes _ if bld.path.find_resource("bindings/%s.py" % (module_py_name,)) is not None: - bld.new_task_gen( - features='copy', + bld(features='copy', source=("bindings/%s.py" % (module_py_name,)), target=('%s/%s.py' % (module_target_dir, module_py_name))) extension_name = '_%s' % (module_py_name,) @@ -240,7 +249,7 @@ if was_enabled: features.append(name) - bindgen = bld.new_task_gen(features=['command'], source=source, target=target, command=argv) + bindgen = bld(features='command', source=source, target=target, command=argv) bindgen.env['FEATURES'] = ','.join(features) bindgen.dep_vars = ['FEATURES', "GCC_RTTI_ABI_COMPLETE"] bindgen.before = 'cxx' @@ -249,7 +258,7 @@ bindgen.install_path = None # generate the extension module - pymod = bld.new_task_gen(features='cxx cxxshlib pyext') + pymod = bld(features='cxx cxxshlib pyext') pymod.source = ['bindings/ns3module.cc'] pymod.target = '%s/%s' % (module_target_dir, extension_name) pymod.name = 'ns3module_%s' % module @@ -305,14 +314,14 @@ if not_built in all_modules: all_modules.remove(not_built) - bld.add_subdirs(list(all_modules)) + bld.recurse(list(all_modules)) for module in all_modules: - modheader = bld.new_task_gen(features=['ns3moduleheader']) + modheader = bld(features='ns3moduleheader') modheader.module = module.split('/')[-1] class ns3pcfile_task(Task.Task): - after = 'cc cxx' + after = 'cxx' def __str__(self): "string to display to the user" @@ -448,7 +457,7 @@ class ns3header_task(Task.Task): - before = 'cc cxx gen_ns3_module_header' + before = 'cxx gen_ns3_module_header' color = 'BLUE' def __str__(self): @@ -517,7 +526,7 @@ class gen_ns3_module_header_task(Task.Task): - before = 'cc cxx' + before = 'cxx' after = 'ns3header' color = 'BLUE' diff --git a/waf b/waf index e1e34d431afba28d52add07a6094226a1a74374b..e2fce435bc1b6982b9df8c5510c28da6bdd72fad GIT binary patch literal 90486 zc$~Djby!qu+c%7e2*QDsNC*rJLyUAv=KzCrNH+rvFvQR$3P^WJh=_D|mqB-Th?IbY zBA|fqt--zby`SfP-{bx3n}eCP)^(lN8NV|ZUV`&IxVs^p96{!eRv>p*1PJK}a&>Y?TOzJk06FGpZ;-VU8s*9k@dmI!uW8|eyi0GMHT{72liP5)CDK%%9CITD3HbKbeb``iS0|ZAG{iNJ~v# zTUS~W21G1KT~qA|Tn;7&lF061t$t7^kxTI?XWs;sh(99&g_9VDZp4N_Ip1}Vc;;MxG0wi^32kjMx z!*BpySshK73Pv-)S}h$JEp52Ajy4RWpr$5w4W|}N^9fuQrX>neR@1u1L`Mt84oJ|J zz7`Cy0005DF}CPv!LOl#t7^kEHFear;cBXEcNEoh0pkH3rGcYz*BGj)UYiQwpr)yh zVT!@v8e(>kt|AOr*TldESf#BgjR8YTTN5s;{ckcrp0=8%Ht0V#f>dD&%5Vjksw@n% ztA^pC3)h0N0Um(^nkfK~UW?V024w17n~d=Upw*w-f5jgAwZA}cd62Z+6F5fgKg4$c z4{O2yiiT^*WEKB{oAbJQ-a(?AozOsD17*?G+x5;Jz;Z1B2609nP9aWVpuEBWet#AO z5j=wY{FXdI7Uukd7Q+0G`1yJG_$zxGX8}WjD=%<` zu-viqv;v6(QaEi8ZooY&+Z{V6pg>$NIh(uLa$+9u+yUZQUYy0#+?wT%6~Y>1!Ro~( zat9x%mF{Rqkk=igHAYEJTZESf0*%Q*32rYwZp_CTAp83)AIly5f1Up4IOlb9K>)I^ znIq6>RuqN+NN`6tR#p}xZazLkVIC9=jdntdfFQ2d3*0Cc5Cnu`W4nWok&W;|y0P;7 z#lqdu+1%3J6p(3!M6&{43_EL#Rn7=URt&j0+Q!3>+nAjNZNUO?umtv4ES=D3cV{=C z(OB97RS3iiv0?*M_OwMhAV54AjUAAV2!PU>6OAyp!aM*v#%K7PPw~ z2oTQUfGOC2ikUg47z5=EQ>HN;22+#)5(nh9d<>62%*6qCSis`q5=M?J*C^q;dAa?! z%)f;Kn}1|l0$}j`z4LEk5W^pqV&dZ0EdQbAy{5JRDDCh3AKCE%1b>7BzlJ;_96ZJV zUuOq%O9ZP0t1J&2JBBfaDcir-dH-5R1M7DH&VK^g)fVU%4nWH?M_U7U0-Vv_B7d!N zqET*W1mfCJckmHjmI%NLKneWgZ)bB?*FWTdzCe=%d0|?ZA&a(?lY=V@JBS70<%TwQ zWih@+3y52kxjoQi(XOnR*u^jfX#Rql9puIK-y(o>7@HYo%^fiy{D~fncL1MQ0K$O2 z1q7X=3Z@TZRsr$m*Nw;A!U59`(FjX7C$u*sfZ4SPcQ9I5+WsATfbuA3On|v@TKMn+ z5#{!GBm(Q~ES}d9a1DnWCx$D66~G%je25hik9=fs*rYR{t1w zP4I^fqX`i2ZU_`Bi-o(R57LGaXzbj<8|}S=u51=&xrwi)&?F-JP%F2Z@wm;Zo=f#P5A{lDVp+CX6L{1ZF>gpC&v)BM7G*YW(nYn|A?Yu$A%!W2#b zJ;VQwKQ?2~L(tzOn6&?s9M(uLXK!ANJ=Zs!z~!Idxeg|GMf0POv_;j~Af9T5(EyqsDH zH+djLq}~3^eF#_GKN5KVN61~XzplRkh1=g{_b+jnI0OdG|3gk<67ug}@ORfSw{XQ= z|IZcSe~1G7Y-I|tVa3S0o;IO7S-h@SU@L@&>-DP& z6VSMT*$L(KhM`KQc#VlojU1*7j@9pT^X{^ZSnP60bE?m*>n{i}f~}3I0DA^fx{jPS*+o46cI%0{}bdx=RB+#qIjF z2O5jVIFCHW-a|{)hKf8 zHP)-EtJZe6fUEy}u)=J4|Y?+Lro#V_lmfq!TSg zLqKh2~gw%+7=4`;rq;Re{XRnv;F73nVo+-=khtdiNH+T zq1e}x@b-QGQ{PWmSYOC*ZdKyk$iE@MScr=ycHVy2k40_w6%6@G7gX6L^NiXSS$wi( za)OwChh?h>hQ`^B?aD+TpG82VvK1lw?}u(!KVxO%!0Lw<;?8}&&Cs6Zykaw#*vj$x zgU)_~(I<-{ZE-NvDmQVXCwymr`#bHjcw46Dz+&AlYQM~Q<3PYyuz4TVzO}-8?zzH3 z*7mW+Z%cG%3q8^{wd8vcx_r72%f)?T{p0-70nytc5E!~M_lBSU%jn*z|4fsFfv#!< zi)X`|SXohvXWmQmZA&^hn#shh@i$rv!O+tR-|>Q(v9BZTlgrB|!^U z+ewq+icJmtt0%1N<{fgnhj=~a&1d&V{SHcAzj(ZS;P8!S>D0+EAE)s=XvS2{vCgRh zx&5&|jwy>h)Mmx2dwBPKEIR)bT9(((z4K37P z{YTK^qX*@S?!s+a?pX+x z7ayrfoG*PpAMk2$J|sOPEI;KqIh~I_L1i~Lp0VCF*|%>)C69Sluy|%JvG0nu)q4#u zWVoxOo%GBbE@bEqZ!L@N+E1Sy_j%x9gP~YL<_ab+ZQoY7e_HzZ!vAY?$;b5>Z}*mZ z!p|pL5~rC5&unzd%j=W}Xv9W$^X3|CZksRoP7MV!WM(wvpLCyZvfZ`GSnMy^xa-;Q zQe0~oM#Ym3hCLK*?qfe z!h3ti9=jE9)CJyPQTv=M?;jX6ey}@>bjOQ1sL$a#^P)1XVKJL{M#CHoM!{m1%F6XY6x= z9`Rp3-!&I&nDE{2QKg>oEFWGQdGZ~n&CkBaJUlqdq=mx(ze})!(J^UIhDt zoHWiT4z`8uXquXQTz7CmczWEN8g?w(j_omx)|j}w{4;=z=~ziI5E~3p5oCqezE{Rg zl$YX1#_{_+`>Pz`z=@-=h^id3f5^RLEo85nS^WLU{aZeX1d;*hO=|9Sc2s>8H3U{%92 z(xk%Ifa`vw_}dY*9rW#fqEYRzi^{#$$yS5MR+nQZnQGs2`wkTkQd>Kp3201X@k8U5 zz>pt~P`K)E7cTr)y!8apv$_pN$f}k?q0;8G!p{z`wrXvuYgCX(TUv@F=u9SRe`kT^{^8j|y8k zo+=k_(ArYIhAkbZDl9GxET3pb%*+rSL~0eurc5J10x)5ZU{F#YqTsr(K}OxPrPeG$EO1k7EyGE7PE6d67hoYZ~!O zw}Uy91M+>vP{G_P6x?=x6qaZg4U^8D0z+`*riksp5bCjdc0NrS+u+i8)<`Y$q--{v zu}H#6O)Wcn>gWWeYFNS?(jFyXXA6c<5Npm0>M0i$ky;|s%@eH4GBlEz2j>K9w2LzI zvw5fZ`L@F#`>T^32y3$l~i{N!6`g6?xM(LM5M6khDrk^G!AmJo-(#l6+ca>H<|-o}fj39+f~a*nAosoUsFJUxBGqR02^b}Z0>mHfLsnja58Ezojr|pC@xJ!uFssm zpI;-sG`FyZjEtJOj}i8^OFab&<<}@qSLWrDN+M5(RbsvABZfrd)>x6ki}1jZh<+>n zq%<%jp(@9mb#}oj2tVasHW()!DG-TcNytjgI>jcdtx>9EZ7b6ShbTjpm5Rw!_ zhe>LbTq*}dnkkRutui^Y5>vuM`2}J_26%1`yi~^0YD_y_g|fujA`M=h^0t^7p3KYZ zpr=V3Ou=qot;DQBk$8`dU1@S2o>W>SAFWYpPidYVAAN&de$uwIGsg=1S+}CRO0foI zMAD@85DaFUqfwt039pa8X(!mHsUc7LEI!FR8%LvBi`Dkc0FZJ}c6<3~<}xZ)>oEs2 zp2FFI3{CDF!r_)Dh}$7X%=JNeF5-nZBax?rMr?t9ixlu}F(~ zHr9M=4Xb&6HfpG{Uag_M^@3)%HhVgw5`u=BJ%ag7Uv;=0Q-mFd?OP6uTD!Mns9Kcz zP+3@=iqe3ELoNYcZ9?})^>AgU`-*dUa_Y+6-7-mUvL$~nJpVyki~fx{N@{;S=mc&2P1A4fk_Ail$Du!S z?JrHww_d9K{IQ_&SXdS>OyrS>JQ&hTDa$|}x>1==xp7&QOP?tT;d{7f%ntskN!`-H1*bD$QTF6wOUmBA3gXnCfti0GP|7AtCAt+g4(2Mety z-gN1W9YG}%PP`laN?W`EH_?K<6AKX@5d~K<^lKekwiA!3@=5q_!zHZC6F+Z1t*LO_ z#i5qT9XtL&F#W9<3~|9@c8RJBvZ;#?4Z`LYpP!SQDZ`zY^Qj4$zlWS9xQ*ueg=@b= zLVeoKE;X2k%PCM7IUY@{t3%_8C{9@#(NwL`AB3PXyBA_!C*)wL3KU< zFgi>U@=$2Om+FC$PLFFyHT3tS1ez}UiLS5p+cYK-gft$kV+n+75KC-c!c&)f zwhL17>ozEiEA3{Ul?s1ypAnD$jR0`28|U)fd9=^( z=9^B`mR5`#k7fCD)9~XRCft+stx9@eKO^T;|swxi`cdEln$p;dFW zY(l0l7(PcM^`gGFI!(H=_^L`^S`buoA4NR1@mngG{Zezk zdvEsxfm#OO$?lkWjjHIYRhJGKd5`#vvOY@&AXUvzE=e?Ua0`MX(adqP?O^DJk1Hg4 zyYW@2T}SwaN6lV*J)xNozgkpuRmCrhZ=Q99Wl!R~Yg(5yNMJ$Cfik&2Hs$HF#08## zp)rIi#h=CgH7Vg^Mnb^WM$U-JD8#_i7c6uaV{YBfd(!)q)c$_EUChM&mWHNn$U%(4M-ARh}-Et1G6-`$r3n_&?%9)9r37 zclsX6*`wH9Qs9lU8Va2ZQy(2fH2J$Fs=<)D-8eGyJu5j4pJ$9;C)7U$n-vpS70y8; zlUP3uye%}OjSWGXPxr+-u`H3kh;)DX(xxGaxUOgWc60G<&IA$30&LF8$d%1KT)Mar zMf^&CD&mYAZqKP{?7DvStmW~C;>r7~$kSTIItZEme8~Mh)MU@&nQ(zsLiAFY^p)Y_ zWnYD|h!s(vG()+-!NyPTAf7GQ`fr32#VSntrv3e`sPz$n*R%s#4t zJ!owlf7bG`314VxHg40>%o^v3+v%|JPmj16<9x1s!%d(MRs25t%tLswm zVE(s6YfYfur>+D5;1 ztV!wO*P@!NLWDGaqlZLR^B*b-;|<^mwI^G?L;a3(_*IdiJKHPylH!*;R1_Xsjh5hb zBoPIp^2OWU*nRiq^m6`Sl`4ZnxBB2An_}HkOKl6{K`R4}e*l%!nohNQP3O%#)y$uT z!LfJ2Q2w-;Vz&>P(OtK|VUl~3T`RWZFIN3ClnN3<6oNE)!4RL!zUZGaF}3NJm1|4C z4JT}9Hf4vlcBq4FQd%iIf2z5!Ihw(l&ie0NNJ#J}e;cG@G4SBp_Yise#iGA2yLCts zc$s+it2?AbJs{}I&^Fz)f}u)T*VHK59X;Z!?v#2I`HSj=Z|QZ3aC~Xj!{~w^9qk|G z)a7V09Z;viy8=t8%~r%;LGO8fzvvq@Bn7K--cAYf@uo=&Qa_WN2(A>PwUr82<#4k$nj z@KL#YgRfs!j>(SItG^w*uzNmj9|eXA#>%(RTYq;n;c0fcAJ)TAzhtBCpXwB#t@{z- z2Hq-L4YFIMd-colh0~Y8d|T%W)0-#1l?jKvw{Lg=HUe&v4dS+H{CX}3FWPOeJNHcaN7<0jUxPe%98t!ma;;I?Cz81 zZeB2wAC-A@57hO&_UDd0S!GVHGmXm#k&`gCsM(Bd4)y%$?iYH>4$hytAGgwud{3K- zzn3zq-;$Et(I(t2I6}gD<|Ejno0HMmw-)zBJL(ul2q# zCX>@oV9t`=m=JyQ@CEVydK1a=;s{AIgG4bm5 zVBBj84|1Z76$qAVK+_HMk3dHH_5`8s$A0@8KV42INw!Y3b%P~@($eC~4RTZ}^s*xF z;R;TGAl-jkoiFKwNuoZF@I1`&RhhuOCO2*_PgzSToeaMN@s z>!ee{J0X6&g(NU%YNv3qt3sdnC{IIC=#{!$vM^9G=ss!^CkisG-e2?(!yonL5-9ol zk_>?!mdeFqASV%fxLIoL($KiSMw%cuBhGV8e_H1`DjF|bq#a$T?uk{U!>nk?q7OuJz{56B;VB- z!U!qR!M!z7<~@y4+5I_B?N=%WeKe22{wcvQKY-||iQgz^T6h|VJfY`Zcs#s6qga!x zdl$jDvP43E-@-48!g-=;G}P-o&xVS+8eB#umC>>A>4CuTsk^|?KK0KDEPm*-vq`qb zPyu1l=BazHZPlmO-@f{l{`}q=k)L>cdZSi0=_a{QlpI$TNS1+7;z6?M+yzI(jW4vm z3a@zeWSM*(oyf@QI#%(nE|9*-_@J>V&bcyV;^ks!y#5`3!$8%}iQzkBf(ehEDZ*3z z^Fr7T`nT9pFbWbg$^T~V=C>b*%|;(?%x%liTL1b`RT}QC342MTTdT|XtnB+B(kIos zt%g#5l?qp-X7X1L=|pkBd8EnOflOEdNK*!Nu@2ko~vFp;DFH zxn=awx<(;4ng#KD^rAfj`ja0e*z+!wbm;EK{opidr8ubsE$$>Cyr+FD$0c`}U|7MQ z(mKuQ1r!A=`n(&(-Rk?#pIc3Y1xN_%r`@L`e-gz%93@b6(L_Z5K-QnR6n~lBJY$~g zO9U4LY}wUE+^^8I)1Eq?mMe$n7DV#mCsgUhDa%{M(;PUhJJ^z_fR4Iz?txm3-u$_D ztv7BO?ZgL#^|bw~`-AXRWAo*riN}{hQ=}29d3+tAd=pa|`aqg@3-W~8*57?q=kw~| z<##LHvNghmTLv`xuli_F7gS@f0>~wW+UcfSN)JLqG)VB7gIR23Dk?Y*2I?wl@jue} zdcxpMwHC;yH%^8i=-r`u*m&q?Bk|H5nG$4(u5>;Q4AL zk@h0Or?{^7!eKaT2VkOC!ad156fmgH*OnrkxBJVhe`z{7wOe#!OLzG=aH#!8_C?v z(TEoYItjnto7g9w)fJDKPxhKQcirS(`y4z@cHddj)K1DX5%X#iHHs2$yct76xOL;n z+RpArf}`_I3$?V0oUKbWd%v5KXxHdWVj0n|FZU*T{eob;si;otTFlx3TOVLmjvFGu59BuoWk6@;U*az zmRveG-#ukJ*R$Yn+qKwP(P4DlkGh0`B#{5h^YGGU>}k89Jh9 zO%fGkU_HOtZO%e$T+M#*0Kvb5dhpa!bSUSHR`_%v(1>{jC9nmCRuD(F@2-BF&w@^+ za;G`ITBTO0fLw?^mOqFY(Of_3)J%05>%X6AD|w_}Gs5#ZFblh^v-4uZ_<7?`>7Ls} zeGuyJ@ovL51bvB#tFrMZ_~ zu$NF!xX+3psn1??j8<~obEAW+2TO9b4{e62>Xm<7hR=|%2vF;b8O}6H z9r26vZ@7UsA8YUxU9E4$a*rAP3>MEdTZAwA^E~HCt}J!b$SagIf2n}PZAEz zU>|*gENQmMjkph14CnXt%RUH^RV6W1?w-Gv%m;};PrQK@y5u{Q}|FO3lWy&ynwZdYT52LHP+8dw`#fF z_Hd(;wWNHiB68U#totDzCOj`VSG1UR7f4e0pEA5a`m`U6oEk)|Qkn3BCl*jQCb z3F|2qi0n63&?q^mJm0`sBC}S!39cd^kv149M%t|Z8Rq6InLeX>RO8@tr6y@A0=ja4 za1tZ9S+08J00|&^y0WiTFxf;W^I0J@fb4!7A1K>V$?9)N2^)%{mbO#NFmNmLC@zT;e96> z6mhQ28;_5Yx{{Vh@csNGV^Z56Mz#3W;AI-V&351v1VhP$aEHCtQZtolk2<&`rfJ*P zQ+jVzZ>ClVJmKj~GC#JITf69w*m;L=9WHYGc3Z>ewbAqoC34wih3D|;+h1Q_R6eaf zf&RMffO5BBO3t8&%q(kaywdXQ-D|1dj^4Z;@djOEQ^GNp`)eamu*?RvI9^aDCfXoH>k-#U`VeiNRnJitQ= z2gIIJ(3f2oWu#{?&IRy94G>gZCYYZWjsYd&Wkg5eV>MdE>1TEa@5 z8Ma($gGh~d>=oz+-c|rsOR1~S)0_QTWG$C5YXUDS z&=A*lA~}YHGYTrT#X0N2;^o%y{judawpPU#f%m{6h2czp+)`N?gdFA1_F0W0g zu@sJy2zVKU;yQ0J>Xxc59_*~h;K=`Q%1ysz-I!pxnS(NH%Fs63Qch~u(3?=t8V6z&ntnUV5sLVMD^C#c7WKz{OiKXsdU7HgniQBce0P*Bj?6! zx89SzvA*pzgMy{f9GqLU>K}iTR88+Vyu6oAV6Rj06YDBukUlOItDn!-R#`!-*VTMs zm_8s}|3(dWnRPviyy#Zu{_8gdG-nbnM;A)CV8~VP*}F4G1Iuq4?b-P1{_%>T+zBq$ z^uB>p%)Wevy@BRh_WEVD;iL|B}6I6jATrT&1 zY$NlpM)HD2<2Y7iKcF(F3?S%o%i9sPPRV|c!MARygBT9P+N>HSoc0X4v#SR)OhYH` zm&FAq-~{6-xcdbtMIwcsx+M+0IvuM4QSjnh(FU9B9Swc_IAPWI;>tSUGxht;zy)uYhU2XGzTW!JaCPgvdN|YV z$7RS(<0vx8murDV&%zZ8QVZqV60$db)`Fpo#8Sjq@gs;>uli@>Elj!jTSo7>aC2@5 zEIavLsOiofj5^W#_Nsp+oKlL)cvoQth7v2jVhb~v#z)iSex|7idaM$S)uUhwr$J}b z4fnJQnp0R=n4BtWs|cO6c79CL-HvK9I@{gXoWx>pDJf89zyrBpg*ZrlZZ~uh;`w?tZA%qpZthbzNSSi(%f~aG+~Kht_&r36024yBM3_rNqP6MD0)rWpoWx zUb%;{6^)SX(0SN(iQ#K4XR^0sWLC6si)YoJrVnnsfqF}5tGz1qS|mwF=%mqDMY-0(%dkSlVkt`5`_P`H%h?_}Jk5$5busbA z8ed`pdAfM{%=&JJd>^vEv0YS$w|a)&r^s&bVJxF97uGrp?cTwadpJ?t!(!d9X z>}~D^Y-r1ZA#pJezD3{$E{P1@SUJd`JJ{Vx@yZb)lWo+Y5$VJQRn_Onixd>owR!#a zOBZ9Vhy)2Q*eZW#^f(iU3vPeH)%SgnkR#!xg6#T6NAYj%w1Ne{J)2f$Ifwp-0~9S& zWq5_i7NSSDM&IA$d+bXq+Nm_Q=^VLpOIcqL|I`gCzV% zI>z!>D%y^kYYY>I`*MGYZ=AD{gW!>GLw&LDtt>e?eBNFFLpCzsP*gAuG^XH(kW1Ds zPfGPV<~~~IGk7aq+lgJ<(KFaBs`(O!H{xC|+lI);66`5zTmIfh0-v{(bIdYOR-oB@ z6=uua7%5987clR_+i6?XczCMc0e$aYr||>v-_wP?2USiBAjLpp&Y9itY^D(9U|v$3 zDDb}c+dPFGZj|d{Qu^AV74EP=hBaAfP$oP*D9!5ig^v zeqk!((~u%zYxk`$&p47<*Jl~-abrobnZbCTegC!TH#tjp&|WfMxBr7p?=ZAsv8|-+ zsP(k1W}e74_?gRNWrV}x1MfDS$QmsI#;Aj`99qqMCAbci6jVM`B&=gXyM=sq1c%-R z$7Lx#@x!-iK`n#hUE2>2UvhK$b!W``&UK~n8`3rgmd`Y`I)kBU6b02B_ZEttWEg2x z9~n2_2NNV2^U!x3&MOzYhux+~d`;@3?76$>)o%19EsJrIuiSh*+!SxV?cvB1OT}@b z)5lYv$R0eXHdIXWSn9n?e6GxDpdjAz5owM~%()q*8V`mnQAo?xXAX>$1tVf7KRY1j z3PzGW3pj{Zzq`Nqd;kGzx7e#WNU~M-PWe}<$(CbpLui12#DuI*AhU4a&c-%$)4gnV z^yJy|PSc#AoUcw67sn4RP2^nphCKzIR=vla`NqNVp;Z(T(xV`5S-W6=*7LG7CgZV> zpO}=$@{g5=zBu?Besps0a(Fh(I>8Xuo~85OUFJ;s&j+dbzE6FqxLB9Kceoq+%BS@K z)pl0UmOZbDJI{~b>Ed~>%A~%~UmT9m^+n7dbJ(rFm?OMzQ+tE;1shYZ3~7_Vl5S>G zE}WWnp>m@MTbT)makN!#*5&K#tA}0w8C=mydrq$xK()o~`Hd)C&*WbHU9p*x$z(&a zQ~Lpu^jQ^=FFj$T;y+kqRmO@(B!o(y(3D5mGR%`9M8J?7Tl?hHoSSVh7N)G7v_A9M z9YZZ!)}O}jW^1;MKWsJe#Z_!D-Fnd#bg#GWA;KVHGO!-ccq$5F<{O#%Ec_FELiC!O-To5Hj%nt(`RVIZ+P?Ts?ZBJr?)ZIod~p& z>W~lIgQD8V?9;p3mD)KhC-jwYc_^d_9P^)~q@LoaBN^(`Lg0ZrV4H>)7$bz`*ew&>kXH`9eB2kO|dluX}uDmHoM{9uU5#weot679S5urNp&=PMea%5Ur4)7-SqQWE z){e|>&W((sk{Sa1my8Qw=z3iGi^47fZf6NN|GmA`s+**TCOB^enMo5Z6$lRyyy;$J zj7_N@6-djsjwiU!=LP~;6k;@B8RG*3i-hkrwkm74g_z($b@i^bCbykg-0}=q$qX`! z9^pP+Y>QAW9sf)){9q=TX9FuTi~P07N;m6F3)9F>q6Ss_2w$(A~98 z@Nf5sc}Cs=CqG$%Gzy>84F8z-?~nbfY(D(R*7|+fJ^aDI$Ces_%LEh`_J}&_FB{&4 z7W^~HJUY+o^k&^7YOb+vss4hK<}EUM`xf5x-!x*(!kH~N#^qr zHwsd_Sy2pr)}{*E<)an zB>u9G!Uv|B1v%gxW!0}DUu=gh<)I2?6;$h|c-aj8m07hi;hX%Cgf#391f5D30uQAN2K0zb0 zm-;qRYW2-|FLuNlFehW$t;%G>*HV0=y%V}ug$&aNOr1-$l!coMW;3xF!9CcPd z5!=3MqKq=K^D21`_Bj`(Lhh(wdu3&^CyJ>HmVTd0Ojd1ksD4OYI$& z&gKrx`mxUUjP&^-9%|MthF_K}e0r{Bdgi?O77UpqodHE#4!7*WMtreEDRV$Ku$dkj z=|QM}^;M`nG4QFaMhh&{56x$d=pXnpH7l4HdX;OLRE}nR3MmlsNWW|Eue0S+>pI_fkVD$jWMJ$B!nUX4Okwc6+_g=8RMuam%#>MEh0^}Qm&Pv0 z&2pj!6*j8L)qefb_NSHDp$ngLZTD$sH(Td^$B^9PGw77CpV6sMti>L_0pse$hqEj8 zjP!@E)1885c>5}yVWgZh4+_LZ+`S*>A#WNqe_-=+UHtTrJSmWQd0A=cQ+l1~QN^OG zR|_@MV?E-%fd&rgY#P5uEry9P<>AUe8)8Pv4k9 zv95bL-H*AMaB1_U{k7{?f#tnqBA*wA1-H%icRWYc+T(apB%!@ zE*-O9heo`>nHSe;AVBQ==6;r{qyodaI6U3e0*BR^O8u>O-;&aqMoAL4}- z0VF;s7-CgPdFArEe5Dm9sMhvs5e&Uwx3Xl{X$P;^{T;Bqd%_rEC_pNe8`7YxzL%5c z5p;0M-i8nKjpqs^I=MglgNoikpRN~a;8o6Ql*;>L8sOy{Bsw8nDdUSYJ9B>%@ljDb z*j-vU)bk+7dqbAucRoI|1Vi$G{IuS(?)Xl)u2XRreynvt$W>2= zb4k&LbUk=wUe8P48SX&N(yno{-%e`ARH@;@H6`YNjEHJo#`7Jb(kFt@>GR860_JLM zX!;CaPeAj@U9QjaflsFc!=!=~;;tehdrEsg;&sn57kbNV!Q{ohLtcs;Np9k!l!Wf?Y0t^}HZ&V=K!rq{&Q%M-8jX3F;M>gWB+RC7J!6Tem^S_JVCDNyx1QE}EmEXvr(*r}Q-gurB_{|N!q>bYGer6g9 zZyS&O{%w1PqJeF(-)uxFHorSVQZ}}mZa75yN;}F)1wIN|$s9vrmWd1E5qvm(n! z^C$hK!sm@Ie!{sVSdnjYXuGTegPAnl92njmrbCLx|%j73(DyN1C={7AKrPe0X3ad}LHU|6^j{L4c>CpaRj}k?IS)^*{~C zO83;Vr|8oMxeXpd%1lIQoSzt}kc&&*3&nyJG#((yyJIK2)9oYWOKUvsYo1^T{5(0s z_EMDELaGn(=SLr(#K0~ zL3$wio#QW-I}f#ACQcNz^)|bkf8D&eQZ=U*X+Mv@;tE|<=)Em*{>%GJvuW#x4aqmd zmZ_S}ONkO*;t|ugtz+W?j}R-r8x@q++*%om&mvnSP5eaj`jqEin~_c5E)RZiox)5laMb747JEv6Rf9Xd(s zwO%jOwCA2|>!%xX&OzwJ@^cloT5N7~2=K4LWXoVOr;#UMXclhJL()w~!o}jvGqJB} zZN5!J$kM$6M<;TQ0xIiV=fG_Vi3({aDlv_b-&XwYb7F2my3!>x3;>efzq}av5 z&wMT~!Y+ghFFVBjucXkm@4B|jB{_W#-uUb4)A_3&d1ow(zzleD&(F`Y!O%(FkEh%g zqT4nzFDoR!7CX{bpIlx#FKJdjQs7%U!`=^D77KJkHFSCOK7#W$p4fkzatF(`?s>f1 zH;r){Q!xMj%UB@by5L^IQko`?yVit(V4`=zsG zpurg`NwQ&n^Tzk~TjI7byl0qygx?~Kkn$h77wK=Fv3}z7?4t$Ca;r!vozYXaZ93D8 zmd`ySJp&n8v%W+MUp->LX}`WCmaf~iOUb=OPejk2U#k9Ud@*+!V`7&1IVkbv_m*cn z`$r0~yGx~Dh(uOR#vYy2$Fm-imGw^&-!>xr*#^?s`)hA#9gjy2iqku(Rvq~VI63xn z#J1cg2=VjM+0IJP_arL+eg$it-l?Gzyh|w3wyd?>C6+~3boaLY-9aIXPlXD@yqpWf z=~CxUZ?`6~4DIcjL5tTV*((rV&w8I;l-veGZm%x7_VE2AWP2u!zkNEWHGBN|Sr@7F z12P7!jzHutP1(iv=E~qL{aBV7=dU{x1>1=czZNVjZ@<@-ckh1rwCGE|RiD32vHKX4 zsN&8=2cmX}Nx|gTud?o;zzSTKy}PTiA=-AW9(%`!1>7|{H&vNG^xlx4Ee=ePOYzdc ziH+m7D=A5c;=0civiU~ah&*z~MbMh;hGyoQ(cLa?!jOj-ByZjB1t%B#Y?i!eyBK}N zLFaI=@@3KNYxTkpk@-i~F^7V6XFbB|TB0SjoCn#mD3xf@L|>lJ9}cM4(ufc;Z>GZR zPspYIi+9%45@l(giVFDjM3Soi9|h+WTnV#<(M&Q?B^BGr$q7zu+qP}np4hgN6Wg|J zdt%$1```DjUDZ|neS58!j@_>Fiog{?i&5>HNjSAe#5;G$OR6DedZe+cN;dyeYb-05 z-|i9Fyt?YHBJvts$kCS|dk^O2lSx0XCGhdPv17q@54w-;JsZ!DG7qwJWtpo6o=L%~WkG9tjaZz1Hx*xwWm{{Qa{xfM7&~cx zE3;5yYuc~nZM{XNr{XjmIR**3=v~uw4$v+4b1hWoM34!H~M6sZVlUI12y(iR|Kf z7hR3wr2J`IR`UC+5+lGbb@I_z1ON%d=CY3+Fs26KT5O!SBGrVu#Aq38Nw*WlTK5Lj zY-hZD9U3HwI4D^Bv6B`PURq@qs2a#^uD{{do2zilKhb#p_)_m*XpHm5&@0(>T3hHi zUywXrxh`eb4OZXl*rlO1Qut#CauXrD4ke(!yd+PzD)-M_#DGjhsrNfAs*#YGa6r)Y z5ZWK|<5Z#gkc=XFvcyj}7{Ln|x&Af%g!_K+BiJw)&>IlZ->Ms%+C~aV3=^@0K1k)4 zsibL&=T#EHo)&Qcvm1&DE)i~2oyP>@lctPqIOtcyv^F ze9Kf7-k3;KOf_{g2R{{~oyr9h$xwG7{5e$^B`NUvEPv?t!)2M6oAc=9<-#%A)Nw!> z&z#^>n8J=7mf=%UyE=24OPYKs>cgm~^nLm(f;PqCzxGKQh# zT`tqiYq6(8V?~;-Gy^jXB`E_+F*amOJJk}4I5ZU9p_hKDNO}16s5p{W_+r>a?sxvW zp)1YThqf*!cx4o!O^rnX{csZ5SWt_fP9{zD$;@E%kEZS8_1|j?*1bGg41XlWQ)ri* z*`66eqXeUsop*me`ip?e>(3uF?%;8s_ded2xH%1bFemTl*#7R*H(JSFZ5#`cyus`& zK@YEGhP;u)A#xo@G%D&I0Cbh&Yg};I0(KDR8sIwv%5u!~V#?|RlT@XFY1R9>|gS|^p@AdMa>6^aK61%(nuq*#Uqlclm}qx~16 z)W}#iP*I6l4fWDW#3GS=NS(FZ4aOeEM$nkPPBu@sS4CUQBW*V@^Vo|kmq00;`DMsU zT&bI4lIn;=Ntm>>wxqTvb(PNRvQw_d`B!`!V zmB1~-{biS5-$eLx&{Ov~H~l%U)2- zjKL>~h@dqt=&<^&N<=z7wG0Bd8%GFq_6H4Qg{mdX#!g9xougffNnawuEKiu46&_#` zvEE?ls>H!O;g^oG+&*L`uP`RCP8_c^cHisJX_ZQ#^%c&8)?-_3yp~yqc<%o=0M3^6Xm~cax zuGW^9Pxm~z@q`W`h2`bTW7U~!0PV9(vMSH*dB>ipjj58^#)z@|s>^f>r{(1_?|I%W z6Yz^jp0JJI2< zvWJIHLVmSqXb9FS%v7%K@z+X|2Nk#4rdb5o*K{J0_$3Kh=2V9n#S9{ffmoRkq)EJFtl(Yxv;T|Ks)F;^2Y7k+d|uTv-FeL6C5zrmEQ#C@Z7= zVb{`+aHOdTFoWVYSZ54e-H~&b3{LW z%2`0>kp3Y1F2p*Y>@)X#p4#0FsL>Y>1`s0RWH6 znuLSxKeZY%%m3oF&LOoUCavOB7>ieicJdg(B&3hd5rcC53;`-4S=y(+Xyxd`+- zf#iF5bdpD*hKnGo`AHfj5AlWQ-Lt1dmFO*YXk(kIKo9SBdRDwTKvb(vIRM1tQH|xk zONY6aMw0Oov8grE@z*v`9Wk<2!uEiP=+_ic zGmEYRbi_oN)henD4Xzmsqb<%wD7R*AEITdLC6Z;4h%^CnU{)@*T#PekX#EK$YCuk!gTD5fBDxyzRo!nZ51`nSAzo2EJafML?RMn z7e6UGS#2d)z>fLNW|6Y;MwS5jxCNP?$=GZ&v{^?k|C(=V(4#`0s@SI-dlpOw@^K_i8rgXaG7>gLDe z$S*?Bq!Y!{DsnC1;FNk}UtaqB{eBj=!h@jC(blbJoW&rc!;Ic9Y+^lzPBBfdL* z=kHG*ULxI*yV&vC3TXXq4X2Qc0ARxus2UP{T!IO3F{x;5I;AYCUh>9#D?Swm07n79 z(tcZSr;E+7(R^WXEhq#vyN0!yF#ed%|1i&r3ob$;p~OIobpb#IkCZQ~oUXXJz@y{7 zgiG2dA5s9w(L-NqBmiAm-4^9*URtN`jU={v3(Kx=0!53B(SCb?WXF`HHl9>GZrX%b zo8&UaM0%>Qb%+QrbPRvi={dy2j>X2s6N~-GcEn2m1UI!b$1V{poK^)XzJ4H=vWyf8 zEURK;ZlPe12i{H3`ptfC-Ug|az4JI!+v1T7#nJU!7Y)fd{<&C8U1-jZ<(4!}Lh}%& zQ!pm8lX^so0XN0pVq_F-2;S*Vw#?(L58NfOe&X%2g|ku=GMO?Jq+HqSJ@>k1+Ky?4 zY7`ovgtI^$56a3v-jJCADVTS!b3*{2lwFM4u1)z4$B})G1lIDYzspdFf7pwr_zMb# zw8AMx`e)w}NGU7@6A}oi4x=#`(mp^RHu~?&>vZOU^U2zChpPCQQfe{hJJr($iV3M3 z^_jpw|M87tv)fh_0%l`&Ylb!(G-m57o%0dT1suDHC5>VV@2H(fm*d9p>iy38Xt2@l ztW0P2G>3&kv>?YN&{dR*d#Vlya5!}GRvCcd?B>OIza| z7T;NEgJpr>N}`!;Y%3jsA6P6qlL*~JD|hWx|7v<|z2K9m?ijrlPCoNjJ?Y4yMZf=5 zLlM_{Kzs}^y$IJ%lZXmfoCN?cHuE&(B~jE?KVJXU_M| zk2=Q23FT9dd_LrKQ#bq#G7F*kW|znC^7epdeG)31E2(remU3A$-^yDu8aMbM0=N~? zVR3A(EAG+lW$k=5pJXU}_%;)14*+)Rbv}DY=^qcn$tDb&vx+2zQT#jSm=UY4{?vU8 zY#w=%qSnp=0PQ(ha%3Z|Mn%f_BTcwwWEWW0RYYWzjZ7tM`H*~$yx zS3xSELyHKmkwRxiOZ{e7qg>u}H)%{hpN&P9*JAWQlXKx+Yu*k3qysA^laJnf9PYUD zl2mcd#*2zjG9_#aoIN`CaM^0w0EcqTG!*N#l|3*47t6 zZ1;Fkz>OV|W@%CSj1oS;s=ee(^9!Q#oy6W|&lJ=d*$B7TeZkwduWhMcl6`Av|p56$;v$15!TL2J^1#(Z;tK#v+ zEqga!xd%Sa9J0%%t9gLucB%$YuTCuma+7A4=#_#W0P6o8xU_;1T~NG(EmsQh?LjaNBYLzLEPVa?xpntCCr>tUq!5`qIler^m4?9Wu-{2rR3{wn!>;K7V+wGC^G`+yz(aRu(l3*6nK0+f6|U6 z6Vir59x}7g?W==jb^+#NPp2YAH5r}K`=wwMu1t6oA)DzI=#pl3C#Ur;-UwPj#Yk$% z({Tp)9o#ZJYFZ}Aq*nXZWr%@9jp-ujA z#;d7ENU-)wP!S|ow*!E*g&?>4lsOxC|C@|U(Hf8st6=y~PUleMW`g;`GK|38)$U9H z0J2MRSA_qmGVJTvoo3)`w3rJM6^nj`HHOB07+R7iOu`+fefG8&*PP^MHOh)fljSDl z^mEgpYkM{8=~>^i-GX#9EnMwQNkI{LB$I%6FAjT3K{xV^DXx_ua01CD-qMPM<&qV` z1|MCU%R!&PWh~D`R2|)_Z-$(m9@*KusT-(ss;PfVU;0s^gRnnYf3!w9& z)(?o>#gVL85NuHJZ0{D_%UCJ-om%dQ#3}!l*kK&nRuxQ$knN--tM%8TjvGIZrovn% ztTmMD^QtqqA@*{3ooQKMeZtvNGE5zcs}X3lUb4TXN}g}a2+F$M9nzIOuocO3GcgG} zjpLk&2vkUjg$b{9G50H|dNfQKf#heOhiXs_6w^n=le{6!*BCL7a3^WTt|{B*x}WKK z8YrpK(y>JG+I7 zEhtDNL-@OCh1(>P84ulPfS#mGe;X~z+ilQ_*7Nk1F*M`L`psjN+4A=+ zQOV>8=-CnX7R7`5#*~iZqV4!^G;LiUNJmy{$=ei)HS+CgrR;NlO`5|ajsp}i$f3sr z*E<2gCzsH63p;t9aT@Izx}wg_$`~vB)~;cxtu)3aHWMkzuv>oXQUh%^J2Ry3T(WoS zN`Jm+&Bm7E$$f3%+)b9+3K*-}@PV`JNP188C20;9k+BcT#yh>YB9Q(~)gj`>J^CDc zuptet?%(nBgZc5QvuGfKEw3hBQ-|@QR0XlEzxQLTz2GCx@bi|-l6tGaVVAhwnL#D( zrcZdIU9xfr8J7P=>uczVgV$IQPl8r)OD5HNCv9S?i2nJ8?eSz=B;z6(VH5Lt;**iF z(3K}!c_S+FWz~tqffc6b6JV+CihJ+s%mqek)z366wT1dl-=tEmOg@#&Ru!q@P<-b? zEyOn|=29vb00RAK0K+N5BS6|AiLa3Ej6vPd3A;R}cYG!A-Je!IT$Pnccit!r0%ZsR zKre@5`nr^M(P)b4nyil6_Q&U`gTKn&a=!`F>2;%=_(@N9hk9S|0Kg^lw;@>qO9Fs4z0o@&FA*PC!0Jlm8r{>efqt>ghl8$OJMS5muKE6{zk9p2wF5V=@`W}l z8RP&UA51Z9FfEwmiblx{arGj-C0^4l2iulDo$UEjDwHHLu+kdWsyEHC1PwZqKF2|$ zQG8n;?ZVHMr&jz9=01;}^g{30L3aL=2TyM2_gqR`SfxZWH*N0kCwb?rWM$w1-)_l! z`YewJ+seai0k@rWw9<0xTev$J@WN$-v;n6B;62vfbQeW;h~lDwz}f=eQAO6-GXNeJ zH)vq3SR}}qk}uNQMkWfMKX!~pR4OVB-92nm z1@Et+Mu$k^-aYh&XW1I@pBiYc(ZBFuZ<3PMH(<8PY0-J6ps<=t=_Hwo%W0B3L&y1( zkK0hye(frwgn2A_&^KxXcQf3cnUfQSTV=#-b`CM|jqQ?@Wu1q?=jMRDb4ND@h1|Fg0EXxl6p?r-Ge`v~mA18+NtR zM;)%A-)X;JcyQ_(Oj=a8BL+XieQqL*FL5iO`-4#gR!(8TBd~V*1zV%bx=Puyxq} z?DplhLrSvzQ;Ejvp=n^R$-!5Ic0>lIsONq}xpn8QCmOmvo^7VVq5;36V65+YPshow z_PE(Wr8sAUmPmK@ZID!KDVtvM5Gfg1=<+e>3L{jn9xp_K8u^KZFkPZug^Gl zp$A4>Z>U&dKYE|Pf`$rQ7Ez6?by;ID-xR%p_omjahrCkaLU;=RS!@1nQ7IzEm;07j z1;1}bm-UVbx%cv8_v{)Db&K;&QX6dx;pOqk8| z`sJ0Mg)d4;NaxTu)?9jf0*biOo!8dJ1oG;3eN6q{ZZSu|vsYEei+BpozSl4mgIurT zYyAx|65iF%gI;GYNv0VhvfBxi0P(T~(dmf7=Y1z8&Cn*Ktk0e67>5csirFl}RLw`l zZ{5i=`|wc=bD;a4W#?5Mle6nv)bj~@j6~7rTwYsKgcRGxp^W9~?qcjyc^0}80@MnR zPvxSEZnFZ+e+5+IgHNg^?`hxK{WdEGQ)T;K7vd_@pv9TtM@*SDlvw=+fNU!$PBZ=% zbNVAYVY^YK+0qpA2kz!(-5)ioI$!zZJdp!H7hY@7P&ifM-bYk%8UE*ph?cS%IzeM> zf5LSy7m5v)yEBT6lzYmj0_dC?kI}WTc`oSmlscYLmM6cEy;V?{!R4!@08m==ddW$A z8ZvG)l5$o}&x2FRv?1#nk|nD& z@u{jAHBya=oMn2+i>$x(w($53DSwR@k{MT=E=G5da9Bh3CI|kQpiZU}y|2mD1%Y9} zd5GHVjE+LF03b^je8)wS#gt6lo9}JQawY$-@6;ij%5i1;`dR)%BY5=!lNLmAbl*PXe{!K&KvUA=R7(+OZ^AWvajWsP}#i`a~Gj zcH{a!e7v;j<#gMr=P|joqUv;xh2yJ}c_@mnE*LL%{jKwb=dJM-_q?ySX zV_fl7&+N?ds5?EgB6zGkJR$);ptRt2d# zq(N8=q19v2R+&x!C~>y^yaz{u_2gWB@oX`^f+wGv)G3HF%F6BcXe75-o}rfE^()Qm z-HyDKYGO{-tLQnKG*>Pz0Ekv~U%9TvbVn*#f9`LhB}jM}HPY|ciyZq5#eFaD8jSUKT&`8T|j}S0FsK4)}ik;&DI_u0cs=$RcEdkqdlbCKZ28b~r9_mu=Lcq@AT( zxG%V^Qoik;NVv37a(1VLmeE8yRVKQd9q}ZjXnj#yl=)GmNX??C?iAw9HFzE|0p?hf zVIRWKPqml1ne!Nx!+CzD)a*lpNa`;M>decCxGvW^QWGll38uPYSC6xD+yekptNrc5 z1-tz^s;SlGXlus$bwQXo;2;U-WeM1Xj&$5vT(qLI{RNS(q-$uoy89e^pRcZWr6R<} zPhMgOqtIus3V$v0wzunJM7r%rhEKf@Uh6R=D^XlVS0&8Pyrd{}?24P)C;R%H zyoh%@4xS`%AJh5t{-xb$duA|r&aBwD64!^2cZOQv-z?V;? zss|GyRvs4kqdVGSfRSN{P(WZoeA zEjwUi?_Rn}j6-WaEDO_2Kq1#{wtEK(15F3!7hJ;k49Be+Za}0(TT#m`xhN!6OQ|lA zqjQm9wR)mCvUEk1OV5wgilRHGg=yz=kE!4vXqe7V7J5{h9_Z>bdumF` zs(4VINi-yBJqdCfa7gtiKKCdrCt;ia6|%ih#KxZBcKOM6Y$4-gAv)!BE=PVxZ=d-! zRt^9<|93Y83faWKOgY#_VT+B~C%NZa!xJGT({dE4tUqmQG6dGIG-iw0?<&|R#TUM% z96COdM5qD^W#X1HX_v?td!?OEih=UUIwo0VoO@oQwwLlQ0GZdCkxc-omdT84YO$#g zlA8FpeRXft`_GZk21g zLZ(6e=8LJ1HO^$JtIxJmbJ_K@yx%HMHg}_kkp1|lwc%!azATRxA?LL!1uH+jWDHNv zWxH4^CpRG;f5R;e&8n^h{M|{4{b2=aQP;#{Tg__|;gY-fU=B8ALp0tmcm#n7=(wCF zQp%O?`y4~zB{`7J;)iagM3OabZD2VLw@jLPM)FPrL79}*-g&_ua`c`_@2VKK1`O2o z=`s(pV7p!UPBLFB_vpV$dwYz@pd=*JJUP53W+gjZG0X9q%ajGI#9*cpPb$5xvqmvh zw%>s`gn4Q;N5d=R*Yc|^7+;C%Dd1Ti0LWA(Mv^tJYE0u{($rhViPf$Cb0UwYE{7^N zM%I1RrWdM9qK?nf3~%3>c6d)mg4fQggOrzKnq{>6saxFxmxR241T7Htm7R&&nFVXw zH@%3V(Gy`rqLx$<6$r$I)p)wB(xB_7BJ7*^geI{mbzPXs6&5Xvnx}5wM%V%Xwe2Ft zf0Zq*F9*+a8f;8*3H@He&{)y?wW6846K4o3l*n8+S;^iV9Aw3->gaZ_s z=MAG|0iaMeOpGAY3RsntEzTH;fYfII(C7jeyNl0@Ti66EQ+`)dN5=oOVaKb(zZQ7( zjUAA_WFxG-86ff3^7Zoi`oqR^=LxhO>r}o;FJT}#)<0N;8=^?^kxuX(8>N!lFq>>m zUA<07vBc3pmI?qNb=6s*i6I0=wbuhcf@_!#$^G3Ns~gI_gcpy)Mg1i9G!Gt?MP)U_ z28mw*rldoXv%;_teP|(fiKx$B{t(aC;=ZhR>sIso&*DrO=H+20RMZTTo*%cxgN7kq zay{q1%0-O}PckV?PfG?E#t#Vva?L-(gp=GVk&{$bo$|Vk?5z8`m6yd2m=I9e6fE)QlcWiY!zv3%$!S-IJ`D7OHAM3qLq3lEL#cSL>lSA`fBG-& zd~@$U^<`%oHO4z63jVa}Esiy0u|WLrtX7C(7m)57>-gB(x+BRbnnU5YG}`8VEM3em zA;B{?%0yk{{9%vT{#0hC`+A)=nxGRqw-ODv)#N|nQNaGT@cKeN8s+zQ;ZMefMU#sP zlmalg&oolc0?tNy&hc4g2p4K*aEvJ#?N~&?uySO`In$-p(?-xAT|PHgXNKJA1Xm=l zJ%1Y2rtfs6n@LuX)0&Ok zmz2r&LfUhcobH`Qh#ZK`W6&y~ZkvfI#DB5jF1@^dZSFETfb&;9j~JfaIr8QMJX|)J zx7$NQf69vds__|-lnFvO#BKspRBXM`sq%5JA}qsg2USJ-Is<>!&jFywNy&d1Kd$V- zmXSNgAsk_Qp}}PT8B6d=XCiWn-Y6b{aIb`s?E%KnWiWXd*~DftRzXt1^Ju-|YpywM zU?R*LI3_4KVVECQ5#v{EXPSuWOwsJGQxcr3E$60*#<8Hwz}iN`Jy?DYhCtT>4@utRu@RH%U}BqFDuQa$O^)d?WEc zT+GedpNy5f3N31rR^fV_N{!bc3LcA*uD3O!jJQQCk&>T8eKm#t^!5xAMEhO`==3nB zDSSWe|GJf;+QfSPL6!`wZi^8Cl2Dk;A_0c_VXGEOl|dnN&Fzz`jsPOA6Q17Go$A|+MTDM zWpyN*Bw`=LbpK1J6j3UVEb@q$3AJ*bJfg2;kGfhwONYs&V>DU*3^ULzu30{}tpMm-R#>Ux|=?4`ZDbH+8wKBa6*YVYb- zKM8&XKfSUfa?GcqYEgjE>JM6KZ`3}ag%u-`ZML+N2!F}sS!4?g4eqPB8&m>-B!^E@ z=J+ez5F3z!!%Xb(>M6#yId`qu(!C9%B9lfOhdqx^k%#%z#!9Xt!Yr*3J_Ri=H1{_B z8ItNFn?|H5W=M_i+~_-8_G3Kdwl9V+K90sPN)p8YP)KkhE}GaDqI3&E>DHxVRSC88 zhX`j|T<4ww1=)Vw8G{M{hhu#RpxsNf__+mtJ~-}G6h#D z4QvZ^v3EobWsO||G+~7L2%JcyXR%XQb!k6sKj9Gt4<>z3lM)iUYGm#$wwbaMj-Ius zeaq1AQd2~_bkr8BLjX`?K9HeAL6M>qNaaKirS?JAa+**RRI4_uEKru*Z06|IlZh*- z=cf7O*kH)kMWPL$iGjY^b*^))W-Ox^d-vQIX6t#=dJ|Y~J=@ialqFpHy_6EG5=vB_ zYK%Sa@$O&VqlI-1!tWS4zEkiwM@%&= zMD!IkrQDzC_mZ*L>yw4NSB|doC0^=3z&7#J;|X%Tw&H}=98B4(M!`wBffn2X=Xy29 zp=CE7y0fL7T{Et*HX+L-Sa^0xOD&k-|_$0 z*fA0AW+9UO4JM8_rQ(O4n?dVceZqZdnLEw*NTRzY zo6uYa-|;(pJ6Da#TrFB5DS=qrXLt?xdbTIOEwj22?H{}mrV*UA|VY2w@ZUB&AgbqAh-hkKSP!()@U)Yb+Ik2g!l0W~s3 zCU~k!!YTmJyMTJ!Q4q;XQmGgwsxZJukz7w9OX-3B#{(fSF4ucRFqO&j==tQo^E8w!?*~>roGPYkrm)3@a9v>eC8rVb%NxEYn9vFRpe>sNK*X1Um-_lVaqV(B$nrn2hyPfS-iT_ywOofo$dk|{-V0z91C}7l z3vv9FNfw9R4hkIwoPHc0`8dL^@~3XU?EQ+qoi31RAMfTMtY3!#z>GmG_7s(C0rNeJ zPW~DH{L*$Nn#;I1G@dw9C&-D1z`v~`<5h(9I;o@4@NAWV03df&Cc^>;02p50Hx_?! zHu{#oP*8vKvTwx)S0T~2sd=A{q*%b3ymE6K&TP~hwKchUEh~HiMw1Lam@4+dupA8< z=W)50f=4lIY>uSFQ!$t)W8QY3yLVU*NXMJ`c;+kC?yvqF%n2WYzRAi5v1h_u_$xMe zP%l7!-0{c&h-%rgPmpGGAx@|Ef?=2PU4?6-$T>UGg%l);oxW8i(a4iY5@<*s%aLmo zP4Cpn8Bk|PCI(*8Xx{S){0w3eEb!hHb;d&Oxq-beDI15fALZH7uV9Cz2j3Y2U8vfe))217- zI!R*x0flj?C`XGn3ucb_y|98ICQy>|El-OCNro>gI6M$s(A-_@D%w7;7csW;o0T>+ zngXSTetvZZ!FYj{t{DKFJdN*hopb+#7$vF$BZY@bAEs!pB)5WCKw5a(i$WfV=0A=h zsV|@aXvjOKJVk!%?&_20)jHE)06~~j->546^3)knE?|_%X<$_Jd76aZE`it+<1dqW zfA$K%rh}?BpBw?NrOUZW%nktA7#Qwj$MZUj2E{sUzT`^bx_|pVprQYCod9 zWR?4_h=4*j4J0K8>$5MS3m$rFW00l(1_MB)_g^jeyOYayw(9y3^#=iWwp{A8!vI>B zW}i>b*Aso|`?=kXwV@b4_|1Xl;SW?o%t)t3HxCTW zL)?n8OS1%SM!w%`l0AaLp+9E%999xZu88qO>j_tmbl?Mh8yC-(<1{QU#O<9}+k^hz zdK8Q0d7l`KHn|Jf_U|XWf}R{#ma=pZxd0_PaklsnVT-DQ1uK2?Yj{C($zvug}W@D0=MwgYro{M6B2>_rIbn8?f&o@utgAv{tZ2!yF zUrx9?obmdgoR{ni_WskIdR5x6b^!2HmnKdSrb`*Rh(*q9rK<=X-zL|s?vB}g>$>79p?;clS|w_0;@cGe#UVPxX%Rd`VPnOi;n^v4Wir%Y+hZ?_qMg$udF zQ#Af8lJ3%w7lGIW&*RK}EX6sRA@A17ueei5s7Q{6BKnn<`d~BBVgQ_MR9~=*wt)ix z!OepBG0iX1l|8F}03b<3vX$Qayc4=&=n6FDw=bHD^yC;8sd(RC$7n_B@XTbS+U{Gw zNX*3FJ1LJjj%OV?#WPlnC6z$ZJ9x4%T`^r^{aa|_Dr1F#;Zz@%gh}En3XL<2Tnqc= z#lwK3l`bADj`WlF7flNc!VoF)U*yU-rhlIM4K1J0AwuxIL@`3bg_c}Q-AX&=zw1nl zZus^6L>qhtYQ(5gql2nJR_lbAB(s_*|6u}r;#;>9n7Nh0G!pJ`#Ly!ddETXE?379m zV(%Ccx^4a8gMCTokY&xaWpXQQ3lk_ADu$RK;C=j?iA<7IkM2aqYJuMe**=S%=Q(g> z<~Uc20k6p2`(j+vC6uo?L<)t&6&kJ+08->ZqL55;fBs9yqdz9`&{pJ)2>^B-Lh?)| zf>FXEV*8t5P0i8p;n+@lzW{m-ooDe~Ltgzuk7-bNoTn44M=SF1^C_X^a^z&8M14e6 z&-TX!FF7Bvs3K~3at$%W!T_KUC!##exAdMV4R2%8Fhl0xkTR_nL?W^zEs)VDu&gzf zNRR6L!5(Hj%npj%sN>$jcfQl5E*`V20UvS_6E=dIVI?^8z}--yip7AyvG%=s+wP9) zsX9p@6mNXA&XJsu%t9Q?!`p8hsn#Zl9nPOmkCmEdde$s!vex3!&}b|1 zUH{N1K{^|&vfQFsuc%t4MOk*c55cZLdB;d9y^q5lW-|jotpYT48muop3rA9v(k(TB z!*lNVjY_;@z~zOw3tY&E7dZe#HN({jD~yd78i7Q%Kng#xp$W~#*SLfJqTB4MeyJz3 zJzFpu&U`aBLD|cU&(4^Ac2S2w@unnO5lW3vXP%*(Hlop9^M?PBw6WA*`l!4IYis*St(}PLhB5v#5c`y|z&c016MQNE*i{u9u&0zin1j2+;9u;aQ(U}vSNe0x~n5CP5J-H*Gwxdx?% zwTF<18`$&Njh4hj#OBlt%#3}!-7zO~Dz(Y#m*iqkS z|FfUqvYV2ECy!b7qxPM8x8xK9A=h+&>E2qrO^v?S3q5%0GNZe>Z;=i1)|#%c12m8ZyC^f>>P^?l z)=05=8Xb0Nmu)tAGWl9<%UviQd+(@zK4n6AWil<+bQ)>89e09JPl2gvh`drF04SRz z)c%WfU@n)c^o(Y_uQ4PyTmwJ=tg|g^?(sh?+8y zZa6w&_+=Ynx&?(L^Ethy#((PthC~Kp_vf8717ATe0)vQ@HBpX7we+RwBi$jAbxx5fSHZkHXW;Z?@k5yTZ#YtO&A zM~D(g5~7hj-`|{PV;2=P&-A6lDxv+|NQ?iqQ=l{lnU9^6F&n(La5H`C-e>uhlCSib z#@+Y7Wm^ES)K#vJ-&26U=JS$)L~-)ek2InrJQvemM@S^S8iU;|p0rHmwx6_O+LC^>IX%m_LLwO0QhbaQ`Eu zxX26uN@;6q$0U(Hr7va=eHi5hjJIZ<5bRDgddHuARyx+q+uZ$#EU$S-%!^MDkgm+X zA7cvLjA4pXANIi&Y`*u1Dy|8Sz^Q087f86pHxoCuy~yR%*zwu`KqZR$=($%i5M(!H zcllTU#Qbm1fBJS_Gui`SnT7Vov0489l|^iH^sNCL_De!sycFVWhC} z{^>zt6gFXE3BkYf6KbM5#XrCEmK^TDS`TA=xVsujlu%9a)5iT_nmy z<*`)1@fsNbgnxB{J6to70ZW^df>r5w);sm6)+zrI@h>@29{}P~d_ICvWIKGMY;21{9TJyo8eN-GYvpaRs#;lNC2K?ZllwL%$BB!SU@iF=Z5r4mGI8J0 zX>n06e4IA$_ES6a5mp| zQL1^Jc0R5@y6?GjN`AqW_3Vl4pjV53Bl4WCgyai+@!WbH3gt|>QT9@BfKW_LQTt1u zrSIDkHhm~MurOywkqgm;LII#A7F(C{2rNyqLA~v5aGmAc{>IX4)PZ}+YY_}wrY^^? zC^9(6AhnVE+}Ezl%WX%0RBvzPFH!~>GNOSk0FXHZR3rICyZ55~+KcPY^0q5$#uY3( zV!R3+v}S;)2h$MRejk+uD?9c+yd`%ZHc+M5UrS@lWN3*PII~+JMp>vj;E6#;ah$qCH;0nV{SQnIZpC z+w*^q9~>yAP6BNkspmGe-1wbK8fy#av!AkkX55y-+}l&)uN}2~o~6 zkg9ve)s%P4enKMQ4K5%$Ko<{15)<%R{)^1wEmHT@Bb~=g{rbsnH}|Vqxu_@1Zn)-4 zO;N!DVT?onqkn&VV*FG|f}ChPcnXDah(nR*e*h{#)xYaSMs?mKAn3*R{~SAm=VLlD z@p!|c7z_9Ihb-j}hip0F*(%1jVZF}p@b&wqE*y)SHrlx%tE)Z0NP8y{oD?WSz@#8e zo^-1-{u(YLIMVk!6dK7T>f6N1;t^1gRBx2{>eWE5X0$lcakw~741D3LH%cowdc?z5 z(db~UdO?=0Z7^Yw>kessK9q05Vc1V?u=(3qW>ODpz%}KsWp`rDJalFc?DyVS4Cqb1 z6%i;x-%j$B*>>0(8}*8KtG0iC-TURY&IP*j=3-TCdL@e5(&$i7b$85*M=m&jNe@Hl zeE&~YSs$&|-7TI;(>}cbgN@>E^A#hzN_@kZ>1{%FKn!MnB zYnNu~;ae?jx^KwKE0~caBN+(BB!}VZ_fhR*U#noh)cwh|lbrFvLRew!!NXJOT?U@> z(uRHd4&q$Q7a|6^j$Vls@`;R$r!6+$)ih_NO(~5v`FY}{!`-__Kf6BdoBps+8Y3!$ zl14RlLspn+vKlJ!%u}09K>(TnDgksp2|V@LKx+kJmdB5fXtu)w|%FCBJyWZQdX#R5U=yl+;_%KsL6t*6U!P?0)_ zseWJ@cvGpeh&D`8a)2;#Y?b2o%;uByIiehfhFYe7JLGNQ@g@YKS%MoLA2Oh|)n zD7jRuR9Z_Gev8`n-s9xxqW6p1Duh9yFM`|6Rgf$%w#_MseLsbLR97$JY99V@l(O6* z153M(*!VwPV%i71%9`qim%8^tF&36(qD)XSr#qMkyr`16GgkPfj7g)B-v|YyyfrQ< zW9s>#(ZwcY{F62ruUtQ+2aTWm>C3Q;M&-Cn*i63C-d81AHYj%L@Fn8ew4o6DAW(gR za^t=0QevuR$T#~seY1gcv+Vq2nAd&d8P9xtY<99V4zXgC>LZu2>$cHb?Q+|{p6|xv zwZ+E!k=b?KCU-^|T{~k?D2U9o!-#P&!aU@Dod+pmsNlvc z6=tGN^JQAo&iqz8>hpNawVf$EtVHzs;)-+C8Z7;|n5)`aiV3^$f|?jhcO8m7 zr@ic1E2qB`0ul#t>Rr8ffaz7_y1c~G;1K#X-b^mFpN@)W&!-#X?`FKZ2(rCcXe#>_ z%%yBsR-IxQPd`rU-AJUW2$d<;zZ&fo<|8U&bn#A~=Q9~^ceKp8;v9j|Y#}KIW0-NQ zW8TSUv45MJ%){o+UcZWNBiFht*X%KN9}`(C10t~Gm_SLK5^QYgEpOme@m54 zsvfr{e>hIM^i%SklU>S4%~*S?(dsB>{pk z_YS~uv0q|~NyP4op3!79ZsE_j)1>Ezzb-!%YhYCg6z?(XS+6oJcXcEXg!k;x=4Up& zumt5Z)IL9+Xy@#d)&p^*Mx1aYiLi0oY2eDOqM@Paw7;6bqF%cC72ey}e@8g?&ohtC zAGskH%Mt=uk_xHWfzMTBLuZ_0GLX^Y&knlBy z^r7ZReRO(kK6`4i@8F2Ge&~fGx_5M)J(?`}YHErPk|s!K{%BCe+jBm`e3gTR)Wo`emA8P*8#ePN}tQN+-&#Y9_v57`$Ozr z-KLJ2dY7%oi^aXwD5o41c;m%OQe*uteTZpnH87uH50>!+dUoa)-Cg@qRIy!j$0H^6 z)6f?&&$<(|uXEC;ahu5>g{B`5(K^C(O1=+i{4nk1;9o;N$ST}eyK8Q+RPQMB*^6!c zy*p)}zw`KMU=O>C^14`-cAcN-$?|7*i?4dD0d+addtJPt+(a4qBw#A@iULQt-9Pzm!&>vsjBs^X{>uLrRKQ13D(rfr_PHI zA%ytpj8_PuT)VR_)9(BuD#4e_j{OLdb+elbhbWD=TI}*0X_=HgWx@o1C$9H5GR)}i zu(e-*Gd>-xK))`-^`>->pyP;1w?J=aku{JptY>$4m2cCDhmN6*#~14MVN76oAV^J@ z^x34|{UXFfRKCk7SK!3Kv^CU z*#(eU)Adk`qUeM+BZz8Ai3et#J)R>anN}XeIG5;tIjd8p-4%R$+x59V6<_Jc-PfWq zBE_O)+Vw&sD&V6Nil{(06iZ~!;soOqjMX1Bi|~DW?w>tH&Ro#%FzIdp3{F z*DA=0DDTiBSERHD=CpQpjoZHG*)(_Ai|}zy`CJwqMPY^@A_41-`F(@K+n#xq-@v<0 zlCTt>JCvdWYuHIv{zg|qD@$}%vjHsx1ORFK$GkXE5kswI5(adNxX<^{@uHxwVe zgaddYpg4*UcGa{Fz&YIIzi(KZlFScof%^vi!AIsV?M2%bY^TSqb^Tuj7}&v7#4T>a zpg0aiR~j-Ug@Zyu0|(SxL|agZB_ zfPEB!eg1IC%nwhWE8>HM%J7n)ULWla+QcC|=;nGaT3gpP^`IUf2>w(jXLwZ|mJdT| zUM;_~o#|uJB!0&ZxnWXu_Br+YzfMoSj0Z6rcZ?W^{Iq3|f-lZ&c0^qKsf@JaH9vls z%|L-8B~f?$laJ&`e&1PaSez-qiKf(XzMUz1!*6w7wx_#i!x17uAgOyGMj#_4U%tPo z1hygc?DTv>pH8n8DO=Dx=mkD-r=jTRI+Z6Hb#lJM?kD8yl1W zJ-7v&q!d&Ul%Cl2rQ%i~>5mqBA9Cr_?oP1&056$%Fsqf<6=V5r{ zs2ys_5qf}iuRwC4cBKsE1tkuB`+}4lgeCX$xJJPUl2ee02r6~mw=KF$VxND)zq|2# zc3(N8NxRHmm{3$wq6C0DcTs5~1b}p_ULQ0%W2kXTXCtl{bu!(S3p+ERBncyS)qC%f z+UmcQf)Uoc$Dg>g2Pk)KO-PG~1`^O>K$wMsy2>jZS1ueQB?Y@R!(2Wk<3jw~uTFV1 zQ}$%&u_EmW%ez-IY!VR+cYu1{zKFnv_3{o(o}0{a0EQs1OkETuNzgl=H9Kax%sFD!$0qkJcJ7%M5m==j0cSgJ zqmN|(JPh{Ti^4Fm!NbWzY@=5rDjzxrmz~?+uxrvdY5|x%28;b1G;QV6WW%k4LnA6* znevdzP?+kbH0X#AwmGAJJs8(erz?RZj~_TADhBreWJ31Xc{88bLERdGAQ0(FbAf5v zPB~W2G~+RaX{sltj?>f0>U=1^J1ZSbxpFKK7}et1!;Y>Z&F=$coQ?GTYAhBBHI6{< z>hbvfL&>K}PVonr^|H4X4_`;#A z)=sT1z05v7TGqv(aPeV6c0%oWJ-}o@&*SN|_XBO?Dl&Uxh(?+{3))voWA#W!&UAeH z->;_r2yP#2^-Tw5e3u?8dK&$v3;VuyGwIToGIcv`!r^gjRjb9H1oF#KDic3Tak)uh z&sM#eTZrW~v=g09|Ja6ZX>HZ(3zHyh)9`avt-<^Ktt2AK@oWkBn=Z#PzkFs-k|rSC_sbFONmbK=^c> z?RjzWNQ^&IhJN0x5FwOzzTL^yz49>hbB(=Q=Wa#}8;Cx9s=m@vK{YyTfc^A$NR>VQtJBlWiJ7 zNOWSthKb3oo9$K`*Ghp1LgM4#AQcMo~J1xVa{3M+f}sK zM-Gy0iV{vcB!SydY>SF|cWEHRNhD7^*f3yvx)kvnn5t)&7b@x4bSmlmdYTRfe&+7( zv^h#YPY%^-H745F*sI9Mx~p-GFWvIhyHE3egI11M8TRi(3`?h>4$8%N3}w+8fp&28 zbu~h-KWC<^(9BUoSUcqw=Trn@!FwI#lxT6=`ag&7xscs0d@xx1JvbJR<>PK!PofKX zs}Tp!5IV)dd|jfPULKNgs?&TNUw~KZcmq5mBHgrp^jiIfF%R(?-57SSPf!?}u4Iy% zD!&_Hn3*FgSqDK5B#aeE=NH>@O%h|pTvN9h&>yq0Xsaa#^g}y(@_%t@^s5_h)6eE# zG4F}wIMv(nTXpMl^cvcwM>B-dDTsGYyBegBodg1iHf1jD4@Bs-K@|whNs{VB0Oy)n zMB!$AJF;5MVmpRaJC+bZ5TINJF2(MbQLoPXJ{({jEJaw?BPudzX;j1~$izL>j9XOOmJEs{r|nUGh>OaRi{k9^+lY7w^tf<_raZy?T?*7|nUH|E(z zX;rshr;Ye(z)qY&rK%3_j=^WvyRJLY5`6xwm%R9)Gs7!mc7i$($+x&y)1K{v$YUOz zSY5i>xNGriRT$Fs*u_t9??2GFoNKx(9S7;lr5;HJn(xH=+Bwl^Yuk9MV6{&x*w$HS z$2rdgub;CeTU{G-unujy7J>=R@qrjJ9ZILY%V4B$%>;Rvw_>t#SIHGURQB&A6VlR(fmS0binPErLC?)E9|Z<{ zpV~EiEliME&k@-;BPfK{V!H_XCuawlwhOr71)|Yz6SS#UmtMnmsvgb{YlJ$IWJ*I^R2J5w)!;250lTppmasd^iPpGgW+Vh-yRXvm+{?Gn@}`M9@YgBPGQI zBPxGw!&vupJFl0QIO=W1IUOI#29qK?=hO*rP~OJ>hSt^jPu?7zo#!v#(aRXShlT`7 zN(FA`yN?zVTfmB77gdpP>!d=*>5A))m?_OS$64+iU@Et0>+ol`G~=9OPFNPTqpjy1 z8(zr5urwB{hEI5+T>98o2)5nRJD|i?_l%=aJE9<&<-r9bDmI9pj#*GCPR;Tg&du&T zIgUO4``6jl@wbU+$&15irhf-!cI0Z4eh4^w%Y`S!DxRtE0 zcF*dE&yZ_ZsZjsDs)?#v0S4h7}KH}5*?nowke>1 z$qVTh!NQ2Vv|JsXYJxf=Dv0RChT8;7144j>>-?4&Wn=>Br=fk06#QswRXe+Y9emSaaZr0oo=$KTo~neBNTEWat#u|O zRwc#+EV>jpD6h@V1K|93SyF>lA*nfr&bivbXg7->{n+tS$NQ{*zos<>!C0;H2=RR61241mi*+af7?$X{Pu6WS)NG@&A|y z!!CdD^8M%e{vYL=!hd=n+!i0&jfJp43z+c`&aPCDD=+!nLIVT#vQO-Pk(Lt5D&()6 z%!q$;2_q#?-UN3DSfa?>G!7#wBn5!};-JeojX%`N{ilYG-r7E`#oPAiEFa^plW0Q| z{(D%U`@ogJ_1pNYAaMxvk7ac1Hk`p0k9%=4jfQ?9_2GT0od^Nyx+|}pL>Jy zeGkIo06pfIdI)NUh$s5s0cB3`=>qNtQg(@;+%n!+ec}?^2^iv-a3^Mni$BLLOqDs9WkqkxzVo4gY zAtNe%!4u;WXnc>&&A<_2VU;aF^eavOzm{@yJpzKO#Mop@7=L(QAh6dUkJyI#{X>^$ z@h&GmGiUfxr8`r}_&dmR>dbQv0tsHn>WtHh{a9VWbX1(m2Hpvr&@>=$lmgd-}i-djBK|8gIT zf*;HU0{Mk4WaI?NKMMp)S>5^9OMMe`*)Rl<%R)KOAz|%wDKmZn-2GlZ)R|2>sDI)7 zcF2^wTyV?1Ui{|<_|O@Dw*%4{`NduJuE>O#}vvnpMGYo8cCUREb}tG6Q4a) zp%|=^2ix)WbPh+2B`b-M?)Ciudu3O;-uM@R?uvaO`eu70Dn5hoK9-m0&WzzR&Tj5c zBPGO+9`Y_~i&h_{s`=lnBPHPo5V=O#5|1z2-Fv&>Xxn-Bul4k0-%a6-v5?*J(tjOO zNmNM5kbWGT1Cfj#{Bstf>?%X@Pcwhq=4?42P#ON0DybtS!TGz!g!{*ChjBzg6;PBA z0^k-h^EEek^I_WQgmjVQVE+kV(&bJChgQvygm%vF(~Orf$82Tkz3X<$KSJI|nK8E+ zhG|yb95aq&^8!gE8A+AyW|9Rx*|efSAg-sqlDoMp1K{+0XSLly{)5om^4v4XH9W() z*5?@+85z5Fhq6jW3W>^d6^)+awQ}gXvZI<54_n<%7Oj73OCz`Ol#YAeh5f_dQK~MKG?O-L}QH z=yz99+TXFt9+t2*CY;M#Jk}rMP(ifMa6@G&Y#{X}VJ# znx`pm#{1P9g@9{(5GW9UMc{3IWrO9!M{eN$P)*LmQC|NRlNHE_WQm}->0$6dqc6kw ze~&aa{KMzR>LL*;k`kE&=h&v>dVcOEYMtQ%vLGFYd9oRz$ULopcw!x)ac-!ZUHeMJ z0n9%dQ{Y@RtcI%OQ9(M@5<`_W9eiZ!F?jS~?#zUQRWN2&QDFdr+DKzcbyEc9B&^KM zL1^Sm4=(e+p>Lovawc(KaQ1kZNd$}}Y7!bU{r^^~l64~`24<*tAn$lwf$EBq76Zk$54ErTAJG~W^&O*B}^#~Eb7{{*-;oMsZ*Ycm$dm~yGA<3>8r zJFOJ2dLt#O3}|H_O*=L)oV!``^#(uT9?-R{C)6zIVgk*Ur8=`zM#L zo#*jeKm*rYA?gpf$qU{}BPwX~PuQM+dK>BdI0oaG1ho7lhnIP1OJb2?V1Vj`AtI%_ z^C+Bu248fa7)s<%hv_3KN+{TId_=@7oApp!?9}U!g#oggFe3fC_G_Fs zW|epwB#9zGU|Nwavwy>fx(B{)G5Ehb?!fw(?A!V2gI#EpA;RFLrN)`A8jgpl^6W#ANWyP)mxS=)ZALmpHe0UF>c84JKeMcTL0qP>H zNaIV%Acum-`Jxy`N2nCyhb7w^32=<^35Bo+P-Ob-CYyu6`fiQ!7L5oxPumc|6Xg~9 zb#1bzhsK3m$iRw|+)2Su`q1kKujPH_2cl=5>;T~TBP9;dhW||=ZV(b70!9fF z?cx#!{Z7+@ea_$Qq7kP7%b)Fj8hzyX)j7Z(pN)%tfO#8s_ow7=SCI1#^kdpDVF4*H zj_@}fIx2+1WVC7@usYa?K~?eH%d)rrM`_~kHWY>N;yYgStOJC&1vK~ zZ6TGX%OfT3!Riz?dszt-2?+ucNJH}-fajsJ#ZT!tt-vAPg8b$s2%5ZXb3?g0-&fJ+tLg%;&$RqF_n3__`a+MbwrnFmAIIft82e<; zUprk}#P|oOKVCQQ?C|}RC*A8lHqLSrLlC>H+o(SQp-Rbp6x54$At9&9l1V49TZ$); z=seUoev4^9wdloDLttnE$pJjSx9AV*5D7l-s08)H9wy-L+HLSV4|!MX{mb*ySU|^u zepkwOX{Rj|T0PLu6JLV3+yhmO(Dr19f&d4r@AKS_rVI<6e9x|=tOgFhxX8nl@32UI zNX_qlFd+|>sv`)Q2L<95N6g}#*}$V$8N?|*2ExJAT9ZyD?@`P1>dz{J21h+iinnJ< zfq5t>_(Dh>plCNo;D&>28%B)dm@G-b#--q)`&(>hPF_Y-l_VwLNglm?hXw%*69>LR z1Y*EskcHH_cZ9wRGj*=9ZynghSTlL3&~Facp`S3^`6j(w3_x%ZQ=A$5Pph2I0fP|_ zcL1RzLPEUvJWkdWFcMJ_w0{Sg>M=9xOmcG-t+v{fg`D*49gi_DD4tKZjUHg00Ch1B zh7Wjp1A!wYn)Xg3Du;p(X{hXae==|A!7)d18mg37>+<@Y&*($hiTLyM>mw?f2i0gL z?wa1{#`P!2^Z3M{^XVV-#?d(c?8r3Arc#xm$Oi*Pta^}Pgd#_c=#hFj3I1jqOyYDK za+S911uQD6M*)wQPU+%zNz!;*^FA59f?ZA^8U;VmNv*qIU_uMVmaE^{RaVVoh#0Gw zDF4cyX7S)?cgJVCPzmM*4nZGCiNJ>5X5Y1b<9EVq6y*1kMnxoqBuW`kN+Ntj+)w8p$m$el*Z8ayw zkk6B#@Q)OmFp&@jAtoWDHLV=$CA zq>CYw2EiEy%d10Iph*$%f;fakf+L8b6EN7S8J-A!xgdeW5QCy@0vfd~eoezL?RK9| zUc@>Y2w2GP>4hKX>wHX;Af;W>EFzE+8`Wu|0kwsc>3zUl)jUJ;iB8@Is%As&(KRfT z6rE&eXtWkck^R5H{k=K~W|w}+x71qT)1aLu`denLd}5DSJ%9)8DokkvK>G7jFu@XbrR zk6OQ-TdLn1=+}tXzjh?m5sOfiBPAxr4g@UN;gp6zVMs%(Q$Q|7zMmB-Ou+C5*Ln#9 zvb|jcZw1l>@!{8r+lLi4fr1hI;Iugg^B5Y2(k-mqotpmn_$Z(z>fZ#N!H9C=^IHO% zji5pf@GDJ9I)IxJ9JqnlcODvhO7Fimb{Qr<|4=3d0l2tv8cNa*gAW@9zWbtdAoll5 zCRC*wJaA(#+(@AR>8&geh=IIpgLQSc z5&P)(1V3cN?N?{@!e&!or90aJBPEIO%mM{tp_j=r&4i7b`lU3lsYh3v;nL}r?aDs> z<5@ppU%&MEg|LUwQ`h?@alblOk?Y8mAdny_EZf`+@@CKEd*F z;RDuj_Juv&kAF=q?*lP2I)P{urHII{H83y?P<{}0n?nZYc97bTxbit5WSv1HB?I<+ z1G>h4O&oT2n>L9EgWhaYygn`l03;EzJ>FlE!EqoWV5%8$N7dMF!45B$tpmwUA;>ko zBeqQV$W!J6yzXqUYr1a1qE_udVK{Dk19@AD5=kf=9)$r$ z39`(kq@W$J(4Xu0-l~KN+)monqX_6)P_~ys>$_3;Uh^fI zr)7F-o^SV@kp0}Un={+Qin7LX^w-O0}SD``bJRZ(Y(O+Z& zK{kPd5bKgJlr3%}Dih9+$Bq>wlOrYBp#;{YX|R%mSnDGt=YgZ@&i37Dk~(t;oCL{G zgYO_FV0W(rYhk5fjF5^0x{AC-Eds$v6mT|Piu{}Bm>9kW;d`JR!CQ^tbh~;92CC(% zErP6EH$B^ToA|xDosNjeJtHb96N&UZlQSIf3{I*C%;`doywk%)`}ZPcBPAzterZR7 z5o7EbMk6W^^ej+xVR9QhVJi_K5)hEHYa#55C$8fMZ3Yk+Jh&TOk?LJt_L zXqbRzv~q|VtxYfaleaS#Xva*UOSkh3AU3MRya-7g7BQ8RMR!((d=Ta?+^)Jnen3@d zhS8wa;+c>^(T2hF3wj~LDJ}0*2CjH5S_(PQvq?07^ zje2OS02l`95(u_3%2?RD)Yd3U8c}b1?A-f$BX#LP*#_GhN8rS;?~!_apAVot8T3Ds zmeGAV5PkphzG?G?%$Lv>2Cyyw5Qo7m5Dfjp*iWqaJVDIV0NL<_X2taG_gr2E^8ju5 zB^G~=%8x#|g-25Yl0vxoUufob!84yQMW7=kjgybxeP`YNqsyV?;7eOi>mwJFAeyo? zGbl2~Z#CW5P5YPcyH)*zt za3_rQ&uEv$6elAkx=%<*=HO5HAtMiy*bCfaxOwmN&x9|+U-RrZKC+t06_C-9P|AVr z^gP`^&!2&+5JqAMG;)uthwJ*t!Gq)BN|S3MglR?*ga(jQI%FeDm$OXhvOR z|9-n|YbKn)tc+%KK(eLckO<)Rp3php(GE?a5Q8iTaIm|R4>x1@U#ONnly6M19l?+< ze13`IBl@~|NgkC0j=hlX{wgKxkW`T?@L=xBphcgiAu%+9gIGr!gFrFR$fiVy@t}n! zWJa556lrORu^2)va)y}MHx|=EtpI(aLMEm$DI#M?tpYVMQ3xwhf+H%>8Kr?zMPp@D zR+M5x8UqG|mYA@x5#lxE(P|5NTJc+zYrI`~bX71jR)2LS)&Aj(*SZ`G;M2$dVBfDR= zME{$)uiQiXYwj)iV5mQ9fJcHEUfTeoo!+GS>rdPGe#-T?1?6)P!~%ht`%W=dB`XLf z37W;bp;_Pi$L;&S%M5*fJ4SZ7TK{%MZk^UYY(V^ek%c>>BGsu%h-JD^bK}d(SSe%? z)omPjZ}&ggNJ;TrECdK0{k%+`2jPPJwXtnX0B4LYSv&^0bsJ5z++}^CgW#zYtbrbp zK~m6-P3cEqPZb}3l%j9tuC#VlytttJizthr7%F}?g|>Zap8%5N43Y756L)7j4*H^p z5CB0UhR8dhDas%Og+rgAJ)Abk!GnoJRB8l~A*R(~AwO)X<@9aEpAP@B>GpheW&1D> zcv@G4-AL~&JZcyaK@2!-dVwU~F&*=#T!jcf!iP4}BPwM4M)q;>td zp5h4e;MtTQyBrp5dWp{@8GALCbR2~e zB!yA3g@AgZy>yl|3I7;HC9>tj#N7VZc_xt{Dy(E`BULJrEnI`$L90BPFu;c+Dz*s@ zq(RLKZP@w%C&|h%*!##4{RZtvspFtRs@wt$?+y$*2s`oe)c1;eI~mu%%2p1w4}~Az zgq{7L$=87RNiy)LL}VconjWg#3Yepv4X5fti$(aGR;oVqGTFsSZ5&ye!>`h6}VwhSoV zp>lI*6)k~&QVFUtl)TUa4X1j0U9>V=YqHq#4fsm@R#4=CDp@%A_R9AHXmW$Gyibce z6K@*TO9=^hOb*r)xlYlSXH&#NT61+$HxTI7)9KS2Zxs0{8PsNZkMctgX7}@x##gq! z8}<9*`~6>6mDXu$GZ>W>Ge(0_lBT4n+wAT0^7(ns&EH@k5@eQBbnCDZsCLgU++U9rLH z?fJDZbGh0u8e1@mQK{ZkGbn}joV1WZ_Gjv z(C+q9L@6cC$)ehMQZf3?;5HO%tWsufZtWgD@OS>4WI45)!dBhzu{qW@T879J!20Tz z@Z%d04hha% za)$CD`Tw?sezWezv4y3p+s(%qG9X}3Q{iH#<>O=e|B?I;=l*A)*&opZy)p1l=7W!x z1$fm}TSNUt#{&fYU)m6{sCCdE+ncF1#NJlTq`=6}_MfmLB}2T&B1t190?y3e+)pp9&~SgNq6XkR^0XQ7$<0_p!QldY896z$p@hMZA%eu`{hYJK&2AkR zqcPwM2cuXEkPBmhJ8<3E`V*UeF5wmiuzc9tL!lcI+h=PJ?>9IFyV37?8i#OZj~&uU(PSz`#-pXm|#_0NDOI4I~G4t>PJs!mUI6Zq zq`?@BL=GwgHI;@M2&#}UOfX@gi$RbG5;K$3v~U^SCOas#dF>$w5mO)zH`dia+$0n>A^f;_b^x6-oVtOh^{M=-nwwx*RqfTGNqfcl8%O`8+GXkOCDb$CA4 z@6(?kx;kACbjC4TvQuIceqFzOWO9|P!EPR^-AW>37{&>hz* zDY7+G+9p}Xy|hpD73ZtlcrNAGtlK8&-Q5Bq#VlBrmOa3^IA}hEK4c>*1*(HkYh*Gj ztNFK^c{5okEg#BQzpBFkY!Ye%QX?h828k*NkIVjr%J#Ick{d&;BN($krOm&Db> zk)fb-P>gM$n1b@Lw$CN!B&$g;Exs^@4)V!~A+xR&9C8SlIvQxZk~?&us!NdHjx|-t z)f*cFClmRem1xA0>OQ=orVbNe;ddmL-6fO22xW;Xl@^dj|79CcP+T#K2dvQUmpW??#i8ysCP0b zIPsv-IpVv+Hsr?dIObO~6j_bM;UgtIYm2z$B5_%4)wg#BJH0Hdg?*)G)cjF_N2+AcRxGP~YnvL&d=}Fs^Z+n}Wp%@Gb$@BL|VW%g{4K zKb*B1`uzPi8THo*7+7;CUTnvaOhIt*@StV|k&`unlIxFkr3q>?B#*$eCI zuWyG_rtX`4I1%o1dBnn#6x8LDyeEsqh7Mari*f>%1>hYUv;Uq4Oo63bK@1a9RQBnB zK!l6|>9EE|v>}pNdpS*k8xsUPJUsu0X95Dj(~Gp&sy)kc#~H5}T$&>)EgMJM;>Qu_ z(LE1ALuUyiDug2lU4esS8b1!F&Ah%ueFija-UO0f2_9)fCyNX7IPP4`izqKWHrT;| z@d+l)Lpt>|-Wx&h+sjEOgc@>bQK931cIEQG;d1_--pO)UUy8Bai5$n6$Z;JGG%klD zCCQ0o)Iia``r?eaNy-#KyMZdW29dxvZ3AO8TTp}2X1ZQbA{qk2%cYzYi$>;74hAyL zCV2^PNsg$djhV#-#3D#h1B4|ojocbXN<+8Ud<=}YmLpVZ$O)L*`!-8ch=Eauyuz#lRCLDx=iOITt;)5m3R)I!pj;avoFNiU8a(JMLf`a(LX_h1H)jbUB%8G9Qw2Ou^M1fXI-m&jfnf97a~}WU zeul6!RnkzEt z1K0?f5q~2u33;cxcEk>tSd$cOVsGk|Gc8Ug`O+<{;5H*ADnvMLBPyqm5vPX&GKPbL zx&#&_0_rq#(#I8&%Oh0xa&j@BI^m}bo`Yjg14&RE4B1Q}2{T01ViUp=UBz8-kyb*j zif(S8ks)ofAfn|E)A@axoR^%hmAuvPOmy8}L+h`f&1#-QDAE{tCizg@M)mcb6vM>v zcMe9*%A$<{0fQxvR@@~BD7XkD>;sHliJ`~Xz4BU4Ff5st?I?xIM^d*mj?BR>U^&Qc zj5X!v6{j&a-{ayzrZ=&*rkse2szg~AU1{t^;vQNW+m_5?tye%X3>4Fr3pOC`Yl8j6 zF^jQA1kA{>^OumgAZmmoeF?lom_A%?HLN z>$+RTvtq}o&V&ex6)HlEQ9uXs+if!>GLv#vAG11>idc)p8h~$R=&#+mRhKyR;@eIp zqemRORyI4ijeGs7E&Sc>mIA26EA7KYn;x~hsaBK5z zskW}3Ow+39SNUX$V=}U{F2CEhR|aSfBPy-EFPO)GuqYZz9?qGE&xxen<$!ulQbrZy z7xFP>Frs2<5tNV-L?TqGXWvrw>rW9BDiyE!=JG)4DvBi|B~BnoE)*7Q6f_cmfO+hD zbBC*uZFfqC!@`STAK?%3|8qa#Ki_Jx{~!3~<1;klTMu8-a;N~o`cNbHBUUp!$>5N=d)+@@PB{GMkY-4uF*D&<~O2O(~``Hfv06ltv}5 zD56M_7!ZpDfgq0*qkY{e9nF^dD}d547?P7#1!Et_>6$V$kTw{peiZ2*E&>et{dwD7 zKL0N-$-h~#6*t67o#`V8(oB5C#;*?}DpcN!YoG)pB?l4Q z_Ag2}*w!;t}yBZieE5abDxqMrX(L&$X#6ugQzgra1DtHh|h(w6*0f;_l5`_D7K9Q3A zPYyz$29JhO20^km6c@%|V?t%`83~(XvfNY)YuT7{KVk#o5fwCem^dK4@l=Yz9=dO` zW3?1y2t^4LVnRS60DO!FsIECWw?!{e;ySuvtcM3&Ip_KN$?-%Us&fU4^poi%@f}!R+CCP)#V92CF*d}8a zS(d8+;_bs)18U6s2DL0McZ^@M*L_Q$*`?b&G(n2DghK%rkoyZMwqjh(*xadcxuRr$ zxEedTA?mw=t_8KmEPfGDy1Arl5+Pa}_gxWI;>jUhn|}ifUQM5co$s(@^kWq> z5752u;}yqc6pCik`tG~m#Cm62QOP`!Q!apuQJ8{! z;#8Ey_6tX0qksPZ>{nBo!-9f=_px4LfF0>456QL&2)cCmUsW&=Q#_V`Qh3o(=rb)@ zr^{>eMdrD~2ZTJ6Qxp4G!<6U0zGatVKfm7M1v?s2*Qh^Wi1U*8!q@bVr4}7QgOR6Z z){vT^ogX|-fYhV7J{?1Qux(UBkT}d}MYc0j3QFSfm3h@5Ey{$o3@_-CnQWz%tbpFNg4OL#ZeF5z(H#E-* zdc76H9Z1Sc`CIsFM6=3)EYvAPFzT}(3rWe>So+%aj_c8SIY)|BWNvecW(=&k9R%Gr z&z!2L(^cB0(Phh3shI;qrFFzrr&up<@_yV!AcjG0j6VS=azXvJWxK{7F~>7{y#P9 zDfzG4XtTc+c&PavjLaclzH|Mh5ZK3yqskku- z`y6v&wPT+gexLlkjjugrF}^+x6Wn`e1knE`g^w=7q)-)oi5c_xcanr@;Q!QMyQ*56 zhC^Rl(L^4PEyN4md^hS|LvCA1WIwLsEZx1pF~Ye@gOC5_e)*a<@bL7uKk~AIKnD;l z3jsukh&82T)z}k?>02c3*RR0f@#rgwX8BobJ20dKWxQr@)30;4ifWiXn}bIuC1|Cb z7S!x^pIsUY8NCxu%#vYOkH=cWLYpUelf5rVFta{QA^jKq+3ZkxnvXG%+3U8io=YGS z8a%27>?miS@iJ>jtNB~__$ECZBr5CGr5+#M@B?>XQ%OO>r29c#oapDp^F$pV7}7PY zJT^M|5oTlhyF(xMz-$=wIH*jXSEb(Evw4QXb@Nagh?1#2Rj>zab(U|@F%6PJqBKN^ znTN`0u0~sbTdRTJumy|58?{O|cKq%zV|D;P%$~(s{OBdTz9@bmYCk858#eS-o=-Dz z4EX+nr23Edb*r0QUpwURw3)wzcR5SqmMedkjArpot_4Wj+5yc8+! zJZb%xjNwUEOVXB^GuWn5n?x3t8*=VEoF{{xPC(iIuVQd8#l8lUIu=C3o6+?%2Oj2v zM2#eg=kBd~$hOa$zSjgmEod-l*p*^v zY!kt8-S_qc?yI`>p3M8nxQZ;nSd8Hqc>NKAK;n0$%SmlyVqeWMOBp5oiF5J3pN}M1 zmArk3`!oCR;S1Xc-^`clubiu3NG8SDs-0W7tF#K3QK?{Gey-A-wmp@F8L_jbE}so& z0^=c=A0GbPVUa?Nk)!G@=#81Zs6)DL?{sooM%lN>cSV?Z(}3XnT2y*@Cd)@<27^!b z%|+|Ze4?9$cS)qQArJDgXr|h@#^#f(DTHg$G_Q+Ea?$|S^z*&i*?#Y%Y3xbCl=_-s z9)Dji&ch{Vg~CO5|5Xt%RLg~apJ2l_F$UH?d66Hb)5Y_=5acb||8k1|--L$`HGltf zXerJ%dL_^ro-oBWOUyIgUae0^YU%s@r=p*Yj0|D@D(%18clSO9;HWwOP8-eX5NG}G zyGeIF`~I*iI-%P-1>vQ9v5&9=F}#vYJuqa`IkQQrTGf+Jb;EXE>^R7wHGm1s9CzuDTyWXuzm1hk_HR)M8X!SzsAmOSsN1702f%Vhvk z2{)W(iDQksYaNXQ`HMfkFlw~P{lNF^Jh)CK(9oGAYJHR$!5!BgIhOrF!ZxCB^skDD z?SP8#i4*8UQ9@!cj=m7l_}=EYx(6N;f8ZDHehEK9l4GwC9M^{MAtX% zWBY$jn5ZX(Ds9@iKOCABwf?p)0g62LT0VO!MF&F_I@Ak4`jzL*#L^16HFB4$*5A{y zZmPQY8Riw_^oC`B?@0th=0-9+zGrgI%Za+5>DE(=#`I_^)vz~X0K<(F{`~sIa_qS} zw!^B=o~dvbj=_D&q-6TPtnt0VYDVHz(y)#m>Lx_NJ*QL*1_?QdMK%2!a@t5~>YcZV8fonc zaZ5iL+w+)Oof|%b>ACN@wj(UCmDyya25E$3LZW3E;c#Yo62@HlFDpFA1O1J$mBke8h1N1-<*Fgq7k zzyB3QYY|0%#!dBgDzy!Btjk0rZY;v0B6_$V42`+`T@FItKm0gFYs}X!$x_Opibw0} zV#pM18g-w4m#zr126zO7ZYP-<6bi>I1-oE)o4et1lLZZY^cD2b*-)-+quA+iF{srNFyvoz=VwZ{a=@V?bLS)QSYRT#`@`{lay?BA zdMLVN$xu2|joNv79)gF(IEyUskBUn5%O8tjA6IS+?^a~WC4b1t_o89o0?X8o<97bK zoAj~FJK{{`Wxknzbk7NWwOLU*)AazNmx+Qdmm*E=#KH{YJVb3iSQj4!v_D%}Gg*B9_$N8w|;yZvd86^INIn;9xAO z`%0I;+ye~(;~?WOax+^gix!JmdLaC3RIwhhqG1hIg%fQBg6SPiSux!SejbX*t1UO9 zPoZBWL4>M*T7{ppwb>N2Je-9-v|L)gBuw4j%P%7p45djvk;MasIoM|)*ur_E?{TDn z$%K|ReEcl@LzMJ5ZD+_?6_m+Vo<>XPa_$HRQ;51rvIEkSRsCD#cTJu6-6AAT>YtAG z@hL zw#RtbYiX#Xfa{?Q62}k>{cN2kNudrU>ZDw8r0!QtuJjCb5|kM7xMn8xS$&1eCS7=O z0eelr5OP_hwiPOUNmdLDX>9EpDE?gP=a<6zC%5f9W%XG&(o&2)Ii3j&1y|YSA@~mh znueUHD0l|P_il-aZ9Tre??m4S*tQeG`Gf2IpjzNq(AUL+XQjipLTwT3@ala{w@oJi z2NB3_YDlv{gK22rUKut42=ovz1nNO1!ftxY(;{U3q(N7)kfK}9SN=6G?B{wk7)p`q z_fx<|{NfH3k?Y{I1#Zy6hFc+k8--#qmJCFHg8bv;E2Ov=jb^Ag69Q(zkO*cXuVsy7 z^U_d{E6V^p6C5yvuRbaW(^nBE#hy{IxRt4rdh!gF<*CB4o>i;Qg@L2M^81A~NuBXt znVdR5?eQ@i7D_0Qx5MliO(%0}U-qHTwVMWMY_%8$?1NkpauGG)7vmO1;9S0oahI0@ zOeFe6^Wo`&B8SrXC5EePl`RB9zeEJjQvei;r{A*g#6)wdpz*a?n*J)Y?D$pUnR- z;o>WYg=cEcTVN=6HLSqFL3)NeM-YrNC8!6d!*{o{cWYc3x0LZ0B=n-7nx&RqhrLY}X0ko<1(tMDzwYWe1%-3;eXArUNM+pYotry42s(6<1I3;$+XT0xiuYI#;yqqHRu8!sPjyo5sU6qJIfi&LGTJkWR2q zU{E6`BJlM^i7xw}qdxHq=^Hm>)1_q0Q ze({_?5cwTB98cigmYMpSl3Cz_@6?+U{#44&;PWAZB%2eWgu>CSxbg&`uDaPQ6o*ag zJi6Xa|J1jvArthlA)n-O^9~Z>cWFAI$wq5kIo({uQG`WdVCXb@%;c}nLju$@PJ7HU z;>0Pz8BK1tw=_5XtRn+Ar3KBiq4wT?e$f!e^G?T}EwWp}h3aSd{fTh?M|3_P(r-kS zU>BxxgCWHt&G;iWhR4@OA6wPo-k| zRtF#Sy0qvC-ojIu8_OJuBn3m`nM2t6-|oy;SYmYf(NdC&qTv{Fa~Ma$RCufySNHRj zgfb`cd6&5Jvy^8ihrNB%&hOnmK6EsNvnr?WJMmMoiv&#He8Avj(3G?Ws;Bx%wm!aa zGTa1)TKTbJ05t*91O>K%!K`O7m(qJ-_o*b*H1-0{W=ST!&K@aca&{=Ydim{AM}$su zy>1!hbGV!<7D!qunIyW7jomA^@4TbEf!Lm!id`xr zM?oTx!)L>$SkK;`oMVlHpysUBNJnG~uo%dZgQ@aRTR+Vl8Y4x#Pu@hE?eK}ygx|xR zOZO8g>MD3I45n=)d0fly;0*9+TGCp%BMluL9VSAG(j&Jz<2o?(dPwCj{ow*;TL=fN z$7vG?0W`>={={7=qjMuj#Z}*CM>^b0j+Qhee}9+IHuIYx?5q~H1Mj%u&i=^6M(Gt& zmpaiS4#QV1sy|+5_7QgLreOLI3QfHq=;Ah-6>nd2e)qq-$`%X-FVpsC-lgEB7Dl$t0H<;?+{<#`G z9)AEubQF@QwUu*qR`^%>^bPSb>LYK`8C#iYDw*cH3(NOL3ukYeEhNNdWX6S+7|A5# z{}aaP{aD^#93ViGi>HP{w-JLz=8|9~ut78sfC)Ewx_pJom3itF0r1urv%8s%zN@T8 z$t26tDNm+{m-(lX`CH+_mOYPsNZ-ZuF+hm{df?iY6ty{0fovw4qF<-pWR(hmv?V70 zLr-a7Xqy^2=M54F+n?L8hVOh2;emYP1y|`siW%n;Ve-D1{g+#8M7K&wB%JD^mc836) zE+c1DX4+n=3l_@S8@8mcYTS9yRV}9j$`k*dA01xcvuZG5uafAx4L^3!Ej}twBvzw2 z>xqU7YHlIBbgmfFRR&AtjVk7+nC0%QGry?=mY$mVk@?{H#0WG5b;EItlbB~FZJH49dHMxz8HjZpmcpKmAX&6GlBRbSoKbhcFQ zFR0Ph=OYm9Zol+uw7qH;6J!8T$tev;Zl{T$(2X!*)&2aAi7!R`9EIhLU?v|XlQ$+~ z)y1cw0|SC>BO01zu+2`_Yvaym0!m@($Gaf))E%l}meB82>^%_it6%S2RsAxFZu5@k zN#J0}=U;Coo>Vyxu@Z2mlivdJP4-D@2qVxMT|IF4UMK5(*aZYSb9*@k_xL1ey2gPa zXHiKkf-LbqG2vZd%uz(^0gy)Lwi%9v{`y`MVdFFR_h%+I$AaEMs_m02VR(i{Hhia9 zW?wb?*i~$5b71e}%C!YrYZ4r4=BwFd;3-Rg*vm%yz}Q&*X=$pe*_Oa^HyZ-L;P)>DLMG1|=@HT0QsZN3yK2;}dL*dvxrdZ1d9M z#M9qDcd(*?p_$zb^<|J^X}%M#5~@n~Wc(CC3N3I$51qHr=$X}J+`6v7ab;i4X8W&i zcpvhzTxt!i@;CeWLGs*G{wD6wc~ioNgK^n{7sw@^-o?4{CMj$GpC{gXjz5>%rL#;oCDHcD>?b9QKAZ(9)NIIwS>n=I=`U)@|Jx(TsCCfXF?5Tc+#S zS%(;BWyP?shPlQki}}=a^X75fSDrc*(HgQUI%xoaqj>G|bfnrn-Y+zr%G7ziUjXV> zx6`qWm+}VwSX|v2!oN@KnLo|_bGHI~zswRQW&rwma?vO7{cCZy3k+%o?oWslVUO!G zNn4|kCSF ztQ46-gLo-x9hCV-nulX94Ra%c5vXrI^U3xFCCk{_#0!maNGlXaC#aw1--;&)f^)4l zDp}2k#XebOU$;vI?gRwoCXU#KZ69;2TkFBDELNf`7{6hKU^m9MBR6I|X>5d!kq#Fv zl2|#0Bn}eqGPOF(k2Ndu?>>8y8Rm!Lxh9zGhf6#Or#j|iBe>^L@8k=YxKyelNw#Q8 z+??go>$#S`c{L>%%u;4WGCfr~>f#)%6HqqC4^pN?&DaRba@i@WAbkn(fz)k2YqnzR z57jPZax$KKZS~jd=^VFOp)qL}LE(q03xc&N{ZCdOm)Y`=-8w2_h^fL==YhJ7#=OAH1ig)*X~nUA9+l8*Fi$ zj%dm}Zw%?(k`m1gsP+>&)O%%oYASX&8infLJGt-)OdnY#+o9y_+sATnB#X{TIa0$H zXX}S%`>hfsC}3Z~5L)+$wOzgzc93(vtU_Xn27Fk2o@MbhvyW;gW%slvr`|+jD@|b5 z+T*ky*r_NyEN+w&X=6D~p{<)c)u9iDWc!!03V1ATuQ=1fa-X-mJschR{)0{5mQ28M z_JAEhUXsTQ6du9bnoNnPhj=fM1gpy6c59yf_S0}R*5aCJox9E7XMGrpGSpq6Ieg$x zAOGb5Ha;bWCE{$h^9%VBWN#yb^JsFa7f0=I?5jq*$$Ipm8Y^-6l-hk>N>)TP>Q3i0 zy)F(m61uPe<35}Y<9SiCko+O})~wi75$8@hkn3mP!+7UMSg@e-P68WKar1@rzrVxJOW3tp+LIeu*@Bc{(f~CbL7)l zNPgl{x*Qo$+AT?QiOh3zchVUZXSl@g$=l7}Kwwl@zJJEXviS0rW7Yyuck-kzBgDE?j8B1x5A7g$<4!|z>gs80yO zx3cLT90#k?2b!Cb$pqN&w(2d*wy(li>65F4Ei~yeMBQ6$;Nz##(TxdzVrL3_U4Sa}NGW9ojV8N%s+NTUPjd!~maYKK>l{ zFbN_tR*{BM;IuD!II+cw3B52RP9RQD;3-@hoQoL^uUC;`_Yc4mKl_92;>aCG8f{gy z1tiYc+*2)g&a;$X))JS80c`3=E(ix4wtogv6U8ccHzoNC$s@yr!=)J|a+xP{Wx7XA zVNR?WBbt zXE}S$tfbq&TMjyTaDgEurE~8i@Vul6OL%dDPvO3494yK2omS+M-N+ijR;=OH8fvsZ zO7Y7^rKU;CXY3Rhg>c3bI*j#!b4t^yV{6+~rbHpJbf{@H^qi8p#hBJ=Ieaiw6?+!1 zDYSLascCL*G~$<&f3y>BXsB;<9ERF97-Bu@#;vi2GfqgwU5QzB9nUyRCVU21-kNdt zlrGLR5YSF3UoCQzAaqNkp=SDsGhu)$yW@f}Ufk*hhHPpP4GlF5DtQ9=7w0c~yfuwt z-ZS39I>YM63o0zKO(O4LU0l~1Qkz1q*kDNf`$#r0R6AT>Rv(R_H&h+}cN-b*Gh8ki z;6Z7C#xJ|9Nf{eJ60C_4W48a}ONak}S+H5*BG#NJR;(wxk~v{Kiv>#vbF*{|Q`7Gc zGr`FB_;YCVo;8+eB4B6~Z>i>`)@$-8Tc}htjchv5l8LG;QqMzUxC69>Ygdbm@;21% z`ybl*&aDY_h2veyob^jXGSATx_rkX@`}Gxl2KXiUpPkgavlj}Vz&NK;aPn<{>SCO; zJq?$mK!0{_ORpJ}yTymG+ugNVaDiQ5{#%W(7~0Osj!H(;5BXv+UOVy#j=M7gddT1vo6W(({mp!%8V)hug^;mhNO>`}{*P-FTD1#?mgGi2q~m3; znOKl`aF{t9%BkaI#Ylm@e@Iq57&jVif!r3q-&oHJA9NBKoIGQe#%7~fqq@6nBKt;uP7GtZannT)FoxnqpO^I$yp9R94P7_3-CjI$VBn z>s=lA`q6-*G0q|6nL5h65o=TFSq^9R?>jvSXmP!QI_tsyUtx8vSOBfO2(`O#66B8A zEv}p32PfFB--`6DdU7l=D2PLs+d<>;e;UD>2e@}$>^YGlcJ)k~o0wE(YhXyr z2Mj#?KJPaaV4>)cPKX(4AGQ)a1y)VUwsbyVw$5{p_B)ir1D?ip zf>N4RVFCWGeGM?fG$5vd=*{w+{paYl0wuMpo>CCJHe!rp$m2)b-B{ruZi4zC zEM)`os`#wv#`5HSGE4y}suY0W4#}*C)ZHRqb^G$(a^$t^@%w((S6J-!X8``o`-Ds^ zL#sDh=}BIiOCrK~kLzRK*fsM&@ev#WN|tp$-NW2FKW`?MGjh|D`*z2ZN3iVWevke>KJ*$PrfOT+W zuIHg&B+}9~(s7Ip$(CCLXBx1u#a>&Aw279%Oe?{+C?aBVOG%$x22RpZ!b2uM5q#H% z1JJNoNodhaOITLS>L@OFqZhGp|KMkg8~;tgCsQqXFZ6wr;_k^b$$Y6k6Qjjc%;Ab;}U+6jrRi#U0(a-srq4$+a>RaYbsngYGR!# zeYw6?B_3--{r2G+Zh`ODQ?iEHy@2NW*Rzx{jJb{(Pce3~N|JdncG6$CLDA^D9>)U5 z;fbw7Ey7(wmVx?P_`(NI0zs|hD%Sl2@3p#5ZSoFuqJMO*zTCy5RNDQS_Ra);{;BPu zY)C+|p(sRVA}3kz9!%7Xzd0$F%Z9dY=E`lYce-?y?8tQf9_CPA4KK0yzDBM@;Jo~dN|~Lx$>tK(#v0#A$&3K0@pW;Q|>O{ zVoN_7%T-8Yn-SZjt&=4FPrW!9bkdli`Y=mI4U)eU|Hy)-)Tu5X&Os?XUP%5NuiTY!F#!Aa}%~d$gnwN2?8cL>I>$eSJ54Onn(mq zcJ`zbOi{8Q+tv_S3V^i%49lAZRi3E|Aql>T z9@F!>%12S|IYunUJ-tD9U+U%Y{zK$4B>vOiQPBmNp#GYYJ1x(k4=T5Z^){I4>hKcC zZ#awrsfKV;H4 zv&*YyG_9`~v|ax&l5qrT9PLu%!5(YNkIwS!b5Bj`)>t2zuQ)hJP;f_MFa$s~B)~`| zpgunkw^QT2^=>XNI-4j`^z}!k-cRz9X%RV96rbeR%DoK<@%YD;R;M-5t@?wgd%wcU?MQT;2}d`fa^NpG?_mVCy{> z-y3vHwQF8zgGqHLuz%*_MI*5^1evg^s+%pHmF6m99aJ0!KAb;a(meb$Xq_roZDDV7 zaD-{LD{Cp)m8WTF$;cv&tgCX<*x#p@aY5MA?7!vYD7Gu{^0vrtaeZ@6UyfC`hQN^7 zb%-|3EgN}l-Pp+~OX@P%9Fr=EfuIc-lD-8dtVSUCY{1O3x$M^3>jW|!QX@{O)BlZk zC}-!jR%LIk97bt5cjwmW)H&C+ZdWYZI|mWycvh`x=GL;J3||EOzM=ebx49g+(${&) zbx+I90kZh$E3i5zVbP2|I|?s8kpNmCbbBbLa3VvhO z8ehsE4~~Zq@_t|5*)A$B(R?X9;Pc@%ZAxVcmw58noh;=l0tBY;%Ms|{ZV_3FiZU@5 z-3SdzqH|$i-99HI8orfEOWE<*l!V%d&6Ji}MJl^bkobThk&qHc=$humb%5?$VPAK| zz{vY)+(wGiPZ^y_Ym0wp4tf7ObMIc6fse0gt(mn6MWf?&NO1T0Mf+P$kW%B?%0N|H zs2_*!xp}AL=|@tFwU&6%|AOZ!L!Wax)PR0FDJ2#Hga!WV&W?>J6Y!mL9OmhYpmFZ- zV5qzzt}Ibk-3;rvV04rv6Z^T9IgqSiPsfpPADAUOnJHrKokWW1y?K!J5MjWn{sjid-c0v0X`ta--wEm2^vrY4?UEiReeZ4G(Oxm=6(SgmG<|vqVut_!RV(uXkh4AyCAv#kn>OIP4@PV{c^uIQ}y+nv-9afPl5v*W{D@WD|XK5n?H%o#v6^#o2lRu zRwi{b()|fTRFE-0qy5q(%*YW{?m+XmBJu^NMB`s#o=?D}3Zn4K1zsu+-ikmOS>|n%4U@ zocpj{jF)AN>0{HxB)KawLzjxPtyHY+;&FDv?arBv2`6y!S(4+A<`Z#>HWOH}kaaqj z2d`Fww5kd3$0<5>qEm;~X90R< zbcxC02smK-*EYqvKQj1BmOrbSmeps#!$b0SfucE)&45_>1ReJG?Dr!FgQ5U^mXB-| z1q4Eul`=U`z|Y@qCMQ+T7jy=`2>YQW`LYCL#4b0u6=hof94-Mn=3!O_A{M)d3P0n6>^c|U=d{+=Q-zJ zv&AvY7{?lZvL{%_{b!#*1~=&^@{*89Xbrl#2zJ_0A0W|acSH|TnY*3<|Xws7->qlJFWxcE{xec8is7Q<5N?T(=l@E)-hEj7movT((wN9MUS<_96Ar0gthSV@ zkOo7Gn}qw5B8E#U|(RZasi zG*YHMLEEZp`wE}Xoxd)oWkyIQ{E(!n0*PSBQm?0w`yLC|9Oi5&`O~+Sq_yC5@iCeQ zGsB2?(y72>W?#Ly03t7XCX^9`Z8li6o?_l?UWW-LiLKJQgJG)@wa<5tw$&M`a%yB+ zgnUB127c}6uwo#+dFx&SAEk>}xUYI2(Y=PpOa@Ja&+|!#Ac|iX4D^@5P*yDWLjhQl z8DQBQ<`Cd>nA{D9h)=HxKiyXpS~1^-%kM15Q)pR7C~EVGH8#L{A`AZI7>YByG4;oi zoNaxD5M9u0J9#=zNa(u=)ni1;y5Ka$be(QVU2U;gou(4zRVRDEQ_5DI+G^sHfx1fz3 z3}LDAL+iZwZ4+%cjOOZOw7|{3hv&M>jO!qdE{M}&pu{wMs))_P1`vvu4`tnzi`8F` z#mjzsIKA)bCxUTbB?YL-lPvh($SDW7y7bKdn!8v*ZLptrm_@bUMm{&llc1YkOTTqn zc7~}W{3p6O^uh5UXF4Ra4GJ~qQ^_(F^QX4$xNUcG)V3kf%Nus0d9D=KaMkez-!II` zMnyX%OiF~VnIs|OowhS?K`{vZ1}8_~UTBNrXVGflD9a6HbB%A0)?@&s^a>qi+bzR<(|Ond9K@pE?#b9e*mV6wCb7#hB3C=PDODylU# zyi2vmG$o+n0nRls88Wz7inVIG6CRv`L( zELa*1KtdMNDmi%K=*X!7w%c04$Osn*B_%8NCLv&EGtFUTrOGUdDM|pWIWd8uK+Tj` zGIL&m15yczj2s`VXg}uui1hs#F0q0~;N5SB9T#m)Myg-0cvscmuZ8ZDL?AI*UL8yW zU#Z4^^~|??mhd~8C|GvfaMMg)ruv^1n7RQN&tdszZ#R#TJnDr;+)$e(k*R+w1yjU* zR16sxjUB_pIPQq3cQ_l*v(B~eK02-NF)o*1BOg%C9f~8-S1qF=1W8p`vuz4Q7*Iw0 z5BCM)&xO!k-ZFA9P4Ub*pMPkJ&NcVXjbD*yCsqPO8b^Doc<<**?P*Y38u2oAs=?#Q zgYE_K`=Di~k6W1NQ~=I&I^&-t$92}XsoYTYgLH~?c55EAJ$uXDT)Y3t|HW0`{ypwz z%n2D8MU4ig>c{{{4FDfH6GQN@!)%4+$MOB{J_hPlUheMG)QhhCvVvkCm4vW1&9kb9 zYgVp0%c7z%Tc)W0$4VI7BO7_gSCJ7sUnAxdk#C%zrkK43`oK@L5K#LC@1dZ;=6Ghvt&|BnR+B#p6Y6w8V4=LUa? zX`8>@FOE21$l-@scMDQO#~|+nT*kbDiZri$Rf?JCn2sog2ta)3WK1t}BN!@1Aa~Eh zpaX_P^HGGUN9@=WTuPV)U{1@chunSu&(%e9#@t%h#{e<^Jf#zw)5(tVp+8>);sHFL z>1Q4${poyuzDVcCHfSAk-IQL|1ZYZZDL?M`zuV>wm+1*FMjQFYL{OzUUtF9V2!^zF ze}HV6*Xy#Oco){lEE2x6{sVU)jen+R!Sv5P~GRtS9?7P~$f-%kac*%1{ zp<)81INFNBA?gfQ5z?%!S**dH1BA-$e0`jonx_6CQ& z89f-zkZu?aMWH~88}B+8QeNZ8i<2wYtKREC$ZSdxs`%|ERU00X#ku~AIFCLHF8DNp zy1An?6qq2)HyIrN{k|g&Y+Z)4MJc;v$lGAJdnVC~+UgT3k2h@;liTx3j(7RwyC)dC zCy*tWpvV5Ts?WjB-&rV(F$+AdQDvEuuL!e6U{_e`78DzTUMZxbRCQ{#1FMY`g4Z{UPY4qEd=X?v@EvUf)Wl%K57$zjm zm6IjI9`(I=Fuw);IIgjk6ydjjkIwI69{&F7>i%d=P1CUY`aExHHeGwqGuAfxb;>2o zsnj-syaNoOPOaYkWZaE1IrrWpOJQfPfGowh?*7)yJPiHXlksD~;-_BMDY34L!z~(a zb#;{v)+15*2#9 zmsGzYx2LLMrRHs2-F11SN_u_X4vfp#CCs(}&MHDpIq8s{w=A@-+(Zp&cpO}sGymIW z5N_eaNZAK*v=CgYZ{~I{6I~+DsyJK$V2H~H@a%G-AAa>=Gk`A|4i)&!E>$&3vV_m> zjo9j6i)JB}DWWUd>ef{*&i}Tb_=WD*snv|CSK;~O%a^oO{{>PF)nrNj0JKrVHgXa; zhuLKJk4ExO#{C4-dGebb*R@+v7WpDlQD^K?nRwZ63MApFs#crr%Qf7&W3k_R+EXx9 z37dTtk*V3=&>Ye18M$(l*xy$ORG?V5OF3U!+t-}z!OpFj*&&wp#U^5&i9AM(u8mEzokg{4Aa`d~=W4FZWnsJKGnRH~r6Sqs-I1eqUy zjX-4J<6^+OvhxrAk<-cA7Y!v=P}+SlDpS=+Vb#vF$aLzXSqJGtm>!c_V{sU%-NX{! znZ7zNcf`$b2ECi%V{ydYD5XWDG%^%Yz{@5cJ{yu_kAU5d9rP zJ}ge<{qEwK=LAR{n|C@pH(Z3s{gHZ%_K{Kwes{YChB)Ezyt|PMbQczNPiTv1_FT0h z=-jXw0z;&{v>(;MHw1`#hLXo$kVe|?S3dZ12ra0Vpk2F`vVeViMdq}rs?ub5^yE0B z7H!`K8!`6}luoQtRQDXueBKp07NZ3i3Wol63*^Xn9x*1o3qM@gL`c6D44*dI0zTd( zP)EhprJj%FWT)0jZhz}`=q18ztEwnT-&_3Wj^CLfhzwYg=;^4x8EU9*Q zUDdmKw7Rq|Uk*>zIMD6sGi_Uv;PLnr39p9JL> zUfr5h2LBma6WXSIy#H5Eh{!8MExQOZd&{3Y1|0n4;2?QC3#l~`$bCNp9wUD%;4B8!)?AusZm(mQmB3lf}*2}aw1Ua|YIe=0uDZz6e@BA?a zKTMn~dhGVXW-MjHRk7YW%AHjOw`F{^n4zHigXk z7QD4vp*I1U^3_xDsWIe%qD&YU;>C<#NYUr#*ul@~>Z*CyJcZqOij!UBI>0LUp6Yv1 zjgMv#Q~qOBO{oFi<(QVb)`imOU1~`za<@Ya^k26xgqm?ZfmL9L978V0-o;8YvA|yD z2Q55+$4|4mlr1H9`k89n3hghm zAFt|dMs$7C_XdmEhpSOyhw8~`?W;XZjEaJU712Y~`NLJltF1#}gMYUS&}S}M!&Oq) ziSvIvA4io`Uom^f!+Z0lFh}We1xf@5w>>hn&pj9SoVi^A^u&_EHg{pYp;M{!2hPkr zl+ue}Xj?($gdZpDbca?YhjB1iQW1CUndJ+AT@Wvv+tC6inM_L1#O^N`@=MX&J~@J- zySW*|rzdIV$4$#ITIpug?sFF9b)qQWX(h!=0)EBv;9qJ#&9C8KKgviSmwxBlP6%Jw zNd(}2Dv$eh4~B#|ZIu$nFjI;2W%vEhWL^`lh!s9NMEX-c)=XI_M}e`f-l2#Q4^{$( zrfKSFu(ISrAMnvkwuzggR}{uFszy$8lu%xSG)~rs>LK>ZGS2cp<#?x3NbTd*5l7Vv8+X;?0Ajl=F3 z+BDraYA-a}$SO3MpI!B4mW~H;#1vk9-eQ{p+s8k(N|%8lm4)P)|9RgB%N(=>d~IHI zLQAGqb0i!GEQlcxCe)Lv7RcsY9;&96Xu%n=q-ASh)r=PlEWI!s)w-RIz(+|}{#F9Q zEEL5oio)>}M~~2==kC$O7n48L`H{N72PotE86taLL5H74py9BbM^TFaTNMQfSm=d$ z%1EMo6`Ooh@HCiKV_JxBsk1)+qYAgn=(r=5sR#06-TPKEnwK;M%Y%>< zoe&Joo&-YxPeAn&^F=vxGA62MlC(T&Ta0uw%-Pfa3AcB8{mde~62A0gnWTo`WJj6n zAH3QtSxEYh+QWYB{Tj@A+h>iBVmZkTBHJ&q(G^W6fzT)!99>+Off#yK}Va7AHK`)150i zVskqkJe=0Y$CusQK|6CW1s($W+FC9)HO90{Ip(Kq;g)6 zBegWr-5tWxAYIbk-7O)C@_Ya9XSmOtb6qocg_{mMRq_sigpq3q*%1#P(8V|p6mNa0 zr5km$N+x_LAtU&ewe??MdhGKv$RG4^Dj%19V_zsDLg(AWY@hZrU`Ge>7yjMC6NiacpNx3uAI96EU)_Ir0i;2_e~A~J z&HaUH(UEwceiTJ!D`z4`i)ch#SaOzpI8tqzAuoS7Le%l}c=*SGi1n)ZGll<9I zCX)|oBM1=(Kw4#O?*0v61CW(;Tk7(JVO zzXOmFX#*Q3Ynthkdl&EGxIpEjfWW>hwV_Y9(Ux zrQ{m8vGa^4-<~{rz9B8~wl;j&Z_ z7<`WU>aImBf{(>25b39X8_IOLga4_IxD|kY35F9Al7SX6U3xy$T>UP&y8G?NQ*8X7 zPpKgPzdtO3`5XR7n;^*{y`*5Zz6&jl6orIIu_V;GaSNn57ds04`x9A`7>t({C(-H3 z$w)_ef@*jnjgn2PmJ_|a5&b@5vD~v=`67ZN1gsB0qefu_|IEV*`n#Wsk0>rjqMP>H!V_W^iHN{&rP$jG| zk6g2jc1`mBLhGp|l4CMz>36}jAn$9{(AZz>Y>xF&Q&*1?iq}r3>6m&YH2k(SIYJk_|}!d@YKfzfG+>fSN9v9k2O2uF14mNloKc$j%{cIkX9q!-CHU)m&D-% zKv0@fqe|p+b_r@+&G9`aw;lt-_RoCr+4oGs*rPX?dN)=&Wv^)k10-u0N2QZE`3SKO zZ{*7e8y9x68B;e1t8a$)_xIvS3I+JSALZI&3;d~^e`}vKuVs;H9@l@tufH9HC6^cw zAL?vj>(6VO?Z?)}k42+V7v!H(^L`aEh3Y7bUU5l$*?q+oKqQ(%fh)yc0(Fiis{>Ue zm$ zcOer18UbR#b}>=C#y06)uYI~+)F#OpW%-+K=V6-Pc6t6xtPw7IALx+#`_$OHSwKVK zPnYnq3q|F$)HTnllY~m>WqGd0)alm3+FA;-*M$p8805oAZNd>gj77Bt=kNaf#zRu; z=tAlpY$GFsKHlYPCYGc#msM-R;lCwU*Ic`zQ1wbfYh+pr-Npuf1MV-YqyWFW?dplw zk(Evo-6Z}$Rc`X|J3v{V^+2B@XO$Ne_(X$MMHWJ8GOQ9xU3m)WH?D_$!OM*W z)$6}{3;RZXH8jE+_lK1mXJ0BQ9pp0}=ULX?q=;KZgJ}coN!%;O3JKFFFR{w#Ykl7xYe6_&V@f_7f|(ENFyEgu!hIPJJg@%YPUghvbt9{=N=3y6}@1i3C;Z6iyTYl_J&Lx%t1TYDgm+iyfT zW4U~a-jCT7mrAnE_tSEPSTijk8Z zHc@ke?W|*j|JyCUfBD~TUfw6a{I5N}+*6PXVa2+Mz{IPaWsJV^&Odigl5AIn@+_ixsuJv z6QZBrFJlKgR9srT8`Hnv&_*xae?2Ym^!hY}e@NmmMa$%tN0>spA#>5uN?R4_HLX+e z8O)d`(1X{_r7Z&M#d5xHQG3i$u4Udq;9@lWI@?WxPdzS}OGcyZC?&QI#Do~+C)+CI zNUcDibusHb7^7a^cE<`^H2~3Ysz9(0^F{Tu^BpA}sSOv5+4P#62@2CG{qiNr6_U*R zKAYLL4ks^lAStJ@8u9{lP>qJe|I58D z5`}W?GG9kHnWI~N=3VJD1~5+ld5ktN~MDCID%GV&}}?mvR@q|4Q}JXVQvEFCO_if{0uEF_Jn*%1av=j>v}C5qP)oRBa2O&4@$L1EAHm&H)hrqEplEfr;9NIl-v>gO~O+NQMfLElVIa@~=(cdqI=> z`d*4!%utfz^UBxgJ)#OV91oCa_Nm)+*%<(N|KuMScpn&KW%;b4wOOPSedIS6_iy#J zN=Vwa6z<_$?TX(MjRGOY9mfCv=dQYj{gNi2dP3xKpJv#X5bT=lm^%W^{ zE7tLceH9{Zp;(D{&1dCIcJ@7-h1jNFB2&Y1<#<>`%8=|bk&O=i>5HYp2`kdb6=bvI)(s<);F%{z}9cu>rIjBx`oF> zykaig%E+x>_0mq~D*yyK1#OE;u^E;qQ)@iM##RiT$7a>Fm+Qznhra~-G z>dr1mz6_VW+B}93wobWHxADYPjXGEKeS6MQQG{Ie_$q3PDw97At)YqpAZ+|K@8rgD zj*1af$#$Rkmfv7C48!_S{AivVozYag0V0+fj+HDtQB>Ra#Hvi#=zZmc)AV%q|ZYV;s6C+6wsIsl#T(1H%~ccxG&-A?D8pCzsX z3?U|7lncbt^e|sMQMNcBlf&CU;vZsZE6cs3$nMc*urXtri6&04AG-49Eu|ri>w?82 zFP^F6?5DPf=n#J`^(5Mv!DhOfIc)jJ%KJv9kjWvQOq@koz>G5~HI3`NMfMtpRo6{$ zgHQfI!6zGbUTYNCo{d!iur!L?)zJ@o|0a8@Brq9j93!<^;oOYk8%}cpD=XvBiaU%E zBQh!s<@4^>H5eS$;CR(202*iaQIo*FZ7Z5?&g{qIP$99zM~<3s<0{Vnesj*GAB}Q( zSdlF>cCqcBe-W*1{zLpy=IE_6DGcwkyRaeB?#%}W5ANe7ivkcq+=Wn>nrc}=PUS8S zt6e`?(OeShsjy+&@lF)e0k;o;Vij4#mGH2snX7*NtTTn4wuo4$r=8U-b=45-hzOwA zU?Ej87=``(Aml`0$lo|@*XZ@l&in@Pzb#p*8u>=(tb9ok#k*aS?1!t4XJZn-$Od8S zewiP}J}uIB`m0Z)vwARFMkb?`)@=K>yPOwBwD?&fvYEbjh%BlffGPkB$;GOwCD1Hp z6Q9e#5BkE#{Uu#`R7PxdPY!;T44XJUHja8RGyp`CZgqmW{1AXRPw`Kt`=&&>bGq0o zyB{XG=T*Tg#lx?Ow=9ID68G-~O=Kg{%CV4U4$&O1Y}0U#E@eyjr1KWI7va`ezWK%J zLXu;H5rF1=B^|sJ8;a84g^zQvnSAg z&-6(k_ieW*?cyws%UD4Hm7tUZzR4uM;%C$;)3q8#_EQeO_s#>O{}YdBee%gD17j@e zUsMD_mIw!bGn$#To`lF7Ic=rV(-8Oc?bDI9@;b60o;5V;R`k!mE{Vt3)$?Z5VBwp7 ze67wQ58d)6*UMX%Fw!A6)&w|>-y*YVF**JqTDlvD39aMpR`&ngz{`_cP@w9@8{2d zy-P7`zSNj)8HBI1A>m3e?n; zql3jIW8lR9Oq_D)bOj+XKp|;#$qP74$wE$&J}z|jb9-Sv7Ek5cdj86o1R)B-(|}AX#})ITyi1Vn^}^kfWi42LiCNo@1WiU3ZrR&ps!ul{ z{Rlu*iuP;2@!JfKFuVT!Dj|*;SC27l$Ck0dhEc4hAz!U2kd#z5nB~|i`}TF+c~a7S z=kI*Uj8Pe%^tUO-ae|QE=$Wa!>&`sSf_0~IHB&w|GZ@?D+vXqWIVD;>Es< z@4EKxV>_ABEBg%DTD;0#r=H<0i^2=v{^rh+Ns1H2g?{Gc%s}Q9k&2!y)zCQ%hi<=j zZZ*Wq)G>Elow)e(&GrT6Yq*B=ClNj9doGen0T_&q8>;up!mH*?_R09qm(X(;%un0e zFTH4zU+*I3ESI|Q*4Z;#!u_xAM=wyQS{hFeZxME*u|V}_azaV%gn5TYxa^RA@yK?XdLy)G;OqOfyK0L&#J1Q1uz@aegG2lp=Pn95M;QaTx;47QRY7&i@ zP*T*4(vISzW>i#;mv2NzX7JfF8(03-#m&G{wSJ8&htG!91!t;ruH}zYbbvR65e(ii zqy|&3%Vc^9rFR<>c;?agYUozIeC#kKppHI>X6#=g=s(^~W=Djqlf`b4A zG=Ha8Zg$du9MA&%JB`_Hk?&pQi>poCd3+QV9k?W5UTY!X;q`!KQnht}he0_o=n=6>OXv zl*t@w6Tcjo43^@tI&BP8m4ek2O68*3G9s7`0B8l#;7jlFj>w7#o9$YBC**EYFslyk zvE|b>sgTpMoP!u2Z00oBcQ(;86iWddG40=V^(eUsCKc&X3+;(`K{A2*0?N9(xOtpp`y`gXv5~b(_*#b+}(b@vpU=3 zm4yavoIYg|lt>379GBq|3Q1KNlPaJiD*JB5@`!wNc|AOq>fgUv6JtD;FuyN%@WnTO zek-B?JWQX#Kn+E=&<0Xa%ZdxeAug@9i=3#e_hYBv|z?+xVUU)QJF97 zqqnAE(&Da1!EgQ59*cp!?0z&RAcixQ^}ml;Z9b`m)D=w}ucIIex77N8?M@KMwvcp7 zr6qHs#GstzP%tJ-pDt7tBp-r75EopcABGcw_M-jxz2n3aWS|(Fg>^xxgx$Fwj}pgKb3L}KZJKOexSijE)gqIt}t1P`aU zO}~!mb3n%<+tK_kNMW$?aBLz6XTTSV;(65Nb=(i(n|-s>?uj&gTS2F%)&a08D{2vA z&>|}_i)ss#oXd5oSG8&m+%S@?3_u7P@K(<0000Uxf(VjgVp#!@5(1=XaDi$y6f3zR z9LoR3aRf6}e_BwB+BPck&;r8N?K`h+4pxqDE^BbkMe3#P)=~cpdkkt zh=CfU?P`#SBOD6X=4WECmV7nPGy47kV-#1GOqo9_atlm-4&l_nh^18Ek8Y=U=PJh^ z%HBg+XGUvuw2*FzwiGE^LJHBQhKKSn3*q|4H#|Mff~P_q;Aa))4&LkYddNOg3)KGU>))~M z{#WV;Q;wuAa9cCU^PbE+Itnz{?lfW1Z+82P7fZmmZPJQq|B9MQhpd3Z*W#Ox$e=f) z_+N-%AqqLP2S7z8=89VK_)Hx_`Y)J!?p?vt^pd-lRg7>6h?jkrlJLNhiaWwd+K{+& zD#Z8+4-=H{&T{UgMz@+9P%AYG$1<|SZdMf#Hw zPcrjzVf_9&v+%s-R^3dI==^k49ZRR#(z?wcZ4R{RO+Yd-M7rpa9ZxIWP;-Ivnfckh z=W7g;5A!sm$;@2bX_F^$(h({C!B6FTCpnQdTD;T~d%0RO_4#;PdE-p&Y+Eg?;=b5X zp;{v&*_n}vfm*wPRacY~Yy zZ5p@{E$X`~TxEUuL}M1&2Ny$ZDs#m-oq+Y9&Bt{qNUj6txFcR}iDOy)8xMv*iRsej zc@^QagsFf0gQ;KITfdTlu;hjY&>naR{OoTU|l?yR=z|r8)X#-Zd078e5j%{48t+a@CG25I`1$=M-DyfOJ6@{=b-AHf8bNK30f zzmkw)E4k2vDSp!uqUYRYh4rkFLcIp7_a#3I7K}g4A}Fbh%XPNzecSk4v_e-5`G04w z^sdjey|AUc=lnMGVvC1yew7oH&bSJM;W)Uw6E&tmA#jW z=_qVp9!Jt;vof!?*P|w}c7;hK+A|7TJ7c+3M{2MQ5EqZb$(dSi*$0~aikU8DQk{8F zqOwSWTotRlJud+5Sh)UrZQ8gJB#YIF^Vxad zb#EFs^JCB#IKNo@@M?H2WX<5C%W(k>0?>nYzNNr9BNIUqM2pmTLlLc4jAzd#At7su z-l-q~a;cBt(Rp>IyGj^a6fe}6AkIc9xNq?%4ne*aVQ@V|dVsV{B}M~ee}IF)(Ia6+ z)J86vpwa=GH5fmJsgn5`KluIim+w3vl4JSQUmywv7$F%*7Z$92wP9Mv)vPz)e@ysl zdHPybQ)XmEJnjpLYPTG{WJe^QFW!LQ^~eRM&VSZV582H;=OmWS0Hi-E`(8#x68vGc z<#;8KO&%HXtk@#rLCiw5ZHM?ro1>wqiCf*az;A?9YA&pFJ?=>t8+|T=sj>aBW0gvA z^$r2Q?FXO_4L9MzAIcw>2jaNCULHw4F$u|Ie=}gLRX$J&U=mK3m1cO{hAu5ECZsEN zd=j%Ym4UjF>x39#bJ>!43>IOnZyMa6oJ9AtFoVIP3hc(QI8nO%4Dy3niycFSR3IRP1 zR(uT$%kmdR+!80^au`-5S^U675LSJ{4{x{U-PqANJYp<*wY}kLh$<>zR`@MB5Y75h zmp&X&P*9oqr-IG%>mZSc^lFfODpxA>?ba{Q-hZaqVw$nN9(ddI*#XpAEX_SyIFvVC zm~PIziKYY?4;aIbUU-H~pMH*!UG6Xgz9Zyq0(0>t|5;CSyn2#u)ZD?G9S(=<=@!zH zl>o3JQUx*#!oU9&OKe2$j=suLLIwP>kU8pMvXf0HAMsmFM3p~7bfNRkq7?p7DgwaK z;u3^^BVYDR`lBoXVr^G!XT~X=XV%OfE?J819{O8fqU$eFsX_g&<8j27E{0$&Xn^6M z;zw}6F^}@#OL0b;ts?*T#1OE2lzduRxJ2WrdmA`Brm$9y@Tvvl9Ou(J4;<=&+br?y zc^N|h%AKv7Vt)E|>+d&0SGyRTXx1blWYfQA9(!HK50uSIsdFj9B9m%J>sZ9<@4)>0 ztX3&btml;IMCz;Q?LGac@0Y=H&}1dY?XbuHyiT`C!h`&NZCV0QI}_%tC?OOl2gQng z$rANyX6QH~`Kz4*>#8ndjs|0Uczx~9brHJW6IDN|Cc4N>$hWP(fn0qF`nV+3rNqg) zvauNVx@E#esA@}H7j!VEhJOSnu84Ab7;n4$#Z=%y0V3;_OS9=$A8NhjEWwh}n%8-) zUewL1zo_4robPtfEnci&GZDK7Zu|@H~pw(fsYMU?^j~F_YktQl8^Qm(F2`Osg=HY3fOhPMXqnP84+84(&s~5Gr zo%&7T&DIeWbxPKZNxvf~92~+;i7av^vO6t+?t0Pm$mXC8^=CISrX7x6h|- zTzWY#)n+e`^)T@u0cf`9Yzp6eO_s_(VAm51See0fIGGEUfgWbr-ha?fHm(?HO|@%k zX#U7u`>YvadUpOQW98F$>Y#j$kjJYZ0Yyej6I>3FYo+b>FgXkWq64J)XD3vFl{l)M)ZSp%SO<-UUcuTiwLj%=f& za*t#SI51HdoWCWWlud5fgf>RCa8SpZjuB^lx&C9g`U8V&YIo)OvXPq4q_qNNSoYbqUOod(iKwbfglw;Rjc8Xr8VqB<1ln?sv(=`ow*6HL;ulPIjm>LTsz$|5J8CVsdKvQk+3PY5>A5&~4z&DBURM&`^k0+V*VR+23Ghq6sn3UX`0mGh!(PoOOy6xkvUvNa&&-^ zzI9RwW>1wWqKI?SZYVU5>8EeDaal?PB&&Mio?E=i%0a=EI!2r$PrgL$tld**%;*6S zSWjN<;TL%T@)^PT!GfR#fDGX&lO^$W@T2-7)NIV6QLItga|X=R6>^-EZ-~{33o;4@ zxcmm2`$RaBtx{*R0x99|841^+`Xm!r(|c9XI=ud$s|GX10BX%IHxjB@VT_a&3cS*u zU6wsYQ`??#+Dx zvkJ(3N@Y>ngspHmqRE99CmcE?av@o;DwU#0lVBqkMQ#BnzM>{g{o^x{k z&wnCaw~ANEW{q;&JxNWDqf@4qe9W{>_OoxnLecPg(dR&qf>w>)xl^01pPc*%v)TvJ z?r*xu4*tP|(j#hPrt@~-PTW@)OV!NRGh`KUM1PCXkRJ-k>>-9`q#LHI4Z*KjpCUSc zi;|D(bFL1w(7)Wk{u6S_vtv;d6&`(@{P@BIEGVTjE@2@))r9^7<>oXx(Mcn>ZN4^8-8fzX|w|p z9mE}C!s;}Pmr-SP5l5%GnO1fHLpBqhwij(pIeD)=W;^*rTS_O@A?s;3mJVZw+*~M4 zfU*_w>avRJw9gf5Jay@0O#~$`eR2`O8S}^jz|>(OmKK19>QEg(XpBVw2p?Bfm`@M( zA&v~DD{*VjyUcw8EA;S*@o+FN3#rBsrEd}_n8<0SCukxh8t+^|nXPBjqQx8?*ufss zl*bN07Omc=Vpo8Id#xgavY7uyafL4iu>TC!HAo1}4(7`)#v=Gy#yR|l?!M*T*LnSO z8NAg!cubo!YK#Mb0+4?kDur)KqVbd2>3hI=xbW< z#bS^gs4-(^%%&oA(DvgxMX>@JuoMNM(vk&%WVNi}W`VV0C!H4kg>~8qn@Yo&p~l9q z|J45m_)Csr@(Dr^p(u71I(WkA(rcW)I7g{!Zd$y}Sj9;NR)-pnjS4cuB4YHca$}?} zrvN3{V769T4Rr!3K7*#YUwCdXFD2hid5Tc6T|#m!->+zDAYp~ zvbNlMdTvS4h3Hro>P%G{rF;AyDTm_6u?l4-9?$`x@4e}ri>R^-)Ik9z zuO9t=x?Lu-e|WcC+q%7B+tcmo_bEKFQdg}zAgYELkE4gVV0uJ8ocU8O+fxZUp*4(w z)pH_dSns`;Oj#JM!u_aH5yARI_EAkZ~EC9F(N~CQVRcXW> z7ZUzvBg*~8)%d~Vh15N^Ca8%F+ab$ppMG7^oMR0$5*8rSbtC?-bL6K(99fKlWuLvC zpQ{r96}DE0SJF8s2n zvI^95dMoW(W_d+!qHRbY#D1I=>w58Lz3gE_TBMkYOh!WHpOlFPTPdBLfeb;E=77c^ zAr#;u2|yx!>IS#n0W_Q5pLW$;cfFDK7Si^mz34$2zVAQtUOwDozgzJ$*|NB`^b}Lxg!?_Phiiw(*|eEG01| z0I`~G&T(_Yqk~=hZHSF^7sS`sEQVyu?YV9xyW1Qd&voc+8P4UocUJvH5ujyRJR~M- zjt1$eRdD}@QB_$^5vK3=?)fdaU-5EYt;{j6&PiEMj$xM>QSM$XZCYFI`|(h@DJFQG zp$t4XFCl0+C~@;|)mu!x%g^sWa{GApW^H#cby%hTAo(_Nb>ydWR@=jfH{H3DM@<|` zH{GkLE`8$3l@aVN38DB|1?4!VWZ<{!S<~LcUHYfpWVQX}q-+UT zo9h7}sIjFR8G2=5k$M+dq{uR_Yh11RluNWr?6`NoOtRXs?frR0Z8~npgFx4H%Z35kj30}a+u5EpwM54T-PjpOh?(wvZ`E4(A)w*bWKUBsll zDB68eMcgwZBdb zE}dHi9v3>@rA5M0eb*5_fmFWBthwll-OUs4$5Wk?rpCaSR}0GN@0GE?e1hhoXQNBz z%TKcHMQ8N)Ne-6R2+I7N?+)W3#{%7DuXNUUp-g&nY0^Ft1Tki*l?w<%Yim-w7hvsXD0YgPb!h-jj0GFnqDN)XH=Swbh9dBk*dUC zc$?Ap#0K89Vkmu#{&m`jU#BSk>TT99hVT}@l%@P}ChXk~@=yA~yAimX0JP6pHTm*{ zGq`Y`>Jypk4-1hTa;aTQmw9b)8Lo8t>_MO7p)jVOBdYO_Z`}`q;cON8Jdd}zT(%9i zQSoq%VuJIq%f0YP_Pvh^rDx%9!KEtlHblpLu5#bSCs?i3$#^r13d6CnD{K|`GCb{r zr(nZqfA%kk$jP+mjuQciF}C$^>{kMj*rjM6yw1Z~CwoGH$&y6GaMVQMaguw^29;>F znp%>g766s{(BF>}%0&Wt06NF-}%UV6vY$gPW>0 z#^6Ie9d12cudkWriO_GDWC1HAN3@@}ObYh`kTu~{(zJ5gr6&WSwlGiUzAuW>^a%Ky z0Cb&r<%$7e9HT2ab-%=Z1_yY@rBlL%n78~W9U0%1H@@c|?Xp+7xhTm1QP&a}8-ro} z68u7{E%7tofEMw7wL!0Z;<|81dVf$Hy^;J>R|SjD+4BVesI;P#j6j_9pB)d%SEC5! zYvxlo^uH!YN2052jB1Spio@nF8>HYr>)%?iTNGb*uHNxrY^49!nPxJ>5q>4eqCl@-K^?`Kpb4fRn?#FM9p7)cL zi{8gZ#Hk)yNb8Q>0gpyMms-s_9sm-$lyA~mL?H5_LDSN*9&mC#(E2eDaf-PsYbm+) zm4)z7bM(xwyMz9?i*S2jJ=*=RAF5-m=JzDSDbZ%Y_j@Ur4^z|8-${z_IefC=ee_7! ze0C1jO|v6zLAk0Sgm?&m>MQs;f76l|7Uavai|oov9{2y$_U^ShceK(NC)bvPEy(7y z&p_3v#B#15cLFPd@ z{l2+OIYHqt{wMj0Z;iI^j`@8hJko2+Re-OQukRy~tsu}yEZBbSe!*~MdN?)N`8JXj zv=cst9$+QP{X*V>{{x5L=1EmQeb^Kp{i>fVv8`P}yxMaEfcjZLMzFOh!ECcW5bZ3~ z4{O%dek~*K$h)qMBYRhZ5R8pwYSqZ>F0mq%zhX`999$ySzJNtHYIlx(=SC&CA+N4M z(X;3q-_t5ZTe*+UZPj$JycPQ_5Y~4r*8;5U2P{x+ zuu>>T6~{PtGuYjThx4>kLu{V0*mFc+LXKXO?PH3BByDlaQoTJNxh;w1;-|vaEe!8^ zI$NLSrsj3i`XN(cM}Dw6TVnVMp&~-GC7XA0XebVygry(AwJ(_Z(?U=xzZ>ew^e1Pv z@FBoD7k~hVZ6J6%fh6gpNlN}CA7X8mW7%1P6FY=yjdcC)l1KT1gOjiqfAm);13EkwBX6($uR zS(-~G%xoQO7lfnv3zMY{Ud4)LP@+jyo6?*l%XD*dS<}WREkRB8tR9J(p2KfSx+>K6NQHB z8&?)qyg^TKm> z9M)Dy!YRHNTX;C`cL5NIu||;c>cY41Witu9M}c2mmf>QYRTW)b)xy;k98|ww;2X~e ztl?hjY7|LYsKV$7PL2yPzG;U~_d#7A>@)l1$XEiCvccQeqiO_n1#66hWyuBl$uQ~P zKL%nF5T{TOQGi{jGgcm%s$1#FC!rg9Cl-`I)BG=nDC)s=TJ4#Ufd$Xsh52Wuf3$&6 z9>G7|&B-4#m>0G9o7>(g_yWr^vj*cO;ZUw^uA zB4frPL0nYr&WVHOg6c|obq0FB(MPY~N7vl2Hwj}jOW^QJ=_n?K9(02uSr$wvjBD_4 zDD9YuK&HVw3bS(D-&qMs-`Uu%{$a!ay7afHx31Ud>Mw(T{=~BhDtIxCO4p!b9V?li zdJY9i4MS!+akoG!%ZAL9veXc2C2?aZv?d7MY@sv&B2=kbSiuQfpp9>){?uV2r`S$$%)lpzepnMCxvUAlot$RWR{ld zkSvXvI7-bwmKP-^(Od)})J5-DOE~qvO7DgX3Q7J9Cf>!$Pj`q4;t>HLh6%ZcK5Q>G zCkxRPnWS`)nt^w|^v?n(v&O>Y;vYWp>!iAWDEgfnuPgFcUB}l1k(rF$5om1eE6M%wQs^XKv=Rge1N%8`k*?=2wH#y&STU&QcwpcTQv- z^Ew&%Di|7B`JP>S8+(WeSWIOs0Vv45hW>?cU6)yZzUehL?HIAeycj8o1sR~L&e37c zzp1)r61feU9+kF|brQXw`6UV>*s+SovA2`znL55P{TO6`^#z}Sl@&rlB)IUU{@Ya7 z_7tzperJ60&|-+sLuFDu>A>{Fn z;O}-Qeb|mYMJ{tXJy6P;O=l@!bQd=;BL+c z-bVk>jQP#JlC^eQJh0nB14kukY@i1^V;2~G-` zxfeWo;$MZ4akan*pBE#r&R`nDKfu}Glb$h%qFD@u{b~uyc3Ihu9bI-8~})i z_OFv-^7Z-y+>~Vue1hEnfXqi<25=*m0&y^zDvqkghwG1IYe%DoVqHOm7fb~!S=QrU z`eTI1IccAFDgTLP=f8PFFlH5~4-KSu*zU_R&pN~wWaZGjVGWL^&_uM^JHHDRefRj# zz+5A<`uCl;>pKI={VlULT#|1?BQ+2MnZ%o}XAT~dwVP_)wX1D2xvFuFbX7F~s{7+X zKD0(a>vaeb-hw~9#+-8e|5!s%wDa6jhfd2?=8Qt|dveH!BF&+O~2hJU2-(uN*`xGSwG)9K7z^;@-O4rixSASP4>+^g}{Q!Kd)lx0o9NLJR* z5vsN;n|F=tW$5)w*7t0i2C$4~T`{&Y>HeCq3==?Xy@oXEM+h&B_KjGAqZV+Mc* zJ7Po$T@-)8I`XO{7zFnvS58|-#tHfsx@AF)9c+}oAz=XIwnbQ&fXp5Vqr$T~IgA6u zvzPCGdk4|(e@L9#I2Yl<`7U-C7Td{oKs`BSGS0I?TMe2<` z0o{j&8p8I@R$hE*n}?6xU3aUE!-pB1LvFQWb5wM8q~0Gq%U{WnKnm>U=+pgd})s*=M7=YaVuURKyZu&&Mj9 zku5RK8~eV(l{}yN;%pgC#Xf?_UzhXPP_W~jMkz|-mNkA_Oh)`r;ZdN4F&8|*Zc~&d z_CIJks+t(}MOiP^CYa!bueezua~UI(0SIkNlZ2oKIV-lrH!HqD;wMHlqs!Z2q$l_Y zfC>y|i&%t0KqsytyRV)K@{A+`zEtdrtok>B{_rUbx7bos4jwLPN;5yY76K4Q*9fvJ z0S@Gs0k-2$Px5iA<0;DQLUUmX?W|aaI-Gj_ol=FD>Se-)dQ%0HSvOSfuH%NYlTuZ~ zj$``Iz8OfH`BIBmO9^|S`p(RfpJ0#3hKs^6P&DkX_0XHd+X;Z{>(&;|u;~9xUDii* zs`)Zw>wwPp{{oN~Z|Jn`IYvz_FGqVsbgmmbVM;}vXPx4dD!UE^Wyw>~%S7I@C91$c zu)09Xn28n4xCz22LitLcS>Qg6ZdxevknFISZpfD&dOt+bV__pDt;*&l2sh>KrD^tH zfY~+90&v#ht+DSV+RFnpG;uuLoILGzK-JTJoxwW=$@Jigq_qShQwU$3nCu3u4*i=mwDp zvwl|oKUR_~*urMOp~?@!?Cp8O@bl6exM{DM(lqXGkM6~vt(!!bJt+eu;d492&(v^8%@>LVrXfa}z0 zYVEf1QzM61d@Er~;anl@u`+^ov^14&)LpD>%hsYKG_Ywl1RNMB#x#^@t(^gqqSkr| zG!it*ShX|-ig6aEBj)lt23RKeL*bOX-=DyTpl&U_zH=u^u$zw3%#_wTloBQvUSp(~ zO-3D>6A0E~<>E(u8#v5$?Tww?%p)cCv@{xL?dy~zII;OvS8JT&@Ec?A8+>&(%!w!N zk730F+${^rj6l{K=nfaNN{*;-sXm5wIE$#ckt5-dN->Rs1rbh=FKVeoB-cza#vzTo zk+9|PRvaGGxjveB@y&>j+ShPjPdl0b$j%y;^BZW*BPCG~mpDSq7iJsmg$5*YBP9%A zGm=H<$IVKif$~?Idfyw@#UnHcneR4tO}(w|k=!UaX=#HSZNp88f_>e zC5Wg*BVNh9Oi^yN!q?JBF#jnpiBwrWh=nM3FT@1?j4_kopI%*H46_*@byZlNdym zB^1I)5uGxZbmpU)n*94D_70%S52JwrLL5U#2*M;J6wFm4DuN5bE8@5D<4ZgQKsOA- z66M^ha2bef<}d;Aa(DEroQWj+x#_0V9k#Lm2~ju2&WBPF7d zE%vR(Hs>YCRh__yEqXt1do71D&p-=DXbFg7@Z>C=6%;t!z!gOtxPjy%e(M*CH66`T|Gr*|*KHeiG;pAD(fntq5SkzD%;ns@=aM9Fe$LpjV zakpYRke*)>TEp+*+oF*Od2+WhqR3Fmn^#qi5&Tox`V8GK8JSH@RV5o-s30~e8VUBK zie+@!eDqaVL~W&dHc8r-O??kqCs*2US-2Ktwl93Icrwz9!03vf&5Py-pQr>v!i>ig z>^>rOaFZLPNyz1Gc1N`jNU9c6eUVBRS%6`{_hpE2A`i4uC}@WGO6{Y5RpoiwWbM&A zu3gKkQodfZx>Pb9_|M`n#$!etWh{#tBPx~wF}#kG$+JlmiYu*o-V*ajHo##XFpLa@ zAuMF086Fh~8W4m4q9Y}OFtbWf5T+}y-}I)A!5uOH$N$<+5_50Z0QA1<^Y!GozDO<9SI^- zp;7JXM?uu#NpG@YKM$1AhWqeEi=3z zGBEs%5TZd%wzQ;Dm9s1L>1>v%1R*gLsDz592q6e9peLpVffckz1aByd0s)H|SyrHh zk|Qczgdn)EK#3G}2nT#sHG+in#|h&=9kgJX6Zm4Fzd$G&^CrFdJv7%Nz~sA~e7?=} zs}(Ggh>K!`6w29k=gGtY^~dPn%)=!g$cYjtEQpMX2_U1N(s7vkahBb}1sP+&s7+r= z>0civCN}Te@&uYwO;DF$bW{#d!#?Z)XRqw)aCDtIlB6`)ROKLw%a9;|j95JLOyi=? z?6&Q&mRRO{tfYS7xc^>j*L^PC#|?-ElI?U?d|Y#Y29%A(#Me5U>=1 zs^%q_28yZnh$qj_x%1re4o)zGOdj8_L-u~N?u47*9|R)OH`EA-z(`hmt12~(BP#f7 zSu#&!Oa+2lkM})0v@z`2u0&KQ3yc-BmhHHPq87^_ZD7<<1L0KI@{$rdaV{}rNaiq* zDT=JdA~cjk8hF4^Yh7VjXfIrzJUT+}$+<6-D z)n5#b8!?0o0&LSnG{f*yp@Y&I2>g8j^N65oX%z#|mM9y+Bq$=;riddYRZwA$xI$>w zOW5-vc3)#h!!MyeN0I_|ufupo1LT0FLF%?pB1D3Oia}~+EsVhi$TMqJMrs+b(X!N{ zzl_mp-8SejfQ3lPBSev?B_RRY8P0*b=Qo-F)7_yIg zTJ!7pPOJHZJUVUUnd>7Z4%v(yfde$m-kbsYf+z$CtRSdi5JZBGHEDV(G?hH}b_H>X5)u_vAuRLj%RwW?*P*oUM%f?Z zI}h40eP@@~2qURcXcx-u{?qa(-kSr{)8pT`J-t@cjA({<^Zib3d=CF7VJf~Gzl1hF zbew%(E?pbkBPCk3k*^~vtsqg_1_?+=k-wc54C%ZJd(ZHtqidS_&%~C8%p1~&#s;D) z2YBZJBPs;iDb9k;f(K^pBDP!0=q-8ILm?QEXx2hR1`E5CR~xl`D!h2FKXjGCMVV+L zB>@{rq|$AmF%d-D2A*4`jkL`cnP$|=wb~GWY80guNIj@OxFDNC046`SZrk$sZl13Q z!GY)SK3Dr}d56?Vpe`RHPnE*?y?~v6sb6*XS~iNB*%n)6QF_+BUyb+L)$jL4(JEA# zB(Y@L!Dg8?nn`N?Kd~DZ*YN%|DYOh~RT{>UqRLWRJ<^FGA%f9Aq9_GL49~twTIuGq zLAXNb_>pV@t^#YIBqJrHVLag@k#}{=w5EwRGOVm)TQxE(0Ta`zsZ(UFue++RP!NXD zC>q|1ALHU;@$M(J_WVCdgQpTn&>o=#&o^WEj)~`)^2o@N(9{F<=XMr|PaHz#N!TKH z5&;r+C9XUX%5nuW&S1z%1IZHs_TGy9Hmg{I6%+|16I`k31M*cq6C)*JpzA~3MPn09 z1ET&OAazFF9(HOPppqe98~z@dW0Wgf^E|~ig99v4eYQl%Q0osxq5upa9)K+Xp-0Bv zL+a}7O;nX|xh=L^P%t9I2mvUSAV85&EaqEZJ*NH=?%Csf(F9N4YEjrRM5P!dgJBDj zsiVRY2of;)sAvyquN|hdv)f4_+iYSF%<`J`6Eif^9uC0#^evu@+_a=@PQA8Fh4+XW z@l?!ap9x4!c{(*vhFYRynUXj4ceTsuQW_iR*9-G36noTD;CTNaf9wORtMRMv`5a)R zDB2}rn;I%8EN!DDwk^L)TkdM{GAOG-r9V2X{Yvug^4?#qrWPy@xHjNvf-!|j8blbF zv7^R{s6uGp*EfN{fxYKRiC@31|rUu>Ljh#)q;HgN%{9MI$PWvLh-u z>qhuFv#-%3B{6-&?0jJuHi*T;7F?;A1+};YS|o`#$8@-2sfD3HOn=l1*!O zcIK;m`?j}@MH?~^i~wyA^faRcU9kUpNT#q$L~fK9R|GS#=ekL#b0p%9L|B(5cK%aA zUcz9@-%+Waw3Sn9bKCY;2i+qjT^1o4Th56U z9fD;eDkCM}7a(J_r3lqbj539?lG`b2S*BYu*G!_26mf)X7&b8-iqQlIiZ#TtCZm)K zyi9c2E)XN!fM@>GUSFRDTmsAwQ4fzOtJ=-D>um>aFsY(&9?b}2W8@q$-zQe>p)IAh zcW<-X^gaKX5Oty$O#~1pY?tx%UaajG7&dZh6^%4U@{=0;y7!D4Lxh)!Dov(YaM)fL zlku`6me~R{Z$dbUy?n=7k>(#hBPt^*%1M7|91MXscl|}T!=8R}ah11AN$6{QGarhx zOKrMgX~dcnIJSp6pjfRDxi5`c*CQo<%@~Tw;RLAQGnOqgpHoO_jSzksH1Ic+ncs=3 z^rVR^ZUmO?h~z}$7;n=Sk497F6(q`&@nlpIDjRi0-8Sxkf)$*~)a5r6a0@N8y~9%n znsy1QtC^t)u-8&u1fmDh{c|osV=hx?huZEeLUXXuLYJ=A_Lu6l=cabv_G_k8z37*+ z0Q5v8o5#n7x_6+3ul$fk(}ZY36kt5>a}x1|=Nruj`95(a+aoI8+H%k(H01e3j@e6|j^bLS-Ps|OiUGV8h&kmGzy%Y%%_R5QvBH&Sb!)YHtF^i@REag691BPz(LG#YQ` z1BN)d0+uE{ip=sxwT%N*OeKYrJi61N;Fd4?*CR8bgFquHfv1&ganKPg=5f;_^bXSf z$&9QW#}@pNIGcfJ_{<(2{+EX56GQNiU(>Jb_gTxkEdcr0aG(VJ`ydt(e_Z`C8=@wX zk0UA+QxGgto5k$OlaI(OS?}2}ma2fEC5xQz3EwTy6g{2T_h+A-^k~z9C}E($70Du@ zuda9*%UVo7GzHi|07!%fv+({MYj66y|M>sq!~I|D|3CTm+y3+Z&-Q-b(ckX>_xt?c z@c94d_x+#p|1bLg^#1SP)&Ix)zEAf5!Z~OndHqYn&-}ryw{{P4OzvKTe{(sH! ze}B*aANhaZ{=QG|{{L*eUtzCP{r^`=pikxf+AWX!&+0oa38Dh%KX^kp4usOx&+bf* z?x0WaNEToQBPBoEU&a3fBPxLe$QJTQLQQMwyp6x7U(}`bf1T%!?inBingn6NPw>K& zA-V$q)|W_iT8JjjB^#q99cH`}Qi$oG36v7q>z8%k_5Ze#Du;0YhV2^D>=P~FtgXmB zjNwR2G$hv@IMkccLrg;tP(GI?W?^hQ0qX1qG=$Xf|68>avMeR6#^a^(Kk2{qb#-M2 z`fo)^VV=anMj!cEBPFj7@iioYBOsF)6f%k`V^3X={F$npO~5){-GA!mEpfKlx<;7t z5XMK)rf2*-U4ejZY_1VDCfBBxHpaE7pmH>=m8czirI^OB**~#^T7)tvb~jtzuZ`A- z&8J?~sUswr^e$tZ!tlmO$xwB~U}^^3U}>F!>P{SC(;~)k#}|n%IYwkRQ5w85@>Uh^ zTTKSoC|T!G{+46@u1j677$u1i*M^$)iW0&jCF01#$>)MvBPv4~L4|P;DdF($(MKdP znCXeaIK#7CUiRw4T_Y;B5i~)nW}2AGM`^|v4?Eu$O?;+A_FI+8H5X2ZzpWRmm*noc z2+4N6hjSUZtA-etOhB<%0$(Yf1{@y8{85YB=|Ith2KXWwqsIGrrh;8c)b@d%VBP71 zsz^pIGLSr-KBgcGxd*{EHP7XrbblKz@1UGU+2K#80g> zi%EtkV-bYxf?i0ZjZ5#>hTEcc?$~6vM8`5n8S8h;hA0_Cbu2_w??yvwEx$IGpO?+$ ztI(}zvRhFm9L7@ac2Mleah6dsk{Mm>AbNRT*Gt~`FaJ>D@n-G0UtJp-7-0e3^DBOpy9DnO+{IK&q3y*(i35dSEL z_{49*ij`_z=W9%i2slAJA{|({OR}H^BLqX)?*$KfczUV-Jd9+JPk}1(lj(UUW+#>~ ztbgjbWL&?dI9s_RB`kT6tDiS$&j0N@VY5$HFLzT6eqA_m+-R0M_|(t%pc-L*mXvL- zT62d~gf+yqx_GePKxshMMW_@upsSl%>_3Qer?!wJk`f4)@pFwKRM9J)>LO`2Heofg z{BT+tMefN!_GdPiJkXLb*1*;aFUQ}eMizYVl%~aL>8&FwUPMV2@J2DpCm4ZpBWmi6 z7B=RuO>Y{dG)0PKr8QTJ=~ma0(X>{NWzYNm2B9+7F- z)6|Er{-d+D>S$j2G|349LPKcyu7Uzz{+GPz4^~c~aeX$4w1wCIK)@(ACe-*Gz)$+% z2?7EdokPB#&iQJSJ5-lyteb3&aN6xxOpZocZf7~PeLBHz<)<^eyeZT42N*{xh$P0)9G;ed9D<5{6_!#0S>j|lU z!YLFFzqUPJ{QqlT;a`j6Te8`bO5Fr+IZshbYT|AB|70OcL_6nJ~uhJt-i9~P07 zBd<`y|54{CJwGIwJLO6eGl37*fZr0LIDtp#ZHpu4^vKiy#b|j{qbR!eS14CdnsWc| z?h(2>Iv&H60rf@;~b6f7^jKn+KaSv~v zXAasSkCF_m+41`GA#9^?wPCE5H{szCX^Pgb2{C2d@$=($V7plfG9ypYdM76P>#=!~ z+VmD^>)Gs>2YyEM@VT+W7CWPJ*qM<@@hX%kK|8>mQ=6YL-}4Cwcs;()Z~!6?|Ha&q RP81|8lcNOy3L`u{Jqn^~^9=w1 diff --git a/waf-tools/boost.py b/waf-tools/boost.py --- a/waf-tools/boost.py +++ b/waf-tools/boost.py @@ -1,278 +1,371 @@ -#!/usr/bin/env python -# encoding: utf-8 -# -# partially based on boost.py written by Gernot Vormayr -# written by Ruediger Sonderfeld , 2008 -# modified by Bjoern Michaelsen, 2008 -# modified by Luca Fossati, 2008 -# rewritten for waf 1.5.1, Thomas Nagy, 2008 -# rewritten for waf 1.6.2, Sylvain Rouquette, 2011 - -''' -To add the boost tool to the waf file: -$ ./waf-light --tools=compat15,boost - or, if you have waf >= 1.6.2 -$ ./waf update --files=boost - -The wscript will look like: - -def options(opt): - opt.load('compiler_cxx boost') - -def configure(conf): - conf.load('compiler_cxx boost') - conf.check_boost(lib='system filesystem', mt=True, static=True) - -def build(bld): - bld(source='main.cpp', target='app', use='BOOST') -''' - -import sys -import re -from waflib import Utils, Logs -from waflib.Configure import conf -from waflib.Errors import WafError - -BOOST_LIBS = ('/usr/lib', '/usr/local/lib', - '/opt/local/lib', '/sw/lib', '/lib') -BOOST_INCLUDES = ('/usr/include', '/usr/local/include', - '/opt/local/include', '/sw/include') -BOOST_VERSION_FILE = 'boost/version.hpp' -BOOST_VERSION_CODE = ''' -#include -#include -int main() { std::cout << BOOST_LIB_VERSION << std::endl; } -''' - -# toolsets from {boost_dir}/tools/build/v2/tools/common.jam -PLATFORM = Utils.unversioned_sys_platform() -detect_intel = lambda env: (PLATFORM == 'win32') and 'iw' or 'il' -detect_clang = lambda env: (PLATFORM == 'darwin') and 'clang-darwin' or 'clang' -detect_mingw = lambda env: (re.search('MinGW', env.CXX[0])) and 'mgw' or 'gcc' -BOOST_TOOLSETS = { - 'borland': 'bcb', - 'clang': detect_clang, - 'como': 'como', - 'cw': 'cw', - 'darwin': 'xgcc', - 'edg': 'edg', - 'g++': detect_mingw, - 'gcc': detect_mingw, - 'icpc': detect_intel, - 'intel': detect_intel, - 'kcc': 'kcc', - 'kylix': 'bck', - 'mipspro': 'mp', - 'mingw': 'mgw', - 'msvc': 'vc', - 'qcc': 'qcc', - 'sun': 'sw', - 'sunc++': 'sw', - 'tru64cxx': 'tru', - 'vacpp': 'xlc' -} - - -def options(opt): - opt.add_option('--boost-includes', type='string', - default='', dest='boost_includes', - help='''path to the boost directory where the includes are - e.g. /boost_1_45_0/include''') - opt.add_option('--boost-libs', type='string', - default='', dest='boost_libs', - help='''path to the directory where the boost libs are - e.g. /boost_1_45_0/stage/lib''') - opt.add_option('--boost-static', action='store_true', - default=False, dest='boost_static', - help='link static libraries') - opt.add_option('--boost-mt', action='store_true', - default=False, dest='boost_mt', - help='select multi-threaded libraries') - opt.add_option('--boost-abi', type='string', default='', dest='boost_abi', - help='''select libraries with tags (dgsyp, d for debug), - see doc Boost, Getting Started, chapter 6.1''') - opt.add_option('--boost-toolset', type='string', - default='', dest='boost_toolset', - help='force a toolset e.g. msvc, vc90, \ - gcc, mingw, mgw45 (default: auto)') - py_version = '%d%d' % (sys.version_info[0], sys.version_info[1]) - opt.add_option('--boost-python', type='string', - default=py_version, dest='boost_python', - help='select the lib python with this version \ - (default: %s)' % py_version) - - -@conf -def __boost_get_version_file(self, dir): - try: - return self.root.find_dir(dir).find_node(BOOST_VERSION_FILE) - except: - return None - - -@conf -def boost_get_version(self, dir): - """silently retrieve the boost version number""" - re_but = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.*)"$', re.M) - try: - val = re_but.search(self.__boost_get_version_file(dir).read()).group(1) - except: - val = self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[dir], - execute=True, define_ret=True) - return val - - -@conf -def boost_get_includes(self, *k, **kw): - includes = k and k[0] or kw.get('includes', None) - if includes and self.__boost_get_version_file(includes): - return includes - for dir in BOOST_INCLUDES: - if self.__boost_get_version_file(dir): - return dir - if includes: - self.fatal('headers not found in %s' % includes) - else: - self.fatal('headers not found, use --boost-includes=/path/to/boost') - - -@conf -def boost_get_toolset(self, cc): - toolset = cc - if not cc: - build_platform = Utils.unversioned_sys_platform() - if build_platform in BOOST_TOOLSETS: - cc = build_platform - else: - cc = self.env.CXX_NAME - if cc in BOOST_TOOLSETS: - toolset = BOOST_TOOLSETS[cc] - return isinstance(toolset, str) and toolset or toolset(self.env) - - -@conf -def __boost_get_libs_path(self, *k, **kw): - ''' return the lib path and all the files in it ''' - if 'files' in kw: - return self.root.find_dir('.'), Utils.to_list(kw['files']) - libs = k and k[0] or kw.get('libs', None) - if libs: - path = self.root.find_dir(libs) - files = path.ant_glob('*boost_*') - if not libs or not files: - for dir in BOOST_LIBS: - try: - path = self.root.find_dir(dir) - files = path.ant_glob('*boost_*') - if files: - break - path = self.root.find_dir(dir + '64') - files = path.ant_glob('*boost_*') - if files: - break - except: - path = None - if not path: - if libs: - self.fatal('libs not found in %s' % libs) - else: - self.fatal('libs not found, \ - use --boost-includes=/path/to/boost/lib') - return path, files - - -@conf -def boost_get_libs(self, *k, **kw): - ''' - return the lib path and the required libs - according to the parameters - ''' - path, files = self.__boost_get_libs_path(**kw) - t = [] - if kw.get('mt', False): - t.append('mt') - if kw.get('abi', None): - t.append(kw['abi']) - tags = t and '(-%s)+' % '-'.join(t) or '' - toolset = '(-%s[0-9]{0,3})+' % self.boost_get_toolset(kw.get('toolset', '')) - version = '(-%s)+' % self.env.BOOST_VERSION - - def find_lib(re_lib, files): - for file in files: - if re_lib.search(file.name): - return file - return None - - def format_lib_name(name): - if name.startswith('lib'): - name = name[3:] - return name.split('.')[0] - - libs = [] - for lib in Utils.to_list(k and k[0] or kw.get('lib', None)): - py = (lib == 'python') and '(-py%s)+' % kw['python'] or '' - # Trying libraries, from most strict match to least one - for pattern in ['boost_%s%s%s%s%s' % (lib, toolset, tags, py, version), - 'boost_%s%s%s%s' % (lib, tags, py, version), - 'boost_%s%s%s' % (lib, tags, version), - # Give up trying to find the right version - 'boost_%s%s%s%s' % (lib, toolset, tags, py), - 'boost_%s%s%s' % (lib, tags, py), - 'boost_%s%s' % (lib, tags)]: - file = find_lib(re.compile(pattern), files) - if file: - libs.append(format_lib_name(file.name)) - break - else: - self.fatal('lib %s not found in %s' % (lib, path)) - - return path.abspath(), libs - - -@conf -def check_boost(self, *k, **kw): - """ - initialize boost - - You can pass the same parameters as the command line (without "--boost-"), - but the command line has the priority. - """ - if not self.env['CXX']: - self.fatal('load a c++ compiler first, conf.load("compiler_cxx")') - - params = {'lib': k and k[0] or kw.get('lib', None)} - for key, value in self.options.__dict__.items(): - if not key.startswith('boost_'): - continue - key = key[len('boost_'):] - params[key] = value and value or kw.get(key, '') - - var = kw.get('uselib_store', 'BOOST') - - self.start_msg('Checking boost includes') - try: - self.env['INCLUDES_%s' % var] = self.boost_get_includes(**params) - self.env.BOOST_VERSION = self.boost_get_version(self.env['INCLUDES_%s' % var]) - except WafError: - self.end_msg("not found", 'YELLOW') - raise - self.end_msg(self.env.BOOST_VERSION) - if Logs.verbose: - Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var]) - - if not params['lib']: - return - self.start_msg('Checking boost libs') - try: - suffix = params.get('static', 'ST') or '' - path, libs = self.boost_get_libs(**params) - except WafError: - self.end_msg("not found", 'YELLOW') - raise - self.env['%sLIBPATH_%s' % (suffix, var)] = [path] - self.env['%sLIB_%s' % (suffix, var)] = libs - self.end_msg('ok') - if Logs.verbose: - Logs.pprint('CYAN', ' path : %s' % path) - Logs.pprint('CYAN', ' libs : %s' % libs) - +#!/usr/bin/env python +# encoding: utf-8 +# +# partially based on boost.py written by Gernot Vormayr +# written by Ruediger Sonderfeld , 2008 +# modified by Bjoern Michaelsen, 2008 +# modified by Luca Fossati, 2008 +# rewritten for waf 1.5.1, Thomas Nagy, 2008 +# rewritten for waf 1.6.2, Sylvain Rouquette, 2011 + +''' + +This is an extra tool, not bundled with the default waf binary. +To add the boost tool to the waf file: +$ ./waf-light --tools=compat15,boost + or, if you have waf >= 1.6.2 +$ ./waf update --files=boost + +When using this tool, the wscript will look like: + + def options(opt): + opt.load('compiler_cxx boost') + + def configure(conf): + conf.load('compiler_cxx boost') + conf.check_boost(lib='system filesystem') + + def build(bld): + bld(source='main.cpp', target='app', use='BOOST') + +Options are generated, in order to specify the location of boost includes/libraries. +The `check_boost` configuration function allows to specify the used boost libraries. +It can also provide default arguments to the --boost-static and --boost-mt command-line arguments. +Everything will be packaged together in a BOOST component that you can use. + +When using MSVC, a lot of compilation flags need to match your BOOST build configuration: + - you may have to add /EHsc to your CXXFLAGS or define boost::throw_exception if BOOST_NO_EXCEPTIONS is defined. + Errors: C4530 + - boost libraries will try to be smart and use the (pretty but often not useful) auto-linking feature of MSVC + So before calling `conf.check_boost` you might want to disabling by adding: + conf.env.DEFINES_BOOST += ['BOOST_ALL_NO_LIB'] + Errors: + - boost might also be compiled with /MT, which links the runtime statically. + If you have problems with redefined symbols, + self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB'] + self.env['CXXFLAGS_%s' % var] += ['/MD', '/EHsc'] +Passing `--boost-linkage_autodetect` might help ensuring having a correct linkage in some basic cases. + +''' + +import sys +import re +from waflib import Utils, Logs, Errors +from waflib.Configure import conf + +BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib'] +BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include'] +BOOST_VERSION_FILE = 'boost/version.hpp' +BOOST_VERSION_CODE = ''' +#include +#include +int main() { std::cout << BOOST_LIB_VERSION << std::endl; } +''' + +# toolsets from {boost_dir}/tools/build/v2/tools/common.jam +PLATFORM = Utils.unversioned_sys_platform() +detect_intel = lambda env: (PLATFORM == 'win32') and 'iw' or 'il' +detect_clang = lambda env: (PLATFORM == 'darwin') and 'clang-darwin' or 'clang' +detect_mingw = lambda env: (re.search('MinGW', env.CXX[0])) and 'mgw' or 'gcc' +BOOST_TOOLSETS = { + 'borland': 'bcb', + 'clang': detect_clang, + 'como': 'como', + 'cw': 'cw', + 'darwin': 'xgcc', + 'edg': 'edg', + 'g++': detect_mingw, + 'gcc': detect_mingw, + 'icpc': detect_intel, + 'intel': detect_intel, + 'kcc': 'kcc', + 'kylix': 'bck', + 'mipspro': 'mp', + 'mingw': 'mgw', + 'msvc': 'vc', + 'qcc': 'qcc', + 'sun': 'sw', + 'sunc++': 'sw', + 'tru64cxx': 'tru', + 'vacpp': 'xlc' +} + + +def options(opt): + opt.add_option('--boost-includes', type='string', + default='', dest='boost_includes', + help='''path to the boost includes root (~boost root) + e.g. /path/to/boost_1_47_0''') + opt.add_option('--boost-libs', type='string', + default='', dest='boost_libs', + help='''path to the directory where the boost libs are + e.g. /path/to/boost_1_47_0/stage/lib''') + opt.add_option('--boost-static', action='store_true', + default=False, dest='boost_static', + help='link with static boost libraries (.lib/.a)') + opt.add_option('--boost-mt', action='store_true', + default=False, dest='boost_mt', + help='select multi-threaded libraries') + opt.add_option('--boost-abi', type='string', default='', dest='boost_abi', + help='''select libraries with tags (dgsyp, d for debug), + see doc Boost, Getting Started, chapter 6.1''') + opt.add_option('--boost-linkage_autodetect', action="store_true", dest='boost_linkage_autodetect', + help="auto-detect boost linkage options (don't get used to it / might break other stuff)") + opt.add_option('--boost-toolset', type='string', + default='', dest='boost_toolset', + help='force a toolset e.g. msvc, vc90, \ + gcc, mingw, mgw45 (default: auto)') + py_version = '%d%d' % (sys.version_info[0], sys.version_info[1]) + opt.add_option('--boost-python', type='string', + default=py_version, dest='boost_python', + help='select the lib python with this version \ + (default: %s)' % py_version) + + +@conf +def __boost_get_version_file(self, dir): + try: + return self.root.find_dir(dir).find_node(BOOST_VERSION_FILE) + except: + return None + + +@conf +def boost_get_version(self, dir): + """silently retrieve the boost version number""" + re_but = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.*)"$', re.M) + try: + val = re_but.search(self.__boost_get_version_file(dir).read()).group(1) + except: + val = self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[dir], execute=False, define_ret=True) + return val + + +@conf +def boost_get_includes(self, *k, **kw): + includes = k and k[0] or kw.get('includes', None) + if includes and self.__boost_get_version_file(includes): + return includes + for dir in BOOST_INCLUDES: + if self.__boost_get_version_file(dir): + return dir + if includes: + self.fatal('headers not found in %s' % includes) + else: + self.fatal('headers not found, please provide a --boost-includes argument (see help)') + + +@conf +def boost_get_toolset(self, cc): + toolset = cc + if not cc: + build_platform = Utils.unversioned_sys_platform() + if build_platform in BOOST_TOOLSETS: + cc = build_platform + else: + cc = self.env.CXX_NAME + if cc in BOOST_TOOLSETS: + toolset = BOOST_TOOLSETS[cc] + return isinstance(toolset, str) and toolset or toolset(self.env) + + +@conf +def __boost_get_libs_path(self, *k, **kw): + ''' return the lib path and all the files in it ''' + if 'files' in kw: + return self.root.find_dir('.'), Utils.to_list(kw['files']) + libs = k and k[0] or kw.get('libs', None) + if libs: + path = self.root.find_dir(libs) + files = path.ant_glob('*boost_*') + if not libs or not files: + for dir in BOOST_LIBS: + try: + path = self.root.find_dir(dir) + files = path.ant_glob('*boost_*') + if files: + break + path = self.root.find_dir(dir + '64') + files = path.ant_glob('*boost_*') + if files: + break + except: + path = None + if not path: + if libs: + self.fatal('libs not found in %s' % libs) + else: + self.fatal('libs not found, please provide a --boost-libs argument (see help)') + + self.to_log('Found the boost path in %r with the libraries:' % path) + for x in files: + self.to_log(' %r' % x) + return path, files + +@conf +def boost_get_libs(self, *k, **kw): + ''' + return the lib path and the required libs + according to the parameters + ''' + path, files = self.__boost_get_libs_path(**kw) + t = [] + if kw.get('mt', False): + t.append('mt') + if kw.get('abi', None): + t.append(kw['abi']) + tags = t and '(-%s)+' % '-'.join(t) or '' + toolset = self.boost_get_toolset(kw.get('toolset', '')) + toolset_pat = '(-%s[0-9]{0,3})+' % toolset + version = '(-%s)+' % self.env.BOOST_VERSION + + def find_lib(re_lib, files): + for file in files: + if re_lib.search(file.name): + self.to_log('Found boost lib %s' % file) + return file + return None + + def format_lib_name(name): + if name.startswith('lib') and self.env.CC_NAME != 'msvc': + name = name[3:] + return name[:name.rfind('.')] + + found_libs = [] + libs = [] + for lib in Utils.to_list(k and k[0] or kw.get('lib', None)): + py = (lib == 'python') and '(-py%s)+' % kw['python'] or '' + # Trying libraries, from most strict match to least one + for pattern in ['boost_%s%s%s%s%s' % (lib, toolset_pat, tags, py, version), + 'boost_%s%s%s%s' % (lib, tags, py, version), + 'boost_%s%s%s' % (lib, tags, version), + # Give up trying to find the right version + 'boost_%s%s%s%s' % (lib, toolset_pat, tags, py), + 'boost_%s%s%s' % (lib, tags, py), + 'boost_%s%s' % (lib, tags)]: + self.to_log('Trying pattern %s' % pattern) + file = find_lib(re.compile(pattern), files) + if file: + found_libs.append (lib) + libs.append(format_lib_name(file.name)) + break + else: + # Don't fail, but just ignore failed library + Logs.error ('lib %s not found in %s' % (lib, path.abspath())) + + return path.abspath(), libs, found_libs + + +@conf +def check_boost(self, *k, **kw): + """ + Initialize boost libraries to be used. + + Keywords: you can pass the same parameters as with the command line (without "--boost-"). + Note that the command line has the priority, and should preferably be used. + """ + if not self.env['CXX']: + self.fatal('load a c++ compiler first, conf.load("compiler_cxx")') + + params = {'lib': k and k[0] or kw.get('lib', None)} + for key, value in self.options.__dict__.items(): + if not key.startswith('boost_'): + continue + key = key[len('boost_'):] + params[key] = value and value or kw.get(key, '') + + var = kw.get('uselib_store', 'BOOST') + + self.start_msg('Checking boost includes') + self.env['INCLUDES_%s' % var] = inc = self.boost_get_includes(**params) + self.env.BOOST_VERSION = self.boost_get_version(inc) + self.end_msg(self.env.BOOST_VERSION) + if Logs.verbose: + Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var]) + + if not params['lib']: + return + self.start_msg('Checking boost libs') + suffix = params.get('static', None) and 'ST' or '' + path, libs, found_libs = self.boost_get_libs(**params) + self.env['%sLIBPATH_%s' % (suffix, var)] = [path] + self.env['%sLIB_%s' % (suffix, var)] = libs + self.env['%s_FOUND_LIBS' % var] = found_libs + + if kw.get('require_all', True): + if found_libs != Utils.to_list(k and k[0] or kw.get('lib', None)): + required_libs = Utils.to_list(k and k[0] or kw.get('lib', None)) + not_found = [lib for lib in required_libs if lib not in found_libs] + self.fatal('boost libraries %s not found' % (str(not_found))) + + self.end_msg('ok') + if Logs.verbose: + Logs.pprint('CYAN', ' path : %s' % path) + Logs.pprint('CYAN', ' libs : %s' % libs) + + + def try_link(): + if 'system' in params['lib']: + self.check_cxx( + fragment="\n".join([ + '#include ', + 'int main() { boost::system::error_code c; }', + ]), + use=var, + execute=False, + ) + if 'thread' in params['lib']: + self.check_cxx( + fragment="\n".join([ + '#include ', + 'int main() { boost::thread t; }', + ]), + use=var, + execute=False, + ) + + if params.get('linkage_autodetect', False): + self.start_msg("Attempting to detect boost linkage flags") + toolset = self.boost_get_toolset(kw.get('toolset', '')) + if toolset in ['vc']: + # disable auto-linking feature, causing error LNK1181 + # because the code wants to be linked against + self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB'] + + # if no dlls are present, we guess the .lib files are not stubs + has_dlls = False + for x in Utils.listdir(path): + if x.endswith(self.env.cxxshlib_PATTERN % ''): + has_dlls = True + break + if not has_dlls: + self.env['STLIBPATH_%s' % var] = [path] + self.env['STLIB_%s' % var] = libs + del self.env['LIB_%s' % var] + del self.env['LIBPATH_%s' % var] + + # we attempt to play with some known-to-work CXXFLAGS combinations + for cxxflags in (['/MD', '/EHsc'], []): + self.env.stash() + self.env["CXXFLAGS_%s" % var] += cxxflags + try: + try_link() + self.end_msg("ok: winning cxxflags combination: %s" % (self.env["CXXFLAGS_%s" % var])) + e = None + break + except Errors.ConfigurationError as exc: + self.env.revert() + e = exc + + if e is not None: + self.fatal("Could not auto-detect boost linking flags combination, you may report it to boost.py author", ex=e) + else: + self.fatal("Boost linkage flags auto-detection not implemented (needed ?) for this toolchain") + else: + self.start_msg('Checking for boost linkage') + try: + try_link() + except Errors.ConfigurationError as e: + self.fatal("Could not link against boost libraries using supplied options") + self.end_msg('ok') + diff --git a/waf-tools/cflags.py b/waf-tools/cflags.py --- a/waf-tools/cflags.py +++ b/waf-tools/cflags.py @@ -1,6 +1,4 @@ -import Logs -import Options -import Utils +from waflib import Logs, Options, Utils class CompilerTraits(object): diff --git a/waf-tools/command.py b/waf-tools/command.py --- a/waf-tools/command.py +++ b/waf-tools/command.py @@ -1,18 +1,15 @@ -import TaskGen# import feature, taskgen_method, before_method, task_gen -import Node, Task, Utils, Build +import re import subprocess -import Options + +# import feature, taskgen_method, before_method, task_gen +from waflib import TaskGen, Node, Task, Utils, Build, Options, Logs, Task +debug = Logs.debug +error = Logs.error import shellcmd #shellcmd.subprocess = pproc # the WAF version of the subprocess module is supposedly less buggy - -from Logs import debug, error shellcmd.debug = debug -import Task - -import re - arg_rx = re.compile(r"(?P\$\$)|(?P\$\{(?P\w+)(?P.*?)\})", re.M) diff --git a/waf-tools/misc.py b/waf-tools/misc.py --- a/waf-tools/misc.py +++ b/waf-tools/misc.py @@ -322,9 +322,6 @@ if self.cwd is None: cwd = None - else: - assert isinstance(cwd, CmdDirArg) - self.cwd.find_node(self.path) args = [] inputs = [] diff --git a/waf-tools/pkgconfig.py b/waf-tools/pkgconfig.py deleted file mode 100644 --- a/waf-tools/pkgconfig.py +++ /dev/null @@ -1,78 +0,0 @@ -# -*- mode: python; encoding: utf-8 -*- -# Gustavo Carneiro (gjamc) 2008 - -import Options -import Configure -import subprocess -import config_c -import sys - -def configure(conf): - pkg_config = conf.find_program('pkg-config', var='PKG_CONFIG') - if not pkg_config: return - -@Configure.conf -def pkg_check_modules(conf, uselib_name, expression, mandatory=True): - pkg_config = conf.env['PKG_CONFIG'] - if not pkg_config: - if mandatory: - conf.fatal("pkg-config is not available") - else: - return False - - if Options.options.verbose: - extra_msg = ' (%s)' % expression - else: - extra_msg = '' - - conf.start_msg('Checking for pkg-config flags for %s%s' % (uselib_name, extra_msg)) - - argv = [pkg_config, '--cflags', '--libs', expression] - cmd = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - out, err = cmd.communicate() - retval = cmd.wait() - - conf.to_log('%r: %r (exit code %i)\n%s' % (argv, out, retval, err)) - - if retval != 0: - conf.end_msg(False) - sys.stderr.write(err) - else: - if Options.options.verbose: - conf.end_msg(out) - else: - conf.end_msg(True) - - if retval == 0: - conf.parse_flags(out, uselib_name, conf.env) - conf.env[uselib_name] = True - return True - - else: - - conf.env[uselib_name] = False - if mandatory: - raise Configure.ConfigurationError('pkg-config check failed') - else: - return False - -@Configure.conf -def pkg_check_module_variable(conf, module, variable): - pkg_config = conf.env['PKG_CONFIG'] - if not pkg_config: - conf.fatal("pkg-config is not available") - - argv = [pkg_config, '--variable', variable, module] - cmd = subprocess.Popen(argv, stdout=subprocess.PIPE) - out, dummy = cmd.communicate() - retval = cmd.wait() - out = out.rstrip() # strip the trailing newline - - msg_checking = ("Checking for pkg-config variable %r in %s" % (variable, module,)) - conf.check_message_custom(msg_checking, '', out) - conf.log.write('%r: %r (exit code %i)\n' % (argv, out, retval)) - - if retval == 0: - return out - else: - raise Configure.ConfigurationError('pkg-config check failed') diff --git a/waf-tools/relocation.py b/waf-tools/relocation.py --- a/waf-tools/relocation.py +++ b/waf-tools/relocation.py @@ -64,7 +64,7 @@ try: return self.uid_ except AttributeError: - # this is not a real hot zone, but we want to avoid surprizes here + # this is not a real hot zone, but we want to avoid surprises here m = Utils.md5() up = m.update up(self.__class__.__name__.encode()) @@ -80,6 +80,6 @@ lst = self.to_incnodes(self.to_list(getattr(self, 'includes', [])) + self.env['INCLUDES']) self.includes_nodes = lst bld = self.bld - self.env['INCPATHS'] = [x.is_child_of(bld.srcnode) and x.path_from(bld.srcnode) or x.abspath() for x in lst] + self.env['INCPATHS'] = [x.is_child_of(bld.srcnode) and x.path_from(bld.bldnode) or x.abspath() for x in lst] diff --git a/wscript b/wscript --- a/wscript +++ b/wscript @@ -8,25 +8,20 @@ import os.path import re import shlex +import subprocess import textwrap +from utils import read_config_file + + # WAF modules -import subprocess -import Options - -import Logs -import TaskGen - -import Task - -import Utils -import Build -import Configure -import Scripting - +from waflib import Utils, Scripting, Configure, Build, Options, TaskGen, Context, Task, Logs, Errors from waflib.Errors import WafError -from utils import read_config_file + +# local modules +import wutils + # By default, all modules will be enabled, examples will be disabled, # and tests will be disabled. @@ -52,9 +47,6 @@ } cflags.default_profile = 'debug' -# local modules -import wutils - Configure.autoconfig = 0 # the following two variables are used by the target "waf dist" @@ -214,9 +206,9 @@ dest='doxygen_no_build') # options provided in subdirectories - opt.sub_options('src') - opt.sub_options('bindings/python') - opt.sub_options('src/internet') + opt.recurse('src') + opt.recurse('bindings/python') + opt.recurse('src/internet') def _check_compilation_flag(conf, flag, mode='cxx', linkflags=None): @@ -240,7 +232,7 @@ flag_str = flag_str[:28] + "..." conf.start_msg('Checking for compilation %s support' % (flag_str,)) - env = conf.env.copy() + env = conf.env.derive() if mode == 'cc': mode = 'c' @@ -259,7 +251,7 @@ retval = conf.run_c_code(code='#include \nint main() { return 0; }\n', env=env, compile_filename=fname, features=[mode, mode+'program'], execute=False) - except Configure.ConfigurationError: + except Errors.ConfigurationError: ok = False else: ok = (retval == 0) @@ -286,7 +278,7 @@ return None def configure(conf): - conf.check_tool("relocation", ["waf-tools"]) + conf.load('relocation', tooldir=['waf-tools']) # attach some extra methods conf.check_nonfatal = types.MethodType(_check_nonfatal, conf) @@ -295,15 +287,11 @@ conf.check_optional_feature = types.MethodType(check_optional_feature, conf) conf.env['NS3_OPTIONAL_FEATURES'] = [] - conf.check_tool('compiler_c') - conf.check_tool('compiler_cxx') - conf.check_tool('cflags', ['waf-tools']) - try: - conf.check_tool('pkgconfig', ['waf-tools']) - except Configure.ConfigurationError: - pass - conf.check_tool('command', ['waf-tools']) - conf.check_tool('gnu_dirs') + conf.load('compiler_c') + conf.load('compiler_cxx') + conf.load('cflags', tooldir=['waf-tools']) + conf.load('command', tooldir=['waf-tools']) + conf.load('gnu_dirs') env = conf.env @@ -376,9 +364,9 @@ conf.env['MODULES_NOT_BUILT'] = [] - conf.sub_config('bindings/python') + conf.recurse('bindings/python') - conf.sub_config('src') + conf.recurse('src') # Set the list of enabled modules. if Options.options.enable_modules: @@ -410,7 +398,7 @@ if not conf.env['NS3_ENABLED_MODULES']: raise WafError('Exiting because the ' + not_built + ' module can not be built and it was the only one enabled.') - conf.sub_config('src/mpi') + conf.recurse('src/mpi') # for suid bits try: @@ -488,19 +476,18 @@ # These flags are used for the implicitly dependent modules. if env['ENABLE_STATIC_NS3']: if sys.platform == 'darwin': - env.STATICLIB_MARKER = '-Wl,-all_load' + env.STLIB_MARKER = '-Wl,-all_load' else: - env.STATICLIB_MARKER = '-Wl,--whole-archive,-Bstatic' + env.STLIB_MARKER = '-Wl,--whole-archive,-Bstatic' env.SHLIB_MARKER = '-Wl,-Bdynamic,--no-whole-archive' - have_gsl = conf.pkg_check_modules('GSL', 'gsl', mandatory=False) + + have_gsl = conf.check_cfg(package='gsl', args=['--cflags', '--libs'], + uselib_store='GSL', mandatory=False) conf.env['ENABLE_GSL'] = have_gsl - conf.report_optional_feature("GSL", "GNU Scientific Library (GSL)", conf.env['ENABLE_GSL'], "GSL not found") - if have_gsl: - conf.env.append_value('DEFINES', "ENABLE_GSL") # for compiling C code, copy over the CXX* flags conf.env.append_value('CCFLAGS', conf.env['CXXFLAGS']) @@ -555,7 +542,7 @@ except ValueError, ex: raise WafError(str(ex)) program_node = program_obj.path.find_or_declare(program_obj.target) - self.filename = program_node.abspath() + self.filename = program_node.get_bld().abspath() def run(self): @@ -580,7 +567,7 @@ def create_suid_program(bld, name): grp = bld.current_group bld.add_group() # this to make sure no two sudo tasks run at the same time - program = bld.new_task_gen(features=['cxx', 'cxxprogram']) + program = bld(features='cxx cxxprogram') program.is_ns3_program = True program.module_deps = list() program.name = name @@ -594,7 +581,7 @@ return program def create_ns3_program(bld, name, dependencies=('core',)): - program = bld.new_task_gen(features=['cxx', 'cxxprogram']) + program = bld(features='cxx cxxprogram') program.is_ns3_program = True program.name = name @@ -607,7 +594,7 @@ if sys.platform == 'darwin': program.env.STLIB_MARKER = '-Wl,-all_load' else: - program.env.STLIB_MARKER = '-Wl,--whole-archive,-Bstatic' + program.env.STLIB_MARKER = '-Wl,-Bstatic,--whole-archive' program.env.SHLIB_MARKER = '-Wl,-Bdynamic,--no-whole-archive' else: if program.env.DEST_BINFMT == 'elf': @@ -628,8 +615,7 @@ if dir.startswith('.') or dir == 'CVS': continue if os.path.isdir(os.path.join('examples', dir)): - bld.add_subdirs(os.path.join('examples', dir)) - + bld.recurse(os.path.join('examples', dir)) def add_scratch_programs(bld): all_modules = [mod[len("ns3-"):] for mod in bld.env['NS3_ENABLED_MODULES']] @@ -652,7 +638,6 @@ obj.name = obj.target obj.install_path = None - def _get_all_task_gen(self): for group in self.groups: for taskgen in group: @@ -699,12 +684,12 @@ wutils.bld = bld if Options.options.no_task_lines: - import Runner + from waflib import Runner def null_printout(s): pass Runner.printout = null_printout - Options.cwd_launch = bld.path.abspath() + Options.cwd_launch = bld.path.get_bld().abspath() bld.create_ns3_program = types.MethodType(create_ns3_program, bld) bld.register_ns3_script = types.MethodType(register_ns3_script, bld) bld.create_suid_program = types.MethodType(create_suid_program, bld) @@ -713,7 +698,7 @@ bld.find_ns3_module = types.MethodType(_find_ns3_module, bld) # process subfolders from here - bld.add_subdirs('src') + bld.recurse('src') # If modules have been enabled, then set lists of enabled modules # and enabled module test libraries. @@ -780,7 +765,7 @@ # launch directory. launch_dir = os.path.abspath(Context.launch_dir) object_relative_path = os.path.join( - wutils.relpath(obj.path.abspath(), launch_dir), + wutils.relpath(obj.path.get_bld().abspath(), launch_dir), object_name) bld.env.append_value('NS3_RUNNABLE_PROGRAMS', object_relative_path) @@ -821,11 +806,11 @@ if script_runnable: bld.env.append_value('NS3_RUNNABLE_SCRIPTS', script) - bld.add_subdirs('bindings/python') + bld.recurse('bindings/python') # Process this subfolder here after the lists of enabled modules # and module test libraries have been set. - bld.add_subdirs('utils') + bld.recurse('utils') # Set this so that the lists will be printed at the end of this # build command. @@ -920,7 +905,6 @@ -from waflib import Context, Build class CheckContext(Context.Context): """run the equivalent of the old ns-3 unit tests using test.py""" cmd = 'check' @@ -938,7 +922,7 @@ class print_introspected_doxygen_task(Task.TaskBase): - after = 'cc cxx link' + after = 'cxx link' color = 'BLUE' def __init__(self, bld): @@ -962,7 +946,7 @@ # --enable-modules=xxx pass else: - prog = program_obj.path.find_or_declare(ccroot.get_target_name(program_obj)).abspath(env) + prog = program_obj.path.find_or_declare(ccroot.get_target_name(program_obj)).get_bld().abspath(env) # Create a header file with the introspected information. doxygen_out = open(os.path.join('doc', 'introspected-doxygen.h'), 'w') @@ -977,7 +961,7 @@ text_out.close() class run_python_unit_tests_task(Task.TaskBase): - after = 'cc cxx link' + after = 'cxx link' color = 'BLUE' def __init__(self, bld): @@ -1016,7 +1000,6 @@ raise WafError(msg) -from waflib import Context, Build class Ns3ShellContext(Context.Context): """run a shell with an environment suitably modified to run locally built programs""" cmd = 'shell' @@ -1062,7 +1045,7 @@ raise SystemExit(1) return - prog = program_obj.path.find_or_declare(program_obj.target).abspath() + prog = program_obj.path.find_or_declare(program_obj.target).get_bld().abspath() if not os.path.exists(prog): Logs.error("print-introspected-doxygen has not been built yet." @@ -1089,8 +1072,6 @@ raise SystemExit(1) -from waflib import Context, Build - def _getVersion(): """update the ns3_version.js file, when building documentation""" @@ -1110,7 +1091,6 @@ bld.execute() _doxygen(bld) -from waflib import Context, Build class Ns3SphinxContext(Context.Context): """build the Sphinx documentation: manual, tutorial, models""" @@ -1131,7 +1111,6 @@ self.sphinx_build(os.path.join("doc", sphinxdir)) -from waflib import Context, Build class Ns3DocContext(Context.Context): """build all the documentation: doxygen, manual, tutorial, models""" diff --git a/wutils.py b/wutils.py --- a/wutils.py +++ b/wutils.py @@ -1,16 +1,12 @@ import os import os.path +import re import sys import subprocess import shlex # WAF modules -import Options -import Utils -import Logs -import TaskGen -import Build -import re +from waflib import Options, Utils, Logs, TaskGen, Build, Context from waflib.Errors import WafError # these are set from the main wscript file @@ -47,7 +43,7 @@ return os.path.curdir return os.path.join(*rel_list) -from waflib import Context + def find_program(program_name, env): launch_dir = os.path.abspath(Context.launch_dir) #top_dir = os.path.abspath(Options.cwd_launch)