From 2f003e703971b5d9862c322715e3759e1dd8a56a Mon Sep 17 00:00:00 2001 From: Zac Hatfield-Dodds Date: Tue, 14 May 2024 21:53:53 -0400 Subject: [PATCH 01/17] PEP 9999: First draft for limiting-yield --- peps/pep-9999.rst | 469 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 469 insertions(+) create mode 100644 peps/pep-9999.rst diff --git a/peps/pep-9999.rst b/peps/pep-9999.rst new file mode 100644 index 00000000000..8038bcc9ef1 --- /dev/null +++ b/peps/pep-9999.rst @@ -0,0 +1,469 @@ +PEP: 9999 +Title: Preventing task-cancellation bugs by limiting yield in async generators +Author: Zac Hatfield-Dodds , + Nathaniel J. Smith +PEP-Delegate: +Discussions-To: [URL] +Status: Draft +Type: Standards Track +Created: 14-May-2024 +Python-Version: 3.14 + + +Abstract +-------- + +`Structured concurrency +`__ +is increasingly popular in Python. Interfaces such as the ``asyncio.TaskGroup`` +and ``asyncio.timeout`` context managers support compositional reasoning, and +allow developers to clearly scope the lifetimes of concurrent tasks. However, +using ``yield`` to suspend a frame inside such a context (a "CancelScope") +corrupts this structure, resulting in situations where the wrong task is +canceled, timeouts are not respected, and exceptions are not properly propagated +or handled. + +To address this issue, this PEP proposes a new ``sys.block_yields()`` context +manager. When inside this context, attempting to ``yield`` will raise a +RuntimeError, preventing the task from yielding across a scope boundary. +Additionally, a mechanism will be provided to allow generator-based context +managers to permit yields across a single call. ``sys.block_yields()`` will be +used by asyncio and downstream libraries to implement task groups, timeouts, and +cancellation; and by ``contextlib`` etc. to convert generators into context +managers which allow safe yields. + +Motivation +---------- + +Structured concurrency is increasingly popular in Python, in the form of newer +``asyncio`` interfaces and third-party libraries such as Trio and anyio. These +interfaces support compositional reasoning, *so long as* users never write a +``yield`` which takes control-flow across a ``CancelScope``. + +A ``CancelScope`` is a context manager which can… cancel… whatever work occurs +within that context (...scope). In asyncio, this is implicit in the design of +``with asyncio.timeout():`` or ``async with asyncio.TaskGroup() as tg:``, which +respectively cancel the contained work after the specified duration, or cancel +sibling tasks when one of them raises an exception. In Trio, the analogous +``trio.fail_after`` and ``trio.open_nursery`` context managers work the same way +by literally wrapping an instance of ``trio.CancelScope()``. We'll generally +use asyncio in our code samples, but say ``CancelScope`` to refer to the +framework-independent concept. + +This structured approach works beautifully, unless you hit one specific sharp +edge: breaking the nesting structure by ``yield``\ ing across the boundary of a +``CancelScope``. This has much the same effect on structured control flow as +adding just a few cross-function ``goto``\ s, and the effects are truly dire: + +- The wrong task can be canceled, whether due to a timeout, an error in a + sibling task, or an explicit request to cancel some other task + +- Exceptions, including ``CancelledError``, can be delivered to the wrong task + +- Exceptions can go missing entirely, being dropped instead of added to an + ``ExceptionGroup`` + +Let's consider three examples, to see what this might look like in practice. + +Leaking a timeout to the outer scope +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Suppose that we want to iterate over an async iterator, but wait for at most +``max_time`` seconds for each element. We might naturally encapsulate the logic +for doing so in an async generator, so that the call site can continue to use a +straightforward ``async for`` loop: + +.. code-block:: python + + async def iter_with_timeout(ait, max_time): + try: + while True: + with timeout(max_time): + yield anext(ait) + except StopAsyncIteration: + return + + async def fn(): + async for elem in iter_with_timeout(ait, max_time=1.0): + await do_something_with(elem) + +Unfortunately, there's a bug in this version: the timeout might expire after the +generator yields but before it is resumed! In this case, we'll see a +``CancelledError`` raised in the outer task, where it cannot be caught by the +``with timeout(max_time):`` statement. + +The fix is fairly simple: get the next element inside the timeout context, and +then yield *outside* that context. + +.. code-block:: python + + async def correct_iter_with_timeout(ait, max_time): + try: + while True: + with timeout(max_time): + tmp = anext(ait) + yield tmp + except StopAsyncIteration: + return + +Leaking background tasks -> breaks cancellation and exception handling +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Timeouts are not the only interface which wrap a ``CancelScope`` - and if you +need some background worker tasks, you can't simply close the ``TaskGroup`` +before yielding. + +As an example, let's look at a fan-in generator, which we'll use to merge the +feeds from several "sensors". We'll also set up our mock sensors with a small +buffer, so that we'll raise an error in the background task while control-flow +is outside the ``combined_iterators`` generator. + +.. code-block:: python + + import asyncio, itertools + + async def mock_sensor(name): + for n in itertools.count(): + await asyncio.sleep(0.1) + if n == 1 and name == "b": # 'presence detection' + yield "PRESENT" + elif n == 3 and name == "a": # inject a simple bug + print("oops, raising RuntimeError\n") + raise RuntimeError + else: + yield f"{name}-{n}" # non-presence sensor data + + async def move_elements_to_queue(ait, queue): + async for obj in ait: + await queue.put(obj) + + async def combined_iterators(*aits): + """Combine async iterators by starting N tasks, each of + which move elements from one iterable to a shared queue.""" + q = asyncio.Queue(maxsize=2) + async with asyncio.TaskGroup() as tg: + for ait in aits: + tg.create_task(move_elements_to_queue(ait, q)) + while True: + yield await q.get() + + async def turn_on_lights_when_someone_gets_home(): + combined = combined_iterators(mock_sensor("a"), mock_sensor("b")) + async for event in combined: + print(event) + if event == "PRESENT": + break + print("main task sleeping for a bit") + await asyncio.sleep(1) # do some other operation + + asyncio.run(turn_on_lights_when_someone_gets_home()) + +When we run this code, we see the expected sequence of observations, then a +'detection', and then while the main task is sleeping we trigger that +``RuntimeError`` in the background. But… we don't actually observe the +``RuntimeError``, not even as the ``__context__`` of another exception! + +.. code-block:: pycon + + >> python3.11 demo.py + a-0 + b-0 + a-1 + PRESENT + main task sleeping for a bit + oops, raising RuntimeError + + Traceback (most recent call last): + File "demo.py", line 39, in + asyncio.run(turn_on_lights_when_someone_gets_home()) + ... + File "demo.py", line 37, in turn_on_lights_when_someone_gets_home + await asyncio.sleep(1) # do some other operation + ^^^^^^^^^^^^^^^^^^^^^^ + File ".../python3.11/asyncio/tasks.py", line 649, in sleep + return await future + asyncio.exceptions.CancelledError + +Here, again, the problem is that we've ``yield``\ ed across a ``CancelScope``; +this time the scope which a ``TaskGroup`` uses to cancel sibling tasks when one +of the child tasks raises an exception. However, the ``CancelledError`` which +was intended for the sibling task was instead injected into the *outer* task, +and so we never got a chance to create and raise an ``ExceptionGroup(..., +[RuntimeError()])``. + +In a user-defined context manager +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Yielding across a CancelScope can be safe, if and only if you're using the +generator to implement a context manager - in this case any propagating +exceptions will be redirected to the expected task. + +(footnote: via e.g. ``contextlib.[async]contextmanager``, or 'moral equivalents' +such as ``@pytest.fixture``) + +We've also implemented a lint rule -- the amusingly named ``ASYNC101`` rule in +`flake8-async `__ -- which warns against +yielding across cancel scopes. Could user education be sufficient to avoid +these problems? Unfortunately not: while it's safe to define context managers +which yield across a cancel scope, that user-defined context manager now wraps a +cancel scope, and is therefore unsafe to yield across! + +This regularly arises in practice, because 'run some background tasks for the +duration of this context' is a very common pattern in structured concurrency. +We saw that in ``combined_iterators()`` above; and have seen this bug in +multiple implementations of the websocket protocol: + +.. code-block:: python + + async def get_messages(websocket_url): + # The websocket protocol requires background tasks to manage the socket heartbeat + async with open_websocket(websocket_url) as ws: # contains a TaskGroup! + while True: + yield await ws.get_message() + + async with open_websocket(websocket_url) as ws: + async for message in get_messages(ws): + ... + +Restating the problem +--------------------- + +Here's the fundamental issue: yield suspends a call frame. It only makes sense +to yield in a leaf frame -- i.e., if your call stack goes like A -> B -> C, then +you can suspend C, but you can't suspend B while leaving C running. + +But, TaskGroup is a kind of "concurrent call" primitive, where a single frame +can have multiple child frames that run concurrently. This means that if we +allow people to mix yield and TaskGroup, then we can end up in exactly this +situation, where B gets suspended but C is actively running. This is +nonsensical, and causes serious practical problems (e.g., if C raises an +exception, we have no way to propagate it). + +This is a fundamental incompatibility between generator control flow and +structured concurrency control flow, not something we can fix by tweaking our +APIs. The only solution seems to be to forbid yield inside a TaskGroup. +Although timeouts don't leave a child task running, the close analogy and +related problems lead us to conclude that yield should be forbidden inside all +CancelScopes, not only TaskGroups. + +Solution +-------- + +We propose: + +1. a new context manager, ``with sys.block_yields(reason): ...`` which will + raise a RuntimeError if you attempt to yield across it. CancelScope-like + context managers in asyncio and downstream code can then wrap this to block + yielding across *their* contexts. + +2. a mechanism by which generator-to-context-manager decorators can allow yields + across one call. We're not yet sure what this should look like; the leading + candidates are + +3. a code-object attribute, ``fn.__code__.co_allow_yields = True``, or + +4. some sort of invocation flag, e.g. ``fn.__invoke_with_yields__``, to avoid + mutating a code object that might be shared between decorated and undecorated + functions + +Implementation +-------------- + +The new ``sys.block_yields`` context manager will require interpreter support. +For each frame, we track the entries and exits of this context manager. + +We're not particularly attached to the exact representation; we'll discuss it as +a stack (which would support clear error messages), but more compact +representations such as pair-of-integers would also work. + +TODO: ask Mark Shannon about how to store this on the frame object + +- When entering a newly-created or resumed frame, initialize empty stacks of + entries and exits. + +- When returning from a frame, merge these stacks into that of the parent + frame. + +- When yielding: + +- if ``entries != [] and not frame.allow_yield_flag``, raise a ``RuntimeError`` + instead of yielding (the new behavior this PEP proposes) + +- otherwise, merge stacks into the parent frame as for a return. + +Because this is about yielding frames *within* a task, not switching between +tasks, syntactic ``yield`` and ``yield from`` should be affected, but ``await`` +expressions should not. + +Worked examples +~~~~~~~~~~~~~~~ + +TODO: it'd be great to have diagrams for these. + +No-yield example +^^^^^^^^^^^^^^^^ + +- enter frame + +- use context manager + + - which calls ``__enter__``, which calls + ``sys.block_yields(reason).__enter__``, so there's multiple rounds of the + stack merging as this unwinds, to get the reason attached to the original + frame + + - then ``__exit__`` repeats that process, ending with the corresponding exit + on the stack. + +- leave frame. Entries and exits are balanced, so they don't propagate any + further. + +Attempts-to-yield example +^^^^^^^^^^^^^^^^^^^^^^^^^ + +- enter frame + +- use context manager + + - which calls ``__enter__``, which … as above + + - ``yield``: interpreter observes that ``frame.allow_yield_flag`` is not + set, and raises a RuntimeError. + + - then ``__exit__``, as above + +- leave frame with an exception active, but still a balanced entry/exit stack + +Allowed-to-yield example +^^^^^^^^^^^^^^^^^^^^^^^^ + +- enter frame, which a decorator has marked as allowing yields. + +- use context manager + + - which calls ``__enter__``, which … as above + + - ``yield`` -- this time it's allowed! + + - Our entry/exit stack is merged with the parent frame, adding one enter to + the parent stack, and this frame is suspended. + + - This frame is resumed (possibly with an exception active; it's a context + manager after all). Our frame's stack is currently empty. + + - then ``__exit__``, as above + +- leave frame, merging our exit into the parent frame's stack (rebalancing that + parent stack). + +Allowing yield for context managers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +defining ``open_websocket_url``, how ``@asynccontextmanager`` sets the flag + +also show a third-party case such as ``@pytest.fixture``; we can't just +special-case the contextlib decorators in the interpreter. + +Behavior if ``sys.block_yields`` is misused +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +While unwise, it's possible to call ``sys.block_yields.__enter__`` and +``.__exit__`` in an order that does not correspond to any valid nesting, or get +an invalid frame state in some other way. + +There are two ways ``sys.block_yields.__exit__`` could detect an invalid state. +First, if yields are not blocked, we can simply raise an exception without +changing the state. Second, if an unexpected entry is at the top of the stack, +we suggest popping that entry and raising an exception -- this ensures that +out-of-order calls will still clear the stack, while still making it clear that +something is wrong. + +(and if we choose e.g. an integer- rather than stack-based representation, such +states may not be distinguishable from correct nesting at all, in which case the +question will not arise) + +Anticipated uses +---------------- + +In the standard library, ``sys.block_yields`` would be used by +``asyncio.TaskGroup``, ``asycio.timeout``, and ``asyncio.timeout_at``. +Downstream, we expect to use it in ``trio.CancelScope``, async fixtures (in +pytest-trio, anyio, etc.), and perhaps other places. + +We consider use-cases unrelated to async correctness, such as preventing +``decimal.localcontext`` from leaking out of a generator, out of scope for this +PEP. + +The generator-to-context-manager support would be used by +``contextlib.(async)contextmanager``, and if necessary in ``(Async)ExitStack``. + +Teaching +-------- + +Async generators are very rarely taught to novice programmers. + +Most intermediate and advanced Python programmers will only interact with this +PEP as users of ``TaskGroup``, ``timeout``, and ``@contextmanager``. For this +group, we expect a clear exception message and documentation to be sufficient. + +- A new section will be added to the '\ `developing with asyncio + `__\ ' page, which + briefly states that async generators are not permitted to ``yield`` when + inside a "cancel scope" context, i.e. ``TaskGroup`` or ``timeout`` context + manager. We anticipate that the problem-restatement and some parts of the + motivation section will provide a basis for these docs. We may also suggest + refactoring affected code into a context manager which yields an async + iterable -- see below. + +- In the docs for each context manager which wraps a cancel scope, and thus now + ``sys.block_yields``, include a standard sentence such as "If used within an + async generator, [it is an error to ``yield`` inside this context manager]." + with a hyperlink to the explanation above. + +For asyncio, Trio, curio, or other-framework maintainers who implement +CancelScope semantics, we will ensure that the documentation of +``sys.block_yields`` gives a full explanation distilled from the solution and +implementation sections of this PEP. We anticipate consulting most such +maintainers for their feedback on the draft PEP. + +Consider making ``asyncio.Queue`` async-iterable +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When working in codebases which `avoid async generators entirely +`__ +[footnote: see `experience report +`__], +we've found that an async context manager yielding an async iterable is a safe +and ergonomic replacement for async generators -- and avoids the delayed-cleanup +problems described in PEP-533, which this PEP will not solve. + +Trio (or anyio) `channels +`__ +are particularly nice for this purpose, because the receive-side is async +iterable and the send-side has a ``.close()`` method to signal when iteration +should stop. A send+receive pair of channels are otherwise almost identical to +an ``asyncio.Queue``, and so *independently of this PEP* we recommend adding +``Queue.__aiter__`` and ``Queue.close`` methods to support this design pattern. + +Rejected alternatives +--------------------- + +`PEP 533 `__ - deterministic cleanup for +iterators would ensure that misfired cancellations are eventually directed to +the correct scope, but only after they had wreaked havoc elsewhere. Plausibly +still useful to ensure that cleanup is *timely*, but does not solve this +problem. + +Note: `more\_itertools.with\_iter +`__ +seems wildly unsafe - should I report that?? + +`PEP 568 `__ - would make it possible to work +around some bugs which this PEP makes impossible. We recommend marking it as +rejected. + +If you want more details on all the specific problems that arise, and how they +relate to this proposal, and to PEP 533 and PEP 568, then see `this comment +`__ and +`this Discuss thread +`__. From f80e2f2d865ccc7e7c946fe8aeab1702fa839d1d Mon Sep 17 00:00:00 2001 From: Zac Hatfield-Dodds Date: Tue, 14 May 2024 23:03:39 -0400 Subject: [PATCH 02/17] PEP 9999: cleanups and clarifications --- peps/pep-9999.rst | 251 +++++++++++++++++++++++----------------------- 1 file changed, 125 insertions(+), 126 deletions(-) diff --git a/peps/pep-9999.rst b/peps/pep-9999.rst index 8038bcc9ef1..ea2c3756244 100644 --- a/peps/pep-9999.rst +++ b/peps/pep-9999.rst @@ -3,7 +3,7 @@ Title: Preventing task-cancellation bugs by limiting yield in async generators Author: Zac Hatfield-Dodds , Nathaniel J. Smith PEP-Delegate: -Discussions-To: [URL] +Discussions-To: https://discuss.python.org/t/preventing-yield-inside-certain-context-managers/1091 Status: Draft Type: Standards Track Created: 14-May-2024 @@ -11,17 +11,15 @@ Python-Version: 3.14 Abstract --------- - -`Structured concurrency -`__ -is increasingly popular in Python. Interfaces such as the ``asyncio.TaskGroup`` -and ``asyncio.timeout`` context managers support compositional reasoning, and -allow developers to clearly scope the lifetimes of concurrent tasks. However, -using ``yield`` to suspend a frame inside such a context (a "CancelScope") -corrupts this structure, resulting in situations where the wrong task is -canceled, timeouts are not respected, and exceptions are not properly propagated -or handled. +======== + +`Structured concurrency`_ is increasingly popular in Python. Interfaces such as +the ``asyncio.TaskGroup`` and ``asyncio.timeout`` context managers support +compositional reasoning, and allow developers to clearly scope the lifetimes of +concurrent tasks. However, using ``yield`` to suspend a frame inside such a +context (a "CancelScope") corrupts this structure, resulting in situations where +the wrong task is canceled, timeouts are not respected, and exceptions are not +properly propagated or handled. To address this issue, this PEP proposes a new ``sys.block_yields()`` context manager. When inside this context, attempting to ``yield`` will raise a @@ -32,15 +30,17 @@ used by asyncio and downstream libraries to implement task groups, timeouts, and cancellation; and by ``contextlib`` etc. to convert generators into context managers which allow safe yields. +.. _Structured concurrency: https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/ + Motivation ----------- +========== Structured concurrency is increasingly popular in Python, in the form of newer ``asyncio`` interfaces and third-party libraries such as Trio and anyio. These interfaces support compositional reasoning, *so long as* users never write a ``yield`` which takes control-flow across a ``CancelScope``. -A ``CancelScope`` is a context manager which can… cancel… whatever work occurs +A ``CancelScope`` is a context manager which can... cancel... whatever work occurs within that context (...scope). In asyncio, this is implicit in the design of ``with asyncio.timeout():`` or ``async with asyncio.TaskGroup() as tg:``, which respectively cancel the contained work after the specified duration, or cancel @@ -66,7 +66,7 @@ adding just a few cross-function ``goto``\ s, and the effects are truly dire: Let's consider three examples, to see what this might look like in practice. Leaking a timeout to the outer scope -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------ Suppose that we want to iterate over an async iterator, but wait for at most ``max_time`` seconds for each element. We might naturally encapsulate the logic @@ -106,8 +106,8 @@ then yield *outside* that context. except StopAsyncIteration: return -Leaking background tasks -> breaks cancellation and exception handling -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Leaking background tasks (breaks cancellation and exception handling) +--------------------------------------------------------------------- Timeouts are not the only interface which wrap a ``CancelScope`` - and if you need some background worker tasks, you can't simply close the ``TaskGroup`` @@ -160,7 +160,7 @@ is outside the ``combined_iterators`` generator. When we run this code, we see the expected sequence of observations, then a 'detection', and then while the main task is sleeping we trigger that -``RuntimeError`` in the background. But… we don't actually observe the +``RuntimeError`` in the background. But... we don't actually observe the ``RuntimeError``, not even as the ``__context__`` of another exception! .. code-block:: pycon @@ -192,14 +192,14 @@ and so we never got a chance to create and raise an ``ExceptionGroup(..., [RuntimeError()])``. In a user-defined context manager -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------------- Yielding across a CancelScope can be safe, if and only if you're using the generator to implement a context manager - in this case any propagating -exceptions will be redirected to the expected task. +exceptions will be redirected to the expected task. [#redirected]_ -(footnote: via e.g. ``contextlib.[async]contextmanager``, or 'moral equivalents' -such as ``@pytest.fixture``) +.. [#redirected] via e.g. ``contextlib.[async]contextmanager``, + or moral equivalents such as ``@pytest.fixture`` We've also implemented a lint rule -- the amusingly named ``ASYNC101`` rule in `flake8-async `__ -- which warns against @@ -226,7 +226,7 @@ multiple implementations of the websocket protocol: ... Restating the problem ---------------------- +===================== Here's the fundamental issue: yield suspends a call frame. It only makes sense to yield in a leaf frame -- i.e., if your call stack goes like A -> B -> C, then @@ -247,7 +247,7 @@ related problems lead us to conclude that yield should be forbidden inside all CancelScopes, not only TaskGroups. Solution --------- +======== We propose: @@ -258,16 +258,16 @@ We propose: 2. a mechanism by which generator-to-context-manager decorators can allow yields across one call. We're not yet sure what this should look like; the leading - candidates are + candidates are: -3. a code-object attribute, ``fn.__code__.co_allow_yields = True``, or + a. a code-object attribute, ``fn.__code__.co_allow_yields = True``, or -4. some sort of invocation flag, e.g. ``fn.__invoke_with_yields__``, to avoid - mutating a code object that might be shared between decorated and undecorated - functions + b. some sort of invocation flag, e.g. ``fn.__invoke_with_yields__``, to avoid + mutating a code object that might be shared between decorated and undecorated + functions Implementation --------------- +============== The new ``sys.block_yields`` context manager will require interpreter support. For each frame, we track the entries and exits of this context manager. @@ -276,96 +276,86 @@ We're not particularly attached to the exact representation; we'll discuss it as a stack (which would support clear error messages), but more compact representations such as pair-of-integers would also work. -TODO: ask Mark Shannon about how to store this on the frame object - -- When entering a newly-created or resumed frame, initialize empty stacks of - entries and exits. - -- When returning from a frame, merge these stacks into that of the parent - frame. +- When entering a newly-created or resumed frame, initialize empty stacks of + entries and exits. +- When returning from a frame, merge these stacks into that of the parent frame. +- When yielding: -- When yielding: - -- if ``entries != [] and not frame.allow_yield_flag``, raise a ``RuntimeError`` - instead of yielding (the new behavior this PEP proposes) - -- otherwise, merge stacks into the parent frame as for a return. + - if ``entries != [] and not frame.allow_yield_flag``, raise a ``RuntimeError`` + instead of yielding (the new behavior this PEP proposes) + - otherwise, merge stacks into the parent frame as for a return. Because this is about yielding frames *within* a task, not switching between tasks, syntactic ``yield`` and ``yield from`` should be affected, but ``await`` expressions should not. Worked examples -~~~~~~~~~~~~~~~ +--------------- -TODO: it'd be great to have diagrams for these. +*TODO: it'd be great to have diagrams for these examples* No-yield example -^^^^^^^^^^^^^^^^ - -- enter frame +~~~~~~~~~~~~~~~~ +- enter frame - use context manager - - which calls ``__enter__``, which calls - ``sys.block_yields(reason).__enter__``, so there's multiple rounds of the - stack merging as this unwinds, to get the reason attached to the original - frame + - which calls ``__enter__``, which calls ``sys.block_yields(reason).__enter__``, + so there are multiple rounds of the stack merging as this unwinds, to get the + reason attached to the original frame + - then ``__exit__`` repeats that process, ending with the corresponding exit + on the stack. - - then ``__exit__`` repeats that process, ending with the corresponding exit - on the stack. +- leave frame. Entries and exits are balanced, so they don't propagate any further. -- leave frame. Entries and exits are balanced, so they don't propagate any - further. Attempts-to-yield example -^^^^^^^^^^^^^^^^^^^^^^^^^ - -- enter frame +~~~~~~~~~~~~~~~~~~~~~~~~~ +- enter frame - use context manager - - which calls ``__enter__``, which … as above - - - ``yield``: interpreter observes that ``frame.allow_yield_flag`` is not - set, and raises a RuntimeError. + - which calls ``__enter__``, which ... as above + - ``yield``: interpreter observes that ``frame.allow_yield_flag`` is not set, + and raises a RuntimeError. + - then ``__exit__``, as above - - then ``__exit__``, as above +- leave frame with an exception active, but still a balanced entry/exit stack -- leave frame with an exception active, but still a balanced entry/exit stack Allowed-to-yield example -^^^^^^^^^^^^^^^^^^^^^^^^ - -- enter frame, which a decorator has marked as allowing yields. +~~~~~~~~~~~~~~~~~~~~~~~~ +- enter frame, which a decorator has marked as allowing yields. - use context manager - - which calls ``__enter__``, which … as above - - - ``yield`` -- this time it's allowed! + - which calls ``__enter__``, which ... as above + - ``yield`` -- this time it's allowed! - - Our entry/exit stack is merged with the parent frame, adding one enter to + - Our entry/exit stack is merged with the parent frame, adding one enter to the parent stack, and this frame is suspended. - - - This frame is resumed (possibly with an exception active; it's a context + - This frame is resumed (possibly with an exception active; it's a context manager after all). Our frame's stack is currently empty. - - then ``__exit__``, as above + - then ``__exit__``, as above + +- leave frame, merging our exit into the parent frame's stack + (rebalancing that parent stack). -- leave frame, merging our exit into the parent frame's stack (rebalancing that - parent stack). Allowing yield for context managers -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +*TODO: this section is a placeholder, pending a decision on the mechanism for +``@contextmanager`` to unblock yields.* -defining ``open_websocket_url``, how ``@asynccontextmanager`` sets the flag +- Explain and show a code sample of how ``@asynccontextmanager`` sets the flag +- also show a third-party case such as ``@pytest.fixture`` to demonstrate that + we can't just have the interpreter special-case contextlib. -also show a third-party case such as ``@pytest.fixture``; we can't just -special-case the contextlib decorators in the interpreter. Behavior if ``sys.block_yields`` is misused -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------- While unwise, it's possible to call ``sys.block_yields.__enter__`` and ``.__exit__`` in an order that does not correspond to any valid nesting, or get @@ -382,10 +372,11 @@ something is wrong. states may not be distinguishable from correct nesting at all, in which case the question will not arise) + Anticipated uses ----------------- +================ -In the standard library, ``sys.block_yields`` would be used by +In the standard library, ``sys.block_yields`` could be used by ``asyncio.TaskGroup``, ``asycio.timeout``, and ``asyncio.timeout_at``. Downstream, we expect to use it in ``trio.CancelScope``, async fixtures (in pytest-trio, anyio, etc.), and perhaps other places. @@ -395,10 +386,29 @@ We consider use-cases unrelated to async correctness, such as preventing PEP. The generator-to-context-manager support would be used by -``contextlib.(async)contextmanager``, and if necessary in ``(Async)ExitStack``. +``@contextlib.(async)contextmanager``, and if necessary in ``(Async)ExitStack``. + + +Backwards Compatibility +======================= + +The addition of the ``sys.block_yields`` context manager, changes to +``@contextlib.(async)contextmanager``, and corresponding interpreter +support are all fully backwards-compatible. + +Blocking yields from ``asyncio.TaskGroup``, ``asycio.timeout``, and +``asyncio.timeout_at`` would be a breaking change to at least some code in the +wild, which (however unsafe and prone to the motivating problems above) may work +often enough to make it into production. + +We will seek community feedback on appropriate deprecation pathways for +standard-library code, including the suggested length of any deprecation period. +Irrespective of stdlib usage, downstream frameworks would adopt this +functionality immediately. + -Teaching --------- +How to Teach This +================= Async generators are very rarely taught to novice programmers. @@ -406,64 +416,53 @@ Most intermediate and advanced Python programmers will only interact with this PEP as users of ``TaskGroup``, ``timeout``, and ``@contextmanager``. For this group, we expect a clear exception message and documentation to be sufficient. -- A new section will be added to the '\ `developing with asyncio - `__\ ' page, which - briefly states that async generators are not permitted to ``yield`` when - inside a "cancel scope" context, i.e. ``TaskGroup`` or ``timeout`` context - manager. We anticipate that the problem-restatement and some parts of the - motivation section will provide a basis for these docs. We may also suggest - refactoring affected code into a context manager which yields an async - iterable -- see below. +- A new section will be added to the `developing with asyncio + `__ page, which + briefly states that async generators are not permitted to ``yield`` when + inside a "cancel scope" context, i.e. ``TaskGroup`` or ``timeout`` context + manager. We anticipate that the problem-restatement and some parts of the + motivation section will provide a basis for these docs. + + - When working in codebases which avoid async generators entirely [#exp-report]_, + we've found that an async context manager yielding an async iterable is a safe + and ergonomic replacement for async generators -- and avoids the delayed-cleanup + problems described in :pep:`533`, which this proposal does not address. - In the docs for each context manager which wraps a cancel scope, and thus now ``sys.block_yields``, include a standard sentence such as "If used within an async generator, [it is an error to ``yield`` inside this context manager]." with a hyperlink to the explanation above. +.. [#exp-report] see `experience report + `__ + For asyncio, Trio, curio, or other-framework maintainers who implement CancelScope semantics, we will ensure that the documentation of ``sys.block_yields`` gives a full explanation distilled from the solution and implementation sections of this PEP. We anticipate consulting most such maintainers for their feedback on the draft PEP. -Consider making ``asyncio.Queue`` async-iterable -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -When working in codebases which `avoid async generators entirely -`__ -[footnote: see `experience report -`__], -we've found that an async context manager yielding an async iterable is a safe -and ergonomic replacement for async generators -- and avoids the delayed-cleanup -problems described in PEP-533, which this PEP will not solve. - -Trio (or anyio) `channels -`__ -are particularly nice for this purpose, because the receive-side is async -iterable and the send-side has a ``.close()`` method to signal when iteration -should stop. A send+receive pair of channels are otherwise almost identical to -an ``asyncio.Queue``, and so *independently of this PEP* we recommend adding -``Queue.__aiter__`` and ``Queue.close`` methods to support this design pattern. Rejected alternatives ---------------------- - -`PEP 533 `__ - deterministic cleanup for -iterators would ensure that misfired cancellations are eventually directed to -the correct scope, but only after they had wreaked havoc elsewhere. Plausibly -still useful to ensure that cleanup is *timely*, but does not solve this -problem. +===================== -Note: `more\_itertools.with\_iter -`__ -seems wildly unsafe - should I report that?? +:pep:`533` - deterministic cleanup for iterators would ensure that misfired +cancellations are eventually directed to the correct scope, but only after they +had wreaked havoc elsewhere. Plausibly still useful to ensure that cleanup is +*timely*, but does not solve this problem. -`PEP 568 `__ - would make it possible to work -around some bugs which this PEP makes impossible. We recommend marking it as -rejected. +:pep:`568` - would make it possible to work around some bugs which this PEP +makes impossible. We recommend marking it as rejected. If you want more details on all the specific problems that arise, and how they relate to this proposal, and to PEP 533 and PEP 568, then see `this comment `__ and `this Discuss thread `__. + + +Copyright +========= + +This document is placed in the public domain or under the +CC0-1.0-Universal license, whichever is more permissive. From 7b80d6e7f492a18eb9d8687a6b11bce025644847 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Wed, 15 May 2024 06:12:42 -0400 Subject: [PATCH 03/17] PEP 789 --- peps/{pep-9999.rst => pep-0789.rst} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename peps/{pep-9999.rst => pep-0789.rst} (99%) diff --git a/peps/pep-9999.rst b/peps/pep-0789.rst similarity index 99% rename from peps/pep-9999.rst rename to peps/pep-0789.rst index ea2c3756244..0b2a1b77858 100644 --- a/peps/pep-9999.rst +++ b/peps/pep-0789.rst @@ -1,4 +1,4 @@ -PEP: 9999 +PEP: 789 Title: Preventing task-cancellation bugs by limiting yield in async generators Author: Zac Hatfield-Dodds , Nathaniel J. Smith From 38623b6c6c6492b8bc4a5aaa512a15f9cf90059f Mon Sep 17 00:00:00 2001 From: Zac Hatfield-Dodds Date: Wed, 15 May 2024 11:38:30 -0400 Subject: [PATCH 04/17] PEP 789: further clarifications --- .github/CODEOWNERS | 1 + peps/conf.py | 1 + peps/pep-0789.rst | 95 +++++++++++++++++++++++++--------------------- 3 files changed, 53 insertions(+), 44 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a90a99d7547..15fc5bd4903 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -624,6 +624,7 @@ peps/pep-0742.rst @JelleZijlstra peps/pep-0743.rst @vstinner peps/pep-0744.rst @brandtbucher peps/pep-0745.rst @hugovk +peps/pep-0789.rst @njsmith # ... # peps/pep-0754.rst # ... diff --git a/peps/conf.py b/peps/conf.py index d8e851a5035..69c7489fd7d 100644 --- a/peps/conf.py +++ b/peps/conf.py @@ -53,6 +53,7 @@ 'python': ('https://docs.python.org/3/', None), 'packaging': ('https://packaging.python.org/en/latest/', None), 'typing': ('https://typing.readthedocs.io/en/latest/', None), + 'trio': ('https://typing.readthedocs.io/en/latest/', None), 'devguide': ('https://devguide.python.org/', None), 'py3.11': ('https://docs.python.org/3.11/', None), 'py3.12': ('https://docs.python.org/3.12/', None), diff --git a/peps/pep-0789.rst b/peps/pep-0789.rst index 0b2a1b77858..be60ae3f1a1 100644 --- a/peps/pep-0789.rst +++ b/peps/pep-0789.rst @@ -17,16 +17,16 @@ Abstract the ``asyncio.TaskGroup`` and ``asyncio.timeout`` context managers support compositional reasoning, and allow developers to clearly scope the lifetimes of concurrent tasks. However, using ``yield`` to suspend a frame inside such a -context (a "CancelScope") corrupts this structure, resulting in situations where +context (a "cancel scope") corrupts this structure, resulting in situations where the wrong task is canceled, timeouts are not respected, and exceptions are not properly propagated or handled. To address this issue, this PEP proposes a new ``sys.block_yields()`` context -manager. When inside this context, attempting to ``yield`` will raise a -RuntimeError, preventing the task from yielding across a scope boundary. -Additionally, a mechanism will be provided to allow generator-based context -managers to permit yields across a single call. ``sys.block_yields()`` will be -used by asyncio and downstream libraries to implement task groups, timeouts, and +manager. When syntatically inside this context, attempting to ``yield`` will +raise a RuntimeError, preventing the task from yielding. Additionally, a +mechanism will be provided for decorators such as ``@contextmanager`` to allow +yields inside the decorated function. ``sys.block_yields()`` will be used by +asyncio and downstream libraries to implement task groups, timeouts, and cancellation; and by ``contextlib`` etc. to convert generators into context managers which allow safe yields. @@ -36,32 +36,35 @@ Motivation ========== Structured concurrency is increasingly popular in Python, in the form of newer -``asyncio`` interfaces and third-party libraries such as Trio and anyio. These -interfaces support compositional reasoning, *so long as* users never write a -``yield`` which takes control-flow across a ``CancelScope``. +:py:mod:`asyncio` interfaces and third-party libraries such as Trio and anyio. +These interfaces support compositional reasoning, *so long as* users never write +a ``yield`` which suspends a frame while inside a cancel scope. -A ``CancelScope`` is a context manager which can... cancel... whatever work occurs +A cancel scope is a context manager which can... cancel... whatever work occurs within that context (...scope). In asyncio, this is implicit in the design of ``with asyncio.timeout():`` or ``async with asyncio.TaskGroup() as tg:``, which respectively cancel the contained work after the specified duration, or cancel -sibling tasks when one of them raises an exception. In Trio, the analogous -``trio.fail_after`` and ``trio.open_nursery`` context managers work the same way -by literally wrapping an instance of ``trio.CancelScope()``. We'll generally -use asyncio in our code samples, but say ``CancelScope`` to refer to the -framework-independent concept. +sibling tasks when one of them raises an exception. The core functionality of +a cancel scope is synchronous, but the user-facing context managers may be +either sync or async. [#trio-cancel-scope]_ -This structured approach works beautifully, unless you hit one specific sharp -edge: breaking the nesting structure by ``yield``\ ing across the boundary of a -``CancelScope``. This has much the same effect on structured control flow as -adding just a few cross-function ``goto``\ s, and the effects are truly dire: - -- The wrong task can be canceled, whether due to a timeout, an error in a - sibling task, or an explicit request to cancel some other task +.. [#trio-cancel-scope] + While cancel scopes are implicit in asyncio, the analogous + :py:func:`trio.fail_after` (sync) and :py:func:`trio.open_nursery` (async) + context managers literally wrap an instance of :py:class:`trio.CancelScope`. + We'll stick with asyncio for examples here, but say "cancel scope" when + referring to the framework-independent concept. -- Exceptions, including ``CancelledError``, can be delivered to the wrong task +This structured approach works beautifully, unless you hit one specific sharp +edge: breaking the nesting structure by ``yield``\ ing inside a cancel scope. +This has much the same effect on structured control flow as adding just a few +cross-function ``goto``\ s, and the effects are truly dire: -- Exceptions can go missing entirely, being dropped instead of added to an - ``ExceptionGroup`` +- The wrong task can be canceled, whether due to a timeout, an error in a + sibling task, or an explicit request to cancel some other task +- Exceptions, including ``CancelledError``, can be delivered to the wrong task +- Exceptions can go missing entirely, being dropped instead of added to an + ``ExceptionGroup`` Let's consider three examples, to see what this might look like in practice. @@ -109,13 +112,13 @@ then yield *outside* that context. Leaking background tasks (breaks cancellation and exception handling) --------------------------------------------------------------------- -Timeouts are not the only interface which wrap a ``CancelScope`` - and if you +Timeouts are not the only interface which wrap a cancel scope - and if you need some background worker tasks, you can't simply close the ``TaskGroup`` before yielding. As an example, let's look at a fan-in generator, which we'll use to merge the feeds from several "sensors". We'll also set up our mock sensors with a small -buffer, so that we'll raise an error in the background task while control-flow +buffer, so that we'll raise an error in the background task while control flow is outside the ``combined_iterators`` generator. .. code-block:: python @@ -128,7 +131,7 @@ is outside the ``combined_iterators`` generator. if n == 1 and name == "b": # 'presence detection' yield "PRESENT" elif n == 3 and name == "a": # inject a simple bug - print("oops, raising RuntimeError\n") + print("oops, raising RuntimeError") raise RuntimeError else: yield f"{name}-{n}" # non-presence sensor data @@ -184,17 +187,17 @@ When we run this code, we see the expected sequence of observations, then a return await future asyncio.exceptions.CancelledError -Here, again, the problem is that we've ``yield``\ ed across a ``CancelScope``; +Here, again, the problem is that we've ``yield``\ ed inside a cancel scope; this time the scope which a ``TaskGroup`` uses to cancel sibling tasks when one of the child tasks raises an exception. However, the ``CancelledError`` which was intended for the sibling task was instead injected into the *outer* task, -and so we never got a chance to create and raise an ``ExceptionGroup(..., -[RuntimeError()])``. +and so we never got a chance to create and raise an +``ExceptionGroup(..., [RuntimeError()])``. In a user-defined context manager --------------------------------- -Yielding across a CancelScope can be safe, if and only if you're using the +Yielding inside a cancel scope can be safe, if and only if you're using the generator to implement a context manager - in this case any propagating exceptions will be redirected to the expected task. [#redirected]_ @@ -203,10 +206,9 @@ exceptions will be redirected to the expected task. [#redirected]_ We've also implemented a lint rule -- the amusingly named ``ASYNC101`` rule in `flake8-async `__ -- which warns against -yielding across cancel scopes. Could user education be sufficient to avoid -these problems? Unfortunately not: while it's safe to define context managers -which yield across a cancel scope, that user-defined context manager now wraps a -cancel scope, and is therefore unsafe to yield across! +yielding inside know cancel scopes. Could user education be sufficient to avoid +these problems? Unfortunately not: user-defined context managers can also wrap +a cancel scope, and it's infeasible to recognize or lint for all such cases. This regularly arises in practice, because 'run some background tasks for the duration of this context' is a very common pattern in structured concurrency. @@ -244,17 +246,17 @@ structured concurrency control flow, not something we can fix by tweaking our APIs. The only solution seems to be to forbid yield inside a TaskGroup. Although timeouts don't leave a child task running, the close analogy and related problems lead us to conclude that yield should be forbidden inside all -CancelScopes, not only TaskGroups. +cancel scopes, not only TaskGroups. -Solution -======== +Specification +============= We propose: 1. a new context manager, ``with sys.block_yields(reason): ...`` which will - raise a RuntimeError if you attempt to yield across it. CancelScope-like - context managers in asyncio and downstream code can then wrap this to block - yielding across *their* contexts. + raise a RuntimeError if you attempt to yield while inside it. [#also-sync]_ + Cancel-scope-like context managers in asyncio and downstream code can then + wrap this to block yielding across *their* contexts. 2. a mechanism by which generator-to-context-manager decorators can allow yields across one call. We're not yet sure what this should look like; the leading @@ -266,8 +268,13 @@ We propose: mutating a code object that might be shared between decorated and undecorated functions +.. [#also-sync] + Note that this blocks yields in both sync and async generators, so that + downstream frameworks can define sync cancel scope countexts such as + :py:func:`trio.fail_after`. + Implementation -============== +-------------- The new ``sys.block_yields`` context manager will require interpreter support. For each frame, we track the entries and exits of this context manager. @@ -437,7 +444,7 @@ group, we expect a clear exception message and documentation to be sufficient. `__ For asyncio, Trio, curio, or other-framework maintainers who implement -CancelScope semantics, we will ensure that the documentation of +cancel scope semantics, we will ensure that the documentation of ``sys.block_yields`` gives a full explanation distilled from the solution and implementation sections of this PEP. We anticipate consulting most such maintainers for their feedback on the draft PEP. From faf6fe9e98c5e2ffe3075459d7bc3c2da617bd4b Mon Sep 17 00:00:00 2001 From: Zac Hatfield-Dodds Date: Wed, 15 May 2024 11:48:50 -0400 Subject: [PATCH 05/17] PEP 789: fix typos --- peps/conf.py | 2 +- peps/pep-0789.rst | 35 +++++++++++++++++++---------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/peps/conf.py b/peps/conf.py index 69c7489fd7d..60556e45384 100644 --- a/peps/conf.py +++ b/peps/conf.py @@ -53,7 +53,7 @@ 'python': ('https://docs.python.org/3/', None), 'packaging': ('https://packaging.python.org/en/latest/', None), 'typing': ('https://typing.readthedocs.io/en/latest/', None), - 'trio': ('https://typing.readthedocs.io/en/latest/', None), + 'trio': ('https://trio.readthedocs.io/en/latest/', None), 'devguide': ('https://devguide.python.org/', None), 'py3.11': ('https://docs.python.org/3.11/', None), 'py3.12': ('https://docs.python.org/3.12/', None), diff --git a/peps/pep-0789.rst b/peps/pep-0789.rst index be60ae3f1a1..26427ffb5c0 100644 --- a/peps/pep-0789.rst +++ b/peps/pep-0789.rst @@ -22,7 +22,7 @@ the wrong task is canceled, timeouts are not respected, and exceptions are not properly propagated or handled. To address this issue, this PEP proposes a new ``sys.block_yields()`` context -manager. When syntatically inside this context, attempting to ``yield`` will +manager. When syntactically inside this context, attempting to ``yield`` will raise a RuntimeError, preventing the task from yielding. Additionally, a mechanism will be provided for decorators such as ``@contextmanager`` to allow yields inside the decorated function. ``sys.block_yields()`` will be used by @@ -48,13 +48,6 @@ sibling tasks when one of them raises an exception. The core functionality of a cancel scope is synchronous, but the user-facing context managers may be either sync or async. [#trio-cancel-scope]_ -.. [#trio-cancel-scope] - While cancel scopes are implicit in asyncio, the analogous - :py:func:`trio.fail_after` (sync) and :py:func:`trio.open_nursery` (async) - context managers literally wrap an instance of :py:class:`trio.CancelScope`. - We'll stick with asyncio for examples here, but say "cancel scope" when - referring to the framework-independent concept. - This structured approach works beautifully, unless you hit one specific sharp edge: breaking the nesting structure by ``yield``\ ing inside a cancel scope. This has much the same effect on structured control flow as adding just a few @@ -68,6 +61,14 @@ cross-function ``goto``\ s, and the effects are truly dire: Let's consider three examples, to see what this might look like in practice. +.. [#trio-cancel-scope] + While cancel scopes are implicit in asyncio, the analogous + :py:func:`trio:trio.fail_after` (sync) and :py:func:`trio:trio.open_nursery` + (async) context managers literally wrap an instance of + :py:class:`trio:trio.CancelScope`. We'll stick with asyncio for examples + here, but say "cancel scope" when referring to the framework-independent + concept. + Leaking a timeout to the outer scope ------------------------------------ @@ -201,9 +202,6 @@ Yielding inside a cancel scope can be safe, if and only if you're using the generator to implement a context manager - in this case any propagating exceptions will be redirected to the expected task. [#redirected]_ -.. [#redirected] via e.g. ``contextlib.[async]contextmanager``, - or moral equivalents such as ``@pytest.fixture`` - We've also implemented a lint rule -- the amusingly named ``ASYNC101`` rule in `flake8-async `__ -- which warns against yielding inside know cancel scopes. Could user education be sufficient to avoid @@ -227,6 +225,11 @@ multiple implementations of the websocket protocol: async for message in get_messages(ws): ... + +.. [#redirected] via e.g. ``contextlib.[async]contextmanager``, + or moral equivalents such as ``@pytest.fixture`` + + Restating the problem ===================== @@ -270,8 +273,8 @@ We propose: .. [#also-sync] Note that this blocks yields in both sync and async generators, so that - downstream frameworks can define sync cancel scope countexts such as - :py:func:`trio.fail_after`. + downstream frameworks can safely define sync cancel scope countexts such as + :py:func:`trio:trio.fail_after`. Implementation -------------- @@ -440,15 +443,15 @@ group, we expect a clear exception message and documentation to be sufficient. async generator, [it is an error to ``yield`` inside this context manager]." with a hyperlink to the explanation above. -.. [#exp-report] see `experience report - `__ - For asyncio, Trio, curio, or other-framework maintainers who implement cancel scope semantics, we will ensure that the documentation of ``sys.block_yields`` gives a full explanation distilled from the solution and implementation sections of this PEP. We anticipate consulting most such maintainers for their feedback on the draft PEP. +.. [#exp-report] see `Zac's experience report here + `__ + Rejected alternatives ===================== From 3b201470a377e058bacfa831cba3c9943c081af4 Mon Sep 17 00:00:00 2001 From: Zac Hatfield-Dodds Date: Wed, 15 May 2024 11:51:46 -0400 Subject: [PATCH 06/17] PEP 789: move codeowners entry --- .github/CODEOWNERS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 15fc5bd4903..f574043e194 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -624,10 +624,11 @@ peps/pep-0742.rst @JelleZijlstra peps/pep-0743.rst @vstinner peps/pep-0744.rst @brandtbucher peps/pep-0745.rst @hugovk -peps/pep-0789.rst @njsmith # ... # peps/pep-0754.rst # ... +peps/pep-0789.rst @njsmith +# ... peps/pep-0801.rst @warsaw # ... peps/pep-3000.rst @gvanrossum From d40352a35e56d2d230d0c0d0e37c6c0cfe179e70 Mon Sep 17 00:00:00 2001 From: Zac Hatfield-Dodds Date: Wed, 15 May 2024 13:56:44 -0400 Subject: [PATCH 07/17] PEP 789: "block" -> "prevent" because the term "block" is overloaded in this context. --- peps/pep-0789.rst | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/peps/pep-0789.rst b/peps/pep-0789.rst index 26427ffb5c0..15f09b1de29 100644 --- a/peps/pep-0789.rst +++ b/peps/pep-0789.rst @@ -21,11 +21,11 @@ context (a "cancel scope") corrupts this structure, resulting in situations wher the wrong task is canceled, timeouts are not respected, and exceptions are not properly propagated or handled. -To address this issue, this PEP proposes a new ``sys.block_yields()`` context +To address this issue, this PEP proposes a new ``sys.prevent_yields()`` context manager. When syntactically inside this context, attempting to ``yield`` will raise a RuntimeError, preventing the task from yielding. Additionally, a mechanism will be provided for decorators such as ``@contextmanager`` to allow -yields inside the decorated function. ``sys.block_yields()`` will be used by +yields inside the decorated function. ``sys.prevent_yields()`` will be used by asyncio and downstream libraries to implement task groups, timeouts, and cancellation; and by ``contextlib`` etc. to convert generators into context managers which allow safe yields. @@ -256,10 +256,10 @@ Specification We propose: -1. a new context manager, ``with sys.block_yields(reason): ...`` which will +1. a new context manager, ``with sys.prevent_yields(reason): ...`` which will raise a RuntimeError if you attempt to yield while inside it. [#also-sync]_ Cancel-scope-like context managers in asyncio and downstream code can then - wrap this to block yielding across *their* contexts. + wrap this to prevent yielding inside *their* with-block. 2. a mechanism by which generator-to-context-manager decorators can allow yields across one call. We're not yet sure what this should look like; the leading @@ -272,14 +272,14 @@ We propose: functions .. [#also-sync] - Note that this blocks yields in both sync and async generators, so that + Note that this prevents yields in both sync and async generators, so that downstream frameworks can safely define sync cancel scope countexts such as :py:func:`trio:trio.fail_after`. Implementation -------------- -The new ``sys.block_yields`` context manager will require interpreter support. +The new ``sys.prevent_yields`` context manager will require interpreter support. For each frame, we track the entries and exits of this context manager. We're not particularly attached to the exact representation; we'll discuss it as @@ -310,7 +310,7 @@ No-yield example - enter frame - use context manager - - which calls ``__enter__``, which calls ``sys.block_yields(reason).__enter__``, + - which calls ``__enter__``, which calls ``sys.prevent_yields(reason).__enter__``, so there are multiple rounds of the stack merging as this unwinds, to get the reason attached to the original frame - then ``__exit__`` repeats that process, ending with the corresponding exit @@ -357,22 +357,22 @@ Allowing yield for context managers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *TODO: this section is a placeholder, pending a decision on the mechanism for -``@contextmanager`` to unblock yields.* +``@contextmanager`` to re-enable yields in the wrapped function.* - Explain and show a code sample of how ``@asynccontextmanager`` sets the flag - also show a third-party case such as ``@pytest.fixture`` to demonstrate that we can't just have the interpreter special-case contextlib. -Behavior if ``sys.block_yields`` is misused -------------------------------------------- +Behavior if ``sys.prevent_yields`` is misused +--------------------------------------------- -While unwise, it's possible to call ``sys.block_yields.__enter__`` and +While unwise, it's possible to call ``sys.prevent_yields.__enter__`` and ``.__exit__`` in an order that does not correspond to any valid nesting, or get an invalid frame state in some other way. -There are two ways ``sys.block_yields.__exit__`` could detect an invalid state. -First, if yields are not blocked, we can simply raise an exception without +There are two ways ``sys.prevent_yields.__exit__`` could detect an invalid state. +First, if yields are not prevented, we can simply raise an exception without changing the state. Second, if an unexpected entry is at the top of the stack, we suggest popping that entry and raising an exception -- this ensures that out-of-order calls will still clear the stack, while still making it clear that @@ -386,7 +386,7 @@ question will not arise) Anticipated uses ================ -In the standard library, ``sys.block_yields`` could be used by +In the standard library, ``sys.prevent_yields`` could be used by ``asyncio.TaskGroup``, ``asycio.timeout``, and ``asyncio.timeout_at``. Downstream, we expect to use it in ``trio.CancelScope``, async fixtures (in pytest-trio, anyio, etc.), and perhaps other places. @@ -402,11 +402,11 @@ The generator-to-context-manager support would be used by Backwards Compatibility ======================= -The addition of the ``sys.block_yields`` context manager, changes to +The addition of the ``sys.prevent_yields`` context manager, changes to ``@contextlib.(async)contextmanager``, and corresponding interpreter support are all fully backwards-compatible. -Blocking yields from ``asyncio.TaskGroup``, ``asycio.timeout``, and +Preventing yields inside ``asyncio.TaskGroup``, ``asycio.timeout``, and ``asyncio.timeout_at`` would be a breaking change to at least some code in the wild, which (however unsafe and prone to the motivating problems above) may work often enough to make it into production. @@ -439,13 +439,13 @@ group, we expect a clear exception message and documentation to be sufficient. problems described in :pep:`533`, which this proposal does not address. - In the docs for each context manager which wraps a cancel scope, and thus now - ``sys.block_yields``, include a standard sentence such as "If used within an + ``sys.prevent_yields``, include a standard sentence such as "If used within an async generator, [it is an error to ``yield`` inside this context manager]." with a hyperlink to the explanation above. For asyncio, Trio, curio, or other-framework maintainers who implement cancel scope semantics, we will ensure that the documentation of -``sys.block_yields`` gives a full explanation distilled from the solution and +``sys.prevent_yields`` gives a full explanation distilled from the solution and implementation sections of this PEP. We anticipate consulting most such maintainers for their feedback on the draft PEP. From 4e0efc052f5fef27b6308939635cdb504f6b3877 Mon Sep 17 00:00:00 2001 From: Zac Hatfield-Dodds Date: Wed, 15 May 2024 16:34:24 -0400 Subject: [PATCH 08/17] PEP 789: maybe just deprecate asyncgens? --- peps/pep-0789.rst | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/peps/pep-0789.rst b/peps/pep-0789.rst index 15f09b1de29..5542347a11f 100644 --- a/peps/pep-0789.rst +++ b/peps/pep-0789.rst @@ -83,7 +83,7 @@ straightforward ``async for`` loop: try: while True: with timeout(max_time): - yield anext(ait) + yield await anext(ait) except StopAsyncIteration: return @@ -105,7 +105,7 @@ then yield *outside* that context. try: while True: with timeout(max_time): - tmp = anext(ait) + tmp = await anext(ait) yield tmp except StopAsyncIteration: return @@ -449,9 +449,6 @@ cancel scope semantics, we will ensure that the documentation of implementation sections of this PEP. We anticipate consulting most such maintainers for their feedback on the draft PEP. -.. [#exp-report] see `Zac's experience report here - `__ - Rejected alternatives ===================== @@ -471,6 +468,32 @@ relate to this proposal, and to PEP 533 and PEP 568, then see `this comment `__. +Deprecate async generators entirely +----------------------------------- + +At the 2024 language summit, several attendees suggested instead deprecating async +generators *in toto.* I'm not opposed to that [#exp-report]_ -- it's a reasonable +alternative to this PEP, albeit with enormous backwards-compatibilty costs. +Two library features that I think would be important in this scenario are: + +1. Ergonomic async iterables in the standard library. This could be addressed by + adding ``__aiter__`` to ``asyncio.Queue``, and a ``close()`` method to allow + for finite iteration. This would almost exactly match Trio's SendChannel / + ReceiveChannel interface, which has been working well in production for years. + +2. An alternative convenient syntax to define async context managers with an + ``@asynccontextmanager`` decorator. I think we could make this work by + injecting a magic awaitable as a positional-only first argument, but haven't + prototyped that yet. + +Both of these could be prototyped in asyncio-compatible downstream libraries +such as ``anyio``, and later considered for inclusion in the standard library. + + +.. [#exp-report] see `Zac's experience report here + `__ + + Copyright ========= From 69cf57a5c6ea1d1fe7dc2cfa4cb8b5fc5f8c6a07 Mon Sep 17 00:00:00 2001 From: Zac Hatfield-Dodds Date: Mon, 20 May 2024 02:54:24 -0400 Subject: [PATCH 09/17] PEP 789: why to keep async gens --- peps/pep-0789.rst | 78 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 10 deletions(-) diff --git a/peps/pep-0789.rst b/peps/pep-0789.rst index 5542347a11f..8d233cf4033 100644 --- a/peps/pep-0789.rst +++ b/peps/pep-0789.rst @@ -472,23 +472,81 @@ Deprecate async generators entirely ----------------------------------- At the 2024 language summit, several attendees suggested instead deprecating async -generators *in toto.* I'm not opposed to that [#exp-report]_ -- it's a reasonable -alternative to this PEP, albeit with enormous backwards-compatibilty costs. -Two library features that I think would be important in this scenario are: +generators *in toto.* Unfortunately, while the common-in-practice cases all use +async generators, Trio code can trigger the same problem with standard generators: -1. Ergonomic async iterables in the standard library. This could be addressed by - adding ``__aiter__`` to ``asyncio.Queue``, and a ``close()`` method to allow - for finite iteration. This would almost exactly match Trio's SendChannel / - ReceiveChannel interface, which has been working well in production for years. +.. code-block:: python + + # We use Trio for this example, because while `asyncio.timeout()` is async, + # Trio's CancelScope type and timeout context managers are synchronous. + import trio + + def abandon_each_iteration_after(max_seconds): + # This is of course broken, but I can imagine someone trying it... + while True: + with trio.move_on_after(max_seconds): + yield + + @trio.run + async def main(): + for _ in abandon_each_iteration_after(max_seconds=1): + await trio.sleep(3) + +If it wasn't for the bug in question, this code would look pretty idiomatic - +but after about a second, instead of moving on to the next iteration it raises: + +.. code-block:: pycon + + Traceback (most recent call last): + File "demo.py", line 10, in + async def main(): + File "trio/_core/_run.py", line 2297, in run + raise runner.main_task_outcome.error + File "demo.py", line 12, in main + await trio.sleep(3) + File "trio/_timeouts.py", line 87, in sleep + await sleep_until(trio.current_time() + seconds) + ... + File "trio/_core/_run.py", line 1450, in raise_cancel + raise Cancelled._create() + trio.Cancelled: Cancelled + +Furthermore, there are some non-cancel-scope synchronous context managers which +exhibit related problems, such as the abovementioned ``decimal.localcontext``. +While fixing the example below is not a goal of this PEP, it demonstrates that +yield-within-with problems are not exclusive to async generators: + +.. code-block:: python + + import decimal + + def why_would_you_do_this(): + with decimal.localcontext(decimal.Context(prec=1)): + yield + + one = decimal.Decimal(1) + x = one / 3 + next(gen := why_would_you_do_this()) + y = one / 3 + print(x) # 0.3333333333333333333333333333 + print(y) # 0.3 + + +While I've had good experiences in async Python without async generators +[#exp-report]_, I'd prefer to fix the problem than remove them from the +language. However, if the Steering Council decided that reducing the frequency +of the problem was worth the compatibility costs of removing async generators, +I'd suggest two library features to partially replace them: + +1. Ergonomic async iterables in the standard library. These would be nice + regardless, so `I've proposed `__ + adding ``__aiter__`` to ``asyncio.Queue``. 2. An alternative convenient syntax to define async context managers with an ``@asynccontextmanager`` decorator. I think we could make this work by injecting a magic awaitable as a positional-only first argument, but haven't prototyped that yet. -Both of these could be prototyped in asyncio-compatible downstream libraries -such as ``anyio``, and later considered for inclusion in the standard library. - .. [#exp-report] see `Zac's experience report here `__ From 41b268433bbb662d539314513fd37cdd5f172c6d Mon Sep 17 00:00:00 2001 From: Zac Hatfield-Dodds Date: Mon, 20 May 2024 02:55:06 -0400 Subject: [PATCH 10/17] PEP 789: add corrected code sample --- peps/pep-0789.rst | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/peps/pep-0789.rst b/peps/pep-0789.rst index 8d233cf4033..b72a792ee64 100644 --- a/peps/pep-0789.rst +++ b/peps/pep-0789.rst @@ -195,6 +195,38 @@ was intended for the sibling task was instead injected into the *outer* task, and so we never got a chance to create and raise an ``ExceptionGroup(..., [RuntimeError()])``. +To fix this, we need to turn our async generator into an async context manager, +which yields an async iterable - in this case a generator wrapping the queue; in +future `perhaps the queue itself +`__: + +.. code-block:: python + + async def queue_as_aiterable(queue): + # async generators that don't `yield` inside a cancel scope are fine! + while True: + try: + item = await queue.get() + except asyncio.QueueShutDown: + return + yield item + queue.task_done() + + @asynccontextmanager # yield-in-cancel-scope is OK in a context manager + async def combined_iterators(*aits): + q = asyncio.Queue(maxsize=2) + async with asyncio.TaskGroup() as tg: + for ait in aits: + tg.create_task(move_elements_to_queue(ait, q)) + yield queue_as_aiterable(q) + + async def turn_on_lights_when_someone_gets_home(): + ... + async with combined_iterators(...) as ait: + async for event in ait: + ... + + In a user-defined context manager --------------------------------- From 76423d2bfdfd0f22a44c0fad3a3f57e2f44ddf51 Mon Sep 17 00:00:00 2001 From: Zac Hatfield-Dodds Date: Mon, 20 May 2024 03:32:07 -0400 Subject: [PATCH 11/17] PEP 789: can't just deliver exceptions --- peps/pep-0789.rst | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/peps/pep-0789.rst b/peps/pep-0789.rst index b72a792ee64..fd57888cbb0 100644 --- a/peps/pep-0789.rst +++ b/peps/pep-0789.rst @@ -46,7 +46,7 @@ within that context (...scope). In asyncio, this is implicit in the design of respectively cancel the contained work after the specified duration, or cancel sibling tasks when one of them raises an exception. The core functionality of a cancel scope is synchronous, but the user-facing context managers may be -either sync or async. [#trio-cancel-scope]_ +either sync or async. [#trio-cancel-scope]_ [#tg-cs]_ This structured approach works beautifully, unless you hit one specific sharp edge: breaking the nesting structure by ``yield``\ ing inside a cancel scope. @@ -69,6 +69,11 @@ Let's consider three examples, to see what this might look like in practice. here, but say "cancel scope" when referring to the framework-independent concept. +.. [#tg-cs] + A ``TaskGroup`` is not _only_ a cancel scope, but preventing yields would + resolve their further problem too. See :ref:`just-deliver`. + + Leaking a timeout to the outer scope ------------------------------------ @@ -490,9 +495,6 @@ cancellations are eventually directed to the correct scope, but only after they had wreaked havoc elsewhere. Plausibly still useful to ensure that cleanup is *timely*, but does not solve this problem. -:pep:`568` - would make it possible to work around some bugs which this PEP -makes impossible. We recommend marking it as rejected. - If you want more details on all the specific problems that arise, and how they relate to this proposal, and to PEP 533 and PEP 568, then see `this comment `__ and @@ -584,6 +586,38 @@ I'd suggest two library features to partially replace them: `__ +.. _just-deliver: + +Can't we just deliver exceptions to the _right_ place? +------------------------------------------------------ + +If we implemented :pep:`568` (Generator-sensitivity for Context Variables; see +also :pep:`550`), it would be possible to handle exceptions from timeouts: the +event loop could avoid firing a ``CancelledError`` until the generator frame +which contains the context manager is on the stack - either when the generator +is resumed, or when it is finalized. + +This can take arbitrarily long; even if we implemented :pep:`533` to ensure +timely cleanup on exiting (async) for-loops it's still possible to drive a +generator manually with next/send. + +However, this doesn't address the other problem with ``TaskGroup``. The model +for generators is that you put a stack frame in suspended animation and can then +treat it as an inert value which can be stored, moved around, and maybe +discarded or revived in some arbitrary place. The model for structured +concurrency is that your stack becomes a tree, with child tasks encapsulated +within some parent frame. They're extending the basic structured programming +model in different, and unfortunately incompatible, directions. + +Note that ``TaskGroup`` *would* play nicely with generators if suspending the +frame with the context manager also suspended all child tasks. Note also that +this would cause all of our motivating examples to deadlock, as we wait for +values to be produced by suspended child tasks - a prohibitive design problem. + +We don't think it's worth adding this much machinery to handle cancel scopes, +while leaving task groups (and no-exception cases) broken. + + Copyright ========= From 667387b4809f16fb08c47b3ab42bddbd3922a985 Mon Sep 17 00:00:00 2001 From: Zac Hatfield-Dodds Date: Mon, 20 May 2024 12:27:24 -0400 Subject: [PATCH 12/17] PEP 789: bytecode inspection? --- peps/pep-0789.rst | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/peps/pep-0789.rst b/peps/pep-0789.rst index fd57888cbb0..fb81d80cd80 100644 --- a/peps/pep-0789.rst +++ b/peps/pep-0789.rst @@ -313,8 +313,8 @@ We propose: downstream frameworks can safely define sync cancel scope countexts such as :py:func:`trio:trio.fail_after`. -Implementation --------------- +Implementation - tracking frames +-------------------------------- The new ``sys.prevent_yields`` context manager will require interpreter support. For each frame, we track the entries and exits of this context manager. @@ -336,6 +336,9 @@ Because this is about yielding frames *within* a task, not switching between tasks, syntactic ``yield`` and ``yield from`` should be affected, but ``await`` expressions should not. +We can reduce the overhead by storing this metadata in a single stack per thread +for all stack frames which are not generators. + Worked examples --------------- @@ -401,6 +404,23 @@ Allowing yield for context managers we can't just have the interpreter special-case contextlib. +Alternative implementation - inspecting bytecode +------------------------------------------------ + +Jelle Zijlstra has `sketched an alternative`_, where ``sys.prevent_yields`` +inspects the bytecode of callers until satisfied that there is no yield +between the calling instruction pointer and the next context exit. +It's not yet clear how this would work when user-defined context managers +wrap ``sys.prevent_yields``. + +If implemented outside CPython, we'd expect challenges from the performance +impact of de-optimization, as well as ongoing maintainence costs as the CPython +bytecode continues to evolve. As for tracking frames, we would also need an +entirely different solution for other Python implemetations such as PyPy. + +.. _sketched an alternative: https://gist.github.com/JelleZijlstra/a53b17417c5189b487316628acc5555f + + Behavior if ``sys.prevent_yields`` is misused --------------------------------------------- From d7674beb4bb907aa206eec9b0515d3998444089f Mon Sep 17 00:00:00 2001 From: Zac Hatfield-Dodds Date: Sun, 26 May 2024 23:58:23 -0700 Subject: [PATCH 13/17] PEP 789: various small updates --- peps/pep-0789.rst | 183 ++++++++++++++++++++++++++-------------------- 1 file changed, 102 insertions(+), 81 deletions(-) diff --git a/peps/pep-0789.rst b/peps/pep-0789.rst index fb81d80cd80..a84b92c0d04 100644 --- a/peps/pep-0789.rst +++ b/peps/pep-0789.rst @@ -17,22 +17,23 @@ Abstract the ``asyncio.TaskGroup`` and ``asyncio.timeout`` context managers support compositional reasoning, and allow developers to clearly scope the lifetimes of concurrent tasks. However, using ``yield`` to suspend a frame inside such a -context (a "cancel scope") corrupts this structure, resulting in situations where -the wrong task is canceled, timeouts are not respected, and exceptions are not -properly propagated or handled. +context leads to situations where the wrong task is canceled, timeouts are +ignored, and exceptions are mishandled. More fundamentally, suspending a frame +inside a ``TaskGroup`` violates the structured concurrency design principle that +child tasks are encapsulated within their parent frame. -To address this issue, this PEP proposes a new ``sys.prevent_yields()`` context +To address these issues, this PEP proposes a new ``sys.prevent_yields()`` context manager. When syntactically inside this context, attempting to ``yield`` will raise a RuntimeError, preventing the task from yielding. Additionally, a mechanism will be provided for decorators such as ``@contextmanager`` to allow yields inside the decorated function. ``sys.prevent_yields()`` will be used by asyncio and downstream libraries to implement task groups, timeouts, and -cancellation; and by ``contextlib`` etc. to convert generators into context -managers which allow safe yields. +cancellation; and a related mechanism by ``contextlib`` etc. to convert +generators into context managers which allow safe yields. .. _Structured concurrency: https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/ -Motivation +Background ========== Structured concurrency is increasingly popular in Python, in the form of newer @@ -59,8 +60,6 @@ cross-function ``goto``\ s, and the effects are truly dire: - Exceptions can go missing entirely, being dropped instead of added to an ``ExceptionGroup`` -Let's consider three examples, to see what this might look like in practice. - .. [#trio-cancel-scope] While cancel scopes are implicit in asyncio, the analogous :py:func:`trio:trio.fail_after` (sync) and :py:func:`trio:trio.open_nursery` @@ -74,6 +73,35 @@ Let's consider three examples, to see what this might look like in practice. resolve their further problem too. See :ref:`just-deliver`. +Problem statement +================= + +Here's the fundamental issue: yield suspends a call frame. It only makes sense +to yield in a leaf frame -- i.e., if your call stack goes like A -> B -> C, then +you can suspend C, but you can't suspend B while leaving C running. + +But, TaskGroup is a kind of "concurrent call" primitive, where a single frame +can have multiple child frames that run concurrently. This means that if we +allow people to mix yield and TaskGroup, then we can end up in exactly this +situation, where B gets suspended but C is actively running. This is +nonsensical, and causes serious practical problems (e.g., if C raises an +exception and A has returned, we have no way to propagate it). + +This is a fundamental incompatibility between generator control flow and +structured concurrency control flow, not something we can fix by tweaking our +APIs. The only solution seems to be to forbid yield inside a TaskGroup. + +Although timeouts don't leave a child task running, the close analogy and +related problems lead us to conclude that yield should be forbidden inside all +cancel scopes, not only TaskGroups. See :ref:`just-deliver` for discussion. + + +Motivating examples +=================== + +Let's consider three examples, to see what this might look like in practice. + + Leaking a timeout to the outer scope ------------------------------------ @@ -211,11 +239,9 @@ future `perhaps the queue itself # async generators that don't `yield` inside a cancel scope are fine! while True: try: - item = await queue.get() + yield await queue.get() except asyncio.QueueShutDown: return - yield item - queue.task_done() @asynccontextmanager # yield-in-cancel-scope is OK in a context manager async def combined_iterators(*aits): @@ -236,14 +262,14 @@ In a user-defined context manager --------------------------------- Yielding inside a cancel scope can be safe, if and only if you're using the -generator to implement a context manager - in this case any propagating -exceptions will be redirected to the expected task. [#redirected]_ +generator to implement a context manager [#redirected]_ - in this case any +propagating exceptions will be redirected to the expected task. -We've also implemented a lint rule -- the amusingly named ``ASYNC101`` rule in -`flake8-async `__ -- which warns against -yielding inside know cancel scopes. Could user education be sufficient to avoid -these problems? Unfortunately not: user-defined context managers can also wrap -a cancel scope, and it's infeasible to recognize or lint for all such cases. +We've also implemented the ``ASYNC101`` linter rule in `flake8-async +`__, which warns against yielding in +known cancel scopes. Could user education be sufficient to avoid these +problems? Unfortunately not: user-defined context managers can also wrap a +cancel scope, and it's infeasible to recognize or lint for all such cases. This regularly arises in practice, because 'run some background tasks for the duration of this context' is a very common pattern in structured concurrency. @@ -267,31 +293,10 @@ multiple implementations of the websocket protocol: or moral equivalents such as ``@pytest.fixture`` -Restating the problem -===================== - -Here's the fundamental issue: yield suspends a call frame. It only makes sense -to yield in a leaf frame -- i.e., if your call stack goes like A -> B -> C, then -you can suspend C, but you can't suspend B while leaving C running. - -But, TaskGroup is a kind of "concurrent call" primitive, where a single frame -can have multiple child frames that run concurrently. This means that if we -allow people to mix yield and TaskGroup, then we can end up in exactly this -situation, where B gets suspended but C is actively running. This is -nonsensical, and causes serious practical problems (e.g., if C raises an -exception, we have no way to propagate it). - -This is a fundamental incompatibility between generator control flow and -structured concurrency control flow, not something we can fix by tweaking our -APIs. The only solution seems to be to forbid yield inside a TaskGroup. -Although timeouts don't leave a child task running, the close analogy and -related problems lead us to conclude that yield should be forbidden inside all -cancel scopes, not only TaskGroups. - Specification ============= -We propose: +To prevent these problems, we propose: 1. a new context manager, ``with sys.prevent_yields(reason): ...`` which will raise a RuntimeError if you attempt to yield while inside it. [#also-sync]_ @@ -400,25 +405,9 @@ Allowing yield for context managers ``@contextmanager`` to re-enable yields in the wrapped function.* - Explain and show a code sample of how ``@asynccontextmanager`` sets the flag -- also show a third-party case such as ``@pytest.fixture`` to demonstrate that - we can't just have the interpreter special-case contextlib. - -Alternative implementation - inspecting bytecode ------------------------------------------------- - -Jelle Zijlstra has `sketched an alternative`_, where ``sys.prevent_yields`` -inspects the bytecode of callers until satisfied that there is no yield -between the calling instruction pointer and the next context exit. -It's not yet clear how this would work when user-defined context managers -wrap ``sys.prevent_yields``. - -If implemented outside CPython, we'd expect challenges from the performance -impact of de-optimization, as well as ongoing maintainence costs as the CPython -bytecode continues to evolve. As for tracking frames, we would also need an -entirely different solution for other Python implemetations such as PyPy. - -.. _sketched an alternative: https://gist.github.com/JelleZijlstra/a53b17417c5189b487316628acc5555f +Note that third-party decorators such as ``@pytest.fixture`` demonstrate that +we can't just have the interpreter special-case contextlib. Behavior if ``sys.prevent_yields`` is misused @@ -470,10 +459,29 @@ often enough to make it into production. We will seek community feedback on appropriate deprecation pathways for standard-library code, including the suggested length of any deprecation period. +As an initial suggestion, we could make suspending stdlib contexts emit a +DeprecationWarning only under asyncio debug mode in 3.14; then transition to +warn-by-default and error under debug mode in 3.15; and finally a hard error in +3.16. + Irrespective of stdlib usage, downstream frameworks would adopt this functionality immediately. +How widespread is this bug? +--------------------------- + +We don't have solid numbers here, but believe that many projects are affected +in the wild. After one moderate and one critical bug attributed to suspending +a cancel scope at work, Zac developed tooling to enforce a company-wide ban +on async generators. When describing this PEP at PyCon, three attendees +recognized the symptoms and concluded that they had likely been affected. + +*TODO: run the ASYNC101 lint rule across ecosystem projects, e.g. the aio-libs +packages, and get some sense of frequency in widely-used PyPI packages? +This would help inform the break/deprecation pathways for stdlib code.* + + How to Teach This ================= @@ -510,16 +518,19 @@ maintainers for their feedback on the draft PEP. Rejected alternatives ===================== -:pep:`533` - deterministic cleanup for iterators would ensure that misfired -cancellations are eventually directed to the correct scope, but only after they -had wreaked havoc elsewhere. Plausibly still useful to ensure that cleanup is -*timely*, but does not solve this problem. +PEP 533, deterministic cleanup for iterators +----------------------------------------------- +:pep:`533` proposes adding ``__(a)iterclose__`` to the iterator protocol, +essentially wrapping a ``with (a)closing(ait)`` around each (async) for loop. +While this would be useful for ensuring timely and deterministic cleanup of +resources held by iterators, the problem it aims to solve, it does not fully +address the issues that motivate PEP 789. -If you want more details on all the specific problems that arise, and how they -relate to this proposal, and to PEP 533 and PEP 568, then see `this comment -`__ and -`this Discuss thread -`__. +Even with PEP 533, misfired cancellations would still be delivered to the wrong +task and could wreak havoc before the iterator is closed. Moreover, it does not +address the fundamental structured concurrency problem with ``TaskGroup``, where +suspending a frame that owns a TaskGroup is incompatible with the model of child +tasks being fully encapsulated within their parent frame. Deprecate async generators entirely @@ -588,19 +599,7 @@ yield-within-with problems are not exclusive to async generators: While I've had good experiences in async Python without async generators [#exp-report]_, I'd prefer to fix the problem than remove them from the -language. However, if the Steering Council decided that reducing the frequency -of the problem was worth the compatibility costs of removing async generators, -I'd suggest two library features to partially replace them: - -1. Ergonomic async iterables in the standard library. These would be nice - regardless, so `I've proposed `__ - adding ``__aiter__`` to ``asyncio.Queue``. - -2. An alternative convenient syntax to define async context managers with an - ``@asynccontextmanager`` decorator. I think we could make this work by - injecting a magic awaitable as a positional-only first argument, but haven't - prototyped that yet. - +language. .. [#exp-report] see `Zac's experience report here `__ @@ -638,6 +637,28 @@ We don't think it's worth adding this much machinery to handle cancel scopes, while leaving task groups (and no-exception cases) broken. +Alternative implementation - inspecting bytecode +------------------------------------------------ + +Jelle Zijlstra has `sketched an alternative`_, where ``sys.prevent_yields`` +inspects the bytecode of callers until satisfied that there is no yield between +the calling instruction pointer and the next context exit. We expect that +support for syntatically-nested context managers could be added fairly easily. + +However, it's not yet clear how this would work when user-defined context +managers wrap ``sys.prevent_yields``. Worse, this approach ignores explicit +calls to ``__enter__()`` and ``__exit__()``, meaning that the context management +protocol would vary depending on whether the ``with`` statement was used. + +The 'only pay if you use it' performance cost is very attractive. However, +inspecting frame objects is prohibitively expensive for core control-flow +constructs, and causes whole-program slowdowns via de-optimization. +On the other hand, adding interpreter support for better performance leads +back to the same pay-regardless semantics as our preferred solution above. + +.. _sketched an alternative: https://gist.github.com/JelleZijlstra/a53b17417c5189b487316628acc5555f + + Copyright ========= From f8d6b8c8ce5d10b2ef33b34c23d66931342afb0f Mon Sep 17 00:00:00 2001 From: Zac Hatfield-Dodds Date: Mon, 27 May 2024 00:01:05 -0700 Subject: [PATCH 14/17] PEP 789: mermaid diagrams For expedience I'm using sphinxcontrib-mermaid here; we can easily embed .png versions before merging if preferred. --- peps/pep-0789.rst | 135 +++++++++++++++++++------ peps/pep-789-example-no-yield.png | Bin 0 -> 79002 bytes peps/pep-789-example-yield-allowed.png | Bin 0 -> 84865 bytes peps/pep-789-example-yield-errors.png | Bin 0 -> 67683 bytes 4 files changed, 105 insertions(+), 30 deletions(-) create mode 100644 peps/pep-789-example-no-yield.png create mode 100644 peps/pep-789-example-yield-allowed.png create mode 100644 peps/pep-789-example-yield-errors.png diff --git a/peps/pep-0789.rst b/peps/pep-0789.rst index a84b92c0d04..8bb78ee9a2f 100644 --- a/peps/pep-0789.rst +++ b/peps/pep-0789.rst @@ -347,55 +347,130 @@ for all stack frames which are not generators. Worked examples --------------- -*TODO: it'd be great to have diagrams for these examples* - No-yield example ~~~~~~~~~~~~~~~~ -- enter frame -- use context manager - - - which calls ``__enter__``, which calls ``sys.prevent_yields(reason).__enter__``, - so there are multiple rounds of the stack merging as this unwinds, to get the - reason attached to the original frame - - then ``__exit__`` repeats that process, ending with the corresponding exit - on the stack. - -- leave frame. Entries and exits are balanced, so they don't propagate any further. +In this example, we see multiple rounds of the stack merging as we unwind from +``sys.prevent_yields``, through the user-defined ContextManager, back to the +original Frame. For brevity, the reason for preventing yields is not shown; +it is part of the "1 enter" state. + +.. image:: pep-789-example-no-yield.png + :width: 600 px + :align: center + +.. + sequenceDiagram + participant Frame + create participant ContextManager + + Frame->>ContextManager: __enter__() + create participant sys.prevent_yields + ContextManager->>sys.prevent_yields: __enter__() + Note over sys.prevent_yields: 1 enter, 0 exits + sys.prevent_yields-->>ContextManager: ; + Note over ContextManager: 1 enter, 0 exits + ContextManager-->>Frame: ; + + Note over Frame: 1 enter, 0 exits + Note over Frame: Code execution
(no yield) + + Frame->>ContextManager: __exit__() + ContextManager->>sys.prevent_yields: __exit__() + Note over sys.prevent_yields: 0 enters, 1 exit + destroy sys.prevent_yields + sys.prevent_yields-->>ContextManager: ; + Note over ContextManager: 0 enters, 1 exit + destroy ContextManager + ContextManager-->>Frame: ; + Note over Frame: Entry/exit stack is balanced + +With no ``yield`` we don't raise any errors, and because the number of enters +and exits balance the frame returns as usual with no further tracking. Attempts-to-yield example ~~~~~~~~~~~~~~~~~~~~~~~~~ -- enter frame -- use context manager +In this example, the Frame attempts to ``yield`` while inside the +``sys.prevent_yields`` context. This is detected by the interpreter, +which raises a ``RuntimeError`` instead of suspending the frame. + +.. image:: pep-789-example-yield-errors.png + :width: 500 px + :align: center + +.. + sequenceDiagram + participant Frame + create participant sys.prevent_yields + Frame->>sys.prevent_yields: __enter__() + Note over sys.prevent_yields: 1 enter, 0 exits + sys.prevent_yields-->>Frame: ; + + Note over Frame: 1 enter, 0 exits + + Frame->>Frame: attempted yield + Note over Frame: allow_yield flag not set,
so raise RuntimeError - - which calls ``__enter__``, which ... as above - - ``yield``: interpreter observes that ``frame.allow_yield_flag`` is not set, - and raises a RuntimeError. - - then ``__exit__``, as above + Frame->>sys.prevent_yields: __exit__() + Note over sys.prevent_yields: 0 enters, 1 exit + destroy sys.prevent_yields + sys.prevent_yields-->>Frame: ; -- leave frame with an exception active, but still a balanced entry/exit stack + Note over Frame: Entry/exit stack is balanced + Note over Frame: Frame exits with exception Allowed-to-yield example ~~~~~~~~~~~~~~~~~~~~~~~~ -- enter frame, which a decorator has marked as allowing yields. -- use context manager +In this example, a decorator has marked the Frame as allowing yields. This +could be ``@contextlib.contextmanager`` or a related decorator. + +.. image:: pep-789-example-yield-allowed.png + :width: 600 px + :align: center + +.. + sequenceDiagram + participant ParentFrame + create participant Frame + + ParentFrame ->> Frame: call + enter context + Note over Frame: frame.allow_yield_flag is set + + create participant sys.prevent_yields + Frame->>sys.prevent_yields: __enter__() + Note over sys.prevent_yields: 1 enter, 0 exits + sys.prevent_yields-->> Frame: ; + + Note over Frame: 1 enter, 0 exits + + Frame->>ParentFrame: yield, suspending frame
merge entry/exit stack + Note over ParentFrame: 1 enter, 0 exits + Note over ParentFrame: run arbitrary code + ParentFrame ->> Frame: resume frame
no change to stacks + Note over Frame: 0 enters, 0 exits - - which calls ``__enter__``, which ... as above - - ``yield`` -- this time it's allowed! + Frame->>sys.prevent_yields: __exit__() + Note over sys.prevent_yields: 0 enters, 1 exit + destroy sys.prevent_yields + sys.prevent_yields-->>Frame: ; + Note over Frame: 0 enters, 1 exit - - Our entry/exit stack is merged with the parent frame, adding one enter to - the parent stack, and this frame is suspended. - - This frame is resumed (possibly with an exception active; it's a context - manager after all). Our frame's stack is currently empty. + destroy Frame + Frame-->>ParentFrame: ; + Note over ParentFrame: Entry/exit stack is balanced - - then ``__exit__``, as above +When the Frame is allowed to yield, the entry/exit stack is merged into the +parent frame's stack before suspending. When the Frame resumes, its stack is +empty. Finally, when the Frame exits, the exit is merged into the parent +frame's stack, rebalancing it. -- leave frame, merging our exit into the parent frame's stack - (rebalancing that parent stack). +This ensures that the parent frame correctly inherits any remaining +``sys.prevent_yields`` state, while allowing the Frame to safely suspend +and resume. Allowing yield for context managers diff --git a/peps/pep-789-example-no-yield.png b/peps/pep-789-example-no-yield.png new file mode 100644 index 0000000000000000000000000000000000000000..b27a9350c07383b04f76572f9a31c7ecb0dd6ed1 GIT binary patch literal 79002 zcmd?RcT|(l+b4__1pyTS=^{-+Q>t_UDS~tY(v=ROhF$_l5v5C&u5?m}^iDveg$@Zw zMz;-RaeKvFiqv`W0WZYQrHPeM{2Pk#FD2J!y3 zo2roq2?=HU<xu6wG%dG5-KqTvb4DX&jlB3g7?Rz*pzZXQnZ`SvEpiX3b z24&_>V!Hr6kBIe>kURqIS^V=0OF%fWQsU?JfA(td>gL|DmEbeBSKsIs9?;xF7F_pW z3(2e~FHg+RjGdNVw{|uqC04}Z9d50s|0eY6MXc^?&rqigXKR~|D{^j9sWU1HPN7U@ z&dI{a%AJXC9+!q?aS69pG4C#zIPr|i)C4}5u&G! z)D3r?rMcKtPsRr@-QxgQAd8C4;ek%QBtpdYTuYLM7V)zeBxJ@yE#tPyD(Q1jGB&VM zG8w_Y)(gwvZ&(|hi{s@JQ{xtg6g)$qp<-S2FmCiZ>}&F3 z*T+n<8T?lZbw2m0$=BarzCjgQ7UN4TCqNf?f}oyD#lNa9%X5Es##SRuK`V zW>6xaVn0-_BWcg; z25(88=sIq`0jP5RNhC~^SVxEoGaEhCheF_?t&Cg#fxSG^e|HU|Re2z}lJ4Cu>SWC* zv$o;Arwu_~jR&a&#yk!yUaQ`nNS>N9o^=q&ar`@=lU?tr{p{JWrS|1&+xC6Lu^>lV z5W96Sguw=+tYMXoamCmS(V+0zbs3%fW6WnCXo+M)~bC3^lI9l6d6SCAS6%rK$J9z+) z&0mQ;v12G7z8w{>@tQ?!bH$0BQ7ZI}?K>+gP8D&+dcR*ilXaAr%~`+I)4d-$sJv$R z)@e8Xp#=H!UhIsf!QwxFjXtF0pCSK0hDCY+J#WoPg$m~@hZ`O~g#8TX!12xV8Tv>W z?d(yq2oXC-*8H$|i=m^Q11^J%5{iDs}bF4jW7CO7yf1cRqJ~wsoE4(Y1U3D)lt_liE-^irvP> ziaiY;S5c&NN41tXuu7&M6PugwCGSb~jKyWkkvv-1alS@E|76`V%i4x>nUC_i^*rUo z>=&NC!Pf>TGwOq_@l03@4mw4sTH6<0!?#_V>fw5Mz3XiH+=kIyMBz3H^p_0QGqKRd@9V|qDblojG>{;2}c z5FRTLp9LPXkD5YhmnD5ZB;1h(D^%@erW@}r@MOoo#^lq|vDfsCba#wFbqPE+9zF>v z^`@ICn37M~V*KaI!C4eKcO>X9%Mzj5{O`|h3LskNp$P6?s3nV`#MGBwjT-=Q{ow?! zV|-VB!(A3vflGfl5}$DAl1(pJghC)VDnMdv!xCHMurvfgtsLS_`V{qH=^hR*Do* zelliyIhX}${q|vg%-zX(KNe`1KY!(5kF2*TPihW}g_rG@LvAUtj-@I3gMK8=?YpM# zLiLIp(70D4J zW=sx0Xg|Q3O~&MLyfl-uP0E8}Hxnt&o2-VdoLVW+(HDaHuoCcKvd*XC-qM8Hr1eA- ziv`cWur|ERj{4aFG7XJ-qmIq($>+E*JND|YJwE>qQ%iv;$d(hz68YJCHx}126C1YbUtcKlToD|ahd~e+I&^{a?G+-&hG< zpR%Acwa7^eE-v&_Gg2~b15jpM=Y@iY1B)`~v`AaanfgBvv1J!eO# zulE9Bb{_JU##0+slQYCJRg5WdV(~lg;z>`qGcBbcL^3bmP*(dmB!;@ywN&;L*A$u) zWaippYC18kd*gX79VQSrfYB03cZz&wBQ8ezWB07#wD@aD-i9;|@A8Ga?8iCXDi zy`@xK>*_uo#Gk#_IAGyxj6@AvoDtsU&>;FyN2iS`*43l%g4u4lIO!x;ghb=EKmFh%`h= z;)Ge*R>e9{TghXhcPF=f7j+j=hlwcBetE+bnd7}GPqriXZKduFXG%AMFYZ9xxw*ze zOAvPK#0(xK1~KK<^5rQ z9OIVptk{)I0`#Guc@%q8h==+*)1yU4e{R@$K9l`%YyXqlYqML7>?{{5kQpoLg=Fhh z4_EF9Mx{Ck&neBr`^CPxmvD2FgpJ-e#4@(kw#QEiCJJ0TV8)j3X$S-XQwI6NI**I8 z=u5jj94CurVsqt=MqUER8)n{u;TOs;S0p&Oz{cFfcUbdXHrE#|j*MMjFAN<#Duon} zWAg*z87=S+fV9go>27G@W!$qyz;@Q@q}TA8xc~X0x)}|@vqjSUNG`Qw)KE-Jxqh@? zNq}<9GLDt_%IVw0SCSmb?quCdG^+~g3Nrf`Gmx-}F+Aes5YfCn?kzrGqCYqxg|-=W z*`SKj-A9nh+A(-*3RF}Gc^kRw!gbthk&Px=+n26(`c`Co>$OGQZ=WY093-r1Meq0E z70KdMry$S&bO$k0#cNW&_Zie{iD0r>b~A6J%+a^r7u}O;)Yr{7jP7oCXr_fUs6~c8 zF57R_q;-FDazSah-%RtT#iM5x#^ilaakgh+78BRJ8g6=zjZLlUR7jhvwnB4;Rj_3Q~=J?;L#MeZuGEFsuwwem%TTW#@qY zK92cn9^l0wq9qmjLuh<82~4ML#Lgi_Us#dF%-bJsS^DzjLpF(L^0FOd=o8w?x0g*5 zS0FY`Bv;KJg1@T4h*7i2rgS(P&jqzj(;W8}l`v3zDLtG7YEvFc(FX)vlNGd|$B1LA z{0)v=P0BjRTSjx{7bNK{y-_tgI)&o1qoF*C7%04%@@zj=HdjuI_q@VjIPCOwbaEGfQt^B@ z)Bw3@`Rgpz@)hpyB?IRzB9yv{VJy?r>ooW775~hn0BEvDlcl1I`82%^J3st9tJiK; zA%)KV)r10{!?JXn>8=Jdm6fT3SNoqKp=vo7Ei@CM|Dpc;M$wU|(cgnNSI&Of`u8G3 z!2w@%p8KaQd0!Z?H2as%j!xh*UKLeyaa=o$BLX?!gpUj)EJEIZN&is)y6ZeocqIL5 zT%r@0xs$EjSh4)LB!{b)4u(axirBk+Vmd~&A$S#R(4K(Zt;F> zxU3hD9~BMuH|cHkG{X8-M;8S*>Yb;)8tqg017)`m1NNrFyzrJ)^&E)r8tnS+BZtSl zPlU{@?u^u)4Dv|Nn*M#HbOh>6)WORJdUNaGLXXtI1#|wrn|EOvNrugxLK$E>`6cP;5pO(rh_Q|c5g5-iFp4>8M^ZA2 zIATg7pYX9_(wZ~vM|QKx1TdzGa#Kjf^Kwbn0?!s zmX+c|*(q4a(0=yg^%kiX-7_voLE%Lf@TZ2B)B%#xHAb&*GiCC~uH-RNqokd)7;uqqJ*J35LdZvaA zdi0nko_F&GQ#9)~mrR?jC$h%thn{&oeyUl1o3z??*(E}$(Ahn12BiVYdrSjOkqng7 ze@5k?2VOsz$Y}9KhCXJgV7X5WyWSEr;dP%Px%j$Vuu&5*8iw@}12aijhO2=@QNR`p zl%1Em)FOHWy|wmeD=z|AJo*+=jtl=`H7b^V6B(d~gHeqcMut78vn!w7Fapx-N&p&n z#3@dKzs|*y&}RzGOSlz&NEJksRmQJ6{gsUMmxw1@{GM7{Tm2!}N0qK@^@zzkFk6;+ zLR*yFoJGY9s?1Ets(Bq5%AVp@c;%M`Xbu3se+0p-MWY@(NN=!tuFBXY4NJTME+xQY zB^hap&-S8VuSZ!V{Uue83#tKh?yrJ^wrKUL_#f#Tnwzz{BVyxqzPJ;*FKQfv?I#7s zBM$}iUhEexcIDpLHgpP{++bZo8Chtp6f9w77BlyDAG)E$x$slX%Mb3Q)ew&3@I#*5 zYg)9nO*!<;*spnwU>lTa+L>&|H+Skz$0bb1q_^zrXQdZ?zNek_Vc6pcK8G>X?vRpF zkstYWdV?b=|kziAT;2WUM&La({fl;&`pM=AaRapHgZ?{W9L+q{V;v{DmN zzq+G@Lmpjw^JB|r4pOY1CXlW!pe~^|+mpmiI6ItM!<6cwb7UGTta~0aGG;EGxNz-< z-Yba_hi6|#mBK5r0d9rL{Km!9V$K+k6?K1fm(i*eulo05g0x$ta1ZG*g8qB0quw%;4 zUO-v|bvZ3Ip-Zsx1v+aH+$eH?=T|)pe&?siy8ds*!L5AO_f>k@&mE;7rB$8QI z^NEj@yHwqLZIYkBus{eJlw5bX0^ z-Niw!a!(ji?qBT0G(*F9w=hpoWMs63rQx)K3SWF^3p(=yNho#TRm&J0&2g`6JX%g` zqh|6218On92*tRa*B%R^EqQA7`PEyIH;ngp93#?v&24sVQj+{8^Q55djc-s_#~l=k z4Mh%MVQNoCUo&T5lgCk0g!V+vkluJ!!UUy~EUx$yZ)c3dpRIC{5Cef1lvMNN<;klNOkjy|*3~7guyWv!gbCTjV;!UW#rDdKY7Fsxl zFoD?*=T%fTx{EK7y5}qk!{+q!uaJB0cF<3X zT?nGKu}Q|kO=`{N-AKNkYq|XV@q^I0T(lz|}4LCa*~ zIgv(jkou2 z#?Dx$3k3-6c}9@{1DtNpwppk~>L52va!c=pY+PK0Ft4olmZw*cbCy^#ODWA(mEr2T zOOIE;vX?LS8WlFxfq-!yV+HJXUhK;kq zB??A0Xy-(3nR7c;7B&5a%1WBQQZyLUhE+%`W&qZ+jAq+z<;``sVC{~fhB7#UXVd-d zUBa6}s!0Rg0sT+nM-SAj3}A1!s!KN;%~TJ@cY{Plt<#&0gObG_n%jmq9xK;P?KE|s ziVWXMmIZ5;{YXZ62%m3WqdBW@o;~l>5JVlO9FOzD;c=z-qZ+n}H{+R|4J|NxII_}m zZmWdnbGC?`t(HvYl;U#I+Pi#w%!R?=`Gl?_-2))9qY?`>EfXPl$>gu6#8$8(ia(k3 z&Aae5?@2bLGs5M(VYd39Z&Y#3CAH#(Wr9{77m}KS2fkWeYe6OaVX^+(;F0u{8La)b z<%GCN3367X#+_FEHgZx9nX%I{35Bxz*kgD(aT`p5oE(O}piHhBKG=F~S@;PtMfC4h zrdp20vP#uH5lc<_{>Y=}GrP*}YJP?&h)Y~t+{1y3vWMq)`OjO3j1hBOMI(>K^s9PQ z_alTq3Wmmc8g}zvosDgub5;OvOU6Q{bfOi`L_GRU{L4eeMTK1>9eWpd@nTa3L9C|K zd1q-*i-lQZ?_K!gm`qL!3-5ZM1k7sEV1FuNG5M_nR(DH~9^QoV90s|nl=Q235LaG) zP24jys-dM*0HR)aNTt2UHdoU5iFgrWj(^luVx8(4{J&JU4rr|t`7ZF~YbiZ3uMC5!)`S-BU zPAaEcgxF}LZ3qQwj_qjP3F|7OE2T*~f095=p$JzgfJN!1Mr(dwAlI_BX6kA8aw*o~l>{TcEkLiJ8M4h5(L;%*sV|+&W?P-8H4^_>J<3oE*oS_K8 zo~F6l8=8?iAV60+bwuFr;jaD~1kspw*KMnXoeJ>CwY;1zvU}0V_TQ`_)5)U~O0apa@&hr8W3Cy{kMbE4-Z<5l z&25y>nIM?v9_TIXwt#(_REdfJX#`!8YKVqAPKFkdrUaz^Np+>?V20D5rP zh(*N^f0(^Ya}RPdC)*6BO+sYfD?A%qQ!qUx@YlcZs(vP`{F{ahJvAYlU1>AN#%h86 zUY!O?jdJ`|R@^{XN3w`Fd15{M^hmAQwOxD-lTuln>;%VV$-gy>CVAXo zvVhfnc}mmso1Iju7sgj)hfn#ucRHXji#tn8i`3C$igJla^dMxBLdDl7L2 ztt@OKg{y=gt5%c7CCrUZYy})HNSUC*avY>}`E$@^s99H}@=Sok2_Vye2rE~C zkWfH4E~OMFaatb(#>u@aJP1R=6jCs~ct-3APQ7t?m;TC8TZ{}br!M@6J>rS`8 z2ooi&Q|{ocOchbPV<%^6FZto|EYSF$zMX}rkFh{-_<*6Q#s)L4+&^CPx>BKxYuWGa z+)Ns3=5LRc0#ioY1U7teQcK8rb@wQg*r$^Rx}}x};ORz9skm?+K=W+OZ2st0H?KA{Tg>_Fuzx98I1?N>geYj+eRO+gW`8PoxEoPX9#hjt>m_m*|~| zG1Q)h3%sN!k9})aY$8z~04bHoy(kEY)-n8Hvo04c>N>gAkg%U8i76|AmyP$WB)cfz z<;_w&pj07rwOK_)wTOMB(F-eM2DXAwvf1bFYqILTe!=jFwLLjJCs9)F$|UC_MvDtO z#@-w{UN;X6n;+K$cd9@8@71qM3ST()PkE}*>D3l2^A$|iP=cqbG*kvu%=Z@B{IaK6 zkiWVW(CMS{hFn~Nrs^8G9!ZgvwWok&;d71EybV~E(z^BXcU|tmaDbQqj&N3nio5;< zu!KjF*ck|prG2AIIUn8-2QRNtO$ll8PX@6^9?UuH&1&Dc$+faw6YG!k@S<_6)Y>bw zD45N3%$_qLm1QojM=^`y`8SXc?YuXK>q|n^%p{gRoGOf`s6f0M}2C}RVz}fHJadwQ+mw$6)E=wEPU1MWL=95&DZkY zC2>3a_`U=^3-sYXWWMT5Fo)!MpR8*)g)vYbfN{h~TpQ0o)-& z)B|b@X;NJy<|2f|fQ!{lcCruimFuZiM=3@1VK&8!hpl}+C#6=z;AncAGxlW3l}K&B zo029WiRa54zPTrvz@tR3(l~tYb`QU$i_yCE*4y^=vF^L66Num=9G$4k^c$EBS$+JokXPzEfZxIHjcUID2mFWGhZ@ zkLZA_#e-R^d%ul%Wv)y}Qqb+re->P)+;-Ap1OJ;fjVkxkmV z68E(nyL@`9EYBF2@3@bTip~zr--Zx$hn>LXul;Gi>rzWLsME#9hOIT%3JP(i|sIc6RNTOZWd@k@JnR((Q>FsoD!xW=43e-eXlWEpCN ziLE&mrs7Qybrr;ix7U{LBNa6{u}w}_@+r#%eBva^SX-vx2$vL06FLckVMPW(#b30Hrd12lNcG8&HKfNn>sx5y5;QlA;WWJ$#RSrU zUP37y#&0DOuY)RS%8G@!fN!&Vofc~m7FzfKbNe*<4S zQFdx#>!^r|m2?)OY)4o@$ZhK%V))blVRHWe4}l_m_vECSnuq|&rm=1!uF~4{cm8z} zUlL;f6W%kK!D(0-kw5>w^tc@&b&vWUQ6KP9;`x;6`S5L$kUPqkg!lIPvld5fiIdzN-m+8Grwp=dV+hz)fT0`-#bwA(f^x z8`d3zQobKws&GA7nR}w7#L+$3Ia%jckZWXme)IJaL)GJOo5#0re^QIlO3WZHchA1Dj%O~c2nTT*-MnNbf=EpgagfWd){6~QCpI6TQ?<#LE6+%RJ`#(?$4O2Z) zxjrP*r0W(W(oa&)Ufa86{ZO!^p-X$>ex0%)v${Hk$;@dny0Y z`gyhc$z_pS?$2&Z1^|qQKkpFf-K1(}DTett4z==OccLwm9 z8JYBqwHZ8n_6glhIsA{&9))pmF_7*SSk0fK=dZN??;7&|sa%MPk;2!Sfpde#Fhv?G z0kVlEZHukl@xm{}nN9NO1`*PcNRKJRISrkMJB6At#c@B)%~b_RHeJ)r(zvlC0?^D*OV4z-lC@oDV&bH==fU?CDyBK<}z`+zfRC_{G|2=B^Nzd~}^wS?7(b(1oOYZ+@D02*M6sZI0BxcUNWR^VdjO(6^L z{~JxlpGCn8xt2->0~nmF(+Y~3mOryYj1Nbbj-{`Er#%+M?BP1`U8u9_t*%4N9I^qb z|D>3X`?Lfl*eRVryY_LTm(bCp4$!VBXv$_n%B}RC6##JF$rn%y&lSsX%l;0M?Yc^O z=cmYP>AL#9O?mA1ldYL_>i$iVL3b^rvFjZ7?rw3r1%<)ZCkuRSaI^k-hcWd0H4Ep_ z)(8^Rf<25h147rScipSCDBri8w2Vzsa6j-rpz1$&K{4f&z@avKJv-C#8xs}EC>7d~ zO3vNx_F)5qSMFrB)q0lO?l(+#^-Cow_7$q50Ee&XQ+yk;$o!;w2Am)i)6z;Zq`?KO zRN2_lK$20B?>Y zQqaE(z+M@!Kv^w%t=zW9RU2!E`+K=#(4m3|z@m80UPh`lPxSo(!O>2+8lG>e*HR7$ z$$B5s)^@0w)8Crjx7l*y27$bvwl+t_Mv2R+C&D5TaA%<NYk-_8#P+|E~m6VHK(fTZ^ z$L2N}2TL`T+}mpzizyGoEXQ79Ky6DwM)E6~1O>)VES$#E)yHe@BF8EgaH30RJPZ>k z}h%Q#j*^EDV6zD#@ol=q z1}~N#)LN)7pO)>><&3Slis-wu8k+U^|4+h+j&vU*49L{5qoT1#0H@kj2?rQ>CPt46 zN`fU7hF3RDm`VubsVnn0NRJ4cC5}fG=pFQMQg&3$CL1biHp+Yl=1oe!rje8g!9Z=O zQ~G`fRWnhcQQTFc0?MD!d3*w574D4=Lc=@>cj#|2~-ne1_EOfej%` z?SUBD&6)RmEHWy!GAVylGyAW&Zn=Z5Ehi1nJYOW~FgP&w?ge#JTr^Pk(=_^zJ#x+8 zICGt8!`g=4%1v6EF8@y%y$JC!Q*y0FG{kTTr@ z`-6K)B|l@nQ1A{}oGe(;FgL$$&&24atf95dWaQ)uTR*-~dfCPMJL9X1E0e<+UB31| zA`E&bSG(l4C#@U3^T^hO=N(CjSN@U336&;S-ly@?)R?N$>l$Eo1v}(HZ_KzneTIc3 z+=V@7cj7uq1~#W6p=T7ibKq5^Bxm!YrR(`jFyG_-tozgw2x^jPihs3P+QXbh5O#I2 z2WdvvJbSiVU_5Sthn5uYVRz7nN%2VZj@I$zvbag|&nw}(v{;XWIPgT3$w^q=14!?)u0ym1+c$T$x|+tF6!$^Y z${?zp<}9Jl$!2-+F)#1J)4?aMPKhJ#=1c!*Fyg7bBZ$XnJiw&|%1GMJk)!_n$DS#a zHy$3gf&nE2?!w3r@~%_uG*4)%`qPIDZv7b#TL`{|{1$m47T%FYQ5+ zB%J%Y<3-yeB^A4}wk81yNJ{&Fc}?&+EPA+HJUfB+F~`eKsTMcUiw54@3p-0-5?`W% zggEVsfb+O_3}b)kJ6v)L1^6dR20!v-od4$2pg+i9z<`jNVM`7w+P`G78%kF8vVjv= z^!&T{9AkX;vWB%4#KReF^QUdIC(*S6{O%sY>M5!btgRAtCq6X`fq6Qw7 zH!#Ds7R)VRE_(>J{oELWW?-A>DM`PT4|WkNHF_C-FOiyhQ4jvL$@Lkz7>Tqd5&V%n z+N=0~rJne-H?!v_f33Ksv?4xR$@n{Q_yTxT7xPe|Sz_XZ4EhsvJ0!TmA)#X}ps z1Z?QhF}`*WZT2mRYk%(S=&R(=0|I11InWWIcQ$SW%#pAtov zT&c*F?sbRc+{)lp&oU{A5b}Q(t9~%L(%Ni!5vpP|-BRx;wNH-o_bU1z1}Jh87;mXR ztM=b!^xtw5rN|yO0`B^M{1SL!Ce3PP`ezZ3<6tzo^tohIaj6K6#ENCFWQ18~V9_PO zeE#u9g3d40bY^?*kwa@}5?P(KKwXNEhW^RWP3KPy1y4PO5y>0R3|++qOV`WdjY;R* zjaS59kZaw1f-wd27Ul?+vQNbWB&8>bcd;Tt4qDjmTp(p?=56jO_*UjIrZL)fA6}?n z#5|fKDDf}(hDR)y!!LHD@$_qK^mV9PJt6PI-jL8oob@(;dR}eObv2(RGe-i(G_y#{ z`0eA*mxXpKWso>-g0+jG#4lOLWsazXixw-gn1&;3<5D9=(vVL(%CUuO_Wb{@!WixN z4=M~$hQROla+HSSob~%lUkrhqRETc+2%-kVBHX&Q^}j;H_?G9)=T0HB@ylxvZf>5shuFn?)jzt=vYSbOUH#z# zKCfF_9}Y#|(8n~!$)0Xl6rKzU@mzWhlDE5idwSWDULro5rV$Z^b^_k54{%6+b>-5N z^;k*j#2ot7t;(!IU~x=R&OWTLc(<|V{q40ahD(r0qRRRF`I}0+K~2iOaGQduofN$I zDm(w#GW_xVi?I67GQ6dSO~F+T-hwijM1kOv<)z}6Sj_EOxXt{|Kj+U#Tz;b{d)uUz z*EYm(`a|RLvr6PJ&EmEUls_^w|IdR;j|Ovp$;=8=y>{>oCG%i4=ZiwTp+MTMC=*h{ zPJn0N%>(bi!r3h|4VpcoD8a`Z>ohFC6-;P6ZMPcrV)2OnM>(JaqOjPPgGlXZh{D%P zO(zh*O9jG-eY0k`vPETC@-rBOurW+MSqqMtEm$<1jpnRfvCTZ_xl74hX}WXd`&~WX_p_}oX8hhX%Ze!G-DWw&`vzw937`RP$ zcAxp1?x3OmJ3~88<}5@@5VNSw&Z{HLYSH_46R7oHT8-RhwE)3z?#LCXXT=uRV$Yww z;mo+BGpHGazE`hg5nG06aD9#4Dvs3-GHW5n4k(#n)|+Q4%EkhFt zLoah95G8n~a!)K9cv62A>`^cM{IKuCJ;%|y`dMSJs)WTVQl9-Ltn5(Y%+(mwJndg+ zz)Wu7nQ=@$5?ambXjwaU>>Hng7GW$B=+8~)pN;T`L8u_rQZIhn0`>ty+7OeYo~d>q zblSL?RBPzhaFS?^yb%suKAPRn9!wxW8XaJo5h|v8VTuXo)5l49>}aU+DmM;qef?Z5 z46{Xu^B3#I8m%KgPUhce#+Q0s+&=DyHW?o>!-6z=pEz8oF#M`(@E<(USpG3ukJB3y z^@N_^3efELZ$^kSEDpCF7TFKizc3SGP31fIO1qCJG~W^!;>lI^cW%AjtSj_7IPj?= zi0V4;V`{BUrGEx`vo(yoSAOzn?{Jrj9Lw9D=5YM$8D7dWW9iIOA@hTn;U_-L&bGj3 zGJ3@^Su-uzPP5_%Ea?q?1Ak96U^F!5opxmb2n3X(=d|BumYtaI9+=*?;IxOXSh;;8G zMXgo3Ya~xOhAkmyipYPbSy+@onK1)fem3qt$!a3nFilse%HTPE_`nb6Uh7mWrC*nb zPjyS3f)XZ=wCYBj###}_M_sBBY4Ad@(#)dua#X$!_QUw{&oF+8qc7DPt2V4RH!IjO6dcC9YsUusv@@>sggYMj z7eX$WCJH2^+G$Mj{2JM3?>oN`4tqOYF&iDGVAQDi)HUlA>whB9?FoCcJ261wp&l@; zTPmzE8~)div=x%ze<9?v(@0kDIom|qx`1zee=RDmr850fb5j!rZX{f7Kdj*5;<7Z- zE07caOu!vX04K(7WV5tB{AS%(iLajj;utfPuY*iZuI1b@>m4aYLTaSS?udcqK#oZc7!z+`HT-jcf}Hii2Fg=#HgSw^#6PMJC%E z`NKy@oq2hRGdFOg#Z8;j%~ihw<;)<51x|C1@n`MQ)vzxnE-H4gptaAFpZ7E%&MuWF z&(h!cx>Y$jCnn1v^PM(?xE}oL^wJgUWXwrgdT!isoS6v?@euheImzns{QTF>SfVI; zs%Cd*=W{gy7nTx0-lO{qxqxZv3Ybi(&QXqILU;qox;Gj;P719u1_J=&kz zT+c339y+r4ndI+$dV&X{!YiaEX5abDPla1EizwJZ*ga_twp{hlN%!;c4u4Y1{Y$^s z-pkUHu)hht&t4U%7LX$R!*tTnPurpfhJ41DgZ)mUhpqDTuK$_Yc5DraJ#&FG(Cnn{ zq0)k%{;i*U2@!2dkMfo11^8wwV>e2az6E7Cgdfnw4&~I`6V^B3N;9mTsM$Sfy)&HV zaxc;KuCnlB4vV9md~G=h1m_o8b%3zLZta=kpUUA>NcMKbpNzZjseI->IWKTP8t76Q z3U3#w-fqElI(F2J0X7z((c-szRQkMV0{4omeoIVHC{!TI`x_okIeFEQ`Ftt5Et5%{ z9hFX-`~BX;*zYZoL+*Z3dML;}xM`3FjDc_N^fI=#Zx984<41d|TR?E7Th?kXAmm$q7>$VGnhi+PYB?mYP}_SdZ*S9-RIk%qt& zn{}@lS=P0eFG}hcZ53KXPUR? zi^E)`-W$|v_3eJJ4NVBlH`w{;m7(33zeMY+XE9r2T7KNI{^_n;RpdpPeK5{tkML!ycv6a-jZgEscp5|K9XblPRCK~k4$ zleI(CL-w19`!o{mGOJj@(`RAQlKb`90%~aX5owA)B-Qp1fjm{dtA6e*`16j|L?fuB zkQct^t`pw^vm(8^} zGbJwpTI;8yRPn{iRnOR@H*U;l0lm^1Ld!rm@yf%t08g29-<+AZ6p|l>-dgfaV!bx4 zU!g;ua!5$9(zd+cTIrP?uIlHS=S+<`%!fg>U1<~f60rUCvjzED()6qTK#!jO4i|O*8MUbpo-|k8+ z?;;Ar^e)cNQrK1EGH))Pp!>&fy{)WTS{B3*=mVIKe3NCT{59Els15uK^s*_BaNa8* z=SdG8yIR*VDxKc|ljg+T2FYTIZd$Qfz=T`L(z$DM=h$HJ7lNzfW|U$>0^akL&sNjG zdYqxDK0j{vnSu}WyQi?ZL^S>TE_uKkbq%Tgv9;7!NEcrRc(Lx)iU?O{QU4B&&9!mR zat7hpMXSJZ41wUD(Ua-yG8A>%z-1KXG1RP;x`>-1aU;M%oaj|Bmzt_e${Ngy#fSOa zJKH-lYj_J4gy{ZA20ik;QZG4EX4#xl`4z#3C8B@E>aDS@o5+bK5xx|r1lIv`7Z!sG zv02q`pUc%=H&uEYAnym^Pgaq~-hI4i>S{H`<-mM)x*sDDbUA74KXK7?XE1FXGNtnU zsc~KJ=-$_Z?0rK|Cv@^pN`O(DR(XWwv`9DTOj4jKzs zm>Wgz^aEwE4!Ma(|3TG(*BtclDh^eoq0My*zWNnHp91<~sA)HDzuZ|p`JF@e9u8D$ zDlaZkoNvBI=fEEj$!FXMsSRaErq`du)$v*k+r@fG%(XZ0Rl3yz%?|m%W=FM}A36b* z16Tir&0YS;QFW<^gErboB07qywmXT;gU;^LUoWk&DDi`toG=xaf;DS$_+Q>!dJc1fIAS!H}&G zMmN}`J_O+3?Kt7te0b(^!^}f=@q1W+=Mz3P2Pk&(m!*M$GKAI8{`GpwMh;9@4-4MW z@1q+f^juKl74X!|DiMHgU#dbx+oKKB!^~5~$6h#oOKE{VUsKC>0SlEjUR~6kGEe@Y zRpuGe^Ks9WrN*hoTa^b(Z1*%7#QYM8$L>mHS+g(_bK<~8HTimp!Z@`;g40?BSRzPN63!^@YqQIjxrK$)B2t0J@3etNCB{Zdz(4==%L=@@0_nHuT=mZgIK|o4^ z^cq^|ozTvL=iU39U9SC}>s-}&*aKP#+cP1YJ~&bj8e$GGpYb)skr(dp==m9%ZN zYMd|#j9(qB+w{3P%>u(?qDw>rRx-`ZXbZOoz2>8>8m5$Zk+cmj(oF9R)c5x-2i>rb zt~m}(k`e4Itx7KeX*%{23|?mGK{5EG8<40m<1JG+jY?tfWjMq8kTN^pj2kP0MS)5< z@hl!foL&zhVM>O7(qE>>#M@va0|;Do!)t#AImAe!##)Zgk1V!Hz&{I_7E z)#>S7v+*bd3Sr-0con3x&yW zSO%9?b}~J^aVXSZ_>T4@)hP5;0yoE6nY^-f=zveRdpBbLVb9TnhEk8?^b5?+ksjPS9J3oCydoV>SP@#I;YuAh!Bytb(xh^u zVB;Guh$Fl38{+t4sph2IFOK9x0}P5BBYQGjX%ZS3XREq5BF-Rt7%P`3?Csl#6qOs6 zLzZw6!g@nn@~_6i?*S*Tv^&WAPe{+udgh@E+-Xmnvq$Eg)l)`avNZhsHU7wWFL%$1 zD@jtCsYE=pS&jIqP`dIYmx-x40VPqYvTh* zQu#zj_?dLT?^w+Pb}5L%!D8H?1PI|x8*x4h4a4`V)Sa1RGhd;hGUu(M7`_qs zI$%xtGYCQFifj+)*v^qo%EoT*t99hHQQF_Wsp_J(IQ?!y>2ts`Sp#^^p+7oQB_f{j z0&u+jE_DBeVKi5aRnt)j>w0naOol3G@ZQKq`SE5?f3&al_p=dL;FYKlMfFnXA|L`H zUNg>MAH!BnGA3r|XF^xR5ZAF>S&jfbPQja>&UFOZD6#^KtGS2NFXY~wUwxP(5gEDK zY~Vuemu)$9o+)+iB^}1#98-7~d+>hw zXe=9$(0NJu$|L@l3)uY9@J^nd>p~C$i2uI094r3~8e0EPw(~IX_ir#KJFlh^9}Q70 zo1&s(MKzMI#DM!j;N{xE;!iefsDYsYJL}`#o83<=r%eFy22M%Vv+YHWYcbC*!OzZz z?qovSKdpegL48@15KS}bY%g*kF@%n);PcmhK*lQyUXTWaEK68MIJyQ*NG;4-taIFW z|H2+>DQfjz1@wAqVyL7xh-%4!g|4Rtck0)E*}3S~tB!Vdp$w|+3{!L5xoWR;?NU@a zw&$WP>FR37&}F`-N}(a&-@z-zx|GwT~bIhYUWnRSJl^{&a4#fylOzcL)Xin z{3(HU(H)JCE6b{A4Z)ENY4%K=2Lcy~J;dcid?d#-MDJw3eNhMs2DgVPAAPOsnvCKJ z?08^!!R;j?qPV=v|Gs?;D7vMQ%tGmJE9ic?rHD58W>B*3UNO7KKy+{gxSR)Thg&#N z?_J`ywxAT{$Oi@}VlA_%u&^!J*Kxj7NwEdikK#Co)z#D{7ov~9{;xI&wYt^S5$+FP zH5swAwg$u-oNA<7Kg3z2fh^JckDknJwfzITe<7!Qs|$q2#KS9t>nOiXjMf39k{@E0 zHVO-uc^vGo>$-eWH(ydF7aZe(hO9|Y6dkIJNY^KKLV6T0Y1|<(=8$K|HJv}w;e$;$W@L;AX<|L%Pds&Ha8?$gd!{+1z#WuNW zCf&Z^MU0NKY!IV+9shX3VdG`2P{488S#50Yz65?L=&FO&VU>0kD{`pm zLrTT^q0AVW9LILEdRHwViv~0>eV3-nA)TXnzYhBw)E~;uHJ>s#(YUz&$J*~gO=Du1 z!oHrx;s97(CqOTdhT+$j&F6XR4;iYw!%6f~3$7FMEU%V?(GK>Uq%@|1nueY232a*B zUlsxZVrF3d(lQyR>$8VS_)nzKj^PQGxPceC*M#sIPQ^#H-O>>o*y1d69acSx5xR&j zZLg1`&BrNcBq4SA*9ne2+=H5u+)Q{l^I{eBC;?)clQ%9-xAf&vircL8=-#C6@3;1+ z+`3WKf;vrF)ODhUNgn$1puABNXLm6eBDjz9v1r;vTWc?5V)Y23fecCwb2gyDBSwvz zu@%>5irR%cZ2RQr;-oe>VUo5HCp>xU%nSvAJCmC4eN}bZ3*pRi#%pJ}4cm+SSj(d3 z`C&%L51-b$wH4!v0&u|nO#U|wf@SN_?akVgT1n+os?_akO45bZ+(v~784X7Hc6m1n zaho85|2YfuiPWfl-`}Rzq;V_&2Y!O?kQ-xA*)>LMTEq=vZ~j1fZ4@~Sk_*hx(8UEH zf+iWa8`1hqgT<0EAVfFqskab^z3|*L1}unoL9SF88Qvp-uf6*O(fcjugF4jlzb0&> z_c~U@D>2O%E~H($z=Fd$6qxPdZRb15lKD_E`8qwEOu_K}wtxw1h>mqM!S^i~rJ7qrTq$mZ(N3n9VHe+QP~b$@IvK@*=;99K@DLEwN&iv z@8`zP@LZ%=0ZSIgNo@IDp#X2JEkE(z1sEMAvdb2`)O%HQw7!D zU|CBTE};ihlECDiR9OStgBDVQCUEPKdZeP&1GVLH40L-&Ic350cF)L3F!h?|IN^E2 zQ~zc5rqR;0dhFIf*7cpeQ|ybNwm&bX0V44qjd&!cxI`VESdbRY|I3(!@B1>IqIzj6 z#J>aJc<;y%||C z_T413N@DCbxXL>jm3{{Mbl_NOz&SbCt{8`Nb`F#CuaGa`Za3k_x;N!BagY?9XNcW`Gghgn{_YnKpngM%dy)bu!>BnM`S!jKM?MCc!nt0ysgX0uptIh5bd&HZ&DuvWQKyogSa#$58M1lvf@;`UEKB}6mBB= zCQ*8Uq8P0_@sf(>1WHOrFUx}h7R-4EE_r*5#mfUwdORhbqmgc1xQ> zd+6x_Lp8m1ss_V2O0Pd^A7+etH=bImUUU6xd|XptOf}n^JUfz5EGM@Eb>U>AElC5k?A`OU8%RpzTtW%kH3$4$;)BCcLWs^5)~5QJY? z&&^UcL&DQJhg96VD5UdHyBZx-i94|9jm0f2?U`kNaIo?&Gmgf}xcVAqn=#7>HmTBh z`4}IAX*+W!7ext|u%g(ALDdHTDG@dhe$bR@uL$-- z(6sPP(lDrCQ41kXnN`>^or?ZP?@AcxsZ}B+r9B(P-9kEedMP3^oTCO$mF@H%T;b~6 zR_`ZSk*rOdtee>}htW&7>MF&#W&$qN8JeLi~~AndGA$yGiPPO-&^w6&-~5 zq%$Dqb&3uveCT>e500(fcLdoA{+h(jw$;&k!cVMBdNppFUKAMe)lFk-++g0u10K1`H3b%`aB1H|FW)h zcaJHZVDCw;SHi1(ns_a@;j@@t^HH=}7$hcTpBvKd;`iJgA(U}@IL8-e|BoKQ87Yrg zTZ^^CWQ_U=iOO6xfSk2F3TfD?vr{MFzL!yo-Vcs(REUxk&NpSNZ=FL2_HLCS0=gC+K;^#ov9rc1smD9p zQV7bk=j~CU+XF9Xe2*W3&an~9-?R=y!i1{ASWhQ*A%l%D4$GkRLKeL(0Mkf zilO5fSd?$2@>gZv4NH~sQ?Q;hqilAp6Ivq$z1luXb}UW2t3oWbSY#(34+pLJd!yF> z1bHohB&25bWU1|P%S+>Q-1}TzpC3HSddbwp(L7!th{v?RHqow4B3pD#V*Vw`m{ph= zQr`CP9<#W-k=h3DF%~*d7?{?4+jPf!SjaD{+IP3fui?mzG1#r8vIG?5uka>^z z+kZQLjXL(fUf3ViC&=lz{hBOA^>;>PtbCQq<&*HXSv$%1mP~-J+oPTVH_e!}++?B= z-dqjYKMVpNLd(K4nsN{4{af7S^f&TI&*^fP5q?yJWXjG|YRG0PV*9`kY)%t4oJ);DFPIfS+ji_>JP5;P z>}U<2?SZ(|VT+w6a&xSLI$iXOdoyCo^ckt}53D@+{40n`$oaW0bbe`X)Kloi`g4Gxh+*EGn%iHzmhwy#|^T!h_a7o7iBfaH(g zoN3idUksu#`Bm8`$tf@2F+X;^zcvU1!6_LT(|yH!_E#Ze)d)b7Cfavwdr!iT;F=~C zAbC_B#PXYl3#?OJUENhPTxwd%Wmx@GR8;iHy+|uhr`g}HuD+giDnB)r|2i%=l{&&j z#IzXuN~GyFK)90o8+r=txrClJe~Z0cDV$6ae@Vfnra;!|A!_KRq46s&Q1Ev5`;mOr zl-;=qDOOW#i81{1=bJl|-TSK}Ic|8Yu~#V0Yi@S-rwHb(;AeyrI zjDU|j=A!AIdIHGg9w>E$GYqOrox0-uyItCU{75{|QbT(k`J)v@w8eXI;sKLStp_m9 zvs-e?KxY6)133}U1D>-h9Z0*8f%!nb?w5w%t=nIDP=)WW5u>}iIghGwsa=4W)lS?s zF-}fSL7QJM*4Nho!wNZ07V}&88hMc^LqqbAZIhFdNBh7Ja~Q4Sxs!YI| zZF5Gw*+=NEo{G576*^GW{y|yUd)0tqSXtKm<9_H^Fq@ZN;WNtRdlWE+WS8uhi7k=#D`HumCV) z|>ssS2o{b!X2{%bYfd+*=-P%<%D0wbEjn^!F=VKy!?G56UB z!#toq+`AC#b#xdTk3htD-6mSkxE#k}+FJh@$0EOdfrRr*wcfvuj}}oRWRkhLKy8Ox z?;117Xz^z-`NWZ$wN-`dnQS%H$UAhe{%pZJ;3?2GSxR`7& ziVFOHw-*oTJt=C-uJ**jsc)#m-`J26m=_GveaJRPi zlU46)$|_4FLCpZsWc`>b!-D&#U9bIcL!i*g3%gsYM*P|h*k-t@RFCF2SU6;Xt^h=V zh4w5v$y$BbrhyD;k5xwu#RxWAA= za@yrcnEG-wzo)C>{0n`j$bB0zs?wC45S!4D7J?})h+-DAK_99mYYCS6Y9$=~bZEku zl_irJ6v&9cAm4uN(;9WlEb98_>AJ~7f1~;39yUsL9+f7uHTxU7R(lFIO=d-d1=&ll zmV_%YxH#g+4c5*$)c}Fm`IHGY_u-RrkNs4D`=$MBM8h~#`Ir6JDpyRQ8(ooHQ-V#7 z+g-Q&o3KwcPji1X!H4GZUamYpc-Q;M0Me}@b5KafQy^*G3Ziu-& zncEBaW5jzoC$fdiUB%$7wD+DSU5&DT^em zTpX>KM~Bf}^gasHu;!fN5X2zm&G$BTLI}dWrNt#yv|%E7BQjPibM}l7DeLTNzx_|` zWc!1;4;-P#$=s0Hdzld(B}4VvZ63W4FcOohi%hOHHH&F)bQ4z=!u{w4Y*z8yiL+x7;~$gySWxsO$uV+`?XM2)8nY^#-5+;nUS}aYX9scPV${$P$kUW^C+=luOo%7PQjGDaGb@Mc3k0SjA4266R~c6KjkS~m!~Mj%hG^|fOkcBn znTdJre9l?*Xf3+2p++YITsQBA{L}d^>i_Ok|)Fv|4_U2JbgwHk8O(T`x+`a{>LDZUN25tVPD3x`Q9xO~~l~FTuZ# zxUK$!A6PXqUEPXk#HxL4D z{OW7&=Ensg!&PyC_`3|^4-iYxPk)+nrX(cT*>4o)R6f!nuGs*&<~BhRcpeHb;wj#= zWLsKpOy?pxu2MdT5k<#qwy{;x;(EnRy#h9lLFaO^g$@{LAkDE9TG`;yBF$mzSSk_R zyJF&HwECujVQ4bG8)v~wB<(SjjUf8NR}F-a~W9P)3Ii{vFHK4+Pz&)701 z>EE*d5)yU?vnymgzvgED;9n5D+P?wmWNCe^B~0bR2?k;@Dt_$DeQN7JI&#Nc3s7+y zN9TT;Z_96iMQkFS7yn}GQ}Sa!Mxl-uqq9rb>eo(k>my(}Y?TdYEM8WXQByU~H+9|4 zZjVc(2%K?7C{zcrlpINub~l!YN+dvVSvO@TB3NAkR{vFCviyd~bLHm-znmbh85E2E zlJ4NSTqH+T(Roq*WWqFF`o1QwWGStyUEW)B$K8_z9v524qEuU}bd+<*XZ z;v^^I8hm2sO_m4mb=5t)$0qmVTLf8kyQElkpbG`%IgTfy(L8J2u-X(qm|NTOl==Bm zX!(c3>1O1jQ*E}{hGfZ9qzjqg{pT9ZCz5hZZhP3Q4N1M$(HwzY)|l)oM4N>dj;8}x zLjq)Ew3AC&Q*ce+)Q^ioVq#NEuW!*!QPAYbe>>ihi#fAi1U}G>#8e)HrJrx-LEV_V zo?E?mRN(`UL?Bk(z-QL8l-9j}rOlo^0EG0~V7iQsbt6-d&C0vgx9LjTUUKaEy1DtZ zri$a`5{4)e9+;6ORvL&kbPcb^TB#c6xv{kl^m6!T)Gl&m^=_zQde!NQvbT(w!j0iQ zi{ImXh1dbJzPU83WnUJb`bd}UfrGsmWnL%r`^@PA6Mc5=Ayhk~fh3OOp-;ygxM9vT zC{Ng7ih+se$=a65Bj_%d8r_q(;4EA8pT!8N)4b1{-(hF55k?G-5;FQN z*@6}u(=aN-aJ=uU(FZM#Xug!aSAb}k$;#fk1tM8b-Rs(L(Qv2gs1ME+yzDXOjY|J_ z_}^qOj2KX=y3lfSVE&JIo;Car=7;MInVmkVGhJe)Cb+W7;eJGc+cQ4hVXG}OQraT( zm*i{bhn#+8A}?qLD8JwI6Fbv=x8mVmOyMhR1#iteLDCkRnze<4Y5u-z%D_?x$B1 zWf7lYGZM_)kRC3n`@UOYtoCG@>%w4|Jmwh(=7;)54Vv@V6ooxx>7YzR(Yzh=maO$^ zAWIF?u~XWUlUwmM%hoJqboQu@5|k$cW>tDqH(*wEF2(A&$m>RJw8TNQ;H4|Br}~cS zCi$Az*kEQ!4zNkjC`l>WlFcz;l}V%j2>HdApLq-uKY0JUcB=B@4ZmI3iE{?FSdSR~ zopW$+;fLey`e7YJw-O$LVa%IR4&9`Gd+a_^7I3YKpIc3{WejO{YyeR6c%~cl;CWd+ zF5PSn1vjv3@D(>={1JLW2e#vE@9{L}%>*Z`ECGPGL8d&VqAIKKbT?_F_u-2;xS+vA zyC1@1(lnEi)Q4lk<#Y%a*hJFkD)PO3)v#1?aG(7zJ>xJtL+KF-F7|O{Qtu`hRu+Nu znrHL&Xsz1~dw>E-n2P2i%_X&v);@6EZK3o6HBzZxv4b>m8+#etg~+Pjc^1^6$rZbd#XZa;C9?K8SSGDx}1LdRtC5p2oLd?SkmF>)4AHW zqbIU@%ujrlex$b&j!dC(&_PAI^Mm|)P-nJlMi{%^t*}Hf&{V)LC5*9}%~lnUfW=|o zsM*d(!q5BgQtx+teBRP*j& zo61hd!ADySiwq}H>uU!p!kRIoohK_o_Sq-~V}qc^)eWy`CqSP=4F2S@M8@AWYKres z{2Or=g_9E(Q_HtVz4Grk-0KYsZrS`YM`Q@{cdp#VK4yA!ByO*MM~b=f(5qX^a*LzX ztZlTjrKQz~gy=y1GSjA=om~@c`crlP0q>P3jI?%sz)Ny@dVRv#5B14}eS_QMD&SLJ zVoDKdzYyJm5X+ZM7`%bR+MH{*3oXF8@3=r`HxotRaou^t9nHC;vg7b3{e)W&YRlBbm@o@^*G;)B4fHEx)WdH^X zkSlYcT6CGxMpX6?@ZGB=FD<}&fl>h5f3j!1ZCGum`Rdh204V@AhtSAS`D7OQgY^l+ zYd7xv8n1J4TOMH9VZ8XV7HB*ocWCCfvji(^dn4fO0w;t6C!oW=^A=pa_&d@BxafNq zcpXr;0Vol{2>ED!@%bPo?(S0s%Fdzx(6g%C#;E;{a0#PzE(K=h=7UtBzy%cv*^fR2 z(6)+d6yaFI)wSy0y?Z|mqtnuix7*Nwwv4;4uW#~V*$E;iXAZ!&va_>e6BBJFwYE=% zgoGBj*tr48wCD;lLqo%nu`yGFV4NctPT^D(Ky;oKd~w!N`x^SxdMW6YtdWYqK2Lo` zKzTjE3FwQDFCRqM#{D_y(*R!K5wUH{&F9QOrlK-Kw0g!=!G@kM!nnabPh=WJ0jQIK z&Q6Yc3-}g?57*H?!3{6yg|@g(Ow2aLty35|8F220`|nxp`9oWiPUHzL4VRV9>ih(EykIO09>kbC?iSP2vl3roDj06x2mb?J)*|8TL=u zp`c_+dD1P00Y;#ZyY7NSr``DY zc9D&y)Foo}?q}EtkcmnSr11iG_$eb`os$mkG@?HSfNA4J%2_RFoS}AG2ogxi%ep|e z^)CnQ$m?5O1{14$^Avy2s@I*^{3k1P3>wiC(OVi9OT=fFkMMFf1FD1BWlJzzT>J|K zAp>3-%8QTU`!~B-0j&1o^G6Hd;a+^W6vhB{tkM-<)-TIS68)P`@fTTNL_l$s%N@m| zkypUu`8P-Y^_w3*01O}4fb)6((RRg`e?9+@C+$f4tJGL_+PNINP`}XyS$bMZMnT9D zwvLSofVz)uAZK(6vwzCgx@2|KKxgrRAc14f3KuU`OWMAn;AQ|+VXe&V*FdBQ8VBA8 z)0-f7$LlDh*3knEeG3SRv_lI_Aej3g%e6_gm6H04IX#w1ik<9;R0;KK%_2oEGq)DL z|Lh3Z6UUVB%QDlX>3)w1+Ow0DXE?HK^2Rb`tL;Rr*yTTMXduz`1lR4vVxe(B{mV*3 z-S}qY5I^uwE>_~!tZxbg0yf3G=LY9Q>5@ePHGjopR>Ulk`{`eFe61Kd{2Ur48LBji z&6I6slaoe~XU6sf+wiNpZaVx^&k@OGCQ!9tPCkm*W{sTm(Q3cce1TpTo(}lL1I7>l zw*%H4FF($!Jl;KYq{Z6R68znD-dE92#sosKP+9#%^e!YfK5rc7;Ney0lLuZIK!XhC z^q@OTG?a|8gg=1OBdH&a>}G^3N|u55=zb2&2ZTVUchw*XW7-Z2#vaVOhYmfoqH>nb zf>BM%*KkGR(rZ(vssY#Aa&6=8fF_1SYt;56guu3u(wcoAcOl*WEMeMlNS` z>cl7pL2#Me-u0~{47WcI)V~RwPnokccz~~=Ei(xIVBXV_^!Jr1RH3h(3G7xUrVo zoA?;CPSF!KYiq>wKQn(Vxt54L(lKl{Dz4^nk4w?y=FIWus7WhT4-hLTrktxs$%Ubsdh((5N~1MkU})7D1+?e&X$4$o^C(rfmM}zD zIc1snuREVwaSFcR3N9TuIObvJ3*WpLOygYA&Q`DIi`Y!oU_DZM{h9T3xEZH|lz);R z_y2=x|NEdCP;u^Sq#Z$>ZJh(8z7wpchf7tHdsXklORNihu^~8`zIL4pETL+uE_~Ja zd_NgED`B6iW5CTeY%|a1wkCGPOvx=a_10VB8}>>!MT{{Bx*dOnk_{_m%ze zDrp$QYJnpEBz9lWc<2Yq3#JI;BDaF?vDGy@4yvZm0?8c$bX^P~V7sExW0NF5V!W}* zMf?9QuEumRZBIMA6|hI^6uhhFYytD)4ed$xHA>&`!1pQEo$D*y)^zHX`AOMli!#;S zZM%~S1+E}>vMMD83z8CZ|kXSEDy;=smKV}>B%E(_XScwOU#(P@V+m*2F8^(R-l^$%bh2qHRI|9u2ClcR0li7cH)1Wfm zE~v8;teEw2HM%hNPbzlGI7-dYS0{?`(JW#HmE`S-ymP&%$@4mXVt#D-oxqL7W$~WI zgK?KW=f&sEJKSu|SDnSsQOy?xf2Ql-irAxhBi_}U%*aoGLz6)zzbp{Pw>2%UA1qY?!!+=-m|$rM+w5IkFbZ(J7 zt?m^`XBVY_u^vmqTg)7+G@3gl47T=Z-6^^CWtr>F3X*i7Q<$fT!B#tggJW?y_Kks}=>F6j24U(* zdjA)O`>!~;w+M3tmO7l?4zQkIoN}~P@{n3PTc$(WoP7FZVx<9ufr*F=WE4<_hsUs} zz$S6OtC)QJ+=?~b(sH!6wuIIX37G&~N|*YTu+Voa%lXOb0=lJ=351i~BA-*=ZTGHE zahnI)w}^>FmJ2^bu(5a1zabQBcLc_z#umy2oz5@2=Joc;{pPl``&y|p8%0>zsu1zS z=H-W8OL%b4Jvqmq!HeVD)@Rn{W({R>SxZLH3F{VzmI;sVAxg-9QcEzjk641Xq_JKbhYBp%pa-9 z?H;mOlb_aGHLJB*Fy1|>u*)%ss1CDQgHLXR4SwfIE>c+1+G8x&GVGI3fEOD=%Va`K{oT%nu#J z5Wnf@XSy~}kI@@Txqi@ymFC~Cj1$|sg&d1Y+M1B3l_JSiD<9RY!MB)q?Vo2-v>#VQ z&)7v&LC&XdqnQrFSxY4lRULOt4CegBm?f|; zdN@2g=Qx;EeK0->GSE8CVUL}?b#h`#+BC20&&0@WI+9+cIZmYJa#f;+6G2fNyUsp) z#dA3!>NjkqgC9E+cErMxk29nztMBSf^fl-rhI=FRS<)w(%F9Io+8miyVK*z$t%|#5!>kuT2$1XFZF6uv$s+>kmPBx6R|? z;3bc^#$z4FhP~J8*l9P{54dDt*kV50dOMDE z74JPj4fsn|8Y)jFXM2IKnx` z>T2Roh4d-JZgg&snKhj*BqX0SJ5l-MRxb2zWcOM&&A*kApSbDgNH+Xqk~Hpo3Yjdr z!s)lCSGymas_E?P{n?GoS103C6g(B~r}JJDDrmo|N4vcYzD_Kj8O1MetI|M(b89C2 zh4l{;UBc_Z3KbaHM8u4`zYVvGqISY{dsZAiS~xO{SIBoq;IuGmeb6??(n5JRCd(sR zmFwNm!`*|uom?{5hQCIoRAQc9FxN2carDY@ze3M4NHM4}>@Rws7ur)tCe0bUpo1$B zaFaLcb*aX0&e7i1Dz`zM0ZJL6J&^Nx&Q zeX@N4a%$ziJ>o})y4oWZKqzX}KK`nRp{GLQV`+-GWHZovGl%U>=U9fCh%3|SF0-$T zv$+&2@|9$}z0vGqHxkd|^= zeVhD?-Yc7IE$w0sji0KFCgBxx`@BTsE^73lpehzctWJ@Qfx1ZDW<*O{`{=qR#&b0Mb3~A0P4L`5c>GZ0p#qQdPL`(T=@BkY=)v11P1at zF`l2b;t>E z4!h@c(cS;j*}oz6QC8``zHs0-@)wB7rO9&s1u^;ewY=?Sqogl88h~faT!KWGvdX}r ze+mcz=t{)9iz?hie@3f{U%eD50rXlf4t)Dt)9*jsJLJuY2^`}EM?IgZeJQfK7y$3+ z10z!@a`mhB6E=pLjiutyW8m=hp17LX7no%}ZSD9Q-S;xgdOi6Ks$M$@Q=zAf{1&fs zicdb16RNOTp8rBC?irh`Hd@RarD!E`(OxRB`fFgADjqi6)g839UTM94ylZL~9UV4X zcG`d>9B&M{V9C}*VsckMch%NC6B~wZ!%b~^u?n&yWV5o3I*o*D9Dq7kI>JCl(t+%M zwkamN{%b6a4YIxBB!Yz$Eh|gv>HP3DFsJVHCipO%`h2F|FDc@i?5z-<`jCpw2Jz?H z4uuAiROc=^M@(?{S0rE&0rGQ(RI#OB(+n;Q_ORgLlPMuZu$Xy%{zh1&UrY(%th?7c zzq(mG^{342D(oHc%1Sx0OLxp)7qxMTYW{e1eI{6(fQ8e{)zWIUiP*?<|$F- zxrcn5-F}vwZnMcSsQ|T&~>Sci~>e;?AA$t`F)FlVD|ey2KGy?xBZx>p|7Wp zP8?sR#xPYnvf-OKN);G-@VnYFniV0*qC6|e_~gQZwl}+K6n{61?aKQ$X48T6PLC(% z(=i`?eVc9|y^Z@KP7IGpu!G;SjCW6D1{V4X3SUmVCD`oQ8t{b?Q-Vb2kr6u&CJhc|v^67UEL+aarE z03qm9i>c%$XdbstYxE^0V`a}V%iXPU9%uBbr-8Pc;i$1a!rO#Y$*X$=t1Id8hLrKw zOFu)e?hc7l`v)xd9}z}Az6i9s=aJu77RFf9_P3fx3E^{lwl~~wskdZ zNmPwOc%%pt?7lLXmANW>o^{5MzXT7vo3KoCu~L~*}F8akR&nW>MOtC-|+sQC@?=!VTiBZ{zutoF7Z*FYGG>-%vSBIl8H1gq``m8{Q= zZcm=Ra-`cy@LLu{7>Vd;%ZcYb^0UY9l!veS>gA-+Xr$w9N7oIEUiJz0Q;^qow|436 zWk6t)rB&E>C!KdL(yy3x{S4rPBhOs#5A zWjLc5ntr)%rh-6OYb4H8$+EuH=M- zDhe%_B6xSyo>ob_kZx$29T3H1;7m z{@NepS1&AxsL^Wv9gR(uWHq;U&bhHN^t9BM&zBsHEzU+el!(@Hy=vK7X3o1Z} zRC}ps*{PL4?f(j|%ff-pi-yGWFL(%b_pxU>lZ$nZn3uXUgy=Qi-R8m9C*a_jEyhE9 zrXN{rm~yQPGBi-!YnYuV-z10^x!tjH$E?}VZuGJAHm8X+RcdOLrN?Krb~b2+$a!ne zRS;4!0QQ#x{y>{fp~V4LgEVcxS?Zsj7GOvujtqv&IELMj7KXpq*67nUNT z^^lz}3T-TT9EZQWSy!^a6hB5{4lpF!-O$y{QFW-%2C>ew2=h;16LVAg&l*~0A=Gymi=~e;YG04E z>sWs97xk6f0+hWJ!iF?m&Yas(PH)kQeQadfn_6?Va&a2(N@M7Gz=CrPTIj=)=gPW9F^5;^SvSDWw+y>j?D z#ks)|`&*F{$^OjzrZ}hK@j);rzuy`a%*OB(8i{B3aK=#57{9`W9HQI0 zOxl#=fyL@q>{+?IPYwll`N{3WMLpax1Fqhy61x_zy&85W+_$M)6lG#AkNDL)wBn6V z*&>{!L4fcllA!uKJFp<8*M4WjZwsG%DoW+D7ggQ2*3i6vh|MPV$9BWcJ-&;U31 zZWTbK?0u<*8q#PFy*RCAXduVq!pU`nTs5}*{OhPcnCVXmlfm8 zcz~raE=>&3YrQkLd|284>*nCpd4A2XK`g%rK^qUmO;># z`MTt$4%mW>A^yt?fIK+*vJ`vJUvBFna1`;&Wo#9+@rV?GD>0ht8E%lG*RXM2aIzio zdLh>PWM!3GR4f3+G6k6rH5N5n{TkXLYS(&YElgF1P^)i3@>E+Ty!S1*!Yt!^c3-el zckh(oLQa6|N)-SlhlZ9Jws+i|?Wo$HqG)$F)?x8Au%wfKQKzR9JhpxPYI>q)M26pj z1m21_;lS^AZA86=EMpZ`P} zL4RgQEQ{Di-$S|%(4yG2+oUzy=PazBF>=`$Rce+nu;`pf(nAV-iv%1!aE_rjgX9X~ z2=q>{*^w*QOJ37rAqOq&HQ?;Rx?eXq3&OXswQ{YOCcjE-_|ScqKs?+LL%muFM%x^| zKD^ZB<5pcAdSV=Sgr&T?zvy|FC%WQ8ct)Ic-+BYSU#mtFbTp}Ryq+j9aC-cb9W@YmqwQGtY!mOC7DLhOmxaQ+(8W0Y7yh+7r--ob~;;5gIw&wc74tw@G$CFTgnTC0(0svwtKa#gHZHYWKOfR%1B{SO$CO z%4cQPYr%TDLAk16e7db)&GOc+;Zl(aH40lk@XU$0_m8S( zkCz`8;uKv9(rE1NKS(ix5YKyNnexdjuIB;vf+7>Ye+iCf+B%Gf2G$!5G-z0w0O;+$ zQHZISK&Ce)eOMG7>ND!D4uUE@lUu~@_#9G?*J)?RnRCeW{hgYxLo0%Alrt#Z zuAFxA!n_^}y0YyQ87(-%`K-7R_x*zB=0+6gleYmf?kK%#tAgi&n~Kcfs=kI-%}1+C zmDzQ20BleRoNj1nm;s&Ae}}^K*tED}x%D-=H4DtReUbksu-6#Ay5u*SR>6M(JJ9=F z415%BE`}4q%6NxujZr|y1^k@hIKa<;fjj1~5G0v#5y4N!UJwjY6Z{1~OkVmkYTe0!MYrDU5qR51c$bm!H9Dv&XJpezDo^8`(%pg)Vz{c-?;Uh27VN> zKPuop(bkn9ZW4a&`Gb$6X9S;7kKfyNi)ScQ&+x8d;wrBagICGVZk@c>E)XZa{BCM6 zCaWfsrE_zny&(j|o>~Bt)h8TJeJoCBI{R{Kf4rad8oYs$*w#DN+kHwBSmh?NME*?( zg^~V3RUDe2jvYPbh=RXCI6#mAED0?iTg5CV!@-XY$%$ez$MvvaPxPEAe0!iN& z*qtvH%4xpkw)|q?qKt2*e5vztyp?fo@~9*8R_tnK^H@Xwb*W5xFMM*m9o6A3!yqU)xA{nAP;u`)rI&{818$}5=j(y`&bAr#<9f6K#3gEBb zR5Z;tB&LE(?Kj1ie;#?`Rk*WrY0GWtfD>@;IU`UjxuZ9U%Wo!;>RH2Kb-1j%+Ko`U5a`+)p*SvC^)gIS7^O$x z6EFCgFX|U2lZKH|%$xhdPTl={NUAy&V*1gpB{hEdG}S*z=e@*;fBQJXn4dp)yQy79 zk~P^P?hFiT1)O1b(~M5@$@4#6(DO`Z*J|!m4@4Mki7FF)r~y7lr8NQ9m$Ah7KlbkDYJ;2Fu{whgTaO@~#i|yn<5tF|LqnQ?KYO)y&q_o|IAfLvK2 zOP{$0`dbV!2q>P0IC&#dBJ*t&g3Z?9( zokt~ik7?T%z>PKFMzfYDJ~t2o7sY>c2znEC*wwY~u|}UAETqnJ?5EtyIi}N#v4~Wi z-HnRAF%&UGWpxy%)J^gz$9tm-G@6HCC%= zuG@+BbKPw*>vCsAf z$!&wnbrIckC}3t9lvHn2(~G$ckv~_j=~(-y!IL{Jrj8{!`|uUoavzchhFn+}yen`mmn9egtdcYf1{`7jl4yn59f$ocPH_kxJeKz6Q{ zVT{gOxJk8gHJw6<706rU~6?tk%DOfEi$g|bmgEDGk+_TgwsM^UG!S| zr&(RqN1o6zu3C-h*i%-sj?yi7LGd>A7-N}x*%E!0gz77G4p<*Ee=R(b8j?`E%-whO zjhx>NAD%nW(P~M9tFo9+bccJ2Y`w$TAA>#?WH|a8*^D_8x~tw>mA3QjMqD*GYs? zDm(N>`0soP!U#lw{y?7P#n^4sLqOTXYIu9Wbv=gQdoOxD&^KS?0i1;nw1pZ+)mi9&OA^@RAiqVq}!FsN?> zh4TRU3sd)^(46A(fnTvHNZKatT6-GEx){`r8Vh6MC%rOx6fD=}Rl@ zIR7Zrk|C{jZQ*_mtZwJPbcc@Vha}-zw-h$>#sV^-zrx0Md>IPyxOS2$pmdsVdHNl< zh7_=}_d)C@Y#GhI`4IPzt7AWM8ap|~%TRI`STj$$&CEqU$xW2R39NImU+0SDgJ^V@ zySBR3*>_Q>SWi1VzHOpZr{pl?Ph@?R-fsd&;Hw8m1?_(0q^xevn2DM0>eO3DGrx)4 zb$?;=upY}1dK}v_+5>+TnaO1(%yny1%mL z!^s7!DbE>{2v9H_Ji%2CyO1)lK*Ysc-?M(!C?Bw_9uYi4g-c1VY{sHbq^Fa<7kfmG zqfS5RGDEI08t3T5mIxOB zl0nha0=u9|$d<^o{|R<@Tj+RJPoL1Bt(T30JDZ!%KENMuhz(u0#4Rw-R&gch|0?!w z$#2%>zjO&rG&Xif-%t&yIp&tICfXgW`bJw(nbY_hcA#V?fK_Qx@184O^{nQK9AS#@ z0_01y2c=I18C_gW^66_rJQ$UD04+3MrD%`W>=bTXc+jiFEb z-@h3Z{P&^c-UH^FH@p9ga4P)J^IP&|t%eU&foYJK*37-ZZtoisVSIm$4E5f-;C2Zh z>;G!(0^Qz?N+52|NW6jOf78hPKl}3ke`H4kvk6es|F3U+Fp-d@KI5!8pOO-ypOLNFiHY=PDu2^u$uy|JXg)r} za_mQd1KTL;CM|Xf#lJ~_!A!TjT8GAYVNvp8M;W`c-WU>xxwCA-_@xc6ZPG}8%;aao zs-&b&dG4QYy$$|8k~yxVW@SWoowbWc?*M&jH(CP7b85!l;Adk$Hetf(npu(ali+4` z^4C};dX!<}s}_sZfg1@(gyGfph1d$9<7xY77;Iy8l)K(wlyRJE^4!D$7^;y#V5};> zo-`#?t(2<5@agZ^Y$aj6$<0P0>>lc2H4THcWn9h=yRG7Y+iVgFumCEv?^Se>X)mPq zWtJiH3`ho^!g&>ns0!o8xaZjkTaTPSkK2&IE|fpW;a-|NYol}lKjo;lfo51kLXGUi zOJoWQ#x&CaXE}z&8jwC!qYC)AGW(GxZm8_Ec>&A5^jpOi^#K<}pf)4YkkDP*$Kzfd zSZkBg9kRaU8}6Jdb4RoDjvE+qk+TQM$+ZWYjdZ>zxpPzxjLR23z&XP{_<Fx3` zI;4JVG4G1T@X}J426)&u-pA|I)P+eDmMH%^W{^`1@vN=~m*PDJvpA^0(cfewlva~s zwD}TuBB88OnOFfTq@&nlZfY{m7yHzTJpU?o)3K|kb9nMrp6Dt&ggUzB2u)kQL8A}UU7oGjMnsATgt&s&hfXDx+QLs z!GYa2;QJLY17+Lc`e4u6A9^x~l{6-Q={fJTq^ zt%SHuUo{`s?ORH!XP=c7_^icD*yJmEphhSt6P{?6$}u8aDwZx z9ezil3AC!BymQV9kV-?gf=TbRe0t(oM@Jbj6LxQq1;kypm; zto7bO=&$UxHvQffKQpzG39kwvhbug~$L+6E0KAp$1t5Rjnt{<#dqd@8vF)ck1~wdl z$ijan`33J%mU80z zE)lB-2EcEt#vcD+O^=bw)#yuY>3$Sn6Rj(XDzFT8<(59sR85j?H)=KB`K)-mCdhlu z5kQbl4&cDeJgV_)QX`*`TpS~TB%5KjJGpzjvcHLMhqoPAG+j={^eO3?`Q*i8XM549 zp?wT!TAq7T27zTk+RxR4bZz%9d|;hhv(1G!4~cS%=s=No25Yo!_r;kShmYuiyRqUL zpa9%)B4FZ@)jCF~Ze2&->8^pFiO*zt%)-mrKR~@-2hcE9tM|(pW=H(ME^o;{qvw0^ zEE!>myW(@F>-0^|Ag$6P4z;&rL=#T3b;t&PGUlbYL1rnii>WyZo{jg5_A5{QpzXam z=f$M-{1Oi*rwZt1+Nfq2usZ@98xR#d8TV-CJJJ(R@>7M&>5mP&=uS+{h-^f+F`W*V zSdHfgr?4OSi@sOLmOJ6*1b5Vb!a`d3K!@@SGH~JW(U9+pFUm7LT?_td_@vd**sYrPV5Ib*XxGz?y88W1y5j@DGhJ5j2|M~{ zE%wl>?atL_@ml1pISxs^H4hgg7>N2dr+``Mf4D|?LOZyKtI^c9cga^eZ+_z*EK^o-uK)t#>>sGatp zjpW}CNRPg(zBKRBrInc6x%{7qX7}YL!=kcQQ|0jKC0DRpS?N~#qJ&ZYqib9?ecLz41|%(}zBn>ENFXe}p0 zo=G}1^HxT+Yhl~gOb?{iLNYotcrblV)#ER>X zw$%oE!0(P6KqrsR(-ZvToKFFtTmL823w0Ya>IK`{hkHt963CgYA9J(fj~}b~iW}CD<5>Dv{sU zdtrVLA7PFuR)+Y9+T_knlVD-%0Ur^j9-XqFxk#ajb;E%Ffn{fptNd+wNKj^ujV)(j z@3#`|;SvdO7h*M!N#Szq*&W9$0#s~yOXvPovE`{KDzf}{ec=~YJ`hM1gVASH1fbc; zW#IPrl`^QX9Rp`7UOh7;lRMsy29&Q|FyOTcSb=@Z9`>UF-JlrClwDv{a}!WBesMWl z!)sT}Thbo@Vn<)*Gx6XkV+Tq}@2bo++N$q`4R+jGGreDSl@M^9Q~e8u~17 zzH*@saDtQcIohkz_LgvM{`gH)t1XI?RA3|}V%hiHAr1~)Mf1feD)KTgLdMMzM{NxE zsl;XxRdsb?#6@4ElPGUI2%_4>RHi$3Na+}Aiv??d*SwT|667B}#85?G$hf92ExksV}T} zolM1F7xe$v5&g3R)qkZU@L#xo?P)smJf($Gik>a{0Z#uC%^5+GX4LE6>A<#*-u4ud zNGTz;(0_gzw;;@&ZXiWfvbk2VxB^lvI8dFixia|qJs4n7$m$H%^jzg+TslQ`$n?hxTQ{ifJF#aGv> zh7#v;UY8j>`r8pRe`J@csl=6-O=Iu$YbG7@K0QM(cjyS@DbyKYjmxmhavMpP)K82K z?@hZDq=*3zoN>$S92cbJp4RD-GrSo~Qa+ZL=N7^3MpUCW!Zn%RIuglGt$GWwSf&n~ zflJnj+oH2)39z?u=k2Q{I4{2EO(48_8VZrJNm)Da?pINm_!>0#iMl01>0zYDX+QNT z;AcP--T`GM_``44{?u9x`=FDd{|Aj25aSJyA8D@`i5QO|SaP_7uVJ3l4KDA&y+~~+ z)l=`|gp{S7^f=ZJ+QUB}JNpBLUUsA{>R^y%N!h`R_tRa1c=^*$`Qgx{p3flEKt!H>}2?QrG4a($(cWbK^y9fq-=W=83JNGdvD*89 zzcuV>vWK$d*9%-9$Rqglm8O)MBLYJ4q?b^xO#BFzNkEqjJ;=*y}pTRn8 z|CAVi9x5^oOP4vkxM@NCP}kg>{5=v`=0$p>it0no3zaJW zOtgw>MpQ_IMHft=YuF7MU)os0FLG5o`bxc{8(?VlP`A-5oQIo3U$R)mOY?jC&P?)y zW=CBNMtbn_m(??;D4JH4&5L~7)hr=XR&PwZjTcRgrHWUsH6;aZH6YN8>2`&o`YmgulI*JnOipwJQE6elI^v znZ8;*nv2l)5hzxLmJCrA%&VU3!l4INW$*5H=@gdm%HI&={+#GIaWAZ3t++&pUng`` zQy6-%OhL_^tEZVXaF7Hx*jAk&%u@f=*cPrALb;uT3HQzWQUkrAs(Iz>SMoH04k-D2ME+idTkW_%-k$=Oz8&xe_tK~5oswN%(#ARhnhyEy| zbTQej%pR8a8X)gMY)RJRstR@Rvh8CA>T;e#!p}DMtDaj7s}l51NW}<#usS3pVg>u4 z>46F+zHLcRP*GV^L#MvDY0k}Gr|{gQ!7nRcM;0Y|uT3M=Nt-g&+B21x!eG%IA|PT; z<)+7;)GDGSUxdeQ#^P30`JF%Kpi5ObdQGWEbfJ)Y;fGaU7GG5RU83e=ylqddHgoAp zg|?TEqggxTa24a;&~W+^azXY4CDD$7(v$L%RZFu<1eM5o0a9O30v~hZ5f(OXi{I~w zZX5xGa2W}6K^zSPA)3RXq;7=jU4*!#y<=>Kov%>g%D}NHgUgqAZJB(OY zp{(?6x-*K$62qpI-&0F}$3ImtxFBm&E#X8{3i5Ne)uSu$Tl~`4LW`x2{iovMISm6? z?*w{9ci?mWYA%oygn8O4?O1-C;HWLP?WK@<=+duL$Ao##7T-x!6D7~R=@9f>#a!9k zO)CYv|j z+Pk*0Tyc7rrM)`jp{}#hrq9GZ(%-KlD5#=Z2k_R^y}`B9s7(hKX)?p#mMyU5Ewj9Y zP*3Af)j1VA1KTUd6Mws;8fp`2N&01Udch&gNNf!Y$UEk~Qdxdwnbyi9%orPpcL}Z?qs>h|Qy}DA;%+tslI%==I zAGi(a58D5|m8SUO|7%rzRxKO1c|QD5hCu*B8W+?+t5A&32f6DJD_ z(WgFuQLrlDyu!&lQ~i(i^eBCIn2P#~=FndS4^1WR&p3zszxFelHP!c~@L$HfG`=-V zuNcW+yZ63kp-p^QK++G4Z=`=z)hNO~5ft-qmuL?gk)pAE7qSo^E{9fY(PWWz#A5mGb~}Uz)<_v#PP9= z9Q-vRzY)mpleas8Mz|~wNH9darTf=-y8PZ!37Ges&5PUBuY$I>&x#eGP!6{bN%a3` zCc@^YrXofEVwk%7PbmZZtKH<6x9?3xZ~t@Qzi0G6|LF?#+ZT$s|G$9Ny=cE^eA&PF z#C4pV{@Mm5e`9sua)?ZklSjI)CrO)=d9 z1Iyoe+W|x=E<3{2C!y>17Q&GZEJ|Mz1>>zRfEdsCD4FnbvRbv)$UjI zLE~0(J9yBC8k>?gqG?-|$Ya;^)=F+uz(y`M?F~-ix^40dMP!jgKYZsV?oG)fr5{!D zW3)cm{NWm;&aTLyb{!r!#j~Z%w=V``n*20DP|Fjr#MB>@3#o{U#v` zdFrxR)!x6{_vAjj%qK}R6_<|`^NX3HN z%B`dwa>G`~u^2yNNYxR3?!}v|W`YEtA*bh$fC-V(Ri5_Mk>%0i9A5D}y`na;>_K7c zB?c^YMa*F3g&}*WU9RtW<9Qx3m-RQm000%CddNI7WxGN=ShsBLOqRTxoORoY&9GrX zb}ls%7I`_L=s4uH&{|wHpjT=v+2prf@skThMZD>K*Ej}#)KJtQFuE{u2V*@nZz-1V;A3UJqkG$1KOC%j=6Q~5 z$r+t~_x?9xorOz*n{>xHXqJNakwpc%th@GCLe*01>s4p(Vn)puT z`G(Os8^9ytQ`HdHtxE~P$rNPFm zhpvMbBMyuZL&%y_uY4!csmJIz?XE(a)!PFk8)MT;Cphen08jVn$noPaeIARoijT>(Ec-3QG67 z0|fiSy|Tidl}#qXgdHplLlY&(e4I1BTy(QR-Y*nK$0mBaXAn zYmH&olWbCa{EiZ2024HJ?V-^yvC`VYYy>6SjlB3GRMVjP-|8!7N{x4E{i?n$h9?I( zFzR&$n2FThr!<$IcLoM4utCia}Sf!xK4yvpFtTkI)^1mh`W<;C@ z^6o~2o#vD4WI{B0pxxe%>a%)TgnucPgGBKJ6F+T zZpKyCH3qM*5IY8Uu{ZqiZYH|;=x)~gt32C-wKI}KliZ<;+PWvk3jqjCoCNFRtn$sd zF+4kz9rC90qMFT+x`4=5Ji%*zZ)WAe&=BLPSRZcnbO{dm`n#`Y1ukJ*_ogdy@RMBG zI@q*M^ye#?7hg0Mc(PEWS~sb(jjh4q{gEf;mcpz9wd*1+$$6Desgs{6`sb$?2~6n>x833w2<=h7HohX*R4Y2S-nsbmRajK z!X1Ajhqp*Y44R30{2Un_Mb9jY(1NZ!BA32Re5`2$K@T`wR5HUa?NEyz?LB!PbyKhO z<OVUcQ7I(6S8qoO)w-UHtu3OcyZDSMatDvXJ%qt*T<#LfU(ZPo^X=d?BYpl4+;YH$7&_kYA9VZ%qWEvE9+$p48{}DoC|5%}jVI=32fA zGz0nS;%($sP0uHPT7eh z19}Ksc)r4{lQaslUKL+9zy8!SJHgLY^K-T(?*8q_m-Rl0`}ClDv`SniGdviRinwJo zW>quM3iCQ8#LrH@)VYrrRl@}_zKC)*Yt!;XulXcb5BxqUe%8?kpjZF%s&U#1=3G@r zl}1RdCT`JZWfouOSrgb91ai58aPKOd=37qSi*Pi#%b;T9g{CX)SwIsABq5@g`Z{s? z?bX@Ym2?F8E{DLwL@N(EC@fdgcC!ujJn{N_9)7_Yg9mLlW8J+jneaeguqLz2mDmT0 z27X8U%)@uk84GKDTVT;qjn+Jvt4L?+|Dl5%PsrJgO9s0imDvV1{qUKoob9n45&I{b zx03l{95mR9e=|rw>tiagbq&pbi>wi$&iD_r#=(ff1$pOFx?zlSmH*k6uyh7VY#LYQ^%w9vav-rB-n5%9~W$WuPSZk+_dDk6&JLj)xUU0Q+MLLbu{HBY> zkR9 zyUSE>aTWBO zb0`>K6^zgx$zINotQ|tI_G{~)a`oYKjaLpqVu&h8yQ_~ef|`#lR6t<6?>`$TTDK1M zIpwMwHm_v+eFe8HaFR8bE~v^5mxj|lB$8HSpd{uVc$b=2`!{39g1tP4PEh;l-s@k6 zJ%^X|W0*zajluQifRTU3k$(=F>!M^Axv zl+C-6Clr!9Jlkdh`usCNb=w*9f1uUpSX~!!yXIC$M5VITR!hzln;FBx+5jyyLQZQr z?O=^oH6PE=grB-MdVJ(@tFnO4!ko z+&J$c#qitP5jLZxlm1%+yCe5i^G6IW4ByrLUHF>%+e$0Qv>6=xOXZi#QT?$61nB$ckgk2OZ?O zL9y~?{4W@n#+Rqi`a~@e>r5VbY6|YzVoGfckpk!hXBQTH!MR3^Uj?Nf{Wj}${-59d zUk^$DkD=ked|LjPRR(-Uf_~QkTLnQb2356v>(Fr>9Y1G(3+U`djJaAL>L`VsGK3v@jbc79ZuA*Zs1p>hN>+e*gBy`@c! z!Qm?OJ)MALq<@H{H@>-{fH-F>3@XZ?m+-53TNL@VAQP#BXSE%zM3KaBlZ`GC_pDGyK$ z@|?oz`x;&qRWJTQFRgWqyEA~|Q?#7h5K?^{l(8ew^Inz;o{?qPKcw&dwwluaUINV{ zE~$fATCc{gB4YIBzQCD8x5SS3Hh8Rbcq*~;h9-!D%wM#!PVG;;k-UYh0)x?B?5C39j3lNS>iH29pl!I#=b=ISKL5{fy=XqctJDucaF` zVpQF&Cu6XlrO{oB!34h`&D!Sfj&f6!5IC8gs^jZ$bRH=TXiCu}ezhe2H8w!_HP=4MtUTHJX|wTHp^SX z)1s$v2m5E8;;mf%fx-S>OO68r@8O23@gqcKyWBq3Q-(e3s0b;%(A8{puz7fJn0KRH zK+?sa)WJ-w?AX4Q5iQ26ze54?^M>Jho-d`Uuv@lu+c(WlHrB0#pttv7>=Fk5p>^_D zQ~1}$33vA?D$yD^LZExaCcHECay3mQ?#dl3W?BuGVn)ZtAbHvx`-g`e%l7H5SBazOWT9I8tFp6#fYVs3dc%t9W=-pO))cv>@PX9vcyIL{>z>-3=p{!QZo4L4X{Xo*8{T2Pq6vA5 z){>AIMy}_JTAl9PgD_RaF zL`Ae9;@ve?+01trH(T4zTEG@YQjtV2cVbm)a;KVgnbjKB@#ijt$_mX z5 zE#DoN?MW2Rx^iqz@#8Oxo#>Z_a@|=BP>uhg&Q|begV;?kb%#NzP$xsflo? zwb^1D7f^fqb<@G|@!1e~?O+2YAK;a>{A#9{69vi>X0A&4kZak^ zd3bqO0<1z2-Wv*KNU~;1N{VHJfKfFVaMIVRaWCiA$$0-z{Zrcci&wIaZ4Y@3L#gS{ z0{eU_Jl5-W!MU2OGp|Xm5*!-Ik`SkbZU`6*9$p6;P<>zCUg+oFw6SJbLmlprKHlO2 zE-@NKpC0dm3`#AA*G2tkuMZ;7$JyV%e=nWT*Bb1fx1w0m`Dp=>iaAskG20|7askR# zCRhD)RCx-}x3O#xvmJc_Q1^U#uy3W36jF zM~gcNg+G4JY6^Mc$^W1R)8E;dE~+tYfEvaok59aK=647F=M|f7TQy@7!yLvD-B!a5 zoU*RdPL1wP6?5#bxH2r`hZw(kB$TvNlpZ8qZ9B|a z-Uz#2n*N37pj+CEyld030)77`0|-$}Sy-OVIdEal^Vqtx`SYhTj=uO}SpMebrf%dt zg+BfqVBS#$^X<(*lmouJeJ8=Dm?SMB{-yv^6q}416CE0l-q^C~kgo9_i4j25JBh$V z%M%KHeSOtC#0{lf<5p#M$J{2W$p2mghCqmVKU6BgK?ddR{TQVaBP#MOLxZUCW8Q1_R4`YPdf_ zu5}Q(HCfU@+F0dt0%;Jo57-iP-PXN&SYdJUQ9Ria4xqh8jzr?g?YReG{#C6$ynt-Q6~r2=NYv>Pm3IR)07>;ktFR;0G6KeF9TTgW*gVwrK?OYa4>=`-k=OiZKP$dofdxe^*7|3H(6C+8u4{! zi&~e{2A#oZj<&(V!U4*s>3rsTRvXmji8NHqOP_Agvs?1@&Na&0$?xi0tVgdtl|4Ua zhs3{9%O3%Jbxb1%J&slN>D)z%>!}?&l*WiZw)hW654^j)q1To4QEI{!JBRMcE?ZN- zAuR&tjBE@}j2V%y5c*!~BbH;#-cywH!6AXT()r!iy@Q98J>6Y>6g7xiB9fcm_<3Hd zZ0)mDk3qg~JfFOgX?v{gI+kB_)%4&_<}*F!%sgvh&&FOZEDvsv|ir zL*(t95~ixdn;jj}$%YfjTlldc`ch9}Z(_B*R~Ge6fJ@y9lINkJ8e?jvZ3!N^)0~ug zTAf?cQkdehxT};;t9jS-^q4r@;Ld@A#SQWdND|yskmrbMcE}v=Z<{;bBO?a94Y_5F zt&qW0TA~k;-$h+W(>#3r;zY%%s6Lkq&W5^WU)o;rzHEaB@gm;3_=VPcGw<~>jliAn z27af(MGra65RWQD+S3N^04hRhl(E&fZ#@JujCFF0;MPPAL_TgsMbRws!@Jf-r;1kYKNNzGwdB z3m1r%D*{s66!T0ldC3lSpn6s2WE1S9oj>wGr167Q^WYnn?d7O`H7o6IL;m@ln1YF? zSEZw<$Lu&4aVx)*J=>2N9p&I-RoP8(LzAR?$>qlcu#*ep&+_rwSx1|Gun4NqceKxN zae>Czv#?vw(P;umH*@8YhJ-xlS{JR5nh;%2aDSxP}OUyW6B^`E9L`Gq5I0od^iCy;wG`zYlc zmb(3h&sbJ%jNQ3!oH*V?Mrwf`qml&ghYaXNF9fwa?YbFMamsU02sd+9j=||o+8U>; zZlT^svYbaJK{=<@hPgu0{7VPPeH&eEszJ!Ccl*+FpZxDE)L(3GZ|qerYhuQ9Iia?7 z3FnqQ+Ay(eyBp#Y17c}K2IV_3m2rrLhp*YYTekMLRm=_(>kK#+iR=}K>*BtTT8 zg(i_A-A6=}-cefUkOT-V^ni-=4hfO2(g}o`(8HcQ@7nvkd+l}hSs%_idyK=E43dnI zIp;mgegFTz>$+;6e@yPhdy?OD3qk60)6)a1UL4tnwr9HgzFckeg#A=&tC#?+v24%- zhfW~sW?cK*vvMz<5Qz1`(_$xuhKe_3fBvlgQKPNnondJDdz5494-Kt?F4`RtWpfAF zS-D^)gkM=xCgZx{V#UYQeb-O=B8Z(EoX5e%*0$-NA^w*V4Q&}5d`qng@rBRDU(at+5hEd9 z@qS z)J5{yAC6ZC_6GqPr+)68x1jN&IDa?(p41|z=GCF4NM^a{O2M98CcCMSXJfUV09yFq z&mVR@Y<4{P^}`T!fyK_`iT^O)bv9S&7SvYGxkJN@iaERhUU~o@rZ*nqtPR z<*CWBuZMGx#Kih_TOOGYsc~aEjtDBNdLPUa1?M+S-ze#L?R0=l^SXJL5`UDmKy@!Iv0CvSp}c zWkYb(K_m%Tcw5})z`_jhW4sqL5rfh@f_JUPZTOllDUkmh`kt*KT13p)BECc1 zWuDf7EkNc7Ig{knn&YbHZg+m{kC+(x%xslRFGrP%JO21&w7Log4Vk z6e6u$KE1B+ME~E`h}q7WEDHZfC_fjJRb@oTs_} zv-sNg5cR!1FYmJ4&!rhb0S9Pr)ZXn=6K^uAov89O^z;Y*^eiYym zE|Cue%^TH8687z*LKI%HC1ceZ_2~z>tYQ{^hMzK{T0yHE+x`?iJgDW0kTGiiYC<(z zYX^_C6Mwv|RIQrZs@o@fvMcVZDkg1ub+3^oxZL`c-^V1 zMb~iV)W8B&aAz9D$Lu-#1Ns;v>R>9pU7ge2dsjh;Oq(SGswJFehIE43*!nQ@KGA|! z`dD0X;HTYX-x?&(r5+I<|E&xOf1C^L%<4J{RjtQss$#IPCBrFpkQ#ExTU-LCT-^8B z5{Fd0F0XzsC&K?zMbQTJp|LMo+PimC`xz4cRry(k)Jpa(6(ab@Zcjw@27)~2i{yb1 znGqxW7Pl#OsmEIe`+=h>{3)*=bK9_EpK&jvvs{rG)>#n}!Ih9M2i)S9dgLta=dfSd zC!|XWO))|_XI`(XTXZgx=?JebV(vmvY0vRnNwPs#d*i(=H_`TC0^5(?q@+)7c8Y&d z>3eptz4MK?>Lrnw*?Kmerlf3~N6E%uD-PL;x!h8yGsfE1#Mw$54%D@chR>dmra)cW%}KAqb)eWB;=J89#zCVVz)hxLl+o=t z!W~#zQHwKrLDf6^0dRJSEpH@~K=w$yyA|_Dm-SmX5kPwj9oMhm-?yAe>j#|*Sogj2R zgSBbNjtpe4#bMbr>P-N~FadB!Pv!aB9Ua(!ZU)L33W9J#>H{s0eP2=9* zwCb0V`1C|{hsnqAXk9bo+j`i)oS$9#E=HksWsoc>JWQi>chJAWou^*j`uk-6FF1yy zmVm|Mqv-2ASFs-k)bk50z<*oVbJ?}8a!=ff=CaJr%X2(&!5>V1(W=ScoeEE?!6u|z zui7~{G=1PId>nTk;kkW3`0S~h{s0j@0~pT>K!H2~edLrV21LAf`lX_Fq9Y11C)YhX zI)3l;zkIDS^u>R7ANgP0>41*P8y79Y$$9%9`pEx({{BxMwno3urhTe%Mx=f`5l|og zv;pM)ZyGHAFQ8D{Tf@e%q_BB#=Oq7cH2rjqK7f@5?mLLeKQ~IZOyqm#KJq=K$rMTB zliJ_8pAjw7efm_b7Qlr5EKST49d1Lz(>gh}pn2h7MnX%dG0yeZjvsmy>gPP@!T0A} zqFl?r@T5ldA`c)gALj8} z^jaZUnVuKiXF<$2zXrND?{uD5E9rGboJ}zWrNBuathX)??`0R-E43SKhG22r1wpVi z6Gu<|KLH8pPgP(VUpub8N*Y66Wg!ndqB`$)w489J1s~wjw4}5JrIN{4+7cU3&>x^sOGv@8rNbVm z`NsFI5vJ8EFY#3}riD^4ZegFqw1)D4oqxIsvZrJ`9~^UcATMb(bOV<8_Pk_q>fUlf zxOPXGuG+s^)qA@W2`X5$6@3J8PttgXl&%jgwLA8U3Uc~z<|qoW;{dKB{t=al)6vRF z@HF|o(x>6qxc4GT-bz2@t`gRPaW1)VZ-`p zh=F@QkH3xH75dVv5^cX>>3b;=kdP(Nkdda(5v*qGyY~1gw+~}Y^`;G5q(Q*_UMerH zMqlhxE|cCg!TD0O$l+UhFNPI6P?YWNJiuINTI9q@C7VH;w4|5u(Y8{X!2*5#$cD1> z%#L|kjXax%zFsTimbqGr*o|B`rYlekp>TjrbREF(@DVEdtx7t;kba<>1q68sdXZJB z0WM|r`qQX?@NHYq{)Zf?EX6vH(krmM`uSGZbTLY^(GmvE@pkIT3$Bt-pwCOG$(R+s zSfD_tTCmG*kjGPfq+=qVond!^`xvYbJq{FNE+-Tva)SyYReg(@=l)%QSC6 z0Mv7r!EL-6XuNo7yZu+?T$?0o@9?^;R^m`z!W0~)P0wWd8;@0kd_GVPDdtImeuoEG z7o$Em+X8&(Nv!OP+^PuwtpzCm%Irmc0d@&&9`Z1qYxZd}%<&{c49lu;HQI3*!%MF8 znp)mmax6L6w~OMsnkT`FFQG;>EIrw|w(l}~MpW@?er;p~q`~H^o!?^N+JVzD*}#cV zo4tQTzNu(&-xPV+XwA@fCyzA3`aiHq1lR-jnkIoCs==NACpVea`yDtzC@=5;yA87O z*CNkTiCS13QNB%*^q<2-kr-MrUBlV7fAOzu{5JJnDTh)KMhQkMm+tjdjbVG45V1$+ zG%o+##AODD#r&asyocG{hn2}_;vU2CgFl~MR3bP~zdO>Fa!{(**kVwz(a1iHv+ zwpilZ?p5*Cgkvx}?+`EfJ&5lgOzg(cy-mspGbTn@a{g`NM8#(t_`Eo5r{{P=cHEzx zZ1-KAfv;&S!&*%%NpM+IKmZ!hBlL|*p5?_!PC)T6f7K`*doGLae`kj8L($au-x=Xs zwAoF_8oSDPy0sv$o%%TiFez_blFF6WGum>j$u+`CBTu3*ED43z+vzU&~QLyu| zeD;rb7*A8Gr^%F6ofxz-P?n+kDBspY0uCvB$5gDdct`FPwC;dGSihi>CO<@`B!KSzsK z(ePEG4H9P_W-A%CGERB%VdO5qh;%?xX7LXrfN5>;hZ1?ctiHx+0l-OOoh%}5Z216w zZf_1mQ&}wpmF}DsPF@J;1(ZUyCo;?lyGDe6_teydPJw$T)hfa5*7nv;_`A-NoI2mu zg4RysPjU6}5kz?_`M+jY?qzg8$3ULtL#X;tloxeGqTMF-Z1<>FjJ-eoS&1~ z+S>Pqdt-z$Be`0Qhh!!$6X%6$?Yx7^Ai8Z?5wT?RJRq^UGnZZt>PV zv=O><@K1xpNz<*5ZOg>=6M(glLfz^d=a;8H*)V=2WXqkNe>H|+9+LvK-rO24Fw;nC zpWz6p$EOG@ZY0j%0p?$sV0w9t-C3~W%qDY_H!XSLL>g2E^UBS0mGBzyh$`5eMBy|mWqFMgIWTbD; zrp~7E$MDwK*$SABG?$6#Ji~2=vk~`YjzA?}WwAOqr zyob;%*J*)Ox5Zb?C187|A13c`wj;LeOUAhie-z)H0F*)A1jbd}lG2(ccI?_T>h1y# zhM9gRD)(A$iDTziehgrn63n^KErrZa*HD9H03-bVfgYB#2(AH0rOZ zA!k0)vNt*Foy3H;ORF&@{hk`5k8iY~0u{oB9 zJI*v(IoEGRL+`}CA3>OxuFaDtd6@*I1ytcs9`O>n8Z&Du-$$z z=%FnU|I|{3p>9^L!S)_74KPd+nKT2#pt*Pw*L`=>f9FCkXealF&@V{CYE^l^q%@kD z^tSUA$Ug?$8&*AX?XM>EFfPQVWG&Zrc;0c7H@nTFr_0Q0uNGJ))&PXe7we*x1QiZr znVL;X29_!6fE-tVMbknus2%Ig*P)I1no3X=dR^uE_SD22=(V=PITkr|XGU0&ANg-o z)6bpYi3_Z4=#manYnkWxB|EQqCNX6h=adbf8mhrImn?+!3>ED-Ebh@os#ag5U-=TT zST}e?zdW@2@M)5dww^L2@NcyS8C(SaRI;fi;ovl@v^E$ z=J-kv+{rv^^2F=ShmY?%{-N#L`QQno44s9c=*tb;J}$Qur`*fvpGYdb;r_xHgENT# zOyFL*L_&s04Iz)+0HfurRgy}@+aPySyeSt3KjtNF-#7bDke`>brxR=1aygESO~77C zS?-Z`czK`Z#4M>SnoKqOaug{wQ7fSf8{+td6X3jj_^i+0J^jM zf1x`mk`*N0;QoX(XBIGeGt$ZmNTUNv{R~Ec|BJ}KqdNhzE9Jx?=B4caOn1s)TnT_b z3U>rBSYPZcq>uCU!1d(SEJ@)-->Cklz+K7b4sfNPO8Etrf4p`+$uQ^)@ZZj#C+`7& zcmJzjGZK1BZeTJw$xVn}Foq2htgDJ#tGyN7es609~jGcE!kH5pGmq5)D` zfc}`#uMX->36F`1#V6obRxWgXp+1h(iBC(b5jKPC0EpuY`F|>ADKE5kT07wHY|X{l z<|+j4oF%m&BsF=an7U@x?)fv&qk-y4#EHA@|5gAR>HjT9Bf@iW;8uQK-Y5PqlU+G# zB8BA1COt5=sDW{JE*_RI3?HgXyGyS%`U+^XK?~n~{hM8LX}sb?aUWh+-l;4~Y608! z^zX~uGmG@T2wY83v5^g_qFg?U11j!Kdj&yzb8H$~T4~r*KH0URse_f-S3dYJhqxy@ zI(VkXyUcxsR(WhJ`1w!xjB)TJ*?32&uR^l=!daN~Cqj(w{4Dw93|Rc0ER5jmWBIoNURQz@EE7IN6)9u?Phwx^Q9 zVD7|=I-9Ggzb2a>9kuHYHn!Xfe}bRj;2O?kd7}NJ@e!ww#dZH@+WHfy;GhrY6Ys6% zf^OS9N!JIa9T=d1Vt$Kj#>Ojvu8wb((|yJd8+1VG0U$gj1sM@Clqu-Ec5gc8GNC>w zt8s#RcwX!Ludi}9QuDqiT0su*Tdo-<81mI zn}xPsCU1_VGn25K#MZRY?vS}@3H=|vqt^-sL@TK_SUGeMGU705r|QQ2C&8SjC4rve z!oWEWNJ)IX!I8nOK^w{4`fFKz|zVf$VxfwU*>yxJx6kI)$5pJy7R>Qu9{iLMM&AI;qLVr7XCA@c=<-!A6u#@ev%n6_D z)Q>cwLdXZ;;;e)-NFMBEfd?xlz@70aO|$6r@X1yGJ12pKH{mwM!)W2}7L5OBJ~$>n zY~~7|=3*f-$k@W-lSDti*bO~qh4nYWVDud}Hnz$?I)ajiHM1m}%A)(2D!T20Jlv~+ z?A*4Vd^yMIC;0bD1qWMoonHf%x*`Ym%yhiC6`>6YJf_`+@+j~*_oE#WY2SW1WsCw= z!*ySe58IG&xaRY;ylKy=K8LRbCEdN#oc%F!EL2 zO)QTp0aqF}Rv$^KJy3?`EpEmXZ3g_`zRDytku#zq0%=d1 zMKBSKuY()xQQQym9=}zm`St7RUwEr-G_!NmxG+PT@b6b#knQjFr|+;YJa^pL+>8$k z3-jziHPWsL=$9c2{C$=CkrfG1<(D0p1xCjvGb0WX zA{fwAol4KyxR3jR>I_LVk0+O2%9I_Gqy08}dFKfGCVHGBD*27pLvJlVT&ZuM5?5AR z3Bi;Uzk+CFB-R=(;#kS%uvBIsptrv(iW6JqV{_iPvpPr$ge>>+_bu;^_Hzsr#Uk>U z0;;POl=4(ytRt1jY1v|+&F-V{ZJuU_@O>{X6n|!hl*i^voZz!R$b^g!!+q?Ngt?GV zM376pJ+rT=M$}Jd#nOaJ2WVDYT{Yw1b&)Gq1=7+TfTh~#son=4+94TAMWlm`; z*39|73=ClRXA=-KQR{&^Ej(Fn+rE7QI|VeUg)yN{-^-P-ZOijM)(`Fla43@yt9mc; z2+AC5!-nLQa*XXum$g;$mswrdCsPWEQM9cz_omK~AV>=5>O!OMRs}fI%%>%2O6=LK z?!?3!LUk6ij?M}BZ;CsJkcUB0ePPw6J4|}uf$l#$%zUA!{#Q|Rt9SrxJ4C%QO4*5W zTYs%Z6rW9Er4+AdqqK9i5gziz&C!2|NGoB6Ef}0TtI8p4nL79|CexPNOQ%P>auAB| zot~CYFs7C3rm5X#v8CswVW}^pT;?$*mD3}~(k_EFGd6^`fptWWflF}1`!muNw=Kea z_yxtP;~7ED1r+ea^(y;ZCYulX8RrgXN07K%V>!u0q-iThCPE>II%^$$PDiMDEB}=9 zoJDpMkGFTic#fjn)hj;4$RDFZE%)4~<-Y!?`5G=uvRq9|Oet*GI~)B<14o`Rv5`%X z3MMIKMCgsDCFlq^4(%KI?r>x)MTMuI%CtUp3a|-NS248)jzqNG0sQBi_%0UuM>98t z>`P0b?(oSS;qCRS*MeKh3#OEUDjI$_c&a_~ubPXoXnhDWN;0O5Lvvq-5w1(x`;>e12KL?I-rOqG1_ZgG z;?>VP);N7(?qc>B&Z*>i#(0soMsN~(J(f#UL^7k1+~v{25BD7So_i}i)+nfOCNVa2 z`f{oHd&@C;onh!5e)eBeEk*v`T|Y!dC%d((HMvIypN6&z+*o*EdQekrXjPTKVJ0LX z!}kt`GJJGx=Jh0Q&M-D-=0Wt3Te0xzy~r&MRlxfax#$+vU}Ha7vcvl$WlX!qbIG{1 zwKd;64sQh3UvpbsT5>8q?bbZQkdyfQk2(3F$@)3d5?)$SxIb(%e^;BW;pjZaT4yn5 zh1c(rS3^V6QcU~)v=qZP?3Vw=!oL#eeuBut((q3*%Wi>B3+k0N!jnlyk910`iTy#j zZf!s>gKm6nyw%z4Kxw~eFl>M1wL3i|!F262^DKa4DN)R(AGTE)R7RsH2jA`-vH#9G zj2cG=5^rn%tTgD6L#S6mstHBCTGzdEzXi{WRIcQ>{RpIcXE%TV@BR8l_CIR15(SM^ zTf&%0RZhd#Z`}AahIm~m+WiIJ*FG*@qV=73yh>SkzT)#|_f*isNea?1s{cX_-J~(8 z{&Eo1y>TOZs>}0pjy-s@t5ssv)k)P0aeRgUJO2$Q-&}9*XycXqsVz%Z-{p6-yLXF< zgM)l6{f)01YEGeR?&V0D^Ieh?mx_o%1#LA7a2tbEEDMz2+W6GiI^L#l)&^x4pCaWPk7-E=~p zxhaFnd=jD29E>YNu)uw0vu53tDKvS_chq90Y+93iwAYXX$du~%f`|epO+(S^9|#`b zN3UG1B3u}YW9&$PvNDj3l8uw*lV&TN>IwoRG@f~jn&v-e%AfCQ3=)3vhf}*=1E4E1 z8@W*L-mC8VkrAA5i;vLs7CRJndRlmNyh#H*7D>2f7eL+Fb%Rg(yqV&aSMRS0P(QoC zlN8u;#Sfj`+?ZYx%zKoGjSJzLPyq9nrTEdhizkMY#k?+cwR|iko_fQ;aEpEC+&4)c zM+%5g236s6;Ta%Y1PZklwa>A&q*7vM)=iDp_CnA<*zT2hN9%7|HCl(M*@`v0mp(f# zC5A^t89#c1+=Os#uiZ8-`_?BQxY2bdv!SRf1(7%$Z8v}8>8qotclU|&KQrkXMwx|rtpp5fF_C5^{z zfuUuQ3<(_xGEhG* zjOZPhCWY;gQupT=L(`+`Zivmq1m&~Oj0h>rUGZ`^R+F79%_ImpN8U73h~W}t*j~sC z39myddkW!}C)GmnKJfi_F*y3m+TW4|KknEz1F?>B(lf>8Um^RW4UjTrOTDl^&9>eg zq6fY5&W})uouA#E+t%7WrEPWmrgGrV-Qy0{IC00i+bqgF>4R~4fK{Xzy3tn@@z_0I zbjo6NxxRb2Rcp1kbj0Z}QRa&ZQ?iB}LQ-|(;!=B!e()Nzk?ur3?6kfZT^pvAPR!pM zbl0TS@Yd0}6$gDY?@cz5mbtIU1>eP|gb1q`5%$x8D zMEkH&O@vrt5ie+9K;8f2HzXFBN<+k!dAuWV^6xgvc-_U^FD=s-{9Z>T=|o zq;$Prog+u2z=qy(->Q$z#Nf%Oz%}@$_8tVgvzSks3O2tsP07!mKFl`>qd844y>2B6 z-FBC0|FdK+2t8I5ZN;ec3WdQ5!M>VR_-qd}{e0TWe?z1!$E4 z4@Gqw=Zw8wJzQV2`EY}b;f#QP!N^}vav4xsTUXI6KUCLxMMaw=g#x@=3h#Ba48t^dp+Up98`XN`QncIpU;l(&4=hYOat0EB(VcH!MVabc#uo}Q*R{&S^Q^2P? zf7%kem+t>&8MJM_8OjZ5+;sq~t5sTk_lk5^_l4(YgteglzA2YX$2I2?1@=Bj2RA=b z7KP;~E-090e|^P4n~H!N-A=J8c@PqIZ^&O!%L%NjhhL`|f`sRDx3ep}>(FR;)6Ju* z-vT9!eJBnuz%eqd^+FSEv&0xmw3^x8spiFbc3xe5=xP)XW5IcjmkcUnN0dQGLIhP? zBxNiAbTg&&;~3dWKgL|lCGl%MRm?+Wf8&5S_S42Bh9rivYO*tJuz9o6?@APJzBjZP zxG-zB?SWUC7p3~=;21Sm1~>bko7TF5S+>26RK2?g1e;e}l!G%7;mTE3Tl2xW`I@q& zR=9hvd#en+$fLMqtwiI=E)A2IP6+2}qX^29oGhH6C09)qIjUM`6P*s!bhG0?kwlP1 zuimTE@zBqS%zc|6y>`uZ~xm`(8>$8+`v}z=FF*yC+a{b0>#G$ z1kR7fSXu1|iit_P7Rv$s>66~pn*)uW^S#JQ)iBlEq(q4eT5hCdkVJSix-i|wt)l;% z`sk@s3PmRqH=fB75Aoav5GDPg>t}+o;@!jSYt?i#^`#Dxxufv=gEZXpy{oHo%Xz{_ zh2)vjQNX&SlglB%J?rmz3qX{WYCUelN5)3Vi>L~a#0N>ry~KDs9qLZGW9vdm(Rmyc zW4%COEOyDLU7d2)JYn7_K%txB2juc}U+DbOd?I51=iUId-hZ>9{QuQ!ZIp{kafItK zkRWub_TYrHlCJQn0voHw8yg$0SurUpN}{LKPTIs z2iw)ecwNKu6(Z8NZD`){X<;EQtB(ORZM^?(==|l0xo`B3#L?jmZGCN{sc&K^Hf`y{ z#t{F$EN4Vzvkitw&nSW`OnGa7hyoDB5Qce(0#H`13Vz=(6RhUe5e z^5)+koHSKm7XIUe7X5z_5FE|B(bHb@9c40}`00i%oo#(hBU8_iu&2&1P$(FN)zBC7 zt|*s4{z2#GY4*scAY?IZoR&_3lvhsDGolpOyT;*iT zO(Hk(pAefrC3PoGu;2fa&XfVo5eh(@vN@cZE!cYJGdWgKz-I{~OUBKqNB&Oe^*Y%+ ziq5g?W4d#>cGB`4PLdhPQfYYN=t{W6Gy*%e)#@*7<(Q*1j?ibLJRKN&;2wXzQNo4_ zv&j~9c%JB3+C1%w95D}NtRA|w6~e;mT-qpf1wvc;<1+VtX=-4jUV9(^C-QN|K&uJ3 z(SiZ=xeO|B+r1sj7ABQ%%skg*(4=gc5Y)pbH6L?dLqRa5U~_c{C4 zR`env^cXEf{Um*l$=Gvz2>omA9!cI}d9T~t9JFx8uRiD*%PX%~d>vgsQRh2FZ-0A^ zJ+)yb{r1}Em*3g9i6Vl*e}ykYDq|6~R`*m+_ID?{f$xqCC0m&(2=lH;L%R;XR3dOz zVb-NdszH?`J`!Qe>fGMx$Y1bDWUZ>1J`%|t?bitRn0w`w7*)5gzg{$EGfm0JlkHCe z^X%xHUZbVxyff=hE%0&RHhZZaPsijmvxHYuuu*AKgP)}LW>-B0`gwrgeIp+w(OF~t zR{F5XxIJCCNZU@lPVQR8$tL}D^D+pXC3vKR>>WokxAq;#!uU~#4`%|#yS_H3EHhga zO~+_De6kQyjd-t=%QzW4^fmT|sJ~ay;if{Wbl+Y+ag37{NvqiQ7##7^VusV@c~KBL z4dJ<(&o+Ntg2HDSO-+a|P0l%Z($T+)G*8iA7csIf7CRjKm^$P zMC@F>m(nANFn%W;aFiscJOri4Mg>Ym7n&`6PHmzk-kuS={4{#J+R#J?S_f?x>fvB06DC*~VN|d2)$6ZBOX@o*g`D994lYO~WX?uM$EFfEptaOVFYt{v( z^DFL+_3uAh@YN8wVfV6YfAomBkpRFx69u<=>$`>@xGIbB@^R(<#ED2%96wI#-}+=U zUt*dya>0x9sG&Oj1Na-L%`J?Mdy?=TUzj>K*7@8;#(Xb@NG-90cnNBjlU8LjvsQ529@GZkKjgZ0E6D(_Hnwbv8@)4Q-}e#WE{9BbYd;HzmlT3vumLE?s}( z&>Mqjf>p2(P4}NQK9L_#v z>9-3AwvtC%91U_vyM{4o+3eLh%>;}G*IIwQ^%WxRHE(wyci5i57}I%JS@|mS_S@>E zVe=`|`~Y_HSI7}JM~bgO7-l)EeDz~mmB_c(_`Rzq=Y{09^lg>uA%A~U5qvKx>8ItP8rC`b0CwO znD-`M95-90UWVDjC$g;7bXl@-%CH-4iCGqN#-1qU%*O zAHCykpVi(gS$_G5uHNS&2aOu0LzFkHM`fn|id`rVc3$5bJyhUFHSDU%FfRJ!#$w7A^kQJ`KJ&JL>W`H9vd-?&=STVl7<-9aUFw#ZMDtG7>5+` zZJn|-9{BX*7=~n{uRlWeY27f8hi{cINU-#qtY}5EMS*5VhJ;bf&K?A|5(y5q?IN|HVrh4D&c;C-=k)l~z z&QNmJQ51Rex7t|a>x>bbb)!jp9I-4i?Jdb=&|q40Bweu-ZB&!B$>}BQ%F9=^7sPH3_~Q z%klYOzvb9luwL~XSY*~MQD^^S*S>E>6W{AmF0a>!_XVyo;JNBvs^@rom;Zk3e6Mwm zEG7rMl3nHZa-$)Mp0W2DA1$9p{AzakB1G2dGi#WQVd5sba~PP&zKIZH)w+8%;i}i{ z?(`-NbyFOBy8@>tehau{6gpgt|D2zJJ|~ZS3&3XFM|LSzP&F^ zL=s+ttx-g2J&4q*uD(O!D6?XC1sdo<8IU(5GZE!?Kjhh_jvndZ4=Xh$?eV40^aAXx zOklLkZ)X9Tj|a#VJqou-e8$VsyjfqcjV=0S!<5o?8983?i`wQKAE?%Q*p!jVCiM-u zmq^8XMeXne8f((h^E-JKo1YK|betxeBG%Tui@Q z;saGWSk4(tzyAek4{kx!u{w)v@Fhr*4Sl05$91^7{X2U()ccNdpZa!_T2z=&U%!t% zSF{MUUl@$ol3Y2qyL!E9t&#EiW_&LH(G$L>dORi4xzd<1OfGd}SR?97ak72uP+5kH)U|J$#gwX{39d6@Lev(D(a`5L;4@&l@Zsei)Lx%CQ>;`$i{y6;aGt- za;2>X=ywEt+4@0Yq;+pRrg|G}_$CkhJTdpuJffqv(ikqp|Er&I8M? zAN>Rp1bQ^QjME8Y+ddKjvHW!9?nlxyWV5U?&O1k!Hzfihhq{qWRs$uFxlS}2aa^Yq zydd^5Dq^t9Yg#z#1slt~ACGA?8TqXfY=t5~YL0K#0R>fLbFg{qT;tKA60J(W6b(@yS94lU3WzwgC6sKEwm^RFNHBPS2(M= zTZ-=8+3<-%y9YC~<_{hvO=Of_=xEb8ng{#6qCd%iuh(iSfqO1|VlQ3X0+Y&~;gaM@ zHlh~(Rtq^j`gvmfp!LaQ;kh!cHND9^(dNLyE4Ds@sJ3B0D(ci+lZ|jK%L@04@^Xo2 zqD{1BSGk_DBUWMaK^Nux=sF{lFyxzn+M{ZOVe44Z+{$v!p1+!>*oXqzWr7^* z%@pU*HP?GIZ`JzOb@hq0kS8OG*8CNT((X*$Tn+loJmK}8-DLs3rcw^?0rnW1ms(ZU zar7egEmOOQl8#T&rrBT)h5bxLQVm?XSeUKm!I<}bbqNo1Z-`r#ehiBV&x4!LJyQ`3 ztC&6l>7%Q%5Y=B@+B4$IIBb9nDx7Xn0R1Ft5%Vnk9#u;&e|^Bcjd+uyTIfpLPml;N zr>EDrC)^EY%PB)}Q-4K(O}_yhsAO$BB4P9g?^ZJ~zHidvHa4lv2}>&@qiICBl$x5A z)nkoE#pdeyR-)$TEXl2Y`4BJDFCeSR;OWBkOG~!i%uX#e+2Pd~6bI>3tjOc4;BOINcn_Inhq*WMM_KD|66vRvXhDtBLY?a!%Ks7_Me> z=y9O38q(%&uXB0m(lqERy{A>wu97nO%ELij&-%ym$5_2oyr9V@Ld=EZuxa3^uYakNSKXZa;+G#B zwekW5F;Wzf6Y>3}Un0w$OW3QUaSsh$^QcfTqi|e9wB9)VlUXCBq@XQnVm1hT>Vx5W zcBS?QgQ1*kwIt=h&EiO%xs84LqHk+vgqalr@xC*Q%d`^8MrG{C=A!W|)Ah|2jc$cW zPW)PuMwsE*&O2{j@=9!+4Q4FfE>5K(u^Rrl*ArIR6TVfgM9F|FTh#IR^*l!J*Sgqd zqVZpIR&#!>I8Sl;c7idJc$s<_QjHIQt_%WrK zgrxBkw(<+9Dq)DOx#Zp=NABTqhrCoE7sf-L%M^cb&F^6KJsR09o51_ALIAq3L{J`! zjV)R%3-v1w(2|8&9$U*7(HjI*qDlK1jA=WUWJE08O*$#RwX*7vI^Xsm`J*J1?6!j%Ay~@tzp_ld2z81E?pX7 zRV9B|_v0QTm&o|Rdm2a<^h%R*_e3_bj-{rzpTd zFFw#Mb_(w9&<3a0noXZ3kf>cb35?x{GkOD=>`2T`&rvvLSVM%QNAS6Z9B~ejU&?(Z zI!j)KH}xetu4<(p@g2f9RWnuxw5FqiEkgB0iM!{*u5-k#N+B;Yu((dyz(kRGtutxe z?#GbJ?#C6W_;MA77Wezk-qN!Ok61iTc?adnK|i!QDjSCO2hcuNA3uD24YrzD{EnEO=)EQO~E{T3Elx~9F#yi0v`Dz%hRDGXl24B}ujO1jJ^mo?3bSDBH+|9~GA zs(VqnM>Kd}nC+OP(BamKVOI3H(vwGorOM;J9OKJm%tvT^lU22r)@^3T)!#QYp#H3n+XSC6A09|16!NHb7<~RZ7`#Z>*Sa*7U4ajINU!j@Z#-1K#i;kVYtuF85VAA4n}S9erO-Ic z+D-hGtg`CH`$TT**!om{nS@g7l?$ol_l{3N{;QdX%6d?LGlvI}*8NQv&hb7rR!t8> z%pnr+_>#9W?n686xk=5(34YlgO1?0T#xzBNo#jGaeUaPl&?qj$C#{l^OL&$Fugm~E z@yC=tMOM4WIwsjqqOu-YFE!jkFGW;)#fGIsxkPbCf6zBH-pnXj0}kfv`wI7O$v#|3 zzk2n!wbtl39zOBqiCeSF@OxM_Ijy7|;bLtJ#-~fN%WxN5*6|TU+xrs5XL5Ak^A!pk z=lsPb>bCC`7~7|AhoefUj5`FE>;x-g4*RKtse5V!(ptLxpQ)wT>J0D;Y0f9dUUfGP zA<~92%rbL7*z&S$H^Q4;c)xkhTjgBEu7m~%o2q>L7+w>7u76Fikdq(x?HplnP(?Oq zD&MvJIZHyTP4DU$*w|9sLDu4sh=;v8x64KNVL)>70mw)^(yeKEnb4^r+Za80IP0<0 zch0FL{{hb0z0RFqf@#$YCRvESW6Sid zaD8OHT*j4H?FEn6;d-^PSKl7CZQoD2UZ628X8yhI(mZ2=za@^>7?N2>CqQkJ;gfMi zI!JexYV&dCHuhhH!!=zCcs0S_`shV74H{UzUG>d`A!Rx*u%T*kt&;ujiZ&1_cAcL+ z%(pzklT|%40;tTsKl>znU|CjYyLI$23&rfo<*nMhXrCPsQ)?zBvHidu35`}8Ip~$~ z5jgFeBfEI>TO)Enq|6wv_Q9{)N1}UMMM)ueg^}~lF;^tTtM|2dh7ONi344_i^WkZU zC0nyVSTqObQ~wn`j)un=W({HK8Rw|_vR~MjxfCnyu^?b)E}5IR_SzIZiHH`F5>{hu zwqX8y-r?i(Zr1LBY0ZxrL@oR`kFC>I#>hMM>BCU>rDYD*#hi)YUZWjK0%#ZS%c1ll zQB#~5{CZ^n9BkGEQ=j?LW3V%@{W`QL9-b_7rU!ftVW~E|2Jyqus`jhz<#WK&_e?eeSgeOSsOZK zTolJYfc5pqALTW#(05hEqo+$-ep%i?22{>ntufb`PA~RjR>Zd9m50Z9`waWP#DL~^ zEm;Dp>p89?;xN7)`KdVbtcJpB{860T<#e}3?`WHqsz=S4A50@XR!Ytj&El-arHaT5 z%LiRn_+#3_vf-NS<%hokjh_CdMV%fe%^Lpf9@Wzza76S`G6;sTZ24<`L42UQKgKW= zfkp3s$RA_jdF8>nj*-RK^fSTJhBdd^#fQRkuY`Br=&HD~i$J+e}+J>Q77SG{vUvv!xm z6yInekY7?dS1=%yu>E*Vh-2?-0DfYJAMD(uTb&f%H8}i4hs0&P7`px6y1UkJD7QUs z*N!$vY>_riwvq`Asjv~sB_X%TjEQOFQew!RFfNsFQ0|x9Mj08yxQ}tCT`HHzWo8;9 zWDsK{*Kr%pJI;Qdb3X15`<&-IXMI^8-u3+7^{%zvcm3b>`~CiZDlCGsV5eWMxrV-< z$f2OwSLXF3E94fcSr-aweWM^Y3+;(3+xAz&q%|*-SgmEx)H`7G2}QDmHi_%sW1eBY z)|(ozueQ&anlYAd6jHVr@9y5Z7Eq{6#Sa;;GJ2?)0?Non;S8?;VGs?GzMMa>vZI1u zI$1c_dY)PxI_ddDONvl44Y17tU)GTm{R)FIi;D8Fal&LRO)H-k*plw4^Aa^Kpt<$4WtMWwgHT zx|v(Kr5Mx9>yP*>8}fxs88MLrmIKXFSJJCB_b0G1(+|#~wMb5K45eF!3JNf}6&S86 zBxE5JqKvXPU>tZq_WH|an_>M|I2RyRmB!ZmzB5|BF-D}RnC)6SRh?t4K}A}&{53a% zr5KeaAJ_Vd3A>pwX^exih1%&!*q9bgS+bE4dQ-_~1J14f9y!r%3tc_&&9{o&u;JUl zzSI26r~0nJF@vXzUxpW%Az@_yOpB>A756H1idDIa_{vOX5i_8#B1U=&ZaV1*L9P@Z zQPD0zsEDLj*rQHiawo69D3dxurZs@(R=IsSq~+Wi)7sf`x0Az!(C&*`Z4vRhjY+na z@LuP9Nl6J$EBi!vmqPb5QEtP!CHF3y^F>Yt=DC|S8c|+Okn~P3BtF@pH(vF#HO9LP z!U;0tj%h~2%AJt5t|`su!9upPmJBDsvNU6qZQkqdn=KIS;QJfz-|3=co2au}G8*WB ztQe_4HeO+YOg(8dqTHt8EnoI^%9z2QeO|#zLWMmjf`!mV(!uG-0$=wV;pfVtyQXT9 ztjFU?1~3_AFm}dZcqP?m#NJX-)YGjM6X_}m4^Ho0I5Fqe3u~?3 zXNC}$6vN5L605?@HHAb{gi^91O}Y)?A?l0Klh&gy?fv_XFkpO5=) zlUIx;m_DfWtSVr+d0l+B^WAo47tVc#Y z6agzd_g+N@l6W8(-$>KJPP*v!GNz?wym?6nc_m#Z?;f|Oop&vAS6p@@+Nn0|%SGXP zgATWw&e&L85_-Z$KwFO|IQ+0_F^j96o`I zg-X(5VsNlvE#o-s*G?7So3dANrk47E8|Bl9&<6U*aH`(|7vh? zFAdsX2v+`CdwZa!NHY#6&I2=h9s^)zj?yC5EY=*VkEt$Gqf9t~Lj}Sa4fdbt^!M}+ z7T-{Zs@0D3rkA6oU#*~Z&bs)KbDC)8nb7z=>vPEO`!&*XU%XkDJ9(PXO&hy$=;?MO z@1q_nEla=US#;6oterxgy6>uQ3J8*ZDdW@|d6xeDgxs5K=%aHGE?~7j(?<;*doZ4? z9^2W`t$&HXy7N^hs$4Ty{BU|&BkrsXZ{2auianQ=*HR$GlZcRxA4dLW{IyoK)8}oF z!n0llo{^YjL16{z9T%l&+5H+H-csS6)CI9$cvvbgJvmVQ7c^}DyZ5PfYq~>GEEChM zTWT0x>Oz7JCaR9@y|EnrfA#tv)VXDY=>ysU-+2D~*_pz8o5kGTX*6&A$44&#a6M4k z4X?hPCjn%ASXZ9OSEev0o|YKia=j?-{Bz*2af^H6FV45d(q@ zUFp*sya9tSNZ!}btH+uQW1iULt8((UJ)^Wp!N}Kb^wMTe0rX6)qx-aVYz`8p{6%=kuR8|mTn_M*6z0QWF#?1=mySq z-xh1`r0@#$4-Ro1bUR;xMf1UB+z%Xh)A^e6B8r>~jZi;Vr&gHLh^e&dO*E%@Fz?4n zy)*bw-x@pE?;Ai)4>}H})34hBk65qKpOTvt`70+HcDeK=d#Y{Z_r^;5do zhxw@a{tP`Q3FeR?%(S6q>a6U>t;ewg4^Sf7Wrd^ z_4NqV(|b$!tZ2%jj1Yy;&%F@1cxWm#q;3aMg}}CI>+i?P6ww^+Dq1`nI1_7RLnX1r8BfFW+BOVHLUN;A4M|Tew=( zGhfWV_SCoA+Tg*>%~H$VSFFt00s8>1&iMq}z1>caIUuu3th_}ujiWubE0P#z`ENDa zIw%BLr>jhzE(Uei21nqW%5x=od9K>`19H(__#fQU&CkO!5~aWSkxr23iYp`)Cy=;? z3Aj=byd@N0$+0lUey^g+9I{2e-I4_#KzH|w8oj&Y`1@JF4j)HY|J;uK=<3i8U291Y zi@OYJoSou~Qr?h5OX$G5B$=zhyjRlZ2$bPqdDE(24A_uylxwVf^8jjN%>tg;F6F*E zA|$okf460q#dL?3*6za|E#J8OC9bgp3-|bG1p1837DUdrMrB zhqo{3x<1BE-w>PR<)oRhfP!t`0ZMBMDODKw}mX@lq)Ld0lVkYKx&HP;mL9BQ6L zsiCGIVkYJxL=X}p!yEmdbKd`Z?>*<9bMJkg`<^@xww=Add+oKqYpw74tk2q?wO^{S zv+=VrF)^_}fA&O|iRt)06BA4FsgsO7A3(xJj6cWRb=4j-mGoa;WBhZ%R#{V-iK#5= z48@X#@&9R;XGZQ!OdM@TKgT+q^WQNs(Q}?ZQP%f1-gdE~BVTJz%up*nfY$^4F9udZaxKvfG{^skZ0 zlIVkkr-ZFdxGBcx0n;(zKO3x9W{)3j%rc$u|Fh$Ax;o}2e&q~r99YW4RtuIO zZcw3dj4RJK5?JVN#g2A&TW!%~m77o5=Tz-f)O}c^Ve=SW(3m)Op)a z`39JhyyOd}pp289c>gF(Ju=Y3=pigUOD&*UD3q8Zx}Cbl=5R;wz`I;1t=ha3hrRWUSaZkjqIOODdoy^Gkqw{_HQNP%$ zM|>WNtB|2h=8zpvu$0B9YobA&Oo9?D13BYu9OdCWhsDoqd$L~^&Z%lB-{9W)>#0DG z@MrX~RP+p3CuuAXz78;>0$evoC}QkG3G3T8#de4J3C~l~c06$v2enDG-5atc3-;^W z@;*Pvo>dss7^3qQ5_Jp1yLrLVv9!|x_xFkt44$_^7%1~gcYU!f=Qi{DYaM#bJm3H< zRWte+s>Q#uf(faKTj*NpSdki@k#MK7!Ul@gJzveoUpmrAi3~IJ#){BYQ^Fc{!qsM;CZQn*eUQN>&o6^O<*t8Af^YV&$fg!%oN0=ThU zpGDNK>_tF(>3U9!{dxXfQNrh_lbTYb@x3i4hj_D``7i4!=Q~14qwcEdP6O9leG#_4 zQbS*4U?bO4@#rE9*ZE#VDm?!O4ZFRlRyge(ZO+e|`SJU9$32$9PW;LBZ=19vx(X}1 zz{QLoEfW(0wka@HRi1k#Ek-xmFO~Xi*|%@*4KWei*@Ux4zOPFWylO<>_@{7;fsVY# zBYXV@yB{k>5mXE59{_$?Vw*)v`3_+kAX-oG$`nGj$1&JLH@@9Q5T zWd{wS-T&p-fRT`CCHxJSyHJeCE*ZXZ7!+s}jPZ&e_UIDurN{j}Z7}-EsquT-`n}g> zY8}{ANU7+L_hwFworQl_@F>weckZbT;w9Umx?^Vqc1Q>W#g%Vm6LY(JYiCdlu)(ad zd2rUK0OB4LR}o$}NdWW{8ajOXjozdLcgl03jIFBaqVyq)k6vHb1>(H=ZTXN^p=C@G(7z(j>_~O9 zzL_Tx_vPX;nqW`Xysk(54Sa|rdwe~=shP&o+Voq`?07J|E=S(e2=(~!HK~I9bCiRJ z3ZN4&LweCYn{zY6a!*jUiIb72A+0l`^HG=Qcs4aPk9$}sx!a`a(jDVs5pTcr=&vUn zv^5osm?@WtbN1*}j^6oQN{_MhVVqu{eDZZCSMjkX_tvJ{_!Ruux7_O^DRZWcJXE~f zf={A(+NRK^ra3w1Et}e;bb|Dy==J%?Y6heb3a2SRC`{(iQV4 zx+*@!iFr*Tg`0)ba6Hn}yNJnKHPsW-GmEc5RAmyGyRLD~ak^NUrl=wI9JBoqIMAEc zq}v{mX)(2W&@O2BC5XBu?DfC$Gs zc_2dW!q*o~hF_mJy0XjZ6aJmg216yQ`B9lVGQfmjs{mK4uR?R}p{__$N&77mPOmob6NMVETT1j1$x7G6_#hUNNT(nflD?e^S{xe)KVfXA^(7A~iJV$wo-u)|^>4qh(?m@t25LP-rBiM3QSC+W^wHMxiAS+{gFY3R0YV) zGx5LT!se&GpOJ&%fJT;{dFe2(cAX|w0J^U1BUYx^KH=!Je33$r7PWSd#aX`f*6;#w zgYQnUijwouSGAX&V*aE>{~N6D({Q+uemS2lQ@nh5&Ht%C^P1 z+33PoG5xj{KZIler8zfc{3aL{AmVqzU;n`g|Ma(Hgo-VAqe~X;tZO0!22SKKsn7RD zt$4_-rzBOCz)wahY%mhxZXO6D{Yls(goGQ^mQJ?>yKtJmpO6{R6Cx38hJaqefmv|mgmFRBDgmC|8+unSDu zFaPh8(*N3o7J1*xd9!PD)bOHWSEYvAJ7Ax;h1K{8xa?crqcpAs%*ftc_{P;S<@(>Q z^NOOy-zTHi)V)P@ug^3>ZEv}E^0&YEGJI0}KI3S8dq!fMP-Y^U_IdE5Gqe(R9o8f& zW!Zl+C+!E!!u>m$61iqvzxJVj{Kx?Elm6*mzPQgfoDfTuGv;JTf-FR;&8ql%jL@i8sG5WP{G=lSUvRR5Q2BrT!@8En6DVimaATjAVnQ?K%qBYZVY~uMJ~%P z59%e{DbS9=>9=3%Q7e9t@G@`7PZRkQ33PRPfA3`T=X>#y1G?+KbtC_-aa0JqnYB0EVYp6JPJByW6Nh-(_ zN}`k-_kQ|@J!mA`ml5qDLQLxAti!&gHbW8ktm{T%X=tx?uvIJ& zss*Rw;A@|khfZj6mSZs9rfAY>h63Ys_v}yl3FV)AN%c0j)oO^=48AE;s8g{xnlUsg z@E*L&?07&rUBz)J6N=bFmOb3puM7#3#y=pkCdhf z$&=_+`i085Hh`}m%4d4-jUk|Db0T-GH;vtxj0^@+C$;w+ZJn-m^5G8b3aT$lRZCWu zPK;KCYb?Z`?@w^l$vT7$oAu$!hn`{5ZH4*r#w0ik$f?1*s}RJX1PGERK`T>sEut3? z6ps&A`Skz1Ji;4bmK8v8Q8u#Z9meQJQa3SrihUAxT0^|*uanaW(?a^ADZ%u$%Kp*P zk~5PutHvP{h${a|VMUa`T+OIps^S-B7M!LJ z)O*eE!su%`hfpJo`8dvhW)BQCOdjsT>HQ*BNRN=^<{?CU@5p)j&U$=vf!x z%*7;vBj(w63utyN*nWq9z!336DSX5Et(3=V54qE8oV)~C_G+D^6)#lo#-Qqp=w?6z zR8`4(#aK4`_^sGIgNPaWZxe_gCX2W?6ic=)mxg2DBh;O0$lR_Ey2MBMHeK;97@Kvz z1G=BMlGi4Pohmb$agCj)=sOP@As!rj8-dg-ul13OoLLVW`6j&~^HPq#cZL!VN(-Y7 z%noEtZUOo6(c2P&4+kI9IF+&w>%YUIqMQ&}MUDKm=EgkbNNVxLPN*(UKtUh(5y(KB zhH71Cw$=gxGW-BI15P5yGc(0D0eRVp54Epemi1OOQZobOz$ei$wt_X;kkbZV1?u$e zYZTM@0@5-S;TtTu8y?naP8l8SxRq{$iT{u(*soP+vC>Y@DQ_q|!y|y&t^M1J4 zb(5+aM9G5|k8V0UBqa6f?Dp~N2WT46lZ5Pmya^wT&Im}EnTJOMwnsgUo?8q2y!Y+{ zPryo!6_n8WBZbAE)HTjLVe8cdY zYPY{Z+rlQri`yZ{{_SAA?{mbr{9aJH4WZiu zfJVquH>GIIB~OUoVIK4J{`|gDC;iAIhEshszF=YR^2wu#o^;+OGEsW*`^rwJUreZ9 zt&9)XDbh_&F#D+=%k%WA$s_}hHQ`^E=4L+q&azoNL%JDdp*0-a88MdBtS=BvkP%Dx zDAFr7mCS$0(j`ZZ(u*X#b{n_oz~+c`5Rc~pRhwt+?Y0ARKOPE5o;EHk_yj-sWpH)q zgP#hSeChg>K&Om%W|})EDHkim$U%SDf+Nmv_7NmI7$ZJhQ~+kW@J@6Cu@sfVC>`oLfl4Y@d7cX}5hhY0Q%h zx5ngf!vBGaP2mO4L`julg3M;w-UYV3Hj*BmcceBRl3-qV&QMO4)L$cP5Ls5~k!@o1 zd9w&sF#Lot;vj@22-NUf%a{wA@!nO$=mm9|BR(gMRpgY(FG0R1a8mGVSc7#~p6j7} z@tek508JKmk5P;_??KZ1(&dWn=d9$FhDSQDbIY7M>Jy*oM`C(werE9F7jlW>Zo>X5%RT%u_+O_*SL+G+ z(D4}}%i`qB zL=>y{vJcM)-m_;JYHthKcsy6;J+2P13c98wYYFh7y+L*Q;tuZdO9C@(UU;{d=RHIx zklqle8=ZLO;v`G_o0@VRl|{3lLYxEWSAe?M{aegllW;l9}jN}@AAJse{U-3epf$q+xu74*(0&VW|TXSc{8s8D$jmU(0bls`_ zaAuMl(dAGslwP1G>K?Nazf+!+IGR9L+2mzqQ~F4$_h6sX5HICvguuQ%ZT8yCvNhTj zM9MDzB`D{>ZQ8mtqG?DrcgJRU!n@~(RCG$_Dev-tgTg$bef$3FGOjhwE$d%7aOrri zsJzm+y4izi{zrqLjmM6@pfF0LGj3=*rYd8sjBhCRyET%rf=^e!HrsY}Vl87EvY6q~ z2P2nXVDl_cEK_?fkK0ENYmC4*5YG(?{jSu1Ede;gf55o3+W^lejB3Aoh=GiviIf$# z1xFO?uJI1{)HURQ)9jO?C{OIe>t{DbE=!;gFVJX`xN`xKl!)@affw;-gw2n@i1S}7 z3_Dh}giV@$6J*QU9>`cHQry4DLM*e*U*2``;C*Qqb)Mqh|D*wGY0&dUf$+An12QW9 z?vCZ0|H7vTCIz=oo6SilIp7lw#!>z@{;;rBMVA{Zw+@pJl4u4=9_yF-yo*x-6Et@{ zs#z8mX`Hoth8Py#v4geakVz~->Xo#I2r;ZjUmu;vx8ali_`%+SPpSe={crXp?|jw1 zXtU5l^s*C}df*P>LOflMZ-xg@4nKX_#FTvCB3b1?k${s| zc&H1(61&tvm5C;BBv0c5Gf)!Mz>8{;#IcFEQc8oMXE>l>nuQnyu_HWD0SPv6K#nK77D-v>;zz2* zI<{X#>G%49z?sx@RAPL}&kc_Ca72ktVdGv)jMr`Yn0vceQPxPL)_PXeZSp(}zitt# zC4!sOG_EIq*lZ;67P_lkJeZ=M5u72Xjr?kY*T~S+)S&w{)wi67{3@;iaCld;Vep|; zzTR~|zoG960+qWkRy4UL0}C>9yv;&Lg!Hcyw508OSTzVU$cM}MYsOpVLD(5;zCR6C z<}^*LUkIRORS85QeftU-7DLRWCB@!|vWOZ?Svkx%(j3hN1EZwxPG$zfp+y7DxX9~X zdQ;_caP;D$nsE*8Ond2J!hNl5`@>rrRm+|7+*=w}@S!vqs=${@LRH=9(YQ{duDA7LyK=3U59jwTr zxFDJU*|be%WN$#sY6eioh3+(~Zu)>;QLY6u%*w6uPys{Lm;%eyTGT?^bB@=V14|+}`t8c?d5k3b)#FtL43+owoD{<4mm-ScUb3AEm zLIl>QQ}i=vx5G=NcV-0&W$=Z{9VztLi~)L`@YfyMI{nPx9BJO%EAq?udz$D}Vx=<#D@Y5$blu#U0;`S5K!g*JOSr^BO}3o0`gJrqe%2=z%x;StIf3 zO_fl;X+JL&L9$l)g$uood25ejZq`%NFx^GFc{R^Y_|Ia`GjiW0_&=xTI)=$hBRK5u zikCTpESxS8F`WUrWEu)MT%LCRg}Uz`dtk$cq|(|ida6#c#dJPD;PgJ@DR&}F>b><-nQ1N26W4%xrQZa4h&&2B&} z(+8B>I-ZE!{ZUQq&>URgj2JdP40@bap&oY6oG^&bSUOI^shx-tgeJR_W z0Pn3g4cR~bX+k*V_gBsJ-2Y$7J2IdtMjgtw_rR`K9)`_n`B=i@)K8Uv%4e=vpYze| z&4WLcDd8N!tD;rTFMsflEisBdsU=Y}k=mmvEEtK=h15`c_`OMbT)>({n|ywJRm-XE zf7Gi|a|7U-S&(8~)KL-lx&%J0p23V zlJ&|w0Ch{dROmDcLu|~TMZy7uY{uQpv{hDj3XpxR6B&gO9Vy0yNN+s9r88H{N>O?e zg-%mwU}$@(NHvmQE`Zj^%*@QlShc5JI|Ydsn4twrAFSQEsAK00UpIf4dZZWtqe=hj z5f|&-2t~Nj-omFY=VeP3*oSfyHh~g2L;~JOD9+m2y?T8{p(^)NAnfAEH0dB&1bj9n z^ZI6n5{#=4e^fRREb<~Ym9#`#e9w<&AUc6Nstg~!AhdN6VPr+Q{^{>yu?B8#<%)EQ z`{8)bv`ZU1`CtVWewHYEYCp##=NSEh<}@dxM)T9MOf}KDWHKlenCRthEjX6_%DF_M zCeT?LiMNwRB8sn7hd%zd@l}Kw?j|mqla>SAICE__L6?t};*NQ;_Os=-I*^}%pT90t zhT~Z3Gb@VxV|9$H7viE8a#3ya!C-!5W6!TN6)>6^=gAc*y-X$|;(@_4D?&X>D}-*7Eq zKE{hlV#4e}QVzZ{Yh4a~Dd+Q!ui$nrck0FNI-V!ZGVs<>mLvBS_6C1BH7E;^Ur@R0 zWwy&GVI(Peg{Apr!|Pwf__E(?3rJCVEtv7iOpczpR4hJC0k}>$EKqGh zSnmL^{p3@~b*oqP0{592&**UrD-&z|c89=e;>#hqC+;J6(TR`NVq~(U_VC+sQ&>L8 z?znDyWBJPfw$1d?j=MGFwFCtT7TUHRgxbH()*z-Ku<~+b*gmGp3E#(-Qmvc(wi7Gu zr^#@wkb7Z@cP^_AvfdG5{3;R3T0PFxEkIZQ!=3rhuxkEm0Op@S@qeb~{C689u&2u1yt)Yqqe!}Rl@?9(p6 z>p^@BXB5fc--vumPC^fjUtIAZ@5?rvc=S9GK)NM~#OAs47GoHd&83`wj?MoDovWCr zre}6h@J7})DSA~vw0_evd&jVO;JP?oX$8G+dgmO$T^2^Icm=`~gB{V%`Y3Y-mOg&{ zU$Ar&;`kXkA4(&)v9{~w8oE=G*=;P~uO|k738kUoZ=9jhjA(j`nK36A-YRxxCU#+D zn38Ny!!fMm73UFL{{JM>GtRmEpLoXqZb(XZtIyX`^4uh|;%RB>sT&Y4! zMaEUwdeTfCQIcWg$_!to(h^!>I_!tvGnh1y8%G{Xcax;AB{FQ8p>ghW$Aq~#jtTeA zv+bM7vE*xl9xDcRQQSayf7SqcOn7HJ}1!;zH<8J9XM9}YjXkgTG7HH!t+WJVBP!#5iyfC&#q zs;k)e`HH@g#I&a@8#dJa_e%Dri=;s{X4)5IVafqdA=bQRk-gJNGOkH-)%R-n3cnm5 zxzm0ZkqHsCwFb`|W2$94y08m}DDg9|lpR^sx)N9VDgSR4C6`bN|77@kjk=tsk2AM@ zLdd`KzMC2FrB0P}rOok^IuzGxj&lp5HI!B4x;o8G=kyB+Y4FNO5MVO{U2=x89_c(< zwXwKML*c4WmlujiHP8xHC+XhcDVd89^nf{ssqTV2SCc)QD6t!pV5ZNP(^T_VN41*M z{2hg3<}51vb4D14BS-=scn9r+DP20w3!EW4q*gJCLj6aspUq~px^Kio8&BM+Tn;Q; zPSm|nEug2wUcVyuDik(VlD`rYXQRZzlz#t6j;EF+(M`(yy>MTL%ecg; z!)TapcXSBWmW0AzN<|4D#1wHjWQ>dvX~yT}c=W9w&$m2rhv^T^z6Ij{<|c(Y+RstuAyPehC~WzD>r>KDD_ z-#a!k!i@*M!wlAs`{K318}e#8qC}&^SDwA@d_~F%ZQ^A}S!$0;_=ZJV^}8fhsP?aW zHaCIUb$#yzGz58&PDb-`o1bt`M=Lic^PzQ<{p)lmg&m0V&O3*D$u_(XV8XSED??=n z30YW$SFLKl`cOZCI4>Go_BOZ5B6vm`b_2NTNZgLCL{R6ZjTJ#(HpRB6Ce83#yv5wY zC9X1^vH;WKu2GE6l(b*fTeIaxVWs?~^Rf%47AZUztBO8Y0pH=KinpeaqA#EsX8@)7 z$f9h7{5t+c?KSu$Sru-Z04ST*kp&;PAd zu)oTSK8O<@wtSL!lYRTu>r&!KbcF>Ro&Nqz70^q8MZvjI5o^f;n9B2+Lk-)sG^pRc zb6fng-s{zH?1P0LRZX96`A1&)nm^vACMx2Q%k0l1(%d1)F96WKDp*lPiwxNjF#T2i za?@ZqaJyc{AMQzwLI9wTeo^~&F_9Wl`Rm@1cb8VJ_*~B{%J_etM|uuu6HK4%eMJub z^^^ma&T;)>_}L#hUax!9zUZ##6vcU$2jBdTC)k0OXMp}YHFRx}$O@k3CkBm-5m{vtuBWON+1 zG_cuW%ePYR9l!E=)71ebIAW_*&~y7nNAF-)B81KSfl-XyWD(E$g%#?C;!}kO#wu3P zU?PX#!$=cO;H&)xV~e1_A)b>BY*>Ey_<9BU;4}gM9@gl2%Wg{eOyymXK72n}9%Z3C za?xTz#u0`QvG74xupMKHdws-fVARCETz;5UoHah;zwWuWXp~nE;M9M~yEo(4gwD|m zoT%Jz z6^|)~u=yRDiPa-Y%+g5EK4Esl`BtHw!nr$2$+b_QB)+TWjsW|;7f(suK9T1?skBA> z_$v~EH|t~XzAe)_)U|EU2kOeS6Z0F!Q8^t(2GRzNp<`M-#OCy`@tz0Pf+HoVd&3!4 zGqmL<#CiSd=G^C==RDBaANiM_HmUXdoOv~05Q^>-2jnygmGmR=@koMB7|cy=<~3{G z;YQKZ0u+~xCtVt}V1m>y_DZaF6inn@)io?~uX(+08s`sFzj?zZNKTE5HnmfYs}9Ij zNd~M|+qJWVt|K&j^Xtq~&hv`F2Ksd0Bgf@n*CVwl#4-v-wj#G?<$}F>rMM!#-g_|` z9=pmre9%4}(k!_wD=<9h?QG@Qky{m3i+W}1E8A(%>lrpJ)Al}i0{tUSPU;6N*^OA# zvJzkAnjv@Av?yYBdxCBwarhtt(_PFPf%)L-pOt5C=yAFeA%bmO*{}`VHlYse!;MAx z5%4C~IIv046f*aLETS(kk%heb*}$`4`*6ljUC^oLVAACVqG3LO^Tzhx7p*w(eG}4* z{3wHMtaVB~QQ(FuYt*nd&qBRl7cSPQF|dUpwMm0^oDl^y?&JiVcI)cYB3Oy1i{- z=%ZA=@H-69+BB^3&5BXu_&v75r#hPu4REF^8X7Ue3K#H&o{Xp>`qjIWCHt>jiFS*J zTut3@S!xFEKF{-?P`272hFp9DNb=>kqs~aoU3uHdrU*w1r;WObNr23hgWQY;ffh@5 zmqyxl3Ab`N^tOvVulE;&=DI3IxRlx)uezJtQtecy65Pvfrd7iz0p+Gp)u(gJSWTZU zuTxSxRW)t5HrwQ}PG@fCKfnjFv19}Vq zfFlF5s;0l13x*YMJIu_0!z=c2IU9Jhd|_xJv$<<~N$qi#WYdJ9G)R)|OJP92?fIIk zyYc-Xf?20@ zG9MXcS9^(!`S;vNCIHs^$2~tM(eP97*OC}+_Y~lG_Z}n+Q)>3qgT*CbTkHB=e$=uS zSu~wdk`y1~#2m8pJ^P#YuRCHgD`~nNq>?(-y{Y4s8OjRN4tCf$ialk@ zg~;%kl89@px*};>rEiKn6`*A1r;f4)ix18&5s!4E{zo@#C!+mLsacbWH9yrKN;X}nP6^v}xlE-9ppFEQY33*t&9Ew5jL@u}3 zbaK%xGwNH!8@n4km;%g`0dL&ejf)iK~(g^{W^|=j0Ja)#(Mu`%sUU8VE#wk+xS>?LV^m5W6 zevtY2prDd{zzlp593m!RIsqK&wtLFzXGaY`UtgD1qy(L?7SCMV5z61ApVD(_diRvb z9+xmK9I#+nlWzVJA~e);h=GexHz33%}iFH#cGm zC`n$#*fmN`KK6(7VdDHv)!S}8_rS>);8q1FDX%b}yOv1`vUxJ@vZBBz`yE~)`=_mv zl8PMJt58paheAnAftXbJmjQiR$~C?xU?noYCirrB7{X;e0@zMH+fapA|O?^n3biMSujq!v#x$wMB$Q2QAIPD6UY==PEaU?2c0Qa{<65o{po%~DyO?2wG@ zMxN>(@)U#d6#1w&bMnWa3e(|1o%`wnqqldWK98ItSt_%Ti58zbn%Pb}zjKrk2ROf@ zMN3nW3jJTErKROJ)7XxJ&%1Zdcqq2&n{t*mHAhyzFhy%ct(do!>pH=q1&|o889` zCV;nHKdb9VT>rHaa;x;pLLJfmU~(Dcce{(eqfFR&xaj39VI@qoH}Wr^A5C7ky>I_D z;B+!=MaZ`Nf&}UW-A!(6;li(gH#Il&AKm9joaTur4Oq!cTI9|79%N+$9N#kN9;-8| zxc(M!2-98pJU4ML?#+_m1NvC6s*T5EiDip#)>yYd1Ll@lxS#jE>QDAGCSg*?)t6sC zZ#cumbcf~Wi9hc#z&hCU?KQ+juiYt6Q7T>vFas&w7G@9L)Z0x}?Fuu>+~Q=58cVI} z8_Roq`qzf;xsnMnAp=|*%Vtr4hGJ;_TH>BegX$aNFjRDZDFj`ha<8ya@!j-uk-Ei1X=5-cu1B>p{2bZIVOj2Fjbf zdTzi;O|5-1FoAM8jpTuTuy9Ft#w?T1hCmq*V!LC{v9xusENx-a}*-3-ak}Pc~ks4eFHb37_zQm4IUHT1Agb?cCp#U>PA5}%V+3&Le zV6@&?|B+33$24CFxJGM$w(A969yT_cLOfc}^yL!zOb@%PM+w7qyC`AuUe@=2_o98< z3-_>Vh^lzc>ZeSAHl_xy0p0re_uh9@!dqFn9XfCsfyzG(ih|49 zBOIXC6QXwhCJX)>72@8p)oTbOih;Lz_&J*Wt>-8g3VQe9V7%C1Ki{Rw{+==v>DX(L zmBM&F9kM&?@@jdcBYM>Dz{g?%>XJZfxPm~35Z^O?w!|1^mvV8M(a>xDUUY1Qhl#;S}KhOJRbcz&V^>D8w zb94pmB7K%WCpM~;%QGtUf)#P;jHsd(U0FVoaKT^W#h8dOmNZW5M?KaZvrGpW9RxW9dOH^HAwKw1&ncbELfR zNS;X+m!NOx_V}VdvV2L#I%wHE=5Us`!g<-&{)@3vcG?&C->uY?Nc94=3PINfIM_O9 zEHh|mR58z$;J)4)}G%rM>BP}BHqSl*+a`s$?q`y#IM%?riE$p%qCEv4qN~0~0YDO|vo2$US+!XTfB!-N9 z+QCt5q5S?2&H(ni+=&Blkv&J2WbXA%Cy?^@xo^f7vIy26Yi@kTi-ur>LZ_H zWA?SSW!Oty>-raMOx{{M!) zl4jQ7;;GET`O10?XPNGlQZWHV#WCYY(5vTZru58zP_^5POc^DRl*Qa+r|U;}-jja= zWXr7RWh?J@2-LKgk>NJNNdO|}3xG2=Pc;&1k7O*i*#14pIe6pGP5;j}-v0!S%z%}S zKL0^4@PA>DNB=HH!6fp}_;}!s2ZQO);P0FNbvk{qkdIz8r=wW~Ot5Ia`VZ*+(Hf)T zZhBGG?E!_JI_P?c0Wzs0DbC;+p0q+e#78q-&r^)(a0H3@G7^{3Ryql$C+EJ?2$ads zF$RNt2DVRR!E-eB#3jD~oes+COR}EoW z*!A^rZ-bFz9eUw`tpmT+3#Sd+9!HQ)Z-~-)h~+!+ap~;B0w^A@e2AW*&egriqN37! z)Wz%Vy!Ee{nO>>=FVs(5494gx;v@fGcl<%l#0= znmWh2Cw2Ql5xBnuCd)Jk?|^NR$GPgB?nJ#V7(H2kV|N#jwAJNtBZW8`yH~n)O#WFi zV86*i{qJRCyRITNY&%tj3G zdkk0~)=oW{=6O0$l+pZy>{eGQh!>Pb{4nO`~HHkB%+(b{42tsH@*R?0MZ(***rH)$em*PO=gQ@VSTF4k)E}Qy$S;{0lbmc5G zfo=&cK#&$HFfUS=f{9qAv9>*eKg5caU=Eiw&GuT z42#t_VmLphK(~0v1clDC6Y#)xt09xYP+hQwTL|^1dTBNVhe7dEoh>C#r@}UUWixs~ z(#A?m`p|!zhSoKQE>|{Fg!!}XWrYQtJplUvJ~-bkwWwX5An_S3`mHGXnitJ&Yh-@r z#{iM>`r!iLrU?PY3m5*pNkYUh5*21Ln58kQd_ z>^L5gH+$i#+U9&&N)Xf9>BG;0&nNWeq5~jRl#rsQ%0oXjNX1G?_7)EhLJV23ZyBrt zo+E#g-Uv85FdSmF2-oiuo-t`sQ@vv|=ie6q(7hf+@t}|CBq4G>0ZF>{#erWfff){P zZ)o7n-uu;vEo;qBW3%<%+D)mdy*@^qQ%Sji^Q5AcS=+txI?fI`B*$h!TASK>PTXi_ zi1M0uRl_8}y?$#pU=#Xqx!!It&*~u3im`$d{Nwfbw^koK4mXq-iS67RiNrV#3_T66 z+Nb`N+CWuSkax~WBOu5$l2G%-sx7qTPN~=9)1r|$3A(--rx5z8U!Cy@yKWQV)hY&4 z7EE@B|4p(SR8t2nm!8+@soa_iGEbbs?@z0VD`%`_B6Ai_EFeB zBDgTZKBeeuYRPb{%AL7OIN(5f{1;(~wF%8(nvD6EVx9h%T4-YM4JA%GYB8UN(1?mj z$a|?VJy;O3lj&O>Z7x`RdK_s_AkdtaZW^-FKNRzkAKVF?ICOi`!rINKdcQi!c!cUv zft;Q4sfCH1x$7O@@%FzQJ-@FtaPyx}EBWlK8S5q3aCRvukTW)Qhi(6CIfK*^7*_hF z=4SIjasSP{2^R5!&ueUlXXb>MUL4JNCVh^*2H=ZlwDatZDmS}f0+{1}*1e2x@*gx? zl#a>FSCV3>mv8*bYg+Wr@fph(A<_;pKYh0%xfnHQ2Xv99lXlEa9rbbz^}l4hy(72l ze=Nzp<$ZPY&jng6p_Fa4Y4E7o&fXqcn7*$Dp;Jl33$r_40xC>PzXTYAP`DsaVVzTh z{4>qulXi>Kf*bc^xsGNllS?{b1!;l;fJQ_fJV;EBy3jpvtCSPfyF?e;#;Np7I9>%+ zxv$*v?MRT9j{Re1OfG*1DQbiNycH$z&TKs^mB2@K*u03HL~rmyg5^9phkvaukv9%2 zI$A5p4ytF0{INC!A4}GFQcb*4`NO_fF28Yc+GIBcCsNJKcKbsG(lZl7`udj|(Cq#= zIs22N;Aa5`IKkWWBjD0hk=9Jfml4oM`#8TCPj~vCmveXtCV-N4j2lFI%zwt_=0qhP zVjfE>NdOU&m3MkgXPy!eRpAb5iZVp6eCkZcI#tO3acRk9&H{1g^7Fxt9ksXMmIs}F zqfhPM3Ljo-AcN+o;0L2M{b~$aScm_Gyu8Lf#|EL&nqAAKG{uH!4uaY|AfORZ{~B+b(w3nGTI20lG5)a75Dx-w9yk>> zTWX0`e@tSPpopAGA+G)uoXsa5iOvT3{GW$OSBxH zJ7Kh)_k7a*Sjw8O6@NBuy0LgAVaEJ6oG&-+`m$&d^-`0RWAw)=>7bRJ-@e&|CeQG`kvABo5(Z5MJ=pB++(fgp1>k=L5B^@zrO0DgQkE&YJ@6%&+KgQ8vF&2 zwI9_u{5jjE9 z_jhpl+~mrIzC6GWwRCe$@dMicaoKL)zTqYNLT(2qP&Bi`C}_UYhsf{K54o75R?mr| zL?OHVyg!sV{V>Lx<*b++m4=P*6UvesyyIk?z|>DB1(m|J@d z80!C^?!BX$>bq@WtSCOfV?l}vDmFksq)7>g2&jnkULw+KfY3vTihv?Tq=(*XC_-o< zAfO<<1QG~M1VShD03qbt=zHGtp6@%~9p{XD$GG?IG5CYcNXXv#?e$x0t~uxG_V)zD zOarBl=xGW8hx|jd^BB?W^S=kkpG)U$~$-iEcB7)x#To822q z8!-320Z8*^6$p~o088uif&aX;x0ifxOeEj<%3qTx07`+daM4@%P5tcgxfn--4ch z_aNDL`?bcqYg43YKC-D5YoWltmGn8o96?tQp_!1OmR6Kkm zD{R?W%xB|VpcC9_g4H#;_V}NaWGl44%-8ipdEK>RUzo|!`<4iO1bnTXFD4nzcO*ycq zsP+}Iy7zTXJNue1OM{^L<35tjdjWvr&0pM<2Yxxd7#{=(>}cZJ%EOwOokqA=?%dp? zjF(as8=aDM`|l#Q!d^rka+}Mp+1p2xmeeWw2ib$o(31x;g;;ubzf*&I@@#+Yp)xQ# zRi{J3L#IkX4YLUlx&KlAxg9;A$E`s?GFH*ztPI(a=QkNyxgAf?^iW2_swTw%N!@%s zKU_Jj{{~8KGo*I*M$OSq>mAdUk{)(jHK}xImu@-i`B%qD=bXu3+>X{8$9F*WQuiTO zKydS?c7a4 zpH3IVMwjGbT*JOqx(i|ud2%j&()wWvDghVkppsKqon~Ci96c-zvm5oTf_<`?EBCMt z^Ler1r+B)`%R_bsuK!-V$`dikGEF0I^IaHMgGE`O;5_an;K+`|aeP<7_k+9QC3MeR ze+!dVtfj8=#vU}a)o!Iq>*e(Ox-%S@O8fkpwco}nY9!-BW0lwA`(X$0;qFQ1!L$UB zaj~q2O~gIkJGr(iK`74zyFxkRCA=*C^Zkk`X!%EFDD%B;n5Ofh*bk(Cr9+&!Akfnh znOG9~yC`@?(9nQ<;XzyN!_{G)RD5BojY$>eO!RSa09(jwWPIJ4muw?-mlj_5d% z;H$@u9$m7DvpGqfYz{VtuYZKtwz4t}fbeICH&vAnmbY47@t0GOX~xv(m9vePT)+~` zK3d0GUIkgeR8Y%o+5xE}*v$7i)ST;bP~4iZwL=qtuS=-e6R$me`BU(_KolK zACN4XPjskZwdu^>YBQ@a=Ss)pF%~W{+Ic7Oqf4r+Pg3J~f3kCNpweq85{y>HC1_() zKqS+!^F%ewj_!YC_n7yGO0VVQ@{-xkVm5JZ-S>P%z?On70_tP~|t zGmAj#{xLe+*8BNLoJzf;c(udlgGwMgbR}eYCUl5zMOG@Y+IlDdV>=}wPg0L^d7rR* zz9a_+$v;+$_~u}}Bg;ECWB2z?UW&+P@@+(zXnXnQaBG>eUFpeD-OZQQaUqozSYAv!k*n{5(wd$1IVuXuH{8+s_c5^pxB1%CIx3xyUWc(BFT?yX%;W&}T z#xq~2t@l*w8E%qiY52=ewzLD%!())*N;v|hUVNSQ{&kbu^v3~{s$C?zWsaD@H5(I;4^XX|G9y3J|>Eko!RSm98B>GHeXVCU&F(R zloxoGdSQ-$5E5ukfkttc=%&sJ_eif0gI{=*xI7PWJLIJU2wOqZz)Du;fD;QkIHo+*0yecaZ+P$zI_>z0kxCrcNEqF+2GL5~>}j>+ z#Hz8%HwVbtx_G0B76mS`zEcD>Ua`Dh+Lozwm|1~W%3MyCy>NJ-W=sEkC`^|`;I)2c-$PCzg2V4zLUgMsZo7l zYP7E67uyMYY|cr~=!xE3ahz;Pc?zC)%s8(jAV7?Ap3*~5p@5vs9vYNq6Cd z3EFb)ha6asJBvs?i*R==te?6)o1)mDLK=3Mkt*HQ1#P9Rac|p5LER7_X{qrcjrT2E z0=_!*#lyY<0CIMQNsb$sBYznec;R2`n`s(U1?^E1HIer3`loAYn@tn+Y_BHF%%aW8 zugqfj((tGH1+&#ymz(2e&@stZwY8El&OSdqm>2b)J2^Dyi_t`cuNc_8leI8b6-_Lp zuM*I{8%ANfgKPu6l`Q?KddoN&#N|S8ic#(^?$#y1=PV^w`3a3m*fX|uRXYF;(i)#K zT|V#k0Y-)Ktwy9SEP9#g4>=hU9}q^jEm0$|@}s$^ft;bT+Agz=5Hw34SfU}l^dVrC zHS1NQ)nhZ~{f4-r<*<~wLNh5(KFMfMb>?oEQ3Eo|OO9%U@TpJbT1w8<@7mbYtLxtV zOSh9ca^Y+|y?jB;H~Ac0`YFvg*KU5+&e`-<-2kGSP;6DN)$cY1O>HoMIRx68JHErd zNFjkzG&`&Bp)2J(^aAAD&pJC0+We zv^MkuuC#%k7Vm!(avjVchf(8hH|a0BG$2V-5q3H-vUsK)K)!eQN&wx8ah;|fi~>5 zXVlrRp8l7%z|6AI@%>{w>V5lFzcwdZG49{IipF;r7n$z%$aNpzcetwhv?H^kbH^m^ zR&Kr>S$}f{d^=yeUgowA=r9oifNNV7&&Tu4WUScFh*aBIq8keZU;r;r)om6~|3(+(52(+;@PCo^!vwE1 zg&2I#`Y<6cRumO0sxPqk@0!nxQ(qYI3=oKy~OB%Q`oHijvb6>GJRFovJ ze_xO+$iF2htBX}024DS$2;@&E$^kI9y`Y)#O3I7$mStJSs%yeKDwyrMX4ycVVLf*G zUsv7NVI2GBVe8JX`4+c5v7k~sq98zF`}cDAZ_7S`SN#uGj>d9EV+texJ6^_~JBzlJ z;uE!|ARm0bbJsD3kSfWUYH{&D$!l6sb}j@xtD$L?N;OnrO-7Rz#|;z#^|`@DUUh*k zMnQ67{}Oe0@Lw-Ex{6i)az?pL`H~God()Vg`t6_1!+(%BV3l|Mwc})5rJsmz0L;}) z_(X$BXkxLiS!WMBnTM^r=&GdG6Kio+?8>hT7CMKcX3nj0S{_D*|ASVwMq{#8`$!>M zqIbK0c*Y-dUmdMsqO^dCCU{ug)he84VEw(_!ca~_!QgU<1jvTp@4JH4@JE4nP7Z8h z_w{(m#%a~fo}5g8?-p=jdGEfU7rUgGQtC(i&H5|_oTiMzV76$jrO!#-$#Hg6owSbT- z;%3RI>cw9t>pwpkE1G*?K@`vt<@PANDB0w`LxypRwqDp;D`xV0a}==QJ?u8?oTFZt z5jEnCdt!bj*KUR8xfUbsui;uw`q48oNU1}5Ri9KdDcpGkuk#XUHyDR}DEn!7K&Y6P zQYk;fvcEluY5C%!WTYPZqi3{oD?WcFxTr~XHiB>5@zuEa0QyB@U#-^wCS=6W`(8~b zn<&cTB#QKouN+W-*< z=H?JpS5oH+wOez5@xp%N+Tl(X>laJ)&1+;2RSq8q{<}~TeHG2 zRC(wuC`>rO&euC~G5(9Ev!3^gTwt59dpe12^mg!{u5aEA|Ib9`0RVz9x@GG~5Kzesob8~cTWvT4cd&(Esw zaGCpOHj!bPnj@ol$S5AL{XJo*?kA2Ps;r^S{UQIG{zu)#^-z!NE07$zvq^@6X{&>! zYi8T>L|!@wtnFtiA1Dv0Q!h<@YeejLwiNFPpIN9H-^DBA#Zs*$^E0JDe$VM3=NJ>^ z%1ULGAGsxGQz&A%wArvJ_&C^1CF;U%UZFe!iOq4IPoGn2X_Konnna8*;~)Jjjcus@ zx^VxV=ZbCM=&M+tABAycs8#OuGJG3ubmWet{4wp4gKa4ZZY;6`r&~}yGOnvZuUA;LVbE< zjhoKC24h88w)mfk;_G1-?tA6D3a)Br{=~_1H@YX&A!hBH*p-iKx{4TCGT^lIg7dJ? zd0Bh(#~RmW<%KVIj5y%0^v@5@u8af zwn*7pBn2ELN8Yxfe>6@3E1OjKJ(5(72oi8LXZ4ve^AmYQ{o%q4r^dgXFv-wWbQ8LD zS#Rm-LeW(SOXz2u69wL^c#*}v=i_7-SMiFX4|M@TweKcF)~ zayzDgk2);qAdWwUWx9g$0Ze_}Rav`IW^6id@OxUEMen4u3al42Vdrm)TEvC@VfJ5~ z0GR#LfHQB`h4tWjCoVxl~cO~-O^{snbVH_ES=bQOz9e8O{ZmL_Oiwb|^f?$(% z7`j#;6zpKXR$V+a;-Iby~omm_#|M(ZjqlqEugAFJd93IaPWP~yfAMKs}%Eu zqx%+aa|0G##wbJzX<5cVt$(VDeMNwKf22~Wo>V(rV_Zi1{#FG(Lm1MHR`1YT-;l^z zqoO;oHHZ;2qzqw+^mk$Rl}xtWZKMb+tv1G7Q7qN0QE&0X&it7R=$ZH_#=ma-3G0vi zdyBoHzRx4amKBDXWVt{Ucq7s5QD>|tz=@AAgj!1mWNfD!RT&Uy8=~qLS+WPm95PFE z)O?WX#<}h!er-sL7o%wa5evd`|0w=x@wQ33i_Kp{?~TG%T~IJTamDPcnAev6(8pFwB&FidtvseG@3%XB4eG;xT>8c-zU>?Z& z@Lj%XrH<&o^4;!6$%rZR$_iQkuv7e&X|qRIv_)=|gdC|XdEdRGybAagAHOu)!GFhW z!+5!v4<#$suWd2Lz;lC2A`JCFGE5S8(^xnn% zZl*FkWb1!&Wku}Ryytf(zTA5WJt9{Gen~*D)KQIbR;ereiT;zba<`G=Ow3=un`94Tew{y8P}Y^Tg=4qfu53bA z+ZlUe_M*Wt)(fk7QfeCegur7C&1ux4`dLm9)e8p-lV_L>M?3|xv)U%=mM7qi_5;_S zD^8g(FRErtLi|u0X<@4CgGs4l7|lprRG8viN!d+1h2F3F=HP#cV)DA1LiAnwqRM?!l#JDoHDN!e4R@3K+f#tz(nfHBGE54 z@mwCP`a7S`;qURt7bSxeL|ZHTwzfZmlkRmlX8}y+nJy$0%5&WvGSRobo{%{c3`7Q! z`3XSh>39vhCl4f1Mj1apNX^dQNAB8>ZaASno>7D;W4g^BS11$NrTc${t=G5M*r!hX_<$RL z{PLXg0A27$^m%FKb^eB>04jz$`HfNBCNfrSz90yO=jXq!Hwkej3=4rO<}#&_eTxe! zP|D_+!2(uAw*H;0*h`HdzZU=yzn?}Yc6fX&A^CF@di2o-CoMmpeIDj<{TzA&QOm!# zOsKH;KFzr6K+5&uk#ihld4YabHDRXMgcg`T(RE5ZV9WD6L@Hld0Z=>HgDELib?Ji94M2gy| z+b`#q)lygHYj;UssA`%4zmxqK(*+@vJzg=g@g21w^fy?;5MxO4RC@8GH_fX>V8@M8 z6rA}dyrrERVWY4PhVKPjU#Z)3J*H9fZ|4_RA6H-BUm*5q#QZt+-?z^JHo*Tu9R;YK z54Xtw#KPe}@F>JakdU$B6xl_cD$)^#?<0wBqevt|w5uVRK?5(h@ABT+-X)6m*Vn;k z@^xUZ36SYwS%sPY_ns55>e`JTHGSN^%wGU_7!S-x&7yXZ+>&{EP6t;^`_Ojh9|MYf z;2M9k6JHZaR z2M5!hAG)S^kUBZ3394hY9?Mef(3%=EmW?fvr(67p(+KN}rafn3VZomfu6rpT<+(DN-^vZ^^taw`&M*?c zdGqFQk4X^orJOO0*GNy+`}e1qFF)w@zxDn5cRNyN!nSC>MQb?zVD=t8zaQ(27?5k>=ZlCG}rYYyP?-tpnR$DoZU(CHTsZRFTv2 zqew;@$M*~P$mh-jb?9a%;wo|ySkOA4e_~T5FVDlv=kp8`Hz^HtT0!Dmsyt%c|5l-$ zZR4#Ro1PSOYRy2tc54b$Bn~4fA`T{xe;XL}Z_Fu8NlDojjl<=tk3fY;ZcyyyC7U&> zA=cNU(6B^iTa*>JIAqe7RC!Ls3M*oE;o?JP|G__0W}ts2z_ALAmYAb&q|)yWFkS!% z^hqGN!US2$uIv12VNRXubKt3S?JPZ*j#9UuY6-(vykrJO`na(CUWE(_05RndQULg= ze*@fb7op#$|Ned2{1Zs$!6EA=TYvN_jN$bm#_|y0e;*$I6;q1P41guCx%npKHV9tW z-!JziHT}A@$9|nSws9xQ5M##dz|E!|Cv<*h-UoQ58QNJg=K=s%q~O=AIE0Qm7?vzaRX@~aH+kR7st{&2H3)~1i|A9=$&V^~;h%9JM7>5}?s|Jo6rhc(xJ z2FU%dX8`|Cz$$5vR7a}yHsl`Um2U&1t2BOFFKIn9K8s2h2p{foQR?Q=_UpV1NIvw@ zwKNYX;Z#`YaB=9y_Ik)qmyGL-LIc$*;NB%CPr$3?&N(1W(wMjWF5K5UnJC~G=8UiG z3gJR)xCSr14VjyERvKe3fbmM$7ZL@o{$vqvA1xkwe`@zH15|W~n_D7U>!Aj(ctdW( zQRniGyTf{22i3u$@Iz5V-U1LiUq8FK91zIFwOV}knLvSs5q;KHNoY6ys3czx9$$0j z!fwof)3b{3Y~@89Yi5P0$D4~F;uB8eS8TiE=CH9vR7}&jaR%Lgv$S@w{Nvq!gHY6P z@ZZj?3=d~q#!q$Qc&90IM5fCt0v|dpzrUEcEexB$*XlVE&md*+6IA3HE6X#M)00OG$#tCf-S60&IRTN zIVM}(<*DvFg&8JpHDb7iMLV~+$S%MwMcsvgI?@40VM!gusm|LUxO@`}A(-9wd+kQN zsiA__=QjYv!|3)ufDFbB2ySx_Q@q?s6udH#I|O7nExuiI*Q;PshTt52e7pqWOW{#j zQ>&Uftax66NSL}VVEM3C?s<#fUZ)xhrVZxIJ`Xe2D3zz13$l7#aq#x5G>vWE2~|O+ z2D={URgVuzQ?|DY20a|m=E)I%AR1w>wIpIzw9j4UiJkx}2H(-A~ z+)VN=bmLcXqdgZFaD4Ua1y1Z{r_0H^|Lz%aJ)`M@D?*g!HFb`8LE4OWD&z_J5zSvxUYwz|H)H8;<|}KA9Wr1p5RcNmKV(S%SjH9!>!&^x-=rmBL{efIsU`w z;fy#$U6k2(++fxR;d4bzYdZ4~RD0Ejp1oZuu+Vrqq}?&QO!F99e_`C)m5R8Srs4rK zexM{QVfsw%Q?mooW?KIo_r&j3ehz53^ z(l0$rvQepyOANTxV!t%fI#8r+5La!Q!3ecj?T)(#JYMnY4<$jUE756Y>b zQ1L(R58(&+*~@;53MeLo{-VJ8&?!LQ6ZrpfsFwLB3i5jKFeIHjXEyNqYvg*7EdQR-UYp9fiqINQ2X#xIsLm}4|%E5 zi>(*_p>mwF;2VWUuWEGTlT#9gJrr7HET^3jv*Sk{g};D7k;G6{y(;;-oSoIm^-d{D z7q{Lo`A26q(G#dUg_Yw&2YeP(PrJ35$|UH;d(UL#mr7VX*M@)lB?yRDrGi!GgDC>n zb`_a9R>NgMkT0r7(w6>gD6Xa;r=f3(YR0BrY_2-Whoe0TLd%WuM(A(<34SqIu;{8@ z8wk@bm$~5HAXTo%2P^vgSqftcZI%>J#EOyC0l;J6`8C8T?NSl;svG$(g7seU*Gu?E zF-ahs9usu4k;K?3ihbc6VYC_BrZ|?ulh4^=_aY%B?QvD)YF$tSKEtdZ&(3aZwqPz8 zAtqc@LHG-LX}5`{d#}4t;2UgO2Ao3R8$AXn5Dtqn-In4K39d#Xruo5Zke5=DT_awl zC*wa(m_3%?d9+Z_7jxr#GKS5;Ox}Ay-+vdmJYrP&Id%A(ynln|6)(0KCbwm9psRQ4 zFG(((wLep7?ad1V&*bn*pLDX9&`ge97cPRv7f64P3wGKI_Aaw#iqF4bh52yK{i`>? zUqM7bNp%F+#2&I8YW)v!jq{szjU%JnW3NmpIz6(6&Q)d|J1c1(kqVHW3Pys!PJG&` z4m6M_dIqmDriDu}V`CMs5Wag^#?U1Vqb2RGu}0clJ?9~`ZosYAAlb>bJ@43fo>&=Y z-DyuolEuwBI&=1lZLG3Tw@{&a?xn%_29ESZncBUnT(&w}z{)M)_pMQWf!j>G?RL^i zfCL~M>kcjOah5^s9y@KkCcSc!GC1N?v>71x7Dx6Fo5k-?nv}KtGX!+F>IO{htkJUN~j%?34!RER(X z4;JxyC?U*=W^1vS{=K69iA}vEXPWVz6#Ay*ZKcr^y(U&|LTvBJ^5L-j4 zinm~X;tC7lxJ7pi@=O?9?;@JX{j74d4r5QdHO?fk&f&(51uzmxMy?8#F38C9E>;LW zYd*1Kxt`iZUdo<}xXADN3}!c>%)Dpu>U8Z(U@PAJa|am72YC14TueLaw0}zT9z>I3 z3?b-Qbj^>nJ-a(}oE~B+u;@LHB*Mm=DKiMsr)wu(d>j5|DJYuLr8okvZ$PYgANde6 zG0V>%c}zJC_yCT0a9QHTJ1e`D?cOp*ienHdgIBHYMUT5y77L7R5rh*TZZe`f_>VDs z1;l*}ulY00d*LDV+U@Uu%ee_=Hclg`=)xBVVFQya8{3}L3v`dO;?vB2Y}VT#`8uOW z+_@OfaiJbpztqZ{Sh3Q?s=71UnHL+^1=JpFZ{szf47JT<{`=Nm$zawV2C|7&T1yi{TXM!);EsbiN5Z~6Qnux&v zWr66_+_FLF_FF)5SR#jkj7;9|G_R= zi||YF24PEf$7c@J(r&$Gl=fZO>Ds}uJy+qpiElSsw&QF^zYY=?jP9o9-gX$9+a}h& z%ptn75PqD3@&L90I@QFA_^S=G60xO0yNt^rUMJ>I!nZIdPu-2IGDjJ~^V9DPH+QbM1@+huEVse};>YHP?kzymGsbe92mf^oxYC?ojk#Ch{@AB~e=;4-9P((pF z3e%^~nN9)Zt$(PP_g?_I@c?%Iac|QfWEwwy4A_3|@E$(tgKqx%KM6qJ2Ees zj??XfH00k&Yi&NS%WtqP#MhuF&cxu$jnr$2VuYggd)z`GsBb z+2_q+wDC(X5$~B@BYis3k|~DnKg68B(KM0NcO_g_&ia1)&TR{Yaw@4W z?smQ3=3e*lMS8+77IR_&A5o9GvJkbMr~VP)gxu6X{yVed+l&$de$~Tb4Z+sxYaNoG z(rspg(T>F>?%w4s^#)%Kc2fM)jke759&x1(xNThSeyZ2#$tjtIF%TlK$r1Ce*+*mz{_tQz2*8lC*7YA?3dW={0ZvnwRxWeZpi ziFSFN_r3V!im}$RBsD;_`bVIrVVEqNH#GaogVfa)GPh*T4#d6R(z=H?V`8c`jbU9` z>QW30rH6qaFNB-Z)5Ax3U;~6v%u$hc=puJL#3!11%&S{Ws$RrXxm^@&zpeSrlh3AZ#Ii~;%3xt z<2wQ0E5&*RuR1qYWE332hm>NUJMC;7|K9mwptp)2Z}T~!4j7vR>*yIJ!+ag))RIyJj{8Dsv^HLyT$Y{aT0dvbZ|!!S#G9S7@H%-n35%&_d@ z02SMB0hEO!6Q0|^kg0#XLH#>-~zg;@SX&sMEfxIO>Mp z+`E18ndFEq;)aD7DZxg3S^_2lyuKJ%8Vouf?EMwj?aQ{KDK~yPTbs(5jh;pq`x_9uu~_9M@m|3t}iHs z(291Tzdq-SPlXY-!gb#6in-SMvX?=mrXD=s`8qV-_^u9$=sE86q)K1LR7+qEI(; zT59x{RZI|%{9Cg7x3lq!h334$`8_2dU8+J3O58%f9&6a<2XymSBd@vx&Wf4cz5coCcHMY3aWp^!{LO;k@(Hy?_)61xi)N6Mm#mEuGaf`^WuVo-|e7LZSd`S!}R&)+YXBL zjeDWwp6eS_i=?W%!doKvEBMUpe#tJvX5eZ2{Z$8KAEpfJ>?%9$5#joRdpoZ1*SIk} zlqO2)!{o*JQ;Ki>m0XlXZ1FiQQcrjTpMhZSX**bl_HI^vj)qeM@QW(P(F9FicXdhm zxGg19+b4t!eHDjqKTq!sjHbX-C>&II;!cvXyj2pe>i*!tfjQU3X_S%5xuS{h(~m~@ zM-J_F9|pRe&3nm$K?q)+RbcD1+}qb+~?g~zh1&Df0i8qFIwMS^juR1 zCzY!{9}zwnHfT_dlfMM@2`|2cC`;5FU#5`3veW)X-8{8B2js40_nHU(U7DEQPwO^? zMI8<+#;#Iv(&S$+p@x(-_6hp9kXXWqFVT;j0oJzX2@FUdIOdJashkl1ue zoC2bLCx)6Mlp-ou*ocR*+}jqJHH|3dgv5AoZsvYW#U$^2ob>{SUa@pWJgi?%q#i`l z44M6x3qQ)&!oz1jANaYx#x{_7D$h8LfJHknCi~D3)0gd_ssP~wzD8P?u-Par2wU=T ztR6}S+(s*p>_#kqa{Y@$Dd1ygx%GT>-AC-%9Kbs~Y$@NzcDu_a zKVip?l(BnZ5Upe3TRl&mh27}&a!yMPBVKnYe#nt89nZ55uIOHuLP)YM$(aMFegW6U zM7IE)&%8_(p2fD;4heDyI*mF68MeYPlhFPZ}dFN+J^9BZ%DE2 zPqvJl?Kr)tqQgRwlT^@_*``PFD{#N*X6+d-c2D211 z9k+E*Nb<2u7ZFy|A^0V(f1(WWaasF^L!3&H)0hp!-RB1@;zNTYZ4If0y2-`Mm@)fL zUd4U;f-N6qK!tIwp1Sa=p1x+uuRHD~uP5#W?#`6RLA=z#g+U;Ym6!9Gw-wV7MPy}6 zI_tDd!*{_02lTHQ1Ns-ci53>+orR zF!jos(d41xWc!Ap+OCKC>skqSwi#RncIBQTv0EpbZQ+OML+iJ4d*9;moEdTre6yOv zm#B+x#!0Xujm{!*V$=+Oy>!?N&p_+@(H1>0EegL>H+qDnV1IDR1Q_d4<$DOWa7-b$hDD1sjI?XjR?4f4$+XGUK>_FvZ0X&n2PP=q2wu zRTp-5s+?RJryU~F;2nx1Byi5uHeFb_w@t{(W{Gg%e2@Esm(+}=@V z@bW<%)ExDXC=M7w-|^yJAVRW?;%V9RNXz|(j+AL{i*ZH8l|}m#U8-%e)va5#f{`@= z$Qi_6gMNkETkl>ZiR8w)xKug3t^mXGt$c!>tHMt_zKe@~v+O<>Fwey`q|IxM(pbRQ|Mg zYgVf@X7v++rd{DU2J>}_K5ODt)Z4+!Xgk+5FnZ=rw&%5xE#k%EH{=kx2GW$_i3+rt zW`4!$vK{ky`~ivUX7%6;o7=^G*F^_B7xIg(m$%R^mI1dSBq1G#v*aZ0aEYQ~t^*ul zKK=zQ`$S-Fl@96mHJk>PrbD`~%$85*d;MH}+pdeerpr%zsmgil9G9<>&kbZqIy*^L zI}`MIyRPai@qXnV+dsE3I%jlyG0DGzsW@z}YR}wV zw7lCJ2~^5;y7Vxy{En7tmvMf~w@JlfE||P9S}a#E)F}ZMbl{u!1Dd$Oah3#Qx_rmUi-}m?`{H2CR!yZJtPEl5~1B|wE|9SkK z$qLtY70$+StU6pu;9tI&$cqiGV+YR7w@*KN;s>4wbWyO7`fFy_oUntfNyX|K{cPf_ zUQh>_F{c+^&Kg>$_dd@;_ujoQv665Sx%XVLGhuVN{R*PEHn=dc$!lI|RIl4x9ad?8 z;?@{?3B6@HLf8J1vj?jmeK|N(wQ46^*y!g>Ule#Cd{YZ-HctBL-%mAOueCRk;a>ND zm41=y8rU$OSn5|6Tdb}fm10rxa^`;6oO@09b*tGq1ppq2@dEAoJoAkxl zZenq{LLQD|6(w3rU_EwK6d?kGjSp#qdz)JEs7d4sKA zAXHjs8INF;Whd4n<*N1`jtFHrD7rtNq&Abo2uSS8r7j?8WN6s)U^=NgMPqtbbG}U^ z#KhJ!a+MJ8FLkXvnVSp3GH#O;$N4eFXtm&Nnefx>$>QJ* z_HIH4kPr8y@QV2oL-wn-7raZ9k(rrfZ$m{zUi4;S($3s9a-^u(F9}vFh)C?#BI>NR zMW_>Jx|bz{87_{PYj^$ilbf)uetRxc_!)ojcAs!k3H3d+HpQn>$)|=Ro`lW^ao11lQJPaP8>>4ZJ{O|Jl3O ztR{+EGP@XMXZu0X;J*V8YCGHGCZZ%5bq=U*&&u2D%LZ?%gmO)xgN zlJk9+&8b&L$?^!k!I8x`@6Rsa=9RM($Yr*HT8pD7bHJ`*=v4oT$MQ0_agmjF@Q)FT zszJYf>^DarbqRdpXzoLVEi0NVsmuFzrT5S#Lu=}C(G#qum%MdSfaLA=k!7Lph<#&@-PWkGc8TWZ{ zpg(N2Pq!hP{rr-5o)&=s4EsBB3RRf(&j^;Nm@wVFW_okuZB^ZDU^mk?7?O|4@HpC~ zWg>cab9%<{73{GS`q5gfVYk7W?IllG$p(-drjVRmd!?>I4KI47EmD8cXVMQgNVd_~7d5uMs#CX5{Fv(S zz>7#Vkb)z08l0op$fLd)vYZVKd~~eNlneo1W7=|1^np-cfE9x-+jm7IW$p%GJ)FDv zvHC3$%jMDAzrSRrtY_f>{okaiEmMA>lTU@iiTEY9fN+OmQ!^&5|Cx=p`T(_lxnyur z@tJM_`CR?`SaSUFFmSo%HNmC(aWMt96Mv)bzuE`^`~s>}HGjl7WJS&>7bV1W>f6v((x~+^laqJ%wf~)|+)+oRJ{R{GBtDEhrikR_V zea#&Yt^56y9M24Vkpf-G?9Oa@I#HX^`|}+O=ZDjH-eVx7w-yX|vBsOTK<4Esq`TOu zFyOn1TQdDjc_+n195vH3&sxNK+1vR>!bdf)`C(s_+X(e7oi*KHq!>$pag1KN^5s4U zaGJPH7Wj=TP`)r|lpSVq+ZMIwCZ5Lnb-o!JCxr9~3cP&3-k+!6+7YoZ7P45MZdB$G zXdODAulEcu?eH4QOq`v}P45vLq&nE#DP4^Z0NyB1gTsVC5>LyVil{lfwBQ-jXUn82H+FX_ShaSsYOpU>QD9^<-h8 z42kutZ&7mAwrbx=xODr{?1+Apq?-*OGpLpXu(EbuQQftVIRd|EBb=Mve6A{Q2dtxO zD@#8*pA{zGp3WvREs;>Zo(VIrg3jqH-;x^IJ2Y7rY^=^6qI-t}Bb zkHqQS+0D}Qzp3439W{RyQAjRD^ja!4q!v3UEq3)NF z=$kS|Xn$+Bw7Ph3aPH20nE|aprbquv*+>E`StIO3~Qy zip~pdYMs5Y@zHy#N>U5dIfbs5e|)y1a{ebLEO7D1J%2@#)HdCs?!NQSDkea-W?#^K ze`w>iYV~R}ARBkzcc8B9aTj<7CyoWzx@e5(LHbCW7j6mxhS9_Or?=*b&&2z+W7Y?A ziC+%1vzHEpX}gey0SKe4P^z;2W{L2&J>*eczd!ArFG!<#{1cyXen(3G4=H2!dy7Xv za-~($RfQ!RRC*4p1Qu0Yl2`yEP<3S}7r5y-~m%so;G*MPIaTSgN$` z5U#!eQWQsO_uA z?Crw#61od$h5p)}dsm02jwjaxBh*n6m&zrLLO5m1#PYB@;|f@-=36&xDi#_f?qE!X zxAsv}vMXxi={wD8TaP2CGY^dQqv7cVEBoJ1!?(Jmd_1`eu0_b-O=W~n<46j-K7*C` z&oAb1@~xLd8e$gg@~u%t854l{>CTiV*R$_Cd_)+*gGy6Qls+M2IJs}*Sd-I~l7mV0sVV(agGGg+H2Kkbfe zXqMYE#{A8ms}ADsJ73R?g1(~Z9e7rJbxo9fa=oRvpCBHzFvyl}52GDJ{e3?|W=}r; z4;S)v`|P^9lyu^Jb({lkS_C2NRJ=LkgtzdZ`llLItEX6ux2^ z%i8^c7H4W*9bNmtrnCmDP%^XRYBXl>xg0Y2auK#CG^+oNVuGq@b>sK{th?Qt76+Ac zmHw90VJ9WBE%NPhMTcWeDxb>>rlGhEWR2Q}?i`mvrxQgyPQAm2Twxk3K&d@&cIpcqddD02S!Mc8j_)O`qzC)aef}jLar11f73OY zw!2VL5;|MaV10Q9i8NzjA1U2c-<^~Ey-96DxtpV&xZ$>tgt$CMi?+@L+RVHOz}hdQ zLwoqY#;f_w@@C6C+wch|?3kO?7KD=*EwL1|h?D3u8jmMYvgd$Hp135MQVdWBNwb{9 z)di-^Z`xB}-r9V|<$>@)#%$*|OnDaU zQkY1n#-OSqI9>>nY5DzQq5GraWu!Qy>7Hmah>?h>yO6+8w$g77fd&Pb|LA*Mr-Kcqt-$L z(GwatW(I~)#v?o~*Sz$wdPBB%g%Pcz*`xJMj8W*urNmJw4S%H*EhkX}jt&-QgN)zLHiN;tc_Wq^H@0uvD+Ude z8@~?ete5mDliAO#5;hPRzTNmvbr9^bS$7`i#eYr%1480Je>D=3CmM6fx=x+s%^0`oXr1tH>;=al1H*rN0$H6x3;cGrGtfUvhXvl%8oc0G9 zmQY{Uz(*nb2gS&PdUS?=b@x@foJ8qZH#Zwi$%oI?eC=!{Esz&VBEqFZ+;16vc-pcl z9WZ<4Iq_xEhxCQPnz@4IL@7qIfYd>6nK@te#FDjTXI+%L(}|!GeCQED563CTuqC|i zwGBMq;N?4CDvB*_jlJcWcP%O^;kyBKjKOy-J2iI2E8=9@Wb~ctiu;T*Y=`L~gB7!Q zDLIVj|3lq-hBdMF{h}yV6j&@ol)97!QUs)TP!v#lFQEzoLg)wxp(!Ft6{*sDNr2Eo z??~vKgia{Z2`waaI1_x=^FDi@z29r^eeLt%%%@yQW-@cnow@(zS4_T&l%@iq3lD%$ z*Vc~1=8HXMicpYWxOTOV2vap(4gblSpy0mS%K-n7N^A1FM->nuFHMnQhe8=8U zOu0k{`nA8*ki%76jsFVfim>1iLC_4K?1WRG_NfM64VR^r)Iai(uMqN*Ah&*1e~0et zT6I|H>m3?%K`=dH9m=E95(POvv0h+>Pw=_yGx-j`^W;Ff^I~V+nIG_P%`CU1W774B z-sPnar6nIl^a+$Zw*zJFsrO;b5^}C=`+%jxcSw;Uhi5M*>v7+}nqE*>>w!vRd5hf= z5M#~)-O{I5b>R8ax9cr=!|sDWr-SP+D`|AE=09Q!%Cii!D?GN43G4|)f7fHVGvru` zHr`WLVsVm+G<=R-wZz}lOC}-b*oC;7K8J6z7{5GZP&&+?cKh-f{iJ21%U(RsRdMQd z8|13A=9@Y_!i+uo5R&0~3?_s$?zn!-x5t@iW|W*xxJgFWuUppFwK*@$=|X)>{blcN z4IsBkSR|Q8f`7o?6=#Xi6>Vs>xReFHq*|c7^I*$JOk|SxQpDW{AmQ9bkUIscrw>`} zwQR{fuJjX#WH$qdx2v}vHJs$2qV2+`GON_OAhLk4i=^5On@y;3i_t9@&)F0IK-c&_ zN;hJsk225Gr=^mkx=NbR#*u4L9lO`l!uW?`XJ&m3L8$Kq@*3-=qIOG={13l0Chk(V zXB7nOMA`=3bJXy@xXQBQHp3e`?^nFou2_W#v56|@ba_uJuAS^o(C#Anl~L;4P?)c) zRsd16r|YI0%D`oF6Cdz@}F9MGG3(h8kDeOulsMEtQD|>p;a!~tuY`}YqK(Q`nZTyxnz0uh{0z)W=6w} zAqbBx6YP^jV;Q3=cfc@KdClg^nYLWNLHbBb=eFYK?~UxQPi@5*m0siPKp+uzes`?a zk&2MT{x{6R^RV;YfzNrYy10|3nGbRz{r#%waK!koH#Dvet|#Ebviui|32$O%=jckl z*zjeY+Rv%TMnOfO*>$884H}}qssa)NS$Nk~{z@%jJb7YrJsE!5=1NfcI05yE6SAn@ ztahAbUEkR=y@%Oi80)n@f*V;k5+`V=!1<8UdbG*=R5dnQzv0z}bT9N2a+K>%z4TT! zP+TXWp}WMK*94MAsN;_BJ3Cl>I>O(}SjEM@?JQ+Ykg@+#<4!(UWgvf0GRpl!IU6gL zw;`~qI9;Jz!o@gQX0l~B+#LGxQki?@4=>k`l~g^k>{%X^3Q@im(FOLv&jw;8j22DN~*Lc@I&|1Sc(%;8=DQ8OmqnWSm_>HK~aHRBw_dANGV| zXLmcJjAe56=D@8|;u(lCF1K;wY36q-VoR1KmxP0mQ!KTT7cF-WKB2KttJ zM`ZT|6ku`ji0W(&wR)tghJU+sp+JR&1J{-iuPn>4+u*OTzE>U3xfS38IU-?cd)vG* z4#KMaP$vUiPa}+4Yva)V6%AnH&%r#tW_h;5@i8uZkeo$xD=;GE%0)llKoH zqe@=+P57F-l!q!NIe}_d^9YA8)+gW-Zi=h9;p5%#bXzVwC8b8cd-bSqvL;v(su2l8 zn19srpwQx5o+-m{fuvmXsPI|{`(Cp8wIz|j2fwZ*oZBGXa;(|y(*_T8d* z`BI$I?n;EXYnO)BRJkR$4qT(>i(wUOX=C_kc`oogFjwov@F{#?CEs*-Y;h`z4^h@N z`$f^a)qJxV>&CuV@Q)?~NsJo0jq8Xo>j`d9^`R7cJ3nGd5px-+9Vq@>Xi%Uzpm*Iw zONGp!lErKK4=`Yne&CTu;=l@I{~sG>a%ku&*No;q421h;Tq$dO7lzz@-1&0ZVRLE* zAYK39j_{R&4@v@$6p|{$+YHLM=hUZ@9LDSNl!GU{VdLT^WWaK{e}4{tGRNrUs8G|_ zsdT!`Jre4$gxlfF4P_hzl^#j4dPnAO93O$tGVYTV)a8=$d}2EyAxQve5Ww-88heZ0 zaJqGa3L$<$f653vum3femd%8nGJP)lxeMN5U9ZQKAL1?Ko>+M~l_6IqbWcmlH^qqx zC_Vu4CRe_)EZlV|_vFz)7sHzZtH%0I5ISGz<<2(LzCWlxWu0NAfdG&vxSo5%!$HUe@)idnErY-A^YZ0z%_Es2qviw50cp#TOAt*6+i?<-IHqjSyNCq z2g7!+UqJ$oNu544O~z*EZz=qU*2PH#Y4(A%h@cjeE8b5!m^ee}glty;4o|)G!7QoN z>E3V+u1^9>w0qM;w zoXPj#HRLAo{fm*+?T+Qf0$?+sMnv>XC2mvyNYRM=Ly;pVBGG`&iB!ksHo-f)#Lurl z>bl;$xuEW@n)hu9jkPI3&}ogfgrIf4bFXrHdb>taCkaMHF|Z13G!L4?4K@JO%DdW5 zMD{AL_Z#Be)*yM$qG}5~wV7i0XB{U5m34mI_~s-hrt2iAlP_E4p(7?H12ez@$mAwD z;%@_5!xR3Pf>*Z?_B&sUFQ=6Y``mlpblvF2#Z*$r#s;XhJt3Z9Q!+4I#1|wEX+zge zx<>gfPJFfx_&*Te^`{4Fm&6w&B2StBxm=VJ9zSBfL zaQ&a%r~&2(uuYNtYq#IJLBN;Pe-j{qAEEs3i-5p8PFy}^dLeOat4*HA0Gto75vH=; zHf}x?lyf(RO%n{K;suU9IPE$_r?tu=pd+_q{G3A38;xeXZdY?@L?E$jpL=y?O9APT zi+#zjjn_{1G3)e1zm(f3!PF-7w1Na2BiS4z?P;rW_S`gVv9#G&4f|mZ%LKBGzp&wk z@JQb%L8K+%ZVmz%|6z0$qd)spHuw#%iuDtZXarbsIOdiGACU*P@qh&&Gy!_3S(qO6@9W{?gTB(Eh%1ds)}&1_{iIn}VUTLg|- zJY;)iAs#lIHr^?Y8z2EE=bveI(Rc6Zw>z=)++~y<#sq&qAJd*jIi|Iw5>RQrzP4|8 zxk@Y)Vxn#P1mpB9U|Ih1jqZDHGG~psZpZ|#&tkK$F|WKH+m%tAh(Db}mVDX==WSKA z+kP8QmEjTTf#fYPBRQrFC&c;W!3`xLw2B?ibLUi z*5AvAEs*3#UOJ4`QSR6TL{lt zs@h+|;uTr}pnK0$niXrz2={rb3;IVni?s^eJ)TI{HXm$E6E2szd(Pl?QJexDK$AUbJH8VzU9jz?5gjOaCS8zKJ`{HI+nIX-{t8KIhcnaGJd0-u+iH!fiR%%xkMSzZd2k~B{DrJcWdd8Uf@;mcnaq4 zMlZ8sUA27Jf+II7sqj(xF(MlYh}KX!em0@mbkrB3RNx|+25JTc_k+ADc>#tE@GzI! zYli2kGU&FrTTBd?eoz(KJWS}wO%+qo>3RU0t=Y8EuR8a7m89E+AGVf%WQ8#mLq1t79T6W2^y~(rM7NPfZ-G`y~oStG}?d|zc1gn#= z5RIU9k*>_J$*NN3p4qTEo&r-etw(M~e8{Hpv&`ygSE~%y*XoltFOv7TqW~psLr^OF zb@{iIvR1BPH@Mbnai-m*i~-Xz)n0Ckma5dMwBy<`>vd9HW|Q)5pEnDX!fghI<(Qw( zfZwmnPIl=Yo%xA1od3LpoiU|gnH;svpu#yjFBKjx;Qs*lY5%SuU@U|j zR^Hc{_&5ft-cQRP^>*VOk!gG^6di}4M%+2j*1#m6lVR0Wdw1wXG{NAd;-O^u(tiB3 zh(ZCNtkov;1I`7n2(Lz;deM5`_JpT>oa{Q9ViIbsc9xFL`C>h4db;VRMw7Zj=T%aKs8_EPiX;k^TwSl@XFq|d+@v1vxA$K+NS zTaK8VoLo)j(22XeASr3D8dZJ-^$|_~6m}e%5C6!-Ie(KRu$-`Ip`z#aF3pVkWL+#Z z=c-n3Gle0Ctxl*kXpMn4W!_j!Ntg)1B0pMs$*n0OM}E>}*-VAZnL z@uv;@ob%QA($w(itx_t7{b+|5CmDh@jnyayDb~5-Ax62Y2cb96pFR(v$CVJXxLfWv z4SU8mtQ0j%7Uw7Q6k5~58o^x7ZwoojH^a}i3{Ahdc`^A^P}JQAmJB4H^m>d#wSjXT-G@*GcJdfG4ZYlNovD_B;--4HATNf zq=F^-ISf74{Bc6kekK?LfksWnl+OSUmZa%v6TE5dO5oddNmG__ zT;^Sm5jIrN_LR_JbfP`ynHeqjlf*ek)2#MukF`G4pI(*ELyX{bMn0=wwSl*Yhv_6f z2zR^NW0EuD+iZ*G($tt#LaUwhj4B`|lf+82VAM*!t{JKWB-~GA5r@^0_Ogo@5u=F1 zKxpqzASS7+y{m@fcF{h835||4_6&WZumRa!!CM*Aa`Z^XuG|Y-rGwTax7@j#crNH) zAhj;!=AJO}KtCk4uRdTvoyCM9mx^2s+`FQ8=g{-!afj)aq&0T9mO68UZHun`?VHg+ zklo`o(aey`K)_18Z={zRWpUs71$R8NMBV@iyU=B6qZiaF?}u;fhu*l@UjzWb5I^!Kw%v&@ z{w`DpXs&OJbT91fYby%R(LP)%QJKr@?e&4eHQdKfBHvw`!%cdZ( zgy)_@vRI6LZ{qn&q4N?lk}9HP2LL>P$`ivQAfx$TNa_AhzM{_BZq~0ymncjwa8^0Q z=pML(>qnvv$DMtAH4wp2?GmfGj|oESunPMCtOtoh?sE?7LK{4t4hkrqfSE|ttKVGA zhLp;s_5Yj=oc2wQGv$GN3NBY1M&=yP(ye;01IZulv!?4Le{5^mkouOfagS8Au>jL+ zXkza*pw8s<;CE>urh-zsx8dTNH$VL&yGa@&Jge6bev#{vc*y@3dE3B?f0DcZ(2{WQ z{|~u_s!Itg|1pjJ2N~qQzWrNmjb!R+Hu-OvhbroS+b_b!(FRQ&>AF^CKH4VZN6<0}~8l-)d?oy~H1W%M0D8wFick`5PVDe{PCnE4I zYVH>!llJ)E@>AdZY>v{Lag1l7dm?FP8;_Qwqr&;Ju!aqqZWLSAU|onP=#p%&iM5ar z%Cjnd=x(X>!v-X289N~;P)SuF{M@{J>6?ZLnKi|hPz9gf8NpX)hhjL51NgbbhZPHT zGS-w_$b(I*rQ?K!qKR|n^UCc8?%{dkTx@pr?s0%2d=|*7cuV?}M)lhh$6w18MV%j3 zgItvrF%7ybrymRPoA;v{O~x4)ZnoWivfN6e^#=aIjQ$$auA7fcNc12<{nZBCm{|9VC)0soXoyEn^)fw{fR%b~#QyxrF& zl+rtcBIVgb?=j@JwbR+m{_UEGc;~h56}D0R(pi3tJMuBhr-+2?uk;a6huJ59ivy=* zajfQye$I@2ir%l~(Hr^81diRWoxweJ88;(I1v4NXSKW%^#vcZ>mN)4$B~&^l3YF*; zpM=dOS;AQWsYOU$MoUdcJ5ML7W0Ku(Vss}5!VJa~=Bj8H)tpI+mf zI+(gh&3M>{E$s51W!BQ)+PB$3XZ(3ag$3>|LpDbr#(WdkekT}t+R>+i| z{rg0y3A`{a0o>w>tOyd+IZCDFaLKG!e6Z>qvX_Q2lCx_}3)kxLxu5ow5j|h*bhrnU zHkPq8#0jYV{y(ZmHp5Q|S^k;(r=A0X@?z8$>(+Pz_u)(d}cp=nTS+(;~UdK`6$w312_}J!~ z7&S!ydck+uP$zng7gZkaYNsEMb0D?sR)-`kb*bq2@yQr-+PIj3bMMj)Cr8d=crB!UVZQ9)pIEpGYVgadhB%;o^ea?l{{ z90deqD}N7R8xa*uffC77C$BFnl}4^5pVC-enOpEv)s=M!b6>ku4{5oL@+Es*L4ItL zJ^A{id8ut9sCrW`yjr-iXg!|eC+tU~kjfDO0#5LKn=6EO)SarZZx82ePD=TL3LwmS zT{UeTIVN`vZ0*XpsGK_8y5cQjL8xWAUuV2ZUi%h*rjPX#(ALVmJ&?5Wh*1c;m{Sd< zrT^G1f5>3rdX)m~aAh8=IJR)_1~2RDTup5~YEmWP_vUC;NY3q(_iZWF8gYv&Lvzz| zbLgjjqh2bSW=iXTo)yp$5WU=x_-fpoP#Y_o*>3Z*KD>0-O?Gu@#liL={7+pTOu??W zd}>2I%^T_7zj$=4-|623Q!0@k11Qa>U*(_|$>HhwdR}K^#r&w$8T@ZB-Pnd6Q0!1? zCke6UiQd-m38U|_)z`onrfXf(7kL`&OUyutk-$?qxhCH0D41A+F)htZY2O{%GY6zi zw&7{M52_^oY~2!RhjdV_g>>f%UOGSUWO;%4;v$J$!U_#|o6pd{QXETxqVfU00%2`M zA5?&z@hMnMz+MlQs;F~2KPwz&x#r5KJEZG6VMIBzb-;~qSYLUWTI`%UR9I~;=rDhe zJ$q0aWnsY;lUfOwpUR7jw|;!7Cl4BQIM+feV^K; zIy2#Z$D-o2??U||sGD9!8dmmx8=5NbaVt8_rw2vlb%UqtSKJ2~1pF1+Z9h!2Ha##T zW;#!BOD)^4>1-&!=}pTtm7EduoZ9{hTi=_~3YcrQV63_n-9^Jmis)el9DNk$y+O`@5GK zUrQ#{Uymqm=#)9#pF`b7zVh-Iz1iNCUH-n~iO{WZzKT`R6k+KF!6j~v?KYr!AVYfY zMR#O7?`mbbk4FpawT9Yr--sBBulgR;yDN#5k8mqF+R4pgsyKqvN?krh2m-mHBz#~g z7hyFo>Ur2Z^m81!BiH^`c~pIRm`nMV@Pr5}v~p-9u$jy*KIco(LQ=Rz(uDG>@8WwJ zJ-7W>(k6G&9(J{En-$i)T8@p&LW6V~@HFvf4<^L>^(N>tuZMvb4=4a)*$tG18q#K+ zeEJP>8JrEiaj@8O!;3!F7JtW72UBSfIhPpo4F%HZD{Ix#SN9d% zG$~QTOiMg{)%hC4B&7tWw9m-mlPHwl$R2c-k8TjC;CljwXS7({IYerpZmwjGVhpo@ z%#r3e^uU`5S&=fTAW)O%u%yZ|)y{4UJOWakLhqVBTznTA>(xv1R!UlR_x_Uck;3(v zb@(DPFRE6c1{OvE-l@A682HG>uaJ;{vx;7N*WXB`S>O7^r(8l4E;DVEOC7p!!xZLm zUKuGHhAZ=H)xSzZXZn}NY2GXWSv?81hd9etoLDQP*Y%{XV}3nIwYFMqYJZL12XT{z z;uxb2qE3R;h7_2ubLIUVaZ#>Qf1v%JmE3>zd45ew)kd5w3+at)1}1=@bSGVw!$Ewu zXm9_C3i1jik}1`ojRsK^SX*Z}cB-D#zl(i+p2i0dC{wx0t6GE(w0l0`Tj5|`0h5-#&qNd-C1G8@zy|4eW%lLnilK#JYmH)pvN}8mx@@R$J zuuxVa+}p@chNAzj3#;+^nW!ce7xg>nE445>>I@V4fqj@YFR`=T z1vI=#x?T~i9l>WacAnw-(0xo&CWl2k_-O1Ysv?d!gDt-TRguNNx!nSU$ZzjO1ql&% zjAjO41>l!D64%)`4F@}^)6 zKkmR!Hurx7r@o0*)2%C+4mBQ3VEE-&xP0Dj-}OX~uMcumq!S#kelW$xxsZW~ysSxk ze_gUtWjVB;aY|HX%j-w#kH(!e4Tq$!t$m|Vm~78N4LY7gk3XhvsA`koyJ!NpM~eYv zOn(^QpP;D<@Uwz?y zs0AT%s6rk*H5&=qZPQ7u0!cZpyDmw`OG-#oP!Em6IucIysygWyA`2#_8 zo7s_MKLk}-g6gy0M35{nkn21RP*N0%Sl^ekTQ`TsUfD-g$xTMjJQ<*qG1HDiisQ#Q zI(B4-2|Nz<$k7s`PjR-}%5D@>d>p5?$neVJ$f*k) zz9lH_ftd2~>W%M?F+}rOYfkai_Ppb;?*G^jZjbj7TaMClFIgS?ob(E9-Qp_kGP9+0 z>~fcqzx(=fU98cpzYEX(V@pP`=|XL?`?(i^Td)$Z-k0?raO#TjlP;QQl#Fu;_g?f? z&N*2~01(&GOTMP~sh>bKPZ=%%8H z&_<;vfB77WMo}cLQBcnJs(d)^+XYVAo6TZTm~|4->Y>XeiqI~61V8RFAFEC$V>ClU zmUq9IE^{*2 zW!poP)I&_kK2RfRrWz%gc5N5DmDv`mE;9mbWdH!pZMULzx@ds%wbs4$=7xa?kidABIiK|mU)TCVg=mk<48LdAmo!`fN^quMx`I9UU zxWHbUic;LsoHeIV=f?O}dI}}2TN8gv1q+*>OY!4?!qm$X#>>~*{~foSbhKxxfRe!e zfT6%^mMUe*n+93gcEvS3SKbl0Tz;N=6;2o$-=N6J37H{QOnCTXoI4^3)Yb&{UCD!R z{rP)Wwx_CL?L>G=lRXeDI9U|Ek!VS__Wztf+F^_nGXBt8sCG~C7s~OouA`^nt@fi= zrbWXid_F=h22=sl)7Qq)VK>yS-sV~p-8CJSkg%=q)~nFO#20*_?C;FP-L{|FX}Bvb zVzSV#I+)aXigoL1&+ZP-_fQ{fPu-`R&3y;~G_OczD}ZpJiZ8{a)XQ=7=D@cStL-{8 zIIr$jC9cTc+r38(Lh1eMO$B#xwPg^OR!n_(E4} z23G`lOzle}JjUYZzVX&7HGtAcJRQu;u%zVG;{j2`XQT*ajkJ{^=DT5ztZ%$yL8Z^I zU9zMAr#;nZyUiqfV!6XSDd-?(eM4k1(|yz|tg*jJeCx&f;y&DW=CqnO%I(`PAT^tH z0p`6!yx7~BMC!V*KWbh)sE4q>u_}*!Y?$%y$kV!{q{3eZH+q={pGzTMuuteao-rTW zPRLsf0!)Pwj03?$LcN)~M|$&X!m0L`hbG1utZ;euECrdi_Xpz<5UxjVmxWx%-+OZD zD9JBx<>F7Dovn$yE{NUWY!tq7)pPx8F^MPpGpc}FDM4}gyvse?snP1&Y%c+_y5@tB zCD^&oYB1$iZc#ukxWSVt77&zaUYh-~us0+j`4G5@CKOO&pSnVcV5pZ(oJmU8pgh-H zHPo|d+ob{hJM6P=bB)Os1<9d`o?MSJbsXk&tsgO68_ZpLi%-=0h22X!ja4fgSo`sO z5gVCf57u45W&u=R!$O*2FHnRvml~73Y`OUzZ$8F`7Dxos?1-B0MsK(*MuD}|U`|{_ zg2#&8+47U@%rC+%ATE&rq}ZQUzZ|ZSkq1xG%8YFpH>JBJ)V)pA>>u9(4lt_=OhC@U zJr65z+nL=lBk&hdF9GPX!A)z88}P%_`>zEB3}66%Qo*_mUfbvu`U8H@3e=&0hL9~}S$$p^;D9up1l8j6%68VG!__V`Vy zt}=Z_k?N#riF07aavS)t>l5tgQ>sL{%An_Z;v`e4wLZZ;#G%fsK*E=qXG z^?c)$&m{2pXR5MJowJF;wL{vm)B|4luxmqfW7uW>P)x<4;ig>@{X*#y=jMB0#GDY& zvfBj7**|$soD2+T8P9_oYa0MCW3vyt@spO_HO7fpA608zd2p-R%o-}Q41`kDTeF5B zEWil~gw5<@@Wgsz&#d4Z=vmEHG}QfG)?9>4ft8MCxzEDg`cs0Q?O0|U2vsr4t%?*@ z@pDOvJ;R!ckN&Ox{Maql5mwW6vLV%G|0+%oGqok1u6EAg_;cHJ;=J;n&$f?})XcPv z4Ca+Og6H|7R{sQ))fMMw+o5Fm4(hIe7rH#(N-3-r<1>k{1Sg>xZK036rr>mhn(E2( z*<&to+^W$jD(&Ie9C#<=MDD^y3nedU{gltNFAC`T90DD##g)$q;7$g_=_ z$Bibwwkzenk-jx~-3ZuP*YY_(Va!mfeNT58pjP6{xDbBDg>*AEa1Yk!JHyxBuB~Y& z?`{vL%|)!wvFSvYx`tGo;JJNJd2wEd$7c^M{i^ibs>hzOA+I$~zrtreHA(2?^~o7D>8{I|Bn(!FMK* z&eMu6l2xFk9VPV0Nutde_6mu%bevz;;JC6vpd!%0)WL1epABBFj3TXyr^cA{h#ef> zU&k*5cDviKdYC`&%L-!Z@?1%87UO-CQhJMVXy%?>v`qA{hg^cOc~w#@wLphaqhlX9 z6+lFYGlZl@4-ZbEx6n%rW!**VEe%Pd1@`29o;HT*YDNvwt{b0lgfO?l(~Wq6Rk(r+ z&vzKFsrSlZgbUfm;G%_?&GlQGnFbYe_uJ3fy)EMmit0}RYA9p7j@hw-i+PAR zWqT-Yyz?=067?}}ZI9FM_?te!q*1&76hx85|cHyE7i&O<0$X7BI(C)&6`3uoN4~&U9TgP0G-a4$;qG@z~fX-4z%8 zV+-FRM`hInoNw$>W#lovuhsK#3wWq&&4}|!z^&xrKba}X{-^OVz*PJbU@GE0pl8D6 z8&gUtNI@1>ZaCmG%UA;1Meq&V*U2*T=#y@YI|k>J^I0_*W!ncaSdK=O2!UXs_MW#> zGOQu-m|t1YAW8Z=I<1o0>8*9YjDl9iA$c0M?`3pWb-xxub3qmC<>Z+gKzxf-{`{R% z95LDFiYKfeUI)04&NFADonHNtl=kxZjX2Nk4fsxGuf;1pbK6aV05M>f|C$SsVt|O< zz4Q4Dwbff~a*M*4$!Mdy(}aFjcK4F%+z)ij^SKj;VH5?YiTvr=d{IyxW~O)1#t}h2 zY)O@`H_G&I9~)!-+_B4t(UHHGhCcPPNQf*brw)HO9Cj+qP}-=UG2T7AIOzHLuIe_A z6L@hQbg1#pB0QTdN}A;Nk`XZC2pv@$A&LNRL-+eNUdKshf~{1nRlLs7*=Qqw+< zs_NFK;-TF)2yfv>Z~VGgA83Xk zpcV5Ul*A?SZ!P}{+yP3W1A0!|Kri1l?PN`#_3C@XURh3`h(l4Egi|P_HQmJ$J-wg5A2PUwfC}g6!p}4JxdxTZ(TWb5oH3_HATQMp(&Tx@$8DSG!Ds~viouPT zn_X}3ufa4)Ppn(%wmaDoiLEg4X*clvt&IMtA7W*WF{i zTawH#c5ycV1^=pKuiY99UtEgDyM;}Q)$pY)Uln@8VKDeHZ`l^&yIW8GmfMfcgP%8M z3%4?TN@;R*XF)Hsk%avK4{iyZ3 zi~}zV-wfGgiba^&mf_U1nOVn7d8NR|UUH{~SJ?NeNj!~=a^vDyX?+A1*dl<6R$3`g z$#Lj_si=Vy;uGB6oN8RuO*aLtB>_Rh`D@&;TwQ4^a*v7%AKj15Gm7h3jOG#ut!{qG zeF~<=`*6#U&~I>8#pxPFF0`GNSMt*^)4Er%c2V+8G%=M4s_{$w-klNQlcFWAqs?Z& z$-T~rRn!4dtrBKwZ=y%alJy2v4&b>JsUK5a-nG6I)i-u@;;v;ozd&~_zVtgR;UmTanikBuE%~6k(d!LBF`OgwY9W@dt@Mf-CCZF zF5E*XmH*v(qanE+=69?1K>Q+)Sz6iYekdrDuWpQsaTS02sg}M-%YLX!1AMjJc75h)gqc5Iw>Q7My*C0$zH)(yV3JOBP{Z=u?nCGa?S?OpVhLH-?zZULL z;4C)bG^BJ#Qj5E8o+NS88ox z3|$lk+d~ulR)6iEk2DzXfat^wl`yK>y$V6y%b1=RwF?CZs&T{9a}0~^Tl>HCsJd+h zbruS)wE69R5OzFK{INWQ*lN`Ye(#*GT0yBj%(5!JAUKW<|aL zw-3@mw|4v#C*ul!)f3j&l}}4mwNM^wv`*G#3iuVq&R|TrfwN;HOl?>o3`eN`Q-lX~ zi&uUfyWf|Ooy9-==M)O)`6q!>@3c@PP>Yz z(m49VG+|RJ_m*qV4)@C!acVKetmoeC=L63^P>!gFA;a9973%(!nJVxY=6B=qNp&yy zs{V66$`(_YKNOKPkPnik8!0JSxappKXm7MGVgxS)S=Q$sP*!kczGlYT8rS}654g-9 zVOsj1GD6iSTH$?G;!tuZKnP0kFg*8{WhFxW9?a6FmtVrDBO+6;;RzaH!wNA8HTALHQm2R2}=Rfj(X5GnVkS-MGX4csrSr!_|E!r&S(Xt_} zqH^(Jj#5LsV`Y0}yJc;RLBu_e$;MsY6#HK3`nml#FN9!3LHQ&+-D)4L zKB16^z%JA)9!`yIO^rUf84TglH5FR3w386w)79}wJ@d-Q+*$1jINA#^KI+jI!P+sp zt=xsKmbI@$9L zx?k8U9Vq9w^K`EdK09iiqNM?~guJt6R6`xFDp;PZQ)BtT%VGBAUMKqrH28wc^y6Fx zP^fbd25L{JJlea3^Uhs?X(2uBmkOU@!=(5L%aQHg+Sth#KDHI^FOPNO68DC(;+Acu z(iGmE|A6l`PXs{EU+^NJHjX7(jbY%k&%N}FDsEO-Vf*8~@=fMH@^r%#y(FFFn=Zh0 zL_8lU&)ly;X1Aqi0CG4Siztv$eQMBsCT=pEl2G_FL`ul7o#Cn`S18%0dY1v%_N-U% z-2E~MCv(~NjmZGO(o7sLHImk8jF#ji!Vk3-nf9fiPuB+>m)~tFT!=8|4FLJ-)a2-7 zx%tAgWUiBwz06ehxmy;X%o53UQ6eDPKRA@_$Vp6aP+|PlXwBer!E+^xitxD0wQeXM z`FI(>_dzq0kwvacPu+2MZRJH=1tDqXnO_0KBiqqmv#pB&NHFKW;wOHv5K7DV-G%!7 z_1~6j0Ge{;AL16Vr#5?;urbbJYHE7*>Qx)SoQ%jreA-DAUw3-&NG)aL^pDUnDhHrsel=-GA393pWJws`FnBRSCO zr3N&Ex`6g25nHJKK?kPW>jl&S090Sxf>FS^qY4a!&>)%JBy3K@WKQNN3AOW{US1%f zebVa`jFso57m|v@ZGzRHp{c^C9U$|=XYQ4h%6*XRAtwq)YX`rPuy0>s(M*uNy_&-=?NERbP`WNDnu%>Qfamuw zI^_ReHHf$~z&iv61=#*?9EC>nh|mkF+sP~40Pc{sJ8(Mw-C|{axh9q~!%I z0XUG-D^uERw66xJ7+<&M?f`G17}~7D)2)iUvJg(G7H&3#;;)wj)}R{8(qwk8cFxBkYwMF0zqYU1af zNx`dF8HuiG=UBig*?4kf-FyW<`IX8cI^u4&8F2L-=+RZh{=Hc9RIjn7VHs!?FTm> zKwFea7iwPGH49|D)9}F+aOY&>a0a9SK*b=%ogyo1@ub)+g>%st$1V;uj-KFG10}$97(~~rWgImGx zHX$bP>WqiS>>XYUu$#z=%z`+09ho34z`M)?FsJ;o2hE@9_L55aTrcg4#}s^-TiBZ& z%gRWsO`Xi`c*MrVU-q>Gdx>tazV@T|OM_In&Nm_HXBAA|Uhz9VXS<3@BR^%Z+=*7W z>y+RUG4i+Uys)%1NJ2$L&h>B~N0kt~%6H^Dy4+`FQEp4=m(XGfYrNTYB|U5X%+-(f zlY~dUh`pwJ`|0rNoV=NgBQ5>VXxrNs!(7zLY9~l?#Cah%veL82wZAb66n5v1m@-RG z>^0=p+ZXzqZZ~7pq`>40e=`a9VMW72XJ7>cA3%b=={S6Cx)?E`nCb%ztKNURSTp;m z7@{?S(o~@*Nu`=R(t(w&A+2E=nRk>dgdO6y`ZNj=Z(BRK0JO@5ZOltrVckddSBbPk zu+Jl#0mGp$iy9!QseHL65ecDEa5Oq;dvxu2KlqcIKyyK}2>92!?ay^r8iAUxP(v=I zb`hSa{_S4zv%Sa3;RGGVTFG+(BGEFO$_cUHtg(A@hJ&0^Yp9e50O0aI0T;A?vdN+{ zy54Xf<^jM_7Cui|2;L4gfuhuww}LtgstKvwSLwQ?`D4Z2tT(0KvYl?3L8?62-)D05 zvwp#`T&)Wbofg)Y)&TzQsF8{P{Va%z?#~q61YC0n*?#}|^qc$b_un!sJ2);(VW0FR z`+QqElOhLITX|Q>q8@{8Ulb$S7&%YPx>+OuQYoIEr;GAl#+Dh0@){s7M`ND-0X8ne}0MAsEzVf_~1f$U2XYsU^Xbp zOBVdFhn}xc(E9b*2F3=xm_)_`|ub~j~sd8z8be_gnMK@k(scBz)VPtvAB}j_92O!`2 z{sH}fAaG{r71sfLr%AQwUJ}UXHN=M1!ZOeFum6X+_W)~Z?e=|xiUkCg1yPDDMWhL+ z5D^ei5m1m`qEr#7k=}$rf+C_+6%Ys=qy`8r^iV`VdMC6H6bLm0=_HWc8C~n!-*@-E z`|Ri3z0Y&^L@wok1>A3XV?75$<75v)#c&{_3x@ncnLsG_r@jqc&*b{ zqRPge=aFAPRFTj{dEF51`LqJb*GtJaB4|4cLCz(B{l&yEdkWLc%~~6rj%9~F&r9)~ z)M|9(;T(^aTl#3lz2QOo6RJ}8rb43LX0)mcU$ZSjsaZG24;8Jx6`;Er`2c9@48u}0Ri0Me z3a|~1F~8SKSxFEWF57W=3^8})b1$H74iAbPEZk=ibuy7D?DO{;*to$5PRk*8!*h5y)7mD3EtBO}M=uWqr-V9fQLgbCVvIRcRq(f7#6`+og#R_{6 z%07>I@-iE;L*$5i5WC=4`|FXdqZvdQ=NwfbFNekDB-UElwe&dE z9Nrhn?KD;fmQ{I%oh6a}ZZG9V_5))qYIVw6D7vWccx)YuZ_WG3tYc}X<>&^n;Wdy^Y}2aOtbj9ZC4}^U z%W0Bv;nSY4IjMlF%aS|1?K&~?R>8RX6A+Dz60`OV?J+uxkFvHBx#Ay=4`fZ*>_2_?i{Gn;<+$6qhI=@)qnkiw|R1t2W}dw z;hGN=V1HSr!;L>k=6m~|-)9!AJ&9s&$z9$#f?)oXs$bjl_KBvQooUCfGE$TY*JrZ2 z*dXWh>*3CbKIAD+@b}Fp%tPx}>!684cN=*P5qBn~)*@aFWGr;nK=op*)c^< zDG~A(k*srk;O$9fwPB#MRXQMBflO7CQkjgeP8_ubuJ5x1o!xCVoE1FHLCO`d>&S)8 z1Bofh2!$^2revvfnlkbX2Zv#4Vd&{ISaa5NE9op~&Y~BK{-fm~@MNYw3Mq^lyLZrgktZTz^OPn`uJnXt9)IlF5W#(Pe(td>g zfPJ+dAq3Q*ZYGy#JB+AU?z2qp?yS5$@w6*mp?J)JjR?7}n9=$uZEP>Ge*30^jp;!I z+0yrlsAjlau*1&*!OEtmd2^^7wltQ0^B_-d)D7iNB426`m&WE+q_`f(UgX3mD3xWS zLx&7X?P;s7AxBFRNH~YgT-H}Zy7nP2+&=t>kPQi)miqeh=$C?1DKg#K`L5koVAlp; z(haWjTEnmUzE=xv`^HhFUc{daTax|3K~qu0G8|w)8wcD>Ht^Hk>m-EOBcKM(@r$D1 zvthm7=&L09i;sstJ-sT2Uqazzn(Z_U_%Vvkud7#oCF|1B`=>XD?_%YvSErmZfz0ej zWG9y4x4v_jmZRI2p<9bPGK3|0Se4JMJG$GTZSe=ENu#;l@>K$!h`z!H7Rl zkzwm+p7BCnxw3hoV(tnE#FW?v_^InQo8f`^_mbq`;yHMpyG!ZCF6b&z(OO|pr2|M( zmc^4=2|&$}Wky%lt{Je7Azr@ZKq=jPh_cwmI8h$HNPE5ilT1nn$)-Up#zs zPJVNDmh3r}-|M`bo!fC(xUAS;fhZ`7wdThJ z>qi(T0R);{pcZxbR=~KBfK|mwzzrlgSsCnizY0um^yIUUfozA-V#=R|8TR76E;uEG zol=Xg^p2uz?W6J_75op5f~@~eEw0b|m(*gQJg=WwQ1DXjbZDg5d!UB(b|%BYYaqoP zJSAZ`GJCav9opUC3OH3Kfyn_h(KTw&yoZPIi!TA$fXjfB%mVoHpn#gHafmLO=X;%W z;1Uz?W+d??Zky!23mwXj~um z`zLAyAY=fYvn!J)0yw6Kz#19N#c1K?A`4J`HvP8owm>%VP;nDier{`$;ihwap;K2A zc&LC1WMAB_`g7_xaSG@sE+6eSj70v8nFaRv4=B(7Eq?fak2n9nwHE`^IX%w$=Sd%> zNZTNtcMMAeq+^*`cpf#{F$XoBxl!fT(lc4F-ba=vTjm*I%QVkHmMcIyzY#|{MYXjl z?_(XrfOegWqt>57 Z9OM5S)PkJ>jEMPv+a=D|U)rSK+i@T&6nB9D8jVbyZLk0qg z=8w?^Hn%4Eko+_Du_NpS12aH=sBbqMQDZ8b!x?2G=I@f@3ohz-E`H?oVxO7h((C~+ z734DgOZ~YmE4ytO_Q{WwD^%^%(InBKFQl`7#8%AJJnUmB={kT!WIQXNXtY?o`i+E+ zBfA|q9HcG@W;au2=O}Mba37tr%QTl}VL-@tC*hit zaTct})!&49O51BN6VoSZWw@woiMY!e&H_+ZE?sYZJB_U6+WS58s^~ zzF}^f=HX+%HzBfCXc>*4%>-GQD9dv>Af0mv68A3LnT(Jj`HFsh)Z^>9Rb71sdyAw! zczFG)oKFWTFC(XD%yDnV_Tj1WOO+dcz66OL{(T$|{)!~(-QH0py>O4n3gbhINEY-` z5lLwQ+;h=a*R7j@R@E{;DhMOC;K8G-@6gzMMpo@Yc@50%G)3ghu@&zsOz?-lZy zV*)t=W!Av8n7#Nb4OGlz@rJ(p;nR8c+so*9OCW}xK1{mr9Ubp*$gaIMZLKmcC-%%` zVJq@UmHdaXYIEm&%Lzl6%|bE#1q(Uj3onLHfctEKsk=2EC-qKlM^f&`!Af90U|j6b zvS_yJ0?^yG^%tQDX7burD{WxnWwT@HpumiK)yTKWJLU2 zh&#S<2b6l~*Fz@Eg{e6V-Sby{h7dBAtS4`n!p0fNi$ywXJ+!CqfJOkZD?DgfZA_W! zIKs;&09X!vezsRWML$ZsT<|QS4;{HJI^?j3K=~}zc|}xhge@t2r$t|{_v-WkV<(^Z zfpl*DzDw1HKCwKOw%8|YK>S`PdGg&dTaOj*`)Ium_IH7J@+oLZVy8FW)`sR9U$>3v zpUr&FrJ9?m;815(}?P?omH+A!w=0V%m_>VB-I*2~ps^0ZlrkoSK zk2`uJYZ5~^BlLtwH6D?ym)x)75Ez`UIT>F-Ub7b@ap^&Qbltvp&Kt%UtRa_T2Lh^I03lFfBFU&%X2@Gdj=(x zdMUM+S~3d#xHoo`cOu3LZ6*ej8CU*p<$Bv^Z5bWpOj%g!NmN_aHvCbnBc5=(@`#QX zzzpd~11eF~BN^G6;GKWt`7xeU5QqyvQ3&$2pRD}-Ac9Q4w#SIgE-j(xJCXEWHGcnR zu?GZyJ=MUrr3gA)fx29J$UmCp*K-RpeYo;y9{BO_Uq7C{!=K5Jrx|-z>s5QO$_r2| zlYwwiW-OI=FC`|^LP=);38=}ppu_onDfB&CDjs8)tJlo3?>JsQq_3@z*?JxpHpeh$ zaKP6F^mnlB&|!NiNJXoBfCJ)!=)Qya8r8VwFk>5YYE?|=H#g!o^Jb{U&5LFLpmLq4 z>!S;Vc$5LXDcanLtuBxD`7(eU3}Ar*zon4rG-u!|<6qK%^IY57Do4(HFZ2ifiiiQ7 zae;fs?O@&Sn-G)}2T(5S=QnW{6$G<_oF^%O?K$ScIJbaMsX%PoGL)Z_Gm}%y==9O; z07l6W@RA65650PdcoPtMVPsnMx6#$m{KvAZ0HY5|Fu>bL-2navnrQ7#l6Mv!l=^la zsCHm{nCou1g45~WL;0UZJ~HN;X0L_-CwM+%{-CgPir@97oSV0pN_Ej zHZ4KpBP}9j$QiH|pAoqC`fpnjB>bz9aJl_}&Jaq!2YzJAhEE>;C{j@_A%J5Wh;Ih; z12I2gXB!4xBxdZEj+f=3oP2nv9J-6YIohWo``@t|{|lk2|Jh9%{1X-O!F}Tx`2o1a zyWazDaNIW1L30PdDh;a{I&A5d7P@nmuK+QCP*-RsI<)_rXEw>ZP+&IvG55K;`?Q|R z3zcR@kAHu*vd-Dd;d9R~MR{OzOzdh=OqtLFR@KOXKr6E=->lCMBYi@pT{D(~2qkWp zFBl1^kqtiWPsY6PoKKH%$mvZbIy{SgEZXS#Yk2~>xMpK6UsQ)`4Gz7Xy+)Cc)#G;z z>Hpv?z&UwGJ<==>=WRW{Gzo82GDdwUtyq$WJgm3=(|`Ip^Cp9H34`coyXSnA_-eP? z@W$(1V2uUWsb6FQs+TC<}XPpuie$*x4@JvX;r zTny!`pufVtQZ~}dKQA52F;eJJa|JRy2b~324-Sc3>vFu~xp#;#Dp=UrFQDHnHUz-d z0}oj03)!uWPx1u^VeBUE9Fq_n@=Wh4#KB5SJ8{_Cw&3H_XHaj0NOZ`MD{a>(=SvmKusKkz%sk-b|@%})# zJ7@9!D>N`k4=1y-RVp7V%{aY1 zq#Y6Y>1DnH&3Av=nqv0`UAt1k>iiXeqHck=Wd7zz(%$^dktAFSeD zH|I{h7=(?naB{M09DGDF5>pZ9&5FQ;l>niYXHFf8^j&qhnP|1B?60gMp-5VeR5q_S zcS3o7<{~)H7znOI<)eS>KnnhvA+5y~;W_6k(ZD>hT4d&i;x&3!+7@#2J9;QM8TYou z%k_Mzm;A#M)x&GAB3f12gkEGz-+K6Un%* zlXQ_Q&4;`4mMU4!xyhwq-D1MCD(0^#a=uT^b}1RwzEUs3=x7fDohFwXveKT}kV`&b zw9&z&L03=Qk60k?k(;Jkdp7T7i>c}JHABqKzaSw`{6a#8wZreCY!kpeU3}mk<}Ve& za*8sl?qRja>+-q}AZ(&f{A`TVT%7ZWmV~2~%0o$!x#qjCsR=tTM z&xmOdTfWz=d9yE7F+v)TPo=orJEGn@K~H`o^M{1?zcC{*w0~koHoPk)sQ71D!ovN= z@;{iP-@Z*!Z}T`^lYS6ZZeqr*>fu}<2h_ZAV;sc!t&m0NsTW6w4hCX;)y?=2R-cdx zbw(lpF5_pYSs`~+TKewpZ-e7@rfYDXN!r#ccx{{IS|q}Mu+M^4Pz8WDf-IsqKRFbx zV!Ka|9;rLd`wJZT<@~LcJlxeyc$4Y(qLM;6a}JpCBTeQmpcJmB3_|G_Ru}=7d#ofSs&fUerh*{3_k{zy5jWwa* zO4B}qbKPZ;qRh>AA9IK92@q8lZ!ca^VT&$D3M_gbhs-3GaI4fmKO5U|asw!%Ti)QF zG!ExQ5!)!lBE>=SYPIjB?5C9-~W*1+DUJ0Vi#Xd|T)*-ohG6Xtma{Au+hr|J` zC*Y>9T*b%bh{oGXW?!$#V_&fVEyd-YMaGs-91qF2-fvM72wo zjq<&HB;v8kZns5m{J6nBer()ToPmct4PG4`e8u(fVrL}c_%D^L>O`tLXFTA@S?oe#u$U zciWVpJ-(VrNtZp34*jr2nq-jFu=eFTBe};Um#_TbA&Ig)v@|NhlkRH}(&Ae8u0Iql=0y z9f-1zX+2IjCK#S)i$RVY{|7m;c>k?PY1xxVE7zpdKOB?h#2mx>0u`qRVe0u94x*f+ z@$1E6q3JS=wD|Fotp)r$U5BWOg0tbv)jFZ!Dtxvcx~cm5bSVq|At(2iqpbi|5+U%N z_;1k2TNAaPLQmW9)>QRaRlmt|%Dx)Zd>(@XCu$G8vITT%Af9^18T#5k3a2Bm%z*}g zv?}(`2ETvA92O>4|D_&*V&}lp5089I!6i-scecO!h^M({;9)z@wTt3pTg8iopSeYa z9SS4z`BBHjCGA2_TxkOE9p0-DmJmPl6!c=o@D@_0FirIe10Bh80Zz41;U2drB@6j` zi^}N0zRkrymRog=BYL274?5>#wk}-$DYVOx@;OqG-AL!VE#5*K16T=i2B!|VRbb3( zpu6_nCK{N{Dx)o_HNM|q$uM_2;nmJPlZC&@kzwxsijP^ttT^%5&qmAuHO*VZEWr>zHW%Kj@KzgBMepBZ0<@!#<8QVbwZC$!|+EP|XGr z@Opp;0u*y!UGF0|8-Lb^*RYD;o?C$WkB30S_$yURVyu2An?3c*Z_D&{ri%f}N}=pY z(^b#UGO;F%h$kT5WcJ=WH7WfCJCH+hk^DW&{2$~`-2Rtn#OSaekX&g1K)3)9qKo4% z(*L@1)^5cqQ2W>$Hszr&sF+%083v%6gaHo9H{2Yv51#)?>;#~;FjCY2#}_DPu8n7+ zXQyXZls^53S_q$wMcBzVMa0kiwbyyTr&m+`JaB9nU|ukw)1RhRu-{0qwl|4fl2igz= zX^NGS4BaXQ)OfzZ(R;U25x#G~xh6$bq2G0s^BjoI0aJFyuUJ`rQcRw3jcd+ueiJtUy>UUZp@bt{LX+=!CJ(to;;7BZnT+M_IMG$3X&d zUxQ}JHL3-Fx=g-LtqJd;D*Y@o$GhDIP=-|>Gs0%ITjqJDfsCw^xgrWAs}0uPXq-2f zDM5}unc`o&ds(Y~`$h%n1-2SzoDuC7iB2#YjV(x>SaRY=IMKJ4{O3jwj`7AI@Lkh8 z__Aioj;dT|%ER7|514$vQ52_nBm7iRir_-%iSF}{GU9#aYN~vL6f@#3c5jmyiNX!x zCzhEi-vAeN;SO7z^`Wjs0crTK829FVPybua(I;MXJuxv$N{-9(YMJ;beoWQ&y_09_%w(5nt!G6V8gRn|g#P z9V=f`G(673Giql;+;{x=IKBn7T`wQfsguZy*ECDMdVqLgdfgH|pILOr0a>NuPR}Sf zAk=&=u%|5#1k$j6aPN+RW!-xYf?j9hHQ%S7T-o`rMf6QrkcRUfGx=VZ6QskSzPaQ1 zE^H-r9cqDDXUA`B;r)DYQXT4I+dC¨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�{$Gv7PD(OklSqQ2^yP{2_ZXU-T7n8W`@ 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 K;-#WS!T$?kz}A2O literal 0 HcmV?d00001 From a2cb879ed24e9fa2e81de92a009c013fda1ba27f Mon Sep 17 00:00:00 2001 From: Zac Hatfield-Dodds Date: Mon, 27 May 2024 11:07:44 -0700 Subject: [PATCH 15/17] PEP 789: footnotes section --- peps/pep-0789.rst | 67 +++++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/peps/pep-0789.rst b/peps/pep-0789.rst index 8bb78ee9a2f..7e44b8379b4 100644 --- a/peps/pep-0789.rst +++ b/peps/pep-0789.rst @@ -31,7 +31,6 @@ asyncio and downstream libraries to implement task groups, timeouts, and cancellation; and a related mechanism by ``contextlib`` etc. to convert generators into context managers which allow safe yields. -.. _Structured concurrency: https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/ Background ========== @@ -60,18 +59,6 @@ cross-function ``goto``\ s, and the effects are truly dire: - Exceptions can go missing entirely, being dropped instead of added to an ``ExceptionGroup`` -.. [#trio-cancel-scope] - While cancel scopes are implicit in asyncio, the analogous - :py:func:`trio:trio.fail_after` (sync) and :py:func:`trio:trio.open_nursery` - (async) context managers literally wrap an instance of - :py:class:`trio:trio.CancelScope`. We'll stick with asyncio for examples - here, but say "cancel scope" when referring to the framework-independent - concept. - -.. [#tg-cs] - A ``TaskGroup`` is not _only_ a cancel scope, but preventing yields would - resolve their further problem too. See :ref:`just-deliver`. - Problem statement ================= @@ -289,10 +276,6 @@ multiple implementations of the websocket protocol: ... -.. [#redirected] via e.g. ``contextlib.[async]contextmanager``, - or moral equivalents such as ``@pytest.fixture`` - - Specification ============= @@ -313,10 +296,6 @@ To prevent these problems, we propose: mutating a code object that might be shared between decorated and undecorated functions -.. [#also-sync] - Note that this prevents yields in both sync and async generators, so that - downstream frameworks can safely define sync cancel scope countexts such as - :py:func:`trio:trio.fail_after`. Implementation - tracking frames -------------------------------- @@ -546,11 +525,12 @@ functionality immediately. How widespread is this bug? --------------------------- -We don't have solid numbers here, but believe that many projects are affected -in the wild. After one moderate and one critical bug attributed to suspending -a cancel scope at work, Zac developed tooling to enforce a company-wide ban -on async generators. When describing this PEP at PyCon, three attendees -recognized the symptoms and concluded that they had likely been affected. +We don't have solid numbers here, but believe that many projects are affected in +the wild. Since hitting a moderate and a critical bug attributed to suspending +a cancel scope in the same week at work, we've `used static analysis +`__ with some success. Three +people Zac spoke to at PyCon recognized the symptoms and concluded that they had +likely been affected. *TODO: run the ASYNC101 lint rule across ecosystem projects, e.g. the aio-libs packages, and get some sense of frequency in widely-used PyPI packages? @@ -595,8 +575,8 @@ Rejected alternatives PEP 533, deterministic cleanup for iterators ----------------------------------------------- -:pep:`533` proposes adding ``__(a)iterclose__`` to the iterator protocol, -essentially wrapping a ``with (a)closing(ait)`` around each (async) for loop. +:pep:`533` proposes adding ``__[a]iterclose__`` to the iterator protocol, +essentially wrapping a ``with [a]closing(ait)`` around each (async) for loop. While this would be useful for ensuring timely and deterministic cleanup of resources held by iterators, the problem it aims to solve, it does not fully address the issues that motivate PEP 789. @@ -676,9 +656,6 @@ While I've had good experiences in async Python without async generators [#exp-report]_, I'd prefer to fix the problem than remove them from the language. -.. [#exp-report] see `Zac's experience report here - `__ - .. _just-deliver: @@ -731,8 +708,36 @@ constructs, and causes whole-program slowdowns via de-optimization. On the other hand, adding interpreter support for better performance leads back to the same pay-regardless semantics as our preferred solution above. + +Footnotes +========= + +.. _Structured concurrency: https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/ .. _sketched an alternative: https://gist.github.com/JelleZijlstra/a53b17417c5189b487316628acc5555f +.. [#trio-cancel-scope] + While cancel scopes are implicit in asyncio, the analogous + :py:func:`trio:trio.fail_after` (sync) and :py:func:`trio:trio.open_nursery` + (async) context managers literally wrap an instance of + :py:class:`trio:trio.CancelScope`. We'll stick with asyncio for examples + here, but say "cancel scope" when referring to the framework-independent + concept. + +.. [#tg-cs] + A ``TaskGroup`` is not _only_ a cancel scope, but preventing yields would + resolve their further problem too. See :ref:`just-deliver`. + +.. [#redirected] via e.g. ``contextlib.[async]contextmanager``, or moral + equivalents such as ``@pytest.fixture`` + +.. [#also-sync] + Note that this prevents yields in both sync and async generators, so that + downstream frameworks can safely define sync cancel scope countexts such as + :py:func:`trio:trio.fail_after`. + +.. [#exp-report] see `Zac's experience report here + `__ + Copyright ========= From c1a2d278cc2a4593ce6ff103de7417de1d01d513 Mon Sep 17 00:00:00 2001 From: Zac Hatfield-Dodds Date: Mon, 27 May 2024 11:16:44 -0700 Subject: [PATCH 16/17] PEP 789: minor clarifications --- peps/pep-0789.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/peps/pep-0789.rst b/peps/pep-0789.rst index 7e44b8379b4..69b32361e9b 100644 --- a/peps/pep-0789.rst +++ b/peps/pep-0789.rst @@ -645,11 +645,9 @@ yield-within-with problems are not exclusive to async generators: yield one = decimal.Decimal(1) - x = one / 3 + print(one / 3) # 0.3333333333333333333333333333 next(gen := why_would_you_do_this()) - y = one / 3 - print(x) # 0.3333333333333333333333333333 - print(y) # 0.3 + print(one / 3) # 0.3 While I've had good experiences in async Python without async generators @@ -680,13 +678,15 @@ concurrency is that your stack becomes a tree, with child tasks encapsulated within some parent frame. They're extending the basic structured programming model in different, and unfortunately incompatible, directions. -Note that ``TaskGroup`` *would* play nicely with generators if suspending the -frame with the context manager also suspended all child tasks. Note also that -this would cause all of our motivating examples to deadlock, as we wait for -values to be produced by suspended child tasks - a prohibitive design problem. +Suppose for example that suspending a frame containing an open ``TaskGroup`` +also suspended all child tasks. This would preserve the 'downward' structured +concurrency, in that children remain encapsulated - albeit at the cost of +deadlocking both of our motivating examples, and much real-world code. +However, it would still be possible to resume the generator in a different +task, violating the 'upwards' invariant of structured concurrency. We don't think it's worth adding this much machinery to handle cancel scopes, -while leaving task groups (and no-exception cases) broken. +while still leaving task groups broken. Alternative implementation - inspecting bytecode From c37ea4fb2987c53b56a746d8df31a0695b33c5f8 Mon Sep 17 00:00:00 2001 From: Zac Hatfield-Dodds Date: Thu, 30 May 2024 21:33:23 -0700 Subject: [PATCH 17/17] PEP 789: minor expression edits --- peps/pep-0789.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/peps/pep-0789.rst b/peps/pep-0789.rst index 69b32361e9b..726fe979453 100644 --- a/peps/pep-0789.rst +++ b/peps/pep-0789.rst @@ -203,7 +203,6 @@ When we run this code, we see the expected sequence of observations, then a ... File "demo.py", line 37, in turn_on_lights_when_someone_gets_home await asyncio.sleep(1) # do some other operation - ^^^^^^^^^^^^^^^^^^^^^^ File ".../python3.11/asyncio/tasks.py", line 649, in sleep return await future asyncio.exceptions.CancelledError @@ -487,7 +486,7 @@ Anticipated uses ================ In the standard library, ``sys.prevent_yields`` could be used by -``asyncio.TaskGroup``, ``asycio.timeout``, and ``asyncio.timeout_at``. +``asyncio.TaskGroup``, ``asyncio.timeout``, and ``asyncio.timeout_at``. Downstream, we expect to use it in ``trio.CancelScope``, async fixtures (in pytest-trio, anyio, etc.), and perhaps other places. @@ -579,7 +578,7 @@ PEP 533, deterministic cleanup for iterators essentially wrapping a ``with [a]closing(ait)`` around each (async) for loop. While this would be useful for ensuring timely and deterministic cleanup of resources held by iterators, the problem it aims to solve, it does not fully -address the issues that motivate PEP 789. +address the issues that motivate this PEP. Even with PEP 533, misfired cancellations would still be delivered to the wrong task and could wreak havoc before the iterator is closed. Moreover, it does not @@ -657,8 +656,8 @@ language. .. _just-deliver: -Can't we just deliver exceptions to the _right_ place? ------------------------------------------------------- +Can't we just deliver exceptions to the right place? +---------------------------------------------------- If we implemented :pep:`568` (Generator-sensitivity for Context Variables; see also :pep:`550`), it would be possible to handle exceptions from timeouts: the