From 4e75c0abf6cb84396873fd6aac284cee17c754d0 Mon Sep 17 00:00:00 2001 From: Dhruvan Date: Mon, 11 Mar 2024 18:51:13 -0400 Subject: [PATCH 1/2] move everything; consolidate imports into one file --- .helix/cache/build_cache/test_hlx.py | 36 ++-- .helix/cache/build_cache/test_hlx.py.lines | 31 ++-- .helix/include/core.py | 47 +++-- README.md | 13 +- core/__pycache__/better_print.cpython-312.pyc | Bin 22680 -> 0 bytes core/__pycache__/cache_store.cpython-312.pyc | Bin 3560 -> 0 bytes core/__pycache__/compile_bar.cpython-312.pyc | Bin 1642 -> 0 bytes core/__pycache__/config.cpython-312.pyc | Bin 1775 -> 0 bytes core/__pycache__/panic.cpython-312.pyc | Bin 29268 -> 0 bytes .../normalize_tokens.cpython-312.pyc | Bin 8381 -> 0 bytes .../remove_comments.cpython-312.pyc | Bin 1633 -> 0 bytes .../__pycache__/tokenize_file.cpython-312.pyc | Bin 3579 -> 0 bytes .../__pycache__/tokenize_line.cpython-312.pyc | Bin 7746 -> 0 bytes docs/doc.py | 10 +- .../__pycache__/_async_pre.cpython-312.pyc | Bin 1167 -> 0 bytes .../__pycache__/_functions.cpython-312.pyc | Bin 15919 -> 0 bytes .../__pycache__/_include.cpython-312.pyc | Bin 13513 -> 0 bytes functions/_match.py | 13 -- helix.py | 135 +++++++++----- init | 19 +- out/helix.pyi | 102 ----------- {core => src}/better_print.py | 13 +- {core => src}/cache_store.py | 23 +-- {classes => src/classes}/Scope.py | 37 ++-- {classes => src/classes}/Token.py | 10 +- {classes => src/classes}/Transpiler.py | 32 ++-- {classes => src/classes}/WorkerPool.py | 1 - {core => src}/compile_bar.py | 4 +- {core => src}/config.py | 10 +- globals.py => src/core/base.py | 169 +++++++++--------- src/core/framework.py | 0 src/core/imports.py | 110 ++++++++++++ src/core/utils.py | 0 {functions => src/functions}/_class.py | 16 +- {functions => src/functions}/_for.py | 87 +++++---- {functions => src/functions}/_functions.py | 33 ++-- {functions => src/functions}/_include.py | 53 +++--- {functions => src/functions}/_let.py | 25 ++- src/functions/_match.py | 14 ++ {functions => src/functions}/_process.py | 22 +-- {functions => src/functions}/_unless.py | 28 ++- {functions => src/functions}/_unmarked.py | 17 +- {core => src}/panic.py | 27 +-- {core => src}/token/normalize_tokens.py | 10 +- {core => src}/token/remove_comments.py | 10 +- {core => src}/token/tokenize_file.py | 28 +-- {core => src}/token/tokenize_line.py | 34 ++-- syntax/head_syntax.hdlx | 16 +- syntax/syntax.hlx | 3 +- syntax/test.hlx | 29 +-- tests/ThreadPool_test.py | 2 +- 51 files changed, 695 insertions(+), 574 deletions(-) delete mode 100644 core/__pycache__/better_print.cpython-312.pyc delete mode 100644 core/__pycache__/cache_store.cpython-312.pyc delete mode 100644 core/__pycache__/compile_bar.cpython-312.pyc delete mode 100644 core/__pycache__/config.cpython-312.pyc delete mode 100644 core/__pycache__/panic.cpython-312.pyc delete mode 100644 core/token/__pycache__/normalize_tokens.cpython-312.pyc delete mode 100644 core/token/__pycache__/remove_comments.cpython-312.pyc delete mode 100644 core/token/__pycache__/tokenize_file.cpython-312.pyc delete mode 100644 core/token/__pycache__/tokenize_line.cpython-312.pyc delete mode 100644 functions/__pycache__/_async_pre.cpython-312.pyc delete mode 100644 functions/__pycache__/_functions.cpython-312.pyc delete mode 100644 functions/__pycache__/_include.cpython-312.pyc delete mode 100644 functions/_match.py delete mode 100644 out/helix.pyi rename {core => src}/better_print.py (97%) rename {core => src}/cache_store.py (79%) rename {classes => src/classes}/Scope.py (79%) rename {classes => src/classes}/Token.py (99%) rename {classes => src/classes}/Transpiler.py (84%) rename {classes => src/classes}/WorkerPool.py (99%) rename {core => src}/compile_bar.py (95%) rename {core => src}/config.py (91%) rename globals.py => src/core/base.py (93%) create mode 100644 src/core/framework.py create mode 100644 src/core/imports.py create mode 100644 src/core/utils.py rename {functions => src/functions}/_class.py (96%) rename {functions => src/functions}/_for.py (80%) rename {functions => src/functions}/_functions.py (94%) rename {functions => src/functions}/_include.py (92%) rename {functions => src/functions}/_let.py (90%) create mode 100644 src/functions/_match.py rename {functions => src/functions}/_process.py (85%) rename {functions => src/functions}/_unless.py (53%) rename {functions => src/functions}/_unmarked.py (95%) rename {core => src}/panic.py (93%) rename {core => src}/token/normalize_tokens.py (95%) rename {core => src}/token/remove_comments.py (78%) rename {core => src}/token/tokenize_file.py (70%) rename {core => src}/token/tokenize_line.py (68%) diff --git a/.helix/cache/build_cache/test_hlx.py b/.helix/cache/build_cache/test_hlx.py index 894c862..a9d98d2 100644 --- a/.helix/cache/build_cache/test_hlx.py +++ b/.helix/cache/build_cache/test_hlx.py @@ -4,7 +4,7 @@ # GENERATED FILE # -------------------------------------------------------------------------------- # Filename: test.hlx -# Generation Date: 2024-03-09 21:43:31 +# Generation Date: 2024-03-11 18:49:50 # Generator: Helix Transpiler # -------------------------------------------------------------------------------- # WARNING: This file is AUTO-GENERATED by the Helix Transpiler. Any modifications @@ -29,18 +29,18 @@ import os # type: ignore import sys # type: ignore import types # type: ignore -sys.path.append(os.path.dirname(os.path.realpath("c:\\Users\\dhruv\\Documents\\Projects\\helix\\helix.py")) + os.sep + ".helix") # type: ignore -sys.path.append(os.path.dirname(os.path.realpath("c:\\Users\\dhruv\\Documents\\Projects\\helix\\helix.py"))) # type: ignore +sys.path.append(os.path.dirname(os.path.realpath("z:\\devolopment\\helix\\helix-lang\\helix.py")) + os.sep + ".helix") # type: ignore +sys.path.append(os.path.dirname(os.path.realpath("z:\\devolopment\\helix\\helix-lang\\helix.py"))) # type: ignore sys.path.append(os.path.dirname(os.path.realpath(os.getcwd()))) # type: ignore # trunk-ignore(ruff/F401) -from include.core import ABC, Any, C_For, Callable, DEFAULT_VALUE, DispatchError, Enum, FastMap, FunctionType, Iterator, Literal, NoReturn, NoneType, Optional, Self, Thread, Type, TypeVar, UnionType, __import_c__, __import_cpp__, __import_py__, __import_rs__, annotations, array, auto, dataclass, double, getcontext, hx__abstract_method, hx__async, hx__multi_method, hx_array, hx_bool, hx_bytes, hx_char, hx_double, hx_float, hx_int, hx_list, hx_map, hx_set, hx_string, hx_tuple, hx_unknown, hx_void, inspect, multimeta, panic, printf, ref, replace_primitives, scanf, sleep, std, string, subtype, unknown, void, wraps # type: ignore +from include.core import ABC, Any, BuiltinFunctionType, C_For, Callable, DEFAULT_VALUE, DispatchError, Enum, FastMap, FunctionType, Iterator, Literal, NoReturn, NoneType, Optional, Self, T, Thread, Type, TypeVar, UnionType, __import_c__, __import_cpp__, __import_py__, __import_rs__, annotations, array, auto, beartype, dataclass, double, getcontext, hx__abstract_method, hx__async, hx__multi_method, hx_array, hx_bool, hx_bytes, hx_char, hx_double, hx_float, hx_int, hx_list, hx_map, hx_set, hx_string, hx_tuple, hx_unknown, hx_void, inspect, multimeta, panic, printf, ref, replace_primitives, scanf, sleep, std, string, subtype, unknown, void, wraps # type: ignore # trunk-ignore(ruff/F401) # trunk-ignore(ruff/F811) from include.core import __import_c__, __import_cpp__, __import_py__, __import_rs__ # type: ignore import threading # type: ignore import functools # type: ignore __lock = threading.Lock() -__file__ = "C:\\Users\\dhruv\\Documents\\Projects\\helix\\syntax\\test.hlx" +__file__ = "Z:\\devolopment\\helix\\helix-lang\\syntax\\test.hlx" # trunk-ignore(ruff/F821) def exception_handler(exception_type: type[BaseException] | threading.ExceptHookArgs, exception: Optional[Exception] = None, tb: Optional[types.TracebackType] = None, debug_hook: bool = False, thread_error: bool = False): import traceback @@ -173,7 +173,7 @@ def exception_handler(exception_type: type[BaseException] | threading.ExceptHook exit(1) sys.excepthook = exception_handler # type: ignore threading.excepthook = functools.partial(exception_handler, thread_error=True) -sys.argv = ["C:\\Users\\dhruv\\Documents\\Projects\\helix\\helix.py", "C:\\Users\\dhruv\\Documents\\Projects\\helix\\syntax\\test.hlx"] + list(sys.argv)[2:] +sys.argv = ["Z:\\devolopment\\helix\\helix-lang\\helix.py", "Z:\\devolopment\\helix\\helix-lang\\syntax\\test.hlx"] + list(sys.argv)[2:] del os, threading, functools overload_with_type_check = beartype(conf=BeartypeConf(is_color=False)) # type: ignore class C_cout(): @@ -184,23 +184,29 @@ def __lshift__(self: Any, a: str | hx_string): print ( a ) @overload_with_type_check def main(argv: list[str | hx_string] | hx_list[str | hx_string]): - do_something ( ) a: int | hx_int = int("12") - print ( add ( a , [ "a" , "b" , "c" ] ) ) + add ( 123 , 123 ) + print ( add . join ( ) ) + do_something ( ) + do_something . join ( ) + print ( "done" ) + return 0 +@hx__async +def add(a: int | hx_int, b: int | hx_int) -> int: + printf ( "adding: %d + %d" , a , b ) + return a + b @overload_with_type_check def subtract(a: int | hx_int, b: int | hx_int) -> int: return a - b -@overload_with_type_check -def add(a: int | hx_int, b: int | hx_int) -> int: - a: Type = Type(10) - print ( a ) - return a - b -@overload_with_type_check @hx__async def do_something(): for i in C_For(i = int(0)).set_con('i < 10').set_inc('i ++'): - print ( "doing something: %d" , i ) + printf ( "doing something: %d" , i ) del i +@overload_with_type_check +def a_cursed_fucntion(a: int | hx_int) -> FunctionType: + printf ( "new something: %d" , a ) + return a_cursed_fucntion if __name__ == "__main__": try: main() # type: ignore diff --git a/.helix/cache/build_cache/test_hlx.py.lines b/.helix/cache/build_cache/test_hlx.py.lines index 7b4cb02..f4ec04a 100644 --- a/.helix/cache/build_cache/test_hlx.py.lines +++ b/.helix/cache/build_cache/test_hlx.py.lines @@ -185,19 +185,30 @@ 85 85 86 -87 88 +89 +91 92 -92 -93 -96 -96 -97 +94 +95 +98 98 99 -102 -102 -102 +100 +103 103 104 -103 \ No newline at end of file +108 +108 +109 +110 +109 +115 +115 +115 +115 +-1 +-1 +-1 +-1 +-1 \ No newline at end of file diff --git a/.helix/include/core.py b/.helix/include/core.py index 2ac4185..ffdf8c1 100644 --- a/.helix/include/core.py +++ b/.helix/include/core.py @@ -12,7 +12,7 @@ from functools import wraps import inspect from threading import Thread -from types import MappingProxyType as FastMap, NoneType, FunctionType, UnionType +from types import MappingProxyType as FastMap, NoneType, FunctionType, UnionType, BuiltinFunctionType from beartype.typing import Any, Callable, Literal, NoReturn, Self from weakref import ref @@ -20,7 +20,7 @@ from multimethod import subtype from typing import Type, TypeVar, Optional -from core.panic import panic, standalone_tokenize_line as _H_tokenize_line__ +from src.panic import panic, standalone_tokenize_line as _H_tokenize_line__ from time import sleep #from include.c_cpp import __import_c__ @@ -234,10 +234,29 @@ def set_inc(self, increment): ) return self -def hx__async(func): - def wrapper(*args, **kwargs): - Thread(target=func, args=args, kwargs=kwargs, daemon=True).start() +from beartype import beartype + +def hx__async(func: Callable) -> Callable: + def run_thread(func, args, kwargs): + func._result = func(*args, **kwargs) + func._thread_started = False + @wraps(func) + def wrapper(*args, **kwargs): + if not hasattr(func, "_thread_started") or not func._thread_started: + func._thread = Thread(target=run_thread, args=(func, args, kwargs)) + func._thread_started = True + func._thread.start() + return func + + def join(timeout=None): + if hasattr(func, "_thread"): + func._thread.join(timeout) + return getattr(func, "_result", None) + return None + + func.join = join + wrapper.join = join return wrapper class hx_void(void): pass @@ -710,7 +729,9 @@ def __repr__(self) -> str: def __bytes__(self) -> bytes: return self.__value__ -class hx_tuple[T](tuple, metaclass=multimeta): +T = TypeVar("T") + +class hx_tuple(tuple, metaclass=multimeta): __value__: tuple | hx_tuple | None = () __generic__: subtype = None @@ -792,7 +813,7 @@ def last(self) -> T: return self.__value__[-1] # Derived Types -class hx_list[T](list, metaclass=multimeta): +class hx_list(list, metaclass=multimeta): __value__: list = None __generic__: subtype = None __initialized__ = False @@ -821,7 +842,7 @@ def __type_check__(self, __o: Any) -> None: def __set_generic__(self, __o: str) -> Self: exec( - f"self.__generic__ = subtype(list{__o} | {((" | ".join(["list[" + _ + "]" for _ in [replace_primitives[_] for _ in replace_primitives if _ in __o]])) + " | ") if " | ".join(["list[" + _ + "]" for _ in [replace_primitives[_] for _ in replace_primitives if _ in __o] if _]) else ""} void {'| list' if not __o.endswith(']') else ''})" + f"self.__generic__ = subtype(list{__o} | {((' | '.join(['list[' + _ + ']' for _ in [replace_primitives[_] for _ in replace_primitives if _ in __o]])) + ' | ') if ' | '.join(['list[' + _ + ']' for _ in [replace_primitives[_] for _ in replace_primitives if _ in __o] if _]) else ''} void {'| list' if not __o.endswith(']') else ''})" ) if self.__initialized__: panic( @@ -860,7 +881,7 @@ def length(self) -> int: self.__check_if_initialed() return len(self.__value__) -class hx_array[T](array, metaclass=multimeta): +class hx_array(array, metaclass=multimeta): __value__: list = None __generic__: subtype = None __initialized__ = False @@ -889,7 +910,7 @@ def __type_check__(self, __o: Any) -> None: def __set_generic__(self, __o: str) -> Self: exec( - f"self.__generic__ = subtype(list{__o} | {((" | ".join(["list[" + _ + "]" for _ in [replace_primitives[_] for _ in replace_primitives if _ in __o]])) + " | ") if " | ".join(["array[" + _ + "]" for _ in [replace_primitives[_] for _ in replace_primitives if _ in __o] if _]) else ""} void {'| array' if not __o.endswith(']') else ''})" + f"self.__generic__ = subtype(list{__o} | {((' | '.join(['list[' + _ + ']' for _ in [replace_primitives[_] for _ in replace_primitives if _ in __o]])) + ' | ') if ' | '.join(['array[' + _ + ']' for _ in [replace_primitives[_] for _ in replace_primitives if _ in __o] if _]) else ''} void {'| array' if not __o.endswith(']') else ''})" ) if self.__initialized__: panic( @@ -927,7 +948,7 @@ def length(self) -> int: self.__check_if_initialed() return len(self.__value__) -class hx_set[T](set, metaclass=multimeta): +class hx_set(set, metaclass=multimeta): __value__: list = None __generic__: subtype = None __initialized__ = False @@ -956,7 +977,7 @@ def __type_check__(self, __o: Any) -> None: def __set_generic__(self, __o: str) -> Self: exec( - f"self.__generic__ = subtype(set{__o} | {((" | ".join(["set[" + _ + "]" for _ in [replace_primitives[_] for _ in replace_primitives if _ in __o]])) + " | ") if " | ".join(["set[" + _ + "]" for _ in [replace_primitives[_] for _ in replace_primitives if _ in __o] if _]) else ""} void {'| set' if not __o.endswith(']') else ''})" + f"self.__generic__ = subtype(set{__o} | {((' | '.join(['set[' + _ + ']' for _ in [replace_primitives[_] for _ in replace_primitives if _ in __o]])) + ' | ') if ' | '.join(['set[' + _ + ']' for _ in [replace_primitives[_] for _ in replace_primitives if _ in __o] if _]) else ''} void {'| set' if not __o.endswith(']') else ''})" ) if self.__initialized__: panic( @@ -997,7 +1018,7 @@ def length(self) -> int: -class hx_map[T](dict, metaclass=multimeta): +class hx_map(dict, metaclass=multimeta): __value__: list = None __generic__: subtype = None __initialized__ = False diff --git a/README.md b/README.md index 8a6f103..4552894 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,13 @@ # Installation +### create a virtual environment +### install the requirements +### run helix.py with a test file + ```bash -./init -.venv/bin/python3.12 helix.py -``` \ No newline at end of file +python3 -m venv .venv +source .venv/bin/activate +pip install -r requirements.txt +python helix.py syntax/test.hlx +deactivate # to exit the virtual environment when done +``` diff --git a/core/__pycache__/better_print.cpython-312.pyc b/core/__pycache__/better_print.cpython-312.pyc deleted file mode 100644 index 46889f93ff1b2be2dbccfe1b4cb0da782c4db06f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22680 zcmeHvYiwKBnc(G{5?^{y@7L8^lx4}1{EBTkm2LSYTaGL_ep{w=uVl&;WnWU3L{lEM zlj%r_TT4x{rW$p_%w$?-l9{S#fVyaQ$DIZkcee{%ifTm@4&Zd>$7q2C=r{`m!C+^< z@7xDTiFVq_4zRn}YxCUieCIpg`OfP*-#O>I`p+g)It5SYh5ybj9HXfJiV^9dMd0Zx zdWyPBouU}(9K|YFrB_E$tcp?W0Rl$JsGRB%%{i?CVYO2?qCcl6u*R7-l723oz*?ta z#CXmKu*|(Auu7;~qP+Pc7Vrst z3q%gdw1qNN~R(SQ^iy>HA$FSrjDsg!q}L4W|M?r8WxRzrFdTf+Y;i5q z#B5=jnHHv%*~)BVwlg~x_3}u-*4HvSnHQK{%x-26)5h#w)XJ&Y3ph?*WWE9YSIM+P zSi$Ura6fYZ!Vcyjgol{J5FTNULfFY1gYY=h1>p(iB?!BjlMwbWy%3&aUWV{Aa|XgX z<}8G@%sB|Fnez}{U@kJ3n7&0-LJhK+%dC~Lvx-4A)BlS4Tn;n9Dj}|fI0NxqhGng+ zvH*3ifE@&E9y0_~SJ-^U!77+xnc^y7kjlt7fvO+{1?EGFbY=u73KChcW@50EnFLP7jF-8|_?QXuPk8%a zPT`MYrWVc2dj1o*){s&J2qhCBtS^=-#IS4u8Uutb8xGA|~!B~UcRWu2UuoUpyo8_hk{b)>iN#L2#%BVC7%b@cUi^z;I>hUM85(TwBv zYu6mEp_jPPiOJr{Yb@Y0hgeUahvh~bF1xeO?eHQ}+sjUPj+{Wq?O{g8JOhamqZtAN zk9tZ&a2L9aQ49mL{_#=YrFtlvvdf!MbiQ@x?v~v*r-c6_?*Ze%QEtTU0mw8k>Kx_z zJe=d2ll8c9aiYK6>fLpLVQ)anwGr0kxp0MbIwpj0v(xSxx-c-xu^0MT4~X7(jdQp> zjn^i>)bDZHNBSB2Ud{|$h>SS^OjCT_0luznweCQu?!f&KzOHwgdW!OX?RsrZsu!0A zJUIgdLNz!O#!(g$fTc)r77Q{Vh-&(s_JONW&G;3Ehh6&@M5#EIS$jYdhd7pXMb-Vz zF*d55WS!2@@u+%W((a1tM(jh-CibX$h_g?wO#`{t*v~nJu6Ss|(wi>EfSa5`_<0R7 z-5BdNi4lRjoQ8#X&0?BZmYhh6{5}-9wt&HX3~+p{{SyW_G}dsMt$hcBObkB204uzP zRbP9IK@|o^A+Q;}X-*qCj?$Nx4O2AYCrjo8)!wKj$v;n3KFl}_(8mt6>xdoV8fVoBATEm&?HS__d4={an z-x^L+ui+A4E&=8eeaUOM43WzaxlCX78k!(-0U{UZCa+-+MD|LNI*8aHVx#N4hVu}) z2$75Qd9UFnM5Z7zMc=fk*0P|4wQLNm5JVNusFq_rW1MS1w8#NVQ8m=0fiUKz>yXN}i)1GmJfrjgG8V{B zlA0yt=pP+*?xK6SF*aqv@!}fjgLbEzrAI+9ZrtH!NudXOZOW(yXT-Ir&fzAK*_7N% zQ01t?;YOuH(}Ke71(?I&D*W8_5KL3CEXr*8j8bTtXA}`j#+~um@z*9-Ep*62|JG9R z-nN(uk{%l@f@)Uw4<+>pjylpOe-GtgpQP#uM&4PuYdt6rd4N{5fFumQrJfnaF~9DS z($Jcng0gzBJk*`*9!4eE42&9SQ_^Vu02W*SSIYbR8FP7q{_Moy7(iG2Y4Y{QBs|P4*UU{2V1CJ@W&AB{} zLE^+1JUG9}6PM8oaf!>f6dtT9dEyi>)58Lz5=mww{6v=vW+U^E@^t{5qRC7c9bzho~xNg9@%825FB{kH~wL^PG z6?IXCjlsbT zT?^|1sJINuXui`n+vd+*G0=~)iv0WDKD==Ft)r{O4WZ(OaB*WOt7+yWA)7uDGf?J? zJ7;Fk%(1Wa`MX1=vQ<-c$W$E|2%GAI%^}m~Ra0xo)Vj1kY}$D*Gi2JmYHAOe+V59} zO$TR`j|}D+?zJ6r_E+~Tjt98Kn;#7D-95i+>3z`tVe8WMpN;=y{HK#Y-Ftt3xb@I- zOYchKsYhAGd`a_%`|l}#dMH$~JDjzLH|}|qUmmD<%e1U-pFKR&G1r`!H^2p}|6-EY zw?8sLRs7c%Isz>L`#al$6~XTJs>7x&Gs=j;G=1cY&n;9&{<8k~qL;7V^-<6LtY4h| zyNf@+_=~j+nl0vf-s@1GqX5T4dz;x*Sm&IAPF$j)ay( zt%hr%D5bp82xVc&$g9+IXwsxL;5jtuG7ahT;Z$WABpO%|6V^8g%NWHKF}}XZqXSk% ztQvXHzPqDLSP_*8YlrfA?JbvNN?H+>5*}7W*=k_SsaEaeb;45;mr3H0up+9a{%FZy zMO4WvVp*KKFq5R7gtrBoBVk39d;6KQP3V{Bj8uvH^JdD z!g?l;=9FXW|Bqwkl-xJ}FN|Zb?{E)F9=A3R+2;f6p6B$+LHzm8Tr1 z)|H7i^aYak#!NwOL3n%I!FTojy2t2 z#lf+d!v!!gYS))O%F)APu(QPtuaK6AArhuP-#m@iLgej!mTl@LoJ6yeCYESdl;Y07 z2;k0Qa1Mj>7+k>MA_kQhpmEAw!hl$#8Bz7{sKdqC0Tb2s^qxJ|(L+p7u8&{@+m!3a z3R_W~_ zdV84Oxm@r9Zy%V;iPccX%(-o|ZM-@^R!-#<`pf4J-|d?33Tz8oZNc)8wPDrT60)`| zwT7)b?kPgnU8~k_gsk7VpB=V#+_#6UhgYp#A#2wIci7r9)A7iXHMi|GufO}%KY4d3 z$iD0PNX4JO{JTAN{^iqPh-Usn-Y@fhRq%^T4+g?*-OGFID?9ri<nKcQYZRHpT=eqQgd4k#At-fmoI3>Vf1JC@4dJN)CW_qxIjd-#I3 zaK_%%j02&J1L2H=q?uPOWg$yhK)Yh8eN<2u(EP~oj^Qs&p@K$eHP~3lt!98$yW2V6 z8PJ5SHG%6Pt8LZV6tXrgslwK+OWh&sj#X=0$l7*qAZ&%63Ryc=t(_rj=Y#!W>r4OV zv{=NDA&!GDKCh;%#mmOi@9yFo_kNsx|I~x#U!M6@$!dFVsJ%Db{&J}C<#6R`zT`A- zJdL}EwtmGIpJ$Lfy>gyk6|S~-huXWt?LDE!o^WL^U((APdqsM8HO!M=wzQj%(bUJy zmB(}R4>IzO7gGNzr?Sha{|()8JWKUo3Y)spR8bwOD97L=+zU7u+<%Uba!lViXNP02 z(f(m}z~hdZgjKUqbfC{z=dK;?Ne|XpF)Va;4l#n6y3LdO82Wi zRjMrwxL<%i$7f3AL5}3{$%js08iF<>hb5XREt*^8QqbyC`7~(eq&oKUsU@DS?T|yg zE=P*Pu!I~XkVCUBM~W>?LJqYg3%-dVdQOcSIQgJRtQ5TB^_o)oR6W!)Y8*_cvG)0` zCY71UNoX0V4WI=a8M%vf$?DkEryVN?j|N7ZEq;?W|#HO|XY=eOzOcuw0-QyUAlk0VdR$?m4 zh!#SsgKTlSC7xL&GaX?)S4J5)?q&x)4K%rCYoPJUh~;eQxH{rP<{@1NXFTG$*NA;W zM8dJSREB3XoyT z`v6EHm>VdGs3U~qdC62li$_X`%OeYutWFZEA=C>@EaV`Ok$lfS!`sm6C>F7RxZN;* zqgtWyqH1i>sD`vC+`F-mM$8j#3aK}7dL^yBnGJ1xSJTDxgwmM zY024HOH}D-apOqF!pS2TF&VNEBX$b+3J~G(hWl?|bb%RDLFHBj?4g|6>8^(brEnTp)|j1Et)YQy>UpHZr`?ZN?8`|R?;v;Nb8 zQwx_?OIkuDElYb>O7=yz?!I?pd27eap}CIPu2mx)GSY$472}qOCD&iOY$=basAGyA z1>bY#*Lznx`$C<4{AJfl=V+w1F*x?lt(b-~S?4-l?TV?Ow3wdC&bw=yxA_l+v#Mrv zz+}e!kJb|Z5G>1|QCdywtbRr_b3IZ}_;%hxUcmZR$&7AJGi!cSSQ$7J?0BauT-b_o z@0~q5b8v27r{bi7KY9Asjr`fZ(9z4QM+ZYk2l*lA%Fz+A9!rCv+BUH= zvt9n}%fii3k884!ENvC4HvYaz^|HPCa4UUAeQVqj#-Ca7dF$=ha!fo z=`M0tGk`{_^xzdES^O5s;x`1#9;2Ajz*`H8-4A`>wdSJ=Q{LX-5WvR=6pZruG;q47 zOi=6K+>m7Esu-}BqY4PTF$sPiHUKc$40*ZGvN$iYSCls=(M`E&!)bv_NwVzFJSeCm`ZE$Wm@wtRLe zwXT91g7elXG)J_l`1s_K6_iio(=nuMFWePPX>RwbsjpkQPvy>Jv?*nk+XY%q4Q??y z`}l^%Oi;G}nnmpY?&U|+#9w0x{$m#-)Dc~4{{jy;3SfM3f^`V5cgWTmTs2&7mh+I6 z3H(H^U1MF0v=Xgbgm7Vs8eHsnpJbyO;reIDa|Ld9#_;0D!;W0*!)tO_*jQJegDh65 z7O40xn{+Do9pJnSKldeJc`Bv~il#dw`32L*BDwj~M;;oik?cbMc7Mm*i>ujnq3pVF zc75>BQpeK4;EC0S_E1B6xM4q^bpVztbLL#FzhZvVYF1?^s}h#5u(>8!y=-oZ7_;wm zfiiCK!(Gn8&EWQ62Vd5*TDCJ(wliF|YsI)bQV16{3!4ILV304|yjs{ADr^lGZiDq; z-)!gS8VWYTDOiWiO))K%kvC(0EH0cXVYSN1g-vH>{%4dvZRt@%q7;4&3hh zLYB(F*s`S|l2NppQ4z|h2(h+eA!DiE{r1GdL@+H}*0N%3{S;PQ&)bs=lfj~J z*)~3ZTf|bx>kEaue?vc5SKw9V0SCFH#RaVivbdato`4G>m0RgkPN{H_@j#OBq&jYn zUofXs`m$|(0hTXRUQ@6em`a;U2ZxUowtswI2C5bOl%@=zwo=*pdY=JRE2HqKJhDyi zldmn%nUPT;g%?U8N?4C!T$$e90xD7C)B05F=yZgyQV5@~?&6fbv=p4uF&%%P64my7 z8&smu7yl~5KA{_B8@m^+Sm;+8ELxE@n8Rb>Y*N<@t~xDS;ugJRE{k{BCxopxn&m=9 zVg#dMDOtsRNlF+?5)i43XUz9}aN^TaSQN3pr)EC<8=~qTMhZhf8 zouJhKOYHZk9$eQvun%)aVg7hLqay;fQH&5GLFeH)IM!c!1iRcK+vP%?I6shm0YCRA z5KL1~XgGt4WR%Wm9_JTMcRuPoz1n#`)Onu2Fcj{*vfAkib-MUbF5Kx3sSi&do*DMr z0%w9Z?;U$=vfjBkd(po&Y@*Tsr$+$}K>F-eePKvn=-(NzFYF1nE>(Y2dC&ffnx8bn ziB-#i(58-1(ZL7#p`z~J>QAC;P>%xim^s&97#Is)e`hjO02kyfOJ_r-z4xm^#)A=4 z=AE;%XXkE)O_fhn3S(8IrXJs$B2ByQ4L|7Mdr$rPNNDfNp{CRPxxrA=ASOB#F_6ch z5Y&#!&0dSDV1E8G~=JE|UZIKfwdBhFOv+G2K(f$IS{5Wp(9Ig@@bQD>Llfvlv9_oOkGk=*)mPasgK_)CX}g9$|>JxL#w4FwRhTA zw6}cA4LJ>5eL^c4Qq(oEZRJG-b27#o3NFFp3cd#u+Z$4i+@=J+#;@ROPRz+zuEH)Z ziE~Cmx+$ryrmv`LW0cpJR$|VC8?b$N4z z`>73l@+Av z&O$B_9H3BJ38r`zK+nvxrGaj4z|*f5Z+WsJOu?4>HnM7Y1|4{sgD(~br(1Rxas;n7 zJ2=FS(wm#T`GQi7^Muuww6nKVNFf$tJXx*@slpn%gm|k`QNmXX#jonuece2tH-tJ3i_ZF7Hr%l1n}~7K4u=jFOu$r&m{qYO@aW=evkZ&8rl-hS&;dUx`h;MlD<4L~zYWR?oZ+E81 zGZfx`g>SopDHV$YD{ynj1#W$GmOpeM+;)-QaS;=$-o>k~-~qm2&&NmjuHo>3tNh-p z4|N%sXnVI8t{OkI@q5mOTh8$f=N{^E5a0Mg<%*^8LkItjf$(;Q-@-%;1%ZN)q5i{q zzU^|j#m+a_pF`^3w`?eVcbIQx!!?6EJ@`;(LasIMR)HuVO!6=EgqwPKTkk_%7UDO( z3oX0p!x#9ri{aKw{N_s$L+&CQXb*62ImI#u!YvHn!0?88I8oDQ6H|h_hW(26-$584 z&mS9PM8pS3@~|N0VASXuO&A3~0=5J2BM%On4EUj2!P9?+gE%lVOz!*y|^~np?lsUmkSH{8) zty;X{$)2*t7Z0D+gY8BhX%PYQEACirm6nhxtIz5)`?AUHN-gZi%&8oPq&5OaCD|2C z;tw^K<(V>1<@nT$mfWJL866yt>fx|V1&eIlO-(k#;NC?CDFqTIpKRX1!JU?a9tFcJ zb4ugWaOMQ3HQX_p;TBHprzwCrOM-J5js&F0ls*jvigYH8$kgu3^28m*%qe?AHd~}N z68ezrXANEh?12{+y_}Cp!yT_HJyja!<&H2|H;pe7I74<9!~_WQF=Wr` zOGg-bqf+7@e=~APz{4!i!^klquRoMC(n7nK84Y7DM92Vb3}Z=nU=Bh1`7{Y_tb*HJ zmCr2Z(?Lup$I=)DXpQEOk2|IbPYa z?Z-gDyo4VkqAL=7)Ce1Ma%%?$1zLX6NkL<(d&qim3%`qQcTLjZCf<*Cf$)WnY%b!_ z153jvY+#`=jp@>Q4VEK(Rs-w-fZIS1m@$%tA=1WqG}7WXY`f^owY8UJ9$;q*Jka2j zFBQpQN4&(uyy*#-7%_O}F8Djz6d;lG_b883H%5-AEb@ zFgBju;K_TAq*fP_NMnif4tmk;VeO=0$-EK02uE;VU?0R?!UnVp#$R$POOq1cbz649 zO}_XQ4eVKViQqbJ4Rni~($B)4P@Hj4zAdqCTjH&oyqnoYA08d2N8lq9_;3%7gK)k` z6p2I0a|J&Sc3l;y8tJ;tAQI5xh`GX&k8tJQ5xxg+NE$(;Ixe;Wwk?yw$9bZfvL#H( z1Sy5RPg1i#LoB;^keOKBbqXS3BPEQ5jmNmpU@o2PCNgin9PhS7^EOFXvh5+Q6W77< zEqfxn_}D+W{;NkE$~c1X>W6q^2+~V~PSVgokuS;8y}0-7yzC0e2g)iqKctNmM}c z3PD#y6&3ht^Og}?0on3#VCKNL&%kJG#N~$DD;#3Nm6#eUCAe(-1rP~4SM|W?wMlYI z#-W2K`ACUeVi89R;j|e&QKNd$V&oGma?~q0u>K_`s6i+wXqrzcMFHM>`9_J?Zr-?uN< z9EzAKR!#LG_^b;)^J?U`bgXXa3~lLrU=M9M0Zu15RnuKhv{Xa$+}Pcl^EU&nD|xj` z%yh>;nzQD1yf!j@=#lJJqS6!zZY8)qEnn_FVhx+L?CnG!Y#(bU+5)93@q6 zA6q!~R#$NUj}O0hc3{q`q*QgdCs=1D+=83pT4&(I0@VTH(Y^J;oMC#>_c7J zN(NjshBK;XT3|1}kP|cqG(fRvhJ$yK zg$o*j+;TzlZ+iIdzVPwOGiKPpM{@Fi!uq>{-OI&|_j4X({<0vH)A_&?vi9(&*-$nc zY1+Qp^kS&##rx`&rVf8zVC(lwAGADCDYJ7Q7nT0JBha|iyj-#M{@8=-znp|y1pd_7 zP~lnr;?+>W)h8Nd_K0Fe2Nw!(Z(HeanQNHQeX27pmIaHJhVI>ZFcvO2H8cLH&gjWjCzoH$McI*Q&eq^Yw2we7a-rZS5W7ta0wNe=?L)7isaR1YdlfLm91jjp9~3G-NIo@YSbR&RpOx z4y<0h61sRLd~rB@<|^+T37v8Ar$_nGYkcMPZ~@0>bFuNr(v6?N|3i-Eh?@Gf zdh3zhs$cI?Kp55c!55JZS6^RL4c~iu9RH*OU7$sOHz(`WpB!@$zkaV4%xJgAO`OEM znfUEz^Hw+!Y=vLTmMu1$TF{YrtR)?7mew(2fovE?V`O|a$zmowuz;w)|D33dEoX7a&fqU@V;1) zo-Qf}_?F&n?{~5cI1l1i@?>F2{r6hv8+Oitw2ihV4v(0*cQIffh+6vk>@M&RBo2>m zXefq)u@ozC89~C$eB08RYS?~%*(OW^#=RZUURUCG#%Ra(_ zta>~Ay_S({;K8gP5W9o>2uZZp;P4YV^*>;y|A-j)Qyrwc@S_Cy7B{M8UDzVrUm?XQ zLLoLNe62gmdHM*0sDUhXVgw4t9>)>IPB=X834eEmXkz$NF(aeQn3LVhtpGF7!j$`M zJw?G7RVX5qEzrwTxqh|Zy^tQJY@bj&KB4GOsDe+Z+)p!mr_B#B_%y9BMwJ#TBWlCE zE6^QO1e?RTn`0_KJtnB0U}ex9&TWlp00q-slMZw}!SY~tIJYULL!_S47)fT8fJ{SV zI;D{~wj!kgkw!{mBH1g0*TcEZF%u%q5~V8GgGdV^GboK&EQla85t$`W$|7YW(n@Kv zMV>^?97N_)noKb}kuwjG`2uBkP?WO(k%g2d3n;PXM9v~a7E>Cl$dkxfg2+;dQk1g{ zku;^r5ep)6mLsx4pp@mT1mu${Dz6$EPH4@C;GX$!0ZSby@UI9CgmYUEJ{imko($)1 zk?{S{(4XxFv7S<;>8fe%lf9IwG)Co@Z5RlET0al~wQ(RIa>GDCI>AacV%K;(vjfXEF40g)R90wOmI1VnBa2!Px;5dN4>i{#Ru zH365WRK7_yo%W=KN-qK*q6j!pne!r0m3BQv=_Nto#4O zq^kuIU5<*UGM{8n8Rao5rve6nhEJ=EsQ`Q|fEoa?)3u1#VFWsxMA9$#v=BsvkSs(mVe+iMl9!f*8tEEL2jguyb5sStP! zfCd4`nO_{!5l~O%7sb*Dm`)Xz#0&&9BGyDeGX>c!1k9lFN@AG=%%Y0vST+Hz6x1k( zfVot8bu5p7`3M#eu#hS!junYudG%8PguO#?X{4wuQd$|Qssry63@d6Q<<$t+Y>L#> zM#`!pl~s{y+h-;H3dIYgA_$O*ARtzRfLIZK@4PpbMxt05zh|K^W*||l5J@$Ws2Rn# z5HJJk=dYSS8p|ZnEU2U3Gd~i`CQ&O@UKPtBAXKg@mPf#Rs-PrRK)^z(v^-Wsz+xB& zF(N69)6$AS<-*yZHB_?sX&FgAtfJJ$8Sk>HAf{Am^eB7dQtoozj#&@C?+kx|S>DI| zyqh1sI(_(|uH>OUd+v&V!ap3;^46w%`46i2mmR$K=5O`BPxMuv=;=@NB@eR-UboHY z9%fi!H=~K@EqBbb<`sSZ!_3^diPy`(=uO)>)Bezy=Ql0o{LZ)oOogYn`VYyGq38)L;CW7Ev#=?)$a`H zcizkTt$xp^AfDZ?pY!tN{k(O69~pzL4EXN1{|_kRkm6Id{?87^Hc@K9L-BtB`B4_I diff --git a/core/__pycache__/cache_store.cpython-312.pyc b/core/__pycache__/cache_store.cpython-312.pyc deleted file mode 100644 index 6b8b32e61126f10264d29078a6e15a41025d3620..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3560 zcmaJDYiv{3`CQ+J?bwcE94Cal3^qwTNGL6^@ld5KkHMJ2M1lk^n&{DAXZ7&El|>sN|3Iet0MDMyW(y(L$r&P(Fi|+gB6G)JLAJ!zF)4*54tXJAP1?e?q&;kByqIW6I>HV{O9^Mv6?QS&nrKYA!|r5LxGCugdpKet ziZ~mryl)F)@}4b%3i-d}O7m^5tWw3Y?KW7CPuQolfbDj)Jx-#n%68z}rYvp1gS-Ld z?A!xDy!0r(>Up{ibfh{D{y3Bt*{QV4E~QOwl-*M{x#_YH?x@Kd6%VYq%Ws;JWDl%% zLbSF)M7qLVaDrEH%Z-YAN|2jjt$Pda1KzLflv^(J5kf~{S8HNdG7t`MMCq2dD?!*7 zgnez7h1(UI!@I%4K#l7Gt{47y%R8z*R56QtU9%50<#we{=~;lPkUJI}06XQbnxy-- zRDKCZ((bf7%s2t)4@MB%+fE#S|yzQi#r|aZNSFSTr`HnD(K;q2nWw;S;A#M?#B56A>n- z0=&%>qI6m}C93Fi2?Mb)N7bMgAO_=R%e-(=tC9;;9>sGzBfCs1z*= z3Ct1N1T^)qwW)YQ(a}3UJkMWSIC5TA-qaFWDygW(`57e;V<~lJd{YS{`RxPFqAt%+^ zqX+BZeJSu3J29-44Un+vj;N5~jOt7xZxU*+a~Tf1Smk6Av%H*^aY#de7;MhrsX;;= zn4p*S(qz7puK$}xIvJ8otENX-ol9{Y6GnY-Fh!%w8Mcj_8XcijqmXjUWjVnuK$l`D7bV_nr1Zzj)t=()-;U(taN4fH=6< zdW$pd2|8DH#uTRJ)L5)m3UC-k0bSqh0dO4#ZM{%r@-bIUa=k#tVVI1;$gn1(7xnmp zLc3vOh@(3J>3DKEgwzEj13_G929PD|j$Q8_E=;UBAUs7!--^(;33Bp+L6|INP!@_^ElM#HaIm_Ih!FIMi_!k?6Y5U&}mGJfWn=$C}iMP%WxlYzl8JZLv6NZbxobr ztzHynYaLZzzX^lz150(VU9x1hbPwyhS}$b?_8q(rv%sDVXxDb~8J=1){5Yh0t9>w9 zaU#|9GyHAL1Uwu;ZAkorG{A;h$VM>%v>kvc%xZC!HX><@MAT?fi9}exQEVQHlP)Bd zTMetsbeHEMHYn>>Het&Jgwcd9^k>U`XvNzorO<_Trp)#Y9Ao#5{`x>=5pH0jrvZGE zCI57IZwxO5S334D_pEm8U-9jKY9s#M4>LD1AD_4v{8RrQ`tNl=kXF8Zs@VO*ococ( zeeLL~qie(4RWMe)!4+rlD_>XP?K?uzcQ7~l(Cu4q?aaHrY}rv5UTN90G`iZdCns&# zy!lg06U&FzY_C3Y`*JRdH4ZM?0a3V|iOEORG~BWAm|^m|0T(WFkM4mr9Rv5{%Ajee z`$hMGycZQl0DvzWVngo0&)z6mJYvhWx%bDH0)?|z-!2hg?*{Mce;m4V@%ICa{qy)! zly34w@-X#MkT|{BF=iL$BpHpXkqC6HJ4LmaqU#YO4p~xllT%;lK8!!>zV8D8*D_Sx zg&p7&R1Z{BZE&C*zeTF!;e{2;)|CY~2P%gjdyJbOqwin_KNX*Znei%cTW7{0;3jrzc?_W=lT{u*7p5 zw@zB}zN{@5ERvRgkypMTfzL@7{Cz?8t&)9@Je~R0>m64+3R+?ML+ysPtSwJ}qTSN& z%@hZ|SL{0epttBbowes)E0WXeUH+^iH<1tI^?cvrkBY?q$l9EpzjEoFOZjta*6xRb zJr`ONnoEMn`SUTj2|53gkD)s}L-&MD6qXttTvL9iL;w}$7+Ur%>vx8i)2pGwn<)Oz z4gz`>jtk{&@F~TG3THPFm853Qn?GA3fR^A60#w>d1ZQsHGrsL}AqdyD+H$PO^ef8whkyUU1 ca{Au4KGh$bx&PCZGn0Q4Vx?{(>|l}qFM`YlcmMzZ diff --git a/core/__pycache__/compile_bar.cpython-312.pyc b/core/__pycache__/compile_bar.cpython-312.pyc deleted file mode 100644 index 8c916971c5c557fe12aa524dedcefe6953b4b819..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1642 zcmcIjU2Gdg5Z=8#`_6ZE(xfG&tw5l}V~VOCzcXMBP-@#k<%JXFJ)u z{J9P?QVB+uJn-O0UU=dqQ5q?_8VOV(6!Bu}KKY5+vo9_Pl_%zO zGqba^JG0-+{1ggl2C33?9T8AM@eVD|tR!^9yMBkwzM+OU%jVN;`F*-_%-oI_HMHf&fdW|@qQ zI(XQ@Q{Nj^R?)R&Eqr{Rn>^bXICusA45W~Qcw;#tmsrAJdH ziwzt6h0$r}2*k-|z&mA_G0Nh`bS%L#j2m{A^L-Ga4SwqcumajqwL)Y^ZC!X~J_L&X z#I3{2^iFaqxsJc(>yed-t>?Nn4|Q$o-5YXu6^>_bqMz@fLhN@punDX2T2X^lwqTZ2QpF%g~be ze?r1bK_FH~{IS^Bt=@rV&NSfV+QjYp6&X##7uE)LMXThb(3KiKUc;R=e6@x{Fsg)Q zXrlD=Cx2WjeSP-#YX`pT|1~#zHmq`(K*U8)IsTLtvzYDpMtKS*Mz&LF=J@I(E1-vdq_;2hes+A(cPF?MTy80= zt;Lh`!8xU@hKi)vdt3SZLh;Pv{$*>ed+FMGWGTCOv}>cYdwp!9<<*kCt@f4G;0n{iQ-8esg{_eq-zV9ye zZ5@nk2j8eD;x-5rXszf-?cidl!E6l;6;i`$z|SRVMhAiiRYmBI&rbc7%g5T3U`{!QZ4by6CNyKO_MRR}@^RZXj))HJk0GDr=FT9M4kZN5(?aZ5b^X9$% z=9~SwyE_Ir?w|a_I-~*oMn*97&ZPMvPFCT4;J{fK@@>uX3~i;XRMfo6$fuUIik{aQ zlpr6n!dApmr58u%8ahd9z08@-dtO$?dn#N-{^n6#_<_zsP z#&$2TOxN!ep35*VnlmewTQ!Ro8hX{VOGQu5j%ClCT}%#LvdX3TSBs84Rhk}>PNnRH z+D4HD$Dt14tK!>SMzIQVXH6>T@CRpiI`cQ+8j}GWaGCc0YshHesKK31uG-Figh!z# z$j4woIRdYN%jOgY7lGlkpvyAWwbADNatB=s#LaOF$2e#n080} z8Cjj+V^6^uF(!5;aWStS?y@eU8 z-cX#9*ck2cf0e(yQ~4kYFh{@vcRK(c#4jUVbflRb5 z%Eq;TIX)Bj1S?!Gf!rHdmv`DJ@Zeq+obe6&m|at9%ClcgO<7Zl3N|l3!5Iuu_zydw z!_H7{F`ad0%G|IWX-t)D9`KI%VVKgG$S7XKb_(T^ZMmWckMNlI4l;2;9VDpop5nNI zzQPMx^Cefhf*|(xjAM$NBgdT?o1YcJ5rV)Kgo_{;J+17RJfr%1+o?5fO4FqX>;OTS zd2tE~$aVldgp2zHiaKnBQqxz_9Po27)WpQ?f)wt>h5XuLbCtwRtOoq#8l3%%L}N+Y=pR_tm-x;2Mq=+)7~{4m_)iksZWmtf z$HSR3ed2!>|NrV&s9iy#v8TFHc!@&6w2=p< zEIGDYDEPPW`&$t1{-L6uW(P@7b+#j?D-NG2TcctSO}euC0g8so7~6#CuMmF(=|^zj zaoVWsb-9#X*}s&#AAbG;7#lr@>+wb?%#N-_n}Dj7f)|cGffP%v6dRMkN7*g22 PwIdBcwLaJ)<=@~Resq2B diff --git a/core/__pycache__/panic.cpython-312.pyc b/core/__pycache__/panic.cpython-312.pyc deleted file mode 100644 index c7e91cea71f0e6904aa53888d68ebee325a7f297..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29268 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 OtTy@0xqlF#(9ORjCzWCV diff --git a/core/token/__pycache__/tokenize_file.cpython-312.pyc b/core/token/__pycache__/tokenize_file.cpython-312.pyc deleted file mode 100644 index 16ea2ea9191cd2577553b86ddab34eead6f98aff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3579 zcmb^!TTC3+_0DTw?AjQx!C=hPrmn|M)}&3G20K&^kk|=wBHK}-E!JkdbAfedXULsd zY@2t4Ii{z1EG=S#qS7Oz zYl7Ek*(|4<*-4sq?O#yKfw_H*=IjZY&e*vewOmc~5_}Dr%&bMdHpkU1LpN=!Diy2% zt8xw1criYthq8{F@jvXteN|#}1dw?`NlGwCN;HI&L}f#yiXqVu4IA=^co;ZFWJ8&e zm#RXk2=Fu*A>cyJFpU}!cy~&~jOdI~lZf4kX>l*gcLTd*lWf3NE!$NyW4bj;P% z3|LKj)&Bk-^@U`Q`mU9opv=+Db80{GWUW!v9m_f@ny$jAs}ot<)ZMIYsrCr0QCQ+i zRPYL?^}IV~Ge>nP%Q;C;9@pJ5FT|*uXI3&JRL#Kw@_0ia6q~EP5u-iyMny9*$~WbkAWALsyiMa-<_Ef>h==f zmJBfVupkVOSurDyl8ku$1R+ymokWlg0XvL057ZG=)NKmp3bp-yB;GqIgU%_aj6F0S z45YWmzz&dY4Q6k)1=#lJwg-5TJdgrkO-VbfI`+R=RgiXA)BXRj#(H5p>TYMS_d5Rx zfek@S!2`8C*_OCVMg&8ii4=C@?+Wx5gdz#_)x}_!tSyrBAhZ{cpSKx^D8}^`zyQ;f z$=}D+>Jt<*RN_e1q{&!qNTiTPP;a*QWRDZ$BqTfVO!4? zUa8+vWkN6eIR~Kb`gLDlt$iAP@mEzDd}p?nCG#Gk;sIRM}-B0$j>$aP4*VQ}1( z00mNO5Czd71;G#|ffGu#dPw|6m=^?cuU#g0q)((6_ z==o7<(c9y!Z}Lmmc+|9SfDb&S|3d%8K~Hh><0kc@)XL{5(_QMx_BfoBQATxxN5_l2dv!4V z&f9Mfc`}C~eH=IphIV>kdYfkQAQm0TTN&53L3MasXKq$ExoMu1)5jTxSd+Php2F2K zbdk5uKi`9sn!EM`$OUeH-2snLo^1UOPQVWD9E4N@lh@lwyz&0a^RIsNYPmsu)ZC6( zsioX}VkLg!@$r*SFvO3$PCjT^G?x39y4JMU%GzrcZJ^RMxTV0_CXu>hca^Oei8rq` zbo{xY-zuKQud4oLab6-hXT*a_s5GVUl=Lc)Ah8!9n-@ zA$j_BN&e&EAH5!teb0xm0xj1IV>Hs1ovD^FFcT7j7elsb0N9zphQLpVD)*G^A|HPW z@=~=$)OYV4v$fN{Add*!T^ve5ocvp@F9l&%b$+|~-cE|UukWOsuJ4|ZOtok4w##o# z{)H-Q{WqN#o9-Sx7q?WijqL|tK_#Fkcm?qy@#{n3k>N$cuqUzS06>NE8!)yBZU`?8 zF12ex;MdLouk#9kX|i>Mv~@0AEB&~1YdKVDeHk)4M53*8`PE1#Vu$AFYUIdPgfyz9 zgQdt~cV+*XmB<-}H;l`g$a^;jT7wr!r!754(`hf3PUmbRZz3K~r$5Z=roY1Qw&KO% zChlf4ISThp!;`>A3{QO)L4Xa)ld_h}ZTKDGpYn~u9}$KC?}APqzzq2!QkcH*jdEaJ zRF&fk{p$pV(%|B$<;>!la(C|r(whQ&TFsZ*!iR4_>Hoy zj)6xs=y`quV8wZfjHx>gb&|XS{2bvv!()m&hP{Ls1}8Wn{5bTnUYNu3bAA9|T@nQ0 gOVaoi`RP~WrLW1**W~npF diff --git a/core/token/__pycache__/tokenize_line.cpython-312.pyc b/core/token/__pycache__/tokenize_line.cpython-312.pyc deleted file mode 100644 index 874d177c6354b73785600eee09d502e304bd36c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7746 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 UJ5WSGe!lyb{)>Ifgj6m6H!^zHWB>pF diff --git a/docs/doc.py b/docs/doc.py index cbe46b6..1060980 100644 --- a/docs/doc.py +++ b/docs/doc.py @@ -1,7 +1,7 @@ -from rich.markdown import Markdown -from rich.console import Console -from rich.style import Style -from globals import HelixSyntaxHighlightingLexer, lexer, highlight_code, formatter +from rich.markdown import Markdown +from rich.console import Console +from rich.style import Style +import src.core.base as base console = Console() @@ -38,7 +38,7 @@ def doc(doc_id: str): from rich.syntax import Syntax - md = Panel(Markdown(md_file, inline_code_lexer=lexer, style=special_style, inline_code_theme="ansi_dark", code_theme="ansi_dark"), title=doc_id, border_style="yellow") + md = Panel(Markdown(md_file, inline_code_lexer=base.lexer, style=special_style, inline_code_theme="ansi_dark", code_theme="ansi_dark"), title=doc_id, border_style="yellow") # terminal width should always be greater then 40 but if it is then minus the width by 50 if terminal_width > 70: console.print(md, width=100) diff --git a/functions/__pycache__/_async_pre.cpython-312.pyc b/functions/__pycache__/_async_pre.cpython-312.pyc deleted file mode 100644 index b0def472873982efcb60c4778d6282c6a86ceaa0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1167 zcmah|O>7f66!!d25>iEi(yoMxB@T2-Rjt^=N(l9bZc&S1K(s|{)b23EPBUdP4z@#^ zhyw=>>}ii6A4NgdH+17qo9Q?|skq`|S7p{5qe{ z0x5sLd5NFu0Q{?*RLlX`yCT6ufB@2BP}PcBRWItA^7YuLnnkmZjo7N%MZ1s9*r~e3 zOdnfuwwOaU){uh_l}+T{H;eg(>TPMRGKk;sg7CTwYmT2?#M|RPo}OCx$(ud{YZRBG?I_uRAuQLE5|2m%w<2DF z!kSzD)t_(v3<-r{(tuThqH=^Oj2KJ^hj+p_LX)u0@ctBoVVTPnyn>-{&#(IPD@&LC zW&z&9jV(eEj1tCih~(XyHum@7z1Mket1MiJ_MA~=m z;nvaVf12Hy)%MJ4>)Lu}=C{^#&^mHs=jf$Zn_VBZebmCF^j7EVQ80m783?ibk-QOT)S_OX`xdr4900c=|2JeLGg`9_1QfuTcaN1X?jAs>Y1@|sd|Q{Y45?QU2uFC9NPtB XZ$Y7FW;FXzu?M7StzQ4AY@g{11nwq{ diff --git a/functions/__pycache__/_functions.cpython-312.pyc b/functions/__pycache__/_functions.cpython-312.pyc deleted file mode 100644 index 7aa420cb23b4d3812436f62ded8172050c563ac1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15919 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 P4?7i%;l7i(q|X1py`0pF diff --git a/functions/__pycache__/_include.cpython-312.pyc b/functions/__pycache__/_include.cpython-312.pyc deleted file mode 100644 index ab5402b7cff424b618ccde332fe7ba6fa63ce948..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13513 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 W_f!p+1JpQ4>Xri;nWRo-`+ot8JP3&Z diff --git a/functions/_match.py b/functions/_match.py deleted file mode 100644 index 515ddf1..0000000 --- a/functions/_match.py +++ /dev/null @@ -1,13 +0,0 @@ -from classes.Token import Processed_Line, Token, Token_List -from core.config import load_config - -INDENT_CHAR = load_config().Formatter["indent_char"] -re = __import__(load_config().Transpiler["regex_module"]) - -from core.panic import panic -from functions._class import _class - - -def _match(ast_list: Token_List, current_scope, parent_scope, root_scope, modifiers=None) -> Processed_Line: - print(ast_list) - return Processed_Line("yessir", ast_list) \ No newline at end of file diff --git a/helix.py b/helix.py index e9436f1..8f47a78 100644 --- a/helix.py +++ b/helix.py @@ -1,40 +1,44 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- from __future__ import annotations -from datetime import datetime -import gc +import tracemalloc +import atexit +# q: what is the purpose of atexit? +# a: atexit is a module that provides a simple interface to register functions to be called when a program is closing down. + +tracemalloc.start() +atexit.register(tracemalloc.stop) -gc.disable() - -import os -import signal -import sys -import shutil -import hashlib -import threading -import subprocess -import functools -from sys import exit -from threading import Event -from io import TextIOWrapper -from types import FrameType, ModuleType -from typing import Any, Callable, Iterable, Optional, Tuple -from argparse import Namespace, ArgumentParser -from time import perf_counter_ns as time - -from black import FileMode, format_file_contents - -# from black.parsing import InvalidInput -from classes.Token import Processed_Line, Token_List - -from globals import POOL, EARLY_REPLACEMENTS -from core.better_print import color_print as print -from core.token.tokenize_file import Tokenizer -from core.config import load_config -from core.panic import panic -from classes.Scope import Scope -from classes.Transpiler import Transpiler +import gc +gc.disable() # disable garbage collection for performance + +import src.core.base as base +from src.core.imports import ( + os, + signal, + sys, + shutil, + hashlib, + threading, + subprocess, + functools, + datetime, + exit, + Event, + Any, Callable, Iterable, Optional, Tuple, FrameType, ModuleType, + Namespace, ArgumentParser, + perf_counter_ns as time, + TextIOWrapper, + Processed_Line, Token_List, + Tokenizer, + load_config, + panic, + Scope, + Transpiler, + FileMode, format_file_contents, + color_print as print, +) __version__: str = "0.1.0-alpha.a" USE_CACHE: bool = False @@ -222,6 +226,36 @@ def watch_processes() -> None: del ThreadedProcess.__processes_queue__[pid] +def clean_docstring(docstring: str) -> str: + """ + Cleans up the given docstring by removing unnecessary whitespace and newlines. + + Parameters + ---------- + docstring : str + The docstring to be cleaned. + + Returns + ------- + str + The cleaned docstring. + """ + if not docstring: + return "" + + indentation_level: int = 0 + for char in docstring.splitlines()[1]: + if not char.isspace(): + break + indentation_level += 1 + + return "\n".join( + [ + line[indentation_level:] + for line in docstring.splitlines() + ] + ) + class ThreadedProcess: """ Manages threaded execution of processes. @@ -336,8 +370,8 @@ class ArgParser: Returns the namespace of parsed command-line arguments. """ def help_screen(self): - print( - """usage: helix [-h] [-v] [-o COMPILE] [-d] [-l LOG] [-c CONFIG] [-s] file ... + print(clean_docstring(""" + usage: helix [-h] [-v] [-o COMPILE] [-d] [-l LOG] [-c CONFIG] [-s] file ... Welcome to the Helix CLI, the gateway to harnessing the power and simplicity of Helix, a programming language designed for developers who cherish Python's ease but crave more @@ -361,7 +395,7 @@ def help_screen(self): -i, --install PACKAGE_NAME install new packages -u, --uninstall PACKAGE_NAME uninstall packages -doc DOC the name of the documentation page to be displayed - """, + """), word_wrap=False, end="", ) @@ -917,6 +951,25 @@ def run(self) -> None: ) self.timer.start("run") + #_locals = {} + #_globals = {} + #try: + # exec( + # compile( + # open(self.__out_file__).read(), + # self.__out_file__, + # "exec", + # ), + # _globals, + # _locals, + # ) + #except Exception as e: + # panic( + # "THIS NEEDS TO BE CHANGED TO A CUSTOM EXCEPTION", + # file=self.__out_file__, + # line_no=1, + # no_lines=True, + # ) try: subprocess.Popen( [sys.executable, self.__out_file__] @@ -1237,7 +1290,7 @@ def exception_handler(exception_type: type[BaseException] | threading.ExceptHook current_exception = exception relevant_frames = [] - early_replacements = dict((v, k) for k, v in {EARLY_REPLACEMENTS}.items()) + early_replacements = dict((v, k) for k, v in {base.EARLY_REPLACEMENTS}.items()) # First loop: filter out irrelevant frames index = 0 @@ -1488,14 +1541,16 @@ def __hook_import__( os.path.join(".helix", "config.toml"), profile=True, ) - Helix.__hook_import__("syntax/test.hlx") + #Helix.__hook_import__("syntax/test.hlx") # from test_hlx import subtract # subtract(5, 3) # Helix.REPL() finally: - if POOL.is_alive: - POOL.close() - + if base.POOL.is_alive: + base.POOL.close() + + print("Memory Usage: ", tracemalloc.get_traced_memory()[1] / 10**6, "MB") + gc.collect(0) gc.collect(1) gc.collect(2) diff --git a/init b/init index 079178c..608435f 100644 --- a/init +++ b/init @@ -5,20 +5,27 @@ command_exists () { type "$1" &> /dev/null ; } -# Clone the repository -git clone https://github.com/kneorain/helix -cd helix/helix-lang +# make sure python version is 3.12 or higher # Python execution logic -if command_exists python3 ; then - PYTHON_CMD=python3 -elif command_exists python ; then +if command_exists python ; then PYTHON_CMD=python +elif command_exists python3 ; then + PYTHON_CMD=python3 else echo "Python is not installed or not found in PATH" exit 1 fi +echo "Using Python command: $PYTHON_CMD" + +version = $("$PYTHON_CMD --version") + +if [[ "$version" < "3.12" ]]; then + echo "Python version is too low. Please install Python 3.12 or higher." + exit 1 +fi + # Creating a virtual environment $PYTHON_CMD -m venv .venv diff --git a/out/helix.pyi b/out/helix.pyi deleted file mode 100644 index 7ec5e95..0000000 --- a/out/helix.pyi +++ /dev/null @@ -1,102 +0,0 @@ -import threading -from _typeshed import Incomplete -from argparse import Namespace -from classes.Scope import Scope -from classes.Token import Processed_Line as Processed_Line, Token_List as Token_List -from types import ModuleType -from typing import Any, Callable, Iterable, Optional - -__version__: str -USE_CACHE: bool -bar_thread: Incomplete - -class Hashing: - def __init__(self, file_path: str, output_path: str) -> None: ... - def __int__(self) -> int: ... - @staticmethod - def compute_hash(code: str) -> bytes: ... - def create_hash_only(self) -> None: ... - @staticmethod - def get_mount(path): ... - def create_file(self, code: str) -> None: ... - def is_code_altered(self) -> bool: ... - def get_hash(self) -> bytes | None: ... - -def watch_processes() -> None: ... - -class ThreadedProcess: - __processes_queue__: dict[int, threading.Thread] - def __new__(cls, func: Callable[..., None]): ... - __func__: Incomplete - def __init__(self, func: Callable[..., None]) -> None: ... - __pid__: Incomplete - __thread__: Incomplete - def __call__(self, *args, **kwargs) -> None: ... - @property - def processes(self) -> dict[int, threading.Thread]: ... - -class ArgParser: - def help_screen(self) -> None: ... - def version_screen(self) -> None: ... - __args__: Incomplete - def __init__(self, argv: Optional[Iterable[str]] = None) -> None: ... - @property - def args(self) -> Namespace: ... - -class HelixLanguage: - def __init__(self, *args: str, **kwargs: str) -> None: ... - @staticmethod - def make_folder(directory: str) -> None: ... - @staticmethod - def make_file(file: str) -> None: ... - @staticmethod - def generate_folder_structure(directory: str = ...): ... - @staticmethod - def install_helix(config: dict) -> None: ... - -class Timer: - def __init__(self) -> None: ... - def start(self, name: str) -> None: ... - def end(self, name: str) -> None: ... - def get_time(self, name: str) -> float: ... - def decorator(self, func: Callable) -> Callable: ... - -class DisabledKeyboardInterrupt: - signal_received: Incomplete - old_handler: Incomplete - def __enter__(self) -> None: ... - def handler(self, sig: int, frame: Any) -> None: ... - def __exit__(self, type: Any, value: Any, traceback: Any) -> None: ... - -class Helix: - config: Namespace - @classmethod - def interpreter(cls, code: str, globals_: dict, locals_: dict) -> str: ... - def build_path(self) -> str: ... - def remove_blank_lines(self, file: str, hash: Hashing | None) -> None: ... - def __exit__(self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: types.TracebackType | None) -> None: ... - def __del__(self) -> None: ... - def __delattr__(self, name) -> None: ... - profile: Incomplete - import_: Incomplete - timer: Incomplete - __config_file__: Incomplete - __args__: Incomplete - __argv__: Incomplete - __format_out__: bool - __out_file__: Incomplete - __file_hash__: Incomplete - def __init__(self, conf_file: Optional[str] = None, *args: str, profile: bool = False, import_: bool = False) -> None: ... - @classmethod - def factory(cls, config_file: str, *args: str, **kwargs: Any) -> None: ... - def run(self) -> None: ... - def cleanup(self) -> None: ... - def compile_file(self, file: Optional[str] = None) -> Scope: ... - def transpile(self, file: Optional[str] = None) -> tuple[Scope, list[Processed_Line]]: ... - def generate_line_numbers(self, transpiled: list[Processed_Line]) -> str: ... - def generate_source_code(self, scope_parsed: Scope, transpiled_lines: list[Processed_Line], format_source: bool = False, is_main: bool = True, no_inject: bool = False) -> str: ... - def inject_core(self, code: Optional[str] = None, is_main: bool = True) -> str: ... - @staticmethod - def REPL() -> None: ... - @classmethod - def __hook_import__(cls, file: str, *args: str, config_file: Optional[str] = None, **kwargs: Any) -> ModuleType: ... diff --git a/core/better_print.py b/src/better_print.py similarity index 97% rename from core/better_print.py rename to src/better_print.py index 59dad0f..8c97258 100644 --- a/core/better_print.py +++ b/src/better_print.py @@ -123,16 +123,17 @@ def _process_bg_color(bg: str) -> str: Returns: str: the background color as a unicode escape sequence """ - + bg_list: list[str] = [] + if not bg.startswith('rgb('): try: bg = BG_COLORS[bg.lower().strip()] except KeyError: raise ValueError('Invalid color ' + str(bg).strip()) else: - bg = bg.split('rgb')[1].split('(')[1].split(')')[0].split(',') - if len(bg) != 3 or not isdigit(bg) or any([int(i.strip()) > 255 for i in bg]): - raise ValueError('Invalid rgb color ' + str(bg)) - for index, i in enumerate(bg): bg[index] = int(i.strip()) - bg = _make_bg_color(bg[0], bg[1], bg[2]) + bg_list = bg_list.split('rgb')[1].split('(')[1].split(')')[0].split(',') + if len(bg_list) != 3 or not isdigit(bg_list) or any([int(i.strip()) > 255 for i in bg_list]): + raise ValueError('Invalid rgb color ' + str(bg_list)) + for index, i in enumerate(bg_list): bg_list[index] = int(i.strip()) + bg = _make_bg_color(bg_list[0], bg_list[1], bg_list[2]) return bg def _process_style(color: list[str]) -> str: """Processes the color and style and returns the unicode escape sequence diff --git a/core/cache_store.py b/src/cache_store.py similarity index 79% rename from core/cache_store.py rename to src/cache_store.py index 72727b4..b9ee8c6 100644 --- a/core/cache_store.py +++ b/src/cache_store.py @@ -1,16 +1,18 @@ DISABLED: bool = False -from os import (path as os_path, mkdir) -from pickle import dump, load -from threading import Thread -from functools import wraps -from typing import Callable, Tuple, Union +from src.core.imports import ( + dump, load, + wraps, + Callable, Tuple, Union, + lru_cache, + os, +) -CACHE_DIR: str = os_path.join(os_path.dirname(os_path.dirname(__file__)), "cache") +CACHE_DIR: str = os.path.join(os.path.dirname(os.path.dirname(__file__)), "cache") local_cache: dict[str, any] = {} -if not os_path.isdir(CACHE_DIR): - mkdir(CACHE_DIR) +if not os.path.isdir(CACHE_DIR): + os.mkdir(CACHE_DIR) def async_cache(path: str, args: tuple, result: any) -> None: global local_cache @@ -22,7 +24,7 @@ def async_cache(path: str, args: tuple, result: any) -> None: def get_cache(path: str, args: tuple) -> Union[any, None]: global local_cache - if os_path.isfile(path): + if os.path.isfile(path): with open(path, "rb") as file: try: local_cache = load(file) @@ -32,7 +34,6 @@ def get_cache(path: str, args: tuple) -> Union[any, None]: return None -from functools import lru_cache def cache(func: Callable) -> Callable: return lru_cache(maxsize=None)(func) @@ -43,7 +44,7 @@ def wrapper(*args: Tuple[any, ...], **kwargs: dict[str, any]) -> any: global local_cache - cache_file_path: str = os_path.join(CACHE_DIR, f"{func.__name__}.cache") + cache_file_path: str = os.path.join(CACHE_DIR, f"{func.__name__}.cache") if args in local_cache: return local_cache[args] diff --git a/classes/Scope.py b/src/classes/Scope.py similarity index 79% rename from classes/Scope.py rename to src/classes/Scope.py index 5aca152..b7d784a 100644 --- a/classes/Scope.py +++ b/src/classes/Scope.py @@ -1,12 +1,11 @@ -from concurrent.futures import Future -from dataclasses import dataclass -from threading import Thread -from time import time -from typing import Any, Optional -from core.cache_store import cache -from core.panic import panic -from classes.Token import Token_List, Token -import globals +import src.core.base as base +from src.core.imports import ( + Optional, + Token_List, + Token, + cache, + Any, +) class Scope: name: str | Token_List @@ -97,7 +96,7 @@ def contains(cls, line: Token_List | tuple[str, ...], keys: tuple): @classmethod def get_match(cls, line: Token_List, keys: Optional[tuple] = None, depth: int = 0) -> Optional[str]: - all_keywords = tuple(globals.KEYWORDS.keys()) if not keys else keys + all_keywords = tuple(base.KEYWORDS.keys()) if not keys else keys matches = [ast.token for ast in line if ast.token in all_keywords] if len(matches) >= depth + 1: return matches[depth] @@ -114,8 +113,8 @@ def process_scope_from_scope(cls, scope: 'Scope') -> 'Scope': in_scope = False for index in range(len(scope.children)): - if not in_scope and cls.contains(scope.children[index], globals.NAMESPACED_KEYWORD.keys()) and temp_scope.indent_level != scope.children[index].indent_level: - new_scope = Scope(scope.children[index], globals.NAMESPACED_KEYWORD[cls.get_match(scope.children[index], globals.NAMESPACED_KEYWORD.keys())], [scope.children[index]], scope.children[index].indent_level) + if not in_scope and cls.contains(scope.children[index], base.NAMESPACED_KEYWORD.keys()) and temp_scope.indent_level != scope.children[index].indent_level: + new_scope = Scope(scope.children[index], base.NAMESPACED_KEYWORD[cls.get_match(scope.children[index], base.NAMESPACED_KEYWORD.keys())], [scope.children[index]], scope.children[index].indent_level) new_scope.namespace_header = scope.children[index] in_scope = True continue @@ -124,8 +123,8 @@ def process_scope_from_scope(cls, scope: 'Scope') -> 'Scope': temp_scope.append_child(new_scope) new_scope = None in_scope = False - if cls.contains(scope.children[index], globals.NAMESPACED_KEYWORD.keys()): - new_scope = Scope(scope.children[index], globals.NAMESPACED_KEYWORD[cls.get_match(scope.children[index], globals.NAMESPACED_KEYWORD.keys())], [scope.children[index]], scope.children[index].indent_level) + if cls.contains(scope.children[index], base.NAMESPACED_KEYWORD.keys()): + new_scope = Scope(scope.children[index], base.NAMESPACED_KEYWORD[cls.get_match(scope.children[index], base.NAMESPACED_KEYWORD.keys())], [scope.children[index]], scope.children[index].indent_level) new_scope.namespace_header = scope.children[index] in_scope = True continue @@ -148,8 +147,8 @@ def process_from_lines(cls, lines: tuple[Token_List, ...]) -> 'Scope': in_scope = False for index in range(len(lines)): - if not in_scope and cls.contains(lines[index], globals.NAMESPACED_KEYWORD.keys()): - new_scope = Scope(lines[index], globals.NAMESPACED_KEYWORD[cls.get_match(lines[index], globals.NAMESPACED_KEYWORD.keys())], [lines[index]], lines[index].indent_level) + if not in_scope and cls.contains(lines[index], base.NAMESPACED_KEYWORD.keys()): + new_scope = Scope(lines[index], base.NAMESPACED_KEYWORD[cls.get_match(lines[index], base.NAMESPACED_KEYWORD.keys())], [lines[index]], lines[index].indent_level) new_scope.namespace_header = lines[index] in_scope = True continue @@ -158,8 +157,8 @@ def process_from_lines(cls, lines: tuple[Token_List, ...]) -> 'Scope': root_scope.append_child(new_scope) new_scope = None in_scope = False - if cls.contains(lines[index], globals.NAMESPACED_KEYWORD.keys()): - new_scope = Scope(lines[index], globals.NAMESPACED_KEYWORD[cls.get_match(lines[index], globals.NAMESPACED_KEYWORD.keys())], [lines[index]], lines[index].indent_level) + if cls.contains(lines[index], base.NAMESPACED_KEYWORD.keys()): + new_scope = Scope(lines[index], base.NAMESPACED_KEYWORD[cls.get_match(lines[index], base.NAMESPACED_KEYWORD.keys())], [lines[index]], lines[index].indent_level) new_scope.namespace_header = lines[index] in_scope = True continue @@ -177,4 +176,4 @@ def process_from_lines(cls, lines: tuple[Token_List, ...]) -> 'Scope': @cache def get_keyword(self, internal_name: str) -> str: - return next((keyword for keyword in globals.KEYWORDS if globals.KEYWORDS[keyword]["internal_name"] == internal_name), None) \ No newline at end of file + return next((keyword for keyword in base.KEYWORDS if base.KEYWORDS[keyword]["internal_name"] == internal_name), None) \ No newline at end of file diff --git a/classes/Token.py b/src/classes/Token.py similarity index 99% rename from classes/Token.py rename to src/classes/Token.py index 5d4303f..0356744 100644 --- a/classes/Token.py +++ b/src/classes/Token.py @@ -1,8 +1,10 @@ from __future__ import annotations -import json -from typing import Iterable, Iterator, override - -from multimethod import subtype +from src.core.imports import ( + json, + subtype, + Iterable, + Iterator, +) class Token: _: str = "Helix Token" diff --git a/classes/Transpiler.py b/src/classes/Transpiler.py similarity index 84% rename from classes/Transpiler.py rename to src/classes/Transpiler.py index c43face..08b9599 100644 --- a/classes/Transpiler.py +++ b/src/classes/Transpiler.py @@ -1,16 +1,14 @@ -from concurrent.futures import ThreadPoolExecutor -from logging import root -from typing import Callable, Optional - -from classes.Scope import Scope -from classes.Token import Processed_Line, Token_List -from core.config import load_config -from functions._unmarked import _unmarked -import globals -from core.better_print import color_print - - -INDENT_CHAR = load_config().Formatter["indent_char"] +import src.core.base as base +from src.functions._unmarked import _unmarked +from src.core.imports import ( + Callable, + Optional, + Scope, + Processed_Line, + Token_List, + color_print, + INDENT_CHAR, +) class Transpiler: @@ -27,10 +25,10 @@ def parse_non_keyword(self, line: Token_List, *_: Scope) -> str: return _unmarked(line, self.scope_stack[-1] if len(self.scope_stack) >= 1 else self.root_scope, self.scope_stack[-2] if len(self.scope_stack) >= 2 else self.root_scope, self.root_scope, self.ignore_main) def get_match_function(self, child: Token_List) -> Callable[[Token_List, Optional[Scope], Optional[Scope], Scope], Processed_Line]: - match = Scope.get_match(child, tuple(globals.KEYWORDS.keys())) + match = Scope.get_match(child, tuple(base.KEYWORDS.keys())) if match: - return globals.KEYWORDS[match]["parser"] + return base.KEYWORDS[match]["parser"] else: return self.parse_non_keyword @@ -79,8 +77,8 @@ def transpile(self, root_scope: Scope, ignore_main: bool = False): self.ignore_main = ignore_main self.root_scope.transpiler_instance = self - if globals.USE_POOL: - globals.POOL.map(self.__transpile, root_scope.children, chunksize=6) + if base.USE_POOL: + base.POOL.map(self.__transpile, root_scope.children, chunksize=6) else: [self.__transpile(child) for child in root_scope.children] diff --git a/classes/WorkerPool.py b/src/classes/WorkerPool.py similarity index 99% rename from classes/WorkerPool.py rename to src/classes/WorkerPool.py index e31cdfc..5d6c08f 100644 --- a/classes/WorkerPool.py +++ b/src/classes/WorkerPool.py @@ -3,7 +3,6 @@ ProcessPoolExecutor as ProcessPool, ThreadPoolExecutor as ThreadPool, ) -import multiprocessing from typing import ( Literal, diff --git a/core/compile_bar.py b/src/compile_bar.py similarity index 95% rename from core/compile_bar.py rename to src/compile_bar.py index 10e602b..6dc9799 100644 --- a/core/compile_bar.py +++ b/src/compile_bar.py @@ -1,4 +1,4 @@ -from globals import ASYNC +import src.core.base as base # get the signal int to see when the program ends import signal @@ -19,7 +19,7 @@ def exponential_decay_generator(current, base_sleep=0.01): x = current / MAX return base_sleep - (base_sleep * math.exp(-b * x)) -@ASYNC +@base.ASYNC def show_bar(event: Event): global current while current < MAX and not event.is_set(): diff --git a/core/config.py b/src/config.py similarity index 91% rename from core/config.py rename to src/config.py index c2673c3..c35d131 100644 --- a/core/config.py +++ b/src/config.py @@ -1,7 +1,9 @@ -import os -import toml -from argparse import Namespace -from core.panic import panic +from src.core.imports import ( + os, + toml, + Namespace, + panic, +) CACHE: dict[str, Namespace] = {} CONFIG_PATH = ".helix/config.toml" diff --git a/globals.py b/src/core/base.py similarity index 93% rename from globals.py rename to src/core/base.py index 7b1e000..474e9a5 100644 --- a/globals.py +++ b/src/core/base.py @@ -1,20 +1,52 @@ -import re -from sys import stdout as sys_stdout -from threading import Thread -from types import MappingProxyType as map -from typing import Callable, Iterable, Optional - -from classes.Token import Processed_Line, Token_List -from classes.WorkerPool import WorkerPool -from functions._class import _class -from functions._for import _for -from functions._functions import function as _function -from functions._include import include as _include -from functions._let import _let -from functions._match import _match -from functions._unless import _unless -from enum import Enum, unique +from src.core.imports import ( + re, + map, + enum, + Thread, + Callable, + Iterable, + Optional, + Token_List, + WorkerPool, + Processed_Line, + + _unless, + _for, + _match, + _function, + _class, + _let, + _include, + file_cache, + +) +# All Primitive Types +# int; +# string; +# float; +# map; +# list; +# bool; +# char; +# void; +# tuple; +# array; +# set; +# +# u8; +# u16; +# u32; +# u64; +# u128; +# i8; +# i16; +# i32; +# i64; +# i128; +# f32; +# f64; +# f128; def dummy( line: Token_List, @@ -24,7 +56,7 @@ def dummy( ) -> Processed_Line: return Processed_Line( " " * line.indent_level - + " ".join([_.token for _ in line]), + + " ".join([str(_.token) for _ in line]), line, ) @@ -32,7 +64,7 @@ def dummy( def _no_change(line: Token_List, *args) -> Processed_Line: return Processed_Line( " " * line.indent_level - + " ".join([_.token for _ in line]), + + " ".join([str(_.token) for _ in line]), line, ) @@ -80,215 +112,187 @@ def _no_change(line: Token_List, *args) -> Processed_Line: r"\?\=", # ?= ] -# All Primitive Types -# int; -# string; -# float; -# map; -# list; -# bool; -# char; -# void; -# tuple; -# array; -# set; -# -# u8; -# u16; -# u32; -# u64; -# u128; -# i8; -# i16; -# i32; -# i64; -# i128; -# f32; -# f64; -# f128; - - -@unique -class ERROR_CODES(Enum): +@enum.unique +class ERROR_CODES(enum.Enum): # Command-Line Interface Errors CLI_ARGUMENT_INVALID = ( - "[HEX-001]", + "HEX-001", "Invalid command-line argument: {argument}", ValueError, ) CLI_FILE_NOT_FOUND = ( - "[HEX-002]", + "HEX-002", "Input file not found: {filename}", FileNotFoundError, ) CLI_OPTION_UNSUPPORTED = ( - "[HEX-003]", + "HEX-003", "Unsupported command-line option: {option}", ValueError, ) # Syntax Errors SYNTAX_UNEXPECTED_TOKEN = ( - "[HEX-100]", + "HEX-100", "Unexpected token in source code: {token}", SyntaxError, ) SYNTAX_INVALID_SYNTAX = ( - "[HEX-101]", + "HEX-101", "General syntax error at {location}", SyntaxError, ) SYNTAX_MISSING_SEMICOLON = ( - "[HEX-102]", + "HEX-102", "Missing semicolon at end of statement", SyntaxError, ) SYNTAX_UNBALANCED_PARENTHESIS = ( - "[HEX-103]", + "HEX-103", "Unbalanced parenthesis", SyntaxError, ) SYNTAX_INVALID_LITERAL = ( - "[HEX-104]", + "HEX-104", "Invalid literal: {literal}", ValueError, ) SYNTAX_UNSUPPORTED_SYNTAX = ( - "[HEX-105]", + "HEX-105", "Unsupported syntax in Helix: {syntax}", SyntaxError, ) # Type and Declaration Errors TYPE_INVALID_CAST = ( - "[HEX-200]", + "HEX-200", "Invalid type cast: {details}", TypeError, ) TYPE_UNDECLARED_VARIABLE = ( - "[HEX-201]", + "HEX-201", "Use of undeclared variable: {variable}", NameError, ) TYPE_MISMATCH = ( - "[HEX-202]", + "HEX-202", "Type mismatch in expression: {expression}", TypeError, ) TYPE_REDECLARATION = ( - "[HEX-203]", + "HEX-203", "Redeclaration of a variable or function: {identifier}", SyntaxError, ) # Semantic Errors SEMANTIC_UNRESOLVED_REFERENCE = ( - "[HEX-300]", + "HEX-300", "Unresolved reference: {reference}", NameError, ) SEMANTIC_ARGUMENT_MISMATCH = ( - "[HEX-301]", + "HEX-301", "Function argument mismatch in {function}", TypeError, ) SEMANTIC_INFINITE_LOOP_DETECTED = ( - "[HEX-302]", + "HEX-302", "Potential infinite loop detected", RuntimeError, ) SEMANTIC_INVALID_OPERATION = ( - "[HEX-303]", + "HEX-303", "Invalid operation: {operation}", ValueError, ) # Linking and Dependency Errors LINKING_FAILED = ( - "[HEX-400]", + "HEX-400", "Linking failed: {details}", ImportError, ) DEPENDENCY_NOT_FOUND = ( - "[HEX-401]", + "HEX-401", "Dependency not found: {dependency}", ImportError, ) DEPENDENCY_CONFLICT = ( - "[HEX-402]", + "HEX-402", "Dependency version conflict: {details}", ImportError, ) # File and I/O Errors FILE_READ_ERROR = ( - "[HEX-500]", + "HEX-500", "Error reading file: {filename}", IOError, ) FILE_WRITE_ERROR = ( - "[HEX-501]", + "HEX-501", "Error writing file: {filename}", IOError, ) FILE_FORMAT_UNSUPPORTED = ( - "[HEX-502]", + "HEX-502", "Unsupported file format: {format}", ValueError, ) IO_PERMISSION_DENIED = ( - "[HEX-503]", + "HEX-503", "Permission denied for file operation: {filename}", PermissionError, ) # Resource and Memory Errors RESOURCE_LIMIT_EXCEEDED = ( - "[HEX-600]", + "HEX-600", "Resource limit exceeded: {resource}", MemoryError, ) MEMORY_ALLOCATION_ERROR = ( - "[HEX-601]", + "HEX-601", "Memory allocation error", MemoryError, ) RESOURCE_LEAK_DETECTED = ( - "[HEX-602]", + "HEX-602", "Resource leak detected: {resource}", ResourceWarning, ) # Environment and System Errors SYSTEM_ERROR = ( - "[HEX-700]", + "HEX-700", "System error encountered: {details}", SystemError, ) ENVIRONMENT_VARIABLE_NOT_FOUND = ( - "[HEX-701]", + "HEX-701", "Environment variable not found: {variable}", EnvironmentError, ) UNSUPPORTED_PLATFORM = ( - "[HEX-702]", + "HEX-702", "Unsupported operating system or platform: {platform}", OSError, ) # Miscellaneous Errors INTERNAL_COMPILER_ERROR = ( - "[HEX-800]", + "HEX-800", "Internal compiler error: {details}", RuntimeError, ) FEATURE_NOT_IMPLEMENTED = ( - "[HEX-801]", + "HEX-801", "Feature not yet implemented: {feature}", NotImplementedError, ) UNEXPECTED_ERROR = ( - "[HEX-802]", + "HEX-802", "Unexpected error occurred: {details}", RuntimeError, ) @@ -584,9 +588,6 @@ def replace_primitive( CHAR = r"'.*'" INDENT_CHAR = " " -from core.cache_store import file_cache - - @file_cache def find_keyword(internal_name: str) -> str: return [ diff --git a/src/core/framework.py b/src/core/framework.py new file mode 100644 index 0000000..e69de29 diff --git a/src/core/imports.py b/src/core/imports.py new file mode 100644 index 0000000..d9d5ad9 --- /dev/null +++ b/src/core/imports.py @@ -0,0 +1,110 @@ +import enum +import re +import os +import sys +import signal +import shutil +import hashlib +import threading +import subprocess +import functools +import json +import toml + +from sys import exit +from io import TextIOWrapper +from pickle import ( + dump, + load +) +from functools import ( + wraps, + lru_cache +) +from argparse import ( + Namespace, + ArgumentParser +) + +from threading import ( + Thread, + Event, + Lock, +) + +from typing import ( + Any, + Optional, + Union, + Tuple, + Mapping, + Type, + TypeVar, + Generic, + Callable, + Iterable, + Iterator, + Sequence, + Protocol, +) + +from concurrent.futures import ( + Future, + ThreadPoolExecutor, + ProcessPoolExecutor +) +from multimethod import subtype +from black import FileMode, format_file_contents +from dataclasses import dataclass +from datetime import datetime +from time import ( + time, + sleep, + perf_counter, + perf_counter_ns, + process_time, +) + +from types import ( + MappingProxyType as map, + UnionType, + FunctionType, + MethodType, + FrameType, + ModuleType, +) + +from src.panic import panic +from src.better_print import color_print +from src.config import load_config +from src.cache_store import ( + cache, + file_cache +) + +from src.token.normalize_tokens import normalize_tokens +from src.token.remove_comments import remove_comment +from src.token.tokenize_file import Tokenizer +from src.token.tokenize_line import tokenize_line + +INDENT_CHAR = load_config().Formatter["indent_char"] +re = __import__(load_config().Transpiler["regex_module"]) + +from src.classes.WorkerPool import WorkerPool +from src.classes.Token import ( + Processed_Line, + Token_List, + Token, +) +from src.classes.Scope import Scope +from src.classes.Transpiler import Transpiler + + +from src.functions._class import _class +from src.functions._for import _for +from src.functions._functions import _function +from src.functions._include import _include +from src.functions._let import _let +from src.functions._match import _match +from src.functions._unless import _unless +from src.functions._unmarked import _unmarked diff --git a/src/core/utils.py b/src/core/utils.py new file mode 100644 index 0000000..e69de29 diff --git a/functions/_class.py b/src/functions/_class.py similarity index 96% rename from functions/_class.py rename to src/functions/_class.py index c2ecfb5..85b0195 100644 --- a/functions/_class.py +++ b/src/functions/_class.py @@ -1,10 +1,11 @@ -from classes.Token import Processed_Line, Token, Token_List -from core.config import load_config - -INDENT_CHAR = load_config().Formatter["indent_char"] -re = __import__(load_config().Transpiler["regex_module"]) - -from core.panic import panic +from src.core.imports import ( + Processed_Line, + Token, + Token_List, + panic, + INDENT_CHAR, + re, +) CLASS_EXTENSION = "::" SEPARATOR_FOR_CLASSES = "+" @@ -15,7 +16,6 @@ def generate_default_code(indent_chars: str, class_name) -> str: {indent_chars} raise NotImplementedError("Define an __init__ method for this class with the function signature new(self: Any, inst_class: '{class_name}')") """ - def _class(ast_list: Token_List, current_scope, parent_scope, root_scope, modifiers=None) -> Processed_Line: data_structure_types = ( parent_scope.get_keyword("INTERFACE"), diff --git a/functions/_for.py b/src/functions/_for.py similarity index 80% rename from functions/_for.py rename to src/functions/_for.py index 4a9d133..1d72d44 100644 --- a/functions/_for.py +++ b/src/functions/_for.py @@ -1,16 +1,15 @@ # THIS TOOK ME 2 DAYS TO WRITE, I'M SO PROUD OF MYSELF -import classes.Transpiler as Transpiler -import globals -from classes.Scope import Scope -from classes.Token import Processed_Line, Token, Token_List -from core.cache_store import cache -from core.config import load_config - -INDENT_CHAR = load_config().Formatter["indent_char"] -re = __import__(load_config().Transpiler["regex_module"]) - -from core.panic import panic - +import src.core.base as base +from src.core.imports import ( + Scope, + Processed_Line, + Token, + Token_List, + cache, + panic, + INDENT_CHAR, + re, +) def _for(ast_list: Token_List, current_scope: Scope, parent_scope: Scope, root_scope: Scope, modifiers=None) -> Processed_Line: output = "" @@ -59,17 +58,17 @@ def process_init_statement(init_statement: Token_List) -> dict: def extract_variables(index: int, token: Token) -> None: nonlocal current_var_name, in_generic, generic_count, current_var_type, current_var_value, current_var_unsafe, current_var_discard, expecting_type, expecting_value, excepting_name - if token in [globals.find_keyword("LET"), globals.find_keyword("VAR"), globals.find_keyword("UNSAFE")]: + if token in [base.find_keyword("LET"), base.find_keyword("VAR"), base.find_keyword("UNSAFE")]: if expecting_value: excepting_name = True expecting_value = False processed_decls[stack[-1]]["value"] = current_var_value.strip()[:-2] current_var_value = "" - current_var_unsafe = token == globals.find_keyword("UNSAFE") or init_statement[index-1] == globals.find_keyword("UNSAFE") + current_var_unsafe = token == base.find_keyword("UNSAFE") or init_statement[index-1] == base.find_keyword("UNSAFE") - current_var_discard = not (token == globals.find_keyword("LET")) - current_var_discard = not (token == globals.find_keyword("LET") or init_statement[index+1] == globals.find_keyword("LET")) + current_var_discard = not (token == base.find_keyword("LET")) + current_var_discard = not (token == base.find_keyword("LET") or init_statement[index+1] == base.find_keyword("LET")) excepting_name = True return @@ -80,7 +79,7 @@ def extract_variables(index: int, token: Token) -> None: processed_decls[current_var_name.strip()] = { "type": current_var_type.strip(), "value": current_var_value.strip(), - globals.find_keyword("UNSAFE"): current_var_unsafe, + base.find_keyword("UNSAFE"): current_var_unsafe, "discard": current_var_discard } current_var_name = "" @@ -92,7 +91,7 @@ def extract_variables(index: int, token: Token) -> None: processed_decls[current_var_name.strip()] = { "type": current_var_type.strip(), "value": current_var_value.strip(), - globals.find_keyword("UNSAFE"): current_var_unsafe, + base.find_keyword("UNSAFE"): current_var_unsafe, "discard": current_var_discard } current_var_name = "" @@ -115,11 +114,11 @@ def extract_variables(index: int, token: Token) -> None: expecting_type = False for _name in stack: processed_decls[_name] = { - "type": processed_decls[_name]["type"] if processed_decls[_name]["type"] != '' else current_var_type.strip(), + "type": processed_decls[_name]['type'] if processed_decls[_name]['type'] != '' else current_var_type.strip(), "value": processed_decls[_name]["value"] if processed_decls[_name]["value"] != '' else current_var_value.strip(), - globals.find_keyword("UNSAFE"): processed_decls[_name][globals.find_keyword("UNSAFE")], + base.find_keyword("UNSAFE"): processed_decls[_name][base.find_keyword("UNSAFE")], "discard": processed_decls[_name]["discard"] - } if processed_decls[_name]["type"] == "" and processed_decls[_name]["value"] == "" else processed_decls[_name] + } if processed_decls[_name]['type'] == "" and processed_decls[_name]["value"] == "" else processed_decls[_name] current_var_type = "" return if token == ",": @@ -128,7 +127,7 @@ def extract_variables(index: int, token: Token) -> None: processed_decls[stack[-1]] = { "type": current_var_type.strip(), "value": current_var_value.strip(), - globals.find_keyword("UNSAFE"): current_var_unsafe, + base.find_keyword("UNSAFE"): current_var_unsafe, "discard": current_var_discard } current_var_type = "" @@ -149,36 +148,36 @@ def extract_variables(index: int, token: Token) -> None: [extract_variables(index, token) for index, token in enumerate(init_statement)] if expecting_type: - processed_decls[stack[-1]]["type"] = current_var_type.strip() + processed_decls[stack[-1]]['type'] = current_var_type.strip() if expecting_value: processed_decls[stack[-1]]["value"] = current_var_value.strip() def re_process_stack(_name: str, processed_decls: dict[str, dict[str, str]]) -> dict[str, dict[str, str]]: if processed_decls[_name]["value"] == "": - if processed_decls[_name]["type"].endswith("?"): - processed_decls[_name]["type"] = processed_decls[_name]["type"][:-1].strip() - processed_decls[_name]["value"] = f"{processed_decls[_name]["type"]}(None)" - elif processed_decls[_name]["type"] != "": - processed_decls[_name]["value"] = f"{processed_decls[_name]["type"]}()" + if processed_decls[_name]['type'].endswith("?"): + processed_decls[_name]['type'] = processed_decls[_name]['type'][:-1].strip() + processed_decls[_name]["value"] = f"{processed_decls[_name]['type']}(None)" + elif processed_decls[_name]['type'] != "": + processed_decls[_name]["value"] = f"{processed_decls[_name]['type']}()" else: # set the type to the type of the next non empty type for __name in reversed(stack): - if processed_decls[__name]["type"] != "": - processed_decls[_name]["value"] = f"{processed_decls[__name]["type"]}()" if not processed_decls[__name]["type"].endswith("?") else f"{processed_decls[__name]["type"][:-1].strip()}(None)" - processed_decls[_name]["type"] = processed_decls[__name]["type"] + if processed_decls[__name]['type'] != "": + processed_decls[_name]["value"] = f"{processed_decls[__name]['type']}()" if not processed_decls[__name]['type'].endswith("?") else f"{processed_decls[__name]['type'][:-1].strip()}(None)" + processed_decls[_name]['type'] = processed_decls[__name]['type'] break else: - if processed_decls[_name]["type"].endswith("?"): - processed_decls[_name]["type"] = processed_decls[_name]["type"][:-1].strip() - processed_decls[_name]["value"] = f"{processed_decls[_name]["type"]}(None)" if processed_decls[_name]["value"] == "" else f"{processed_decls[_name]["type"]}({processed_decls[_name]['value']})" - elif processed_decls[_name]["type"] != "": - processed_decls[_name]["value"] = f"{processed_decls[_name]["type"]}({processed_decls[_name]['value']})" + if processed_decls[_name]['type'].endswith("?"): + processed_decls[_name]['type'] = processed_decls[_name]['type'][:-1].strip() + processed_decls[_name]["value"] = f"{processed_decls[_name]['type']}(None)" if processed_decls[_name]["value"] == "" else f"{processed_decls[_name]['type']}({processed_decls[_name]['value']})" + elif processed_decls[_name]['type'] != "": + processed_decls[_name]["value"] = f"{processed_decls[_name]['type']}({processed_decls[_name]['value']})" [re_process_stack(_name, processed_decls) for _name in stack] return processed_decls - if len(init_statement) > 1 and init_statement[0].token in (globals.find_keyword("LET"), globals.find_keyword("VAR"), globals.find_keyword("UNSAFE")): + if len(init_statement) > 1 and init_statement[0].token in (base.find_keyword("LET"), base.find_keyword("VAR"), base.find_keyword("UNSAFE")): declarations = process_init_statement(init_statement) # if any vars need to be discarded if any([declarations[_name]["discard"] for _name in declarations]): @@ -262,11 +261,11 @@ def process_init_statement(init_statement: Token_List) -> dict: def extract_variables(index: int, token: Token) -> None: nonlocal current_var_name, current_var_unsafe, current_var_discard, excepting_name - if token in [globals.find_keyword("LET"), globals.find_keyword("VAR"), globals.find_keyword("UNSAFE")]: - current_var_unsafe = token == globals.find_keyword("UNSAFE") or init_statement[index-1] == globals.find_keyword("UNSAFE") + if token in [base.find_keyword("LET"), base.find_keyword("VAR"), base.find_keyword("UNSAFE")]: + current_var_unsafe = token == base.find_keyword("UNSAFE") or init_statement[index-1] == base.find_keyword("UNSAFE") - current_var_discard = not (token == globals.find_keyword("LET")) - current_var_discard = not (token == globals.find_keyword("LET") or init_statement[index+1] == globals.find_keyword("LET")) + current_var_discard = not (token == base.find_keyword("LET")) + current_var_discard = not (token == base.find_keyword("LET") or init_statement[index+1] == base.find_keyword("LET")) excepting_name = True return @@ -275,7 +274,7 @@ def extract_variables(index: int, token: Token) -> None: if token == ",": stack.append(current_var_name.strip()) processed_decls[current_var_name.strip()] = { - globals.find_keyword("UNSAFE"): current_var_unsafe, + base.find_keyword("UNSAFE"): current_var_unsafe, "discard": current_var_discard } current_var_name = "" @@ -289,14 +288,14 @@ def extract_variables(index: int, token: Token) -> None: if excepting_name: stack.append(current_var_name.strip()) processed_decls[current_var_name.strip()] = { - globals.find_keyword("UNSAFE"): current_var_unsafe, + base.find_keyword("UNSAFE"): current_var_unsafe, "discard": current_var_discard } for _name in stack: processed_decls[_name] = { - globals.find_keyword("UNSAFE"): processed_decls[_name][globals.find_keyword("UNSAFE")], + base.find_keyword("UNSAFE"): processed_decls[_name][base.find_keyword("UNSAFE")], "discard": processed_decls[_name]["discard"] } diff --git a/functions/_functions.py b/src/functions/_functions.py similarity index 94% rename from functions/_functions.py rename to src/functions/_functions.py index 82f88aa..58c0565 100644 --- a/functions/_functions.py +++ b/src/functions/_functions.py @@ -1,16 +1,13 @@ -from classes.Token import Processed_Line, Token, Token_List -from core.config import load_config - -INDENT_CHAR = load_config().Formatter["indent_char"] -re = __import__(load_config().Transpiler["regex_module"]) - -from types import MappingProxyType as map - -from classes.Scope import Scope -from core.panic import panic -from functions._class import _class - -import globals +import src.core.base as base +from src.core.imports import ( + Processed_Line, + Token_List, + map, + Scope, + panic, + _class, + INDENT_CHAR, +) replace_function_name = map({ "==" : "__eq__", @@ -47,13 +44,13 @@ "@" : "__matmul__", }) -def extract_variables(ast_line: Token_List, root_scope: Scope) -> str: +def extract_variables(ast_line: Token_List, root_scope: Scope) -> dict[str, dict[str, str]]: allowed_untyped = ( "self", "cls", "super" ) - variables = {} + variables: dict[str, dict[str, str]] = {} # remove the fn keyword line = ast_line.line[1:] @@ -184,7 +181,7 @@ def contains(line: Token_List, compare: tuple): return any([_ in line for _ in compare]) # static async fn factorial(n: int) -> int { -def function(ast_list: Token_List, current_scope: Scope, parent_scope: Scope, root_scope: Scope) -> Processed_Line: +def _function(ast_list: Token_List, current_scope: Scope, parent_scope: Scope, root_scope: Scope) -> Processed_Line: decorators = [] if ast_list.line[0].token == "#": for _ in range(ast_list.count("#")): @@ -226,7 +223,7 @@ def function(ast_list: Token_List, current_scope: Scope, parent_scope: Scope, ro for k, v in variables["params"].items(): if v["type"] == "void": panic(SyntaxError(f": The type void is not allowed for variables"), file=ast_list.file, line_no=ast_list.find_line_number(k)) - output += f"{k}: {globals.replace_primitive(v['type'], 0)}, " + output += f"{k}: {base.replace_primitive(v['type'], 0)}, " current_scope.variables[k] = v["type"] output = output[:-2] + ")" @@ -297,4 +294,4 @@ def function(ast_list: Token_List, current_scope: Scope, parent_scope: Scope, ro for _, decorator in enumerate(reversed(decorators)): output = f"{INDENT_CHAR*ast_list.indent_level}{decorator}\n{INDENT_CHAR*ast_list.indent_level}{output.strip()}" - return Processed_Line(f'\n{INDENT_CHAR*ast_list.indent_level}@overload_with_type_check' + output, ast_list) \ No newline at end of file + return Processed_Line((f'\n{INDENT_CHAR*ast_list.indent_level}@overload_with_type_check' if not async_ else '\n') + output, ast_list) \ No newline at end of file diff --git a/functions/_include.py b/src/functions/_include.py similarity index 92% rename from functions/_include.py rename to src/functions/_include.py index bb691e9..305f54c 100644 --- a/functions/_include.py +++ b/src/functions/_include.py @@ -1,14 +1,11 @@ -from classes.Token import Processed_Line, Token, Token_List -from core.config import load_config - -INDENT_CHAR = load_config().Formatter["indent_char"] - -from os import path as os_path - -re = __import__(load_config().Transpiler["regex_module"]) - -from core.panic import panic - +from src.core.imports import ( + Processed_Line, + Token_List, + panic, + os, + INDENT_CHAR, + re, +) def is_in_string(token: str) -> bool: return re.search(r"\".*?\"", token) or re.search(r"\'[a-zA-Z0-9]\'", token) @@ -32,7 +29,7 @@ def identify_import_type(combined_line: str, ast_list: Token_List) -> dict: if match: match = match.groupdict() if not match.get('type', ""): - match["type"] = os_path.splitext(match["path"])[1][1:].upper() + match["type"] = os.path.splitext(match["path"])[1][1:].upper() if not match.get('modules', ""): match["modules"] = False else: @@ -50,7 +47,7 @@ def identify_import_type(combined_line: str, ast_list: Token_List) -> dict: return match panic(SyntaxError(f"Invalid include statement: {combined_line}"), file=ast_list.file, line_no=ast_list.line[0].line_number) -def include(ast_list: Token_List, current_scope, parent_scope, root_scope) -> Processed_Line: +def _include(ast_list: Token_List, current_scope, parent_scope, root_scope) -> Processed_Line: combined_line: str = ' '.join([_.token for _ in ast_list.line]) match = identify_import_type(combined_line, ast_list) @@ -62,7 +59,7 @@ def include(ast_list: Token_List, current_scope, parent_scope, root_scope) -> Pr import_statement = "" if type == "C": if not alias and not modules: - return Processed_Line(f"{INDENT_CHAR*ast_list.line[0].indent_level}{os_path.splitext(path)[0].strip()} = __import_c__(\"{path}\")\n", ast_list) + return Processed_Line(f"{INDENT_CHAR*ast_list.line[0].indent_level}{os.path.splitext(path)[0].strip()} = __import_c__(\"{path}\")\n", ast_list) elif alias and modules and len(modules) == 1: return Processed_Line(f"{INDENT_CHAR*ast_list.line[0].indent_level}{alias} = __import_c__(\"{path}\").{modules[0]}\n", ast_list) elif alias and modules and len(modules) > 1: @@ -70,18 +67,18 @@ def include(ast_list: Token_List, current_scope, parent_scope, root_scope) -> Pr elif alias and not modules: return Processed_Line(f"{INDENT_CHAR*ast_list.line[0].indent_level}{alias} = __import_c__(\"{path}\")\n", ast_list) elif not alias and modules and len(modules) == 1: - return Processed_Line(f"{INDENT_CHAR*ast_list.line[0].indent_level}{os_path.splitext(path)[0].strip()} = __import_c__(\"{path}\").{modules[0]}\n", ast_list) + return Processed_Line(f"{INDENT_CHAR*ast_list.line[0].indent_level}{os.path.splitext(path)[0].strip()} = __import_c__(\"{path}\").{modules[0]}\n", ast_list) elif not alias and modules and len(modules) > 1: - import_statement = f"{INDENT_CHAR*ast_list.line[0].indent_level}{os_path.splitext(path)[0].strip()} = __import_c__(\"{path}\")\n" + import_statement = f"{INDENT_CHAR*ast_list.line[0].indent_level}{os.path.splitext(path)[0].strip()} = __import_c__(\"{path}\")\n" for module in modules: - import_statement += f"{INDENT_CHAR*ast_list.line[0].indent_level}{module.strip()} = {os_path.splitext(path)[0].strip()}.{module}\n" - import_statement += f"{INDENT_CHAR*ast_list.line[0].indent_level}del {os_path.splitext(path)[0].strip()}\n" + import_statement += f"{INDENT_CHAR*ast_list.line[0].indent_level}{module.strip()} = {os.path.splitext(path)[0].strip()}.{module}\n" + import_statement += f"{INDENT_CHAR*ast_list.line[0].indent_level}del {os.path.splitext(path)[0].strip()}\n" return Processed_Line(import_statement, ast_list) else: panic(SyntaxError(f"Invalid include statement: {combined_line}"), file=ast_list.file, line_no=ast_list.line[0].line_number) elif type == "CPP": if not alias and not modules: - return Processed_Line(f"{INDENT_CHAR*ast_list.line[0].indent_level}{os_path.splitext(path)[0].strip()} = __import_c__(\"{path}\")\n", ast_list) + return Processed_Line(f"{INDENT_CHAR*ast_list.line[0].indent_level}{os.path.splitext(path)[0].strip()} = __import_c__(\"{path}\")\n", ast_list) elif alias and modules and len(modules) == 1: return Processed_Line(f"{INDENT_CHAR*ast_list.line[0].indent_level}{alias} = __import_c__(\"{path}\").{modules[0]}\n", ast_list) elif alias and modules and len(modules) > 1: @@ -89,12 +86,12 @@ def include(ast_list: Token_List, current_scope, parent_scope, root_scope) -> Pr elif alias and not modules: return Processed_Line(f"{INDENT_CHAR*ast_list.line[0].indent_level}{alias} = __import_c__(\"{path}\")\n", ast_list) elif not alias and modules and len(modules) == 1: - return Processed_Line(f"{INDENT_CHAR*ast_list.line[0].indent_level}{os_path.splitext(path)[0].strip()} = __import_c__(\"{path}\").{modules[0]}\n", ast_list) + return Processed_Line(f"{INDENT_CHAR*ast_list.line[0].indent_level}{os.path.splitext(path)[0].strip()} = __import_c__(\"{path}\").{modules[0]}\n", ast_list) elif not alias and modules and len(modules) > 1: - import_statement = f"{INDENT_CHAR*ast_list.line[0].indent_level}{os_path.splitext(path)[0].strip()} = __import_c__(\"{path}\")\n" + import_statement = f"{INDENT_CHAR*ast_list.line[0].indent_level}{os.path.splitext(path)[0].strip()} = __import_c__(\"{path}\")\n" for module in modules: - import_statement += f"{INDENT_CHAR*ast_list.line[0].indent_level}{module} = {os_path.splitext(path)[0].strip()}.{module}\n" - import_statement += f"{INDENT_CHAR*ast_list.line[0].indent_level}del {os_path.splitext(path)[0].strip()}\n" + import_statement += f"{INDENT_CHAR*ast_list.line[0].indent_level}{module} = {os.path.splitext(path)[0].strip()}.{module}\n" + import_statement += f"{INDENT_CHAR*ast_list.line[0].indent_level}del {os.path.splitext(path)[0].strip()}\n" return Processed_Line(import_statement, ast_list) else: panic(SyntaxError(f"Invalid include statement: {combined_line}"), file=ast_list.file, line_no=ast_list.line[0].line_number) @@ -113,7 +110,7 @@ def include(ast_list: Token_List, current_scope, parent_scope, root_scope) -> Pr panic(SyntaxError(f"Invalid include statement: {combined_line}"), file=ast_list.file, line_no=ast_list.line[0].line_number) elif type == "RS": if not alias and not modules: - return Processed_Line(f"{INDENT_CHAR*ast_list.line[0].indent_level}{os_path.splitext(path)[0].strip()} = __rs_import__(\"{path}\")\n", ast_list) + return Processed_Line(f"{INDENT_CHAR*ast_list.line[0].indent_level}{os.path.splitext(path)[0].strip()} = __rs_import__(\"{path}\")\n", ast_list) elif alias and not modules: return Processed_Line(f"{INDENT_CHAR*ast_list.line[0].indent_level}{alias} = __rs_import__(\"{path}\")\n", ast_list) elif alias and modules and len(modules) == 1: @@ -121,12 +118,12 @@ def include(ast_list: Token_List, current_scope, parent_scope, root_scope) -> Pr elif alias and modules and len(modules) > 1: panic(SyntaxError(f"Invalid include statement: {combined_line} cannot have multiple modules and an alias"), file=ast_list.file, line_no=ast_list.line[0].line_number) elif not alias and modules and len(modules) == 1: - return Processed_Line(f"{INDENT_CHAR*ast_list.line[0].indent_level}{os_path.splitext(path)[0].strip()} = __rs_import__(\"{path}\").{modules[0]}\n", ast_list) + return Processed_Line(f"{INDENT_CHAR*ast_list.line[0].indent_level}{os.path.splitext(path)[0].strip()} = __rs_import__(\"{path}\").{modules[0]}\n", ast_list) elif not alias and modules and len(modules) > 1: - import_statement = f"{INDENT_CHAR*ast_list.line[0].indent_level}{os_path.splitext(path)[0].strip()} = __rs_import__(\"{path}\")\n" + import_statement = f"{INDENT_CHAR*ast_list.line[0].indent_level}{os.path.splitext(path)[0].strip()} = __rs_import__(\"{path}\")\n" for module in modules: - import_statement += f"{INDENT_CHAR*ast_list.line[0].indent_level}{module} = {os_path.splitext(path)[0].strip()}.{module}\n" - import_statement += f"{INDENT_CHAR*ast_list.line[0].indent_level}del {os_path.splitext(path)[0].strip()}\n" + import_statement += f"{INDENT_CHAR*ast_list.line[0].indent_level}{module} = {os.path.splitext(path)[0].strip()}.{module}\n" + import_statement += f"{INDENT_CHAR*ast_list.line[0].indent_level}del {os.path.splitext(path)[0].strip()}\n" return Processed_Line(import_statement, ast_list) else: panic(SyntaxError(f"Invalid include statement: {combined_line}"), file=ast_list.file, line_no=ast_list.line[0].line_number) diff --git a/functions/_let.py b/src/functions/_let.py similarity index 90% rename from functions/_let.py rename to src/functions/_let.py index 8e27be8..a879186 100644 --- a/functions/_let.py +++ b/src/functions/_let.py @@ -1,13 +1,10 @@ -from classes.Token import Token, Token_List, Processed_Line -from core.config import load_config -from core.token.tokenize_line import tokenize_line -import globals - -INDENT_CHAR = load_config().Formatter["indent_char"] -re = __import__(load_config().Transpiler["regex_module"]) - -from core.panic import panic - +import src.core.base as base +from src.core.imports import ( + Token_List, + Processed_Line, + INDENT_CHAR, + panic, +) def _let(ast_list: Token_List, current_scope, parent_scope, root_scope) -> Processed_Line: output = "" @@ -195,7 +192,7 @@ def mass_replace(string: str, replacements: dict[str, str]) -> str: ) - for values in globals.IGNORE_TYPES_MAP: + for values in base.IGNORE_TYPES_MAP: if values in value["type"]: value["value"] = "Any" broken_type = True @@ -203,11 +200,11 @@ def mass_replace(string: str, replacements: dict[str, str]) -> str: value["type"] = mass_replace(value["type"].full_line().strip(), cleaning) if not broken_type else "Any" if not null_value: - output += f"{INDENT_CHAR*(ast_list.indent_level + (1 if override_dispatch_error else 0))}{name}: {globals.replace_primitive(value['type'])} = {globals.replace_primitive(value['type'], 3) if globals.replace_primitive(value['type'], 3) not in value['value'] else ''}({value['value']})\n" + output += f"{INDENT_CHAR*(ast_list.indent_level + (1 if override_dispatch_error else 0))}{name}: {base.replace_primitive(value['type'])} = {base.replace_primitive(value['type'], 3) if base.replace_primitive(value['type'], 3) not in value['value'] else ''}({value['value']})\n" elif null_value and value["value"] == "None": - output += f"{INDENT_CHAR*(ast_list.indent_level + (1 if override_dispatch_error else 0))}{name}: Optional[{globals.replace_primitive(value['type'])}] = {value['value']}\n" + output += f"{INDENT_CHAR*(ast_list.indent_level + (1 if override_dispatch_error else 0))}{name}: Optional[{base.replace_primitive(value['type'])}] = {value['value']}\n" elif null_value and value["value"]: - output += f"{INDENT_CHAR*(ast_list.indent_level + (1 if override_dispatch_error else 0))}{name}: Optional[{globals.replace_primitive(value['type'])}]= {globals.replace_primitive(value['type'], 3) if globals.replace_primitive(value['type'], 3) not in value['value'] else ''}({value['value']})\n" + output += f"{INDENT_CHAR*(ast_list.indent_level + (1 if override_dispatch_error else 0))}{name}: Optional[{base.replace_primitive(value['type'])}]= {base.replace_primitive(value['type'], 3) if base.replace_primitive(value['type'], 3) not in value['value'] else ''}({value['value']})\n" # + "\n" + ( # ( # INDENT_CHAR*(ast_list.indent_level) + "print(" + name + ")\n" diff --git a/src/functions/_match.py b/src/functions/_match.py new file mode 100644 index 0000000..81b1464 --- /dev/null +++ b/src/functions/_match.py @@ -0,0 +1,14 @@ +from src.core.imports import ( + Processed_Line, + Token, + Token_List, + load_config, + INDENT_CHAR, + re, + panic, + _class, +) + +def _match(ast_list: Token_List, current_scope, parent_scope, root_scope, modifiers=None) -> Processed_Line: + print(ast_list) + return Processed_Line("yessir", ast_list) \ No newline at end of file diff --git a/functions/_process.py b/src/functions/_process.py similarity index 85% rename from functions/_process.py rename to src/functions/_process.py index 8964de9..ce6aac6 100644 --- a/functions/_process.py +++ b/src/functions/_process.py @@ -1,19 +1,9 @@ -# move the dir one up -import os -import sys - -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - -from classes.Scope import Scope -from classes.Token import Processed_Line, Token, Token_List -from core.config import load_config - -INDENT_CHAR = load_config().Formatter["indent_char"] -re = __import__(load_config().Transpiler["regex_module"]) - -from core.panic import panic -from functions._class import _class - +from src.core.imports import ( + Scope, + Processed_Line, + Token, + Token_List, +) def _match(ast_list: Token_List, current_scope, parent_scope, root_scope) -> Token_List: return Processed_Line("JOSH!!!!!!!!!!!!!!!!!!!!!!!!", ast_list) diff --git a/functions/_unless.py b/src/functions/_unless.py similarity index 53% rename from functions/_unless.py rename to src/functions/_unless.py index dc7ef43..d3ecd77 100644 --- a/functions/_unless.py +++ b/src/functions/_unless.py @@ -1,27 +1,25 @@ -from classes.Token import Processed_Line, Token, Token_List -import globals -from core.cache_store import cache -from core.config import load_config -from classes.Scope import Scope - -INDENT_CHAR = load_config().Formatter["indent_char"] -re = __import__(load_config().Transpiler["regex_module"]) - -from core.panic import panic +import src.core.base as base +from src.core.imports import ( + Processed_Line, + Token_List, + Scope, + INDENT_CHAR, + panic, +) def _unless(ast_list: Token_List, current_scope: Scope, parent_scope: Scope, root_scope: Scope, modifiers=None) -> Processed_Line: # unless condition: -> if not condition: # else if condition: -> elif condition: output = "" - if ast_list[0].token == globals.find_keyword("UNLESS"): + if ast_list[0].token == base.find_keyword("UNLESS"): output = f"if not ({ast_list.splice(1, -1).full_line()}):" - elif ast_list[0].token == globals.find_keyword("IF"): + elif ast_list[0].token == base.find_keyword("IF"): output = f"if ({ast_list.splice(1, -1).full_line()}):" - elif ast_list[0].token == globals.find_keyword("ELSE_IF"): + elif ast_list[0].token == base.find_keyword("ELSE_IF"): output = f"elif ({ast_list.splice(1, -1).full_line()}):" - elif ast_list[0].token == globals.find_keyword("ELSE") and ast_list[1].token == globals.find_keyword("IF"): + elif ast_list[0].token == base.find_keyword("ELSE") and ast_list[1].token == base.find_keyword("IF"): output = f"elif ({ast_list.splice(2, -1).full_line()}):" - elif ast_list[0].token == globals.find_keyword("ELSE") and len(ast_list) == 2: + elif ast_list[0].token == base.find_keyword("ELSE") and len(ast_list) == 2: output = "else:" else: panic(SyntaxError(f"Unexpected token '{ast_list[0].token}'"), ast_list[0].token, file=ast_list.file, line_no=ast_list.find_line_number(ast_list[0].token)) diff --git a/functions/_unmarked.py b/src/functions/_unmarked.py similarity index 95% rename from functions/_unmarked.py rename to src/functions/_unmarked.py index 2720c74..1b6f840 100644 --- a/functions/_unmarked.py +++ b/src/functions/_unmarked.py @@ -1,13 +1,22 @@ from types import UnionType -from classes.Token import Token, Token_List, Processed_Line -from core.config import load_config -from core.token.tokenize_line import tokenize_line +from src.classes.Token import Token, Token_List, Processed_Line +from src.config import load_config +from src.token.tokenize_line import tokenize_line INDENT_CHAR = load_config().Formatter["indent_char"] re = __import__(load_config().Transpiler["regex_module"]) -from core.panic import panic +from src.panic import panic +""" +from src.core.imports import ( + Token_List, + UnionType, + Processed_Line, + INDENT_CHAR, + panic, +) +""" def _unmarked(ast_list: Token_List, current_scope, parent_scope, root_scope, ignore_main) -> str: diff --git a/core/panic.py b/src/panic.py similarity index 93% rename from core/panic.py rename to src/panic.py index ab3b779..82403f0 100644 --- a/core/panic.py +++ b/src/panic.py @@ -4,7 +4,7 @@ from sys import exit from sys import stdout as sys_stdout from types import FrameType -from typing import Any, Callable, NoReturn, Optional +from typing import Any, Optional from weakref import ref from pygments import highlight # type: ignore @@ -26,7 +26,6 @@ Whitespace, ) - class HelixSyntaxHighlightingLexer(RegexLexer): name = "Helix" aliases = ["Helix"] @@ -188,18 +187,22 @@ def standalone_tokenize_line(line: str, preserve_spaces: bool = False) -> list[s # Pattern for ANSI color escape sequences color_escape_pattern = r"(\x1b\[[0-9;]*m)" + double_character_operators = ['\\=\\=\\=', '\\!\\=\\=', '\\.\\.\\.', '\\=\\=', '\\!\\=', '\\-\\>', '\\<\\-', '\\<\\=', '\\>\\=', '\\&\\&', '\\-\\-', '\\:\\:', '\\|\\|', '\\+\\+', '\\+\\=', '\\-\\=', '\\*\\=', '\\/\\=', '\\&\\=', '\\|\\=', '\\^\\=', '\\%\\=', '\\*\\*', '\\<\\<', '\\>\\>', '\\<\\<\\=', '\\>\\>\\=', '\\=\\>', '\\@\\=', '\\_\\_', '\\?\\?', '\\?\\:', '\\?\\='] + comment_pattern = r"\~\~.*" + multi_line_comment_pattern = r"\~\*\~" + pattern = re.compile( rf""" - {color_escape_pattern} | # ANSI color escape sequences - ({back_slash.join(r"\~\~.*".split())}[^\n]*) | # Single line comments (~~) - ({back_slash.join(r"\~\*\~".split())}[\s\S]*?{back_slash.join(r"\~\*\~".split())}) | # Multi line comments (~*~ ... ~*~) - (\b\d+\.\d+\b) | # Decimal numbers - (\b\w+\b) | # Words (identifiers, keywords) - ({'|'.join(['\\=\\=\\=', '\\!\\=\\=', '\\.\\.\\.', '\\=\\=', '\\!\\=', '\\-\\>', '\\<\\-', '\\<\\=', '\\>\\=', '\\&\\&', '\\-\\-', '\\:\\:', '\\|\\|', '\\+\\+', '\\+\\=', '\\-\\=', '\\*\\=', '\\/\\=', '\\&\\=', '\\|\\=', '\\^\\=', '\\%\\=', '\\*\\*', '\\<\\<', '\\>\\>', '\\<\\<\\=', '\\>\\>\\=', '\\=\\>', '\\@\\=', '\\_\\_', '\\?\\?', '\\?\\:', '\\?\\='])}) | # Double character operators - ([\(\){{}};,]) | # Single character delimiters - {space_group} | # Spaces - (\S) | # Catch other characters - """, + {color_escape_pattern} | # ANSI color escape sequences + ({back_slash.join(comment_pattern.split())}[^\n]*) | # Single line comments (~~) + ({back_slash.join(multi_line_comment_pattern.split())}[\s\S]*?{back_slash.join(multi_line_comment_pattern.split())}) | # Multi line comments (~*~ ... ~*~) + (\b\d+\.\d+\b) | # Decimal numbers + (\b\w+\b) | # Words (identifiers, keywords) + ({'|'.join(double_character_operators)}) | # Double character operators + ([\(\){{}};,]) | # Single character delimiters + {space_group} | # Spaces + (\S) | # Catch other characters + """, re.MULTILINE | re.VERBOSE, ) diff --git a/core/token/normalize_tokens.py b/src/token/normalize_tokens.py similarity index 95% rename from core/token/normalize_tokens.py rename to src/token/normalize_tokens.py index 882168a..88c5004 100644 --- a/core/token/normalize_tokens.py +++ b/src/token/normalize_tokens.py @@ -1,7 +1,7 @@ -from core.cache_store import cache -from core.panic import panic -from globals import BODY_REQUIRED_KEYWORDS, find_keyword -from classes.Token import Token, Token_List +from src.cache_store import cache +from src.panic import panic +import src.core.base as base +from src.classes.Token import Token, Token_List @cache def normalize_tokens(_lines: tuple[Token, ...], path: str) -> tuple[Token_List, ...]: @@ -43,7 +43,7 @@ def process_line(index: int): nonlocal stack, indent_level, firs_inst, previous_element token = lines[index].line - if token in BODY_REQUIRED_KEYWORDS.keys() and lines[index-1].line not in (find_keyword("ELSE"), ): + if token in base.BODY_REQUIRED_KEYWORDS.keys() and lines[index-1].line not in (base.find_keyword("ELSE"), ): # append the line to the stack for i in range(index, len(lines)): if lines[i].line == "{": diff --git a/core/token/remove_comments.py b/src/token/remove_comments.py similarity index 78% rename from core/token/remove_comments.py rename to src/token/remove_comments.py index ee3fffd..c65ae15 100644 --- a/core/token/remove_comments.py +++ b/src/token/remove_comments.py @@ -1,11 +1,11 @@ import ast from functools import cache -from core.config import load_config +from src.config import load_config re = __import__(load_config().Transpiler["regex_module"]) -from classes.Token import Token -from globals import BLOCK_COMMENT, COMMENT, INLINE_COMMENT +from src.classes.Token import Token +import src.core.base as base in_block_comment: bool = False @@ -26,12 +26,12 @@ def remove_comment(_code: Token): global in_block_comment code: str = _code.original_line - code = re.sub(INLINE_COMMENT, "", re.sub(COMMENT, "", code)) + code = re.sub(base.INLINE_COMMENT, "", re.sub(base.COMMENT, "", code)) code = re.sub(r"override\s+.*\:", "", code) code = re.sub(r"impl\s+.*:", "", code) - if re.search(BLOCK_COMMENT, code): + if re.search(base.BLOCK_COMMENT, code): in_block_comment = ~in_block_comment # type: ignore code = "" diff --git a/core/token/tokenize_file.py b/src/token/tokenize_file.py similarity index 70% rename from core/token/tokenize_file.py rename to src/token/tokenize_file.py index 4bf7b31..10d32d2 100644 --- a/core/token/tokenize_file.py +++ b/src/token/tokenize_file.py @@ -1,9 +1,9 @@ import functools -from core.token.normalize_tokens import normalize_tokens -from core.token.remove_comments import remove_comment -from core.token.tokenize_line import tokenize_line, standalone_tokenize_line -from classes.Token import Token, Token_List -import globals +from src.token.normalize_tokens import normalize_tokens +from src.token.remove_comments import remove_comment +from src.token.tokenize_line import tokenize_line +from src.classes.Token import Token, Token_List +import src.core.base as base class Tokenizer: @@ -21,28 +21,28 @@ def tokenize_file(path: str) -> tuple[Token_List, ...]: list[list[str]]: The normalized and tokenized file """ - if path in globals.CACHE: - return globals.CACHE[path] + if path in base.CACHE: + return base.CACHE[path] lines: tuple[Token, ...] = tuple( Token(line, "", index + 1, 0) for index, line in enumerate(open(path, "r").readlines()) ) - if globals.USE_POOL: - [globals.POOL.append(remove_comment, line) for line in lines] - globals.POOL.execute() + if base.USE_POOL: + [base.POOL.append(remove_comment, line) for line in lines] + base.POOL.execute() _tokenize_line = functools.partial(tokenize_line, path=path) - [globals.POOL.append(_tokenize_line, line) for line in lines] - globals.POOL.execute() + [base.POOL.append(_tokenize_line, line) for line in lines] + base.POOL.execute() else: tuple(map(remove_comment, lines)) tuple(map(lambda _: tokenize_line(_, path), lines)) - globals.CACHE[path] = normalize_tokens(lines, path) - return globals.CACHE[path] + base.CACHE[path] = normalize_tokens(lines, path) + return base.CACHE[path] @staticmethod def tokenize_line(line: str, path: str, indent: int = 0, line_no: int = 0) -> tuple[Token_List, ...]: diff --git a/core/token/tokenize_line.py b/src/token/tokenize_line.py similarity index 68% rename from core/token/tokenize_line.py rename to src/token/tokenize_line.py index 2c66b4e..5bc2ed4 100644 --- a/core/token/tokenize_line.py +++ b/src/token/tokenize_line.py @@ -1,9 +1,9 @@ import re # #### Keep from functools import cache -from core.panic import panic +from src.panic import panic -import globals -from classes.Token import Token +import src.core.base as base +from src.classes.Token import Token COMPILED_RE: re.Pattern = None @@ -14,21 +14,21 @@ def compiled_re(ignore_strings: bool = False) -> re.Pattern: COMPILED_RE = re.compile(rf""" ([fbur]*"[^"\\]*(?:\\.[^"\\]*)*") | # Double quotes strings, including f, b, r, u strings ([fbur]*'[^'\\]*(?:\\.[^'\\]*)*') | # Single quotes strings, including f, b, r, u strings - ({back_slash.join(globals.COMMENT.split())}[^\n]*) | # Single line comments (~~) - ({back_slash.join(globals.BLOCK_COMMENT.split())}[\s\S]*?{back_slash.join(globals.BLOCK_COMMENT.split())}) | # Multi line comments (~*~ ... ~*~) + ({back_slash.join(base.COMMENT.split())}[^\n]*) | # Single line comments (~~) + ({back_slash.join(base.BLOCK_COMMENT.split())}[\s\S]*?{back_slash.join(base.BLOCK_COMMENT.split())}) | # Multi line comments (~*~ ... ~*~) (\b\d+\.\d+\b) | # Decimal numbers (\b\w+\b) | # Words (identifiers, keywords) - ({'|'.join(globals.FAT_CHARACTER)}) | # Double character operators + ({'|'.join(base.FAT_CHARACTER)}) | # Double character operators ([\(\){{}};,]) | # Single character delimiters (\S) | # Catch other characters """, re.MULTILINE | re.VERBOSE) if ignore_strings: return re.compile(rf""" - ({back_slash.join(globals.COMMENT.split())}[^\n]*) | # Single line comments (~~) - ({back_slash.join(globals.BLOCK_COMMENT.split())}[\s\S]*?{back_slash.join(globals.BLOCK_COMMENT.split())}) | # Multi line comments (~*~ ... ~*~) + ({back_slash.join(base.COMMENT.split())}[^\n]*) | # Single line comments (~~) + ({back_slash.join(base.BLOCK_COMMENT.split())}[\s\S]*?{back_slash.join(base.BLOCK_COMMENT.split())}) | # Multi line comments (~*~ ... ~*~) (\b\d+\.\d+\b) | # Decimal numbers (\b\w+\b) | # Words (identifiers, keywords) - ({'|'.join(globals.FAT_CHARACTER)}) | # Double character operators + ({'|'.join(base.FAT_CHARACTER)}) | # Double character operators ([\(\){{}};,]) | # Single character delimiters (\S) | # Catch other characters """, re.MULTILINE | re.VERBOSE) @@ -61,7 +61,7 @@ def tokenize_line(code: Token | str, path: str = None, ignore_errors: bool = Fal token for group in tokens for token in group - if token and not token.startswith(globals.COMMENT) and not token.startswith(globals.BLOCK_COMMENT) and not token.endswith(globals.BLOCK_COMMENT) + if token and not token.startswith(base.COMMENT) and not token.startswith(base.BLOCK_COMMENT) and not token.endswith(base.BLOCK_COMMENT) ] [ @@ -72,13 +72,13 @@ def tokenize_line(code: Token | str, path: str = None, ignore_errors: bool = Fal line_no=code.line_number ) for token in flattened_tokens - if token.strip() in globals.RESERVED_KEYWORDS and not ignore_errors + if token.strip() in base.RESERVED_KEYWORDS and not ignore_errors ] code.line = [ - globals.EARLY_REPLACEMENTS[token] + base.EARLY_REPLACEMENTS[token] if ( - token in globals.EARLY_REPLACEMENTS + token in base.EARLY_REPLACEMENTS ) else ( token ) for token in flattened_tokens @@ -94,11 +94,11 @@ def standalone_tokenize_line(line: str | Token) -> list[str]: back_slash = "\\" pattern = re.compile(rf""" - ({back_slash.join(globals.COMMENT.split())}[^\n]*) | # Single line comments (~~) - ({back_slash.join(globals.BLOCK_COMMENT.split())}[\s\S]*?{back_slash.join(globals.BLOCK_COMMENT.split())}) | # Multi line comments (~*~ ... ~*~) + ({back_slash.join(base.COMMENT.split())}[^\n]*) | # Single line comments (~~) + ({back_slash.join(base.BLOCK_COMMENT.split())}[\s\S]*?{back_slash.join(base.BLOCK_COMMENT.split())}) | # Multi line comments (~*~ ... ~*~) (\b\d+\.\d+\b) | # Decimal numbers (\b\w+\b) | # Words (identifiers, keywords) - ({'|'.join(globals.FAT_CHARACTER)}) | # Double character operators + ({'|'.join(base.FAT_CHARACTER)}) | # Double character operators ([\(\){{}};,]) | # Single character delimiters (\S) | # Catch other characters """, re.MULTILINE | re.VERBOSE) @@ -116,5 +116,5 @@ def standalone_tokenize_line(line: str | Token) -> list[str]: token for group in tokens for token in group - if token and not token.startswith(globals.COMMENT) and not token.startswith(globals.BLOCK_COMMENT) and not token.endswith(globals.BLOCK_COMMENT) + if token and not token.startswith(base.COMMENT) and not token.startswith(base.BLOCK_COMMENT) and not token.endswith(base.BLOCK_COMMENT) ] \ No newline at end of file diff --git a/syntax/head_syntax.hdlx b/syntax/head_syntax.hdlx index 400ebb0..9704a3b 100644 --- a/syntax/head_syntax.hdlx +++ b/syntax/head_syntax.hdlx @@ -1,9 +1,17 @@ -target "rust"; use "syntax.hlx"; -include system; -if system::is_windows() { +if sys::is_windows() { define set_something(int value) -> void; } else { define set_something_else(int value) -> void; -} \ No newline at end of file +} + +namespace python { + fn set_something(value: int) -> None; + fn set_something_else(value: int) -> None; +} + +namespace c { + fn set_something(value: int) -> void; + fn set_something_else(value: int) -> void; +} diff --git a/syntax/syntax.hlx b/syntax/syntax.hlx index 7606b26..fcfdfc6 100644 --- a/syntax/syntax.hlx +++ b/syntax/syntax.hlx @@ -176,7 +176,8 @@ enum dog { } -or and is as use elif switch union enum unsafe +~~ all keywords to make sure the syntax highlighting works +or and is as use elif switch union enum unsafe in auto diff --git a/syntax/test.hlx b/syntax/test.hlx index 8724e32..9b76136 100644 --- a/syntax/test.hlx +++ b/syntax/test.hlx @@ -83,35 +83,38 @@ class C_cout { } fn main(argv: list) { - do_something(); let a: int = "12"; - print(add(a, ["a", "b", "c"])); + + add(123, 123); + print(add.join()); + + do_something(); + do_something.join(); + + print("done"); + return 0; } +async fn add(a: int, b: int) -> int { + printf("adding: %d + %d", a, b); + return a + b; +} private fn subtract(a: int, b: int) -> int { return a - b } -fn add(a: int, b: int) -> int { - let a: Type = 10; - print(a); - return a - b -} async fn do_something() { for (var i: int = 0; i < 10; i++) { - print("doing something: %d", i); + printf("doing something: %d", i); } } -~*~ -fn a_cursed_fucntion(a: int) -> FunctionType { printf("new something: %d", a); return a_cursed_fucntion } -fn a_cursed_fucntion(a: string) -> FunctionType { let data: list = []; return "kys" } - - +fn a_cursed_fucntion(a: int) -> FunctionType { printf("new something: %d", a); return a_cursed_fucntion } +~*~ fn test_int() { let a: int = 21; let b: int = 42; diff --git a/tests/ThreadPool_test.py b/tests/ThreadPool_test.py index cad0cc1..0cad76a 100644 --- a/tests/ThreadPool_test.py +++ b/tests/ThreadPool_test.py @@ -8,7 +8,7 @@ from concurrent.futures import Future from multiprocessing import cpu_count -from classes.WorkerPool import WorkerPool +from src.classes.WorkerPool import WorkerPool def test_func(x): From 17a666498bb30a6b3e746283cf7158d21695054d Mon Sep 17 00:00:00 2001 From: Dhruvan Date: Mon, 11 Mar 2024 23:27:21 -0400 Subject: [PATCH 2/2] Update requirements.txt and setup.py, remove test.py, and modify Transpiler.py and test.hlx --- .helix/cache/build_cache/test_hlx.py | 5 +- .helix/cache/build_cache/test_hlx.py.lines | 33 +- .helix/include/core.py | 45 +- build/__native.c | 1782 +++++++++++++++++ build/__native.h | 29 + build/__native_internal.h | 39 + build/ops.txt | 908 +++++++++ build/setup.py | 2 +- .../Release/build/__native.obj | Bin 0 -> 469412 bytes .../Release/build/test.cp311-win_amd64.exp | Bin 0 -> 740 bytes .../Release/build/test.cp311-win_amd64.lib | Bin 0 -> 1960 bytes helix.py | 71 +- out/helix.pyi | 96 + requirements.txt | 3 +- src/classes/Transpiler.py | 5 +- src/core/base.py | 146 +- src/core/framework.py | 169 ++ src/core/imports.py | 2 + src/core/utils.py | 145 ++ syntax/test.hlx | 4 +- test.py | 10 - tests.py | 1 + 22 files changed, 3297 insertions(+), 198 deletions(-) create mode 100644 build/__native.c create mode 100644 build/__native.h create mode 100644 build/__native_internal.h create mode 100644 build/ops.txt create mode 100644 build/temp.win-amd64-cpython-311/Release/build/__native.obj create mode 100644 build/temp.win-amd64-cpython-311/Release/build/test.cp311-win_amd64.exp create mode 100644 build/temp.win-amd64-cpython-311/Release/build/test.cp311-win_amd64.lib create mode 100644 out/helix.pyi delete mode 100644 test.py create mode 100644 tests.py diff --git a/.helix/cache/build_cache/test_hlx.py b/.helix/cache/build_cache/test_hlx.py index a9d98d2..f26fb50 100644 --- a/.helix/cache/build_cache/test_hlx.py +++ b/.helix/cache/build_cache/test_hlx.py @@ -4,7 +4,7 @@ # GENERATED FILE # -------------------------------------------------------------------------------- # Filename: test.hlx -# Generation Date: 2024-03-11 18:49:50 +# Generation Date: 2024-03-11 23:27:01 # Generator: Helix Transpiler # -------------------------------------------------------------------------------- # WARNING: This file is AUTO-GENERATED by the Helix Transpiler. Any modifications @@ -188,6 +188,9 @@ def main(argv: list[str | hx_string] | hx_list[str | hx_string]): add ( 123 , 123 ) print ( add . join ( ) ) do_something ( ) + for i in C_For(i = int(0)).set_con('i < 10').set_inc('i ++'): + printf ( "doing something else eeeee: %d" , i ) + del i do_something . join ( ) print ( "done" ) return 0 diff --git a/.helix/cache/build_cache/test_hlx.py.lines b/.helix/cache/build_cache/test_hlx.py.lines index f4ec04a..bfe8dd3 100644 --- a/.helix/cache/build_cache/test_hlx.py.lines +++ b/.helix/cache/build_cache/test_hlx.py.lines @@ -189,24 +189,27 @@ 89 91 92 -94 +93 +92 95 -98 -98 -99 +96 +97 +100 100 -103 -103 -104 -108 -108 -109 +101 +102 +105 +105 +106 +110 110 -109 -115 -115 -115 -115 +111 +112 +111 +117 +117 +117 +117 -1 -1 -1 diff --git a/.helix/include/core.py b/.helix/include/core.py index ffdf8c1..9789624 100644 --- a/.helix/include/core.py +++ b/.helix/include/core.py @@ -197,6 +197,42 @@ def __void__(self) -> bool: DEFAULT_VALUE = void() +#class C_For: +# def __init__(self, **kwargs): +# # Initialize loop variables +# self.loop_vars = kwargs +# # Extract condition and increment expressions +# self.condition = "True" +# self.increment = "" +# # Evaluate initial conditions +# [exec(f"{var} = {value}") for var, value in self.loop_vars.items()] +# +# def __iter__(self): +# return self +# +# def __next__(self): +# if not self.loop_condition_met: +# raise StopIteration +# current_values = tuple(self.loop_vars.values()) +# exec(self.increment, None, self.loop_vars) +# self.loop_condition_met = eval(self.condition, None, self.loop_vars) +# return current_values if len(current_values) > 1 else current_values[0] +# +# def set_con(self, condition): +# self.condition = condition +# self.loop_condition_met = eval(self.condition, None, self.loop_vars) +# return self +# +# def set_inc(self, increment): +# self.increment = ( +# increment.replace("++", "+= 1") +# .replace("--", "-= 1") +# .replace("+*", "*= 1") +# .replace("-*", "*= -1") +# .replace("/-", "/ -1") +# .replace("/*", "*= 1") +# ) +# return self class C_For: def __init__(self, **kwargs): # Initialize loop variables @@ -206,16 +242,18 @@ def __init__(self, **kwargs): self.increment = "" # Evaluate initial conditions [exec(f"{var} = {value}") for var, value in self.loop_vars.items()] + self.loop_condition_met = eval(self.condition, None, self.loop_vars) - def __iter__(self): + async def __aiter__(self): return self - def __next__(self): + async def __anext__(self): if not self.loop_condition_met: - raise StopIteration + raise StopAsyncIteration current_values = tuple(self.loop_vars.values()) exec(self.increment, None, self.loop_vars) self.loop_condition_met = eval(self.condition, None, self.loop_vars) + await asyncio.sleep(0) # Yield control to allow other tasks to run return current_values if len(current_values) > 1 else current_values[0] def set_con(self, condition): @@ -234,6 +272,7 @@ def set_inc(self, increment): ) return self + from beartype import beartype def hx__async(func: Callable) -> Callable: diff --git a/build/__native.c b/build/__native.c new file mode 100644 index 0000000..cee8eae --- /dev/null +++ b/build/__native.c @@ -0,0 +1,1782 @@ +#include "init.c" +#include "getargs.c" +#include "getargsfast.c" +#include "int_ops.c" +#include "float_ops.c" +#include "str_ops.c" +#include "bytes_ops.c" +#include "list_ops.c" +#include "dict_ops.c" +#include "set_ops.c" +#include "tuple_ops.c" +#include "exc_ops.c" +#include "misc_ops.c" +#include "generic_ops.c" +#include "__native.h" +#include "__native_internal.h" + +static PyObject *test_env_setup(PyTypeObject *type); +PyObject *CPyDef_test_env(void); + +static PyObject * +test_env_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + if (type != CPyType_test_env) { + PyErr_SetString(PyExc_TypeError, "interpreted classes cannot inherit from compiled"); + return NULL; + } + return test_env_setup(type); +} + +static int +test_env_traverse(test___test_envObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->___mypyc_self__); + Py_VISIT(self->_transpose); + Py_VISIT(self->_multiply_matrix); + Py_VISIT(self->_mat1); + Py_VISIT(self->_mat2); + return 0; +} + +static int +test_env_clear(test___test_envObject *self) +{ + Py_CLEAR(self->___mypyc_self__); + Py_CLEAR(self->_transpose); + Py_CLEAR(self->_multiply_matrix); + Py_CLEAR(self->_mat1); + Py_CLEAR(self->_mat2); + return 0; +} + +static void +test_env_dealloc(test___test_envObject *self) +{ + PyObject_GC_UnTrack(self); + CPy_TRASHCAN_BEGIN(self, test_env_dealloc) + test_env_clear(self); + Py_TYPE(self)->tp_free((PyObject *)self); + CPy_TRASHCAN_END(self) +} + +static CPyVTableItem test_env_vtable[1]; +static bool +CPyDef_test_env_trait_vtable_setup(void) +{ + CPyVTableItem test_env_vtable_scratch[] = { + NULL + }; + memcpy(test_env_vtable, test_env_vtable_scratch, sizeof(test_env_vtable)); + return 1; +} + +static PyMethodDef test_env_methods[] = { + {"__setstate__", (PyCFunction)CPyPickle_SetState, METH_O, NULL}, + {"__getstate__", (PyCFunction)CPyPickle_GetState, METH_NOARGS, NULL}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject CPyType_test_env_template_ = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "test_env", + .tp_new = test_env_new, + .tp_dealloc = (destructor)test_env_dealloc, + .tp_traverse = (traverseproc)test_env_traverse, + .tp_clear = (inquiry)test_env_clear, + .tp_methods = test_env_methods, + .tp_basicsize = sizeof(test___test_envObject), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, +}; +static PyTypeObject *CPyType_test_env_template = &CPyType_test_env_template_; + +static PyObject * +test_env_setup(PyTypeObject *type) +{ + test___test_envObject *self; + self = (test___test_envObject *)type->tp_alloc(type, 0); + if (self == NULL) + return NULL; + self->vtable = test_env_vtable; + return (PyObject *)self; +} + +PyObject *CPyDef_test_env(void) +{ + PyObject *self = test_env_setup(CPyType_test_env); + if (self == NULL) + return NULL; + return self; +} + + +static PyObject *CPyDunder___get__transpose_test_obj(PyObject *self, PyObject *instance, PyObject *owner) { + instance = instance ? instance : Py_None; + return CPyDef_transpose_test_obj_____get__(self, instance, owner); +} +static PyObject *transpose_test_obj_setup(PyTypeObject *type); +PyObject *CPyDef_transpose_test_obj(void); + +static PyObject * +transpose_test_obj_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + if (type != CPyType_transpose_test_obj) { + PyErr_SetString(PyExc_TypeError, "interpreted classes cannot inherit from compiled"); + return NULL; + } + return transpose_test_obj_setup(type); +} + +static int +transpose_test_obj_traverse(test___transpose_test_objObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->___mypyc_env__); + _PyObject_VisitManagedDict((PyObject *)self, visit, arg); + return 0; +} + +static int +transpose_test_obj_clear(test___transpose_test_objObject *self) +{ + Py_CLEAR(self->___mypyc_env__); + _PyObject_ClearManagedDict((PyObject *)self); + return 0; +} + +static void +transpose_test_obj_dealloc(test___transpose_test_objObject *self) +{ + PyObject_GC_UnTrack(self); + CPy_TRASHCAN_BEGIN(self, transpose_test_obj_dealloc) + transpose_test_obj_clear(self); + Py_TYPE(self)->tp_free((PyObject *)self); + CPy_TRASHCAN_END(self) +} + +static CPyVTableItem transpose_test_obj_vtable[2]; +static bool +CPyDef_transpose_test_obj_trait_vtable_setup(void) +{ + CPyVTableItem transpose_test_obj_vtable_scratch[] = { + (CPyVTableItem)CPyDef_transpose_test_obj_____call__, + (CPyVTableItem)CPyDef_transpose_test_obj_____get__, + }; + memcpy(transpose_test_obj_vtable, transpose_test_obj_vtable_scratch, sizeof(transpose_test_obj_vtable)); + return 1; +} + +static PyObject * +transpose_test_obj_get___3_mypyc_env__(test___transpose_test_objObject *self, void *closure); +static int +transpose_test_obj_set___3_mypyc_env__(test___transpose_test_objObject *self, PyObject *value, void *closure); + +static PyGetSetDef transpose_test_obj_getseters[] = { + {"__mypyc_env__", + (getter)transpose_test_obj_get___3_mypyc_env__, (setter)transpose_test_obj_set___3_mypyc_env__, + NULL, NULL}, + {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, + {NULL} /* Sentinel */ +}; + +static PyMethodDef transpose_test_obj_methods[] = { + {"__call__", + (PyCFunction)CPyPy_transpose_test_obj_____call__, + METH_FASTCALL | METH_KEYWORDS, NULL}, + {"__get__", + (PyCFunction)CPyPy_transpose_test_obj_____get__, + METH_FASTCALL | METH_KEYWORDS, NULL}, + {"__setstate__", (PyCFunction)CPyPickle_SetState, METH_O, NULL}, + {"__getstate__", (PyCFunction)CPyPickle_GetState, METH_NOARGS, NULL}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject CPyType_transpose_test_obj_template_ = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "transpose_test_obj", + .tp_new = transpose_test_obj_new, + .tp_dealloc = (destructor)transpose_test_obj_dealloc, + .tp_traverse = (traverseproc)transpose_test_obj_traverse, + .tp_clear = (inquiry)transpose_test_obj_clear, + .tp_getset = transpose_test_obj_getseters, + .tp_methods = transpose_test_obj_methods, + .tp_call = PyVectorcall_Call, + .tp_descr_get = CPyDunder___get__transpose_test_obj, + .tp_basicsize = sizeof(test___transpose_test_objObject), + .tp_vectorcall_offset = offsetof(test___transpose_test_objObject, vectorcall), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | _Py_TPFLAGS_HAVE_VECTORCALL | Py_TPFLAGS_MANAGED_DICT, +}; +static PyTypeObject *CPyType_transpose_test_obj_template = &CPyType_transpose_test_obj_template_; + +static PyObject * +transpose_test_obj_setup(PyTypeObject *type) +{ + test___transpose_test_objObject *self; + self = (test___transpose_test_objObject *)type->tp_alloc(type, 0); + if (self == NULL) + return NULL; + self->vtable = transpose_test_obj_vtable; + self->vectorcall = CPyPy_transpose_test_obj_____call__; + return (PyObject *)self; +} + +PyObject *CPyDef_transpose_test_obj(void) +{ + PyObject *self = transpose_test_obj_setup(CPyType_transpose_test_obj); + if (self == NULL) + return NULL; + return self; +} + +static PyObject * +transpose_test_obj_get___3_mypyc_env__(test___transpose_test_objObject *self, void *closure) +{ + if (unlikely(self->___mypyc_env__ == NULL)) { + PyErr_SetString(PyExc_AttributeError, + "attribute '__mypyc_env__' of 'transpose_test_obj' undefined"); + return NULL; + } + CPy_INCREF(self->___mypyc_env__); + PyObject *retval = self->___mypyc_env__; + return retval; +} + +static int +transpose_test_obj_set___3_mypyc_env__(test___transpose_test_objObject *self, PyObject *value, void *closure) +{ + if (value == NULL) { + PyErr_SetString(PyExc_AttributeError, + "'transpose_test_obj' object attribute '__mypyc_env__' cannot be deleted"); + return -1; + } + if (self->___mypyc_env__ != NULL) { + CPy_DECREF(self->___mypyc_env__); + } + PyObject *tmp; + if (likely(Py_TYPE(value) == CPyType_test_env)) + tmp = value; + else { + CPy_TypeError("test.test_env", value); + tmp = NULL; + } + if (!tmp) + return -1; + CPy_INCREF(tmp); + self->___mypyc_env__ = tmp; + return 0; +} + +static PyObject *CPyDunder___get__multiply_matrix_test_obj(PyObject *self, PyObject *instance, PyObject *owner) { + instance = instance ? instance : Py_None; + return CPyDef_multiply_matrix_test_obj_____get__(self, instance, owner); +} +static PyObject *multiply_matrix_test_obj_setup(PyTypeObject *type); +PyObject *CPyDef_multiply_matrix_test_obj(void); + +static PyObject * +multiply_matrix_test_obj_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + if (type != CPyType_multiply_matrix_test_obj) { + PyErr_SetString(PyExc_TypeError, "interpreted classes cannot inherit from compiled"); + return NULL; + } + return multiply_matrix_test_obj_setup(type); +} + +static int +multiply_matrix_test_obj_traverse(test___multiply_matrix_test_objObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->___mypyc_env__); + _PyObject_VisitManagedDict((PyObject *)self, visit, arg); + return 0; +} + +static int +multiply_matrix_test_obj_clear(test___multiply_matrix_test_objObject *self) +{ + Py_CLEAR(self->___mypyc_env__); + _PyObject_ClearManagedDict((PyObject *)self); + return 0; +} + +static void +multiply_matrix_test_obj_dealloc(test___multiply_matrix_test_objObject *self) +{ + PyObject_GC_UnTrack(self); + CPy_TRASHCAN_BEGIN(self, multiply_matrix_test_obj_dealloc) + multiply_matrix_test_obj_clear(self); + Py_TYPE(self)->tp_free((PyObject *)self); + CPy_TRASHCAN_END(self) +} + +static CPyVTableItem multiply_matrix_test_obj_vtable[2]; +static bool +CPyDef_multiply_matrix_test_obj_trait_vtable_setup(void) +{ + CPyVTableItem multiply_matrix_test_obj_vtable_scratch[] = { + (CPyVTableItem)CPyDef_multiply_matrix_test_obj_____call__, + (CPyVTableItem)CPyDef_multiply_matrix_test_obj_____get__, + }; + memcpy(multiply_matrix_test_obj_vtable, multiply_matrix_test_obj_vtable_scratch, sizeof(multiply_matrix_test_obj_vtable)); + return 1; +} + +static PyObject * +multiply_matrix_test_obj_get___3_mypyc_env__(test___multiply_matrix_test_objObject *self, void *closure); +static int +multiply_matrix_test_obj_set___3_mypyc_env__(test___multiply_matrix_test_objObject *self, PyObject *value, void *closure); + +static PyGetSetDef multiply_matrix_test_obj_getseters[] = { + {"__mypyc_env__", + (getter)multiply_matrix_test_obj_get___3_mypyc_env__, (setter)multiply_matrix_test_obj_set___3_mypyc_env__, + NULL, NULL}, + {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, + {NULL} /* Sentinel */ +}; + +static PyMethodDef multiply_matrix_test_obj_methods[] = { + {"__call__", + (PyCFunction)CPyPy_multiply_matrix_test_obj_____call__, + METH_FASTCALL | METH_KEYWORDS, NULL}, + {"__get__", + (PyCFunction)CPyPy_multiply_matrix_test_obj_____get__, + METH_FASTCALL | METH_KEYWORDS, NULL}, + {"__setstate__", (PyCFunction)CPyPickle_SetState, METH_O, NULL}, + {"__getstate__", (PyCFunction)CPyPickle_GetState, METH_NOARGS, NULL}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject CPyType_multiply_matrix_test_obj_template_ = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "multiply_matrix_test_obj", + .tp_new = multiply_matrix_test_obj_new, + .tp_dealloc = (destructor)multiply_matrix_test_obj_dealloc, + .tp_traverse = (traverseproc)multiply_matrix_test_obj_traverse, + .tp_clear = (inquiry)multiply_matrix_test_obj_clear, + .tp_getset = multiply_matrix_test_obj_getseters, + .tp_methods = multiply_matrix_test_obj_methods, + .tp_call = PyVectorcall_Call, + .tp_descr_get = CPyDunder___get__multiply_matrix_test_obj, + .tp_basicsize = sizeof(test___multiply_matrix_test_objObject), + .tp_vectorcall_offset = offsetof(test___multiply_matrix_test_objObject, vectorcall), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | _Py_TPFLAGS_HAVE_VECTORCALL | Py_TPFLAGS_MANAGED_DICT, +}; +static PyTypeObject *CPyType_multiply_matrix_test_obj_template = &CPyType_multiply_matrix_test_obj_template_; + +static PyObject * +multiply_matrix_test_obj_setup(PyTypeObject *type) +{ + test___multiply_matrix_test_objObject *self; + self = (test___multiply_matrix_test_objObject *)type->tp_alloc(type, 0); + if (self == NULL) + return NULL; + self->vtable = multiply_matrix_test_obj_vtable; + self->vectorcall = CPyPy_multiply_matrix_test_obj_____call__; + return (PyObject *)self; +} + +PyObject *CPyDef_multiply_matrix_test_obj(void) +{ + PyObject *self = multiply_matrix_test_obj_setup(CPyType_multiply_matrix_test_obj); + if (self == NULL) + return NULL; + return self; +} + +static PyObject * +multiply_matrix_test_obj_get___3_mypyc_env__(test___multiply_matrix_test_objObject *self, void *closure) +{ + if (unlikely(self->___mypyc_env__ == NULL)) { + PyErr_SetString(PyExc_AttributeError, + "attribute '__mypyc_env__' of 'multiply_matrix_test_obj' undefined"); + return NULL; + } + CPy_INCREF(self->___mypyc_env__); + PyObject *retval = self->___mypyc_env__; + return retval; +} + +static int +multiply_matrix_test_obj_set___3_mypyc_env__(test___multiply_matrix_test_objObject *self, PyObject *value, void *closure) +{ + if (value == NULL) { + PyErr_SetString(PyExc_AttributeError, + "'multiply_matrix_test_obj' object attribute '__mypyc_env__' cannot be deleted"); + return -1; + } + if (self->___mypyc_env__ != NULL) { + CPy_DECREF(self->___mypyc_env__); + } + PyObject *tmp; + if (likely(Py_TYPE(value) == CPyType_test_env)) + tmp = value; + else { + CPy_TypeError("test.test_env", value); + tmp = NULL; + } + if (!tmp) + return -1; + CPy_INCREF(tmp); + self->___mypyc_env__ = tmp; + return 0; +} +static PyMethodDef module_methods[] = { + {"test", (PyCFunction)CPyPy_test, METH_FASTCALL | METH_KEYWORDS, NULL /* docstring */}, + {NULL, NULL, 0, NULL} +}; + +static struct PyModuleDef module = { + PyModuleDef_HEAD_INIT, + "test", + NULL, /* docstring */ + -1, /* size of per-interpreter state of the module, + or -1 if the module keeps state in global variables. */ + module_methods +}; + +PyMODINIT_FUNC PyInit_test(void) +{ + PyObject* modname = NULL; + if (CPyModule_test_internal) { + Py_INCREF(CPyModule_test_internal); + return CPyModule_test_internal; + } + CPyModule_test_internal = PyModule_Create(&module); + if (unlikely(CPyModule_test_internal == NULL)) + goto fail; + modname = PyObject_GetAttrString((PyObject *)CPyModule_test_internal, "__name__"); + CPyStatic_globals = PyModule_GetDict(CPyModule_test_internal); + if (unlikely(CPyStatic_globals == NULL)) + goto fail; + CPyType_test_env = (PyTypeObject *)CPyType_FromTemplate((PyObject *)CPyType_test_env_template, NULL, modname); + if (unlikely(!CPyType_test_env)) + goto fail; + CPyType_transpose_test_obj = (PyTypeObject *)CPyType_FromTemplate((PyObject *)CPyType_transpose_test_obj_template, NULL, modname); + if (unlikely(!CPyType_transpose_test_obj)) + goto fail; + CPyType_multiply_matrix_test_obj = (PyTypeObject *)CPyType_FromTemplate((PyObject *)CPyType_multiply_matrix_test_obj_template, NULL, modname); + if (unlikely(!CPyType_multiply_matrix_test_obj)) + goto fail; + if (CPyGlobalsInit() < 0) + goto fail; + char result = CPyDef___top_level__(); + if (result == 2) + goto fail; + Py_DECREF(modname); + return CPyModule_test_internal; + fail: + Py_CLEAR(CPyModule_test_internal); + Py_CLEAR(modname); + Py_CLEAR(CPyType_test_env); + Py_CLEAR(CPyType_transpose_test_obj); + Py_CLEAR(CPyType_multiply_matrix_test_obj); + return NULL; +} + +PyObject *CPyDef_transpose_test_obj_____get__(PyObject *cpy_r___mypyc_self__, PyObject *cpy_r_instance, PyObject *cpy_r_owner) { + PyObject *cpy_r_r0; + char cpy_r_r1; + PyObject *cpy_r_r2; + PyObject *cpy_r_r3; + cpy_r_r0 = (PyObject *)&_Py_NoneStruct; + cpy_r_r1 = cpy_r_instance == cpy_r_r0; + if (!cpy_r_r1) goto CPyL2; + CPy_INCREF(cpy_r___mypyc_self__); + return cpy_r___mypyc_self__; +CPyL2: ; + cpy_r_r2 = PyMethod_New(cpy_r___mypyc_self__, cpy_r_instance); + if (cpy_r_r2 == NULL) goto CPyL4; + return cpy_r_r2; +CPyL4: ; + cpy_r_r3 = NULL; + return cpy_r_r3; +} + +PyObject *CPyPy_transpose_test_obj_____get__(PyObject *self, PyObject *const *args, size_t nargs, PyObject *kwnames) { + PyObject *obj___mypyc_self__ = self; + static const char * const kwlist[] = {"instance", "owner", 0}; + static CPyArg_Parser parser = {"OO:__get__", kwlist, 0}; + PyObject *obj_instance; + PyObject *obj_owner; + if (!CPyArg_ParseStackAndKeywordsSimple(args, nargs, kwnames, &parser, &obj_instance, &obj_owner)) { + return NULL; + } + PyObject *arg___mypyc_self__ = obj___mypyc_self__; + PyObject *arg_instance = obj_instance; + PyObject *arg_owner = obj_owner; + PyObject *retval = CPyDef_transpose_test_obj_____get__(arg___mypyc_self__, arg_instance, arg_owner); + return retval; +fail: ; + CPy_AddTraceback("test.py", "__get__", -1, CPyStatic_globals); + return NULL; +} + +PyObject *CPyDef_transpose_test_obj_____call__(PyObject *cpy_r___mypyc_self__, PyObject *cpy_r_matrix) { + PyObject *cpy_r_r0; + PyObject *cpy_r_r1; + PyObject *cpy_r_r2; + PyObject *cpy_r_r3; + CPyPtr cpy_r_r4; + int64_t cpy_r_r5; + CPyTagged cpy_r_r6; + CPyTagged cpy_r_r7; + CPyTagged cpy_r_i; + char cpy_r_r8; + PyObject *cpy_r_r9; + CPyPtr cpy_r_r10; + int64_t cpy_r_r11; + CPyTagged cpy_r_r12; + CPyTagged cpy_r_r13; + CPyTagged cpy_r_j; + char cpy_r_r14; + PyObject *cpy_r_r15; + PyObject *cpy_r_r16; + PyObject *cpy_r_r17; + CPyTagged cpy_r_r18; + PyObject *cpy_r_r19; + int32_t cpy_r_r20; + char cpy_r_r21; + CPyTagged cpy_r_r22; + int32_t cpy_r_r23; + char cpy_r_r24; + CPyTagged cpy_r_r25; + PyObject *cpy_r_r26; + cpy_r_r0 = ((test___transpose_test_objObject *)cpy_r___mypyc_self__)->___mypyc_env__; + if (unlikely(cpy_r_r0 == NULL)) { + CPy_AttributeError("test.py", "transpose", "transpose_test_obj", "__mypyc_env__", 4, CPyStatic_globals); + goto CPyL18; + } + CPy_INCREF(cpy_r_r0); + goto CPyL19; +CPyL1: ; + cpy_r_r1 = PyList_New(0); + if (unlikely(cpy_r_r1 == NULL)) { + CPy_AddTraceback("test.py", "transpose", 5, CPyStatic_globals); + goto CPyL18; + } + cpy_r_r2 = CPyList_GetItemShortBorrow(cpy_r_matrix, 0); + if (unlikely(cpy_r_r2 == NULL)) { + CPy_AddTraceback("test.py", "transpose", 5, CPyStatic_globals); + goto CPyL20; + } + if (likely(PyList_Check(cpy_r_r2))) + cpy_r_r3 = cpy_r_r2; + else { + CPy_TypeErrorTraceback("test.py", "transpose", 5, CPyStatic_globals, "list", cpy_r_r2); + goto CPyL20; + } + cpy_r_r4 = (CPyPtr)&((PyVarObject *)cpy_r_r3)->ob_size; + cpy_r_r5 = *(int64_t *)cpy_r_r4; + cpy_r_r6 = cpy_r_r5 << 1; + cpy_r_r7 = 0; + cpy_r_i = cpy_r_r7; +CPyL5: ; + cpy_r_r8 = (Py_ssize_t)cpy_r_r7 < (Py_ssize_t)cpy_r_r6; + if (!cpy_r_r8) goto CPyL21; + cpy_r_r9 = PyList_New(0); + if (unlikely(cpy_r_r9 == NULL)) { + CPy_AddTraceback("test.py", "transpose", 5, CPyStatic_globals); + goto CPyL22; + } + cpy_r_r10 = (CPyPtr)&((PyVarObject *)cpy_r_matrix)->ob_size; + cpy_r_r11 = *(int64_t *)cpy_r_r10; + cpy_r_r12 = cpy_r_r11 << 1; + cpy_r_r13 = 0; + cpy_r_j = cpy_r_r13; +CPyL8: ; + cpy_r_r14 = (Py_ssize_t)cpy_r_r13 < (Py_ssize_t)cpy_r_r12; + if (!cpy_r_r14) goto CPyL23; + cpy_r_r15 = CPyList_GetItemBorrow(cpy_r_matrix, cpy_r_j); + if (unlikely(cpy_r_r15 == NULL)) { + CPy_AddTraceback("test.py", "transpose", 5, CPyStatic_globals); + goto CPyL24; + } + if (likely(PyList_Check(cpy_r_r15))) + cpy_r_r16 = cpy_r_r15; + else { + CPy_TypeErrorTraceback("test.py", "transpose", 5, CPyStatic_globals, "list", cpy_r_r15); + goto CPyL24; + } + cpy_r_r17 = CPyList_GetItem(cpy_r_r16, cpy_r_i); + if (unlikely(cpy_r_r17 == NULL)) { + CPy_AddTraceback("test.py", "transpose", 5, CPyStatic_globals); + goto CPyL24; + } + if (likely(PyLong_Check(cpy_r_r17))) + cpy_r_r18 = CPyTagged_FromObject(cpy_r_r17); + else { + CPy_TypeError("int", cpy_r_r17); cpy_r_r18 = CPY_INT_TAG; + } + CPy_DECREF(cpy_r_r17); + if (unlikely(cpy_r_r18 == CPY_INT_TAG)) { + CPy_AddTraceback("test.py", "transpose", 5, CPyStatic_globals); + goto CPyL24; + } + CPyTagged_DECREF(cpy_r_j); + cpy_r_r19 = CPyTagged_StealAsObject(cpy_r_r18); + cpy_r_r20 = PyList_Append(cpy_r_r9, cpy_r_r19); + CPy_DECREF(cpy_r_r19); + cpy_r_r21 = cpy_r_r20 >= 0; + if (unlikely(!cpy_r_r21)) { + CPy_AddTraceback("test.py", "transpose", 5, CPyStatic_globals); + goto CPyL25; + } + cpy_r_r22 = cpy_r_r13 + 2; + cpy_r_r13 = cpy_r_r22; + cpy_r_j = cpy_r_r22; + goto CPyL8; +CPyL15: ; + cpy_r_r23 = PyList_Append(cpy_r_r1, cpy_r_r9); + CPy_DECREF(cpy_r_r9); + cpy_r_r24 = cpy_r_r23 >= 0; + if (unlikely(!cpy_r_r24)) { + CPy_AddTraceback("test.py", "transpose", 5, CPyStatic_globals); + goto CPyL20; + } + cpy_r_r25 = cpy_r_r7 + 2; + cpy_r_r7 = cpy_r_r25; + cpy_r_i = cpy_r_r25; + goto CPyL5; +CPyL17: ; + return cpy_r_r1; +CPyL18: ; + cpy_r_r26 = NULL; + return cpy_r_r26; +CPyL19: ; + CPy_DECREF(cpy_r_r0); + goto CPyL1; +CPyL20: ; + CPy_DecRef(cpy_r_r1); + goto CPyL18; +CPyL21: ; + CPyTagged_DECREF(cpy_r_i); + goto CPyL17; +CPyL22: ; + CPy_DecRef(cpy_r_r1); + CPyTagged_DecRef(cpy_r_i); + goto CPyL18; +CPyL23: ; + CPyTagged_DECREF(cpy_r_i); + CPyTagged_DECREF(cpy_r_j); + goto CPyL15; +CPyL24: ; + CPy_DecRef(cpy_r_r1); + CPyTagged_DecRef(cpy_r_i); + CPy_DecRef(cpy_r_r9); + CPyTagged_DecRef(cpy_r_j); + goto CPyL18; +CPyL25: ; + CPy_DecRef(cpy_r_r1); + CPyTagged_DecRef(cpy_r_i); + CPy_DecRef(cpy_r_r9); + goto CPyL18; +} + +PyObject *CPyPy_transpose_test_obj_____call__(PyObject *self, PyObject *const *args, size_t nargs, PyObject *kwnames) { + PyObject *obj___mypyc_self__ = self; + static const char * const kwlist[] = {"matrix", 0}; + static CPyArg_Parser parser = {"O:__call__", kwlist, 0}; + PyObject *obj_matrix; + if (!CPyArg_ParseStackAndKeywordsOneArg(args, PyVectorcall_NARGS(nargs), kwnames, &parser, &obj_matrix)) { + return NULL; + } + PyObject *arg___mypyc_self__ = obj___mypyc_self__; + PyObject *arg_matrix; + if (likely(PyList_Check(obj_matrix))) + arg_matrix = obj_matrix; + else { + CPy_TypeError("list", obj_matrix); + goto fail; + } + PyObject *retval = CPyDef_transpose_test_obj_____call__(arg___mypyc_self__, arg_matrix); + return retval; +fail: ; + CPy_AddTraceback("test.py", "transpose", 4, CPyStatic_globals); + return NULL; +} + +PyObject *CPyDef_multiply_matrix_test_obj_____get__(PyObject *cpy_r___mypyc_self__, PyObject *cpy_r_instance, PyObject *cpy_r_owner) { + PyObject *cpy_r_r0; + char cpy_r_r1; + PyObject *cpy_r_r2; + PyObject *cpy_r_r3; + cpy_r_r0 = (PyObject *)&_Py_NoneStruct; + cpy_r_r1 = cpy_r_instance == cpy_r_r0; + if (!cpy_r_r1) goto CPyL2; + CPy_INCREF(cpy_r___mypyc_self__); + return cpy_r___mypyc_self__; +CPyL2: ; + cpy_r_r2 = PyMethod_New(cpy_r___mypyc_self__, cpy_r_instance); + if (cpy_r_r2 == NULL) goto CPyL4; + return cpy_r_r2; +CPyL4: ; + cpy_r_r3 = NULL; + return cpy_r_r3; +} + +PyObject *CPyPy_multiply_matrix_test_obj_____get__(PyObject *self, PyObject *const *args, size_t nargs, PyObject *kwnames) { + PyObject *obj___mypyc_self__ = self; + static const char * const kwlist[] = {"instance", "owner", 0}; + static CPyArg_Parser parser = {"OO:__get__", kwlist, 0}; + PyObject *obj_instance; + PyObject *obj_owner; + if (!CPyArg_ParseStackAndKeywordsSimple(args, nargs, kwnames, &parser, &obj_instance, &obj_owner)) { + return NULL; + } + PyObject *arg___mypyc_self__ = obj___mypyc_self__; + PyObject *arg_instance = obj_instance; + PyObject *arg_owner = obj_owner; + PyObject *retval = CPyDef_multiply_matrix_test_obj_____get__(arg___mypyc_self__, arg_instance, arg_owner); + return retval; +fail: ; + CPy_AddTraceback("test.py", "__get__", -1, CPyStatic_globals); + return NULL; +} + +PyObject *CPyDef_multiply_matrix_test_obj_____call__(PyObject *cpy_r___mypyc_self__, PyObject *cpy_r_matrix1, PyObject *cpy_r_matrix2) { + PyObject *cpy_r_r0; + CPyPtr cpy_r_r1; + int64_t cpy_r_r2; + PyObject *cpy_r_r3; + CPyTagged cpy_r_r4; + CPyPtr cpy_r_r5; + int64_t cpy_r_r6; + CPyTagged cpy_r_r7; + char cpy_r_r8; + PyObject *cpy_r_r9; + PyObject *cpy_r_r10; + PyObject *cpy_r_X_row; + PyObject *cpy_r_r11; + PyObject *cpy_r_r12; + PyObject *cpy_r_r13; + PyObject *cpy_r_r14; + PyObject *cpy_r_r15; + PyObject *cpy_r_r16; + PyObject *cpy_r_r17; + PyObject *cpy_r_r18; + PyObject *cpy_r_r19; + PyObject *cpy_r_r20; + PyObject *cpy_r_r21; + PyObject *cpy_r_r22; + PyObject *cpy_r_Y_col; + CPyTagged cpy_r_r23; + CPyTagged cpy_r_r24; + CPyTagged cpy_r_r25; + CPyPtr cpy_r_r26; + int64_t cpy_r_r27; + CPyTagged cpy_r_r28; + char cpy_r_r29; + CPyPtr cpy_r_r30; + int64_t cpy_r_r31; + CPyTagged cpy_r_r32; + char cpy_r_r33; + PyObject *cpy_r_r34; + CPyTagged cpy_r_r35; + CPyTagged cpy_r_a; + PyObject *cpy_r_r36; + PyObject *cpy_r_b; + PyObject *cpy_r_r37; + PyObject *cpy_r_r38; + PyObject *cpy_r_r39; + PyObject *cpy_r_r40; + CPyTagged cpy_r_r41; + CPyTagged cpy_r_r42; + CPyTagged cpy_r_r43; + PyObject *cpy_r_r44; + int32_t cpy_r_r45; + char cpy_r_r46; + char cpy_r_r47; + char cpy_r_r48; + CPyTagged cpy_r_r49; + PyObject *cpy_r_r50; + cpy_r_r0 = ((test___multiply_matrix_test_objObject *)cpy_r___mypyc_self__)->___mypyc_env__; + if (unlikely(cpy_r_r0 == NULL)) { + CPy_AttributeError("test.py", "multiply_matrix", "multiply_matrix_test_obj", "__mypyc_env__", 9, CPyStatic_globals); + goto CPyL30; + } + CPy_INCREF(cpy_r_r0); + goto CPyL31; +CPyL1: ; + cpy_r_r1 = (CPyPtr)&((PyVarObject *)cpy_r_matrix1)->ob_size; + cpy_r_r2 = *(int64_t *)cpy_r_r1; + cpy_r_r3 = PyList_New(cpy_r_r2); + if (unlikely(cpy_r_r3 == NULL)) { + CPy_AddTraceback("test.py", "multiply_matrix", 10, CPyStatic_globals); + goto CPyL30; + } + cpy_r_r4 = 0; +CPyL3: ; + cpy_r_r5 = (CPyPtr)&((PyVarObject *)cpy_r_matrix1)->ob_size; + cpy_r_r6 = *(int64_t *)cpy_r_r5; + cpy_r_r7 = cpy_r_r6 << 1; + cpy_r_r8 = (Py_ssize_t)cpy_r_r4 < (Py_ssize_t)cpy_r_r7; + if (!cpy_r_r8) goto CPyL29; + cpy_r_r9 = CPyList_GetItemUnsafe(cpy_r_matrix1, cpy_r_r4); + if (likely(PyList_Check(cpy_r_r9))) + cpy_r_r10 = cpy_r_r9; + else { + CPy_TypeErrorTraceback("test.py", "multiply_matrix", 10, CPyStatic_globals, "list", cpy_r_r9); + goto CPyL32; + } + cpy_r_X_row = cpy_r_r10; + cpy_r_r11 = PyList_New(0); + if (unlikely(cpy_r_r11 == NULL)) { + CPy_AddTraceback("test.py", "multiply_matrix", 10, CPyStatic_globals); + goto CPyL33; + } + cpy_r_r12 = CPyModule_builtins; + cpy_r_r13 = CPyStatics[3]; /* 'zip' */ + cpy_r_r14 = CPyObject_GetAttr(cpy_r_r12, cpy_r_r13); + if (unlikely(cpy_r_r14 == NULL)) { + CPy_AddTraceback("test.py", "multiply_matrix", 10, CPyStatic_globals); + goto CPyL34; + } + cpy_r_r15 = PyList_New(0); + if (unlikely(cpy_r_r15 == NULL)) { + CPy_AddTraceback("test.py", "multiply_matrix", 10, CPyStatic_globals); + goto CPyL35; + } + cpy_r_r16 = CPyList_Extend(cpy_r_r15, cpy_r_matrix2); + if (unlikely(cpy_r_r16 == NULL)) { + CPy_AddTraceback("test.py", "multiply_matrix", 10, CPyStatic_globals); + goto CPyL36; + } else + goto CPyL37; +CPyL9: ; + cpy_r_r17 = PyList_AsTuple(cpy_r_r15); + CPy_DECREF(cpy_r_r15); + if (unlikely(cpy_r_r17 == NULL)) { + CPy_AddTraceback("test.py", "multiply_matrix", 10, CPyStatic_globals); + goto CPyL35; + } + cpy_r_r18 = PyDict_New(); + if (unlikely(cpy_r_r18 == NULL)) { + CPy_AddTraceback("test.py", "multiply_matrix", 10, CPyStatic_globals); + goto CPyL38; + } + cpy_r_r19 = PyObject_Call(cpy_r_r14, cpy_r_r17, cpy_r_r18); + CPy_DECREF(cpy_r_r14); + CPy_DECREF(cpy_r_r17); + CPy_DECREF(cpy_r_r18); + if (unlikely(cpy_r_r19 == NULL)) { + CPy_AddTraceback("test.py", "multiply_matrix", 10, CPyStatic_globals); + goto CPyL34; + } + cpy_r_r20 = PyObject_GetIter(cpy_r_r19); + CPy_DECREF(cpy_r_r19); + if (unlikely(cpy_r_r20 == NULL)) { + CPy_AddTraceback("test.py", "multiply_matrix", 10, CPyStatic_globals); + goto CPyL34; + } +CPyL13: ; + cpy_r_r21 = PyIter_Next(cpy_r_r20); + if (cpy_r_r21 == NULL) goto CPyL39; + if (likely(PyTuple_Check(cpy_r_r21))) + cpy_r_r22 = cpy_r_r21; + else { + CPy_TypeErrorTraceback("test.py", "multiply_matrix", 10, CPyStatic_globals, "tuple", cpy_r_r21); + goto CPyL40; + } + cpy_r_Y_col = cpy_r_r22; + cpy_r_r23 = 0; + cpy_r_r24 = 0; + cpy_r_r25 = 0; +CPyL16: ; + cpy_r_r26 = (CPyPtr)&((PyVarObject *)cpy_r_X_row)->ob_size; + cpy_r_r27 = *(int64_t *)cpy_r_r26; + cpy_r_r28 = cpy_r_r27 << 1; + cpy_r_r29 = (Py_ssize_t)cpy_r_r24 < (Py_ssize_t)cpy_r_r28; + if (!cpy_r_r29) goto CPyL41; + cpy_r_r30 = (CPyPtr)&((PyVarObject *)cpy_r_Y_col)->ob_size; + cpy_r_r31 = *(int64_t *)cpy_r_r30; + cpy_r_r32 = cpy_r_r31 << 1; + cpy_r_r33 = (Py_ssize_t)cpy_r_r25 < (Py_ssize_t)cpy_r_r32; + if (!cpy_r_r33) goto CPyL41; + cpy_r_r34 = CPyList_GetItemUnsafe(cpy_r_X_row, cpy_r_r24); + if (likely(PyLong_Check(cpy_r_r34))) + cpy_r_r35 = CPyTagged_FromObject(cpy_r_r34); + else { + CPy_TypeError("int", cpy_r_r34); cpy_r_r35 = CPY_INT_TAG; + } + CPy_DECREF(cpy_r_r34); + if (unlikely(cpy_r_r35 == CPY_INT_TAG)) { + CPy_AddTraceback("test.py", "multiply_matrix", 10, CPyStatic_globals); + goto CPyL42; + } + cpy_r_a = cpy_r_r35; + cpy_r_r36 = CPySequenceTuple_GetItem(cpy_r_Y_col, cpy_r_r25); + if (unlikely(cpy_r_r36 == NULL)) { + CPy_AddTraceback("test.py", "multiply_matrix", 10, CPyStatic_globals); + goto CPyL43; + } + cpy_r_b = cpy_r_r36; + cpy_r_r37 = CPyTagged_StealAsObject(cpy_r_a); + cpy_r_r38 = PyNumber_Multiply(cpy_r_r37, cpy_r_b); + CPy_DECREF(cpy_r_r37); + CPy_DECREF(cpy_r_b); + if (unlikely(cpy_r_r38 == NULL)) { + CPy_AddTraceback("test.py", "multiply_matrix", 10, CPyStatic_globals); + goto CPyL42; + } + cpy_r_r39 = CPyTagged_StealAsObject(cpy_r_r23); + cpy_r_r40 = PyNumber_Add(cpy_r_r39, cpy_r_r38); + CPy_DECREF(cpy_r_r39); + CPy_DECREF(cpy_r_r38); + if (unlikely(cpy_r_r40 == NULL)) { + CPy_AddTraceback("test.py", "multiply_matrix", -1, CPyStatic_globals); + goto CPyL44; + } + if (likely(PyLong_Check(cpy_r_r40))) + cpy_r_r41 = CPyTagged_FromObject(cpy_r_r40); + else { + CPy_TypeError("int", cpy_r_r40); cpy_r_r41 = CPY_INT_TAG; + } + CPy_DECREF(cpy_r_r40); + if (unlikely(cpy_r_r41 == CPY_INT_TAG)) { + CPy_AddTraceback("test.py", "multiply_matrix", -1, CPyStatic_globals); + goto CPyL44; + } + cpy_r_r23 = cpy_r_r41; + cpy_r_r42 = cpy_r_r24 + 2; + cpy_r_r24 = cpy_r_r42; + cpy_r_r43 = cpy_r_r25 + 2; + cpy_r_r25 = cpy_r_r43; + goto CPyL16; +CPyL25: ; + cpy_r_r44 = CPyTagged_StealAsObject(cpy_r_r23); + cpy_r_r45 = PyList_Append(cpy_r_r11, cpy_r_r44); + CPy_DECREF(cpy_r_r44); + cpy_r_r46 = cpy_r_r45 >= 0; + if (unlikely(!cpy_r_r46)) { + CPy_AddTraceback("test.py", "multiply_matrix", 10, CPyStatic_globals); + goto CPyL40; + } else + goto CPyL13; +CPyL26: ; + cpy_r_r47 = CPy_NoErrOccured(); + if (unlikely(!cpy_r_r47)) { + CPy_AddTraceback("test.py", "multiply_matrix", 10, CPyStatic_globals); + goto CPyL45; + } + cpy_r_r48 = CPyList_SetItemUnsafe(cpy_r_r3, cpy_r_r4, cpy_r_r11); + if (unlikely(!cpy_r_r48)) { + CPy_AddTraceback("test.py", "multiply_matrix", 10, CPyStatic_globals); + goto CPyL32; + } + cpy_r_r49 = cpy_r_r4 + 2; + cpy_r_r4 = cpy_r_r49; + goto CPyL3; +CPyL29: ; + return cpy_r_r3; +CPyL30: ; + cpy_r_r50 = NULL; + return cpy_r_r50; +CPyL31: ; + CPy_DECREF(cpy_r_r0); + goto CPyL1; +CPyL32: ; + CPy_DecRef(cpy_r_r3); + goto CPyL30; +CPyL33: ; + CPy_DecRef(cpy_r_r3); + CPy_DecRef(cpy_r_X_row); + goto CPyL30; +CPyL34: ; + CPy_DecRef(cpy_r_r3); + CPy_DecRef(cpy_r_X_row); + CPy_DecRef(cpy_r_r11); + goto CPyL30; +CPyL35: ; + CPy_DecRef(cpy_r_r3); + CPy_DecRef(cpy_r_X_row); + CPy_DecRef(cpy_r_r11); + CPy_DecRef(cpy_r_r14); + goto CPyL30; +CPyL36: ; + CPy_DecRef(cpy_r_r3); + CPy_DecRef(cpy_r_X_row); + CPy_DecRef(cpy_r_r11); + CPy_DecRef(cpy_r_r14); + CPy_DecRef(cpy_r_r15); + goto CPyL30; +CPyL37: ; + CPy_DECREF(cpy_r_r16); + goto CPyL9; +CPyL38: ; + CPy_DecRef(cpy_r_r3); + CPy_DecRef(cpy_r_X_row); + CPy_DecRef(cpy_r_r11); + CPy_DecRef(cpy_r_r14); + CPy_DecRef(cpy_r_r17); + goto CPyL30; +CPyL39: ; + CPy_DECREF(cpy_r_X_row); + CPy_DECREF(cpy_r_r20); + goto CPyL26; +CPyL40: ; + CPy_DecRef(cpy_r_r3); + CPy_DecRef(cpy_r_X_row); + CPy_DecRef(cpy_r_r11); + CPy_DecRef(cpy_r_r20); + goto CPyL30; +CPyL41: ; + CPy_DECREF(cpy_r_Y_col); + goto CPyL25; +CPyL42: ; + CPy_DecRef(cpy_r_r3); + CPy_DecRef(cpy_r_X_row); + CPy_DecRef(cpy_r_r11); + CPy_DecRef(cpy_r_r20); + CPy_DecRef(cpy_r_Y_col); + CPyTagged_DecRef(cpy_r_r23); + goto CPyL30; +CPyL43: ; + CPy_DecRef(cpy_r_r3); + CPy_DecRef(cpy_r_X_row); + CPy_DecRef(cpy_r_r11); + CPy_DecRef(cpy_r_r20); + CPy_DecRef(cpy_r_Y_col); + CPyTagged_DecRef(cpy_r_r23); + CPyTagged_DecRef(cpy_r_a); + goto CPyL30; +CPyL44: ; + CPy_DecRef(cpy_r_r3); + CPy_DecRef(cpy_r_X_row); + CPy_DecRef(cpy_r_r11); + CPy_DecRef(cpy_r_r20); + CPy_DecRef(cpy_r_Y_col); + goto CPyL30; +CPyL45: ; + CPy_DecRef(cpy_r_r3); + CPy_DecRef(cpy_r_r11); + goto CPyL30; +} + +PyObject *CPyPy_multiply_matrix_test_obj_____call__(PyObject *self, PyObject *const *args, size_t nargs, PyObject *kwnames) { + PyObject *obj___mypyc_self__ = self; + static const char * const kwlist[] = {"matrix1", "matrix2", 0}; + static CPyArg_Parser parser = {"OO:__call__", kwlist, 0}; + PyObject *obj_matrix1; + PyObject *obj_matrix2; + if (!CPyArg_ParseStackAndKeywordsSimple(args, PyVectorcall_NARGS(nargs), kwnames, &parser, &obj_matrix1, &obj_matrix2)) { + return NULL; + } + PyObject *arg___mypyc_self__ = obj___mypyc_self__; + PyObject *arg_matrix1; + if (likely(PyList_Check(obj_matrix1))) + arg_matrix1 = obj_matrix1; + else { + CPy_TypeError("list", obj_matrix1); + goto fail; + } + PyObject *arg_matrix2; + if (likely(PyList_Check(obj_matrix2))) + arg_matrix2 = obj_matrix2; + else { + CPy_TypeError("list", obj_matrix2); + goto fail; + } + PyObject *retval = CPyDef_multiply_matrix_test_obj_____call__(arg___mypyc_self__, arg_matrix1, arg_matrix2); + return retval; +fail: ; + CPy_AddTraceback("test.py", "multiply_matrix", 9, CPyStatic_globals); + return NULL; +} + +PyObject *CPyDef_test(void) { + PyObject *cpy_r_r0; + PyObject *cpy_r_r1; + PyObject *cpy_r_r2; + PyObject *cpy_r_r3; + PyObject *cpy_r_r4; + CPyPtr cpy_r_r5; + CPyPtr cpy_r_r6; + CPyPtr cpy_r_r7; + CPyPtr cpy_r_r8; + PyObject *cpy_r_r9; + PyObject *cpy_r_r10; + PyObject *cpy_r_r11; + PyObject *cpy_r_r12; + CPyPtr cpy_r_r13; + CPyPtr cpy_r_r14; + CPyPtr cpy_r_r15; + CPyPtr cpy_r_r16; + PyObject *cpy_r_r17; + PyObject *cpy_r_r18; + PyObject *cpy_r_r19; + PyObject *cpy_r_r20; + CPyPtr cpy_r_r21; + CPyPtr cpy_r_r22; + CPyPtr cpy_r_r23; + CPyPtr cpy_r_r24; + PyObject *cpy_r_r25; + CPyPtr cpy_r_r26; + CPyPtr cpy_r_r27; + CPyPtr cpy_r_r28; + CPyPtr cpy_r_r29; + PyObject *cpy_r_mat1; + PyObject *cpy_r_r30; + PyObject *cpy_r_r31; + PyObject *cpy_r_r32; + PyObject *cpy_r_r33; + CPyPtr cpy_r_r34; + CPyPtr cpy_r_r35; + CPyPtr cpy_r_r36; + CPyPtr cpy_r_r37; + PyObject *cpy_r_r38; + PyObject *cpy_r_r39; + PyObject *cpy_r_r40; + PyObject *cpy_r_r41; + CPyPtr cpy_r_r42; + CPyPtr cpy_r_r43; + CPyPtr cpy_r_r44; + CPyPtr cpy_r_r45; + PyObject *cpy_r_r46; + PyObject *cpy_r_r47; + PyObject *cpy_r_r48; + PyObject *cpy_r_r49; + CPyPtr cpy_r_r50; + CPyPtr cpy_r_r51; + CPyPtr cpy_r_r52; + CPyPtr cpy_r_r53; + PyObject *cpy_r_r54; + CPyPtr cpy_r_r55; + CPyPtr cpy_r_r56; + CPyPtr cpy_r_r57; + CPyPtr cpy_r_r58; + PyObject *cpy_r_mat2; + PyObject *cpy_r_r59; + char cpy_r_r60; + PyObject *cpy_r_transpose; + PyObject **cpy_r_r62; + PyObject *cpy_r_r63; + PyObject *cpy_r_r64; + PyObject *cpy_r_r65; + PyObject *cpy_r_r66; + PyObject **cpy_r_r68; + PyObject *cpy_r_r69; + PyObject *cpy_r_r70; + char cpy_r_r71; + PyObject *cpy_r_multiply_matrix; + PyObject **cpy_r_r73; + PyObject *cpy_r_r74; + PyObject *cpy_r_r75; + PyObject *cpy_r_r76; + PyObject *cpy_r_r77; + PyObject **cpy_r_r79; + PyObject *cpy_r_r80; + PyObject *cpy_r_r81; + PyObject *cpy_r_r82; + cpy_r_r0 = CPyDef_test_env(); + if (unlikely(cpy_r_r0 == NULL)) { + CPy_AddTraceback("test.py", "test", 1, CPyStatic_globals); + goto CPyL20; + } + cpy_r_r1 = PyList_New(3); + if (unlikely(cpy_r_r1 == NULL)) { + CPy_AddTraceback("test.py", "test", 2, CPyStatic_globals); + goto CPyL21; + } + cpy_r_r2 = CPyStatics[14]; /* 1 */ + cpy_r_r3 = CPyStatics[15]; /* 2 */ + cpy_r_r4 = CPyStatics[16]; /* 3 */ + cpy_r_r5 = (CPyPtr)&((PyListObject *)cpy_r_r1)->ob_item; + cpy_r_r6 = *(CPyPtr *)cpy_r_r5; + CPy_INCREF(cpy_r_r2); + *(PyObject * *)cpy_r_r6 = cpy_r_r2; + cpy_r_r7 = cpy_r_r6 + 8; + CPy_INCREF(cpy_r_r3); + *(PyObject * *)cpy_r_r7 = cpy_r_r3; + cpy_r_r8 = cpy_r_r6 + 16; + CPy_INCREF(cpy_r_r4); + *(PyObject * *)cpy_r_r8 = cpy_r_r4; + cpy_r_r9 = PyList_New(3); + if (unlikely(cpy_r_r9 == NULL)) { + CPy_AddTraceback("test.py", "test", 2, CPyStatic_globals); + goto CPyL22; + } + cpy_r_r10 = CPyStatics[17]; /* 4 */ + cpy_r_r11 = CPyStatics[18]; /* 5 */ + cpy_r_r12 = CPyStatics[19]; /* 6 */ + cpy_r_r13 = (CPyPtr)&((PyListObject *)cpy_r_r9)->ob_item; + cpy_r_r14 = *(CPyPtr *)cpy_r_r13; + CPy_INCREF(cpy_r_r10); + *(PyObject * *)cpy_r_r14 = cpy_r_r10; + cpy_r_r15 = cpy_r_r14 + 8; + CPy_INCREF(cpy_r_r11); + *(PyObject * *)cpy_r_r15 = cpy_r_r11; + cpy_r_r16 = cpy_r_r14 + 16; + CPy_INCREF(cpy_r_r12); + *(PyObject * *)cpy_r_r16 = cpy_r_r12; + cpy_r_r17 = PyList_New(3); + if (unlikely(cpy_r_r17 == NULL)) { + CPy_AddTraceback("test.py", "test", 2, CPyStatic_globals); + goto CPyL23; + } + cpy_r_r18 = CPyStatics[20]; /* 7 */ + cpy_r_r19 = CPyStatics[21]; /* 8 */ + cpy_r_r20 = CPyStatics[22]; /* 9 */ + cpy_r_r21 = (CPyPtr)&((PyListObject *)cpy_r_r17)->ob_item; + cpy_r_r22 = *(CPyPtr *)cpy_r_r21; + CPy_INCREF(cpy_r_r18); + *(PyObject * *)cpy_r_r22 = cpy_r_r18; + cpy_r_r23 = cpy_r_r22 + 8; + CPy_INCREF(cpy_r_r19); + *(PyObject * *)cpy_r_r23 = cpy_r_r19; + cpy_r_r24 = cpy_r_r22 + 16; + CPy_INCREF(cpy_r_r20); + *(PyObject * *)cpy_r_r24 = cpy_r_r20; + cpy_r_r25 = PyList_New(3); + if (unlikely(cpy_r_r25 == NULL)) { + CPy_AddTraceback("test.py", "test", 2, CPyStatic_globals); + goto CPyL24; + } + cpy_r_r26 = (CPyPtr)&((PyListObject *)cpy_r_r25)->ob_item; + cpy_r_r27 = *(CPyPtr *)cpy_r_r26; + *(PyObject * *)cpy_r_r27 = cpy_r_r1; + cpy_r_r28 = cpy_r_r27 + 8; + *(PyObject * *)cpy_r_r28 = cpy_r_r9; + cpy_r_r29 = cpy_r_r27 + 16; + *(PyObject * *)cpy_r_r29 = cpy_r_r17; + cpy_r_mat1 = cpy_r_r25; + cpy_r_r30 = PyList_New(3); + if (unlikely(cpy_r_r30 == NULL)) { + CPy_AddTraceback("test.py", "test", 3, CPyStatic_globals); + goto CPyL25; + } + cpy_r_r31 = CPyStatics[14]; /* 1 */ + cpy_r_r32 = CPyStatics[15]; /* 2 */ + cpy_r_r33 = CPyStatics[16]; /* 3 */ + cpy_r_r34 = (CPyPtr)&((PyListObject *)cpy_r_r30)->ob_item; + cpy_r_r35 = *(CPyPtr *)cpy_r_r34; + CPy_INCREF(cpy_r_r31); + *(PyObject * *)cpy_r_r35 = cpy_r_r31; + cpy_r_r36 = cpy_r_r35 + 8; + CPy_INCREF(cpy_r_r32); + *(PyObject * *)cpy_r_r36 = cpy_r_r32; + cpy_r_r37 = cpy_r_r35 + 16; + CPy_INCREF(cpy_r_r33); + *(PyObject * *)cpy_r_r37 = cpy_r_r33; + cpy_r_r38 = PyList_New(3); + if (unlikely(cpy_r_r38 == NULL)) { + CPy_AddTraceback("test.py", "test", 3, CPyStatic_globals); + goto CPyL26; + } + cpy_r_r39 = CPyStatics[17]; /* 4 */ + cpy_r_r40 = CPyStatics[18]; /* 5 */ + cpy_r_r41 = CPyStatics[19]; /* 6 */ + cpy_r_r42 = (CPyPtr)&((PyListObject *)cpy_r_r38)->ob_item; + cpy_r_r43 = *(CPyPtr *)cpy_r_r42; + CPy_INCREF(cpy_r_r39); + *(PyObject * *)cpy_r_r43 = cpy_r_r39; + cpy_r_r44 = cpy_r_r43 + 8; + CPy_INCREF(cpy_r_r40); + *(PyObject * *)cpy_r_r44 = cpy_r_r40; + cpy_r_r45 = cpy_r_r43 + 16; + CPy_INCREF(cpy_r_r41); + *(PyObject * *)cpy_r_r45 = cpy_r_r41; + cpy_r_r46 = PyList_New(3); + if (unlikely(cpy_r_r46 == NULL)) { + CPy_AddTraceback("test.py", "test", 3, CPyStatic_globals); + goto CPyL27; + } + cpy_r_r47 = CPyStatics[20]; /* 7 */ + cpy_r_r48 = CPyStatics[21]; /* 8 */ + cpy_r_r49 = CPyStatics[22]; /* 9 */ + cpy_r_r50 = (CPyPtr)&((PyListObject *)cpy_r_r46)->ob_item; + cpy_r_r51 = *(CPyPtr *)cpy_r_r50; + CPy_INCREF(cpy_r_r47); + *(PyObject * *)cpy_r_r51 = cpy_r_r47; + cpy_r_r52 = cpy_r_r51 + 8; + CPy_INCREF(cpy_r_r48); + *(PyObject * *)cpy_r_r52 = cpy_r_r48; + cpy_r_r53 = cpy_r_r51 + 16; + CPy_INCREF(cpy_r_r49); + *(PyObject * *)cpy_r_r53 = cpy_r_r49; + cpy_r_r54 = PyList_New(3); + if (unlikely(cpy_r_r54 == NULL)) { + CPy_AddTraceback("test.py", "test", 3, CPyStatic_globals); + goto CPyL28; + } + cpy_r_r55 = (CPyPtr)&((PyListObject *)cpy_r_r54)->ob_item; + cpy_r_r56 = *(CPyPtr *)cpy_r_r55; + *(PyObject * *)cpy_r_r56 = cpy_r_r30; + cpy_r_r57 = cpy_r_r56 + 8; + *(PyObject * *)cpy_r_r57 = cpy_r_r38; + cpy_r_r58 = cpy_r_r56 + 16; + *(PyObject * *)cpy_r_r58 = cpy_r_r46; + cpy_r_mat2 = cpy_r_r54; + cpy_r_r59 = CPyDef_transpose_test_obj(); + if (unlikely(cpy_r_r59 == NULL)) { + CPy_AddTraceback("test.py", "test", 4, CPyStatic_globals); + goto CPyL29; + } + CPy_INCREF(cpy_r_r0); + if (((test___transpose_test_objObject *)cpy_r_r59)->___mypyc_env__ != NULL) { + CPy_DECREF(((test___transpose_test_objObject *)cpy_r_r59)->___mypyc_env__); + } + ((test___transpose_test_objObject *)cpy_r_r59)->___mypyc_env__ = cpy_r_r0; + cpy_r_r60 = 1; + if (unlikely(!cpy_r_r60)) { + CPy_AddTraceback("test.py", "test", 4, CPyStatic_globals); + goto CPyL30; + } + cpy_r_transpose = cpy_r_r59; + PyObject *cpy_r_r61[1] = {cpy_r_mat1}; + cpy_r_r62 = (PyObject **)&cpy_r_r61; + cpy_r_r63 = _PyObject_Vectorcall(cpy_r_transpose, cpy_r_r62, 1, 0); + CPy_DECREF(cpy_r_transpose); + if (unlikely(cpy_r_r63 == NULL)) { + CPy_AddTraceback("test.py", "test", 7, CPyStatic_globals); + goto CPyL29; + } + cpy_r_r64 = CPyModule_builtins; + cpy_r_r65 = CPyStatics[4]; /* 'print' */ + cpy_r_r66 = CPyObject_GetAttr(cpy_r_r64, cpy_r_r65); + if (unlikely(cpy_r_r66 == NULL)) { + CPy_AddTraceback("test.py", "test", 7, CPyStatic_globals); + goto CPyL31; + } + PyObject *cpy_r_r67[1] = {cpy_r_r63}; + cpy_r_r68 = (PyObject **)&cpy_r_r67; + cpy_r_r69 = _PyObject_Vectorcall(cpy_r_r66, cpy_r_r68, 1, 0); + CPy_DECREF(cpy_r_r66); + if (unlikely(cpy_r_r69 == NULL)) { + CPy_AddTraceback("test.py", "test", 7, CPyStatic_globals); + goto CPyL31; + } else + goto CPyL32; +CPyL14: ; + CPy_DECREF(cpy_r_r63); + cpy_r_r70 = CPyDef_multiply_matrix_test_obj(); + if (unlikely(cpy_r_r70 == NULL)) { + CPy_AddTraceback("test.py", "test", 9, CPyStatic_globals); + goto CPyL29; + } + if (((test___multiply_matrix_test_objObject *)cpy_r_r70)->___mypyc_env__ != NULL) { + CPy_DECREF(((test___multiply_matrix_test_objObject *)cpy_r_r70)->___mypyc_env__); + } + ((test___multiply_matrix_test_objObject *)cpy_r_r70)->___mypyc_env__ = cpy_r_r0; + cpy_r_r71 = 1; + if (unlikely(!cpy_r_r71)) { + CPy_AddTraceback("test.py", "test", 9, CPyStatic_globals); + goto CPyL33; + } + cpy_r_multiply_matrix = cpy_r_r70; + PyObject *cpy_r_r72[2] = {cpy_r_mat1, cpy_r_mat2}; + cpy_r_r73 = (PyObject **)&cpy_r_r72; + cpy_r_r74 = _PyObject_Vectorcall(cpy_r_multiply_matrix, cpy_r_r73, 2, 0); + CPy_DECREF(cpy_r_multiply_matrix); + if (unlikely(cpy_r_r74 == NULL)) { + CPy_AddTraceback("test.py", "test", 12, CPyStatic_globals); + goto CPyL34; + } + CPy_DECREF(cpy_r_mat1); + CPy_DECREF(cpy_r_mat2); + cpy_r_r75 = CPyModule_builtins; + cpy_r_r76 = CPyStatics[4]; /* 'print' */ + cpy_r_r77 = CPyObject_GetAttr(cpy_r_r75, cpy_r_r76); + if (unlikely(cpy_r_r77 == NULL)) { + CPy_AddTraceback("test.py", "test", 12, CPyStatic_globals); + goto CPyL35; + } + PyObject *cpy_r_r78[1] = {cpy_r_r74}; + cpy_r_r79 = (PyObject **)&cpy_r_r78; + cpy_r_r80 = _PyObject_Vectorcall(cpy_r_r77, cpy_r_r79, 1, 0); + CPy_DECREF(cpy_r_r77); + if (unlikely(cpy_r_r80 == NULL)) { + CPy_AddTraceback("test.py", "test", 12, CPyStatic_globals); + goto CPyL35; + } else + goto CPyL36; +CPyL19: ; + CPy_DECREF(cpy_r_r74); + cpy_r_r81 = Py_None; + CPy_INCREF(cpy_r_r81); + return cpy_r_r81; +CPyL20: ; + cpy_r_r82 = NULL; + return cpy_r_r82; +CPyL21: ; + CPy_DecRef(cpy_r_r0); + goto CPyL20; +CPyL22: ; + CPy_DecRef(cpy_r_r0); + CPy_DecRef(cpy_r_r1); + goto CPyL20; +CPyL23: ; + CPy_DecRef(cpy_r_r0); + CPy_DecRef(cpy_r_r1); + CPy_DecRef(cpy_r_r9); + goto CPyL20; +CPyL24: ; + CPy_DecRef(cpy_r_r0); + CPy_DecRef(cpy_r_r1); + CPy_DecRef(cpy_r_r9); + CPy_DecRef(cpy_r_r17); + goto CPyL20; +CPyL25: ; + CPy_DecRef(cpy_r_r0); + CPy_DecRef(cpy_r_mat1); + goto CPyL20; +CPyL26: ; + CPy_DecRef(cpy_r_r0); + CPy_DecRef(cpy_r_mat1); + CPy_DecRef(cpy_r_r30); + goto CPyL20; +CPyL27: ; + CPy_DecRef(cpy_r_r0); + CPy_DecRef(cpy_r_mat1); + CPy_DecRef(cpy_r_r30); + CPy_DecRef(cpy_r_r38); + goto CPyL20; +CPyL28: ; + CPy_DecRef(cpy_r_r0); + CPy_DecRef(cpy_r_mat1); + CPy_DecRef(cpy_r_r30); + CPy_DecRef(cpy_r_r38); + CPy_DecRef(cpy_r_r46); + goto CPyL20; +CPyL29: ; + CPy_DecRef(cpy_r_r0); + CPy_DecRef(cpy_r_mat1); + CPy_DecRef(cpy_r_mat2); + goto CPyL20; +CPyL30: ; + CPy_DecRef(cpy_r_r0); + CPy_DecRef(cpy_r_mat1); + CPy_DecRef(cpy_r_mat2); + CPy_DecRef(cpy_r_r59); + goto CPyL20; +CPyL31: ; + CPy_DecRef(cpy_r_r0); + CPy_DecRef(cpy_r_mat1); + CPy_DecRef(cpy_r_mat2); + CPy_DecRef(cpy_r_r63); + goto CPyL20; +CPyL32: ; + CPy_DECREF(cpy_r_r69); + goto CPyL14; +CPyL33: ; + CPy_DecRef(cpy_r_mat1); + CPy_DecRef(cpy_r_mat2); + CPy_DecRef(cpy_r_r70); + goto CPyL20; +CPyL34: ; + CPy_DecRef(cpy_r_mat1); + CPy_DecRef(cpy_r_mat2); + goto CPyL20; +CPyL35: ; + CPy_DecRef(cpy_r_r74); + goto CPyL20; +CPyL36: ; + CPy_DECREF(cpy_r_r80); + goto CPyL19; +} + +PyObject *CPyPy_test(PyObject *self, PyObject *const *args, size_t nargs, PyObject *kwnames) { + static const char * const kwlist[] = {0}; + static CPyArg_Parser parser = {":test", kwlist, 0}; + if (!CPyArg_ParseStackAndKeywordsNoArgs(args, nargs, kwnames, &parser)) { + return NULL; + } + PyObject *retval = CPyDef_test(); + return retval; +fail: ; + CPy_AddTraceback("test.py", "test", 1, CPyStatic_globals); + return NULL; +} + +char CPyDef___top_level__(void) { + PyObject *cpy_r_r0; + PyObject *cpy_r_r1; + char cpy_r_r2; + PyObject *cpy_r_r3; + PyObject *cpy_r_r4; + PyObject **cpy_r_r5; + void *cpy_r_r7; + void *cpy_r_r9; + PyObject *cpy_r_r10; + PyObject *cpy_r_r11; + PyObject *cpy_r_r12; + PyObject *cpy_r_r13; + char cpy_r_r14; + PyObject *cpy_r_r15; + PyObject *cpy_r_r16; + PyObject *cpy_r_r17; + PyObject *cpy_r_r18; + CPyTagged cpy_r_r19; + PyObject *cpy_r_r20; + PyObject *cpy_r_r21; + PyObject *cpy_r_r22; + int32_t cpy_r_r23; + char cpy_r_r24; + PyObject *cpy_r_r25; + PyObject *cpy_r_r26; + PyObject *cpy_r_r27; + PyObject *cpy_r_r28; + PyObject *cpy_r_r29; + CPyTagged cpy_r_r30; + PyObject *cpy_r_r31; + PyObject *cpy_r_r32; + PyObject *cpy_r_r33; + int32_t cpy_r_r34; + char cpy_r_r35; + PyObject *cpy_r_r36; + PyObject *cpy_r_r37; + PyObject *cpy_r_r38; + PyObject *cpy_r_r39; + CPyTagged cpy_r_r40; + PyObject *cpy_r_r41; + PyObject *cpy_r_r42; + PyObject *cpy_r_r43; + CPyTagged cpy_r_r44; + CPyTagged cpy_r_r45; + PyObject *cpy_r_r46; + PyObject *cpy_r_r47; + PyObject *cpy_r_r48; + PyObject *cpy_r_r49; + PyObject *cpy_r_r50; + PyObject *cpy_r_r51; + PyObject **cpy_r_r53; + PyObject *cpy_r_r54; + char cpy_r_r55; + cpy_r_r0 = CPyModule_builtins; + cpy_r_r1 = (PyObject *)&_Py_NoneStruct; + cpy_r_r2 = cpy_r_r0 != cpy_r_r1; + if (cpy_r_r2) goto CPyL3; + cpy_r_r3 = CPyStatics[5]; /* 'builtins' */ + cpy_r_r4 = PyImport_Import(cpy_r_r3); + if (unlikely(cpy_r_r4 == NULL)) { + CPy_AddTraceback("test.py", "", -1, CPyStatic_globals); + goto CPyL22; + } + CPyModule_builtins = cpy_r_r4; + CPy_INCREF(CPyModule_builtins); + CPy_DECREF(cpy_r_r4); +CPyL3: ; + cpy_r_r5 = (PyObject **)&CPyModule_time; + PyObject **cpy_r_r6[1] = {cpy_r_r5}; + cpy_r_r7 = (void *)&cpy_r_r6; + int64_t cpy_r_r8[1] = {14}; + cpy_r_r9 = (void *)&cpy_r_r8; + cpy_r_r10 = CPyStatics[24]; /* (('time', 'time', 'time'),) */ + cpy_r_r11 = CPyStatic_globals; + cpy_r_r12 = CPyStatics[7]; /* 'test.py' */ + cpy_r_r13 = CPyStatics[8]; /* '' */ + cpy_r_r14 = CPyImport_ImportMany(cpy_r_r10, cpy_r_r7, cpy_r_r11, cpy_r_r12, cpy_r_r13, cpy_r_r9); + if (!cpy_r_r14) goto CPyL22; + cpy_r_r15 = CPyModule_time; + cpy_r_r16 = CPyStatics[9]; /* 'perf_counter_ns' */ + cpy_r_r17 = CPyObject_GetAttr(cpy_r_r15, cpy_r_r16); + if (unlikely(cpy_r_r17 == NULL)) { + CPy_AddTraceback("test.py", "", 15, CPyStatic_globals); + goto CPyL22; + } + cpy_r_r18 = _PyObject_Vectorcall(cpy_r_r17, 0, 0, 0); + CPy_DECREF(cpy_r_r17); + if (unlikely(cpy_r_r18 == NULL)) { + CPy_AddTraceback("test.py", "", 15, CPyStatic_globals); + goto CPyL22; + } + if (likely(PyLong_Check(cpy_r_r18))) + cpy_r_r19 = CPyTagged_FromObject(cpy_r_r18); + else { + CPy_TypeError("int", cpy_r_r18); cpy_r_r19 = CPY_INT_TAG; + } + CPy_DECREF(cpy_r_r18); + if (unlikely(cpy_r_r19 == CPY_INT_TAG)) { + CPy_AddTraceback("test.py", "", 15, CPyStatic_globals); + goto CPyL22; + } + cpy_r_r20 = CPyStatic_globals; + cpy_r_r21 = CPyStatics[10]; /* 'start' */ + cpy_r_r22 = CPyTagged_StealAsObject(cpy_r_r19); + cpy_r_r23 = CPyDict_SetItem(cpy_r_r20, cpy_r_r21, cpy_r_r22); + CPy_DECREF(cpy_r_r22); + cpy_r_r24 = cpy_r_r23 >= 0; + if (unlikely(!cpy_r_r24)) { + CPy_AddTraceback("test.py", "", 15, CPyStatic_globals); + goto CPyL22; + } + cpy_r_r25 = CPyDef_test(); + if (unlikely(cpy_r_r25 == NULL)) { + CPy_AddTraceback("test.py", "", 16, CPyStatic_globals); + goto CPyL22; + } else + goto CPyL23; +CPyL9: ; + cpy_r_r26 = CPyModule_time; + cpy_r_r27 = CPyStatics[9]; /* 'perf_counter_ns' */ + cpy_r_r28 = CPyObject_GetAttr(cpy_r_r26, cpy_r_r27); + if (unlikely(cpy_r_r28 == NULL)) { + CPy_AddTraceback("test.py", "", 17, CPyStatic_globals); + goto CPyL22; + } + cpy_r_r29 = _PyObject_Vectorcall(cpy_r_r28, 0, 0, 0); + CPy_DECREF(cpy_r_r28); + if (unlikely(cpy_r_r29 == NULL)) { + CPy_AddTraceback("test.py", "", 17, CPyStatic_globals); + goto CPyL22; + } + if (likely(PyLong_Check(cpy_r_r29))) + cpy_r_r30 = CPyTagged_FromObject(cpy_r_r29); + else { + CPy_TypeError("int", cpy_r_r29); cpy_r_r30 = CPY_INT_TAG; + } + CPy_DECREF(cpy_r_r29); + if (unlikely(cpy_r_r30 == CPY_INT_TAG)) { + CPy_AddTraceback("test.py", "", 17, CPyStatic_globals); + goto CPyL22; + } + cpy_r_r31 = CPyStatic_globals; + cpy_r_r32 = CPyStatics[11]; /* 'end' */ + cpy_r_r33 = CPyTagged_StealAsObject(cpy_r_r30); + cpy_r_r34 = CPyDict_SetItem(cpy_r_r31, cpy_r_r32, cpy_r_r33); + CPy_DECREF(cpy_r_r33); + cpy_r_r35 = cpy_r_r34 >= 0; + if (unlikely(!cpy_r_r35)) { + CPy_AddTraceback("test.py", "", 17, CPyStatic_globals); + goto CPyL22; + } + cpy_r_r36 = CPyStatics[12]; /* 'Time: ' */ + cpy_r_r37 = CPyStatic_globals; + cpy_r_r38 = CPyStatics[11]; /* 'end' */ + cpy_r_r39 = CPyDict_GetItem(cpy_r_r37, cpy_r_r38); + if (unlikely(cpy_r_r39 == NULL)) { + CPy_AddTraceback("test.py", "", 18, CPyStatic_globals); + goto CPyL22; + } + if (likely(PyLong_Check(cpy_r_r39))) + cpy_r_r40 = CPyTagged_FromObject(cpy_r_r39); + else { + CPy_TypeError("int", cpy_r_r39); cpy_r_r40 = CPY_INT_TAG; + } + CPy_DECREF(cpy_r_r39); + if (unlikely(cpy_r_r40 == CPY_INT_TAG)) { + CPy_AddTraceback("test.py", "", 18, CPyStatic_globals); + goto CPyL22; + } + cpy_r_r41 = CPyStatic_globals; + cpy_r_r42 = CPyStatics[10]; /* 'start' */ + cpy_r_r43 = CPyDict_GetItem(cpy_r_r41, cpy_r_r42); + if (unlikely(cpy_r_r43 == NULL)) { + CPy_AddTraceback("test.py", "", 18, CPyStatic_globals); + goto CPyL24; + } + if (likely(PyLong_Check(cpy_r_r43))) + cpy_r_r44 = CPyTagged_FromObject(cpy_r_r43); + else { + CPy_TypeError("int", cpy_r_r43); cpy_r_r44 = CPY_INT_TAG; + } + CPy_DECREF(cpy_r_r43); + if (unlikely(cpy_r_r44 == CPY_INT_TAG)) { + CPy_AddTraceback("test.py", "", 18, CPyStatic_globals); + goto CPyL24; + } + cpy_r_r45 = CPyTagged_Subtract(cpy_r_r40, cpy_r_r44); + CPyTagged_DECREF(cpy_r_r40); + CPyTagged_DECREF(cpy_r_r44); + cpy_r_r46 = CPyTagged_Str(cpy_r_r45); + CPyTagged_DECREF(cpy_r_r45); + if (unlikely(cpy_r_r46 == NULL)) { + CPy_AddTraceback("test.py", "", 18, CPyStatic_globals); + goto CPyL22; + } + cpy_r_r47 = CPyStatics[13]; /* 'ns' */ + cpy_r_r48 = CPyStr_Build(3, cpy_r_r36, cpy_r_r46, cpy_r_r47); + CPy_DECREF(cpy_r_r46); + if (unlikely(cpy_r_r48 == NULL)) { + CPy_AddTraceback("test.py", "", 18, CPyStatic_globals); + goto CPyL22; + } + cpy_r_r49 = CPyModule_builtins; + cpy_r_r50 = CPyStatics[4]; /* 'print' */ + cpy_r_r51 = CPyObject_GetAttr(cpy_r_r49, cpy_r_r50); + if (unlikely(cpy_r_r51 == NULL)) { + CPy_AddTraceback("test.py", "", 18, CPyStatic_globals); + goto CPyL25; + } + PyObject *cpy_r_r52[1] = {cpy_r_r48}; + cpy_r_r53 = (PyObject **)&cpy_r_r52; + cpy_r_r54 = _PyObject_Vectorcall(cpy_r_r51, cpy_r_r53, 1, 0); + CPy_DECREF(cpy_r_r51); + if (unlikely(cpy_r_r54 == NULL)) { + CPy_AddTraceback("test.py", "", 18, CPyStatic_globals); + goto CPyL25; + } else + goto CPyL26; +CPyL21: ; + CPy_DECREF(cpy_r_r48); + return 1; +CPyL22: ; + cpy_r_r55 = 2; + return cpy_r_r55; +CPyL23: ; + CPy_DECREF(cpy_r_r25); + goto CPyL9; +CPyL24: ; + CPyTagged_DecRef(cpy_r_r40); + goto CPyL22; +CPyL25: ; + CPy_DecRef(cpy_r_r48); + goto CPyL22; +CPyL26: ; + CPy_DECREF(cpy_r_r54); + goto CPyL21; +} + +int CPyGlobalsInit(void) +{ + static int is_initialized = 0; + if (is_initialized) return 0; + + CPy_Init(); + CPyModule_test = Py_None; + CPyModule_builtins = Py_None; + CPyModule_time = Py_None; + if (CPyStatics_Initialize(CPyStatics, CPyLit_Str, CPyLit_Bytes, CPyLit_Int, CPyLit_Float, CPyLit_Complex, CPyLit_Tuple, CPyLit_FrozenSet) < 0) { + return -1; + } + is_initialized = 1; + return 0; +} + +PyObject *CPyStatics[25]; +const char * const CPyLit_Str[] = { + "\t\003zip\005print\bbuiltins\004time\atest.py\b\017perf_counter_ns\005start\003end", + "\002\006Time: \002ns", + "", +}; +const char * const CPyLit_Bytes[] = { + "", +}; +const char * const CPyLit_Int[] = { + "\t1\0002\0003\0004\0005\0006\0007\0008\0009", + "", +}; +const double CPyLit_Float[] = {0}; +const double CPyLit_Complex[] = {0}; +const int CPyLit_Tuple[] = {2, 3, 6, 6, 6, 1, 23}; +const int CPyLit_FrozenSet[] = {0}; +CPyModule *CPyModule_test_internal = NULL; +CPyModule *CPyModule_test; +PyObject *CPyStatic_globals; +CPyModule *CPyModule_builtins; +CPyModule *CPyModule_time; +PyTypeObject *CPyType_test_env; +PyObject *CPyDef_test_env(void); +PyTypeObject *CPyType_transpose_test_obj; +PyObject *CPyDef_transpose_test_obj(void); +PyTypeObject *CPyType_multiply_matrix_test_obj; +PyObject *CPyDef_multiply_matrix_test_obj(void); +PyObject *CPyDef_transpose_test_obj_____get__(PyObject *cpy_r___mypyc_self__, PyObject *cpy_r_instance, PyObject *cpy_r_owner); +PyObject *CPyPy_transpose_test_obj_____get__(PyObject *self, PyObject *const *args, size_t nargs, PyObject *kwnames); +PyObject *CPyDef_transpose_test_obj_____call__(PyObject *cpy_r___mypyc_self__, PyObject *cpy_r_matrix); +PyObject *CPyPy_transpose_test_obj_____call__(PyObject *self, PyObject *const *args, size_t nargs, PyObject *kwnames); +PyObject *CPyDef_multiply_matrix_test_obj_____get__(PyObject *cpy_r___mypyc_self__, PyObject *cpy_r_instance, PyObject *cpy_r_owner); +PyObject *CPyPy_multiply_matrix_test_obj_____get__(PyObject *self, PyObject *const *args, size_t nargs, PyObject *kwnames); +PyObject *CPyDef_multiply_matrix_test_obj_____call__(PyObject *cpy_r___mypyc_self__, PyObject *cpy_r_matrix1, PyObject *cpy_r_matrix2); +PyObject *CPyPy_multiply_matrix_test_obj_____call__(PyObject *self, PyObject *const *args, size_t nargs, PyObject *kwnames); +PyObject *CPyDef_test(void); +PyObject *CPyPy_test(PyObject *self, PyObject *const *args, size_t nargs, PyObject *kwnames); +char CPyDef___top_level__(void); diff --git a/build/__native.h b/build/__native.h new file mode 100644 index 0000000..4a533c0 --- /dev/null +++ b/build/__native.h @@ -0,0 +1,29 @@ +#ifndef MYPYC_NATIVE_H +#define MYPYC_NATIVE_H +#include +#include +typedef struct { + PyObject_HEAD + CPyVTableItem *vtable; + PyObject *___mypyc_self__; + PyObject *_transpose; + PyObject *_multiply_matrix; + PyObject *_mat1; + PyObject *_mat2; +} test___test_envObject; + +typedef struct { + PyObject_HEAD + CPyVTableItem *vtable; + vectorcallfunc vectorcall; + PyObject *___mypyc_env__; +} test___transpose_test_objObject; + +typedef struct { + PyObject_HEAD + CPyVTableItem *vtable; + vectorcallfunc vectorcall; + PyObject *___mypyc_env__; +} test___multiply_matrix_test_objObject; + +#endif diff --git a/build/__native_internal.h b/build/__native_internal.h new file mode 100644 index 0000000..091d68b --- /dev/null +++ b/build/__native_internal.h @@ -0,0 +1,39 @@ +#ifndef MYPYC_NATIVE_INTERNAL_H +#define MYPYC_NATIVE_INTERNAL_H +#include +#include +#include "__native.h" + +int CPyGlobalsInit(void); + +extern PyObject *CPyStatics[25]; +extern const char * const CPyLit_Str[]; +extern const char * const CPyLit_Bytes[]; +extern const char * const CPyLit_Int[]; +extern const double CPyLit_Float[]; +extern const double CPyLit_Complex[]; +extern const int CPyLit_Tuple[]; +extern const int CPyLit_FrozenSet[]; +extern CPyModule *CPyModule_test_internal; +extern CPyModule *CPyModule_test; +extern PyObject *CPyStatic_globals; +extern CPyModule *CPyModule_builtins; +extern CPyModule *CPyModule_time; +extern PyTypeObject *CPyType_test_env; +extern PyObject *CPyDef_test_env(void); +extern PyTypeObject *CPyType_transpose_test_obj; +extern PyObject *CPyDef_transpose_test_obj(void); +extern PyTypeObject *CPyType_multiply_matrix_test_obj; +extern PyObject *CPyDef_multiply_matrix_test_obj(void); +extern PyObject *CPyDef_transpose_test_obj_____get__(PyObject *cpy_r___mypyc_self__, PyObject *cpy_r_instance, PyObject *cpy_r_owner); +extern PyObject *CPyPy_transpose_test_obj_____get__(PyObject *self, PyObject *const *args, size_t nargs, PyObject *kwnames); +extern PyObject *CPyDef_transpose_test_obj_____call__(PyObject *cpy_r___mypyc_self__, PyObject *cpy_r_matrix); +extern PyObject *CPyPy_transpose_test_obj_____call__(PyObject *self, PyObject *const *args, size_t nargs, PyObject *kwnames); +extern PyObject *CPyDef_multiply_matrix_test_obj_____get__(PyObject *cpy_r___mypyc_self__, PyObject *cpy_r_instance, PyObject *cpy_r_owner); +extern PyObject *CPyPy_multiply_matrix_test_obj_____get__(PyObject *self, PyObject *const *args, size_t nargs, PyObject *kwnames); +extern PyObject *CPyDef_multiply_matrix_test_obj_____call__(PyObject *cpy_r___mypyc_self__, PyObject *cpy_r_matrix1, PyObject *cpy_r_matrix2); +extern PyObject *CPyPy_multiply_matrix_test_obj_____call__(PyObject *self, PyObject *const *args, size_t nargs, PyObject *kwnames); +extern PyObject *CPyDef_test(void); +extern PyObject *CPyPy_test(PyObject *self, PyObject *const *args, size_t nargs, PyObject *kwnames); +extern char CPyDef___top_level__(void); +#endif diff --git a/build/ops.txt b/build/ops.txt new file mode 100644 index 0000000..d4912c9 --- /dev/null +++ b/build/ops.txt @@ -0,0 +1,908 @@ +def transpose_test_obj.__get__(__mypyc_self__, instance, owner): + __mypyc_self__, instance, owner, r0 :: object + r1 :: bit + r2, r3 :: object +L0: + r0 = load_address _Py_NoneStruct + r1 = instance == r0 + if r1 goto L1 else goto L2 :: bool +L1: + inc_ref __mypyc_self__ + return __mypyc_self__ +L2: + r2 = PyMethod_New(__mypyc_self__, instance) + if is_error(r2) goto L4 else goto L3 +L3: + return r2 +L4: + r3 = :: object + return r3 + +def transpose_test_obj.__call__(__mypyc_self__, matrix): + __mypyc_self__ :: test.transpose_test_obj + matrix :: list + r0 :: test.test_env + r1 :: list + r2 :: object + r3 :: list + r4 :: ptr + r5 :: native_int + r6, r7 :: short_int + i :: int + r8 :: bit + r9 :: list + r10 :: ptr + r11 :: native_int + r12, r13 :: short_int + j :: int + r14 :: bit + r15 :: object + r16 :: list + r17 :: object + r18 :: int + r19 :: object + r20 :: i32 + r21 :: bit + r22 :: short_int + r23 :: i32 + r24 :: bit + r25 :: short_int + r26 :: list +L0: + r0 = __mypyc_self__.__mypyc_env__ + if is_error(r0) goto L18 (error at transpose:4) else goto L19 +L1: + r1 = PyList_New(0) + if is_error(r1) goto L18 (error at transpose:5) else goto L2 +L2: + r2 = CPyList_GetItemShortBorrow(matrix, 0) + if is_error(r2) goto L20 (error at transpose:5) else goto L3 +L3: + r3 = borrow cast(list, r2) + if is_error(r3) goto L20 (error at transpose:5) else goto L4 +L4: + r4 = get_element_ptr r3 ob_size :: PyVarObject + r5 = load_mem r4 :: native_int* + r6 = r5 << 1 + r7 = 0 + i = r7 +L5: + r8 = r7 < r6 :: signed + if r8 goto L6 else goto L21 :: bool +L6: + r9 = PyList_New(0) + if is_error(r9) goto L22 (error at transpose:5) else goto L7 +L7: + r10 = get_element_ptr matrix ob_size :: PyVarObject + r11 = load_mem r10 :: native_int* + r12 = r11 << 1 + r13 = 0 + j = r13 +L8: + r14 = r13 < r12 :: signed + if r14 goto L9 else goto L23 :: bool +L9: + r15 = CPyList_GetItemBorrow(matrix, j) + if is_error(r15) goto L24 (error at transpose:5) else goto L10 +L10: + r16 = borrow cast(list, r15) + if is_error(r16) goto L24 (error at transpose:5) else goto L11 +L11: + r17 = CPyList_GetItem(r16, i) + if is_error(r17) goto L24 (error at transpose:5) else goto L12 +L12: + r18 = unbox(int, r17) + dec_ref r17 + if is_error(r18) goto L24 (error at transpose:5) else goto L13 +L13: + dec_ref j :: int + r19 = box(int, r18) + r20 = PyList_Append(r9, r19) + dec_ref r19 + r21 = r20 >= 0 :: signed + if not r21 goto L25 (error at transpose:5) else goto L14 :: bool +L14: + r22 = r13 + 2 + r13 = r22 + j = r22 + goto L8 +L15: + r23 = PyList_Append(r1, r9) + dec_ref r9 + r24 = r23 >= 0 :: signed + if not r24 goto L20 (error at transpose:5) else goto L16 :: bool +L16: + r25 = r7 + 2 + r7 = r25 + i = r25 + goto L5 +L17: + return r1 +L18: + r26 = :: list + return r26 +L19: + dec_ref r0 + goto L1 +L20: + dec_ref r1 + goto L18 +L21: + dec_ref i :: int + goto L17 +L22: + dec_ref r1 + dec_ref i :: int + goto L18 +L23: + dec_ref i :: int + dec_ref j :: int + goto L15 +L24: + dec_ref r1 + dec_ref i :: int + dec_ref r9 + dec_ref j :: int + goto L18 +L25: + dec_ref r1 + dec_ref i :: int + dec_ref r9 + goto L18 + +def multiply_matrix_test_obj.__get__(__mypyc_self__, instance, owner): + __mypyc_self__, instance, owner, r0 :: object + r1 :: bit + r2, r3 :: object +L0: + r0 = load_address _Py_NoneStruct + r1 = instance == r0 + if r1 goto L1 else goto L2 :: bool +L1: + inc_ref __mypyc_self__ + return __mypyc_self__ +L2: + r2 = PyMethod_New(__mypyc_self__, instance) + if is_error(r2) goto L4 else goto L3 +L3: + return r2 +L4: + r3 = :: object + return r3 + +def multiply_matrix_test_obj.__call__(__mypyc_self__, matrix1, matrix2): + __mypyc_self__ :: test.multiply_matrix_test_obj + matrix1, matrix2 :: list + r0 :: test.test_env + r1 :: ptr + r2 :: native_int + r3 :: list + r4 :: short_int + r5 :: ptr + r6 :: native_int + r7 :: short_int + r8 :: bit + r9 :: object + r10, X_row, r11 :: list + r12 :: object + r13 :: str + r14 :: object + r15 :: list + r16 :: object + r17 :: tuple + r18 :: dict + r19, r20, r21 :: object + r22, Y_col :: tuple + r23 :: int + r24, r25 :: short_int + r26 :: ptr + r27 :: native_int + r28 :: short_int + r29 :: bit + r30 :: ptr + r31 :: native_int + r32 :: short_int + r33 :: bit + r34 :: object + r35, a :: int + r36, b, r37, r38, r39, r40 :: object + r41 :: int + r42, r43 :: short_int + r44 :: object + r45 :: i32 + r46, r47, r48 :: bit + r49 :: short_int + r50 :: list +L0: + r0 = __mypyc_self__.__mypyc_env__ + if is_error(r0) goto L30 (error at multiply_matrix:9) else goto L31 +L1: + r1 = get_element_ptr matrix1 ob_size :: PyVarObject + r2 = load_mem r1 :: native_int* + r3 = PyList_New(r2) + if is_error(r3) goto L30 (error at multiply_matrix:10) else goto L2 +L2: + r4 = 0 +L3: + r5 = get_element_ptr matrix1 ob_size :: PyVarObject + r6 = load_mem r5 :: native_int* + r7 = r6 << 1 + r8 = r4 < r7 :: signed + if r8 goto L4 else goto L29 :: bool +L4: + r9 = CPyList_GetItemUnsafe(matrix1, r4) + r10 = cast(list, r9) + if is_error(r10) goto L32 (error at multiply_matrix:10) else goto L5 +L5: + X_row = r10 + r11 = PyList_New(0) + if is_error(r11) goto L33 (error at multiply_matrix:10) else goto L6 +L6: + r12 = builtins :: module + r13 = 'zip' + r14 = CPyObject_GetAttr(r12, r13) + if is_error(r14) goto L34 (error at multiply_matrix:10) else goto L7 +L7: + r15 = PyList_New(0) + if is_error(r15) goto L35 (error at multiply_matrix:10) else goto L8 +L8: + r16 = CPyList_Extend(r15, matrix2) + if is_error(r16) goto L36 (error at multiply_matrix:10) else goto L37 +L9: + r17 = PyList_AsTuple(r15) + dec_ref r15 + if is_error(r17) goto L35 (error at multiply_matrix:10) else goto L10 +L10: + r18 = PyDict_New() + if is_error(r18) goto L38 (error at multiply_matrix:10) else goto L11 +L11: + r19 = PyObject_Call(r14, r17, r18) + dec_ref r14 + dec_ref r17 + dec_ref r18 + if is_error(r19) goto L34 (error at multiply_matrix:10) else goto L12 +L12: + r20 = PyObject_GetIter(r19) + dec_ref r19 + if is_error(r20) goto L34 (error at multiply_matrix:10) else goto L13 +L13: + r21 = PyIter_Next(r20) + if is_error(r21) goto L39 else goto L14 +L14: + r22 = cast(tuple, r21) + if is_error(r22) goto L40 (error at multiply_matrix:10) else goto L15 +L15: + Y_col = r22 + r23 = 0 + r24 = 0 + r25 = 0 +L16: + r26 = get_element_ptr X_row ob_size :: PyVarObject + r27 = load_mem r26 :: native_int* + r28 = r27 << 1 + r29 = r24 < r28 :: signed + if r29 goto L17 else goto L41 :: bool +L17: + r30 = get_element_ptr Y_col ob_size :: PyVarObject + r31 = load_mem r30 :: native_int* + r32 = r31 << 1 + r33 = r25 < r32 :: signed + if r33 goto L18 else goto L41 :: bool +L18: + r34 = CPyList_GetItemUnsafe(X_row, r24) + r35 = unbox(int, r34) + dec_ref r34 + if is_error(r35) goto L42 (error at multiply_matrix:10) else goto L19 +L19: + a = r35 + r36 = CPySequenceTuple_GetItem(Y_col, r25) + if is_error(r36) goto L43 (error at multiply_matrix:10) else goto L20 +L20: + b = r36 + r37 = box(int, a) + r38 = PyNumber_Multiply(r37, b) + dec_ref r37 + dec_ref b + if is_error(r38) goto L42 (error at multiply_matrix:10) else goto L21 +L21: + r39 = box(int, r23) + r40 = PyNumber_Add(r39, r38) + dec_ref r39 + dec_ref r38 + if is_error(r40) goto L44 (error at multiply_matrix:-1) else goto L22 +L22: + r41 = unbox(int, r40) + dec_ref r40 + if is_error(r41) goto L44 (error at multiply_matrix:-1) else goto L23 +L23: + r23 = r41 +L24: + r42 = r24 + 2 + r24 = r42 + r43 = r25 + 2 + r25 = r43 + goto L16 +L25: + r44 = box(int, r23) + r45 = PyList_Append(r11, r44) + dec_ref r44 + r46 = r45 >= 0 :: signed + if not r46 goto L40 (error at multiply_matrix:10) else goto L13 :: bool +L26: + r47 = CPy_NoErrOccured() + if not r47 goto L45 (error at multiply_matrix:10) else goto L27 :: bool +L27: + r48 = CPyList_SetItemUnsafe(r3, r4, r11) + if not r48 goto L32 (error at multiply_matrix:10) else goto L28 :: bool +L28: + r49 = r4 + 2 + r4 = r49 + goto L3 +L29: + return r3 +L30: + r50 = :: list + return r50 +L31: + dec_ref r0 + goto L1 +L32: + dec_ref r3 + goto L30 +L33: + dec_ref r3 + dec_ref X_row + goto L30 +L34: + dec_ref r3 + dec_ref X_row + dec_ref r11 + goto L30 +L35: + dec_ref r3 + dec_ref X_row + dec_ref r11 + dec_ref r14 + goto L30 +L36: + dec_ref r3 + dec_ref X_row + dec_ref r11 + dec_ref r14 + dec_ref r15 + goto L30 +L37: + dec_ref r16 + goto L9 +L38: + dec_ref r3 + dec_ref X_row + dec_ref r11 + dec_ref r14 + dec_ref r17 + goto L30 +L39: + dec_ref X_row + dec_ref r20 + goto L26 +L40: + dec_ref r3 + dec_ref X_row + dec_ref r11 + dec_ref r20 + goto L30 +L41: + dec_ref Y_col + goto L25 +L42: + dec_ref r3 + dec_ref X_row + dec_ref r11 + dec_ref r20 + dec_ref Y_col + dec_ref r23 :: int + goto L30 +L43: + dec_ref r3 + dec_ref X_row + dec_ref r11 + dec_ref r20 + dec_ref Y_col + dec_ref r23 :: int + dec_ref a :: int + goto L30 +L44: + dec_ref r3 + dec_ref X_row + dec_ref r11 + dec_ref r20 + dec_ref Y_col + goto L30 +L45: + dec_ref r3 + dec_ref r11 + goto L30 + +def test(): + r0 :: test.test_env + r1 :: list + r2, r3, r4 :: object + r5, r6, r7, r8 :: ptr + r9 :: list + r10, r11, r12 :: object + r13, r14, r15, r16 :: ptr + r17 :: list + r18, r19, r20 :: object + r21, r22, r23, r24 :: ptr + r25 :: list + r26, r27, r28, r29 :: ptr + mat1 :: object + r30 :: list + r31, r32, r33 :: object + r34, r35, r36, r37 :: ptr + r38 :: list + r39, r40, r41 :: object + r42, r43, r44, r45 :: ptr + r46 :: list + r47, r48, r49 :: object + r50, r51, r52, r53 :: ptr + r54 :: list + r55, r56, r57, r58 :: ptr + mat2 :: object + r59 :: test.transpose_test_obj + r60 :: bool + transpose :: object + r61 :: object[1] + r62 :: object_ptr + r63, r64 :: object + r65 :: str + r66 :: object + r67 :: object[1] + r68 :: object_ptr + r69 :: object + r70 :: test.multiply_matrix_test_obj + r71 :: bool + multiply_matrix :: object + r72 :: object[2] + r73 :: object_ptr + r74, r75 :: object + r76 :: str + r77 :: object + r78 :: object[1] + r79 :: object_ptr + r80, r81, r82 :: object +L0: + r0 = test_env() + if is_error(r0) goto L20 (error at test:1) else goto L1 +L1: + r1 = PyList_New(3) + if is_error(r1) goto L21 (error at test:2) else goto L2 +L2: + r2 = object 1 + r3 = object 2 + r4 = object 3 + r5 = get_element_ptr r1 ob_item :: PyListObject + r6 = load_mem r5 :: ptr* + inc_ref r2 + set_mem r6, r2 :: builtins.object* + r7 = r6 + 8 + inc_ref r3 + set_mem r7, r3 :: builtins.object* + r8 = r6 + 16 + inc_ref r4 + set_mem r8, r4 :: builtins.object* + r9 = PyList_New(3) + if is_error(r9) goto L22 (error at test:2) else goto L3 +L3: + r10 = object 4 + r11 = object 5 + r12 = object 6 + r13 = get_element_ptr r9 ob_item :: PyListObject + r14 = load_mem r13 :: ptr* + inc_ref r10 + set_mem r14, r10 :: builtins.object* + r15 = r14 + 8 + inc_ref r11 + set_mem r15, r11 :: builtins.object* + r16 = r14 + 16 + inc_ref r12 + set_mem r16, r12 :: builtins.object* + r17 = PyList_New(3) + if is_error(r17) goto L23 (error at test:2) else goto L4 +L4: + r18 = object 7 + r19 = object 8 + r20 = object 9 + r21 = get_element_ptr r17 ob_item :: PyListObject + r22 = load_mem r21 :: ptr* + inc_ref r18 + set_mem r22, r18 :: builtins.object* + r23 = r22 + 8 + inc_ref r19 + set_mem r23, r19 :: builtins.object* + r24 = r22 + 16 + inc_ref r20 + set_mem r24, r20 :: builtins.object* + r25 = PyList_New(3) + if is_error(r25) goto L24 (error at test:2) else goto L5 +L5: + r26 = get_element_ptr r25 ob_item :: PyListObject + r27 = load_mem r26 :: ptr* + set_mem r27, r1 :: builtins.object* + r28 = r27 + 8 + set_mem r28, r9 :: builtins.object* + r29 = r27 + 16 + set_mem r29, r17 :: builtins.object* + mat1 = r25 + r30 = PyList_New(3) + if is_error(r30) goto L25 (error at test:3) else goto L6 +L6: + r31 = object 1 + r32 = object 2 + r33 = object 3 + r34 = get_element_ptr r30 ob_item :: PyListObject + r35 = load_mem r34 :: ptr* + inc_ref r31 + set_mem r35, r31 :: builtins.object* + r36 = r35 + 8 + inc_ref r32 + set_mem r36, r32 :: builtins.object* + r37 = r35 + 16 + inc_ref r33 + set_mem r37, r33 :: builtins.object* + r38 = PyList_New(3) + if is_error(r38) goto L26 (error at test:3) else goto L7 +L7: + r39 = object 4 + r40 = object 5 + r41 = object 6 + r42 = get_element_ptr r38 ob_item :: PyListObject + r43 = load_mem r42 :: ptr* + inc_ref r39 + set_mem r43, r39 :: builtins.object* + r44 = r43 + 8 + inc_ref r40 + set_mem r44, r40 :: builtins.object* + r45 = r43 + 16 + inc_ref r41 + set_mem r45, r41 :: builtins.object* + r46 = PyList_New(3) + if is_error(r46) goto L27 (error at test:3) else goto L8 +L8: + r47 = object 7 + r48 = object 8 + r49 = object 9 + r50 = get_element_ptr r46 ob_item :: PyListObject + r51 = load_mem r50 :: ptr* + inc_ref r47 + set_mem r51, r47 :: builtins.object* + r52 = r51 + 8 + inc_ref r48 + set_mem r52, r48 :: builtins.object* + r53 = r51 + 16 + inc_ref r49 + set_mem r53, r49 :: builtins.object* + r54 = PyList_New(3) + if is_error(r54) goto L28 (error at test:3) else goto L9 +L9: + r55 = get_element_ptr r54 ob_item :: PyListObject + r56 = load_mem r55 :: ptr* + set_mem r56, r30 :: builtins.object* + r57 = r56 + 8 + set_mem r57, r38 :: builtins.object* + r58 = r56 + 16 + set_mem r58, r46 :: builtins.object* + mat2 = r54 + r59 = transpose_test_obj() + if is_error(r59) goto L29 (error at test:4) else goto L10 +L10: + inc_ref r0 + r59.__mypyc_env__ = r0; r60 = is_error + if not r60 goto L30 (error at test:4) else goto L11 :: bool +L11: + transpose = r59 + r61 = [mat1] + r62 = load_address r61 + r63 = _PyObject_Vectorcall(transpose, r62, 1, 0) + dec_ref transpose + if is_error(r63) goto L29 (error at test:7) else goto L12 +L12: + r64 = builtins :: module + r65 = 'print' + r66 = CPyObject_GetAttr(r64, r65) + if is_error(r66) goto L31 (error at test:7) else goto L13 +L13: + r67 = [r63] + r68 = load_address r67 + r69 = _PyObject_Vectorcall(r66, r68, 1, 0) + dec_ref r66 + if is_error(r69) goto L31 (error at test:7) else goto L32 +L14: + dec_ref r63 + r70 = multiply_matrix_test_obj() + if is_error(r70) goto L29 (error at test:9) else goto L15 +L15: + r70.__mypyc_env__ = r0; r71 = is_error + if not r71 goto L33 (error at test:9) else goto L16 :: bool +L16: + multiply_matrix = r70 + r72 = [mat1, mat2] + r73 = load_address r72 + r74 = _PyObject_Vectorcall(multiply_matrix, r73, 2, 0) + dec_ref multiply_matrix + if is_error(r74) goto L34 (error at test:12) else goto L17 +L17: + dec_ref mat1 + dec_ref mat2 + r75 = builtins :: module + r76 = 'print' + r77 = CPyObject_GetAttr(r75, r76) + if is_error(r77) goto L35 (error at test:12) else goto L18 +L18: + r78 = [r74] + r79 = load_address r78 + r80 = _PyObject_Vectorcall(r77, r79, 1, 0) + dec_ref r77 + if is_error(r80) goto L35 (error at test:12) else goto L36 +L19: + dec_ref r74 + r81 = box(None, 1) + inc_ref r81 + return r81 +L20: + r82 = :: object + return r82 +L21: + dec_ref r0 + goto L20 +L22: + dec_ref r0 + dec_ref r1 + goto L20 +L23: + dec_ref r0 + dec_ref r1 + dec_ref r9 + goto L20 +L24: + dec_ref r0 + dec_ref r1 + dec_ref r9 + dec_ref r17 + goto L20 +L25: + dec_ref r0 + dec_ref mat1 + goto L20 +L26: + dec_ref r0 + dec_ref mat1 + dec_ref r30 + goto L20 +L27: + dec_ref r0 + dec_ref mat1 + dec_ref r30 + dec_ref r38 + goto L20 +L28: + dec_ref r0 + dec_ref mat1 + dec_ref r30 + dec_ref r38 + dec_ref r46 + goto L20 +L29: + dec_ref r0 + dec_ref mat1 + dec_ref mat2 + goto L20 +L30: + dec_ref r0 + dec_ref mat1 + dec_ref mat2 + dec_ref r59 + goto L20 +L31: + dec_ref r0 + dec_ref mat1 + dec_ref mat2 + dec_ref r63 + goto L20 +L32: + dec_ref r69 + goto L14 +L33: + dec_ref mat1 + dec_ref mat2 + dec_ref r70 + goto L20 +L34: + dec_ref mat1 + dec_ref mat2 + goto L20 +L35: + dec_ref r74 + goto L20 +L36: + dec_ref r80 + goto L19 + +def __top_level__(): + r0, r1 :: object + r2 :: bit + r3 :: str + r4 :: object + r5 :: object_ptr + r6 :: object_ptr[1] + r7 :: c_ptr + r8 :: native_int[1] + r9 :: c_ptr + r10 :: object + r11 :: dict + r12, r13 :: str + r14 :: bit + r15 :: object + r16 :: str + r17, r18 :: object + r19 :: int + r20 :: dict + r21 :: str + r22 :: object + r23 :: i32 + r24 :: bit + r25, r26 :: object + r27 :: str + r28, r29 :: object + r30 :: int + r31 :: dict + r32 :: str + r33 :: object + r34 :: i32 + r35 :: bit + r36 :: str + r37 :: dict + r38 :: str + r39 :: object + r40 :: int + r41 :: dict + r42 :: str + r43 :: object + r44, r45 :: int + r46, r47, r48 :: str + r49 :: object + r50 :: str + r51 :: object + r52 :: object[1] + r53 :: object_ptr + r54 :: object + r55 :: None +L0: + r0 = builtins :: module + r1 = load_address _Py_NoneStruct + r2 = r0 != r1 + if r2 goto L3 else goto L1 :: bool +L1: + r3 = 'builtins' + r4 = PyImport_Import(r3) + if is_error(r4) goto L22 (error at :-1) else goto L2 +L2: + builtins = r4 :: module + dec_ref r4 +L3: + r5 = load_address time :: module + r6 = [r5] + r7 = load_address r6 + r8 = [14] + r9 = load_address r8 + r10 = (('time', 'time', 'time'),) + r11 = test.globals :: static + r12 = 'test.py' + r13 = '' + r14 = CPyImport_ImportMany(r10, r7, r11, r12, r13, r9) + if not r14 goto L22 else goto L4 :: bool +L4: + r15 = time :: module + r16 = 'perf_counter_ns' + r17 = CPyObject_GetAttr(r15, r16) + if is_error(r17) goto L22 (error at :15) else goto L5 +L5: + r18 = _PyObject_Vectorcall(r17, 0, 0, 0) + dec_ref r17 + if is_error(r18) goto L22 (error at :15) else goto L6 +L6: + r19 = unbox(int, r18) + dec_ref r18 + if is_error(r19) goto L22 (error at :15) else goto L7 +L7: + r20 = test.globals :: static + r21 = 'start' + r22 = box(int, r19) + r23 = CPyDict_SetItem(r20, r21, r22) + dec_ref r22 + r24 = r23 >= 0 :: signed + if not r24 goto L22 (error at :15) else goto L8 :: bool +L8: + r25 = test() + if is_error(r25) goto L22 (error at :16) else goto L23 +L9: + r26 = time :: module + r27 = 'perf_counter_ns' + r28 = CPyObject_GetAttr(r26, r27) + if is_error(r28) goto L22 (error at :17) else goto L10 +L10: + r29 = _PyObject_Vectorcall(r28, 0, 0, 0) + dec_ref r28 + if is_error(r29) goto L22 (error at :17) else goto L11 +L11: + r30 = unbox(int, r29) + dec_ref r29 + if is_error(r30) goto L22 (error at :17) else goto L12 +L12: + r31 = test.globals :: static + r32 = 'end' + r33 = box(int, r30) + r34 = CPyDict_SetItem(r31, r32, r33) + dec_ref r33 + r35 = r34 >= 0 :: signed + if not r35 goto L22 (error at :17) else goto L13 :: bool +L13: + r36 = 'Time: ' + r37 = test.globals :: static + r38 = 'end' + r39 = CPyDict_GetItem(r37, r38) + if is_error(r39) goto L22 (error at :18) else goto L14 +L14: + r40 = unbox(int, r39) + dec_ref r39 + if is_error(r40) goto L22 (error at :18) else goto L15 +L15: + r41 = test.globals :: static + r42 = 'start' + r43 = CPyDict_GetItem(r41, r42) + if is_error(r43) goto L24 (error at :18) else goto L16 +L16: + r44 = unbox(int, r43) + dec_ref r43 + if is_error(r44) goto L24 (error at :18) else goto L17 +L17: + r45 = CPyTagged_Subtract(r40, r44) + dec_ref r40 :: int + dec_ref r44 :: int + r46 = CPyTagged_Str(r45) + dec_ref r45 :: int + if is_error(r46) goto L22 (error at :18) else goto L18 +L18: + r47 = 'ns' + r48 = CPyStr_Build(3, r36, r46, r47) + dec_ref r46 + if is_error(r48) goto L22 (error at :18) else goto L19 +L19: + r49 = builtins :: module + r50 = 'print' + r51 = CPyObject_GetAttr(r49, r50) + if is_error(r51) goto L25 (error at :18) else goto L20 +L20: + r52 = [r48] + r53 = load_address r52 + r54 = _PyObject_Vectorcall(r51, r53, 1, 0) + dec_ref r51 + if is_error(r54) goto L25 (error at :18) else goto L26 +L21: + dec_ref r48 + return 1 +L22: + r55 = :: None + return r55 +L23: + dec_ref r25 + goto L9 +L24: + dec_ref r40 :: int + goto L22 +L25: + dec_ref r48 + goto L22 +L26: + dec_ref r54 + goto L21 diff --git a/build/setup.py b/build/setup.py index e7b69dc..b99e71a 100644 --- a/build/setup.py +++ b/build/setup.py @@ -2,5 +2,5 @@ from mypyc.build import mypycify setup(name='mypyc_output', - ext_modules=mypycify(['helix.py'], opt_level="3", debug_level="1"), + ext_modules=mypycify(['test.py'], opt_level="3", debug_level="1"), ) diff --git a/build/temp.win-amd64-cpython-311/Release/build/__native.obj b/build/temp.win-amd64-cpython-311/Release/build/__native.obj new file mode 100644 index 0000000000000000000000000000000000000000..f7dc8058f90ba7a2533d03ea1b322ee2b30fdc86 GIT binary patch literal 469412 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⪚XWd$4C2jMhDV?#=?67w9>k9f706KT%kU^KGv%GH9)66A!|G#? z-P{_ce+SM{DIOz=N+I5yrT8z@B>t2p&V%@o;sB(m^rd)~mzm1WR}VWDDFlhI6jdt4 zb3{=o#GA7euR%@XFKgmFh#x6xkfPd`;&onTsMQL#;2v`@GE5Mr3FbyKJ%sE>;;nAcD#u-kfFl9BO3vM3d%0{K!y`40XN?U+^+h z7m*=l^*An-w1&x_fy-2oFNvjsh&N|JzK5FhztQx05I=%6A;@xHkRN!NS)R3k9IP_@ zNCcHZygAG8JJcloizdy3_>tjIWLW9Tz~`Q=%*u!i%cYPmw+0@jGO%gJ$ROUFW#EIr zB10TUjY9m$a1=5e>C3=P!B*zThzuRckmS~62!94Ps~~*V)(9froCV>Vq9O>Nj5UIY zA3=^skmGzo_#&s3IgWCAT$XaWN~PelmqrTl<}Af7P$LE3M>JB1A1O{kiW7Y)_>!NM zIgvW+_$+nS$tnfk;4@N)H)knIp+<_NCeDNSk>YfuIL((L&CASbZPZz3s1$s=&PXBN zoTb8y%Jsrt{5jD6E|wOT>t02tISKWIUi1QI@Na^t+xsO%mOZ?j5pV7q4L2J3Wk>vI zGyskIC!9SK&K|xxV$`T=)F}~l`UmQiX-S$PDrNRG+K5V-J&ZP@k}LK=6?-2~Z1LtU zw%8-eO9|0(CVs>oir7OE&ftWzcfuLuOFos*bhmIu3<)I93`RsRBlb3;Yeoz*qW^hD z3{#D!k%*d>cyrgN3UV}>t%~p>2d=ClJvu+Ot%VGhnZZh&Ojd zE`l8S*QoqFh#y5NP^3KJ%=WdonDr{3g z#E%kHC~-i-sZ2Qg`+8hQP_#535a^Mq4CTiDxhXPF6}cYvs)%@VSL9B}k^g3up9k@y zNDYcqC!G1d78%}0wWtoX2}_LO56o^RYJVEEAbfQ$bP@d&V%?-Vlhe_m~d(n z&LUrr#|erS=>r2jGPR-HSd^P0OH`5nz+M#*Z|;h`2s!dUt@86AeiW%kk-CJl)YsxA z-bb~l3$zI5#?suBSf)z640lyRytym!9^}aWy2{Rj_)($>C6*_g#)Q-0>+!yc`hjsi z#F2`p`Axc)LyyVN%PcqfvD!K#kzOHvruB&l<6-#`G1G@6qSeES00NItE4ju1gG>X@ zbiTAs>qAn)>|B;MQs`Wxg}&vrO!J>mzTvjFJKgmZ?EPA3y@SL1ZXiK26+QB1Ap zoDez*Vy4%$K3QjR^6&&&A4o+{#0jC>| zf+K#wxdd=7PB<4O9Qrcu^m`u@wahquaiaKKj6RU6=)+J%riX>;UaaSmv?-pi32?{=8Ly#G5-nBOnK$K{yJK_yOo@0J`*Ns zEOS=?RYsv&%3Fm>ytzZQ0&<`_2uGn3KT!P}s2)f-_xotAH1Q5K&S5xFv>pgq*25vR z4ku>%p%#_)!vR_umryP1{#-5V2;u&4cDRltEb~wR*MkbzQM^^S#G5-@CqoWg$Kxnm z;s>t(0N3L_R;QRqryA!poG4b0hb-%<5LTxXGyP->tey(63R{-T`k49~UusdIzZ{^IaS7G3p3Bv;t`zPsXNT)5!ZI%faJ{H-UCmpCOT4+m^$*B_>pC2T zOZ>p~25`OZV|BBMbc=Cr#ff6|ddRZg4qPW5W3<;ry6ze()v#me6QMYz!pN{Dg?oHIa1>g7Huv?|ouH@@6$N@^wg~0M z=D8`dl`7H;_Ns_@b5~?<$dP{!m7fRkqsTTW(lP05?Q1cZ_fai623mx3W9!_M*jAMo z0(VtHytyke5prZ7sj~ARew5e=C3Z|YJ0zX$eLW_bsFRH|1t;3b?r8EuXK((N4Cem! zC1!e;WYi%47C?}33AI@55MYqmp68Zxe^Z6o-;%)AdhTx;VVPZ${@mZr3ea@kDnR1R z9iU3c!DSYXHmc$WpcDWllTN}%=KvG0$~g0IqUa=zVmkgV4WToinCX%h=#&QNgbl>y zp><^<3pmxnt28?}HH2kK0&t2IoCUm9aKxKCI1P{k&Ve`zj`#t`0h}I5r+d=b&Bv$F zL|ty2CY&ffJ25$)fOg9Q&>_OCS9X9_5SH0J z0H~(|w34?9ka%+kXcgoDbQF#PBz^$e1AzJ^oxVOgCzyC#nk3Or#EGKQ&nTwWGa!V{ zNyJR|Z-LH$0G+V)xI7e`zFELIS$GY|4$dirW%>u;?5W_K%3B3Tyt#vOA>?R#HjaWL ze!v+DI75=oU>}@|OuUPYa|uoqoFORVna+q1IF}MLJ-kKH8WDh#aS7FQ1{;L`ygm13 zZ!Qz=BeKJ_maxq50Ip#Q*E-%RT;k0guInKOuB&hqF7X4`7~mT1V|9axbfaQXT(fE0AE=H4s$-MRF-hm>q|=;qj`Cqk6Cu4SnO>AMW1;S{PwUt~{me10jmZG-Xct2n zX*Va=A9Di(zhjCsNAdbb83TU3d6pe$p|M^c*<~xspu3T3W>r$Wl1o-f{{G><88O^) zcOxIKkaQ=qLL%PWA=wLZlI(?}kcb~hP6d)vlFrFV=cJ@_V$xZibWZS58AP1)>B;mV zE-JkQl~Y2foE$>sq!2162B@qK9#7aLKspTep&3fjnbTWAW8MVNoTktWBeFsx-rS*? z0y)r(!cl0%4>ach&6=chcG5X3>71E#&hT;Bmk1zdOr=afSrdQ~E-7alOtdjS%K#zf zk~uT@e5?84bi{YzEh&Oj7j)ffASE}qh zh#w_xK#A*<&UH!W+N85S>0IOMaU2oSe{WHauMbqoTnF0TM9sA(cXXm=ePE{7m<(y7 z97oM`HR)yk-pWkPo4`zOR4`5?vVtMr+`%{xaxgdzN6l3HfN?8e+>&%|PCEZcIyd=9 zoKGk~g>v+k0EV!Q-fU1%8~sPfE^jh0gtGKD)#3ses}|zTU5oXQqs65vJP+bWi@VX{ zuB4MmI(H_WJCe@rz9QEWA*#q-fg+g(2c z0*}L16%cRk3cL(CazCwd^B{f{cm@TYPC8E|ohOsd6TS|w5E?b6r?czuRG>rV$&f8Q z(MpT|sur)pShWyu?pk~dIl{lC!t)@0w0IdUUP?MICY=|O&hts(6YnXY#& zN;@ns1-fKjL{P7yd%-B972WeeMfaT1JHK!pm{n*j`AvwXv#pcUQgp)7sPz!0kF z-c~LCfU#;J-rTj=v7KsBgri!BA1yvaiw}~{`$^}$q_ZLEyz48n6A{uMC(}oUv-E>N zm(2SJ>SgJBMj6f04MCQ^YjpWbS=x#8G9S0fQu8Lr(vK93U5TtnItpcx5`iRCdkk46p3L(RwTrmI}#Hi2Y^vHnxEnaiH#ufQ_}g- zhhY-$!N=s}0O?o$6krg}$sdE9bbG-+tDKWzpmK^gcRA-kj-1m~JRZc4oPQwa?@8yk zr1PsU>Rf`-b}Cx@eh;M0{1(cwU;m%vSQSZT>{QF~pLrAHn3WP8<`G$u5O3~C)IkoH zg*cjH;s=R#DVEn#PF~7eTdU_i_=IvSp7Ph$!a0_gl47SzYi^FUS2>r#K;;x~?s6Uh zIdV3scsz(7ISY|P&|~%}fE$jPSKu@g^9L5oSdxkZHZtaV%k(EmHnc$L0#qalBQ4 z#G5-nXF(1wC*o*EiXVWs2cYdz&bBFMo0QYh$LMSmdyR3g0YZgw(afOeb4dQz}3zTxMJz+Fo_a z0?u{9E0rCb>j}#w18@=w&JDa(aKxKCI2p(R=VlxQNBn@Z8{l+HIbBmu7ayOyOw_xL za}Q1wpKc+1oDe?u5;NVSg(W%J@o{-5K3zkG)Flg6{}R4VcC79rEYl;vs=H!!KW`N) z@#c=zTabg*i#Upv_`zy8SPe@#LsQO>lrz|e>unSJ9pk)<6NPISDtVRD$Pio`h?(9e z746ZE4B*PRgj(>18q5{1AtAg5XTj?|VLUQBUhfl@*(bnjgyQu9Zxt``=8o65kb~D} zIEt6}!D|9|jZZn_QqEW(tnWLh*;YjeuI-4KE>A_f))fI<8JAFPYd?dz;x!|L*YqrSZ7+-~ zvg5S_VVUv(ui1*%j=WX8#G5-_rI2G=op2N{@q^bq@Ty8V2c(=zAFQ;A+Qm3saiU;V z89mjuYC>RjBWAj~1z0r!SYg|8c_>x~gs`g2g4J%qw_Nua8z&0aQdIJ6>!1)^gNd15)}op} zD1a;D5~^)2F_x~hp=kO zg4HzPdsud?rW2MqG{9=5Vl{)eij{bC$7(+0U{#KzScxC3jsvS>Q_e9d=jfEv?88-U zV%HdF0ZtUIV^PVotrJ3UEh1)mRVunbaY6uB#wAqSI>unGcpV+Wt2ql^2MXg8vg5Uw zu*|9euj3W3CA?L<#G5-_DU&fz#wuuesP zR$^9LCneHnguptInCa77fOSRyR@k;&9*Wf|DStKRWMX@(Io>#@S=gSD9jc=V%bXrS zb(%tT3~v=G@#YTInUDk32{;Os_<`y|OzVP_bAHM>FXfz@a?bGqJIfH9ZJaeYQNS(; zS=S{Yz|J9N`r=e{LGO|Pu#8Kn)^&c!y3Pw(*SVqRbFx_4xsu2w+2K2nu*}5)d>1Kv z=kr$K6L0SDT@5+#U4o=x!h^b4>u<)e7B>yjAGLn>%#( zLk@Hq9EDE&Kz9?+{XON}=!5oviT7{gJctto?e8e#RcE(^KzoRo>6=s0d9hmp&@wKe z8r+Qrc|mQ0R~8=@2DfBKu97RO@AaVzY-0s8i zyovOJabCoU!f|`ZhVBZ%@e(o9nHF%|6~Ga;A(ux4jhBV~uIy;MLRcmfpmC?7@hWc> z4e{oV#s`pt##=awhWJ6_0noTV<=p23@}Y_Mk#Ro8i2`ze$UYtl0rCkk(+{Sivv3au zfMi@kwU7I<*vF^B;Gyh@d`4L2!2pqeD>o`$9y<` zGLbeK=VzQK9FK+UnkwNljG~Z|krR444*_~8=PsKhMW-7LLa~JzK$dUFim6iwbBlahV z{c+0qDCK;Zaz5}SKc3KNj(i+Qp7|)0BOeCf2RZUV@G?t|NW93IpHEf6)ugEkiZ^!! z&x0JjPFKBn5I+k34+XzWIbWol&wcIACkV|$`SN9;T{vI9FnVZv{dw^0=F3+q_60Cg zvBjIa*tbBAwChz`9>kB>KO*)IDd+o?^IgjMHsyTd3x6vSqFM7pAbjR~q?86%3d?sv zE@ZwnJq#%>-vqC-WR7m`875ot2L7b_-A;O{pLlcE?_tPM>uyzx2l1od@96hi%K0_r z{E~8hPB|NW{T?AgRKMRs`u!Tx@0UQ4%+G;-8-v$b^lN2&f2fv^ld5Vd-rTi(338Ns zT9xBL{Aih1Jj#g`J9e>S6?>~oFPo^Z80S@-Xd4hKmds;Nb4nuJo?H98n`vGnX1ZN* zv_5H1Wbax)mr$ETyI5>iSEe#n@a%V=UKeKVWrel%lFb{0W!e?{OE&RhQSD9MDnR1R z9iUGjhsy>WZ4kr{K$`M_8sP0A~vY=PTYSIO5G6oZlb^obPcI9PtCr4uG?Lv9n#V zv#pQM?xl`o zowEbP_3>6_rvRWG6(BDAHvow@cYr!Vj=F_73Xu2#C;>p7i=AD4bha_^wl&UnI8p2A zY?M*!DGs5tJu%a%7U&cQ=!C7u<)PNIYZh>J5MIUE!P$|pOez2;so?CyTeTkX<_=Cb z$N?vTqu_`iaC!hv_hM(aVy9cN)76J)Hxs+NaeClHA?l7wo&oJ1f~Y4k(>;r6m`t-d zQo1v{2M}dkLN%b>0$eiPii6eAuEBfXn0g80-LvD>o3KpJ053=J>cd;bOT4+`H3V|- z+7n0d5Sy#(dm0b|Yae2!`?mmVKmbtL?WtIe;jLmN-rTX;4|1@Yh@)7EAFPIh)v#h`Xt6V- z*ct4@HPghNWt`bKQMiVol4n~ZLvWQ7GrdnSoq~{UjSS$*xP)q3LjzngLqd2B4&M8= zRUwQ=X2)v|VVQjbyhbQqb9t+Hi8pt=4ul-M=HVz_;s>t@;5EM38CUF#^}$+fqAoGc zQk*DQM58W+N9Y!g*}{dx9of!O4g$a|NFEUQRFH4<;`8p(w#a5+g8;X(Xp zGz^V~mN-L7oWZ_2XA^{~Mx9Bb&d@-ea25_R+K5V-!A6_VwFARd>@_e`vBjIa*y|ui z+VfRf9>kB>V-S0Ei8HFi8Cl}&<4b-yq3Pb?j2InAo*9LR-uPpr5nVH4A0zteKfRlJ ztZH-xiKs^6&0V9LAxDvGRS_Pt;aEphfOai;i^KS*eL&u~Ue3nb4> zMMN(n_BEnwMoclH|9M8tP>miU5!Fb%xoh-a$Wi1mRfGreqtR?MnpNV=EOGYp)p?d6 zR1IastU#S`M$9zYXh!U3v| z#eSQhXhGgT5IZv$`N#$NlbI99z3FS$%;@_7RpcGmt0LmfU6IcqNB;L!ejdb+BJ)vX zUWrrXYwBy?S0%)oyAm5ANA|B(b{@o!616C?sKi-V;w

z_?e(+Xk9ljVRGj;v7`sEc5k{`(L6(x*^ab zb5JNZmgT0%a#dt!*sCJq&0UdF$dP|nm7fRkqsSpBa&U>$ zu|k#T0(VtHytyk;205~KSJ`vZl zB$#;GlbGqFN}|<6a{xicCDcmpumFS1p***|7Nx&1Yc2t{))P+y2+JH*;!ivssQ?Y+ ztpX(8+yNR1Ik?E(Hd^My4?wE`==c)nI3Jx+Cf;b{jKPVbbG%V(we>_IePRfmvBXTT zZh_8;0Xks=ad~LVbzBy3#tE+zvx769u*~WJoD&qB3A|Ns#G5-f`$G;m`{5`!;s=~_ z0B22!b9RYymXD8ICqvW&j8laZ#b*urcw@WsL-@!AGwJh6qSe{?0X`X*P_5@|1F`~i zRu+Kt4x00`10;9KWX=l!I#&Uz;jIEB-rNCl?~Pdu7X`?@H|A0Rx}?Op*hi<42%yvE zr7@Qn#ngJ%h0r+|y7bx>=&TFS30sfLL&3Q?3pjdb%)0F0=$$cZ18^==a8`QYh&Oj| z+`C}>J7dI;^;`=$>r0$#N}Q{Gd_wod0Fzt>6Sbc8=;K+>4Iz9^7JRNRiB`Wi1o&iJ zLbaZ249E)5)mZ>KMVQ@?9U!?OCUboN&~*yXX}neI5pV7QT>v@io`s{5(2*Nv(zmrh=br&OVe4^uC^-Mf0?wtv>z~=dksD+( zw*}zbs^F~Ut%4)o+`+jXa=^I~N5K(4;M@Z^cb7PK`QY4O;> zf3>KX?+d`mxP)ptcNv5QolW=6z5OS8Q_OwY;nJI8{uRJ=uflZ;dMI4t%^j|L3=Fp` zO5i4b;CcwS9`vztuao(gi7U6oL=EY|kRd%9!s>ovrXOj6)uRDcVMB6x{B@`v5ay3& zhe~dc$vhH3^{_%EcgHAH;>{hZry&QSM{(4$#1B+Y1JzR{&XYb`&zN}br807DOcbrB zLYDPx2(9Ocnf`B!O8eOWt&B^kmi1(=mL(U~q@T?Wmt0Yk`ELN%GYXg7Eu(OWH+Q(+ zg&eqE$5FV%4_q$+*NZ+@8%(74jPpKD6ss3Qmi1}~s}G2oex(IguLf9!Ez9Nc*DdQq zVg71%s6HYr^GX2K%L>)Uyj7^gn>$qBLk?75;wV(&2dZ~~>g^KeEg!8POuQeB^Ak=K zt+zv#^`-k^Smx6Js!tTEEqJR?i8ptsx@opIE%#1B+I1J%Y7=cf|q#}elUAG2% z*LafB>=1A6dX+0^fxRjs-rN;A1ajnGrt3R>EDC5O3~E91l6NAEC1IAbynC1toSab#^LscJ%dFMNrg;b`JE&>=eq49dlFU zZ>q=%uvbOIo4X=wAV>aFRem1Ck0PB>WYgA;9JOH6*~++WwyVD4`{G1Fa2 zqXyYEfFR=%YKNpaz#x<2x#is7wZg1xDX_Jk`;&{PGF?jjxxcgmbUkksAo1o7(Cv_e z%S||1=ZPPHdIFGB>h$o@xx>V}(>NKNC_0W&Ovm57L+IQ^%yh37==2WI2^)yZL+i>O zS-`nlc=gT>&OL->dIjL@uHf9uTLnkFxr6gKF0Rt+*NHAjp3`3MG!StSrf;s0=9t+1Ef?#GT7O}XD8@AR)>%?AO|^X zscVni;x%1zhLh|>)|UG+lOF9;R7 zC`PBN3EqtdU4KA}&_x+^4F_GrJg)LhqNe8343{uh!vc=9Ux2ITNU8SC;A%ggtDqxU z9eDmEtdW=ukXrXIIgbH00 zqtjK6?4YX%7om$X=sE&)9qw_}$s~%K%PzQtxjH=HS>pp-RUoArm%-I|pR1r}Ssj1h zv-kltH9j|04&wAUpQswhUM>R4n4RfppuR8a<1i$T@dWzM29XJMJMpv;-? z(Z=sMsikG=MEfkXH_vIE?VGO`Ss&vA-a^YEpR^a0$(dKaZ80CgFYz?mw}1DO$S0yy zy|gUzlUOEX@F4e-$V-HhlaN>_p%|SKex3=GOux+=af0iJU;l@ zCeURb3`dZR^L#RbzHqMLLWZkz3>PFsFEeD25&I6!1!Bc4C>ARyMz>-)vcrmV1w3vj z!;0mw;^H#rqB7^gGUwl(6_+4ZU7As=7iSs5w=ncYfl9s5uhf5UvQjg@Om`Uy)t6>f zstNHc^%9}uawHZyC`PB_R%8bY{3?@FDrL}dCFr=K%(=YGxvb1t>Ctf;V#Aesh0le) z9G1F|&6gQ6SgYn$FR9a&hKoR*UL{7{4!vRo#pp(?LUtIT1v_pi!-(r)#C2uPwPnsV zo&^shDr~`Zz6C+Iyf&u+*JK%RgBb7#)QSNVqZ{xNvIF-Mf*UuKVZa?Q;Px`-wle3| zGUt{u=Vs50mytl-Ri>r}dz;&ROZ063%DEC9^HyVu9O=8ocg&lOEsgXx;SV>zj`H+f zSuSZpe3!ga$an*Zg$#<($@mo6!2!PrB`!%BWZVZb?k#ifDRXq0bGOIDXNUz+fqv#* zpN3$C-eXvhentoSnY#@Q0iV2ItoR&?#R`hit;okqv9RJ-*9yw8;!#-fNSX6+nX{_Q zd8o{J&@-ed5~#<^)VyGoKH}S=9|lmjN>>?Uq)H$1tMox*%ipTfmMBj@o>iqL#IMrF zgp5{5EM!oOPDXoV2N|2=B2`KmWIPQro+@*mEOVYHb5?sy@MA|HDo~|Q`7{Kp^hv{l zROu6eDqU@82vq4aV#W4QELKpAZUsMa1S@tH@VKE2D_(&WFPAwll{qh#IWLqs&zCvR zdA7*si(V^JGpsrLb0mD(H%Gq&tZuEoXzY<%eZjBQ=l$E~jAehTg1Z2oel4qlO^9E? zuL?C?kyxmq7@eBkkR6Ql5=L-C8PvQ3YThn$-YRq6EOXu{b6)p&ktNJ}WzO0% z=Yuk5O_}q)XVig633o7#D@J{o+o-hxqdo{2vLIRb3QF|KJm;s5mD;PjLFYuzD4>|Ky-cg6Jrv6m(L4%p^x%5I-kv)`kaa) z^_N*bYeIaV{X&?SjKosC6r(dS6WLL{r{f|_PzDpm|7i0SN+E4 zAn2-J`?YFktm_5mY$y<%6rT050ByL+}$WoH&>aDjV8pe zv}THCXe1UgC`KoP-_n7W2XK)}qYN_IfQ;74X{DT&%4wn8P0}Y23!(yJe`}wHVAZuU zEXcUf(y$ARyMz?}r-GLR)33%L4h80`EiY=A1g>p9cOnBWS zeZySd#3j6dvZbv{erI_bO23F3!xz{@&Zq?##%pdCQa_R8ttvBOX2Al+By z@-;4DcD6T$$qIPK06X6zrP?WjosK>`LEo@C#5X$RAm=;k>X@6H?-8eW^2ymz$oT=G zLJq~~MVS1iBRE-VsyR=kR3F& z$3>ipGWhBZzIrLAr*e9DWEGmEMdnhBOPH))#!m64M1ZUkq*Q$~$V&KR1^vnD5UzR# zxayIEt5WJsAyl}c7@ezKksVz1!bP~E46X)(s{zW{T{*icXIGD| z-AwA;&1C>CVY&vuB-giw1n3%wlxnaFKb8&g>C!f%_}1=*bKz^Z0AIW2;A;>S56R8f zV8rRcK3{``uOSE(z9>fLYj0!+U)8t>UzEXDE%>TYPPKBXJhJvNNr#!sa9qM<)fhX) zw;BRujX+9OpFviGPgc;ktPbI-I>1#`4zBj4-iF*sW*eUlgPBbr!ONfirOtz9@sQ zvEXZraz-m>lt&i7V1=Y}&1D`gVY0>;JH@vS3y?J*Db=A03)W_qa2RI^hXu&88HJ$H z0fI*5AZP)V9hRG*g^1IK`UD*!1T8|S5JWLLK^G!BtX_tT5JVXSO$0#`lrvsA<2-^c zGD$Bsm*u#G37QZf=$HUOmmsA&T47%zK+rJ(f^0@1XncU6aXAROl**3DP0$L&>7#vu zjuL`aB2);X7@Z)E>>%i7T!bLXAn0@ubeeLeDrbsvCVL#+V^Z^jS;%xBE@6&NgGp|S zO9wc*A1T$DDm>9n2RO1BrNvD(Ln!j!TRF3oGt(pMIg|8xb9n)mFj=#Wozmjw1;~04Db?HzvgY|@ z1$%R=L%5n1;A&J@|vR}`aj^&zr@B7R0pe2X%;ItN@W zQ_fQ5EK$y4<(%y?w$5bu$Xq_gCCu0|SmnCc`2og0K}vO=3NMA7?=z-tMscsDhIXNB zNr1A&f%~&_(Dx||IX^djpCL}4=hJtt(8uqE34Ii!)AtLqgFb%MOX#Bv`Yr)|%awDn zaxPNNg&udmn$*9U%kQ{^xm#|`7H?Y_;O-BkR4X#LTj_Hb^fs$QsJl2o*F}N*3v*ES zC(Brwn>v0pOt0{%yHu##fKZ{1Vsz>n`6kyjpzdnrT;-9rsc&*!4P#t~yFNgge3R=s z6<(#g-X~4ljN))t8Rp5F_wgV35ZCp&8IcchUFS1$tuW$!h>K!$MoREK95_=)T*R3u z!$fe+cN05-KQhyLsmzKjZVyedu}%P#V~!F z&&I972EP<0{y{N18@-VoZ1B5b!UkoqaWB}oM>*Ofq>o9*&v7An0+%o$_XPaofdC~o|Kg8+#eMasRM*1UE7@-)Q5q`Z3Ci0_V!U$zB z@(37t*rS7=@j@bgw+okQT*7ob9Pp3F19a3NrFu+Z;nYl#j^rHj@cuH<2<$0PCa@_+ zhkX{Z1NIq$7B`dudo5sppqw?zd0#p2dC2D=He4eg_{jAdKx9|W8hPI*->;GP{J6WGh4Okh)t4*L#d2ihA1Ep8|S_Sb;@m2$pR&KDl+J5AEN%;j!e!d=E! zKjPbeMoRUq3VY&u-(qbuN)P&_Z>IjjzxPJld#G%E?ylrs#OZJSuH+jb=stuB zK@_7Cv>MsL%R{(Gd!r13eg;85Dd$IzohMAXC(Y$4T*B=9WQ>tX+iwAOo<>UbYX&>N z`RoM!!RnB9`eP1qo}sSaa+C8c;`FaRIll-w&mmOEp%|TKl{pTXR{DOPHP3#xU`o%>(RwkCbY&a&$AMH#v^I{N@36Y(`KIZ~<)<>4`8`v5O)MvfudSaLC{>vrYduISc&aE?*L?25u$YEi#iv$*YZ zv)B%Cx`WSRdtq@KgbIrkqqA6u>?pSbF2W*ZuviEd3(B3H%bkuMg+(T5vALAs5~i@g zn#nH?l>{g(LrPVgL1Bqcq3xJt6n1rx!JT~uJN|tJ<1DQtH-oz%P8a(O772qD2o(k? zMrW`R*}-5pT!cZ&V6Zb7tSEPODR<)KPA8AVq)FY+T>9e@Cb0sRx?^A00ExRHrRtJF zVppF;?PjDO?&8y><35X>{NNmZ7?{nt8@Pj5XxH3a4n~~r;&bT;mqQRLTvCkAFE)xeUW4Ok{6sEWNQZK;#IdREZ2CD}5q^-stL} zH}>**>=~8E16XEdZXQP>PA7aG`wEW-B2;*!7>UOZc1gvYRIHr*IpD5k#Zae3h10yk zX;$Ght+3-n7u}-b>gnqXd-6|SL1N1aB=5>R-AH4edCq9X(C)+Y;}YEy+FDoWrWIGu z_zq7kGiJ2SE8JlR@fF>=0=X);s$gxcD92Bl{LnTpeImw?I;z`F5~)=k@1NcxKQDbU z!)qnND`$AqIC2lqPsMua<|yH3TS7r)y9#{WU%*<-#fhye^5O_i#d;HQAF22o^78Tq z5EP}@2>h|R*uOFi?@1%fpvSCWM%y}cxC!9htRhsRXVYe4(>DKsP0ixSJ-lfuR*7P^ zs0f=;;&Qizl(TIk`_Q?Xr9d0;CQ+f7KiK8qxuE#naKAZjWA zBuy*KBy4w~(knU@8z62O#q3<6I|O{y^PHWf zn3Dgf802O#d!v}b3fWaAEs>a4`a0P z55u$9poRzhL+WLO_y=zz`A6Rhj00D|U2$1~3+r5D@G%;`GOEHk*!7b1l}MluuHbJH zN$~|7%ktDg75DR+p2E58s0!Q*dXo@{=M~n;IWs0oj-eB!uYx84Offp(?+xH@T)>n8 zcrpN=TH&1H0saBu>SVyfZ#L$o&j3Eb4NSim>QmuT_$?IT)2HAbKVQ#ubps`Ja*6=` z5gG(2#YjNk#{iL@go?)HSX_iz$^bg2^HArk&d%)4?&HLX2-mYadnalwv$HxIW~Y(a zvpT!XnuI{RI>_wY&MfLAXcE8_BLRN7b1F6_72BUc#{lFX0Qq}o=eN$zuP)B9>g&$t zxn(91{SLtHsm0$qn+X-?MZe%9ympl)=0M@Gf{C}0F-=XyCK1zAU}_Fb%^atx12k{;cWK^AOt=7w#RQ7cO}Gr%f&3ytjvLA_VH=px&T+Q(@L!H_7#5(q zosU0A_10NbZ!0+2p$krm(Q)34?0|QTz{3q?;M^WKJ2*~z59ci=-L2+w8!qf#)9>PD z0A`@NgJqhB7k6^dUtL|u$zb|+Bv3m#;Rd>sZ=#z~T4?)#jqU@}9aONB11hqYh3-V0 z-q8UNGke-W7`Y3f!U)CajI2U-0KXR(>BlL9ks>fs=+W`8N%V-hJc>)0jza5fdH*U@ zr2#q~LrPVWK}V@iN3h1N4ryF28;>)8X>K-FBTkq2Y!nL{Pass-pctKvmysQ8JcEm{ zK^bgRfQ?-oC+-pQib?mXxx9u;n2=op{?R2s$m>X{94Fk{bnyw%Hlz4QJcob0K?PlM zGx8?lwBs|p~48o=!~pGb};fDF2V?9Fwzr@^zi8T$RzsMTt2}iOh=D^fAk5^ z@hMWO-WhcC@#zTqht(1CkI$IDPi{6oN1X2Mv(Zb~_yVEA2F2)X{Dkaa!<(K_1{=GA zjsA|)&m-h#lkOLD`4yKiA^ijXF(5$5Z%C$KzxdM5(>)P$-km;l5#dm~{|NI`^^cU^<^;)s0Uic7nIBnBYLMm_RYQ2?=C} z3Ec%bZYaZq17O1bjKq1z-bH_BZkyKy%<6HCfd*yzp{##6z> z+^u~A;`9W+wT~A@CL&ZAp%|SJK9Pb5?-`gf7%9P80>vPpD`xtxkin2uwu%W>{B zDL}^*q*Nzl&@suUBUs~BN2u>Rjrk|#X5)0k=@Wc5ju$r0K&Y@mF*+M_ksWMI$3^-+ z%3xy(*qH1%r+S3UGwJ4=%K}`&giH?j$LRq=79yoO%?USw(|tm;%_#nHY7YNcLC=2hrV1mA5h{#OjLyivksXYjgNrai8H`K^Bhx%OE;NZQGM9^S3DYqx;2*OB zbSy_oH8X>bSw0;>|FAkj{&5NO&&tilrHIoreKuwY8!HehY*38EM*l9L;XX_>aJdH; zVS_T*IJV1B=a??;a?$+=RHM7tb*;Hv-#Dhr)idT7;Tdaok-LI*To-D30BHpe#prnW zZ~-l=1O{#>1J8-TGpUPnLKo+F4;7y^)S+EW*SmGv>Ee9s0sYpbTaSx+ z&H}xJKtIU>`Y}T6i^A?{BSHEd@(R+=q9T0>%Ym*p-t8i_-q@|{P^W8Gr%TtML+UPF z`Rj2#x%V`LkNNaG-LgSt8cJx<=1sALr&4Fx9ygPaTs z2t(B15JSjd7#eIC+EXll2io+&Ooj$!1QaH!B{i3=Hl4bd^ladtnE&$p9>5DFNnnnf zqTh!ymrB-45=p?p8U{BR9*a|q?p?Nr<3fTkX?wVOFj?2tsqO02cucZ)Bg%AWFR}@{ zG6u_yt|MC{u1QnbvZ)nn(Dh9#)HS$Y&rcFy2RGz54PuGc1yYP|3HMdN2YWcNgfe_$ zI4l{~)!C=3v$tmnR|&+D(5_jACBrf-*(YGh-i=u@LM-9(gVYJd=$7!A9+v#!T0$9? z90*HBc6AQu>g?}X(gacJ;I4Xq0n~&1vY*VC9LX_oo>6f6gFQcA-&TzbxjB*;Hy>%- ze6$$QRPsYnGu-HdMY%qJ{Xh@=X9>*_F}!IK+T+N=eaJLdAS@8u)(;Y8T!audC`MxA z)~--{6@Cd3mn(6RdZi3D_Ut~?8QR?)Ev`l&Yjmptb7l?HL%Yx3W55X9)pf=V_L}i0 zS=F6t_(QD%hGKLutB@U99uf?=p$sr7fNALN)O&dNd#Y+txBG!1FMSOM*oN*rS^?+( zp{=gZg>Nsx$Ddjid=#VOdmPyT>oI|a8_H}1z&EVBvyX>wHNvF@w2fnB9sKBFf{Azg zxOW)#N!$nl#vfKSKK+k?J&o+Z^OWGh4P^k^AHeqO?(FLUdj{d^0!!TWByPX%s8=}w zvTrWh4iI$DBAcM27@fAQ@#`Z1wG}SnW0Zkz0?>{3ptVDwa5fDMQ~YdvchqlZ*0DI- zK;9)M3ZQL}SO8Is4rqI12O#r{m$;z}K*s^lu^u4)DkTA(DPWGx1?G4Gv!e@!VstP& z8!#OO1He!Qn3DkJ#O}@{4^IKYg`in3K_`YV=}93G4;AF=WPw&<7X9EQXZYTrL`2cjD z2WT(?3Fuhq7S78B<^lmT1PKKU#pq!88=}C#pCy$Fqzo{Z0L*d^Of3QlW~_i&o(s&S z0;UcL1q{XLVD>?FfZ1Cx;D$25Tm>*!dSHejkYLO#;mTZKt`;!Ekx;-;j1J}iWCw=* z1p{s<1IbAtzFBm%{6_`E6X+>i^KC@D4*hfk!bqyd#kvsE!a+xSpX6!uN>a8;^{Fk79Iu#~?dk9WAhMLmBv<1imM_JF7i>$0A&+v<+uf7~S*} zAxwI8NVF6_B@mB8UV%t4I>brH4rC_?GTcxG#ODF=x$e%h9z_0bY#8EmAx!$&kZ2*k zAP`SNUV%t4I>b|v9mx3OvC>~q2E`zifZ`U|1{|a6=hj)&tD9-JNedJWEZwWw@yC zyQ}N$kbMV+Z1qETJo&6@tG@}O?147Ir^$1WM}Ld9j3hrWi5qb)Bfe*dnJj)M2Azjc zF^FPxgO(#Z3cVN?aYV{6s7VjJvev`N>)}3B^2cbUt=#DL&@tljCj2@tB-*x;--F7% zpRA=A9pbeH;x#Tr%7EAb5ZinB_&c_O?<^Nz`&@vw7eM@RTj7jibU^%#TbOmD;J^)K z0NM$FcJu(VLU?@fhb33vF!)<~AH$BwtEwaypfUk;FA@tNiqQc* zfb76=zu>?PWdP~~K;<4F_ZNF72|MMvz{CX%f3R1;P>cj-w;m|`7cBnZ@*^(N)+hsv z2AI1&Fux*DP3(cqCmg;@-^Drp-918^PY6%mBY1v8TERmxI-VF73V`QN7Y}9NxgU7$ z>*3t%L2ANvh?4+`3pn=>(S1Fxo;DBLVbj{_d%auR<{uDf`R*bF#puvl8feW05in8) zw1)ugK@V3e1gg_W)qO>I>4ypI!7x<_Pp%R?t&vu!q8J^|mdFkmn+XiuPzIhyfahTk z&sGRjvqN|u&c^eo;Mp2!1rNpOcsd|EU~DTea6=h*9tWPsJUrVYP%Q)=?8>AcBR!7+ z&g0z1ypP+M2u`jRG&>-rprIHYO(C)aL`MOE8_GcQB+xwJp(#S3S`tL_L>8K-1Whqg z3L1*h(Uc=QK$Hpy+)xIZXMpBu4^1Zos%tHpC&|szK=Ty2S;m(X$j!5YCXSSXhGKLy z-H;t1ItvKgPzIV8fadug&T}51?g&>m_b}VL&lAw|J>1<<{T#5p$gR_7Wb5=9)E;{C zyyT05um`dVLWm$H$Lm3EP1HxB(IIr|@UiLutN0d6&f_$4GUj;I|F|J?f z;q5`cj9~i-WefFnfx0Uc2vmyEp^ip&AUseI;)XJyz6Gdn_Hf?taE?K^I@98Ok2v29 z;Cuu3UMmnD-xhFVkxRf)j1F!bvIEm$f(bX20q#A3d$))4jt6c$!qwa$xOW5K-pK;@ zzJQy6Tmp{bCcw#&^1RJgZJoD8s>#%z^0ow!%b`&^Vb$1O3p%tdJ$qi6FRocpktxH zI@^UsF*2-kU06#2Ye`RMv4`wDBAeS2qZlYie?w7= z(O0tQe|be4-_ZXS+fh$zrJk;G3%}@}6n=wS_$4TOc~9qJuW&xo=!;QSu>SS(pxrmQ zMPK?)islZXG>D>Jc%`A2Q_#zOu4;i8wX~<{_P=B07xtpLsQk4>x&ZfUcn?QVJNGiF ze#}Uf;XJ`SqNUEBz$os;*5&O$QjF|7UjiMG*Bv&20%Kbj2E`~ahWAOuwoS#hVbyMnY8}-F zzv|k@*6DU?OdmN_s1NQ#5->MfRh%~jgYGKUUwgFxa}&%F(|dwLJqBr36(bFr1<+z# zN*vZle5Qkqqc?QI4C;wuOzpmH3n%4*#ppgLdwaBVq)x?lPzUu1M(ik_%QR8VDwLW( z0tOxK8dRjlS%VJGWl(Y0pmA9SnK|&0#91P^cpC-RGSFR$%%r;%bYBZ}*SP4)4AY~5Z$vco-&JVn$C1mGTEeQr@TCz*?h6soZ0LxI@_3* z)R);0g&&HZ!=*0@#2g{EF;QgO(*FWJbY>UeLU&Lr%tbS+H(8?n05vvOcbqCc$k z14b4x0J$%8)m#+Lu_oWZ?I)=?mxnPXi%j2*s$d##%FZm&&02{ffM-V@nbPV3r>+rHBDgbGfUAj{<=Nh1RUyB^93rV3x_kS-(wb%ra>>;7Dyz zjBeI-$PPT$;v%(08D93C4$Q1^ zY>-h2VDal@BYpbx0sg(E?O;(PN38SXM(b}Z$E2hh45Opb6Z-*n7)2mT=9}6Aoad|I zr9mDI)|@7O#AO(XxizE@`+8amK^qz+<%Xh<9KnU=Z`Tx3~tyO}IvA!F65&_{^zu z_`(f|q0aRQ_xVXm;wwD*`h=Zqf8$L6XV3UizWXLvnqaKJW7J6l@jowlV}jM?L82HL zQd<}#6T@2p=@t(X-$6HX(pwsb)PnTHLXd6~NZz~Z6eC00&V_UrAl>OfYVSf~huFat z^qr04Yo3koZo#)ba!V~zjEt|)#dkmO-RI#e@*v&UIHYFTkRA|7#V#a@ks+D4`Qca( z1JWuF65r%EwYaKrNFkQg{fYbOTj|r;dQ2|!L}w=pj|kcd7cIreXa^#<_}sHV`;3Qn z5Q5cR!SbIG)b@$;wS?)F275-CXpDevYw6Ym0+z)v9O7^CIl(%FSo7n^4!_wWJM#wH z)T(l29?HyIdZMn#hE^fB82Sbbecdy(8o|KAxAUcT=+Lzg)LRKtTd%vdHM7J#2Ug+H zd436os~K(aa5h6;VW|sduZN)DLbe%vwx;oKioJYyU+`0mjDIiW7W`{~|9ubt-Utpm z%KO2J`p{O?K1}v(0>cOJq!-emg6S;I4+Q5h;>?dDE4UcWjBotCjQl2n7)U*l4Lkz5 z#lVkX;5yI1BN6P?%s5xj>)dK_{Vj7(=wpFD-i1UlG9>%zzWHh$$gr>Oe+__NC7dr4 z&KC*ia}O!s;n$xh+!3)L@v9}DZ}od7oXS*Rh508oqkPrjk!ezJ!sgyx#YmnNi(rH=g&Xuk(>8`}Z zgL)MN)wWV(`J-D_Had@L!Vx&%PFjYzU+B0RDs04tZn=`aF!t1rr0g|B-7G4)B33a!+&D72srdg3|_#Wg2DvgWOFlE&6j;P@syz0HzB)T6L5BdWT z!t;V1q$icpDek6wr;3^U)(?I({w zh3**elQLWSqqcN;k_sYt%pgEIAb32K9hI+a_SIf?JO%}`KVh;X9kM^kRD4iiulAIm zWy?^Or6dZh(hB z$u45Vw+KX)APtIHPem1#=85ebP7#8Ng4w=fHd;k3k*%6ywx}lKB34m`Rik0mD9@^? z2*eCJ0A^Issw1pbry-f?W=wRzeKIEmW5meQkpW}rk(GII=z!H{Na?saGh3BA9UYKy z-o&U%i>f$OA@?*2q=a#iDOrfzP_h6Qp@cFh84pUvd6X!A=(b6yLBN?H z;0%udd4YUdC1?q{*%^U)@hpE7`Smoh9Bp-4VIKajF62`p{wC969p3{N#1x|--oIZe zww*jf9NG`xMeAoLD(%(b{Y=9-q@SIOT!4o;V7j0L&fX!swRSktTu=g7YupV~<4%Y5 z0}-#y^^>eOu(K+fSi|*Q7=(^~e1dz`hI>_ZE`noWE*GpcPzODlE z#)vSV=%0#p5}2>|AL_i;-#T90c-?FLt=C;;mk>BKUC$+i%Zdq(XX$Q*IP->*f&7z~ ze4{@Y+eM)8HVR{ef?wD`8+`{*-gcpMQ}6XRXxP2D&Xn z3%!MH5^MWQSJ1Sho(= zedt9F3p4W7k`iDbRPP^ zHi`9y>LI4)OkVU%w_86-fZFf@-Op*!9;gQ7OvQ$JRkRjWByoF+wY-gD?H>c=r(WPx ztp*NtS`M`S-6<7|!%qbroTx&z8K_%IB?F``;rU%n@9M1D4%BTBp*;t)9^p2-o;dp) z7}B|L=AQOpJ?51rwj3y4*Gro?>q@N$!pz>V7t#2M7Ij6hU_@UrmT96G+odWMOUjR_ z;0lv>tHMTll{LAa-nGhpG$_5n{5unt0b+9ZDnKya#M`Jvj!(tLafls{BFCV}(N)eU zx6}#hkSc!ph6^wJm+k=p#7?GIEPHf!jqdco8R>24FDCQX`*nVWT?GtGGNn$&1quQS4adXU! z%yD+yPzDb(!NZIyXL^-0t;$KeRHPRpR?V(biKMNsM>!Ku1J)|k68_Y=O(DGmN%d?2 zTsfyoygt1YVP0cqA3BTZ)5{PH=SM0C=dg&7Kj<00*?PK5jh=?kJBkf4rX1YkpqO|CeTSbFOg1Q$E5C#VFkDh@VvwWEQ+|L!{uQ zWA#vHr)t|{8pH+FYV2;P%4hIHIj_?7cdDK<<0ZQOOXB*^usf4q-U%N@E-?JQ*X_P=+tl^Ot9K;Ts6)u%z!DkCv!xJ&uM8O*9OqPf>JQO2!Lou>7TVkw$@-1)?Ybe8- za#*80Yqmn5idU<7yIX7Cp*0FH-(=mqDRpD4*_ug1*2HsK(+=shiL%yo5^J_WxL89m ziZvDH2fTp22e5Z{u@BMRtKBu?Rs%86D1Y;#EsYD@(YNxMT&hff0$o$5e9xZFD6D-)i)pLRrmyB544j`^D z6)Rx%7oyPJQ0T61iAAYcu^L)!1{HVgDN$7j@kZ=jfoV;V8(Hf1K}ywBt3&$*=4&RQ z8AU8){4$^#P%SHt5|V7F&WqPoOCU-xZ<@prs0YwcUBkb{iTY~s)=p|rwG^j~YBU)> zvJ;zq2$o!w#0mp0aj4P1iykVWiNlQSs5$-2TI0`b0D&wv zp~)`h6ekWhnYtwRp)YhD-Xe|={HEdX=5gr5(^L|MreZyYH;bb@JQt~{7SM0dt_D{_ z+wv0CkJnWt!P3m{%@rq(FeUUdCG>_OgkXZJ2Mg@VBTal?*NkySPDCkK-4zYV0TvfmYt>_4B4OAX&%BVw|Qm3MA$fUd}$}#>;lFSsZ@)(n{ z-e_t7+XzX;_=AE2gAHbXG?;zSU=WDRw!t7!50nNY4WKx&pV7A0CL4_8%H3f0RyXuB z#Izvbp!Z8I`Hp~TFostUu}}CFoj@M`#?i3hEt0?<2fE?SQ?cQo3k2bCIjm8a2fL1- zTHAH(tCrZt*qU$xHDF8^IJtq@270U^Wj{ml{wN(Gsn`JP~0L2kwVk$O)BgRDd<4G7XPONq&xr4@0_^mlLB{)P( z0^+rNB?S*9rls3>JI&3G$1|fkB}YHfMEa2_!G1)Q_X^IH+@9n(eTwj8tS(5*G8J?@ zD}RGo**Te&asp}xajDpe>eOm=Y;W5rw?OTv<89w-G#RgU^`8{3rC<`&(#iVNQ0cQx z>8E6tekw{wTq-t2O|Dk;Znw$jbbX>|kW$5C`J8U7K^PuaO$lLCQ^Tl&Nr37!JvoHx zEQ9LwOjKt872+^4OmlV`dhyR_Fr`9edKyv)ya1=^>F%VI6i4+f`OPe7ei}+-Qu>VC zsCn?Sxz)}b*U!@YIJjC+t>=hQaDs1SHR&6fS3i$PDB&4yTwXMnm&}C+uJv5x`oWyk zbPpB0hH$l5y4MZ1n@PXUuqD;uMeGI0`%UP9!%hAsRWD)REB$dnVuj&Yj%P!+Hdz_T zIm+Tv-r=czT066YKWETMuBx}83cHXi(c3_YuN3=smszFn_<+%{%)8zEL^rZsj%-Ng zXWLMaxWZ<8&t&@>SmfQCmab}^EQjhVq1siohN_kdWigk=4;Z${9i?OqD!mqAK9;=V z#8nmxkEB}#8(alEln%~KdarbzP{(iHA|oo4hs@*WV&Ge120rg~;F837R`Vy+a(1;| zRE>sX*TT|r9(|Dwq~Gq`DvJgmr&lNZS<$>Et`h!wf>A3PTI;h}L}B7;TQbk1TmRBa z`TXG;_5~u6=ZgVf;ub>=vcQ_JC^SvNo;c7WU_CVma9Po_i-@}yC9bhWe1`;dCrKkm zxJ^lN+tjVF?~UGTp%)pUmq*)8LTR(biR<7ZemRKczX1gdm$t_P?`#rqt~8_Y?;%$^ zkG=!-_0W#w(Ec+5Bp1)J=OlpV+EIth0#L}pv+L+>=u-4pI6DG)jy-N@;)!#;nC;1| zpU#&Ae=!%gD=9|qUw8l;r8LDw&{D=Yb`$!S8>^igy#A%RNynG_k-Q}?>h@}V1KR!y zc?K&)12!Mra2eSgY4q(f^SY6LOA-%&U%55GWIfhef~9Cac)L$bX+C_bOM03~Ry$4) zB&W<|OsVMOK9dc{&x+(nBKc%46=^!(n}r-cgM(6(4AdQ|^VVvkNxazHGFN`D(t=neky}tN zaS=DBj284LTF@ia&cj{{>TS~XF_#1`;c@g~X-mQBn{|TMEZs?F2|bX#ZXd`h!w+QX zen=Ub;XWp`_eU`50Q!J;R|xtMcW}la^o9iQ#zG#+7~->`ZGl!&8#h^Y&(Ku)7TURJ z-jsnQi8s;DA-NDYfJKMwd%F?)1|nq+`*;Q)_CY7?8%%AFS8IcvR0cfVH#~bWBs~N< z{~ms7jpY|4-mw@_)Lc4h=xX<+y_g*3_(urhrYaFl=^epIwYq}!6!^; z#?yj=c~Jqo4=E-c+AS z4#M|gB94@74w2jWe#i|a`{E+*N*V2ZE!z19)y^8Po$rruwa)FW%{=q~llMTA<)c7k z@>A5=$C$ezklxf=8WsZeM{Jv6?^%=8MHDAKvD6*JVn44|L+v+p3gCO}>C6wed?2o3 zYRqWKY!Ol%1N|0ZoWQNLgHeF~-1EfJ#1}&LD3%LzJ@CmdVUdX&9nMmm_)4;jK`^1k z%p&xMNRNm(@`2y6h{Qw+l*D10{Pf5nETVU{`Dyzi4rJ@d4V?^Ia9qcR3S>Q$Sy{gn zBiAptilO98T%>*}qkg|Z{eJCL?lhBV1}^$*;nX-|LFF%~!(89y$hG2TavFN^mn&{R zHSzx9fK$WG#?SI~ha99Hb5mjNgi`xd=q70yZe-@qD$u zTJ7&Xn3rx$r@J&DKhvkz2dPT@YF$>2?E4cUQznn@qfDehnLL&sw!vsJj+|-31xy|4 zJp!p^3idCg$g=X^ERk+Q0FmA13giaT%W)C6p$xaltHBEu)y`j@=UjH=dmd2thU4GRf%=YRPP zUl`zVeow18x^#1?HmLyMIstH<0N`PN^>J@A1^<|HSYH4oy4_yjiJEvv%46&WlebFVDlP)#d(P~pwS*1 z(5-Rr9+h$Xw!4v8Z!Qsut!qq0@~nT@n@j@nJu#mz0l-y}0oL;HzuvM2?rfevHj~i% zn1sGXF){}qAvaX7!$o|HGJIIk-W^4R(VfvUiB zo|zActN&@TZeV2S14hFwl{*EftlYJRbr3jdAB;`(M{7h1fe>o~g`xHsOiGIRC1Py? zZR6Ql_>r#-<1;8CG^3iLnv5?z1y!NS%m)SeePLY$wB{pLd*QKs6>Bw(gOhv^EKKZX zv9+Mmf||w>n?22^kry2G;2*+miA<d5 z%Rnuw{OLB-R4yF5ng&=+ZK)||otX5dIaUtNtdn4DVj$`SDWp!epu*5&#t`-r+51}Q zt&lR_nc0+6W8s^qv7X3z}3p)SAN8dXVO$&(z{mK}L-Zi<1_(Pq zu=NmXEITq$ejLt+L>(c72?@A3p8-S0S2tpOA+#7*43$*GlGvZKl}72Ie#aTfS{cs{ zLVt8%jWg2ilIl{idU)8V8g_?&%7~O43;Rc-`b}W|mWZj1BajZ`x_(<6}zUs+8YX0oM1*`%k&JL7h}J(T&?Qodb)zsZA1=w7G~=t#x( z#wj02o;y%wZbE7WTnr0Fq)1t=X~ZEPfkXH9B9Sn zC&&TJ_)&(OgM=I=iAs(f)e?f%fS~tXYUHGre&1lhFTL7Nk$k|i)82=pC`K;Od@u^U ze~1FtdIj?HQEH7H=JsdTy_ThO`LJ#WGsjscrSp?gVlKtVrSnU*V(!N%{UfjRo3cv( z$SXbZsi{Z#Mv0nPV`iu$3DHl)(drf=%a0>Dgj-#hpZpV;x4SSu2h7hrnEX;yn555q zm|t3$JRhfK2Vwe&2$RR=029d}@VK0?`Ncnh$&+!y=GTDvl?Rgt$sc9Kr(>*b#p7PhdWT+ye7Ez+CUad>FxcJ&~E72`w|$+U#|FFQq=> zmP#?Qt3BqH`V&h1(JOT|OZ}0hay|dAHlatEpQYR<+;S;KF83+7+}}{{uU@&_%GJNt zpbwV)1&+<`3HjYiO$5X8O8omYvhd$S#XIgKv*!Z&E4}&PL3sIg`qtg@lD`XP?g&c_ zQH+e)eD4dLLX%qjZceTH?DZ0q>R4?fm?gqu_U_Zj!hajboL@_?;%2m9rWhGBx2(mh z+5&T%TBmib)5=5s1|oH)A`=jkwGnjhy+J^)TBoN+KohQkgdCu!Pe5gDMqIB@oH$256llpK zJ*<`_ax1&)*0nQ+tUh8>Q)C5ANzjCnL|Ze$xjE=2UXi8{@l3;#QPNzL#GwQ%wV=Rh z3gaTP)C#%9O?CxK{cD|m9!sqWE5uSipNWB)EcFk?iCt}=KuaFOk|dGalE$5BH?gTL zZOTs$0!t`Kv~5N>A(p%%O(DXPbta>Q$1^aSgBH-lqZdLG<08|zJK!I(Jagk~2kKE!+ z$AP9}J&t%>A$}qenj=Et<+WpL{Wbks06C%7F03I(e3GEz!3IHf{69f8&_#7BP@UqT z;)#RsLE}?`NI=G5x7f-5q}V;&VoyV{Q@vt&C_tT2t19;lyizhXP_ld6Wltp3XK=bM zv-0A^nYNCr5FuT#S<5(GD5^#vd?5|a+;p-be?m=Q>s7P`wq8wEZp(vrWQEPL8BYgb zTx18h8LGqq3hVHLk9E$@b?(E*Ere>WYl_(E*tyQH|H`sD$Qf zi|UB&b^{b?AaIXKmDH)}Fc1$~>Cv2q6x6x%9hXJfa4M}+F9wg{2a9wQat}(E)Ipan z<=?`DvRJsm6kc>LuQQ9zyJu{~a@$E7?Z5zPyVC@1K+T<|EW5moCYl+U^PiwnI6o1b zPx1)=8NqrIxV0~zn+4H=#HrS*Ul1SO-Z&vp5nMC))z_d+oVQ`eeHyq7bRix0YNU0Z z^iSY(`$phT0sP4x{J&WEWI<#LFG!qG7hcw#T9+3`7$C^zPiU{kWVNf-NWo7GSbcU; z7`YK1L%4va7@2$S^a%KL-B8!ln<7m8G%$FA&~k4U-lj>p+!m5@DMl`r`#)0dOut-i z?^x&KLc%O5hTA++48_RB?CKWt2cymK%MS-!DCdcaSdJqR z!Azp2ZX-`}kBV8lyJk_0Y}R1ctS4dC6LrpN&$1zzmgy(NqRz4`Z){v0uu=HV`K0%h z;M~K-Nij0cJzbp71Lt#f&a)oQD&pLarxCDQkUo@M-*Y}J{cI*^o=;d)#H|7RO}-%5 zs$FapqhPzDV=C50yzd9k``W7G<@4rz5$2O3rFyxWnwyFDCF`RV(XSq_h^1mRoYU}C zvEM+z>GjTO_0H6KXG*;@x!$(6y|A@`7qD0lX|B2qz(?xz>GgAFtSiL^*}77du1Bq1 zUC2HE;p)tKbyB@~JU$YfxshH5%oKLz*p=z*T>-@AwXMnD;wIeuIQ zmVet;COSh<=)U^QdVn)c{|wL&+fNwbZ4}bU$f#88ATlxvjGR=Dmq_ZJIrYw2_0H^i zXI8y4(Ye$>=r5-T%hPLRwt*wr(hE=;W0bee7}w|cy=5(&xYB<%m7pg2Tsj-3P`OX`h! zv!!QETb{5p= zW%Wp)&*9%D+UK=2@iXW?9|bHgspRdyyjywhnMVkro%E0<^absVHZmP6P`}i7p3cUq zezi9Qf>htOHTeX6f%?r&=BD?P3APcl^G?)f0m^FB5*tE5^Y2-j!wLVe@ixDwS^dc_ zE60(BrLd9k?ME%=NhR5jqJR=q#Cb>o=RG^viXMjFJp|u1f!22ssL!U;8d8cAtE}gp z&pOEEou?Hf{<3KN=1lTvD^AkoA|@a4Y@#|*oH>sjg_`%BY? z-2TEh2k~ZdenVayXkd=n7sAbp*`TD|Niz|9H{DDmnfU*FaU_w8RkH@$u$tQ&&#(XM z?W9E`cE2Td$6+^21ueDtfj3|zT}3HGwlD| z1IThUS?F&TM@FcYcge)>DqC4iT*@|TWEgY(t2O+~v`#~60s-P>vcP?Az3Ej=PmEqQ z<69AuGhUGusMN~ zPCF9kDv~3y@k=u-;2vLH@<4DsT%RigMq+bY2A9P#j>wS2_aHg8@Sq}`cng3XR+&c*SBbNniR;8k^yB~_>%Yz8C>sLbwzKXc zEwQ+=omYtq*)&TMTLU@*#YQgp+T>Ej#ffcf3>SRe$yl0;x1PY|SUU;yUXJCGC@N-K zsD=XI;7X{JAS;>y|1C*uXG`FMWkzSXNe{|&7w0?w1}hrkiwzRJPtpB&;tT4J#jI; zLgfx{DARNCZV{bI!t8vEfp$KITVyq_(cz{ybO=S}`NvFI`k2B@(!La$#nB@oc|Qp1 z)OvF!=oEG^W(JJDXVztx%ez0^GlS7kAvzQzQji{7;N#c3+ zc0Mg5l9@G@nv0qCkTn@}N{zg+Bt{i;xYND;Sa-&o5*=;j?eB-F5$?xErqC(uTm{bw z=g}4Ag|+Z=35FUD9tZd;@VK<5sB&kkdn6*VTEu|}#Bo)mLDqvPITfgnnH#zT-N!yo^DO$Lud(ODLcLm(^$JQz8F1{ovO z9WLMU0<Mf3%8Qv5@v#9Yy`+RDrc(V}}{{of!r2P=m8EE8cEqi->H|zs@{g79DDK0ph zOnhmd{?4M>uL6&~C~6MFa=q2JWsWuI4`e2a5->-_U%u5>ZY`WkJ)w6FIyFM&e5ABg zF2F5@HRu46g%GkldOcYACex!4Xg%6G@VC~$MFjD+{ke*1e|zd3G%FFe2Axe^hAeM3 zw-{kb6b7_QaEplnQbSlup?MNOpOy{A5LMdlU~nw ziFBsLiLTb%<$gJru$&fg#DJ|!rO-GEg|LD`vp8sju#!U4Bpg2uH%7o^49Jh8SA=i{ z1Qrns&YZ4BVBB=G*WlJ2F}qm|*CH&uqix2Y0BVkk*C83oK`sc_Q;!|mx?4RrWa%*p zGW6VN^dJ}X+yo(OeBpMmtafwa7j?B;c6g!rb|{ffoIAc~MyF!syJv&bqru&9yA$E6 zcZ2TH;JqJ$5z8!Sa#vUNX+X3*RrY4MEW7r=4lT*xmaXoIoLpx$FIf$?G;rhAi)wTU zRvwbL(l2|v;1$^++|SGgk?sxks|!6$44lV0SQ*lQUm=j6E|8ydR~xV^vQLAv zcZ0K6gOhUkz;C^m;REKZ41Y^xA3&H@hI#L-GBtut#cYXmQo|cmZG+hoS;%hJMrt<$ za_PO1*=~Ipj-&X^e`6(2e=sHbJ0g1NP}cNlZXy8YKzcrv1HU}78-+$3IJhrWHzJy;9DpN zU#e7Na#Fji9_>>*iYa#!YIz%#+99dfAeu7-)V2b(6C0cf4bJ!mXPisz9{6}^@I?WXM)`EF4?hy1Y{P5MpUPcZ&1g;yhhs_nvraI)a&D+liyPps-)WZ z$K40Iz1W?$HmIXRHJ0Kz8Pu39buUDRYs@0ot~IPNV?b7oi4{^~1_lz`QS7#Xy-{N* zh@X$7N!g8Im_FLCv7?xBxYQVLqt@6+yi!FHN210yM~%&FaAq_((;J*=ZjBv??L%xH zhHGqQpvKPfYiu+>&^RMhX&0l?Ols1cz(#NAWJzIy38u4F1IbFg*N)}kuq0=qPT@pF zOhi)-NyQGu_9F~hAQfnKijrre?iMykAPTcz-9VsTAcYHr;>04O<8U>U`OlOzJtwT%45XAcpKHhPEEy5VXd5s`dHa8)LG&B)nt72 zF%_GN&oZWBXSi#IXX+K=S&jJ0qo#Ibr&D@UGay_>i0Nrupw5pY4FqmUs>>S!>UhRr zQ5hy9>+o(f{&4K&UL|l{W&H#rOl|TORKZQ~6BB56z7VJ{2Qus*Uqxy%7RqJ+_~uQg zG5g0zNJeA>6jM1A7Dte*M#*NTPXT}4?}xUgNO#d=u3%2yj$F59!bIREVcup-=icY0 z5*xga*&Or9Y3PyWaW;MIIS$P@(Y6pNSwD7p$kfjw1Y#NsZLs}p3Qd!+APzuc`(moU zx*=@sQUnGn(R`0U`l7%o1^JDKKq~&2hJEEXYqNZ{HRhbKVv~h#hn~UC0{Qa}0j<5H zGQ{oNy5P;7Y3t6Hizy7lsSsM)!-Q+1sB<+5Yss zBcNWYf!icz{(4a^g>Ze8`J^rL;#^6>_Ad`7F)vb^iHBDbfARtK_!R09n!&=Q2oUdH zkt=t$QT_h5Q7dyPG)6rwMPHUHLBOQANp?AsVfhM>0hhm$pss09*Gd<_m+|E2i(A20 zAv&{zxEr?Knc4CXXdG8x&HkY{ahK(pFY4O*4*Mdu#-Fiiu3?&Mn9uX(Jc zwYujTX?1)nH>=g%fIvJ}LL02*&bq!fqoC()LEJnK7xY3S1@R@@tb%Se1wk7Mx{bQ7 z$!N=bp%x7!P$Njm*J-hb04gBd2_Yw0*s_1o!sM&7SvI_6Bl#+A*oK!Iv4NZXSvK5@ zK#&D(0COJ;lHNYh378(an^f^Dw$S^t3VpSaLLbak=tBrZq0ojxS5eos8N@xzz)a$J zAOXaI7G!%ALQdka0sWeV`54pqy+_8UUFi9RiPvq~$5~>?>E39>B%XZ8;*lpHU=p+e zn;dcodv`(NO|+M=BTAU`9CG*}RQOws6#iVU!p#AOI7&d_JiL%a9S<@DnCP6{vA+~f zVYmv9OfMq|_y@ZvhHtUv^fJgPguDvv8H-}#m$G9d z{SEKbyN$5K_h7TC=uHD3#Q;8!JE(>Re+SKbyu=3D6;x|C(Bue2vn0B|I6634o8>`> z0GVd$ZhAA*7nYif2^t*OzL8TCzC)V%yzz=~PH~iA&NVDE7pI{6y~gQoEGpS}uG0z= zjpZtpD5;EpK4a4B8&s9MBO|}Ea2 zYC>Oo%;bD5N^NR#>&=BRtZ$cytHu@ev*#*EKjFHaKhDN62&&L?J1U=BQ5_!beWm zN>!RFa?gsIBRlGo;JUz<;O=vH8Up=w0R-w#WL@A>{w+>?VO>Ga`h3+O+-Xxp_E{>) zNp1EcJ0RU-o+p0vSAtEilS@J37puGt<32HM$JH}#FSh6KKNf##i?nbqWCa16 zQD~Zk8F2s=H{ko7U@c_ocZmNs(^Le8OP#MLdSLpG96rq#r90e_tr>iWKZ20 zxlx>Vgo!dZuZ5>>XmI{&aQVcZ zEGxbKMK-uPbom2J1@z#VsRNFSCH^9EXcS4>AjX-RK90}wA zBPbG#Bnjycac)zOg^3d^7CE)lB4v6KlO*R^cen47vrGBONvXUzR6sZ1kJW#Mbf0K- z??%)uQeomu(r||;N1a-w^lwmuPUm-acBbRv@N7J8fEbiK2?awx3Lc06>6r(aV#Fz2 zn1dyCoT&j7sfQrIDAp}fP~Sv1XQi4`KZ%o5dAcoX6zB7KySaBO1?Ii)%zBKhG}t+k{~|#4@#~G|^G@&QOvNcKZ2Gos zqlfuZAS9~|?qw(kf1rDB((P-{SR^+UQJgr%ryaM#^*)Vdl=AQfs7*Hv=`!lXFYbRp zRb%Jac{mJ%z+^Zgpo1Bn3=>OvzAM85@eXk(-xi;`O?y|aTp3>E?`h<$o{gS?_tpOo z2yX1a{8%A44uV1MArP`0^H8S9kHf=|;&8IwB-rf-)-Tc7n3YSOEyEDnG$qQUXHWJ) z74}NGfp$e6fx0O>64RX&Cwg1|91jh;3HlMcW$(Qyg$1`MHVqH00SgBtjjdS%KmUBUnj*V&U~Q+bjT@1}*nN*SCmPiBGPA#|E8XNoaK-RnN( z%J<3h{Rx82=Z<;y;b$r}wv<$rGvHU@x2_Wi5-UzavMiTA9f4TcLK<*!28HIy=^zJ? z5Wu5wk~fVT(2R!``#`#a)2bk{Rw&>7f$8wbY*9`V<#8y7;^`19{~uz2O>M>s9`?%k$7FV9-`J*52 zuX2_oX2UR~5eDQqTEGR16LV|~Po=3n?bI{SRr@93)Lg!Lb zj@gThGkbC_Bz3pZX^SNDGXzTZTeq~HjUEg4@%|qgKbEs{nOG1(apEjZa=lVxFz|l`J(}U2cQLQNaN7{{s#eq|k@uc)9Z`V8-h-^T8p^0Eay5 zCmiymUxqc}?lPA#ub%v$v2I}_*2z)97I9by%Wk5n&Es$v2s|Q~)i>Y56wTsj=19Tg zeP*1hT!enXZvketpO1wSVIMx2#y))DRv5g?mSLB+%=7NurVOM(8TUa5Et}iNMAQ}5 z&706FyKc^NeVB}*SBqnwA}bOPQa!#qkjJO`Rn*ibWuKFLu)d#~X-=uR1kCYMu*R01u^W=G;1V9k*B?2VJSGf5Pr^;W8@;H=3@i!3M zN$Uj`)q0i@9@_uU4u=0~WH9_0HdtnVG4{eb*!wGmW=S|&9Ihmt#_u%uK>G*{w`Je* z2g2fqr=&f_5=U5K{zNDu|H381UH)xTY@n{tD>eraAYQS_x7P!C#Va=E8O`)&l@|#% zem*OSvf@UJK?Kwb5diflmp_FfPQWi>=>s_>ZhXxWr$8kWzmz3PjVQmA;!YOLlT`M@ zrl|gZw0#GdR7KYIG&3jyN)ofqFoPwnwj#-%F##$V(4IUa=7dvx0G`F$RluBuZf*QvU7Pu1lJF7rl)-%l~y z6e4{hQ!WzF;AvPspaR7LktUEr2Khcp-zqqhR`M;=Sl_>nu!lk-vNGCRh0s z$_&ny66{9gFSokqhfpGEXuQH!EzT;tP`S$1EkOZ7@BaT1&f^m`WwCEK*HSE>!3MbK0lqfi0vrRJH29MFI3U3}271rmkwYuRKO)MSx&`7^5 zT3{&o$jG8u5JiC>89{Km5*#=^^ZO#U-wM*2MJqu0sS&I(VIdS&Vxgu9qbdt0M@20w zsvNoQsJbZe^XEV~AE;aMD=x;+6om{$Q9=%5!0qlicKkpH8_ zlP$qhqA227Rq>z~3ag<|GTW|B2)-cW^0(p_WTVj=nAgM~8Rjfwn%ojE$Zja)t}nQ= zIBTKa+*F9Jhm~#OX1pUfhHW<&&}@gD+t_nwamE24x&b|tvpDx#HH`P0dORB-t8h7s zGXe0>E4qX0JUc5#(M>?_oyBP+9JO*|g<6SlJ=svX1Z@^R4Df(cz;N?}z3=!M?h`%0 zKqzbG{39yKQs$w8X>PKcNs`Qw0J-gyrK5*rl-O?z;FBQ(^{&qcDbF%UFMkxCYB4UW zRK!6S^T3va`~WLtmKOopwGy*az!gQn10mpCC*VraT(CBKV993>jv1MMQbnvaj~C3Y zPQ>e|2knCy1s|VtLe@o(mlyIeGCcx9J_R8y&UzDEWa@apLQb@+VoS#ch>ebg%t#TN zb(M;3MC^kh_R~)6Rq!nZz3%)5%JXz$*XLE}QRdl#*~1Baa|q-_&PLCc7x@`7yedR~ z0U}$Bt0@)Vt^&3?1O!+ilM?}1SE+z&ihzegz!#l>qYIfa=C1{F3O?1z>r`)p1ZEy% zKGN1-6s~naVE4qvM)Tr%t}g$IDq&psWaW25kQ#6Clz8<^lx6~?e-+YORBK0nm3=ja zUF+2XmWT8JD`Xl)de&7c{W>E3;gJ4sPWp9mR>~|$N&mW){%@tyZxFriN&kjQKQU6s z68T;uzmp)}n~=`}PY%T;IhS7qw^nzp~NDm~1%*G-;>nfFgsz`q%q<_mvkI!4- z+m|5WLxMG9FW{oCYs3rPPyq_@CZM(?KO6EGaj$^wiZu3}JT zU8VB1ihM^yz7L#yZM^$2_!`m&1$R$y{u5=t!+cmU-{3A`tnI3bcX0eBKyLhYhW`Db zry3Zo3o`y2GFpt?#27?+^M!v`ae_YBRM{$0wDtvc{!`^|y18tcrkou-Sieb+uU2Kz zh(lda8t4`>+uE)!F@|;9i6Z~?I~2KtD6$Ae{>LeDN1VwD75Se;k)JE0JDbnaicEl< zB6oqRzJRK1pIzDKS5%cC2voIO^qE+|sp?DRU`C0mc899ah#M=RD$p%t_OxBCs{YHm zy+l>~S*g$MBdR(Ms`|>QYG!yT{8x#dzELjs4ZR@&&~GMvO^)`1n!bgaY?uAbR+wNI zou>{#bPl~WL7;KkLo*9f15E)JU2;?rb)^y>ED|0M3BPj^9uj)OcZq~Qs)UCIqb0>| z0hc}zOos&rZ!IFuSM8lHbNw@3J zEgBv;%<@(yIgXZ|vgJdN5CcFE;|3B9K6&mFp~LVvSqR~=BrhxEOj+Pk%8u_+s?M8% zOI(V@id~9_&%~w9flIB}oLeDwDLHHwd;n#I*ur^}cBvJEHgTytC}eGOB;6tbsCF)O zC)o)RzvKS~zP&JOVihTm$S|6^-;!e|Q)QeUVCI1EB z@FMhvK6$IYXS@E&2adfGV>im?|xO~70lFrgO%^8B4yquI;~yeOA=PPBURJMkhp zskcVpMdPfnawf0Di}*cDhyfso@dAkkfypOAFXC~%5W-_gyohJ_!nsb_@x4gZIgh02 zMJ!hAMf1^Hyyzl$(S+vQ_}GhhtPiZpk-NZ|#wQLlDeX)X!nRu9hvK#G3FFlyAnE&uuVsP2#4Jz{}4? zoNF%xGhRJC60R-i0@v=qW5K5MXo0B9qbyY9&>pA=>Ot0(zW`DMVZcCKp3l>+YOPJA zmIw8qa4-uHIhVI(+8q;_Vt3?0JX1&m#%f3$kjL{(GXMj>EhN4gZJGQ|x_!rPf#3RI z^jjY33n4tD;2w0!XM4 zoxxibULuR%vaMpj?StOpx3|J?w`$IH$9`Llme66hN}O^BD_aeKI413lWdITF?wMyVYo2Al3`F}fUW=CZ_B3mERc8v*BOKE#R?KvRV>$xU`^6lOBrCJ9F1EWVBkX|e zZ#Rf_M`C3{-RE|Q9wfuFoK(?%r3~*c3>(KVixo3G$}xNo7(O6oIE(7&faWvf2+n_b-Kj(cdx__6oyv=0K5tC@TS#KFh?|- zR%fS&DYg*k0QF=d$`S1mq6D|wb+lku0}bBN2Q;$UuqIIlbB1>J=M3d&G$6%MS*%!v zW6)b1^+Blcm{^5!l(cD_zm0cHGd@8r=Yq^LO-L5PyBqVg{h?_rsG4Tou_)4wbF8sg zF>4bXYsWWF$<2;gTN~Bp#O7!=)cF~=WZP&dB^6l#@=pnCYyM z2|%WrsA_6P;V{pf$p^{YSIa)IbEA?ZKt|U0O~9SiHXc?rjhpJ$@LbwoXmV^=YB1Sn zdSSsjfE81n@O$*JK6;C(PJ=#9ZO)z2oI5$z$_8ZPjCA}y*^R)&6(d3L;PNNi^{n+t-4*_p|3kIqPbCroUFZdgd14=n;y3O$aT zU0~5~Y|;OrGW1gv{e?j9Fio|XF0KsICW0wTOkfu3*c27fS;0uY$TGVbNt8@Kn=1wY zq4zX`1k<0d9!`H-lt6gOl<99vLIjaP+3_R8=|ZhQ(wxFrta$i!ptrc&AK-46Hs>yB z&Rrb4TPK+ap7bw{Jt%*xRY(_sE>AtDCva}Cb`$K1=IHWxtd{)%`WS>CYG^BhU)d~C z(5_j^T&WO zCr&Zi(w&ylP9fGlX{?yMR_gEg z-kEHv+Tsguc0nCdOYeerJDj^FVDS|Jy9rnpU=U>n3pH6ti^A?GM3+E=$Yd4uON@xF zaR1 zjBs~63Za^>2U0bMv-`v8?orVFLEHVF((Xqp6G!1s^guE~8~=*9{a{kg&x7$$C#$Gq zNb)qW%a?CYa!$OL6G#XCk75!Yuey_PpD4MAzF1%Z9eAG|Q&n0c^Ybl<<4NMt=I9|A zzOk?;u==6q=;5&XL{>lC96cIVpTz39%_^63(mAYrpjipJ%9C07U~@E=61&P%PzhGS z5?DQz5RWvQ$GH}SYZjl5<@P2{C8fA^(WLiEsTZFH9ML1zeR)B8ZT@8|@99KeGP#_g z8~_L$oQVSdoJAy}Z;x*N6^n=GL6J=QXNjNolHb3;bdO`B3YCz~Uh<2|=+Bf^S+37N zVKJOT{Eo?EhuL+MfF=P*&7uh6+R+H1)-q*U28_Y7iw?_Erie=5C<~gBo6qB=2oSHL z$_a8l*$BnN!r^b0$qUe$7V~NJeljg4Dnl`!vKTHT{{IhR4s>E(M41+80!LZUl+Qg} z%&MBE*HGmIxulFB&!PR9v>>Pq1$ovAa_RpkK^Av{{6Pf)M_JGmK`s+PvJeFJyj(t>SrlNY_Y)G`vhW4wxq zZ-nv0$IVa0a|`iMdKN2|{&w^h>92zHZ#L)Nh^6Pr)lkAW5((cmWv|4d8&ZqO#uM?erspGaC4SDU>j0zW{mtFyoZ=^rGiwDjAF^f6w=WKZ@QW{b`W?{aEz58zu-H|-${)IezA}wy` z=QGRRlf+Uor9XvQtgitCb39Fu;Cay}!pZU(LIm+iiTRO91%8%@tFsUo-JWBC#$sE= z#(ELG#aP$FSf4lN7RL5^iR=XSTA0}D=d`PS9<)VLOkPtp76HFc1NypxtI~hoCg2av=3M8>l8yC!;>yu?$?wFi-(k1F zF?}#1ezyd|Ln<2??*StEAs8Cf))w!hNgnWhTYP{@C=oC~|1Y8s{9ZBney?i$klm0% zD)#({1^PYPD)#$N&|Ca|k(MdBzAd?$7MDf(Z?r@;EnF`5<-d#RpZ;1`Cw^5c|B6^# z`cJ}cMOD+HBF(3cEfyodpJO&E^-TXKuVY%N4fI2;#if!|8(&JS-%we=6$A}RVK z1s$|f;%$-JBKWVKh+vT~g$w-nibR)a3DYnV+-{hDO|V5;^rX*xuDzB}`p}`}63<4B zO9}FC0j#wOWsj*0z_?U^?*ITRD=R+`^`Mqi!fGOVJWPHh;NUc%&#N6KKM`<9i#aP8 zCWBkzh#w6~eka4^f9w_v6CaGjQE4G-^#wH2-(egm{S%beycTep+Z5*x0K`KwXwfTBWL=FyX zKem+H8{(S*P4-__)XRg#cwlRQ8v;v$6%XzsEmod0mVxj08zlX*fXSjS>@=7a)mg}k z!cY|OXBhsNx)yVwJ&5oM#)zqHfogC}%vY9^jK_ncIwu+4Td!<+;9=qPgWd~kFI<9K&JEXOfh`OCkdvo| zAv>5wf#-%*2A>}}K+LdBwO8z%JYX!&ITy~kT1#%#*gxw?Z8fJcSZxg};|Mf_GOlT5 zETm+t2c#$C>LNu0Dj^cEK_s4DPKdxPqoLAO9nqo$QRL)Hz0C4F;~WxSs|N-1P1OwTa;C*0!7I)(m)9qpya7& zGoeMXDDF6$YaNn{(ZfKAd@xWWXispotE4P6*R>c0*yV7or!>(AG}k9y>FTq!0YNy( z$YsTrnS|al$o>M$G{t6_jOwyqhAlS(G?mT(ldU4RAfEMFA_Ym!09&$ggO+GL3HtO% z-p6z9z|r{Sf@1+N(FRUk_z>QP7IO<5lAb+>eI!FQtt0wtMHhs}jS#|sCBX`>+t^}l z0|Fj@44Av#%6orRDnbfbVjTj7tH)MC1L?f1~C;_D3i6K&Y{HH4R6 zL%D>Qjtc}_I`E9HpuJs8TVQJQn^D zZI7LZEf~YodWeWSm&3h_;LZYD7Wl#TuB@oef>{)HLqS#K^D~1W91Ucz;?b}Nddp~d z8lz#$mfRNcfY_7Nwxo1a0X(L~%D5LALK%CCQ+or_(_cZP*awvm3D_Xg%zy~uR4Y`v zg(J#1h3N)$V)%Va2=_GI>{pKP{z@3wKzJ5$HMb}&6|=8a%U#sAA0`5N*Y~JIE3g0gPKv*awtJ)MiwhJ}big z$7Vc&)H<9-Va9H&%_Gs!J2M^yNY9L&BE`|Dgc*SiA{7H7FymHGQoAE+&4@Zt(6JVs zjW~+#I7J5-pqq_?>1t67%KReEI46))j2gyCWP@?0gKn3ji>U@>p?RXkD8PfPRZdcx zfC0@p#4BCZD$3T$1ff+}tk^22qPJM(h0Uh82k_HS7plFd2ywcjz4h;*eWs)R5p zIk^rX#8?&gg`fOU`egx=MPF3hz>4ZD6obM|DB#b{_+xfSO^rL-snOS}o2za?hiDf# z?obiomt#01?ghS*I!=Z4`8`1w_2SgGlFH8EM0lH0CYE?2yd8Dm5M9CA9RVc_)x9mY zJJ~Ze5$=Bhe&N!3;ZX3PYowI z$O`%}T0=p5nhhTTq^HCKM3hHS3Aum`a?LHJ1Opum^%gJ@g7{U~bN@3=8ODgF$$eM70as)td^moz{ zBx*us`X2X8F;6BCJcm7H8y`5)^ zrSt5`R;vq%XLd`ZAgOuwb2gsP63zaVdG-syL??Lj>?s!WSL}SE-}$%Z*{_M}#AKeu zes6vLG_mS8aTDGa)KxVdi@>cd-=YPx#HpwN<%AQ2(9Ha)i<6Ap5n5cWNOHt0h*{6 zudb>Fg_FWLHp99(QWwv$eNYGP&=qV|qmW?5NIuJAt6|U79DBBH>x(vOp~wStz9tqS z>YAo=z!hMllVqMf*Y?5<(H_k$^&qZ}6?1qI55m60?k8x9Ti(fo}Cag{p-cgcfWdDBYe0tz??| zV@n~kn7I56E$&gUf9UQvS)bZ6+_xW4PTm{I>pJt~xXUU{iMOiL|zN~H!IrOuX<`XvgB+d8uV zDr8oRgp^7xO{x?N%=2fZ%#Ro5cL4L>IOZor-;m#Uz+kz}9--N%H5K5tF!$JVzwdCiuZi0=HLIFDZz(+SXQezf3s1X)r@oG-7PF}G^tj`x zZ%orpBdsA%i^lEB(<0=lO?cwZN_pxKp7sV${Txr7qNF%__anhn9Ls2Wm&^y{&y_Dm zwz`BZ{;ZU(t%R+aU~9NzYkJ7m@G@-m`AxQ#B3oMvTl`rmTRRjo+jHpcfS2;7bxLmK z*4)U}TtjQF-f_vBOrw=s=gfX=Ao*QJ{H(#*EUI_EuvC>Pbq_PDRcmdp(WtN9Dv~Zp zUJ#%?y|#Q-N7vp8lEemyfF59~r7pjkcHGCpX#YV> zjka$no!HMBhdd>O(?S-H1r7)b%s_Y?3taTCf?}m!m)z#rfdMhPHMgeow&DrE3-r9Q zGa5}@h78r_$EhZYyr45&p^tCXJf`&X=Nv%BSiFVkS|Z5FXoXZj3$nbb6XQTnl>C#g z?#B@6V*|}t{i{4tQPG;@PRz*7U*6^!jb)Y2O^TeCdy1A=tXNBDqPK*NZfI%k*4%_x zOJ|`aj2;t6Iu+C~bKTUMf?K;RT;q*!7r=_I@WRmFMvisy&7!k&03He2Sjnite4iBQ zq>*sA;bd&%fYYj`d}~$HEugAM&Ml!?j#1FORcP{(QAHRMNz)W0Apd?nVq2Urw}m!&EPVQ`7* zCn(~m5>^HLWr-O)Vp#DORc!O!feKgw6}&n%G+H?Wz-aecqg`P;sLErGrX}=6+xb5U z`YQ*6Nae0`uqdEAtGQh zo^Om1;gVoG^gx{#qT+DGgCGcmsNlV)A*mQVODM7i9RTtccCE=m#aUX0LkdF~4ZQpm z!4%O1h1*atC+TqE@6hMfSH(HUfGft(+W{2X_N4OB>LF{}J9^atQR89TL2gMc^K_12 z1p0RY9h~hEh=UHO;1#34%@CaJQH!4!kEY|2#KQbsLC7me%RNMZe$!(ht59f zTDQuHIP6b__2EC&8?If&v(_773+jWF`8moDR>tU9(#&f$??8N>EH9p();IQ-XY;~< z;bwlTse)A|A5>NRn9qEo5V_E19_+*K(ab)!ju#IcTNgctS>uD1Wv@$)K-uJxrOd0X zCfjK55Bii?=C=YP(*7lzBolmGVCm>pF}&NC{+vQDlU7Jps+aQ=p}l&c2x z@+mDS8r`S_vMUE7h}jze8 z%44UG$IkKfBdW&WAF#6$*!ddlScJ906YA@J9W!o^hy|6aFH}%#!V&O3B88mTceEDr z-LnCa?o$BR0XQ;r^KY!1r_Kc6`_FVgACEyC0-i!<6+Cr(0)%$Rk1`*%rjGFVLt0Pf zWX<})YmkqU2ogjSpCGprK?mE363sZ)Dvf5kd6-2s`__fBH47Ph*k_#iQRb^E8&1ZX zpKKYP50gwV|C6#yv0dBzjHgVh1mjPRn>o;i5?1i}f2EXtM{ zmtTPm$IH59-?a}eb9kqwEs5M<6Nh&iyOr8{;aB#|$vCEi_NwA%d^Yy`(HZ%&+C(XNx>x}c74`-Ia=K#bE%ZGJkz5JW>1S*f04mTU{> z3m<_!$2Qe0)n=Br;c_7ZT>zw3-vnL|{lowmE!Bp9NBRY>TPo-Qs9@8-yYkCPF8uWnn@(3YB-#4?IRiz)Q~Tj6*4o-TD^=KyPI`W<7O>Up^9w-;~vqvZ6Hd*RdxBDRAYOJ6nr?C z$Pp>iHkTFgk0{IGBk$m~e+}Q>rd?Fe}51pAxGZDij~2nUFWyaT-F@P1(0 zP*Z>pFB?Kbp)xeo#;U}F%+y{Q>R{8FGSt*kLmd*edWPCrX&h?SZ`3`muNd+Kg2P56 zm8GJGDVj_KQtSIabafb%qn&LKIviRDi9+TGXdMz~ArrNJWDiGcX zt*ezCM>~M+3P2`^Wb={5N+2f8 z>;B~KPP3Sa_Jn;?FTqhIB9-n`_OQB=?+gX8X@(%MTa>^D1<4lWR6Ym1gIV}n+E4fp z1MQkPK(tHp8}FbA-K6NaRVhm+7Aw}?8R!i*PRAeNhh@k<9=e>_mfNQ-w|84^uUMVj z!ZiD()H$<6o!rli_Vd&^t5lt+5`x^G4Cl|D)Oijd19k2z2)Ne>e*-?qA)hNc#HsTK zs#Ew7b?%d>FxuPuy;t(vsa8>QOHowIV#TWEMjwSV8$g){w&f0p)yOSAb8rxeirl(0 zhomCF0Ul@0SGk90cC-)9|AT}a=5pmlbVxk34~~Bwn4pM!bP^oO-hyzDX!25!5!qR+ zSaxpoiR_ah`{8Z5!(!RF<7bWxW#^`zIVvUlVF}}S8KqY@UP-{T>^QuLz0#v%iI0qb z9iE_wd~`j_euT)*4MCBe#foLW7QIFGJY+An<&KGEzmDur%xkQ!8V2VqCLEe$xNf{$ zFQ@$@AfscX(GK=wg|q7&XDn9C8Mh9FvvtAQ@ol-;ZMoxO=D2}q&Kav4Kwsc-!0fU% z7yZwEU@X=-^J7+41l%Z96__!}#Q;qzJ-gg*mA$+$2g+IfHWt(#%PLC0HF8 z_amc|X!o)BpBcLp6ZE(TNixAklP`~*>WbWZ3^1H-F~}a{Nuj^q1z@aw0Rj?tvrv-- zMHKjLrD%@F$Qc&Ry=b5yzsU%{vlL)B(_*+!F^KOvxw)eWMgRiZ+^qy7pooHOP0n1~ z&MSvA5DHro2t`x!%U6YUv=gL1Kd6ML3Tp$I>|ma=xkXk@$Bk_e#YPMKBtRzno7}4; z?uxy3E?A)s%tr9qvtoaJ4AthGlt$0;T-7P*&j5_hiEUEX^XNZYq-CmujD8j?=Jqd+ z+bQ7oyqMc3$!)N`dY;EBS;F?}Mb^|$5jgM^A6SoxpD(;VOi|#jrG?%vJE@{hM9Lw|q8qH;GW94}rk4{fp1bVa)MCBR0Ph{*XH zteEq(zj=jj`cz$2aS?cyVng7;1*!^<-?+;>#{XAhx(t|}s%yNl&B9xE`vVrKr~?=C z0R_c?6bdi1%cV;ECQJMk62GFYXW|Nb&wJ+EH6y7dnf3D)JaN!3laLaUC8H^{|Fj*Ef6%>~dVH_?mJnRB}>5HxMv{eN5=a5gxY_h^v|L{U_NJop2fC`JPY5=9w1(| z1H9^qw%p^+r3Quzq?r>$2hro6R`M@lrV5r(4(f>%6q#Jy_Kmc$Ha}0bxdh{QMo($~ zg@A)Fv!e~~q0G~5;q6L3bvx$`3n6^U(bJp>>+*k9LQBeQ=n)zYLTE#Jxp}V5a)(HQ zPyr8rwjRn~+Pu(a`3)PEiJpUq&(<^K)M4xRY564~Mqb^Fo@2jT5WUblxVrp&<#O3H zm&<`mwBh9sTjb^UMEnq~g?m&YE+6&-qBh_ii+5%oD{<{Kp;zmvWkn2DSQf8$diWNS zr{lmMJRG&+jWlPa-Z(cIea^crh*r&20c@!=ZZ#h#e-Q@DowI~dofWcN|wGyi*b z&ph=WHY*0zMABE;ZB^JESn#&UENCkmwaU$^Dj&uwW+EA}(-M*6IgtLEu%B|+SVNDw zDU;xMJ+p9Nx{v!fhrCHRPTo-Fq6KaE6(2%yU$GI9*1#6!TTqO(*_xqZde{sZomLFf z+<^sY?&4&`T&a_d6DOMvCwspw_fO|!<9n^;e~K6RTF!rkSXgdqDQBej%XX(o6U;|# zkz)T9A6?sg(iSO_UxCV-Put9_3HDKDDAz9^(TSr^_-`MskH*Tp0y&7z<0pVT<#2WYw0^;t% z*I3A$se$NrLw;S1F-TU(tY$wEMcmi*6Y#tbIIsyT)e#pXv-#$}sm z31y%K3`C2t-fjoAVhErO2N$Bg9{3;yZwE60cn84I#Ch1oH2b<>ytAx{2A+jHpK;q^m4q?2; zEiO&zd{0OetHA`((+>@G=BXCP263-wwQyB9KhnDaKV)7 z@N!nPKnj&=VIR>#GqkY0Q^CwaW?!>XJ0~;u0(SpGW|mBD@jKY%)zy$>de{`h30W^FTAQ9oWVq?)*lI%|T|(_GqN2yL=3h z&nq4ht;rZh%1L6#N+j$OLz_Xw0iPTI4FttB@D3W_){U91D{i$4XMzNv(18E$w*dAX(?MsyOnZ)-<+9 zuGKx};mL3z(snUi#qRpOG^@PdHJi3a>;H;r z^$io>?*8U#Yg6@6JX6L9%dEB9u97%Xhx>lZ*Ph$g8ES-?m0CaT7cax?x}n}2&@Mg|?dwL#RSlZb%sjv=8t}Axc|$adYNTrW z>DM`-0Ste!a)UW(oa*RXygrN$NOVMPjI8NPl|@YctW?ZZM9j+|=ArGmL!6kS z%;7094^4}iHAl3YYvHe002ZeX0iTC>d|F+s8XfM$tZK;5R%cmFE2AUW)Q~?xYgZ3r z{E0Tkr#3Qjfu|ov+1J2w1vmz%7MneXrVMG2}9y9g%la%b3UXdMJN_HH` z0!JY;9wQB8`FMSdHN0v9aig5!V~vy=e(lik$9M{b;q#GJSi_6(jbeEItkm%9h~ck+ z;ZJVQ&2ffb*PNO%{K;vBnjW?_cPf=;XLu{{6f(Prs}Xmlu7*@wtP-w- ztKHO|yV1GYjL_9?N?h$8HNfuXmXxa{FxJ)fFt?^$?M6>C7HH4t7SGlGq{#Qu%IH>g zwfnVp?@&uUOeXsTTDqCanF*T%2OhBCYWG3ymdt*TL1|c5+uviRJ|8LBS-m2AKq=V+ zK^8c0)*h|~vW3jS8dFpaJ@{Fyj>ONb=ZGwaz;o_}2-Xa#ho~Mr=de=d4u|Ie51*#^ z7Ld3r^_-)`bN&d=d9XeAfb*QA&BH0HKM+`59ukj<9;9jIq(JmAovS|otg2fd&gR-7 zseOA;mEb79+L8yga9Gau*ub!q=e0;Ht%4t-KIAbC$^knl9M30)m=2aZ&si?z5i7Xf zwg-Qd$E!g9N`}u;AOn0L!(;pA!FE-Jb;cqedpz3p`R6TddHCrSZFv;(L$A`d4@JNS z+RSb>PyS!^%}1+H-%qCW&Bv=qD+7I>g?jNp@>Z!27SBO%@xvS8hcCA0UT}U`JeM5J zOZnmp9#ih~PIAEh#l#=ysXs2T+Loj9JdzP<=N_C<5QNTX#e7NB%mekXH?TtIa?CyM z0k`_QB__$Qy)rFRVgt8QGE9I48Q=pMrm312+ar<4xs@DXPiWWY|6yq}Ewxv%P7kL0 zZl$!DsS4V_2ijMnpyBTSq_#NQlq4$l4xTF)@3|xBs3?_4ByuVOnu4uR~@m69F zHG%9)_*UY)z*JK5oxydd`0Sl3QF2MEn?8o#oM$kjG&D;Ov#+F^mT1D}kOCuUGKW-R zAgNXC4f!9f z;h9mY%?xrl-}jSkU}1g}4^BM?%~A;*+TKDA(uz zXDL5L=wA6EGeJuzKZ8n81~yQZOwj5qq($L*BKALqr@p9K>%kXAb7A~XeDOsh4ED%A zPb{Fai7)zgp)WEq)bmBv*gW#hMH`D1JIl-HEzWW$oTaKG_e*>3=h#^!?=yT^nS{i? z9q0(AnC5BvbfjKN#&9kqGS4%VnFsOh>zqiE2}I_f6HQ3=8dE|&nKK=v$^1^Nd>84c z$~ra{5Px9(p2pwbEk+v_6{DtaW`PmtnYbw`Wn0B6eH*=jgvpwsAeQk=bsrSGXoov& z#T-iW1U|+J6;u^h!b>L#`HQGvQBjOK7JgpEPgN7Fsh@E7KDr8bELP0jhv*INm{Td- zu?+4W0CxjAa{XflC8sj5{Q%}n@c(J~!PfR4qqA8&W%~rq*`7I+p|H{7lvJec-;=Zh zMOvm@!qh`xYDe``qU)8ZnIjpjiWKL61!opGp^48};P_!%#p?V5y@7=JlcG+Rq0Wb) z&S4$7p|Lu@M7?>>etdTX%pF1c*!_o=(E(0PH!Ud~eucimA&V7r_$_*a!*7H!{9qXz zJ_Zh#>BueJky|Qe@;fwzOQ59_n=fx|{yl+~OW8bub2k5hU?;4jxu^{kco|RNd<${O{-uOt=v(?N(?{y!UvVnNZKPzgsn>?nO2`S*82T{)nxTVeWV~g%z%P2oB`bq zS#bcd1TR3c9yLyN0|}Aq=plhrlK`Yk&aLUjh(O&ZWO1KW$Ab z;GnQ!WPY@57|aF{N{@^*h!KaNwtbPNwV+rBI22XX`OiMwFoDYg4#byap>Gx>Q5eob zO%u$Lg_8O5tGJZK@QaUOX~Hp1k#NQCvMhRw6F&tf9@~){6T8cDXffkEOnryG=UIhr zJT@^$G$#4&vT%yaqf<1VPD2a-jE`1YEv4b~1D zige>q4SfO%qD~;$x7Pz+%NpXhd&O!aOKplaAcf zSP4z!<^^~3@IiQeG}Wmf+N6}5O+|)v95*ah%*}d^n^(Ziw2s{79l6b7hSn!T!TF8@ z>D)LbyP3yLz70kQR+^hTuBVl@At~LhLeUR4*g!bIkBOvKNG(hfRL%z`5v(}{mSA;Y zlK~bLoU7oNY`gV~4K11Ay|^!rdr;j7fOw!pKQOm3(KUPMIxM;=LRgjD03D@$=XUjfAY$5$OC9>+QYH%|m3$y=XeMGSW1DgfNHYYOrGjUh! zL0h1=`19Z3L7lPhY)PiVE0;Pwr{T0yDJ(V635Sue%-9*r42yZ0a0RAhg*G3& zmxb#B7@0YiA#3t&ShqZ$$aVxKE9MHRyUcuMd>MTdJR}4ZyaSG|L$sBer%ufCIn1-G zv&{&6V8ZO)VMed(Ct2;v!NC79hax0Hx{=ZDBB=)W+WaZ1)bNtG-N>E+pJ>G?9DL}3 z{*~NSWYHqYYA;Tfntr(&o~>s1Ywmrar+pCNPzes~nj4kT3>l(=q&`1W8Cc!y*8yz3 zNV3YABYFwBhI!O3gl5xIju64+pJ+etw<<&`aC3pOvu3!6_CcV;(ZTd6+FA>~hQ2&n zQ_}>gvyh8R+HoROX+GC@YX|EYf@6X>1bjli*Ikh|HF7 z^eHg`<>=ecQnz{$w0aVQKP%OXp2T<`dbyw@cfM1~RP(M|E99_pG1rX~^3etIM}ME6 z{B~=Y3(376!QjtIdC?;nAAy%kI&v3xTZN6bV*R)cGG(l#V$l~ubaDvBXq_+cSX;8(G!qK&+6LzpS0(0?75e7&jIM^oCK3k zjARCo+y^AK)9yhWxrwIO195~9Bn3u!{o9+H>xP;{@>>#>MLnsKV&ggIe&uZMQX>0+ zjR*uR#LP&sTK5z__}vJA=nZjq0@j*ie`_8eb{0koKnj@y#E;m&Qa?IKeELmz&_f-$ z2Rm{PI1f6we1v!)QNy(Sqblej;hgtS0unvw{r0=+s_|j+ekhhVb0McihRfcjdTOr_ z8B=S3%%#?lK&2Yd)S5qIqwg`Ni=(5*M2`GlRN!O6nOYkKg2SX(#41@vfJ*r|`H`d; zNctoswOAwzMqI{+<4FYw0XTFzo&~Phh@(P3o`wWD6x+C|LlSe*k0rYc#-n`I} zI*;>oVl(r+4W>^eb@7;zBpLJP4z-rt%>9A~rb0a{axiN~~wdQZsDz@4-@zB$8m<@yB4?-v~_XUms=1^b; zOC&t2TK_7w7ZQZ-!D7W~WfqI5^((0L^^V+Yv09nPQhxZq=IJy4533MKbqP%HdIA>t zU6lC+!aQ?fFd*K*fN+Q;3+5T?P-4s8Ai7)-Wq}Bax`G9&ghVP<$yMkrD)|8_d8;G$ zW~`E{(NbO|Zzi%%%fD|`axK8YjbyNtJ7->3=8B!SJVf}(%aK3Eqs+j~bbyWHvhh7T z9(~yShfpCPWg|_JVFFutppnn3+Tv}|8Z%=sHGKp`KqiRzxNqLIP@ilP#X7<29D1QL1xqdyJXP>?)ABKFQ3)?w-)mQ=w<$s3br1k zd6aB{v<=_8os_CcnPaS- z3y3m$dJNUj6Yv0r=`~iWz+g1-0Q3Y4j5t(u#cs$18*#&*;f6oNZYb$B!Dg=8 z`TD{0x%@9y+^2!XRN)JJeB)W1z)11gIsnAxuMcm9_)++l6rAcTP(TQ#;NZ`5#B-`U zojZtA+t1b|dc?zo9g&}CE0&+xIU;`*?+NI185>N#DIadDI+Kn5eBVwDR!qxD$-mIb z@55X9Go6(6ujIQr3lu2KM*)9cCZ16K8g7K*ak57|%-a$9iMC?-nW-c4_ksM2#`3>L zM#|cMQD6RnR(_`Fq~!nH%J0Kl`TL2;%;ACjKmoy-rh`9B%t^^Vz{=kvo;ZJpXe*Xq z6L;_sTLbx*h~;M*PkH&5@a138%Kr|*p9`X`4`<~bB%;0xSjdg85LhyUhIIbc(`)g4 zbOQJXq_bpaN=3u0ihPo8`$KYnq9uiC4L7yU) z_^~VoR#-?hjGC0WVz2oEy=Bxa0`unSBTB59@FsKUc(e0fJ+jONqf!8)@yu{vE`W16Pds+qb=9W)d}pP4E}^_FbF76 z{2vM?oAw&Tr(V<0v)4%ePvA9PM=>h%exhu^-CCAAX8)AoE`w@t2PkmI9G}o@6j$Ok z%=L+s#lQ-277t~v*lQL6R`HsC@R~8P*D$%Kyw{BJy=Ib?kQqPbrNC=^ILq%?k(6mc z5F1?~w&dZA|81{fHV(igttOxLnzgOh_#|VmkvyAxV3*03Yi8O6c2NeIX9ETS1&U0s zG3%tgM)9fFjPKcNn1~Y^)$1r;!>pWWoq)RyEqBb(DZ`y)>r`g}1@4%q6B1BdiPtb` zCsGyzD=dS0i8YkDVy|J!j(AOfc+Ez!*Dxukyw_~xd(GxnLZ<4NC+tamIfd?naY3qi zJ5AF%tFo>Wvv<%UxjLJsJz*2;2|k|K6PUCUZ5rr$OUnsUcXW3O7s6FFZ7j-V3J;dO zfB`*8z^TrH6BI^TaHQlX;7qa+jk0&e8f8w6XmlVnT8K5ujGFQqE%+L3w{kGoCiR5n z!&wh#79p6512;!kNW}CT{9$fQY9ep5D(w-Eq~37WBHD`OWGjGJ)#8a`@ zdGr>s2SeVgOAx-4Ftb`f7*L=nnJl|>rc|!@G=#;Jn9CAI zIv13^IODFWT0Y0G0#N|H57*0JvJ26SIQe|ci&J4SY0N^f0wVAL_qJP>0o#TBEsNKUi&@zo0N4&Y5)+}LxkK0|p_y?sca%<9bOHlAu|Vw} z`g^oH1HDDN!!Znw?#vw(Yj=0F0R0~LV~*_%^B<4ybg6PKsclb%-kZ>6!~0R5A@V0! z_3lIPVkfPqVwz{{ChXDNjyaB=50fecm3IY>iLmBaw%~4hAFI>O%rw%`Fjf8}OLE_& zwI2{(GtkV!RuYax6i0w$bZjShu?anTTx~yez;^K*Sjgd+mByhS0W9>01CrKKdmkv+ zvcLw&g9+)+Zl0u<^QIqnCmqoq!k*PlCxQ>BzQYnqDoZ4WaR==VXY(PQn#;8T_Q`y8 zffQ628FAAi1a}s=LFh;nqGIRCC*E%+@t>-uW2F8l0@2Y}taun7gWlq3%fQi2>CBxR zJ6aJfAbTwSnA1~^c1nq(9jDO86S}OUo$Nc>+1BbO5d5?r9Zg$&2Rp;M-s#rSe5}sV zPD~>eM?2S&JSk}{=V+&wINBU^fTNuU13Mh2q;Uj}c52dE>S(74wk)tgw`UMCaI{3? z5=T3eJ*%6}0Uu6%XD5`bqlsahqn*R%z|lN)LG6j7oh!Jrzzwd>Lm@iNceGQb{(J(_ z(O9h5(Jn-9akS;(Xcu(m&W|1KBD8?)#rR_`PC42IC60C}!OD8r`M!r;Z_WJ&f?w35 zhiQvm;iVx=YkZ%(*!r4}-}%~QY4qZ2H(KJCC#~gt?cx$&y8<2HYd68h4#!n#9D%Q0 zowSzv+BHcdB}9DoX1HsGR2HP5`|DV!Zn^<Oik;7ifra( z@dkiKmx^)hJl=R~XZaUgHDz8&YEKv^zMnkL?mJ`mBfh1~hvBT%r!IdpWC5JKN4zo3 zL0$ef+jJA<2o9RvPIH%eF@7^3k?e?$P}nW(=DSs}__#G`Ew##RNn@#1ZYPnNrdz-~ z1Q6!$NZ`w?Iqpnam6RS;R)t_g_M+gHI+@Y=PjX;BUh>?PU{bz*6H}%KOm`Dguq5^E z!%6cVK;TgyVxn*_3-}t16z*f+AS5OOvLqzl-vhAnpPHy607n;f&RL{xu9+nNRyAEH zG#?-X3~Ve`9M~R0ZwYKGBCy>NN41B^TbRy%hZmrzy7KAl6Ky*CoxEcMZyI=isfE4wP zgg=qhfv_Rk_}Pvays9=IDfklR{0+V94?T)p=?p?&03rcj#*v40h!}v@~>ka3*2#D;*KS4e+}Aj?18hxNb^d{TN4!4TUR!(ra%%*7Q{ra z#J*aeU!d->3Q-4M?(=RPYZRh5;BitSdeuYmcSW%(N&gm#)qn!ILHpnXxp-IJ`uj314`# zGxtVk?jOz<#)npZBeCRrs;CL(?UaoY7;B@o&EEbUyKg3b6unK&i+cW%)H1B*y%_x# zwbO`!^G^&MOSY+314llvVeifmEbBtqz=CgJh{9M`iNfBGgY!vH)dx;ViHfk2MEQQKF_A*DHB)Eqv|=Kk?To>?q*so=3q#4QU-kLV>Rov;*?N^BAN`u`63+C;u{A>RNe zU%MIN+ipOj@GzQ~V>W=~3$RyRK(v%}`$NIuJcB3D59CW2B@FxVULJYMer$XoP1YeI z@n@wb>k^U9kH>wt8PZh|uP!ET6^64Ri6W@;>5*30_1IuCy|pmSpOrGbtuVc07p_xs zcGxZ&28!0;I=*W2%jo#pK48s%$+Ls)7RO^SNm1v87g;D;j)K&HuMlXvQ zon=lO$;HCNVi(sp^<5n|%zm!UJX4F&IR{@*US+Umo%F#j<3ZEVcu5^Kb$~gxLDv{t zvs+K##6j=_&GVzwWbRDjK_bD3-yy-FBEd*FdxP_%!;FD;d0V=UJ~JvP7BYvMRZ}%b zqKnydoQ=M-7=6dsNw5L#=H6Dh(R@^7q&7dUtNbo(xo_KQ7oDu|FAs){?W)QG1s7dM zH|1!`V=%r@i#@#}lmAAgxf=f~TosRHLfz&HwlpCJC8o`*ubuw|S z+GWnruL4gjZqKE*lZGdX9V0wZypA%L9DI}GY}Hv{1XZ3+%Zdr~I_LBJ!|IyH z&CH(elgSs-LY-C#mZ|lHDLH^vokcgu#`9$5H(r#28mh6&(vU-DBfI={OSon0_wwiL zfCHXAgXaS&IFR#W!JdbYgUjsxBlF#sK97xs4iIja_+4@0e3;p)oCf5)S#=gjL0=Au zZPb<0-1M~jTm#C{Mxyn`tt~e^Fcxf*se*Zc4B`O_=y^&De|Rzr&lFR-WPr%2#->f- z+*2`dwK6jvk$CegDx)b~__;bHPrbGArK`_xV!5~xsLkeGWuEto#P zA$_gcwrh3fuvD4t><@kd6DG$ebd_WLMo4hXF(hoCw&@+@;#Xyn6JY^_L+*zDUDQ#t z>Szb6qr1y%fCs~{6AUP5fXBehMqRdRta6?N!`?L9A`AP# z99($DOM=UlSeotBmD@3nFLKmtmy|z6JBf%X2jRJ{XcuY8?`DPP@viWst%Xp7>Hxgdh+VFuLX=ss3T*Qd2d547yDFkpgF;$vYuSE$lG zyKv)&sPjz3>NA`!H;vAKxbI0?*Cw(N;8oP2;?a?K7gWv9VY+8tF@CGR{f z=NFN4z1@R9E9D$ldmzI90i0jjmAk|-zg2We%(LYxsYtXM>NC0&eUeY1P4{qka?6C_ z9vv_H9USk0=P9oF_5k14f$wX(a@Ta_uI|cR<+$H7x+>JFE|Idn8y5Aa$yF3ImaPzK~5 ze}|JCfhQ}-z2Z-P9i0jvAZVwo^q9IBu$__0TPVXd#`gp_F1uRy~qU2?0v?;xYiy{dvsd?D9WGYouD;-Nk0|rr-@_(vqyU@e33vFx zGT6KyY~C01$VZ3hzL-aKA7*9=BNAlmymobEjIOH&dbPdq=U;*50-68C^GqBO`_%NQ zUx7SSmEH4;#FiJKt0;-Zifze-Jaoe~zSxpwDCrR>>ET#Oe?+C5iDX%C9_xx8j+Lh4 zA4-|ufB`GRUsnCmV*r_tDV~9$F8{c)Xk;`t;0P$3;fv3?M1fRkm(E!WPz$?(e%U!wou@as^eXInY1CQoI zyalp?DUL$!4gW(hupjueQb#X$A*t90<@uQq)Nd_Cf z1@kF(?~ZF|c8QccA02%p;z3n-0*pST)~SR{4c4Wz9~fB$rtxpnCn743OAFI1R>Cyj zyBFz7vaq`j&q-f(<-Y97ebJTsJm!}-5&&#I{+RF6Zwp|>1!5EW5}>HR@KxG(d@RAM zv~TU-Z}hM1JMoad`LWBaygtl?l~VB-n(0ffKX`ja^aYf_M=8F%`#ky0EiYM7$vvFW zk7(f&2E$KnzE8L6o=5nb{wMn3v3*1ww1C5RN%My;Q_T-=Fz6fyni70L2hY=A0h{|I ziDE|m^9|AWs9(TC4e<9k{JjTc(GO^G;jcDdZRyJy{@}q{vB7@+dwn^>Z~5doe((tl z;FC@iqds=nD48}?H*VgfdxbBKzw?;?*8BZU@>>*7A2hSp*R9UusdN~Xm2yx6_ zuuo?VcNi2?T1=kXZ~9uy!Q=T^wagdneVt7Ml*EGGO7InWiq8{g#XkQXdPB!NF)ss^ zWen6?Faj3q&h_igE!v%1q&wHQJ6F@~F8`48@>klI9w$*}i*+Zi(ht9_tBU@3RNh=? zp-&<7q8{`j-Ok1PCjFwCdit%GG zHjh^5uF8TGF%3(d@bsDXyDf?MgKqekyy%XoDsepOZW$yCk>oPa-D}X@O5M2?o%)t9 zWLAh)5{1dmeuHwiqM73^1(iqY6+M+&?rO;tvNM}TLMYp0|6P@pPgMu?z9U#XyLAjyz|t^q;+4na+KZe=Ivnz$OdkXg&Dp7NH8Ubc%QHW3W2 zB)3+NL52;o3XvZZ8EENpJMX#XwZjC3HIj^%XmwAi`Sn%tc{8Tl>^t5%l-#V8wTfHW z19#XPqcKvOpQzoN%-HT!zMTRn=dRm2;RNA>U~sG(jTNMglWC6iI2HHNTi{lKsikuL z5P`xg4Isc>%T1F23Z{PLp2Q86<%uOpF_X}JBXqX_lS2lWg;SGdJ4h5V8^HrNK*8#7 z<5K;t_AC0E;`Fz%GBY)NiM|%QVyQIR{#{f5GMsHfO^?yc#)-wV5t21jV4E424zFcx z#rFZDz29qkzkRJc!)zMr)q%s)NOQBW)giX6n}@BA1=~6;Z1sr)^A^_R`KhXhEv+xx zYR6tdmSwRoaMQJK(y0>7Vi&VzxB8S*|E^}kiMm2O7ygE3@lJZiZqb(F zSvEFrL6&C-Km1u~9L44=IBDsgl52M1bDyXg1l}8goZs4f7tzmDOUVZ~TcIzh+}E^q z_mJkG{ry#_6KlVyO_*=&R-5f#VzXJKWz(BMix(N=T`GSZWIDQ~aSRxNA`TAo1-7P& zu%1x@8lVKcHosN3JY>k-n-hWFY-?eaQ9j&p&-SleIJkABc5U1y-F3U)-*x-mb|u4E zP%dN+qpuup1;@#D5&Q_m!RdeiRH%ZTdRD;>X*qh&47wIFN0O1FQj8o8Ms@@vfCw4c zrDsNVPBXG=ueE}%NNOP?vU{6iMmBcgD}c(9DQF0Q$6-+&hC|;!;6<`e8+CL;wR+A; zoG!U$nZ-&6l_Y=w^(k)o&x8;Rvv;si*}XeAqdT{o8*G{&vS)X+n~V#LnfFG>_6)z0 zp}8S@C!yiORanb>5HmBWeNSMS4Py37YGuVzJe#$%(zWNH7KoUuky=piDMQ~Mx{ZI( zp<3i7sJV2kCR<(3sI)S_Sbz&9OFNNGCV#*l=#GMg zJ!$cN6p2MXkv);yODxG{!^sam`0`!^{wMpQu_I#Rj*rF5-~)5BkFB$mz=K~ud!Rh4 zG9e-Kl)C)2)(p%*Fk6h%iTGMt%X2pKM{5$5!yhvue|`Qsk&Gz|BAFJMegMOO1Pt>; zLOg%HCHfcEDNfo(HUv<`C)E!}$mXSG7Zk(H8-k}^n*+uVC{F@U==?nq!c_R)2wx@+ z>8H>gyn|B|xLNP>*<6hZ{0Bbq?n!+n_M>Of5E51ZJL-V$IY9X6cK9`P&!>QS!4Lma z+B!^Q+I*3K7#Ie}xRqP5W;JW$>uKZIp3t0*Z)?vRL~icMiaoXXGK%q*^6NwvWF+eF zPAihTE`O6q{w6pO$+gH0So4u3E~6vXoMYVF5{!{w<3>r<=WiBL+`$!6T6`ZxI3C1? zr^p8Cf$7EPtpO!p;jyW?uNoaF!7P89)gbrp%~{=MAL{{fut{N5^=`wLo2cPR!iVDM z;613(S==BKt&PmzA?$L?HQa!^vs^6CDzw~=njopm-z7*E0*UBDi=U&2#n-5=HR zphqDpUXw14-jHJ;{>T!VWvof>!=vAyx^wr&3(_S}ZzB7og$aei57NGa@hAHb7W={d zQxDRcv2*f({TuNwZk_s5;#<@558L4;7m9Y-u_j;9c`yNs9`JtOoBVcB=n;!#DEQzI z`$abo?iZU5LnWT)0Rx7YWTCnVyk+(j3{GW{6sWG3#iGxhfjv~o~VpW!k_GODSOA`8zz6& zn*2#?@;`ev%Rg@kPX-p_n>@yV2=Q#v!>UH3uAO&Ywm3Ef4$J&T_z63s1Oj-5QSMjNfCwPT>_xfma$@3Y!ViELwnY3nF}~+jP4t@a4-{YDHl+dNd)B zoCnwv-J++YrSVluqL7f_dIc6h3rO$^!fpO{gHoMPZre=_7) zta!-njNagWC;X8i$1;Z8rxF5B2qWVx;J`N6kOxQT(XdDAC|LLVVoYNb7Kfy(GZt_jPW zIq+q!&wp$w^NH4c+O1D|3IbDvPkJ6o&IrjFi`Y=d63b`Zrp-N1v{Q#B@56KP}>BpKxe!O5L^6!N8u#atJBP3ecvp|q5fnP z%);*Q`*F&UMmt{wwV67NTc^uyfI;$v*IPmxZv>1M#_ROD{Qs;3rzJd{t~{XyJn>>c zyh?x+Sr|!to7n^E3Em4 zfsI&hw(8~PHez$OdJ*Uxx>Vlk))Q`~$XD;Tagg*{Kz2`?wRV4>>pnL-IGxI-bF%Jp zAoml4{H&A8qUx#gbNHLn;b%A1jdFgGo|B)&z1^Y~S-cNH88+mXxY!s%0%rpf4ZW1k zs-NWpmRm~nHafdeRu*7-;ha@3>(tM>J2UxD<#$IKG@ZuvX|PwW`$EFU$S9Si!N#re zAI;bt&y%bX7^An)VToywRanLFYBywl{7SjT%CF08E@3nYvV9t3D%h5a^D{J*lcoD! zN}E0EhhLdJg`9Q?KTE)k8Ca8h4r3q(P%x#Jyp7DsGzY(?NU3mORh7LI{lUb6Lv3g{ zO(<7RWBR{yQ8Pu#@koh6kdDqVpM7|L3c_6JsbQBYzb7s~0~R)*d9R$83@wwZUP(-E zgcE9Vev-%G=@-1wW~~eN6;2Kg)2&gst#sACieam5*0PJ$kNrR5W-^hvnEv#cI_>CY zsdx7H8gXljd0Ww`c$aK&|89eLF@~vlonYH#t=z1f?mkI-WGmV;_}1%+B6!1Nc{NwJ z(rB_&;&5_z(;WPd+o2fQ*wlTsT+KqyF~mQ2hHH5d39jeb(KM>pAJx3!DXP^Cyuj&A zjPs69o3+m0+py+!XYP=}=?*%7?_fCi&ZZ7o+})*HzQc-kRb}-qDYee34Cf=m!S}{_ zCY)=ZsrlC-%XYG-NEBsD;nD=-Nr|C8~YQRPODvHQ# z7^jB;=WE8XfrF|41{<`0t2-6D@!)dO$g>ddnF)Q(711=)cb3Ut7Br?XB|soq#xd z@i7>|HE0yD#fU6!O?Y9?b(f5FWS8b+VX6;J0UZp##~}7R__u+Nfghsi0VClD?m10e z;Po(ZdV>9Zcp8UDxes&yNCF89dncZF%=BU(8^|f8mo{si-alatq8rihl^Jbg$=?~p zzJE5oUpAe|ri-)bqHMZvHob2)-AAW?Gc>J!S*H)U&Z58LkVoqOl3`kE8zM2dui|?# z@ZTi#|DvETHYt7oL`>h#VBucDzah&n!2d=7Tou{n2xe;p=AAIiwg`-?;=$zPBH#NW zxYb>Yu2$8O!WhmM4#5Nu#`(g&JpUBt>aIg=j4J(J^llKDTep7j=PU;+kX(R(W*!=A zNY-zHBuXLWi_F@SjsTeIn&+@4T8Gk3in18OwT=E;g>;k^lX@_*hl13hAT^~+YG3?E zot&;k!<6It;b1T&NN-s`TS4;RprN79hai0gZK3)^DPxwVlX9l`v9G)=_blup>SZuzHfDk6x-$*s*_c_#yI{j9 zlDWQKaqNmQ%yk)TN|4r~z+7Wg>BrA?sRG#zAi%fKSQS~niJt3jA`8uRxtflOxVi2Q z6T1?m$|G}Kr5xMhcy|IHm9-{i)WkX1g(>rm=?7M;n!LQ-*$H`(`P&1w&Zxlr%~0q) zAd1Xi8iSZW=pf>r;#JS}UW8mfgNSX!2lU=F zP%nddv5{$>&%J3V&&KRQz7IB>Vz{2yt!Sp=+y`UU30bRHPvpFAy=GtbVz(Z&Ub@HI zeW7Kah}51CN$p7rs4oGH$y#5!Ih{`@>JiwZr(HI{yBsPaMq>iWyg}g=LljA727|bv z1RaF4A9)NUNRV`b_9yN940zjM35);HK%R}*vC$73PDZkEqjGuxL7tqoGKtyf4=wvt zWaH#WHcnGO0|@B!7@*#WpAO6eN#TqHg+Zh+E^Gax^GS!9GqSL!96G1FJujOF!o(RD z$mUIo&p{AHvN;%o$R>0^=wR{}$fh9aY#u_|`5DA*BT85tN&|T|a)*r}*l_lP@0Yt3 z-K?ArCCKqvYd_9rJ}Ud=ZoM8HaA~1?vtt+(?6Z)_@p4~+ZZHr_9H-A#7{du;LITEN zq%bjS9pb*zm@W{V33N#ty!0LcMQ36lJGUq&heH&}&Jh?ycA$gsj>HCa918Yibmu9Wg_E&2= zUE%wFnDlm+Drh>F1`6Uf<)s>;NI{IkAPNFHi0^o8pc1b1SHcxY#pPfxgQ^lR=v>K_ za0&h2xoDd5aRLym>ADgkNlB`N(PSH_gz2G5IFU5Q`9D73(@;^%{BxWIMYk(jC&4fh z`WOu2AO;XAr54Sh!eDCU1dak-X|+IfZQUGniW&GYODWX&}!=X<*|tY>-cN zsVt|!r;`R<%h6`7ujR(WnlF_*;_B_rZ2As;t#%e9)?L}quVxR@F&{S%?(pSNvp*Xq z&Rr}ieux=Qz)0Zc{47K!qKSlmPuBc*C3h+p^lqu(k94ktc4xWR!wm`imM*Skx-_Xt z!=Rzw;=+HU_M9rWiy^e0$Xd$>`*v4nwn`Bt0s$}Jr=x2K=Ltv_ zbd%H<6g{s{CPO3zgkJ=5GLLhZQ!t3<37`YImyofLP#8Lqmy%wd4MxzLiVf?jto4S= zC-4U_HJ6ikZr1wT{mVN3@$C_huJe@F_oz=J?{fpxUr^MqfG9%!N(_P$bU&lbJnFf09`pM8-tSce5U3QNHQyq;8XC?sv_3JF&P9%5cMSv)cGqGM z?4Sd7*DDQtGuBJ}4AP)|mu8~Y6?PM>fqWwxt}xn0h1uAX7i7~fXVdeu>6fzUdD--f zy2x%8orP*W#zAgq=5_3ouVOvMAYJwLp+Osi&O*AE6nq2Vi@v;dE_zLce+y8pH?#7K zt*BtX4Eh^7ZGTzp$I6*$@1BHxw*xP`u;m4lDjb<$4xe>BnvF!Ujs< zZgL-Zhxig&r*R|gQ`Ih(maF(4(q5XiUZ7uN=uXj_M0mc>8TNU(?{P0wou!bxRp_oI zUn(B=DU`3W@}@v-b3X+5l^c3s_5f)u3;TLG&ewzFYgxe8*UHyJ3MJxew)lb`d_7EB zfe!^N@%%WS`udB#K4;_+vJCvmw}1K;KpQ{*gzFc-GGQT5jFD{|6(v*LXWU1D>suCH zVVaK-=Xy5g6P)MJMt%mnpN*Y~f5UrR8L5>*jGiDpS}AC=)+@!+u!gg_Xn3WdZLAb4 zaV+{an_iJkFVCjG(QCxBkXoy=p(iI+csX;v@%r9*;&U)_RSSXTkH3j=TLO6t z-RN^9Z`0`dtd;to{|q2Dig!r$$8fsWdnxv(+dmD~uX1|lP3j_ox_6**nWlxp#i1m+ z(?Z#{85ti5r%nhpv_wE4U1t7exIP>y@9r| zH}u4D^UrMhk8Jw)Z2C97H+%}IwFNh9+%uhbkObbTdH4U_i&_S`xc>A;o!`8^m)9jg zb+)j?-C0_c2%V)61!CUJ1@ak&QAN-K_s_8b%G>;h@vT@x{=s1!gE&&E!#D<=ZPCNH zkM*$5MgOV-{sO30szeUsq7pd@3!49E<-JI;=1T&|R{(!-bhQKciU1mvU}aJjw}>h( zzl4%1yKTzX_hnY)l6AZ+e+@XN0b96PZmF{T4S5Pwr_6>RQ2j24M$9~{z%Z6?;6UeF zLTOSGJm(aLLf22-R}}i3b7h2v&zg6VRnTynlz8WytyBc7Bc|a9)<7dBg0&b%1i(QA z-_b^X28Cmz4EO-F4nr!RYKf8x{GL?l7(|=3-s?8Nny)l>C>fk?Tas>5l5Sn%KGyUT zgu$P#LzjGQylLn6oCN+{nO=4qyh3cf9d)NI6x?S8b}qqO;piRy%fjD4Dv-W*oUz~C zG|*G8x&qK z(!m$0zEs-^GpCRxZr$&uswM}2RhIB9qoveRq_#te+6zCTy|AN78KuhS)!D_zfcBeQ znBv$6By8kiBap)a9?mD7JR78-Q=fcwDG5Dc?t@jK$gZh_Y(Qp#Jy;?ZHDb~b8cr9c zrwUoTHzMy;$h2AO8Egh?fHy(IGf3N*!QPlbyCmJcB;8F*h>Cu)n+A}=bibi{dM_bcq@9=0_j5>R;N4F$~mE>gll;9Ulo`oGq!44=4 zSH-X+AqGBt)!j$E=rE`@Z+79HjN5JXfiWOR9xg%jtbWeHsB+lnsnaYf- zDc+s!c7+{^5YzxtNFc=}R+)>#e>UyI@s1dsNHtSp9Z?dxs<9w&iUUlKRB?ABo8WUd zE;gOoW?-aVst{RXy2F&_03>a6!5E;}*n=PgH!j7sSKDdQuuB~Aqzk1d4fiau-gnPd z_(KKi)ev5odqU0W8Hi@2$~#&R=tVfa!gG0)noF?^?T@|5q<45XmWpCkrx!a6ne7cT zINXP<58yYH;O8`XP_z$?1^(2kI}yNTZ9ml>KrOD#di#)zk5=>2m(1%nFGVm_^HPj1 z<^`Z&nITByo=|*@^1L6Z4JfgW4Oh|rBrsFzr^2AJ8Gyd2Z2kurMXw*apa;*OcK~hV z+1PKf(Vu)RP=B4uH^cmM;Z`V}xy!O3^Fk-F+X{+~Q;`htJPj0ZNC18ife#GVM^@EG z?8-J6CeA>P&|QH_RL!9U=D~!yP<>VM&z4$Sh|z+6C}{+C3tvclwlsvC$Y5YS7>03M zcC_IH5_ss`A3wP{ETSPxlt*MlM8m&J5C;7*c+iW#`bp!6h=#w4N#jUp1P-3EwjG6G zK77$;tq)(v!5Y}dqT$0AZR7B@4-Q|Y`oNXNpjEDqA$U0)@hPFv%97BzR;h2_!#X7I zfhdEjQwfRu#h&lAbP`Zu(dnwf%EgsQ8Mh1ZH|^>Tb-kx4CKWJ3p#uZ7=nv(c@)DA{ zg>{AkuO{%|{^pU2oI{RNs zUDcV@F!~kNkEU1hlcDa6=G+#aslquW-p#4v23l})I=Km+4GW6ezp=JPW}~3^tdd$8 z$urS`_XZXejmNnJaKPaVaNy!PlgI?}za46kIXT-fCld%cFem;fX-+0WBW6y{!7%0o zWTA5|HdK<;av>9U9x2foB5l@s7rO}70KX6oXMwh{i|vbDY=Yj!F2SesD9ncM$sdC00lGA%8we7Vffi=o!5es-YR3p`w~aD6n^+qIv~MmCH9_AqVa*(gD5Jcy{F0EdDA3zlGH- zq091{0{c6kI5&1~DS-l|7pHQ!%G5NWGrN@hjoQt`zA5&w+mIk7Z)1&Df7sTEj!BH5 z{!j!@xMkRcUeF2?_XVvqR@<2TFKC^L$nGpj-%*mj-HorkbyrE~hle}70G->tzP^~* z*}02Hi|@fP%=}lHkkVeXOXSXahu|6Iojw<+s*WJ!$e3IIcoD1(v=ONS`$ZC&R6SvukSK?gc$9~jHp{%MtkwTI|E$i zl%yXkNk8h+>1{nxVg>(_>ah|$M9P26<(Amq){|kSIT59OoF|yJI;s}WFUfJ9^p6z1 zgxwpXl$kz(#p!VhZeP?fH0Vp#&y-j<(`)eYcM~-E^Gty7%R+X)DB1l%7E-*U*Ltxe^s}B|2*XExGwEhC^afv_I$bj!;JnB- zYTw}0^yhh}Zf)j0zXRSrjqlo1zVQ}ntFUx%x}Y?@YiYV;sk+m>lhd)3&%4&Z=gLln zMO{jHdfEs7zQ1cJqKV#;-Z_w$PNnd(3-SUCyxQ8@rBuyeH(J2O4`A>n0Tmh>bmY*e zTieh&VRfU>Iw7>~2(4Rb+A2-&=7!eU?m@9QyCJ}3c=RanS*fByB(u_`j#WDC(wjTW zndpx6hnd}=e@Rmi#k+)KZFyql7ZWF4ilbQ3fu;DfChEywuG*zJHimHe2rtOT?xper zT`>sRdr)$^*n5Sz74niQxN*4sTI;>8$B5J(wAbPIW*vsT zZn(R@rR^g*#*wAY@VH%0RzGJXWbR*66&6k6l!f(WSrLQadM(zHk)a3}_6YcJH()TZ zkD!2i+9gb;)KA8@pC~e=0W#-?$cVm~j97bQU=K3Kxn#h=&JvkD?NLnTct086j-kjL zA0TsHh>Yl)$%wT_2KFFR<&psdyPC-KvQK6*r})YE_5?-dlmMCYLu5qXOh&9dGO!1k zF)kS}u*VXaz3lN!<}5!MU+F6{X9dVy5F#V`W-?;!k%2wPjC09=fqf>C>FwJ|M$o|C zypvG3wuh#^IGdrJq%U@oi?EYi=0<`nm#ANm!34td(@FChmRK z&Ltq^e%PmIIw55yBVF}u^s&1E8z)KF?}gAB4+PGab)(al{X$m<5g+_}c@4eMjQ(MX zTuavoPj{BI?CqsR^OEH3ugDc$#Q{F1^0B!7CF*W3?%{k&x2FeFIc@KCxee(w8z6{vGJgPO za-nrKZQ&M@E{lWZQkfsry^g{-gu|e2Z40v!uhXY6DiOvmD9roZ!mJvRsKG)bC2%2|d}G zQyMyPl`~_BPu3&)4(c34<{rihik_s%P7Or%7$W20)0D2Fjd8rdpJ`LKwi9?JU&lRz zse8IKJ-0Odlskdrt+}PnTxO*jToG%`cx`U#s}eRf>M#1@EI$=biAi%Dd2a zuT^4gc}mr_%13^7xMJQ7YVa*I)15Vm>;`gbKA9h3a-tO-B zayu>!26M;2%x+o(+4ZU8&G zaT!fMeeu^`8w2fKsS>~QV$)}QgVJh9TVrxqY z=I+z3I1!-}V@qTW`HUH-Bz_r?=|dY-soOhoZpkOky-*h3iE|Iy@}D>}2%)LJUD=Z} zz@O!y-@s_I)*1LlGC;51=M2y`GOz&4X{oMz`p7DRS%JnXFLO#!U$r}_77Ogza#Fp4 zPpUWY-&1}IP^X-CBiUaHibiobxp?v(!C z&DvUmIeUTM-@e8}kp0f{fk4+n%0&g2wNEL11^^)R839fyZ6l>W=(F;gA24E#E(@Ky z$+@B=Nmf^&(DwtJ(MXSbkSZt|!|9>#1q9M_0@5QQ{!oC}sIVXd7JVsz!=lYvSIRH2 z2FNBf92RXOtUg#FPcBQ3)y48F#+|WhLh))f@2;Uczh~3_4k-H0Yw%=vLK(uxjrs6L zL+PUcfnZPJfd0fVmIdGejlL9Mk0WUL`@P`rj>ve-rksviMN+ z{Lr^xowIm;RIY^@eR6-7270#@3uGzIw?$zrJWRBZnkjs=dYh9-8V9gis zGf|i`%F@@DrLWV4xg&(u^<~cWoCDQ_F5+u;BBfmS3YIVAXRtoUtBj<7oj2}Y$lt)x zw|8Tp&05FM71o%pE@-$2XdAoQJ&5S;vh-bL=~+6W-5_#ifd($@*Q*Qr`&HFjkOlWO z!;g$L-Jls*%kJeUx?>o{13a*?3GI$D{|}Dh7pd@ma1_Jc$&il!v{~!$d%_wH(`Yz+ z+D7=Z5&lDE=?BZw59sjsgvfr3;&mQC61GGx?B61pHK)vZuq^Z=u>KAY?zvNuwKl_ESE7II_oH*uTR(pZ!lf z4H$mD&obY4!Iyg;UkrgSyn*i%E?*F|pJcv!5#N_$`3A3;>$NZTl< z4^WBk>l!S=p#2GFVsV-Ceq0&Kg6AxT%spo+Ec%1f9M<=*-@yxev6f8H^#|;ch>zSv zfPwun$6QQ=zF_1%CN35M~Af+$t8xT_FU!=00jXsJL*obrx#qvR!{G_#wF6?zITjaw2K+*_a*hhT* zhYS0VjY`x(09Qnd8gj6K3wwVEv|~X9rSOki3dpdHkPyaT;P7JdcU@+ED69c81P#wR zZ6ohZ%Jqf)FpOBu%6%91P3Wgc@4{YW>cT!ZAOrH@FsDlWZx{B>%25Q9-Cx8S(N^HX z{s@JpF6^7~L>`Gj&H!!Jy6!K5HF(koH#h^djSSp@y6;o&-q5;KlrBSK^(}Y$l-Ksc zUM#Si$c6nDzOdiI7xq&D>huL7ohVSa1x5RFT=Z!U8BteE`$bRSfKsKgB$|;4*+NbmySOes0G@Me}MoKq$7xvd; z#5$lnbm}JOijpK*U4e2PRGkBm9`_(sP&AO!b3Fus^z=h|L^Q**QDH#_teF_+uxPW^ zm2xwz0df->4vV%CR_pS?=>yBtgLJXnf^lb%n$Xw_`@?8|2h^?544w>+C`b4)7xuS9 zGZ5@S9MByY#8VI8(HZT(?86k1S6gQJy|rr~3hjoFf7Sa=gm# zgAfJtdx9aqv!Us`<{Zfhco>674bVX45pr|5c~%RHMk}w6LeoCZHxGde`&bBf9`F~G z?mPg%K9)T{CNuyK8gsCL=5aKkLzARHko1N9iEQ))X_uC(EXmYmPJ#mwKM65s`6<#1 zT-f_S0~hvl1yM>;*TT~nMZ$m#iu}=&Ql6LMF+4&aH3=r!7Qu56*j2ua1upCb!%b11 zUE!t(7Iq~gKM#P&GJOZu2=#3=oIu(}nNIW$pYLMC znuNnAt?Zi0dl+?A;L>K;WXF0*9OTJu9`Vox{<8fN`W9Kv4RSU{;h^ z=N&ko&!=kYx0S5d{Ej~Y;Ws9aqn+TA?)0Y%@~*y*JYXSOQ1lFgeGEb70;E|sKOyW% z<)Ie|JgfF8KV2Q^Vlr7-Vr|)9(c!=6iB35ulpxoX;4|(D zl5dAh;!5LWNetX|?#0i8!4D|oaJSO;ZTHW}tK0`GexBVebKS}2=j3kPe{@%ZGtWeK zUywVwgI)XryZh30C!74Si}nA}-9899(H(sSL*0WZcGw+#3WJj=oAeP3>$4I$3vQ0H zVEGhZ=b{%`dxfhlo8OZ5v~sI`>3n>?C#R+bYHOJLA)u8II@8J_(4VZxEhw7DIICP7 z*<4LHfo0J*eSGI|4S`9S1ZsUP#%)w2DxE%nVP8dik9Bpq(v`Y%uI6HpIw&l9iFHeyo2%XELWu}=WNRJodM4;v*sEvTKp+=(6i`!o?!vcx4E9-%D$aF z|3IGaXS@f>Rn-POKM?S|fHl`8cou!nGc4fwUe_~R+4r&M_2l_6#+y^F3OL|-PQddk zthqkHv*>%CVFAyNxSrw4ew01`2+vYDfx6p(VLndKl3VNJ#Luwi8^D|J)}hzS)324M zU)3it8zDqFZ<6L0X?~UFH#F88<+vTJSJdBW=*@EHHO_$Z1~&!nPWT6;&YQFo7B4Q( z$-IlW&;tHX2<-PMPjP35uQH08o;>?KH!-lV7cszQLKZ!hnT0&Qg@EA)KKKhNZXn!c%GLk%kY>6Ev_$65MXit{!j z2MlxYW+I+V3Zd4snG0*4%|9@k%gWQAm8X}Mr>&!db%-HB&;CzHnl%WvcXLli=$y z=^#xm*W%+J{ncb=ReMnd6!0E4|K$GfW6jVQS zQTlL#jRUY@w}do5oZo1X z9Ef*;`5|AAiW90bgdsgY-4Wko?auxTmA{$YV)ybGh>;Po^F|4#T#^JhR(z zRYLMD|G`x$DgIS%4Rk;5xTCsI<%?A3cdyW#EneR%x-#Nqn`YN`+XA(l)NR5YSrVsNt3tf-` zD14nwkU15hHG-W7*N6$En5qb@5ff=FutuaR`1Db&5$BLRHw^CS=*3_XDdtr;xfQff z>EUxRZ12lF&)bfx^GTlnA6#8PiuEc?YeWt+kONb`*Z0xtiaLiCf*~w+5z}|FMI~=)yHXF~3s?vVKKyjS%m_HR2K|+Wk#& z`7J1}er{Z_un%BQmy)Lj6;Az%$Qp4OL{5VWx`LdhLY+$5bqn=!n5s~xp$j$uMW|O0 zWJ5*3T_di{=DQWnAw9(Y4Vx#8Qy_znqXlc z#D1?PLX85`f2GRFHAJayIk^_5nIY`pI&_f}fFjE439@lG%FW)vPf<~|KzkppKr>)w z4>v_A?8StNVW=A=EbL+IcP0Rw#(^lOt0-?EN_C6!MwqH7Z$cNY0SdY|6J(PLYnpl| z#CvJ5d3fRV4E17uA1PvuZ_ZVrhwsO5M%MTT(6x`@&>ke^ z7NHsS&7!)>3C`$4WS=$7sLz^b^jLRBVPPM~UT2fnmK9Em=!`xLk<*fA^lCMukC1lV zX7o{*X3E&-W9VW=0g4%zLy)aZGwMINmKlAV^aC^M>ClWmLGr+iwhGMXlO+G6+~HAo zMxUa=*5MiT4E5B_B}JUsw+_ze(-_WJ9M3c8+U4AR7F{)K>Tb->d<*6|QjtsP=h3y= zRLD_LdwGEj+pvp(p+kmpsr({!t4$LhzU;1aCmt4d6_c9>fQ(#gzeHGtJUSm;Yur$| z1mf4W%C)sx`HrD~DOCX$sLB)ERKda?%>ZwaJ0?{D$_emomryoQR0(61!VMHUaszBo-XsE1zjIJ%GWS>Or z!j-f*q7i2QDQP6IUlKtGvtJs~2($kzqTxFq=Bip2VG%rrd>%mvoD(5KUqC};=u32M zoRVSmE9#E>uVr((TQ;z;&tQPB31ET=AP@%X?kpDo7WUZ;@C^Whg&mA+IXO7b)e>Ya$5Y(pVeO2$#lp5sg4j zF@@_QEP@IA9&$DDKcH*N@o#+uH@s{77|{sFzkxIo;{OS9<@slH`Tjf|eQJGweiN+u z{`^+lpTE8$eO*QR+KTiw74AcQzYvj`70xxmBjT?ZMuL8m=67lSAl*j(-)C;Yoo4!d z=4QI%jNfIhXB0l#Sp5!>H)D37`_|X#gE+r8<67wHUuy253Wc*j0WU{Vb<~`}MYtKm zC{JiXXA4odt-_fZr27{Q-(KO|5*+@UhVQ7rUt!Ld+llYj#EGw^bp^ zRj2Ibd`F*^ zKB#cs<>|!Ft9X>$^z-UrFmXO$MR(u7vr-N?BOprrd9_jC=heOCw{&Y(B}y*z^D2E} zBJ&$p(GlpP`r!oe(q|*=KTV6G(2~W97RBG)MG+SEAB;AVfdAqyeQU!0o4ZG&YkgR; z-Je&Ffu8eWAo#mf@buA%#A0vE!N&zlpQ%v6X3+(4fFjrug8Zn$Ds|uS%a1v}$L>Qb zaw$}uj{?N*R>bIY6?G(54%5t5&QJxqAO=tntHg%AjmN79{o@Mj_y9*?65?15Rp;XX z$9pPsGO5ZO8!cc*5!NRaN=Gll$J6lQ?N81Lgugg|f3M2HXo5&uiOiF8B1|)R%==Ulw8B}%58P_9V`+Fvh5AW6&+wD@$)vTkf*%nGy%KzhH@(iMUVqqu+Qlg_ zc9sU>yidh>D&f{G&eLF;sn4OEjxOQ^DB?VWAV1rF_Qyfb`7FTde#Pocf~Xs-@i5Ia zWFlvw3swLHtFsAmS%tMQ@Dc7sUcMBSPzg?enX@cF@&QGXKB-YhlJwb)Ok?IX30=H< z{z23DhWJu;5VUF zuUVyfs00>vbM|#10G!VQaX+NuzKCelZE`M#shXS`bm1DH2y!w(eoqZv*fcg}O zoi74pW-Bt6kY(M-Tnf`nTlRk$x*!8kkeN!5UshNJ?gGURc8hyXv&xI~Ww#2Y|8hXs zJDSq(H=*?J;HDoIc01-UjQ~2B0AyaoCjsp20>HxFg#oT0fKDa=Uod=MyTAp2gdoVFQUv(?A>|VYU1}+qrvsSwDrZ~v?5y$n-o@qPFtZ1l zrp<3c(>B1JHdxpLndK7%aEJ+DtWkB<>|mD}0o7cAtfrJ;D^F--MzZ?nVg<`!M$V9043< z0`U3gzY+Cb{~LyC8C4nmLXgyofHi0~BeRN03;k z#Gy{ZOQbG)&3tt2EGxfE%HQKh%wfL2LvkMqSpcE)J>PYktN6Y``bm7v*9fn|G*iM} zUqcss0Sdma6XXvD3JW20eqahuD++Ire%&a%2~$PkEp$NvprG(JL9P$|jP9!pb-|=o z0rj-tJ20}#O=aP;=CUYt%K{d58GC(~y#83>tdIVT{vJfmk8;0Lg}sQh>lXI=FwIo4 z&kxYWsrR!W@eB`qNHQF&Z44n3A7Rt3=I+PnS{n@W@(F~_1}6BNBDk3J>qhWXm}W+? z*Cps;UH}RO3RoGvUcHP4M5~i6k?DH#hF)uHG1b`9x*CfN;0~ad=(FptgE20tD^}z0LXef67pldf|cK=4~ z!tAz2G{Wq*MKr?fa`MCZ53@@}Gy>PK;GYW(#Xk>STW)UTN9@A<>qRue{OdAEFt2M| zSXkKCGC*$vxX}a<<~7p=fQ5Yn1ME!zx0wLsD&Jf3ZgBx%Vc*IC`v5=%)`zg<@^)Wz zlXtwn5sh%s6-6|{MOPfr2p3%@q7g2-{URFSqT4^B5ttZEMwneGG?ec$bZxnMERWcQ zeOE*@!oDj#N-_h^}9*3Z302iwEb$UDk&jQY8P+p3I&jP+w>HftX zKMObydiu$tk7!|s@3C+bc%J5EUb|1mFb-GHg3c*K<*iC*L6H5aH2ij@voJV(8V$cw z>AVpfKAnc&t+bj1UMu|$D=~NHZD0Q_ukYRbJp&NVyDU*x(n59|#_ji*>Y3yv>B3*0 zG>N;nI3A`knK%o>To~l5)`c+v)?65^_2=AbCSnX(Jx7{J(wr;JdD5IO%>~k2D9uIE zTr5qEG?S&7BF!bzTq@0F(oB`+a%rYXbA>clN;6%WtE9PFnro!FR+{Uixn7zX(#(|R z25D}T<|b)wmgW{|Zk6UXX>OP14r%U`W|lN}NprU}_egWEH1|n!zcdd>^Pn^jNi$oT zhoyN$nn$I1Oqw~;JTA=>(mW~6Q_{?p=4ol3k>*)xo|EQzX*8d=1KFCH1nl- zS(*jXydur3(!3_k>(VTg<_&4yl;$mI-j?PaG}huud{s_8aU1+8{auKi#k{Myzfz>D zWsiT4ER%MT6hDu2hI$Cg|89##FwJzUqUwDgT`Uj)#l{B&`DtbJDXF~RODH~sp7Uvd zRZqq0BZ5d`m1|`6F-$Wyv-$*GumUJpEhfk%mFkI`7KSHoJ|(TCu2xHf))LbC%++dT z&{|4b%PLifcwFwDF8sJ0y%2R)_a5|@c)w;-?&eFXd7M7~$~e2b0t{R{bCz5P=Cm2g%EO0}0N)!zuB zZl(G=Of$za(Lc~dsR9(G`X@oIam#B5LwRi`t+lRJJA>91()!NT+R>o(7iq1lR3Rpo z>ffaLeWkN5zEuB#*e*9s*_zOlmAX>~3%iUn@hl+sKWcFP^zBl`P zi;ebONWQoDe0v4hiF{8p`TjlRd#dXj7WU=ryEFOT;`1#w+IJW7{nz$OwJYKL6)4rc zRjKYq5Oph63#OT?nP@k3QK|q%sdgvGzuodOosHR~^^dD%Ivd-awElIqOlM< zXR+^n$al);TWqxNKIA*MYP;9C`w~uW)imFG#rILA+Ls{eR;ooX&D_sKi_t}?0u-g1 zA;`Qcb&YE}8{3bx@?9;{+1UQ1RnOHjosIpEwCY!>5EDzaAE`E|a_XzBhOTiBfY^S- zG-Y|5LhlEr+3u9V!hV=D(H{U#1K*U1jh?arAS# z2;npilxiPUs)rIp-AZ)`Of&PC=umV~ssKf)4kO4WRmx#v;S49$rd3Xp_`*31VyCGu zemRNJ@sA+$W>umRocF`Yw3*LT4l3I82r_N%GxetJNHT5iGnJiOn~o&Y7H)ic_$V4~ zS%nYH#@?tqnowH?=3rkn2gi_Q(j3U2zQ^6DI~Jyy*Le<(Ll<)ZP|QIV8}^%~(v$mz z-Y&P$Ej?J+Z!lU302E!!VDx3Xa7-FH7;>y0~YpD z4s;9voVI}yE>@WwODvNz*}!-maWYI*37>*4TmuxDJe44Ks0#mi zPFg!w#r=6@J1;lR4qo5)=apx`*x4}LtJbK1@)*;)|55VCjyHtp}2%Z1ea!4!-n z*Ijk;>~(H1u&}>pfQtZN?OcT~i^ZQ zngNQyF7do!`lElA?=Hms6opHnZ~tP7UTDVxxhcuFH@YbSjJ=6da+y$q6HuCJrW9U? zFNdnNOK>5cM&`TlLVSQCeFdr2EpJ!CH1j8uoQ^K?22hZ^iXb~wsfp5+el-nm_U~=} zg;+`GtAn$;I4yXNwdplv+OY~cq5be$66~6|AIj?(JNov+4h$aJ53d7~{f}w#{3f&? z{^iaSEbPBI1=j<>*)>p`{Z)=<5X+<-H#IKNGhv#^;k4d>E?ff?Ild7ab{^r!{Z+Cg z)-9_%J5{ZIyn=JDY-$IRs44)uFn+=~N!@xV{0#^aZ&Qs7(Kl;xlJNfzY>FwG*6VZ^H z<|=(ae%3>Nj*yRKM$bp=!i-*sXoQiSh=$yC_k6zy4HeZqbZzRohgxu5l3#4hZ6QA8u``~8SU*!Kq!4Y~67*nJ2M#qJ|?ZMlW< zal|gn?vsc{nBC%tMws2F5sfgrB@vBW|H6TpT?!4w|1)%Lx%^)iu?zG6Jfaci|3yS2 za0rI)FQK7)e}%3sSHNFK?83gkiD-m;1@O$d+<~wKvZk)&^m5LAtjV|s%0~U5y zK4|iU79_l=^;&8nx4|^DNQeF_L8QzG>C(h7y%&7 z;5eK(mQ-7-OTbU=N*_i;x9aQBySg|f$k;4A)~XankV0uSbZ|W?->AN%DgAZc;Uu_S zTh44scd(oH#*J~39zoKwYAA%vjwC_3JI(D4(>#*2Dyr2-{q&R`MZ=Y@aRY<#(WF)7 zYBe-y9Yb2x)s{Vc{*>0ea%wuaMY)tA_)D51pEH{}RbEj!mA-z3uV3owFYM-&d*k|> z$H&5nQ%%)g{5Pr{bz`GNevTvWqpF?N!FLX3Y4~`TdLsk%64E-MI_{?U@g50hl-Kv& z?#)kdrOwt-#9r|t>GpE}0{+?+(DV|(yeLYlW z_7eJ(;#hAtbH@1kCwcv0z18b@&H{iv$COha62JE4Q8%Zsupi@`o=pr+sdi4T1|sh? z`r~~QAaYLOwI)|3dLn7pEz#$|R3&;6x=1uYk?3;?@>Jsq=6Mi1rv`SjJVoYwvP>e= z(zv=@08>TgLUeI!Fn<(oSTmuENcI#Ggdy;|7@PK7&Q%S%)@hM7b}|j0?$(59jh#YT zXT+|tr+X9YoaXg?YwRU3cFqW7p`OaZrG%T5g;vHaTn1B>g{kObN&t$GFDJ-xwOV6^ zo4bhM0)+PdX~40cHx;Mfgm(C6-Qt9W{TwI!3II6c0%6xzVP8oc>lXHOn5wX^LKm(9 z3c6PlV|`}6HTKNl z8hbs=5CZ@a!whWLFPl>C!{hbfB{$`;u;+8iX9B=E)3?SpQVG9-*wroJH^NjU{3dik z7N8(|GeM4ztg*My@LBHu)WopH-bz|$hu2tU9$aH@BgF}!HTG<8H*?PN^~ZaCy~f@S z0Q+@QPJKw6(^uV`!oq%yb9x6cm{{#hh_11BLgY;3HMX%z^eob@TcYoRsY>+S=pxYo zMWXK^$aCC`HZ^4QUecNrnU4Et_*~c6G#&So)_K*|=Yh8_pX;U5ndJ4o1K5g>Ov*!RagwGRV-6DJerkM{ofeyNe5TJf&HYy$mzN06@gB02}rvrjqjEaY=pTmJ}@Pk2xc+ z0KmD}S5mE2!e1qJbxZhbFjWbE9bJ$GD9A1($eLEalCJoFicjlD|dr$<@}}z=zUnDB9qG=IscOr$j*SK<-Qq6lNQhr+3M;Zh3kS zrfSz)gf8*~Pq1TM8tr+Z7?GJ=Ku8JE#V0B|k|B&e-Q(8t8HZVCDXrYb>;(S>V( zB0--Lh*nR^Pj=knHq?52NmZs!mV4J zpTjis4JYyobP*>&5$Bf#xm@2@!{bYmVtp&*D^j=|w?M;Bh|2Fo_{YrMoG)8};?(e1`Wd6M% zeszO@h5Z`?{7$ekO@E-vzY{ z92RvLCC{-9z(!7{JxU290Qnax)^Ft=lw*!q&TR(B=4)m^PG z0$ZO4wwBQro<4`>tS-a&K2hhQj%p9g1tA*RrUOUNc^JgL3>|Fb6Xjh-anZZCuIeeP z9KTh4vdTRwWg~mONy|$eSx}IZN;ONRQim7hjLE@gGxG8q=A?3JQpjhs-1>Q`W3|T7 z28}YUQ9>G1bAgdh7`ZM+wbrO)jg+gA=W3j&HBKnV85hUn6sM#&NXP%XpM^u8dJ5#r3E=-bEfKO^WA8tYmF-kawb4Ur>vfIjb^zGa$hc}95L?f zv1goq*2uHZ7+-zT=$vV}ISuo3x-2NjK{37NQ+?f}x{y`-6uOnUcVSNDfbk~{8++E- zzQP!XojR534cV|Wj;}ryj&$v|M0BatUJwmFWBh5=eyjE@>IKorv&WCFKFw#fvzwEQ z_FRo9m_+z-8vgVI_|pvc(9Z;1DLW0Kcd+Up%qGo;~m zhzx1C4I*P2?t(BT4R>SMn1+Wmp$E)f?@#hNJKpQVNnW4QUY~%PAq|g16q|--xvAW_ z@m`-!^6F@>&nH2@7!N%!3Ho&n{VLQ90lkvsbz!{MHWAlH_%1yw}f?ynd~{ewhUQO+57SByG&pDmk)9I}Vp8qw&|C0z`U&H5j z3ans(8Owvr5Lhlmu`|Y}NR2go!vy#Si5M+4M)L%WW{?>uHcfSF~-G0I$?ix+{Dros?K0tapWCqe#LS!I)1w_NEC&e?K24PY}muq=UMAt%Sis&XC z(GActMKlvK1ML|Q8EIb+VG`}@v^+u^*?vHCyB~TcZudbJ;ntYv`Cbhl%4(NX>K-lg zxjqw@j(pIZqg_9m;QA5B3={n@L=jeU2W__Y9AZ@?)%lQ?`Go(nBg zzMg{2!0buwIiA@QS{`AB>3T`Ke=)(m1DPRbFF<5q_Pq8S&+IuZk7M?lX7&p7Oo>?l znSt5M5E+=wPxSn@_WWjo=Qqso3lrf#((oT7z`t*XU!>vV^ZK5a$K`dIcE2>i{SwFw zdHob3LtYna&+*JY(eenhRPN^xn)Z_An)KJuG8MyDkQtbLsXfOt`$Eej%&?byr`@kf zaK9QdL(Wz~WMH;ZdyZ%Jt(HfarE=FnXv*17n)Hv*GUaSNWCmtGXwUJ?zSr^yGvw?y z?f#bp_nROyD5NZoiY)q+C8;Fw5Nm^@p4B?$1j3L|}!$!h|n((erGqCEI#>lh+?2Lz)hNC~5NgX?YCc10jqdd=Q3> zgokUwL!oA1HAH)jPvfCl9>eM|2xC}{z_5{3ReMc2xC}{#;}pq8Jg8;P&1_QREP|OPk|_j@X1;p zLwFp7F@(>=u#xb&n(#SLGq9Sdy~bDL1TBwYbsmHo9C& zbh~DBE7S}ryal2NS-GaX86x9V_)QQd<@ZJ{_eJAgaNYr7Of+|5*ci=&I-2{TW}ti@ zL`KT@LYPGP9xacd{1AjOlxJhuNcl-k`EjTjCSVRkvC+_JVFNb>r6yw`Zqv;Eg`R0f z|AEZF>~Dw+we*+v9M5cvmd7#6@8Vu8=5~qk-jwfarXVtS&wS0v7*@p?HnJL|Sq*@iA&vbZG7vrhqNFtT)AAU?2SOM__#g}$2@ltV zheFN3YKZn4pTYW+*RdMGzT& zcg9Vqf!cHb1kVSU;rk`RAFAOGPJkZ_nIW))%$^TS^n951JS@TUP&53HMEIjM{Ky3O zBOx;cc7)mU;fbD0wCCdzJRfU@KPC~rO2bzqz?Va22&~NHnNP`1(D0)Y;HwicPSzM> z5-?7J%s}zPMEKJ+{HY1>rzB#Wtue+YV4Mk=f#SGC_(>XmVgmexM2w3x#sy{?=bIo> zsq-K*tShP9iy@3z1ZyyCTm&!Igf26Cy)?<|w0N&qBze6_d%Xc_hS``2kzskA0g*8c zH$xbchFdUfOv7E8(4A(lcO-eeJKpO(NnRh(US~tikcNjKGNj=_h>U4?6vCJ^JceOo z8lKjKo-%uVGRf;R@m`-z@;YC8od-2T8eW7bHVt&M;^la+3zEFPp}oGI1pQ__^jk^L zA8P3Lp=JnZQIgk>;=O*H;;~;Q{#MXTEsrq65%w}vVcbMJZ zuHoa|-=^ge_o>{wAv7iCAovFU zp=aW@4l+X}dDwP9KQpIiqGs9snm0KUirofwO(v6{I zDwsxQW(~K)tbvxt)oW|*z9sYwd1+zx-rS6y%54K-IBq<5+!n*WK!ZPo@1hB{H+$VF z$!mvruN{-T_RwB;hngV`HbjQ<=nhd*d34kA$Rwn4(-6j_sV9bwY1&s4-Un(1R(or& z@k?26EstT<7s41;MHn`+8mL+IhngXc2S8*X+z+CpH2zP^V+ap|Foy7f7&a0frU?&$ znt|1!+G~6o57F`%R>L8TVRaaWjjWE-td4=2A&o~vWFUMLL`i8JspT<*vk=A*F2S&o z@F-2V3Tg&cmD+238Y{FshSl*9#;`g8!$wx8YE~yh&A@7`_8QM>jF!i+It{`YR;Odw z$m$}^>H?@4Cii@Z41~{vC~0!f)$$m^7eg3BxCX;U!qYV2sZcYpx=eeGPvfOp9>eMi z2xC}XiD4tF8#Sw$P&1@)21EwJ*F$7H2fPl#q#R$X3Ha8lAvGG&@V#G5RjAPb$-0pmy^6M)Lvgpf_@_&`pqQhr5gIvpjzO5*J8*F!F~c! z?ChmdA44SN<|`+9#)yBl_)2^JBEj?LX82`^@T)ZZw+ZkoATtEE-0bc0LgfXnTVA#ki zty%2>HA5PAhsZ$KhA1hG-L*W1a8C$h2=9quBjLW9a381{SnZ>|#;0*_EstSU1Yr!T zVhkHuHQJ*fCoh$k+j5Ux@#@;VyjIfYwpMK$YIF1Q+sbzS4&2gvn;YzbUnS3&F#h<_ zBgdY{uiI4zpfmZI)cRWNV|osY>Opki=(ElqdwMm!u{YK{Kd9rw7|(~JW_is(yD_v5 znlx^F<-}@!Rk3=xWwU&U^HcfF4B~nuY+(}Op3^QWE1e|jyw0laqS~%H3+;iDkcFMJ z*cX9hVMmCzmxXpg9Uq223mu?k$U-V_*Cb(~Nr)U&AqVn??h0r{&rtD~eB}^G@c$?8 ztK+OVns!Id?h-77xI;(?5eP0J0wEzd8+3t%!?JsT4Qrg;1vc`AIC1wk?(XjH?(XjH z$$hG;x~Jz%&q?lgzyB`zkz%T7uxJ7SXO!T%! z^wwZY@#|K_wDxvu?NdzaK%=#PG0}tEq6Zffy^|5W1K3hJG`yJBo!weT6w^A|Xx+7# z=-u6-#}pGi!-$?1XN%>Qsi38Fb_z)86L+=|Ur|K-%%U>p8yWM8$e0USiiwp)#n%|| z3yO%ZDk`Ja$XJwa#=>+Fey}Hqj)}Vj=+ue3)M#xiCOYpH-CRuc-bQpA*i!tuqL|iw z+*xR~gsK6;UB=;LLl)z;fzJvc(Iw5^7#+0BI)m4iU_-q?nj zjrp49#LESjf}YrInOfjoqu_0l(-Ql_!bz&Od<%rpwRO2MRSh+DIqUNk<{KEF8X+I2 z3HeBbOsa}?)EtEL+fKVnCDigYTzhe5=o$a|>8h5|FnJBVJ^7Hz< zTdLnKINb=Fnh-X{Eo_feVUe@(U^-@D_bdi@Ca!Uc(_nU!1H{B9N0>>le_DC2rM;rs44}xu+WP z$u9CahJ2Qbe2F1n$lM<32R{HaR%5z*BQeXv{(6@C{R_v#1E!)dw$?Wd)^(9LHslRm#z(z9L)?8?Fb5%l_)pLweDD%o*!;}?@EsKoO97eL_RX_vN^T(Wq2p0uhrH(LtKL%FXT1+S(lc!dZ~C%tVN zznRwfjnu}64$za}-~nFa0?W8}bng#0EUVI3jxsDqI9dGQ=mFlcs(h9;$cpYAcz-wu1vg_CPlyi@D3PsaX(bQ8#*U1CCd~RViy%Sr9?V7%SQd-0Rnue#R=sYd0 z={ct9Sp&Rgb-Ze6JhPw~^-)co%?4^mcN^&L<)#Bu24EGMaxV`7i~S)yGe$=!mM}PS zpsqp>bF!+E?-*e|-Y_4P&U}(EpK6#-NM}A9%v=PY38n>my29yv!*gyb&kcjLoa+X8 z3v*R1t$EB>{VluAeE-@(E+5h@?iTI~}U82MwW9-R33HCQALV!}kY*FlsU8GtTx~lbLh? z$h@=8HdWJ%&Q|5~Rc%%@Od)UZ24uLX-NC3GM$!v(3iHmwJi;*Vn9e*3%HX{a8A zC!DORZ?778FFTq1;I*M%O;t;kl{`XJy6E$}qUU|1=WVA5rRO7~=L07bib^|^=cbxaw}p>?&p#5Qdg4k_{7psZwa`gY289o zTE^QS#z9s(j2svSWeQRX`rD=BuY?ZzGOh3bnW6(-?I0S~6AkMd4XX`v^rGD`ueG7J zy0OMCMtHULgO0;YSM*Iy4%>}H$>ySD3xPe2vJHm0!r2ctc8XNv*at!>xcV9)+d73P z=J~?BP&6+xjpn5^QqA^6GxGaV!@f9$9jZn)Rd+JsZcXoWtNm%)0pT5reP46;No8E3D?Icnx@1TfQ(A)~ckr77fYFFed zQ>i~YkJ0|yag2vUEd9Zr9%@riWvE$D<0sl2YV*dJLXy1D-CN0C@Ph@^BEP5^MJ83c zw1w{hg?k#2i^q7N7mSzhFG|t0Fs=zFqFPg(LsJkeQQ}d<OzKvg~g7q8&^)7$#6S ztQw#s`t3{gnyh@1@8=-G9g!uTguja1f3( zJ~`ak-uDlSciwXIQMP@Nn@=(#PjI{W_!LdY#Wh)OKEX=qW1g5wXMhQJcuHq7Q)vY=Wva)j;-sX8 zVQG$GW}(1ELSHQOTEXuraEZWrh9wPh-N-O#Qjpfw9m(y@iOE7?K5DF2pKDpHM??ZO z2*!-{FbXtO6elWCoQB@F^Ml>SBA=-*3`a|yntH)5tVYX{Q1pY*aBFUP)|ene$Bjmg z^^nr(Tg8-d*7SoBWAQzE8!-;eDKW*6yGAk#^wHyBok}{Db}GaFBS`;Z9Hr4^Jb=N$ z;;Tah9%_8nG8QR@?pm6R!TF^b@tHhRB3HJhI%YYX+1kX9L&ZA30s$>+poI^Dy~a|i zP2@sT-yWd?It)+Z&Q89R~bm=^S=L@_*;DrJ&Vi;b`Fms7qUn=l2 zftLd!3x`*zYYMBwFgupz@(b%4ms@V)dkL$?ddrqsSaKdY>3Fz;?!MrV-+Z0=Nbp*N zNVCijj#b`_jrnnfk#V$|&1SX28|BA(P5B&z863Mz#RNq~hW^9&UnApx7k4VSn>!iY zBk*3+$*WYLCC=rpL_g#}Myd&_q^O72!pfFhy^0(e)U#BNuH%rcs;g_PMt-ZYtn`EH zL2Rwh8e(>VKK5l9J^bJX1Vz-=%or0C4@#e2l0Lj5@Ku4Y5e&lM4ZaTF6!@0V-&T+Y z_I`9Bu@Sp3wZ{*Gf{fjYGcs#bABvBv3IMe~Q+3(q4kydPLFF>q6j;os0#_6i&Z)a-p{lCU~HMP|^iH@Zrk{*onYV4`A zRado|c7kYHhPoQj9mW-wgH-4Ee*1Ae^h3JEniH-R*8lx#h&3^s-(+l-?fe^|2ZINX2>!jb`k zA1L@ij1P8T?ZJ)&F+e-X_09~#5ezdU1@0nn6hSP|yUF!vhNWW^qzSQ+s~3K-={Rpu zu0=iPnvn%;

OcA9P0pHDHnf=)MC_R6pEOIaj+;7i?6g7gmi^g-NEybZHJozNKmb?^tE{r<3jeYz%Y03adyI zZ_0ec+q`jDo1>6WX|)7uYenr6QClZ!>qTvoQM(8dIJKCai|;Q?wI!Es%bqE=ysK=X zQG0tF6?;aHD)v4w)b||Jk3ppatWS)+9~N?{?De_uePQ@Mb@F{JeBT(pFP(hf8>_x8 zq{F*E8|se^>hFg7E8NJL(Uh>N&*6Ao*!$z%9GwhDhw)y%cF|%CzVREf#CWeRw=j-d zZ9Hlk+&?sIO4V9MP*<0rH5`Jvj7N4`sCJ#QT~m@aFp}1DNm@4{Nww-`T5aNLwXwTZ zPt$61SF0ZJR-VV3?XA&@)`M-vQvwfzZ55=z>*bQNWn2n&*L+}!0q!f3`iZ3eMp7S_ zq~7V028*O&kU+L=ZzK(LNg9wYX(y31QY7tSB<XpuBlB#kqYc6CV_l`d(L zNZLarO)-)txFn5Fm$Vd;XrkxGt0g9A9

|pk+KQF*JsaqfAF~jl5gu-1IDe(P=Q(8V_T0WKJ@ck#9;*^Qo zPvp}9b@3lu@LjQeCt`c3&r)S9Yt-_&&qQybJ~$Er{XWI__XeRcUmtsrl_`5cSgvh3 zKP4M0@_fH-qHG0Ycq;x@PDC=-Wdy3RCJNzTzlkW_TCfgS>oi<J-`Pz;kZ}$?_+%M&P1;co0x@FwRI#n^8vTde8_y6 zkEH$QBKHfHTk&&4Uop6yWlrtSkgn_<^p>%%xuZ9bSt^uTIkyd+*at@F%0?&?57}Q zio+&)O}MXa&D&lo99N}A@S$lDd`MvgBkDMU4<=!JWD$!~-#;idevd;4<>Ds+$HLae z_%`z7iQWS2-DK1kipJNF|Xu{Lh$X~Z0LImUj>#8{Q=2PaPS8Z@u913hV? zSKXS==Nei_t)9tJ@B6_CXvOAOZH}JkEv{ggC<$YS4K;P zZZLR~SM41@F7`doYwASH*;HudJU<0etMbjUpE4e-^86l?Qtv^OPl`s4mjFCFHhEHE zBBxsrWZU#fu0%dKN%LO6t0+(pJQb5l*NOgD9o%hcJarp|Yoik~MW)*Ol+ zc(P8+-A~M2Y0O=cYVMxt=GMB*U7TuegVWr4r@4N(6c*{A#Vl0wf%^u8V7>f8RQeLK|Iw?k6;c0{soet6`h*ipNh zq155?(P3JouI3Jh*Pz2xEL_VS4zCmZ_3Vi72F7P@5(nKZ4!TA7Zx{YMg#S))+ylyC zVdg=G!NUR{VHiFt@G*v&#~GG9!Lam6flmwmS-E~r;0uC(Nv>ZO_$nY32d@kL4Z22= z^A;ctCMDLfiza#X%_gIJvPuS*0bQ^%U09fx^pYA}j&NAA z+{%!Ca4FgstV0(do~+VQGMlPIgNtc+?bY%M3ckX}6!eiKC3%hj1u5xsLM~JHO``u3 zpE@kPYZA_V&7&4DT#2IdppPVgK9hm}Tn7FN35ah5|E=J^lK}cf9RI6v{0FLkG%KwQ zlkdMzJ&_w!hQzmY-y;$g;Dz^YXskYtN4y_=qP$$N%yRd>)Pk&>z&&L8_o;Mvz?;ld zXy9b7p9f9mx_atcYvKjnbQTH!La1N0?!ouS#o{0z;hUuo-6P?hGiEp3@#LSk%E*u{zmF> z)!%=mq!c`MrUR=mf_?uFBIz16HY0v_tscLnt{$a`vx4HgWOAbT?l8Gn@x9t)dlE|O zQIjwTCKr@jCaraZ7I&51nJ7{3VkLEEazQE!p_}ubo}H3^{Ge>Iv)cB_T37P(gLadP z6yhq|QO4u{R57e_BNeQ=Xr+=B|Mp9EKqs_CzSI!v+yBUNrKa zvYT1+o7S#pEnVDa9N;~J2KpYnEcM;J7K&AP;$_kEhUj_I=y|D#o>yIZUMZ&MZPD|- z==s3td8>$?cU^kkDW>Nm=%JJL&qUAX48t#sz7HoC-15PaZ`7FIPRP8%#DkN*5~1IU z(C*1| zys(@K16qi@@&eze7%2fC&Av|HBiPySXUgf3gxDP(KWJZ$t)BDgpVbt*e$FvADV3r% zMA7=JDBM6P!ikwt*afl^_nuZSFTD3eb7AdNGu9Fz4nzE4O%~>$Q4Z)@u5W3v^*xYD zX&P-JmiH9Pw-n2J8Ot|zS-z3e^375$?_SLEZbdEMwA|c7i<`cUnBHGZA0Va=G^TIu zGJPwj>3vd7?_JFFZHt&L9v%WSsk$2pvjD?g*v!l*F?UyiyD3P)JlJLSAg9?orkcG& zF|&skG20J^MncW$oLYD}^Nx`YO@qPIq3M7$yJkp7W}1%d?&`>BXGh8-ov~Er2a}6+ zWKz+NjE#ia9pP@wmhhP`W>+x`7Z~$rxy-L{m``cW59bMFT6r=_aEb(=5i1B+O3xy_`%*HIF_>^WTjEP zA9Q#J(5*(8=Jn-!cc9XOb!fTT$p)*+>5zzeeqed*p(1{27Ee@{$4;A|;3%aa3{F(m zg~3SzPZoHJz*7|@(MQ14CMqD=k|y6joJ@a{e!!UEL!0Qww>(784t?<4%v1p}RcK+#Dchv8G z4Sr39KMgBttS2;s&Y}2=-HQm%g1>RUFA5t!JR41Oi)hH`Seu57&vUTb@WadDME)Ix zc!Nd=!*MfrEOS4PXyyToD5h5C!E$wGQSuPuOCDx?$s>Y)RPc`p{&B`*oc&An-+o;Y$KvR*)QdVph00c1_> zqS_YwflW0o!JUxlBn81OXhlPL2t6I$(L2{`=dFAKw*@kOa9=#k{orEE*ZOM(DMCI-7O(8Y z&!EUzz=od|P7Ae7pf%<@sH1H97sM0%Thw`bD76`1V8Ad86(lphb#?0-XSe+DhjRUx zYV`OrjhdRYzopv!D=6{#Oosd6FHn=jt36NI9{T=P$sS(w;#zvP%WScIKSRjId`lL; zC$VC^tt^Wjxv6=JzQn{8enw}M$iS6r15^RI^-nrl+`+$ zoNP?0{&NFP`zeLzzB;1ub@Mfxr*Jsc%)SAn}R3`Pswogh|* zF+v|JaGb#L3R0i9caOjnXjxpJ>*qEq8JNRv~^lT5dESLgFqcT-N zvTzdl4OWC1JR|JkWm^-;ZxMnDlydT$u~Z%3s60DEq*sXaSt5P5kv_dp`n06KNzLoIqAJI#!i54CG0ZHM>sp4vo&uK;#8A}?KjoBNHeNgy4=d92Fn0x?3OD?Cg;h!2hrF;g13h6FC}pi zg2t|eybF}iJZ47iCDQj1>HCWG{}}0Qh0<3frSF|0eLs8b_7_!$v8wQJfk!aR94XgF zF$|6tcnm>|-LXPHPT=tZPf(B?vC=(utDIwZXzJJ<>=?TPQ^)R*B4c-w-Tzai|L3yZ z!TEqRkQYclE;Ri(g1QlY{ zT6-ysGY>poXL868!F3w7QSB$-%n1y--PckW5}tl^7ZFcVR0T_HP!tz)Qb zJE&WNO55nIR1d;nYlh)Aa=op<-h%I=AoX;MDPDae7IU*}*$P)p^VmR3QiN_!D8|z#alm^Oz}3*n9_F&O)KM6-`}pVr+(01 z%;gZoEA#wdfNiS5s{tDd9aLssD&4<~ARf`UoUg+x1YRldDuGuEyoO=sT7lOIyk6i9 z48t4c`X+%l3%msoeaze{*SE>_?R*{F!7#j2;9UamW|+B0;Jpgca1AN+(cq+y4xK^= z57s25`*%%KyvCZEtSTb(`$1@1pi7Vk#Z{lO%HT7G;pYOsV3_$*;8y~_CWuE6zLo3m z1b#2@2Z28-NL_efisQ#S_fOGJfyC}tk$HaR@hJtbHd*;0Jv^6rafT%I@D(}Oe?fD zv({9c%hY74Ytep=MpEsDx0)((6@^3CQ*}FA5Io)JECkcVFX`vjRI&r(=~T_y7~%0( zKiq{yHZEM)oU_kmS>Wy|0;jkIBE%L=<;=M!hLq1;7EYx>$u>9D(GTvdA9LiU;s?g| zuPxLd`ZYkuZebIe!eH@K55GEYA|GpM)-Dga8%1~C=x$)$`CL<7RW%;#wY1kyRX^Ep zZe5VnhGXohUSl1`#!X$4W@3|NqEQ+*vK2=1I^6;(t@_l~$}GO$OrGI);aPa{!SbnI z4zGlYM$r$Jkumh7cZ7s5_BLwvN>$UAs%GD$nthyV_BU!)!ejldrJ4tGKVZ#kv@y?k zEMeclGFC@mtPqCbktzj*nWGqnN6Ymw3Q}q~NNlpk@IYgeg**T%9q-VgU|*#~*pt8y z4;2|UmV%%D!p`GN2ak2j#Si|cQqEdLub41Hjg}`#4^K5cIFVGTWB1sos%qfB;D&|4 zCDQ*(83vch_2qJXg}^HnB)^=2PSKk!9-djT0c@vG$L;Y6poFC$V5>W=Uw zB+OU`UIhYAPnbI}-C!Jr!iQqq4^U1;^p9f9PYi>f1^%KSg}?_>=?+)SZFm3{%cDk` z%%N%=5VG;L%nv_r~FBM>Gp>H&H>#^;@`o{J(r%|O-n8kd*D+DH1 zb3SY+3)h)e-Zr)-yC+`XNw3@KlJQnPgiv318r_uJh;@bCr*T!f*)*<7draf1bU5QP zJ1{=8qu|TMwkgK84UJP|Bx%Xq1ct?{$BoeiJCcJR=A8^l&B9E1CJL2PY}aS6nK&`@GzHwt5OX-(qYCCsb-uiW}Gi(Tp;Q%6nGKC%*6sP zQIJyADK4{4PBDuT(^+Yr3r|m)9G+HSvJ_q_KVL3J-@rx%H!=)w5_mJi%q;?MRgjFn z%w_bYMU1}EVcHc%OuIu&dyG{Fj|+Ulm~gu>!7Lj1W<`n#e(+G5*Md8>Y0(}LUcM)V zUzWC~#lBa?uGa*J?AIx_;kz2z zGHdu~okec&r}G+HGF{aRL8*eOKA0Y5)tF=cHp(r>{FS1d91~2BrA#%i+CeX8=CbL| ztrBeOD7JMG+tx6)b(rqR=Iz~r$bwD|3)V6gteMu+u5O7iZGACqLu1l0}UZD++sRcH9e_lk@-th34<{%EYd*HR_!$MdI*=_6hOkA! zP-D>mw?+L^EgEDTZziNS$@ZyAc1%?=3QDMY9Sz}p2(`;}uSFg! zvS!Z6>8M$k>P?0jJwMnLg!m$_X3kj1<(V_a)zbHOcc@X(Fi|X;3X3Qzrg8Vf>8AS= zrYH6U&z1^&idSw;cfYxXX5GB$j?-K!im8l(5es1iIjvr%QiDvTMxIK+;bO!Q z#)w=re%4N4u}hC1EQ(JbKUgx|wH=@Urirz;m2K?OIn!i%ZlTp7(lO%26WGx3L}TdD z)4hdw<>3N(Wo#_jA7$jl&_||t5-*f=^^c5(4^J_JeX?8ZNhxB{_6#xqJY)9hmJeda zo#qyPYKri(;OyyYXNbe+8oX*nRsGTa@SN#*$j=YYq<$4{2VmDlrcW2T)n1UI7Huy> zTZj&>;UNjGm7%##;PnD;5O|}&n*`o0@D_o$Do7LHQYgjUoveC?YV;6{?_c6J^5PUD z{or!3WLSf=p0S;tdi>VSymw@jToW$5l^GlP4KnRlcO;q7iSZ%Z*#^7{Rv=s{8R zkWqB6JGn@^$IKW$LYWHRdrG8^hf_5B!ILfrl?9J;Otm&)9B}9##nThh>Ac}tr7{d& zU{k{vjj7M1necR~3D0qC#-41V`Sz;#<8|@J8%D`1X-ZyBQ6ipt8xkpEKM;u@G7LW! z_=&(z392){x6(AdnX0KQe3zYv9F7C!$aU{wD(ay6TrBy4H3mP5=AQ)qEbteBzbZ&` zcC7JlQl=-cTyD*cipz;eIL01UzJG6a7c^}j_LtgO{3C=32{>-dWj z5JdSiq*R|lrMfE7XSmn1vLKwHGMajkOw5Iu87!=w2&(bB5+e9yK{H>KUiaisi`ed z6u8QL-Nnl7#Jau$`xz^{rCQlD#mddo+`I+Zxs}__9>wh(Aa;%v`*smH%GlXI)y|<# zJN;m|%aXESaLT|AA?pVfH*+@$pz&hf1cu=xW9F_YX3}{0;aI0h;qGiwbzKhk&#kFH z2C+sdtz6VjGioNMs3{Akh^$83E4M^Vm9U*DqGlUWGg3sU_^Fg}S;!p?7MW&qQkwZe zRmynO%rNKIR;ZQ**^~j9PbMoXYQ>6Xv7*ITu{hO=2B#HeK^<#LCW(3)|D{eF#f%j& zgC3{aTg=$Un6Zq_$U4vGTWQekn^VKqq}%EubUz5iJ&WLA5qb#2@KAxPjFSJ%@btq1 z)~;krV)b!i_3>iu2?9?vRv+%P`mler`lvLkk504t$bYo@6tVhZvHB9R_ELeD z3A|k36#}mW#5;U4SE*}Sgidz$>ZE_{)oE$HI@L118@qfL%jJG}hKkI@5rW#QAw^uP zx<;m51JfLL;lXngcxZEe3wJBH)pX~^8P2Wa4KuJyw);&8TaZK zL-b@tb-{*#&q6*i{kO8bO5@)^EdM3|@26Z?EkeL}* zXPJll(=($%ixC2}5_K`WKa&>@D-BQJoIr!r9(M4jWmcPsd9x7D6O`gU`g-2}l&=+I z0Je_GT$)}TA~lv9)FD|HVWK{)F;fpM8RPSlLlCsK(uW(<(qG?Sb0)u!Mx?2C+VLxU zH!`+u2%fBK2#DMFHz2YZO-qpPudiChhk;eVm`yB$H+8!ST;0VC)yFMVlQ8H#(`#&P zQHgMX4BLC=}=Bz0@->ur2fb?ce< zKuaBdTN}F(Ol5(T20OuG%0;`+`Zl#9ZVPVW(uqjIEP`TQs8_A$^0Fx z5RAnD4qla8n&6qZJ@~{9!YlCuB4s4bg*u*@nLXSsLz}E197AWJ&@mMwJ)b*p`ZL9GDRfEBt6AZ_3 zDIBL7j+0Y3&Qx6@EoY>4;q;WI7n!CPz?1a#mO4DI*{ar6^Q*4&XX1y6M6o)cV#q%a zV&fmWt3k)`PC?)czOrR{e3j|X6-BtNHC$I0;kwb7e?11AKI(*b>8dZqTBh<;zpjXw zTaB`ti*VfyE~;PdHxYAZ8n++ZOIg7VLHe4PO5iUVWzWNARU}yT^mCZu=!oMRVF;Et z#Dcet1+O_oyqYS4ihwr@4Wog9?9Yr@pQQKd3&gs5U>HB2%`T#+ip||ki1<;72!lT{ zU(_eU$Xh`LuT!Cd6r?}Q^cLZVuC93c9+6htV0|SSzbX6<<{-uz;va2O4=4KHf>w(s z!jd$anLn%9K#>qz*M5P2%(Hi9-T!^2`e;kR*(!Yj&JTWytx2ZIuMo62pR2;-!g|Cc z_r9u{{U(kqkjastVxfJ7Swt(M)!9mozTd7QE&2F|Re05S?7rDa>{!Iu4n>R&g02ygC9p#c-g{zqaXCE zC{n8SwI)Ms>TZWt$x^i}=*14Ju4`tWxvGimdmfD47bfyX>0|3cWHBi<5bPw=dUxDvWC- zjQ4^E^miVE|BC)I8HQ&GJX_#7LO)O7`2sHx`h{|RvA|0NUMlp<1YR!qs{~#x_-h1S zC;00H-k>1)W3lRRK_=mOwg@4M2e+e-G+MI_A80~I;m0NP#Rtoe)RG1=k6fZZFDbcQ z2@RSm-1T-#1)jxijJE%7}yq)YgqV5Ja?)0jW%+}EO;JD zdg5VMlJbKGpq~w}hSv`sOYs}!B)xrmRs8pc@xd#IOhvJmg{sHMk*M0wQa=lbx)B5=v!Xg^9URNxJx&#BcNSzIHuefFKj<(EFWQY-`$6d} zmpf@SmbRY-QU#6-AKtbyQ5C}rbTzO z;IpT0v-I2OC7^j%4yjv+)Ltw#+)CiqM*8NntjgMYrnAQ^dN`~Vzo2rh2t8+cRn;x6 zv6qrj#!@+}FO<^BWq%&wV1OE78p%HFk7(d}P)zu}q00&(eWuV)9LkZurkaR5LN;P6 zGn!>*cIW8HjN#}h8PE8V34$*dzCGl6ittSrz8Qj_Eqrt2x>ESE!Z)As;X=L+7s+*< zT-VEWvs}0EbxE7F-%GCdX1U@1!gqk+4;8*ua(x){1xN9Kl^)G7I7Y6ImFwf=`gplM zfnnxExjsp*PnPRb)^7u8Mt&_=v z5kM)VK}5oOS8ccABTPToX;$*qg`%ml)-M@1tMI4lYR6qN7Lmzs&ZXGw?)9Lr?M#&5 z=EDFW{nAOX$=+Rl09vMI3cU|JMf_Bk_?b!Z6*2KTMH}(+QpC@7iLXK)ppBL}CQ!c# zFI|wP!Vha=VthCOi_Bstzxqk{o-Y0-7r&orL>$yt;Z^D8RSABkfd-2*j=^Eyfn1Ph zxl!6CJ6aWz?#ALn%@N7ZEORSdQIP1>p2jcT2WZDL!_d0YrS-rxtp~ZZ(#FXzIlMqK zBIyXX)-ojYvm~KkZ06~il&BNGmiGPs(!y6;*HW7(^k`)|*Ae+#L7WYF^euDOwhsne z#R)jLi4#V6GsEB(fwvmNu9%g2E_1mdWu2Rq%OZNMecH^0=cQQg8u_@X)~-5v4}J+# z6YZ$i*D}pnj$Rk(l(()(#dWvZXxu;!vnwPDy{nZxJ!vojiI=NSxauArtMFdQ_4jdZ z5AWyPo_UR3R`R;QH;wD=Ms~&TIdKSRXDxnd=v|6Nhk;bYTgxUp=T1d#s-oXxn^Srw z-C=r|Al>fDk`Jh4eVghd?w#1CkU%O#{O|z^-{_a$H20o1dd%qB#cSpvEzxqEvM}=~ zj}MPstj!aV%mkHY(F?Qa!YML9S9E!(kD3i3$#!RJxif{rNF!3VSGwMnsiMSk!F7KMD?`qGhJV=(X^k+L|25$|6F#y4!+0ntr1U5dHD4m$ZFjFqq zQv^;GI9=cjhCzkE*$PsaZ3XG^TX#GWd(Fn7ya_LzH~cMU<6c$6qPkp7Z8K(3_2R6f zHHFkJvvFP|EY(#wXH0Z|Tk8HI{00~+trlVjP0)X~I_1qS)&+5l+DB34)fO>I-`Vud zdbN6|wB1Il&YP#sta-ij?7{=8a3_Rzevv)RwMW8XAjMCVY-7UhXQQ4+Vy>;pF09St z-9nI)jpq}!+vCGztQ{kx29aD>3p%%}lo)A{acva1RA63UGePxC_#8763vxh~y=@H> zA3Dxe-c-N%$NMGuS&R|%hN~b4OXW=fR+lMl(0{OQnM}F;XIp2;hl@!^Fbt0rc$C1S z1s=mNbF5q+FYp8fDRf)md2K*JXZB6$%-(3S9F3|LIG%)9p4!tkWIQ}xU>5dkvCYBh#^#gZesXbvy{FFh?6=2=|IUIKIz~7b&G|v1Gcl`j3)L!b zNkFL^rQ{g?jM?+8*MxDdNlu!Os%>Y{AbLe3jrA2!65PYX!fj;F|=$RPcGmhbzRn zZ36caxVON46eMR)Om&_gPMzar@mx3F+FvkNkO~oUbBdFzi<6fWCpV{);otq>Upj7I zDgECc{U?7PApJj_`+Q(gk|jbf_rUq8odT;AY#trE*!1Q8 zl!SI)N$F8q>`ufrebk7SWHv8yI8yxTbkKgEZ)XgyisLg{@3pJ!_A|rbdij}- zAn033PpmXFH{ltRteV`oo8_F`U1)OuAd|ZiB4~0iFec4`p!jpeykh&o+{jp&++-~J zUn4>mix8UJxdgLJ?j^$9AkJ!(;ca4P1ue#sJu9)-Yiw@Kn;TsyD|kVzjik#IXTRY! zO_j8Fw~n054oc0?HfYCihx@Sha9`FQ{ztSQBvu_PRvjYv!<1EFaD>1k1s)~v7zHT^ zSEO6LyfWn}x@D=|*&m~kT*GK5qi&_c`6r@BT$>$VnUXAzt4vRp$0k(MIH_cLo{ZE5 zrf=s|x~splE8W%KSt+rkhT>8lir_MF`Q_sBE5zkj3;r6xUn}_A1b@5W?_hlRFb_rM z5r*NTa{ZWGKQ7l#C`dzfu`)YRtzCp+awf|Q6TbS@N|slmnX6j6F$I5b0*}#rT8(BH zJR_ZaRyz5dbp92=zbg3G1pkrXKNkEa;*_7H^FIsx#dQA3)XwIV;HtmkcR8mA{PJskIAy*+$dRgn(Ni$v5MNJ zx;DJF7dI$Z{9mNZ!4O0#a|dJCpt)%&bI4qi-z8;I#J~$XiI81H2&K%O6U>q_cN69@ zb9qG^JC|3)adUZ}G|5=9>)h0oIVzGaDU*ZO4<^nnnlh(CJEhDStUa8`+QSObK2NO5 zidFLkU#+YPgPg#H0v8EftRM~Slys~2n46L^%Tv2E2cuCuWiIC)1^dj6jxZ0GUK}C4 zI8u6Xyx>m|{E31;UGQfJ{=b4hPw?jp{sO^YCiu$*e}&+$7jN7k@Fsyb3%o_(tpaZo zcss-J4uN+Hyi4HS0`F0fpZi=z1FcSW@f|<@JYAC?tiWV&-z&f}=*Od*mlDlW8A07shf^_HAgmE-`3QIhp}<*H>)0&jBP^v;6crq?_01p^@E2EO})}f zat5UVyo=A!`sojO`yR&c5rZF4AWto`uZovGl3=IY`?=}&D|4};yYI}rJQw#<^7K%L zbzb$-+}KKw;!1sX-hVMM9l4As3tpeQWI4Z5v(#G;FIZi3Ezf&nZaY7CdoJC4!A~`! zZ5;I%#VPmqHKr&18S~2f%AkZ4srt%-H|I80<(p{-S?Y~}`c*h1erqn=`5rg?2k{>; zmx+p)?swS27}1#jVQN-I=zfhsp*3Wkc^ta^ybvda>(1l+zTP~}@9WRw{JxQJafENo zSN+uCVmBcTP~y6afXzfe4-wFlxdy2wTMAPzVcJTVdW)!mY75&(xV96nzQQ#?xF8Gm z50b0F>S{1w^<&e9h=idcVVFqRQQ8bqChsI%I}6tc;Tk1eLzU!Rg=;tA8ZBJoglm|x zdAx8<5Uz>BwTIxR2!5*IXNbMf0q@Tgt_tCrC0v!vHK4DuWUgq$720H_&3tK7C2eX1 zpA-B-!Pg3YPr)w{e1qT{1>Yq2X2G`zzE$um1m7n3y#&ASJXJge`w3hraDRaZ2s}{W zK>`mJc!`vV9fE~8GO?3-x`{FPh~8zhFZ~{iEjNJHH+&i(QWemk`DGGVmvfD7()L+ zvEgbT5um5Qw|_)N#Mk0q4I%0CzYMKk(&s-KVlt$@H?(BCHI11AlEf|%v2QH214HOH zB+Y4MnP^a4ET$5^!o0nR<96QfZ zyBssmUAr7T&ur3SDX1(sab8rr(97XBM(uLaJk%~{C{eO^OnC5wd8)EWW;iRz%Yu{V zB`cFt=3!YmorM=|?gyu`k|@oRa8rH!cV60_4sN|r+5d4OM z-$?MA3cj1*y9<5`!S@vWmV)1gwV~>vO18J?9-_M0N7`&BZTd=^fx^WO9VA?Xg=>g# z4HvFqO4bgdhj$-4@zp@CrboyXJ9nhW+ePG!5_zKqzq{ba2!4XJ=6%sb;hH2|lZ9)F z;HL_Hn&2y>H3l66JBzRS_f@}aoh`J1Dmvzfgi4VxS0v0AE*|14k-$N;KxjOc)gqxr zB;-WGV&P)1*NO!8)Dme^CvEDbO_Si43O+CRR>3b5{BptXCHTDszmMSe6Z}fS?=Sd+ z1b?vL4-x!ffbitpQ<-N<<0?!e6uE6sI zo-gnMffowANZ`c+FA;dDz{><)F7OJ0R|>pJ;MD@J5qPb@>jYje@CJc53cN|+%>r)` zc&mc6H+n)ZIJ{`9mC9P#p_r-J(R3qvf}LA_`QD3c2s zJ*R0ES@oOr0`lvcoJU3}Z2Pq#VlQPMKE7=Tj=j`dnm8+4-DsX6mletnUe)A$zvQ;* z6+=w!2A(psWV`natzWW)|H=@tr?P&$5_}pF2E_XJNkm9`<%5WrG~{_hOzuCPF|?%6 zrwuK+uX;10C565p5tA-^Cn6>z<8wnS*hGC65eCNG@|q#wu&6LtUN*$!2z;n%Rf%SA zXj0y>zk0zCll!Y@4Xv;a^n-6AT6_!jktUd*E10-^SCjIN-PKEmnA}}`X=vD8*|X&1 zh*0RR|LN}PpW9)ha95W1Uyo;_{ns-lo!yyD-GAMYb?m=x&${eGqTmsmTsUed zzirzL*%ZN#WsB_Jp2M(E5xnJmK0WTMir}r}ifgIf^SQ?CGoNeB?dEfhIY96O1wTme z!vw#*;D-x-gh=HYYggggO}Iu2*EqqC7yJalmkWLm!A}wVOp(g9*Bs%h6t20#RVDZZ zg0B|*BEc^fe68RcL@F2H%jAlyv%RFv-qL0tX|q!B`wRX6!5<>{Lj}J|@JESMuIr8y zuH%L41mQYG@TUs?G{K)K__G9mw%{)isaywMB3zdW*JZ+WmEf-y{568VLGU*U{wBfS zE>gK#zhAESto#9K^PseOh}(pZGd_HR@!^vq>p5;Mo1zz`^-I$FW#M{LxcaI1d`Gz6 z6|VP$>m%XfnEIHn`eD?t5BWsed@5}|6T7|z7ttLi!6?$-=y{L()thK!Y3Q) z7U2Mn48Mx!Mo`6bBdp@NQ7ZT{!M789Cuu!M^{R_-tsz`pg=-z*;>cK+uW%OWqgU%m zoAss52GV9@!EYk?O$FaW@S6*M3&Hmi{8obBTJXKAxOVO%a65s01@;rzU*G_N0|gEe zI9T8ifkOoj6S%#=;R1IMxTCNw*FP3e_(S5yh{4hWV-?#PORNRYQ`+!$z7|@IXmIZF|j_AC#=U zR*Q(JL9BDt(ujZ((IWg{jCI`8c-s&YwRjM8uF}pK0?(PpeNV%~!dO{1HwuR)UH7e) zi$yO<{YF#sDDrJv-!lX%@~uvEGs=b}tIE(22PR7;FCxO5mdKxsE=+ct@TMU+b_;J9 zVzTso-q4ao`X7dd1C7E!`_K>_TZuJH2L{Ir%hfdjKDOrr-xUAa$fUbER=+=s2=NH| zG$KHp)#BrbkhJ|}Lrezii-wl8?*&6k#>YCkXZgX&d9+qUOjhCVMpEO0x^~nmX=fKh z9F!c@zz_!}L+_(VU$W)<5iy=8x@wW;LEJ=0{BGI~NDBTXBE|)OVF=h?6-L?T5i#zY zw+z9t$9mlm?Jx?0UvwYxLom3M9Mt2&cXM*sFrvnf(l>|*$yi#~5CU_5R& zGp&Z$uHt23bcQ8+L;?Y1y2hbHH1XG0uh2Lf)gM}&AV zc8CaZcl>6I7+|}dE&Mqm##{9;;)W(8r@J8zNiG5F8{*)kNB%PU2F8c^6+?*I@sh#Y z0ma7u7}1i%?;>Kd10NWo<0#-YL$t#u2;Pc120~$!d}Ue{+=BfiBG>`^&l~+B9P+-l z7>5g|Zt~*5U`!Ps7)-8;4h*J9t%uJLR;3;ojIMGV80=Q%J}}s|Dt2HXHyi2Iq+_e1 z1A}(BVY?}A*p91eR~C$~O78V1RG~JXR8?f7Jq_KVjrI{z+N(PSNAX2}+yX*nf3#HO z$4EtftW@MD2>wLDpCtIR1%Hm<&lUVdg1=bsmk9oH!CxWxD+Pb8Si$?A>-dT{8#hXm zo21Fj(&P@o-zoUJ1b?sK?-Ts}f`3Htj|%=V!9OLc`R2$o!u70hJttf*3I1ilzasdz zq&07*-W9I*gzJ6b`dGMlGxdpF@vXa0rOjv3=5uNDmEgY?{5OLCUhqE%{zt+8BAbz4 z1^zDZ4}pIQ{7c~90{sQN*$M=P0y6?j1eOXc6WC7RY69B}>>#kCz)k`?3tU}b7lCUC z>?&|gfolm|Ti`kZ*Hw^z`FENr{*l#9YUzn-g4+K;Lv-w^@`mWxQ`H+H?WqbjT&oPx zvGX}JBHFo?7wdx~VluZj8=_+elr_Y}4#*Fh43Rb}1=cPwM8_S80}RozC)qC|#w)Q_ zL%^QIzHKnq5FC4wN<*}bRKI@;rW;z)FMAsr?MY1afuCdlRY!!vfDVE) z3=xHnnM7OiB-+am9VPzqh*&7r59$ojQRXj+i1Gf-GXzJO{~tr7>N*zbLGZRAQYmcu zAqN46MAW3WR~lkLO}xSos3wjn^n>|^=(t03kRdt>+M-5krWhz>o4G9a3fiVHa6=}S+KzZyz;rWp|+(K@1WTWUoJsf z%w)Wl4HwX7C^~xW@t%YX9wY0}-tQ6u`rdcnc4!}T@$gd!yq;F!H#2y@3!ds19=}VA z_3u{mZ*JRuC1h@0vNmeQ03_>AwzhFW>q4*3&LgMuKSzuZon@BJrD&mTSxw_dJLP4o z@wzbeWs;o!>_;<;cTu2?`qx3r+`#Wz0$n}uw;gcp36H<@^2ZLH+o?W!UWwNUIBM6K z=*ll5BLg4p^pAGYd!myz5mxM3L(47FM|JW^Zvo8~h>H`9KiAYUw+_2@T08W*;@YEc zxTxm-sz|Le}NUWPjwNE6voWDJAPr+fmzBmggH6 z;VUrRM&rX0&E0yf7&>^X%9(g)OylzAZsTiPnk)PDt*mXRu4}Ey;h%l__UYe$aQ}XN z`c}4LU@NN|^Etpii@k3&rS3!0x4&lKY{ zv$hbvo`x^zLb6nwP5iE80?mn~_yb_JxZYO&x_waU^^>;!bz7O^x~;oii8oN%4bttp`dvfV?B)->A;LdY z^UL^<9(S9Jx4pC(uG?6?CLgE!q}1C{+U}&=iayenrf-C_8L8WdFNmM~=x$fyjgoe| z>ULNknyhght?>opg8reS$P|Xo5p0)mT8_K*H(tf6HFZOG_>AFk3 zS<-g4ZYy!=wl(xBg@3N*7yptjcbkltl{WJoZM1ELxn_a1sn%^e`(2Tim5w-X;N^sO zq2{&5kH#(CcctE9X`gL+oH7<(Lyc>G@81nRH=U@>YO{;;hYTM>$x)1>SL@>v+xE)1`}KD=qX7BmYEdL;YF#md6zdt->B&M2D}1 zEc3qS3amRY8N$^zG}^dQ!r=$wIao`T8tx3CQUk65uSH(s8C-k9wc?$?B9Hhw5^hn1 zBfVV+mnX$6kIId;2&X5uaU-ZjE| zt&6w7*6W4$2E*G<)$rtboojD0G+vu&Hq+n8zQDUh+T z5v6xQ_ucrr0Sur~xkK3!jo`hwRJlCRYHRFRWk84>H-A~|}#)b3}q}lbP=zU7_Ix~wF z&7&ZCP1HR@ZK-c^s=}Wm$Z?r5Z6p*#k)+cn)p#AH58W@|Z*Lgze`PzygKU2(W_wl}?;a1t)ytx;rqbrKRDI0^+Y;)Mq}TG*TOdp=-1DjPcfG{!TA94 zKE&S|@-h5JdX@j2eJgL9QI($@`Ng^x-+ZFmOW(*>9`%F1J}9}4;=K#uq;BgV@$s4B zC4S0!M+N;4&Wm{ zcGUdVSjTw-ue0#3Zg}+?6UkXa(+0c8b(hwK3v+oKPUFK^RKb?FSs3xrnp%cs3!N%Q zaTIuKi!JMDUaOz<^65B#=&dLG>uY|qK1T7fp{7}~$On2o)jr!;WNo7P;Xe~=_Pc3j}!W^C<$ z%NS9vp&UtL#C{6AZ6JqYYg;W({7SsULw_Uw(CZ`o+i8BOqx4u}CxSn|*H8HR8@`~6 zTHjRd6?7S>@p8ICdgwh~vMa(0IIOSCE!t^&IQhl;m}zk?I)-cj8) z(Q1Luz0o)2)hPjaqZi@T$G`~9{J%g(U&7bmt75nRTSiu|f)gWg1d+#jo zceEQpbbMxmzUr;p{RR9O!sCN^HlB_y$_bCJ{-_UVi~az3eAu)JD|eHwBW`aZv#{Np!Izg1eqmh|Uh$@Eps~A#a5a(7 zH$eMa2#05ym*JCvdW<##{vN_t*U@%IwcixDM+ld%tzJx@8mz*bd&L(tcFz!Pd9G>+ zy$((Wj{4pW?Oq|8`f3LIqdRc#XdHdyLi*VQ_)iF5FDswO-van=7|)+J6#SOJ|3Y~9 z3&U@!FwY0hs$MAS+YwHEf{bnGg|=N3E{C_HlLYSPR=}?p;YqBC=Wbet)xWL5-;3~c zzgzmz8@RrN;|N#n`vNzVa1FWT+HV7Z8$q~*`JCFi~;elBHF^*26eYznc02qpT=iLx%u3wssa5j>QkcLG$EQc8tG2Sg+D`Kq>99bJHx z)nkN~wP$)BrTMZRRnt~{P-WRoRo(Q(O&)i`^-@*0`ih8&!@h*et)NeqHPblIvjBLW zAlL=E^`D`r#tSUe6-T@`WcT2I;o}8pRz*%Q&Q>Q0qo8wF{DrB?x70VgiXW~00Y6iJ zl%Lb8BkFp>$AS_6j@9xyhif-M6Rm2#hf|fE{)NArRZ>=d91l6l-_7(oarh86VTBDQ z0I&b_5+4?|ssF$9U31)T6QO4k{?c0y91}sG4~+6b*hp<97i$ids9KD z_S3BP=m+jt@D5>yX&-dyindC}Bv*ABd)|T`_Q*E1F2DzAcsp%BjA0QmDy(Og(I0eC zHlqg}=JA-!0S(VY=*MNM)hp;Fe^7OaGgYD0FUVH6=JD#S6*|9A?&)agb=7!TL`|*< zALApv=m(8irIJrNXqWo`&=2fT=Ry{p-!2H?SE<;h07rh0`#$utz?1Li11i6w`s2Pv z_u>|4npAT$sSWsM1JWqh&^2V_3}2vRD0!k^>+TX8`_Nk~ZEJN~;U}NcU%H?azuICC@TG`Tc)!IVnN~}K`V`U(B(f`?i3z#iXY?zRi#n? zsQ-Pv)|Q1sv*H*YV_GwYDm=#l@r_V^i1<3dRy?B=tW+{dF6{~ahql5;`$G@U(Z2uF_82;||x76nV{#>Pah>!MC0&O45U_~n_c>Zdkvfd@*gnwnzMH2CVWhemmA7e4KM%b657l9jN^whsU>p98U+QRY zs?NgAY5Mula{>M;zogXvqejaIiepYFz|z}<58OXmqOoV_)E`Sl0T@gI?l|=sjLBXCV_hab@qAEmEgy-!FB2kK-PJx zW#F&6!t)IHtWKY2(B6{PfUD46|DpM0P8X%8=9>Drb&=ZL(YLE1`x^XJ&oZEIWUK01 z${I0>mBpjR#!1XvujTaQn4uW*_!GIR7NWiDP_Moo=P^~y*cKr$ouFT`tR3#5@|dGQB=}5jjc+w zoqS(aN7{pEr~hDw_3!LLq&E8 zeDb)KvGTnjeO)FGt>;xYVqb}GRYYfF-3Z6u&QNoZ_<9j8x1u`N)Phqm{-7^KG3BSe zM6=FYq1+otxaC#(`qn0urwKRMgQhH=rsKmDe5J7^-^RC9l^&8cl-l9z9Mz4jxVOx8 zFyVI~JiYyW%cA|PobVg5Y#t>e8C7NuCo(3e^1fn&l zt$A}(U8_24((=kJnvNW5Gfm-}>ZA?{>exa*$ z(>c*Cgd_3Us+uaq;xc*~5;J9EWVt6P$mGvGv?iE|p%(;$;F(fv4bIfu}a_={C+Ur|}VGgNKKa~pYNNed1yqwLuY?}EVLqPl^R&($MA(V`d8 zH@E0@we{w14$13f(H7%;Dc{&wZ`-jgeV-FQXS3z?)wt~P#ds!}GY9&C?9MYpX8HTT zA#HRmX(3hp+zkH3-Oa^xZkNU5TGHrkhkb{4}uv z-#aGf8+&l~)28Ei1r~@uK0+U^@o*Q58!LU3X>W;e{98xir}4iB88_e93MIL0W4?A# zE$)HAGgxsJK}-{l@gko-BK=#GYv6^|y7Ni>eG|^vyE_f`uD+>MZXdK;w z6J2!b@QD{aZ~rm+g}bCQU_3fv|EIur^Xbgqnu{WXcI3S*T1z8WDunNA;qCcA8DywW zF`x!m`HwQ%7$36&Pv>)RV`qR&+6ybvXQ1gn^KrK?mZAU6-MywZr3edHb%z6p(D^-t~yP+U>n zP2(Ezhu$xA4S)RV;HMg$_F=?N?dhJ<@529w=C__vqP+z1;`9c80`D*3{oC+HckDJN zyJba=>+rn*57LrNAz)!2h?i`M^n_lC@Rw?SYgHwFyNzB|+ew?%bQ|dN9d?2Y|MFAp z+J})p01@fN(^`%#Zucqd)qT{ySwq@&)$NRrqdP}y85+x>97S=e`i_5-kJk}7 z>l)t3$7?CuqigK;O<&GMU$sr_lfc_hWNl<*>9`6#^URk;BU`94)8p06qUnBimKfMf z)8J=w3MAuCryG$^@hf5Q()jn(ZFX_aalG<%*V^iq8MV3P)=n^+Kx4-9DMc?W&sn*! zG)t0=Ffz8*GKxGayA61{cs0xP(5UsQOK?ZDxl(aHqjQD2g4 zlUvtpU>pbQXsr5aIqrN+ZB&IJxj(v=_5*bLhV)ZYidUQhR%Kh8aZb$ZEyW;C0jpe3 zru2tQoS;@^sRzP85ICHmf}iT0W^gqISjF>jsRT7E zE|1>jckfM`w3bEWRUe+FX-cDQTGJGYFM3Inn>KHg+>oVtxKgBE_%*te;r z*xJ;#ptU8~DrqCzOkz`O>)ck8R;6$)O$*!T)sEf$qbyxbOFkX#GA6sPv(>x?j9J+J zd-^HpnBv(8SVrTotp=W+r$9Neo&sSw@;Bjs_GKpim%iv4{xr#N?=7}3Z>Lv8o-u7q zz%+4vUD|j_ljT}T+ZS*Xm^KJ>sUfgJT*IFwb+TP*a6I%~+2jYvqeF)7%_zs!#zRq# zxDt=;=;LldS-)1!wW!-386SSZX)-~6wi*Qn}SJxhi(RO$KMmhg1cAKlioY|xG zVq0bet_t?kw)VGh&YOzz4sdzKD_|YAo~if_@&*4#>p9TDMklvy8$WP)k%utR^AI>H zQx1q9zq8(Ut#^?vi~jLkyU;?<*0T)%NF)Ar0=5?aNB#UrP||w3Y&{+wA&StU2q&DB zi~WY2nH74H`myR<5I1=r$XI@L|w9H>$UZD$+zBae|i2>$`xr zeFnaQ*RbNX%+}@U8%H+ljgfZLw-pM%(!zUq{wLe=ygz}a*iRA`y#AE6R~0=dcrFbCi;MHji_Bd7iKReGS;t|ve*gQ(o4RjAj$-Gl zJb?SL?R=dQG$z0xzPvnu^<85*05?A9lCg>whvg<<%>vuI*fJe-dl~FqD!`Jtj)43f z20RpM{0IJ~Kd{34UC(_dgohtI+&xh0#Cp26N!Y1a2Xg6LXXl_ZV0K}dzb78FACPyo zqxFEjaWATD$ZH!%pg+@eZHudD9F>kln*Ge;YX%=g$#4Ao{vc{~eh44RJ_>*JP`9zF zxpuy1HTZDkTPbGW7~^>~(#XYQ@V~XJ8;k~41*a<9X%4P>Jb7XIVJtHH99gQW;FntF3=8LJE$KxZ zB3x>MvlRYp3lBV}3hknK(z#xq?Za-Ui*#LU^AdAoTgN)B|NK$lY<(9h+(j17o5R}E z=d?Jqn3pK*dIuZP){YjJdU@a-K2b!?rJGT*V#r+#+HMADL)7&z{dE_o{x9JD8HFAb;l6lGuWpa!5^*P&D)k(?) zVaPvYQ>ud(6!t|28}T0J%VYdQgpBadv=iBiS1XjALRh^Ki*2!O`+r=eAEW!|=BJlrfi@v=I`?~EUNSIfO;%PB264zV2Z zGBO5lOJTQJSg#+HUH##*Dlf{)6t@tvxJofLLw3#)x*K9Zbg9@W27 z@KG%@#+LE$VY&F2TN8X-;m2Bd^o{i3=PT?haQ%eKi{u1Jkc-HB$8WEn)d4S>u&wcgpW)@P+W7#s7vbb|w(X+^#M!!UNHMv6&y�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 literal 0 HcmV?d00001 diff --git a/build/temp.win-amd64-cpython-311/Release/build/test.cp311-win_amd64.exp b/build/temp.win-amd64-cpython-311/Release/build/test.cp311-win_amd64.exp new file mode 100644 index 0000000000000000000000000000000000000000..93db03cb275014c2133b81c64e26334049b38f68 GIT binary patch literal 740 zcmZuv&2G~`5dMn7pI z0f~3wA$SzHaf4YqZiB?g^Y`uS&Uj|T*E;?XId$MMN@7w3CRjP7&WQ!__Z75BdPpA= za*|Km;}wif4ftI-D?LQ>jWunK>WIQnafSV>jm!)S)1L3UbCp~Lu^9AOx)k`ZJW7lB-B?Bjc1& zR=3FNhUwDW=)|R3_^FI!kV#$z{-;Q}Nbv%%T3eLohkdl5Z9K!zFTjZkXFAi@#_60s zcitV1j`0nzTL|X@moK@Hw>r{kEEB_TWTY0QbfX}dLN26@xqsqJWqA-eW0MP|dDrW9 z`Js;EoEo&`XNUZw)=|b!#$@_^);nOm-kyKJCo17@b!IO12YfN;^GGG1n0*{ivEQ-=E#>}SaEjh5$ msgN?tPN_oX?`O1n-W}2&c|<;r?+`MIEwI{B9Ziz!|L_;^I+y27vc4Xwl%U|ni)W8s6c5s~m-^oBOuA_kn;>;y=6&p&nfH4ivlnmHR_n{R)ST8m zGJ3ZxrAfi))(ycessN4w${3K^Aa)xVF?hOeVYWP1sk+m5=kHVsmJmcOtvsS z>{QFNJ2l~LCGocX>igvcaGavZBkL_ac=Bj`K9YbEF)yVcsDt$Ftnbx=+BnrvG|mwD zO7oYHlSCa%wuPN7)Hp}XDBUORSnohSfOyb@9-yeR` z4N)!hj^STA)RJN24(ASy4+oCyP*dvJ?wb?@WxJz|^&oM+M&1ng)(-nBUKb(P_)p1Q W?rpt(@$BQJ5Pz!c57PIgQ2ziOC3imn literal 0 HcmV?d00001 diff --git a/helix.py b/helix.py index 8f47a78..1a9f8b5 100644 --- a/helix.py +++ b/helix.py @@ -2,15 +2,14 @@ # -*- coding: utf-8 -*- from __future__ import annotations -import tracemalloc -import atexit -# q: what is the purpose of atexit? -# a: atexit is a module that provides a simple interface to register functions to be called when a program is closing down. +#import tracemalloc +#import atexit -tracemalloc.start() -atexit.register(tracemalloc.stop) +#tracemalloc.start() +#atexit.register(tracemalloc.stop) import gc +import atexit gc.disable() # disable garbage collection for performance import src.core.base as base @@ -38,6 +37,7 @@ Transpiler, FileMode, format_file_contents, color_print as print, + framework, ) __version__: str = "0.1.0-alpha.a" @@ -339,16 +339,6 @@ def __str__(self) -> str: def __repr__(self) -> str: return self.__str__() - -# @ThreadedProcess -# def test() -> None: -# for i in range(10): -# print(i) -# sleep(1/3) - -# test() - - class ArgParser: """ Parses command-line arguments for the Helix language application. @@ -775,7 +765,7 @@ def __exit__( self.old_handler(*self.signal_received) # type: ignore -class Helix: +class Helix(framework.HelixLanguage): """ Main class for the Helix programming language interpreter and compiler. @@ -1012,6 +1002,11 @@ def cleanup(self) -> None: style="bold", border=True, ) + + gc.collect(0) + gc.collect(1) + gc.collect(2) + def compile_file( self, file: Optional[str] = None @@ -1534,23 +1529,31 @@ def __hook_import__( return helix_import - -if __name__ == "__main__": - try: - Helix.factory( - os.path.join(".helix", "config.toml"), - profile=True, - ) - #Helix.__hook_import__("syntax/test.hlx") - # from test_hlx import subtract - # subtract(5, 3) - # Helix.REPL() - finally: - if base.POOL.is_alive: - base.POOL.close() - - print("Memory Usage: ", tracemalloc.get_traced_memory()[1] / 10**6, "MB") - + def __del__(self) -> None: gc.collect(0) gc.collect(1) gc.collect(2) + +def exit_func(*args: Any) -> None: + if base.POOL.is_alive: + base.POOL.close() + + #print("Memory Usage: ", tracemalloc.get_traced_memory()[1] / 10**6, "MB") + + gc.collect(0) + gc.collect(1) + gc.collect(2) + +atexit.register(exit_func) +signal.signal(signal.SIGTERM, exit_func) + +if __name__ == "__main__": + Helix.factory( + os.path.join(".helix", "config.toml"), + profile=True, + ) + #Helix.__hook_import__("syntax/test.hlx") + # from test_hlx import subtract + # subtract(5, 3) + # Helix.REPL() + \ No newline at end of file diff --git a/out/helix.pyi b/out/helix.pyi new file mode 100644 index 0000000..8ff1571 --- /dev/null +++ b/out/helix.pyi @@ -0,0 +1,96 @@ +from _typeshed import Incomplete +from src.core.imports import Any as Any, Callable as Callable, FrameType as FrameType, Iterable as Iterable, ModuleType as ModuleType, Namespace, Optional as Optional, Processed_Line as Processed_Line, Scope, TextIOWrapper as TextIOWrapper, Token_List as Token_List, Tuple as Tuple, threading + +__version__: str +USE_CACHE: bool +bar_thread: Incomplete + +class Hashing: + def __init__(self, file_path: str, output_path: str) -> None: ... + def __int__(self) -> int: ... + @staticmethod + def compute_hash(code: str) -> bytes: ... + def create_hash_only(self) -> None: ... + @staticmethod + def get_mount(path): ... + def create_file(self, code: str) -> None: ... + def is_code_altered(self) -> bool: ... + def get_hash(self) -> bytes | None: ... + +def watch_processes() -> None: ... +def clean_docstring(docstring: str) -> str: ... + +class ThreadedProcess: + __processes_queue__: dict[int, threading.Thread] + def __new__(cls, func: Callable[..., None]): ... + __func__: Incomplete + def __init__(self, func: Callable[..., None]) -> None: ... + __pid__: Incomplete + __thread__: Incomplete + def __call__(self, *args, **kwargs) -> None: ... + @property + def processes(self) -> dict[int, threading.Thread]: ... + +class ArgParser: + def help_screen(self) -> None: ... + def version_screen(self) -> None: ... + __args__: Incomplete + def __init__(self, argv: Optional[Iterable[str]] = None) -> None: ... + @property + def args(self) -> Namespace: ... + +class HelixLanguage: + def __init__(self, *args: str, **kwargs: str) -> None: ... + @staticmethod + def make_folder(directory: str) -> None: ... + @staticmethod + def make_file(file: str) -> None: ... + @staticmethod + def generate_folder_structure(directory: str = ...): ... + @staticmethod + def install_helix(config: dict) -> None: ... + @staticmethod + def remove_blank_lines(file: str, hash: Hashing | None) -> None: ... + +class Timer: + def __init__(self) -> None: ... + def start(self, name: str) -> None: ... + def end(self, name: str) -> None: ... + def get_time(self, name: str) -> float: ... + def decorator(self, func: Callable) -> Callable: ... + +class DisabledKeyboardInterrupt: + signal_received: Incomplete + old_handler: Incomplete + def __enter__(self) -> None: ... + def handler(self, sig: int, frame: Any) -> None: ... + def __exit__(self, type: Any, value: Any, traceback: Any) -> None: ... + +class Helix: + config: Namespace + @classmethod + def interpreter(cls, code: str, globals_: dict, locals_: dict) -> str: ... + def build_path(self) -> str: ... + profile: Incomplete + import_: Incomplete + timer: Incomplete + __config_file__: Incomplete + __args__: Incomplete + __argv__: Incomplete + __format_out__: bool + __out_file__: Incomplete + __file_hash__: Incomplete + def __init__(self, conf_file: Optional[str] = None, *args: str, profile: bool = False, import_: bool = False) -> None: ... + @classmethod + def factory(cls, config_file: str, *args: str, **kwargs: Any) -> None: ... + def run(self) -> None: ... + def cleanup(self) -> None: ... + def compile_file(self, file: Optional[str] = None) -> Scope: ... + def transpile(self, file: Optional[str] = None) -> tuple[Scope, list[Processed_Line]]: ... + def generate_line_numbers(self, transpiled: list[Processed_Line]) -> str: ... + def generate_source_code(self, scope_parsed: Scope, transpiled_lines: list[Processed_Line], format_source: bool = False, is_main: bool = True, no_inject: bool = False) -> str: ... + def inject_core(self, code: Optional[str] = None, is_main: bool = True) -> str: ... + @staticmethod + def REPL() -> None: ... + @classmethod + def __hook_import__(cls, file: str, *args: str, config_file: Optional[str] = None, **kwargs: Any) -> ModuleType: ... diff --git a/requirements.txt b/requirements.txt index 5dc8781..902314f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,4 +8,5 @@ multipledispatch argparse black beartype -multimethod \ No newline at end of file +multimethod +mypy \ No newline at end of file diff --git a/src/classes/Transpiler.py b/src/classes/Transpiler.py index 08b9599..dc54233 100644 --- a/src/classes/Transpiler.py +++ b/src/classes/Transpiler.py @@ -77,10 +77,7 @@ def transpile(self, root_scope: Scope, ignore_main: bool = False): self.ignore_main = ignore_main self.root_scope.transpiler_instance = self - if base.USE_POOL: - base.POOL.map(self.__transpile, root_scope.children, chunksize=6) - else: - [self.__transpile(child) for child in root_scope.children] + [self.__transpile(child) for child in root_scope.children] self.__add_from_queue(root_scope) diff --git a/src/core/base.py b/src/core/base.py index 474e9a5..883bba9 100644 --- a/src/core/base.py +++ b/src/core/base.py @@ -9,7 +9,7 @@ Token_List, WorkerPool, Processed_Line, - + _unless, _for, _match, @@ -21,6 +21,8 @@ ) + + # All Primitive Types # int; # string; @@ -69,12 +71,20 @@ def _no_change(line: Token_List, *args) -> Processed_Line: ) + CACHE: dict[str, tuple[Token_List, ...]] = {} POOL: WorkerPool = WorkerPool(50) USE_POOL: bool = True LINE_BREAK: str = "\x03" SUB_LINE_BREAK: str = "\x04" +PUNCTUATION = r".,:?()[]{}<>+-*/=|&^%$#~" +COMMENT = r"\~\~.*" +BLOCK_COMMENT = r"\~\*\~" +INLINE_COMMENT = r"\~\*.*\*\~" +STRING = r"\".*\"" +CHAR = r"'.*'" +INDENT_CHAR = " " FAT_CHARACTER: list[str] = [ r"\=\=\=", # === @@ -311,7 +321,6 @@ def raise_as_python_exception(self, **kwargs): """Raise the corresponding Python exception with the formatted error message.""" raise self.py_exception(self.format_error(**kwargs)) - IGNORE_TYPES_MAP: tuple[str, ...] = ("Callable",) PRIMITIVES_MAP: map[str, tuple[str, str]] = map( @@ -386,108 +395,6 @@ def raise_as_python_exception(self, **kwargs): } ) - -def multi_split( - string: str, - *separators: str, - discard: Optional[Iterable[str]] = None, -) -> list[str]: - # split the string by all the separators but keep the separators - # so like "a + b" would become ["a", "+", "b"], if the separators are [" ", "+"] - # Escape special regex characters in separators and join them with '|' for regex 'or' - if not discard: - discard = [] - - regex_pattern = "|".join( - re.escape(sep) for sep in separators - ) - - # Use re.split with a capturing group to keep separators - return [ - s - for s in re.split(f"({regex_pattern})", string) - if s and s not in discard - ] - - -def replace_primitive( - type: str, operation: int = 0 -) -> ( - str -): # 0: helix ir type | python type, 1: python type, 2: helix ir type - full_type: list[str] = multi_split( - type, " ", "[", "]", ",", discard=["", " "] - ) - - # for each type in full_type, replace it with the python type | helix ir type - if isinstance(full_type, str): - return ( - PRIMITIVES_MAP[full_type][1] - if operation == 2 - else ( - PRIMITIVES_MAP[full_type][0] - if operation == 0 - else f"{PRIMITIVES_MAP[full_type][0]} | {PRIMITIVES_MAP[full_type][1]}" - ) - ) - - for i, t in enumerate(full_type): - if t in PRIMITIVES_MAP: - match operation: - case 0: - if ( - len(full_type) - i - ) > 1 and full_type[i + 1] == "[": - # get everything after the current type and keep track of the brackets, then process that again - # and then set a copy of the full_type to the processed type - # so like if the type is "list[int]" then it would become "list[hx_int|int] | hx_list[hx_int|int]" - # Process the nested type - end_index = i + 2 - brackets = 1 - while ( - end_index < len(full_type) - and brackets - ): - if full_type[end_index] == "[": - brackets += 1 - elif ( - full_type[end_index] == "]" - ): - brackets -= 1 - end_index += 1 - - nested_type = replace_primitive( - " ".join( - full_type[ - i + 2 : end_index - 1 - ] - ), - operation, - ) - python_type = f"{PRIMITIVES_MAP[t][0]}[{nested_type}]" - helix_type = f"{PRIMITIVES_MAP[t][1]}[{nested_type}]" - full_type[i:end_index] = [ - f"{python_type} | {helix_type}" - ] - else: - full_type[i] = ( - f"{PRIMITIVES_MAP[t][0]} | {PRIMITIVES_MAP[t][1]}" - ) - case 1: - full_type[i] = PRIMITIVES_MAP[t][0] - case 2: - full_type[i] = PRIMITIVES_MAP[t][0] - case 3: - # only the base type no generics - return PRIMITIVES_MAP[t][0] - case _: - raise ValueError("Invalid operation") - elif operation == 3: - return full_type[0] - - return " ".join(full_type) - - KEYWORDS: map[str, map[str, str | bool | Callable[..., Processed_Line]]] = map({ # Control Flow "if" : map({"internal_name": "IF" , "parser": _unless , "scoped": False, "body_required": True , "keyword_type": "control_flow"}), @@ -580,31 +487,14 @@ def replace_primitive( } ) -PUNCTUATION = r".,:?()[]{}<>+-*/=|&^%$#~" -COMMENT = r"\~\~.*" -BLOCK_COMMENT = r"\~\*\~" -INLINE_COMMENT = r"\~\*.*\*\~" -STRING = r"\".*\"" -CHAR = r"'.*'" -INDENT_CHAR = " " - -@file_cache -def find_keyword(internal_name: str) -> str: - return [ - keyword - for keyword in KEYWORDS.keys() - if KEYWORDS[keyword]["internal_name"] - == internal_name - ][0] - -def ASYNC(func): - def wrapper(*args, **kwargs): - Thread( - target=func, args=args, kwargs=kwargs - ).start() +from src.core.utils import ( + multi_split, + replace_primitive, + find_keyword, + ASYNC +) - return wrapper # print(highlight_code(""" @@ -626,4 +516,4 @@ def wrapper(*args, **kwargs): # } # } # """)) -# exit() \ No newline at end of file +# exit() diff --git a/src/core/framework.py b/src/core/framework.py index e69de29..3b32080 100644 --- a/src/core/framework.py +++ b/src/core/framework.py @@ -0,0 +1,169 @@ +from abc import ABC, abstractmethod +from src.core.imports import ( + Any, + Callable, + Iterable, + ModuleType, + Namespace, + Optional, + Processed_Line, + Scope, + threading +) + +class Hashing(ABC): + @abstractmethod + def __init__(self, file_path: str, output_path: str) -> None: + pass + @abstractmethod + def __int__(self) -> int: + pass + @staticmethod + @abstractmethod + def compute_hash(code: str) -> bytes: + pass + @abstractmethod + def create_hash_only(self) -> None: + pass + @staticmethod + @abstractmethod + def get_mount(path): + pass + @abstractmethod + def create_file(self, code: str) -> None: + pass + @abstractmethod + def is_code_altered(self) -> bool: + pass + @abstractmethod + def get_hash(self) -> bytes | None: + pass + +class ThreadedProcess: + __processes_queue__: dict[int, threading.Thread] + @abstractmethod + def __new__(cls, func: Callable[..., None]): + pass + @abstractmethod + def __init__(self, func: Callable[..., None]) -> None: + pass + @abstractmethod + def __call__(self, *args, **kwargs) -> None: + pass + @property + @abstractmethod + def processes(self) -> dict[int, threading.Thread]: + pass + +class ArgParser: + @abstractmethod + def help_screen(self) -> None: + pass + @abstractmethod + def version_screen(self) -> None: + pass + @abstractmethod + def __init__(self, argv: Optional[Iterable[str]] = None) -> None: + pass + @property + @abstractmethod + def args(self) -> Namespace: + pass + +class HelixLanguage: + @abstractmethod + def __init__(self, *args: str, **kwargs: str) -> None: + pass + @staticmethod + @abstractmethod + def make_folder(directory: str) -> None: + pass + @staticmethod + @abstractmethod + def make_file(file: str) -> None: + pass + @staticmethod + @abstractmethod + def generate_folder_structure(directory: str = ...): + pass + @staticmethod + @abstractmethod + def install_helix(config: dict) -> None: + pass + @staticmethod + @abstractmethod + def remove_blank_lines(file: str, hash: Hashing | None) -> None: + pass + +class Timer: + @abstractmethod + def __init__(self) -> None: + pass + @abstractmethod + def start(self, name: str) -> None: + pass + @abstractmethod + def end(self, name: str) -> None: + pass + @abstractmethod + def get_time(self, name: str) -> float: + pass + @abstractmethod + def decorator(self, func: Callable) -> Callable: + pass + +class DisabledKeyboardInterrupt: + @abstractmethod + def __enter__(self) -> None: + pass + @abstractmethod + def handler(self, sig: int, frame: Any) -> None: + pass + @abstractmethod + def __exit__(self, type: Any, value: Any, traceback: Any) -> None: + pass + +class Helix: + @classmethod + @abstractmethod + def interpreter(cls, code: str, globals_: dict, locals_: dict) -> str: + pass + @abstractmethod + def build_path(self) -> str: + pass + @abstractmethod + def __init__(self, conf_file: Optional[str] = None, *args: str, profile: bool = False, import_: bool = False) -> None: + pass + @classmethod + @abstractmethod + def factory(cls, config_file: str, *args: str, **kwargs: Any) -> None: + pass + @abstractmethod + def run(self) -> None: + pass + @abstractmethod + def cleanup(self) -> None: + pass + @abstractmethod + def compile_file(self, file: Optional[str] = None) -> Scope: + pass + @abstractmethod + def transpile(self, file: Optional[str] = None) -> tuple[Scope, list[Processed_Line]]: + pass + @abstractmethod + def generate_line_numbers(self, transpiled: list[Processed_Line]) -> str: + pass + @abstractmethod + def generate_source_code(self, scope_parsed: Scope, transpiled_lines: list[Processed_Line], format_source: bool = False, is_main: bool = True, no_inject: bool = False) -> str: + pass + @abstractmethod + def inject_core(self, code: Optional[str] = None, is_main: bool = True) -> str: + pass + @staticmethod + @abstractmethod + def REPL() -> None: + pass + @classmethod + @abstractmethod + def __hook_import__(cls, file: str, *args: str, config_file: Optional[str] = None, **kwargs: Any) -> ModuleType: + pass diff --git a/src/core/imports.py b/src/core/imports.py index d9d5ad9..9f844a8 100644 --- a/src/core/imports.py +++ b/src/core/imports.py @@ -108,3 +108,5 @@ from src.functions._match import _match from src.functions._unless import _unless from src.functions._unmarked import _unmarked + +import src.core.framework as framework \ No newline at end of file diff --git a/src/core/utils.py b/src/core/utils.py index e69de29..27dec1b 100644 --- a/src/core/utils.py +++ b/src/core/utils.py @@ -0,0 +1,145 @@ +from src.core.base import ( + Processed_Line, + Token_List, + INDENT_CHAR, + re, + Optional, + Iterable, + PRIMITIVES_MAP, + file_cache, + KEYWORDS, + Thread, +) + +def multi_split( + string: str, + *separators: str, + discard: Optional[Iterable[str]] = None, +) -> list[str]: + # split the string by all the separators but keep the separators + # so like "a + b" would become ["a", "+", "b"], if the separators are [" ", "+"] + # Escape special regex characters in separators and join them with '|' for regex 'or' + if not discard: + discard = [] + + regex_pattern = "|".join( + re.escape(sep) for sep in separators + ) + + # Use re.split with a capturing group to keep separators + return [ + s + for s in re.split(f"({regex_pattern})", string) + if s and s not in discard + ] + + +def replace_primitive( + type: str, operation: int = 0 +) -> ( + str +): # 0: helix ir type | python type, 1: python type, 2: helix ir type + full_type: list[str] = multi_split( + type, " ", "[", "]", ",", discard=["", " "] + ) + + # for each type in full_type, replace it with the python type | helix ir type + if isinstance(full_type, str): + return ( + PRIMITIVES_MAP[full_type][1] + if operation == 2 + else ( + PRIMITIVES_MAP[full_type][0] + if operation == 0 + else f"{PRIMITIVES_MAP[full_type][0]} | {PRIMITIVES_MAP[full_type][1]}" + ) + ) + + for i, t in enumerate(full_type): + if t in PRIMITIVES_MAP: + match operation: + case 0: + if ( + len(full_type) - i + ) > 1 and full_type[i + 1] == "[": + # get everything after the current type and keep track of the brackets, then process that again + # and then set a copy of the full_type to the processed type + # so like if the type is "list[int]" then it would become "list[hx_int|int] | hx_list[hx_int|int]" + # Process the nested type + end_index = i + 2 + brackets = 1 + while ( + end_index < len(full_type) + and brackets + ): + if full_type[end_index] == "[": + brackets += 1 + elif ( + full_type[end_index] == "]" + ): + brackets -= 1 + end_index += 1 + + nested_type = replace_primitive( + " ".join( + full_type[ + i + 2 : end_index - 1 + ] + ), + operation, + ) + python_type = f"{PRIMITIVES_MAP[t][0]}[{nested_type}]" + helix_type = f"{PRIMITIVES_MAP[t][1]}[{nested_type}]" + full_type[i:end_index] = [ + f"{python_type} | {helix_type}" + ] + else: + full_type[i] = ( + f"{PRIMITIVES_MAP[t][0]} | {PRIMITIVES_MAP[t][1]}" + ) + case 1: + full_type[i] = PRIMITIVES_MAP[t][0] + case 2: + full_type[i] = PRIMITIVES_MAP[t][0] + case 3: + # only the base type no generics + return PRIMITIVES_MAP[t][0] + case _: + raise ValueError("Invalid operation") + elif operation == 3: + return full_type[0] + + return " ".join(full_type) + +@file_cache +def find_keyword(internal_name: str) -> str: + return [ + keyword + for keyword in KEYWORDS.keys() + if KEYWORDS[keyword]["internal_name"] + == internal_name + ][0] + + +def ASYNC(func): + def run_thread(func, args, kwargs): + func._result = func(*args, **kwargs) + func._thread_started = False + + @wraps(func) + def wrapper(*args, **kwargs): + if not hasattr(func, "_thread_started") or not func._thread_started: + func._thread = Thread(target=run_thread, args=(func, args, kwargs)) + func._thread_started = True + func._thread.start() + return func + + def join(timeout=None): + if hasattr(func, "_thread"): + func._thread.join(timeout) + return getattr(func, "_result", None) + return None + + func.join = join + wrapper.join = join + return wrapper diff --git a/syntax/test.hlx b/syntax/test.hlx index 9b76136..bbb1289 100644 --- a/syntax/test.hlx +++ b/syntax/test.hlx @@ -89,8 +89,10 @@ fn main(argv: list) { print(add.join()); do_something(); + for (var i: int = 0; i < 10; i++) { + printf("doing something else eeeee: %d", i); + } do_something.join(); - print("done"); return 0; } diff --git a/test.py b/test.py deleted file mode 100644 index afacb01..0000000 --- a/test.py +++ /dev/null @@ -1,10 +0,0 @@ -from helix import HelixProcess -helix_import = HelixProcess.__hook_import__("syntax/test.hlx") - - - -a: list[int] = [1, 2, 3, 4, 5] -b: list[str] = ["a", "b", "c", "d", "e"] - - -print(helix_import.is_typeof(b, list[str])) \ No newline at end of file diff --git a/tests.py b/tests.py new file mode 100644 index 0000000..29b92d6 --- /dev/null +++ b/tests.py @@ -0,0 +1 @@ +import helix \ No newline at end of file