summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2004-04-28 17:34:07 (GMT)
committerSteven Knight <knight@baldmt.com>2004-04-28 17:34:07 (GMT)
commita293ba1834e12a50ec1f79c5aa746a182285f60f (patch)
tree179cec49dd725057f4489e13a8e1ed30ddb47f2f
parent31e22cb37b82c626158506282733b8a646bd863e (diff)
downloadSCons-a293ba1834e12a50ec1f79c5aa746a182285f60f.zip
SCons-a293ba1834e12a50ec1f79c5aa746a182285f60f.tar.gz
SCons-a293ba1834e12a50ec1f79c5aa746a182285f60f.tar.bz2
Support use of strfunction() with all kinds of Action objects.
-rw-r--r--doc/man/scons.134
-rw-r--r--src/CHANGES.txt3
-rw-r--r--src/engine/SCons/Action.py50
-rw-r--r--src/engine/SCons/ActionTests.py182
4 files changed, 191 insertions, 78 deletions
diff --git a/doc/man/scons.1 b/doc/man/scons.1
index e1bcf51..ba4e690 100644
--- a/doc/man/scons.1
+++ b/doc/man/scons.1
@@ -6445,19 +6445,31 @@ and emitter functions.
.SS Action Objects
-The Builder function will turn its
+The
+.BR Builder()
+function will turn its
.B action
keyword argument into an appropriate
internal Action object.
-Occasionally, it may be more efficient
-to create an explicit Action object
-and use it to initialize multiple
-Builder objects,
-rather than let each separate Builder object
-create a separate Action.
-
-The Action method takes one or two arguments
-and returns an appropriate object for the action
+You can also explicity create Action objects
+using the
+.BR Action ()
+global function,
+which can then be passed to the
+.BR Builder ()
+function.
+This can be used to configure
+an Action object more flexibly,
+or it may simply be more efficient
+than letting each separate Builder object
+create a separate Action
+when multiple
+Builder objects need to do the same thing.
+
+The
+.BR Action ()
+global function
+returns an appropriate object for the action
represented by the type of the first argument:
.IP Action
@@ -6548,7 +6560,7 @@ a = Action(build_it)
The second, optional argument
is a Python function that returns
a string to be printed to describe the action being executed.
-Like the function to build a file,
+Like a function to build a file,
this function takes three arguments:
.B target
(a Node object representing the target file),
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index bba15e7..f34104d 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -98,6 +98,9 @@ RELEASE 0.96 - XXX
or env.Execute() environment method, or may be used as a Builder
action or in an env.Command() action list.
+ - Add support for the strfunction argument to all types of Actions:
+ CommandAction, ListAction, and CommandGeneratorAction.
+
From Gary Oberbrunner:
- Add a --debug=presub option to print actions prior to substitution.
diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py
index 6b8b184..37665b9 100644
--- a/src/engine/SCons/Action.py
+++ b/src/engine/SCons/Action.py
@@ -153,7 +153,7 @@ class CommandGenerator:
def __radd__(self, other):
return _actionAppend(other, self)
-def _do_create_action(act, strfunction=_null, varlist=[]):
+def _do_create_action(act, *args, **kw):
"""This is the actual "implementation" for the
Action factory method, below. This handles the
fact that passing lists to Action() itself has
@@ -166,42 +166,42 @@ def _do_create_action(act, strfunction=_null, varlist=[]):
if isinstance(act, ActionBase):
return act
- elif SCons.Util.is_List(act):
- return CommandAction(act)
- elif isinstance(act, CommandGenerator):
- return CommandGeneratorAction(act.generator)
- elif callable(act):
- return FunctionAction(act, strfunction=strfunction, varlist=varlist)
- elif SCons.Util.is_String(act):
+ if SCons.Util.is_List(act):
+ return apply(CommandAction, (act,)+args, kw)
+ if isinstance(act, CommandGenerator):
+ return apply(CommandGeneratorAction, (act.generator,)+args, kw)
+ if callable(act):
+ return apply(FunctionAction, (act,)+args, kw)
+ if SCons.Util.is_String(act):
var=SCons.Util.get_environment_var(act)
if var:
# This looks like a string that is purely an Environment
# variable reference, like "$FOO" or "${FOO}". We do
# something special here...we lazily evaluate the contents
- # of that Environment variable, so a user could but something
+ # of that Environment variable, so a user could put something
# like a function or a CommandGenerator in that variable
# instead of a string.
- return CommandGeneratorAction(LazyCmdGenerator(var))
- listCmds = map(lambda x: CommandAction(x),
- string.split(str(act), '\n'))
- if len(listCmds) == 1:
- return listCmds[0]
+ lcg = LazyCmdGenerator(var)
+ return apply(CommandGeneratorAction, (lcg,)+args, kw)
+ commands = string.split(str(act), '\n')
+ if len(commands) == 1:
+ return apply(CommandAction, (commands[0],)+args, kw)
else:
- return ListAction(listCmds)
- else:
- return None
+ listCmdActions = map(lambda x: CommandAction(x), commands)
+ return apply(ListAction, (listCmdActions,)+args, kw)
+ return None
def Action(act, strfunction=_null, varlist=[]):
"""A factory for action objects."""
if SCons.Util.is_List(act):
acts = map(lambda x, s=strfunction, v=varlist:
- _do_create_action(x, s, v),
+ _do_create_action(x, strfunction=s, varlist=v),
act)
acts = filter(lambda x: not x is None, acts)
if len(acts) == 1:
return acts[0]
else:
- return ListAction(acts)
+ return ListAction(acts, strfunction=strfunction, varlist=varlist)
else:
return _do_create_action(act, strfunction=strfunction, varlist=varlist)
@@ -255,12 +255,14 @@ def _string_from_cmd_list(cmd_list):
class CommandAction(ActionBase):
"""Class for command-execution actions."""
- def __init__(self, cmd):
+ def __init__(self, cmd, strfunction=_null, varlist=[]):
# Cmd list can actually be a list or a single item...basically
# anything that we could pass in as the first arg to
# Environment.subst_list().
if __debug__: logInstanceCreation(self)
self.cmd_list = cmd
+ if not strfunction is _null:
+ self.strfunction = strfunction
def __str__(self):
return str(self.cmd_list)
@@ -372,9 +374,11 @@ class CommandAction(ActionBase):
class CommandGeneratorAction(ActionBase):
"""Class for command-generator actions."""
- def __init__(self, generator):
+ def __init__(self, generator, strfunction=_null, varlist=[]):
if __debug__: logInstanceCreation(self)
self.generator = generator
+ if not strfunction is _null:
+ self.strfunction = strfunction
def __generate(self, target, source, env, for_signature):
# ensure that target is a list, to make it easier to write
@@ -539,9 +543,11 @@ class FunctionAction(ActionBase):
class ListAction(ActionBase):
"""Class for lists of other actions."""
- def __init__(self, list):
+ def __init__(self, list, strfunction=_null, varlist=[]):
if __debug__: logInstanceCreation(self)
self.list = map(lambda x: Action(x), list)
+ if not strfunction is _null:
+ self.strfunction = strfunction
def get_actions(self):
return self.list
diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py
index bc8e39f..3def857 100644
--- a/src/engine/SCons/ActionTests.py
+++ b/src/engine/SCons/ActionTests.py
@@ -176,9 +176,10 @@ else:
python = sys.executable
class ActionTestCase(unittest.TestCase):
+ """Test the Action() factory function"""
- def test_factory(self):
- """Test the Action factory
+ def test_FunctionAction(self):
+ """Test the Action() factory's creation of FunctionAction objects
"""
def foo():
pass
@@ -188,61 +189,134 @@ class ActionTestCase(unittest.TestCase):
assert isinstance(a1, SCons.Action.FunctionAction), a1
assert a1.execfunction == foo, a1.execfunction
- a2 = SCons.Action.Action("string")
- assert isinstance(a2, SCons.Action.CommandAction), a2
- assert a2.cmd_list == "string", a2.cmd_list
+ a11 = SCons.Action.Action(foo, strfunction=bar)
+ assert isinstance(a11, SCons.Action.FunctionAction), a11
+ assert a11.execfunction == foo, a11.execfunction
+ assert a11.strfunction == bar, a11.strfunction
+
+ def test_CommandAction(self):
+ """Test the Action() factory's creation of CommandAction objects
+ """
+ a1 = SCons.Action.Action("string")
+ assert isinstance(a1, SCons.Action.CommandAction), a1
+ assert a1.cmd_list == "string", a1.cmd_list
if hasattr(types, 'UnicodeType'):
- exec "a3 = SCons.Action.Action(u'string')"
- exec "assert isinstance(a3, SCons.Action.CommandAction), a3"
+ exec "a2 = SCons.Action.Action(u'string')"
+ exec "assert isinstance(a2, SCons.Action.CommandAction), a2"
+
+ a3 = SCons.Action.Action(["a3"])
+ assert isinstance(a3, SCons.Action.CommandAction), a3
+ assert a3.cmd_list == "a3", a3.cmd_list
+
+ a4 = SCons.Action.Action([[ "explicit", "command", "line" ]])
+ assert isinstance(a4, SCons.Action.CommandAction), a4
+ assert a4.cmd_list == [ "explicit", "command", "line" ], a4.cmd_list
+
+ def foo():
+ pass
- a4 = SCons.Action.Action(["x", "y", "z", [ "a", "b", "c"]])
+ a5 = SCons.Action.Action("string", strfunction=foo)
+ assert isinstance(a5, SCons.Action.CommandAction), a5
+ assert a5.cmd_list == "string", a5.cmd_list
+ assert a5.strfunction == foo, a5.strfunction
+
+ def test_ListAction(self):
+ """Test the Action() factory's creation of ListAction objects
+ """
+ a1 = SCons.Action.Action(["x", "y", "z", [ "a", "b", "c"]])
+ assert isinstance(a1, SCons.Action.ListAction), a1
+ assert isinstance(a1.list[0], SCons.Action.CommandAction), a1.list[0]
+ assert a1.list[0].cmd_list == "x", a1.list[0].cmd_list
+ assert isinstance(a1.list[1], SCons.Action.CommandAction), a1.list[1]
+ assert a1.list[1].cmd_list == "y", a1.list[1].cmd_list
+ assert isinstance(a1.list[2], SCons.Action.CommandAction), a1.list[2]
+ assert a1.list[2].cmd_list == "z", a1.list[2].cmd_list
+ assert isinstance(a1.list[3], SCons.Action.CommandAction), a1.list[3]
+ assert a1.list[3].cmd_list == [ "a", "b", "c" ], a1.list[3].cmd_list
+
+ a2 = SCons.Action.Action("x\ny\nz")
+ assert isinstance(a2, SCons.Action.ListAction), a2
+ assert isinstance(a2.list[0], SCons.Action.CommandAction), a2.list[0]
+ assert a2.list[0].cmd_list == "x", a2.list[0].cmd_list
+ assert isinstance(a2.list[1], SCons.Action.CommandAction), a2.list[1]
+ assert a2.list[1].cmd_list == "y", a2.list[1].cmd_list
+ assert isinstance(a2.list[2], SCons.Action.CommandAction), a2.list[2]
+ assert a2.list[2].cmd_list == "z", a2.list[2].cmd_list
+
+ def foo():
+ pass
+
+ a3 = SCons.Action.Action(["x", foo, "z"])
+ assert isinstance(a3, SCons.Action.ListAction), a3
+ assert isinstance(a3.list[0], SCons.Action.CommandAction), a3.list[0]
+ assert a3.list[0].cmd_list == "x", a3.list[0].cmd_list
+ assert isinstance(a3.list[1], SCons.Action.FunctionAction), a3.list[1]
+ assert a3.list[1].execfunction == foo, a3.list[1].execfunction
+ assert isinstance(a3.list[2], SCons.Action.CommandAction), a3.list[2]
+ assert a3.list[2].cmd_list == "z", a3.list[2].cmd_list
+
+ a4 = SCons.Action.Action(["x", "y"], strfunction=foo)
assert isinstance(a4, SCons.Action.ListAction), a4
assert isinstance(a4.list[0], SCons.Action.CommandAction), a4.list[0]
assert a4.list[0].cmd_list == "x", a4.list[0].cmd_list
assert isinstance(a4.list[1], SCons.Action.CommandAction), a4.list[1]
assert a4.list[1].cmd_list == "y", a4.list[1].cmd_list
- assert isinstance(a4.list[2], SCons.Action.CommandAction), a4.list[2]
- assert a4.list[2].cmd_list == "z", a4.list[2].cmd_list
- assert isinstance(a4.list[3], SCons.Action.CommandAction), a4.list[3]
- assert a4.list[3].cmd_list == [ "a", "b", "c" ], a4.list[3].cmd_list
+ assert a4.strfunction == foo, a4.strfunction
+
+ a5 = SCons.Action.Action("x\ny", strfunction=foo)
+ assert isinstance(a5, SCons.Action.ListAction), a5
+ assert isinstance(a5.list[0], SCons.Action.CommandAction), a5.list[0]
+ assert a5.list[0].cmd_list == "x", a5.list[0].cmd_list
+ assert isinstance(a5.list[1], SCons.Action.CommandAction), a5.list[1]
+ assert a5.list[1].cmd_list == "y", a5.list[1].cmd_list
+ assert a5.strfunction == foo, a5.strfunction
+
+ def test_CommandGeneratorAction(self):
+ """Test the Action() factory's creation of CommandGeneratorAction objects
+ """
+ def foo():
+ pass
+ def bar():
+ pass
+ cg = SCons.Action.CommandGenerator(foo)
+
+ a1 = SCons.Action.Action(cg)
+ assert isinstance(a1, SCons.Action.CommandGeneratorAction), a1
+ assert a1.generator is foo, a1.generator
+ a2 = SCons.Action.Action(cg, strfunction=bar)
+ assert isinstance(a2, SCons.Action.CommandGeneratorAction), a2
+ assert a2.generator is foo, a2.generator
+ assert a2.strfunction is bar, a2.strfunction
+
+ def test_LazyCmdGeneratorAction(self):
+ """Test the Action() factory's creation of lazy CommandGeneratorAction objects
+ """
+ def foo():
+ pass
+
+ a1 = SCons.Action.Action("$FOO")
+ assert isinstance(a1, SCons.Action.CommandGeneratorAction), a1
+ assert isinstance(a1.generator, SCons.Action.LazyCmdGenerator), a1.generator
+
+ a2 = SCons.Action.Action("$FOO", strfunction=foo)
+ assert isinstance(a2, SCons.Action.CommandGeneratorAction), a2
+ assert isinstance(a2.generator, SCons.Action.LazyCmdGenerator), a2.generator
+ assert a2.strfunction is foo, a2.strfunction
+
+ def test_no_action(self):
+ """Test when the Action() factory can't create an action object
+ """
a5 = SCons.Action.Action(1)
assert a5 is None, a5
- a6 = SCons.Action.Action(a1)
- assert a6 is a1, a6
-
- a7 = SCons.Action.Action([[ "explicit", "command", "line" ]])
- assert isinstance(a7, SCons.Action.CommandAction), a7
- assert a7.cmd_list == [ "explicit", "command", "line" ], a7.cmd_list
-
- a8 = SCons.Action.Action(["a8"])
- assert isinstance(a8, SCons.Action.CommandAction), a8
- assert a8.cmd_list == "a8", a8.cmd_list
-
- a9 = SCons.Action.Action("x\ny\nz")
- assert isinstance(a9, SCons.Action.ListAction), a9
- assert isinstance(a9.list[0], SCons.Action.CommandAction), a9.list[0]
- assert a9.list[0].cmd_list == "x", a9.list[0].cmd_list
- assert isinstance(a9.list[1], SCons.Action.CommandAction), a9.list[1]
- assert a9.list[1].cmd_list == "y", a9.list[1].cmd_list
- assert isinstance(a9.list[2], SCons.Action.CommandAction), a9.list[2]
- assert a9.list[2].cmd_list == "z", a9.list[2].cmd_list
-
- a10 = SCons.Action.Action(["x", foo, "z"])
- assert isinstance(a10, SCons.Action.ListAction), a10
- assert isinstance(a10.list[0], SCons.Action.CommandAction), a10.list[0]
- assert a10.list[0].cmd_list == "x", a10.list[0].cmd_list
- assert isinstance(a10.list[1], SCons.Action.FunctionAction), a10.list[1]
- assert a10.list[1].execfunction == foo, a10.list[1].execfunction
- assert isinstance(a10.list[2], SCons.Action.CommandAction), a10.list[2]
- assert a10.list[2].cmd_list == "z", a10.list[2].cmd_list
-
- a11 = SCons.Action.Action(foo, strfunction=bar)
- assert isinstance(a11, SCons.Action.FunctionAction), a11
- assert a11.execfunction == foo, a11.execfunction
- assert a11.strfunction == bar, a11.strfunction
+ def test_reentrance(self):
+ """Test the Action() factory when the action is already an Action object
+ """
+ a1 = SCons.Action.Action("foo")
+ a2 = SCons.Action.Action(a1)
+ assert a2 is a1, a2
class ActionBaseTestCase(unittest.TestCase):
@@ -542,6 +616,12 @@ class CommandActionTestCase(unittest.TestCase):
s = act.strfunction([t1, t2], [s1, s2], env)
assert s == ['xyzzy t1 s1 t1 t2 s1 s2'], s
+ def sf(target, source, env):
+ return "sf was called"
+ act = SCons.Action.CommandAction('foo', strfunction=sf)
+ s = act.strfunction([], [], env)
+ assert s == "sf was called", s
+
def test_execute(self):
"""Test execution of command Actions
@@ -897,6 +977,12 @@ class CommandGeneratorActionTestCase(unittest.TestCase):
assert self.dummy == 1, self.dummy
assert s == ['xyzzy'], s
+ def sf(target, source, env):
+ return "sf was called"
+ a = SCons.Action.CommandGeneratorAction(f, strfunction=sf)
+ s = a.strfunction([], [], env=Environment())
+ assert s == "sf was called", s
+
def test_execute(self):
"""Test executing a command generator Action
"""
@@ -1183,6 +1269,12 @@ class ListActionTestCase(unittest.TestCase):
s = a.strfunction([], [], Environment())
assert s == "f([], [])\ng([], [])\nXXX\nf([], [])", s
+ def sf(target, source, env):
+ return "sf was called"
+ act = SCons.Action.ListAction([f, g, "XXX", f], strfunction=sf)
+ s = act.strfunction([], [], Environment())
+ assert s == "sf was called", s
+
def test_execute(self):
"""Test executing a list of subsidiary Actions
"""
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[7 eOLjQLmSMoTMnSMlRMhPL_9 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\nSMtVMzYN~[N~[N\N\O\O]O]O]O]O\O\O}[NyYNtVM\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\G-wXN}[N]O^O_O`O`O`O`OaOaOaOaOaOaOaOaO`O_O^O\N \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\aMLyYN_OaPbPcPcPdPdPdPdPdPdPdPdPdPePePePePePdPcP_OpUM\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\wXN_OdPfPgQhQhQiQiQiQiQiQjQjQjQjQjQjQjQjQjQjQiQfP`O\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\NCJiQLbPhQkQmRnRoRoRoRoRoRoRoRoRpRpSqSqSrSrSrSqSoRjQ]O\KK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\fOLrUMcPlRqStSuTwTxTxTyTyTzTzUzUzUzUzUyTxTwTtSmRaOhPL\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\a0 cNLqUM\OfQpSwVzV|V}VVVǀVɂW̅[ՏewꪅĈgqTfQ{ZNYIK9\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\O1{G#JkRMqUMtVNiSv\dbzZvUuTsSqSnRjQeP^OrUMHh>!T4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\G-V5wE"~I#M%U+e7l:g2b*a(`(^(])^-]1S,qC$`9 R3G-\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\@)J/i>!pA"tD"wF$yH&xH&tE$wE#yG%}M+T4S5mE*Z7!K/B*;'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\aOoR{UǀVυX<(F-a: e<!h>!j@#k@$h>"d<!c=$hD-fF2[<)K0@);'5$˂VǀV|U_LKYIK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\_OxTɂW֒k|X>f-^(Z'W&T&N>)F-J/b; g>#nD(jB&c<!b=%jH2_A/I0!<(8&5$JYS%8&;'?)E,<:HA=HE?IJAISFJYIKXIK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\nR}UܘqʊevUe,V&VC @ |> y< u: r9 o7 l6 j5 h4 g3 5$D,K/b; h>"wM1tK.e="a<#cA,U8&E-<(9&.!a0 b1 c1      +3#@)46G<:HMCIXHK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\U*vT~X{Yk+W&N$|> u: p8 k5 f3 a0 _/ ]. [- I\*_(LkRMmSMmSMnSMnSMD,R3W5mA"|O0|P1j?"c<!a=%Y7"N1F,;'NCJNCJNDJODJODJODJh>!a: X/K%