From 0a10b20dde9d1b16fd1b37e3ea64961b56a3e92f Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Mon, 3 Aug 2026 02:00:49 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=BA=86=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=8C=E4=BD=BF=20TPV=20=E8=83=BD=E5=A4=9F=E6=AD=A3=E5=B8=B8?= =?UTF-8?q?=E7=BC=96=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Notify.py | 53 + TODO | 21 +- TransPyV/temp/_phase1_manifest.json | 2 +- TransPyV/temp/_sha1_map.txt | 29 +- TransPyV/temp/_shared_sym.json | Bin 1977081 -> 1984300 bytes _RemoveDebug.py | 84 + _console.py | 2 + includes/llvmlite/__builder.vp | 2 +- includes/memhub.vp | 11 +- includes/viperlib.vp | 2753 +++++++++++++------------- lib/core/ConstEvaluator.py | 22 +- lib/core/Handles/HandlesAssign.py | 29 +- lib/core/Handles/HandlesAugAssign.py | 24 +- lib/core/Handles/HandlesBase.py | 10 + lib/core/Handles/HandlesExpr.py | 996 +++++----- lib/core/Handles/HandlesExprAsm.py | 12 +- lib/core/Handles/HandlesExprCall.py | 9 + lib/core/Handles/HandlesIf.py | 10 + lib/core/Handles/HandlesImports.py | 20 +- lib/core/Handles/HandlesWhile.py | 105 +- lib/core/LLVMCG/BaseGen.py | 30 +- run_err.txt | 0 run_out.txt | 478 +++++ run_output.txt | 1 + 24 files changed, 2718 insertions(+), 1985 deletions(-) create mode 100644 Notify.py create mode 100644 _RemoveDebug.py create mode 100644 run_err.txt create mode 100644 run_out.txt create mode 100644 run_output.txt diff --git a/Notify.py b/Notify.py new file mode 100644 index 0000000..de1f2e4 --- /dev/null +++ b/Notify.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +"""非阻塞式 Windows Toast 通知工具。 + +用法: + python Notify.py "标题(任务事项内容)" ["正文(可选)"] + +替代旧的阻塞式 `msg *` 弹窗,通知右下角弹出后自动消失,无需手动点击。 +""" + +import subprocess +import sys + + +def SendToast(Title: str, Body: str = ""): + """发送一条非阻塞式 Windows Toast 通知(Balloon Tip)。 + + 参数: + Title: 通知标题,即"本次完成的任务事项内容",用于识别是谁完成了什么任务。 + Body: 通知正文,可省略。 + """ + # 转义 PowerShell 单引号,防止任务内容中的特殊字符破坏脚本 + # BalloonTipText 不能为空,Body 省略时用默认正文 + TitleEsc = Title.replace("'", "''") + BodyEsc = (Body if Body else "任务完成").replace("'", "''") + PsScript = ( + "Add-Type -AssemblyName System.Windows.Forms; " + "Add-Type -AssemblyName System.Drawing; " + "$n = New-Object System.Windows.Forms.NotifyIcon; " + "$n.Icon = [System.Drawing.SystemIcons]::Information; " + "$n.BalloonTipIcon = 'Info'; " + "$n.BalloonTipTitle = '{0}'; " + "$n.BalloonTipText = '{1}'; " + "$n.Visible = $true; " + "$n.ShowBalloonTip(5000); " + "Start-Sleep -Milliseconds 6000; " + "$n.Dispose()" + ).format(TitleEsc, BodyEsc) + try: + subprocess.run( + ["powershell", "-NoProfile", "-WindowStyle", "Hidden", "-Command", PsScript], + check=True, + timeout=15, + ) + except Exception as Ex: + sys.stderr.write("Notify failed: %s\n" % Ex) + sys.exit(1) + + +if __name__ == "__main__": + if len(sys.argv) < 2: + sys.stderr.write("Usage: python Notify.py [Body]\n") + sys.exit(2) + SendToast(sys.argv[1], sys.argv[2] if len(sys.argv) > 2 else "") diff --git a/TODO b/TODO index 42ed134..f038a5c 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,5 @@ 更复杂的 泛型 -函数装饰器 +复杂原始(仿Python)函数装饰器 # main 收集(和 导入模块的自动执行) 元类型 # @p.set @@ -7,24 +7,26 @@ 崩溃/返回作用域 回调 # 假鸭子 # f-string 自动 snprintf -__doc__ -自动索引 -testcheck默认中文 +# __doc__(后续需完善) +# 自动索引 +# testcheck默认中文 vdebug 工具和 vsdt 工具 多态 ops 允许单个函数拥有装饰器(可修改,走函数指针) 协程关键字支持 with 出入多态 -哈希表 +# 哈希表 内联快速迭代器 出栈调用函数 -构造函数隐式参数 +# 构造函数隐式参数 小数组直接栈上创建+ i in [xxx] -字符串索引 +# 字符串索引 -单 @t.Object +单函数 @t.CVTable import 自动执行代码 限制全局 import 符号到局部(其他文件import而本文件没import,但是仍然生效不报错) +生成器表达式 +await 表达式(平台无关协程支持) # 统一 mpool 和 mbuddy 接口 MCViper after 自举 @@ -35,4 +37,5 @@ init_set 构造 不在乎编译器时间的大小优化(无关符号剔除) 给 linkedlist 库改成 node 库,或者拆分 linkedlist 库 -TPV 的 typedef 名是硬编码的,后期尝试修正 \ No newline at end of file +TPV 的 typedef 名是硬编码的,后期尝试修正 +TPV 再次支持泛型能力检查和字节序 \ No newline at end of file diff --git a/TransPyV/temp/_phase1_manifest.json b/TransPyV/temp/_phase1_manifest.json index 9460ed5..b74797d 100644 --- a/TransPyV/temp/_phase1_manifest.json +++ b/TransPyV/temp/_phase1_manifest.json @@ -1 +1 @@ -{"D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\Projectrans\\Config.vp": {"sha1": "c0042adc0b7ec5df", "mtime": 1785332415.2264168, "size": 14060}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\Projectrans\\Utils.vp": {"sha1": "4650533467115342", "mtime": 1785332415.2054548, "size": 4900}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\StubGen\\Converter.vp": {"sha1": "edfb76eb5b11cb51", "mtime": 1785470008.8908188, "size": 36399}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\StubGen\\VpiReader.vp": {"sha1": "60b1f1f83634820e", "mtime": 1785470742.1546993, "size": 12673}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\__init__.vp": {"sha1": "c2a4277744568003", "mtime": 1785424554.7031634, "size": 820}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\BuildPipeline.vp": {"sha1": "0029b86ca4ba3c8a", "mtime": 1785469972.0876107, "size": 25400}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesAnnAssign.vp": {"sha1": "b7705a803012e701", "mtime": 1785478290.7112954, "size": 25035}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesAssign.vp": {"sha1": "0fd87ff8da897c9b", "mtime": 1785478447.198817, "size": 25107}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesAugAssign.vp": {"sha1": "0d60272ffec7421e", "mtime": 1785478333.5054357, "size": 14418}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesBase.vp": {"sha1": "63a3d17e96a083ac", "mtime": 1785332415.2080498, "size": 8740}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesBody.vp": {"sha1": "8a88001814aa6e7b", "mtime": 1785485408.946777, "size": 10469}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesClassDef.vp": {"sha1": "07093bc887a35256", "mtime": 1785478535.6808052, "size": 145619}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesEnum.vp": {"sha1": "f05b14a2ad5767a7", "mtime": 1784741624.7278736, "size": 8520}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesExpr.vp": {"sha1": "ebe9603dbffb6a35", "mtime": 1785478439.6070976, "size": 155333}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesExprCall.vp": {"sha1": "b70057095779b5be", "mtime": 1785482646.5378678, "size": 281321}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesExprOps.vp": {"sha1": "ede39cea216a347e", "mtime": 1785478524.0725746, "size": 13507}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesFor.vp": {"sha1": "456fb516ba3c5002", "mtime": 1785332415.1896677, "size": 17319}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesFunctions.vp": {"sha1": "f33eba0679c883b5", "mtime": 1785482062.1941507, "size": 48438}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesIf.vp": {"sha1": "f4cdbca2f8802c12", "mtime": 1785390159.3673935, "size": 5626}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesImports.vp": {"sha1": "c34e22cc668c6a6e", "mtime": 1785424554.7057025, "size": 25292}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesMain.vp": {"sha1": "4a7b57e6bd18f65e", "mtime": 1785332415.1935978, "size": 21362}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesNonlocal.vp": {"sha1": "3e7835a9deb60427", "mtime": 1785485362.3779018, "size": 7459}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesReturn.vp": {"sha1": "9224f6a9c894a6cf", "mtime": 1785478537.512802, "size": 6346}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesStruct.vp": {"sha1": "f09b2f4a0f9d053e", "mtime": 1785426809.706652, "size": 47907}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesTranslator.vp": {"sha1": "decd2fdd82387662", "mtime": 1785481813.1345608, "size": 23666}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesType.vp": {"sha1": "735fcd4c340edd2d", "mtime": 1785470195.0236213, "size": 79666}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesVar.vp": {"sha1": "ea374464a0b93230", "mtime": 1785474869.3558953, "size": 16575}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesWhile.vp": {"sha1": "8dc65d4c71e2936a", "mtime": 1785390170.5239043, "size": 5202}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\IncludesScanner.vp": {"sha1": "55be14b41dd7ca15", "mtime": 1785424554.7031634, "size": 13067}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Phase1.vp": {"sha1": "8a526c65749808c5", "mtime": 1785470618.1566038, "size": 51263}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Phase2.vp": {"sha1": "f34071b7cf6c8158", "mtime": 1785469983.5727682, "size": 49494}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\StubMerger.vp": {"sha1": "0f9622f83dd1f680", "mtime": 1785470514.574895, "size": 99549}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\VLogger.vp": {"sha1": "bdf5730851fb95f2", "mtime": 1785332415.2542837, "size": 10068}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\main.vp": {"sha1": "f30a3b2d5f6bf092", "mtime": 1785424554.7082667, "size": 27278}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\_list.vp": {"sha1": "7cadfe07e983fd90", "mtime": 1785338614.5410473, "size": 3238}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\argparse.vp": {"sha1": "b370d93b74bf55cc", "mtime": 1785347242.759819, "size": 18275}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\ast\\__init__.vp": {"sha1": "f3444ec56937284f", "mtime": 1785332415.2553575, "size": 3421}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\ast\\astaux.vp": {"sha1": "4337fb260448bbe2", "mtime": 1784006094.7981195, "size": 11489}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\ast\\base.vp": {"sha1": "22bc0df83b3f0e62", "mtime": 1785332415.1850114, "size": 14992}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\ast\\exprs.vp": {"sha1": "b543bc1dfb592119", "mtime": 1785332415.2436252, "size": 40886}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\ast\\lexer.vp": {"sha1": "e217def267d3d4a8", "mtime": 1785332415.2310088, "size": 24109}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\ast\\match.vp": {"sha1": "4dd6b3f1427d1cc5", "mtime": 1782961799.8492737, "size": 12309}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\ast\\parser.vp": {"sha1": "fde6db0747bdd959", "mtime": 1785348036.106818, "size": 87525}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\ast\\stmts.vp": {"sha1": "657e182b27c2a022", "mtime": 1783929993.759902, "size": 37926}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\ast\\tokens.vp": {"sha1": "b547ac4f380bddb6", "mtime": 1783165480.469121, "size": 13722}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\atom.vp": {"sha1": "aa246c6e6aa30484", "mtime": 1785389628.701967, "size": 1198}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\hashlib\\__init__.vp": {"sha1": "96837bcc64032444", "mtime": 1777902641.540433, "size": 186}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\hashlib\\__md5.vp": {"sha1": "19f8024d10c828e8", "mtime": 1784356818.7075372, "size": 5847}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\hashlib\\__sha1.vp": {"sha1": "0df65b8ed15664b0", "mtime": 1784356827.656474, "size": 4516}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\hashlib\\__sha256.vp": {"sha1": "c9d54a4158f7f5a8", "mtime": 1782266203.9352357, "size": 5332}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\hashlib\\__sha512.vp": {"sha1": "6ff26590374ae6fc", "mtime": 1782266223.3380039, "size": 7162}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\hashtable.vp": {"sha1": "2b77d783c41d21d1", "mtime": 1785424554.7031634, "size": 9719}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\json\\__init__.vp": {"sha1": "6ddf430432a0e373", "mtime": 1785424554.7204792, "size": 7707}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\json\\__parser.vp": {"sha1": "240a9a4157959a9f", "mtime": 1782826918.100951, "size": 7517}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\json\\__writer.vp": {"sha1": "20cd49775c100a38", "mtime": 1782826901.8906734, "size": 3784}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\linkedlist.vp": {"sha1": "a5e9a83e9db303ad", "mtime": 1785337078.812168, "size": 17137}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\llvmlite\\__init__.vp": {"sha1": "33d64eeb99369a85", "mtime": 1785480244.1533804, "size": 17045}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\llvmlite\\__builder.vp": {"sha1": "e4eb57e8026bccc7", "mtime": 1785480214.1090708, "size": 52230}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\llvmlite\\__function.vp": {"sha1": "874bac141c97bae9", "mtime": 1785342172.222551, "size": 30049}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\llvmlite\\__module.vp": {"sha1": "692919c5a194ac8d", "mtime": 1785332415.2502255, "size": 23144}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\llvmlite\\__types.vp": {"sha1": "295b7ed2c244f309", "mtime": 1785486521.0491738, "size": 20633}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\llvmlite\\__values.vp": {"sha1": "f9e36e2cd6fa659f", "mtime": 1784566611.8301415, "size": 6739}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\llvmlite\\__verify.vp": {"sha1": "6b3bc463fd044545", "mtime": 1784566611.82952, "size": 14751}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\memhub.vp": {"sha1": "ca40915f11b8b6ad", "mtime": 1785336321.3175714, "size": 21931}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\platmacro.vp": {"sha1": "b57252077e6b596b", "mtime": 1785332415.2187803, "size": 1266}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\posix.vp": {"sha1": "28de517e3820658a", "mtime": 1785335629.2014928, "size": 10586}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\stdarg.vp": {"sha1": "71e0a3ffcb3ebfad", "mtime": 1781258888.113146, "size": 277}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\stdint.vp": {"sha1": "f5522571bcce7bcb", "mtime": 1782383975.8824987, "size": 4356}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\stdio.vp": {"sha1": "285b6aa29a34754d", "mtime": 1785332415.1829746, "size": 561}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\stdlib.vp": {"sha1": "3aa6057398be5673", "mtime": 1785319487.0321114, "size": 374}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\string.vp": {"sha1": "ffaf70367668b227", "mtime": 1785424554.7179716, "size": 11048}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\subprocess.vp": {"sha1": "a335eb99f2e34479", "mtime": 1785319401.2041914, "size": 7841}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\sys.vp": {"sha1": "0c67644125bea0fd", "mtime": 1785325556.7317626, "size": 5606}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\viperio.vp": {"sha1": "c9f4be41ca1cc2b4", "mtime": 1782812279.506002, "size": 1556}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\viperlib.vp": {"sha1": "3ed8c578036234a7", "mtime": 1785439636.6696486, "size": 57646}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\w32\\fileio.vp": {"sha1": "72dbbb563aa943b0", "mtime": 1785332415.1891341, "size": 13751}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\w32\\win32base.vp": {"sha1": "fc980acec33d69a7", "mtime": 1785332415.2228394, "size": 2653}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\w32\\win32console.vp": {"sha1": "bbdf3bbd4c3bc28c", "mtime": 1781200703.5338137, "size": 5604}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\w32\\win32file.vp": {"sha1": "f6b51804a0ba8ff0", "mtime": 1782531158.744144, "size": 8424}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\w32\\win32process.vp": {"sha1": "067c78e9f121dce3", "mtime": 1781200703.5409546, "size": 4802}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\w32\\win32sync.vp": {"sha1": "06f53cc594b4ac6c", "mtime": 1782297500.2581685, "size": 4726}} \ No newline at end of file +{"D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\Projectrans\\Config.vp": {"sha1": "c0042adc0b7ec5df", "mtime": 1785332415.2264168, "size": 14060}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\Projectrans\\Utils.vp": {"sha1": "4650533467115342", "mtime": 1785332415.2054548, "size": 4900}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\StubGen\\Converter.vp": {"sha1": "edfb76eb5b11cb51", "mtime": 1785470008.8908188, "size": 36399}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\StubGen\\VpiReader.vp": {"sha1": "3395dd5ebf7032b7", "mtime": 1785688467.8441546, "size": 21045}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\__init__.vp": {"sha1": "c2a4277744568003", "mtime": 1785424554.7031634, "size": 820}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\BuildPipeline.vp": {"sha1": "0029b86ca4ba3c8a", "mtime": 1785469972.0876107, "size": 25400}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesAnnAssign.vp": {"sha1": "b7705a803012e701", "mtime": 1785478290.7112954, "size": 25035}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesAssign.vp": {"sha1": "4614c82057c20ce0", "mtime": 1785612002.0288458, "size": 26204}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesAugAssign.vp": {"sha1": "0d60272ffec7421e", "mtime": 1785478333.5054357, "size": 14418}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesBase.vp": {"sha1": "63a3d17e96a083ac", "mtime": 1785332415.2080498, "size": 8740}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesBody.vp": {"sha1": "144543e5c3a8e884", "mtime": 1785500799.3788817, "size": 10543}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesClassDef.vp": {"sha1": "22b233500a91b82a", "mtime": 1785688461.7589297, "size": 147577}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesEnum.vp": {"sha1": "d8379d695f0ce7ea", "mtime": 1785598131.284988, "size": 8533}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesExpr.vp": {"sha1": "ebe9603dbffb6a35", "mtime": 1785478439.6070976, "size": 155333}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesExprCall.vp": {"sha1": "1d86dddccc01909b", "mtime": 1785688462.1500714, "size": 296707}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesExprOps.vp": {"sha1": "ede39cea216a347e", "mtime": 1785478524.0725746, "size": 13507}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesFor.vp": {"sha1": "456fb516ba3c5002", "mtime": 1785332415.1896677, "size": 17319}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesFunctions.vp": {"sha1": "f33eba0679c883b5", "mtime": 1785580039.9426627, "size": 49481}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesIf.vp": {"sha1": "f4cdbca2f8802c12", "mtime": 1785390159.3673935, "size": 5626}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesImports.vp": {"sha1": "c34e22cc668c6a6e", "mtime": 1785424554.7057025, "size": 25292}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesMain.vp": {"sha1": "4a7b57e6bd18f65e", "mtime": 1785332415.1935978, "size": 21362}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesMatch.vp": {"sha1": "4eb645a9b00ea530", "mtime": 1785688462.3238158, "size": 39328}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesNonlocal.vp": {"sha1": "3e7835a9deb60427", "mtime": 1785485362.3779018, "size": 7459}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesReturn.vp": {"sha1": "9224f6a9c894a6cf", "mtime": 1785478537.512802, "size": 6346}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesStruct.vp": {"sha1": "d539c830f47d8334", "mtime": 1785688462.3561263, "size": 48050}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesTranslator.vp": {"sha1": "d064df0bb07fe1ff", "mtime": 1785688462.4070482, "size": 24182}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesType.vp": {"sha1": "6a25d9b413498b72", "mtime": 1785608629.9467041, "size": 80761}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesVar.vp": {"sha1": "ea374464a0b93230", "mtime": 1785474869.3558953, "size": 16575}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Handles\\HandlesWhile.vp": {"sha1": "8dc65d4c71e2936a", "mtime": 1785390170.5239043, "size": 5202}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\IncludesScanner.vp": {"sha1": "55be14b41dd7ca15", "mtime": 1785424554.7031634, "size": 13067}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Phase1.vp": {"sha1": "8a526c65749808c5", "mtime": 1785470618.1566038, "size": 51263}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\Phase2.vp": {"sha1": "f34071b7cf6c8158", "mtime": 1785469983.5727682, "size": 49494}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\StubMerger.vp": {"sha1": "0bae3da2213d51e9", "mtime": 1785600884.7381954, "size": 104586}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\lib\\core\\VLogger.vp": {"sha1": "bdf5730851fb95f2", "mtime": 1785332415.2542837, "size": 10068}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\TransPyV\\App\\main.vp": {"sha1": "a6c58174a4b03877", "mtime": 1785612916.0578, "size": 28757}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\_list.vp": {"sha1": "7cadfe07e983fd90", "mtime": 1785338614.5410473, "size": 3238}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\argparse.vp": {"sha1": "b370d93b74bf55cc", "mtime": 1785347242.759819, "size": 18275}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\ast\\__init__.vp": {"sha1": "f3444ec56937284f", "mtime": 1785332415.2553575, "size": 3421}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\ast\\astaux.vp": {"sha1": "4337fb260448bbe2", "mtime": 1784006094.7981195, "size": 11489}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\ast\\base.vp": {"sha1": "22bc0df83b3f0e62", "mtime": 1785332415.1850114, "size": 14992}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\ast\\exprs.vp": {"sha1": "b543bc1dfb592119", "mtime": 1785332415.2436252, "size": 40886}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\ast\\lexer.vp": {"sha1": "e217def267d3d4a8", "mtime": 1785332415.2310088, "size": 24109}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\ast\\match.vp": {"sha1": "4dd6b3f1427d1cc5", "mtime": 1782961799.8492737, "size": 12309}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\ast\\parser.vp": {"sha1": "fde6db0747bdd959", "mtime": 1785348036.106818, "size": 87525}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\ast\\stmts.vp": {"sha1": "657e182b27c2a022", "mtime": 1783929993.759902, "size": 37926}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\ast\\tokens.vp": {"sha1": "b547ac4f380bddb6", "mtime": 1783165480.469121, "size": 13722}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\atom.vp": {"sha1": "aa246c6e6aa30484", "mtime": 1785389628.701967, "size": 1198}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\hashlib\\__init__.vp": {"sha1": "96837bcc64032444", "mtime": 1777902641.540433, "size": 186}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\hashlib\\__md5.vp": {"sha1": "19f8024d10c828e8", "mtime": 1784356818.7075372, "size": 5847}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\hashlib\\__sha1.vp": {"sha1": "0df65b8ed15664b0", "mtime": 1784356827.656474, "size": 4516}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\hashlib\\__sha256.vp": {"sha1": "c9d54a4158f7f5a8", "mtime": 1782266203.9352357, "size": 5332}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\hashlib\\__sha512.vp": {"sha1": "6ff26590374ae6fc", "mtime": 1782266223.3380039, "size": 7162}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\hashtable.vp": {"sha1": "2b77d783c41d21d1", "mtime": 1785424554.7031634, "size": 9719}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\json\\__init__.vp": {"sha1": "6ddf430432a0e373", "mtime": 1785424554.7204792, "size": 7707}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\json\\__parser.vp": {"sha1": "240a9a4157959a9f", "mtime": 1782826918.100951, "size": 7517}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\json\\__writer.vp": {"sha1": "20cd49775c100a38", "mtime": 1782826901.8906734, "size": 3784}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\linkedlist.vp": {"sha1": "a5e9a83e9db303ad", "mtime": 1785337078.812168, "size": 17137}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\llvmlite\\__init__.vp": {"sha1": "33d64eeb99369a85", "mtime": 1785480244.1533804, "size": 17045}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\llvmlite\\__builder.vp": {"sha1": "a7748ef067f79205", "mtime": 1785688461.307784, "size": 52267}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\llvmlite\\__function.vp": {"sha1": "874bac141c97bae9", "mtime": 1785342172.222551, "size": 30049}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\llvmlite\\__module.vp": {"sha1": "692919c5a194ac8d", "mtime": 1785332415.2502255, "size": 23144}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\llvmlite\\__types.vp": {"sha1": "295b7ed2c244f309", "mtime": 1785486521.0491738, "size": 20633}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\llvmlite\\__values.vp": {"sha1": "f9e36e2cd6fa659f", "mtime": 1784566611.8301415, "size": 6739}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\llvmlite\\__verify.vp": {"sha1": "6b3bc463fd044545", "mtime": 1784566611.82952, "size": 14751}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\memhub.vp": {"sha1": "c2d8b39bbdb8380a", "mtime": 1785684738.5654402, "size": 22256}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\platmacro.vp": {"sha1": "b57252077e6b596b", "mtime": 1785332415.2187803, "size": 1266}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\posix.vp": {"sha1": "28de517e3820658a", "mtime": 1785335629.2014928, "size": 10586}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\stdarg.vp": {"sha1": "71e0a3ffcb3ebfad", "mtime": 1781258888.113146, "size": 277}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\stdint.vp": {"sha1": "f5522571bcce7bcb", "mtime": 1785563642.3805652, "size": 4356}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\stdio.vp": {"sha1": "285b6aa29a34754d", "mtime": 1785332415.1829746, "size": 561}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\stdlib.vp": {"sha1": "3aa6057398be5673", "mtime": 1785319487.0321114, "size": 374}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\string.vp": {"sha1": "ffaf70367668b227", "mtime": 1785671630.828129, "size": 11048}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\subprocess.vp": {"sha1": "a335eb99f2e34479", "mtime": 1785319401.2041914, "size": 7841}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\sys.vp": {"sha1": "0c67644125bea0fd", "mtime": 1785325556.7317626, "size": 5606}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\viperio.vp": {"sha1": "c9f4be41ca1cc2b4", "mtime": 1782812279.506002, "size": 1556}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\viperlib.vp": {"sha1": "f6ab8989f3545e83", "mtime": 1785568198.234555, "size": 59045}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\w32\\fileio.vp": {"sha1": "72dbbb563aa943b0", "mtime": 1785332415.1891341, "size": 13751}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\w32\\win32base.vp": {"sha1": "fc980acec33d69a7", "mtime": 1785332415.2228394, "size": 2653}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\w32\\win32console.vp": {"sha1": "bbdf3bbd4c3bc28c", "mtime": 1781200703.5338137, "size": 5604}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\w32\\win32file.vp": {"sha1": "f6b51804a0ba8ff0", "mtime": 1782531158.744144, "size": 8424}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\w32\\win32process.vp": {"sha1": "067c78e9f121dce3", "mtime": 1781200703.5409546, "size": 4802}, "D:\\Users\\TermiNexus\\Desktop\\TransPyC\\includes\\w32\\win32sync.vp": {"sha1": "06f53cc594b4ac6c", "mtime": 1782297500.2581685, "size": 4726}} \ No newline at end of file diff --git a/TransPyV/temp/_sha1_map.txt b/TransPyV/temp/_sha1_map.txt index 972d4dc..f44dcbc 100644 --- a/TransPyV/temp/_sha1_map.txt +++ b/TransPyV/temp/_sha1_map.txt @@ -1,79 +1,80 @@ 0029b86ca4ba3c8a:lib/core/BuildPipeline.vp 067c78e9f121dce3:includes/w32\win32process.vp 06f53cc594b4ac6c:includes/w32\win32sync.vp -07093bc887a35256:lib/core/Handles/HandlesClassDef.vp +0bae3da2213d51e9:lib/core/StubMerger.vp 0c67644125bea0fd:includes/sys.vp 0d60272ffec7421e:lib/core/Handles/HandlesAugAssign.vp 0df65b8ed15664b0:includes/hashlib\__sha1.vp -0f9622f83dd1f680:lib/core/StubMerger.vp -0fd87ff8da897c9b:lib/core/Handles/HandlesAssign.vp +144543e5c3a8e884:lib/core/Handles/HandlesBody.vp 19f8024d10c828e8:includes/hashlib\__md5.vp +1d86dddccc01909b:lib/core/Handles/HandlesExprCall.vp 20cd49775c100a38:includes/json\__writer.vp +22b233500a91b82a:lib/core/Handles/HandlesClassDef.vp 22bc0df83b3f0e62:includes/ast\base.vp 240a9a4157959a9f:includes/json\__parser.vp 285b6aa29a34754d:includes/stdio.vp 28de517e3820658a:includes/posix.vp 295b7ed2c244f309:includes/llvmlite\__types.vp 2b77d783c41d21d1:includes/hashtable.vp +3395dd5ebf7032b7:lib/StubGen/VpiReader.vp 33d64eeb99369a85:includes/llvmlite\__init__.vp 3aa6057398be5673:includes/stdlib.vp 3e7835a9deb60427:lib/core/Handles/HandlesNonlocal.vp -3ed8c578036234a7:includes/viperlib.vp 4337fb260448bbe2:includes/ast\astaux.vp 456fb516ba3c5002:lib/core/Handles/HandlesFor.vp +4614c82057c20ce0:lib/core/Handles/HandlesAssign.vp 4650533467115342:lib/Projectrans/Utils.vp 4a7b57e6bd18f65e:lib/core/Handles/HandlesMain.vp 4dd6b3f1427d1cc5:includes/ast\match.vp +4eb645a9b00ea530:lib/core/Handles/HandlesMatch.vp 55be14b41dd7ca15:lib/core/IncludesScanner.vp -60b1f1f83634820e:lib/StubGen/VpiReader.vp 63a3d17e96a083ac:lib/core/Handles/HandlesBase.vp 657e182b27c2a022:includes/ast\stmts.vp 692919c5a194ac8d:includes/llvmlite\__module.vp +6a25d9b413498b72:lib/core/Handles/HandlesType.vp 6b3bc463fd044545:includes/llvmlite\__verify.vp 6ddf430432a0e373:includes/json\__init__.vp 6ff26590374ae6fc:includes/hashlib\__sha512.vp 71e0a3ffcb3ebfad:includes/stdarg.vp 72dbbb563aa943b0:includes/w32\fileio.vp -735fcd4c340edd2d:lib/core/Handles/HandlesType.vp 7cadfe07e983fd90:includes/_list.vp 874bac141c97bae9:includes/llvmlite\__function.vp 8a526c65749808c5:lib/core/Phase1.vp -8a88001814aa6e7b:lib/core/Handles/HandlesBody.vp 8dc65d4c71e2936a:lib/core/Handles/HandlesWhile.vp 9224f6a9c894a6cf:lib/core/Handles/HandlesReturn.vp 96837bcc64032444:includes/hashlib\__init__.vp a335eb99f2e34479:includes/subprocess.vp a5e9a83e9db303ad:includes/linkedlist.vp +a6c58174a4b03877:main.vp +a7748ef067f79205:includes/llvmlite\__builder.vp aa246c6e6aa30484:includes/atom.vp b370d93b74bf55cc:includes/argparse.vp b543bc1dfb592119:includes/ast\exprs.vp b547ac4f380bddb6:includes/ast\tokens.vp b57252077e6b596b:includes/platmacro.vp -b70057095779b5be:lib/core/Handles/HandlesExprCall.vp b7705a803012e701:lib/core/Handles/HandlesAnnAssign.vp bbdf3bbd4c3bc28c:includes/w32\win32console.vp bdf5730851fb95f2:lib/core/VLogger.vp c0042adc0b7ec5df:lib/Projectrans/Config.vp c2a4277744568003:lib/__init__.vp +c2d8b39bbdb8380a:includes/memhub.vp c34e22cc668c6a6e:lib/core/Handles/HandlesImports.vp c9d54a4158f7f5a8:includes/hashlib\__sha256.vp c9f4be41ca1cc2b4:includes/viperio.vp -ca40915f11b8b6ad:includes/memhub.vp -decd2fdd82387662:lib/core/Handles/HandlesTranslator.vp +d064df0bb07fe1ff:lib/core/Handles/HandlesTranslator.vp +d539c830f47d8334:lib/core/Handles/HandlesStruct.vp +d8379d695f0ce7ea:lib/core/Handles/HandlesEnum.vp e217def267d3d4a8:includes/ast\lexer.vp -e4eb57e8026bccc7:includes/llvmlite\__builder.vp ea374464a0b93230:lib/core/Handles/HandlesVar.vp ebe9603dbffb6a35:lib/core/Handles/HandlesExpr.vp ede39cea216a347e:lib/core/Handles/HandlesExprOps.vp edfb76eb5b11cb51:lib/StubGen/Converter.vp -f05b14a2ad5767a7:lib/core/Handles/HandlesEnum.vp -f09b2f4a0f9d053e:lib/core/Handles/HandlesStruct.vp -f30a3b2d5f6bf092:main.vp f33eba0679c883b5:lib/core/Handles/HandlesFunctions.vp f34071b7cf6c8158:lib/core/Phase2.vp f3444ec56937284f:includes/ast\__init__.vp f4cdbca2f8802c12:lib/core/Handles/HandlesIf.vp f5522571bcce7bcb:includes/stdint.vp +f6ab8989f3545e83:includes/viperlib.vp f6b51804a0ba8ff0:includes/w32\win32file.vp f9e36e2cd6fa659f:includes/llvmlite\__values.vp fc980acec33d69a7:includes/w32\win32base.vp diff --git a/TransPyV/temp/_shared_sym.json b/TransPyV/temp/_shared_sym.json index b25d260355a74584eb3a6fe9c0960a0630011fd6..8c81d8fbbde1dd26379936ca43039eb933f588fe 100644 GIT binary patch delta 149131 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℞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%0AgAtx3K1hEJMoTWNG_yd@2! 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 E5AU8k^Z)<= delta 148385 zcmZ@>2YeL8_jfmKFW2vK7ZN%sh_r+f2vQP}UXsvzdOOlcLN5s*RZ2q218G6PE(B2* z3lcyPMIop^6%`4hh)M|-5JmXEd9&pL{QZ3Vka_R>%Dj2=W_EXW@0E3PZ~bph^@L?Y zQ`pfnpoc9vv0GSVc=xpM@T8te5s4}LtCk(}frO#KzWY6^E{j6={_$&?8Nl|P+jsxm ziZcO_a8vXxdvZtm{)1ar3sAeuhqqqaz7AVWd|B&4S#_FkS^1ufva)9vmzC@Zfs!g= zbXoDvrz+inzGaPe20=-Yb!^#;T}vRL&fr^CR2>BMf#R65_}xn(b{1l8?#e*CZ`r8l zip!#=_?At7%~cll?3l8C&lf|@Ih$|U(dRFbmt}ijxFm#^ZG7=E_i^P*CPDMD?C#6Y zXfBr3@0H3-uU4vFrk9!bELA+M*S)OY`*cGuFIBJ7y|nc(jV=3r-zwe9`n|@o?_cxw za`e)V_pkVPzaW3SUwo&tt!rvZ&*bhsdWLn4=+d=YVh@O3V8~eU-vtr>_rd>t@qa)0 zzYG35#|W+2p!BqMOHJzDBeiE(mx!d~<YX=($3_O+JtjQ#My%AaAMETI@T&Y%KPfv< zNRwOMHkh%~!=#_IM(invFN_}{{h(1=)Cc>@!(yZl1H?Z!l!XuK4q?9wzA$3E^pP#N z?4gI2m#1btJheQdjVH8>vCFE4`a=8!>7>|)+K{l<<O>-Sk&wU%#aRKqkTOh4hq}p< z8?H{0V#TKv>@aCMqo#?^bAswmI-Ht_*gI3CIN@VCcB&LEXdc$zL4Rf)3{8`7#Y<~^ zgeFj$F13e!$<h)iYGn*5t94Ce$$*T+Tq#)WRsq*5O>q#EDit@R#ljs%>n2}cCt+k- z>=c*~YP+c5gl<rhA&r6y)1{se^^epAEc1;LgneXfT2?a7tVvc^+DXzQ{j5utPDjZ@ zHK9Grs*Js$c!wcUUY8~L2wpyv76!(`$GK7@L0Co$KakVHkFf7$6hE6IE!8!Kw{(w! zBkzTdfcmGT)|z$O6aLKl^_fy0yf;IdqYDVF-EojzC`Cd-Twq^acUXb+xsJNdQ2l2k zs>NWbhv-q`5w@S=fqF0L;Q9knoah-0;ZqtlVv&aG#8B^0?`z^82an8=mMJ1E{6urj zW#N}A=Smj@)pfu28N)pk@ih2-ft0V(q2%3QWhm0%>>_W*zkV8{>M6+=J}H)RRWZMC zT^%tGEYX>e5D?%kTA)dF*QM4h_p((J<zNE#mC`pV7NY(L(v+mEmNX?$Gg=*lbckCc ztrqM`R@EHS&5l_oZQ%?%O9RZbG{`KG7OCp}M(M63Y`}Qg<?|aP4J%J9mnt<u1Q@|_ z$(AUGr5GN?i5<_A5S7YfH%hOlKsn<X9Bo^VuHDm;Q@SO0?G~1rlF}swu7B#vlwaQ> zy{-XIZIcdYjjL7Ca<u{9K8sG0!%m3($ub5e^)#8l`ibNZpYN0wn445Q^ial#jIJ3Y zJxwcM#{pp~eEOBa1S8)<MA#llf=AAoa;X|}HSG<LdZJOtb07wacS|k&J%h28S|)@9 zgEd8J4d3pTRw1;(3=Z3hD!+ZML2l91{%*JAfV0m_Q^i>oRI~J{oCd0t6>h#D&GOQ@ zxGo?LVvnGx_5Dykxb~uyZhHm2&`aE2u1%fZY`E&07)=oKrep<Sx-?tShIIm`>!0c{ zLc*F5ElcV@MW<sApg>5rHaFR<z{wv6P4-Irbg^cXLzEV^KiR0SR`@wbnycHv8W0El zWXTC7?}z%s)Yqh;V#`YEv{DC1T(_FCU$csCVnrCm`#kY=X@+LG?xs<5Snc6*-6&Rw zQ4l3dNn$=XrIdySrdH^9EE4CGmNx%m+F{1v;8|hp+tU1dx#}QUVC*~6Z0~&fppxg4 zo^gZUmBxq{$r0}YLL(V_P>K-@P<2r1g(k>9qK|%0iV-^i#i_)rhG3^0fI_}7>5w#B zj3I<~9U;J^8eFsTxwLl~A?CEh$gJRkUZn)hCW;5Rj8aL+9UO57q#ng8`YmUAmlRUy zc^?(t0od`IZ=~7@bv*qc=L0E2Y`u|s;$2%PzE2&Kio~IuS#?4$JS7GU{=N^<qikY& z7n<$=!vw84E+va4oHs@<LL_(kBPmaOgDY+ErLI&Jw87nvF*Uy72(L1vRf);se;Xm% zWO`Ke-NYRC%hyfBMw(3W6Q4@Ev|^*`^@sRV(ljx46Biv%qEK9<SKtHzCu2pelrGLw zK#RHlIl6wDNMD?m62x6xLEf{Hmg~$o{O}nqvN$?a+{VJm&s9QXWvZzY*s?J{4t^n> z5|35F;#S5-%C?UC7HYZ~rpUj3DXkNP?oj#-R^4-7<75`P%h<4s3K5Lwq(Hb?FO7hN zvr-pfuWTP|#LWiV1A9SMX^ezrxC>Aen$Js*XpK!jNrzNZaOh|09aThL`HQrY*|T4k z{xNsos+Ho1tzJ`S@f9gkoUoOJpLR#w1g~d}|Bx*3^Vd?AkEe(bv^7@Uqacm^OA3Ii z^^yUesxS<1wiB%^FJI%En4jLI-18i@)Q#bbTm{?nt14)E|6DIkvwhkCTB|_4f}uif z;5sLbuzUV!AaFx*PY)7Mj$#k?i1W9}r=NG>#-45cRnw~X%f(^aXwukzqX1*D=EC-? z*sGEo(n4`2G0UP(Xo8en@7$F3i~m#ghW(0VvO6rkCH>y?qitFQx|MrAp_UqfQ&92` z79b_W%}O1C@c6%2^oS5C*Z(WE@-^T}BRs_ZgVIq#wtVtizX$>9LJfZMQNi$hZ?p=F z_xa_?-}N<&6oh7M$8}47INI=&pJnzgb&MC5dx-Nlr6WuqY*^%jT)EB_A_{PIh@m4! z1u!aS;KooxC$%Bp9cJhuFcZYGk2Hj-4Y^5-;Rzq{)-KL!KgwW)Cr29|RVnhIF@|e` z7`j`DbyY`9<k_&J$`Dyr_i87o9&gyHN35<7u7n!5vwVD_0R)}UQ9d^L9>V)m?;#wC zH*9Vo@_wRWWdp+gWW$Rp0mA0lI?3;+8n&wx^s1x$ak>HbIouJb2{m?-FJ>C5RSI)l zzBAphNhLsCk+YM0H(PfFqP|DUom|7#1{gq$QMTk8*68Fqsgo=g8fsJuInZvFZjNh@ zp5x_GwGF+VIuE^u{6uR8ytu$HpS$ZUvmF@&YZhXk$$e!5wqTK=NCnjYGzPFO!So`- zY?T;Wrw~UK>%@}iF+c^e&tk($lb%MNIdFQh;kwz2;=7v{kD7n6#`aulc*>jkh&OZC zGE9*^PZ<(K^K&%A8m2@?$X#x5!l-42`C>N?XqXiQC>AC{{c=Mu?mkPUjz9~+))j_) zVG-C?K7e;{CGvJc*eZ<&)u-K^p<l8o5YDbL%o2~2LBC$O9%xypD-HnZX~PupH^r;p z&1$YTRAYe_YfzWtd0s#89*4J=J=Ypm2tA-?t>y$d|H^L|x9oL>_2M*=t9%u&ro4RE zw%)K&T*g(l2*Itp7motgsSLwv$TEz!dtP|ndsq507b-r0OR<;GsZVenzY2x`Aj!ZS zLxPW|mSd|o7#d)$5<1tm%;2&9(LnVLs48pNjeE4lmm3m=#&Eb?LqYxLj?Q4|gb~lF zFeC|m;dF(eoprzq-YySj5)n{)7)!60%e1R`v(k_tOlMLpA-01_67nG$H1!lq)rnN0 z!V9;BE3J>zhpp}-S7)eiVG5MnZ!$cuPC%%4IXl70uP~kiHX9am5BR*IBHwF^VVy$c zS2wr@m8vK<xv(7y{kQ4!h)pgc_TH`&+2o>H|40>^yfT)=Rs+PeGMG`}Ur<*4es?+h zqT#whyOF_ml8|@Za8aYA{9*V_Yp`n=kd1+9u<{o)pYW>`0l_y6VH$v4mcR*9U^>*? z#1vF-@UXo+)R`IimZ3l+vuhF<@UP)pPU(jWkf1I=_W6cOz%Cyk(h-<0zbgd3T_G;p zN_!n)8Q_kk8B`zf8B5y&*|jk+#Yc?e%M;!Ixwbjb!dIxjVddMlzvZi211AV<u{pon zRH)x~VAm0H+p56jzQQtPAN0=dz`LkRSxkzZ=))(^2j0=wa_Ua?O?0dOOM&H`bZpdz z7@v+VV>-ls6Ii4R^mZGk%Y(lQe9~XX)}8V5mA738{G>@mxL-@CJtlR1<2_^777+7v zfS=qY)zmp$oOGPlTS$1uoC{BY>31=QQ`pTv7_rry1sz|(EN`*N^pm(mVU_Ihg+ANN z)8XPXrfXs)r?MM^@~|zYL85q2QOfS^$kKMxBtbl_h~h0OydFZ){yR|gCk5D|i_I6d z?lgJ8vD0)zymg#qPocbMmnl&Y%^%4a(9Z<1<wx9C+l!_gh<^z;vD;rT)rs9dk{7>d z`dAQ$D15fdguH!dq{AzwdT}Zz)0j=&Z=Npy_o`_XUfKDZugQx9^Di!O=1H!YRV1*9 zmPTUcNq+k*zLz-wVj7v(E0kCt&ngAXu3(@f)J)*RA?BYMq%;FBakeUmT0ct@Mm&8U z?+%fs3yrxZq@bpKs@Y~{!qK%c;a+XZaqL!^kLLr_+swR%scN~?90z&L%^O)GdYdUu zJfkRK7pL%UOYV++7l#Ev|CZ)bhP78A_KJe7Yc68ATXF2ZBZ!q+n}Na3??9MvO38_< z7{{SjB^-DQ3_gFD!>%8Y&@Y#Q>)eL>Pj|ewwJ}#PO^dJi$BFF}M9rJ%-0im9;QFh0 z2ZFkp^C<7;-AB!FVjmTYw~pY|$2fLIJz~QjGnX@!*g&gs3a+>wy<68_>2M0-Znfv$ z*;5!URl!Ad;@*Y*6)+0cMVtNML`NPIq#$nYDcIMEN4NNfe=Mx;Y~IAIVIxjlt0=h= z#+BqA#e1qX{V*w#!_6BQ3@NB&hk|3Z9^UK1ojUxvItpQ3xkaQP_zeX-yamsX(rk2| zl-};fl_CXkAE`a)!Hv&|F#kqzh+taIqTfBZ-%$@+M#0q>>>Bjsp-RYS3a%>(aIv5S zi!0!fuVh-Vfe^o1WvuZ&8oc*7cRczmI^M1~k0v${7oy<u`f^n*U;w-4{zY2Sc2 zv12Wq@5`MM=JH-qFtLG3q7@}|1}xT99eHA%pNBY1=>TZk(L%Y36a<e|z-v13C`JG3 z7Yn(~%?3#9Z!TdyKuVmL$zgs|Glo|@RME%31>@|yh~6C<Y&JsJ0G?up2VjaVR8&TF z!_Fpj;r8n<`ziMS8OVEr6trKefMW;q9_KAVKT+p1%m6kJvRl;`f%-Z{aD9n4)!AM? zl-ouMg5Toc%1GXwnyYA*X2G=K9EKExeX8iJS8%l>%)c;;_%CwLs}=)s$;gXUhN~J? zmGs02{u#rE|NJeC%wGyN>@Y^V*C>vyTf<Wz0FK6Svq(Y3hSNL`s-n1i??tI8wRSYu zd2%hoHC1p?kvRK)9mAE@Ur_rpWh_^U6a<GW;OcQagr)s0N}{(JuOxbZ3*rW-xKB`N z>_8sJg$A6A(|VaD_+tWBij+8UqJj+@%pHxHY>tJfbc7w8#M1&PabmUtD=EMSGk2$O zKjZFVT2RbaPT?w%g7z0H;Nsg@dg`WfaPv(VsbSOjB)|sZDimDoag6B8@f^1=0UbEh z4;^Tlz&nMMIPpaVOAB^F635my#y)LrgV<ja&Fg4b8)KgiD%h$x-ly8_>LBe;=6)gt z?Vna~>ql{%HBIgN!c^XOq{N9oDX>~Uyn|Dd&P|t&!PrNq^X^~+)!kBXvE#YAlHF() z>yQLNnS3T71##xjcy4$+d>9u$hd7)G0Z`{Lm$6<T1#vAET-7Hy9a>E0!`LrdjrpD| z-WR0I7Y$#tEA6IygJqmzvB<r1%z-9_ex@v{@l<)yeDh9GyiG_>nOJ1r>LW&-p{sPn zOo5J1nG2<gGk9lU*sxV_I^N;|=Q4Alxcdy8h_~dyE!KGBjGVjN{0Y;}w_Ng&a&tF7 zapG|Z|1w}IRCjXVo$!t30Qu4;^N=*L@T5Y&Y&KQwwy2AL9MoM6@Pk-Civ^w$EHr*} zC%zhSutMZOy1}jj%`o4`i%h^wUrwQIfePHh!blXt4D;t0+7hT3GxQ7aBIib0%+N`) zP%Wg5LDhu-zsk<&-JIq;9gsQ|oPoTo(xyOxn89H5qOuz>P&3dH0Jn@>AMFZiEEatB zY~npd%2YUO=4{*mV5(Rw&oZ~E!S<ApeG-%Bh}E)|k>hNZ>+E0J7ErHt*tz?-0~p7` zXod=hMu~&kUonhJom`q${<?Fhw5A36l^bNCOygwD-9#7n2bcVDQ1=U_WUSjl%NtVS zpm~VJ1OtM3PjR`A1Fip$H}aw)ZYy(@HUKt*#R<@v&j6x?bv5|IwQAIEZ){Ol{Wz%3 zK<%~7E&d=i@gkGaTTQrn+5>1tuQk=FmCLM{bWG{FW?Y)~0jg5k;Sog*0xdka2Z)21 zWHfv&3=JP@sf2}*wKRr(tt_--!fiktBn-yvuKyAZ?P_fyCAeR>Oe4hh1A2C)^-_u= zk+m2XwNYZ+*766FqTK;?GWk*79oh_Not)TCr>dQlVCZ9<O4|apll~CZp7))|q%^z( z2hzSkQ|h%hhy%*}MxD4@v@gIh3j#}LFG~Fit3OYj|2p#+(WXER9qmepLPmcM=SFEW zz>Gp|7t1!*+q|xpdis|w|0I2=n}wulLqK^gcjsA5OTQXV3%nA+XAY4GxTyyR(&A6R z;+__o`b5EgQ5xb}uVtzQ@_X@a5mg`K#K-v<N3+#mALB8-`4|(KjE?BTjndMudS~`t z|GiVEb3d*YmwRuut)jSE+!s*l(2}nzv*2Yk?`qW(mTN3pxYGZn{M*axlKcAWe!+lF znc?D-T!2>jb5{fWc|ABYfcr}1;*Chgszg^Nw9X&0;M9C~5RV66`TJlMd3i9GqV-*M z$_(3wXymD|b|{x>K8$BETi(^|41gKKc^cAUzBdDP(!9<X;YA+#G`chOAXd0ZBYBOY z<$P}^hd=a-v214jB}x?YDKeHDr?s4XY7xhWnp3pt)p!(lj23h3U=Y|xb5WvD5K1On zq{=azifcDbL$;u+9WcO8W4RVu!}aO)%{blxBCCZY08WhOQ-W4<bxQcd(FtB;%AGeR za-+10>ydqNk~f)k1wC9Xy1#~f`KBaZ)s{`MEE5CHcu{6fManQ-yjvTRAS%HkLE1D+ zzSQ`VzIxAw@$r^?vHc~sdS4SCzl66@&3Rgl3V@!8mK57*T<`Vg)nA;UJCyTQ;sw9z zVgO7?vWyjPa@LPYmRd3N8-k5o(*Tx~g8KS><E`%r4m74(PK&AhZ)ck2q_~p*-F^cq z(5K=0bj#QdFOvfG!O$MP)wSHSuYvN{xf0xeppp#B;%49KV0@zTeFN}$4$iG)E-%6= z{ze9-hvc#3iPE>MH}YPOCDKQH^cOhYSZF5S%D1!>pk1zIkx#2%9)g#0Ep1gE7_u$L zK+dx?Zb&&W!_u@N<(+&>GnK+L?iEPc%Y~K*F&GWuuB~#W<#(^Y56UNJSt0~+xW+vQ zb#p8|Rfvpt(HaR5GtaWZihe0)CKi@I>ZyjrG;<?7g=YO({&BwLEixrnEwubAGNbag zVvBD8ncuy_(ofZg<`2p>D=kJr{OVU&+}6JlM7`s4Q9iNS^1ER1wxAgpCRkKy*|yfQ zksEq>ou#)R7W_(`;$F(lO0mact6yO83A|_6z0C50-WpJ0*}__7hx?|&V6dc!*MF1G z-}dP)__N2yC}dByq{%UxEbo&LwdQYDT06e>O_QJBYB{2+kZZSF4yg?+9X3Dt-yN2> zNp#06?ligSE)Is%pWq>k?JrnDp^;!6F2DMmWi_D~T}JwKYLU6WU$WG5-VsBZ9Q&%} z2dxFzGRZw(w|pi5yDn0D2_0Xz80BmGEMF3oI*z3Ctc6`olV`nYIiNKv58ybF=w%F$ z{I=z5y>;_lr4^p!NRxXUvV2H9>P*^U%WKq%+l_H3K5BVcYXP>baONXR1k^w6`<Pt( zzHd*#e-RHUgTu!kAz=Mc1ccodjgS}QG{K}K;bE3Kz2t=B7Ex0sBlaM*s3X@-;Aksj zCSUzjZ}5Qse#&y3z!bbzpINS|V6c3H6{_e9%MvD?_&pw4`XAOW9OUznrZgD$C2ySe z!+X{Jzp|`gsM6DE(Bce=_4?Yfh!gP03ZCy|)a44HtoXIjO!;c2E4)u&TIIKvRqXHU zTZA;Y{;lO{24n_Lo<miazw@$s<}B`R5lU9S`W~yWVilol`QJ`Cug(%6ib>bGqvw9W z9$<q+KDuC8i4Ah}tsgB*`QM6<yMD4fr4Y!+l8aoD`3UoVCQ0t3=aOZi>SW9>mLld7 zMJ3`_%No`|W9iWTH;!Uav0Ww<8s^3-&-(^~aK%z=*5|9I^)LMCTZ>t?K=|v5Wtlf~ zyu$48uf+j(uVG~FTy2Qht02DLjp8@2S=M=rhy2QQU#o9OAF9w##-KyjY*q=*cCs44 z=MT#)sKaMt-Z~a3*mG~9f%@MqYrUC&E6n#=Ssid9%<2TwpO(4ah?w7CUq|0`u>FnB z3x8RPyqS5wasO1^64c(c1VXz~%aeA`j^Ee<m8hIS-Sr!-Wb7Oai#3~TQ2(dJ&Lx6x zTKd^OY#{J47hq>&8VaoW&til|H!TsB-@60ED+Kdr$MH~Y^iAJf)=3Ev6$s64S)LT_ zmziay*ijXv(I7yJe=HucCjo#Rm_bV_V!0U4>Fk({N^kZj27KCW%RF&8*E)&plFXJn zIL4?oM||}%?C9znsR|*ZSp4EL9PXymsz%{x9KUOsZo75admX>cZARhEIaRzS4Q-x% z*eX@rv8Fp(USV)`)qWUTaQHdPBR-z?S17;<w|pNc84A-y>j+0|1M$(i_#`gQ?z^dm zS(wnK9Skp9#yCAi4MdmdqN}(lySs*>u;V4H`%ORfHNaJ0Ypz&*1x~MbwScN=PDzwG zv>NZ3-3JW<tn!n5Jl}f@{KN&+%CDzQaey^VG+p)5?Yv3>VE4J0?gmgJoRX}Q#a`a{ zXu?;7>7#zC1I_}<3rC=JnwY^AvO7|0NC-hW-pOc<wXMDCJ$5C8_h%=jlr*yaheOxX zWGxWot03gMLdADErtp4DBY4`3E?!W8m$-3uhDtTQ%VJ$6TCY(yvtv_=5lW>qR;x$s zMm%80rc@cVLL`e5IWxgm&kvOutSw_MAI~CgfG=c}*eXn!RLz~%C!6iKrlnzcxn~!( z)H5~Da}CA1i}!2rV<!7H_k7$y&!-La)N(ybNDm*+D3^7j_y_Mvt;?!)vp50+eW(l8 zz>#k2K+#=KsZe6k`-+pW3H*J^GQ-EyuO7mO=~EHY+zE3VS+|N=B<8<bcl=ZpPSZop ztyVZ4V%64E8rI{jkorZam8~g!9ns03HRfbmzNoSz+6KeFQWw}XppseB40Y5twKiOK zRhGIo(z>R4Qp(KH;&y5{_L;npzO^i7WLk@PWns>J-qO01<pEojvA}QB99{E2lswrQ zdyGQlqgrFwI!)^=;zQuebF_+U>mOKGVmRs^!}aD`TdNW7w6V@s4d_FREM}I+geDAu zfBV6bPp=$kMyX&D@8^!zIdl|EHLn_C+YQ~kZsWU-X#QGz>l}s8L)5`q#*|ZZNIAmT z7KaB07g0QV+{wCt$*`EHNh87MooNWT%W936*n-HmH9SPLz8?>_vfUJgNEKJNNPN#! z{dAxoyw=r9+l$1WQmVYMn{~6VIqW7~Fd8wpZrp&w!^Bj1ccisg5O3UIlT2RoxL2c~ zk5^+-Kd(k~v~{~CGpN6HnPAWk2b3K)1=Gths1s-h8Z!Wg0vi;OUIWp0w1&GG3fJAR zKnpxJ*cu4^23ZR%H*TmGIi8z09)g-d*7N4kf8Xmg7(4hGp~Wz306a3p+Rru^yQMGk z!*235=ozywGn+WkkOrm>e)uGw3A7oC0$B|Na!CN+)wv%(&{om_TBhj6*Ng7cEkV2C z*1opa8wki;H$J?-4<7*SMp&add`);-OR<Q3tGDo=<oDE4OWJwGIKC>yLdY(qx{tJu z?jT}-l+_qD_~|XwAW=)zVEmgx!;V_28n!%+1CSJhDXI?9rrt=2kF~C35Othl;;c_G z1WP7-Bxao})@+d97-em15G`NhF>(JRP&LKcT5ZTHrdq!d#eiG<sR7U-${Mi0XU~wo zOSIylIBKNHb;+1lYU9IHug0EquSP|tS7X6+>mp4iF<a-r;9Tn~%!TU-K7abL!_|tF zu`@77RV&d2*2P+*-AwCJt>K(){a$NKnCr!PV!o~bIxVzjs#fS2jG`I-USxfW|BYMq zBJ0=YnhjbyJ8tp2H(wQ7CyC-eG!A-H@I?XkfaL4N7}$2iq@$(WeY^xf-rq~CRj53! zt7AI&K7~q#{{yA}NRf*1H<wvgG2e;**K+G{TlPQRvm%e1%sXQ8RZ%xqAgZ(hs+>@C zOkPoSb0vb_XaG9!59~NdhG+b1PlpyE7GL;#m364?Oas_=+#(&HSCy?sW&brmJ@hXN z1s$Pp(A%f2De8+V>_r@fm$wNc;k(wF(5v;oTGC^hx6xa8<EWk9!aGA9sHIMU&fK1! z96&nzud~LBvBcvqcGW;>3r9NCv$xTPtj9f30cX<79f~(q2hp3DQmiU_H{c_Q@g>$c zv692+4T*bT)5g7}JBCibtGCeULwXCHKBBj}mwP_YTM^}+<J3|+bb=eCcS!CrNPdkI zuPO-kx`=liUn#>r+iz1U(klm?iMK|LaG=~eTI|Mo^rDC&NVm&htH4|%0_FKw*i~s= z$O(~98xh<Ies5u1V0&n>n*HpKmG@crBW`zN_C}m`zIbtK<9nj`&|-*gW9%mEWk<-q zkz?B$-w_zm+|JljA^Lbq?(iE|vB8awLPD9(RG8e}xI%1pM=3SzKs*#ATGOHPO~Fr2 z=x8hvs4b80Y+Not)?#bA{A9Rsy#Q;L;Gey^8du=kP^tLmquq^_0<2n&vN6vY1E50> z;}Z4MJg}Jqt5+beZKQF7Mt&^QIvs4&5FPorah*nHZ=}JRRj4$oj}cGlKD`<R6Z#`; zL_gzN4R$sMrHMQ#+KWs_{Wh-QBIO$T*F4o$;Q%jNbn@@)Iz*Ent{cYbP?BJ5&E@O@ zoLjH*N``pJ(NVcqW~sbw!@PKO{IB;0?m+;&GQ!(COeBaZL*8pK#xl)2mO}910#)RL zI4==8EI6=2<$X5Vi$}-7Xu!z*b7Q^SV6VyX!6e?5@m{<zc5X|Rli>D5FP#bO0G7@R zoZ`i!BULJ|LUW%^MX6*7+9Y_1lw5D1u3M59j}9*Ba!;ffi!_~4J<N(5z0!=kH8MMb z%2RSe21`jMEf4Uhe=6yeW!$Pt2y-DX(duCg3C8Cbx2O!LGGSJdd{!RDhX0wEZ`{lO zq}-Ah6&hD6tn69FWeSTTnlQ)swx%pL4-XSkSIXw$)KlI)5ms>HA1*L%)M%?Thwv%v zBJWWd%||5zel9j@(G}Ku;cqYT!dGWv){sqfEdT<S(cC&O24UXn<R&Y;rd*f-=N9rZ z;L%lHCMvjzh^M{W1V)<<gV*XfsGG+_mI33}>ttawho+T!(YA8h%rY<9b}}O`tuQY2 ziZK*|akCm7sGF{)=E_aRH&wE*n?yn0Y&@XRp69enTaBB=e5Hm7`#6ybL$^oqaA(8! zh}D;Z5*DbjYxJz~8F80d0&8~SDH{qNmN5z7G1ELaw8!|c96QU$DF}zScI0U(DI6x6 zoc)59DN|lj^HCo1igA_F*T_9yzMtiaJk`ec)&Ah&FeM>*3ElG=mR~iI&U3u{x|fa% zoObC=V=;4?zp)RsvT;5&%h-8pZ27}m2aGd0iJhjN_6{b?*0&TA*p3><Li{@jTl}^{ zs~l${*a9vTRYNU&oc^w{kXtGqh={B2p`wllRYg_DP|>ybP?7yTm6kJ@<G7}ZSb?M@ z_~wwRY4}IRG4N)MagpwG@e$O!^RS|$jQNZtu7bH+OHgu>pfT^OQ06I-ZVoW<9s_x5 zJEn@GlUy9gwXjcdkn28FoFV_JK0@n9kE=aE{}h3+kJZ114#!>*F873rvo#kL+UQSI z+IOEAJ^IT>W%j3%@WegNs$i)3)OealvTZEtx^>c6#G7kQ89&$l8Vl#XMrTgd8fO!Y zMs&|<B~}pinej7DXXoLOZh+Zim3~un624H>mPOT!g~9(*gFrDsyae68G|uAYssjQ^ zhXkQtsWb`^!&QE*kSIc^R)ULPD^3B8AkjWOqtY-|W1!?aqXpjnMzKoH6Y0I(_?Fh2 z-x~9|^K5*PzM8l4{u>KR&l*=yi+Yj&y>TVyvEfZRr?mLUj;d3e)B${jCJ4rzH!d*i zJ19@PJNzy;y>6Q@&LlzX55`5_h=q69P4a0_BAA>o{DN_zH*@d3;+1W2o(}ubm?)mV zLpwly--NG*20_wK#!S)wF5evD`*F;9+!is`;)}*fVmr=amoT)Y0`j`_XJfKBl345l zhIUx6`R70rY%!P&@bV?&RG6~H+7sBTaj>YLl+NGU+4Bf?Xz#Da$>NN=bX7weGQgK& z7K!DGr6<t|+MCg9ASc_KEO7C%F+qHb^Y#7NssGU4C;#HOiC3``-*Y}~)aY%&5<7~v zy=Kf3{T_mSOF|-PqsCutq{vn`GvRTldIWTM2o^i7-GN=i@I4%MGZf}rH%=EvD?Hl6 z5qbOXNS>#V^*tQ%()$}dc-mQE(oRly=E|RF>-a-3qn9HRXeX!ha66YJUQ^`g9S+*g z>3}{r5#ScMqxzms2c-UufIb4W9Pf$*+S8FoYj2^qDT-Wzwx`1vAcLUpGFHIX|1o;R zrxk#{yF=k+;%f?7-`J5(+}L3+&nQfNXQw;!=pA(CA(4BlZ|`(K>|F%36`^Gr4h$uo z#>0nv;d>2eV5B0iZ}T(^yeOEm#F?rAc6`2}5(u7VobKb<q9F8bpRVGT52`q-0Q9|| z4(OW1RQ#$S^c|p%7~*f5CRicyZ+!5o?*i4#m0)UsX^GI2^R?|DdpFeum6B<wb)t{p zbxUgs0fm`-twdD3bzuWQG1tW2Te-KpZw2Bp`<*@lgm*Bt6<*?+l>Mac?=>T$K2=d) zaCO?|67-~a#B7=(+*0_b)acSnf}Jg<r-fE<U9?6BMch?Nidk0ERACU&A@-_O@eq3v z1bJ4h3bSV!V?>XK3ohk?s%P_jN`2AwxZn_Lr7sJKdfB^4(Wh-$>D4Tn_4N+ZOrIJQ zD|Lj12p@30$|jaO8f021T;_CTBdgl8K!(edB{;z@S@Ds%vYEwi(Xj70P;sECQQ|gb z3%v-WZf$i9Zv~@<M6N;K-co-__<SQ%p0JV&muf?*OgeKYGVubK%qtt+`^-l+M)O~C z4a&Ax9Ra+V*Tj@7{KuKJ|MlGK{o1A|{xB3fv5V?%*xLryzXD+x@%gs+J`LxZqlSEr zpiT092&p9^HgN>sGJ~G|?OU0~i|_iw^?a;%G(9O%`nERB6@F6u(zejF=1|}Y9yYBN zZ2=%`4N}DDl}}te*4ZKhytAV>9yncUy9XrUnm0#G4xrkj?y<=*?y;xaRyWYFmcu~b zW1}BWgFD2E?`~@QYqd*Ow#lAvJKI1-onlGZZ>!kVBEEXdRuyH_4fMJqWo}SM(>Sq% z!ab^`h6}<v<NDaHlj#ZD2+6xJ#Bwa2s#15|q>L6@lo?^0(EwhksQ#9#RwEk#gTqW? zd_WQ)S`2Dy+eSj_OxvLdDZ70&(X5bPZJdt}&j?KSuklXRrwv4F75DUu0yPL0_^FF2 zN4%-%R;~=x;k1CYo2l5=!r(ootqnYC$`ymENrKVcO%w2<2HyyELf%P(B)m^=dSWKg zMY9fE7-3R&sQAIHA6ViA(S{Dc6|#=E*ftJp-Fn_)J5p>lh9z$+n`_$3At@9lJg#g~ zaa&5LP>AX6wO`MGs6Hls4Fj~RL#Ytx-PfdSRdHKN5P$efz0jb2DZw6#Qem_&RZEKm zRU=J)&@$RIM|Zw@DC!M;LJ^<~4I(W+qHK4|ST~3yJ*l9m8$`ORlBgR*x-mdCj$7;t zWQg~GxIYe3x!42FCBKmw>UG62WvD7jyJ+M#h9kpF%9R&hdnk(Oii2eLj!>hAR~+PU zDD?PLy$Zo=jWK+SNg>!0W8zm6fR`Q@xsQ0&F~+OXt%@`8%Q0xcu)^w5iY$%29^2fp zILGAEibV=!17-j$9HT~=g|q>4A^CuD<<3wvv9tsMY7KzQ@oL}bs-=Nsz`fTm_i!go z^a}VrRs&%4B!x?ZpsrF@7(Q7I5M_|g7&t{`(7<$#H?_Ry@`gwcxV%C7RvziPc+)kt zzhj_JGOC!6i1!$1Lb2&Uq{&GNiC^R(Z8I0A=@6A-TF#oi06%ZhQC<nwd4edE(^D-v zBbu|xx*Q4gl#)*CCOl)!5U=qMzp;<ZF(#g`@IdZn>mJr%r`DhzUvr05TdeaLg&uuQ z-)ilgtY5*xj8RxD=pNE9vu)}4^`H1Tw$YW}SY2{#jc<2Bp6+7{w`u1S!MemY9s0U# z+jY{wrAWdfh<@-&h|LN=Hnv4Tb-8aS4DTo4+roIT4q9{<?#R7EY^%46d-26+{4hsZ zZnvJ0_m-`>^5(OQZ$5wStKJ)-54_0PH8z8wk?4wS+xNC~xOT**-v!36l}u+8f9PLl zo9cC^*DO3=a?Hl$OFy(3MNJR8){^&pY&)-8ql=~47j5aXblO&AU|$;96Otxh{l@mj zBVM7hFS2xdqt0GmAp8iY3+?UI$9qsS)81Hl1a?^7HVZ#TApUR*_O&tGlsC_@{~;nC zpY^3d-beNT`SyG}ekp@f<l77F_`pwTTqv^RlRTwye6d&K)ur|#g_9vyEc23CutMXc z$w{lc8iSv<uhq2mUTZJY8WHR5rCOs?sl7yNJW}SxX<A{&uZ<|~GzR-dwE@U6$!#{- zWtAd7xmjn+{kPij;hQ4Zb-R7N)@ZlGj!zzmlOs3XX`iNYVEu=7N&a=0Jz1gT$?rX9 zpTZi4zqRMct6s1ts8~7nC3~jUXz_~Oqc#8=l6>n`dlIAI<G398<GuD2l`U87)6A#I zi}%}Cs2nyjl05qjdpx6%#Q`$6$QtlMj3f5VgLd|DoZk4vkavv<8RQ?|_UZ*w1N-9~ zF$l)g`%%VW|3p(cyhiT?x7hdyw@BGRA^7E}7J?l4oe%8Us*5tR=V=Wzl&&;#<bfyd zb-{NsxnL6fX5wRCCEiKj*eBsPa`2+as{@j}r`F2{3gCjz>@!qLfWemJDPP#}Lrp)j zhk&{Aq%ZByYHSji{<R&SAuCZi)W#vnlfSX2B1OjNozyrK<U41*%n|mJbM~1UhRju; z*By{oUa(iGY<c}pcKn>pj}V>WNS8PKY~R8fG|*dr@fzri-|Vwg8J-j)uJEMLBi-zp zJs&Z0Y5lz}p8VY_54Qa2HE6uIH@GTFliq)Ov8g-8e|Xo?tLv%{@<;y>k*C(yyLKy{ z5z)S2)UuZ_!tZ5upz!1`W-%O};~2$LuH<L@_6ZNJ+}FpUr85l;d^XP!S5fTK8|w3Y z--Y62p{w6MT@?%Yn*k0=Yu0u7nB>rcEk7IRV57u~6NXljXPF!s3MEG#VR7W>Y&Jn3 zvpLiWn#MEZw%wuU3Weu8r-P;+MVf~ERhO3o1;LIvno>5}FmAacj(Y0%q3$?&^H^i< z4UP6cO&s`DBJS*)%^j?0$(WBKtFDv*Vrw27YW(kE2cBe5qK4z56)*X{M;(+K2veTc zS3Tw^MrAGAJN%dkTAKsgJ2+m%zw!J)0leGMF-olE-*cry3N#Uvr{QmOa#SjIXkC^& zJIWih!>EmlX2a2N$0~(~AKAmF<p;W;V?REROlFvjebCLZR>i#4-SGncjSdyS{~{b! zDxFS8)GlyH@JkQJHl*qg=l|&G*nL0D)Qe#DK8}UZuEIVNW<BmmQ(?8^9cGB_?Wn;R zAY!r_Huf@@8S45v4yj0$5C~199M2<_Jnk9o*uoHf(96M3ILcHs_3+=x4*V)%f5&Q- ziq@Pk@kz&em7v3t2Iw$4hOlQe3a1TptWnj+E_e7t)*wAX=+O>U5&rFj`9mD*kWl)x zV=gQmidmvKwqls>7<G8va7P6)F}8DI>j=lwsutbw0NEZ3zmIhEzMqBb0rQE3_r#Jg z{f(txQ>6Fnz^MEC^^7WhWQ;DtVpBN@pJJUDs}prSwc{L{R9_IfPgU{nga@Ee4~sdu zh0DQxZeiYWrg^H)q!2o$Ikqx0Y&<F8?cyB=7=dkJ4y|?s!IT8Y36;=dDH5Jdq#+3} z#9+Rd<S12{dN5y4W)YLo9bcATgglhWQ(7~0CXHtjGxS}$;~iBEzO#gH(*A_=bxx)} z9F0BX77g`?=`_@+z5qPG*;C++EFDO_nx0LGL7hm*q2Tcf#m>-BqCK6f4{B+i9u&P3 zl{0uMGXF^FmV8~Q4%<~geZ@Wovc8goZ_MPm$VAoYYk@<v^n#$vADOM2q40h*hr+AR z^7rRCY%tizF%+82<NefPi0c8XA2jY~=IgysjXtLZl^wCdB4UC1g}N6QYBsScG<xO< z#SJpg2|<hb1lG(pU7`;i`phOJx$yW?+yw^gwaoD>)2#?;g@T56>I$uH0*-7DWUXWs ziF<;D&<s_p8l>TAR{x)N;1z-rVl4S%AY(1XgYv7{I?6BfBOk)o>xCk+#IcBLj-<;i z_T8zV#%DJ@^w1hdR@SWStjxmHPO*vkiP<A_Q&P)4Ct*aXqsjQB%?L1SfFU`Bc)oDy zeZ-#So(e{^G(h4(rRVRXcEw{)Z$V9|!<BV{F-@9CY+-)6$NWqKg9B&gB$s=_8xqIm zW~P*Tt}vo*Fgia!ac;S1BBNS0oudo$XC@bxdrBdCgCl6t*@o^6%*stf=81+fPv*`{ z%EAy_y9XQ_-Ua(9Y-wP2cw$m&R=KAIp8s+*!<)t@H#k}fZJ~aHqlM51>}8HtLJVs) zg5hNjiQN+}!@sl39D$8zGEI8$$IQ)3jm^)@L5EhshBC(^!g)AQ=4dY5lD{r<7z2iO zGzkx_3DUZjlR7&-X=Y|tN-BnJ65}<}czL-6nT46TIq`{w@u@i&tQ^LFROQ2=-;6C= zdQLK;OC@$9W$}qwS-HuH<(@j+_~&kRv~Kn%Lpkq3Vc<|J`v!XTW=BYmW@g0bT~Rcp zAf(%aI0ZA4$~{BPLgf}maAX2Q+^fGJC39A}XV!yQGl{hZO~-C=H0t^612Orj+2x)C z53-%e!f_I%tF}1YJ$`%;WKJ$d^q&WD3Nmo4Z59Eppy|jqmIrvASdf9zy&uF%OJorl zh2nj;qIkvwG1)WG#G(hXsN>}*zMhG{^gv8bYI?b+=0U8?<m^0j-int)C_d&<D>`q# zXIPWa^(e-0-@{1G%}I%8+%b%M??~sTV$x=z=Hc5MO_~)m$h`xajCob=*?^ek+Z-)@ z_TV2cZF4m4b^Jl#g48*v@O#G6^PMLZ&SzE;{zUn^+Z>I20&N0>Zg({CX@P%4;vW+u zY!47i%OjP;8Smb{rR6C~lO8PDr69B1GY8f0+3pA#yYBx1%|y_y2k~ZRc1gp)zs-2} z1};4nIX|H4CRL86KL6k!y{jC}eAvmSsa1~PK2O?F=-wGxFgvp_IiuW@|3GGHRw^ra zYf#0$Do69^T@0mH24!j%=4NLm=V#9@_k6?n_l5*hWlnMiX40Ri#=gVRtVJ8g13a0P z7>}Rx#iVlJ8_GKzAwIpaXiP`APbZXHvjfLx7*d|!;b_`;3bSL=(rQTm5wY<D;>tZ~ zD0^;)!_{OKv!Ev=0Y(oRQ|?)g2-~v`cTweo5W^Ai+yfZ{$~|vBfH9WoJoZ2aN__bs z2D5R|5qiIWV~3;24fOBOvyMjT{>}!7fvk%$tdH&oF_;@|9>_qQ5f5T8HwHSfdhB$# zn~Zx9VkC;DAtDbEMYA4&7&|fs1NtBa^Rx0n4Cd!^4`iURHy^}cejal+3>O81!u2Kk z*L;`59eI(->NA26V@8c-5oH{G=0}f-88M`P{Dl642Vuy91jyNi^)Dg_L3)`{K%>V# zfkAp8D|+OU<(_dUerT5?q-Pq#=++hSm{GXuJWzT9V=YH%+ipzjO8!Sszab+rI!xd` zcgK#1o`3=Re|Svp7%Ew`+wri^m;8?qz<cgSpNnd1+jqvm0M8Akp(!lh?QnzXIfudD z-=z_(qXrBg5Iq`0=Jp~+_m7K52F6M!!n9<Q<m-uW3G#~P*d36waOHW&(>??KehB8j zfHU?I{;}l+$AHn-e#UKyIkBLy)0o`psX1(0QtoN>EfS54I4pJU?A&}@$F6^eB!hyB z!8%rV9tk!^h|kQ)EQ~Kq#BEeTxo6KMx!a45abj@a9SE>6z<@b<`Kbj3xI@8x0PJ|# z;SQPjtSZg+d~EZ=EoVS2vWGp+*d`|1KP$1I;K|gqa?fl=3uLrWsf9E1QI}bxJc)I% z5FKBxQKHdaI$}mb_$!W}q6)^KZbs+isJvZ_7{D|RWP5<M%wg){_>4@pB|OUr{)|5a z?N4PbiM7UO7Ggo(&!h=HDlxMF;TJV^WAbrt>fVWb@;ADms30}Ju-r3QBMr*RO-jTi zay6q+M@Q!7u&o%<US>2h6pMYwZ-=us8G0f=HF0{m=Q~ZPe{N1;X3k7BepwS@(Z-h` zm@{O3NOoRs5wm`qL1;i2DZg-FelBjCn&P*@x%Lr>w9s^51d@CrH#dt7wR}v4Jdv5h z2=f_%@?&gHV*Xr4TFpo#H9RppDFwHb$26%SX+`K1E-#Ei9eXm9ty(@GVw>VWnr$f@ ztVyvLo>@@XKbLJ_S~410LI@{?X)vaR)A}(QCF7vfoYefp!rXkaIFivZbVY@oqGu;& zqLHZzrLfb)%+xGQ>;;TKnLz{|l+BFjP%<Msv9K^TWn5wwi}Onwd}wZFPHGBXa^MvX zBl2|3%_%5MWV`w-)>+a!GBLX-HH8mLtK%v)y09=mGifHv+T)te(KC|@lJhh3Q2r}M z<UKD;%+F6nS1&RW#Sc}YT%;CH7O-;9UyM(QGG=BTOJHASjS>2F8l9Dyj1(uMkc$4a zMSFp%AS*18iTMcG#7H!fF?syzF#I?y+Up1&YOX>KpG5iTGqY233NbsIFd_|NG}|1s zXHD`UIx8~~`5s1~*sy6cq>ydZ=fb(Yjz$AlYWgVk`X{nk^gJU{mJ(43`<skP147i% znK|h=<5@xZ0Qyur8WnxP0F(g)7?GHlhnRBDg@)>=oRoWhXH@D5SBDYCYdto>DHcSG zM(1q}Nim3O&Pde3;i+@j#n_bFNa$;2$r7K%NK_BYJqsC~I$p>sYvw%c+?D^3Mt0ft z9HGlS({Dc{JN7w3y1@DOf)<HgVj=NRP#;@ZkFdzDNy$BX_DJm7y-W89_JdzT!Dh$D ziSC-96;l6Lfqlv^280;ra89=#4l4E?jda*%b;fd<a3rWmO6J%&j*ZH0)B^rI612d# zfMG|*A(m)A9t~O`E#=rTUf3_*M|v5jkM*Lz{{iaQ$#hhWR&~6746*w;cD$Ew%RdUT zflrhx&-W-3IP|FMATiw0t~}{;E|u9(s@V4e6FB#nDlq5cpjpx%9J`QXYu*u>L*faf z`@~UH7IAvmi^0w1p`QdjC4g^?GhOa}G6>&>V1GjGnIJ#8O>NL(@3!+Z)-FnR27&Es z`&jwE&s9;5zw$p7FaPhWpmKz!s?g8QXwZY-2JO*bkOliAK0ojSrR2kbvq7M^^X9pr zXO%w>oex^0{Q262pjVYYkNp(1ng1z-K=xSIy2?MqNGQ1!^at<HufGK0c}-IL-ETqb zl|Mhb60}ME^P1XW`Mv8w`05E^U;ZQL8RgGc{t7DPe*#iXa`nxibqZ_ut)RD+Kac&Z zdH2?Tn#q^%2DQg4>v=vi>7gOleMoQ}RHQEWxOOXlUh{L|OHpL}uK*XmoYK4_4#$rM z*B*s>%jm*au?TR(?AoA;Sv7#K!=;8z4AQW7U9Qs{3o|}!>V(btt|4;WZO5a6P|Q-m zBex0FEO%()QUe>+%%z4Xs)cK(Vs2<Fmm0&Uhg}C0#Zex&ubkY*Ri(6Z|HDt}tp2#E z2_`OZErIGkoU<Xez0W>=#(=s2kGb|MI`?&Oy{HHt?&Mm<x)?-1+3;Ft*HXQ;HO#dH zpUNLj4^4*^;jX8NL%(JS^SY=_`f07~uCB$LTjKN`3*)<?4@@c4^$QvcPjpwba@p!W zu68gk!ZpkHzyzE`|Bb{+)S`#$m~<SQ_f(H<<6NyFHp1l(!H0w9_<qd<^g7ZaB`5@{ zGhHSqiFD1EE^&FKqU1g98U)YvLNk9eDXJ()J19vL$&6A=kTe2L_Qt8+h|`r~LiBTe zur@r3bY4u5HWGa91m{XUIo7+FkgJWKa9Mao8O)^gilTF=tW4nY-epBaEb`4@qIzwK zy4VPRW-`MS2%Y-73Z*$*RH-sld+S#_6-19GT{ESX9Kq{N<p9?vv1uGX>r6j%$g%-y zhhbo+4RlQqqvBxSw|FR<$YGO_Jb#dDqL|D@D&zcpy;z$DBWt;$jehx%3RCS*;%FdQ zc?betjDy2|jl5O<Zzz&Ki39sDc%WK!V6}KX4iaaDM)H!SD``H$HBrDb{==LR^s{=J zL~H0X(v>bmDlB#&o|LutNexkEjLRcTBfbz$vkl%_g;_%J+ZgMbDJ<o}bTpoX_r_tG zKgUJ7bCIZY48x64u43U+j;7ZeRdj23e2gnc_?@%pI6SdPDhDf~*myLLH=Tqh9**u} zvF~Vp{+%c|4O+vG<6Tq4L<LRf--$<wO)h^j4aeO&(Ul}FS5R~ao=`M~5tDEXUsQN> z5}tTC7z@Nt6f&KGC-TTCt`hOOs)@bWNaW(Ft`%a?7=GSe1$Kllr@4~F$T3Rpu-6%h zXETM+v~xm0f(ySnH3nw<rj9lS6DMq<D_&eS2KFVYd4=6?1GAG{lf@UtK=>p)6-$~v z{?Dxp4T=OoLQT^^IB_><f{*7@#VR}b!LijTuKnT-g<N+@bv<K)I=YXhxh6FW9?Onv zs$Vh)rIvb#wCPyhlPLE2ZL*IeRv|v2kZtuUSxu)@F;(HwH>27502r#)a3|hnfLTYI z+A9NHX%Lm@?8&~K!*#Y;;A&kt-IXBjRb=Ty&SVa|z*sIYTU;?dp3gV{&oHx9foqP* z#yq*DFbX+?+-WhxWrNK*u41v(INlBRMI0qG5)KFh;N5+j9MA{q?i!+eJVQ88n8Vf3 zupw%<n6GGH-^Wp$W)rA5-<2v>5Rb-Z2HZX5wn9|_rqa8Lt|eX*<a{A|b3xI?K0>4D zVpSQF*8q>qa%GFsc<wIy1`P*L-j1K`n&{JhJf5q+5f~zdDWEWR*j-ODngXSBF#AW3 zheW?%C2c6l4$O7s_{>2CJ1nLUaiOAs&bsqpv!IZI%Ztz#+k97!xQnBNQYEkpT<?mf zRMYIBJ4vd;9|$!2US5d(|67r);F9D4>Rli<pFrIcKx4Fm4#lpOOch^LaVoZgzKfM5 zk=9v^Kr0x!L|HWHm}gBDMlInfmlY;2bv;GWe7RH^Wt>LqZNgrc(ziv+Tt&p7vzMwV ze^|TRwSWuI5=@Np73#9gevudsRR-gC&<+M!S(GH$zS317=cPL*=!f>$;Xg5W8boik zq(by`=X%jJO^&`9jCWMo&y{JcY8L989A_Y8WjmKB<i2HfOWLw^hFC9(;aHW~YfKH4 zQlTTs?{b}4;<#xL9vvE~DK1%pE}Dj65+cR`rWwux#=Bl%Plc&J;?v2V7aTd#p=q?B zx1^tawuYreMs(?t*0XC$N_bjCPdFcruMyBPi4yb8wH(|E550Um4NgZo6;0!Ra^#rn zIJ31Ev&TipLUTQ*KkP+s^RuJK{7^hue#DC&e95uMY~%DcoZj-IpmZ?&g7g-g-d4xU zA(tI53;yg!WziiLXu0!M$4UIeBfh*ZA}Ra}SDKtz?|2SLxZW|+=?h4j|2rNo@ek*6 z*Iz-(vOn?62>oO%0}-kEhGV(l-`xxJ?B93*gT5}oKyh#52QPR2<0!<ZX!y%Kj6^Oh zxs7tbRxd^hFAq+W3-90~W%`v+RXd<|32qH?rphI5=cCBP_qQ|^g`yKLYuI9?ky3n} zv+(XE{$>v&oqo-k29HU&Z@sg)X`npC-<c%PZ`G<y8JTlX1+G#=V!gHmI=2ZBhHu?7 z61m^V<iwYt*;`mhdVYu5DFS=Dp7AMmW}6eY)$A23M%w2LN|&8@umQt~FVr&<_1G2U z+={<&h(7>Af~?2Q+)lhAVJ}W;f{!#}g6v%>O|WgK^C!IB-PemWyNUA(Mh|}`gQ3XD z+Gfnj7Di6OuBXd2Eu63MlZ~3Lv#p%fD2QvDM*90<<`-MB7>T?W+d6A7jJR4c5+y^Y zcFxyv2*+_JXy`|_cYcbI8f+m{%Z|>Az<$-5i7aLph{e6})rJZ`<>!>j_C<Gv!cNX5 z^pzaad)|==shyn**bdNJYBY=ta~1>p4P}L#4v&W;g`MZsfVCS#rb4es9NoTMoHNV` zDKt@<>WL5a{hV&-72!0}BsS-9M9T*vJU`;(EanLBnXBud>081P-qSbsEw*otaIP>{ zai;ei4*M}AkU1F&!+JP#&D9*?J)7&o5Yc=nI@!C2(*}=Ta%7upI82$`R6)Wbo#p0Q zPS+>*e0aRKbG%QlcwFQz1+~FnP>HAQE(;QsRMox-3i~*x`J^DQGz)h`SNk|06LaI~ zy-)@&{j*UnY>UNU*7kKS5-a1C6;-JRqzgl_Mm)$lYFTKR;G73tqn#VYONt2F^)ijb zS@MK4UNAywPEdqeBZ$7SzcU9u$O!78)rr$?D}KRtN3el~(g>Z0p(`If>5LZQNV-As z0JT>}$R3GHLft^D+?BT-Lq$&^N2_&({KgL|x-=l3l;sfi=?~4%>w}y*!n+DXsWCGm zLvs1RxQ95W3g<XiEjKEcT}YJ{1Vv~?hll+ucOY~a?hJ;<hdBq}X?cRMO|m{R3S^4# z1m~(%NR71%`i*eT7BV?kElBso3Hv`qSi>Pof#L&?7i^SxCRiNf94o$>SQ&>;t6oz~ zDb-6I^#t*A&i|V8wNmythJdEnOR=c#yEx|%@fJtk;YjZahhLn-nQGg)k&MCKlb z(zzHKwdSd#u~Hbq8CvDj?2H`i94&gdbS?*}wNQ<?5zdZxS|B3S8RP5OfE9gTdnaD< zC270zZsne5^cKFYwN-E7ah)n^sXO+a+=zE|)%szA@5eh+eU7O%PUw2j#!0<}Hcsm; zwDCm)8((o7YPoJOg!r@B6P=R<{KyrHlv=(UB#{vkCpi;+nkFkRw>}Jumm!v2x3Fx| z<Fa$IbEPnXbG=JE&?bk*@xl~mp-{*nTFKX<k9B{e=-JNMYWdgmF+Sdz+4TKnEzn)d zJs(m_4d%yOQduQroa!wE;U*`l>qLXz8{uv;PITWSXW@No$7rC^crD4frs0x7yUM6u zSS3(+{{4$b);wNwjc_}~S>(Np{M&E^!3AnG{F3He!NN#8zUl9}Ubls%rS$BPmew;R zv1eqD<j5qs^Fh}?f_OQdZ%oPH&2&~W7vT#kc;o1BjjPyvGac6-{$uZdr$h8ud}oFB z(1iH-u*)Mh&Y+^I%I}zLOM{wPhXLx2xK@g&kzDA!AAjq%?QYi#`X-tE`klBegVuQ% z@}f)ouu@s^uR0_4Wt{=^<`9bDLVZJhLx%mp9aBRCioVSgXK;_`7w8$sKG?MgDys34 zyh7oqrb&jbTK4aA6^d_jwram+6285YpM(4GA6`T5IYn4?f`sw<JOu2oyJq9%*N%Nb z5vn)g$t(<&SorBeq5m7M`OFm-3;B^ZUHD1xwVBEl0lT*(Zp;Kdh3W_5#y#^byhubc zn&DRjv2VMU;w#|H3jYcwGSBa}q(Q&+Xr|~L*D?kt3#X2{4*H0}9yt9T@)I7$3$(vK zbUkH`^3ZO=j(Y{hWPA9U4}$G*_qZ!d^zqO@vLB3QqBM}THNp6c-^Vc<9{$)hT5Rj7 z*w+ZJGEkOnLPJmB2xEh68a{Dd@)4ioHsy)6u4+MR&G^jq9&5?Cu@pr{X2Fx6`O@_~ zfhd%CgCGPBf9+Z*Zcsd7BdcKXMG)6&@c?J=?yDTU7ZC!U@9<`(>x-trF!)<nx_Hh* z_vSQd6|+&4rt9gdYM_g$gJ)f{#EzT`><%3hrqsFmJ&wef>2zyO(`c*18$yVnzCZq( z3;e|YrUPE%osnO??)p*`$7U(x+oB%Bf5q3GF5mvkb<$sFu%FI_QwDcB^uOaOMR7%- zZZ+N#xfSS6uNdJjFKfPQ6clfC`N7_qp?;8Ma@$~>;9en0S$sO;{v{ARMn)FhE5!tb zOyz{g<9*!u;+||c;p6^U+?7S$kkKEfAfC$NHx?iFcV8C&%;LKvwn2phw_NFfm#2#A z3jywRV$*C6NEnJ8dPQ<y5}!~gYEQ0-=?aDQLB>8z@_{+4T#I~ja&SknZ=%oRwurE# z@U(Ee%#7&Tt!I}oygpVRg~=JK@m2$$<a2X)ibSu)Jfca36ud@Bm#3|F1&cfbRM3oa zcGsVF=?aPMrTk#oMwbIBD_slBJ#s1WU6}ZYNIZ&3+o5l$1Zy|q+P)cF1?E8<;pPaM z8Z(}8%@sH0@J`dLM_H`?9<F%jX3YL0oUM9DiHt>vY&)T7yDLDxyv1eH9gce{h~%Ae zn`d1+bgyYb9U2g7f_}U3?g;bpfGt(Pv*%M9H7cuhO=O=q6@HLUSlpvUIFT!b$WbYN z0fOAu;ZE~mzlgeHwtrJRAyX3?BHQ-+`{P-gLMi0U3iex~f9FE<zoB{Tw@Q^CXcd2~ z;6L@*C)B;9Aq{`h%#=rXNWf2}dNJuYzKl)WPu)xVr-^&1LPL*Br%R*6u3QEE{QM7) zm@5S{lk~%0XfhB!Z|0ukrH23H=OD!{tIxW=@Rsg4==_M=2!Hi=&u%~;B~Dgd#Sg3M zECGLf7SL1to#IyRc@5}a=`H+;+As80{Q+qdggxS3tdN+$^dnwP+PD{B<Ttf(ACd6i zDV=d1;lEFIan}jriWzDd$60}rrRh={Z0+t|D7Ma5IP??QoFkX@aN}!13JkBYLZJRh zH!c$W-M(-r(p_Nw0bjII7TlXSYGd*3)Tm%{8z|a{MVLxJ^B8v!yxpro_~`f8=y`{# z&JPBK-Veb|L<nxN+(lk}q)}Z|iVR)W)kKRL3j;x@(A4yGuT^Amr1!myA;Ud+C|+M- z2U-lruAJ-Vo~t8fM7b|{*`o2k$IsuQ8~8~O_5M{5Tz=x7A;(l0)F@Q*6-S1$i_H|4 zC)4MJ5L4|T(kU74>7X!B>!6CD(ZJZ?H%bS&=j&?O4;k}Kj~*ZU;QJ7Ijiv!|4bggq z1}L}g>38#?-iYd<?w@s=)x+HNUSXp&)U&1I2={F7MA<L{_Kk4=<4x+6&sT>AUaj#) zBq#_qCH$aktUKQnT}YKO0_)%purJpAjkq{pFZ<{dCAdE3!$!F$iMtetlIiD1xxexG zFkiVv{fWY4OM)tot0(25FI0|k7jUZbc0=A+_aY%mzBbnVt*_~K?oBXy69sWe?lkB< z**)JR&Lk(<Jr9N4Zi;)J3EvfD&q3LZ4uyPZhjX^nijx=9ZBAQKkFc=rcpRg9j~<ap z-IKi5AE?{z^o5YAXrL<>VNp;t`A>5foBDHd51sr`q8m5*@$Nj+XwK`Y@}|RY@$NaM zWKND$$!YMv1oskC0VlKHswV@f_>n^8meLv<%s7rdEai~?D&&Hxj8lfIlr(rQ*}d4b zlaoiN<N}zx%pC<a**;;W{hT*a<>3#Er@EJ!j&gF0PA*Er{(a8LaXNWMx_g1?0w<?v zWH~+qr;iW?Gq&LFCEA14ZgZhh?dtE~`=3$r>FI8Vh={{)<Hl!LjysRRk(eg8%EJ*? z8@FfR%Aqzc7Pt$w#^IT6e2G_)d2_b=Rju*yT+U&}<(m0eA5_@3h3=JFV{H+ZIfVm7 zSAzrPg^S(zI<BI!XsLU-*2r3hMN8!jU*V<lu~lyT;I$&t>1oVOwc%Xr<)F0Qy-nko zOWjXvjk_D%_yWD6;BL8lq1L!i=`PV4-)wa6QX4>T=3aS*LL*~0uV|cv<4#}sqit?{ zJzi0Hw95SsYfv;UKI`76aMI<wyWIFLJHgWB8_#+5<DVD2;`GZ)?l(1U{;#?})EeFP zx}Q-Sk}0zwJ`c|@!r?7aFFERqpgw}%D#{2N)#m%%_!j*e{8I$hH{3f_K{-Tr@75ZR zyv2tA)8YcU7Htd;qEE@2-o??Nb~^m?F0R2eE1a<Yp!;`o6u#@EtclMRD!X2Ma$os7 z*6M^0abGZbk~`PbdI8OTuUf$#?-Qu$VO*G+)VODux^j?L<zQ7=1<f_}=X|dcf|p&K z-{y#WmT5HSch;r?dwS3L9geyenUXo*t8lPqJft7_CK&j>yTDYyL0)Bqtxjrp@b~9G zaL+a^<shw|;B_26ylManfcRtBr!tQ8DlzzoTti}g;C!vtq``gW0${;$tYP~(QY$(4 z+ARJEE80;G@~T4Y3R-szK@yaI>@GBY&XHPSdVo5~t5#j$aIad0PYdr=T>S~U@CQeF zl`k#Im=C@{F04tzQ2Q*Tr0}X}4f}rLB!=3_L3(|or*G7w&rZ2V3jad%1Q*`M!V5V* zoxCDgSL>cEHk(D)Q7RKJKDgWeo^}_DgJ$X1RVo7S0dd6RpSuT$847}3Sg8mt?V`SL z4-!`?2wGtI#D}o2+|A@c|HJLODua|X@l#b9`|`R1Wf!>Aoy~u_O>)xLIKPm!__}+! z?D@w1lBPhz-Te{A@bkIuiK3?$Bu;0YkH8O*E9$fmzH`<+T$s!O>^86pP%~Bj@Ow9Y zwc=hcuuJ~(nL6D5s4PVwK>qp%H-4=_5zyu@x-&`mMX`g=l~jOg2SP5oM?h`1s|P(} zQrVh38SL=0z6gQV)0V%uX9%%yIve}QZe^;n>J*Yk{i>I2U2M!{cM^W1hQ#P28;Z;9 zeh@`^))jZY@Rp(%A53X_)pGE{Rd>Ab9S5)<K2iZ%J^ApOJ6pt$N7KV!_IpPvLYr=^ zTkuc4dzjd2E(o)OA`yXudPy9hNU_rwsua7uLY`s9`a|bG@TLHs-DS$z5eyZ@9y=2% z@lSV_ZT(#DZ+LA`w6b#<Dqc$k%&f`ceva^CKVYN;L>r<vZ@8z6Un?r;vmOdU%k;2Y z=-AIU-K#{OdE}ViTwRZ52vN($4je#V&{kd1X5FlR+$mz5ionkt-iLVRU+n!H#YmBE zM056&+wLjiW<>@2?4hax58k{W9+?M1vV%pNEq!WIn4#BQcbRxamBNo3stC0@Rjdt; zhlB)I0MtC`BZ-dryqha@57?v*@Lp-5#U#lsc2|)4f~%D%`CBnq+w`!DF+P6H{e%7S z=d*%mh(+`11c>U3)<;Cl6`$jZ@h~91>8|!iE$0&gf^)?ais@1>C)N74LJA%yw%r8w z35F0KPlrvA_>G{2MXPad{U2NR9iYSUKXBZ$=gujo-NRFKBGDsyFA+izy?1ek)ywHT zr}q|R^xnIKJct@42%;x~1VJK5)I^Qn=RLc7&&l_9f4pvYW_GskGrK!8o7^)*@=o}z zPdLWDPT?6XMMa5_o-9H?_)QeI2XYi9Ri{#U`dBg6-9d0olxI|wQGJ9el*#ifvgrt` zz^~4v@z~X-^?S=@nLWF+*BzelNM9QNHVBQCmbOGPriQ2XyccG+8m{V%O;cK(Pvhxm zy;7*3)zdiLuuytwH$7Zx5<71g<(s{~yOV{P<Az&x@E)X-39l8C3Kw<X^CVL<vUxUT z4Th$cdG891$-MUrS8cL;N*hOpTm9Egbj$Q*a(Jd0e+{=zcHLp^!i*9u8zM!pUrx`q z2-PCWol<2O72PU0t*=xXnDKYLQfW)ID^;p+;SWlEP^?|M5-}y)^DM1X@ZG-Avt7oZ zk=7&esQBoV!9x9_Cx?Qh!feW5!2!`z5`uy`2ieo;ci`EF$g6*H&@ahz43ioOPJThj zZ+ya-l44(Y&=?UtN(bqe2bCsAhpW^R<*B4BZEGV|>J7?8Mn6<{mWh*Dh0>KD9o^QL zWTmqn|2YYDEtpWkj$@+R8(ZxRc{(iV^ds6(l0Mzje`Z{?^U{yjoxDOby*6IntnM2Z z-OhM9(t1wpq~S!h7EID~H?oh?%dX#TI7#FT8(>tiBCO}cPRxH6)*ByPKg^6BWj#0k zZ=&|b_))sh;A~iZ&@=C(s%We{i?3A86&YsAWISP(x6Ofqo=P*8q%1RI<DpW)t9d<P zE~D*e`=0A`W~q_UWwf=!<r3mkiwk+eRsRB>fE{eTLg4CPMGY?K>1+%gZ5?mU<j&iI z<Z4<W&se6^Pq&A??~(7I9#5DVA0WCg+ImxTs;C_D-xrbjNJzq~3a&9qqIw#?IkT`Q zdh7L28q!3lH^n@Cn4FoZvQy>NJ1>pX7UZr|zk1>eBy_}<Gi7e)^CGFINB>|%Y?W(L z!MNZr8GMFI$#+RAtN7Xxdx9rsMc)dGIGHFi%v?Q2Rqo{V%!r?R)7Ytpy))XT`X$W# z&Ke0WDVVX0E74teY879`U4<<kaZTqGT0MDAkV?H=6x}DP>R9UnWF^o~jU_S=)yN8` zLPfzi>qX0%CDB8oVytlLQaIsjmPHSainGE;BnqFkJbGZ%Xe)ewqVV_?(Zix<S>Xo~ zh4)-3`LDFX&m{_Py()S{)OIWUd?-9ve|5A}RnpbbWKs0{m?~@KDq+2qWa;D;Pq5s2 zxh|-*(tWo<5LJmPY>b{J6?dq#;!Ie2bMz*wE|wjl>Tiu6sUG+uZs<OqtV&r{p3kh{ zCDW6ZWP09U1@mu@USQS9azcs*qt{90Bx+sQL8`{i=<l7Ee!AL)L{LXah0V>9UcGGZ z9`ROpdR83_Nu!_1%Ox+BI<-d@Q-9AOoy%Ev^>kl!(8<=Sx#dig`<p~Dx?+VBQ|WYc zvS7<YQq3uX+aNnQ*zQQQG$YX;D3u^xf2rM3>M!X}kUFXA9G6u3bEAo}i%<<u$Q#>Y zW2`e;e`{2tT`$wb1{<A<j+Z)6d|cGYLl$7SY#zQVDnaZP)#+^Xc4s{z_^7Boxl-q& zCnRL7^mjoeO4o>5a4~v<WWxtPC5TJE`fOpA461Wqca327_Q|Dgn*N-pL{cS8b^kd! zGC1j{X!$kN-|9>puKrk<C9P_-GimE!&r4~grLg`)r=21wQ_itJzbrv|m-M<8z0+A> zrN6l;G3{QuJE>JSLNWU5n$9Hh+mlM|9_*g*_MWCd$_nUpO7&ax6_@^mrX8Ywj&P?? zZSF|0{Vj_KKA!31x$SQB3nxP9k7YVB@BJD5+KGwabD2)W!UxfhoCxb%nf9!LDIP~l z6-51oObODzr5`<wo@IU2*`7T3(LZv-srX(?!u~AqJo-yl1m!>{(I+pXcex@c@7Z}< zt5I&Ed&k==Us!7XI{B#Y-$ehbwls9jCq!32yyS8x3-wA#F^?#H)-_M+mhNaa2le+_ z2xa>*n~e!8M^Br?@XHVkPwrmoikKBzNR=+7`;3z|LRk?UvZ`g2`?M3Gd#Sdwmv`a~ z{VCLzH0}dVbi{mXI(@mho6f!86|qo<1Z8n5BrJNwVk?>6rkyjom%AdCS|R$#+?mat zT9sMgo}>bq+%28F^|xG@wLY{rJeCsFW54@%Cpu!KorBa`RI;H`s<v6&za+%2emnor zWNWPmy%96zbWe6g&>f!4hPVDf_dD*N<WQGx@bs4B+-&}?d!jMWIk$IMiS<d)I*)sr zbwS+!o?BlK^<|@OKKE@`#O}}n1eX<X4{}8uv_fQCbqtO#<dy^LaH7n{7k2jwU34S9 zwW9Q5wk+Zv=8CvzXGks0YQ@}NNtMhEQh7_3+*z2E>ZeWa`l{|XNi*tid|h`I`lp2X z#7fVs?q#9XxnjlWOYzV$?#V{+vGzsmmKD=0OzJ|6D(4=o3NN<~C#NE11J$*>J6=Cq zU?Ha8ldE~t3hv=n^;Ze85-ybrE!8TzN6g-6ZBq&DsESvTbh=Kgm9As*bd?*_Zd0qq zr&U$E3hn{&X*=ucsPjncmWtbHyGgbEj32rOS~ZfKIllbRJyKOFmXNxmx?9CPCSs(u z^h*n*&7fMP@<{i@AGre&`>ar%>A<S)ixI~Y1x#Bb-#pi^d6op_n)6FFSq#cDQK7Po zSy9RxRHG^Uu{<=Z=}xYG``A4oomG-?3Owd0J5k#d{w!)*LwC6PtGYWromHesNOjLn zrEjRn>P-#z(8Q$`wf__Mw^0!@|EG{5k3Vv%g0<y{zqeS5F&V8CiHj@xmbIo^KB-*W z-81T4D?#FN%Y&l4XlpHVE&r)IE~<o;Vz{+6bV(>}R%_uSNRdKqTP9USt69ks7j*Ou zX-!#_#&zBOq8eKX5|?=NqZks5Tp>lJSSvx|qL00-DOI19QfBIBB}iNbsyo-6OAT+} zj*l8+MJ6f;ar>TAUMorddz-i;Rkt5AN{!3!l`A5n)JCJWz8oj|^w3XGYRa0FZy`wH z=F*f&C!?Figk<`mC41vaQ+E%!H@C{zP7#XR6}{WjG<SD4%8k=Ep9$02Yocc{+K3rv zReN<7KriX(O)~RoE#03P6UJE;U7cuq#wpZ}R_-CjR(r;}^1CGI)!O~axM&6HdahR3 zI8~&rdxY`YPVJPqB=tBou$_B@k#D?S0jI>Jw}d_{AH=%Tsi*DT<Bdk+^~X;V)<TwZ zrx9;WXH{`^7E#|{U2E^opw`B?#~JJGG`eEz|E4MOP4w6>^Wu2L$4?S+*LlQumg{}} zPVOdQ&*ke@x+%=R_JZ0avaKuKW7YW1?yg3z3Dz!f3TB~IkTWYn-Jd6W-8{<8S~WYR zQ(n_~+?yx+vf1(I_F-lhEB>v*o8D#J+<lB`c4R~A6wq_gw}g6G%XN1*G`_U+Ph6Ix zmW?zaVttzRa8EUUw$nI;JAHqvH`$J!?y*MliPrA0OLz%$kz*=_D%{7NOr`AYZfg{> zk|h-Pq}s_iqT3qv>=>uir*kNjO-|MQ{oPTjWnXs_qpzLDDg5a)(w-)lHHSc)ySbs9 zIq=bTXWzY*CPJ<6Co8?nPUw^e|C8Ct{&F7tGEqOjBp<!a-|r*)#2DzFVx*X4?L4P| zsHaXi()9|r9ORyE6t~hj#YLUV!WefdwMUAJMq4`<r=+MiN2;Oj?Z#9q#wjrBh}7|% zV#C}Ejop*f`vJG#IAEtrTyRXd97yt=VGpFm_mWI*Z<zVip4VGtNqv;Ci`EQxUo!Gd zwsvCTLZv>rtB!PkZ?v*voswlxmg#+$F~JUX3YVe%rjO#PW8B@0&33+gdR;apk7M+; zrr%h1Bjc={fm86*n`r7dck2RACnr29D>Bo378;YPurKwPQx*1Kdj^S0sx%YbX1q7W zS|hu_8rqCfVBKjnwPN)rSrU#Fy}~;u$zl(kqMuME#86vLAJ5K?NI83odzP_oimEit z?GM{5joP#S5+<8^o1L#ytkqX7J<)=xQbf6KPjEY7g1h!&@-S02P-ro0tdS<*7l)*5 zqaIWW&nRtZbDWmTzf=6x+gch-&XpFlM7&i9mi5o2^h{6BkYZ`9mBKC!>nZhBKu%$| z>KG-9WzMp4=j$!3vn<6}CC6$?m1&(U#s1muk!ki%P5k8jpp~axQcgGpl;jz$vdxjs z0{*m8SS4p`z52|R!#m3~Yroi~=l>iua_Jjvd^Ame$|Ygz%Q;+_qV(jj9&(@W^7*r= ze@D7A8Uw7X63Wz}yyAyRcMzu*$`s4rnqtE={k4~boZsHBmp5feqk3d<_YE^IOjEs< zx=R>8Pt#w1u_wqD>UUvA<%nuZ7HqSTY`T>+?R0C!?6SDt^Iey@V~nD9gk2=pOW9|+ z`$*c>(-Uvfc2=^4a(cq=a>|u*JsM+YVinbca;mso#zs4ESE37isDRdQwR@lOvz^2) zx$BwhYvPMF?)t_XJJv46>sT&jYKtiss`!oa6EL@syH%L^&ga(3B`)0CSCHgN7XWIn zch@sMmSpSP`j=7Ge}a0oMlLWtHn=}AI@uZ61%5pzT?f{g(<EcMl_cQ~K-O_Oh5rV| zHhbbwkw0ek8=qYc)pLKj+1<~$Y$vnJ|9T#Ja}?g{?kSJgdp(mA#l8j5k@^)5*T9%B z+=Kp~djb7JC<W&z)%#1iS>TN$M}od92yN%V+vJWxw^xz4(ES00M5QO5vfVw@zEcRM z`$}$c6YdgZY_i%IbPsv^-awby6Uxv#cDRSWeSe@YR0ns;^QE_L5_F;R!Y=oy|GiUi zO1|OhkFVXs-nwTvHd}5HbdLY*c8~bqy9cLn=>%3?KYr~}-t)C#yqRy^&rhl3nd(Xy z8~veYksf0M2Pb^wnI0M&QO)yH!k9W(-80pAGT*v0Q@m*=6TM&bc7IS)USRzBiD!fz zTtRKA=~-u_S)h+Z{e_E!33N?uJwdkGo(@J4JB@Cj>SU_ZEUD{BscL-c>1{MwpmYOO ziIzikn39-OYD68+XU3of>S1F!h@A;_yL5@(VXU_D<y(Xav9jf)o+8VdrM{=Dal)B( z;`MPV52hhua#g#5JYJUE_2cFD8hVBp?H|gQN-C?m-BP@xQZ$mcVC^5OrE9}8h6SX_ z;F)15>Z!jPd4|6gn&Yd8y6SRc&w#f=Kd7IquG|RxC#?=$*VHrkt+efKB$Gy8%{(LD z3SGKO@(ncq&oWf5nxd}yvyrT2w-*1Ir9{<J^;&ucy_L-ew`4)4HIoS{wfg^}a<|s2 zt=G~BEL1thdFrWDZ9Jo$ToM9bwebuJYyU9G>Va)N;ZbWA>08J0a>bKvlq1fFRrg{% zeWG?);T5d#12v79;F(xY50_-8KLWG5le}K2v&cHy^vP&N1jn16;ZCYxudbd62_x;h zd*l_B%;kf6uGnCco{6HW_qL+QI#{l+N8VdG>5BBT(y4kYlg6rd2I$Q@WBQqB)uVc< z1}e?KP{3awL^e<_23qT!?p;a#+aS*vmROR{sPj<+bz!hadS%e#s{0VnHHH%olxZV9 z>D9MG|Fb*vaZx*!H-(xyN*Yo;YxMucuL*d@v&0F<m_9=EE5mssWU8Z0JpKPSzV>99 z;rikK*`4};kt2N8TN7BJBRvz|3e|^^vv6-OLAu>h_0*@6W#+R+|7Q-?u{6SyNzEGb z|3wWN>zVA##y)I*`_FhiwYQHv<{LWRGdxO;C8zRM^F`L954~oCCU|;Bm07BfuX3T| zNVT5m858x16>cAQ9A8Rin_hLABnMw}D>Bi+rzFQl#_2`YwMzeR$mTwCLcUO1X{xkf zX*|VK&3Gu$4bqinQJt6=!!6CiXk4!!7FoxrlHHYFHJj#XZIrfS<K??VdKG_^qegGF zF4H~jjMjGamd}$Dt&e<tn8bhXX=99Btge49?|Iqr3DeD(A=9m~rqk~Z?8)@nt(oa* zZ=AF<)px6jGu=B&GJRyn>N`|BR(>*OGW&Kv$MOO@z1p`xF1s(@OVd|3OOW|rFP$n@ zIR`?d6@T|e>V7QSneY_yaSU4f?wKn;5t7gJGl}y#GfyAVp>s-RmqneLuMb%rs!yy? zMdKmkJbD(KN=lz+y5{(?*`8>1bfG??63)2LGHqEZ%e>&WwM-wBmu1qcqJw`_p1#(r zR=sr5y2hX^MtY^A_bmx6%d{o(^XjZkB=KWejE4)PTpr5s`ryzy$%)=TEm*G4eErQS zHFkw3&Umsc`0ol&URPB3a(#%>bmYx4>s8*|RdN(clM^Z%XG|16Y_%sYDz_ExNfaKl z#?wElxE1cT!avyJiB)yhdIm;SwZeUg(wA8$=^I(${zT!q)=T;rD?C%8@YEY*zHwG~ z=0xF7H%LCCt?(>~!hhcA84xwg3eReVS1yw&Rz7hq-@59O+FZU;PT86@vn85j&1TP# zsBP9H*{yI{g<ql$SwT4xB^|NV(=Y106;3@$XRDcC$kN=j!g<nYhX)&c$t7II^po$Z z+dX6Tm@d&24SJ@9#`5j-jM8Jee}ar(dxq&To-YSq?UtG%<f6xZ*sDuI%Mx0#jgPvs zLhrBWggKkig4Z)P>bVu}P6&@t$G-7Qj7q*T@qU*kLw`m2tf0^?*I7iXpALEYM&-34 z6YqCvTQ?=Dv=wgecdO0a5zq9f8diAX{VwUfs_Z)1e9f%L#5>=6K_V|7l|9$liVPhA z_F`N;CW|r9icEYM=xi?^mu$ydk%^B5IXA;qg&*bIy!@T)pSe~F`>4=M8%lBIgrrz& zrAT~mNX@Hob^N5P>`p7vK0=(8^{N}E<j6f{MJ7I0<dh6oZ_dfwZ+$Pv@Fgon;-f|{ z{LRy{@OP}pM28N~(8JZ?!!r5JGjh59ce!;j*RL7mP|$6)?wplMOgUCqG5RU2#OQLb zGxPpNwH4N5SSLodbx))73hU{s6DZHA!`1s2J+a1w71o1SCnmIo>ipoTZmhRwrk}k2 zH_brfv=yzN!Ah*W<&qafm!yOsBf7x<$xl-7j#|G;AAhOjxLmnPxvqK+8`Gt;EvnLN ziA`!qn0~L)`DdwnAtQRqI=^_<xuX8GreqKOzRJ2{4Y}rtQUk7gdPe<gMY4yS$mTcX z+)lk(&yJnrgzJg)<NvHyB>TmV43@m<k+z#Mrq9!=w>@+8n64pE^>>dn_mnvO>Z!{g zo+Y7_z3+Ke=`nq_$N%YBkuaT#ADJ;(aK-})dor<Z?Kl3BXJ=^QwNE_D62{aQe@j8+ z>M9DEX?3XHAUmJQ29e42OCnw8=h`dzLHg#oC*EFMt1gVb>yfAoYQi;7kEk<i^!g{> zXif^ZwdJl`DH3lv>S`*<V`S7rD>Cus3r()Kp=+(4L85J_^gXLyy6`u0w@_}iwR>rR zYj0Sk8z+-wRuykoqupxV{?>`Ko-46-gI(Sk#w2Tc`G%oX&~egiF}$;ltxgQ}gq)a! ztX1-)-a*EXb{c&b=cIAgAyQQf_YO4PthOpMInkj77!l#^Y`n9^s?p>`%aaeid6KKm z$-KS7YOIk@i|>&xxXn-3Sf``z3q?}vTSC1d-b8x)8GY<%eU~cH`Vn~H6yDy(96RR0 zX?b+!%tqI0(o@Hz^oI7mlr3hEM&I{ItD>Z;W|X&|>s^(jk+)Qun9n*CiS5v#RFR^k zN|q>5L?ut{En)aqsxzxITnaOf%+|GyW-M%cMP*Iv%`a~|)%E<|pMts5d8;Kgvi_^n z1*>KB9*s=&X|$!)!^^4~*}NY()sz}#_jZqzHuidAwK%W0fYhV1MpozZ7L=oxkt^zp z{4yeU=Q5JqC7ng-B*7yEy?J#luZM-aQr&B^wD)EiP8aqTa>-j(YwUVa?|sASjKaOn zsxVTfq*uDW)ZI`>kbW^MFO-u8OPBU8uzTUL!)M>{B@I?B>y-zjx~~Wc*5`AD@?Pn- zQ+MrP2U#`!Dpe$B-JgS<L$GXRuhekS-8MK==dI#hE)^VTLoGqpGa5Q2C|%VXulS%P z!3U~IJpp}w#@F!5Q-W&Vfr_?6QSNneqF7xHWRS(N-<8gedbm-aK<(usB$Mmk7JUfo z$y-*J<8Rjn>#)*2bJz=Gzh0@~?PL66M>`uv{|M*@3Ob9OpU4p&u~A*GnZ7g&_@C%z zpL(Ozr)9nJcrO1&-Ekj@<f+*(C6lLC1!{Xc8g)17zWWj;*WCl?++}k4vi(NghhIXp zHS;<$;hc@uqC4AB*QC@FZmjF=uOETP+(MgDAM-kXdp+-f|7Tn4Yl}{>x4t*<_Ery- z)upLo8WvxAY-=D}NM@nWmYS7)(sSKLD%Q!D*iU}w%V!_Z>TDI?tKcWiyb-S8(W<^n zuC%+^D+#sqc1G&+#wf8_$uWCbeOcX?$2hr3AE~Q@HGD2(Mlb5&c~#*7VZX>DCg1n} z$szHXH?6iWFIjQat687=3dl$>ozGX?rJmLC^_Pr;z3Tep+P{0FwYPq+=bPbF->@pJ zNsO+L^0a|(4(Y8<*mUJJXQGJ4zR3wux<fH5CN>z=)VDq%^I*2-zPX9UTKd)|jH&lq z`x3gZuxhPI9-MfbV5&@8U#PkZor*cL?%Q6LO4i9*D*DP~RrCp4v9C8GIH`kA3d0gK z{YR-nF*w#YHk4YwGqp1c4({X|p0G5*&rF{@6|{2-cJAtv-&i}P>f2qiwCh1x4@M<M zZ=$%Kz6l92x>FxJ2Q{#FqP5c<`bdoarH}9Hld8dXI%i!|sCzSfW8SW%q<is^bowWH z(EwjSuhqTO(MrBx+fa=e=o^+0vSqB?!%4H$IZ>g5%lvVZN;lZ|C~;8b&Gywns-vsZ z6J<kB7~&h2IK^x`g>E{lQ%oJ|YiRtm**e*DIZ+l$pXoBgENa;>Ur)oe#fsL2MTy>8 z);G+`|4hKw&&adIDl9q^>Qk}jG+#;;HQe`^QG1J3Y;>aaIj-mZ{s>>Z(RYhgc66fk zPpA_esrrrd#Taw#1<(aZC!xNHmgd)KtVNkO$~V;b#!9G*k_qXk<Et~gINE0#zu9@| z7yC{cx$I_9Z^rnR8}6-oUG>|2CstP=);Y8r=ZiDSZnfU-JJEV#*^c3A-gsXVqqUWT z^`75JLt6|MB3x~q;Ok(Fw9`1ptaR?9w`enC)mH1}zD(!@CRM*r^7S@O+SBOH@tl11 zynR!A1C1wkw0;xdOs)4q)2Y5zhVKh|AJS=_MC*Mh(Or!Sc8qg`>zyz8jx#>9W1J&g zUxW2_IQ+S<xiRJo-OVexIn(Hkn3}_Vtg+Re+BwqY=0iH#n&tc4Ij(1H*)4tjO06Gj z@06JB8}3AXo=aj9j^c9a|2Y}5sETuZgPB182uL?^HyE)BH;u!?Rn~dFfmZv=imGj^ zG<kw==J}*)t=%H?&H|r&Q*^uPb;{Q<cxRC>)K>G-5}&jnvy*+Z%r`1wWaElNBXd^y z7CSL&(Hh^BgiFPi$<lntnqIA3=Ubf+ajm@kde{+Cb2GK7R48kNy0pQ!G9gKPw6u)c z9+dA_Co`O+Z?^b`I0?eb$klSYa$WLuv}z8%`NFr~iB#7fNmDR;2HA&6&q=xe@vV6K zx|8-w#<!D93CcCyx&G-!ZFUA<?DXw$B6wo$Wc=&bp>X|}(1~#G^__DjP&^^DBZ6)B z%de0#()=6W-h`3BA)mC!wPzT2#22b)$<sb3V*XLz1S4v@^Q$2BekDeBTvs)#eC9Oj z-YMT;X@U|dzsbRL)l)`U^?;rEojIZRQ&7^EOxUDp&LrAjyu`9H?5Gx8l^$Nomdq+0 zoHa>bPgQ#1`@q?LXU_T3B`j-=3vwJ^SQM1fvGid|)e&c58~)&%m#`qz7m?j5yX$en zq%AJ{zD-D=o3U9(A@dH^|DDz+RYI1P%F12+p|t*K&Z1arsT;G|+fFA*dc*gnle2Ea zW=G1IG~Zghin=RRea>C`!<Sq&yya^spZME)-&=w<9nLyfw=sXn)vD8NUsqQxoj{kV z{+lAXn)92lnbCBxz7KL@_3OSZzx&#_dRUX{Ht_b+(7a8_+{4xPcYKXqpIa%o^O4Eh z{o%VJ|5zaXPR<G%rC#6lHFf=Hh3ht-lG#1qKd#qSknT!Bg3|d%sp^0Fx)?dXvMzUt z&qZAiQO~%~U%pXBO*={Av(mb~W7&caq$IL*k$N~Ld1+_0LYpPcBj0SJpPhkq&Z_H= ze9w*fcG&5Kp~F|tH|>32gqr`v*VNc+C9%(BzEp4D_cB|_Se`pS^(`{)I*XU+oYqwg zr~M{B>^hyC-75`$Q01r=ov@7mNiy@9Z@f`8Xl)GV>}D%T2C3AY=MvjfV&ydeD``ih zP~~3wCK~gd$)w(>vkByP!QOd#38ugDtul_==@Omt@_Ia*diL5EYuvXZc_m<HB9U8M z8C5#NCoN2~NiQ|_fkB<CSv~w6q)rKO;nZ8RqeA;d&o)KztSQyRBfh@UhoF^@eYuds zXOy~a_&d7BTH#bIbMn_mWvZn9InqC(o;fwjh`i?;tzyFcy<I<8Gj1N5v7TmjgnyNh zbf>D^F0`3mCG&SN^6s=YtbGO1`%+Jl`jM1=-nxtwF&a9FON2J3yv3hv474K>UqwQ@ zabrq<e`ATA#JZl)r$Cd$ciH7L<WX%O`;w{Ksr+q>gU*a-M7upWJj$QPW&CLe+83Pv zEb6MOzDZ%GZ<nrg#wJPUAEz!>$eda=$>z<VDxLFn3o}33Wv#7s-3dw>xqazj1tz}S z=*EgQrAzV7(f&Tx#<v?QR&o1xg&8UKTD_&kc>TAW%av{oM+CLQ5BdEGEjO&@ZxUnI zN0CE6i>%|{d+cTDClyWq6C19IWc4>U{Cn-Ao^JIdi7unaF?Q3aX~j76)DfK9QpGB% zI+NY6jDGgCx|1tsT6unAC3!EWzaKg3vPRNe{`kn(d-bh&G(D=63LeVkf8#PD_gS|D z`QP=+ErE>bhxFb&etDWFW6U*}DxZH)XzYG||Cgb$WQAlakW%h-ItFtW_HWZ;`f+~c zBL1_Xl!J=-zX^>kFX8`Ak4X{FR6mvSPmfx?-&#C5u30L&xzmrRbC>r=s}yDZDQB1Q z*EPKR^aj&UQ%Ocwt&hw2dm3e}2ztwMmRyCG^A9vy@6(UpB(Z+7EZMa+0#;({p_{}w z4cwB_!C2F5OZFvHt&?V?%R^&Q(QcLWI&D1<TkmAT^Et`H={+#1(u>@$qW|M;CqmOo zPTz;dB&V~I)0?YFeZ~)VM*1P1WTf}Ce$Kt1lD|c^XQ8PikC&k_$>U$iL-z<DwqNP0 z8Z5^|x$WF9&vDen%KnyF-;wPa`bNNep)r{}-+op1Lw^aQ=zgm@hcoj$Rs5~9HVh?| z`8ElS$%M`IgxS@#9_~n^-F|DIQ02qPL2gIFt?e-8BmbbR<3dwQccl~cm{UD*iZ!{? z&zNL-r&G0YWTp?_D(QS*WQZ+XyuCD;Ez+(-@scG<wkuhvU(e1nS6|QIbA{=4hVMmq zRh@h8TZWmH?$@5Fv@@bxsdgFUp~#j4JQOJ$W~@BGlZXwjs7l}HgN+BrTMk$U+xwY( z{iEty;XE$3!-L+;zA-Mz!aD8uJ(OzwDYMFRj5`OMvYzxXLA>5=@~N5#<;pI%7BVmE z2?6B_C*BpMx|a0y)n%km4*H3zJ%?cQJHCB-emcL>?<SrVr3xo2l{b%XYG^K$E}W>~ z2l?bCz!}pI0ab=vS<?gy7x2Y}!c!H}+lIPY(W=e+85+vtAKwTj(;?ZC^O=*IG#Dr? zzvj>1_YIBOa=>|TWNwu;<}shN7@wCo{D~c|i%@@+mhys8#MdwCkAwfS#X~6~i%N<Y zR*FR1Udb=a0GFwH4VPbG{bbVF%o34R<tgrK?wV}H(#=Q03hM%Zp7n<%e5U-8>I|Iy zAeWqx?1ebjB`d<&{Cb1yoR^mJ^$$yOP@0dYm*0<YRe6jofPSzo3m~_=Ke+N(VQ=ja zUG&nkjVvoA(%M!MXUE8FFS~kLVU+k1mNqn5t@6HBt{L`Zavw&L|8y{_v+rC%ZYtl} zO?s)#ivQhvy2q|=mE;hT)cRCf)zHhSRJwhU*kbME;{hEC7cUy4Po*HIlJq~=*!x;O za3*Ka3l-bcdo#>TEze^*dH+#$n|m)C{~WR!?#fvflr--e#=S$<BkiJXys45KvFokG z`;$hrQu9skfT$Kn^p2<VoqrBlr`qT)-hokFtnk8#!h3f04v89Ug@2GJymdG4u&9Yv zc#%+e@YC*II;iKhf@IC^3)b!FmDZe;b_vq2tLpaVSvQ5<gdllNH_{csZK|C}73$|5 zX4F4ypR(MeI$0`xO6MQo9V@G9$8&>9ye<h8801|YnpD?gv7>^uhj<scxG$B&!G}Y= zzsX~G8aPS3UfL@0UOC8gMHMHg*9dQ4X@*JV6baIg5bKTd4hYSF(x{#{ow-&S<DH%m zrK_gc`N*fyE8X(8QV&K&=1NFlwQ`jd`hi~c3Epv`Rnm1+BuZa>KbhoRoDiiOPDqR_ zf3INoDe^W(H*~dUr0PubPEAN_HF&k7f=xd6j<IfZ6V|x;Os}-Oqwwk^sx;dh?}})d zC?x+Jc9^cV>C8leqSXAqyr0?)Ty=w3iDdf(BNuq3X{K%(AwjzJ?ZbtVsnrbD$wKB6 zp>96%)(^Hll0n+Y>b9_UWboUi%u+XYkRV-r`D(d$nBDkQg7kyaB`dwsh*mdhkRaXx z2PdzVLr}M0kPzL>aoSo|TDMtnrW>(drqhiTBt-A{?i;<MUAjf99imvgV291#L2^9E zr*0B9SdFccoo>kL<W}}euT<FXDPOaZM8PxLII48}0w?oaLGLoF@v4OAhL**@_NEV3 z*-1|E)`r&QJP97}iWp&q=+()$hck+=+pqw#$EEk*eQaI6XG4&FIqW~+UFV7zXHBPD znHE0i-QbFt5ZZ|x7Sb#+(pUehQR(uyA}0Me>UnZs{b2mbv=TSP&WNV#d5(FzxFV*7 zQV0J%&Jpu@C`A2zLe5oL7X7mL>PhcVM)Xfsk5k?Y2_x3;7yT*}{@I&Mo%r56H0qy2 z3BO;@WLG#%`c&O0U!*#J`t2004qGYovtpgc<uh_Y+j#PSE@+_?x6Vq6Jywdumo|No z*LnPP&O12jq?ID^MNV!Xv#VF<Wf87gk%_K!y0;o@HBw&m_Api-v2Gg@U;21wmR*(m zLEc!Mu%n&JV2+=>qm}uix25ry9phXLb<DU+5|jR0ouzY8l!)s_aVtzevSYLAAIQ*} z9J=f^jppC#Tl-M-74J%8q&=Z?F|;PUA|Jgh`Lnmbu}-3?)aPVb_ZNAUebSl6zCb#U zV$)dbJ?WZvzVX6NllY3M`_xhUfA^+WPp*3_8<~z;+s3(s>W9b=Zg^W66^>eU`<&TY z)sk<>g#Me}4#sEJgo&@ByvZMCjIndnmHRl<p2+5Gd)pgpthZyFi>F>sovq&0k|vdE zJjvTrzJ6tAUO&-sEUTSgo&DWg$9QVT(hAL4I@z81)crf&_J;qMwMM!DniDNcmR+U0 z>uqh6x1)Jd;0+z%LuYoXJAPKuB(5a<%@|(2sgiGEy`%15my@B~J#TZPtu<ldtFi8i z$lBn)Jdy``t?qjp7$cAArwR$XD|7@*{YzGG*q^cntL%k%>#F@$!WPCcCyhK@ATzyZ z^oG*&+WNp-&$#ET4BZ<z>#EChI^m&*-e#^eYU>**kLh-9PLj|WD0ww?6|s^ezQ$X} ziO%KuV{Z#rBP)q>&6k~eMZO)TbLP2b!pu)|*uMX_x4CP+73*C8_0HDsisj%-sp|aW z?dsaElQ_Qz`aQFr<Irc`Hm+Z->7Ad3&`BYSoLsGbE~_8$opl!We)~Yku6DhU130f8 zOM|xmcg4fi&o5<%)w0sP^+Up;oLxPBB?n9oI~y9ZIoas7jQ&^N$IrAUwtrx(lU@$h zchrY(yp4^Z9i8|WM_+noHTMlNezvn7mMH6h%QxK>rd(<LC7fR$z3LKPM1B0V96aW` zR;>L?^q&p;B1{U?HFb)FUnZSIFI0hWc|P0SigkXZbgXVUqc{FX5%Nw&K4r!N*gsmj z?uw2apG;nc?zSQm|9;8oH&i~fq9;oH<E2ka`SEIC7$>cLW&eEXnd)<29}ekL`dS*f z?IekQ&o~K38`bQH#6N5L4W9fEjpESLzis*kNiSuq)N-pP!OpK-1FI5-j%$}j-bp!e z`bSSHsp}uT2-P{QuMcs$?0>1aXG7Z9qJ`TPZC|8A@z@gW<vySYy-$@@r%Om3v{P!U zeBVh;Dd{<H4+r~|@*HtlBT^N&tn~Y{wv6-(7E0NK&=F3+yXB<yiXE9Ym#0Z^Q#Jo8 zm#etd!RXi3{qiEk9@+YdUnPueuI2xn5qSsEDY))azjR<~B~wK{%o-isU)PG}fnacF zeZRcZ(rKk5*@k}U9M;bAo5p_Wz|@{l?}@81Qlb5?rv5=jgR|B(l+LA`B>D)^NeVUh ze`fSMtGktQVs%{%9ox8tJVu>wWuV_c*t5`=B~k>(wDe1-uo9fkA5eOlC9VCj#{RR` z8;9aNcMnCRQa`lucQ9_9wfdj5b4!@t>~`|hD%Ck_dG#v?JB4nYqjRs&-rvXgz)r$_ zsmwbxi}f93t>ZtF1!!z1(QhN{T=Z8cbuN;wzcJWOqTfz9i$ddONwUz$v1rBz9~W2p z4TX-3G2-&5t)FD@TdP^Iqkp)}TRxim%Gz$$Lsa!nXa5u<xqQ_?ZXCnROxA$)M8@dq z?;Cmfye>n%qk8r7*V3Q94*t>A9~WV4JFnXH@n4JVe?ce6VI|NXw3FV}(x`9x`ujzW zwIc1QPal<UR7xl7W5S-Fcd3Wvqu(=<TnNgSRxi1XiWl^Y`(WGv|I?&Kx{LPxo9;U+ z^F{007J5hjYM6hRVFg>&4e1R}y$JX_8HFxd`{S)CrPV_Um3p{;6cb6${~dzQhWj^_ zlDp{DyX5(A_L;KrN~_upBc*GwBcD@GTe{?=XTT~mRlBd`ORybkM#k1K|M)yf67w!Z z%@9&UQ78tDp$QCv!LSe(!G1UZzs^vu*vRH#=I_k5xUQC^`t9*|3?!Q=(UFi5JWv|S zKuc%^-Ju7JfRQj0X2B|04Le{b9Eb1V3S1T9O#i|pN$C75opg$Crk|ChqpS#n#bMWM z;cK`8SK$pLQ9@401y!LMbb`(>5hlToIzkun`w$jGHT}^A)iYUGao67}-9CRAS7!P> zk5PN~`&*~!FfWNb26dh}b|is3(vc5uIjN5Kh%Bv6ABoIuESRTUJu>)ROYKDR5iUDX zz}&>_H$zos>SfW-FnSiAz*G2`*v`ay<_KOW2j$^2=m2A2EUblfa0<SM$M6KQ(3^59 z6&@Q|!&tY#?z?gG0`_z`#Q|$o17<ZzXMPMlp%=`9`LGA}!bvy<SKunNn=iD7p3n<M zz(|-0vtSjhh8?gIj>C8A>Op@ddB*wtpg(iD4`ho^%FwlIziwSS_l+skrcK|0J!AS5 zYTTo9hnePmA~XI^WaZwy+YOv)HdFNu`Lm{+E{V)5<a|{PI^@ri;X4BUB;YSdvOsXD z4H6Z|PC$ABqTyY556VG#_!R0uTWAM;Ar8jDcvu2U;V2w~Yj7Q&!E;C<2fCS3h%;YR zU2Gln`3TDowV*cig5EF}=D|TY1b5&MNV7;j-{fzh3O|d?6lV5ZtWRS)GvU(uQ)G<C zEW1dOm4g_Fg{f~%b!@S!{6o^x_7nm0Ym)4SJMafQgXfS+mfDPhoRAAjL20N3wV^Gv zgYhr{mclaF3A^A1{3^tmvzN#QQ4Nmzml+=|QA>BYTB-)e{Mo9fl5jH$GC^j@2l=5i zl!4A*!T=ZuV_}>SXBJeuj``cQTt&!g*bZO8Avg@@;5^)bU*RD<f+R}?7o>r-kQK5C zab_#k|G0mF(Q&D@@ZJsKeU$zx(Cg^rDWt1MJN(MP2)}&krKOthO`bB${LK#DvRRV1 z&6GTKnCX!QEv$aJQ~oQ)9(yFvPfyk?9VNiA9THmGJ+R~V46x!=!TjWreYurKpoJZL zt&3E;O*CDMo#5^n{|IBIJ<{f0c%O7%ygh^Mc3j&yJEwWYlbh<7*49|?<$3=xmn%Y@ z8J@hA%K3wTlB<Ls4w&WHG!>vWd<re06-<K3a0RYHs%1hH<c9)K2FgMW_yn3lGw2AN zpda*y(J&@}Ghr4ihZXPzd<nPUHe^^XWQ69>0>;AxSO@FjJ2(NC;R@V^d+-uoLFN@n z0&)pnA%pp$fDmVXy52hFFK{MxBm6nM0KYWGGBbf|m0-ZT@E+8LPoX#T0R?klH|&Ay za08O|SS^M_ekcHSp&s;y0k8-b!yz~fci<05vqne@#h^H}gZ3~HCc*YKlqG7bsz3Rg zxcaN5OOlsXTlV-12E#7<d$|ldI(YDkznvlNesllg?;4hIG}o~4yM=mek?$EAEX_CN z#hg*`-{658ya0A4J$uvtw~@5s(IiRKnac8tY5xHEg6ig&RB~ojIbt2_DIWXx8mH}% zcc1u=8Xdp2V(w>&=%e;M^`|k$*dYb}_V);sIwEr{4PBrs41&Qh9wxvXm<y|64SWSb zI1ESNF+2g|TOkb6L3+pzIpBRL{B1z2z+gqF4WB|wXa$2|2+V`|uol+A4%i9b!cn*g zKfo=x4Nu@HgvsVJlR|nSU`8{T19C!P_&|s=lijh7)%aKmszZ3Y&xD4(gwCe~6O#WZ zq<~lO8Y*29D#I+84J%<4Y=^Jl@Fmv&2!r?GPe}WdkPeDMF=zoTVHgBpDJ+ANa0*_) zOUQ9q$O#Xw2oK?x>%uko^EcryAz;2{@Lx#vyATDLAT#8L0#FvpK~1Oy?VvsMfxa*r z#=v}702^Tw?1TOA1N<1khww;<GcW&bZF7%od(#WGpf;?4m5}-mAq`Z7O3(-T!hQG? zKDsMZg&2s1xiAm*2?29IgSX%|B)=!5fC5ku8bCuB1cPBIEQ6zP4E}-#;JGh&p&EP) zanKJ|z)Cn9z;lq~Pr(I+;C*NbtzaaKg7vTget;h#>@OiH<b(WB2kJs!h=aK>559qe ze{qSv%iujo{Xj?qA3zak4lQ6Ti~|L8U^T3PAnbr|;VAq7Kf-VDJNyIBAel6mH{Xv$ z4|w4{$O9#z6nqTTp~*w;2Yc$q-Z}3`Gw_%&vy=3r&@iH}k@F6Xza?ORmB{*Vo`g!X zZwVb|hw6UrWZLOxByf%$s6VKu1EZC+tCs%J*4Qz+zdI{tR`yH{j2%|E?k8LFmgd`% z%~2~*w_TAyX@VUSFn?r$FTw9{2cE%mh<qd@2QT;_59EcCPztKS$Iu8GLkEa~KF}9N zz(|-5p9gRWEQQUm1rESBa1PGHuW%C{!xKpMScrs7kQv^G!cYZ1f+o-ux<FSL{g~rw z41<ed3G9Sja1PGHefSfSJrN=y2jqm}Py%YeC(sVs!$24WlVJ)hh9wZ#ieJD%I0Qey zk8l_6!Ap1rDW3|dAP3}xvQQ3cLM><kEujl^g~2ccCc>nrT-WC_xB%9}2KX9w!*_53 zF2fbL3-{n9yn>W+MKn`ECddr=p#YSHa!?a$K?@;Zwq&pibcMk%1SY~Hm=6nJJ#2ul zVK;mSCxkfjpJ&!p`7S~CpzuG!2T%zrLkEa~asROX;~Crl8{ssZffw)+-jR&W+)xaP z!$(jR8bCw%3_3s@^n<Z54(7r<SPvV7mgWHlzkwg%NB9kX7vjv+|5~e*?70L*!ZUad znO+E)Ve#j}68MnOD)81rsc&BC8%`R~$a{=*d(*`fH)BW@3*%t|Y=lj42F}7$_#3Xp z+mE3tzt-8&gvHJ-VESH43O`hXkD)V|FbO8ZX4nEZ;T9x&B}76#$PYE47PNqtU_uud z0z=_*m=VBLuo`y2PPhzL;6D5bZy?EQAswWLT<{JQhZ4{nT0mcjgE24`=D=K7_nHgI zdIpceG585C!#%hU|H2y~&a9fjrJtl_l^twmgWk{wR=`TQ02ko}yo79TgzWGkRDo-O zc=0-PWV{nhfQhgXHo;jq2min`$SUs<&1_H=szF!i1~XtL?1Hc1I^2Lrmmr;1%lg01 zU}0zsO+db_CS^g8Z>h;T!FO;19)UDWkRKL9@Ixi23>~2pOo6Ge9lnAqa23MBgg{cv z19_ny)Q33e2XkQ_9E3w~AN~aS+=@J3g0fH!+Cn=R38UZ(_!54GUm!d@AV!1>1)v}_ zfQB##2E$TV21nr-`~?pnV}#&=@=yUfKnzTTN$>@H2^Zj^5HSB`@D1cmCgg)g&=`im zP*?@4;Ut`b=kNk@Mhdy0DpZ5cAbVO)V3-2C;A^-8e*`dXav>dTUn9rWS5S`8@=yzE zLrZ7{U7;HcfuS%7Cc^?)2peD{?1nvX0#3q}<Q#uj8N3Jg;T61wR4Ifg$P8Ja02G9B zP#$VQZD<LtpeuBPAutps!DLtf3n8!pH^Oe%11I1lT!E`_5AMS&cnzsi3Q>?5vOobS z2<4zW)Pma35?Vo5=$4Y>ZwP}!VG>M+1+Wk{z(&{&d*B3|ge!0r?!kR{1+O7hDj^Co zLl!6i1);1EFv~Ic3DksU&>Xr!cNh*MU<S;D)vyM>hTU)yPQfp54IaZ2NERhTLKesh zMFUt2YQQJZ2HHX#^n-~o36{b#2*M6H38&y!xCzhU1*AzWq=nq@E|i6GsX6}YF<2iu zLMIps!(ax?gtf2^_Q8HQ2j}4~+=JKfFQiE$q=ok&4^)Io&;ZIe#4gYk0uT?=;d9ss zo8VhG3RmH0wLCmi&Oq_BGF$>`LM><q?V&#mfXOfgmct6z3A^BXI1Sg~20Vus5S>nN zLqRA6Rp6s^9KtOaYze)fH%x>{upCyvcK8aug`;o@euBsF1k$7z(n4-{7b-#}XatQR zMhKX(48}n}7!6}!7R-i~unM-rS8y1Pzy-Jnx8OEBg})&@T8MxQkP&jjyHGrUC7>!) zgGSI8VjvdcpdXBeF)#~e!%A2M+u<uX3`gJsT!dS28=k`7(Hz3zZW)Y#43H6W!@E!% zN<dYp292OG#6T>>K|dG`V_+7{hLx}iw!>F&7|I{P3vdx`!EJa7e?z#Gn#>5u02v`S zysH{UW}0Tm7XS~`G&&@cH>UF2b2C^kd8T#Aq>az3w3%*%M;xJq{B7`N#!QEd$XRKn z{33tB)xJ#iBa^*qrORXLTFy*01LlgllINGO4GzK~I0xt9SGWm};R%G*6OuwSxS<4; zgl5njhQLr*3`^h}I0&}_cpFmG7g9n&C<OJP0rZCfumBdqKG+Yp;WtRxKu86}pg1&v zrZ5Nw!(v#{fFt1>1`on5xD6>93Mru=6oUHD00zSlSOkmV0DJ?t;WtRrNJtAMpd_?_ zmM{zg0bB{I;3yn}yKoQEHx{CyG?an1&<-ZTB-jL-;R0NQSMVBgG!b$_4fq7QHmN3d zV{kSo*aLgvcen%TnhNQm6qJVQPy?DaRh3`*d+PRMDruc)w^WhvHw<(lt}_gPfiMon z!yK3kYhW$xfSqs@j=_&`34Vt=@C=?qWHTW-NR2uvTtgnn+l-5BDF#bJb*KSNp&4|7 z&M*K5!Z;WYb6_s4gY~c*_P{Cl9<IT4cm$6jX>%^J;i4%u?qs<jALNG$P!Z}w1Biu= zFaQR^6qpLjU^(o9ui*rogrDITcm$6jX`qD|4jI7%`5-@(gYr-p>Om*y41-`WOoGX< z1eU@M*a;`#BwT~*@CY8a;M9t2DTB$u51F6<6oe0<3N(in&>Q-|B$y0~U@>fi?Qk5v zgP-9Scmhu$LauOTAQ@(bY)}k}!>3ROVxc1pfuS%7Cc^?)2peD{?1nvX0#3pexC-~+ zz7S__{<yVu+nY-Mn^BMjvce}&6M8^T2tYi{hXq2Md8MONq+jhH6hXgv$6G7uD={Xp zkNEv?8qUBqxDF5CAtY%dxF9X0gY1w43d0A`99qCQ7!R9a3tWUBz|~eT+6KgT7|abd z;1e*R3rvP7um!fl1-J;$;5qo(34SO8WuXPMgb^?jR>CUyP6(JM7<>qiz|&svLV2hF z?cp;R2jgKk?12aH5TZX5+)y4WKrD2G$uI?Wz)tuzfHxs+2O%9~ha6BCK7dM48R|kk zXbbJ2C-j1N7!K25IxK;uum!flemKy96YDgCXW$xKhiC8{+%ZB1$OrkM5>$rf&;q(b zH;9MfFb$@|GFT4VU^^Uzz%l#@F2f&i7hb?iND(WfgzS(5ia=4Q1|LInXaU`!2aJG` zFdG!CgY|GUmgDajgSX)~cm~fQZAT#;<bk|U0V+aMXa+r@7fgc5umBdq2G|I@VGo>u zlR_ZQY|_a(x9<^lAJRyOnHGvcai{_x332Ao&ejAS3F-tBVG?YD&2SFR!!vjeS!7Bx zE4&YdJG&amj%4sdXatR+Gnhi0`I|`HwaElcfkm(w4#FWg2j_)2v!B#IlFQ66!(&>P zn16_S23brYD^!BYP#5Y!2Z#~k%==xenT{c7ENp;{a0br8Gk6X;B)ypvs=>$54Z3%6 zeJV#IgCk%T%!c)_0S>|;_yK+t;>_0FttEI((7({AtI)WsN?Re*uYq}t%!fU&7k-C3 z5Y<gc4JDu?w1Ac{ElSGM(;=SG;W`Ya!(vzhn_x5Sg?(@u&UB+h_y>b`;a_+I8D*(W z59EXVPys5!r%*?TGq3irR<AojJs{AXf|vA~8;~)(L*RiD#*f5Q5=?_H;7hm+S0KIQ zWky3uC<Pxwb!Y-jp);5;97ezn*eS%B6Z=|=baR$$nfru~?In!s<%*VPYrSRg9cToN zd#k!xGYtqYA-`ld)YiHg<&|82A_l-bm=AkkFWiFL;FkHA86X$D14W=HRE7_s9@K}= zpaaA~KOxS{H{4p>`2;QKn@fDe;A1f2gfK`C(U3DvZ{R2yNN6pkKNc;^UX%pIpbC5h z4WJ=>1|6Ue^o5Zy3TD7eSPm=TOV|bn;SijI^YAO&gvanCfbM=m1}F)ope?k6;V=T0 z!E!hZN8mR62Fd#iDWEWX01coa^o2N3Fb8(@=SOHKgTKHvFa`)=kPF^{kDw}a1`{U0 zMA!(M;4GYjr|>uU2MU>>ER=)R&;|k{aTKhDb#MYs!b5ljnFk43pej@Y6S}~3_#C#u zcDM{zAY!nP4Dv$(_*CeWDzA#IlIde(V!TzKy0Cl*Q@#~0pJbN<qZi3~!yK3k`(Qs% z1=h?8HyOPJPv9ve9U_E-8!|vHcn69?F{lC`K?7(ApFxKJ_JO`I5=Oxcm<h{a1$+tH z;2<1=b8sGhg`4mgo<P`8At}g*L}e)<7rX;ShjL&PW3VbzgI3TQx<Pjs3d3LtEQKww z70$tVcmXdV)i5CnGD8-q2$i5Mw1dD{90zk@9;}6Ra2&papWzpH14$@W=qGdO8Ojas zLP;nEHK7)?fR@k=y2Ef75kLiVU@feJJ+K#kfFI#6cmQGXLQ?R7AM!&1s0<%M3up;F zpeGE65wJq2X0Bv#7kmw;;SAh_Tkry2LJGMgnkhk=K*;$f#F?K+D`M_C)cB7x#pNzT zL|Nzu{b4CAgJ0m9d=9f_ra0<bs0GzCbqPd{kkI7d1?lEZ3S^KM__;FUp%kN~p*qxn zrqB#JL1&l-(_sy)g|l!D{(!si0$z?_lcpFcqy#@?f_#u4%0O8m&a6Ay`c-I7Pz#8M z;jj``!EyKw{(=YK9wlUe(ohCkLZFov;$ayqhp!+A$KgBp8GeCB@E9Uwq0D3;UE0Xf zLjfoV6`-OJXYLXy>$N4Q9rPN_N!Xjg*`Qz*tQO+Tcg9##94F{IxC~byiNu*MNDJwN zIP>OwYl30~6^DT^2(H5oC_Yvw0aeGc{i`w92pR*QA2(xx-%>Ld#4*|r_}I8P24=x* z;Dh4kD%cKR!C^Q8zr!6!IZj9gh2aAsU^Zf~F${wMEQb|v9KM6U-~nVDFL<B|d<5O0 z2h4?ea0m{=U+@6rD*|$)LpdlPz&6kpM!{%U3+vznoP>Yi8RVQO<bsc(I+)M}Cc_li z0$br6oQG%d9CA%!|GzUy20w*5Fc1d88dwWI!DUE2Sx5s_;3Mb<{b4z*fTM5>?!rBg zPvXeBLnWvTfnL}fW`ly0a0-%66~dt)6oUHD00IyXn_x3sfvb>gnh*&kpd_?{)-WAD zpT_Zbn873P4?Kgs(}jFc3u?n47z~SH2^@iM;U9Pg(kr!G$e=t_fVR*MhQkP0Cj`v( z44#Bj@C2TMZ-(H9ypRt{Lm8+6pFlHc4xPb-fiMWh!vvTM^I$EkgPj4~1;^kx{0Nue zH~1a?hJPSprjQIWf(PD(_n-unglh0HG=?S+3mu^!^q<M`H-^EnFdG!Cfwiy;zJ^oq zJ=}m_;RU>e)U$*%@DAjLQcxN`g*sqD7Z?SB(YOc}!w%R9XW<<D4tL-cyoS`Xg*1>8 zazP0w3Duznw1>}N2n>a3Fddf7=J;FA;5OI}N8nrd5iY?!xDV3Xl5Bp+4mqF<l!d0y z3<khJkk(yt!vuR_A6$d$Lcn~*;A==bM@R=bAs3W^vQQryKyT;+V_+<-gY|F<zK7fJ z8@zy*ka4cyfnrcRfOVlBn9v2r!FX5%i(x+;fE(~D81sZM$O*Zi7!-%PP!Bpl3=D$7 zFmE2m-+Ttw!Ft#W``|R3fopIbp22fSA-{EIO2`g5pcoW~kDw|vghtQ-VxTX?fyz`P zQwsHdjZAq0=NZ2s#F;%7TEC-D2zm<P3xo*B19_n))PkPS3ueGf*bfKb7TkuX@HZrr zIhc{)1OGx-8M($XSO_XYC1?RH1^IPfW-V2Kpm?aWNT|C=->yf5zK_)*VDe2ib1m$E zop2P6!5#PmQY;oyLP015^`QauhXJqv7QzAe25!S|(1d!qO`#KX4&VS72;*Qpq+BAY zQ$Z%k4Edn|l!bDzgTy;w4XlMZFc*%(F{nx6TF?SoLjI*3RRxyHU>PV2pFmA$4lTfh zE-(lN!vvTJ3t%B^fvs=|4#SUd3GTstNFw{kbV0z48Q>kr4aJ~1d<0dYAvA&x5CeT7 z4o1Ofm<h9B1+0W^upJJ;VK@&LmPK&5^k1bm*U1#%i!u5+(-Y#JLilna0y02G$PMp8 zaVP;*p&B%T#t;Ls5C{EWG>m~+FdO(hl(~{2J_u!QUmg(o5R`cs`1F%`0r=RHc?+Jv zQ}C=1yif+pLK|ocBVZ&fhZS%L4g;TXGXDTR+9b`Rgybu^(xwni=~r4#H^>Y5pfr?$ z8t@4;gXYi~Oc)4*U_4BKxiAmb!aCRqyWkichfA&SC%6NDz;k#3DOU-pAPZ!L51<HC zfsdd8G=$HfgAiw)TxGv|vcChQclTK0#{nM+GB?22uv>^TpRctpCRYji8TcZQ`4{l{ zAM*|H!5=dX@O2+E8x(@~p%FBOK`<Cr!m8Drg2x&B4j#fI@U9VjP#!8kN9Y8TU@~ll zFW>-t183kY@Rc3&20VmEz^8Le1JXetJ-!Edpe&SwM$i~Kg9!nMhgmQi*1|eC0N=m` zxCnRP4<XLnv&q_&$=69x3WzY0sK!|{^^UN=L&6TJzG;KRY=(1i9-hH-$hJ|)4j(~P z=nN)IfvK=nI+mAL_-}vgqj9DNfp3UC2xs9O+<;$!@1mHGz$Hs-8jt}pLSD!R6`>L| zfQHZ!I>BHV0+V41EQCdyIK4MAxJigJUvIOv$w`7vL5a;mNug7iIf>!Za0VX36Yy^l zGC^hd5MrStOol1&1$+sY;mQ_{w<KF-&;<pd5Hy5F&>sfC0$2$9U_ac3-yrG>AvF|% zqR<4I!Vnk=i(v^Ihh*QOUBN<k7b_j_(|yY4x#|bZpNPB+TiFL+z#oj>h3D`BBEJ-p zg9p5j7xF<xs059mF?0qK0uT=~U?!}G4LW8YgZtq!T!Dx12*PB4nMuI|UdRjipdwU) zM$i~Kg9$@n7)*!HVL7aTJ=@qfdl@_lr{F654ENzrL0+Nnv5uLj?Glt4vOrd-1eJlu zx@H}SVKf%T!FX5?8{iat4-W(Q2r_;pc%UqlgQ<(;muebxU^GUD!8F(g+u;ZJ5t0Ul za3~7Jpf$9C@h}0lf%J4Q>;Ef*Hz8t&kPP03!cZR?z+e~xOF$ZO%Ow;}zyo*)S#}Cp z;X|kb-Jm;s4l`gU1a{#SxC+U336W3)ib5-B4dY-u%z?SE4%Wk7*axTK4BUWU;R!s2 zh_8iY;Qg9wgO9-iP!K9XWoQb`pf~h^NiZ3fz*6`EzJycoJ=}x)5V2cG2H7D8l!3BB zz--E3GcchGjDV3a6K25%*a-XK0Q>}(;ZOJrQplldri84J4N5_2s0Fp5J$x3xz7Pjf zU@EMEweSrb6y){nUh6ctN6>vpD<Nh&C<?`(1H`~om<CH>8GH%b;G7UJ&x>*9tOHig z^vrGk3#s=BY2X7W0u7-N^oId32j;>dI1CTqA!Ob!WPw^x8wSB(SiL_Wu3<0;JKz`` zhs$sU?!%w(8vcb0vdCseC<uk1DpZ4Z&>jZE5J4^@hpe?+Nzf_?+`&J9j+o8LK-bG= zJ!lK<U?hx!Rj?YqgA?!w9z)iHLN=%jA3`j2gz+!|Ho(S%tp9EX_rM7_376pt&|9&2 z7hb?iNFnQCri9Fp1q#9Y@F7%zrqB#}LmwCgqhXE^Fy}J34%WkN*aIivq!4F*dB#5O z2)YmT4+{-|PIb+eKsUP5)Lo$CTyqG}RjxS+=EDNm4+r4Z5!U}UgOT3~$ss=!fKQ<g z^nt#x02abQI0U!hH;6texS<#nhbGVzhQLr*3`>N7d5FQoa2M`D>SID0C<?`(F*JdJ zFbEdFLf8lU;RgH);m3st$OCzyCe(uN&?A7;;d9sq+u;)Y1h3#VWcyCY4j)1lh=Eub z2jgKQY=YBp2L6F(kokm=1uCB4_ootr9UunA!Z_Fjo8banglF&^GMyAMLpdl9ZJ;gm zfSwS5c$f;)U=b{az((8zbX98Zg_Cd!=zrAw8ScZM;5sE3kO4Bndyof8Lm8+EwV(~O zh5j%ACc~6d9Dj=$TmoOiZukyPz*YDe9>OCC`(8*29`HgzC<GOu5;TB@5CgH$9|pj9 zAz)5ma6T-6jj##!!G1UcXW>`42~Xi~NOoF?1RwaJAQXa%PzmZmefSJIKwJR(!B`jv z^I-vOgiUY|4#5xbBiw;M;5GaUY2->_riI+_E|i6GP#ZplHqiErtE4;}W3V@jgi$a9 zX2Nn<A;e8e+O1vZ?lXB$cJK^$I^_&`LRzm3ooCVSobK!|CcSx{DK5ZGxOIltnggA_ z0Jl`n)FkkPh^LU@tdJ3M!@E!%N(gc0-1F9juPQ;+peuBPsW1&93kb<!8>8Fd68r@J z!W+naPI&hmC*3Cu)`T9=6Vg!7Obbn$%4jo~NyIEz2kT)s?19s82A;y-kX#noOaWOS zD-?xd@G%6cV~hWz?K;4tD!R5=LOKZ{eeY~43897b1Vnn1&_paK5;n;Oa!E4<uo3KS zEofluz-Jd5HpGJBXD`@0X#{MjVEgR)zh~y&yLWd(LK6Pud3M@4XJ*dKoH=u*T>4o; zKQ;7IOFx&>&lUJ-RDC{@Rlk>_?xP<pUD4a<hu+Ln_t4J)`uUcA;y%QWm43F(!_Oo1 zb1DTF)6WX}si2?LA5#6-koQvhxr}}|{oFu5kJ8U$^wU8<d+Fx~`uPz*jp|CRRN-*d zA@q|>KPmJxlYVB=&nfhCDt;Opongfd;<>Nl`m?G^YAWl|fw;9?StzbhsK+hf2g{YH zkmD8r<DsSaiCN08DOaMKVkm&4yU<18a|WH*&{#6pQMcSt*DPYh`9bwp05}KDvR9W? zI_f9a*H<jBZWfW^w4i$N3M7YV$@6NeD{D&amCYhr9Pm?bs36)Jz>FHurWl;%Bf%7- zB5~kJ4HYQ02#E7}>Rl8atl`Y1F(IPF(K+>IoNsf69ba8q*;wYNKe5zaT}>sXXmR*V zJ*yhnfhX5iEOgk*D2XD(Aux3>PJrozN7hfV*E^a;oI2usfK0-97d^Fp5gt%$7Ew58 zz{jir!)Oa$J^Mma*{0N#;RQ8{5<A@LN<cV6w1S_qqM{NcC{FBVs~=LT&dP<3hQ>Nn zj3UL}wK}>H$vP{iuc@t@YOe$<DOwoio78`A2E<^E{N(Cty*VgeSjg297>1qxC(o%_ zE}D^ou!SP^-~RyBZ)#0-dByT(5hBYOOjh`D1{4=pR97?<7dMNru#e$8)<_A}GCRJi zwuXmQC<8+%T3CJP8?%WON=y@dj#k(_@YPPB=xu$n9jvDqv9?to$FMh;OSNkjQ9|Qa zgP@Nac~Rp0T674C6?!{9QiJqBlzx??u7R4AB80MwlgChPU4*L}tD5mS5u}nzhbMQD zsI&aUhPuYm2J~Li@AiI<pWOsQB2dkv;_0lN(O6yDP*GEjGEh7u1s|*`(Xli(RfZpD zpw5@_W<+eCpehMIg@ur3MU%vp6F4N|ihR@+<RpsAB}Ie9&61)3ajj(TF&1&Dq$rVJ zvQmjJ7+mIa%-myq#3Ak3#~d>l%VRBOl5j2JfHpzwT5=5K^Da4qw@;~5_W1Zb%M+@V z<nZXph?^!3g3k5z!7)(2xLO&`Z>m-<i=mTTC<z_oDhd*3xR8zSF+8b8v1J5YK)GAQ zK^V#-9buH0&cGCfivuvo(f_z(jscF(G236MRc`fZio0GGc{p4Ej}^fHu{}(*7K^Y& zYz@ynX0X^82H53V^o?*u3B;c8++z~e9U^70crpg8qxWKpEaI`4B46=R3|L3c#DECB z5z~a)&<imr89fhEv`)MY14Mck28i@13=ru>7$DMfFhHd38fq4DEMlJqAeTuH+GPRA zJ>(>ceHf5_l|t*pyDY%_ib59gB1_RMU-2FbXwzdXK%^a>B7d>HQ-qHoQ^-$j>=X?Y zyER3%!nRAip%*MboSv^h2N++kjA|n57_pv=ndFiw6UCr+7brMBPz2|YgK3Q%A8}tB z#W|NkFfEefE3RoH$NMSdCoX8CP;XKwfUagAQxqt!WrNCJ6!H-lvWuE5;yO0Sj0!@m zuegW}GIJ>8C$3<FOeKW^#N}&{aZ)HqT)Qp`R_~`!h`4WEG)P>wE(#Slt&76MHS3~S zamN}?NH8EVl*sWBSF4LGxUo#Z0peCQvR^`>f#N<jvOkwX{^BAvvcH8wf#M1^vVVp` zP-e;T5jUs7l5Z(AK-`%IF}g4fVsu*?#K>p~1Tstlk`}6Hiac7S!YzJFjs#Nhi!z0F zk66;VW(W8jGfC)NbHDyuO#MZZw(qG|!YxgidmtHhO^2)yzON16;2C;cf#EAPe3ux$ zdkx=bhR<)NjyuxuEiim*4ByQ&n{>dPMr5bq3z(&+W*WYe4Bt71Z;Ro3(eQm^_y!-Z zQ`tSAL}g}vd0tLwY2Mh}l3Y7Kuu2JP$|5GjE&!bH9cTDT4Bw@O?;*qYvElPMLB}0w z_)a!_=NrDe4Bz{P@0f+e1d;K`g}U!#!*`D1+idt=GJHQ8zJwEX+}Vb&(eQ0De6JY3 zA9Y`onz%?uKEd#<GJH21zUK|!e!~}Zl8!sZ@GUlcml(dShVLE27nw^f!t2&3F_!E- z{K_>-;*@M^jG`P66~21-oP%>5Wrd}A1%;V8`Pn(S_JU^hR)WYS*jEhLZ>5ia2Rco8 zlvWT0DB*J$zV(LhS;M#2@C8Nd7}<tzvEe)4@ZDqh-Z6Z?7(QzZHLA#XVvO!vZup#r z?{UNTnc@4#@TJD;xN{8OYQuMn;d{yO9ngJgYG|B}oMZUTFnkwFAI~~lNgR<+ymICN zUicm}e4iS=Zzdr%cMm@k@J$5-zbg$f!uN&YqsQi)gG)-v%5(6OTbff+nq64hES{cI z3khpKJvt|R;^jHv6EDvRpLlsr_{7U|!Y5vy6F%|s9DG=%h^Oa7q<DHx_{7t5!Y7`d z6TUmX)3bZe@QIh_M5=gsPWZ&jbHXQHo)bRt@|^IAm*<2}ygau=c*WCm!Y7`d6F%|u zobZXK=Y&r@JtutP<vHOKFV6{|czI6v#LIJqd-yNsfWu>nSCz5&5x$!Y->Zi27sHnn zr^C%Md^Luz+3@W!e65CWfK|s$H+&1Mw8jw`uQ4KTHGD4^zON16U`59mXZXqt-_?fi zNyFD>`23iTJ5u*GsS9+ky4vvFX82w*eBT<raGOr1!0;6tzDo?>cEk6T;R}z~amNXt zV-Ld1jmT!h_pIUj!tezr=*XFd?{vd=iQ#+1@U=)E|MfgH^*G9FTqgaHuh{TiV)(Wi zzIP1YFNV*WrQ=RCd}W63a>Mtq;rrO|{gqXqBPV6+zL|!v*6>|#_@0nH{?=M0G2~b( za_m?PvSat~-`6SyzH}sspRrDf<zouizyNg;K`h+Fw>BwOUR}Tf{ijgO>P;KhA>!61 z#ovD#Mcg7lQv7F7VAm%8VUse{e-;J4AkZYs>^(eXoifHUcMo5*P8nudu!o<wP8n}G zaSwlboieHEWP&Ag^cl_b?9N25@7L8imRHnc5msEUEvHTu#05h7ym=0%)eFU5R#seI z;i$x0<fjoZS)>K^G%wIfTTRW%###wpTyj=%X{Eg$>#!w+clO=<qsx>L{!1zF`rX|B zawTKXG78X+CQ;<qjAJSOB@|Wm1b^jxWwd`81$?*jKhIY({L3kjvz=#N05U5muyi}O zU!aWgS1EA02&C|d<H6rbig|21f8_#YjDIx+{GQ~0U!WBD*HU2Nll<5Vky1y2%}??( zF9iJt3LFxFc>djSY_R_-ikY&5lJTMB^KsyA(gYUlzlNgypE5;XP0?plboNtJq&U9x zA|=BAT#7kEi;17eA}nh$dt9uH^P>dYQXY1(lJ0*21<H2vtrsaH5-*~_Rizq_hvCbE z`Ptd!g*jzqS>^eKnHk(?SVT;ddI^EiAq>$J$z_hxvh4D*vcl|~!h-z#><ntPYR#fk zTy3v{E#opmp<7&MG^ZCqg?2cVf}FhaQktT2GaY4R*<~5EjrA*v8|v((fWLy^>6R1V zoxvxbRo!4;Grg`3R-mFLfzG_p%k2&J%3_BAQk{fPccYB_k`9AF@7?QI*AN!nloA!o z@xpMdLGk$N%anwK^#n>+sRU@cCn(SQH#)9Ky`G>(FVvtCG7B=tVn!}3EU@R~W#{E* z6fbu)6qmr7q_JrO!PB!KlCxdI*V^kG)eU<8=7d6Tg$R@pW|WCCkNOogjg@7^RgQ)g zHD$#mj^b4nbq$SVY`c+g>2(o-n`Xu(R6c4Zi%q<lfaukXGn$Kzu{(!(K}|k4Dz-_z zmB8p)0>FIi&ZLrp%*;I0H?N>zY)M`TJ}pow2WS-vQNO~DuhniM6uONdYwLvpW>?o& z+8Z3jrNywvIbbr`LMU`?L7)sZQ2e!A@J=<0Zn~YI=t_ft@-B**Fgh#DLU$4dU41wL zjLI52<k8)PL3bMjMxs#?6eLg7*DaHJ7?<uP47#!)FjCAIguov@Co*z@x|N{lj(~tl z@Px`Rkrh_H2MC_-4+!`)Pk6p*DvKTW5COfso`BNl$?=!$2`PqcISg3E4K>9L_7XBd zZrj7BU!jy(w(sHhUZLcZ+i`_5CTu6sn}Z+FQxTbPrIHb{og$y6pJ(>)#aAlHGUhqN zIGjWI!K)RU%`g|fj98~Xb$`qT%^I0qS1L*DHA)$>z+PAHD4Sfjygow*QeWG{|G82b z9w{IMZbfy2377d(SlzvcFLf%h7PtT(YSkh^H9!ovnwm--=?SNjob*0r7~zp&2|=kM zNfez~4O|&JV1>P2Co|?M#l}7%GNC3i1fYu81gbnsb43Ic*Spmm=euUBFMxo<8OOI> ztwi(ZuTlmkwRo1yKvPAMC|Ob(aZpA`x-PDG(M=P~*xMytSCXWg?1~5!84I4srqT%W z`>%##@Z}!<_SK4&+yhrDBgu`uMqz$WQ8vT4eZ7*zM_r=?q>6|bG-_iNB$!}T9X>gt zn~+~5_;dlE>>e3HQ;J=~)4Be}HOgGep*`GsEy@7*xNDW{s6#{}K*&|V>!251tE5?e z+r#g_R<Zg0=E{aYf2|T2BO-#JIaHTHNL3qHgV!q~EdT7`<JT(*<UYJX8OrCcS3)Ro z&3eV^FS`7{NLjB8_w#K*)`@)5dL=HbxEA87VokFuBD1JYBSyMM2FnZ~o$K^YjG^-{ z3g>V#Zd<R!1j;luu!Wy{oswvQd)swN7P;?Ur^L}{{PsE}+Y;Ks6R%fN{X(e#nUq%= zAA3EDiG-%>l_&z-c)gP87fArh#%3@<ct^>$8QiQ4vP8D<gk~k0U<;a+F@A9b%lMXN zC0_bROW<>xl~7Au3*XhOL=f;t&B`dhcmj^&<2ERYCBB6imC9#tP=cdHLQriTx>E59 zM`bM<gyhA_4N9^lrG;O!0i1;kgiMw~M1m!3W4(R3LjwC?(qX)I1Nb3h)$|t5Hi92; zCu{^i;GVfrS!Bs-;je52;oKH}fZT!>9>(F0YvDN@9pJbYemYl1gioT3d}|sTN<{yd z+`<oXMTshDR;N+QfQstXl=Wl;?EKx0N<=ips55mmN=-*Hp~VlGt>KVRamRrGnXBVS zk)vfb5Ge~<_=+3QzfNr7&E%fk!k@oENw+L+;osb#oMu_l!e`v5jI!8Uc*Bj#)W}j$ z!gHs`2$5Sx0Y?je<3=SdbU6hMh!l$Z_eN!OXa&WE`4Y4im%ta_q=ZJUq=X!ikglqM zST~fl@N;fbvf`>JWwCn-^~E&)&W%_ov;o^vgF4@&j8p0W>kKT(&xP(+Q$`JyuGSNN zLkpjFGlt{p7QXyuOc-ak@J%->h4JSRf`4gUY4M6P*9h=nvS--nXKf4r<!1DQ^ILfI zEx@^`h0i1R(iVQnEy_5{6)pS)a<6XT|J;K0#`+dM{#Lln_}<X1O0I>Y|J<r%SZ-?J z?YBY<f!<%YDhcCm6?xjTOWgBZi)e>4HaoAtky(&iGBzi#G$*GdH$w+hH@EPUZc`>$ zZg1fmZc~zMG|27FA=pGJtDwytlf=3kgXTX<Qk*Wq?xrk#SKBM}5zPl}!V*D<iThjl zq)ix%54P}AHYuq?9wb=5>Y9d%^0TPxU|3weNr|^S(!w9yq(u8YLg`8T^i7HquR*CI zE=Y!oY5JFV12!wk$=eA&(p5?mlq%9v1+4_Hcz=88nT-{7+Hm9NZ^k4n>m2T)ro*T^ zTlmh+=%;YM+N>mcL)JMe9b$j<1p%25Z;C((1B;6x`>_fv)(UUmqNF6t{32ZWxuDcn zsbWKA;XR|V0qIyHHXtP@+P5glT{V~nr0y0CHhjo#!Td55wLz~pm>-P~HY-61vM_^P zh0);D4_r+W<ci}v{{ta|=G*%pCD-p0f=S>H-l4=;T~nKg9e_z+^nJk2y<Hg=D>Dk5 zz6u=4phUHUu&n|++7&Ud6f7kzi8{%S+m(c9i5V<0WvcpR3;+IhC3*IjqHY!SG-pd3 z>c26Wr6qYe<>h5rh1q#!jsi!92B97x_z+3TEzTy&5#);F=iH$vky{BqNWzP*u5NAN z_uZi+g;I(d22-vq>8E#im$Zg<&VO#<p?893aI^1J#`yjUJihAzC4#THQwd3>%BfOq z44-AMU$KakQH;83$7<SX{)6&Q<{kGcwm>6_zYT(-8)=wB%$WN4{0AcBekEzBD@;`> zuCJ`Y^n{$W)<O2a@8PH3g(6y7`MGx~RzFKCAX6z*#;?3f306b|^ddrC>7Wrzny|!d zy$d4Hzm@ykt;G5H6XsBfIsR@XC{aWNOUzaF%0?+ZHC)IhKKV{1lGog&4CGCBEB*-~ zL?Fsk9g(NRR6|<%nfED)dG2vQkSZHRn~R17pB2sOfGWt{7xr)zG&YztQ36xLTe<BX zlsMc};!*b~K}jM)Q;^PM9#`Gxm@`!R$UX)37Ds3dKXCiyqgGupqn&QV`+wu=u= ze`?oKdu=m+{sAR2SWj13D<6HY6641xC(#8MAAheBU_nCdy-K89akQa>tjLsnRA?07 z%XU>l-e^svSN}P*re&z$U=si5UL`njC=m`WCjHS9iKuFAbKHGO7!CM&_o1Cf2>emx zZn{q@TTk4l47X&o@{apJAMU^RDWelJG|~_po}{Tf8tG+Qp||C<^6ITnrQo7*llc8x zp-SZtzJGCXrK4Jxour?LVbcx(D$sXZl~})V26JqR1Xe{99o8@l-skRzjqvpQl^|VU znp#eWR428H5yLc0gi#7ms)j8@F9ruCL+YA|Xh7-=L1cK;3_>0N-nzPE8z%Dyl=w8! z{YAU{C^TRkz0e0f!K-r!HJ(P1lH!W+N8@6pV4|lt?al}E^`{>5?E~P=LW4I7|MLMQ zFkVCmGOl$f2C<F=GS=*_Qb>m|2`4ItScaYI${^Sj$#*`eWJWBZL_d3Nt)se3V*&Sh z2$LzAZsbFHflC49K=0nXO<_qIu<9UGf2=A@xF~07E8qB#k}!M)B@dZXQN7YpHV+zE zMi-DoHAPTO*HhJ%gg2<7x*o@4U>Yi~5o&-oOh7#OVI?!Int)<W#NFXlkv?2d&h9EH zM2obS(-9m)P*OeBnpPgV9TV@KhoN3JwDNBsR&3<Xdt6E6e<CuzfpQP2b5zx=f*}Y; zqjc8E>I>{;+ZDecEm1wIm7li_RNx9K&TUHQkh6%2Uzwx9UP@A)Cel6Iplz*f<$rBc z;)IH3*O-pEU4W_QxAG~Ez&J~t)9wuCTOPrh=aN?Ld_+lCE)nHgVXv3@!X_u_(x43A zu0-UzC8<{sc#MgOZporVgt_2xB|hCPNxh0N14PY>?WV4dp|j*sEQ79X<!c{RnA9>6 zx#dx;!LM)SyC0Ryxi22Y+Giv9{1~Ja>Yeo%wEY{2=%Dh7x_Wfnijv9-vFs(bob#BH znsy5%o15GnQWfd4$wzdR6awSB2VtErJmGOP^_EsX=5aI<Tr^S!xoaQS+JSoYZI3JI z@pn-vLgWxA_Ub*d<HSFt_-%XwQ^38gJm?9?Tew?xC{g^lCzRM3_kw~Ne43__P%B2; z^BiOCg*lF~WhFV8Irg%Q(wasx8$Cdog`GGDdlX^>$!OVCZhk@;Hs@giu(-DXjj0GP zihxlc6=ipkbH}5y4~>0-VEkm)HjfKFd%F_Pc2MeI7X=MYrFgyt%nNeG@U7cr<L<^_ z^4m$6i9GX3B{syRgYHBZcv6X${RAu?`J|E>`vQT6%oMqpIU%|*Kj%p$G(s>YPy>-w z<F`DCj`wIQ-wA@gC0c<Zc+CzaC`cDsC7Af0#AGdGQ!-z=Ls3!<!6PCE&s<dJa0qVe zLvF2^){sOBI-^}+?jz$0(bS_YaNpShiyub9H#=a7xt6eE`Ru2lxNRi=aQ^)cC~hY` zg?Sqzq5LT&NmITD&8aC}X<E^J*vhYcMqyKQ4e>)kD!aTK$5!lRdD&&9+4#>emP5~w zG8!U?xX0P}J5MXo!KO$a|Fn{*NLeB=jFr(I%0*)Enx|os5)r`-b!Qdp1Y}3N=4mCx z+D_1eMV@8|wY`<U`7}1>;QsQok{l<q3e{?;ue#LztvvG?CDj7=lxMscp|6y_7K|8L z_%&q~<HZ1d`STvtKUiep7R5yMo6K=I*d?tOWaxAbv{%xJVC?#p+H*6<X62P<Wt9|` z<YPc$Ws9WZ#@c4}AaYlK5_rNsij4(t@Jd+v91u6PHLJ6s9yO~!5>`y`F~^(&t~pRb zyED}rt)vo758-#V17fwfrcNCB{h6v8=MAjeBjxPHKY3OemLznRQ^|%xh7{PiJ<)jL zP9-}3cOr@EB0JY0ml)BW7#R{w{i~H%?o{H$>RO}jRdK#$rxMZhFV&R}jObH{Gs=r- zIYyZ)Ycd`=oMCevRdemtFtgQVbd{dyMa2_A9oXh`OonqHly~z&)4NV40B(OyiHngP z)4M|JpHm{ng@CGBDk_xj99UiDsDfcmvMa``OgJ;{Vk>Wb4j;b=2fj1e3({124M`<P zaq0$*>hwWxlexrt;nq3K*#L=H=nSAmideTeoI?!qyy<x*bcyI1!b%s5OrUpp(KHb1 zGIa8)m5ScQc<`{8eEqzl#MlVdyI1q?pI4&OMPgUI*laAJ33=I!_~<4ziD-HC-V9R_ z4Ks^`4HWz+E@>=xb*nM3<#jchU7%_z<r8TlE7JJ)yA;0|k=8|hT6f_9y+|Ak#0A)v zaY<`Kl{5`PuU<vfa7R-|P&o$a@g8j}J3+j;!J33va)(z(6Oj--va2CvGt+P*A)wVv zw_=z^2?;E70kWlB)bo;%Y7U_jQ%<b3mv}OTpYUHLs>xHbdI78XdKm<fo>`$+!vwC5 z)j1&|O`I614Hbv8OIEnR)$wh7@QX^+a48wgbvLRmptY(`Y~%A@#0`R9Nwju3)~7U< zm7V2ciYg!jipwjD>6n45*V63Z94Mv&%tc)c8688NMzstF2Q|`2;Gr)me$gVqs}LJs zQX-o~lE28chW0+Rg%xEA6SP<N&;ixidege{ss#ZV-(?T)3NV6S|B@0brzy%(4Xo&T znmY6nl*aj#CpMm5R^p?Df3#=$ID1)1m@3i&G4{dW;u@0xm<|GBw(Uv^xZu@AZG7#^ zN^H|2%CJkps8z<u0w@3tlXG-27O7I~8vK+))_cbCL{JwKomkn1e8wwEWVDDG?p4!? zufY7WxQ#D)MTs3pozfYAU2&-+IGkPNR9_3L4(*(4dc;zZ6K{J(u|^BOcOI?CW2#6C zEH16F<CYXoz8H1to|^`|TGqzLzpBK>ly%KbKIv5@(gL9KUxgesrX`1)e9_b{7<yq< ztSBq4r48i@A{g!J?_H!0^W+=JTCMTA03SF4+pDE3QAc4Z#ahe@UjnGrZG6&eO62L) zRE7jEC|53m9>4+SU))HS$V}wB7+@NRTHnSWdQFKQSx=bV4JZ@BA(W`;FOoRjlt@ZY z=x+d{8AftL%KHJ7S(mcS3o6t=)g)e!<ixx#B)UX4!_lOm$7%(N>9V5y-PfT)inM?# z*hn=itkyi<($IiW*AYFJH1tUDl7_C1;Q=|YzM;w9Kqn~<+b8N92td7<a&+;<9NSHM zn8AXm88Fmnxo_mBl*W7V)C8tp(YEnTB`*33%G^ss;$z-aqQ{9eNxS5%28XFGidWAS zq$QMkO&f0_+ShbV`$3{D(t;Xs6b45cd!TKCQk&cOKcL;z+$C*SYq;Z}jzMLORkbi> z$~KYnm2)5z3`ZsANAC)mz||WmvxvER-$PQ9PD-YEG0;^IFFHZ>j>>YF)*R*$?VY~~ zO5Nn1Ka!^D6l7XA`Fqk)_eILZ>P4-5@or_P<#x2zZtTb3)5agzt)#`?i_BEI)L=;L zMb}{^7|hqdqr`-)u7kl`2y?)Pz70bh+_blqkr@wCA!D)&%N%)G1&*A;?9BYULVE_} z42-wU>V>qNquUTf7I`<lt)zuLLV3}}2rcq45VAbp#yj3t#)UmeiF89kOC0fzGBoTN ziloaDTI3n;C`n<@Q6$})ph%SGs&}x#wX2P9dj}@y|F-eZ-@(a&mk7v;8xR;FFSqgN zca_ALS1FF}QAlbCJc}3yKYus2?3TT&_=mqv5Olu+SQnuRc99lXS5;PlspQQz-u$kT z8NQpK=*EQ^Dl%Y&0D7m5|L`sf^j;f}dQTZ0_5lIY1q`hUC%lKmkJ@<Sd&(rsCvAND zd)Q=YY2$m}Q*y)G37BqSfbwVXYx#@K;bwJT8=v|<+VG1uUhzH*Bww}h>)yu+gKygS z>+dV+q2CcUUC03TJ#8C5P~t-mQq)!%^=un&|3I-uESx^GS^a?$-gZxzcKpI-^(RXB z$t{6z{y-TR`U@q*SOs;R)YMtP_>~flH76v5{!VelM%<temBi3LDegjZoHg>q`BRIU z)xRm_Zkh5KD)%8aVgIGLH;lL&K2%adecBOs(1?4D;s#J$grc#G|ACw=1KT<K2uB|R z+WC@?ltN2zJKy+`GQ)y%E3F^Fz!-`rSU*-yQlf$D3@x646H|1P`NRghc7`dYouB!! zl9j0tK%_mpG%G8o&{3A1gC$H(4jttq$s2}LyVJL}re2z}!`k_KA1j&3NrV;ag=Lt@ zMzwIC&y^T{>?cZ)RW2367M?Q4-GZ0a&Wk_608JxeA)5INJBT>6iL7DZPW%)TzgxUI zf?y*wQl3fN{wZvSe|(~Z#tJy>MTip)9yEvA#+a$N0jXo!iOPsL0WwI>L6;I#syjY~ zNiMgYzws%Ku)wYU44HoPsS*~KOJoP>^vpOTKT}fU$5L{nR(5wNb*!K>(gOG9&oF$D z&vT!_Bs+m{lK7<06(vYJjG<0I+kUPjdGS>@2u=}vjSn(~%RX1eT4uEKO`pS(KeL_h z{2YU8c02#l6;8CFmFXbdT*}h7w5C>Wl?!1Blr1evbbyFe7l225aI6in=k8HbEGHsW z3qOPKkdujmUtLv$v}TcX{9zBaa2B`o@D^;mBAng=CN62`^IhS1y#U3c0JMuF<g%#% z%u>?MpKFm>f7XJm9qs&IEo^N?ctty(*s4rDeI?QGFRj7L0k{uNf=R3md{<CU7KgvE ztSc|b&BiUcvfP}~oa_RJ9cFb2uhxnp)Vp^7Faq^+P<%m~5)~uT)CK`p=O|sJ<-r5n zl#$A65nX~oXJoCOi8wlnHor|_5$6zqUnSkLpv@>M9bem~q(`h33HH)bN3C9Lz5^s< zE}#TVwGH(cL^WC>riMS;l&O|W+WDk*w6L?CpVN+WhS#+7huW2#yz2=m+Pj*Sbhtx| zF&f?h#ZxI_h8T7r8PlO8PPma!1B>U{S2`xs!D}j{Rs~uTTfK<7K-F8?d1D8J(WZ9( zYzMBai^WVO2&$E}n0c$(`JoQ1WAC6W5_!#jC1#Mx0B}b;&)kcpP;EQU=u}v|d!q!O zi26I|5Du6N{_`z>QS=Z9>Hwlq)YTHes)qo8J>=>#DBC*UzuT(}kA0BJ5^ADN0P2IH z2&pnPL`y9d+*3I)`1AXfI9rA(#>ieYzIu+xJ~>9T_aKdc*6iw9jN|<ZOK^oz1|3N2 z0_p`4Xs9a;AnFGV6;%$LjMQoY-s0HWwO?R^cI7@LB;jeQPq<MZ16mac$%5(pfqlxL zAtJ)B91mGk*T_D>-`uCf$2?CI^wMa_>hq#BLoINJ?N>4_FSYZ<`!PSi+RoSSSEAy~ zjSTbv6tK9SmU?{smx?uODug?<E%gl(Z5-ax$Eed+z?%9QuiCFzN9d#SZ9)r@l{!%$ zo9`gfH8$6Op(p_&O?@9T+!snjhybvihK{$Uoj8=tJ|a3=KM`G@>P=vDeihv@E=?SM z`qY#iwwdHu7S!~y3~DSuB&mDadDfRol)p%CYUkH{iF4$%MTr5fwh<+*|4ep`Z2^0s zfE_w)FTo7fE7!2d)Vu=jeqoAA5-k^cqQd}C_d^6C=Ya%eCx*oZA76hmnFpHHuiE)> zU&;N(WnV#T9)N)ON*O-u0A=Ruz6g)X&neF?EzB-=6xwqf<%Nz6xn@5|u%X5EwH0F3 zZjMdhO<yTWtO?G~ytL;DUqkBu43YdbhWpP%CrMxg>5Fxwt@|44%Wv)csjtzW{%q&p zevLD>f4B44Z!ksu+s-F{ql_Hu(}6~&tIiNZPCuOAaM*EA!-7~kAX=CQW2ZfPtUV{U zATPHpqg)(K#w8Tr4u0o1%CS}fC@w;i7!!SgEKwl9|M*53-6YfLdNeu$9gnp;qr9lr zHqzoYluAO^r-_m{Njp%KBH9bSTp|o61iHTMp0yc^-*rGq3>Pu#L;<N%fG_w4$IA{J zP=YK2JNT~$l#$C~5$%l0vD@=;WhZBBVTmIzzaS?=-zN!$M(K?8N;bAFA}Kw}D_s~p zQ1hrZe!;g`ImLJIhrdN@Bz5q;<fe4+$nTUqOKJx%`VOs=-oaOYr{qSCpsMXCkX0K= zfl(d&x$l&OxC{!kx~Cu}O(e(g(C?LigiM0*D-_sJF&pZ#nuU|y3^>&Oo$r;%7#JZ+ zt6)#fCg2PS47T%S-zzDR`4qXxh(w@3%iuv|5H^;Q&o+|zOW!NQ!j7fLO|Hm4zgJSj zCQ#&yS|pBHk2#37++>P8=!z^ms0>r4Q6$~sq}H5|uUV@?J(+@NQQ#yhFf=E11_4g# z0+1LK9Sks`;Ha}Y_+JOHs+--x(+**sG^c}~a7alHn@9K`X!y_$E<1#VLB*dqq~wrx zc!1nfI(Xs_xabM@gde2V*!TkuTA$v*xBh^JgWK|hGAV8;5qoyLEcI--YB9wu>)>bp zs3?i6E2?wA^%9EPdl;zXqB0~qqccnM3-WVwv$Am!%AQ${!G@&*#>Egy#nDyI)bdKQ z;;T_a`zbswgKmcPPwS63|FHs9{}Cr%)DAxMC#Zv!=w3g871bTQ@h6-#sm17p8(c@Y z7fm2s-tnUn5s6)7+>~#i=sQKUio-M@86AL>Rn6+E4xaKeczIR_pZBvey5L+Yo25n= z92;*x2BSNoAh)nAGdDZeQ8=~$=LIq|kg7HjoNu|kLLAp_<Vn9MF##f|UeLkc{aKkh z=wixr^d`Dbr3wI><%$kI=@&5nst#WE3r5Ga9sJr~u!g<9gFiv>XspkEQPTZ367@uW z?XNh@m-s&=C|pGNnszz(vHw%zqi!a+;FF=Z*3^lsmU#K9gIE6#ij+tiSiHQhM%;S< z<t_hHY}U<$5u#zpR8_>;WNwH4r}$eocktf{SSVxSh@>+}LlMXH?(E>1zbZ+`-butF zA<gWC+1Ze)`6cBgWp;7snfknej&qv^0jMLmH75wL2rU3Ut%02dd_pmw{uRfO?<dN7 zo=`WM)%zuizaAL$n-Z^|yU@y}9hu%nxLS3V{)Xyo>)^|OQ*8SAY7JUQGWBu6E*4;f z!v9dB!i@7ZvKoBvZ<t_qbnxKcv2K8y`MVMyLDjQ61E(~WL#v~s-0HJ@*&m8EP!9>X zD63rDsar{)3TPvO+y7AFrW-+|`<BXciGp{SSxU#2=ax8fvr6q*rKQ=p&>+&)7paN? zB4=?x@x=~~awk~eqG(Z2VFhOcj4X`^$}-Us&_-@ln(5^I%b3cXgNUSOWIPZ1U5N=c zj+(sOLYYM+y0(wsB-{`USDxHg-)tdnDLnH}9OFV@+@Fd~W0@$pWcYic;BifQ2t8pH zww#IWBqvqc1IE^j=SwBx`e0eba_r7%2faQdj>LMw)$7x{KT+GFkruOh0AjE?C{Ru_ zy@Hal%0T*rh)M`EKz+4NHJGTrET}py<*S-;B*n7`JoNSf(NomV36h@spsJa*3glqH znP@DNJTXxaBcs+1{@7niUg%yT(}^F9l@3hwf1%O$cktN1F<pIyXy<^^8eyycx`R*r zSBZ|Kp!%&yX|RjKj9N+*1=WL;;%l$Rqk5o-r00PYEyC)LGR;Mh(wJRP{DsnjaKy%5 zjTVsCOn~k4kCHt2H;L!Uj_?u)v|0U=(gu=0n^q%EA54E=BhJC!8Nec=MZEftAb>K7 zL!Ek|L|C=#r2?Z2ZfPQ{4issip{Fey$l``zMhT#V0gg4|rkYm&ND8XKBBip1t_M=} z!82uWsGw7SrZ9i$OyTSPRs6!j1-!k)%;P8us*wVz+?9k{v%xVU7M6A$fq0>auxh2W zz;ZhY?+V=9MhVh7HrQB_#kP0DBo=8w=wvp`mPl~HwT`-~Mp*E1SBW?$^d2>7?}nRL zO6*XA7=V*fB8B*={wtVz!rw|nBE_r2L_y${d%G@}#&o{xAKZo$N$LmzR$Ag-^#wl6 zFJ?3)4P0?nt#<i9Bf+bDm@Pb0B$negxVX^*PM$e{MaRepHAhl)$jMS`P~Hlv;rRlw z4%;`vq@W?j$_RC=NX5$%)pW{=nu5qC$_RD5AX|>R=brVZ8YPMZb)q0ae$SfoYX`DO zzS)9OOc9h!Fnqg(rG!rxxab{OnWpSxWQ2OWKth1Jve8X41~9+Db3_t)m^mp%gw^?i zDEw7fE~2*Zg+^X_FQuwty|g?F{q!V}O5;-R+ags)sHe(Q)2NWCa#)-$Q%&Q7Qu#z* z<{!RPq%F5sRoPvIiRM*E3$s(&07o71O&c50Q500mD8(0Ey;Z1J$B3}HTu`LJqvMI( zFnW9=fT{{q)I(1tR31MNOsf(}D6=^!T7=bFk%lVhX&Blpyk6u*V@{8zyy9epx{6Z$ zL>JVPpBc#F!_N{}rRa@%wBVMEP|p>q74_AIv=rqZ;|FdvX=$#~i?lP4mT&>31=Uwn z;ZAc|S+3}kP9J--(+4NraD(#d0H*L|LCkk3*4h`lfa@DeB(Qo3BGpUjM*~lnY3da& z=&Hub!$7lPB1yf<1zc9Ksw?2oV3sftg}8Pvuk~k<AtK)fVKQL+1b-Gilv)p%>h&&K z)sE$6T3QKHWVE``1&GGz0x(@ht2ep;tL$scfToJGVIoPr#RObYeHh^6QJV-XTyP%j zDXzx~*Is9Wh7mwSiDnobh-UaTfQ6?2$Av~0(Y?^r+W|mL0hHm%cM){3$Ye!*W0i?K zKuD30tm9V)vVf#}30U@pvKrzf32e9KMH{d&B1yg91zcWb_XKthET!`st}bK?V*W`F zxp1hnQ9t&`K<{q;Nsqc<sXrYCR`fND&nH~a)YrO(7JUuCJ6yoj*SY{kJ(EW~Ltvr$ z(7=`dI=kF2FtY@_#*%;ZAg1I|b4VcdITtDl-!rNUNPWSDO5LKzTwOrwOD<H@t6S9b z1~Harz^JbhW|*id4I)oe>MCO9hE6MnTBr$1ePb_wE`-In2Bgjr{&xrqPTlP)6^7km zND~LsM!f3+MF;c*6+?~eCe*u8fwZU(2tLp#wkGhuM`I{dz-IMh7l28{0YFmRXOtv6 zyJ`L>`{Mcl7Rx7vGXJO+7dnYq6a54cR@+@fOuB$U<UtUL>vX}GGy)waO;ZZKAgBOQ z6$~ejf${KO9v;pVe@aom-pez>*!0M6T^Qi2R<@eKOc_Q&^#@9pBfqMmnqCxk8*DW4 zI|5h?Zx3Vs$v>Nb?Q0GXoH&^INB-){n3PdD%TmU16jc9kB|{5vB_~Gy?MlH+>Pk`K zD5xIOX|MpZrztssg6aTQvWLn@%t^HPb@H5WHp&v%$?fEZbn<J+4eR93k~^f6A0RiX zlgABVqvB$T-k`cNJnU1Jm5*a44pA3a2$v3Fsd0)aIVamAnI-E{YP<<9Ki3m3SdUVZ zI=N2-i?T@iu{<+^4YCaF<P$w2eO;u7X{75NjxwDNxNV}~%O8$lftC@S{OJgmX&K$g zzauxZlP5&N&FSPPM54<1oxF+Mv7P(@xbfqOus>B?zprSBG#HyVMzSdRdd<X69udW+ z#Y`diVAxOyrKCb0kxJUjtD{(oWo9S8K8mG}n=OboR#)Imq*rH)&CDswag;i8^76{Y z=9LxX<B*92ROfc`U!u@{IF1k#&5|t(I{C5DY^vp?PQEUh9UFfd(G3y0-YPp*9NJly zlM$_+(#b!KW<xDYJNduSEHBwku!E{m0DGkwxP*X9@#En3AuNJd#IUf$asm!TA0_xM zp!p3kEX`8U$)As5v6hlf{#gtg6IUs+sKvWi4K*$#_2f?KHqpE=7L;oR<<*XglEzB6 za_EI#9t+C#=%BGof72ms(F!^j;Mygm;R?IbTd^!FbPWiqQ}Ki5M_fo8vqhgxnS^Lq zI3z{#?rij@IF=&QeAOB;$~21>HqX|?F&5WEc)=Q;08vF0<F{E^tko0~fOC`BWD%Rx zlx<ran&~3+V=IgDyNJjn3Y-uFPDSb@q>@GO6e~-$T;9poTA7vHo2+bP?&X9PZ7<0z zv6pA%W;sgpN;0#v^zFqTg+WFunzrTmV+&P@r5HgFK%+r5a<NKXMPw5=9{P#l^A#3k zS=Gr;R~U=bj9n657y+;E<n7o_r6-%9DPlk<;3a{PwJ%Tt3M&*BfQeb0Xk)SLQDkZQ z@gY-Hki^nscoxHA*r$yzVr+)xwoZNvW7(E1o%|id%Ud+^L4lC6iqZzug6?k6tM#3H za3Ztf#<wftp%fOyXWG~xaW7hXPGFFRr{4>^x09b~!zh4@EMoYBHWsMeYtggN?p{A2 zvrzP#+v)>Uxq;&K9|&C0;ReLBr1%Z=Ksx=Y+Xx~^=17<2@eo%he=v<%10@y(m&CKw zMB<^itL$(N)(Qw7<LDV(cUPb2<Xhs|Fbmw*0WIHE&~7%99;%~&^*YK^0)_F+1Qu*T z;J5@9CpX#!-t>o2I_zXDPhfZfq?4~tU<$bpCP31`1uLQwKu+ArRu|AASji1j95Fn_ zvH(~1bYNkZJlP#sizDFpR2M)X5rXbuzD=p$)xJNGCB?o*tP2&qaDl3?b@F*B%*xj# zG2hV=9dX2D0xGL%q}R@5TWAc`UgJ{uwnP>cq(P{=JNf)148+}po5;g$kUpRpk{}`i z1Tpk4FH(F{GPByKRCrU2aAkKg;1NmPNfdD4P#2h>NE`WGQ{)qqVQu-uouB|$KXDQC zP1U22v7qSoke6}S9c4_kv~==a$#^Rgt|-u<WEK?NLOBGYXBDra=Mwc^J2-`<#qOmv z$#55dx>qnfb-YN8bYzxi+RGg|rFMIkBeyVLI|rr-Nzs1t)_;I#I3Xs!?Bp1T3Cfp5 zA18$H0wk`HyYYc<PR2<6Cxr#Y9B}c#096mjI)u2zh|zu8P!^(J02NspPa~*@1d=UK zzLY>gfw99ILx0`iXMw?(D~uBR<0^n!uNmMVnWIwK(CFW&lyX4m$?9)XJS3PR02EkW zS5xIi;IdRUI`(fDvt0n{-?Dex+@e5aARVgJS;l?SSaRfmeTbKmMJB2P_6f-nX9Nk6 zo;WlRtJ2u$$N(3jOjH8|Vp4=i@fXi%RtUo!YTG)JOmFnECZg0(!W~q+2;mG<B)@hz zhEK*Y78*(r>cJX)UuX6(W{Vsma)feMm(hq96R>A8WFMa}npvZaAduP&r27ad+J#hE zvzm~iC6dhu5(DtGNCjRCm2ZyFG&>}nCC4d*942x!0jSD8J~y4EMT+Er`qlQ@QhMJ= zss)#(v&5K0LL4Lzjbt@(A63vg#~cH&fsnOA*dSXhNSx6nIk@<mTTq^ZGm<zgIW|KA zsHv{17%`&$e8O<72t;xKm885zJc&TnSUeo18R068k*tmor5PF_68$UcB@bmC&|0y) z4Md~I5Ne31hz_ET*~iz8V$7;>U4Vdq<fn^(&fr`#361Hw8VMtaTtLEJS-V2m5@nBx zwaEx|teJ!nN2RdwgCm$<ga7~mv8|&ugs4Q~NK|5i8C`;?6SNW-LA?ZW-9@}30w{s_ z4$M?D2_sIFAkGAVBGlK?d$k4|5~63BQDv$+OXkkUjAH%~0)T2?Us_S&!bIL8LY-?S zV8l`0DG?$KxTZcN%dPd0g=SnMPPAX3D;PQ&TG|5IIl<FM7+&J;5?-Y1pzf7qfomVl z;;m1he>y{G?r`Z#BF@H_jbX9++e=UE;ghpi%xFzBGG@^zdV&8*&~P{hX+(78>5P5+ zpV3gB;3B7(Bu!H)6e@rQYmU=0G@|%<8O#<{OyI!+Tz_()xRoc4!JLqp#RlfPA^{g! zP--tL$BS={v4uJ1Wn(kN9Hh=B8Uccan002i@@-?7RcfjTfLgLOoqz^w<pP+lET!W? zg-piAx<z%F7bf~<wUsn&nU@x(yb>&}c)oEARLHN#uwZMlIWK_ec_oXyhK(2L*uN3$ zW+_3ut0wLW)>B`Q*=b>ZW+qF>7xB?v?9g_i_fsK*L|x4>ut$$!(fW4v{ua^X{I5(F z5Ho>FY_za8ZBD?8Kcks3iz0|Vk`Ob^46DzV(*!IFGKFsiuw~aCzB7wO`|YBBn8fXQ zEY4=^wyPo*LxEnJ)(7C=Y@l7Vk7s3LIRy8NJeC+M($$NI8-4(nt8W_c>#|wA<??-e zb2f|gyPVP!C=(VzASy+uO`qsf(%0E6G5#t78hkRXi1A<>h-s>%h!-Vf%p4U65JS17 zEQ@nkQo?maCEP?s*DgguvM7VqEsn}fI<OQoD0f_vP>DHF3N=x3#mcJ0x*~{GLIIUT zz^b?e5ms*@Dq$undbHqQoE`!Y(V(uO6-3YwVRefq4Lw@Y&_fyxP5&g05Dh*dkNL&j z<w-(7sdtHHOdBGSi4k-;(ZmRGS8=N+BV4hP5&l{P|1pncSRUTTlk;J#d2}CNln*(C z70ucCuns)2kN+p1<y)T;<mCITwRJVCD(Gnl%5xw8k>H-)$E^h{K7~&GKsSYXWO+^9 zS<MbSvrp!Nbd?g+U7+IN%bFAx`2xInao;VGUs(W!<wZ)l#UtgJ0+tZ@GNtVDNI6)* z5_4XqlrP*<NX$m#vmZFWmsyyXRbDbSuRJ@W%u&(^yX5Qp_>@AH93_^E;VW@YLY<F6 zr7b?sDr8AMjr`_942NC&_|t_L0=p@Tg$4`)jr^NJHimsb2`9NFpsp+Cs2}e0;UBJ3 z(iVJ75b`qs=_*YED`vx943ldqeQmH=J+N4u)9`x0-|O=LpNeX}!nclvF$1iBWh~2T z@<O8>0PPb2dk8^(A|M?)9=-psy{o>RQe?(md^w=&4+rceoU`wiY@&KNL(1!dp_NzQ zlXi8m$MNmc*|doL1opZH_5}hfX7ljLP^iK#SJFm&L#gr`1L;oxl198<MM|l70VNRj zBTOBFDR_>@IgX_zd`Ix~MRjVM?<pX19zYw{^eoc5<5>3iA1Izar|t%%{z%dEs1{Za z*aep(#Tg`?^wy5P{IrixJeCbh`Gr8~Gwg?<pi02R5f$aazWh7E)5qGoflnCE5=WKR zRFRnur#A?LKI+~*#_%zJ6Ci!_{cwQ)BY<D&=O_H|cP_x)o_{Gw--IV5*~e7kJ%4UI zo1WyeAF1?pcz2TGy)mMJr}i#XhKKnQ7=18ag7GtsgE0d<PMm;c$+gF^sL_4|L7$Iz zC*)7j0r-JEcZIk!E!sxM8z{ctkP<{t^qqNkWTTac$3PjGGKc`_>+;<LCUW}FLrNGy z(--KwfksnAi;qC0gcCG<rM@R<`ancj1VO(tM?ychhdU>+alyFx?!c8$x}(RNE>=d4 zh$1N4QVB)OmmM{BIflr9$`$p^&H-SHV98e#S!x<1c>3}>mB9sXW(2j#wu_XZDTxFt zzd(^LEN`&T)HK$WIz;}e70En*5=$6-m`_tA6TbX3MY`xO5I%mZ>~%EA@TT68e5zs? zk<dO>q2Aqq0bQiN4oBUCpYFd~(bTMtAZ+c!6=E=oxxg8K?^1|wtwI>PX!Y<Bi%~>N z`-p{$mYIOZM=hq}D;n}M7-E^NeG6j@k&$1uNS9<R6hkfHaC&{@f}eSrl3JKW5c2aD zTAPW{BM@nz3En!Khx_hD4x!8MUZmrlXz_sydM8@TwC4|D<Pib+A&hjVr4+(X3|wcj z=hr9XCp1XrxIT%|R7lwJn;7ZpSPI<Jh9617?GqV2eIesmLjFR0Aw#1iiFkc0BLiQk zXu#oGSjg<Wa3%|xcpRb1?`FuZC`<Agajz3U&cG^r-O6HoCxyD^;XbP|k*LVeYG@51 z*iQu11Nd<q(U&%+5Ec2Q4bLG6?&8RR#$C^ELd-FLZbJVC$21})zro>2Or1_?l9=n` z9B$v{m`M=w+Z^3tAIV2Mjwe#`qa8;~s>$oy9P)D>MMO(}&Z9e8Zr}OvB4ww~e9R?E z@-rV@P_iOX@~7($fHbM|315By#0y^xLiY*L;q3VvAtw+?`Hc`SlBO1;kB1C$`)G^! zdPvNPgsy!(#5qvt7P!2;kMEw!j`jNBNLQZ`IcYz?Z6+H|lk00US>e>BAm|KqeTVq^ z=HUy)*UJO(K#eL=edp14gN%e}FC*bgfBf85EkO9RSu8JKfDXh}srj`o*Z@pK>Plpx z5f!+D15CIN&0@Js$8DHjr{k8WBM5ite*W()7N>a7aQa|bD6&6$KhHUyWm({sAI~a> zpKoNgBGW79ONe_q+Mma>JVJxZ_`KOH#DdJ0%w|{ni>6(+pZ_qMrHxu{5EO6rc+nhX z)TVYnpIXFHGwNL!J=FhfK=Sc(u-Wi%5ev*&OT`n_KJr@F=3wh4tg%FOQe#|76!Z!r zsjSE1PcRq%fjKO7RBwvU{{cpy%6;-&mKx$#+)L-OvW%X%y}(pl(lO^TYjz-NznpsO zk#o&4kBy<W-#CxWq-JlM$CMEIh>j}m&LGBbKFhF*emMY31HD(KtK$2PSS-(*&s4&E zYCcoC?{s3Nr?<(N1?X(n1=!U=Z$Ti1Xe?U5CJcN7O*fBcEnwD(v8d2{2x^07gF{$8 zx~-jCCP^nClaLc+CJ3Yq{@kFpB6FVFiY!lnb@7e;d^OzT`jHpfVCh2i--F1_w-&j` zVB$iYyEJEtFZCkV!i6%|(-(sM$lbY+r8hn6D%)&zDb`G~4R#sP>WlDV$xlr~dh4sM z6s<LYLmgnADww#UXzpAewGcWLzF9mQ4h5G`FanJA#7+~VUGyIhA)~qk6}rme6R{<S zGM{rI_FLcF&$qmZBiy2c_)e!Uq3iMyV(0Vyy!}L0XhDswi`axX0cAP9+<;MEz`~zo z+nI})m3d|>3Z!?KyBA^C7?AHQVzJ)M_}e0Eu_JZTNo;X%o6(#NwcE*P#zQ9=&4^%3 zcw>oO)JN}&TJI@5S!+kQMZsU_sj^yOuCNe)N8E2wh|^C&Av#V*A%tk8V0t7P?RU%t z=m9YxZC8U=h=93!i9S8<6gH!`OfZid<iFrl<p1$0Iuj_E5+#|?Z7YpDRd$ZKr?TO* zdKgYe%nzQp7~}Y}Q!$Rw|3n~ou^iM0q;%hJiWkcgoxhk(>?c#MJq=8WIZbB@1yi)1 z(JfO}o+gWM)oJK0=%f#y#@NUsu02{~{prZ~GN+y~1;-3QZ=mI^R80m<E-TYVRf$JW z#b?A@F~Uw~b7<H;cREX->n3XGDeCS;jhCzty+xNaJa>sp5`_60y<Q4{YnNc$BL5vr z*o6FebK((mfG<4*?SK3kvi%X5-Tg%4rro@IhMeKxGQR{c4LlgSl%>ye<G~~S6}SAR zr7UTxr%a{GhrOMW#}w1dSS%}xfDpDP6nDeo2a4HZVsXGSHsScACWZL(%TSQ5%Va?i z7-s8U?D*Q*44YdEdr79{c2?S>YV&eFm?p%&m`ATEW!8dVG@O{4dZUzK<Qyzv*72eG zQ0a?a`A!MA@N@|abXU?4J+b><XqKqFq7+mXl}cVBFl}@X3ZB!aLR0Jo6SkH0O}|Sk zlfD0xGM3zh9&$w)n@$qx-7*%N;W=M<$~0HIh&kyB2eS@>_|xYkkeT3Miuc@H;b1ez z_tY&tGkYGA!cgG9b+BQ6QhDHZi!IVi;)`*nYYNAgv+2X#`k^Orb4~d6a#k|x6hkm| zy|{4|2kPqd<t#OJ88EsOv==OA6EeJ~zQdOR6u)22Qo8R=Zbe?X0=?<Uhh%R;K!}K| zR`fXh4y|BCy<L@ssTe_N{TV@rDp1<bD?CRKqK~5qX^hG;yRW;OJl~;Woo7LL#5(UP zsK7=yK~j3;wT4oR&sPe?_4@t%7nPk5wE-!OYB?58=RtYa*S4pxJc6~YYn6}2dSGR* z7l**;+v2d&YjIe41Z&v~O^ZVwQ`P&W_~2?ZI*o0iVf008{!oQR-&5t;=!oulDZas6 z{PU}OU;MLcpf7!2-A7Bp={4wKP<FepBp|8h;@@p9{(+j_c9!wAee5jFKy;s^UaCEU z;_fgP_oOp>&+U12{p~Dc>JH0sB=yX3voVA}SI1I&Ax|dMqoWS5m$DRrneK{Vzt`dX z{d$%(!&5PIt+jij(C~2$ee4_80nxp0{I@}hUrS>*n&r|)_5f*?gI2K#Lp-N&O!#N4 zVsW$N#B8=$)?rmo28y0E3bTp?Wi4qnR=H%tJCarI#?@?Mk1C7D(*7OFfYty<k^z5c zH7m2kf5D^HuzAONPw3q)U(6Zvx7VPHJ+%g146_FU-YZr!BY5apazf8MizW3d-)GN4 zzW1CZ^F^Qw^VcEdp;_FXI}1WH^K9nZuRJ%OjXbYBTjq&C4{D8D#ck&RH{cvO6cG?= z&BSw#vT0@Fxu|FPWx8pFg6SmfkEl<?pUY<SmOpNFeCJ%$@#%9Ve-QBQ3vOK}>^#YZ ztn-ehJ>@^=$yLGo<f2ddu4O3`JQY-PIcURq?v0u)F<IIY5frvW(hZ@;Io7g?{o>5v zCUEA@wURRk^uU?<O_DQbHnF6!p6YwIW7DlY{-RvTv_gD9pc}=0>^f;dxpbYU^<a6w ztp|UvV@b1)&Ljar8gc=;_`37^sQ-L-K4#-2w5s<`3X+7*KI(#QCXLH3VB=}hc=-Z0 zVX^0=an6^9kyPlG>kwA^GGFjBF6_}FvE{<v&k<){)SEeC!9{Y8c;cdd&Jnd2qaU7r zvFwKkc=vv{Zu`*1viHAxaX;sXrI#Sz<1dl<BGAPgvHlWcj#zd{-*#opvV>2*6j_eC zRAz}lZ>ETygnKXH!V-*tm?GLQJ<3x=`(<uZ1O?4g#Cur!AKv=@++}RW(KCHNbU7+q zak;Fp2;4*g2rC4<JBb^kzrS4aXYdtlc)vt*!xeI#xbuphvfOut%+l}5e$EElu0*|W zxl&dYfgY-Q=t`Ej<P9wF=V79{N1Lbu<V1y_n5g0)()vD8-0DPu^oat2ZYGM)oN}T_ zzsl3peqN6gMGvO-TR~Fabn`N`|9%yFgaq#cSF;HdJOytrb#do4=<`Rai}RJ&VEYZK z@}t+Vc}I00to>RViP!4N8U@Y!U_Fe)Yme$kTu&o$y*3gla1#Y+B(Cq33>$SFaAU5M zgb)xiY~FQj_))ao|3G={(eglGn5}zO<z0U?S@qxRrGEJ{xnNLgbFUb5X0t?x%lw8* z_437LR(2HmbLIvuiw)q@&J8TM2mXAq;b`)wVWZ6bPIAGYk2dy-Kgpbp8A>*I$hz&C ztg}g3hoD(0Z{%$FQ5}!x-GK2p;0Ap>QZSuPX=sb5?mO9%8;&Lu=iG><^Se<FBM~T| z0N9B@Z*+>+h|psiAq2#DJa8i`JF1+^xEY*#>?WOa6ikmkQqB#!naw!0CyDO1=y3~p zF73>!B$f+nZ$Z&sx>+xp2>#D4n4jn>sWkV@Y%sQ)yHthbIhQkTVKZiQJLev8IeF2o zXr_U;%Jvq4d<vkw5lBrF#Tsy8V~J6&E_Y`(-pVfPmo9Y0Z77CrR6(E%h56ar<f)K$ zxc$njY7_E0b(5?m0$t>_d6S`>*K9&Fwr}da0ms}O_=3&I^VrQYPXxNi^TN$Wo=KaL z=YKb|A+(e8@n%nb=kosQJ9D;lqwn0ag-s%T=bJ5TLa#R%-6~!7pB~qe_xy*=h<Dpn zH1BT9?jCYGD?O@0W8NKLugg|N!6RRYjJ~7W5{pwI>+fKtJ=JQ+ovf%A2K7ts#Jd|< zojrD^l%yZs>1i&xrpI2<!`U`I=dPo4*rMYu^!7LJl0pRmA^Qj1-A$(}zMEB1r`vsZ z|CQ_q?m>GVv6Ah)r^gN6gZHq~9#6Wuwvr(`*WTOP{i(Ns(WlMKQ}2UaiH<FK+m(>i zo6{6OfD+$xpKLV*ruA57xBYwj)?V!pwQogkZ)}yhA<)%9iirE!^zpB{4iSiRjXf>7 zTn&NY(tLl9O8O`F_xB*h=?}1B!#m983s2R+?Igw42YPjqBJRQ7o}{?@!S2@4`yTB5 zNs0vz^`!f`as91_(6;(X3IxRXKlo6O18w2My+28D<~Hn;jza(M^QL;zHqTu=#4ujH zP3jx#w|UOL8+w$qJ=h!k9_dCDmOR4dlPG-jk^auVqaW>Y{yp>2Zf7%btop-8kKlNj zcsbH_yzIEgF~zQXj0N^$ihJZSxqj<>tV>}K{WzQ6+f#0d+xv0KZQT>-S^YZYW`6?x zXwDO!$2Ab$8@c=kQQ7~5l#~ceo6sMTh?PkjxRP!<W7hrpa_4q7v&WNM=H};FPj)AN zs-Nt={Q2z3Udf-d9kM5#vO|iVvv#l<-Je}^l^>JFS37!j7S{O`+Gq7svV9N`((b{h zdUgJ)@M+BAU7x=~(qYbDH9XBu7$(kNIsN4KE5y|*VXa<fKCrd?8z27fY!=(&gdU7< z5$K0RdFC@LWvu5xif&hyZb!<T&#=*?vBK@=si*K~S&I8H3&dFYY0n;kiefX@=yee4 zg+PklDQhr&C!5+M>&BQfdTeKJGTQi@$On#<AO9R1-eX?$){fCkw>{UJy!baVGjgpw z=Xo}~N0}-va=S!(>n;{MBLEX_mnVn2>mN=(e6?r=YzfBM!mpl}9FEz=Qu?I*Rsqqy zYaqtTpV-Bwxt}<4-M-pojEr90{Nb}+z>_nt?#Dx<w%Fbci`%}@n+wC?sTX9G;abOM z^ha-*_+QVuBL+7b{)=+LZg4MLucPy#mx_k#uAx-7fgJpzEHPZGUlB?S;-|fc_k}!n z);YZ%Er@&SziwBZ9(obakATM8FXDj}?W$A13_2&h1V*@xiHlxhNmGRF%6BS#h*7^i zrQS$)JG!m9TT$a*219*b#%mF1IRs`>xtG7p68cr%T`z;7SS7+e?EN2?I6=;%Uy&S} z`wC0w=WUx&uj0Xy7yWG7bvh9|^h%f4=>lGr9ceh+e%1HFSJ~)^bl`qPQBk<OIVU#} z5fXOw!(8`q2_Ep^;H#1cVXyVGG!?H&?%(hlj<~#qp{d=2?73^Wl_%+Sbd8YLq1*jQ z%K`nEJfeHP<LcJ9b+5A&t*_2)taKTGkKn4Vo3-s@&@qhyu*~lbwuCxt*&C=a-0R<9 zY3@?-CK|EgPHJDJqW_yLA;&`yz(m}$6j=PGY|pdabV-4uxD_?%Eh)6%y6tVcEz`}m zMsde)?OSXL?YO@17Mpz(3v<$LS(uA<<I(1&`}x-0EUtS!#I0q&)6n5sdH&lheU{sG zuwM0HGhr+R{&^eXVCUN`Fmw}j1+5qB3E#cVW*tQ~tbIqa0j_nj6%&cJzcucF>EuVZ z!r5GU9`LRtSMV;IOpSK-yR525)yWxX(r_c*>y_$M{GQAZu5~`jkACi{9`~v(+-BKd zHR5US_hd$MV?x9GvP`$X&t^=e+cQ#Zc$VwPxjO0tNf54e{3KmJ@k0~!Rv>Nrz*8V0 z#>)TrfGz2<nP%c!uZD(u!H4}?h_rqvYXsLip04}$*-}*ck*CIW-AC-$-c2HIjqdlc zELz^jEY0ism8+{lmaqPp#dj|<+z9Xd*t4XFv2y=U*zq&_EIgb(_-dvhA~r_bV);X# zuvl@KnnJ>+pkJf+Q~_NrirNH!%HrcZATXNrNp#AmY{{|RZg6_w;(bBAzld9O#h<xp zIU<<&84Eo8{j$lQu~{@nUileIbHB(d1Y@^zWDnN9e?U^#bC04l-Ss&d^#0GK*#Uu6 zTlaI@fIV_<o4JS0wsm_?l0UeI#gKx!&1$n|(}?NiiXozfjXqr-r6@|23SYE1Nr8}1 z_~N@1o<}aEZbk;AlEbwQH5O4WA!VM}i!5|eJD`;<>Gf{rha~m%PPw_2rN$qY#d52% zvz1NB^uE;K*;`$7#WmC)6pW;*Hcutom&$!{n^eNTS8NL3)y9VPxLl8=2e3q;1@TQC z7z!Efy|TnEYnSYWYt8O@qC0$*&@7*~V>$0?jU#W@tPam912I;9b_biB-EEhp*E#9C z4rTa?q;bQSe+P2CTdKPW(c||@Hmup(N9)9HAi7&85QE1KI&pWYTTS7}IkvV_mJzO% zztSnC0R{5%F>ZBXeB|^-?vwQ3S`%sd_iSia_d-KA?_;IC9#w(g>Kzmma`yKqxEl9M z!L?&Qo87N<=!7p&H;6U3))|LcbD9e$7ObgKenm?8l`7>I17qI6f_5IC^aYEZNI~yW zf8<QRCc%~x;#w4<h={TBsxO(pmsa4C9pK)zU&=+)!(XCin7!J*WNGd%-W=cKUR4jL z0>t6pqIAiH5Xpsf$%VnFw#U*BAJWc3>-KWKc>F6iI$4`9w4CDHa-w?^sGjfF|1UG? z4PVPX|H{`r_Qk+&*py@4&Z~HiW6$wowkKg-)&32{@onF*;4a<`c<LLru1E3i(h7xm zKjC}OTX&#W;=SVlWW}2Yq^v+7vB-0|;903|yRunkqK0FrL}lOV=iVroI}Gh7Wl{IW zH?tbYU-?!x%m2P*Gx86=wDDxP+g^L!cYU0RUIn7NHRadu*s22WQSOnwGmswSEE8{6 zn`Ytf4zk!BP2_ko*MoxlyHE$e?`dU_b+A_}gEa>|=cKz2V*QNK_02(+Fr(YP-EB9x z-K;E~e+XTy;t-1_Ee(NGFFAI-c@}u#5UcQlFpnHQ^9L#EmjB>s!)l?|V7k@MdysJa z^B=mfl#6cEOF4GjkFv+Ywfbo?%lTs;4P>o9${PRkqf6-Z`u>4=Fkozs{uyI)(@!io zzmGPT_Mc=8;ad6dpV_cM<_<HDCyjtAd+8`!D8KM$7Izd^JNti@8Atxoql`ZJ7pX7Y z^b4EaqoKhpPWj;f^~xT!<bSeEaF4z{=x2?1%CEh$2c7w=EE8NSf9h8@s;`oh{nkgx zx#c(H?EDReao3g%gaD#f_1GFNBLQ@vslWG2d*A&#%CX~jIm;o?w++Uje|U<^6aVO! z$>)_nWCQ*0kDdg3;h(({>`i}qmJ~5o{_3CX_<q=n%~Bl#Wa8f}Hillr6sHaEFo}FE zk#GKsg?Nc_SG%Goy!uzS#-D%x!qb<Sj#mEdX^B~LT|b{xYXwQo5|dP*nk82+)RLwD z$OeRK<#+$XM)krh_m_qX*Xn1JN^Q}<p7q?<<BaB|b_>OcW-EH6lJ5jby`JOywK7>h z)@I#shD}@uAish)E<N9D6s8Ya3l)yDG40ud&BxhdH?-Tt0ruS!V7dtNu?4%^)gH_1 zXKU8_*z{Va9L1T&*J2a4r5uY*Y}TA+v32qM*2Nav)T5Yb_yCzHTpVl}U<<ab{?4>1 zVzy_Ajj9U<*ruF#<c8dC6*o7fJH}TQWQOK8`r3MU_r(qUzZ%+)zP6@*?o?;`L6vxU zpuSU0!5HnaOfPnX_}RpnhtYnvDg81L+~<etWA1@#jXhjn=fVEA1g)drk77-X!ASOA z85}v&FY%YTKJITz>SA5^C9)%l7!Uw3xCH^Wysls5S{GoeFy5Cw6ktp9yv@2jHPH5m zPhczAF0dOPz_+}?BKgljwuBz%=C>!CcFraS+xlZ!yE$0)GPu_93b@zjEt$j+m`*N5 zbqqT#VzBfGvGsg>y<?!MMxTOEFC=;DAX$S&gKRyY4g1BM(SHZ^Dx<JanGswoKQ+|W z^XaewQ%u!*Ahfp)<#t*rFihrN7-s96{&Y1E-P;E-cmy}>2-+vgT#=cBd&Rcv2g`!L zF!%`CXM~@LV_D(7%ILgsnGswoe>vPX-2H^b<HoDsyU<Csqb9w1ahe}D1f#$I=guA) zBFhQaI(~G2hTLKH7SD^2QtCFiUgyrlQlNLM>5Y-1z;KLHXY(VC89#Oi-oe%xx*}6< zzif%LjmYvA#2y9~e6)r>(r0Xu(AMP?JcUYnji+s<TN!RX4+QnMEeaD>b(AeI)O;dH zPq;P8=3(>8r2U;8QMM^0)BldLC3Js8dF1ydAvZnRCeET=9c}Y4`1bptqnsJyrNK8` znqlLm!IvI%@-+BHHSy{pwt(Jkv$)Bah8Wp1Z;$DtjQJgi?lLAl);6~34Q-OssuJT? zm4Ys+(uYnewg|KgrnzM>owvu@hUix9E<xs?3~2huxbAy(d7N!Tzm%Fc;=o`iHE<7m z-q75ad4bgyujw~$#X-MGMnS!YRkvfqO)JDcvM2!UCpY1G_Tg3#&`7lH;&{nRZM#@L zFfBW#2A~}vGyxo80VDB(p7>6PTM4gHWC`I~WAUVkR|x}XuwoNdC}LsEmeA{MFE?w5 z%4|JuCO^PzQ~IexXT(D!O|$7bGzF(%@4eTO&TNW>KpRA4-?Bl{ePBA;tS9_svyBd+ z!MDLCKXcDV#oN;Q)q}5!*P16DJy@%Nhg26Ipf!}h-{XxQd<_*gH^G+JuM%KGPIO^o zW3G3ne%yvvY$D{9d5+*S6K$!zlb~+B_s&EV4wjV<K)6r)?jw>U0k~FPpCqRwY$_@f z7xZ)JhbK$E!L^QsrtdYd=!%&f*~8?NqYeFGa>~)(mcO3JKvrUdQ{gSip0<R79(Ost z<}JZM!(x(`V#wgWTZSG_kzCxDVw=&6rNoItZN~2BaLEI0_j9=9fwq(IpP{z26Wrd{ z@AosRU_3wJ5Q`nx)u&6A5mSZE<~h{N;()JAwTa{WSEd>)Jeua1gfz)ixYo(^*i`=x zjozz~`y|aarN_Nin{l#R?6tQ3fZda2!)(2|)VOOHM%4YoU_rz9L?E#r!`zxKSpnBN zG#jiCt7g|Z8#jemoO-%6-PZG2OV^PH=m=rMd$syG9pLV&7h<e)a3G>5W%|gqheN|< zwc%Q$=&+ZtJ-f+IN-D@jlD5h0xu5OXfn5!YR@pS7k5coO5wc)IN7~l*S{-n49Ytsz zY3u3uUg9W7Wt?&@8)ch4`^YVS9yNFR;rqN5)%a4deyr`cQL+-lM%%oPpt=>ZVzjM? zBdBhZ(!--AVYt@gvd}i3jdJ8YAU{Kra%A+erJmLZz_oJUF}5@Mr3>6L2F1Zxfoo0C zltm9dt8SbN$TYN(+r~hjP6s!RP+jd(Tiuq4YTS}3&GHB&d2P73b@1<zJx!jWS+*&; zJszWTR643Wk1xEH2Oa8`EL&jjKHv6kRv%Y%!?Hca%E{Tb{v5P^-HRY%tcy|)FEV;% z2{0dl;mdPmZ{3*FE7SQt4J{(qc63hi-;yiK0oOX7^f-^{;>gEeQl6v)*UHsATT`TW z?_CNTMxHIst0yiyXfj(k^Fd%vzAdl|D|dOmZ77W@z<Bp(p^NAu>$QAiI9;7@i#?96 zlJxnsIG<b~M>AY&61^QJ*mT$rk!&rniG$+56xcj2Q}z3(9j_?t!gSV`gD7tl$_9gL z97M5>b?Ik48v9+Xh8DrbUrO%=emgMwbe}hWoaexIjI$kkY@Y`s)}(8(6&XV>t$96= zqb2_TNP$(y$|kt;*j`D2pER`O@wPr6db@3WAE(Km$ICLO9A~@H{i|YEVH8W_HS{{q zxz5#DpvugdfFT|-q01qjHUUFi!p!gz6mE-(2PeoW3wy^N_RV2EF7<ji?j;wS<K;q2 zJJvg1F0|;)MNj)?pANL%G10Z8({f6Z7A-9&?fuQ4CiZnqs*`#<CU*d%Ph&D{vgepY z4ECZX+j@C_)@_#TAR2E@wt0L34AH5_duob(9{zm(6xpNUT5~heyuCh!`ldz!u9a^; z0VmrQO|eByoM@gXy1sMgIZVuF@%ZYgeH^22O_eo*Yvs|?Y)yR~sBcWOr4+a=8C|BB z337DA%04?mjt*LU>r*h0t$gBi+o<k`@ukz{Fur@b=VaOcQ=7_+qcmBbH$!q1t}$7@ z3F3Xa)*L@m)_B6qzK-n2XZChv`_Ag)$UY5-?yGmiSo!U<`Zcou_M(ay>&gEgx;AF; zrXnm&9y=Z;ZgKOEf_)q4F|%bim@&KWGw%zt`#7p&i)7|Ai)=S`u{J&O=~tO!OX)(n zo<Bz_*GRVVYv$PeySaV&&>Y!?-=2dqVcGc49M3s8>FCVC)7<9ZX-9bu{$Q?cbdz?e zM9WE=gSDLG94yrV4Ztb|o(aH19f0=JqeWEg2}*)dMcHl?b09*&(GBzZDjY)Q_f|NZ z4vaoc``du%E*ubp>)Z4DB^(wl@T7X-f}=X)|FA%gB)C>S?gU$K_m+4!lU4Nz5*MzR z>-&6oI&NVf<v`6sSpv9L{^UYiQ@@14oBvnavBktuMcG!0kdUQ9g{<DmB25|%jl(Rn zGfPF=5J+R~N1@20lx1dT1{RbiJU)y`i+usv-ImxT(^AAoY{k}s#M%o&K}}4W)SC21 zo7no}&MbUTqHUr^V?4W;W!Z)D*sb$(GBf9%`#kqN?z#7t0Tp-Ivby-iGBP6oPWB3u z!KVESw)PKYC@TY&aOB3DQt*oGdjNv*rsexl)TZecA6We>Zpv7qXh$x{+yIiHP1A8) zMD$uYv?rLb02dkeTW5er0~e`>jT&;D^R;qRus+-P+1J<0kWG*xCWib55=Js4d@-ph z6>%}7R1r<}OvPhmNJAwV(g02BtCj0w$iwq#0mAOqN|gIpj<~Q^krK&OF>>knJOO~< zPOgq!2Oq0mR$9+i6FWKm04jMY+KgCiCkI8%ZX!mv5J|I}h|z!}D<EkOL~~}`!R1fZ zEO2Iae8J_O8p50aO<9i$3sLXa%m-Z@1Z=3%%Lk*YRJf`-vdUyL0whC|O`H)I6Sbg@ z?yC(&Tm)Y`YEjZMI@#G;Qn4|BD~EnX2q}Xdl`L6ATv0*%b|G>Xd@mh#wDi`W#bZjH z0*ru{1~5(Pzjl-y(`;2x7d@}Q7n6Fdj#T>Ny69dkinkXtg>WxE#?buB0+}rUns!0# zNt_GNtVqa7BHFbrctl-dso-pt!)Mg}_7Oy*MsU6Qy@;{`U80MKG8oiE#~OlK|5`W_ z1>|3wV_nO-Upq)40h(Tfs6P;vYhNwkC6c&aLOYjHU)D}&vkU{~ABik;!Ath4PUvu* zp|NUZl=Dn@-|$jt-!G$rz>IQ7UPJhM*vSdanWL;%>bF3OnE2=hB#e~$e<*Q!#M2sA z@Q4R~{$IBGtTVz^54^@^tDk5fL+on9x@`4`;XylNl>R53XuEOVu&g4ocei@a31juH z6Sc(Zj{Bt%2n;kXtE-PT5`6%0R`HwfY$CRMUDG4Bh~Q6~P@mDr(Kd_d;CW84uncR( zT^JQ+;ICXL$B;%VHY>v@yhW1o6e~~T(zlT_&8SE`rzpH6@HWn26V=k&$boxrq2Y}f z-$t${@cTcak`3v!n5X1HVyh*eXJ|QaBC)#1wZ)`9xQQOBJ8z+K?7M?(8`3xnt2m^5 zhb5nuC5e&n_Mee0(<tyfP3Q4>`GR1TIT6pg5w#J^zoT43hRD%03q@x+&L*-VA-?aE z^rtb~gNnA{ix1G>srZtC+Of$fJ0wPtB%ZPGoYl(Uhe;HZi1*}Be{N3h9e6$=_~0Uz z`YG8+vm)fj2olR#Ie}B@Y-*@5wMDLXwzkPFcDcFzO|Lsw|6))(>DCAOe4~^8k#TLn zH8<g&p7Ltv2h7EQQrz6u@|Ib5ch0=qh3{rlhYT4CZ4((KUw|f+Xx2gsytg?k3zw!+ z)(tN#WC2kb?T$8Y<yJ#N0?EfeenuZS?z?`5WTkqZqB4&JX{V%^;qiM1$sdxTc4~a4 z(=#{G<!m+U!`|u1V{;STP(I(NXCAZ1LvViWI2t4{J#|k108isVeegr=Jyq**YdxL- z$<xEW@eA6C5$(!ZAfWXepYFV*_jmhUpB?dEcKQ2`Ygbf#=u2&=&o|Z`qSo3V<e9b8 zNA=#%wf@2Rrc$r@&tKI~U6>x4^j{w`?>!{7zaf_aCX{pLohj{v$J{En*-7Q?K@xiR z<c#;6Sq`)%)F4FO>ox)=b{VPO&FPAT7Aztov5HlM7G_|K;mlX4!<&+J1Wxz6U#s>P OQ_qE7@OQ;jz2QGAbpUt( diff --git a/_RemoveDebug.py b/_RemoveDebug.py new file mode 100644 index 0000000..7b6fdab --- /dev/null +++ b/_RemoveDebug.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- +import pathlib + +# 1. VpiReader.vp +p = pathlib.Path(r'd:\Users\TermiNexus\Desktop\TransPyC\TransPyV\App\lib\StubGen\VpiReader.vp') +c = p.read_text(encoding='utf-8') +lines = c.split('\n') +new_lines = [] +skip = False +for i, line in enumerate(lines): + if 'DEBUG: sha1_buf length mismatch' in line: + skip = True + # also skip preceding lines + while new_lines and ('_buflen' in new_lines[-1] or 'sha1_buf' in new_lines[-1] or len(new_lines[-1].strip()) == 0 or new_lines[-1].strip().startswith('#')): + new_lines.pop() + continue + if skip: + if 'sys.exit(1)' in line: + skip = False + continue + if 'stdio.' in line or '_buflen' in line: + continue + if line.strip() == '' or line.strip().startswith('if _buflen'): + continue + skip = False + new_lines.append(line) +p.write_text('\n'.join(new_lines), encoding='utf-8') +print('VpiReader.vp done') + +# 2. HandlesFunctions.vp +p2 = pathlib.Path(r'd:\Users\TermiNexus\Desktop\TransPyC\TransPyV\App\lib\core\Handles\HandlesFunctions.vp') +c2 = p2.read_text(encoding='utf-8') +lines2 = c2.split('\n') +new_lines2 = [] +skip2 = False +for line in lines2: + if 'DEBUG: double-dot in _mangle_name' in line: + skip2 = True + while new_lines2 and ('_mi' in new_lines2[-1] or 'mangled[_mi' in new_lines2[-1] or 'stdio.' in new_lines2[-1] or 'sys.exit' in new_lines2[-1] or new_lines2[-1].strip().startswith('#')): + new_lines2.pop() + continue + if skip2: + if 'sys.exit(1)' in line: + skip2 = False + continue + if 'stdio.' in line or '_mi' in line or 'mangled[_mi' in line or line.strip().startswith('if mangled'): + continue + if line.strip() == '' or line.strip() == 'return mangled': + if line.strip() == 'return mangled': + new_lines2.append(line) + skip2 = False + continue + skip2 = False + new_lines2.append(line) +p2.write_text('\n'.join(new_lines2), encoding='utf-8') +print('HandlesFunctions.vp done') + +# 3. HandlesExprCall.vp +p3 = pathlib.Path(r'd:\Users\TermiNexus\Desktop\TransPyC\TransPyV\App\lib\core\Handles\HandlesExprCall.vp') +c3 = p3.read_text(encoding='utf-8') +lines3 = c3.split('\n') +new_lines3 = [] +skip3 = False +for line in lines3: + if 'DEBUG: double-dot in call_name' in line: + skip3 = True + while new_lines3 and ('_cni' in new_lines3[-1] or 'call_name[_cni' in new_lines3[-1] or 'stdio.' in new_lines3[-1] or 'sys.exit' in new_lines3[-1] or new_lines3[-1].strip().startswith('#')): + new_lines3.pop() + continue + if skip3: + if 'sys.exit(1)' in line: + skip3 = False + continue + if 'stdio.' in line or '_cni' in line or 'call_name[_cni' in line or line.strip().startswith('if call_name'): + continue + if line.strip() == '' or line.strip().startswith('#'): + if line.strip().startswith('#'): + new_lines3.append(line) + skip3 = False + continue + skip3 = False + new_lines3.append(line) +p3.write_text('\n'.join(new_lines3), encoding='utf-8') +print('HandlesExprCall.vp done') diff --git a/_console.py b/_console.py index a2eeabe..c6b2531 100644 --- a/_console.py +++ b/_console.py @@ -7,6 +7,8 @@ import os import queue import time + + class ConsoleApp: def __init__(self, root, args): self.root = root diff --git a/includes/llvmlite/__builder.vp b/includes/llvmlite/__builder.vp index 0db52b0..fd8afa5 100644 --- a/includes/llvmlite/__builder.vp +++ b/includes/llvmlite/__builder.vp @@ -7,7 +7,7 @@ import stdio from linkedlist import GSListNode, GSList from .__types import LLVMType, TypePrint from .__values import Value, new_value, SSAValue -from .__function import Function, BasicBlock, block_append_text, block_set_terminated, block_get_terminated, function_move_block_to_end, _ll_name_needs_quote +from .__function import Function, BasicBlock, block_append_text, block_set_terminated, block_get_terminated, function_move_block_to_end, _ll_name_needs_quote, block_insert_text_before_terminator # ============================================================ # IRBuilder: 游标式 IR 指令发射器 diff --git a/includes/memhub.vp b/includes/memhub.vp index fba3a8d..c5ed23b 100644 --- a/includes/memhub.vp +++ b/includes/memhub.vp @@ -4,6 +4,7 @@ import string import atom import viperio import stdio +import sys # ============================================================ # memhub - Unified memory management library @@ -430,11 +431,15 @@ class MemBuddy(MemManager): c.DerefAs(block, t.CVoid(t.CUInt64T((order << 1) | 1), t.CPtr)) result = t.CVoid(t.CUInt64T(block) + MEMBUDDY_HEADER_SIZE, t.CPtr) if result is None: - # Allocation failure: print memory usage statistics + # Allocation failure: print memory usage statistics and exit with OOM fb: t.CSizeT = self.free_bytes() ub: t.CSizeT = self.usable_size - fb - stdio.printf("[MEM-FAIL] alloc(%zu) failed: total=%zu used=%zu free=%zu free_blocks=%zu\n", - size, self.usable_size, ub, fb, self.free_count()) + stdio.printf("\n[OOM] 内存不足 (Out of Memory)\n") + stdio.printf("[OOM] 尝试分配: %zu 字节,失败\n", size) + stdio.printf("[OOM] 内存池: total=%zu used=%zu free=%zu free_blocks=%zu\n", + self.usable_size, ub, fb, self.free_count()) + stdio.printf("[OOM] 说明: 内存池已耗尽。可能原因: (1) 池大小不足,需增大 POOL_SIZE; (2) 存在内存泄漏。\n") + sys.exit(1) self._unlock() return result diff --git a/includes/viperlib.vp b/includes/viperlib.vp index f765701..f1d9c69 100644 --- a/includes/viperlib.vp +++ b/includes/viperlib.vp @@ -1,1376 +1,1377 @@ -import t, c -import viperio -from stdarg import arg, va_arg - -TEMP_BUF_SIZE: t.CDefine = 68 - -def get_digit_count(num: t.CUnsignedInt, base: t.CInt) -> t.CStatic | t.CInt: - count: t.CInt = 0 - if num == 0: return 1 - while num > 0: - count += 1 - num //= base - return count - -def sprintf(buf: t.CChar | t.CPtr, rule: str, *args) -> t.CVoid | t.CExport: - if buf is None or rule is None: return - vsnprintf(buf, 0x7FFFFFFF, rule, args) - -def vsprintf(buf: t.CChar | t.CPtr, rule: str, *args) -> t.CInt: - if buf is None or rule is None: return 0 - return vsnprintf(buf, 0x7FFFFFFF, rule, args) - -def snprintf(buf: t.CChar | t.CPtr, size: t.CSizeT, fmt: str, *args) -> t.CInt | t.CExport: - if fmt is None: return 0 - if buf is None or size == 0: - return vsnprintf(None, 0, fmt, args) - return vsnprintf(buf, size, fmt, args) - -# Check floating-point special values (IEEE 754) -# Return: 0=normal, 1=+inf, 2=-inf, 3=nan -def _check_special_float(fv: t.CDouble) -> t.CInt: - fbits: t.CUInt64T = 0 - c.Load(c.Addr(fbits), c.Addr(fv)) - if ((fbits >> 52) & 0x7FF) != 0x7FF: - return 0 - is_neg: t.CInt = 1 if (fbits >> 63) != 0 else 0 - if (fbits & 0x000FFFFFFFFFFFFF) == 0: - if is_neg: - return 2 - return 1 - return 3 - -def vsnprintf(buf: t.CChar | t.CPtr, size: t.CSizeT, fmt: str, ap: t.CChar | t.CPtr) -> t.CInt | t.CExport: - if fmt is None: return 0 - # 长度探测模式:buf is None 时只计算格式化后长度,不实际写入 - # _step=0 使 ptr 不前进,反复写入同一个 dummy 字节(无害),write_count 正确累加 - count_mode: t.CInt = 0 - _step: t.CInt = 1 - _dummy: t.CChar = '\0' - if buf is None or size == 0: - count_mode = 1 - _step = 0 - buf = c.Addr(_dummy) - size = 0x7FFFFFFF - ptr: t.CChar | t.CPtr = buf - write_count: t.CInt = 0 - temp: t.CArray[t.CChar, 68] - temp[0] = '\t' - while c.Deref(fmt) != 0 and write_count < size - 1: - if c.Deref(fmt) != 37: - ptr[0] = c.Deref(fmt) - write_count += 1 - ptr += _step - fmt += 1 - else: - fmt += 1 - if c.Deref(fmt) == 0: break - width: t.CInt = 0 - pad_zero: t.CInt = 0 - left_align: t.CInt = 0 - show_sign: t.CInt = 0 - space_sign: t.CInt = 0 - alt_form: t.CInt = 0 - precision: t.CInt = -1 - is_long: t.CInt = 0 - is_long_long: t.CInt = 0 - is_size: t.CInt = 0 - is_short: t.CInt = 0 - is_char: t.CInt = 0 - while True: - if c.Deref(fmt) == 45: - left_align = 1 - fmt += 1 - elif c.Deref(fmt) == 48: - pad_zero = 1 - fmt += 1 - elif c.Deref(fmt) == 43: - show_sign = 1 - fmt += 1 - elif c.Deref(fmt) == 32: - space_sign = 1 - fmt += 1 - elif c.Deref(fmt) == 35: - alt_form = 1 - fmt += 1 - else: break - if show_sign: space_sign = 0 - while c.Deref(fmt) >= 48 and c.Deref(fmt) <= 57: - width = width * 10 + (c.Deref(fmt) - 48) - fmt += 1 - if c.Deref(fmt) == 46: - fmt += 1 - precision = 0 - while c.Deref(fmt) >= 48 and c.Deref(fmt) <= 57: - precision = precision * 10 + (c.Deref(fmt) - 48) - fmt += 1 - if left_align: pad_zero = 0 - if c.Deref(fmt) == 108: - is_long = 1 - fmt += 1 - if c.Deref(fmt) == 108: - is_long_long = 1 - is_long = 0 - fmt += 1 - elif c.Deref(fmt) == 104: - is_short = 1 - fmt += 1 - if c.Deref(fmt) == 104: - is_char = 1 - is_short = 0 - fmt += 1 - elif c.Deref(fmt) == 122: - is_size = 1 - fmt += 1 - elif c.Deref(fmt) == 106: - is_long_long = 1 - fmt += 1 - elif c.Deref(fmt) == 116: - is_long = 1 - fmt += 1 - if c.Deref(fmt) == 99: - if write_count < size - 1: - ptr_i: t.CInt = va_arg(ap) - ptr[0] = t.CChar(ptr_i) - write_count += 1 - ptr += _step - else: - ptr_i: t.CInt = va_arg(ap) - elif c.Deref(fmt) == 115: - s: str = va_arg(ap, t.CPtr) - if s is None: s = "(None)" - slen: t.CInt = 0 - sc: str = s - while c.Deref(sc) != 0: - slen += 1 - sc += 1 - if not left_align and width > slen: - pad_count: t.CInt = width - slen - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - while c.Deref(s) != 0 and write_count < size - 1: - ptr[0] = c.Deref(s) - write_count += 1 - ptr += _step - s += 1 - if left_align and width > slen: - pad_count = width - slen - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - elif c.Deref(fmt) == 100 or c.Deref(fmt) == 105: - if is_long_long or is_size or is_long: - num_l: t.CInt64T = va_arg(ap, t.CInt64T) - else: - num_l: t.CInt64T = t.CInt64T(va_arg(ap, t.CInt)) - if is_char: - num_l = t.CInt64T(t.CChar(num_l)) - elif is_short: - num_l = t.CInt64T(t.CShort(num_l)) - sign: t.CInt = 0 - if num_l < 0: - sign = 1 - if num_l == (-9223372036854775807 - 1): - u_num: t.CUInt64T = t.CUInt64T(0x8000000000000000) - else: - u_num: t.CUInt64T = t.CUInt64T(-num_l) - else: - u_num: t.CUInt64T = t.CUInt64T(num_l) - if show_sign: sign = 2 - elif space_sign: sign = 3 - i: t.CInt = 0 - while True: - if i >= TEMP_BUF_SIZE - 1: break - temp[i] = t.CChar(u_num % 10 + 48) - i += 1 - u_num //= 10 - if u_num <= 0: break - if sign == 1 and i < TEMP_BUF_SIZE - 1: - temp[i] = 45 - i += 1 - elif sign == 2 and i < TEMP_BUF_SIZE - 1: - temp[i] = 43 - i += 1 - elif sign == 3 and i < TEMP_BUF_SIZE - 1: - temp[i] = 32 - i += 1 - if not left_align and not pad_zero and width > i: - pad_count = width - i - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - if pad_zero and width > i: - pad_count = width - i - while pad_count > 0 and write_count < size - 1: - ptr[0] = 48 - write_count += 1 - ptr += _step - pad_count -= 1 - while i > 0 and write_count < size - 1: - i -= 1 - ptr[0] = temp[i] - write_count += 1 - ptr += _step - if left_align and width > i: - pad_count = width - i - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - elif c.Deref(fmt) == 117: - if is_long or is_long_long or is_size: - u_num_l: t.CUInt64T = va_arg(ap, t.CUInt64T) - else: - u_num_l: t.CUInt64T = t.CUInt64T(t.CUnsignedInt(va_arg(ap))) - i = 0 - while True: - if i >= TEMP_BUF_SIZE - 1: break - temp[i] = t.CChar(u_num_l % 10 + 48) - i += 1 - u_num_l //= 10 - if u_num_l <= 0: break - if not left_align and not pad_zero and width > i: - pad_count = width - i - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - if pad_zero and width > i: - pad_count = width - i - while pad_count > 0 and write_count < size - 1: - ptr[0] = 48 - write_count += 1 - ptr += _step - pad_count -= 1 - while i > 0 and write_count < size - 1: - i -= 1 - ptr[0] = temp[i] - write_count += 1 - ptr += _step - if left_align and width > i: - pad_count = width - i - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - elif c.Deref(fmt) == 120: - if is_long or is_long_long or is_size: - u_num_l: t.CUInt64T = va_arg(ap, t.CUInt64T) - else: - u_num_l: t.CUInt64T = t.CUInt64T(t.CUnsignedInt(va_arg(ap))) - is_nonzero: t.CInt = 0 - if u_num_l != 0: - is_nonzero = 1 - i = 0 - while True: - if i >= TEMP_BUF_SIZE - 1: break - digit: t.CInt = t.CInt(u_num_l % 16) - if digit < 10: - temp[i] = t.CChar(digit + 48) - else: - temp[i] = t.CChar(digit - 10 + 97) - u_num_l //= 16 - i += 1 - if u_num_l <= 0: break - digit_count: t.CInt = i - prefix_len: t.CInt = 0 - if alt_form and is_nonzero: - prefix_len = 2 - effective_len: t.CInt = digit_count + prefix_len - if not left_align and not pad_zero and width > effective_len: - pad_count = width - effective_len - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - if prefix_len > 0: - if write_count < size - 1: - ptr[0] = 48 - write_count += 1 - ptr += _step - if write_count < size - 1: - ptr[0] = 120 - write_count += 1 - ptr += _step - if pad_zero and width > effective_len: - pad_count = width - effective_len - while pad_count > 0 and write_count < size - 1: - ptr[0] = 48 - write_count += 1 - ptr += _step - pad_count -= 1 - while i > 0 and write_count < size - 1: - i -= 1 - ptr[0] = temp[i] - write_count += 1 - ptr += _step - if left_align and width > effective_len: - pad_count = width - effective_len - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - elif c.Deref(fmt) == 88: - if is_long or is_long_long or is_size: - u_num_l: t.CUInt64T = va_arg(ap) - else: - u_num_l: t.CUInt64T = t.CUInt64T(t.CUnsignedInt(va_arg(ap))) - is_nonzero = 0 - if u_num_l != 0: - is_nonzero = 1 - i = 0 - while True: - if i >= TEMP_BUF_SIZE - 1: break - digit = t.CInt(u_num_l % 16) - if digit < 10: - temp[i] = t.CChar(digit + 48) - else: - temp[i] = t.CChar(digit - 10 + 65) - u_num_l //= 16 - i += 1 - if u_num_l <= 0: break - digit_count = i - prefix_len = 0 - if alt_form and is_nonzero: - prefix_len = 2 - effective_len = digit_count + prefix_len - if not left_align and not pad_zero and width > effective_len: - pad_count = width - effective_len - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - if prefix_len > 0: - if write_count < size - 1: - ptr[0] = 48 - write_count += 1 - ptr += _step - if write_count < size - 1: - ptr[0] = 88 - write_count += 1 - ptr += _step - if pad_zero and width > effective_len: - pad_count = width - effective_len - while pad_count > 0 and write_count < size - 1: - ptr[0] = 48 - write_count += 1 - ptr += _step - pad_count -= 1 - while i > 0 and write_count < size - 1: - i -= 1 - ptr[0] = temp[i] - write_count += 1 - ptr += _step - if left_align and width > effective_len: - pad_count = width - effective_len - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - elif c.Deref(fmt) == 111: - if is_long or is_long_long or is_size: - u_num_l: t.CUInt64T = va_arg(ap, t.CUInt64T) - else: - u_num_l: t.CUInt64T = t.CUInt64T(t.CUnsignedInt(va_arg(ap))) - if is_char: - u_num_l = t.CUInt64T(t.CChar(u_num_l)) - elif is_short: - u_num_l = t.CUInt64T(t.CShort(u_num_l)) - i = 0 - if u_num_l == 0 and not alt_form: - temp[0] = 48 - i = 1 - else: - while True: - if i >= TEMP_BUF_SIZE - 1: break - temp[i] = t.CChar(u_num_l % 8 + 48) - i += 1 - u_num_l //= 8 - if u_num_l <= 0: break - if alt_form and i < TEMP_BUF_SIZE - 1: - temp[i] = 48 - i += 1 - if not left_align and not pad_zero and width > i: - pad_count = width - i - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - if pad_zero and width > i: - pad_count = width - i - while pad_count > 0 and write_count < size - 1: - ptr[0] = 48 - write_count += 1 - ptr += _step - pad_count -= 1 - while i > 0 and write_count < size - 1: - i -= 1 - ptr[0] = temp[i] - write_count += 1 - ptr += _step - if left_align and width > i: - pad_count = width - i - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - elif c.Deref(fmt) == 98: - if is_long or is_long_long or is_size: - u_num_l: t.CUInt64T = va_arg(ap, t.CUInt64T) - else: - u_num_l: t.CUInt64T = t.CUInt64T(t.CUnsignedInt(va_arg(ap))) - if is_char: - u_num_l = t.CUInt64T(t.CChar(u_num_l)) - elif is_short: - u_num_l = t.CUInt64T(t.CShort(u_num_l)) - i = 0 - if u_num_l == 0: - temp[0] = 48 - i = 1 - else: - while True: - if i >= TEMP_BUF_SIZE - 1: break - temp[i] = t.CChar(u_num_l % 2 + 48) - i += 1 - u_num_l //= 2 - if u_num_l <= 0: break - if alt_form and i < TEMP_BUF_SIZE - 1: - temp[i] = 98 - i += 1 - if not left_align and not pad_zero and width > i: - pad_count = width - i - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - if pad_zero and width > i: - pad_count = width - i - while pad_count > 0 and write_count < size - 1: - ptr[0] = 48 - write_count += 1 - ptr += _step - pad_count -= 1 - while i > 0 and write_count < size - 1: - i -= 1 - ptr[0] = temp[i] - write_count += 1 - ptr += _step - if left_align and width > i: - pad_count = width - i - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - elif c.Deref(fmt) == 112: - ptr_val: t.CUInt64T = t.CUInt64T(va_arg(ap, t.CPtr)) - if ptr_val == 0: - temp[0] = 40 - temp[1] = 110 - temp[2] = 105 - temp[3] = 108 - temp[4] = 41 - i = 5 - else: - u_num_l = ptr_val - i = 0 - while True: - if i >= TEMP_BUF_SIZE - 1: break - digit = t.CInt(u_num_l % 16) - if digit < 10: - temp[i] = t.CChar(digit + 48) - else: - temp[i] = t.CChar(digit - 10 + 97) - u_num_l //= 16 - i += 1 - if u_num_l <= 0: break - if i < TEMP_BUF_SIZE - 1: - temp[i] = 120 - i += 1 - if i < TEMP_BUF_SIZE - 1: - temp[i] = 48 - i += 1 - if not left_align and not pad_zero and width > i: - pad_count = width - i - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - if pad_zero and width > i: - pad_count = width - i - while pad_count > 0 and write_count < size - 1: - ptr[0] = 48 - write_count += 1 - ptr += _step - pad_count -= 1 - while i > 0 and write_count < size - 1: - i -= 1 - ptr[0] = temp[i] - write_count += 1 - ptr += _step - if left_align and width > i: - pad_count = width - i - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - elif c.Deref(fmt) == 102 or c.Deref(fmt) == 70: - f_upper: t.CInt = 1 if c.Deref(fmt) == 70 else 0 - if precision < 0: precision = 6 - fv: t.CDouble = va_arg(ap, t.CDouble) - f_sp: t.CInt = _check_special_float(fv) - if f_sp != 0: - f_sgn_len: t.CInt = 0 - if f_sp == 2: - f_sgn_len = 1 - elif f_sp == 1 and show_sign: - f_sgn_len = 1 - elif f_sp == 1 and space_sign: - f_sgn_len = 1 - f_total_len: t.CInt = f_sgn_len + 3 - if not left_align and width > f_total_len: - f_pad: t.CInt = width - f_total_len - while f_pad > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - f_pad -= 1 - if f_sp == 2: - if write_count < size - 1: - ptr[0] = 45 - write_count += 1 - ptr += _step - elif f_sp == 1 and show_sign: - if write_count < size - 1: - ptr[0] = 43 - write_count += 1 - ptr += _step - elif f_sp == 1 and space_sign: - if write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - fi_c: t.CInt = 0 - while fi_c < 3 and write_count < size - 1: - fc: t.CInt = 0 - if f_sp == 3: - # nan - if fi_c == 0: - fc = 110 - elif fi_c == 1: - fc = 97 - else: - fc = 110 - else: - # inf (f_sp==1 +inf 或 f_sp==2 -inf) - if fi_c == 0: - fc = 105 - elif fi_c == 1: - fc = 110 - else: - fc = 102 - if f_upper and fc >= 97 and fc <= 122: - fc -= 32 - ptr[0] = t.CChar(fc) - write_count += 1 - ptr += _step - fi_c += 1 - if left_align and width > f_total_len: - f_pad = width - f_total_len - while f_pad > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - f_pad -= 1 - fmt += 1 - continue - if fv < 0.0: - if write_count < size - 1: - ptr[0] = 45 - write_count += 1 - ptr += _step - fv = 0.0 - fv - elif show_sign: - if write_count < size - 1: - ptr[0] = 43 - write_count += 1 - ptr += _step - elif space_sign: - if write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - di: t.CInt = 0 - work: t.CDouble = fv - if work < 1.0: - temp[0] = 48 - di = 1 - else: - scale: t.CDouble = 1.0 - while work >= scale * 10.0: - scale *= 10.0 - while scale >= 1.0 and di < TEMP_BUF_SIZE - 1: - d: t.CInt = t.CInt(work / scale) - if d > 9: d = 9 - temp[di] = t.CChar(d + 48) - di += 1 - work = work - t.CDouble(d) * scale - scale /= 10.0 - frac_val: t.CDouble = work - p: t.CInt = 0 - while p < precision: - frac_val *= 10.0 - p += 1 - frac_part: t.CUInt64T = t.CUInt64T(frac_val + 0.5) - f_total: t.CInt = di + (precision + 1 if precision > 0 else 0) - if not left_align and not pad_zero and width > f_total: - pad_count = width - f_total - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - if pad_zero and width > f_total: - pad_count = width - f_total - while pad_count > 0 and write_count < size - 1: - ptr[0] = 48 - write_count += 1 - ptr += _step - pad_count -= 1 - while di > 0 and write_count < size - 1: - di -= 1 - ptr[0] = temp[di] - write_count += 1 - ptr += _step - if precision > 0: - if write_count < size - 1: - ptr[0] = 46 - write_count += 1 - ptr += _step - fi: t.CInt = 0 - while fi < precision and fi < TEMP_BUF_SIZE - 1: - temp[fi] = t.CChar(frac_part % 10 + 48) - fi += 1 - frac_part //= 10 - while fi < precision: - temp[fi] = 48 - fi += 1 - while fi > 0 and write_count < size - 1: - fi -= 1 - ptr[0] = temp[fi] - write_count += 1 - ptr += _step - elif alt_form: - if write_count < size - 1: - ptr[0] = 46 - write_count += 1 - ptr += _step - if left_align and width > f_total: - pad_count = width - f_total - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - elif c.Deref(fmt) == 101 or c.Deref(fmt) == 69: - if precision < 0: precision = 6 - fv: t.CDouble = va_arg(ap, t.CDouble) - e_upper: t.CInt = 1 if c.Deref(fmt) == 69 else 0 - e_sp: t.CInt = _check_special_float(fv) - if e_sp != 0: - e_sgn_len: t.CInt = 0 - if e_sp == 2: - e_sgn_len = 1 - elif e_sp == 1 and show_sign: - e_sgn_len = 1 - elif e_sp == 1 and space_sign: - e_sgn_len = 1 - e_total_len: t.CInt = e_sgn_len + 3 - if not left_align and width > e_total_len: - e_pad: t.CInt = width - e_total_len - while e_pad > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - e_pad -= 1 - if e_sp == 2: - if write_count < size - 1: - ptr[0] = 45 - write_count += 1 - ptr += _step - elif e_sp == 1 and show_sign: - if write_count < size - 1: - ptr[0] = 43 - write_count += 1 - ptr += _step - elif e_sp == 1 and space_sign: - if write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - ei_c: t.CInt = 0 - while ei_c < 3 and write_count < size - 1: - ec: t.CInt = 0 - if e_sp == 3: - # nan - if ei_c == 0: - ec = 110 - elif ei_c == 1: - ec = 97 - else: - ec = 110 - else: - # inf (e_sp==1 +inf 或 e_sp==2 -inf) - if ei_c == 0: - ec = 105 - elif ei_c == 1: - ec = 110 - else: - ec = 102 - if e_upper and ec >= 97 and ec <= 122: - ec -= 32 - ptr[0] = t.CChar(ec) - write_count += 1 - ptr += _step - ei_c += 1 - if left_align and width > e_total_len: - e_pad = width - e_total_len - while e_pad > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - e_pad -= 1 - fmt += 1 - continue - if fv < 0.0: - if write_count < size - 1: - ptr[0] = 45 - write_count += 1 - ptr += _step - fv = 0.0 - fv - elif show_sign: - if write_count < size - 1: - ptr[0] = 43 - write_count += 1 - ptr += _step - elif space_sign: - if write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - exp10: t.CInt = 0 - if fv != 0.0: - while fv >= 10.0: - fv /= 10.0 - exp10 += 1 - while fv < 1.0: - fv *= 10.0 - exp10 -= 1 - int_digit: t.CInt = t.CInt(fv) - if int_digit > 9: int_digit = 9 - if int_digit < 0: int_digit = 0 - frac_v: t.CDouble = fv - t.CDouble(int_digit) - p: t.CInt = 0 - while p < precision: - frac_v *= 10.0 - p += 1 - frac_p: t.CUInt64T = t.CUInt64T(frac_v + 0.5) - carry: t.CUInt64T = 1 - p = 0 - while p < precision: - carry *= 10 - p += 1 - if frac_p >= carry and carry > 0: - frac_p = 0 - int_digit += 1 - if int_digit > 9: - int_digit = 1 - exp10 += 1 - e_total: t.CInt = 1 + (precision + 1 if precision > 0 else 0) + 4 - if not left_align and not pad_zero and width > e_total: - pad_count = width - e_total - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - if pad_zero and width > e_total: - pad_count = width - e_total - while pad_count > 0 and write_count < size - 1: - ptr[0] = 48 - write_count += 1 - ptr += _step - pad_count -= 1 - if write_count < size - 1: - ptr[0] = t.CChar(int_digit + 48) - write_count += 1 - ptr += _step - if precision > 0: - if write_count < size - 1: - ptr[0] = 46 - write_count += 1 - ptr += _step - fi: t.CInt = 0 - while fi < precision and fi < TEMP_BUF_SIZE - 1: - temp[fi] = t.CChar(frac_p % 10 + 48) - fi += 1 - frac_p //= 10 - while fi < precision: - temp[fi] = 48 - fi += 1 - while fi > 0 and write_count < size - 1: - fi -= 1 - ptr[0] = temp[fi] - write_count += 1 - ptr += _step - elif alt_form: - if write_count < size - 1: - ptr[0] = 46 - write_count += 1 - ptr += _step - if write_count < size - 1: - ptr[0] = 101 if e_upper == 0 else 69 - write_count += 1 - ptr += _step - if write_count < size - 1: - ptr[0] = 45 if exp10 < 0 else 43 - write_count += 1 - ptr += _step - exp_abs: t.CUInt64T = t.CUInt64T(exp10) if exp10 >= 0 else t.CUInt64T(0 - exp10) - ei: t.CInt = 0 - if exp_abs == 0: - temp[0] = 48 - temp[1] = 48 - ei = 2 - else: - while exp_abs > 0 and ei < TEMP_BUF_SIZE - 1: - temp[ei] = t.CChar(exp_abs % 10 + 48) - ei += 1 - exp_abs //= 10 - while ei < 2: - temp[ei] = 48 - ei += 1 - while ei > 0 and write_count < size - 1: - ei -= 1 - ptr[0] = temp[ei] - write_count += 1 - ptr += _step - if left_align and width > e_total: - pad_count = width - e_total - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - elif c.Deref(fmt) == 103 or c.Deref(fmt) == 71: - if precision < 0: precision = 6 - if precision == 0: precision = 1 - fv: t.CDouble = va_arg(ap, t.CDouble) - g_upper: t.CInt = 1 if c.Deref(fmt) == 71 else 0 - g_sp: t.CInt = _check_special_float(fv) - if g_sp != 0: - g_sgn_len: t.CInt = 0 - if g_sp == 2: - g_sgn_len = 1 - elif g_sp == 1 and show_sign: - g_sgn_len = 1 - elif g_sp == 1 and space_sign: - g_sgn_len = 1 - g_total_len: t.CInt = g_sgn_len + 3 - if not left_align and width > g_total_len: - g_pad: t.CInt = width - g_total_len - while g_pad > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - g_pad -= 1 - if g_sp == 2: - if write_count < size - 1: - ptr[0] = 45 - write_count += 1 - ptr += _step - elif g_sp == 1 and show_sign: - if write_count < size - 1: - ptr[0] = 43 - write_count += 1 - ptr += _step - elif g_sp == 1 and space_sign: - if write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - gi_c: t.CInt = 0 - while gi_c < 3 and write_count < size - 1: - gc: t.CInt = 0 - if g_sp == 3: - # nan - if gi_c == 0: - gc = 110 - elif gi_c == 1: - gc = 97 - else: - gc = 110 - else: - # inf (g_sp==1 +inf 或 g_sp==2 -inf) - if gi_c == 0: - gc = 105 - elif gi_c == 1: - gc = 110 - else: - gc = 102 - if g_upper and gc >= 97 and gc <= 122: - gc -= 32 - ptr[0] = t.CChar(gc) - write_count += 1 - ptr += _step - gi_c += 1 - if left_align and width > g_total_len: - g_pad = width - g_total_len - while g_pad > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - g_pad -= 1 - fmt += 1 - continue - if fv < 0.0: - if write_count < size - 1: - ptr[0] = 45 - write_count += 1 - ptr += _step - fv = 0.0 - fv - elif show_sign: - if write_count < size - 1: - ptr[0] = 43 - write_count += 1 - ptr += _step - elif space_sign: - if write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - fv_orig: t.CDouble = fv - exp10: t.CInt = 0 - if fv != 0.0: - while fv >= 10.0: - fv /= 10.0 - exp10 += 1 - while fv < 1.0: - fv *= 10.0 - exp10 -= 1 - g_use_e: t.CInt = 0 - if exp10 < -4 or exp10 >= precision: - g_use_e = 1 - g_len: t.CInt = 0 - if g_use_e: - int_digit: t.CInt = t.CInt(fv) - if int_digit > 9: int_digit = 9 - if int_digit < 0: int_digit = 0 - frac_v: t.CDouble = fv - t.CDouble(int_digit) - prec_e: t.CInt = precision - 1 - p: t.CInt = 0 - while p < prec_e: - frac_v *= 10.0 - p += 1 - frac_p: t.CUInt64T = t.CUInt64T(frac_v + 0.5) - carry: t.CUInt64T = 1 - p = 0 - while p < prec_e: - carry *= 10 - p += 1 - if frac_p >= carry and carry > 0: - frac_p = 0 - int_digit += 1 - if int_digit > 9: - int_digit = 1 - exp10 += 1 - temp[0] = t.CChar(int_digit + 48) - g_len = 1 - if prec_e > 0: - temp[1] = 46 - g_len = 2 - fi: t.CInt = 0 - while fi < prec_e and g_len < TEMP_BUF_SIZE - 1: - temp[g_len] = t.CChar(frac_p % 10 + 48) - g_len += 1 - frac_p //= 10 - lo: t.CInt = 2 - hi: t.CInt = g_len - 1 - while lo < hi: - tc: t.CChar = temp[lo] - temp[lo] = temp[hi] - temp[hi] = tc - lo += 1 - hi -= 1 - else: - prec_f: t.CInt = precision - 1 - exp10 - if prec_f < 0: prec_f = 0 - work: t.CDouble = fv_orig - if work < 1.0: - temp[0] = 48 - g_len = 1 - else: - scale: t.CDouble = 1.0 - while work >= scale * 10.0: - scale *= 10.0 - while scale >= 1.0 and g_len < TEMP_BUF_SIZE - 1: - d: t.CInt = t.CInt(work / scale) - if d > 9: d = 9 - temp[g_len] = t.CChar(d + 48) - g_len += 1 - work = work - t.CDouble(d) * scale - scale /= 10.0 - if prec_f > 0 and g_len < TEMP_BUF_SIZE - 1: - temp[g_len] = 46 - g_len += 1 - frac_val: t.CDouble = work - p = 0 - while p < prec_f: - frac_val *= 10.0 - p += 1 - frac_part: t.CUInt64T = t.CUInt64T(frac_val + 0.5) - fi = 0 - while fi < prec_f and g_len < TEMP_BUF_SIZE - 1: - temp[g_len] = t.CChar(frac_part % 10 + 48) - g_len += 1 - frac_part //= 10 - lo = g_len - prec_f - hi = g_len - 1 - while lo < hi: - tc = temp[lo] - temp[lo] = temp[hi] - temp[hi] = tc - lo += 1 - hi -= 1 - if not alt_form and g_len > 0: - while g_len > 0: - if temp[g_len - 1] == 48: - g_len -= 1 - else: - break - if g_len > 0 and temp[g_len - 1] == 46: - g_len -= 1 - g_total: t.CInt = g_len - if g_use_e: g_total = g_len + 4 - if not left_align and not pad_zero and width > g_total: - pad_count = width - g_total - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - if pad_zero and width > g_total: - pad_count = width - g_total - while pad_count > 0 and write_count < size - 1: - ptr[0] = 48 - write_count += 1 - ptr += _step - pad_count -= 1 - gi: t.CInt = 0 - while gi < g_len and write_count < size - 1: - ptr[0] = temp[gi] - write_count += 1 - ptr += _step - gi += 1 - if g_use_e: - if write_count < size - 1: - ptr[0] = 101 if g_upper == 0 else 69 - write_count += 1 - ptr += _step - if write_count < size - 1: - ptr[0] = 45 if exp10 < 0 else 43 - write_count += 1 - ptr += _step - exp_abs: t.CUInt64T = t.CUInt64T(exp10) if exp10 >= 0 else t.CUInt64T(0 - exp10) - ei: t.CInt = 0 - if exp_abs == 0: - temp[0] = 48 - temp[1] = 48 - ei = 2 - else: - while exp_abs > 0 and ei < TEMP_BUF_SIZE - 1: - temp[ei] = t.CChar(exp_abs % 10 + 48) - ei += 1 - exp_abs //= 10 - while ei < 2: - temp[ei] = 48 - ei += 1 - while ei > 0 and write_count < size - 1: - ei -= 1 - ptr[0] = temp[ei] - write_count += 1 - ptr += _step - if left_align and width > g_total: - pad_count = width - g_total - while pad_count > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - pad_count -= 1 - elif c.Deref(fmt) == 97 or c.Deref(fmt) == 65: - a_upper: t.CInt = 1 if c.Deref(fmt) == 65 else 0 - fv: t.CDouble = va_arg(ap, t.CDouble) - a_sp: t.CInt = _check_special_float(fv) - if a_sp != 0: - a_sgn_len: t.CInt = 0 - if a_sp == 2: - a_sgn_len = 1 - elif a_sp == 1 and show_sign: - a_sgn_len = 1 - elif a_sp == 1 and space_sign: - a_sgn_len = 1 - a_total_len: t.CInt = a_sgn_len + 3 - if not left_align and width > a_total_len: - a_pad: t.CInt = width - a_total_len - while a_pad > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - a_pad -= 1 - if a_sp == 2: - if write_count < size - 1: - ptr[0] = 45 - write_count += 1 - ptr += _step - elif a_sp == 1 and show_sign: - if write_count < size - 1: - ptr[0] = 43 - write_count += 1 - ptr += _step - elif a_sp == 1 and space_sign: - if write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - ai_c: t.CInt = 0 - while ai_c < 3 and write_count < size - 1: - ac: t.CInt = 0 - if a_sp == 3: - # nan - if ai_c == 0: - ac = 110 - elif ai_c == 1: - ac = 97 - else: - ac = 110 - else: - # inf (a_sp==1 +inf 或 a_sp==2 -inf) - if ai_c == 0: - ac = 105 - elif ai_c == 1: - ac = 110 - else: - ac = 102 - if a_upper and ac >= 97 and ac <= 122: - ac -= 32 - ptr[0] = t.CChar(ac) - write_count += 1 - ptr += _step - ai_c += 1 - if left_align and width > a_total_len: - a_pad = width - a_total_len - while a_pad > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - a_pad -= 1 - fmt += 1 - continue - fbits: t.CUInt64T = 0 - c.Load(c.Addr(fbits), c.Addr(fv)) - a_neg: t.CInt = 1 if (fbits >> 63) != 0 else 0 - a_exp: t.CInt = t.CInt((fbits >> 52) & 0x7FF) - a_frac: t.CUInt64T = fbits & 0x000FFFFFFFFFFFFF - a_leading: t.CInt = 0 - a_binexp: t.CInt = 0 - if a_exp == 0: - a_leading = 0 - if a_frac == 0: - a_binexp = 0 - else: - a_binexp = -1022 - else: - a_leading = 1 - a_binexp = a_exp - 1023 - a_prec: t.CInt = precision - if a_prec < 0: - a_prec = 13 - if a_prec > 50: - a_prec = 50 - a_hi: t.CInt = 0 - while a_hi < 13 and a_hi < a_prec: - a_digit: t.CInt = t.CInt((a_frac >> (48 - 4 * a_hi)) & 0xF) - if a_digit < 10: - temp[a_hi] = t.CChar(a_digit + 48) - else: - if a_upper: - temp[a_hi] = t.CChar(a_digit - 10 + 65) - else: - temp[a_hi] = t.CChar(a_digit - 10 + 97) - a_hi += 1 - while a_hi < a_prec: - temp[a_hi] = 48 - a_hi += 1 - a_hd_count: t.CInt = a_prec - if precision < 0: - while a_hd_count > 0 and temp[a_hd_count - 1] == 48: - a_hd_count -= 1 - a_has_dot: t.CInt = 0 - if a_hd_count > 0: - a_has_dot = 1 - elif alt_form: - a_has_dot = 1 - a_eb: t.CInt = a_binexp - a_esign: t.CInt = 0 - if a_binexp < 0: - a_esign = 1 - a_eb = -a_binexp - a_ei: t.CInt = 0 - if a_eb == 0: - temp[60] = 48 - a_ei = 1 - else: - while a_eb > 0 and a_ei < 7: - temp[60 + a_ei] = t.CChar(a_eb % 10 + 48) - a_ei += 1 - a_eb //= 10 - a_ecount: t.CInt = a_ei - a_sign_len: t.CInt = 0 - if a_neg: - a_sign_len = 1 - elif show_sign: - a_sign_len = 1 - elif space_sign: - a_sign_len = 1 - a_content_len: t.CInt = a_sign_len + 2 + 1 + a_has_dot + a_hd_count + 1 + 1 + a_ecount - if not left_align and not pad_zero and width > a_content_len: - a_pad = width - a_content_len - while a_pad > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - a_pad -= 1 - if a_neg: - if write_count < size - 1: - ptr[0] = 45 - write_count += 1 - ptr += _step - elif show_sign: - if write_count < size - 1: - ptr[0] = 43 - write_count += 1 - ptr += _step - elif space_sign: - if write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - if pad_zero and width > a_content_len: - a_pad = width - a_content_len - while a_pad > 0 and write_count < size - 1: - ptr[0] = 48 - write_count += 1 - ptr += _step - a_pad -= 1 - if write_count < size - 1: - ptr[0] = 48 - write_count += 1 - ptr += _step - if write_count < size - 1: - if a_upper: - ptr[0] = 88 - else: - ptr[0] = 120 - write_count += 1 - ptr += _step - if write_count < size - 1: - ptr[0] = t.CChar(a_leading + 48) - write_count += 1 - ptr += _step - if a_has_dot: - if write_count < size - 1: - ptr[0] = 46 - write_count += 1 - ptr += _step - a_hj: t.CInt = 0 - while a_hj < a_hd_count and write_count < size - 1: - ptr[0] = temp[a_hj] - write_count += 1 - ptr += _step - a_hj += 1 - if write_count < size - 1: - if a_upper: - ptr[0] = 80 - else: - ptr[0] = 112 - write_count += 1 - ptr += _step - if write_count < size - 1: - if a_esign: - ptr[0] = 45 - else: - ptr[0] = 43 - write_count += 1 - ptr += _step - a_ek: t.CInt = a_ecount - while a_ek > 0 and write_count < size - 1: - a_ek -= 1 - ptr[0] = temp[60 + a_ek] - write_count += 1 - ptr += _step - if left_align and width > a_content_len: - a_pad = width - a_content_len - while a_pad > 0 and write_count < size - 1: - ptr[0] = 32 - write_count += 1 - ptr += _step - a_pad -= 1 - elif c.Deref(fmt) == 110: - if is_long_long or is_long: - np: t.CInt64T | t.CPtr = va_arg(ap, t.CInt64T | t.CPtr) - if np != None: - np[0] = t.CInt64T(write_count) - elif is_short: - sp: t.CShort | t.CPtr = va_arg(ap, t.CShort | t.CPtr) - if sp != None: - sp[0] = t.CShort(write_count) - elif is_char: - cp: t.CChar | t.CPtr = va_arg(ap, t.CChar | t.CPtr) - if cp != None: - cp[0] = t.CChar(write_count) - else: - ip: t.CInt | t.CPtr = va_arg(ap, t.CInt | t.CPtr) - if ip != None: - ip[0] = write_count - elif c.Deref(fmt) == 37: - if write_count < size - 1: - ptr[0] = 37 - write_count += 1 - ptr += _step - else: - if write_count < size - 1: - ptr[0] = c.Deref(fmt) - write_count += 1 - ptr += _step - fmt += 1 - ptr[0] = 0 - return write_count +import t, c +import viperio +from stdarg import arg, va_arg + +TEMP_BUF_SIZE: t.CDefine = 68 + +def get_digit_count(num: t.CUnsignedInt, base: t.CInt) -> t.CStatic | t.CInt: + count: t.CInt = 0 + if num == 0: return 1 + while num > 0: + count += 1 + num //= base + return count + +def sprintf(buf: t.CChar | t.CPtr, rule: str, *args) -> t.CVoid | t.CExport: + if buf is None or rule is None: return + vsnprintf(buf, 0x7FFFFFFF, rule, args) + +def vsprintf(buf: t.CChar | t.CPtr, rule: str, *args) -> t.CInt: + if buf is None or rule is None: return 0 + return vsnprintf(buf, 0x7FFFFFFF, rule, args) + +def snprintf(buf: t.CChar | t.CPtr, size: t.CSizeT, fmt: str, *args) -> t.CInt | t.CExport: + if fmt is None: return 0 + if buf is None or size == 0: + return vsnprintf(None, 0, fmt, args) + ret: t.CInt = vsnprintf(buf, size, fmt, args) + return ret + +# Check floating-point special values (IEEE 754) +# Return: 0=normal, 1=+inf, 2=-inf, 3=nan +def _check_special_float(fv: t.CDouble) -> t.CInt: + fbits: t.CUInt64T = 0 + c.Load(c.Addr(fbits), c.Addr(fv)) + if ((fbits >> 52) & 0x7FF) != 0x7FF: + return 0 + is_neg: t.CInt = 1 if (fbits >> 63) != 0 else 0 + if (fbits & 0x000FFFFFFFFFFFFF) == 0: + if is_neg: + return 2 + return 1 + return 3 + +def vsnprintf(buf: t.CChar | t.CPtr, size: t.CSizeT, fmt: str, ap: t.CChar | t.CPtr) -> t.CInt | t.CExport: + if fmt is None: return 0 + # 长度探测模式:buf is None 时只计算格式化后长度,不实际写入 + # _step=0 使 ptr 不前进,反复写入同一个 dummy 字节(无害),write_count 正确累加 + count_mode: t.CInt = 0 + _step: t.CInt = 1 + _dummy: t.CChar = '\0' + if buf is None or size == 0: + count_mode = 1 + _step = 0 + buf = c.Addr(_dummy) + size = 0x7FFFFFFF + ptr: t.CChar | t.CPtr = buf + write_count: t.CInt = 0 + temp: t.CArray[t.CChar, 68] + temp[0] = '\t' + while c.Deref(fmt) != 0 and write_count < size - 1: + if c.Deref(fmt) != 37: + ptr[0] = c.Deref(fmt) + write_count += 1 + ptr += _step + fmt += 1 + else: + fmt += 1 + if c.Deref(fmt) == 0: break + width: t.CInt = 0 + pad_zero: t.CInt = 0 + left_align: t.CInt = 0 + show_sign: t.CInt = 0 + space_sign: t.CInt = 0 + alt_form: t.CInt = 0 + precision: t.CInt = -1 + is_long: t.CInt = 0 + is_long_long: t.CInt = 0 + is_size: t.CInt = 0 + is_short: t.CInt = 0 + is_char: t.CInt = 0 + while True: + if c.Deref(fmt) == 45: + left_align = 1 + fmt += 1 + elif c.Deref(fmt) == 48: + pad_zero = 1 + fmt += 1 + elif c.Deref(fmt) == 43: + show_sign = 1 + fmt += 1 + elif c.Deref(fmt) == 32: + space_sign = 1 + fmt += 1 + elif c.Deref(fmt) == 35: + alt_form = 1 + fmt += 1 + else: break + if show_sign: space_sign = 0 + while c.Deref(fmt) >= 48 and c.Deref(fmt) <= 57: + width = width * 10 + (c.Deref(fmt) - 48) + fmt += 1 + if c.Deref(fmt) == 46: + fmt += 1 + precision = 0 + while c.Deref(fmt) >= 48 and c.Deref(fmt) <= 57: + precision = precision * 10 + (c.Deref(fmt) - 48) + fmt += 1 + if left_align: pad_zero = 0 + if c.Deref(fmt) == 108: + is_long = 1 + fmt += 1 + if c.Deref(fmt) == 108: + is_long_long = 1 + is_long = 0 + fmt += 1 + elif c.Deref(fmt) == 104: + is_short = 1 + fmt += 1 + if c.Deref(fmt) == 104: + is_char = 1 + is_short = 0 + fmt += 1 + elif c.Deref(fmt) == 122: + is_size = 1 + fmt += 1 + elif c.Deref(fmt) == 106: + is_long_long = 1 + fmt += 1 + elif c.Deref(fmt) == 116: + is_long = 1 + fmt += 1 + if c.Deref(fmt) == 99: + if write_count < size - 1: + ptr_i: t.CInt = va_arg(ap) + ptr[0] = t.CChar(ptr_i) + write_count += 1 + ptr += _step + else: + ptr_i: t.CInt = va_arg(ap) + elif c.Deref(fmt) == 115: + s: str = va_arg(ap, t.CPtr) + if s is None: s = "(None)" + slen: t.CInt = 0 + sc: str = s + while c.Deref(sc) != 0: + slen += 1 + sc += 1 + if not left_align and width > slen: + pad_count: t.CInt = width - slen + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + while c.Deref(s) != 0 and write_count < size - 1: + ptr[0] = c.Deref(s) + write_count += 1 + ptr += _step + s += 1 + if left_align and width > slen: + pad_count = width - slen + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + elif c.Deref(fmt) == 100 or c.Deref(fmt) == 105: + if is_long_long or is_size or is_long: + num_l: t.CInt64T = va_arg(ap, t.CInt64T) + else: + num_l: t.CInt64T = t.CInt64T(va_arg(ap, t.CInt)) + if is_char: + num_l = t.CInt64T(t.CChar(num_l)) + elif is_short: + num_l = t.CInt64T(t.CShort(num_l)) + sign: t.CInt = 0 + if num_l < 0: + sign = 1 + if num_l == (-9223372036854775807 - 1): + u_num: t.CUInt64T = t.CUInt64T(0x8000000000000000) + else: + u_num: t.CUInt64T = t.CUInt64T(-num_l) + else: + u_num: t.CUInt64T = t.CUInt64T(num_l) + if show_sign: sign = 2 + elif space_sign: sign = 3 + i: t.CInt = 0 + while True: + if i >= TEMP_BUF_SIZE - 1: break + temp[i] = t.CChar(u_num % 10 + 48) + i += 1 + u_num //= 10 + if u_num <= 0: break + if sign == 1 and i < TEMP_BUF_SIZE - 1: + temp[i] = 45 + i += 1 + elif sign == 2 and i < TEMP_BUF_SIZE - 1: + temp[i] = 43 + i += 1 + elif sign == 3 and i < TEMP_BUF_SIZE - 1: + temp[i] = 32 + i += 1 + if not left_align and not pad_zero and width > i: + pad_count = width - i + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + if pad_zero and width > i: + pad_count = width - i + while pad_count > 0 and write_count < size - 1: + ptr[0] = 48 + write_count += 1 + ptr += _step + pad_count -= 1 + while i > 0 and write_count < size - 1: + i -= 1 + ptr[0] = temp[i] + write_count += 1 + ptr += _step + if left_align and width > i: + pad_count = width - i + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + elif c.Deref(fmt) == 117: + if is_long or is_long_long or is_size: + u_num_l: t.CUInt64T = va_arg(ap, t.CUInt64T) + else: + u_num_l: t.CUInt64T = t.CUInt64T(t.CUnsignedInt(va_arg(ap))) + i = 0 + while True: + if i >= TEMP_BUF_SIZE - 1: break + temp[i] = t.CChar(u_num_l % 10 + 48) + i += 1 + u_num_l //= 10 + if u_num_l <= 0: break + if not left_align and not pad_zero and width > i: + pad_count = width - i + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + if pad_zero and width > i: + pad_count = width - i + while pad_count > 0 and write_count < size - 1: + ptr[0] = 48 + write_count += 1 + ptr += _step + pad_count -= 1 + while i > 0 and write_count < size - 1: + i -= 1 + ptr[0] = temp[i] + write_count += 1 + ptr += _step + if left_align and width > i: + pad_count = width - i + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + elif c.Deref(fmt) == 120: + if is_long or is_long_long or is_size: + u_num_l: t.CUInt64T = va_arg(ap, t.CUInt64T) + else: + u_num_l: t.CUInt64T = t.CUInt64T(t.CUnsignedInt(va_arg(ap))) + is_nonzero: t.CInt = 0 + if u_num_l != 0: + is_nonzero = 1 + i = 0 + while True: + if i >= TEMP_BUF_SIZE - 1: break + digit: t.CInt = t.CInt(u_num_l % 16) + if digit < 10: + temp[i] = t.CChar(digit + 48) + else: + temp[i] = t.CChar(digit - 10 + 97) + u_num_l //= 16 + i += 1 + if u_num_l <= 0: break + digit_count: t.CInt = i + prefix_len: t.CInt = 0 + if alt_form and is_nonzero: + prefix_len = 2 + effective_len: t.CInt = digit_count + prefix_len + if not left_align and not pad_zero and width > effective_len: + pad_count = width - effective_len + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + if prefix_len > 0: + if write_count < size - 1: + ptr[0] = 48 + write_count += 1 + ptr += _step + if write_count < size - 1: + ptr[0] = 120 + write_count += 1 + ptr += _step + if pad_zero and width > effective_len: + pad_count = width - effective_len + while pad_count > 0 and write_count < size - 1: + ptr[0] = 48 + write_count += 1 + ptr += _step + pad_count -= 1 + while i > 0 and write_count < size - 1: + i -= 1 + ptr[0] = temp[i] + write_count += 1 + ptr += _step + if left_align and width > effective_len: + pad_count = width - effective_len + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + elif c.Deref(fmt) == 88: + if is_long or is_long_long or is_size: + u_num_l: t.CUInt64T = va_arg(ap) + else: + u_num_l: t.CUInt64T = t.CUInt64T(t.CUnsignedInt(va_arg(ap))) + is_nonzero = 0 + if u_num_l != 0: + is_nonzero = 1 + i = 0 + while True: + if i >= TEMP_BUF_SIZE - 1: break + digit = t.CInt(u_num_l % 16) + if digit < 10: + temp[i] = t.CChar(digit + 48) + else: + temp[i] = t.CChar(digit - 10 + 65) + u_num_l //= 16 + i += 1 + if u_num_l <= 0: break + digit_count = i + prefix_len = 0 + if alt_form and is_nonzero: + prefix_len = 2 + effective_len = digit_count + prefix_len + if not left_align and not pad_zero and width > effective_len: + pad_count = width - effective_len + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + if prefix_len > 0: + if write_count < size - 1: + ptr[0] = 48 + write_count += 1 + ptr += _step + if write_count < size - 1: + ptr[0] = 88 + write_count += 1 + ptr += _step + if pad_zero and width > effective_len: + pad_count = width - effective_len + while pad_count > 0 and write_count < size - 1: + ptr[0] = 48 + write_count += 1 + ptr += _step + pad_count -= 1 + while i > 0 and write_count < size - 1: + i -= 1 + ptr[0] = temp[i] + write_count += 1 + ptr += _step + if left_align and width > effective_len: + pad_count = width - effective_len + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + elif c.Deref(fmt) == 111: + if is_long or is_long_long or is_size: + u_num_l: t.CUInt64T = va_arg(ap, t.CUInt64T) + else: + u_num_l: t.CUInt64T = t.CUInt64T(t.CUnsignedInt(va_arg(ap))) + if is_char: + u_num_l = t.CUInt64T(t.CChar(u_num_l)) + elif is_short: + u_num_l = t.CUInt64T(t.CShort(u_num_l)) + i = 0 + if u_num_l == 0 and not alt_form: + temp[0] = 48 + i = 1 + else: + while True: + if i >= TEMP_BUF_SIZE - 1: break + temp[i] = t.CChar(u_num_l % 8 + 48) + i += 1 + u_num_l //= 8 + if u_num_l <= 0: break + if alt_form and i < TEMP_BUF_SIZE - 1: + temp[i] = 48 + i += 1 + if not left_align and not pad_zero and width > i: + pad_count = width - i + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + if pad_zero and width > i: + pad_count = width - i + while pad_count > 0 and write_count < size - 1: + ptr[0] = 48 + write_count += 1 + ptr += _step + pad_count -= 1 + while i > 0 and write_count < size - 1: + i -= 1 + ptr[0] = temp[i] + write_count += 1 + ptr += _step + if left_align and width > i: + pad_count = width - i + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + elif c.Deref(fmt) == 98: + if is_long or is_long_long or is_size: + u_num_l: t.CUInt64T = va_arg(ap, t.CUInt64T) + else: + u_num_l: t.CUInt64T = t.CUInt64T(t.CUnsignedInt(va_arg(ap))) + if is_char: + u_num_l = t.CUInt64T(t.CChar(u_num_l)) + elif is_short: + u_num_l = t.CUInt64T(t.CShort(u_num_l)) + i = 0 + if u_num_l == 0: + temp[0] = 48 + i = 1 + else: + while True: + if i >= TEMP_BUF_SIZE - 1: break + temp[i] = t.CChar(u_num_l % 2 + 48) + i += 1 + u_num_l //= 2 + if u_num_l <= 0: break + if alt_form and i < TEMP_BUF_SIZE - 1: + temp[i] = 98 + i += 1 + if not left_align and not pad_zero and width > i: + pad_count = width - i + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + if pad_zero and width > i: + pad_count = width - i + while pad_count > 0 and write_count < size - 1: + ptr[0] = 48 + write_count += 1 + ptr += _step + pad_count -= 1 + while i > 0 and write_count < size - 1: + i -= 1 + ptr[0] = temp[i] + write_count += 1 + ptr += _step + if left_align and width > i: + pad_count = width - i + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + elif c.Deref(fmt) == 112: + ptr_val: t.CUInt64T = t.CUInt64T(va_arg(ap, t.CPtr)) + if ptr_val == 0: + temp[0] = 40 + temp[1] = 110 + temp[2] = 105 + temp[3] = 108 + temp[4] = 41 + i = 5 + else: + u_num_l = ptr_val + i = 0 + while True: + if i >= TEMP_BUF_SIZE - 1: break + digit = t.CInt(u_num_l % 16) + if digit < 10: + temp[i] = t.CChar(digit + 48) + else: + temp[i] = t.CChar(digit - 10 + 97) + u_num_l //= 16 + i += 1 + if u_num_l <= 0: break + if i < TEMP_BUF_SIZE - 1: + temp[i] = 120 + i += 1 + if i < TEMP_BUF_SIZE - 1: + temp[i] = 48 + i += 1 + if not left_align and not pad_zero and width > i: + pad_count = width - i + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + if pad_zero and width > i: + pad_count = width - i + while pad_count > 0 and write_count < size - 1: + ptr[0] = 48 + write_count += 1 + ptr += _step + pad_count -= 1 + while i > 0 and write_count < size - 1: + i -= 1 + ptr[0] = temp[i] + write_count += 1 + ptr += _step + if left_align and width > i: + pad_count = width - i + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + elif c.Deref(fmt) == 102 or c.Deref(fmt) == 70: + f_upper: t.CInt = 1 if c.Deref(fmt) == 70 else 0 + if precision < 0: precision = 6 + fv: t.CDouble = va_arg(ap, t.CDouble) + f_sp: t.CInt = _check_special_float(fv) + if f_sp != 0: + f_sgn_len: t.CInt = 0 + if f_sp == 2: + f_sgn_len = 1 + elif f_sp == 1 and show_sign: + f_sgn_len = 1 + elif f_sp == 1 and space_sign: + f_sgn_len = 1 + f_total_len: t.CInt = f_sgn_len + 3 + if not left_align and width > f_total_len: + f_pad: t.CInt = width - f_total_len + while f_pad > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + f_pad -= 1 + if f_sp == 2: + if write_count < size - 1: + ptr[0] = 45 + write_count += 1 + ptr += _step + elif f_sp == 1 and show_sign: + if write_count < size - 1: + ptr[0] = 43 + write_count += 1 + ptr += _step + elif f_sp == 1 and space_sign: + if write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + fi_c: t.CInt = 0 + while fi_c < 3 and write_count < size - 1: + fc: t.CInt = 0 + if f_sp == 3: + # nan + if fi_c == 0: + fc = 110 + elif fi_c == 1: + fc = 97 + else: + fc = 110 + else: + # inf (f_sp==1 +inf 或 f_sp==2 -inf) + if fi_c == 0: + fc = 105 + elif fi_c == 1: + fc = 110 + else: + fc = 102 + if f_upper and fc >= 97 and fc <= 122: + fc -= 32 + ptr[0] = t.CChar(fc) + write_count += 1 + ptr += _step + fi_c += 1 + if left_align and width > f_total_len: + f_pad = width - f_total_len + while f_pad > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + f_pad -= 1 + fmt += 1 + continue + if fv < 0.0: + if write_count < size - 1: + ptr[0] = 45 + write_count += 1 + ptr += _step + fv = 0.0 - fv + elif show_sign: + if write_count < size - 1: + ptr[0] = 43 + write_count += 1 + ptr += _step + elif space_sign: + if write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + di: t.CInt = 0 + work: t.CDouble = fv + if work < 1.0: + temp[0] = 48 + di = 1 + else: + scale: t.CDouble = 1.0 + while work >= scale * 10.0: + scale *= 10.0 + while scale >= 1.0 and di < TEMP_BUF_SIZE - 1: + d: t.CInt = t.CInt(work / scale) + if d > 9: d = 9 + temp[di] = t.CChar(d + 48) + di += 1 + work = work - t.CDouble(d) * scale + scale /= 10.0 + frac_val: t.CDouble = work + p: t.CInt = 0 + while p < precision: + frac_val *= 10.0 + p += 1 + frac_part: t.CUInt64T = t.CUInt64T(frac_val + 0.5) + f_total: t.CInt = di + (precision + 1 if precision > 0 else 0) + if not left_align and not pad_zero and width > f_total: + pad_count = width - f_total + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + if pad_zero and width > f_total: + pad_count = width - f_total + while pad_count > 0 and write_count < size - 1: + ptr[0] = 48 + write_count += 1 + ptr += _step + pad_count -= 1 + while di > 0 and write_count < size - 1: + di -= 1 + ptr[0] = temp[di] + write_count += 1 + ptr += _step + if precision > 0: + if write_count < size - 1: + ptr[0] = 46 + write_count += 1 + ptr += _step + fi: t.CInt = 0 + while fi < precision and fi < TEMP_BUF_SIZE - 1: + temp[fi] = t.CChar(frac_part % 10 + 48) + fi += 1 + frac_part //= 10 + while fi < precision: + temp[fi] = 48 + fi += 1 + while fi > 0 and write_count < size - 1: + fi -= 1 + ptr[0] = temp[fi] + write_count += 1 + ptr += _step + elif alt_form: + if write_count < size - 1: + ptr[0] = 46 + write_count += 1 + ptr += _step + if left_align and width > f_total: + pad_count = width - f_total + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + elif c.Deref(fmt) == 101 or c.Deref(fmt) == 69: + if precision < 0: precision = 6 + fv: t.CDouble = va_arg(ap, t.CDouble) + e_upper: t.CInt = 1 if c.Deref(fmt) == 69 else 0 + e_sp: t.CInt = _check_special_float(fv) + if e_sp != 0: + e_sgn_len: t.CInt = 0 + if e_sp == 2: + e_sgn_len = 1 + elif e_sp == 1 and show_sign: + e_sgn_len = 1 + elif e_sp == 1 and space_sign: + e_sgn_len = 1 + e_total_len: t.CInt = e_sgn_len + 3 + if not left_align and width > e_total_len: + e_pad: t.CInt = width - e_total_len + while e_pad > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + e_pad -= 1 + if e_sp == 2: + if write_count < size - 1: + ptr[0] = 45 + write_count += 1 + ptr += _step + elif e_sp == 1 and show_sign: + if write_count < size - 1: + ptr[0] = 43 + write_count += 1 + ptr += _step + elif e_sp == 1 and space_sign: + if write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + ei_c: t.CInt = 0 + while ei_c < 3 and write_count < size - 1: + ec: t.CInt = 0 + if e_sp == 3: + # nan + if ei_c == 0: + ec = 110 + elif ei_c == 1: + ec = 97 + else: + ec = 110 + else: + # inf (e_sp==1 +inf 或 e_sp==2 -inf) + if ei_c == 0: + ec = 105 + elif ei_c == 1: + ec = 110 + else: + ec = 102 + if e_upper and ec >= 97 and ec <= 122: + ec -= 32 + ptr[0] = t.CChar(ec) + write_count += 1 + ptr += _step + ei_c += 1 + if left_align and width > e_total_len: + e_pad = width - e_total_len + while e_pad > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + e_pad -= 1 + fmt += 1 + continue + if fv < 0.0: + if write_count < size - 1: + ptr[0] = 45 + write_count += 1 + ptr += _step + fv = 0.0 - fv + elif show_sign: + if write_count < size - 1: + ptr[0] = 43 + write_count += 1 + ptr += _step + elif space_sign: + if write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + exp10: t.CInt = 0 + if fv != 0.0: + while fv >= 10.0: + fv /= 10.0 + exp10 += 1 + while fv < 1.0: + fv *= 10.0 + exp10 -= 1 + int_digit: t.CInt = t.CInt(fv) + if int_digit > 9: int_digit = 9 + if int_digit < 0: int_digit = 0 + frac_v: t.CDouble = fv - t.CDouble(int_digit) + p: t.CInt = 0 + while p < precision: + frac_v *= 10.0 + p += 1 + frac_p: t.CUInt64T = t.CUInt64T(frac_v + 0.5) + carry: t.CUInt64T = 1 + p = 0 + while p < precision: + carry *= 10 + p += 1 + if frac_p >= carry and carry > 0: + frac_p = 0 + int_digit += 1 + if int_digit > 9: + int_digit = 1 + exp10 += 1 + e_total: t.CInt = 1 + (precision + 1 if precision > 0 else 0) + 4 + if not left_align and not pad_zero and width > e_total: + pad_count = width - e_total + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + if pad_zero and width > e_total: + pad_count = width - e_total + while pad_count > 0 and write_count < size - 1: + ptr[0] = 48 + write_count += 1 + ptr += _step + pad_count -= 1 + if write_count < size - 1: + ptr[0] = t.CChar(int_digit + 48) + write_count += 1 + ptr += _step + if precision > 0: + if write_count < size - 1: + ptr[0] = 46 + write_count += 1 + ptr += _step + fi: t.CInt = 0 + while fi < precision and fi < TEMP_BUF_SIZE - 1: + temp[fi] = t.CChar(frac_p % 10 + 48) + fi += 1 + frac_p //= 10 + while fi < precision: + temp[fi] = 48 + fi += 1 + while fi > 0 and write_count < size - 1: + fi -= 1 + ptr[0] = temp[fi] + write_count += 1 + ptr += _step + elif alt_form: + if write_count < size - 1: + ptr[0] = 46 + write_count += 1 + ptr += _step + if write_count < size - 1: + ptr[0] = 101 if e_upper == 0 else 69 + write_count += 1 + ptr += _step + if write_count < size - 1: + ptr[0] = 45 if exp10 < 0 else 43 + write_count += 1 + ptr += _step + exp_abs: t.CUInt64T = t.CUInt64T(exp10) if exp10 >= 0 else t.CUInt64T(0 - exp10) + ei: t.CInt = 0 + if exp_abs == 0: + temp[0] = 48 + temp[1] = 48 + ei = 2 + else: + while exp_abs > 0 and ei < TEMP_BUF_SIZE - 1: + temp[ei] = t.CChar(exp_abs % 10 + 48) + ei += 1 + exp_abs //= 10 + while ei < 2: + temp[ei] = 48 + ei += 1 + while ei > 0 and write_count < size - 1: + ei -= 1 + ptr[0] = temp[ei] + write_count += 1 + ptr += _step + if left_align and width > e_total: + pad_count = width - e_total + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + elif c.Deref(fmt) == 103 or c.Deref(fmt) == 71: + if precision < 0: precision = 6 + if precision == 0: precision = 1 + fv: t.CDouble = va_arg(ap, t.CDouble) + g_upper: t.CInt = 1 if c.Deref(fmt) == 71 else 0 + g_sp: t.CInt = _check_special_float(fv) + if g_sp != 0: + g_sgn_len: t.CInt = 0 + if g_sp == 2: + g_sgn_len = 1 + elif g_sp == 1 and show_sign: + g_sgn_len = 1 + elif g_sp == 1 and space_sign: + g_sgn_len = 1 + g_total_len: t.CInt = g_sgn_len + 3 + if not left_align and width > g_total_len: + g_pad: t.CInt = width - g_total_len + while g_pad > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + g_pad -= 1 + if g_sp == 2: + if write_count < size - 1: + ptr[0] = 45 + write_count += 1 + ptr += _step + elif g_sp == 1 and show_sign: + if write_count < size - 1: + ptr[0] = 43 + write_count += 1 + ptr += _step + elif g_sp == 1 and space_sign: + if write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + gi_c: t.CInt = 0 + while gi_c < 3 and write_count < size - 1: + gc: t.CInt = 0 + if g_sp == 3: + # nan + if gi_c == 0: + gc = 110 + elif gi_c == 1: + gc = 97 + else: + gc = 110 + else: + # inf (g_sp==1 +inf 或 g_sp==2 -inf) + if gi_c == 0: + gc = 105 + elif gi_c == 1: + gc = 110 + else: + gc = 102 + if g_upper and gc >= 97 and gc <= 122: + gc -= 32 + ptr[0] = t.CChar(gc) + write_count += 1 + ptr += _step + gi_c += 1 + if left_align and width > g_total_len: + g_pad = width - g_total_len + while g_pad > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + g_pad -= 1 + fmt += 1 + continue + if fv < 0.0: + if write_count < size - 1: + ptr[0] = 45 + write_count += 1 + ptr += _step + fv = 0.0 - fv + elif show_sign: + if write_count < size - 1: + ptr[0] = 43 + write_count += 1 + ptr += _step + elif space_sign: + if write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + fv_orig: t.CDouble = fv + exp10: t.CInt = 0 + if fv != 0.0: + while fv >= 10.0: + fv /= 10.0 + exp10 += 1 + while fv < 1.0: + fv *= 10.0 + exp10 -= 1 + g_use_e: t.CInt = 0 + if exp10 < -4 or exp10 >= precision: + g_use_e = 1 + g_len: t.CInt = 0 + if g_use_e: + int_digit: t.CInt = t.CInt(fv) + if int_digit > 9: int_digit = 9 + if int_digit < 0: int_digit = 0 + frac_v: t.CDouble = fv - t.CDouble(int_digit) + prec_e: t.CInt = precision - 1 + p: t.CInt = 0 + while p < prec_e: + frac_v *= 10.0 + p += 1 + frac_p: t.CUInt64T = t.CUInt64T(frac_v + 0.5) + carry: t.CUInt64T = 1 + p = 0 + while p < prec_e: + carry *= 10 + p += 1 + if frac_p >= carry and carry > 0: + frac_p = 0 + int_digit += 1 + if int_digit > 9: + int_digit = 1 + exp10 += 1 + temp[0] = t.CChar(int_digit + 48) + g_len = 1 + if prec_e > 0: + temp[1] = 46 + g_len = 2 + fi: t.CInt = 0 + while fi < prec_e and g_len < TEMP_BUF_SIZE - 1: + temp[g_len] = t.CChar(frac_p % 10 + 48) + g_len += 1 + frac_p //= 10 + lo: t.CInt = 2 + hi: t.CInt = g_len - 1 + while lo < hi: + tc: t.CChar = temp[lo] + temp[lo] = temp[hi] + temp[hi] = tc + lo += 1 + hi -= 1 + else: + prec_f: t.CInt = precision - 1 - exp10 + if prec_f < 0: prec_f = 0 + work: t.CDouble = fv_orig + if work < 1.0: + temp[0] = 48 + g_len = 1 + else: + scale: t.CDouble = 1.0 + while work >= scale * 10.0: + scale *= 10.0 + while scale >= 1.0 and g_len < TEMP_BUF_SIZE - 1: + d: t.CInt = t.CInt(work / scale) + if d > 9: d = 9 + temp[g_len] = t.CChar(d + 48) + g_len += 1 + work = work - t.CDouble(d) * scale + scale /= 10.0 + if prec_f > 0 and g_len < TEMP_BUF_SIZE - 1: + temp[g_len] = 46 + g_len += 1 + frac_val: t.CDouble = work + p = 0 + while p < prec_f: + frac_val *= 10.0 + p += 1 + frac_part: t.CUInt64T = t.CUInt64T(frac_val + 0.5) + fi = 0 + while fi < prec_f and g_len < TEMP_BUF_SIZE - 1: + temp[g_len] = t.CChar(frac_part % 10 + 48) + g_len += 1 + frac_part //= 10 + lo = g_len - prec_f + hi = g_len - 1 + while lo < hi: + tc = temp[lo] + temp[lo] = temp[hi] + temp[hi] = tc + lo += 1 + hi -= 1 + if not alt_form and g_len > 0: + while g_len > 0: + if temp[g_len - 1] == 48: + g_len -= 1 + else: + break + if g_len > 0 and temp[g_len - 1] == 46: + g_len -= 1 + g_total: t.CInt = g_len + if g_use_e: g_total = g_len + 4 + if not left_align and not pad_zero and width > g_total: + pad_count = width - g_total + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + if pad_zero and width > g_total: + pad_count = width - g_total + while pad_count > 0 and write_count < size - 1: + ptr[0] = 48 + write_count += 1 + ptr += _step + pad_count -= 1 + gi: t.CInt = 0 + while gi < g_len and write_count < size - 1: + ptr[0] = temp[gi] + write_count += 1 + ptr += _step + gi += 1 + if g_use_e: + if write_count < size - 1: + ptr[0] = 101 if g_upper == 0 else 69 + write_count += 1 + ptr += _step + if write_count < size - 1: + ptr[0] = 45 if exp10 < 0 else 43 + write_count += 1 + ptr += _step + exp_abs: t.CUInt64T = t.CUInt64T(exp10) if exp10 >= 0 else t.CUInt64T(0 - exp10) + ei: t.CInt = 0 + if exp_abs == 0: + temp[0] = 48 + temp[1] = 48 + ei = 2 + else: + while exp_abs > 0 and ei < TEMP_BUF_SIZE - 1: + temp[ei] = t.CChar(exp_abs % 10 + 48) + ei += 1 + exp_abs //= 10 + while ei < 2: + temp[ei] = 48 + ei += 1 + while ei > 0 and write_count < size - 1: + ei -= 1 + ptr[0] = temp[ei] + write_count += 1 + ptr += _step + if left_align and width > g_total: + pad_count = width - g_total + while pad_count > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + pad_count -= 1 + elif c.Deref(fmt) == 97 or c.Deref(fmt) == 65: + a_upper: t.CInt = 1 if c.Deref(fmt) == 65 else 0 + fv: t.CDouble = va_arg(ap, t.CDouble) + a_sp: t.CInt = _check_special_float(fv) + if a_sp != 0: + a_sgn_len: t.CInt = 0 + if a_sp == 2: + a_sgn_len = 1 + elif a_sp == 1 and show_sign: + a_sgn_len = 1 + elif a_sp == 1 and space_sign: + a_sgn_len = 1 + a_total_len: t.CInt = a_sgn_len + 3 + if not left_align and width > a_total_len: + a_pad: t.CInt = width - a_total_len + while a_pad > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + a_pad -= 1 + if a_sp == 2: + if write_count < size - 1: + ptr[0] = 45 + write_count += 1 + ptr += _step + elif a_sp == 1 and show_sign: + if write_count < size - 1: + ptr[0] = 43 + write_count += 1 + ptr += _step + elif a_sp == 1 and space_sign: + if write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + ai_c: t.CInt = 0 + while ai_c < 3 and write_count < size - 1: + ac: t.CInt = 0 + if a_sp == 3: + # nan + if ai_c == 0: + ac = 110 + elif ai_c == 1: + ac = 97 + else: + ac = 110 + else: + # inf (a_sp==1 +inf 或 a_sp==2 -inf) + if ai_c == 0: + ac = 105 + elif ai_c == 1: + ac = 110 + else: + ac = 102 + if a_upper and ac >= 97 and ac <= 122: + ac -= 32 + ptr[0] = t.CChar(ac) + write_count += 1 + ptr += _step + ai_c += 1 + if left_align and width > a_total_len: + a_pad = width - a_total_len + while a_pad > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + a_pad -= 1 + fmt += 1 + continue + fbits: t.CUInt64T = 0 + c.Load(c.Addr(fbits), c.Addr(fv)) + a_neg: t.CInt = 1 if (fbits >> 63) != 0 else 0 + a_exp: t.CInt = t.CInt((fbits >> 52) & 0x7FF) + a_frac: t.CUInt64T = fbits & 0x000FFFFFFFFFFFFF + a_leading: t.CInt = 0 + a_binexp: t.CInt = 0 + if a_exp == 0: + a_leading = 0 + if a_frac == 0: + a_binexp = 0 + else: + a_binexp = -1022 + else: + a_leading = 1 + a_binexp = a_exp - 1023 + a_prec: t.CInt = precision + if a_prec < 0: + a_prec = 13 + if a_prec > 50: + a_prec = 50 + a_hi: t.CInt = 0 + while a_hi < 13 and a_hi < a_prec: + a_digit: t.CInt = t.CInt((a_frac >> (48 - 4 * a_hi)) & 0xF) + if a_digit < 10: + temp[a_hi] = t.CChar(a_digit + 48) + else: + if a_upper: + temp[a_hi] = t.CChar(a_digit - 10 + 65) + else: + temp[a_hi] = t.CChar(a_digit - 10 + 97) + a_hi += 1 + while a_hi < a_prec: + temp[a_hi] = 48 + a_hi += 1 + a_hd_count: t.CInt = a_prec + if precision < 0: + while a_hd_count > 0 and temp[a_hd_count - 1] == 48: + a_hd_count -= 1 + a_has_dot: t.CInt = 0 + if a_hd_count > 0: + a_has_dot = 1 + elif alt_form: + a_has_dot = 1 + a_eb: t.CInt = a_binexp + a_esign: t.CInt = 0 + if a_binexp < 0: + a_esign = 1 + a_eb = -a_binexp + a_ei: t.CInt = 0 + if a_eb == 0: + temp[60] = 48 + a_ei = 1 + else: + while a_eb > 0 and a_ei < 7: + temp[60 + a_ei] = t.CChar(a_eb % 10 + 48) + a_ei += 1 + a_eb //= 10 + a_ecount: t.CInt = a_ei + a_sign_len: t.CInt = 0 + if a_neg: + a_sign_len = 1 + elif show_sign: + a_sign_len = 1 + elif space_sign: + a_sign_len = 1 + a_content_len: t.CInt = a_sign_len + 2 + 1 + a_has_dot + a_hd_count + 1 + 1 + a_ecount + if not left_align and not pad_zero and width > a_content_len: + a_pad = width - a_content_len + while a_pad > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + a_pad -= 1 + if a_neg: + if write_count < size - 1: + ptr[0] = 45 + write_count += 1 + ptr += _step + elif show_sign: + if write_count < size - 1: + ptr[0] = 43 + write_count += 1 + ptr += _step + elif space_sign: + if write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + if pad_zero and width > a_content_len: + a_pad = width - a_content_len + while a_pad > 0 and write_count < size - 1: + ptr[0] = 48 + write_count += 1 + ptr += _step + a_pad -= 1 + if write_count < size - 1: + ptr[0] = 48 + write_count += 1 + ptr += _step + if write_count < size - 1: + if a_upper: + ptr[0] = 88 + else: + ptr[0] = 120 + write_count += 1 + ptr += _step + if write_count < size - 1: + ptr[0] = t.CChar(a_leading + 48) + write_count += 1 + ptr += _step + if a_has_dot: + if write_count < size - 1: + ptr[0] = 46 + write_count += 1 + ptr += _step + a_hj: t.CInt = 0 + while a_hj < a_hd_count and write_count < size - 1: + ptr[0] = temp[a_hj] + write_count += 1 + ptr += _step + a_hj += 1 + if write_count < size - 1: + if a_upper: + ptr[0] = 80 + else: + ptr[0] = 112 + write_count += 1 + ptr += _step + if write_count < size - 1: + if a_esign: + ptr[0] = 45 + else: + ptr[0] = 43 + write_count += 1 + ptr += _step + a_ek: t.CInt = a_ecount + while a_ek > 0 and write_count < size - 1: + a_ek -= 1 + ptr[0] = temp[60 + a_ek] + write_count += 1 + ptr += _step + if left_align and width > a_content_len: + a_pad = width - a_content_len + while a_pad > 0 and write_count < size - 1: + ptr[0] = 32 + write_count += 1 + ptr += _step + a_pad -= 1 + elif c.Deref(fmt) == 110: + if is_long_long or is_long: + np: t.CInt64T | t.CPtr = va_arg(ap, t.CInt64T | t.CPtr) + if np != None: + np[0] = t.CInt64T(write_count) + elif is_short: + sp: t.CShort | t.CPtr = va_arg(ap, t.CShort | t.CPtr) + if sp != None: + sp[0] = t.CShort(write_count) + elif is_char: + cp: t.CChar | t.CPtr = va_arg(ap, t.CChar | t.CPtr) + if cp != None: + cp[0] = t.CChar(write_count) + else: + ip: t.CInt | t.CPtr = va_arg(ap, t.CInt | t.CPtr) + if ip != None: + ip[0] = write_count + elif c.Deref(fmt) == 37: + if write_count < size - 1: + ptr[0] = 37 + write_count += 1 + ptr += _step + else: + if write_count < size - 1: + ptr[0] = c.Deref(fmt) + write_count += 1 + ptr += _step + fmt += 1 + ptr[0] = 0 + return write_count diff --git a/lib/core/ConstEvaluator.py b/lib/core/ConstEvaluator.py index 4a6fd3e..47da8b2 100644 --- a/lib/core/ConstEvaluator.py +++ b/lib/core/ConstEvaluator.py @@ -483,10 +483,30 @@ class EvalContext: self.translator: Any = translator def lookup_name(self, name: str) -> Optional[Any]: - """查找 Name 节点的值:define_constants → SymbolTable → 平台宏""" + """查找 Name 节点的值:define_constants → SymbolTable → 平台宏 + + 治本修复:不再把 module.globals 的 initializer 当常量返回。 + CDefine 不创建 LLVM global(不在 module.globals),仅可变全局变量在 + module.globals 中;把可变全局的 initializer 当编译期常量会让 + range(_sha1_store_count) 等读取处求值成初始值 0 而不生成 load。 + CDefine 通过下方 _define_constants 查询返回常量,双点 bug 不复发。 + """ # 1. Gen._define_constants if self.Gen and name in self.Gen._define_constants: val: Any = self.Gen._define_constants[name] + # 治本修复:本模块全局变量初始化值优先,避免跨模块同名 CDefine 通过 + # 共享 _define_constants 覆盖本模块常量 + # (VpiReader.SHA1_LEN=16 被 Phase1.SHA1_LEN=17 覆盖导致双点符号 bug) + _gvar: Any = None + try: + if hasattr(self.Gen, 'module') and name in self.Gen.module.globals: + _gvar = self.Gen.module.globals[name] + except Exception: + _gvar = None + if _gvar is not None and getattr(_gvar, 'initializer', None) is not None: + _init: Any = _gvar.initializer + if hasattr(_init, 'constant') and isinstance(_init.constant, (int, float)): + val = _init.constant if isinstance(val, (int, float)): return ConstEvaluator._intify(val) diff --git a/lib/core/Handles/HandlesAssign.py b/lib/core/Handles/HandlesAssign.py index b30f086..67c6195 100644 --- a/lib/core/Handles/HandlesAssign.py +++ b/lib/core/Handles/HandlesAssign.py @@ -286,18 +286,23 @@ class AssignHandle(BaseHandle): Gen.var_type_info[VarName] = {'type': 't_type_runtime', 'source': call_func_name} return if VarName in Gen.global_vars: - if VarName in Gen.module.globals: - GVar: ir.GlobalVariable = Gen.module.globals[VarName] - Gen._store(Value, GVar) - Gen.variables[VarName] = GVar - if isinstance(Value.type, ir.PointerType) and isinstance(Value.type.pointee, (ir.LiteralStructType, ir.IdentifiedStructType)): - found: tuple[str, ir.Type] | None = Gen.find_struct_by_pointee(Value.type.pointee) - if found: - CN: str = found[0] - ST: ir.Type = found[1] - Gen.var_struct_class[VarName] = CN - elif VarName in Gen.variables and Gen.variables[VarName] is not None: - Gen._store(Value, Gen.variables[VarName]) + # 治本修复:global 声明的变量若未被模块级 AnnAssign 创建为 LLVM 全局 + # (注解无初始值的全局变量),此处自动创建零初始化全局变量 + GVar: ir.GlobalVariable + if VarName not in Gen.module.globals: + _gv_type: ir.Type = Value.type if isinstance(Value.type, (ir.IntType, ir.PointerType)) else ir.IntType(64) + GVar = ir.GlobalVariable(Gen.module, _gv_type, name=VarName) + GVar.initializer = ir.Constant(_gv_type, None) if isinstance(_gv_type, ir.PointerType) else ir.Constant(_gv_type, 0) + else: + GVar = Gen.module.globals[VarName] + Gen._store(Value, GVar) + Gen.variables[VarName] = GVar + if isinstance(Value.type, ir.PointerType) and isinstance(Value.type.pointee, (ir.LiteralStructType, ir.IdentifiedStructType)): + found: tuple[str, ir.Type] | None = Gen.find_struct_by_pointee(Value.type.pointee) + if found: + CN: str = found[0] + ST: ir.Type = found[1] + Gen.var_struct_class[VarName] = CN return if VarName in Gen._reg_values: OldVal: ir.Value = Gen._reg_values[VarName] diff --git a/lib/core/Handles/HandlesAugAssign.py b/lib/core/Handles/HandlesAugAssign.py index ea78caf..6b6adcd 100644 --- a/lib/core/Handles/HandlesAugAssign.py +++ b/lib/core/Handles/HandlesAugAssign.py @@ -87,8 +87,16 @@ class AugAssignHandle(BaseHandle): if isinstance(Node.target, ast.Name): VarName: str = Node.target.id Op: str = self.Trans.ExprHandler.GetOpSymbol(Node.op) - if VarName in Gen.global_vars and VarName in Gen.module.globals: - GVar: ir.GlobalVariable = Gen.module.globals[VarName] + if VarName in Gen.global_vars: + # 治本修复:global 声明的变量若未被模块级 AnnAssign 创建为 LLVM 全局 + # (注解无初始值的全局变量),此处自动创建零初始化全局变量 + GVar: ir.GlobalVariable + if VarName not in Gen.module.globals: + _gv_type: ir.Type = Value.type if isinstance(Value.type, ir.IntType) else ir.IntType(64) + GVar = ir.GlobalVariable(Gen.module, _gv_type, name=VarName) + GVar.initializer = ir.Constant(_gv_type, 0) + else: + GVar = Gen.module.globals[VarName] Gen.variables[VarName] = GVar OldVal: ir.Value = Gen._load(GVar, name=VarName) NewVal: ir.Value = Gen.emit_binary_op(Op, OldVal, Value, is_unsigned=is_unsigned) @@ -96,22 +104,14 @@ class AugAssignHandle(BaseHandle): return if VarName in Gen._reg_values: OldVal: ir.Value = Gen._reg_values[VarName] - saved_block: ir.Block = Gen.builder.block - entry_block: ir.Block = Gen.func.entry_basic_block - Gen.builder.position_at_start(entry_block) - var: ir.AllocaInstr = Gen.builder.alloca(OldVal.type, name=VarName) + var: ir.AllocaInstr = Gen._allocaEntry(OldVal.type, name=VarName) Gen._store(OldVal, var) - Gen.builder.position_at_end(saved_block) Gen.variables[VarName] = var del Gen._reg_values[VarName] if VarName in Gen._direct_values: OldVal: ir.Value = Gen._direct_values.pop(VarName) - saved_block: ir.Block = Gen.builder.block - entry_block: ir.Block = Gen.func.entry_basic_block - Gen.builder.position_at_start(entry_block) - var: ir.AllocaInstr = Gen.builder.alloca(OldVal.type, name=VarName) + var: ir.AllocaInstr = Gen._allocaEntry(OldVal.type, name=VarName) Gen._store(OldVal, var) - Gen.builder.position_at_end(saved_block) Gen.variables[VarName] = var if Gen.builder.block.is_terminated: return diff --git a/lib/core/Handles/HandlesBase.py b/lib/core/Handles/HandlesBase.py index 35225bb..ae55c22 100644 --- a/lib/core/Handles/HandlesBase.py +++ b/lib/core/Handles/HandlesBase.py @@ -657,6 +657,16 @@ class BaseHandle: ArrayCount = sym_info.value if ArrayCount == 1 and count_node.id in Gen._define_constants: def_val: Any = Gen._define_constants[count_node.id] + # 治本修复:本模块全局变量初始化值优先,避免跨模块同名 CDefine 覆盖 + try: + if hasattr(Gen, 'module') and count_node.id in Gen.module.globals: + _gv: Any = Gen.module.globals[count_node.id] + if getattr(_gv, 'initializer', None) is not None: + _iv: Any = _gv.initializer + if hasattr(_iv, 'constant') and isinstance(_iv.constant, int): + def_val = _iv.constant + except Exception: + pass if isinstance(def_val, int): ArrayCount = def_val return ArrayCount diff --git a/lib/core/Handles/HandlesExpr.py b/lib/core/Handles/HandlesExpr.py index 7522f4c..6e3ea35 100644 --- a/lib/core/Handles/HandlesExpr.py +++ b/lib/core/Handles/HandlesExpr.py @@ -1,493 +1,505 @@ -from __future__ import annotations -from typing import TYPE_CHECKING, Any -if TYPE_CHECKING: - from lib.core.translator import Translator - from lib.core.LlvmCodeGenerator import LlvmCodeGenerator -import ast -import re -import llvmlite.ir as ir -from lib.core.Handles.HandlesBase import BaseHandle -from lib.constants.config import mode as _config_mode -from lib.includes.t import CTypeRegistry as _CR - - -class ExprHandle(BaseHandle): - - # list 元素类型 → (字节大小, LLVM 元素类型) 映射表 - # 用于 _HandleListLlvm 中 alloc_size / byte_offset / elem_ptr 类型统一查表, - # 消除原代码三处重复的 if-elif 链。 - _ELEM_TYPE_INFO: dict[str, tuple[int, ir.Type]] = { - 'i8': (1, ir.IntType(8)), - 'i16': (2, ir.IntType(16)), - 'i32': (4, ir.IntType(32)), - 'float': (4, ir.FloatType()), - 'double': (8, ir.DoubleType()), - } - - def __init__(self, translator: "Translator") -> None: - super().__init__(translator) - - def GetOpSymbol(self, Op: ast.cmpop | ast.operator | ast.unaryoperator) -> str | None: - return self.Trans.ExprUtils.GetOpSymbol(Op) - - def GetUnaryOpSymbol(self, Op: ast.unaryoperator) -> str | None: - return self.Trans.ExprUtils.GetUnaryOpSymbol(Op) - - def GetComparatorSymbol(self, Op: ast.cmpop) -> str | None: - return self.Trans.ExprUtils.GetComparatorSymbol(Op) - - def _get_var_class(self, node: ast.AST, Gen: LlvmCodeGenerator) -> str | None: - return self.Trans.ExprUtils._get_var_class(node, Gen) - - def _try_operator_overLoad(self, ClassName: str, op_name: str, obj_val: ir.Value, Gen: LlvmCodeGenerator, other_val: ir.Value | None = None) -> ir.Value | None: - return self.Trans.ExprUtils._try_operator_overLoad(ClassName, op_name, obj_val, Gen, other_val) - - def _get_llvm_member_offset(self, field_name: str, ClassName: str, Gen: LlvmCodeGenerator) -> int | None: - return self.Trans.ExprAttrHandle._get_llvm_member_offset(field_name, ClassName, Gen) - - def HandleExprLlvm(self, Node: ast.AST, VarType: ir.Type | str | None = None) -> ir.Value | None: - Gen: LlvmCodeGenerator = self.Trans.LlvmGen - if not Gen or not Gen.builder: - return None - if isinstance(Node, ast.Constant): - return self._HandleConstantLlvm(Node, VarType) - elif isinstance(Node, ast.Name): - return self._HandleNameLlvm(Node, VarType) - elif isinstance(Node, ast.BinOp): - return self.Trans.ExprOpsHandle._HandleBinOpLlvm(Node, VarType) - elif isinstance(Node, ast.BoolOp): - return self.Trans.ExprOpsHandle._HandleBoolOpLlvm(Node) - elif isinstance(Node, ast.UnaryOp): - return self.Trans.ExprOpsHandle._HandleUnaryOpLlvm(Node) - elif isinstance(Node, ast.Call): - return self.Trans.ExprCallHandle._HandleCallLlvm(Node) - elif isinstance(Node, ast.Compare): - return self.Trans.ExprOpsHandle._HandleCompareLlvm(Node) - elif isinstance(Node, ast.Attribute): - return self.Trans.ExprAttrHandle._HandleAttributeLlvm(Node) - elif isinstance(Node, ast.Subscript): - return self.Trans.ExprAttrHandle._HandleSubscriptLlvm(Node) - elif isinstance(Node, ast.IfExp): - return self.Trans.ExprLambdaHandle._HandleIfExpLlvm(Node) - elif isinstance(Node, ast.NamedExpr): - return self.Trans.ExprLambdaHandle._HandleNamedExprLlvm(Node) - elif isinstance(Node, ast.JoinedStr): - return self.Trans.ExprFormatHandle._HandleJoinedStrLlvm(Node) - elif isinstance(Node, ast.Lambda): - return self.Trans.ExprLambdaHandle._HandleLambdaLlvm(Node) - elif isinstance(Node, ast.List): - return self._HandleListLlvm(Node, VarType) - return ir.Constant(ir.IntType(32), 0) - - def _HandleListLlvm(self, Node: ast.List, VarType: ir.Type | str | None = None) -> ir.Value | None: - Gen: LlvmCodeGenerator = self.Trans.LlvmGen - elements: list[ast.expr] = Node.elts - if not elements: - return ir.Constant(ir.IntType(8).as_pointer(), None) - - array_len: int = len(elements) - elem_type: str = 'i8' - - if VarType and isinstance(VarType, str) and 'list[' in VarType: - match: re.Match | None = re.search(r'list\[([^,\]]+)(?:,\s*(\d+))?\]', VarType) - if match: - type_str: str = match.group(1).strip() - if match.group(2): - array_len = int(match.group(2)) - if 'CChar' in type_str or 'char' in type_str.lower(): - elem_type = 'i8' - elif 'CFloat' in type_str or type_str.lower() == 'float': - elem_type = 'float' - elif 'CDouble' in type_str or type_str.lower() == 'double': - elem_type = 'double' - elif 'CInt' in type_str or ('int' in type_str.lower() and 'unsigned' not in type_str.lower()): - elem_type = 'i32' - elif 'CUnsignedInt' in type_str or 'unsigned' in type_str.lower(): - elem_type = 'i32' - elif 'CUnsignedChar' in type_str or 'unsigned char' in type_str.lower(): - elem_type = 'i8' - elif 'CShort' in type_str or 'short' in type_str.lower(): - elem_type = 'i16' - elif 'CUnsignedShort' in type_str: - elem_type = 'i16' - elif elements and all(isinstance(e, (ast.Constant,)) and isinstance(getattr(e, 'value', None), float) for e in elements): - elem_type = 'float' - - alloc_size: int = array_len - elem_info: tuple[int, ir.Type] = self._ELEM_TYPE_INFO.get(elem_type, (1, ir.IntType(8))) - elem_size: int = elem_info[0] - elem_llvm_type: ir.Type = elem_info[1] - alloc_size *= elem_size - - malloc_fn: Any = None - malloc_arg_type: ir.IntType = ir.IntType(64) - for fn in Gen.module.global_values: - if fn.name == 'malloc': - malloc_fn = fn - func_ftype: Any = getattr(fn, 'ftype', None) - if func_ftype and getattr(func_ftype, 'args', None): - if func_ftype.args: - malloc_arg_type = fn.ftype.args[0] - break - - if not malloc_fn: - try: - malloc_fn_type: ir.FunctionType = ir.FunctionType(ir.PointerType(ir.IntType(8)), [ir.IntType(64)]) - malloc_fn = ir.Function(Gen.module, malloc_fn_type, name='malloc') - Gen.functions['malloc'] = malloc_fn - except Exception: # 回退:malloc 函数创建失败时返回 null - return ir.Constant(ir.IntType(8).as_pointer(), None) - - alloc_ptr: Any = Gen.builder.call(malloc_fn, [ir.Constant(malloc_arg_type, alloc_size)]) - cast_ptr: Any = Gen.builder.bitcast(alloc_ptr, ir.PointerType(ir.IntType(8))) - - for i, elem in enumerate(elements): - if i >= array_len: - break - - elem_val: Any = self.HandleExprLlvm(elem, VarType=elem_type) - if elem_val is None: - continue - - byte_offset: int = i - if elem_type == 'i32': - byte_offset = i * 4 - elif elem_type == 'i16': - byte_offset = i * 2 - elif elem_type == 'float': - byte_offset = i * 4 - elif elem_type == 'double': - byte_offset = i * 8 - - ptr_as_int: Any = Gen.builder.ptrtoint(cast_ptr, ir.IntType(64)) - new_ptr_val: Any = Gen.builder.add(ptr_as_int, ir.Constant(ir.IntType(64), byte_offset)) - if elem_type == 'i32': - elem_ptr: Any = Gen.builder.inttoptr(new_ptr_val, ir.PointerType(ir.IntType(32))) - elif elem_type == 'i16': - elem_ptr = Gen.builder.inttoptr(new_ptr_val, ir.PointerType(ir.IntType(16))) - elif elem_type == 'float': - elem_ptr = Gen.builder.inttoptr(new_ptr_val, ir.PointerType(ir.FloatType())) - elif elem_type == 'double': - elem_ptr = Gen.builder.inttoptr(new_ptr_val, ir.PointerType(ir.DoubleType())) - else: - elem_ptr = Gen.builder.inttoptr(new_ptr_val, ir.PointerType(ir.IntType(8))) - - if elem_type == 'i8': - if isinstance(elem_val.type, ir.IntType) and elem_val.type.width > 8: - elem_val = Gen.builder.trunc(elem_val, ir.IntType(8), name=f"trunc_elem_{i}") - elif isinstance(elem_val.type, ir.PointerType): - elem_val = Gen.builder.ptrtoint(elem_val, ir.IntType(64), name=f"ptrtoint_elem_{i}") - elem_val = Gen.builder.trunc(elem_val, ir.IntType(8), name=f"trunc_elem_{i}") - elif elem_type == 'i32': - if isinstance(elem_val.type, ir.IntType): - if elem_val.type.width < 32: - elem_val = Gen.builder.zext(elem_val, ir.IntType(32), name=f"zext_elem_{i}") - elif elem_val.type.width > 32: - elem_val = Gen.builder.trunc(elem_val, ir.IntType(32), name=f"trunc_elem_{i}") - elif isinstance(elem_val.type, ir.PointerType): - elem_val = Gen.builder.ptrtoint(elem_val, ir.IntType(32), name=f"ptrtoint_elem_{i}") - elif elem_type == 'i16': - if isinstance(elem_val.type, ir.IntType): - if elem_val.type.width < 16: - elem_val = Gen.builder.zext(elem_val, ir.IntType(16), name=f"zext_elem_{i}") - elif elem_val.type.width > 16: - elem_val = Gen.builder.trunc(elem_val, ir.IntType(16), name=f"trunc_elem_{i}") - elif elem_type == 'float': - if isinstance(elem_val.type, ir.DoubleType): - elem_val = Gen.builder.fptrunc(elem_val, ir.FloatType(), name=f"fptrunc_elem_{i}") - elif isinstance(elem_val.type, ir.IntType): - elem_val = Gen.builder.sitofp(elem_val, ir.FloatType(), name=f"sitofp_elem_{i}") - elif elem_type == 'double': - if isinstance(elem_val.type, ir.FloatType): - elem_val = Gen.builder.fpext(elem_val, ir.DoubleType(), name=f"fpext_elem_{i}") - elif isinstance(elem_val.type, ir.IntType): - elem_val = Gen.builder.sitofp(elem_val, ir.DoubleType(), name=f"sitofp_elem_{i}") - - Gen.builder.store(elem_val, elem_ptr) - - if elem_type in ('float', 'double'): - return Gen.builder.bitcast(alloc_ptr, ir.PointerType(elem_llvm_type), name=f"list_{elem_type}_ptr") - return cast_ptr - - def _HandleConstantLlvm(self, Node: ast.Constant, VarType: ir.Type | str | None = None) -> ir.Value: - Gen: LlvmCodeGenerator = self.Trans.LlvmGen - Value: Any = Node.value - if Value is None: - if VarType is not None and isinstance(VarType, ir.PointerType): - return ir.Constant(VarType, None) - return ir.Constant(ir.IntType(8).as_pointer(), None) - elif isinstance(Value, bool): - return ir.Constant(ir.IntType(32), 1 if Value else 0) - elif isinstance(Value, int): - if VarType is not None: - if isinstance(VarType, ir.IntType): - return ir.Constant(VarType, Value & ((1 << VarType.width) - 1)) - if isinstance(VarType, ir.PointerType): - return ir.Constant(ir.IntType(64), Value) - if isinstance(VarType, (ir.FloatType, ir.DoubleType)): - return ir.Constant(VarType, float(Value)) - if isinstance(VarType, str) and '*' in VarType: - return ir.Constant(ir.IntType(64), Value) - if isinstance(VarType, str): - resolved: Any = _CR.ResolveName(VarType) or _CR.LLVMToCType(VarType) - if resolved: - ctype_cls: type = resolved[0] if isinstance(resolved, tuple) else resolved - inst: Any = ctype_cls() - size: int = getattr(inst, 'Size', 32) - is_unsigned: bool = getattr(inst, 'IsSigned', True) is False - mask: int = (1 << size) - 1 - return ir.Constant(ir.IntType(size), Value & mask) - llvm_match: re.Match | None = re.match(r'^i(\d+)$', VarType) - if llvm_match: - width: int = int(llvm_match.group(1)) - return ir.Constant(ir.IntType(width), Value & ((1 << width) - 1)) - if Value < 0 or Value > 0xFFFFFFFF: - return ir.Constant(ir.IntType(64), Value) - return ir.Constant(ir.IntType(32), Value & 0xFFFFFFFF) - elif isinstance(Value, float): - if VarType and isinstance(VarType, ir.FloatType): - return ir.Constant(VarType, Value) - elif VarType and isinstance(VarType, ir.DoubleType): - return ir.Constant(VarType, Value) - return ir.Constant(ir.DoubleType(), Value) - elif isinstance(Value, str): - is_wide: bool = getattr(Node, 'kind', None) == 'u' - # 引号类型推断:单引号单字符 → i8,双引号/多字符/三重 → i8*,空 → 0(None) - quote_char: str | None = None - is_triple: bool = False - if not is_wide: - col_offset: int = getattr(Node, 'col_offset', 0) - node_lineno: int = getattr(Node, 'lineno', 0) - # AST 的 lineno 可能不准确(常量节点可能指向下一行), - # 因此在 lineno 和 lineno-1 两行中查找引号 - for try_lineno in (node_lineno, node_lineno - 1): - source_line: str | None = Gen._get_source_line(try_lineno) - if source_line and col_offset < len(source_line): - ch: str = source_line[col_offset] - if ch in ("'", '"'): - quote_char = ch - if col_offset + 2 < len(source_line) and source_line[col_offset:col_offset + 3] in ("'''", '"""'): - is_triple = True - break - # 空字符串 → 创建指向 \0 的全局变量 (而非 null, 避免 strcmp 解引用空指针崩溃) - # 走与非空字符串相同的路径, 由下方 else 分支处理 - # 单引号单字符(非三重)→ i8 - is_char_literal: bool = (not is_triple) and (quote_char == "'") and (len(Value) == 1) and not is_wide - if is_char_literal: - if VarType is not None and isinstance(VarType, ir.PointerType): - pass # 类型不匹配:目标是 ptr 但值是 char,走 string 路径 - elif isinstance(VarType, ir.IntType): - return ir.Constant(VarType, ord(Value[0])) - elif isinstance(VarType, str): - resolved = _CR.ResolveName(VarType) or _CR.LLVMToCType(VarType) - if resolved: - ctype_cls = resolved[0] if isinstance(resolved, tuple) else resolved - inst = ctype_cls() - size = getattr(inst, 'Size', 32) - return ir.Constant(ir.IntType(size), ord(Value[0])) - llvm_match = re.match(r'^i(\d+)$', VarType) - if llvm_match: - return ir.Constant(ir.IntType(int(llvm_match.group(1))), ord(Value[0])) - elif VarType is not None: - return ir.Constant(ir.IntType(8), ord(Value[0])) - else: - # 无类型提示:单引号单字符默认为 i8 - return ir.Constant(ir.IntType(8), ord(Value[0])) - if is_wide: - str_value: str = Value + '\x00' - wide_chars: list[int] = [ord(c) for c in str_value] - target_count: int = len(wide_chars) - str_type: ir.ArrayType = ir.ArrayType(ir.IntType(16), target_count) - gv_name: str = f"str_const_{Gen.string_const_counter}" - gv: ir.GlobalVariable = ir.GlobalVariable(Gen.module, str_type, name=gv_name) - gv.initializer = ir.Constant(str_type, wide_chars) - gv.linkage = 'internal' - Gen.string_const_counter += 1 - ptr: Any = Gen.builder.gep(gv, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), 0)], name=f"{gv_name}_cast") - return ptr - else: - str_value = Value + '\x00' - str_bytes: bytes = str_value.encode('utf-8') - target_count = len(str_bytes) - if isinstance(VarType, ir.ArrayType) and isinstance(VarType.element, ir.IntType) and VarType.element.width == 8: - target_count = VarType.count - if len(str_bytes) < target_count: - str_bytes = str_bytes + b'\x00' * (target_count - len(str_bytes)) - else: - str_bytes = str_bytes[:target_count] - str_type = ir.ArrayType(ir.IntType(8), target_count) - gv_name = f"str_const_{Gen.string_const_counter}" - gv = ir.GlobalVariable(Gen.module, str_type, name=gv_name) - gv.initializer = ir.Constant(str_type, bytearray(str_bytes)) - gv.linkage = 'internal' - Gen.string_const_counter += 1 - ptr = Gen.builder.gep(gv, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), 0)], name=f"{gv_name}_cast") - return ptr - return ir.Constant(ir.IntType(32), 0) - - def _HandleNameLlvm(self, Node: ast.Name, VarType: ir.Type | str | None = None) -> ir.Value: - Gen: LlvmCodeGenerator = self.Trans.LlvmGen - VarName: str = Node.id - # [CD] 诊断:仅对关键常量输出(FOREGROUND_*, BACKGROUND_*, STD_*, *HANDLE*) - import sys as _sys - _is_cd_key: bool = isinstance(VarName, str) and (VarName.startswith('FOREGROUND_') or VarName.startswith('BACKGROUND_') or 'STD_' in VarName or 'HANDLE' in VarName) - define_constants: dict[str, Any] = getattr(Gen, '_define_constants', {}) - if VarName in define_constants: - val: Any = define_constants[VarName] - if _is_cd_key: - print(f"[CD] lookup: '{VarName}' found in _define_constants val={val}", file=_sys.stderr, flush=True) - if isinstance(val, int): - # Use VarType hint if available to avoid unnecessary type mismatch - if VarType is not None and isinstance(VarType, ir.IntType): - return ir.Constant(VarType, val & ((1 << VarType.width) - 1)) - if VarName in Gen.var_signedness and Gen.var_signedness[VarName]: - if val < -(1 << 31) or val > 0xFFFFFFFF: - return ir.Constant(ir.IntType(64), val & 0xFFFFFFFFFFFFFFFF) - return ir.Constant(ir.IntType(32), val & 0xFFFFFFFF) - if val < -(1 << 31) or val > 0xFFFFFFFF: - return ir.Constant(ir.IntType(64), val) - return ir.Constant(ir.IntType(32), val & 0xFFFFFFFF) - elif isinstance(val, float): - return ir.Constant(ir.DoubleType(), val) - elif isinstance(val, str): - return Gen._create_string_global(val) - # 如果 _define_constants 中没有,尝试从符号表查找 - if VarName not in define_constants: - try: - sym_info: Any = self.Trans.SymbolTable.lookup(VarName) - if sym_info and sym_info.IsDefine and sym_info.DefineValue is not None: - val = sym_info.DefineValue - if _is_cd_key: - print(f"[CD] lookup: '{VarName}' found in SymbolTable val={val}", file=_sys.stderr, flush=True) - if isinstance(val, int): - # Use VarType hint if available - if VarType is not None and isinstance(VarType, ir.IntType): - return ir.Constant(VarType, val & ((1 << VarType.width) - 1)) - if val < -(1 << 31) or val > 0xFFFFFFFF: - return ir.Constant(ir.IntType(64), val) - return ir.Constant(ir.IntType(32), val & 0xFFFFFFFF) - elif isinstance(val, float): - return ir.Constant(ir.DoubleType(), val) - elif isinstance(val, str): - return Gen._create_string_global(val) - elif _is_cd_key: - print(f"[CD] lookup: '{VarName}' NOT in SymbolTable", file=_sys.stderr, flush=True) - except Exception as _e: - if _config_mode == "strict": - self.Trans.LogWarning(f"异常被忽略: {_e}") - # 治本修复:如果符号表也没有,回退查询 _all_define_constants - # _all_define_constants 由 Phase2Translator 从所有 .pyi 文件预提取, - # 包含跨模块导入的 CDefine 常量(如 FOREGROUND_GREEN、STD_OUTPUT_HANDLE) - if VarName not in define_constants: - all_dc: dict[str, Any] = getattr(Gen, '_all_define_constants', None) or getattr(self.Trans, '_all_define_constants', None) or {} - if VarName in all_dc: - val: Any = all_dc[VarName] - if _is_cd_key: - print(f"[CD] lookup: '{VarName}' found in _all_define_constants val={val}", file=_sys.stderr, flush=True) - if isinstance(val, int): - if VarType is not None and isinstance(VarType, ir.IntType): - return ir.Constant(VarType, val & ((1 << VarType.width) - 1)) - if val < -(1 << 31) or val > 0xFFFFFFFF: - return ir.Constant(ir.IntType(64), val & 0xFFFFFFFFFFFFFFFF) - return ir.Constant(ir.IntType(32), val & 0xFFFFFFFF) - elif isinstance(val, float): - return ir.Constant(ir.DoubleType(), val) - elif isinstance(val, str): - return Gen._create_string_global(val) - elif _is_cd_key: - print(f"[CD] lookup: '{VarName}' NOT found in ANY CDefine table", file=_sys.stderr, flush=True) - # 优先检查 variables(alloca),因为变量可能已被 += 等操作迁移到 variables - if VarName in Gen.variables and Gen.variables[VarName] is not None: - VarPtr: Any = Gen.variables[VarName] - if isinstance(VarPtr, ir.GlobalVariable) and isinstance(VarPtr.type, ir.PointerType) and isinstance(VarPtr.type.pointee, (ir.IdentifiedStructType, ir.LiteralStructType, ir.ArrayType)): - if VarName in Gen.global_struct_class: - Gen.var_struct_class[VarName] = Gen.global_struct_class[VarName] - return VarPtr - if isinstance(VarPtr.type, ir.PointerType) and isinstance(VarPtr.type.pointee, (ir.IdentifiedStructType, ir.LiteralStructType, ir.ArrayType)): - if VarName in Gen.global_struct_class: - Gen.var_struct_class[VarName] = Gen.global_struct_class[VarName] - return VarPtr - # 防御性恢复:对于 double-pointer(如 ndarray**,pointee 是 PointerType) - # 或其他非结构体类型,若 global_struct_class 已记录该变量的类名, - # 也恢复 var_struct_class。这确保方法调用能查找到正确的特化类 - # (如 ndarray[double]),而非 fallback 到 opaque 基础类型。 - if VarName in Gen.global_struct_class and VarName not in Gen.var_struct_class: - Gen.var_struct_class[VarName] = Gen.global_struct_class[VarName] - loaded: ir.Value = Gen._load(VarPtr, name=VarName) - # 大端局部变量:读取时 bswap 还原 - loaded = Gen._apply_bswap_if_big(loaded, getattr(Gen, 'local_var_byteorders', {}).get(VarName, ""), f"bswap_load_{VarName}") - return loaded - if VarName in Gen._reg_values: - return Gen._reg_values[VarName] - if VarName in Gen._direct_values: - return Gen._direct_values[VarName] - if VarName in Gen.global_vars and VarName in Gen.module.globals: - GVar: Any = Gen.module.globals[VarName] - Gen.variables[VarName] = GVar - if isinstance(GVar, ir.Function): - return GVar - if isinstance(GVar.type, ir.PointerType) and isinstance(GVar.type.pointee, (ir.IdentifiedStructType, ir.LiteralStructType, ir.ArrayType)): - return GVar - return Gen._load(GVar, name=VarName) - if VarName in Gen.module.globals: - GVar = Gen.module.globals[VarName] - Gen.variables[VarName] = GVar - if isinstance(GVar, ir.Function): - return GVar - if VarName in Gen.global_struct_class: - Gen.var_struct_class[VarName] = Gen.global_struct_class[VarName] - if isinstance(GVar.type, ir.PointerType) and isinstance(GVar.type.pointee, (ir.IdentifiedStructType, ir.LiteralStructType, ir.ArrayType)): - return GVar - return Gen._load(GVar, name=VarName) - if VarName == 'self': - # 治本修复:方法名为 _get_var_ptr(小写),原 GetVarPtr 不存在会抛 AttributeError。 - # 当 self 未注册到 variables 时(如 opaque struct 参数走了 else 分支), - # 通过 _get_var_ptr 兜底返回 None,由调用方处理。 - SelfPtr: ir.Value | None = Gen._get_var_ptr('self') - if SelfPtr is not None: - return SelfPtr - # 最终兜底:若 _get_var_ptr 返回 None(self 既不在 _reg_values 也不在 variables), - # 直接返回函数参数本身(LLVM Argument)。这避免了 AttributeError 导致的异常路径。 - for arg in getattr(Gen.func, 'args', []): - if getattr(arg, 'name', None) == 'self': - return arg - return ir.Constant(ir.IntType(32), 0) - if Gen._has_function(VarName): - func: Any = Gen._get_function(VarName) - if func: - return Gen.builder.bitcast(func, ir.IntType(8).as_pointer(), name=f"funcptr_{VarName}") - if VarName in Gen.class_methods: - return ir.Constant(ir.IntType(8).as_pointer(), None) - if VarName == 'True' or VarName == 'False': - return ir.Constant(ir.IntType(32), 1 if VarName == 'True' else 0) - SymInfo: Any = self.Trans.SymbolTable.lookup(VarName) - if SymInfo: - if SymInfo.IsEnumMember and isinstance(SymInfo.value, int): - return ir.Constant(ir.IntType(32), SymInfo.value) - if SymInfo.IsFunction or SymInfo.IsFuncPtr: - MangledName: str = Gen._mangle_func_name(VarName) - if MangledName in Gen.module.globals: - g: Any = Gen.module.globals[MangledName] - if isinstance(g, ir.Function): - Gen.functions[VarName] = g - return Gen.builder.bitcast(g, ir.IntType(8).as_pointer(), name=f"funcptr_{VarName}") - for sha1 in Gen.ModuleSha1Map.values(): - prefixed: str = f"{sha1}.{VarName}" - if prefixed in Gen.module.globals: - g = Gen.module.globals[prefixed] - if isinstance(g, ir.Function): - Gen.functions[VarName] = g - return Gen.builder.bitcast(g, ir.IntType(8).as_pointer(), name=f"funcptr_{VarName}") - t_c_imported: dict[str, tuple[str, str]] = getattr(self.Trans, '_t_c_imported_names', {}) - if VarName in t_c_imported: - src_module: str - src_name: str - src_module, src_name = t_c_imported[VarName] - virtual_attr: ast.Attribute = ast.Attribute( - value=ast.Name(id=src_module, ctx=ast.Load()), - attr=src_name, - ctx=ast.Load() - ) - ast.copy_location(virtual_attr, Node) - return self.Trans.ExprAttrHandle._HandleAttributeLlvm(virtual_attr) +from __future__ import annotations +from typing import TYPE_CHECKING, Any +if TYPE_CHECKING: + from lib.core.translator import Translator + from lib.core.LlvmCodeGenerator import LlvmCodeGenerator +import ast +import re +import llvmlite.ir as ir +from lib.core.Handles.HandlesBase import BaseHandle +from lib.constants.config import mode as _config_mode +from lib.includes.t import CTypeRegistry as _CR + + +class ExprHandle(BaseHandle): + + # list 元素类型 → (字节大小, LLVM 元素类型) 映射表 + # 用于 _HandleListLlvm 中 alloc_size / byte_offset / elem_ptr 类型统一查表, + # 消除原代码三处重复的 if-elif 链。 + _ELEM_TYPE_INFO: dict[str, tuple[int, ir.Type]] = { + 'i8': (1, ir.IntType(8)), + 'i16': (2, ir.IntType(16)), + 'i32': (4, ir.IntType(32)), + 'float': (4, ir.FloatType()), + 'double': (8, ir.DoubleType()), + } + + def __init__(self, translator: "Translator") -> None: + super().__init__(translator) + + def GetOpSymbol(self, Op: ast.cmpop | ast.operator | ast.unaryoperator) -> str | None: + return self.Trans.ExprUtils.GetOpSymbol(Op) + + def GetUnaryOpSymbol(self, Op: ast.unaryoperator) -> str | None: + return self.Trans.ExprUtils.GetUnaryOpSymbol(Op) + + def GetComparatorSymbol(self, Op: ast.cmpop) -> str | None: + return self.Trans.ExprUtils.GetComparatorSymbol(Op) + + def _get_var_class(self, node: ast.AST, Gen: LlvmCodeGenerator) -> str | None: + return self.Trans.ExprUtils._get_var_class(node, Gen) + + def _try_operator_overLoad(self, ClassName: str, op_name: str, obj_val: ir.Value, Gen: LlvmCodeGenerator, other_val: ir.Value | None = None) -> ir.Value | None: + return self.Trans.ExprUtils._try_operator_overLoad(ClassName, op_name, obj_val, Gen, other_val) + + def _get_llvm_member_offset(self, field_name: str, ClassName: str, Gen: LlvmCodeGenerator) -> int | None: + return self.Trans.ExprAttrHandle._get_llvm_member_offset(field_name, ClassName, Gen) + + def HandleExprLlvm(self, Node: ast.AST, VarType: ir.Type | str | None = None) -> ir.Value | None: + Gen: LlvmCodeGenerator = self.Trans.LlvmGen + if not Gen or not Gen.builder: + return None + if isinstance(Node, ast.Constant): + return self._HandleConstantLlvm(Node, VarType) + elif isinstance(Node, ast.Name): + return self._HandleNameLlvm(Node, VarType) + elif isinstance(Node, ast.BinOp): + return self.Trans.ExprOpsHandle._HandleBinOpLlvm(Node, VarType) + elif isinstance(Node, ast.BoolOp): + return self.Trans.ExprOpsHandle._HandleBoolOpLlvm(Node) + elif isinstance(Node, ast.UnaryOp): + return self.Trans.ExprOpsHandle._HandleUnaryOpLlvm(Node) + elif isinstance(Node, ast.Call): + return self.Trans.ExprCallHandle._HandleCallLlvm(Node) + elif isinstance(Node, ast.Compare): + return self.Trans.ExprOpsHandle._HandleCompareLlvm(Node) + elif isinstance(Node, ast.Attribute): + return self.Trans.ExprAttrHandle._HandleAttributeLlvm(Node) + elif isinstance(Node, ast.Subscript): + return self.Trans.ExprAttrHandle._HandleSubscriptLlvm(Node) + elif isinstance(Node, ast.IfExp): + return self.Trans.ExprLambdaHandle._HandleIfExpLlvm(Node) + elif isinstance(Node, ast.NamedExpr): + return self.Trans.ExprLambdaHandle._HandleNamedExprLlvm(Node) + elif isinstance(Node, ast.JoinedStr): + return self.Trans.ExprFormatHandle._HandleJoinedStrLlvm(Node) + elif isinstance(Node, ast.Lambda): + return self.Trans.ExprLambdaHandle._HandleLambdaLlvm(Node) + elif isinstance(Node, ast.List): + return self._HandleListLlvm(Node, VarType) + return ir.Constant(ir.IntType(32), 0) + + def _HandleListLlvm(self, Node: ast.List, VarType: ir.Type | str | None = None) -> ir.Value | None: + Gen: LlvmCodeGenerator = self.Trans.LlvmGen + elements: list[ast.expr] = Node.elts + if not elements: + return ir.Constant(ir.IntType(8).as_pointer(), None) + + array_len: int = len(elements) + elem_type: str = 'i8' + + if VarType and isinstance(VarType, str) and 'list[' in VarType: + match: re.Match | None = re.search(r'list\[([^,\]]+)(?:,\s*(\d+))?\]', VarType) + if match: + type_str: str = match.group(1).strip() + if match.group(2): + array_len = int(match.group(2)) + if 'CChar' in type_str or 'char' in type_str.lower(): + elem_type = 'i8' + elif 'CFloat' in type_str or type_str.lower() == 'float': + elem_type = 'float' + elif 'CDouble' in type_str or type_str.lower() == 'double': + elem_type = 'double' + elif 'CInt' in type_str or ('int' in type_str.lower() and 'unsigned' not in type_str.lower()): + elem_type = 'i32' + elif 'CUnsignedInt' in type_str or 'unsigned' in type_str.lower(): + elem_type = 'i32' + elif 'CUnsignedChar' in type_str or 'unsigned char' in type_str.lower(): + elem_type = 'i8' + elif 'CShort' in type_str or 'short' in type_str.lower(): + elem_type = 'i16' + elif 'CUnsignedShort' in type_str: + elem_type = 'i16' + elif elements and all(isinstance(e, (ast.Constant,)) and isinstance(getattr(e, 'value', None), float) for e in elements): + elem_type = 'float' + + alloc_size: int = array_len + elem_info: tuple[int, ir.Type] = self._ELEM_TYPE_INFO.get(elem_type, (1, ir.IntType(8))) + elem_size: int = elem_info[0] + elem_llvm_type: ir.Type = elem_info[1] + alloc_size *= elem_size + + malloc_fn: Any = None + malloc_arg_type: ir.IntType = ir.IntType(64) + for fn in Gen.module.global_values: + if fn.name == 'malloc': + malloc_fn = fn + func_ftype: Any = getattr(fn, 'ftype', None) + if func_ftype and getattr(func_ftype, 'args', None): + if func_ftype.args: + malloc_arg_type = fn.ftype.args[0] + break + + if not malloc_fn: + try: + malloc_fn_type: ir.FunctionType = ir.FunctionType(ir.PointerType(ir.IntType(8)), [ir.IntType(64)]) + malloc_fn = ir.Function(Gen.module, malloc_fn_type, name='malloc') + Gen.functions['malloc'] = malloc_fn + except Exception: # 回退:malloc 函数创建失败时返回 null + return ir.Constant(ir.IntType(8).as_pointer(), None) + + alloc_ptr: Any = Gen.builder.call(malloc_fn, [ir.Constant(malloc_arg_type, alloc_size)]) + cast_ptr: Any = Gen.builder.bitcast(alloc_ptr, ir.PointerType(ir.IntType(8))) + + for i, elem in enumerate(elements): + if i >= array_len: + break + + elem_val: Any = self.HandleExprLlvm(elem, VarType=elem_type) + if elem_val is None: + continue + + byte_offset: int = i + if elem_type == 'i32': + byte_offset = i * 4 + elif elem_type == 'i16': + byte_offset = i * 2 + elif elem_type == 'float': + byte_offset = i * 4 + elif elem_type == 'double': + byte_offset = i * 8 + + ptr_as_int: Any = Gen.builder.ptrtoint(cast_ptr, ir.IntType(64)) + new_ptr_val: Any = Gen.builder.add(ptr_as_int, ir.Constant(ir.IntType(64), byte_offset)) + if elem_type == 'i32': + elem_ptr: Any = Gen.builder.inttoptr(new_ptr_val, ir.PointerType(ir.IntType(32))) + elif elem_type == 'i16': + elem_ptr = Gen.builder.inttoptr(new_ptr_val, ir.PointerType(ir.IntType(16))) + elif elem_type == 'float': + elem_ptr = Gen.builder.inttoptr(new_ptr_val, ir.PointerType(ir.FloatType())) + elif elem_type == 'double': + elem_ptr = Gen.builder.inttoptr(new_ptr_val, ir.PointerType(ir.DoubleType())) + else: + elem_ptr = Gen.builder.inttoptr(new_ptr_val, ir.PointerType(ir.IntType(8))) + + if elem_type == 'i8': + if isinstance(elem_val.type, ir.IntType) and elem_val.type.width > 8: + elem_val = Gen.builder.trunc(elem_val, ir.IntType(8), name=f"trunc_elem_{i}") + elif isinstance(elem_val.type, ir.PointerType): + elem_val = Gen.builder.ptrtoint(elem_val, ir.IntType(64), name=f"ptrtoint_elem_{i}") + elem_val = Gen.builder.trunc(elem_val, ir.IntType(8), name=f"trunc_elem_{i}") + elif elem_type == 'i32': + if isinstance(elem_val.type, ir.IntType): + if elem_val.type.width < 32: + elem_val = Gen.builder.zext(elem_val, ir.IntType(32), name=f"zext_elem_{i}") + elif elem_val.type.width > 32: + elem_val = Gen.builder.trunc(elem_val, ir.IntType(32), name=f"trunc_elem_{i}") + elif isinstance(elem_val.type, ir.PointerType): + elem_val = Gen.builder.ptrtoint(elem_val, ir.IntType(32), name=f"ptrtoint_elem_{i}") + elif elem_type == 'i16': + if isinstance(elem_val.type, ir.IntType): + if elem_val.type.width < 16: + elem_val = Gen.builder.zext(elem_val, ir.IntType(16), name=f"zext_elem_{i}") + elif elem_val.type.width > 16: + elem_val = Gen.builder.trunc(elem_val, ir.IntType(16), name=f"trunc_elem_{i}") + elif elem_type == 'float': + if isinstance(elem_val.type, ir.DoubleType): + elem_val = Gen.builder.fptrunc(elem_val, ir.FloatType(), name=f"fptrunc_elem_{i}") + elif isinstance(elem_val.type, ir.IntType): + elem_val = Gen.builder.sitofp(elem_val, ir.FloatType(), name=f"sitofp_elem_{i}") + elif elem_type == 'double': + if isinstance(elem_val.type, ir.FloatType): + elem_val = Gen.builder.fpext(elem_val, ir.DoubleType(), name=f"fpext_elem_{i}") + elif isinstance(elem_val.type, ir.IntType): + elem_val = Gen.builder.sitofp(elem_val, ir.DoubleType(), name=f"sitofp_elem_{i}") + + Gen.builder.store(elem_val, elem_ptr) + + if elem_type in ('float', 'double'): + return Gen.builder.bitcast(alloc_ptr, ir.PointerType(elem_llvm_type), name=f"list_{elem_type}_ptr") + return cast_ptr + + def _HandleConstantLlvm(self, Node: ast.Constant, VarType: ir.Type | str | None = None) -> ir.Value: + Gen: LlvmCodeGenerator = self.Trans.LlvmGen + Value: Any = Node.value + if Value is None: + if VarType is not None and isinstance(VarType, ir.PointerType): + return ir.Constant(VarType, None) + return ir.Constant(ir.IntType(8).as_pointer(), None) + elif isinstance(Value, bool): + return ir.Constant(ir.IntType(32), 1 if Value else 0) + elif isinstance(Value, int): + if VarType is not None: + if isinstance(VarType, ir.IntType): + return ir.Constant(VarType, Value & ((1 << VarType.width) - 1)) + if isinstance(VarType, ir.PointerType): + return ir.Constant(ir.IntType(64), Value) + if isinstance(VarType, (ir.FloatType, ir.DoubleType)): + return ir.Constant(VarType, float(Value)) + if isinstance(VarType, str) and '*' in VarType: + return ir.Constant(ir.IntType(64), Value) + if isinstance(VarType, str): + resolved: Any = _CR.ResolveName(VarType) or _CR.LLVMToCType(VarType) + if resolved: + ctype_cls: type = resolved[0] if isinstance(resolved, tuple) else resolved + inst: Any = ctype_cls() + size: int = getattr(inst, 'Size', 32) + is_unsigned: bool = getattr(inst, 'IsSigned', True) is False + mask: int = (1 << size) - 1 + return ir.Constant(ir.IntType(size), Value & mask) + llvm_match: re.Match | None = re.match(r'^i(\d+)$', VarType) + if llvm_match: + width: int = int(llvm_match.group(1)) + return ir.Constant(ir.IntType(width), Value & ((1 << width) - 1)) + if Value < 0 or Value > 0xFFFFFFFF: + return ir.Constant(ir.IntType(64), Value) + return ir.Constant(ir.IntType(32), Value & 0xFFFFFFFF) + elif isinstance(Value, float): + if VarType and isinstance(VarType, ir.FloatType): + return ir.Constant(VarType, Value) + elif VarType and isinstance(VarType, ir.DoubleType): + return ir.Constant(VarType, Value) + return ir.Constant(ir.DoubleType(), Value) + elif isinstance(Value, str): + is_wide: bool = getattr(Node, 'kind', None) == 'u' + # 引号类型推断:单引号单字符 → i8,双引号/多字符/三重 → i8*,空 → 0(None) + quote_char: str | None = None + is_triple: bool = False + if not is_wide: + col_offset: int = getattr(Node, 'col_offset', 0) + node_lineno: int = getattr(Node, 'lineno', 0) + # AST 的 lineno 可能不准确(常量节点可能指向下一行), + # 因此在 lineno 和 lineno-1 两行中查找引号 + for try_lineno in (node_lineno, node_lineno - 1): + source_line: str | None = Gen._get_source_line(try_lineno) + if source_line and col_offset < len(source_line): + ch: str = source_line[col_offset] + if ch in ("'", '"'): + quote_char = ch + if col_offset + 2 < len(source_line) and source_line[col_offset:col_offset + 3] in ("'''", '"""'): + is_triple = True + break + # 空字符串 → 创建指向 \0 的全局变量 (而非 null, 避免 strcmp 解引用空指针崩溃) + # 走与非空字符串相同的路径, 由下方 else 分支处理 + # 单引号单字符(非三重)→ i8 + is_char_literal: bool = (not is_triple) and (quote_char == "'") and (len(Value) == 1) and not is_wide + if is_char_literal: + if VarType is not None and isinstance(VarType, ir.PointerType): + pass # 类型不匹配:目标是 ptr 但值是 char,走 string 路径 + elif isinstance(VarType, ir.IntType): + return ir.Constant(VarType, ord(Value[0])) + elif isinstance(VarType, str): + resolved = _CR.ResolveName(VarType) or _CR.LLVMToCType(VarType) + if resolved: + ctype_cls = resolved[0] if isinstance(resolved, tuple) else resolved + inst = ctype_cls() + size = getattr(inst, 'Size', 32) + return ir.Constant(ir.IntType(size), ord(Value[0])) + llvm_match = re.match(r'^i(\d+)$', VarType) + if llvm_match: + return ir.Constant(ir.IntType(int(llvm_match.group(1))), ord(Value[0])) + elif VarType is not None: + return ir.Constant(ir.IntType(8), ord(Value[0])) + else: + # 无类型提示:单引号单字符默认为 i8 + return ir.Constant(ir.IntType(8), ord(Value[0])) + if is_wide: + str_value: str = Value + '\x00' + wide_chars: list[int] = [ord(c) for c in str_value] + target_count: int = len(wide_chars) + str_type: ir.ArrayType = ir.ArrayType(ir.IntType(16), target_count) + gv_name: str = f"str_const_{Gen.string_const_counter}" + gv: ir.GlobalVariable = ir.GlobalVariable(Gen.module, str_type, name=gv_name) + gv.initializer = ir.Constant(str_type, wide_chars) + gv.linkage = 'internal' + Gen.string_const_counter += 1 + ptr: Any = Gen.builder.gep(gv, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), 0)], name=f"{gv_name}_cast") + return ptr + else: + str_value = Value + '\x00' + str_bytes: bytes = str_value.encode('utf-8') + target_count = len(str_bytes) + if isinstance(VarType, ir.ArrayType) and isinstance(VarType.element, ir.IntType) and VarType.element.width == 8: + target_count = VarType.count + if len(str_bytes) < target_count: + str_bytes = str_bytes + b'\x00' * (target_count - len(str_bytes)) + else: + str_bytes = str_bytes[:target_count] + str_type = ir.ArrayType(ir.IntType(8), target_count) + gv_name = f"str_const_{Gen.string_const_counter}" + gv = ir.GlobalVariable(Gen.module, str_type, name=gv_name) + gv.initializer = ir.Constant(str_type, bytearray(str_bytes)) + gv.linkage = 'internal' + Gen.string_const_counter += 1 + ptr = Gen.builder.gep(gv, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), 0)], name=f"{gv_name}_cast") + return ptr + return ir.Constant(ir.IntType(32), 0) + + def _HandleNameLlvm(self, Node: ast.Name, VarType: ir.Type | str | None = None) -> ir.Value: + Gen: LlvmCodeGenerator = self.Trans.LlvmGen + VarName: str = Node.id + # [CD] 诊断:仅对关键常量输出(FOREGROUND_*, BACKGROUND_*, STD_*, *HANDLE*) + import sys as _sys + _is_cd_key: bool = isinstance(VarName, str) and (VarName.startswith('FOREGROUND_') or VarName.startswith('BACKGROUND_') or 'STD_' in VarName or 'HANDLE' in VarName) + # 治本修复:不把 module.globals 的 initializer 注入 _define_constants。 + # 原因:CDefine(t.CDefine 注解)在 AnnAssign/Assign 处理时已注册到 + # _define_constants 且不创建 LLVM global(不在 module.globals); + # module.globals 里全是可变全局变量(如 _sha1_store_count,有 += 写入), + # 若把其 initializer 当常量传播,会导致 range(_sha1_store_count) 被求值成 + # range(0)、printf 印 0 等问题(读取处不生成 load)。 + # CDefine 的本模块优先靠下方 _define_constants 查询保证,双点 bug 不复发。 + define_constants: dict[str, Any] = getattr(Gen, '_define_constants', {}) + # 治本防护:module.globals 里的都是可变全局变量(CDefine 不创建 LLVM global, + # 仅注册到 _define_constants)。可变全局有 += 等写入,不能当常量传播, + # 跳过 _define_constants 查询,直接走下方 variables/global_vars/module.globals 的 load。 + if VarName in define_constants and not (hasattr(Gen, 'module') and VarName in Gen.module.globals): + val: Any = define_constants[VarName] + # 治本修复:本模块全局变量初始化值优先,避免跨模块同名 CDefine 通过 + # 共享 _define_constants 覆盖本模块常量 + # (VpiReader.SHA1_LEN=16 被 Phase1.SHA1_LEN=17 覆盖导致双点符号 bug) + _gvar: Any = None + try: + if hasattr(Gen, 'module') and VarName in Gen.module.globals: + _gvar = Gen.module.globals[VarName] + except Exception: + _gvar = None + if _gvar is not None and getattr(_gvar, 'initializer', None) is not None: + _init: Any = _gvar.initializer + if isinstance(_init, ir.Constant) and isinstance(_init.constant, (int, float, str)): + val = _init.constant + if _is_cd_key: + print(f"[CD] lookup: '{VarName}' found in _define_constants val={val}", file=_sys.stderr, flush=True) + if isinstance(val, int): + # Use VarType hint if available to avoid unnecessary type mismatch + if VarType is not None and isinstance(VarType, ir.IntType): + return ir.Constant(VarType, val & ((1 << VarType.width) - 1)) + if VarName in Gen.var_signedness and Gen.var_signedness[VarName]: + if val < -(1 << 31) or val > 0xFFFFFFFF: + return ir.Constant(ir.IntType(64), val & 0xFFFFFFFFFFFFFFFF) + return ir.Constant(ir.IntType(32), val & 0xFFFFFFFF) + if val < -(1 << 31) or val > 0xFFFFFFFF: + return ir.Constant(ir.IntType(64), val) + return ir.Constant(ir.IntType(32), val & 0xFFFFFFFF) + elif isinstance(val, float): + return ir.Constant(ir.DoubleType(), val) + elif isinstance(val, str): + return Gen._create_string_global(val) + # 治本修复(方案C):CDefine 不通过共享 SymbolTable 跨模块裸名共享。 + # 此处不再消费 SymbolTable 中的 IsDefine 符号,避免其他模块 CDefine + # 覆盖本模块同名全局变量(VpiReader.SHA1_LEN=16 被 Phase1.SHA1_LEN=17 覆盖)。 + # 本模块 CDefine 已在步骤1(_define_constants)解析; + # 跨模块 CDefine 通过 _RegisterFromImportAliases 显式导入注册到 _define_constants。 + if VarName not in define_constants: + try: + sym_info: Any = self.Trans.SymbolTable.lookup(VarName) + if _is_cd_key and sym_info and sym_info.IsDefine: + print(f"[CD] lookup: '{VarName}' skipped in SymbolTable (CDefine not cross-module)", file=_sys.stderr, flush=True) + except Exception as _e: + if _config_mode == "strict": + self.Trans.LogWarning(f"异常被忽略: {_e}") + # 治本修复:如果符号表也没有,回退查询 _all_define_constants + # _all_define_constants 由 Phase2Translator 从所有 .pyi 文件预提取, + # 包含跨模块导入的 CDefine 常量(如 FOREGROUND_GREEN、STD_OUTPUT_HANDLE) + if VarName not in define_constants and VarName not in Gen.variables and not (hasattr(Gen, 'module') and VarName in Gen.module.globals): + all_dc: dict[str, Any] = getattr(Gen, '_all_define_constants', None) or getattr(self.Trans, '_all_define_constants', None) or {} + if VarName in all_dc: + val: Any = all_dc[VarName] + if _is_cd_key: + print(f"[CD] lookup: '{VarName}' found in _all_define_constants val={val}", file=_sys.stderr, flush=True) + if isinstance(val, int): + if VarType is not None and isinstance(VarType, ir.IntType): + return ir.Constant(VarType, val & ((1 << VarType.width) - 1)) + if val < -(1 << 31) or val > 0xFFFFFFFF: + return ir.Constant(ir.IntType(64), val & 0xFFFFFFFFFFFFFFFF) + return ir.Constant(ir.IntType(32), val & 0xFFFFFFFF) + elif isinstance(val, float): + return ir.Constant(ir.DoubleType(), val) + elif isinstance(val, str): + return Gen._create_string_global(val) + elif _is_cd_key: + print(f"[CD] lookup: '{VarName}' NOT found in ANY CDefine table", file=_sys.stderr, flush=True) + # 优先检查 variables(alloca),因为变量可能已被 += 等操作迁移到 variables + if VarName in Gen.variables and Gen.variables[VarName] is not None: + VarPtr: Any = Gen.variables[VarName] + if isinstance(VarPtr, ir.GlobalVariable) and isinstance(VarPtr.type, ir.PointerType) and isinstance(VarPtr.type.pointee, (ir.IdentifiedStructType, ir.LiteralStructType, ir.ArrayType)): + if VarName in Gen.global_struct_class: + Gen.var_struct_class[VarName] = Gen.global_struct_class[VarName] + return VarPtr + if isinstance(VarPtr.type, ir.PointerType) and isinstance(VarPtr.type.pointee, (ir.IdentifiedStructType, ir.LiteralStructType, ir.ArrayType)): + if VarName in Gen.global_struct_class: + Gen.var_struct_class[VarName] = Gen.global_struct_class[VarName] + return VarPtr + # 防御性恢复:对于 double-pointer(如 ndarray**,pointee 是 PointerType) + # 或其他非结构体类型,若 global_struct_class 已记录该变量的类名, + # 也恢复 var_struct_class。这确保方法调用能查找到正确的特化类 + # (如 ndarray[double]),而非 fallback 到 opaque 基础类型。 + if VarName in Gen.global_struct_class and VarName not in Gen.var_struct_class: + Gen.var_struct_class[VarName] = Gen.global_struct_class[VarName] + loaded: ir.Value = Gen._load(VarPtr, name=VarName) + # 大端局部变量:读取时 bswap 还原 + loaded = Gen._apply_bswap_if_big(loaded, getattr(Gen, 'local_var_byteorders', {}).get(VarName, ""), f"bswap_load_{VarName}") + return loaded + if VarName in Gen._reg_values: + return Gen._reg_values[VarName] + if VarName in Gen._direct_values: + return Gen._direct_values[VarName] + if VarName in Gen.global_vars and VarName in Gen.module.globals: + GVar: Any = Gen.module.globals[VarName] + Gen.variables[VarName] = GVar + if isinstance(GVar, ir.Function): + return GVar + if isinstance(GVar.type, ir.PointerType) and isinstance(GVar.type.pointee, (ir.IdentifiedStructType, ir.LiteralStructType, ir.ArrayType)): + return GVar + return Gen._load(GVar, name=VarName) + if VarName in Gen.module.globals: + GVar = Gen.module.globals[VarName] + Gen.variables[VarName] = GVar + if isinstance(GVar, ir.Function): + return GVar + if VarName in Gen.global_struct_class: + Gen.var_struct_class[VarName] = Gen.global_struct_class[VarName] + if isinstance(GVar.type, ir.PointerType) and isinstance(GVar.type.pointee, (ir.IdentifiedStructType, ir.LiteralStructType, ir.ArrayType)): + return GVar + return Gen._load(GVar, name=VarName) + if VarName == 'self': + # 治本修复:方法名为 _get_var_ptr(小写),原 GetVarPtr 不存在会抛 AttributeError。 + # 当 self 未注册到 variables 时(如 opaque struct 参数走了 else 分支), + # 通过 _get_var_ptr 兜底返回 None,由调用方处理。 + SelfPtr: ir.Value | None = Gen._get_var_ptr('self') + if SelfPtr is not None: + return SelfPtr + # 最终兜底:若 _get_var_ptr 返回 None(self 既不在 _reg_values 也不在 variables), + # 直接返回函数参数本身(LLVM Argument)。这避免了 AttributeError 导致的异常路径。 + for arg in getattr(Gen.func, 'args', []): + if getattr(arg, 'name', None) == 'self': + return arg + return ir.Constant(ir.IntType(32), 0) + if Gen._has_function(VarName): + func: Any = Gen._get_function(VarName) + if func: + return Gen.builder.bitcast(func, ir.IntType(8).as_pointer(), name=f"funcptr_{VarName}") + if VarName in Gen.class_methods: + return ir.Constant(ir.IntType(8).as_pointer(), None) + if VarName == 'True' or VarName == 'False': + return ir.Constant(ir.IntType(32), 1 if VarName == 'True' else 0) + SymInfo: Any = self.Trans.SymbolTable.lookup(VarName) + if SymInfo: + if SymInfo.IsEnumMember and isinstance(SymInfo.value, int): + return ir.Constant(ir.IntType(32), SymInfo.value) + if SymInfo.IsFunction or SymInfo.IsFuncPtr: + MangledName: str = Gen._mangle_func_name(VarName) + if MangledName in Gen.module.globals: + g: Any = Gen.module.globals[MangledName] + if isinstance(g, ir.Function): + Gen.functions[VarName] = g + return Gen.builder.bitcast(g, ir.IntType(8).as_pointer(), name=f"funcptr_{VarName}") + for sha1 in Gen.ModuleSha1Map.values(): + prefixed: str = f"{sha1}.{VarName}" + if prefixed in Gen.module.globals: + g = Gen.module.globals[prefixed] + if isinstance(g, ir.Function): + Gen.functions[VarName] = g + return Gen.builder.bitcast(g, ir.IntType(8).as_pointer(), name=f"funcptr_{VarName}") + t_c_imported: dict[str, tuple[str, str]] = getattr(self.Trans, '_t_c_imported_names', {}) + if VarName in t_c_imported: + src_module: str + src_name: str + src_module, src_name = t_c_imported[VarName] + virtual_attr: ast.Attribute = ast.Attribute( + value=ast.Name(id=src_module, ctx=ast.Load()), + attr=src_name, + ctx=ast.Load() + ) + ast.copy_location(virtual_attr, Node) + return self.Trans.ExprAttrHandle._HandleAttributeLlvm(virtual_attr) return ir.Constant(ir.IntType(32), 0) \ No newline at end of file diff --git a/lib/core/Handles/HandlesExprAsm.py b/lib/core/Handles/HandlesExprAsm.py index cacb44d..03d19e9 100644 --- a/lib/core/Handles/HandlesExprAsm.py +++ b/lib/core/Handles/HandlesExprAsm.py @@ -281,6 +281,11 @@ class ExprAsmHandle(BaseHandle): def _mangle_asm_calls(self, template: str) -> str: Gen: LlvmCodeGenerator = self.Trans.LlvmGen sha1: str = getattr(Gen, 'module_sha1', '') + # DDEBUG: 检测 module_sha1 是否带尾随点(双点 bug 根因拦截) + if sha1 and sha1.endswith('.'): + import sys as _dbg_sys + print(f"[DDEBUG_ASM] module_sha1 带尾随点: sha1='{sha1}' len={len(sha1)} template='{template[:80]}'", file=_dbg_sys.stderr) + _dbg_sys.exit(1) if not sha1: return template @@ -290,13 +295,18 @@ class ExprAsmHandle(BaseHandle): if func_name.lower() in self._X86_REGISTERS: return m.group(0) mangled: str = Gen._mangle_func_name(func_name) + # DDEBUG: 检测 mangled 是否含双点(双点 bug 根因拦截) + if '..' in mangled: + import sys as _dbg_sys + print(f"[DDEBUG_ASM] mangled 含双点: func='{func_name}' mangled='{mangled}' sha1='{sha1}'", file=_dbg_sys.stderr) + _dbg_sys.exit(1) if '.' in mangled: return f'{prefix}\\22{mangled}\\22' return f"{prefix}{mangled}" return re.sub(r'(call\s+)(\w+)', replace_call, template) - def _HandleAsmWithOpLlvm(self, asm_template_arg: ast.AST, op_arg: ast.AST | None = None, input_arg: ast.AST | None = None, output_arg: ast.AST | None = None, asm_format: str = 'Intel') -> ir.Value: + def _HandleAsmWithOpLlvm(self, asm_template_arg: ast.AST, op_arg: ast.AST | None = None, input_arg: ast.AST | None = None, output_arg: ast.AST | None = None, asm_format: str = 'Intel') -> ir.Value: Gen: LlvmCodeGenerator = self.Trans.LlvmGen input_ops: list[Any] = [] diff --git a/lib/core/Handles/HandlesExprCall.py b/lib/core/Handles/HandlesExprCall.py index e02fbc3..79dd27b 100644 --- a/lib/core/Handles/HandlesExprCall.py +++ b/lib/core/Handles/HandlesExprCall.py @@ -1873,6 +1873,15 @@ class ExprCallHandle(BaseHandle): def _HandleClosureCallLlvm(self, Node: ast.Call, FuncName: str) -> ir.Value: Gen = self.Trans.LlvmGen func = Gen.functions.get(FuncName) + # DDEBUG: 检测 func.name 含双点(说明 ir.Function 已被错误注册为双点名字) + if func is not None and '..' in getattr(func, 'name', ''): + import sys + sys.stderr.write(f"[DDEBUG] _HandleClosureCallLlvm DOUBLE-DOT func.name='{func.name}' FuncName='{FuncName}'\n") + sys.stderr.write(f"[DDEBUG] Gen.functions keys for '{FuncName}': {[k for k in list(Gen.functions.keys()) if '6ddf' in k or k == FuncName][:20]}\n") + import traceback + traceback.print_stack(file=sys.stderr, limit=10) + sys.stderr.flush() + sys.exit(1) if not func: if FuncName in self.Trans.FunctionDefCache: FuncDef = self.Trans.FunctionDefCache[FuncName] diff --git a/lib/core/Handles/HandlesIf.py b/lib/core/Handles/HandlesIf.py index 2fd361a..f3f577e 100644 --- a/lib/core/Handles/HandlesIf.py +++ b/lib/core/Handles/HandlesIf.py @@ -82,6 +82,16 @@ class IfHandle(BaseHandle): Gen: "Translator.LlvmGen" = self.Trans.LlvmGen if hasattr(Gen, '_define_constants') and name in Gen._define_constants: val: int | float | None = Gen._define_constants[name] + # 治本修复:本模块全局变量初始化值优先,避免跨模块同名 CDefine 覆盖 + try: + if hasattr(Gen, 'module') and name in Gen.module.globals: + _gv: Any = Gen.module.globals[name] + if getattr(_gv, 'initializer', None) is not None: + _iv: Any = _gv.initializer + if hasattr(_iv, 'constant') and isinstance(_iv.constant, (int, float)): + val = _iv.constant + except Exception: + pass if isinstance(val, (int, float)): return val info: "SymbolTable.SymbolInfo" = self.Trans.SymbolTable.lookup(name) diff --git a/lib/core/Handles/HandlesImports.py b/lib/core/Handles/HandlesImports.py index f295e7a..6679833 100644 --- a/lib/core/Handles/HandlesImports.py +++ b/lib/core/Handles/HandlesImports.py @@ -907,17 +907,21 @@ class ImportHandle(BaseHandle): return if IsCDefine: - # CDefine 宏不生成 LLVM 全局变量,只注册到 SymbolTable - # 引用时会直接替换为立即数 + # CDefine 宏不生成 LLVM 全局变量 + # 治本修复(方案C):裸名只注册到本模块 _define_constants, + # 不再注册到跨模块共享的 SymbolTable,避免同名 CDefine 污染其他模块的全局变量 + # (如 Phase1.SHA1_LEN=17 覆盖 VpiReader.SHA1_LEN=16 导致双点链接错误)。 + # 跨模块导入通过 _RegisterFromImportAliases 查带前缀全名后注册到本模块 _define_constants。 DefineValue = None if Node.value: DefineValue = self._ExtractConstValue(Node.value) - # 注册不带前缀的键名(例如 Z_NO_COMPRESSION) - # 但要先检查:如果符号已经存在且是 typedef,不覆盖它 - existing = self.Trans.SymbolTable.lookup(VarName) - if not (existing and existing.IsTypedef and existing.OriginalType): - self._RegisterCDefineSymbol(VarName, DefineValue, Node.lineno, ModulePath or 'unknown') - # 如果提供了模块名,也注册带模块前缀的键名 + # 仅本模块 CDefine 注册到 _define_constants(供 _HandleNameLlvm 步骤1 查找) + if module_name is None and DefineValue is not None: + define_constants = vars(Gen).setdefault('_define_constants', {}) + if VarName not in define_constants: + define_constants[VarName] = DefineValue + # 如果提供了模块名,注册带模块前缀的全名到 SymbolTable + # (供 _RegisterFromImportAliases 的 from X import Y 显式导入查找) if module_name: FullName = f"{module_name}.{VarName}" existing_full = self.Trans.SymbolTable.lookup(FullName) diff --git a/lib/core/Handles/HandlesWhile.py b/lib/core/Handles/HandlesWhile.py index b7b4eb4..4c00686 100644 --- a/lib/core/Handles/HandlesWhile.py +++ b/lib/core/Handles/HandlesWhile.py @@ -1,54 +1,53 @@ -from __future__ import annotations -from typing import TYPE_CHECKING -if TYPE_CHECKING: - from lib.core.translator import Translator -from lib.core.Handles.HandlesBase import BaseHandle -import llvmlite.ir as ir - - -class WhileHandle(BaseHandle): - def _HandleWhileLlvm(self, Node: ast.While) -> None: - Gen: "Translator.LlvmGen" = self.Trans.LlvmGen - if Gen._direct_values: - for var_name in list(Gen._direct_values.keys()): - OldVal: ir.Value = Gen._direct_values.pop(var_name) - if var_name not in Gen.variables or Gen.variables.get(var_name) is None: - saved_block: ir.Block = Gen.builder.block - entry_block: ir.Block = Gen.func.entry_basic_block - Gen.builder.position_at_start(entry_block) - var: ir.AllocaInstr = Gen.builder.alloca(OldVal.type, name=var_name) - Gen._store(OldVal, var) - Gen.builder.position_at_end(saved_block) - Gen.variables[var_name] = var - CondBB: ir.Block = Gen.func.append_basic_block(name="while.cond") - BodyBB: ir.Block = Gen.func.append_basic_block(name="while.body") - ElseBB: ir.Block | None = Gen.func.append_basic_block(name="while.else") if Node.orelse else None - AfterBB: ir.Block = Gen.func.append_basic_block(name="while.end") - Gen.loop_break_targets.append(AfterBB) - Gen.loop_continue_targets.append(CondBB) - Gen.builder.branch(CondBB) - Gen.builder.position_at_start(CondBB) - Cond: ir.Value | None = self.HandleExprLlvm(Node.test) - if Cond: - if not isinstance(Cond.type, ir.IntType) or Cond.type.width != 1: - if isinstance(Cond.type, (ir.FloatType, ir.DoubleType)): - Cond = Gen.builder.fcmp_ordered('!=', Cond, ir.Constant(Cond.type, 0.0), name="whilecond") - else: - Cond = Gen.builder.icmp_signed('!=', Cond, Gen._ZeroConst(Cond.type), name="whilecond") - if not Gen.builder.block.is_terminated: - Gen.builder.cbranch(Cond, BodyBB, ElseBB if ElseBB else AfterBB) - else: - if not Gen.builder.block.is_terminated: - Gen.builder.branch(ElseBB if ElseBB else AfterBB) - Gen.builder.position_at_start(BodyBB) - self.HandleBodyLlvm(Node.body) - if not Gen.builder.block.is_terminated: - Gen.builder.branch(CondBB) - Gen.loop_break_targets.pop() - Gen.loop_continue_targets.pop() - if ElseBB: - Gen.builder.position_at_start(ElseBB) - self.HandleBodyLlvm(Node.orelse) - if not Gen.builder.block.is_terminated: - Gen.builder.branch(AfterBB) +from __future__ import annotations +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from lib.core.translator import Translator +from lib.core.Handles.HandlesBase import BaseHandle +import llvmlite.ir as ir + + +class WhileHandle(BaseHandle): + def _HandleWhileLlvm(self, Node: ast.While) -> None: + Gen: "Translator.LlvmGen" = self.Trans.LlvmGen + if Gen._direct_values: + for var_name in list(Gen._direct_values.keys()): + OldVal: ir.Value = Gen._direct_values.pop(var_name) + if var_name not in Gen.variables or Gen.variables.get(var_name) is None: + # 用 _allocaEntry 在入口块开头插入 alloca,然后在当前 builder + # 位置生成 store。避免 position_at_start 导致 store 插入到 + # 入口块开头(可能在 va_list_ptr 等 bitcast 定义之前,违反支配性)。 + var: ir.AllocaInstr = Gen._allocaEntry(OldVal.type, name=var_name) + Gen._store(OldVal, var) + Gen.variables[var_name] = var + CondBB: ir.Block = Gen.func.append_basic_block(name="while.cond") + BodyBB: ir.Block = Gen.func.append_basic_block(name="while.body") + ElseBB: ir.Block | None = Gen.func.append_basic_block(name="while.else") if Node.orelse else None + AfterBB: ir.Block = Gen.func.append_basic_block(name="while.end") + Gen.loop_break_targets.append(AfterBB) + Gen.loop_continue_targets.append(CondBB) + Gen.builder.branch(CondBB) + Gen.builder.position_at_start(CondBB) + Cond: ir.Value | None = self.HandleExprLlvm(Node.test) + if Cond: + if not isinstance(Cond.type, ir.IntType) or Cond.type.width != 1: + if isinstance(Cond.type, (ir.FloatType, ir.DoubleType)): + Cond = Gen.builder.fcmp_ordered('!=', Cond, ir.Constant(Cond.type, 0.0), name="whilecond") + else: + Cond = Gen.builder.icmp_signed('!=', Cond, Gen._ZeroConst(Cond.type), name="whilecond") + if not Gen.builder.block.is_terminated: + Gen.builder.cbranch(Cond, BodyBB, ElseBB if ElseBB else AfterBB) + else: + if not Gen.builder.block.is_terminated: + Gen.builder.branch(ElseBB if ElseBB else AfterBB) + Gen.builder.position_at_start(BodyBB) + self.HandleBodyLlvm(Node.body) + if not Gen.builder.block.is_terminated: + Gen.builder.branch(CondBB) + Gen.loop_break_targets.pop() + Gen.loop_continue_targets.pop() + if ElseBB: + Gen.builder.position_at_start(ElseBB) + self.HandleBodyLlvm(Node.orelse) + if not Gen.builder.block.is_terminated: + Gen.builder.branch(AfterBB) Gen.builder.position_at_start(AfterBB) \ No newline at end of file diff --git a/lib/core/LLVMCG/BaseGen.py b/lib/core/LLVMCG/BaseGen.py index 37759b5..f409a91 100644 --- a/lib/core/LLVMCG/BaseGen.py +++ b/lib/core/LLVMCG/BaseGen.py @@ -595,6 +595,14 @@ class BaseGenMixin: return self._find_function(name) is not None def _get_or_declare_function(self, mangled_name: str, func_type: ir.FunctionType) -> ir.Function: + # DDEBUG: 检测 mangled_name 含双点(不应到达这里) + if '..' in mangled_name: + import sys + sys.stderr.write(f"[DDEBUG] _get_or_declare_function DOUBLE-DOT mangled_name='{mangled_name}'\n") + import traceback + traceback.print_stack(file=sys.stderr, limit=10) + sys.stderr.flush() + sys.exit(1) g = self.module.globals.get(mangled_name) if g and isinstance(g, ir.Function): return g @@ -605,6 +613,14 @@ class BaseGenMixin: return func def _mangle_func_name(self, name: str, module_name: str | None = None) -> str: + # DDEBUG: 检测即将产生双点的情况,立即打印并终止 + if name.startswith('.') or (module_name and module_name.endswith('.') and len(module_name) > 0): + import sys + sys.stderr.write(f"[DDEBUG] _mangle_func_name LEADING-DOT name='{name}' module_name='{module_name}'\n") + import traceback + traceback.print_stack(file=sys.stderr, limit=8) + sys.stderr.flush() + sys.exit(1) if name in self._export_funcs and not module_name: return name if name in self._export_extern_funcs: @@ -659,8 +675,18 @@ class BaseGenMixin: if self._skip_mangle(name): return name if self.module_sha1: - return f"{self.module_sha1}.{name}" - return name + result = f"{self.module_sha1}.{name}" + else: + result = name + # DDEBUG: 检测返回结果中是否含双点 + if '..' in result: + import sys + sys.stderr.write(f"[DDEBUG] _mangle_func_name RESULT-DOUBLE-DOT name='{name}' module_name='{module_name}' result='{result}'\n") + import traceback + traceback.print_stack(file=sys.stderr, limit=10) + sys.stderr.flush() + sys.exit(1) + return result def _get_source_line(self, lineno: int) -> str | None: if 0 < lineno <= len(self._current_source_lines): diff --git a/run_err.txt b/run_err.txt new file mode 100644 index 0000000..e69de29 diff --git a/run_out.txt b/run_out.txt new file mode 100644 index 0000000..77651ec --- /dev/null +++ b/run_out.txt @@ -0,0 +1,478 @@ +===== TransPyV Test Suite ===== + +asm: nop ok +asm: nop2 ok +asm: multi-clobber ok +asm: input ok val=42 +asm: output result=123 +asm: in+out result2=11 (expect 11) +=== attr_test: c.Attribute 装饰器测试 === + +--- Test 1: c.Attribute(always_inline) --- +AlwaysInlineFunc(21)=42 (expect 42) +AlwaysInlineFunc OK +--- Test 2: c.Attribute(noinline) --- +NoInlineFunc(5)=105 (expect 105) +NoInlineFunc OK +--- Test 3: c.Attribute(noreturn) --- +NoReturnFunc declared with noreturn attr +NoReturnFunc OK (not called to avoid UB) +--- Test 4: normal function (no attr) --- +NormalFunc(7)=21 (expect 21) +NormalFunc OK +--- Test 5: c.Attribute(always_inline, pure) --- +MultiAttrFunc(10)=11 (expect 11) +MultiAttrFunc OK +--- Test 6: c.Attribute(packed) --- +PackedAttrFunc(10)=9 (expect 9) +PackedAttrFunc OK +--- Test 7: c.Attribute(llvm.nounwind) --- +NoUnwindFunc(10)=11 (expect 11) +NoUnwindFunc OK +--- Test 8: c.Attribute(llvm.noredzone) --- +NoRedZoneFunc(10)=12 (expect 12) +NoRedZoneFunc OK +--- Test 9: c.Attribute(llvm.willreturn) --- +WillReturnFunc(10)=13 (expect 13) +WillReturnFunc OK +--- Test 10: c.Attribute(llvm.mustprogress) --- +MustProgressFunc(10)=14 (expect 14) +MustProgressFunc OK +--- Test 11: c.Attribute(const) --- +ConstFunc(99)=42 (expect 42) +ConstFunc OK +--- Test 12: c.Attribute(always_inline, nounwind, noredzone) --- +TripleAttrFunc(10)=15 (expect 15) +TripleAttrFunc OK + +=== attr_test 完成 === +local +=: 15 +local -=: 12 +local *=: 24 +local /=: 6 +local %=: 6 +global +=: 1 +global +=: 11 +global -=: 8 +bit &=: 15 +bit |=: 63 +bit ^=: 192 +bit <<=: 16 +bit >>=: 4 +global: 9 +global: 10 +global: 11 +closure: 1 +closure: 1 +closure: 1 +=== deco_test: t/c 装饰器测试 === + +--- Test 1: t.CDefine --- +MAX_VALUE=256 (expect 256) +PI_APPROX=314 (expect 314) +MAX_VALUE OK +PI_APPROX OK +--- Test 2: t.CExport --- +ExportedAdd(3,4)=7 (expect 7) +ExportedAdd OK +--- Test 3: t.CInline --- +InlineSquare(5)=25 (expect 25) +InlineSquare OK +--- Test 4: normal function --- +NormalSub(10,3)=7 (expect 7) +NormalSub OK +--- Test 5: t.CExport | t.CInline --- +ExportedInlineCube(3)=27 (expect 27) +ExportedInlineCube OK +--- Test 6: t.CExport return ptr --- +ExportedFindChar found, char=108 (expect 108) +ExportedFindChar OK +--- Test 7: t.CExtern | t.CExport --- +ExternalDecl declared (not called) +ExternalDecl OK +--- Test 8: t.State --- +StateDecl declared (not called) +StateDecl OK +--- Test 9: t.State (void) --- +StateVoidDecl declared (not called) +StateVoidDecl OK +--- Test 10: t.CArray[elem, CDefine] --- +ARR_SIZE=8 (expect 8) +arr sum=280 (expect 280) +arr[0]=0 (expect 0) +arr[7]=70 (expect 70) +CArray CDefine count OK + +=== deco_test 完成 === +deref: 104 +ptr: len(hello)=5 +=== eq_test: ==、!=、is、None 比较测试 === + +--- Test 1: int == / != --- +int == int (same) OK +int != int (diff) OK +not (int == diff) OK +--- Test 2: int < > <= >= --- +int < OK +int > OK +int <= OK +int >= OK +--- Test 3: ptr is None / is not None --- +strchr found, is not None OK +strchr not found, is None OK +--- Test 4: assign None and compare --- +None assign, is None OK +None assign, is not None OK +--- Test 5: ptr == None / != None --- +strstr found, != None OK +strstr not found, == None OK +--- Test 6: bool and/or --- +1 and 0 = false OK +1 or 0 = true OK +not 0 = true OK + +=== eq_test 完成 === +float: f=3.140000 +double: d=3.141593 +float: f=2.500000 +union: u.f=3.140000 +union: u.i=42 (after f overwritten) +union: float overwrites int verified +arith: 1.50 + 2.50 = 4.00 +arith: 1.50 - 2.50 = -1.00 +arith: 1.50 * 2.50 = 3.75 +arith: 1.50 / 2.50 = 0.60 +arith: 10.0000 + 3.0000 = 13.0000 +arith: 10.0000 - 3.0000 = 7.0000 +arith: 10.0000 * 3.0000 = 30.0000 +arith: 10.0000 / 3.0000 = 3.3333 +arith: 10.0 % 3.0 = 1.0000 +arith: 3 + 1.50 = 4.50 +while: total=10 i=5 +break: k=0 +break: k=1 +break: k=2 +continue: m=0 +continue: m=1 +continue: m=3 +continue: m=4 +for: j=0 +for: j=1 +for: j=2 +for: j=3 +for: j=4 +add(3,4)=7 +mul(5,6)=30 +square(7)=49 +factorial(5)=120 +add(b=4,a=3)=7 +sub(b=3,a=10)=7 +Hello, World! +Hello, World! +greet mixed: returned=2 +Hi, TransPyC! +greet kwargs: returned=1 +=== llvmir_test: c.LLVMIR 内联 LLVM IR 测试 === + +--- Test 1: LLVMIR add --- +add(10, 20)=30 (expect 30) +LLVMIR add OK +--- Test 2: LLVMIR sub --- +sub(50, 20)=30 (expect 30) +LLVMIR sub OK +--- Test 3: LLVMIR mul --- +mul(6, 7)=42 (expect 42) +LLVMIR mul OK +--- Test 4: LLVMIR sdiv --- +sdiv(100, 4)=25 (expect 25) +LLVMIR sdiv OK +--- Test 5: LLVMIR and --- +and(255, 15)=15 (expect 15) +LLVMIR and OK +--- Test 6: LLVMIR or --- +or(240, 15)=255 (expect 255) +LLVMIR or OK +--- Test 7: LLVMIR xor --- +xor(255, 15)=240 (expect 240) +LLVMIR xor OK +--- Test 8: LLVMIR shl --- +shl(1, 4)=16 (expect 16) +LLVMIR shl OK +--- Test 9: LLVMIR LOut --- +LOut add(10, 20)=30 (expect 30) +LLVMIR LOut OK +--- Test 10: LLVMIR icmp eq --- +icmp eq(5, 5)=-1 (expect nonzero) +LLVMIR icmp eq OK +--- Test 11: LLVMIR icmp ne --- +icmp ne(5, 3)=-1 (expect nonzero) +LLVMIR icmp ne OK +--- Test 12: LLVMIR icmp slt --- +icmp slt(3, 5)=-1 (expect nonzero) +LLVMIR icmp slt OK +--- Test 13: LLVMIR srem --- +srem(17, 5)=2 (expect 2) +LLVMIR srem OK +--- Test 14: LLVMIR lshr --- +lshr(256, 2)=64 (expect 64) +LLVMIR lshr OK +--- Test 15: LLVMIR nested in expression --- +(LLVMIR add(10,20)) + 10 = 40 (expect 40) +LLVMIR nested OK + +=== llvmir_test 完成 === +oop: === Test 1: Basic Methods === +oop: p.x=10 p.y=20 +oop: after move p.x=100 p.y=200 +oop: === Test 2: Defaults + Methods === +oop: initial count=0 step=1 +oop: after 3 increments: 1 2 3 +oop: after reset+increment: 1 +oop: === Test 3: __init__ === +oop: rect 3x4 area=12 +oop: === All OOP Tests Passed === +ptr: len(hello)=5 +ptr: after DerefAs x=88 +ptr: sum(A,B,C)=198 +if: x is truthy +if: 1==1 is truthy +while: total=10 i=5 +for: j=0 +for: j=1 +for: j=2 +for: j=3 +for: j=4 +break: k=0 +break: k=1 +break: k=2 +continue: m=0 +continue: m=1 +continue: m=3 +continue: m=4 +bool: x>5 and x<100 is true +bool: x>100 or x>5 is true +ptr: len(hello)=5 +ptr: after DerefAs v=88 +ptr: sum(A,B,C)=198 +ptr: c.Load v2=42 (expected 42) +ptr: c.Load overwrite v3=200 (expected 200) +ptr: c.Load src unchanged v5=999 v6=999 (expected 999, 999) +hello +strlen(Hello)=5 +=== string_test: string.py 库函数测试 === + +--- Test 1: strlen --- +strlen(Hello)=5 (expect 5) +strlen()=0 (expect 0) +strlen(Hello, World!)=13 (expect 13) +--- Test 2: strcmp --- +strcmp(abc,abc)=0 (expect 0) +strcmp(abc,abd)=-1 (expect <0) +strcmp(abd,abc)=1 (expect >0) +--- Test 3: strncmp --- +strncmp(abcdef,abcXYZ,3)=0 (expect 0) +strncmp(abcdef,abcXYZ,4)=12 (expect <0) +--- Test 4: atoi --- +atoi(123)=123 (expect 123) +atoi(-456)=-456 (expect -456) +atoi( 789)=789 (expect 789) +--- Test 5: strchr --- +strchr(Hello,'l') found, char=108 (expect 108) +strchr(Hello,'z') not found OK +--- Test 6: strstr --- +strstr(Hello,World) found OK +strstr(Hello,xyz) not found OK + +=== string_test 完成 === +struct: p.x=10 p.y=20 +struct: modified p.x=100 p.y=200 +struct: sum=300 +struct: volume=60 +array: total=1500 +array: arr[2]=999 +ptr: len(hello)=5 +ptr: sum(A,B,C)=198 +ctor: z.x=0 z.y=0 +ctor: p3.x=7 p3.y=8 +ctor: bx.w=10 bx.h=20 bx.d=30 +kw: p4.x=10 p4.y=20 +kw: p5.x=5 p5.y=15 +kw: bx2.w=10 bx2.h=20 bx2.d=30 +def: sz.w=100 sz.h=200 +def: sz2.w=5 sz2.h=6 +def: sz3.w=888 sz3.h=999 +def: sz4.w=7 sz4.h=200 +enum: Idle=0 Run=1 Stop=2 +enum: Red=10 Green=11 Blue=20 Yellow=21 +enum: Small=0 Big=1 Medium=2 +enum: sum(Idle,Run,Stop)=3 +enum: Idle==0 true +enum: Red==10 true +enum: Run!=Stop true +union: u.i=42 +union: u.l=20015998343868 +union: shared memory verified +type: CInt=100 CInt32T=200 CUInt32T=300 +type: CLong=1000 CLongLong=2000 CInt64T=3000 CSizeT=4000 +bit: 240&15=0 +bit: 240|15=255 +bit: 240^15=255 +bit: 240<<2=960 +bit: 240>>2=60 +bit: 17%5=2 +vtable: === Test Start === +vtable: a.GetName()=42 (expected 42) +vtable: a.Speak()=0 (expected 0) +vtable: s.SetSides(4)=0 (expected 0) +vtable: s.GetSides()=4 (expected 4) +vtable: === All Tests Passed === +inherit: === Test 1: Base Class === +inherit: a.GetName()=42 (expected 42) +inherit: a.Speak()=0 (expected 0) +inherit: === Test 2: Dog (override Speak) === +inherit: d.GetName()=100 (expected 100) +inherit: d.Speak()=1 (expected 1) +inherit: d.GetBreed()=7 (expected 7) +inherit: === Test 3: Cat (inherit Speak) === +inherit: ct.GetName()=200 (expected 200) +inherit: ct.Speak()=0 (expected 0) +inherit: ct.GetColor()=3 (expected 3) +inherit: === All Tests Passed === +funcvt: === Test Start === +funcvt: A.VirtualMethod()=15 (expected 15) +funcvt: A.NormalMethod()=25 (expected 25) +funcvt: B.KeptMethod()=37 (expected 37) +funcvt: B.ExcludedMethod()=47 (expected 47) +funcvt: C.VirtualMethod()=59 (expected 59) +funcvt: C.NormalMethod()=69 (expected 69) +funcvt: === All Tests Passed === +vdispatch: === Test Start === +vdispatch: === Test 1: Direct Dispatch === +vdispatch: a.Speak()=0 (expected 0) +vdispatch: d.Speak()=1 (expected 1) +vdispatch: === Test 2: Virtual Dispatch === +vdispatch: a.Speak()=1 (expected 1 after vtable copy) +vdispatch: === Test 3: GetName After VTable Copy === +vdispatch: a.GetName()=42 (expected 42) +vdispatch: === All Tests Passed === +new: === Test Start === +new: === Test 1: __new__ returns self === +new: WithNew.__new__ called +new: WithNew.__init__ called +new: w.GetValue()=42 (expected 42) +new: === Test 2: __new__ no extra args === +new: WithNewNoArgs.__new__ called +new: n.GetValue()=99 (expected 99) +new: === Test 3: __new__ + vtable === +new: WithNewVTable.__new__ called +new: vt.GetValue()=10 (expected 10) +new: vt.Speak()=11 (expected 11) +new: === All Tests Passed === +nsisol: === Test Start === +nsisol: === Test 1: from-import bare constructor === +nsisol: w.GetId()=42 (expected 42) +nsisol: w.Render()=100 (expected 100) +nsisol: g.Render()=200 (expected 200) +nsisol: g.GetExtra()=9 (expected 9) +nsisol: === Test 2: module-qualified constructor === +nsisol: ps.Sum()=30 (expected 30) +nsisol: ps2.Sum()=11 (expected 11) +nsisol: === Test 3: type annotation with imported class === +nsisol: annot_w.GetId()=99 (expected 99) +nsisol: === Test 4: cross-module inheritance vtable === +nsisol: base.Render()=100 (expected 100) +nsisol: derived.Render()=200 (expected 200) +nsisol: derived.GetId()=2 (expected 2) +nsisol: === All Tests Passed === +=== testcheck_test === + +--- Arithmetic --- +PASS: 3+4=7 +PASS: 10-3=7 +PASS: 6*7=42 +--- String --- +PASS: strlen(hello)=5 +PASS: strcmp(abc,abc)=0 +--- Module Import --- +testcheck module imported and called successfully +PASS: import testcheck works + +--- Summary --- +PASS: 6, FAIL: 0 +=== Operator Overload Tests === + +--- Counter __add__ --- +PASS: cnt(10)+5=15 +--- Counter __sub__/__mul__/__div__/__mod__ --- +PASS: cnt-3=7 +PASS: cnt*3=30 +PASS: cnt/3=3 +PASS: cnt%3=1 +--- Counter compare overloads --- +PASS: cnt==10:1 +PASS: cnt!=10:0 +PASS: cnt<20:1 +PASS: cnt<=10:1 +PASS: cnt>5:1 +PASS: cnt>=10:1 +--- BitBox bitwise overloads --- +PASS: bb&0x0F=15 +PASS: bb|0x100=511 +PASS: bb^0x55=170 +PASS: bb<<4=4080 +PASS: bb>>4=15 +--- Native int binop --- +PASS: 7+8=15 +PASS: 10-3=7 +PASS: 4*5=20 +--- Native int compare --- +PASS: 3<5 +PASS: 10==10 +--- Vec2 struct overloads --- +PASS: a+b x=4 +PASS: a+b y=6 +PASS: a-b x=2 +PASS: a-b y=2 +--- Vec2 compare overloads --- +PASS: (5,5)==(5,5):1 +PASS: (5,5)!=(5,5):0 + +--- Summary --- +PASS: 27, FAIL: 0 +circ: === Test Start === +circ: === Test 1: A.MakeB() === +circ: a.GetValue()=10 (expected 10) +circ: b.GetValue()=10 (expected 10) +circ: === Test 2: B.MakeA() === +circ: a2.GetValue()=10 (expected 10) +circ: === Test 3: value chain A(20)->B->A === +circ: final=20 (expected 20) +circ: === All Tests Passed === +=== nested_match_test: 嵌套 match REnum 检测测试 === + +[DBG] _init_mbuddy: start +[DBG] _init_mbuddy: malloc arena=0 +[DBG] _init_mbuddy: malloc mb=0 +[DBG] _init_mbuddy: before_init +[DBG] _init_mbuddy: init +[DBG] _init_mbuddy: store +[DBG] _init_mbuddy: done +--- Test 1: 单层 match LLVMType --- +[DBG] Int32 done: 0 +Int(-693633024) OK +bits==-693633024 FAIL +--- Test 2: 嵌套 match(case 块内 match 另一值)--- +outer Int(-688782832), inner Int(0) OK +values FAIL +--- Test 3: 嵌套 match pointee --- +--- Test 4: 3 层嵌套 match --- +--- Test 5: if 块内嵌套 match --- +Float(-688782320) + Double(0) OK +float values FAIL +--- Test 6: 嵌套 match 不同变体(default 分支)--- +outer Int(-688782192), inner Float(0) OK +mismatch values FAIL + +=== nested_match_test: SOME FAIL === + +===== Test Suite Complete ===== diff --git a/run_output.txt b/run_output.txt new file mode 100644 index 0000000..b898f7f --- /dev/null +++ b/run_output.txt @@ -0,0 +1 @@ +===== Test Suite Complete =====