diff --git a/programs/develop/tinypy/CHANGES.txt b/programs/develop/tinypy/CHANGES.txt new file mode 100644 index 0000000000..94484c427a --- /dev/null +++ b/programs/develop/tinypy/CHANGES.txt @@ -0,0 +1,35 @@ +== 1.1 ========================================================================= +* applied patch by Dean Hall to fix several range() bugs +* applied patch by Krzysztof Kowalczyk to add VS 2005, 2008 compatibility. +* reorganized the source so that contributed modules can go into contrib +* reorganized the reorganization so that modules go into modules + since that seems less confusing somehow +* added a crude pygame module - to see it in action: + $ python setup.py linux pygame + $ ./build/tinypy examples/julia.py +* added support for + from x import * + from x import y +* trimmed off 1064 bytes by changing all the tokens from dicts to + a Token class in tokenize, parse, encode modules +* applied patch by Seth Lemons to support /* */ comment stripping in + setup.py and get tinypy up to -std=c89 spec +* cleaned up encode.py so that registers are no longer leaked + added assert after each frame to check that this is the case +* applied patch by KK to improve tinypy/tests.py feedback +* applied patch by allefant to finish namespacing tinypy +* applied patch by allefant to keep blob->tinypy.h from having warnings +* added math module from Rockins Chen +* fixed precedent of ** +* removed unused tp_data meta methods +* made tp_data API "safer" by requiring the magic type +* improved setup.py to handle the clean argument +* renamed some internal fnc names for no good reason +* added boot option to setup.py so that full boostrapping + isn't always required +* applied const correctness patch from allefant +* fixed memory leak in list & dict copy functions +* improved kwargs support +* got it compiling with -Wc++-compat +* applied ord patch from allefant +* fixed mingw build \ No newline at end of file diff --git a/programs/develop/tinypy/LICENSE.txt b/programs/develop/tinypy/LICENSE.txt new file mode 100644 index 0000000000..1043c5af23 --- /dev/null +++ b/programs/develop/tinypy/LICENSE.txt @@ -0,0 +1,82 @@ +================================================================================ + +tinypy contains tinypy code licensed in a MIT format license. It also +contains some goodies grabbed from Python, so that license is included +as well. + +================================================================================ + +The tinypy License + +Copyright (c) 2008 Phil Hassey + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +================================================================================ + +PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +-------------------------------------------- + +1. This LICENSE AGREEMENT is between the Python Software Foundation +("PSF"), and the Individual or Organization ("Licensee") accessing and +otherwise using this software ("Python") in source or binary form and +its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, PSF +hereby grants Licensee a nonexclusive, royalty-free, world-wide +license to reproduce, analyze, test, perform and/or display publicly, +prepare derivative works, distribute, and otherwise use Python +alone or in any derivative version, provided, however, that PSF's +License Agreement and PSF's notice of copyright, i.e., "Copyright (c) +2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation; +All Rights Reserved" are retained in Python alone or in any derivative +version prepared by Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python. + +4. PSF is making Python available to Licensee on an "AS IS" +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF and +Licensee. This License Agreement does not grant permission to use PSF +trademarks or trade name in a trademark sense to endorse or promote +products or services of Licensee, or any third party. + +8. By copying, installing or otherwise using Python, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + +================================================================================ diff --git a/programs/develop/tinypy/README.txt b/programs/develop/tinypy/README.txt new file mode 100644 index 0000000000..954142fe23 --- /dev/null +++ b/programs/develop/tinypy/README.txt @@ -0,0 +1,62 @@ +64k tinypy +"batteries not (yet) included" +Copyright (c) 2008 Phil Hassey + +Check it out: + +$ python setup.py linux pygame +$ ./build/tinypy examples/julia.py +$ ./build/tinypy your-program-goes-here.py + +Depends on: +- python (only for bootstrapping) +- sdl (for the pygame module) +- gcc + +Credits: + - math module - Rockins Chen + - VS support - Krzysztof Kowalczyk + - bug fixin' - Dean Hall & Allefant + +Thanks to allefant and the python community for all the tips and feedback! +Thanks to John M. for a python 2.5 compat. patch. +And to illume and the rest of #ludumdare for morale support. +Also thanks to python.org, lua.org, valgrind.org, nekovm.org, pypy.org +http://javascript.crockford.com/tdop/tdop.html +http://www.memorymanagement.org/articles/recycle.html +http://shed-skin.blogspot.com/ + +Other "tiny" python implementations: +http://pymite.python-hosting.com/ +http://students.ceid.upatras.gr/~sxanth/pyvm/ + +F.A.Q.s: + +Q. If I run boot.py it says you've got like 80k of code! That's TOTALLY + not 64k! I want my money back. +A. Err... that's true. But 64k sounds *SO* much better than 80k. + If you *really* want it to be 64k, just run: + $ python mk64k.py + This does the following things: + - changes 4 spaces into tabs and removes blank lines + - removes comments + - removes the "namespacing" i.e. "tp_print" becomes "print" + +Q. The binary is bigger than 64k. I hate big binaries. +A. I don't really care, but if you run "upx tinypy" it makes the tinypy + binary smaller than 64k. + +Q. No matter how you spin this, it's just plain NOT 64k. +A. Let the buyer beware? I dunno, it's close enough. Let's call it a rounding + error, shall we? + +Q. How come some oddball combinations of variable and named arguments don't work? +A. Ask me some other time. Short answer: I do it like lua does it. Only calls + like this make sense: + call_with_var_args(a,b,c,*d) + call_with_named_args(a=b,**c) + mixes of both just don't work, sorry! + +Q. At the end of build.py tinypy doesn't work! +A. This is probably because of my use of -O3 in the final step. Run the command + again without -O3. Some versions of GCC are buggy and don't do well with it. \ No newline at end of file diff --git a/programs/develop/tinypy/ROADMAP.txt b/programs/develop/tinypy/ROADMAP.txt new file mode 100644 index 0000000000..d930253cc1 --- /dev/null +++ b/programs/develop/tinypy/ROADMAP.txt @@ -0,0 +1,55 @@ +tinypy is a minimalist implementation of python in 64k of code + +"batteries not included (yet)" +"lua for people who like python" + +what tinypy is: + * parser and bytecode compiler written in tinypy + * fully bootstrapped + * luaesque virtual machine with garbage collection written in C + it's "stackless" sans any "stackless" features + * cross-platform :) it runs under windows / linux / macosx + * a fairly decent subset of python + o classes and single inheritance + o functions with variable or keyword arguments + o strings, lists, dicts, numbers + o modules, list comprehensions + o exceptions with full traceback + o some builtins + - an easy C-API for building modules + - 64k of code (for at least some definition of 64k) + - interesting, educational, nifty, and useful + - well tested + - easy to read, maintain, and use + - fun fun fun!!! + - you can static compile it and its modules (MIT license, so "it's all good!") + +what tinypy will be: + - sandboxed + - a Cpython module (setup.py install) + - including some batteries (math, random, re, marshal, pygame?!) + - Visual Studio compatible + - documented + +what tinypy might be: + - as fast as python (maybe faster?) + - including a JIT module + - C89 compatible + - C++ compatible (like lua) + - a shed-skin module + - including a dynamic loading module + +what tinypy won't be: + - a full implementation of python + - totally compatible with python + +alternatives to tinypy: + - lua + - shed-skin + - pymite + - pyvm + - cython + - pypy + - jython + - ironpython + - python diff --git a/programs/develop/tinypy/examples/julia.py b/programs/develop/tinypy/examples/julia.py new file mode 100644 index 0000000000..cdacdf187d --- /dev/null +++ b/programs/develop/tinypy/examples/julia.py @@ -0,0 +1,42 @@ +# center: 10043 +import pygame +if '.' in str(1.0): + import pygame.locals + +SW,SH = 120,120 + +def julia(s,ca,cb): + pal = [((min(255,v)),(min(255,v*3/2)),(min(255,v*2))) for v in range(0,256)] + for y in range(0,SH): + for x in range(0,SW): + i=0 + a=((float(x)/SW) * 4.0 - 2.0) + b=((float(y)/SH) * 4.0 - 2.0) + while i < 15 and (a*a)+(b*b)<4.0: + na=(a*a)-(b*b)+ca + nb=(2.0*a*b)+cb + a=na + b=nb + i = i +1 + s.set_at((x,y),pal[i*16]) + +def main(): + pygame.init() + s = pygame.display.set_mode((SW,SH),0,32) + _quit = False + while not _quit: + for e in pygame.event.get(): + if e.type in (pygame.locals.QUIT,pygame.locals.KEYDOWN): + _quit = True + + x,y = pygame.mouse.get_pos() + ca=((float(x)/SW) * 2.0 - 1.0) + cb=((float(y)/SH) * 2.0 - 1.0) + ticks = pygame.time.get_ticks() + julia(s,ca,cb) + print(pygame.time.get_ticks()-ticks) + pygame.display.flip() + + +if __name__ == '__main__': + main() diff --git a/programs/develop/tinypy/modules/math/init.c b/programs/develop/tinypy/modules/math/init.c new file mode 100644 index 0000000000..1c1e0cbe25 --- /dev/null +++ b/programs/develop/tinypy/modules/math/init.c @@ -0,0 +1,66 @@ +#include "math.c" +#include "../../tinypy/tp.h" + +/* + * init math module, namely, set its dictionary + */ +void math_init(TP) +{ + /* + * new a module dict for math + */ + tp_obj math_mod = tp_dict(tp); + + /* + * initialize pi and e + */ + math_pi = tp_number(M_PI); + math_e = tp_number(M_E); + + /* + * bind math functions to math module + */ + tp_set(tp, math_mod, tp_string("pi"), math_pi); + tp_set(tp, math_mod, tp_string("e"), math_e); + tp_set(tp, math_mod, tp_string("acos"), tp_fnc(tp, math_acos)); + tp_set(tp, math_mod, tp_string("asin"), tp_fnc(tp, math_asin)); + tp_set(tp, math_mod, tp_string("atan"), tp_fnc(tp, math_atan)); + tp_set(tp, math_mod, tp_string("atan2"), tp_fnc(tp, math_atan2)); + tp_set(tp, math_mod, tp_string("ceil"), tp_fnc(tp, math_ceil)); + tp_set(tp, math_mod, tp_string("cos"), tp_fnc(tp, math_cos)); + tp_set(tp, math_mod, tp_string("cosh"), tp_fnc(tp, math_cosh)); + tp_set(tp, math_mod, tp_string("degrees"), tp_fnc(tp, math_degrees)); + tp_set(tp, math_mod, tp_string("exp"), tp_fnc(tp, math_exp)); + tp_set(tp, math_mod, tp_string("fabs"), tp_fnc(tp, math_fabs)); + tp_set(tp, math_mod, tp_string("floor"), tp_fnc(tp, math_floor)); + tp_set(tp, math_mod, tp_string("fmod"), tp_fnc(tp, math_fmod)); + tp_set(tp, math_mod, tp_string("frexp"), tp_fnc(tp, math_frexp)); + tp_set(tp, math_mod, tp_string("hypot"), tp_fnc(tp, math_hypot)); + tp_set(tp, math_mod, tp_string("ldexp"), tp_fnc(tp, math_ldexp)); + tp_set(tp, math_mod, tp_string("log"), tp_fnc(tp, math_log)); + tp_set(tp, math_mod, tp_string("log10"), tp_fnc(tp, math_log10)); + tp_set(tp, math_mod, tp_string("modf"), tp_fnc(tp, math_modf)); + tp_set(tp, math_mod, tp_string("pow"), tp_fnc(tp, math_pow)); + tp_set(tp, math_mod, tp_string("radians"), tp_fnc(tp, math_radians)); + tp_set(tp, math_mod, tp_string("sin"), tp_fnc(tp, math_sin)); + tp_set(tp, math_mod, tp_string("sinh"), tp_fnc(tp, math_sinh)); + tp_set(tp, math_mod, tp_string("sqrt"), tp_fnc(tp, math_sqrt)); + tp_set(tp, math_mod, tp_string("tan"), tp_fnc(tp, math_tan)); + tp_set(tp, math_mod, tp_string("tanh"), tp_fnc(tp, math_tanh)); + + /* + * bind special attributes to math module + */ + tp_set(tp, math_mod, tp_string("__doc__"), + tp_string( + "This module is always available. It provides access to the\n" + "mathematical functions defined by the C standard.")); + tp_set(tp, math_mod, tp_string("__name__"), tp_string("math")); + tp_set(tp, math_mod, tp_string("__file__"), tp_string(__FILE__)); + + /* + * bind to tiny modules[] + */ + tp_set(tp, tp->modules, tp_string("math"), math_mod); +} + diff --git a/programs/develop/tinypy/modules/math/math.c b/programs/develop/tinypy/modules/math/math.c new file mode 100644 index 0000000000..6dbb792201 --- /dev/null +++ b/programs/develop/tinypy/modules/math/math.c @@ -0,0 +1,365 @@ +#include +#ifndef M_E + #define M_E 2.7182818284590452354 +#endif +#ifndef M_PI + #define M_PI 3.14159265358979323846 +#endif + +#include + +/* + * template for tinypy math functions + * with one parameter. + * + * @cfunc is the coresponding function name in C + * math library. + */ +#define TP_MATH_FUNC1(cfunc) \ + static tp_obj math_##cfunc(TP) { \ + double x = TP_NUM(); \ + double r = 0.0; \ + \ + errno = 0; \ + r = cfunc(x); \ + if (errno == EDOM || errno == ERANGE) { \ + tp_raise(tp_None, "%s(x): x=%f, " \ + "out of range", __func__, x); \ + } \ + \ + return (tp_number(r)); \ + } + +/* + * template for tinypy math functions + * with two parameters. + * + * @cfunc is the coresponding function name in C + * math library. + */ +#define TP_MATH_FUNC2(cfunc) \ + static tp_obj math_##cfunc(TP) { \ + double x = TP_NUM(); \ + double y = TP_NUM(); \ + double r = 0.0; \ + \ + errno = 0; \ + r = cfunc(x, y); \ + if (errno == EDOM || errno == ERANGE) { \ + tp_raise(tp_None, "%s(x, y): x=%f,y=%f " \ + "out of range", __func__, x, y);\ + } \ + \ + return (tp_number(r)); \ + } + + +/* + * PI definition: 3.1415926535897931 + */ +static tp_obj math_pi; + +/* + * E definition: 2.7182818284590451 + */ +static tp_obj math_e; + +/* + * acos(x) + * + * return arc cosine of x, return value is measured in radians. + * if x falls out -1 to 1, raise out-of-range exception. + */ +TP_MATH_FUNC1(acos) + +/* + * asin(x) + * + * return arc sine of x, measured in radians, actually [-PI/2, PI/2] + * if x falls out of -1 to 1, raise out-of-range exception + */ +TP_MATH_FUNC1(asin) + +/* + * atan(x) + * + * return arc tangent of x, measured in radians, + */ +TP_MATH_FUNC1(atan) + +/* + * atan2(x, y) + * + * return arc tangent of x/y, measured in radians. + * unlike atan(x/y), both the signs of x and y + * are considered to determine the quaderant of + * the result. + */ +TP_MATH_FUNC2(atan2) + +/* + * ceil(x) + * + * return the ceiling of x, i.e, the smallest + * integer >= x. + */ +TP_MATH_FUNC1(ceil) + +/* + * cos(x) + * + * return cosine of x. x is measured in radians. + */ +TP_MATH_FUNC1(cos) + +/* + * cosh(x) + * + * return hyperbolic cosine of x. + */ +TP_MATH_FUNC1(cosh) + +/* + * degrees(x) + * + * converts angle x from radians to degrees. + * NOTE: this function is introduced by python, + * so we cannot wrap it directly in TP_MATH_FUNC1(), + * here the solution is defining a new + * C function - degrees(). + */ +static const double degToRad = + 3.141592653589793238462643383 / 180.0; +static double degrees(double x) +{ + return (x / degToRad); +} + +TP_MATH_FUNC1(degrees) + +/* + * exp(x) + * + * return the value e raised to power of x. + * e is the base of natural logarithms. + */ +TP_MATH_FUNC1(exp) + +/* + * fabs(x) + * + * return the absolute value of x. + */ +TP_MATH_FUNC1(fabs) + +/* + * floor(x) + * + * return the floor of x, i.e, the largest integer <= x + */ +TP_MATH_FUNC1(floor) + +/* + * fmod(x, y) + * + * return the remainder of dividing x by y. that is, + * return x - n * y, where n is the quotient of x/y. + * NOTE: this function relies on the underlying platform. + */ +TP_MATH_FUNC2(fmod) + +/* + * frexp(x) + * + * return a pair (r, y), which satisfies: + * x = r * (2 ** y), and r is normalized fraction + * which is laid between 1/2 <= abs(r) < 1. + * if x = 0, the (r, y) = (0, 0). + */ +static tp_obj math_frexp(TP) { + double x = TP_NUM(); + int y = 0; + double r = 0.0; + tp_obj rList = tp_list(tp); + + errno = 0; + r = frexp(x, &y); + if (errno == EDOM || errno == ERANGE) { + tp_raise(tp_None, "%s(x): x=%f, " + "out of range", __func__, x); + } + + _tp_list_append(tp, rList.list.val, tp_number(r)); + _tp_list_append(tp, rList.list.val, tp_number((tp_num)y)); + return (rList); +} + + +/* + * hypot(x, y) + * + * return Euclidean distance, namely, + * sqrt(x*x + y*y) + */ +TP_MATH_FUNC2(hypot) + + +/* + * ldexp(x, y) + * + * return the result of multiplying x by 2 + * raised to y. + */ +TP_MATH_FUNC2(ldexp) + +/* + * log(x, [base]) + * + * return logarithm of x to given base. If base is + * not given, return the natural logarithm of x. + * Note: common logarithm(log10) is used to compute + * the denominator and numerator. based on fomula: + * log(x, base) = log10(x) / log10(base). + */ +static tp_obj math_log(TP) { + double x = TP_NUM(); + tp_obj b = TP_DEFAULT(tp_None); + double y = 0.0; + double den = 0.0; /* denominator */ + double num = 0.0; /* numinator */ + double r = 0.0; /* result */ + + if (b.type == TP_NONE) + y = M_E; + else if (b.type == TP_NUMBER) + y = (double)b.number.val; + else + tp_raise(tp_None, "%s(x, [base]): base invalid", __func__); + + errno = 0; + num = log10(x); + if (errno == EDOM || errno == ERANGE) + goto excep; + + errno = 0; + den = log10(y); + if (errno == EDOM || errno == ERANGE) + goto excep; + + r = num / den; + + return (tp_number(r)); + +excep: + tp_raise(tp_None, "%s(x, y): x=%f,y=%f " + "out of range", __func__, x, y); +} + +/* + * log10(x) + * + * return 10-based logarithm of x. + */ +TP_MATH_FUNC1(log10) + +/* + * modf(x) + * + * return a pair (r, y). r is the integral part of + * x and y is the fractional part of x, both holds + * the same sign as x. + */ +static tp_obj math_modf(TP) { + double x = TP_NUM(); + double y = 0.0; + double r = 0.0; + tp_obj rList = tp_list(tp); + + errno = 0; + r = modf(x, &y); + if (errno == EDOM || errno == ERANGE) { + tp_raise(tp_None, "%s(x): x=%f, " + "out of range", __func__, x); + } + + _tp_list_append(tp, rList.list.val, tp_number(r)); + _tp_list_append(tp, rList.list.val, tp_number(y)); + return (rList); +} + +/* + * pow(x, y) + * + * return value of x raised to y. equivalence of x ** y. + * NOTE: conventionally, tp_pow() is the implementation + * of builtin function pow(); whilst, math_pow() is an + * alternative in math module. + */ +static tp_obj math_pow(TP) { + double x = TP_NUM(); + double y = TP_NUM(); + double r = 0.0; + + errno = 0; + r = pow(x, y); + if (errno == EDOM || errno == ERANGE) { + tp_raise(tp_None, "%s(x, y): x=%f,y=%f " + "out of range", __func__, x, y); + } + + return (tp_number(r)); +} + + +/* + * radians(x) + * + * converts angle x from degrees to radians. + * NOTE: this function is introduced by python, + * adopt same solution as degrees(x). + */ +static double radians(double x) +{ + return (x * degToRad); +} + +TP_MATH_FUNC1(radians) + +/* + * sin(x) + * + * return sine of x, x is measured in radians. + */ +TP_MATH_FUNC1(sin) + +/* + * sinh(x) + * + * return hyperbolic sine of x. + * mathematically, sinh(x) = (exp(x) - exp(-x)) / 2. + */ +TP_MATH_FUNC1(sinh) + +/* + * sqrt(x) + * + * return square root of x. + * if x is negtive, raise out-of-range exception. + */ +TP_MATH_FUNC1(sqrt) + +/* + * tan(x) + * + * return tangent of x, x is measured in radians. + */ +TP_MATH_FUNC1(tan) + +/* + * tanh(x) + * + * return hyperbolic tangent of x. + * mathematically, tanh(x) = sinh(x) / cosh(x). + */ +TP_MATH_FUNC1(tanh) + diff --git a/programs/develop/tinypy/modules/math/tests.py b/programs/develop/tinypy/modules/math/tests.py new file mode 100644 index 0000000000..e83cf603cf --- /dev/null +++ b/programs/develop/tinypy/modules/math/tests.py @@ -0,0 +1,176 @@ +### This file is grabbed from Python's Lib/test/test_math.py +###--------------------------------------------------------- +# Python test set -- math module +# XXXX Should not do tests around zero only + +eps = 0.00001 +#print('math module, testing with eps ', eps) +import math + +def testit(name, value, expected): + if abs(value-expected) > eps: + msg = name + " returned " + str(value) + " expected " + str(expected) + raise msg + +#print 'constants' +testit('pi', math.pi, 3.1415926) +testit('e', math.e, 2.7182818) + +#print 'acos' +testit('acos(-1)', math.acos(-1), math.pi) +testit('acos(0)', math.acos(0), math.pi/2) +testit('acos(1)', math.acos(1), 0) + +#print 'asin' +testit('asin(-1)', math.asin(-1), -math.pi/2) +testit('asin(0)', math.asin(0), 0) +testit('asin(1)', math.asin(1), math.pi/2) + +#print 'atan' +testit('atan(-1)', math.atan(-1), -math.pi/4) +testit('atan(0)', math.atan(0), 0) +testit('atan(1)', math.atan(1), math.pi/4) + +#print 'atan2' +testit('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2) +testit('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4) +testit('atan2(0, 1)', math.atan2(0, 1), 0) +testit('atan2(1, 1)', math.atan2(1, 1), math.pi/4) +testit('atan2(1, 0)', math.atan2(1, 0), math.pi/2) + +#print 'ceil' +testit('ceil(0.5)', math.ceil(0.5), 1) +testit('ceil(1.0)', math.ceil(1.0), 1) +testit('ceil(1.5)', math.ceil(1.5), 2) +testit('ceil(-0.5)', math.ceil(-0.5), 0) +testit('ceil(-1.0)', math.ceil(-1.0), -1) +testit('ceil(-1.5)', math.ceil(-1.5), -1) + +#print 'cos' +testit('cos(-pi/2)', math.cos(-math.pi/2), 0) +testit('cos(0)', math.cos(0), 1) +testit('cos(pi/2)', math.cos(math.pi/2), 0) +testit('cos(pi)', math.cos(math.pi), -1) + +#print 'cosh' +testit('cosh(0)', math.cosh(0), 1) +testit('cosh(2)-2*(cosh(1)**2)', math.cosh(2)-2*(math.cosh(1)**2), -1) # Thanks to Lambert + +#print 'degrees' +testit('degrees(pi)', math.degrees(math.pi), 180.0) +testit('degrees(pi/2)', math.degrees(math.pi/2), 90.0) +testit('degrees(-pi/4)', math.degrees(-math.pi/4), -45.0) + +#print 'exp' +testit('exp(-1)', math.exp(-1), 1/math.e) +testit('exp(0)', math.exp(0), 1) +testit('exp(1)', math.exp(1), math.e) + +#print 'fabs' +testit('fabs(-1)', math.fabs(-1), 1) +testit('fabs(0)', math.fabs(0), 0) +testit('fabs(1)', math.fabs(1), 1) + +#print 'floor' +testit('floor(0.5)', math.floor(0.5), 0) +testit('floor(1.0)', math.floor(1.0), 1) +testit('floor(1.5)', math.floor(1.5), 1) +testit('floor(-0.5)', math.floor(-0.5), -1) +testit('floor(-1.0)', math.floor(-1.0), -1) +testit('floor(-1.5)', math.floor(-1.5), -2) + +#print 'fmod' +testit('fmod(10,1)', math.fmod(10,1), 0) +testit('fmod(10,0.5)', math.fmod(10,0.5), 0) +testit('fmod(10,1.5)', math.fmod(10,1.5), 1) +testit('fmod(-10,1)', math.fmod(-10,1), 0) +testit('fmod(-10,0.5)', math.fmod(-10,0.5), 0) +testit('fmod(-10,1.5)', math.fmod(-10,1.5), -1) + +#print 'frexp' +def testfrexp(name, value, expected): + mant = value[0] + exp = value[1] + emant = expected[0] + eexp = expected[1] + if abs(mant-emant) > eps or exp != eexp: + raise '%s returned (%f, %f), expected (%f, %f)'%\ + (name, mant, exp, emant,eexp) + +testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1)) +testfrexp('frexp(0)', math.frexp(0), (0, 0)) +testfrexp('frexp(1)', math.frexp(1), (0.5, 1)) +testfrexp('frexp(2)', math.frexp(2), (0.5, 2)) + +#print 'hypot' +testit('hypot(0,0)', math.hypot(0,0), 0) +testit('hypot(3,4)', math.hypot(3,4), 5) + +#print 'ldexp' +testit('ldexp(0,1)', math.ldexp(0,1), 0) +testit('ldexp(1,1)', math.ldexp(1,1), 2) +testit('ldexp(1,-1)', math.ldexp(1,-1), 0.5) +testit('ldexp(-1,1)', math.ldexp(-1,1), -2) + +#print 'log' +testit('log(1/e)', math.log(1/math.e), -1) +testit('log(1)', math.log(1), 0) +testit('log(e)', math.log(math.e), 1) +testit('log(32,2)', math.log(32,2), 5) +testit('log(10**40, 10)', math.log(10**40, 10), 40) +testit('log(10**40, 10**20)', math.log(10**40, 10**20), 2) + +#print 'log10' +testit('log10(0.1)', math.log10(0.1), -1) +testit('log10(1)', math.log10(1), 0) +testit('log10(10)', math.log10(10), 1) + +#print 'modf' +def testmodf(name, value, expected): + v1 = value[0] + v2 = value[1] + e1 = expected[0] + e2 = expected[1] + if abs(v1-e1) > eps or abs(v2-e2): + raise '%s returned (%f, %f), expected (%f, %f)'%\ + (name, v1,v2, e1,e2) + +testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0)) +testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0)) + +#print 'pow' +testit('pow(0,1)', math.pow(0,1), 0) +testit('pow(1,0)', math.pow(1,0), 1) +testit('pow(2,1)', math.pow(2,1), 2) +testit('pow(2,-1)', math.pow(2,-1), 0.5) + +#print 'radians' +testit('radians(180)', math.radians(180), math.pi) +testit('radians(90)', math.radians(90), math.pi/2) +testit('radians(-45)', math.radians(-45), -math.pi/4) + +#print 'sin' +testit('sin(0)', math.sin(0), 0) +testit('sin(pi/2)', math.sin(math.pi/2), 1) +testit('sin(-pi/2)', math.sin(-math.pi/2), -1) + +#print 'sinh' +testit('sinh(0)', math.sinh(0), 0) +testit('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1) +testit('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0) + +#print 'sqrt' +testit('sqrt(0)', math.sqrt(0), 0) +testit('sqrt(1)', math.sqrt(1), 1) +testit('sqrt(4)', math.sqrt(4), 2) + +#print 'tan' +testit('tan(0)', math.tan(0), 0) +testit('tan(pi/4)', math.tan(math.pi/4), 1) +testit('tan(-pi/4)', math.tan(-math.pi/4), -1) + +#print 'tanh' +testit('tanh(0)', math.tanh(0), 0) +testit('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0) + +#print("OK: math module test pass") diff --git a/programs/develop/tinypy/modules/pygame/init.c b/programs/develop/tinypy/modules/pygame/init.c new file mode 100644 index 0000000000..6145952132 --- /dev/null +++ b/programs/develop/tinypy/modules/pygame/init.c @@ -0,0 +1,182 @@ +#include "SDL.h" + +/* utility functions */ +Uint32 pygame_list_to_color(TP,tp_obj clr,SDL_Surface *s) { + int r,g,b; + r = tp_get(tp,clr,tp_number(0)).number.val; + g = tp_get(tp,clr,tp_number(1)).number.val; + b = tp_get(tp,clr,tp_number(2)).number.val; + return SDL_MapRGB(s->format,r,g,b); +} + +/* surface */ + +#define PYGAME_TYPE_SURF 0x1001 + +void pygame_surf_free(TP,tp_obj d) { + if (d.data.magic != PYGAME_TYPE_SURF) { tp_raise(,"%s","not a surface"); } + SDL_FreeSurface((SDL_Surface*)d.data.val); +} + +SDL_Surface *pygame_obj_to_surf(TP,tp_obj self) { + tp_obj d = tp_get(tp,self,tp_string("__surf")); + if (d.data.magic != PYGAME_TYPE_SURF) { tp_raise(0,"%s","not a surface"); } + return (SDL_Surface*)d.data.val; +} + + +tp_obj pygame_surface_set_at(TP) { + tp_obj self = TP_OBJ(); + tp_obj pos = TP_TYPE(TP_LIST); + tp_obj clr = TP_TYPE(TP_LIST); + SDL_Rect r; + r.x = tp_get(tp,pos,tp_number(0)).number.val; + r.y = tp_get(tp,pos,tp_number(1)).number.val; + r.w = 1; r.h = 1; + SDL_Surface *s =pygame_obj_to_surf(tp,self); + Uint32 c = pygame_list_to_color(tp,clr,s); + SDL_FillRect(s, &r, c); + return tp_None; +} + + +tp_obj pygame_surf_to_obj(TP,SDL_Surface *s) { + tp_obj self = tp_dict(tp); + + tp_obj d = tp_data(tp,PYGAME_TYPE_SURF,s); + d.data.info->free = pygame_surf_free; + + tp_set(tp,self,tp_string("__surf"),d); + tp_set(tp,self,tp_string("set_at"),tp_method(tp,self,pygame_surface_set_at)); + return self; +} + + + + +/* display module */ + +tp_obj pygame_display_set_mode(TP) { + tp_obj sz = TP_TYPE(TP_LIST); + int w = tp_get(tp,sz,tp_number(0)).number.val; + int h = tp_get(tp,sz,tp_number(1)).number.val; + SDL_Surface *s = SDL_SetVideoMode(w, h, 0, 0); + return pygame_surf_to_obj(tp,s); +} + +tp_obj pygame_display_flip(TP) { + SDL_Flip(SDL_GetVideoSurface()); + return tp_None; +} + +SDL_Rect pygame_list_to_rect(TP,tp_obj o) { + SDL_Rect r; + r.x = tp_get(tp,o,tp_number(0)).number.val; + r.y = tp_get(tp,o,tp_number(1)).number.val; + r.w = tp_get(tp,o,tp_number(2)).number.val; + r.h = tp_get(tp,o,tp_number(3)).number.val; + return r; +} + +tp_obj pygame_display_update(TP) { + SDL_Rect r = pygame_list_to_rect(tp,TP_TYPE(TP_LIST)); + SDL_UpdateRects(SDL_GetVideoSurface(), 1, &r); + return tp_None; +} + +/* event module */ +tp_obj pygame_event_get(TP) { + SDL_Event e; + tp_obj r = tp_list(tp); + while (SDL_PollEvent(&e)) { + tp_obj d = tp_dict(tp); + tp_set(tp,d,tp_string("type"),tp_number(e.type)); + switch (e.type) { + case SDL_KEYDOWN: + case SDL_KEYUP: + tp_set(tp,d,tp_string("key"),tp_number(e.key.keysym.sym)); + tp_set(tp,d,tp_string("mod"),tp_number(e.key.keysym.mod)); + break; + case SDL_MOUSEMOTION: + tp_set(tp,d,tp_string("pos"),tp_list_n(tp,2,(tp_obj[]){tp_number(e.motion.x),tp_number(e.motion.y)})); + tp_set(tp,d,tp_string("rel"),tp_list_n(tp,2,(tp_obj[]){tp_number(e.motion.xrel),tp_number(e.motion.yrel)})); + tp_set(tp,d,tp_string("state"),tp_number(e.motion.state)); + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + tp_set(tp,d,tp_string("pos"),tp_list_n(tp,2,(tp_obj[]){tp_number(e.button.x),tp_number(e.button.y)})); + tp_set(tp,d,tp_string("button"),tp_number(e.button.button)); + break; + } + tp_set(tp,r,tp_None,d); + } + return r; +} + +/* mouse */ +tp_obj pygame_mouse_get_pos(TP) { + int x,y; + SDL_GetMouseState(&x,&y); + tp_obj r = tp_list_n(tp,2,(tp_obj[]){tp_number(x),tp_number(y)}); + return r; +} + +/* time */ +tp_obj pygame_time_get_ticks(TP) { + return tp_number(SDL_GetTicks()); +} + + +/* pygame */ +#define PYGAME_LOCALS(a,b) tp_set(tp,m,tp_string(a),tp_number(b)); + +tp_obj _pygame_init(TP) { + SDL_Init(SDL_INIT_VIDEO); + return tp_None; +} + + +void pygame_init(TP) { + tp_obj g,m; + g = tp_dict(tp); + tp_set(tp,tp->modules,tp_string("pygame"),g); + tp_set(tp,g,tp_string("init"),tp_fnc(tp,_pygame_init)); + + /* display */ + m = tp_dict(tp); tp_set(tp,g,tp_string("display"),m); + tp_set(tp,m,tp_string("set_mode"),tp_fnc(tp,pygame_display_set_mode)); + tp_set(tp,m,tp_string("flip"),tp_fnc(tp,pygame_display_flip)); + tp_set(tp,m,tp_string("update"),tp_fnc(tp,pygame_display_update)); + + /* event */ + m = tp_dict(tp); tp_set(tp,g,tp_string("event"),m); + tp_set(tp,m,tp_string("get"),tp_fnc(tp,pygame_event_get)); + + /* locals */ + m = tp_dict(tp); tp_set(tp,g,tp_string("locals"),m); + PYGAME_LOCALS("QUIT",SDL_QUIT); + PYGAME_LOCALS("KEYDOWN",SDL_KEYDOWN); + PYGAME_LOCALS("KEYUP",SDL_KEYUP); + PYGAME_LOCALS("MOUSEBUTTONDOWN",SDL_MOUSEBUTTONDOWN); + PYGAME_LOCALS("MOUSEBUTTONUP",SDL_MOUSEBUTTONUP); + PYGAME_LOCALS("MOUSEMOTION",SDL_MOUSEMOTION); + PYGAME_LOCALS("K_UP",SDLK_UP); + PYGAME_LOCALS("K_DOWN",SDLK_DOWN); + PYGAME_LOCALS("K_LEFT",SDLK_LEFT); + PYGAME_LOCALS("K_RIGHT",SDLK_RIGHT); + PYGAME_LOCALS("K_ESCAPE",SDLK_ESCAPE); + PYGAME_LOCALS("K_SPACE",SDLK_SPACE); + PYGAME_LOCALS("K_RETURN",SDLK_RETURN); + + /* mouse */ + m = tp_dict(tp); tp_set(tp,g,tp_string("mouse"),m); + tp_set(tp,m,tp_string("get_pos"),tp_fnc(tp,pygame_mouse_get_pos)); + + /* time */ + m = tp_dict(tp); tp_set(tp,g,tp_string("time"),m); + tp_set(tp,m,tp_string("get_ticks"),tp_fnc(tp,pygame_time_get_ticks)); + + +} + +/**/ diff --git a/programs/develop/tinypy/setup.py b/programs/develop/tinypy/setup.py new file mode 100644 index 0000000000..262fea93ce --- /dev/null +++ b/programs/develop/tinypy/setup.py @@ -0,0 +1,383 @@ +import os +import sys + +VARS = {} +TOPDIR = os.path.abspath(os.path.dirname(__file__)) +TEST = False +CLEAN = False +BOOT = False +CORE = ['tokenize','parse','encode','py2bc'] +MODULES = [] + +def main(): + chksize() + if len(sys.argv) < 2: + print HELP + return + + global TEST,CLEAN,BOOT + TEST = 'test' in sys.argv + CLEAN = 'clean' in sys.argv + BOOT = 'boot' in sys.argv + CLEAN = CLEAN or BOOT + TEST = TEST or BOOT + + get_libs() + build_mymain() + + cmd = sys.argv[1] + if cmd == 'linux': + vars_linux() + build_gcc() + elif cmd == 'mingw': + vars_windows() + build_gcc() + elif cmd == 'vs': + build_vs() + elif cmd == '64k': + build_64k() + elif cmd == 'blob': + build_blob() + else: + print 'invalid command' + +HELP = """ +python setup.py command [options] [modules] + +Commands: + linux - build tinypy for linux + mingw - build tinypy for mingw under windows + vs - build tinypy using Visual Studio 2005 / 2008 + + 64k - build a 64k version of the tinypy source + blob - build a single tinypy.c and tinypy.h + + build - build CPython module *** + install - install CPython module *** + +Options: + test - run tests during build + clean - rebuild all .tpc during build + boot - fully bootstrap and test tinypy + +Modules: + math - build math module + random - build random module * + pygame - build pygame module ** + marshal - build marshal module *** + jit - build jit module *** + re - build re module *** + +* coming soon!! +** proof-of-concept included +*** vaporware +""" + +def vars_linux(): + VARS['$RM'] = 'rm -f' + VARS['$VM'] = './vm' + VARS['$TINYPY'] = './tinypy' + VARS['$SYS'] = '-linux' + VARS['$FLAGS'] = '' + + VARS['$WFLAGS'] = '-std=c89 -Wall -Wc++-compat' + #-Wwrite-strings - i think this is included in -Wc++-compat + + if 'pygame' in MODULES: + VARS['$FLAGS'] += ' `sdl-config --cflags --libs` ' + +def vars_windows(): + VARS['$RM'] = 'del' + VARS['$VM'] = 'vm' + VARS['$TINYPY'] = 'tinypy' + VARS['$FLAGS'] = '-lmingw32' + VARS['$WFLAGS'] = '-Wwrite-strings -Wall' + VARS['$SYS'] = '-mingw32' + + if 'pygame' in MODULES: + VARS['$FLAGS'] += ' -Ic:\\mingw\\include\\SDL -lSDLmain -lSDL ' + +def do_cmd(cmd): + for k,v in VARS.items(): + cmd = cmd.replace(k,v) + if '$' in cmd: + print 'vars_error',cmd + sys.exit(-1) + + print cmd + r = os.system(cmd) + if r: + print 'exit_status',r + sys.exit(r) + +def do_chdir(dest): + print 'cd',dest + os.chdir(dest) + +def build_bc(opt=False): + out = [] + for mod in CORE: + out.append("""unsigned char tp_%s[] = {"""%mod) + fname = mod+".tpc" + data = open(fname,'rb').read() + cols = 16 + for n in xrange(0,len(data),cols): + out.append(",".join([str(ord(v)) for v in data[n:n+cols]])+',') + out.append("""};""") + out.append("") + f = open('bc.c','wb') + f.write('\n'.join(out)) + f.close() + +def open_tinypy(fname,*args): + return open(os.path.join(TOPDIR,'tinypy',fname),*args) + +def build_blob(): + mods = CORE[:] + do_chdir(os.path.join(TOPDIR,'tinypy')) + for mod in mods: do_cmd('python py2bc.py %s.py %s.tpc'%(mod,mod)) + do_chdir(os.path.join(TOPDIR)) + + out = [] + out.append("/*") + out.extend([v.rstrip() for v in open(os.path.join(TOPDIR,'LICENSE.txt'),'r')]) + out.append("*/") + out.append("") + + out.append("#ifndef TINYPY_H") + out.append("#define TINYPY_H") + out.extend([v.rstrip() for v in open_tinypy('tp.h','r')]) + for fname in ['list.c','dict.c','misc.c','string.c','builtins.c', + 'gc.c','ops.c','vm.c','tp.c']: + for line in open_tinypy(fname,'r'): + line = line.rstrip() + if not len(line): continue + if line[0] == '/': continue + if line[0] == ' ': continue + if line[0] == '\t': continue + if line[-1] != '{': continue + if 'enum' in line: continue + if '=' in line: continue + if '#' in line: continue + line = line.replace('{',';') + + # Do not include prototypes already defined earlier, or gcc will + # warn about doubled prototypes in user code. + if '(' in line: + line2 = line[:line.find('(') + 1] + got_already = False + for already in out: + if already.startswith(line2): + got_already = True + break + if got_already: continue + out.append(line) + out.append("#endif") + out.append('') + dest = os.path.join(TOPDIR,'build','tinypy.h') + print 'writing %s'%dest + f = open(dest,'w') + f.write('\n'.join(out)) + f.close() + + # we leave all the tinypy.h stuff at the top so that + # if someone wants to include tinypy.c they don't have to have + # tinypy.h cluttering up their folder + + for mod in CORE: + out.append("""extern unsigned char tp_%s[];"""%mod) + + for fname in ['list.c','dict.c','misc.c','string.c','builtins.c', + 'gc.c','ops.c','vm.c','tp.c','bc.c']: + for line in open_tinypy(fname,'r'): + line = line.rstrip() + if line.find('#include "') != -1: continue + out.append(line) + out.append('') + dest = os.path.join(TOPDIR,'build','tinypy.c') + print 'writing %s'%dest + f = open(dest,'w') + f.write('\n'.join(out)) + f.close() + +def py2bc(cmd,mod): + src = '%s.py'%mod + dest = '%s.tpc'%mod + if CLEAN or not os.path.exists(dest) or os.stat(src).st_mtime > os.stat(dest).st_mtime: + cmd = cmd.replace('$SRC',src) + cmd = cmd.replace('$DEST',dest) + do_cmd(cmd) + else: + print '#',dest,'is up to date' + +def build_gcc(): + mods = CORE[:] + do_chdir(os.path.join(TOPDIR,'tinypy')) + if TEST: + mods.append('tests') + do_cmd("gcc $WFLAGS -g vmmain.c $FLAGS -lm -o vm") + do_cmd('python tests.py $SYS') + for mod in mods: + py2bc('python py2bc.py $SRC $DEST',mod) + else: + for mod in mods: + py2bc('python py2bc.py $SRC $DEST -nopos',mod) + if BOOT: + do_cmd('$VM tests.tpc $SYS') + for mod in mods: py2bc('$VM py2bc.tpc $SRC $DEST',mod) + build_bc() + do_cmd("gcc $WFLAGS -g tpmain.c $FLAGS -lm -o tinypy") + #second pass - builts optimized binaries and stuff + if BOOT: + do_cmd('$TINYPY tests.py $SYS') + for mod in mods: py2bc('$TINYPY py2bc.py $SRC $DEST -nopos',mod) + build_bc(True) + if BOOT: + do_cmd("gcc $WFLAGS -O2 tpmain.c $FLAGS -lm -o tinypy") + do_cmd('$TINYPY tests.py $SYS') + print("# OK - we'll try -O3 for extra speed ...") + do_cmd("gcc $WFLAGS -O3 tpmain.c $FLAGS -lm -o tinypy") + do_cmd('$TINYPY tests.py $SYS') + do_cmd("gcc $WFLAGS -O3 mymain.c $FLAGS -lm -o ../build/tinypy") + do_chdir('..') + if TEST: + test_mods(os.path.join('.','build','tinypy')+' $TESTS') + print("# OK") + +def get_libs(): + modules = os.listdir('modules') + for m in modules[:]: + if m not in sys.argv: modules.remove(m) + global MODULES + MODULES = modules + +def build_mymain(): + src = os.path.join(TOPDIR,'tinypy','tpmain.c') + out = open(src,'r').read() + dest = os.path.join(TOPDIR,'tinypy','mymain.c') + + vs = [] + for m in MODULES: + vs.append('#include "../modules/%s/init.c"'%m) + out = out.replace('/* INCLUDE */','\n'.join(vs)) + + vs = [] + for m in MODULES: + vs.append('%s_init(tp);'%m) + out = out.replace('/* INIT */','\n'.join(vs)) + + f = open(dest,'w') + f.write(out) + f.close() + return True + +def test_mods(cmd): + for m in MODULES: + tests = os.path.join('modules',m,'tests.py') + if not os.path.exists(tests): continue + cmd = cmd.replace('$TESTS',tests) + do_cmd(cmd) + +def build_vs(): + # How to compile on windows with Visual Studio: + # Call the batch script that sets environement variables for Visual Studio and + # then run this script. + # For VS 2005 the script is: + # "C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\vsvars32.bat" + # For VS 2008: "C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat" + # Doesn't compile with vc6 (no variadic macros) + # Note: /MD option causes to dynamically link with msvcrt80.dll. This dramatically + # reduces size (for vm.exe 159k => 49k). Downside is that msvcrt80.dll must be + # present on the system (and not all windows machine have it). You can either re-distribute + # msvcrt80.dll or statically link with C runtime by changing /MD to /MT. + mods = CORE[:]; mods.append('tests') + os.chdir(os.path.join(TOPDIR,'tinypy')) + do_cmd('cl vmmain.c /D "inline=" /Od /Zi /MD /Fdvm.pdb /Fmvm.map /Fevm.exe') + do_cmd('python tests.py -win') + for mod in mods: do_cmd('python py2bc.py %s.py %s.tpc'%(mod,mod)) + do_cmd('vm.exe tests.tpc -win') + for mod in mods: do_cmd('vm.exe py2bc.tpc %s.py %s.tpc'%(mod,mod)) + build_bc() + do_cmd('cl /Od tpmain.c /D "inline=" /Zi /MD /Fdtinypy.pdb /Fmtinypy.map /Fetinypy.exe') + #second pass - builts optimized binaries and stuff + do_cmd('tinypy.exe tests.py -win') + for mod in mods: do_cmd('tinypy.exe py2bc.py %s.py %s.tpc -nopos'%(mod,mod)) + build_bc(True) + do_cmd('cl /Os vmmain.c /D "inline=__inline" /D "NDEBUG" /Gy /GL /Zi /MD /Fdvm.pdb /Fmvm.map /Fevm.exe /link /opt:ref /opt:icf') + do_cmd('cl /Os tpmain.c /D "inline=__inline" /D "NDEBUG" /Gy /GL /Zi /MD /Fdtinypy.pdb /Fmtinypy.map /Fetinypy.exe /link /opt:ref,icf /OPT:NOWIN98') + do_cmd("tinypy.exe tests.py -win") + do_cmd("dir *.exe") + +def shrink(fname): + f = open(fname,'r'); lines = f.readlines(); f.close() + out = [] + fixes = [ + 'vm','gc','params','STR', + 'int','float','return','free','delete','init', + 'abs','round','system','pow','div','raise','hash','index','printf','main'] + passing = False + for line in lines: + #quit if we've already converted + if '\t' in line: return ''.join(lines) + + #change " " into "\t" and remove blank lines + if len(line.strip()) == 0: continue + line = line.rstrip() + l1,l2 = len(line),len(line.lstrip()) + line = "\t"*((l1-l2)/4)+line.lstrip() + + #remove comments + if '.c' in fname or '.h' in fname: + #start block comment + if line.strip()[:2] == '/*': + passing = True; + #end block comment + if line.strip()[-2:] == '*/': + passing = False; + continue + #skip lines inside block comments + if passing: + continue + if '.py' in fname: + if line.strip()[:1] == '#': continue + + #remove the "namespace penalty" from tinypy ... + for name in fixes: + line = line.replace('TP_'+name,'t'+name) + line = line.replace('tp_'+name,'t'+name) + line = line.replace('TP_','') + line = line.replace('tp_','') + + out.append(line) + return '\n'.join(out)+'\n' + +def chksize(): + t1,t2 = 0,0 + for fname in [ + 'tokenize.py','parse.py','encode.py','py2bc.py', + 'tp.h','list.c','dict.c','misc.c','string.c','builtins.c', + 'gc.c','ops.c','vm.c','tp.c','tpmain.c', + ]: + fname = os.path.join(TOPDIR,'tinypy',fname) + f = open(fname,'r'); t1 += len(f.read()); f.close() + txt = shrink(fname) + t2 += len(txt) + print "#",t1,t2,t2-65536 + return t2 + +def build_64k(): + for fname in [ + 'tokenize.py','parse.py','encode.py','py2bc.py', + 'tp.h','list.c','dict.c','misc.c','string.c','builtins.c', + 'gc.c','ops.c','vm.c','tp.c','tpmain.c', + ]: + src = os.path.join(TOPDIR,'tinypy',fname) + dest = os.path.join(TOPDIR,'build',fname) + txt = shrink(src) + f = open(dest,'w') + f.write(txt) + f.close() + print '%s saved to %s'%(src,dest) + +if __name__ == '__main__': + main() diff --git a/programs/develop/tinypy/tinypy/Makefile b/programs/develop/tinypy/tinypy/Makefile new file mode 100644 index 0000000000..b7d5f48639 --- /dev/null +++ b/programs/develop/tinypy/tinypy/Makefile @@ -0,0 +1,7 @@ +export MENUETDEV=/home/john/Kolibri/kolibrios.org/libc +OUTFILE = tpmain +OBJS = tpmain.o +include $(MENUETDEV)/makefiles/Makefile_for_program +#testmod.o: fasm_modules/testmod.s +# fasm fasm_modules/testmod.s +# cp fasm_modules/testmod.o . diff --git a/programs/develop/tinypy/tinypy/bc.c b/programs/develop/tinypy/tinypy/bc.c new file mode 100644 index 0000000000..941fb4b9b2 --- /dev/null +++ b/programs/develop/tinypy/tinypy/bc.c @@ -0,0 +1,3805 @@ +unsigned char tp_tokenize[] = { +44,65,0,0,26,0,0,0,12,1,0,5,84,111,107,101, +110,0,0,0,14,1,0,0,16,1,0,43,44,11,0,0, +28,2,0,0,9,1,0,2,11,3,0,0,0,0,0,0, +0,0,0,0,11,4,0,0,0,0,0,0,0,0,0,0, +27,2,3,2,28,3,0,0,32,2,0,3,12,3,0,6, +115,121,109,98,111,108,0,0,28,4,0,0,32,3,0,4, +28,4,0,0,28,5,0,0,32,4,0,5,28,5,0,0, +28,6,0,0,32,5,0,6,15,6,2,0,15,7,3,0, +15,8,4,0,15,9,5,0,12,10,0,3,112,111,115,0, +10,1,10,6,12,6,0,4,116,121,112,101,0,0,0,0, +10,1,6,7,12,6,0,3,118,97,108,0,10,1,6,8, +12,6,0,5,105,116,101,109,115,0,0,0,10,1,6,9, +0,0,0,0,12,2,0,8,95,95,105,110,105,116,95,95, +0,0,0,0,10,0,2,1,16,2,0,26,44,7,0,0, +28,2,0,0,9,1,0,2,12,4,0,4,98,105,110,100, +0,0,0,0,13,3,4,0,12,6,0,5,84,111,107,101, +110,0,0,0,13,4,6,0,12,6,0,8,95,95,105,110, +105,116,95,95,0,0,0,0,9,4,4,6,15,5,1,0, +31,2,4,2,19,2,3,2,12,3,0,8,95,95,105,110, +105,116,95,95,0,0,0,0,10,1,3,2,0,0,0,0, +12,3,0,7,95,95,110,101,119,95,95,0,10,0,3,2, +16,3,0,22,44,5,0,0,26,1,0,0,12,4,0,5, +84,111,107,101,110,0,0,0,13,3,4,0,12,4,0,7, +95,95,110,101,119,95,95,0,9,3,3,4,15,4,1,0, +31,2,4,1,19,2,3,2,12,3,0,8,95,95,105,110, +105,116,95,95,0,0,0,0,9,2,1,3,19,4,2,0, +20,1,0,0,0,0,0,0,12,4,0,8,95,95,99,97, +108,108,95,95,0,0,0,0,10,0,4,3,16,0,0,97, +44,12,0,0,28,2,0,0,9,1,0,2,28,3,0,0, +9,2,0,3,28,4,0,0,9,3,0,4,11,6,0,0, +0,0,0,0,0,0,0,0,9,5,3,6,15,4,5,0, +11,7,0,0,0,0,0,0,0,0,240,63,9,6,3,7, +15,5,6,0,12,8,0,5,115,112,108,105,116,0,0,0, +9,7,2,8,12,8,0,1,10,0,0,0,31,6,8,1, +19,6,7,6,11,8,0,0,0,0,0,0,0,0,240,63, +2,7,4,8,9,6,6,7,15,3,6,0,12,7,0,0, +0,0,0,0,15,6,7,0,11,8,0,0,0,0,0,0, +0,0,36,64,25,7,4,8,21,7,0,0,18,0,0,6, +12,8,0,1,32,0,0,0,1,7,6,8,15,6,7,0, +18,0,0,1,11,8,0,0,0,0,0,0,0,0,89,64, +25,7,4,8,21,7,0,0,18,0,0,6,12,8,0,2, +32,32,0,0,1,7,6,8,15,6,7,0,18,0,0,1, +12,11,0,3,115,116,114,0,13,10,11,0,15,11,4,0, +31,9,11,1,19,9,10,9,1,8,6,9,12,9,0,2, +58,32,0,0,1,8,8,9,1,8,8,3,12,9,0,1, +10,0,0,0,1,8,8,9,15,7,8,0,12,9,0,5, +32,32,32,32,32,0,0,0,12,10,0,1,32,0,0,0, +3,10,10,5,1,9,9,10,12,10,0,1,94,0,0,0, +1,9,9,10,12,10,0,1,10,0,0,0,1,9,9,10, +1,8,7,9,15,7,8,0,12,8,0,7,101,114,114,111, +114,58,32,0,1,8,8,1,12,9,0,1,10,0,0,0, +1,8,8,9,1,8,8,7,37,8,0,0,0,0,0,0, +12,4,0,7,117,95,101,114,114,111,114,0,14,4,0,0, +12,4,0,8,73,83,89,77,66,79,76,83,0,0,0,0, +12,5,0,26,96,45,61,91,93,59,44,46,47,126,33,64, +36,37,94,38,42,40,41,43,123,125,58,60,62,63,0,0, +14,4,5,0,12,4,0,7,83,89,77,66,79,76,83,0, +12,6,0,3,100,101,102,0,12,7,0,5,99,108,97,115, +115,0,0,0,12,8,0,5,121,105,101,108,100,0,0,0, +12,9,0,6,114,101,116,117,114,110,0,0,12,10,0,4, +112,97,115,115,0,0,0,0,12,11,0,3,97,110,100,0, +12,12,0,2,111,114,0,0,12,13,0,3,110,111,116,0, +12,14,0,2,105,110,0,0,12,15,0,6,105,109,112,111, +114,116,0,0,12,16,0,2,105,115,0,0,12,17,0,5, +119,104,105,108,101,0,0,0,12,18,0,5,98,114,101,97, +107,0,0,0,12,19,0,3,102,111,114,0,12,20,0,8, +99,111,110,116,105,110,117,101,0,0,0,0,12,21,0,2, +105,102,0,0,12,22,0,4,101,108,115,101,0,0,0,0, +12,23,0,4,101,108,105,102,0,0,0,0,12,24,0,3, +116,114,121,0,12,25,0,6,101,120,99,101,112,116,0,0, +12,26,0,5,114,97,105,115,101,0,0,0,12,27,0,4, +84,114,117,101,0,0,0,0,12,28,0,5,70,97,108,115, +101,0,0,0,12,29,0,4,78,111,110,101,0,0,0,0, +12,30,0,6,103,108,111,98,97,108,0,0,12,31,0,3, +100,101,108,0,12,32,0,4,102,114,111,109,0,0,0,0, +12,33,0,1,45,0,0,0,12,34,0,1,43,0,0,0, +12,35,0,1,42,0,0,0,12,36,0,2,42,42,0,0, +12,37,0,1,47,0,0,0,12,38,0,1,37,0,0,0, +12,39,0,2,60,60,0,0,12,40,0,2,62,62,0,0, +12,41,0,2,45,61,0,0,12,42,0,2,43,61,0,0, +12,43,0,2,42,61,0,0,12,44,0,2,47,61,0,0, +12,45,0,1,61,0,0,0,12,46,0,2,61,61,0,0, +12,47,0,2,33,61,0,0,12,48,0,1,60,0,0,0, +12,49,0,1,62,0,0,0,12,50,0,2,60,61,0,0, +12,51,0,2,62,61,0,0,12,52,0,1,91,0,0,0, +12,53,0,1,93,0,0,0,12,54,0,1,123,0,0,0, +12,55,0,1,125,0,0,0,12,56,0,1,40,0,0,0, +12,57,0,1,41,0,0,0,12,58,0,1,46,0,0,0, +12,59,0,1,58,0,0,0,12,60,0,1,44,0,0,0, +12,61,0,1,59,0,0,0,12,62,0,1,38,0,0,0, +12,63,0,1,124,0,0,0,12,64,0,1,33,0,0,0, +27,5,6,59,14,4,5,0,12,6,0,1,91,0,0,0, +12,7,0,1,40,0,0,0,12,8,0,1,123,0,0,0, +27,5,6,3,15,4,5,0,12,7,0,1,93,0,0,0, +12,8,0,1,41,0,0,0,12,9,0,1,125,0,0,0, +27,6,7,3,15,5,6,0,12,6,0,7,66,95,66,69, +71,73,78,0,14,6,4,0,12,4,0,5,66,95,69,78, +68,0,0,0,14,4,5,0,26,4,0,0,12,5,0,5, +84,68,97,116,97,0,0,0,14,5,4,0,16,5,0,48, +44,6,0,0,28,2,0,0,9,1,0,2,11,3,0,0, +0,0,0,0,0,0,240,63,15,2,3,0,11,4,0,0, +0,0,0,0,0,0,0,0,15,3,4,0,11,5,0,0, +0,0,0,0,0,0,240,63,15,4,5,0,12,5,0,1, +121,0,0,0,10,1,5,2,12,2,0,2,121,105,0,0, +10,1,2,3,12,2,0,2,110,108,0,0,10,1,2,4, +27,3,0,0,15,2,3,0,11,5,0,0,0,0,0,0, +0,0,0,0,27,4,5,1,15,3,4,0,11,5,0,0, +0,0,0,0,0,0,0,0,15,4,5,0,12,5,0,3, +114,101,115,0,10,1,5,2,12,2,0,6,105,110,100,101, +110,116,0,0,10,1,2,3,12,2,0,6,98,114,97,99, +101,115,0,0,10,1,2,4,0,0,0,0,12,6,0,8, +95,95,105,110,105,116,95,95,0,0,0,0,10,4,6,5, +16,6,0,29,44,12,0,0,28,2,0,0,9,1,0,2, +28,3,0,0,9,2,0,3,28,4,0,0,9,3,0,4, +12,6,0,3,114,101,115,0,9,5,1,6,12,6,0,6, +97,112,112,101,110,100,0,0,9,5,5,6,12,8,0,5, +84,111,107,101,110,0,0,0,13,7,8,0,12,11,0,1, +102,0,0,0,9,8,1,11,15,9,2,0,15,10,3,0, +31,6,8,3,19,6,7,6,31,4,6,1,19,4,5,4, +0,0,0,0,12,7,0,3,97,100,100,0,10,4,7,6, +16,7,0,43,44,7,0,0,28,2,0,0,9,1,0,2, +12,4,0,4,98,105,110,100,0,0,0,0,13,3,4,0, +12,6,0,5,84,68,97,116,97,0,0,0,13,4,6,0, +12,6,0,8,95,95,105,110,105,116,95,95,0,0,0,0, +9,4,4,6,15,5,1,0,31,2,4,2,19,2,3,2, +12,3,0,8,95,95,105,110,105,116,95,95,0,0,0,0, +10,1,3,2,12,4,0,4,98,105,110,100,0,0,0,0, +13,3,4,0,12,6,0,5,84,68,97,116,97,0,0,0, +13,4,6,0,12,6,0,3,97,100,100,0,9,4,4,6, +15,5,1,0,31,2,4,2,19,2,3,2,12,3,0,3, +97,100,100,0,10,1,3,2,0,0,0,0,12,8,0,7, +95,95,110,101,119,95,95,0,10,4,8,7,16,8,0,22, +44,5,0,0,26,1,0,0,12,4,0,5,84,68,97,116, +97,0,0,0,13,3,4,0,12,4,0,7,95,95,110,101, +119,95,95,0,9,3,3,4,15,4,1,0,31,2,4,1, +19,2,3,2,12,3,0,8,95,95,105,110,105,116,95,95, +0,0,0,0,9,2,1,3,19,4,2,0,20,1,0,0, +0,0,0,0,12,9,0,8,95,95,99,97,108,108,95,95, +0,0,0,0,10,4,9,8,16,4,0,28,44,6,0,0, +28,2,0,0,9,1,0,2,12,4,0,7,114,101,112,108, +97,99,101,0,9,3,1,4,12,4,0,2,13,10,0,0, +12,5,0,1,10,0,0,0,31,2,4,2,19,2,3,2, +15,1,2,0,12,4,0,7,114,101,112,108,97,99,101,0, +9,3,1,4,12,4,0,1,13,0,0,0,12,5,0,1, +10,0,0,0,31,2,4,2,19,2,3,2,15,1,2,0, +20,1,0,0,0,0,0,0,12,9,0,5,99,108,101,97, +110,0,0,0,14,9,4,0,16,9,0,41,44,8,0,0, +28,2,0,0,9,1,0,2,12,4,0,5,99,108,101,97, +110,0,0,0,13,3,4,0,15,4,1,0,31,2,4,1, +19,2,3,2,15,1,2,0,38,0,0,11,12,4,0,11, +100,111,95,116,111,107,101,110,105,122,101,0,13,3,4,0, +15,4,1,0,31,2,4,1,19,2,3,2,20,2,0,0, +18,0,0,18,12,4,0,7,117,95,101,114,114,111,114,0, +13,3,4,0,12,4,0,8,116,111,107,101,110,105,122,101, +0,0,0,0,15,5,1,0,12,7,0,1,84,0,0,0, +13,6,7,0,12,7,0,1,102,0,0,0,9,6,6,7, +31,2,4,3,19,2,3,2,0,0,0,0,12,10,0,8, +116,111,107,101,110,105,122,101,0,0,0,0,14,10,9,0, +16,10,1,128,44,13,0,0,28,2,0,0,9,1,0,2, +12,5,0,5,84,68,97,116,97,0,0,0,13,4,5,0, +31,3,0,0,19,3,4,3,15,2,3,0,11,4,0,0, +0,0,0,0,0,0,0,0,15,3,4,0,12,7,0,3, +108,101,110,0,13,6,7,0,15,7,1,0,31,5,7,1, +19,5,6,5,15,4,5,0,12,5,0,1,84,0,0,0, +14,5,2,0,15,2,3,0,15,3,4,0,12,5,0,1, +84,0,0,0,13,4,5,0,12,8,0,1,84,0,0,0, +13,6,8,0,12,8,0,1,121,0,0,0,9,6,6,8, +12,9,0,1,84,0,0,0,13,8,9,0,12,9,0,2, +121,105,0,0,9,8,8,9,2,7,2,8,11,8,0,0, +0,0,0,0,0,0,240,63,1,7,7,8,27,5,6,2, +12,6,0,1,102,0,0,0,10,4,6,5,25,4,2,3, +21,4,0,0,18,0,1,53,9,5,1,2,15,4,5,0, +12,6,0,1,84,0,0,0,13,5,6,0,12,9,0,1, +84,0,0,0,13,7,9,0,12,9,0,1,121,0,0,0, +9,7,7,9,12,10,0,1,84,0,0,0,13,9,10,0, +12,10,0,2,121,105,0,0,9,9,9,10,2,8,2,9, +11,9,0,0,0,0,0,0,0,0,240,63,1,8,8,9, +27,6,7,2,12,7,0,1,102,0,0,0,10,5,7,6, +12,6,0,1,84,0,0,0,13,5,6,0,12,6,0,2, +110,108,0,0,9,5,5,6,21,5,0,0,18,0,0,22, +12,6,0,1,84,0,0,0,13,5,6,0,11,6,0,0, +0,0,0,0,0,0,0,0,12,7,0,2,110,108,0,0, +10,5,7,6,12,7,0,9,100,111,95,105,110,100,101,110, +116,0,0,0,13,6,7,0,15,7,1,0,15,8,2,0, +15,9,3,0,31,5,7,3,19,5,6,5,15,2,5,0, +18,0,0,253,12,6,0,1,10,0,0,0,23,5,4,6, +21,5,0,0,18,0,0,12,12,7,0,5,100,111,95,110, +108,0,0,0,13,6,7,0,15,7,1,0,15,8,2,0, +15,9,3,0,31,5,7,3,19,5,6,5,15,2,5,0, +18,0,0,237,12,6,0,8,73,83,89,77,66,79,76,83, +0,0,0,0,13,5,6,0,36,5,5,4,21,5,0,0, +18,0,0,13,12,7,0,9,100,111,95,115,121,109,98,111, +108,0,0,0,13,6,7,0,15,7,1,0,15,8,2,0, +15,9,3,0,31,5,7,3,19,5,6,5,15,2,5,0, +18,0,0,217,11,7,0,0,0,0,0,0,0,0,0,0, +12,5,0,1,48,0,0,0,24,5,5,4,23,6,5,7, +21,6,0,0,18,0,0,2,18,0,0,4,12,8,0,1, +57,0,0,0,24,5,4,8,21,5,0,0,18,0,0,13, +12,7,0,9,100,111,95,110,117,109,98,101,114,0,0,0, +13,6,7,0,15,7,1,0,15,8,2,0,15,9,3,0, +31,5,7,3,19,5,6,5,15,2,5,0,18,0,0,190, +11,7,0,0,0,0,0,0,0,0,240,63,11,9,0,0, +0,0,0,0,0,0,240,63,11,11,0,0,0,0,0,0, +0,0,0,0,12,5,0,1,97,0,0,0,24,5,5,4, +23,10,5,11,21,10,0,0,18,0,0,2,18,0,0,4, +12,12,0,1,122,0,0,0,24,5,4,12,23,8,5,9, +21,8,0,0,18,0,0,2,18,0,0,14,11,11,0,0, +0,0,0,0,0,0,0,0,12,5,0,1,65,0,0,0, +24,5,5,4,23,10,5,11,21,10,0,0,18,0,0,2, +18,0,0,4,12,12,0,1,90,0,0,0,24,5,4,12, +23,6,5,7,21,6,0,0,18,0,0,2,18,0,0,4, +12,8,0,1,95,0,0,0,23,5,4,8,21,5,0,0, +18,0,0,12,12,7,0,7,100,111,95,110,97,109,101,0, +13,6,7,0,15,7,1,0,15,8,2,0,15,9,3,0, +31,5,7,3,19,5,6,5,15,2,5,0,18,0,0,134, +11,7,0,0,0,0,0,0,0,0,240,63,12,8,0,1, +34,0,0,0,23,5,4,8,23,6,5,7,21,6,0,0, +18,0,0,2,18,0,0,4,12,8,0,1,39,0,0,0, +23,5,4,8,21,5,0,0,18,0,0,13,12,7,0,9, +100,111,95,115,116,114,105,110,103,0,0,0,13,6,7,0, +15,7,1,0,15,8,2,0,15,9,3,0,31,5,7,3, +19,5,6,5,15,2,5,0,18,0,0,107,12,6,0,1, +35,0,0,0,23,5,4,6,21,5,0,0,18,0,0,13, +12,7,0,10,100,111,95,99,111,109,109,101,110,116,0,0, +13,6,7,0,15,7,1,0,15,8,2,0,15,9,3,0, +31,5,7,3,19,5,6,5,15,2,5,0,18,0,0,90, +11,7,0,0,0,0,0,0,0,0,0,0,12,8,0,1, +92,0,0,0,23,5,4,8,23,6,5,7,21,6,0,0, +18,0,0,2,18,0,0,9,11,9,0,0,0,0,0,0, +0,0,240,63,1,8,2,9,9,5,1,8,12,8,0,1, +10,0,0,0,23,5,5,8,21,5,0,0,18,0,0,31, +11,6,0,0,0,0,0,0,0,0,0,64,1,5,2,6, +15,2,5,0,12,7,0,1,84,0,0,0,13,6,7,0, +12,7,0,1,121,0,0,0,9,6,6,7,11,7,0,0, +0,0,0,0,0,0,240,63,1,6,6,7,15,5,6,0, +15,6,2,0,12,8,0,1,84,0,0,0,13,7,8,0, +12,8,0,1,121,0,0,0,10,7,8,5,12,7,0,1, +84,0,0,0,13,5,7,0,12,7,0,2,121,105,0,0, +10,5,7,6,18,0,0,40,11,7,0,0,0,0,0,0, +0,0,240,63,12,8,0,1,32,0,0,0,23,5,4,8, +23,6,5,7,21,6,0,0,18,0,0,2,18,0,0,4, +12,8,0,1,9,0,0,0,23,5,4,8,21,5,0,0, +18,0,0,7,11,6,0,0,0,0,0,0,0,0,240,63, +1,5,2,6,15,2,5,0,18,0,0,19,12,7,0,7, +117,95,101,114,114,111,114,0,13,6,7,0,12,7,0,8, +116,111,107,101,110,105,122,101,0,0,0,0,15,8,1,0, +12,10,0,1,84,0,0,0,13,9,10,0,12,10,0,1, +102,0,0,0,9,9,9,10,31,5,7,3,19,5,6,5, +18,0,0,1,18,0,254,202,12,7,0,6,105,110,100,101, +110,116,0,0,13,6,7,0,11,7,0,0,0,0,0,0, +0,0,0,0,31,5,7,1,19,5,6,5,12,7,0,1, +84,0,0,0,13,6,7,0,12,7,0,3,114,101,115,0, +9,6,6,7,15,5,6,0,12,6,0,1,84,0,0,0, +28,7,0,0,14,6,7,0,20,5,0,0,0,0,0,0, +12,11,0,11,100,111,95,116,111,107,101,110,105,122,101,0, +14,11,10,0,16,11,0,75,44,8,0,0,28,2,0,0, +9,1,0,2,28,3,0,0,9,2,0,3,28,4,0,0, +9,3,0,4,11,4,0,0,0,0,0,0,0,0,0,0, +12,6,0,1,84,0,0,0,13,5,6,0,12,6,0,6, +98,114,97,99,101,115,0,0,9,5,5,6,23,4,4,5, +21,4,0,0,18,0,0,13,12,6,0,1,84,0,0,0, +13,5,6,0,12,6,0,3,97,100,100,0,9,5,5,6, +12,6,0,2,110,108,0,0,28,7,0,0,31,4,6,2, +19,4,5,4,18,0,0,1,11,6,0,0,0,0,0,0, +0,0,240,63,1,5,2,6,15,4,5,0,11,6,0,0, +0,0,0,0,0,0,240,63,15,5,6,0,15,2,4,0, +12,6,0,1,84,0,0,0,13,4,6,0,12,6,0,2, +110,108,0,0,10,4,6,5,12,6,0,1,84,0,0,0, +13,5,6,0,12,6,0,1,121,0,0,0,9,5,5,6, +11,6,0,0,0,0,0,0,0,0,240,63,1,5,5,6, +15,4,5,0,15,5,2,0,12,7,0,1,84,0,0,0, +13,6,7,0,12,7,0,1,121,0,0,0,10,6,7,4, +12,6,0,1,84,0,0,0,13,4,6,0,12,6,0,2, +121,105,0,0,10,4,6,5,20,2,0,0,0,0,0,0, +12,12,0,5,100,111,95,110,108,0,0,0,14,12,11,0, +16,12,0,90,44,12,0,0,28,2,0,0,9,1,0,2, +28,3,0,0,9,2,0,3,28,4,0,0,9,3,0,4, +11,5,0,0,0,0,0,0,0,0,0,0,15,4,5,0, +25,5,2,3,21,5,0,0,18,0,0,33,9,6,1,2, +15,5,6,0,11,8,0,0,0,0,0,0,0,0,0,0, +12,9,0,1,32,0,0,0,35,6,5,9,23,7,6,8, +21,7,0,0,18,0,0,2,18,0,0,4,12,9,0,1, +9,0,0,0,35,6,5,9,21,6,0,0,18,0,0,3, +18,0,0,15,18,0,0,1,11,8,0,0,0,0,0,0, +0,0,240,63,1,7,2,8,15,6,7,0,11,9,0,0, +0,0,0,0,0,0,240,63,1,8,4,9,15,7,8,0, +15,2,6,0,15,4,7,0,18,0,255,222,11,8,0,0, +0,0,0,0,0,0,0,0,11,10,0,0,0,0,0,0, +0,0,0,0,12,11,0,1,10,0,0,0,35,6,5,11, +23,9,6,10,21,9,0,0,18,0,0,2,18,0,0,4, +12,11,0,1,35,0,0,0,35,6,5,11,23,7,6,8, +21,7,0,0,18,0,0,2,18,0,0,12,11,6,0,0, +0,0,0,0,0,0,0,0,12,10,0,1,84,0,0,0, +13,9,10,0,12,10,0,6,98,114,97,99,101,115,0,0, +9,9,9,10,23,6,6,9,21,6,0,0,18,0,0,9, +12,8,0,6,105,110,100,101,110,116,0,0,13,7,8,0, +15,8,4,0,31,6,8,1,19,6,7,6,18,0,0,1, +20,2,0,0,0,0,0,0,12,13,0,9,100,111,95,105, +110,100,101,110,116,0,0,0,14,13,12,0,16,13,0,137, +44,8,0,0,28,2,0,0,9,1,0,2,12,4,0,1, +84,0,0,0,13,3,4,0,12,4,0,6,105,110,100,101, +110,116,0,0,9,3,3,4,11,4,0,0,0,0,0,0, +0,0,240,191,9,3,3,4,23,2,1,3,21,2,0,0, +18,0,0,3,17,0,0,0,18,0,0,117,12,3,0,1, +84,0,0,0,13,2,3,0,12,3,0,6,105,110,100,101, +110,116,0,0,9,2,2,3,11,3,0,0,0,0,0,0, +0,0,240,191,9,2,2,3,25,2,2,1,21,2,0,0, +18,0,0,28,12,4,0,1,84,0,0,0,13,3,4,0, +12,4,0,6,105,110,100,101,110,116,0,0,9,3,3,4, +12,4,0,6,97,112,112,101,110,100,0,0,9,3,3,4, +15,4,1,0,31,2,4,1,19,2,3,2,12,4,0,1, +84,0,0,0,13,3,4,0,12,4,0,3,97,100,100,0, +9,3,3,4,12,4,0,6,105,110,100,101,110,116,0,0, +15,5,1,0,31,2,4,2,19,2,3,2,18,0,0,76, +12,4,0,1,84,0,0,0,13,3,4,0,12,4,0,6, +105,110,100,101,110,116,0,0,9,3,3,4,11,4,0,0, +0,0,0,0,0,0,240,191,9,3,3,4,25,2,1,3, +21,2,0,0,18,0,0,62,12,5,0,1,84,0,0,0, +13,4,5,0,12,5,0,6,105,110,100,101,110,116,0,0, +9,4,4,5,12,5,0,5,105,110,100,101,120,0,0,0, +9,4,4,5,15,5,1,0,31,3,5,1,19,3,4,3, +15,2,3,0,11,4,0,0,0,0,0,0,0,0,240,63, +1,3,2,4,12,6,0,3,108,101,110,0,13,5,6,0, +12,7,0,1,84,0,0,0,13,6,7,0,12,7,0,6, +105,110,100,101,110,116,0,0,9,6,6,7,31,4,6,1, +19,4,5,4,25,3,3,4,21,3,0,0,18,0,0,27, +12,5,0,1,84,0,0,0,13,4,5,0,12,5,0,6, +105,110,100,101,110,116,0,0,9,4,4,5,12,5,0,3, +112,111,112,0,9,4,4,5,31,3,0,0,19,3,4,3, +15,1,3,0,12,5,0,1,84,0,0,0,13,4,5,0, +12,5,0,3,97,100,100,0,9,4,4,5,12,5,0,6, +100,101,100,101,110,116,0,0,15,6,1,0,31,3,5,2, +19,3,4,3,18,0,255,212,18,0,0,1,0,0,0,0, +12,14,0,6,105,110,100,101,110,116,0,0,14,14,13,0, +16,14,0,161,44,13,0,0,28,2,0,0,9,1,0,2, +28,3,0,0,9,2,0,3,28,4,0,0,9,3,0,4, +27,5,0,0,15,4,5,0,9,6,1,2,15,5,6,0, +15,6,2,0,11,9,0,0,0,0,0,0,0,0,240,63, +1,8,2,9,15,7,8,0,15,8,5,0,15,5,6,0, +15,2,7,0,12,7,0,7,83,89,77,66,79,76,83,0, +13,6,7,0,36,6,6,8,21,6,0,0,18,0,0,9, +12,9,0,6,97,112,112,101,110,100,0,0,9,7,4,9, +15,9,8,0,31,6,9,1,19,6,7,6,18,0,0,1, +25,6,2,3,21,6,0,0,18,0,0,42,9,7,1,2, +15,6,7,0,11,7,0,0,0,0,0,0,0,0,0,0, +12,10,0,8,73,83,89,77,66,79,76,83,0,0,0,0, +13,9,10,0,36,9,9,6,23,7,7,9,21,7,0,0, +18,0,0,3,18,0,0,27,18,0,0,1,1,9,8,6, +15,7,9,0,11,11,0,0,0,0,0,0,0,0,240,63, +1,10,2,11,15,9,10,0,15,8,7,0,15,2,9,0, +12,9,0,7,83,89,77,66,79,76,83,0,13,7,9,0, +36,7,7,8,21,7,0,0,18,0,0,9,12,10,0,6, +97,112,112,101,110,100,0,0,9,9,4,10,15,10,8,0, +31,7,10,1,19,7,9,7,18,0,0,1,18,0,255,213, +12,10,0,3,112,111,112,0,9,9,4,10,31,7,0,0, +19,7,9,7,15,8,7,0,12,11,0,3,108,101,110,0, +13,10,11,0,15,11,8,0,31,9,11,1,19,9,10,9, +15,7,9,0,1,9,5,7,15,2,9,0,12,11,0,1, +84,0,0,0,13,10,11,0,12,11,0,3,97,100,100,0, +9,10,10,11,12,11,0,6,115,121,109,98,111,108,0,0, +15,12,8,0,31,9,11,2,19,9,10,9,12,10,0,7, +66,95,66,69,71,73,78,0,13,9,10,0,36,9,9,8, +21,9,0,0,18,0,0,20,12,10,0,1,84,0,0,0, +13,9,10,0,12,11,0,1,84,0,0,0,13,10,11,0, +12,11,0,6,98,114,97,99,101,115,0,0,9,10,10,11, +11,11,0,0,0,0,0,0,0,0,240,63,1,10,10,11, +12,11,0,6,98,114,97,99,101,115,0,0,10,9,11,10, +18,0,0,1,12,10,0,5,66,95,69,78,68,0,0,0, +13,9,10,0,36,9,9,8,21,9,0,0,18,0,0,20, +12,10,0,1,84,0,0,0,13,9,10,0,12,11,0,1, +84,0,0,0,13,10,11,0,12,11,0,6,98,114,97,99, +101,115,0,0,9,10,10,11,11,11,0,0,0,0,0,0, +0,0,240,63,2,10,10,11,12,11,0,6,98,114,97,99, +101,115,0,0,10,9,11,10,18,0,0,1,20,2,0,0, +0,0,0,0,12,15,0,9,100,111,95,115,121,109,98,111, +108,0,0,0,14,15,14,0,16,15,0,143,44,14,0,0, +28,2,0,0,9,1,0,2,28,3,0,0,9,2,0,3, +28,4,0,0,9,3,0,4,9,5,1,2,15,4,5,0, +11,7,0,0,0,0,0,0,0,0,240,63,1,6,2,7, +15,5,6,0,9,7,1,2,15,6,7,0,15,7,4,0, +15,2,5,0,15,4,6,0,25,5,2,3,21,5,0,0, +18,0,0,60,9,5,1,2,15,4,5,0,11,8,0,0, +0,0,0,0,0,0,0,0,11,10,0,0,0,0,0,0, +0,0,0,0,11,12,0,0,0,0,0,0,0,0,240,63, +12,13,0,1,48,0,0,0,25,5,4,13,23,11,5,12, +21,11,0,0,18,0,0,2,18,0,0,4,12,5,0,1, +57,0,0,0,25,5,5,4,23,9,5,10,21,9,0,0, +18,0,0,2,18,0,0,14,11,12,0,0,0,0,0,0, +0,0,240,63,12,13,0,1,97,0,0,0,25,5,4,13, +23,11,5,12,21,11,0,0,18,0,0,2,18,0,0,4, +12,5,0,1,102,0,0,0,25,5,5,4,23,6,5,8, +21,6,0,0,18,0,0,2,18,0,0,4,12,9,0,1, +120,0,0,0,35,5,4,9,21,5,0,0,18,0,0,3, +18,0,0,12,18,0,0,1,1,6,7,4,15,5,6,0, +11,9,0,0,0,0,0,0,0,0,240,63,1,8,2,9, +15,6,8,0,15,7,5,0,15,2,6,0,18,0,255,195, +12,6,0,1,46,0,0,0,23,5,4,6,21,5,0,0, +18,0,0,43,1,6,7,4,15,5,6,0,11,9,0,0, +0,0,0,0,0,0,240,63,1,8,2,9,15,6,8,0, +15,7,5,0,15,2,6,0,25,5,2,3,21,5,0,0, +18,0,0,30,9,5,1,2,15,4,5,0,11,8,0,0, +0,0,0,0,0,0,240,63,12,9,0,1,48,0,0,0, +25,5,4,9,23,6,5,8,21,6,0,0,18,0,0,2, +18,0,0,4,12,5,0,1,57,0,0,0,25,5,5,4, +21,5,0,0,18,0,0,3,18,0,0,12,18,0,0,1, +1,6,7,4,15,5,6,0,11,9,0,0,0,0,0,0, +0,0,240,63,1,8,2,9,15,6,8,0,15,7,5,0, +15,2,6,0,18,0,255,225,18,0,0,1,12,8,0,1, +84,0,0,0,13,6,8,0,12,8,0,3,97,100,100,0, +9,6,6,8,12,8,0,6,110,117,109,98,101,114,0,0, +15,9,7,0,31,5,8,2,19,5,6,5,20,2,0,0, +0,0,0,0,12,16,0,9,100,111,95,110,117,109,98,101, +114,0,0,0,14,16,15,0,16,16,0,134,44,16,0,0, +28,2,0,0,9,1,0,2,28,3,0,0,9,2,0,3, +28,4,0,0,9,3,0,4,9,5,1,2,15,4,5,0, +11,7,0,0,0,0,0,0,0,0,240,63,1,6,2,7, +15,5,6,0,15,6,4,0,15,2,5,0,25,4,2,3, +21,4,0,0,18,0,0,80,9,5,1,2,15,4,5,0, +11,8,0,0,0,0,0,0,0,0,0,0,11,10,0,0, +0,0,0,0,0,0,0,0,11,12,0,0,0,0,0,0, +0,0,0,0,11,14,0,0,0,0,0,0,0,0,240,63, +12,15,0,1,97,0,0,0,25,5,4,15,23,13,5,14, +21,13,0,0,18,0,0,2,18,0,0,4,12,5,0,1, +122,0,0,0,25,5,5,4,23,11,5,12,21,11,0,0, +18,0,0,2,18,0,0,14,11,14,0,0,0,0,0,0, +0,0,240,63,12,15,0,1,65,0,0,0,25,5,4,15, +23,13,5,14,21,13,0,0,18,0,0,2,18,0,0,4, +12,5,0,1,90,0,0,0,25,5,5,4,23,9,5,10, +21,9,0,0,18,0,0,2,18,0,0,14,11,12,0,0, +0,0,0,0,0,0,240,63,12,13,0,1,48,0,0,0, +25,5,4,13,23,11,5,12,21,11,0,0,18,0,0,2, +18,0,0,4,12,5,0,1,57,0,0,0,25,5,5,4, +23,7,5,8,21,7,0,0,18,0,0,2,18,0,0,4, +12,9,0,1,95,0,0,0,35,5,4,9,21,5,0,0, +18,0,0,3,18,0,0,12,18,0,0,1,1,7,6,4, +15,5,7,0,11,9,0,0,0,0,0,0,0,0,240,63, +1,8,2,9,15,7,8,0,15,6,5,0,15,2,7,0, +18,0,255,175,12,7,0,7,83,89,77,66,79,76,83,0, +13,5,7,0,36,5,5,6,21,5,0,0,18,0,0,14, +12,8,0,1,84,0,0,0,13,7,8,0,12,8,0,3, +97,100,100,0,9,7,7,8,12,8,0,6,115,121,109,98, +111,108,0,0,15,9,6,0,31,5,8,2,19,5,7,5, +18,0,0,14,12,8,0,1,84,0,0,0,13,7,8,0, +12,8,0,3,97,100,100,0,9,7,7,8,12,8,0,4, +110,97,109,101,0,0,0,0,15,9,6,0,31,5,8,2, +19,5,7,5,18,0,0,1,20,2,0,0,0,0,0,0, +12,17,0,7,100,111,95,110,97,109,101,0,14,17,16,0, +16,17,1,3,44,14,0,0,28,2,0,0,9,1,0,2, +28,3,0,0,9,2,0,3,28,4,0,0,9,3,0,4, +12,5,0,0,0,0,0,0,15,4,5,0,9,6,1,2, +15,5,6,0,11,8,0,0,0,0,0,0,0,0,240,63, +1,7,2,8,15,6,7,0,15,7,4,0,15,4,5,0, +15,2,6,0,11,8,0,0,0,0,0,0,0,0,0,0, +11,10,0,0,0,0,0,0,0,0,0,0,11,5,0,0, +0,0,0,0,0,0,20,64,2,11,3,2,24,5,5,11, +23,9,5,10,21,9,0,0,18,0,0,2,18,0,0,3, +9,5,1,2,23,5,5,4,23,6,5,8,21,6,0,0, +18,0,0,2,18,0,0,7,11,10,0,0,0,0,0,0, +0,0,240,63,1,9,2,10,9,5,1,9,23,5,5,4, +21,5,0,0,18,0,0,105,11,6,0,0,0,0,0,0, +0,0,0,64,1,5,2,6,15,2,5,0,11,8,0,0, +0,0,0,0,0,0,0,64,2,6,3,8,25,5,2,6, +21,5,0,0,18,0,0,92,9,6,1,2,15,5,6,0, +11,9,0,0,0,0,0,0,0,0,0,0,11,11,0,0, +0,0,0,0,0,0,0,0,23,6,5,4,23,10,6,11, +21,10,0,0,18,0,0,2,18,0,0,7,11,13,0,0, +0,0,0,0,0,0,240,63,1,12,2,13,9,6,1,12, +23,6,6,4,23,8,6,9,21,8,0,0,18,0,0,2, +18,0,0,7,11,11,0,0,0,0,0,0,0,0,0,64, +1,10,2,11,9,6,1,10,23,6,6,4,21,6,0,0, +18,0,0,20,11,8,0,0,0,0,0,0,0,0,8,64, +1,6,2,8,15,2,6,0,12,9,0,1,84,0,0,0, +13,8,9,0,12,9,0,3,97,100,100,0,9,8,8,9, +12,9,0,6,115,116,114,105,110,103,0,0,15,10,7,0, +31,6,9,2,19,6,8,6,18,0,0,43,18,0,0,41, +1,8,7,5,15,6,8,0,11,10,0,0,0,0,0,0, +0,0,240,63,1,9,2,10,15,8,9,0,15,7,6,0, +15,2,8,0,12,8,0,1,10,0,0,0,23,6,5,8, +21,6,0,0,18,0,0,26,12,9,0,1,84,0,0,0, +13,8,9,0,12,9,0,1,121,0,0,0,9,8,8,9, +11,9,0,0,0,0,0,0,0,0,240,63,1,8,8,9, +15,6,8,0,15,8,2,0,12,10,0,1,84,0,0,0, +13,9,10,0,12,10,0,1,121,0,0,0,10,9,10,6, +12,9,0,1,84,0,0,0,13,6,9,0,12,9,0,2, +121,105,0,0,10,6,9,8,18,0,0,1,18,0,0,1, +18,0,255,159,18,0,0,104,25,6,2,3,21,6,0,0, +18,0,0,100,9,6,1,2,15,5,6,0,12,8,0,1, +92,0,0,0,23,6,5,8,21,6,0,0,18,0,0,60, +11,8,0,0,0,0,0,0,0,0,240,63,1,6,2,8, +15,2,6,0,9,6,1,2,15,5,6,0,12,8,0,1, +110,0,0,0,23,6,5,8,21,6,0,0,18,0,0,5, +12,6,0,1,10,0,0,0,15,5,6,0,18,0,0,1, +12,8,0,1,114,0,0,0,23,6,5,8,21,6,0,0, +18,0,0,11,12,9,0,3,99,104,114,0,13,8,9,0, +11,9,0,0,0,0,0,0,0,0,42,64,31,6,9,1, +19,6,8,6,15,5,6,0,18,0,0,1,12,8,0,1, +116,0,0,0,23,6,5,8,21,6,0,0,18,0,0,5, +12,6,0,1,9,0,0,0,15,5,6,0,18,0,0,1, +12,8,0,1,48,0,0,0,23,6,5,8,21,6,0,0, +18,0,0,5,12,6,0,1,0,0,0,0,15,5,6,0, +18,0,0,1,1,8,7,5,15,6,8,0,11,10,0,0, +0,0,0,0,0,0,240,63,1,9,2,10,15,8,9,0, +15,7,6,0,15,2,8,0,18,0,0,33,23,6,5,4, +21,6,0,0,18,0,0,20,11,8,0,0,0,0,0,0, +0,0,240,63,1,6,2,8,15,2,6,0,12,9,0,1, +84,0,0,0,13,8,9,0,12,9,0,3,97,100,100,0, +9,8,8,9,12,9,0,6,115,116,114,105,110,103,0,0, +15,10,7,0,31,6,9,2,19,6,8,6,18,0,0,13, +18,0,0,11,1,8,7,5,15,6,8,0,11,10,0,0, +0,0,0,0,0,0,240,63,1,9,2,10,15,8,9,0, +15,7,6,0,15,2,8,0,18,0,0,1,18,0,255,155, +18,0,0,1,20,2,0,0,0,0,0,0,12,18,0,9, +100,111,95,115,116,114,105,110,103,0,0,0,14,18,17,0, +16,18,0,33,44,7,0,0,28,2,0,0,9,1,0,2, +28,3,0,0,9,2,0,3,28,4,0,0,9,3,0,4, +11,5,0,0,0,0,0,0,0,0,240,63,1,4,2,5, +15,2,4,0,25,4,2,3,21,4,0,0,18,0,0,16, +9,5,1,2,15,4,5,0,12,6,0,1,10,0,0,0, +23,5,4,6,21,5,0,0,18,0,0,3,18,0,0,8, +18,0,0,1,11,6,0,0,0,0,0,0,0,0,240,63, +1,5,2,6,15,2,5,0,18,0,255,239,20,2,0,0, +0,0,0,0,12,19,0,10,100,111,95,99,111,109,109,101, +110,116,0,0,14,19,18,0,0,0,0,0, +}; +unsigned char tp_parse[] = { +44,114,0,0,12,2,0,6,105,109,112,111,114,116,0,0, +13,1,2,0,12,2,0,8,116,111,107,101,110,105,122,101, +0,0,0,0,31,0,2,1,19,0,1,0,12,1,0,8, +116,111,107,101,110,105,122,101,0,0,0,0,14,1,0,0, +12,2,0,6,105,109,112,111,114,116,0,0,13,1,2,0, +12,2,0,8,116,111,107,101,110,105,122,101,0,0,0,0, +31,0,2,1,19,0,1,0,12,2,0,8,95,95,100,105, +99,116,95,95,0,0,0,0,13,1,2,0,12,3,0,5, +84,111,107,101,110,0,0,0,9,2,0,3,12,0,0,5, +84,111,107,101,110,0,0,0,10,1,0,2,12,2,0,3, +115,116,114,0,13,1,2,0,11,2,0,0,0,0,0,0, +0,0,240,63,31,0,2,1,19,0,1,0,12,1,0,1, +46,0,0,0,36,0,0,1,21,0,0,0,18,0,0,23, +12,2,0,6,105,109,112,111,114,116,0,0,13,1,2,0, +12,2,0,4,98,111,111,116,0,0,0,0,31,0,2,1, +19,0,1,0,12,3,0,5,109,101,114,103,101,0,0,0, +13,2,3,0,12,5,0,8,95,95,100,105,99,116,95,95, +0,0,0,0,13,3,5,0,15,4,0,0,31,1,3,2, +19,1,2,1,18,0,0,1,16,0,0,63,44,8,0,0, +28,2,0,0,9,1,0,2,12,3,0,1,42,0,0,0, +9,2,0,3,11,4,0,0,0,0,0,0,0,0,0,0, +9,3,2,4,28,4,0,0,23,3,3,4,21,3,0,0, +18,0,0,6,11,3,0,0,0,0,0,0,0,0,240,63, +20,3,0,0,18,0,0,1,12,5,0,4,116,121,112,101, +0,0,0,0,9,4,1,5,36,3,2,4,21,3,0,0, +18,0,0,6,11,3,0,0,0,0,0,0,0,0,240,63, +20,3,0,0,18,0,0,1,11,5,0,0,0,0,0,0, +0,0,0,0,12,6,0,4,116,121,112,101,0,0,0,0, +9,3,1,6,12,6,0,6,115,121,109,98,111,108,0,0, +23,3,3,6,23,4,3,5,21,4,0,0,18,0,0,2, +18,0,0,5,12,7,0,3,118,97,108,0,9,6,1,7, +36,3,2,6,21,3,0,0,18,0,0,6,11,3,0,0, +0,0,0,0,0,0,240,63,20,3,0,0,18,0,0,1, +11,3,0,0,0,0,0,0,0,0,0,0,20,3,0,0, +0,0,0,0,12,1,0,5,99,104,101,99,107,0,0,0, +14,1,0,0,16,1,0,58,44,10,0,0,28,2,0,0, +9,1,0,2,28,3,0,0,9,2,0,3,12,5,0,1, +80,0,0,0,13,4,5,0,12,5,0,5,115,116,97,99, +107,0,0,0,9,4,4,5,12,5,0,6,97,112,112,101, +110,100,0,0,9,4,4,5,15,6,1,0,12,8,0,4, +100,109,97,112,0,0,0,0,13,7,8,0,9,7,7,1, +27,5,6,2,31,3,5,1,19,3,4,3,21,2,0,0, +18,0,0,12,12,4,0,4,100,109,97,112,0,0,0,0, +13,3,4,0,12,5,0,4,111,109,97,112,0,0,0,0, +13,4,5,0,9,4,4,1,10,3,1,4,18,0,0,19, +12,4,0,4,100,109,97,112,0,0,0,0,13,3,4,0, +12,5,0,3,108,98,112,0,11,6,0,0,0,0,0,0, +0,0,0,0,12,7,0,3,110,117,100,0,12,9,0,6, +105,116,115,101,108,102,0,0,13,8,9,0,26,4,5,4, +10,3,1,4,18,0,0,1,0,0,0,0,12,2,0,5, +116,119,101,97,107,0,0,0,14,2,1,0,16,2,0,30, +44,6,0,0,12,3,0,1,80,0,0,0,13,2,3,0, +12,3,0,5,115,116,97,99,107,0,0,0,9,2,2,3, +12,3,0,3,112,111,112,0,9,2,2,3,31,1,0,0, +19,1,2,1,11,4,0,0,0,0,0,0,0,0,0,0, +9,3,1,4,15,2,3,0,11,5,0,0,0,0,0,0, +0,0,240,63,9,4,1,5,15,3,4,0,12,4,0,4, +100,109,97,112,0,0,0,0,13,1,4,0,10,1,2,3, +0,0,0,0,12,3,0,7,114,101,115,116,111,114,101,0, +14,3,2,0,16,3,0,16,44,6,0,0,28,2,0,0, +9,1,0,2,26,3,0,0,15,2,3,0,11,4,0,0, +0,0,0,0,0,0,0,0,42,3,1,4,18,0,0,4, +9,5,1,3,10,2,3,5,18,0,255,252,20,2,0,0, +0,0,0,0,12,4,0,3,99,112,121,0,14,4,3,0, +26,4,0,0,12,5,0,5,80,68,97,116,97,0,0,0, +14,5,4,0,16,5,0,32,44,6,0,0,28,2,0,0, +9,1,0,2,28,3,0,0,9,2,0,3,28,4,0,0, +9,3,0,4,12,4,0,1,115,0,0,0,10,1,4,2, +12,4,0,6,116,111,107,101,110,115,0,0,10,1,4,3, +11,4,0,0,0,0,0,0,0,0,0,0,12,5,0,3, +112,111,115,0,10,1,5,4,28,4,0,0,12,5,0,5, +116,111,107,101,110,0,0,0,10,1,5,4,27,4,0,0, +12,5,0,5,115,116,97,99,107,0,0,0,10,1,5,4, +0,0,0,0,12,6,0,8,95,95,105,110,105,116,95,95, +0,0,0,0,10,4,6,5,16,6,0,39,44,7,0,0, +28,2,0,0,9,1,0,2,12,2,0,4,111,109,97,112, +0,0,0,0,12,5,0,3,99,112,121,0,13,4,5,0, +12,6,0,9,98,97,115,101,95,100,109,97,112,0,0,0, +13,5,6,0,31,3,5,1,19,3,4,3,14,2,3,0, +12,2,0,4,100,109,97,112,0,0,0,0,12,5,0,3, +99,112,121,0,13,4,5,0,12,6,0,9,98,97,115,101, +95,100,109,97,112,0,0,0,13,5,6,0,31,3,5,1, +19,3,4,3,14,2,3,0,12,4,0,7,97,100,118,97, +110,99,101,0,9,3,1,4,31,2,0,0,19,2,3,2, +0,0,0,0,12,7,0,4,105,110,105,116,0,0,0,0, +10,4,7,6,16,7,0,106,44,11,0,0,28,2,0,0, +9,1,0,2,28,2,0,0,28,3,0,0,32,2,0,3, +11,3,0,0,0,0,0,0,0,0,0,0,12,6,0,5, +99,104,101,99,107,0,0,0,13,5,6,0,12,8,0,5, +116,111,107,101,110,0,0,0,9,6,1,8,15,7,2,0, +31,4,6,2,19,4,5,4,23,3,3,4,21,3,0,0, +18,0,0,17,12,5,0,5,101,114,114,111,114,0,0,0, +13,4,5,0,12,5,0,9,101,120,112,101,99,116,101,100, +32,0,0,0,1,5,5,2,12,7,0,5,116,111,107,101, +110,0,0,0,9,6,1,7,31,3,5,2,19,3,4,3, +18,0,0,1,12,4,0,3,112,111,115,0,9,3,1,4, +12,6,0,3,108,101,110,0,13,5,6,0,12,7,0,6, +116,111,107,101,110,115,0,0,9,6,1,7,31,4,6,1, +19,4,5,4,25,3,3,4,21,3,0,0,18,0,0,21, +12,5,0,6,116,111,107,101,110,115,0,0,9,4,1,5, +12,6,0,3,112,111,115,0,9,5,1,6,9,4,4,5, +15,3,4,0,12,5,0,3,112,111,115,0,9,4,1,5, +11,5,0,0,0,0,0,0,0,0,240,63,1,4,4,5, +12,5,0,3,112,111,115,0,10,1,5,4,18,0,0,20, +12,6,0,5,84,111,107,101,110,0,0,0,13,5,6,0, +11,9,0,0,0,0,0,0,0,0,0,0,11,10,0,0, +0,0,0,0,0,0,0,0,27,6,9,2,12,7,0,3, +101,111,102,0,12,8,0,3,101,111,102,0,31,4,6,3, +19,4,5,4,15,3,4,0,18,0,0,1,12,6,0,2, +100,111,0,0,13,5,6,0,15,6,3,0,31,4,6,1, +19,4,5,4,12,5,0,5,116,111,107,101,110,0,0,0, +10,1,5,4,20,3,0,0,0,0,0,0,12,8,0,7, +97,100,118,97,110,99,101,0,10,4,8,7,16,8,0,64, +44,7,0,0,28,2,0,0,9,1,0,2,12,4,0,4, +98,105,110,100,0,0,0,0,13,3,4,0,12,6,0,5, +80,68,97,116,97,0,0,0,13,4,6,0,12,6,0,8, +95,95,105,110,105,116,95,95,0,0,0,0,9,4,4,6, +15,5,1,0,31,2,4,2,19,2,3,2,12,3,0,8, +95,95,105,110,105,116,95,95,0,0,0,0,10,1,3,2, +12,4,0,4,98,105,110,100,0,0,0,0,13,3,4,0, +12,6,0,5,80,68,97,116,97,0,0,0,13,4,6,0, +12,6,0,4,105,110,105,116,0,0,0,0,9,4,4,6, +15,5,1,0,31,2,4,2,19,2,3,2,12,3,0,4, +105,110,105,116,0,0,0,0,10,1,3,2,12,4,0,4, +98,105,110,100,0,0,0,0,13,3,4,0,12,6,0,5, +80,68,97,116,97,0,0,0,13,4,6,0,12,6,0,7, +97,100,118,97,110,99,101,0,9,4,4,6,15,5,1,0, +31,2,4,2,19,2,3,2,12,3,0,7,97,100,118,97, +110,99,101,0,10,1,3,2,0,0,0,0,12,9,0,7, +95,95,110,101,119,95,95,0,10,4,9,8,16,9,0,22, +44,5,0,0,26,1,0,0,12,4,0,5,80,68,97,116, +97,0,0,0,13,3,4,0,12,4,0,7,95,95,110,101, +119,95,95,0,9,3,3,4,15,4,1,0,31,2,4,1, +19,2,3,2,12,3,0,8,95,95,105,110,105,116,95,95, +0,0,0,0,9,2,1,3,19,4,2,0,20,1,0,0, +0,0,0,0,12,10,0,8,95,95,99,97,108,108,95,95, +0,0,0,0,10,4,10,9,16,4,0,32,44,9,0,0, +28,2,0,0,9,1,0,2,28,3,0,0,9,2,0,3, +12,4,0,5,112,114,105,110,116,0,0,0,13,3,4,0, +12,5,0,8,116,111,107,101,110,105,122,101,0,0,0,0, +13,4,5,0,12,5,0,7,117,95,101,114,114,111,114,0, +9,4,4,5,15,5,1,0,12,8,0,1,80,0,0,0, +13,6,8,0,12,8,0,1,115,0,0,0,9,6,6,8, +12,8,0,3,112,111,115,0,9,7,2,8,31,3,5,3, +19,3,4,3,0,0,0,0,12,10,0,5,101,114,114,111, +114,0,0,0,14,10,4,0,16,10,0,12,44,5,0,0, +28,2,0,0,9,1,0,2,12,4,0,3,110,117,100,0, +9,3,1,4,15,4,1,0,31,2,4,1,19,2,3,2, +20,2,0,0,0,0,0,0,12,11,0,3,110,117,100,0, +14,11,10,0,16,11,0,15,44,7,0,0,28,2,0,0, +9,1,0,2,28,3,0,0,9,2,0,3,12,5,0,3, +108,101,100,0,9,4,1,5,15,5,1,0,15,6,2,0, +31,3,5,2,19,3,4,3,20,3,0,0,0,0,0,0, +12,12,0,3,108,101,100,0,14,12,11,0,16,12,0,9, +44,4,0,0,28,2,0,0,9,1,0,2,12,3,0,3, +108,98,112,0,9,2,1,3,20,2,0,0,0,0,0,0, +12,13,0,7,103,101,116,95,108,98,112,0,14,13,12,0, +16,13,0,10,44,4,0,0,28,2,0,0,9,1,0,2, +12,3,0,5,105,116,101,109,115,0,0,0,9,2,1,3, +20,2,0,0,0,0,0,0,12,14,0,9,103,101,116,95, +105,116,101,109,115,0,0,0,14,14,13,0,16,14,0,66, +44,9,0,0,28,2,0,0,9,1,0,2,12,4,0,1, +80,0,0,0,13,3,4,0,12,4,0,5,116,111,107,101, +110,0,0,0,9,3,3,4,15,2,3,0,12,5,0,7, +97,100,118,97,110,99,101,0,13,4,5,0,31,3,0,0, +19,3,4,3,12,6,0,3,110,117,100,0,13,5,6,0, +15,6,2,0,31,4,6,1,19,4,5,4,15,3,4,0, +12,7,0,7,103,101,116,95,108,98,112,0,13,6,7,0, +12,8,0,1,80,0,0,0,13,7,8,0,12,8,0,5, +116,111,107,101,110,0,0,0,9,7,7,8,31,5,7,1, +19,5,6,5,25,4,1,5,21,4,0,0,18,0,0,24, +12,5,0,1,80,0,0,0,13,4,5,0,12,5,0,5, +116,111,107,101,110,0,0,0,9,4,4,5,15,2,4,0, +12,6,0,7,97,100,118,97,110,99,101,0,13,5,6,0, +31,4,0,0,19,4,5,4,12,6,0,3,108,101,100,0, +13,5,6,0,15,6,2,0,15,7,3,0,31,4,6,2, +19,4,5,4,15,3,4,0,18,0,255,218,20,3,0,0, +0,0,0,0,12,15,0,10,101,120,112,114,101,115,115,105, +111,110,0,0,14,15,14,0,16,15,0,24,44,9,0,0, +28,2,0,0,9,1,0,2,28,3,0,0,9,2,0,3, +15,4,2,0,12,7,0,10,101,120,112,114,101,115,115,105, +111,110,0,0,13,6,7,0,12,8,0,2,98,112,0,0, +9,7,1,8,31,5,7,1,19,5,6,5,27,3,4,2, +12,4,0,5,105,116,101,109,115,0,0,0,10,1,4,3, +20,1,0,0,0,0,0,0,12,16,0,9,105,110,102,105, +120,95,108,101,100,0,0,0,14,16,15,0,16,16,0,56, +44,9,0,0,28,2,0,0,9,1,0,2,28,3,0,0, +9,2,0,3,12,5,0,5,99,104,101,99,107,0,0,0, +13,4,5,0,12,7,0,1,80,0,0,0,13,5,7,0, +12,7,0,5,116,111,107,101,110,0,0,0,9,5,5,7, +12,6,0,3,110,111,116,0,31,3,5,2,19,3,4,3, +21,3,0,0,18,0,0,16,12,3,0,5,105,115,110,111, +116,0,0,0,12,4,0,3,118,97,108,0,10,1,4,3, +12,5,0,7,97,100,118,97,110,99,101,0,13,4,5,0, +12,5,0,3,110,111,116,0,31,3,5,1,19,3,4,3, +18,0,0,1,15,4,2,0,12,7,0,10,101,120,112,114, +101,115,115,105,111,110,0,0,13,6,7,0,12,8,0,2, +98,112,0,0,9,7,1,8,31,5,7,1,19,5,6,5, +27,3,4,2,12,4,0,5,105,116,101,109,115,0,0,0, +10,1,4,3,20,1,0,0,0,0,0,0,12,17,0,8, +105,110,102,105,120,95,105,115,0,0,0,0,14,17,16,0, +16,17,0,38,44,9,0,0,28,2,0,0,9,1,0,2, +28,3,0,0,9,2,0,3,12,5,0,7,97,100,118,97, +110,99,101,0,13,4,5,0,12,5,0,2,105,110,0,0, +31,3,5,1,19,3,4,3,12,3,0,5,110,111,116,105, +110,0,0,0,12,4,0,3,118,97,108,0,10,1,4,3, +15,4,2,0,12,7,0,10,101,120,112,114,101,115,115,105, +111,110,0,0,13,6,7,0,12,8,0,2,98,112,0,0, +9,7,1,8,31,5,7,1,19,5,6,5,27,3,4,2, +12,4,0,5,105,116,101,109,115,0,0,0,10,1,4,3, +20,1,0,0,0,0,0,0,12,18,0,9,105,110,102,105, +120,95,110,111,116,0,0,0,14,18,17,0,16,18,0,54, +44,8,0,0,28,2,0,0,9,1,0,2,28,3,0,0, +9,2,0,3,12,6,0,10,101,120,112,114,101,115,115,105, +111,110,0,0,13,5,6,0,12,7,0,2,98,112,0,0, +9,6,1,7,31,4,6,1,19,4,5,4,15,3,4,0, +12,5,0,3,118,97,108,0,9,4,2,5,12,5,0,1, +44,0,0,0,23,4,4,5,21,4,0,0,18,0,0,14, +12,6,0,5,105,116,101,109,115,0,0,0,9,5,2,6, +12,6,0,6,97,112,112,101,110,100,0,0,9,5,5,6, +15,6,3,0,31,4,6,1,19,4,5,4,20,2,0,0, +18,0,0,1,15,5,2,0,15,6,3,0,27,4,5,2, +12,5,0,5,105,116,101,109,115,0,0,0,10,1,5,4, +12,4,0,5,116,117,112,108,101,0,0,0,12,5,0,4, +116,121,112,101,0,0,0,0,10,1,5,4,20,1,0,0, +0,0,0,0,12,19,0,11,105,110,102,105,120,95,116,117, +112,108,101,0,14,19,18,0,16,19,0,43,44,8,0,0, +28,2,0,0,9,1,0,2,28,3,0,0,23,2,1,3, +21,2,0,0,18,0,0,4,27,2,0,0,20,2,0,0, +18,0,0,1,12,4,0,5,99,104,101,99,107,0,0,0, +13,3,4,0,15,4,1,0,12,5,0,1,44,0,0,0, +12,6,0,5,116,117,112,108,101,0,0,0,12,7,0,10, +115,116,97,116,101,109,101,110,116,115,0,0,31,2,4,4, +19,2,3,2,21,2,0,0,18,0,0,11,12,4,0,9, +103,101,116,95,105,116,101,109,115,0,0,0,13,3,4,0, +15,4,1,0,31,2,4,1,19,2,3,2,20,2,0,0, +18,0,0,1,15,3,1,0,27,2,3,1,20,2,0,0, +0,0,0,0,12,20,0,3,108,115,116,0,14,20,19,0, +16,20,0,25,44,11,0,0,28,2,0,0,9,1,0,2, +28,3,0,0,9,2,0,3,12,5,0,5,84,111,107,101, +110,0,0,0,13,4,5,0,12,9,0,3,112,111,115,0, +9,5,2,9,15,6,1,0,15,7,1,0,12,10,0,3, +108,115,116,0,13,9,10,0,15,10,2,0,31,8,10,1, +19,8,9,8,31,3,5,4,19,3,4,3,20,3,0,0, +0,0,0,0,12,21,0,4,105,108,115,116,0,0,0,0, +14,21,20,0,16,21,0,116,44,11,0,0,28,2,0,0, +9,1,0,2,28,3,0,0,9,2,0,3,12,6,0,5, +84,111,107,101,110,0,0,0,13,5,6,0,12,10,0,3, +112,111,115,0,9,6,1,10,12,7,0,4,99,97,108,108, +0,0,0,0,12,8,0,1,36,0,0,0,15,10,2,0, +27,9,10,1,31,4,6,4,19,4,5,4,15,3,4,0, +11,4,0,0,0,0,0,0,0,0,0,0,12,7,0,5, +99,104,101,99,107,0,0,0,13,6,7,0,12,9,0,1, +80,0,0,0,13,7,9,0,12,9,0,5,116,111,107,101, +110,0,0,0,9,7,7,9,12,8,0,1,41,0,0,0, +31,5,7,2,19,5,6,5,23,4,4,5,21,4,0,0, +18,0,0,63,12,6,0,5,116,119,101,97,107,0,0,0, +13,5,6,0,12,6,0,1,44,0,0,0,11,7,0,0, +0,0,0,0,0,0,0,0,31,4,6,2,19,4,5,4, +12,6,0,5,105,116,101,109,115,0,0,0,9,5,3,6, +12,6,0,6,97,112,112,101,110,100,0,0,9,5,5,6, +12,8,0,10,101,120,112,114,101,115,115,105,111,110,0,0, +13,7,8,0,11,8,0,0,0,0,0,0,0,0,0,0, +31,6,8,1,19,6,7,6,31,4,6,1,19,4,5,4, +12,5,0,1,80,0,0,0,13,4,5,0,12,5,0,5, +116,111,107,101,110,0,0,0,9,4,4,5,12,5,0,3, +118,97,108,0,9,4,4,5,12,5,0,1,44,0,0,0, +23,4,4,5,21,4,0,0,18,0,0,10,12,6,0,7, +97,100,118,97,110,99,101,0,13,5,6,0,12,6,0,1, +44,0,0,0,31,4,6,1,19,4,5,4,18,0,0,1, +12,6,0,7,114,101,115,116,111,114,101,0,13,5,6,0, +31,4,0,0,19,4,5,4,18,0,255,174,12,6,0,7, +97,100,118,97,110,99,101,0,13,5,6,0,12,6,0,1, +41,0,0,0,31,4,6,1,19,4,5,4,20,3,0,0, +0,0,0,0,12,22,0,8,99,97,108,108,95,108,101,100, +0,0,0,0,14,22,21,0,16,22,0,229,44,17,0,0, +28,2,0,0,9,1,0,2,28,3,0,0,9,2,0,3, +12,6,0,5,84,111,107,101,110,0,0,0,13,5,6,0, +12,10,0,3,112,111,115,0,9,6,1,10,12,7,0,3, +103,101,116,0,12,8,0,1,46,0,0,0,15,10,2,0, +27,9,10,1,31,4,6,4,19,4,5,4,15,3,4,0, +15,6,2,0,27,5,6,1,15,4,5,0,11,6,0,0, +0,0,0,0,0,0,0,0,15,5,6,0,11,6,0,0, +0,0,0,0,0,0,0,0,12,9,0,5,99,104,101,99, +107,0,0,0,13,8,9,0,12,11,0,1,80,0,0,0, +13,9,11,0,12,11,0,5,116,111,107,101,110,0,0,0, +9,9,9,11,12,10,0,1,93,0,0,0,31,7,9,2, +19,7,8,7,23,6,6,7,21,6,0,0,18,0,0,99, +11,6,0,0,0,0,0,0,0,0,0,0,15,5,6,0, +12,8,0,5,99,104,101,99,107,0,0,0,13,7,8,0, +12,10,0,1,80,0,0,0,13,8,10,0,12,10,0,5, +116,111,107,101,110,0,0,0,9,8,8,10,12,9,0,1, +58,0,0,0,31,6,8,2,19,6,7,6,21,6,0,0, +18,0,0,30,12,8,0,6,97,112,112,101,110,100,0,0, +9,7,4,8,12,10,0,5,84,111,107,101,110,0,0,0, +13,9,10,0,12,13,0,1,80,0,0,0,13,10,13,0, +12,13,0,5,116,111,107,101,110,0,0,0,9,10,10,13, +12,13,0,3,112,111,115,0,9,10,10,13,12,11,0,6, +115,121,109,98,111,108,0,0,12,12,0,4,78,111,110,101, +0,0,0,0,31,8,10,3,19,8,9,8,31,6,8,1, +19,6,7,6,18,0,0,18,12,8,0,6,97,112,112,101, +110,100,0,0,9,7,4,8,12,10,0,10,101,120,112,114, +101,115,115,105,111,110,0,0,13,9,10,0,11,10,0,0, +0,0,0,0,0,0,0,0,31,8,10,1,19,8,9,8, +31,6,8,1,19,6,7,6,18,0,0,1,12,8,0,5, +99,104,101,99,107,0,0,0,13,7,8,0,12,10,0,1, +80,0,0,0,13,8,10,0,12,10,0,5,116,111,107,101, +110,0,0,0,9,8,8,10,12,9,0,1,58,0,0,0, +31,6,8,2,19,6,7,6,21,6,0,0,18,0,0,14, +12,8,0,7,97,100,118,97,110,99,101,0,13,7,8,0, +12,8,0,1,58,0,0,0,31,6,8,1,19,6,7,6, +11,6,0,0,0,0,0,0,0,0,240,63,15,5,6,0, +18,0,0,1,18,0,255,138,21,5,0,0,18,0,0,30, +12,8,0,6,97,112,112,101,110,100,0,0,9,7,4,8, +12,10,0,5,84,111,107,101,110,0,0,0,13,9,10,0, +12,13,0,1,80,0,0,0,13,10,13,0,12,13,0,5, +116,111,107,101,110,0,0,0,9,10,10,13,12,13,0,3, +112,111,115,0,9,10,10,13,12,11,0,6,115,121,109,98, +111,108,0,0,12,12,0,4,78,111,110,101,0,0,0,0, +31,8,10,3,19,8,9,8,31,6,8,1,19,6,7,6, +18,0,0,1,11,6,0,0,0,0,0,0,0,0,0,64, +12,9,0,3,108,101,110,0,13,8,9,0,15,9,4,0, +31,7,9,1,19,7,8,7,25,6,6,7,21,6,0,0, +18,0,0,25,15,7,2,0,12,10,0,5,84,111,107,101, +110,0,0,0,13,9,10,0,12,14,0,3,112,111,115,0, +9,10,1,14,12,11,0,5,115,108,105,99,101,0,0,0, +12,12,0,1,58,0,0,0,11,15,0,0,0,0,0,0, +0,0,240,63,28,16,0,0,27,14,15,2,9,13,4,14, +31,8,10,4,19,8,9,8,27,6,7,2,15,4,6,0, +18,0,0,1,12,6,0,5,105,116,101,109,115,0,0,0, +10,3,6,4,12,8,0,7,97,100,118,97,110,99,101,0, +13,7,8,0,12,8,0,1,93,0,0,0,31,6,8,1, +19,6,7,6,20,3,0,0,0,0,0,0,12,23,0,7, +103,101,116,95,108,101,100,0,14,23,22,0,16,23,0,33, +44,8,0,0,28,2,0,0,9,1,0,2,28,3,0,0, +9,2,0,3,12,6,0,10,101,120,112,114,101,115,115,105, +111,110,0,0,13,5,6,0,12,7,0,2,98,112,0,0, +9,6,1,7,31,4,6,1,19,4,5,4,15,3,4,0, +12,4,0,6,115,116,114,105,110,103,0,0,12,5,0,4, +116,121,112,101,0,0,0,0,10,3,5,4,15,5,2,0, +15,6,3,0,27,4,5,2,12,5,0,5,105,116,101,109, +115,0,0,0,10,1,5,4,20,1,0,0,0,0,0,0, +12,24,0,7,100,111,116,95,108,101,100,0,14,24,23,0, +16,24,0,6,44,3,0,0,28,2,0,0,9,1,0,2, +20,1,0,0,0,0,0,0,12,25,0,6,105,116,115,101, +108,102,0,0,14,25,24,0,16,25,0,42,44,6,0,0, +28,2,0,0,9,1,0,2,12,4,0,5,116,119,101,97, +107,0,0,0,13,3,4,0,12,4,0,1,44,0,0,0, +11,5,0,0,0,0,0,0,0,0,240,63,31,2,4,2, +19,2,3,2,12,5,0,10,101,120,112,114,101,115,115,105, +111,110,0,0,13,4,5,0,11,5,0,0,0,0,0,0, +0,0,0,0,31,3,5,1,19,3,4,3,15,2,3,0, +12,5,0,7,114,101,115,116,111,114,101,0,13,4,5,0, +31,3,0,0,19,3,4,3,12,5,0,7,97,100,118,97, +110,99,101,0,13,4,5,0,12,5,0,1,41,0,0,0, +31,3,5,1,19,3,4,3,20,2,0,0,0,0,0,0, +12,26,0,9,112,97,114,101,110,95,110,117,100,0,0,0, +14,26,25,0,16,26,0,224,44,10,0,0,28,2,0,0, +9,1,0,2,12,2,0,4,108,105,115,116,0,0,0,0, +12,3,0,4,116,121,112,101,0,0,0,0,10,1,3,2, +12,2,0,2,91,93,0,0,12,3,0,3,118,97,108,0, +10,1,3,2,27,2,0,0,12,3,0,5,105,116,101,109, +115,0,0,0,10,1,3,2,12,4,0,1,80,0,0,0, +13,3,4,0,12,4,0,5,116,111,107,101,110,0,0,0, +9,3,3,4,15,2,3,0,12,5,0,5,116,119,101,97, +107,0,0,0,13,4,5,0,12,5,0,1,44,0,0,0, +11,6,0,0,0,0,0,0,0,0,0,0,31,3,5,2, +19,3,4,3,11,3,0,0,0,0,0,0,0,0,0,0, +12,6,0,5,99,104,101,99,107,0,0,0,13,5,6,0, +12,9,0,1,80,0,0,0,13,6,9,0,12,9,0,5, +116,111,107,101,110,0,0,0,9,6,6,9,12,7,0,3, +102,111,114,0,12,8,0,1,93,0,0,0,31,4,6,3, +19,4,5,4,23,3,3,4,21,3,0,0,18,0,0,48, +12,6,0,10,101,120,112,114,101,115,115,105,111,110,0,0, +13,5,6,0,11,6,0,0,0,0,0,0,0,0,0,0, +31,4,6,1,19,4,5,4,15,3,4,0,12,6,0,5, +105,116,101,109,115,0,0,0,9,5,1,6,12,6,0,6, +97,112,112,101,110,100,0,0,9,5,5,6,15,6,3,0, +31,4,6,1,19,4,5,4,12,5,0,1,80,0,0,0, +13,4,5,0,12,5,0,5,116,111,107,101,110,0,0,0, +9,4,4,5,12,5,0,3,118,97,108,0,9,4,4,5, +12,5,0,1,44,0,0,0,23,4,4,5,21,4,0,0, +18,0,0,10,12,6,0,7,97,100,118,97,110,99,101,0, +13,5,6,0,12,6,0,1,44,0,0,0,31,4,6,1, +19,4,5,4,18,0,0,1,18,0,255,187,12,6,0,5, +99,104,101,99,107,0,0,0,13,5,6,0,12,8,0,1, +80,0,0,0,13,6,8,0,12,8,0,5,116,111,107,101, +110,0,0,0,9,6,6,8,12,7,0,3,102,111,114,0, +31,4,6,2,19,4,5,4,21,4,0,0,18,0,0,82, +12,4,0,4,99,111,109,112,0,0,0,0,12,5,0,4, +116,121,112,101,0,0,0,0,10,1,5,4,12,6,0,7, +97,100,118,97,110,99,101,0,13,5,6,0,12,6,0,3, +102,111,114,0,31,4,6,1,19,4,5,4,12,6,0,5, +116,119,101,97,107,0,0,0,13,5,6,0,12,6,0,2, +105,110,0,0,11,7,0,0,0,0,0,0,0,0,0,0, +31,4,6,2,19,4,5,4,12,6,0,5,105,116,101,109, +115,0,0,0,9,5,1,6,12,6,0,6,97,112,112,101, +110,100,0,0,9,5,5,6,12,8,0,10,101,120,112,114, +101,115,115,105,111,110,0,0,13,7,8,0,11,8,0,0, +0,0,0,0,0,0,0,0,31,6,8,1,19,6,7,6, +31,4,6,1,19,4,5,4,12,6,0,7,97,100,118,97, +110,99,101,0,13,5,6,0,12,6,0,2,105,110,0,0, +31,4,6,1,19,4,5,4,12,6,0,5,105,116,101,109, +115,0,0,0,9,5,1,6,12,6,0,6,97,112,112,101, +110,100,0,0,9,5,5,6,12,8,0,10,101,120,112,114, +101,115,115,105,111,110,0,0,13,7,8,0,11,8,0,0, +0,0,0,0,0,0,0,0,31,6,8,1,19,6,7,6, +31,4,6,1,19,4,5,4,12,6,0,7,114,101,115,116, +111,114,101,0,13,5,6,0,31,4,0,0,19,4,5,4, +18,0,0,1,12,6,0,7,114,101,115,116,111,114,101,0, +13,5,6,0,31,4,0,0,19,4,5,4,12,6,0,7, +97,100,118,97,110,99,101,0,13,5,6,0,12,6,0,1, +93,0,0,0,31,4,6,1,19,4,5,4,20,1,0,0, +0,0,0,0,12,27,0,8,108,105,115,116,95,110,117,100, +0,0,0,0,14,27,26,0,16,27,0,116,44,8,0,0, +28,2,0,0,9,1,0,2,12,2,0,4,100,105,99,116, +0,0,0,0,12,3,0,4,116,121,112,101,0,0,0,0, +10,1,3,2,12,2,0,2,123,125,0,0,12,3,0,3, +118,97,108,0,10,1,3,2,27,2,0,0,12,3,0,5, +105,116,101,109,115,0,0,0,10,1,3,2,12,4,0,5, +116,119,101,97,107,0,0,0,13,3,4,0,12,4,0,1, +44,0,0,0,11,5,0,0,0,0,0,0,0,0,0,0, +31,2,4,2,19,2,3,2,11,2,0,0,0,0,0,0, +0,0,0,0,12,5,0,5,99,104,101,99,107,0,0,0, +13,4,5,0,12,7,0,1,80,0,0,0,13,5,7,0, +12,7,0,5,116,111,107,101,110,0,0,0,9,5,5,7, +12,6,0,1,125,0,0,0,31,3,5,2,19,3,4,3, +23,2,2,3,21,2,0,0,18,0,0,48,12,4,0,5, +105,116,101,109,115,0,0,0,9,3,1,4,12,4,0,6, +97,112,112,101,110,100,0,0,9,3,3,4,12,6,0,10, +101,120,112,114,101,115,115,105,111,110,0,0,13,5,6,0, +11,6,0,0,0,0,0,0,0,0,0,0,31,4,6,1, +19,4,5,4,31,2,4,1,19,2,3,2,12,4,0,5, +99,104,101,99,107,0,0,0,13,3,4,0,12,7,0,1, +80,0,0,0,13,4,7,0,12,7,0,5,116,111,107,101, +110,0,0,0,9,4,4,7,12,5,0,1,58,0,0,0, +12,6,0,1,44,0,0,0,31,2,4,3,19,2,3,2, +21,2,0,0,18,0,0,8,12,4,0,7,97,100,118,97, +110,99,101,0,13,3,4,0,31,2,0,0,19,2,3,2, +18,0,0,1,18,0,255,189,12,4,0,7,114,101,115,116, +111,114,101,0,13,3,4,0,31,2,0,0,19,2,3,2, +12,4,0,7,97,100,118,97,110,99,101,0,13,3,4,0, +12,4,0,1,125,0,0,0,31,2,4,1,19,2,3,2, +20,1,0,0,0,0,0,0,12,28,0,8,100,105,99,116, +95,110,117,100,0,0,0,0,14,28,27,0,16,28,0,17, +44,5,0,0,28,1,0,0,28,2,0,0,32,1,0,2, +12,4,0,1,80,0,0,0,13,3,4,0,12,4,0,7, +97,100,118,97,110,99,101,0,9,3,3,4,15,4,1,0, +31,2,4,1,19,2,3,2,20,2,0,0,0,0,0,0, +12,29,0,7,97,100,118,97,110,99,101,0,14,29,28,0, +16,29,1,2,44,10,0,0,27,2,0,0,15,1,2,0, +12,4,0,1,80,0,0,0,13,3,4,0,12,4,0,5, +116,111,107,101,110,0,0,0,9,3,3,4,15,2,3,0, +12,5,0,5,99,104,101,99,107,0,0,0,13,4,5,0, +12,7,0,1,80,0,0,0,13,5,7,0,12,7,0,5, +116,111,107,101,110,0,0,0,9,5,5,7,12,6,0,2, +110,108,0,0,31,3,5,2,19,3,4,3,21,3,0,0, +18,0,0,8,12,5,0,7,97,100,118,97,110,99,101,0, +13,4,5,0,31,3,0,0,19,3,4,3,18,0,255,233, +12,5,0,5,99,104,101,99,107,0,0,0,13,4,5,0, +12,7,0,1,80,0,0,0,13,5,7,0,12,7,0,5, +116,111,107,101,110,0,0,0,9,5,5,7,12,6,0,6, +105,110,100,101,110,116,0,0,31,3,5,2,19,3,4,3, +21,3,0,0,18,0,0,85,12,5,0,7,97,100,118,97, +110,99,101,0,13,4,5,0,12,5,0,6,105,110,100,101, +110,116,0,0,31,3,5,1,19,3,4,3,11,3,0,0, +0,0,0,0,0,0,0,0,12,6,0,5,99,104,101,99, +107,0,0,0,13,5,6,0,12,8,0,1,80,0,0,0, +13,6,8,0,12,8,0,5,116,111,107,101,110,0,0,0, +9,6,6,8,12,7,0,6,100,101,100,101,110,116,0,0, +31,4,6,2,19,4,5,4,23,3,3,4,21,3,0,0, +18,0,0,44,12,5,0,6,97,112,112,101,110,100,0,0, +9,4,1,5,12,7,0,10,101,120,112,114,101,115,115,105, +111,110,0,0,13,6,7,0,11,7,0,0,0,0,0,0, +0,0,0,0,31,5,7,1,19,5,6,5,31,3,5,1, +19,3,4,3,12,5,0,5,99,104,101,99,107,0,0,0, +13,4,5,0,12,8,0,1,80,0,0,0,13,5,8,0, +12,8,0,5,116,111,107,101,110,0,0,0,9,5,5,8, +12,6,0,1,59,0,0,0,12,7,0,2,110,108,0,0, +31,3,5,3,19,3,4,3,21,3,0,0,18,0,0,8, +12,5,0,7,97,100,118,97,110,99,101,0,13,4,5,0, +31,3,0,0,19,3,4,3,18,0,255,231,18,0,255,192, +12,5,0,7,97,100,118,97,110,99,101,0,13,4,5,0, +12,5,0,6,100,101,100,101,110,116,0,0,31,3,5,1, +19,3,4,3,18,0,0,60,12,5,0,6,97,112,112,101, +110,100,0,0,9,4,1,5,12,7,0,10,101,120,112,114, +101,115,115,105,111,110,0,0,13,6,7,0,11,7,0,0, +0,0,0,0,0,0,0,0,31,5,7,1,19,5,6,5, +31,3,5,1,19,3,4,3,12,5,0,5,99,104,101,99, +107,0,0,0,13,4,5,0,12,7,0,1,80,0,0,0, +13,5,7,0,12,7,0,5,116,111,107,101,110,0,0,0, +9,5,5,7,12,6,0,1,59,0,0,0,31,3,5,2, +19,3,4,3,21,3,0,0,18,0,0,26,12,5,0,7, +97,100,118,97,110,99,101,0,13,4,5,0,12,5,0,1, +59,0,0,0,31,3,5,1,19,3,4,3,12,5,0,6, +97,112,112,101,110,100,0,0,9,4,1,5,12,7,0,10, +101,120,112,114,101,115,115,105,111,110,0,0,13,6,7,0, +11,7,0,0,0,0,0,0,0,0,0,0,31,5,7,1, +19,5,6,5,31,3,5,1,19,3,4,3,18,0,255,215, +18,0,0,1,12,5,0,5,99,104,101,99,107,0,0,0, +13,4,5,0,12,7,0,1,80,0,0,0,13,5,7,0, +12,7,0,5,116,111,107,101,110,0,0,0,9,5,5,7, +12,6,0,2,110,108,0,0,31,3,5,2,19,3,4,3, +21,3,0,0,18,0,0,8,12,5,0,7,97,100,118,97, +110,99,101,0,13,4,5,0,31,3,0,0,19,3,4,3, +18,0,255,233,11,3,0,0,0,0,0,0,0,0,240,63, +12,6,0,3,108,101,110,0,13,5,6,0,15,6,1,0, +31,4,6,1,19,4,5,4,25,3,3,4,21,3,0,0, +18,0,0,19,12,5,0,5,84,111,107,101,110,0,0,0, +13,4,5,0,12,9,0,3,112,111,115,0,9,5,2,9, +12,6,0,10,115,116,97,116,101,109,101,110,116,115,0,0, +12,7,0,1,59,0,0,0,15,8,1,0,31,3,5,4, +19,3,4,3,20,3,0,0,18,0,0,1,12,5,0,3, +112,111,112,0,9,4,1,5,31,3,0,0,19,3,4,3, +20,3,0,0,0,0,0,0,12,30,0,5,98,108,111,99, +107,0,0,0,14,30,29,0,16,30,0,175,44,11,0,0, +28,2,0,0,9,1,0,2,27,3,0,0,12,4,0,5, +105,116,101,109,115,0,0,0,10,1,4,3,15,2,3,0, +12,5,0,6,97,112,112,101,110,100,0,0,9,4,2,5, +12,6,0,1,80,0,0,0,13,5,6,0,12,6,0,5, +116,111,107,101,110,0,0,0,9,5,5,6,31,3,5,1, +19,3,4,3,12,5,0,7,97,100,118,97,110,99,101,0, +13,4,5,0,31,3,0,0,19,3,4,3,12,5,0,7, +97,100,118,97,110,99,101,0,13,4,5,0,12,5,0,1, +40,0,0,0,31,3,5,1,19,3,4,3,12,6,0,5, +84,111,107,101,110,0,0,0,13,5,6,0,12,10,0,3, +112,111,115,0,9,6,1,10,12,7,0,6,115,121,109,98, +111,108,0,0,12,8,0,3,40,41,58,0,27,9,0,0, +31,4,6,4,19,4,5,4,15,3,4,0,12,6,0,6, +97,112,112,101,110,100,0,0,9,5,2,6,15,6,3,0, +31,4,6,1,19,4,5,4,11,4,0,0,0,0,0,0, +0,0,0,0,12,7,0,5,99,104,101,99,107,0,0,0, +13,6,7,0,12,9,0,1,80,0,0,0,13,7,9,0, +12,9,0,5,116,111,107,101,110,0,0,0,9,7,7,9, +12,8,0,1,41,0,0,0,31,5,7,2,19,5,6,5, +23,4,4,5,21,4,0,0,18,0,0,65,12,6,0,5, +116,119,101,97,107,0,0,0,13,5,6,0,12,6,0,1, +44,0,0,0,11,7,0,0,0,0,0,0,0,0,0,0, +31,4,6,2,19,4,5,4,12,6,0,5,105,116,101,109, +115,0,0,0,9,5,3,6,12,6,0,6,97,112,112,101, +110,100,0,0,9,5,5,6,12,8,0,10,101,120,112,114, +101,115,115,105,111,110,0,0,13,7,8,0,11,8,0,0, +0,0,0,0,0,0,0,0,31,6,8,1,19,6,7,6, +31,4,6,1,19,4,5,4,12,6,0,5,99,104,101,99, +107,0,0,0,13,5,6,0,12,8,0,1,80,0,0,0, +13,6,8,0,12,8,0,5,116,111,107,101,110,0,0,0, +9,6,6,8,12,7,0,1,44,0,0,0,31,4,6,2, +19,4,5,4,21,4,0,0,18,0,0,10,12,6,0,7, +97,100,118,97,110,99,101,0,13,5,6,0,12,6,0,1, +44,0,0,0,31,4,6,1,19,4,5,4,18,0,0,1, +12,6,0,7,114,101,115,116,111,114,101,0,13,5,6,0, +31,4,0,0,19,4,5,4,18,0,255,172,12,6,0,7, +97,100,118,97,110,99,101,0,13,5,6,0,12,6,0,1, +41,0,0,0,31,4,6,1,19,4,5,4,12,6,0,7, +97,100,118,97,110,99,101,0,13,5,6,0,12,6,0,1, +58,0,0,0,31,4,6,1,19,4,5,4,12,6,0,6, +97,112,112,101,110,100,0,0,9,5,2,6,12,8,0,5, +98,108,111,99,107,0,0,0,13,7,8,0,31,6,0,0, +19,6,7,6,31,4,6,1,19,4,5,4,20,1,0,0, +0,0,0,0,12,31,0,7,100,101,102,95,110,117,100,0, +14,31,30,0,16,31,0,48,44,8,0,0,28,2,0,0, +9,1,0,2,27,3,0,0,12,4,0,5,105,116,101,109, +115,0,0,0,10,1,4,3,15,2,3,0,12,5,0,6, +97,112,112,101,110,100,0,0,9,4,2,5,12,7,0,10, +101,120,112,114,101,115,115,105,111,110,0,0,13,6,7,0, +11,7,0,0,0,0,0,0,0,0,0,0,31,5,7,1, +19,5,6,5,31,3,5,1,19,3,4,3,12,5,0,7, +97,100,118,97,110,99,101,0,13,4,5,0,12,5,0,1, +58,0,0,0,31,3,5,1,19,3,4,3,12,5,0,6, +97,112,112,101,110,100,0,0,9,4,2,5,12,7,0,5, +98,108,111,99,107,0,0,0,13,6,7,0,31,5,0,0, +19,5,6,5,31,3,5,1,19,3,4,3,20,1,0,0, +0,0,0,0,12,32,0,9,119,104,105,108,101,95,110,117, +100,0,0,0,14,32,31,0,16,32,0,57,44,11,0,0, +28,2,0,0,9,1,0,2,27,3,0,0,12,4,0,5, +105,116,101,109,115,0,0,0,10,1,4,3,15,2,3,0, +12,5,0,6,97,112,112,101,110,100,0,0,9,4,2,5, +12,7,0,10,101,120,112,114,101,115,115,105,111,110,0,0, +13,6,7,0,11,7,0,0,0,0,0,0,0,0,0,0, +31,5,7,1,19,5,6,5,31,3,5,1,19,3,4,3, +12,5,0,7,97,100,118,97,110,99,101,0,13,4,5,0, +12,5,0,1,58,0,0,0,31,3,5,1,19,3,4,3, +12,5,0,6,97,112,112,101,110,100,0,0,9,4,2,5, +12,7,0,4,105,108,115,116,0,0,0,0,13,6,7,0, +12,7,0,7,109,101,116,104,111,100,115,0,12,10,0,5, +98,108,111,99,107,0,0,0,13,9,10,0,31,8,0,0, +19,8,9,8,31,5,7,2,19,5,6,5,31,3,5,1, +19,3,4,3,20,1,0,0,0,0,0,0,12,33,0,9, +99,108,97,115,115,95,110,117,100,0,0,0,14,33,32,0, +16,33,0,53,44,8,0,0,28,2,0,0,9,1,0,2, +27,3,0,0,12,4,0,5,105,116,101,109,115,0,0,0, +10,1,4,3,15,2,3,0,12,5,0,6,97,112,112,101, +110,100,0,0,9,4,2,5,12,7,0,10,101,120,112,114, +101,115,115,105,111,110,0,0,13,6,7,0,11,7,0,0, +0,0,0,0,0,0,0,0,31,5,7,1,19,5,6,5, +31,3,5,1,19,3,4,3,12,5,0,7,97,100,118,97, +110,99,101,0,13,4,5,0,12,5,0,6,105,109,112,111, +114,116,0,0,31,3,5,1,19,3,4,3,12,5,0,6, +97,112,112,101,110,100,0,0,9,4,2,5,12,7,0,10, +101,120,112,114,101,115,115,105,111,110,0,0,13,6,7,0, +11,7,0,0,0,0,0,0,0,0,0,0,31,5,7,1, +19,5,6,5,31,3,5,1,19,3,4,3,20,1,0,0, +0,0,0,0,12,34,0,8,102,114,111,109,95,110,117,100, +0,0,0,0,14,34,33,0,16,34,0,89,44,8,0,0, +28,2,0,0,9,1,0,2,27,3,0,0,12,4,0,5, +105,116,101,109,115,0,0,0,10,1,4,3,15,2,3,0, +12,5,0,5,116,119,101,97,107,0,0,0,13,4,5,0, +12,5,0,2,105,110,0,0,11,6,0,0,0,0,0,0, +0,0,0,0,31,3,5,2,19,3,4,3,12,5,0,6, +97,112,112,101,110,100,0,0,9,4,2,5,12,7,0,10, +101,120,112,114,101,115,115,105,111,110,0,0,13,6,7,0, +11,7,0,0,0,0,0,0,0,0,0,0,31,5,7,1, +19,5,6,5,31,3,5,1,19,3,4,3,12,5,0,7, +97,100,118,97,110,99,101,0,13,4,5,0,12,5,0,2, +105,110,0,0,31,3,5,1,19,3,4,3,12,5,0,6, +97,112,112,101,110,100,0,0,9,4,2,5,12,7,0,10, +101,120,112,114,101,115,115,105,111,110,0,0,13,6,7,0, +11,7,0,0,0,0,0,0,0,0,0,0,31,5,7,1, +19,5,6,5,31,3,5,1,19,3,4,3,12,5,0,7, +114,101,115,116,111,114,101,0,13,4,5,0,31,3,0,0, +19,3,4,3,12,5,0,7,97,100,118,97,110,99,101,0, +13,4,5,0,12,5,0,1,58,0,0,0,31,3,5,1, +19,3,4,3,12,5,0,6,97,112,112,101,110,100,0,0, +9,4,2,5,12,7,0,5,98,108,111,99,107,0,0,0, +13,6,7,0,31,5,0,0,19,5,6,5,31,3,5,1, +19,3,4,3,20,1,0,0,0,0,0,0,12,35,0,7, +102,111,114,95,110,117,100,0,14,35,34,0,16,35,0,222, +44,16,0,0,28,2,0,0,9,1,0,2,27,3,0,0, +12,4,0,5,105,116,101,109,115,0,0,0,10,1,4,3, +15,2,3,0,12,6,0,10,101,120,112,114,101,115,115,105, +111,110,0,0,13,5,6,0,11,6,0,0,0,0,0,0, +0,0,0,0,31,4,6,1,19,4,5,4,15,3,4,0, +12,6,0,7,97,100,118,97,110,99,101,0,13,5,6,0, +12,6,0,1,58,0,0,0,31,4,6,1,19,4,5,4, +12,7,0,5,98,108,111,99,107,0,0,0,13,6,7,0, +31,5,0,0,19,5,6,5,15,4,5,0,12,7,0,6, +97,112,112,101,110,100,0,0,9,6,2,7,12,9,0,5, +84,111,107,101,110,0,0,0,13,8,9,0,12,13,0,3, +112,111,115,0,9,9,1,13,12,10,0,4,101,108,105,102, +0,0,0,0,12,11,0,4,101,108,105,102,0,0,0,0, +15,13,3,0,15,14,4,0,27,12,13,2,31,7,9,4, +19,7,8,7,31,5,7,1,19,5,6,5,12,7,0,5, +99,104,101,99,107,0,0,0,13,6,7,0,12,9,0,1, +80,0,0,0,13,7,9,0,12,9,0,5,116,111,107,101, +110,0,0,0,9,7,7,9,12,8,0,4,101,108,105,102, +0,0,0,0,31,5,7,2,19,5,6,5,21,5,0,0, +18,0,0,69,12,7,0,1,80,0,0,0,13,6,7,0, +12,7,0,5,116,111,107,101,110,0,0,0,9,6,6,7, +15,5,6,0,12,8,0,7,97,100,118,97,110,99,101,0, +13,7,8,0,12,8,0,4,101,108,105,102,0,0,0,0, +31,6,8,1,19,6,7,6,12,8,0,10,101,120,112,114, +101,115,115,105,111,110,0,0,13,7,8,0,11,8,0,0, +0,0,0,0,0,0,0,0,31,6,8,1,19,6,7,6, +15,3,6,0,12,8,0,7,97,100,118,97,110,99,101,0, +13,7,8,0,12,8,0,1,58,0,0,0,31,6,8,1, +19,6,7,6,12,8,0,5,98,108,111,99,107,0,0,0, +13,7,8,0,31,6,0,0,19,6,7,6,15,4,6,0, +12,8,0,6,97,112,112,101,110,100,0,0,9,7,2,8, +12,10,0,5,84,111,107,101,110,0,0,0,13,9,10,0, +12,14,0,3,112,111,115,0,9,10,5,14,12,11,0,4, +101,108,105,102,0,0,0,0,12,12,0,4,101,108,105,102, +0,0,0,0,15,14,3,0,15,15,4,0,27,13,14,2, +31,8,10,4,19,8,9,8,31,6,8,1,19,6,7,6, +18,0,255,171,12,8,0,5,99,104,101,99,107,0,0,0, +13,7,8,0,12,10,0,1,80,0,0,0,13,8,10,0, +12,10,0,5,116,111,107,101,110,0,0,0,9,8,8,10, +12,9,0,4,101,108,115,101,0,0,0,0,31,6,8,2, +19,6,7,6,21,6,0,0,18,0,0,57,12,7,0,1, +80,0,0,0,13,6,7,0,12,7,0,5,116,111,107,101, +110,0,0,0,9,6,6,7,15,5,6,0,12,8,0,7, +97,100,118,97,110,99,101,0,13,7,8,0,12,8,0,4, +101,108,115,101,0,0,0,0,31,6,8,1,19,6,7,6, +12,8,0,7,97,100,118,97,110,99,101,0,13,7,8,0, +12,8,0,1,58,0,0,0,31,6,8,1,19,6,7,6, +12,8,0,5,98,108,111,99,107,0,0,0,13,7,8,0, +31,6,0,0,19,6,7,6,15,4,6,0,12,8,0,6, +97,112,112,101,110,100,0,0,9,7,2,8,12,10,0,5, +84,111,107,101,110,0,0,0,13,9,10,0,12,14,0,3, +112,111,115,0,9,10,5,14,12,11,0,4,101,108,115,101, +0,0,0,0,12,12,0,4,101,108,115,101,0,0,0,0, +15,14,4,0,27,13,14,1,31,8,10,4,19,8,9,8, +31,6,8,1,19,6,7,6,18,0,0,1,20,1,0,0, +0,0,0,0,12,36,0,6,105,102,95,110,117,100,0,0, +14,36,35,0,16,36,0,233,44,16,0,0,28,2,0,0, +9,1,0,2,27,3,0,0,12,4,0,5,105,116,101,109, +115,0,0,0,10,1,4,3,15,2,3,0,12,5,0,7, +97,100,118,97,110,99,101,0,13,4,5,0,12,5,0,1, +58,0,0,0,31,3,5,1,19,3,4,3,12,6,0,5, +98,108,111,99,107,0,0,0,13,5,6,0,31,4,0,0, +19,4,5,4,15,3,4,0,12,6,0,6,97,112,112,101, +110,100,0,0,9,5,2,6,15,6,3,0,31,4,6,1, +19,4,5,4,12,6,0,5,99,104,101,99,107,0,0,0, +13,5,6,0,12,8,0,1,80,0,0,0,13,6,8,0, +12,8,0,5,116,111,107,101,110,0,0,0,9,6,6,8, +12,7,0,6,101,120,99,101,112,116,0,0,31,4,6,2, +19,4,5,4,21,4,0,0,18,0,0,108,12,6,0,1, +80,0,0,0,13,5,6,0,12,6,0,5,116,111,107,101, +110,0,0,0,9,5,5,6,15,4,5,0,12,7,0,7, +97,100,118,97,110,99,101,0,13,6,7,0,12,7,0,6, +101,120,99,101,112,116,0,0,31,5,7,1,19,5,6,5, +11,5,0,0,0,0,0,0,0,0,0,0,12,8,0,5, +99,104,101,99,107,0,0,0,13,7,8,0,12,10,0,1, +80,0,0,0,13,8,10,0,12,10,0,5,116,111,107,101, +110,0,0,0,9,8,8,10,12,9,0,1,58,0,0,0, +31,6,8,2,19,6,7,6,23,5,5,6,21,5,0,0, +18,0,0,13,12,8,0,10,101,120,112,114,101,115,115,105, +111,110,0,0,13,7,8,0,11,8,0,0,0,0,0,0, +0,0,0,0,31,6,8,1,19,6,7,6,15,5,6,0, +18,0,0,18,12,8,0,5,84,111,107,101,110,0,0,0, +13,7,8,0,12,11,0,3,112,111,115,0,9,8,4,11, +12,9,0,6,115,121,109,98,111,108,0,0,12,10,0,4, +78,111,110,101,0,0,0,0,31,6,8,3,19,6,7,6, +15,5,6,0,18,0,0,1,12,8,0,7,97,100,118,97, +110,99,101,0,13,7,8,0,12,8,0,1,58,0,0,0, +31,6,8,1,19,6,7,6,12,8,0,5,98,108,111,99, +107,0,0,0,13,7,8,0,31,6,0,0,19,6,7,6, +15,3,6,0,12,8,0,6,97,112,112,101,110,100,0,0, +9,7,2,8,12,10,0,5,84,111,107,101,110,0,0,0, +13,9,10,0,12,14,0,3,112,111,115,0,9,10,4,14, +12,11,0,6,101,120,99,101,112,116,0,0,12,12,0,6, +101,120,99,101,112,116,0,0,15,14,5,0,15,15,3,0, +27,13,14,2,31,8,10,4,19,8,9,8,31,6,8,1, +19,6,7,6,18,0,255,132,12,8,0,5,99,104,101,99, +107,0,0,0,13,7,8,0,12,10,0,1,80,0,0,0, +13,8,10,0,12,10,0,5,116,111,107,101,110,0,0,0, +9,8,8,10,12,9,0,4,101,108,115,101,0,0,0,0, +31,6,8,2,19,6,7,6,21,6,0,0,18,0,0,57, +12,7,0,1,80,0,0,0,13,6,7,0,12,7,0,5, +116,111,107,101,110,0,0,0,9,6,6,7,15,4,6,0, +12,8,0,7,97,100,118,97,110,99,101,0,13,7,8,0, +12,8,0,4,101,108,115,101,0,0,0,0,31,6,8,1, +19,6,7,6,12,8,0,7,97,100,118,97,110,99,101,0, +13,7,8,0,12,8,0,1,58,0,0,0,31,6,8,1, +19,6,7,6,12,8,0,5,98,108,111,99,107,0,0,0, +13,7,8,0,31,6,0,0,19,6,7,6,15,3,6,0, +12,8,0,6,97,112,112,101,110,100,0,0,9,7,2,8, +12,10,0,5,84,111,107,101,110,0,0,0,13,9,10,0, +12,14,0,3,112,111,115,0,9,10,4,14,12,11,0,4, +101,108,115,101,0,0,0,0,12,12,0,4,101,108,115,101, +0,0,0,0,15,14,3,0,27,13,14,1,31,8,10,4, +19,8,9,8,31,6,8,1,19,6,7,6,18,0,0,1, +20,1,0,0,0,0,0,0,12,37,0,7,116,114,121,95, +110,117,100,0,14,37,36,0,16,37,0,23,44,7,0,0, +28,2,0,0,9,1,0,2,12,4,0,2,98,112,0,0, +9,3,1,4,15,2,3,0,12,6,0,10,101,120,112,114, +101,115,115,105,111,110,0,0,13,5,6,0,15,6,2,0, +31,4,6,1,19,4,5,4,27,3,4,1,12,4,0,5, +105,116,101,109,115,0,0,0,10,1,4,3,20,1,0,0, +0,0,0,0,12,38,0,10,112,114,101,102,105,120,95,110, +117,100,0,0,14,38,37,0,16,38,0,40,44,10,0,0, +28,2,0,0,9,1,0,2,12,4,0,5,99,104,101,99, +107,0,0,0,13,3,4,0,12,9,0,1,80,0,0,0, +13,4,9,0,12,9,0,5,116,111,107,101,110,0,0,0, +9,4,4,9,12,5,0,2,110,108,0,0,12,6,0,1, +59,0,0,0,12,7,0,3,101,111,102,0,12,8,0,6, +100,101,100,101,110,116,0,0,31,2,4,5,19,2,3,2, +21,2,0,0,18,0,0,3,20,1,0,0,18,0,0,1, +12,4,0,10,112,114,101,102,105,120,95,110,117,100,0,0, +13,3,4,0,15,4,1,0,31,2,4,1,19,2,3,2, +20,2,0,0,0,0,0,0,12,39,0,11,112,114,101,102, +105,120,95,110,117,100,48,0,14,39,38,0,16,39,0,28, +44,8,0,0,28,2,0,0,9,1,0,2,12,5,0,10, +101,120,112,114,101,115,115,105,111,110,0,0,13,4,5,0, +11,5,0,0,0,0,0,0,0,0,0,0,31,3,5,1, +19,3,4,3,15,2,3,0,12,5,0,4,105,108,115,116, +0,0,0,0,13,4,5,0,12,7,0,4,116,121,112,101, +0,0,0,0,9,5,1,7,15,6,2,0,31,3,5,2, +19,3,4,3,20,3,0,0,0,0,0,0,12,40,0,11, +112,114,101,102,105,120,95,110,117,100,115,0,14,40,39,0, +16,40,0,70,44,11,0,0,28,2,0,0,9,1,0,2, +12,5,0,10,101,120,112,114,101,115,115,105,111,110,0,0, +13,4,5,0,11,5,0,0,0,0,0,0,0,0,73,64, +31,3,5,1,19,3,4,3,15,2,3,0,12,4,0,4, +116,121,112,101,0,0,0,0,9,3,2,4,12,4,0,6, +110,117,109,98,101,114,0,0,23,3,3,4,21,3,0,0, +18,0,0,24,12,5,0,3,115,116,114,0,13,4,5,0, +11,5,0,0,0,0,0,0,0,0,0,0,12,8,0,5, +102,108,111,97,116,0,0,0,13,7,8,0,12,9,0,3, +118,97,108,0,9,8,2,9,31,6,8,1,19,6,7,6, +2,5,5,6,31,3,5,1,19,3,4,3,12,4,0,3, +118,97,108,0,10,2,4,3,20,2,0,0,18,0,0,1, +12,7,0,5,84,111,107,101,110,0,0,0,13,6,7,0, +12,10,0,3,112,111,115,0,9,7,1,10,12,8,0,6, +110,117,109,98,101,114,0,0,12,9,0,1,48,0,0,0, +31,4,7,3,19,4,6,4,15,5,2,0,27,3,4,2, +12,4,0,5,105,116,101,109,115,0,0,0,10,1,4,3, +20,1,0,0,0,0,0,0,12,41,0,10,112,114,101,102, +105,120,95,110,101,103,0,0,14,41,40,0,16,41,0,27, +44,6,0,0,28,2,0,0,9,1,0,2,12,5,0,10, +112,114,101,102,105,120,95,110,117,100,0,0,13,4,5,0, +15,5,1,0,31,3,5,1,19,3,4,3,15,2,3,0, +12,3,0,4,97,114,103,115,0,0,0,0,12,4,0,4, +116,121,112,101,0,0,0,0,10,1,4,3,12,3,0,1, +42,0,0,0,12,4,0,3,118,97,108,0,10,1,4,3, +20,1,0,0,0,0,0,0,12,42,0,9,118,97,114,103, +115,95,110,117,100,0,0,0,14,42,41,0,16,42,0,27, +44,6,0,0,28,2,0,0,9,1,0,2,12,5,0,10, +112,114,101,102,105,120,95,110,117,100,0,0,13,4,5,0, +15,5,1,0,31,3,5,1,19,3,4,3,15,2,3,0, +12,3,0,5,110,97,114,103,115,0,0,0,12,4,0,4, +116,121,112,101,0,0,0,0,10,1,4,3,12,3,0,2, +42,42,0,0,12,4,0,3,118,97,108,0,10,1,4,3, +20,1,0,0,0,0,0,0,12,43,0,9,110,97,114,103, +115,95,110,117,100,0,0,0,14,43,42,0,12,43,0,9, +98,97,115,101,95,100,109,97,112,0,0,0,12,45,0,1, +44,0,0,0,12,103,0,3,108,98,112,0,11,104,0,0, +0,0,0,0,0,0,52,64,12,105,0,2,98,112,0,0, +11,106,0,0,0,0,0,0,0,0,52,64,12,107,0,3, +108,101,100,0,12,109,0,11,105,110,102,105,120,95,116,117, +112,108,101,0,13,108,109,0,26,46,103,6,12,47,0,1, +43,0,0,0,12,103,0,3,108,98,112,0,11,104,0,0, +0,0,0,0,0,0,73,64,12,105,0,2,98,112,0,0, +11,106,0,0,0,0,0,0,0,0,73,64,12,107,0,3, +108,101,100,0,12,109,0,9,105,110,102,105,120,95,108,101, +100,0,0,0,13,108,109,0,26,48,103,6,12,49,0,1, +45,0,0,0,12,103,0,3,108,98,112,0,11,104,0,0, +0,0,0,0,0,0,73,64,12,105,0,3,110,117,100,0, +12,111,0,10,112,114,101,102,105,120,95,110,101,103,0,0, +13,106,111,0,12,107,0,2,98,112,0,0,11,108,0,0, +0,0,0,0,0,0,73,64,12,109,0,3,108,101,100,0, +12,111,0,9,105,110,102,105,120,95,108,101,100,0,0,0, +13,110,111,0,26,50,103,8,12,51,0,3,110,111,116,0, +12,103,0,3,108,98,112,0,11,104,0,0,0,0,0,0, +0,128,65,64,12,105,0,3,110,117,100,0,12,113,0,10, +112,114,101,102,105,120,95,110,117,100,0,0,13,106,113,0, +12,107,0,2,98,112,0,0,11,108,0,0,0,0,0,0, +0,128,65,64,12,109,0,2,98,112,0,0,11,110,0,0, +0,0,0,0,0,128,65,64,12,111,0,3,108,101,100,0, +12,113,0,9,105,110,102,105,120,95,110,111,116,0,0,0, +13,112,113,0,26,52,103,10,12,53,0,1,37,0,0,0, +12,103,0,3,108,98,112,0,11,104,0,0,0,0,0,0, +0,0,78,64,12,105,0,2,98,112,0,0,11,106,0,0, +0,0,0,0,0,0,78,64,12,107,0,3,108,101,100,0, +12,109,0,9,105,110,102,105,120,95,108,101,100,0,0,0, +13,108,109,0,26,54,103,6,12,55,0,1,42,0,0,0, +12,103,0,3,108,98,112,0,11,104,0,0,0,0,0,0, +0,0,78,64,12,105,0,3,110,117,100,0,12,111,0,9, +118,97,114,103,115,95,110,117,100,0,0,0,13,106,111,0, +12,107,0,2,98,112,0,0,11,108,0,0,0,0,0,0, +0,0,78,64,12,109,0,3,108,101,100,0,12,111,0,9, +105,110,102,105,120,95,108,101,100,0,0,0,13,110,111,0, +26,56,103,8,12,57,0,2,42,42,0,0,12,103,0,3, +108,98,112,0,11,104,0,0,0,0,0,0,0,64,80,64, +12,105,0,3,110,117,100,0,12,111,0,9,110,97,114,103, +115,95,110,117,100,0,0,0,13,106,111,0,12,107,0,2, +98,112,0,0,11,108,0,0,0,0,0,0,0,64,80,64, +12,109,0,3,108,101,100,0,12,111,0,9,105,110,102,105, +120,95,108,101,100,0,0,0,13,110,111,0,26,58,103,8, +12,59,0,1,47,0,0,0,12,103,0,3,108,98,112,0, +11,104,0,0,0,0,0,0,0,0,78,64,12,105,0,2, +98,112,0,0,11,106,0,0,0,0,0,0,0,0,78,64, +12,107,0,3,108,101,100,0,12,109,0,9,105,110,102,105, +120,95,108,101,100,0,0,0,13,108,109,0,26,60,103,6, +12,61,0,1,40,0,0,0,12,103,0,3,108,98,112,0, +11,104,0,0,0,0,0,0,0,128,81,64,12,105,0,3, +110,117,100,0,12,111,0,9,112,97,114,101,110,95,110,117, +100,0,0,0,13,106,111,0,12,107,0,2,98,112,0,0, +11,108,0,0,0,0,0,0,0,0,84,64,12,109,0,3, +108,101,100,0,12,111,0,8,99,97,108,108,95,108,101,100, +0,0,0,0,13,110,111,0,26,62,103,8,12,63,0,1, +91,0,0,0,12,103,0,3,108,98,112,0,11,104,0,0, +0,0,0,0,0,128,81,64,12,105,0,3,110,117,100,0, +12,111,0,8,108,105,115,116,95,110,117,100,0,0,0,0, +13,106,111,0,12,107,0,2,98,112,0,0,11,108,0,0, +0,0,0,0,0,0,84,64,12,109,0,3,108,101,100,0, +12,111,0,7,103,101,116,95,108,101,100,0,13,110,111,0, +26,64,103,8,12,65,0,1,123,0,0,0,12,103,0,3, +108,98,112,0,11,104,0,0,0,0,0,0,0,0,0,0, +12,105,0,3,110,117,100,0,12,107,0,8,100,105,99,116, +95,110,117,100,0,0,0,0,13,106,107,0,26,66,103,4, +12,67,0,1,46,0,0,0,12,103,0,3,108,98,112,0, +11,104,0,0,0,0,0,0,0,0,84,64,12,105,0,2, +98,112,0,0,11,106,0,0,0,0,0,0,0,0,84,64, +12,107,0,3,108,101,100,0,12,111,0,7,100,111,116,95, +108,101,100,0,13,108,111,0,12,109,0,4,116,121,112,101, +0,0,0,0,12,110,0,3,103,101,116,0,26,68,103,8, +12,69,0,5,98,114,101,97,107,0,0,0,12,103,0,3, +108,98,112,0,11,104,0,0,0,0,0,0,0,0,0,0, +12,105,0,3,110,117,100,0,12,109,0,6,105,116,115,101, +108,102,0,0,13,106,109,0,12,107,0,4,116,121,112,101, +0,0,0,0,12,108,0,5,98,114,101,97,107,0,0,0, +26,70,103,6,12,71,0,4,112,97,115,115,0,0,0,0, +12,103,0,3,108,98,112,0,11,104,0,0,0,0,0,0, +0,0,0,0,12,105,0,3,110,117,100,0,12,109,0,6, +105,116,115,101,108,102,0,0,13,106,109,0,12,107,0,4, +116,121,112,101,0,0,0,0,12,108,0,4,112,97,115,115, +0,0,0,0,26,72,103,6,12,73,0,8,99,111,110,116, +105,110,117,101,0,0,0,0,12,103,0,3,108,98,112,0, +11,104,0,0,0,0,0,0,0,0,0,0,12,105,0,3, +110,117,100,0,12,109,0,6,105,116,115,101,108,102,0,0, +13,106,109,0,12,107,0,4,116,121,112,101,0,0,0,0, +12,108,0,8,99,111,110,116,105,110,117,101,0,0,0,0, +26,74,103,6,12,75,0,3,101,111,102,0,12,103,0,3, +108,98,112,0,11,104,0,0,0,0,0,0,0,0,0,0, +12,105,0,4,116,121,112,101,0,0,0,0,12,106,0,3, +101,111,102,0,12,107,0,3,118,97,108,0,12,108,0,3, +101,111,102,0,26,76,103,6,12,77,0,3,100,101,102,0, +12,103,0,3,108,98,112,0,11,104,0,0,0,0,0,0, +0,0,0,0,12,105,0,3,110,117,100,0,12,109,0,7, +100,101,102,95,110,117,100,0,13,106,109,0,12,107,0,4, +116,121,112,101,0,0,0,0,12,108,0,3,100,101,102,0, +26,78,103,6,12,79,0,5,119,104,105,108,101,0,0,0, +12,103,0,3,108,98,112,0,11,104,0,0,0,0,0,0, +0,0,0,0,12,105,0,3,110,117,100,0,12,109,0,9, +119,104,105,108,101,95,110,117,100,0,0,0,13,106,109,0, +12,107,0,4,116,121,112,101,0,0,0,0,12,108,0,5, +119,104,105,108,101,0,0,0,26,80,103,6,12,81,0,3, +102,111,114,0,12,103,0,3,108,98,112,0,11,104,0,0, +0,0,0,0,0,0,0,0,12,105,0,3,110,117,100,0, +12,109,0,7,102,111,114,95,110,117,100,0,13,106,109,0, +12,107,0,4,116,121,112,101,0,0,0,0,12,108,0,3, +102,111,114,0,26,82,103,6,12,83,0,3,116,114,121,0, +12,103,0,3,108,98,112,0,11,104,0,0,0,0,0,0, +0,0,0,0,12,105,0,3,110,117,100,0,12,109,0,7, +116,114,121,95,110,117,100,0,13,106,109,0,12,107,0,4, +116,121,112,101,0,0,0,0,12,108,0,3,116,114,121,0, +26,84,103,6,12,85,0,2,105,102,0,0,12,103,0,3, +108,98,112,0,11,104,0,0,0,0,0,0,0,0,0,0, +12,105,0,3,110,117,100,0,12,109,0,6,105,102,95,110, +117,100,0,0,13,106,109,0,12,107,0,4,116,121,112,101, +0,0,0,0,12,108,0,2,105,102,0,0,26,86,103,6, +12,87,0,5,99,108,97,115,115,0,0,0,12,103,0,3, +108,98,112,0,11,104,0,0,0,0,0,0,0,0,0,0, +12,105,0,3,110,117,100,0,12,109,0,9,99,108,97,115, +115,95,110,117,100,0,0,0,13,106,109,0,12,107,0,4, +116,121,112,101,0,0,0,0,12,108,0,5,99,108,97,115, +115,0,0,0,26,88,103,6,12,89,0,5,114,97,105,115, +101,0,0,0,12,103,0,3,108,98,112,0,11,104,0,0, +0,0,0,0,0,0,0,0,12,105,0,3,110,117,100,0, +12,111,0,11,112,114,101,102,105,120,95,110,117,100,48,0, +13,106,111,0,12,107,0,4,116,121,112,101,0,0,0,0, +12,108,0,5,114,97,105,115,101,0,0,0,12,109,0,2, +98,112,0,0,11,110,0,0,0,0,0,0,0,0,52,64, +26,90,103,8,12,91,0,6,114,101,116,117,114,110,0,0, +12,103,0,3,108,98,112,0,11,104,0,0,0,0,0,0, +0,0,0,0,12,105,0,3,110,117,100,0,12,111,0,11, +112,114,101,102,105,120,95,110,117,100,48,0,13,106,111,0, +12,107,0,4,116,121,112,101,0,0,0,0,12,108,0,6, +114,101,116,117,114,110,0,0,12,109,0,2,98,112,0,0, +11,110,0,0,0,0,0,0,0,0,36,64,26,92,103,8, +12,93,0,6,105,109,112,111,114,116,0,0,12,103,0,3, +108,98,112,0,11,104,0,0,0,0,0,0,0,0,0,0, +12,105,0,3,110,117,100,0,12,111,0,11,112,114,101,102, +105,120,95,110,117,100,115,0,13,106,111,0,12,107,0,4, +116,121,112,101,0,0,0,0,12,108,0,6,105,109,112,111, +114,116,0,0,12,109,0,2,98,112,0,0,11,110,0,0, +0,0,0,0,0,0,52,64,26,94,103,8,12,95,0,4, +102,114,111,109,0,0,0,0,12,103,0,3,108,98,112,0, +11,104,0,0,0,0,0,0,0,0,0,0,12,105,0,3, +110,117,100,0,12,111,0,8,102,114,111,109,95,110,117,100, +0,0,0,0,13,106,111,0,12,107,0,4,116,121,112,101, +0,0,0,0,12,108,0,4,102,114,111,109,0,0,0,0, +12,109,0,2,98,112,0,0,11,110,0,0,0,0,0,0, +0,0,52,64,26,96,103,8,12,97,0,3,100,101,108,0, +12,103,0,3,108,98,112,0,11,104,0,0,0,0,0,0, +0,0,0,0,12,105,0,3,110,117,100,0,12,111,0,11, +112,114,101,102,105,120,95,110,117,100,115,0,13,106,111,0, +12,107,0,4,116,121,112,101,0,0,0,0,12,108,0,3, +100,101,108,0,12,109,0,2,98,112,0,0,11,110,0,0, +0,0,0,0,0,0,36,64,26,98,103,8,12,99,0,6, +103,108,111,98,97,108,0,0,12,103,0,3,108,98,112,0, +11,104,0,0,0,0,0,0,0,0,0,0,12,105,0,3, +110,117,100,0,12,111,0,11,112,114,101,102,105,120,95,110, +117,100,115,0,13,106,111,0,12,107,0,4,116,121,112,101, +0,0,0,0,12,108,0,7,103,108,111,98,97,108,115,0, +12,109,0,2,98,112,0,0,11,110,0,0,0,0,0,0, +0,0,52,64,26,100,103,8,12,101,0,1,61,0,0,0, +12,103,0,3,108,98,112,0,11,104,0,0,0,0,0,0, +0,0,36,64,12,105,0,2,98,112,0,0,11,106,0,0, +0,0,0,0,0,0,34,64,12,107,0,3,108,101,100,0, +12,109,0,9,105,110,102,105,120,95,108,101,100,0,0,0, +13,108,109,0,26,102,103,6,26,44,45,58,14,43,44,0, +16,43,0,32,44,14,0,0,28,2,0,0,9,1,0,2, +28,3,0,0,9,2,0,3,12,4,0,1,42,0,0,0, +9,3,0,4,11,5,0,0,0,0,0,0,0,0,0,0, +42,4,3,5,18,0,0,18,12,7,0,9,98,97,115,101, +95,100,109,97,112,0,0,0,13,6,7,0,12,8,0,3, +108,98,112,0,15,9,1,0,12,10,0,2,98,112,0,0, +15,11,1,0,12,12,0,3,108,101,100,0,15,13,2,0, +26,7,8,6,10,6,4,7,18,0,255,238,0,0,0,0, +12,44,0,7,105,95,105,110,102,105,120,0,14,44,43,0, +12,46,0,7,105,95,105,110,102,105,120,0,13,45,46,0, +11,46,0,0,0,0,0,0,0,0,68,64,12,54,0,9, +105,110,102,105,120,95,108,101,100,0,0,0,13,47,54,0, +12,48,0,1,60,0,0,0,12,49,0,1,62,0,0,0, +12,50,0,2,60,61,0,0,12,51,0,2,62,61,0,0, +12,52,0,2,33,61,0,0,12,53,0,2,61,61,0,0, +31,44,46,8,19,44,45,44,12,46,0,7,105,95,105,110, +102,105,120,0,13,45,46,0,11,46,0,0,0,0,0,0, +0,0,68,64,12,50,0,8,105,110,102,105,120,95,105,115, +0,0,0,0,13,47,50,0,12,48,0,2,105,115,0,0, +12,49,0,2,105,110,0,0,31,44,46,4,19,44,45,44, +12,46,0,7,105,95,105,110,102,105,120,0,13,45,46,0, +11,46,0,0,0,0,0,0,0,0,36,64,12,52,0,9, +105,110,102,105,120,95,108,101,100,0,0,0,13,47,52,0, +12,48,0,2,43,61,0,0,12,49,0,2,45,61,0,0, +12,50,0,2,42,61,0,0,12,51,0,2,47,61,0,0, +31,44,46,6,19,44,45,44,12,46,0,7,105,95,105,110, +102,105,120,0,13,45,46,0,11,46,0,0,0,0,0,0, +0,0,63,64,12,50,0,9,105,110,102,105,120,95,108,101, +100,0,0,0,13,47,50,0,12,48,0,3,97,110,100,0, +12,49,0,1,38,0,0,0,31,44,46,4,19,44,45,44, +12,46,0,7,105,95,105,110,102,105,120,0,13,45,46,0, +11,46,0,0,0,0,0,0,0,0,62,64,12,50,0,9, +105,110,102,105,120,95,108,101,100,0,0,0,13,47,50,0, +12,48,0,2,111,114,0,0,12,49,0,1,124,0,0,0, +31,44,46,4,19,44,45,44,12,46,0,7,105,95,105,110, +102,105,120,0,13,45,46,0,11,46,0,0,0,0,0,0, +0,0,66,64,12,50,0,9,105,110,102,105,120,95,108,101, +100,0,0,0,13,47,50,0,12,48,0,2,60,60,0,0, +12,49,0,2,62,62,0,0,31,44,46,4,19,44,45,44, +16,44,0,30,44,11,0,0,12,2,0,1,42,0,0,0, +9,1,0,2,11,3,0,0,0,0,0,0,0,0,0,0, +42,2,1,3,18,0,0,20,12,5,0,9,98,97,115,101, +95,100,109,97,112,0,0,0,13,4,5,0,12,6,0,3, +108,98,112,0,11,7,0,0,0,0,0,0,0,0,0,0, +12,8,0,3,110,117,100,0,12,10,0,6,105,116,115,101, +108,102,0,0,13,9,10,0,26,5,6,4,10,4,2,5, +18,0,255,236,0,0,0,0,12,45,0,7,105,95,116,101, +114,109,115,0,14,45,44,0,12,47,0,7,105,95,116,101, +114,109,115,0,13,46,47,0,12,47,0,1,41,0,0,0, +12,48,0,1,125,0,0,0,12,49,0,1,93,0,0,0, +12,50,0,1,59,0,0,0,12,51,0,1,58,0,0,0, +12,52,0,2,110,108,0,0,12,53,0,4,101,108,105,102, +0,0,0,0,12,54,0,4,101,108,115,101,0,0,0,0, +12,55,0,4,84,114,117,101,0,0,0,0,12,56,0,5, +70,97,108,115,101,0,0,0,12,57,0,4,78,111,110,101, +0,0,0,0,12,58,0,4,110,97,109,101,0,0,0,0, +12,59,0,6,115,116,114,105,110,103,0,0,12,60,0,6, +110,117,109,98,101,114,0,0,12,61,0,6,105,110,100,101, +110,116,0,0,12,62,0,6,100,101,100,101,110,116,0,0, +12,63,0,6,101,120,99,101,112,116,0,0,31,45,47,17, +19,45,46,45,12,46,0,9,98,97,115,101,95,100,109,97, +112,0,0,0,13,45,46,0,12,46,0,2,110,108,0,0, +9,45,45,46,12,46,0,2,110,108,0,0,12,47,0,3, +118,97,108,0,10,45,47,46,16,45,0,38,44,7,0,0, +28,2,0,0,9,1,0,2,28,3,0,0,9,2,0,3, +12,4,0,4,100,109,97,112,0,0,0,0,13,3,4,0, +36,3,3,2,11,4,0,0,0,0,0,0,0,0,0,0, +23,3,3,4,21,3,0,0,18,0,0,15,12,5,0,5, +101,114,114,111,114,0,0,0,13,4,5,0,12,5,0,12, +117,110,107,110,111,119,110,32,34,37,115,34,0,0,0,0, +39,5,5,2,15,6,1,0,31,3,5,2,19,3,4,3, +18,0,0,1,12,4,0,4,100,109,97,112,0,0,0,0, +13,3,4,0,9,3,3,2,20,3,0,0,0,0,0,0, +12,46,0,4,103,109,97,112,0,0,0,0,14,46,45,0, +16,46,0,49,44,8,0,0,28,2,0,0,9,1,0,2, +12,3,0,4,116,121,112,101,0,0,0,0,9,2,1,3, +12,3,0,6,115,121,109,98,111,108,0,0,23,2,2,3, +21,2,0,0,18,0,0,13,12,5,0,4,103,109,97,112, +0,0,0,0,13,4,5,0,15,5,1,0,12,7,0,3, +118,97,108,0,9,6,1,7,31,3,5,2,19,3,4,3, +15,2,3,0,18,0,0,14,12,5,0,4,103,109,97,112, +0,0,0,0,13,4,5,0,15,5,1,0,12,7,0,4, +116,121,112,101,0,0,0,0,9,6,1,7,31,3,5,2, +19,3,4,3,15,2,3,0,18,0,0,1,12,5,0,5, +109,101,114,103,101,0,0,0,13,4,5,0,15,5,1,0, +15,6,2,0,31,3,5,2,19,3,4,3,20,1,0,0, +0,0,0,0,12,47,0,2,100,111,0,0,14,47,46,0, +16,47,0,83,44,10,0,0,12,3,0,1,80,0,0,0, +13,2,3,0,12,3,0,5,116,111,107,101,110,0,0,0, +9,2,2,3,15,1,2,0,27,3,0,0,15,2,3,0, +11,3,0,0,0,0,0,0,0,0,0,0,12,6,0,5, +99,104,101,99,107,0,0,0,13,5,6,0,12,8,0,1, +80,0,0,0,13,6,8,0,12,8,0,5,116,111,107,101, +110,0,0,0,9,6,6,8,12,7,0,3,101,111,102,0, +31,4,6,2,19,4,5,4,23,3,3,4,21,3,0,0, +18,0,0,14,12,5,0,6,97,112,112,101,110,100,0,0, +9,4,2,5,12,7,0,5,98,108,111,99,107,0,0,0, +13,6,7,0,31,5,0,0,19,5,6,5,31,3,5,1, +19,3,4,3,18,0,255,223,11,3,0,0,0,0,0,0, +0,0,240,63,12,6,0,3,108,101,110,0,13,5,6,0, +15,6,2,0,31,4,6,1,19,4,5,4,25,3,3,4, +21,3,0,0,18,0,0,19,12,5,0,5,84,111,107,101, +110,0,0,0,13,4,5,0,12,9,0,3,112,111,115,0, +9,5,1,9,12,6,0,10,115,116,97,116,101,109,101,110, +116,115,0,0,12,7,0,1,59,0,0,0,15,8,2,0, +31,3,5,4,19,3,4,3,20,3,0,0,18,0,0,1, +12,5,0,3,112,111,112,0,9,4,2,5,31,3,0,0, +19,3,4,3,20,3,0,0,0,0,0,0,12,48,0,9, +100,111,95,109,111,100,117,108,101,0,0,0,14,48,47,0, +16,48,0,58,44,9,0,0,28,2,0,0,9,1,0,2, +28,3,0,0,9,2,0,3,11,3,0,0,0,0,0,0, +0,0,0,0,28,4,0,0,32,3,0,4,12,6,0,8, +116,111,107,101,110,105,122,101,0,0,0,0,13,5,6,0, +12,6,0,5,99,108,101,97,110,0,0,0,9,5,5,6, +15,6,1,0,31,4,6,1,19,4,5,4,15,1,4,0, +12,4,0,1,80,0,0,0,12,7,0,5,80,68,97,116, +97,0,0,0,13,6,7,0,15,7,1,0,15,8,2,0, +31,5,7,2,19,5,6,5,14,4,5,0,12,6,0,1, +80,0,0,0,13,5,6,0,12,6,0,4,105,110,105,116, +0,0,0,0,9,5,5,6,31,4,0,0,19,4,5,4, +12,7,0,9,100,111,95,109,111,100,117,108,101,0,0,0, +13,6,7,0,31,5,0,0,19,5,6,5,15,4,5,0, +12,5,0,1,80,0,0,0,28,6,0,0,14,5,6,0, +20,4,0,0,0,0,0,0,12,49,0,5,112,97,114,115, +101,0,0,0,14,49,48,0,0,0,0,0, +}; +unsigned char tp_encode[] = { +44,104,0,0,12,2,0,6,105,109,112,111,114,116,0,0, +13,1,2,0,12,2,0,8,116,111,107,101,110,105,122,101, +0,0,0,0,31,0,2,1,19,0,1,0,12,1,0,8, +116,111,107,101,110,105,122,101,0,0,0,0,14,1,0,0, +12,2,0,6,105,109,112,111,114,116,0,0,13,1,2,0, +12,2,0,8,116,111,107,101,110,105,122,101,0,0,0,0, +31,0,2,1,19,0,1,0,12,2,0,8,95,95,100,105, +99,116,95,95,0,0,0,0,13,1,2,0,12,3,0,5, +84,111,107,101,110,0,0,0,9,2,0,3,12,0,0,5, +84,111,107,101,110,0,0,0,10,1,0,2,12,2,0,3, +115,116,114,0,13,1,2,0,11,2,0,0,0,0,0,0, +0,0,240,63,31,0,2,1,19,0,1,0,12,1,0,1, +46,0,0,0,36,0,0,1,21,0,0,0,18,0,0,23, +12,2,0,6,105,109,112,111,114,116,0,0,13,1,2,0, +12,2,0,4,98,111,111,116,0,0,0,0,31,0,2,1, +19,0,1,0,12,3,0,5,109,101,114,103,101,0,0,0, +13,2,3,0,12,5,0,8,95,95,100,105,99,116,95,95, +0,0,0,0,13,3,5,0,15,4,0,0,31,1,3,2, +19,1,2,1,18,0,0,1,11,1,0,0,0,0,0,0, +0,0,0,0,15,0,1,0,11,2,0,0,0,0,0,0, +0,0,240,63,15,1,2,0,11,3,0,0,0,0,0,0, +0,0,0,64,15,2,3,0,11,4,0,0,0,0,0,0, +0,0,8,64,15,3,4,0,11,5,0,0,0,0,0,0, +0,0,16,64,15,4,5,0,11,6,0,0,0,0,0,0, +0,0,20,64,15,5,6,0,11,7,0,0,0,0,0,0, +0,0,24,64,15,6,7,0,11,8,0,0,0,0,0,0, +0,0,28,64,15,7,8,0,11,9,0,0,0,0,0,0, +0,0,32,64,15,8,9,0,11,10,0,0,0,0,0,0, +0,0,34,64,15,9,10,0,11,11,0,0,0,0,0,0, +0,0,36,64,15,10,11,0,11,12,0,0,0,0,0,0, +0,0,38,64,15,11,12,0,11,13,0,0,0,0,0,0, +0,0,40,64,15,12,13,0,11,14,0,0,0,0,0,0, +0,0,42,64,15,13,14,0,11,15,0,0,0,0,0,0, +0,0,44,64,15,14,15,0,11,16,0,0,0,0,0,0, +0,0,46,64,15,15,16,0,11,17,0,0,0,0,0,0, +0,0,48,64,15,16,17,0,11,18,0,0,0,0,0,0, +0,0,49,64,15,17,18,0,11,19,0,0,0,0,0,0, +0,0,50,64,15,18,19,0,11,20,0,0,0,0,0,0, +0,0,51,64,15,19,20,0,11,21,0,0,0,0,0,0, +0,0,52,64,15,20,21,0,11,22,0,0,0,0,0,0, +0,0,53,64,15,21,22,0,11,23,0,0,0,0,0,0, +0,0,54,64,15,22,23,0,11,24,0,0,0,0,0,0, +0,0,55,64,15,23,24,0,11,25,0,0,0,0,0,0, +0,0,56,64,15,24,25,0,11,26,0,0,0,0,0,0, +0,0,57,64,15,25,26,0,11,27,0,0,0,0,0,0, +0,0,58,64,15,26,27,0,11,28,0,0,0,0,0,0, +0,0,59,64,15,27,28,0,11,29,0,0,0,0,0,0, +0,0,60,64,15,28,29,0,11,30,0,0,0,0,0,0, +0,0,61,64,15,29,30,0,11,31,0,0,0,0,0,0, +0,0,62,64,15,30,31,0,11,32,0,0,0,0,0,0, +0,0,63,64,15,31,32,0,11,33,0,0,0,0,0,0, +0,0,64,64,15,32,33,0,11,34,0,0,0,0,0,0, +0,128,64,64,15,33,34,0,11,35,0,0,0,0,0,0, +0,0,65,64,15,34,35,0,11,36,0,0,0,0,0,0, +0,128,65,64,15,35,36,0,11,37,0,0,0,0,0,0, +0,0,66,64,15,36,37,0,11,38,0,0,0,0,0,0, +0,128,66,64,15,37,38,0,11,39,0,0,0,0,0,0, +0,0,67,64,15,38,39,0,11,40,0,0,0,0,0,0, +0,128,67,64,15,39,40,0,11,41,0,0,0,0,0,0, +0,0,68,64,15,40,41,0,11,42,0,0,0,0,0,0, +0,128,68,64,15,41,42,0,11,43,0,0,0,0,0,0, +0,0,69,64,15,42,43,0,11,44,0,0,0,0,0,0, +0,128,69,64,15,43,44,0,11,45,0,0,0,0,0,0, +0,0,70,64,15,44,45,0,12,45,0,3,69,79,70,0, +14,45,0,0,12,0,0,3,65,68,68,0,14,0,1,0, +12,0,0,3,83,85,66,0,14,0,2,0,12,0,0,3, +77,85,76,0,14,0,3,0,12,0,0,3,68,73,86,0, +14,0,4,0,12,0,0,3,80,79,87,0,14,0,5,0, +12,0,0,3,65,78,68,0,14,0,6,0,12,0,0,2, +79,82,0,0,14,0,7,0,12,0,0,3,67,77,80,0, +14,0,8,0,12,0,0,3,71,69,84,0,14,0,9,0, +12,0,0,3,83,69,84,0,14,0,10,0,12,0,0,6, +78,85,77,66,69,82,0,0,14,0,11,0,12,0,0,6, +83,84,82,73,78,71,0,0,14,0,12,0,12,0,0,4, +71,71,69,84,0,0,0,0,14,0,13,0,12,0,0,4, +71,83,69,84,0,0,0,0,14,0,14,0,12,0,0,4, +77,79,86,69,0,0,0,0,14,0,15,0,12,0,0,3, +68,69,70,0,14,0,16,0,12,0,0,4,80,65,83,83, +0,0,0,0,14,0,17,0,12,0,0,4,74,85,77,80, +0,0,0,0,14,0,18,0,12,0,0,4,67,65,76,76, +0,0,0,0,14,0,19,0,12,0,0,6,82,69,84,85, +82,78,0,0,14,0,20,0,12,0,0,2,73,70,0,0, +14,0,21,0,12,0,0,5,68,69,66,85,71,0,0,0, +14,0,22,0,12,0,0,2,69,81,0,0,14,0,23,0, +12,0,0,2,76,69,0,0,14,0,24,0,12,0,0,2, +76,84,0,0,14,0,25,0,12,0,0,4,68,73,67,84, +0,0,0,0,14,0,26,0,12,0,0,4,76,73,83,84, +0,0,0,0,14,0,27,0,12,0,0,4,78,79,78,69, +0,0,0,0,14,0,28,0,12,0,0,3,76,69,78,0, +14,0,29,0,12,0,0,3,80,79,83,0,14,0,30,0, +12,0,0,6,80,65,82,65,77,83,0,0,14,0,31,0, +12,0,0,4,73,71,69,84,0,0,0,0,14,0,32,0, +12,0,0,4,70,73,76,69,0,0,0,0,14,0,33,0, +12,0,0,4,78,65,77,69,0,0,0,0,14,0,34,0, +12,0,0,2,78,69,0,0,14,0,35,0,12,0,0,3, +72,65,83,0,14,0,36,0,12,0,0,5,82,65,73,83, +69,0,0,0,14,0,37,0,12,0,0,6,83,69,84,74, +77,80,0,0,14,0,38,0,12,0,0,3,77,79,68,0, +14,0,39,0,12,0,0,3,76,83,72,0,14,0,40,0, +12,0,0,3,82,83,72,0,14,0,41,0,12,0,0,4, +73,84,69,82,0,0,0,0,14,0,42,0,12,0,0,3, +68,69,76,0,14,0,43,0,12,0,0,4,82,69,71,83, +0,0,0,0,14,0,44,0,26,0,0,0,12,1,0,6, +68,83,116,97,116,101,0,0,14,1,0,0,16,1,0,86, +44,11,0,0,28,2,0,0,9,1,0,2,28,3,0,0, +9,2,0,3,28,4,0,0,9,3,0,4,15,4,2,0, +15,5,3,0,12,6,0,4,99,111,100,101,0,0,0,0, +10,1,6,4,12,4,0,5,102,110,97,109,101,0,0,0, +10,1,4,5,12,6,0,4,99,111,100,101,0,0,0,0, +9,5,1,6,12,6,0,5,115,112,108,105,116,0,0,0, +9,5,5,6,12,6,0,1,10,0,0,0,31,4,6,1, +19,4,5,4,12,5,0,5,108,105,110,101,115,0,0,0, +10,1,5,4,27,5,0,0,15,4,5,0,12,8,0,3, +116,97,103,0,12,9,0,3,69,79,70,0,27,7,8,2, +27,6,7,1,15,5,6,0,11,7,0,0,0,0,0,0, +0,0,0,0,15,6,7,0,27,8,0,0,15,7,8,0, +11,9,0,0,0,0,0,0,0,0,0,0,15,8,9,0, +26,10,0,0,15,9,10,0,12,10,0,5,115,116,97,99, +107,0,0,0,10,1,10,4,12,4,0,3,111,117,116,0, +10,1,4,5,12,4,0,7,95,115,99,111,112,101,105,0, +10,1,4,6,12,4,0,6,116,115,116,97,99,107,0,0, +10,1,4,7,12,4,0,5,95,116,97,103,105,0,0,0, +10,1,4,8,12,4,0,4,100,97,116,97,0,0,0,0, +10,1,4,9,11,4,0,0,0,0,0,0,0,0,0,0, +12,5,0,5,101,114,114,111,114,0,0,0,10,1,5,4, +0,0,0,0,12,2,0,8,95,95,105,110,105,116,95,95, +0,0,0,0,10,0,2,1,16,2,0,193,44,18,0,0, +28,2,0,0,9,1,0,2,11,2,0,0,0,0,0,0, +0,0,0,0,28,3,0,0,32,2,0,3,12,5,0,3, +108,101,110,0,13,4,5,0,12,6,0,5,115,116,97,99, +107,0,0,0,9,5,1,6,31,3,5,1,19,3,4,3, +21,3,0,0,18,0,0,56,12,5,0,5,115,116,97,99, +107,0,0,0,9,4,1,5,12,5,0,6,97,112,112,101, +110,100,0,0,9,4,4,5,12,17,0,4,118,97,114,115, +0,0,0,0,9,6,1,17,12,17,0,3,114,50,110,0, +9,7,1,17,12,17,0,3,110,50,114,0,9,8,1,17, +12,17,0,5,95,116,109,112,105,0,0,0,9,9,1,17, +12,17,0,4,109,114,101,103,0,0,0,0,9,10,1,17, +12,17,0,4,115,110,117,109,0,0,0,0,9,11,1,17, +12,17,0,8,95,103,108,111,98,97,108,115,0,0,0,0, +9,12,1,17,12,17,0,6,108,105,110,101,110,111,0,0, +9,13,1,17,12,17,0,7,103,108,111,98,97,108,115,0, +9,14,1,17,12,17,0,5,99,114,101,103,115,0,0,0, +9,15,1,17,12,17,0,4,116,109,112,99,0,0,0,0, +9,16,1,17,27,5,6,11,31,3,5,1,19,3,4,3, +18,0,0,13,12,5,0,5,115,116,97,99,107,0,0,0, +9,4,1,5,12,5,0,6,97,112,112,101,110,100,0,0, +9,4,4,5,28,5,0,0,31,3,5,1,19,3,4,3, +18,0,0,1,27,4,0,0,15,3,4,0,26,5,0,0, +15,4,5,0,26,6,0,0,15,5,6,0,11,7,0,0, +0,0,0,0,0,0,0,0,15,6,7,0,11,8,0,0, +0,0,0,0,0,0,0,0,15,7,8,0,12,11,0,3, +115,116,114,0,13,10,11,0,12,12,0,7,95,115,99,111, +112,101,105,0,9,11,1,12,31,9,11,1,19,9,10,9, +15,8,9,0,15,9,2,0,11,11,0,0,0,0,0,0, +0,0,240,191,15,10,11,0,27,12,0,0,15,11,12,0, +12,14,0,4,114,101,103,115,0,0,0,0,27,13,14,1, +15,12,13,0,11,14,0,0,0,0,0,0,0,0,0,0, +15,13,14,0,12,14,0,4,118,97,114,115,0,0,0,0, +10,1,14,3,12,3,0,3,114,50,110,0,10,1,3,4, +12,3,0,3,110,50,114,0,10,1,3,5,12,3,0,5, +95,116,109,112,105,0,0,0,10,1,3,6,12,3,0,4, +109,114,101,103,0,0,0,0,10,1,3,7,12,3,0,4, +115,110,117,109,0,0,0,0,10,1,3,8,12,3,0,8, +95,103,108,111,98,97,108,115,0,0,0,0,10,1,3,9, +12,3,0,6,108,105,110,101,110,111,0,0,10,1,3,10, +12,3,0,7,103,108,111,98,97,108,115,0,10,1,3,11, +12,3,0,5,99,114,101,103,115,0,0,0,10,1,3,12, +12,3,0,4,116,109,112,99,0,0,0,0,10,1,3,13, +12,4,0,7,95,115,99,111,112,101,105,0,9,3,1,4, +11,4,0,0,0,0,0,0,0,0,240,63,1,3,3,4, +12,4,0,7,95,115,99,111,112,101,105,0,10,1,4,3, +12,5,0,6,105,110,115,101,114,116,0,0,13,4,5,0, +12,6,0,5,99,114,101,103,115,0,0,0,9,5,1,6, +31,3,5,1,19,3,4,3,0,0,0,0,12,3,0,5, +98,101,103,105,110,0,0,0,10,0,3,2,16,3,0,164, +44,7,0,0,28,2,0,0,9,1,0,2,12,4,0,5, +99,114,101,103,115,0,0,0,9,3,1,4,12,4,0,6, +97,112,112,101,110,100,0,0,9,3,3,4,12,5,0,4, +109,114,101,103,0,0,0,0,9,4,1,5,31,2,4,1, +19,2,3,2,12,4,0,4,99,111,100,101,0,0,0,0, +13,3,4,0,12,5,0,3,69,79,70,0,13,4,5,0, +31,2,4,1,19,2,3,2,12,4,0,6,97,115,115,101, +114,116,0,0,13,3,4,0,12,5,0,4,116,109,112,99, +0,0,0,0,9,4,1,5,11,5,0,0,0,0,0,0, +0,0,0,0,23,4,4,5,31,2,4,1,19,2,3,2, +11,2,0,0,0,0,0,0,0,0,240,63,12,5,0,3, +108,101,110,0,13,4,5,0,12,6,0,5,115,116,97,99, +107,0,0,0,9,5,1,6,31,3,5,1,19,3,4,3, +25,2,2,3,21,2,0,0,18,0,0,98,12,4,0,5, +115,116,97,99,107,0,0,0,9,3,1,4,12,4,0,3, +112,111,112,0,9,3,3,4,31,2,0,0,19,2,3,2, +11,4,0,0,0,0,0,0,0,0,0,0,9,3,2,4, +12,4,0,4,118,97,114,115,0,0,0,0,10,1,4,3, +11,4,0,0,0,0,0,0,0,0,240,63,9,3,2,4, +12,4,0,3,114,50,110,0,10,1,4,3,11,4,0,0, +0,0,0,0,0,0,0,64,9,3,2,4,12,4,0,3, +110,50,114,0,10,1,4,3,11,4,0,0,0,0,0,0, +0,0,8,64,9,3,2,4,12,4,0,5,95,116,109,112, +105,0,0,0,10,1,4,3,11,4,0,0,0,0,0,0, +0,0,16,64,9,3,2,4,12,4,0,4,109,114,101,103, +0,0,0,0,10,1,4,3,11,4,0,0,0,0,0,0, +0,0,20,64,9,3,2,4,12,4,0,4,115,110,117,109, +0,0,0,0,10,1,4,3,11,4,0,0,0,0,0,0, +0,0,24,64,9,3,2,4,12,4,0,8,95,103,108,111, +98,97,108,115,0,0,0,0,10,1,4,3,11,4,0,0, +0,0,0,0,0,0,28,64,9,3,2,4,12,4,0,6, +108,105,110,101,110,111,0,0,10,1,4,3,11,4,0,0, +0,0,0,0,0,0,32,64,9,3,2,4,12,4,0,7, +103,108,111,98,97,108,115,0,10,1,4,3,11,4,0,0, +0,0,0,0,0,0,34,64,9,3,2,4,12,4,0,5, +99,114,101,103,115,0,0,0,10,1,4,3,11,4,0,0, +0,0,0,0,0,0,36,64,9,3,2,4,12,4,0,4, +116,109,112,99,0,0,0,0,10,1,4,3,18,0,0,11, +12,4,0,5,115,116,97,99,107,0,0,0,9,3,1,4, +12,4,0,3,112,111,112,0,9,3,3,4,31,2,0,0, +19,2,3,2,18,0,0,1,0,0,0,0,12,4,0,3, +101,110,100,0,10,0,4,3,16,4,0,62,44,7,0,0, +28,2,0,0,9,1,0,2,12,4,0,4,98,105,110,100, +0,0,0,0,13,3,4,0,12,6,0,6,68,83,116,97, +116,101,0,0,13,4,6,0,12,6,0,8,95,95,105,110, +105,116,95,95,0,0,0,0,9,4,4,6,15,5,1,0, +31,2,4,2,19,2,3,2,12,3,0,8,95,95,105,110, +105,116,95,95,0,0,0,0,10,1,3,2,12,4,0,4, +98,105,110,100,0,0,0,0,13,3,4,0,12,6,0,6, +68,83,116,97,116,101,0,0,13,4,6,0,12,6,0,5, +98,101,103,105,110,0,0,0,9,4,4,6,15,5,1,0, +31,2,4,2,19,2,3,2,12,3,0,5,98,101,103,105, +110,0,0,0,10,1,3,2,12,4,0,4,98,105,110,100, +0,0,0,0,13,3,4,0,12,6,0,6,68,83,116,97, +116,101,0,0,13,4,6,0,12,6,0,3,101,110,100,0, +9,4,4,6,15,5,1,0,31,2,4,2,19,2,3,2, +12,3,0,3,101,110,100,0,10,1,3,2,0,0,0,0, +12,5,0,7,95,95,110,101,119,95,95,0,10,0,5,4, +16,5,0,22,44,5,0,0,26,1,0,0,12,4,0,6, +68,83,116,97,116,101,0,0,13,3,4,0,12,4,0,7, +95,95,110,101,119,95,95,0,9,3,3,4,15,4,1,0, +31,2,4,1,19,2,3,2,12,3,0,8,95,95,105,110, +105,116,95,95,0,0,0,0,9,2,1,3,19,4,2,0, +20,1,0,0,0,0,0,0,12,6,0,8,95,95,99,97, +108,108,95,95,0,0,0,0,10,0,6,5,16,0,0,18, +44,5,0,0,28,2,0,0,9,1,0,2,12,4,0,1, +68,0,0,0,13,3,4,0,12,4,0,3,111,117,116,0, +9,3,3,4,12,4,0,6,97,112,112,101,110,100,0,0, +9,3,3,4,15,4,1,0,31,2,4,1,19,2,3,2, +0,0,0,0,12,6,0,6,105,110,115,101,114,116,0,0, +14,6,0,0,16,6,0,68,44,14,0,0,28,2,0,0, +9,1,0,2,12,4,0,6,105,115,116,121,112,101,0,0, +13,3,4,0,15,4,1,0,12,5,0,4,108,105,115,116, +0,0,0,0,31,2,4,2,19,2,3,2,21,2,0,0, +18,0,0,11,12,4,0,6,105,110,115,101,114,116,0,0, +13,3,4,0,15,4,1,0,31,2,4,1,19,2,3,2, +28,2,0,0,20,2,0,0,18,0,0,1,12,5,0,5, +114,97,110,103,101,0,0,0,13,4,5,0,11,5,0,0, +0,0,0,0,0,0,0,0,12,9,0,3,108,101,110,0, +13,8,9,0,15,9,1,0,31,6,9,1,19,6,8,6, +11,7,0,0,0,0,0,0,0,0,16,64,31,3,5,3, +19,3,4,3,11,4,0,0,0,0,0,0,0,0,0,0, +42,2,3,4,18,0,0,19,12,7,0,6,105,110,115,101, +114,116,0,0,13,6,7,0,12,8,0,4,100,97,116,97, +0,0,0,0,15,11,2,0,11,13,0,0,0,0,0,0, +0,0,16,64,1,12,2,13,27,10,11,2,9,9,1,10, +27,7,8,2,31,5,7,1,19,5,6,5,18,0,255,237, +0,0,0,0,12,7,0,5,119,114,105,116,101,0,0,0, +14,7,6,0,16,7,0,107,44,12,0,0,28,2,0,0, +9,1,0,2,12,3,0,4,65,82,71,86,0,0,0,0, +13,2,3,0,12,3,0,6,45,110,111,112,111,115,0,0, +36,2,2,3,21,2,0,0,18,0,0,4,28,2,0,0, +20,2,0,0,18,0,0,1,11,4,0,0,0,0,0,0, +0,0,0,0,9,3,1,4,15,2,3,0,11,5,0,0, +0,0,0,0,0,0,240,63,9,4,1,5,15,3,4,0, +12,5,0,1,68,0,0,0,13,4,5,0,12,5,0,6, +108,105,110,101,110,111,0,0,9,4,4,5,23,1,2,4, +21,1,0,0,18,0,0,4,28,1,0,0,20,1,0,0, +18,0,0,1,12,5,0,1,68,0,0,0,13,4,5,0, +12,5,0,5,108,105,110,101,115,0,0,0,9,4,4,5, +11,6,0,0,0,0,0,0,0,0,240,63,2,5,2,6, +9,4,4,5,15,1,4,0,12,5,0,1,68,0,0,0, +13,4,5,0,12,5,0,6,108,105,110,101,110,111,0,0, +10,4,5,2,12,6,0,1,0,0,0,0,11,7,0,0, +0,0,0,0,0,0,16,64,12,10,0,3,108,101,110,0, +13,9,10,0,15,10,1,0,31,8,10,1,19,8,9,8, +11,9,0,0,0,0,0,0,0,0,16,64,39,8,8,9, +2,7,7,8,3,6,6,7,1,5,1,6,15,4,5,0, +12,7,0,7,99,111,100,101,95,49,54,0,13,6,7,0, +12,10,0,3,80,79,83,0,13,7,10,0,12,11,0,3, +108,101,110,0,13,10,11,0,15,11,4,0,31,8,11,1, +19,8,10,8,11,10,0,0,0,0,0,0,0,0,16,64, +4,8,8,10,15,9,2,0,31,5,7,3,19,5,6,5, +12,7,0,5,119,114,105,116,101,0,0,0,13,6,7,0, +15,7,4,0,31,5,7,1,19,5,6,5,0,0,0,0, +12,8,0,6,115,101,116,112,111,115,0,0,14,8,7,0, +16,8,0,110,44,13,0,0,28,2,0,0,9,1,0,2, +11,2,0,0,0,0,0,0,0,0,0,0,28,3,0,0, +32,2,0,3,11,3,0,0,0,0,0,0,0,0,0,0, +28,4,0,0,32,3,0,4,11,4,0,0,0,0,0,0, +0,0,0,0,28,5,0,0,32,4,0,5,11,5,0,0, +0,0,0,0,0,0,0,0,12,8,0,6,105,115,116,121, +112,101,0,0,13,7,8,0,15,8,1,0,12,9,0,6, +110,117,109,98,101,114,0,0,31,6,8,2,19,6,7,6, +23,5,5,6,21,5,0,0,18,0,0,4,28,5,0,0, +37,5,0,0,18,0,0,1,11,5,0,0,0,0,0,0, +0,0,0,0,12,8,0,6,105,115,116,121,112,101,0,0, +13,7,8,0,15,8,2,0,12,9,0,6,110,117,109,98, +101,114,0,0,31,6,8,2,19,6,7,6,23,5,5,6, +21,5,0,0,18,0,0,4,28,5,0,0,37,5,0,0, +18,0,0,1,11,5,0,0,0,0,0,0,0,0,0,0, +12,8,0,6,105,115,116,121,112,101,0,0,13,7,8,0, +15,8,3,0,12,9,0,6,110,117,109,98,101,114,0,0, +31,6,8,2,19,6,7,6,23,5,5,6,21,5,0,0, +18,0,0,4,28,5,0,0,37,5,0,0,18,0,0,1, +11,5,0,0,0,0,0,0,0,0,0,0,12,8,0,6, +105,115,116,121,112,101,0,0,13,7,8,0,15,8,4,0, +12,9,0,6,110,117,109,98,101,114,0,0,31,6,8,2, +19,6,7,6,23,5,5,6,21,5,0,0,18,0,0,4, +28,5,0,0,37,5,0,0,18,0,0,1,12,7,0,5, +119,114,105,116,101,0,0,0,13,6,7,0,12,8,0,4, +99,111,100,101,0,0,0,0,15,9,1,0,15,10,2,0, +15,11,3,0,15,12,4,0,27,7,8,5,31,5,7,1, +19,5,6,5,0,0,0,0,12,9,0,4,99,111,100,101, +0,0,0,0,14,9,8,0,16,9,0,45,44,11,0,0, +28,2,0,0,9,1,0,2,28,3,0,0,9,2,0,3, +28,4,0,0,9,3,0,4,11,5,0,0,0,0,0,0, +0,0,0,0,25,4,3,5,21,4,0,0,18,0,0,7, +11,5,0,0,0,0,0,0,0,0,224,64,1,4,3,5, +15,3,4,0,18,0,0,1,12,6,0,4,99,111,100,101, +0,0,0,0,13,5,6,0,15,6,1,0,15,7,2,0, +11,10,0,0,0,0,0,0,0,224,239,64,6,8,3,10, +11,10,0,0,0,0,0,0,0,0,32,64,41,8,8,10, +11,10,0,0,0,0,0,0,0,224,111,64,6,9,3,10, +11,10,0,0,0,0,0,0,0,0,0,0,41,9,9,10, +31,4,6,4,19,4,5,4,0,0,0,0,12,10,0,7, +99,111,100,101,95,49,54,0,14,10,9,0,16,10,0,32, +44,11,0,0,28,2,0,0,9,1,0,2,28,3,0,0, +9,2,0,3,28,4,0,0,9,3,0,4,12,5,0,4, +99,111,100,101,0,0,0,0,15,6,1,0,15,7,2,0, +11,10,0,0,0,0,0,0,0,224,239,64,6,8,3,10, +11,10,0,0,0,0,0,0,0,0,32,64,41,8,8,10, +11,10,0,0,0,0,0,0,0,224,111,64,6,9,3,10, +11,10,0,0,0,0,0,0,0,0,0,0,41,9,9,10, +27,4,5,5,20,4,0,0,0,0,0,0,12,11,0,10, +103,101,116,95,99,111,100,101,49,54,0,0,14,11,10,0, +16,11,0,60,44,11,0,0,28,2,0,0,9,1,0,2, +28,2,0,0,28,3,0,0,32,2,0,3,12,5,0,7, +103,101,116,95,116,109,112,0,13,4,5,0,15,5,2,0, +31,3,5,1,19,3,4,3,15,2,3,0,12,5,0,1, +0,0,0,0,11,6,0,0,0,0,0,0,0,0,16,64, +12,9,0,3,108,101,110,0,13,8,9,0,15,9,1,0, +31,7,9,1,19,7,8,7,11,8,0,0,0,0,0,0, +0,0,16,64,39,7,7,8,2,6,6,7,3,5,5,6, +1,4,1,5,15,3,4,0,12,6,0,7,99,111,100,101, +95,49,54,0,13,5,6,0,12,9,0,6,83,84,82,73, +78,71,0,0,13,6,9,0,15,7,2,0,12,10,0,3, +108,101,110,0,13,9,10,0,15,10,1,0,31,8,10,1, +19,8,9,8,31,4,6,3,19,4,5,4,12,6,0,5, +119,114,105,116,101,0,0,0,13,5,6,0,15,6,3,0, +31,4,6,1,19,4,5,4,20,2,0,0,0,0,0,0, +12,12,0,10,95,100,111,95,115,116,114,105,110,103,0,0, +14,12,11,0,16,12,0,20,44,8,0,0,28,2,0,0, +9,1,0,2,28,2,0,0,28,3,0,0,32,2,0,3, +12,5,0,10,95,100,111,95,115,116,114,105,110,103,0,0, +13,4,5,0,12,7,0,3,118,97,108,0,9,5,1,7, +15,6,2,0,31,3,5,2,19,3,4,3,20,3,0,0, +0,0,0,0,12,13,0,9,100,111,95,115,116,114,105,110, +103,0,0,0,14,13,12,0,16,13,0,53,44,10,0,0, +28,2,0,0,9,1,0,2,28,2,0,0,28,3,0,0, +32,2,0,3,12,5,0,7,103,101,116,95,116,109,112,0, +13,4,5,0,15,5,2,0,31,3,5,1,19,3,4,3, +15,2,3,0,12,5,0,4,99,111,100,101,0,0,0,0, +13,4,5,0,12,9,0,6,78,85,77,66,69,82,0,0, +13,5,9,0,15,6,2,0,11,7,0,0,0,0,0,0, +0,0,0,0,11,8,0,0,0,0,0,0,0,0,0,0, +31,3,5,4,19,3,4,3,12,5,0,5,119,114,105,116, +101,0,0,0,13,4,5,0,12,7,0,5,102,112,97,99, +107,0,0,0,13,6,7,0,12,9,0,6,110,117,109,98, +101,114,0,0,13,8,9,0,15,9,1,0,31,7,9,1, +19,7,8,7,31,5,7,1,19,5,6,5,31,3,5,1, +19,3,4,3,20,2,0,0,0,0,0,0,12,14,0,10, +95,100,111,95,110,117,109,98,101,114,0,0,14,14,13,0, +16,14,0,20,44,8,0,0,28,2,0,0,9,1,0,2, +28,2,0,0,28,3,0,0,32,2,0,3,12,5,0,10, +95,100,111,95,110,117,109,98,101,114,0,0,13,4,5,0, +12,7,0,3,118,97,108,0,9,5,1,7,15,6,2,0, +31,3,5,2,19,3,4,3,20,3,0,0,0,0,0,0, +12,15,0,9,100,111,95,110,117,109,98,101,114,0,0,0, +14,15,14,0,16,15,0,35,44,6,0,0,12,4,0,3, +115,116,114,0,13,3,4,0,12,5,0,1,68,0,0,0, +13,4,5,0,12,5,0,5,95,116,97,103,105,0,0,0, +9,4,4,5,31,2,4,1,19,2,3,2,15,1,2,0, +12,3,0,1,68,0,0,0,13,2,3,0,12,4,0,1, +68,0,0,0,13,3,4,0,12,4,0,5,95,116,97,103, +105,0,0,0,9,3,3,4,11,4,0,0,0,0,0,0, +0,0,240,63,1,3,3,4,12,4,0,5,95,116,97,103, +105,0,0,0,10,2,4,3,20,1,0,0,0,0,0,0, +12,16,0,7,103,101,116,95,116,97,103,0,14,16,15,0, +16,16,0,25,44,5,0,0,12,4,0,7,103,101,116,95, +116,97,103,0,13,3,4,0,31,2,0,0,19,2,3,2, +15,1,2,0,12,4,0,1,68,0,0,0,13,3,4,0, +12,4,0,6,116,115,116,97,99,107,0,0,9,3,3,4, +12,4,0,6,97,112,112,101,110,100,0,0,9,3,3,4, +15,4,1,0,31,2,4,1,19,2,3,2,20,1,0,0, +0,0,0,0,12,17,0,9,115,116,97,99,107,95,116,97, +103,0,0,0,14,17,16,0,16,17,0,15,44,4,0,0, +12,3,0,1,68,0,0,0,13,2,3,0,12,3,0,6, +116,115,116,97,99,107,0,0,9,2,2,3,12,3,0,3, +112,111,112,0,9,2,2,3,31,1,0,0,19,1,2,1, +0,0,0,0,12,18,0,7,112,111,112,95,116,97,103,0, +14,18,17,0,16,18,0,52,44,12,0,0,12,2,0,1, +42,0,0,0,9,1,0,2,12,3,0,1,68,0,0,0, +13,2,3,0,12,3,0,4,115,110,117,109,0,0,0,0, +9,2,2,3,12,3,0,1,58,0,0,0,1,2,2,3, +12,4,0,1,58,0,0,0,12,5,0,4,106,111,105,110, +0,0,0,0,9,4,4,5,27,6,0,0,11,8,0,0, +0,0,0,0,0,0,0,0,42,7,1,8,18,0,0,10, +12,11,0,3,115,116,114,0,13,10,11,0,15,11,7,0, +31,9,11,1,19,9,10,9,28,10,0,0,10,6,10,9, +18,0,255,246,15,5,6,0,31,3,5,1,19,3,4,3, +1,2,2,3,15,1,2,0,12,4,0,6,105,110,115,101, +114,116,0,0,13,3,4,0,12,8,0,3,116,97,103,0, +15,9,1,0,27,4,8,2,31,2,4,1,19,2,3,2, +0,0,0,0,12,19,0,3,116,97,103,0,14,19,18,0, +16,19,0,53,44,12,0,0,12,2,0,1,42,0,0,0, +9,1,0,2,12,3,0,1,68,0,0,0,13,2,3,0, +12,3,0,4,115,110,117,109,0,0,0,0,9,2,2,3, +12,3,0,1,58,0,0,0,1,2,2,3,12,4,0,1, +58,0,0,0,12,5,0,4,106,111,105,110,0,0,0,0, +9,4,4,5,27,6,0,0,11,8,0,0,0,0,0,0, +0,0,0,0,42,7,1,8,18,0,0,10,12,11,0,3, +115,116,114,0,13,10,11,0,15,11,7,0,31,9,11,1, +19,9,10,9,28,10,0,0,10,6,10,9,18,0,255,246, +15,5,6,0,31,3,5,1,19,3,4,3,1,2,2,3, +15,1,2,0,12,4,0,6,105,110,115,101,114,116,0,0, +13,3,4,0,12,8,0,4,106,117,109,112,0,0,0,0, +15,9,1,0,27,4,8,2,31,2,4,1,19,2,3,2, +0,0,0,0,12,20,0,4,106,117,109,112,0,0,0,0, +14,20,19,0,16,20,0,53,44,12,0,0,12,2,0,1, +42,0,0,0,9,1,0,2,12,3,0,1,68,0,0,0, +13,2,3,0,12,3,0,4,115,110,117,109,0,0,0,0, +9,2,2,3,12,3,0,1,58,0,0,0,1,2,2,3, +12,4,0,1,58,0,0,0,12,5,0,4,106,111,105,110, +0,0,0,0,9,4,4,5,27,6,0,0,11,8,0,0, +0,0,0,0,0,0,0,0,42,7,1,8,18,0,0,10, +12,11,0,3,115,116,114,0,13,10,11,0,15,11,7,0, +31,9,11,1,19,9,10,9,28,10,0,0,10,6,10,9, +18,0,255,246,15,5,6,0,31,3,5,1,19,3,4,3, +1,2,2,3,15,1,2,0,12,4,0,6,105,110,115,101, +114,116,0,0,13,3,4,0,12,8,0,6,115,101,116,106, +109,112,0,0,15,9,1,0,27,4,8,2,31,2,4,1, +19,2,3,2,0,0,0,0,12,21,0,6,115,101,116,106, +109,112,0,0,14,21,20,0,16,21,0,62,44,12,0,0, +12,2,0,1,42,0,0,0,9,1,0,2,12,3,0,1, +68,0,0,0,13,2,3,0,12,3,0,4,115,110,117,109, +0,0,0,0,9,2,2,3,12,3,0,1,58,0,0,0, +1,2,2,3,12,4,0,1,58,0,0,0,12,5,0,4, +106,111,105,110,0,0,0,0,9,4,4,5,27,6,0,0, +11,8,0,0,0,0,0,0,0,0,0,0,42,7,1,8, +18,0,0,10,12,11,0,3,115,116,114,0,13,10,11,0, +15,11,7,0,31,9,11,1,19,9,10,9,28,10,0,0, +10,6,10,9,18,0,255,246,15,5,6,0,31,3,5,1, +19,3,4,3,1,2,2,3,15,1,2,0,12,5,0,7, +103,101,116,95,114,101,103,0,13,4,5,0,15,5,1,0, +31,3,5,1,19,3,4,3,15,2,3,0,12,5,0,6, +105,110,115,101,114,116,0,0,13,4,5,0,12,8,0,3, +102,110,99,0,15,9,2,0,15,10,1,0,27,5,8,3, +31,3,5,1,19,3,4,3,20,2,0,0,0,0,0,0, +12,22,0,3,102,110,99,0,14,22,21,0,16,22,1,119, +44,17,0,0,26,2,0,0,15,1,2,0,27,3,0,0, +15,2,3,0,11,4,0,0,0,0,0,0,0,0,0,0, +15,3,4,0,12,6,0,1,68,0,0,0,13,5,6,0, +12,6,0,3,111,117,116,0,9,5,5,6,11,6,0,0, +0,0,0,0,0,0,0,0,42,4,5,6,18,0,0,71, +11,8,0,0,0,0,0,0,0,0,0,0,9,7,4,8, +12,8,0,3,116,97,103,0,23,7,7,8,21,7,0,0, +18,0,0,8,11,8,0,0,0,0,0,0,0,0,240,63, +9,7,4,8,10,1,7,3,18,0,255,240,18,0,0,1, +11,8,0,0,0,0,0,0,0,0,0,0,9,7,4,8, +12,8,0,4,114,101,103,115,0,0,0,0,23,7,7,8, +21,7,0,0,18,0,0,32,12,9,0,6,97,112,112,101, +110,100,0,0,9,8,2,9,12,11,0,10,103,101,116,95, +99,111,100,101,49,54,0,0,13,10,11,0,12,14,0,4, +82,69,71,83,0,0,0,0,13,11,14,0,11,14,0,0, +0,0,0,0,0,0,240,63,9,12,4,14,11,13,0,0, +0,0,0,0,0,0,0,0,31,9,11,3,19,9,10,9, +31,7,9,1,19,7,8,7,11,8,0,0,0,0,0,0, +0,0,240,63,1,7,3,8,15,3,7,0,18,0,255,199, +18,0,0,1,12,9,0,6,97,112,112,101,110,100,0,0, +9,8,2,9,15,9,4,0,31,7,9,1,19,7,8,7, +11,8,0,0,0,0,0,0,0,0,240,63,1,7,3,8, +15,3,7,0,18,0,255,185,12,7,0,5,114,97,110,103, +101,0,0,0,13,6,7,0,11,7,0,0,0,0,0,0, +0,0,0,0,12,10,0,3,108,101,110,0,13,9,10,0, +15,10,2,0,31,8,10,1,19,8,9,8,31,5,7,2, +19,5,6,5,11,6,0,0,0,0,0,0,0,0,0,0, +42,3,5,6,18,0,0,99,9,7,2,3,15,4,7,0, +11,8,0,0,0,0,0,0,0,0,0,0,9,7,4,8, +12,8,0,4,106,117,109,112,0,0,0,0,23,7,7,8, +21,7,0,0,18,0,0,23,12,9,0,10,103,101,116,95, +99,111,100,101,49,54,0,0,13,8,9,0,12,12,0,4, +74,85,77,80,0,0,0,0,13,9,12,0,11,10,0,0, +0,0,0,0,0,0,0,0,11,13,0,0,0,0,0,0, +0,0,240,63,9,12,4,13,9,11,1,12,2,11,11,3, +31,7,9,3,19,7,8,7,10,2,3,7,18,0,0,64, +11,8,0,0,0,0,0,0,0,0,0,0,9,7,4,8, +12,8,0,6,115,101,116,106,109,112,0,0,23,7,7,8, +21,7,0,0,18,0,0,23,12,9,0,10,103,101,116,95, +99,111,100,101,49,54,0,0,13,8,9,0,12,12,0,6, +83,69,84,74,77,80,0,0,13,9,12,0,11,10,0,0, +0,0,0,0,0,0,0,0,11,13,0,0,0,0,0,0, +0,0,240,63,9,12,4,13,9,11,1,12,2,11,11,3, +31,7,9,3,19,7,8,7,10,2,3,7,18,0,0,32, +11,8,0,0,0,0,0,0,0,0,0,0,9,7,4,8, +12,8,0,3,102,110,99,0,23,7,7,8,21,7,0,0, +18,0,0,23,12,9,0,10,103,101,116,95,99,111,100,101, +49,54,0,0,13,8,9,0,12,12,0,3,68,69,70,0, +13,9,12,0,11,12,0,0,0,0,0,0,0,0,240,63, +9,10,4,12,11,13,0,0,0,0,0,0,0,0,0,64, +9,12,4,13,9,11,1,12,2,11,11,3,31,7,9,3, +19,7,8,7,10,2,3,7,18,0,0,1,18,0,255,157, +12,7,0,5,114,97,110,103,101,0,0,0,13,6,7,0, +11,7,0,0,0,0,0,0,0,0,0,0,12,10,0,3, +108,101,110,0,13,9,10,0,15,10,2,0,31,8,10,1, +19,8,9,8,31,5,7,2,19,5,6,5,11,6,0,0, +0,0,0,0,0,0,0,0,42,3,5,6,18,0,0,140, +9,7,2,3,15,4,7,0,11,8,0,0,0,0,0,0, +0,0,0,0,9,7,4,8,12,8,0,4,100,97,116,97, +0,0,0,0,23,7,7,8,21,7,0,0,18,0,0,7, +11,8,0,0,0,0,0,0,0,0,240,63,9,7,4,8, +10,2,3,7,18,0,0,78,11,8,0,0,0,0,0,0, +0,0,0,0,9,7,4,8,12,8,0,4,99,111,100,101, +0,0,0,0,23,7,7,8,21,7,0,0,18,0,0,56, +11,9,0,0,0,0,0,0,0,0,240,63,28,10,0,0, +27,8,9,2,9,7,4,8,11,10,0,0,0,0,0,0, +0,0,0,0,9,9,7,10,15,8,9,0,11,11,0,0, +0,0,0,0,0,0,240,63,9,10,7,11,15,9,10,0, +11,12,0,0,0,0,0,0,0,0,0,64,9,11,7,12, +15,10,11,0,11,13,0,0,0,0,0,0,0,0,8,64, +9,12,7,13,15,11,12,0,12,13,0,3,99,104,114,0, +13,12,13,0,15,13,8,0,31,7,13,1,19,7,12,7, +12,14,0,3,99,104,114,0,13,13,14,0,15,14,9,0, +31,12,14,1,19,12,13,12,1,7,7,12,12,14,0,3, +99,104,114,0,13,13,14,0,15,14,10,0,31,12,14,1, +19,12,13,12,1,7,7,12,12,14,0,3,99,104,114,0, +13,13,14,0,15,14,11,0,31,12,14,1,19,12,13,12, +1,7,7,12,10,2,3,7,18,0,0,13,12,13,0,3, +115,116,114,0,13,12,13,0,12,14,0,4,104,117,104,63, +0,0,0,0,15,15,4,0,27,13,14,2,31,7,13,1, +19,7,12,7,37,7,0,0,18,0,0,1,12,13,0,3, +108,101,110,0,13,12,13,0,9,13,2,3,31,7,13,1, +19,7,12,7,11,12,0,0,0,0,0,0,0,0,16,64, +35,7,7,12,21,7,0,0,18,0,0,32,12,7,0,5, +99,111,100,101,32,0,0,0,12,14,0,3,115,116,114,0, +13,13,14,0,15,14,3,0,31,12,14,1,19,12,13,12, +1,7,7,12,12,12,0,17,32,105,115,32,119,114,111,110, +103,32,108,101,110,103,116,104,32,0,0,0,1,7,7,12, +12,14,0,3,115,116,114,0,13,13,14,0,12,16,0,3, +108,101,110,0,13,15,16,0,9,16,2,3,31,14,16,1, +19,14,15,14,31,12,14,1,19,12,13,12,1,7,7,12, +37,7,0,0,18,0,0,1,18,0,255,116,12,6,0,1, +68,0,0,0,13,5,6,0,12,6,0,3,111,117,116,0, +10,5,6,2,0,0,0,0,12,23,0,8,109,97,112,95, +116,97,103,115,0,0,0,0,14,23,22,0,16,23,0,27, +44,5,0,0,28,1,0,0,28,2,0,0,32,1,0,2, +28,3,0,0,35,2,1,3,21,2,0,0,18,0,0,3, +20,1,0,0,18,0,0,1,12,4,0,8,103,101,116,95, +116,109,112,115,0,0,0,0,13,3,4,0,11,4,0,0, +0,0,0,0,0,0,240,63,31,2,4,1,19,2,3,2, +11,3,0,0,0,0,0,0,0,0,0,0,9,2,2,3, +20,2,0,0,0,0,0,0,12,24,0,7,103,101,116,95, +116,109,112,0,14,24,23,0,16,24,0,84,44,14,0,0, +28,2,0,0,9,1,0,2,12,5,0,5,97,108,108,111, +99,0,0,0,13,4,5,0,15,5,1,0,31,3,5,1, +19,3,4,3,15,2,3,0,12,6,0,5,114,97,110,103, +101,0,0,0,13,5,6,0,15,6,2,0,1,7,2,1, +31,4,6,2,19,4,5,4,15,3,4,0,11,5,0,0, +0,0,0,0,0,0,0,0,42,4,3,5,18,0,0,42, +12,8,0,7,115,101,116,95,114,101,103,0,13,7,8,0, +15,8,4,0,12,9,0,1,36,0,0,0,12,12,0,3, +115,116,114,0,13,11,12,0,12,13,0,1,68,0,0,0, +13,12,13,0,12,13,0,5,95,116,109,112,105,0,0,0, +9,12,12,13,31,10,12,1,19,10,11,10,1,9,9,10, +31,6,8,2,19,6,7,6,12,7,0,1,68,0,0,0, +13,6,7,0,12,8,0,1,68,0,0,0,13,7,8,0, +12,8,0,5,95,116,109,112,105,0,0,0,9,7,7,8, +11,8,0,0,0,0,0,0,0,0,240,63,1,7,7,8, +12,8,0,5,95,116,109,112,105,0,0,0,10,6,8,7, +18,0,255,214,12,6,0,1,68,0,0,0,13,5,6,0, +12,7,0,1,68,0,0,0,13,6,7,0,12,7,0,4, +116,109,112,99,0,0,0,0,9,6,6,7,1,6,6,1, +12,7,0,4,116,109,112,99,0,0,0,0,10,5,7,6, +20,3,0,0,0,0,0,0,12,25,0,8,103,101,116,95, +116,109,112,115,0,0,0,0,14,25,24,0,16,25,0,69, +44,16,0,0,28,2,0,0,9,1,0,2,12,4,0,0, +0,0,0,0,12,5,0,4,106,111,105,110,0,0,0,0, +9,4,4,5,27,6,0,0,12,10,0,5,114,97,110,103, +101,0,0,0,13,9,10,0,11,10,0,0,0,0,0,0, +0,0,0,0,12,13,0,3,109,105,110,0,13,12,13,0, +11,13,0,0,0,0,0,0,0,0,112,64,12,15,0,1, +68,0,0,0,13,14,15,0,12,15,0,4,109,114,101,103, +0,0,0,0,9,14,14,15,1,14,14,1,31,11,13,2, +19,11,12,11,31,8,10,2,19,8,9,8,11,9,0,0, +0,0,0,0,0,0,0,0,42,7,8,9,18,0,0,14, +12,10,0,2,48,49,0,0,12,12,0,1,68,0,0,0, +13,11,12,0,12,12,0,3,114,50,110,0,9,11,11,12, +36,11,11,7,9,10,10,11,28,11,0,0,10,6,11,10, +18,0,255,242,15,5,6,0,31,3,5,1,19,3,4,3, +15,2,3,0,12,5,0,5,105,110,100,101,120,0,0,0, +9,4,2,5,12,5,0,1,48,0,0,0,3,5,5,1, +31,3,5,1,19,3,4,3,20,3,0,0,0,0,0,0, +12,26,0,5,97,108,108,111,99,0,0,0,14,26,25,0, +16,26,0,29,44,4,0,0,28,2,0,0,9,1,0,2, +28,3,0,0,23,2,1,3,21,2,0,0,18,0,0,6, +11,2,0,0,0,0,0,0,0,0,0,0,20,2,0,0, +18,0,0,1,12,3,0,1,68,0,0,0,13,2,3,0, +12,3,0,3,114,50,110,0,9,2,2,3,9,2,2,1, +11,3,0,0,0,0,0,0,0,0,0,0,9,2,2,3, +12,3,0,1,36,0,0,0,23,2,2,3,20,2,0,0, +0,0,0,0,12,27,0,6,105,115,95,116,109,112,0,0, +14,27,26,0,16,27,0,31,44,7,0,0,28,2,0,0, +9,1,0,2,12,4,0,1,68,0,0,0,13,3,4,0, +12,4,0,3,114,50,110,0,9,3,3,4,9,3,3,1, +15,2,3,0,12,5,0,8,102,114,101,101,95,114,101,103, +0,0,0,0,13,4,5,0,15,5,1,0,31,3,5,1, +19,3,4,3,12,5,0,7,115,101,116,95,114,101,103,0, +13,4,5,0,15,5,1,0,12,6,0,1,42,0,0,0, +1,6,6,2,31,3,5,2,19,3,4,3,0,0,0,0, +12,28,0,6,117,110,95,116,109,112,0,0,14,28,27,0, +16,28,0,24,44,5,0,0,28,2,0,0,9,1,0,2, +12,4,0,6,105,115,95,116,109,112,0,0,13,3,4,0, +15,4,1,0,31,2,4,1,19,2,3,2,21,2,0,0, +18,0,0,10,12,4,0,8,102,114,101,101,95,114,101,103, +0,0,0,0,13,3,4,0,15,4,1,0,31,2,4,1, +19,2,3,2,18,0,0,1,20,1,0,0,0,0,0,0, +12,29,0,8,102,114,101,101,95,116,109,112,0,0,0,0, +14,29,28,0,16,29,0,19,44,7,0,0,28,2,0,0, +9,1,0,2,11,3,0,0,0,0,0,0,0,0,0,0, +42,2,1,3,18,0,0,10,12,6,0,8,102,114,101,101, +95,116,109,112,0,0,0,0,13,5,6,0,15,6,2,0, +31,4,6,1,19,4,5,4,18,0,255,246,0,0,0,0, +12,30,0,9,102,114,101,101,95,116,109,112,115,0,0,0, +14,30,29,0,16,30,0,43,44,8,0,0,28,2,0,0, +9,1,0,2,12,3,0,1,68,0,0,0,13,2,3,0, +12,3,0,3,110,50,114,0,9,2,2,3,36,2,2,1, +11,3,0,0,0,0,0,0,0,0,0,0,23,2,2,3, +21,2,0,0,18,0,0,18,12,4,0,7,115,101,116,95, +114,101,103,0,13,3,4,0,12,7,0,5,97,108,108,111, +99,0,0,0,13,6,7,0,11,7,0,0,0,0,0,0, +0,0,240,63,31,4,7,1,19,4,6,4,15,5,1,0, +31,2,4,2,19,2,3,2,18,0,0,1,12,3,0,1, +68,0,0,0,13,2,3,0,12,3,0,3,110,50,114,0, +9,2,2,3,9,2,2,1,20,2,0,0,0,0,0,0, +12,31,0,7,103,101,116,95,114,101,103,0,14,31,30,0, +16,31,0,44,44,9,0,0,28,2,0,0,9,1,0,2, +28,3,0,0,9,2,0,3,12,4,0,1,68,0,0,0, +13,3,4,0,12,4,0,3,110,50,114,0,9,3,3,4, +10,3,2,1,12,4,0,1,68,0,0,0,13,3,4,0, +12,4,0,3,114,50,110,0,9,3,3,4,10,3,1,2, +12,4,0,1,68,0,0,0,13,3,4,0,12,6,0,3, +109,97,120,0,13,5,6,0,12,8,0,1,68,0,0,0, +13,6,8,0,12,8,0,4,109,114,101,103,0,0,0,0, +9,6,6,8,11,8,0,0,0,0,0,0,0,0,240,63, +1,7,1,8,31,4,6,2,19,4,5,4,12,5,0,4, +109,114,101,103,0,0,0,0,10,3,5,4,0,0,0,0, +12,32,0,7,115,101,116,95,114,101,103,0,14,32,31,0, +16,32,0,55,44,5,0,0,28,2,0,0,9,1,0,2, +12,4,0,6,105,115,95,116,109,112,0,0,13,3,4,0, +15,4,1,0,31,2,4,1,19,2,3,2,21,2,0,0, +18,0,0,20,12,3,0,1,68,0,0,0,13,2,3,0, +12,4,0,1,68,0,0,0,13,3,4,0,12,4,0,4, +116,109,112,99,0,0,0,0,9,3,3,4,11,4,0,0, +0,0,0,0,0,0,240,63,2,3,3,4,12,4,0,4, +116,109,112,99,0,0,0,0,10,2,4,3,18,0,0,1, +12,4,0,1,68,0,0,0,13,3,4,0,12,4,0,3, +114,50,110,0,9,3,3,4,9,3,3,1,15,2,3,0, +12,4,0,1,68,0,0,0,13,3,4,0,12,4,0,3, +114,50,110,0,9,3,3,4,43,3,1,0,12,4,0,1, +68,0,0,0,13,3,4,0,12,4,0,3,110,50,114,0, +9,3,3,4,43,3,2,0,0,0,0,0,12,33,0,8, +102,114,101,101,95,114,101,103,0,0,0,0,14,33,32,0, +16,33,0,49,44,14,0,0,28,2,0,0,9,1,0,2, +28,3,0,0,9,2,0,3,12,5,0,5,105,116,101,109, +115,0,0,0,9,4,1,5,15,3,4,0,12,5,0,3, +118,97,108,0,9,4,1,5,28,6,0,0,11,7,0,0, +0,0,0,0,0,0,240,191,27,5,6,2,9,4,4,5, +12,5,0,3,118,97,108,0,10,1,5,4,12,7,0,5, +84,111,107,101,110,0,0,0,13,6,7,0,12,11,0,3, +112,111,115,0,9,7,1,11,12,8,0,6,115,121,109,98, +111,108,0,0,12,9,0,1,61,0,0,0,11,13,0,0, +0,0,0,0,0,0,0,0,9,11,3,13,15,12,1,0, +27,10,11,2,31,5,7,4,19,5,6,5,15,4,5,0, +15,6,4,0,31,5,6,1,19,5,2,5,20,5,0,0, +0,0,0,0,12,34,0,7,105,109,97,110,97,103,101,0, +14,34,33,0,16,34,0,68,44,13,0,0,28,2,0,0, +9,1,0,2,28,3,0,0,9,2,0,3,28,4,0,0, +9,3,0,4,28,4,0,0,28,5,0,0,32,4,0,5, +12,7,0,7,103,101,116,95,116,109,112,0,13,6,7,0, +15,7,4,0,31,5,7,1,19,5,6,5,15,4,5,0, +12,8,0,2,100,111,0,0,13,7,8,0,15,8,2,0, +15,9,4,0,31,6,8,2,19,6,7,6,15,5,6,0, +12,9,0,2,100,111,0,0,13,8,9,0,15,9,3,0, +31,7,9,1,19,7,8,7,15,6,7,0,15,7,5,0, +15,5,6,0,12,9,0,4,99,111,100,101,0,0,0,0, +13,8,9,0,15,9,1,0,15,10,4,0,15,11,7,0, +15,12,5,0,31,6,9,4,19,6,8,6,35,6,4,7, +21,6,0,0,18,0,0,10,12,9,0,8,102,114,101,101, +95,116,109,112,0,0,0,0,13,8,9,0,15,9,7,0, +31,6,9,1,19,6,8,6,18,0,0,1,12,9,0,8, +102,114,101,101,95,116,109,112,0,0,0,0,13,8,9,0, +15,9,5,0,31,6,9,1,19,6,8,6,20,4,0,0, +0,0,0,0,12,35,0,5,105,110,102,105,120,0,0,0, +14,35,34,0,16,35,0,136,44,15,0,0,28,2,0,0, +9,1,0,2,28,3,0,0,9,2,0,3,28,4,0,0, +9,3,0,4,28,5,0,0,9,4,0,5,28,5,0,0, +28,6,0,0,32,5,0,6,12,8,0,7,103,101,116,95, +116,109,112,0,13,7,8,0,15,8,5,0,31,6,8,1, +19,6,7,6,15,5,6,0,12,9,0,7,103,101,116,95, +116,109,112,0,13,8,9,0,31,7,0,0,19,7,8,7, +15,6,7,0,12,9,0,10,95,100,111,95,110,117,109,98, +101,114,0,0,13,8,9,0,15,9,1,0,31,7,9,1, +19,7,8,7,15,1,7,0,12,10,0,7,103,101,116,95, +116,97,103,0,13,9,10,0,31,8,0,0,19,8,9,8, +15,7,8,0,12,10,0,2,100,111,0,0,13,9,10,0, +15,10,3,0,15,11,5,0,31,8,10,2,19,8,9,8, +15,5,8,0,12,10,0,4,99,111,100,101,0,0,0,0, +13,9,10,0,12,14,0,2,69,81,0,0,13,10,14,0, +15,11,6,0,15,12,5,0,15,13,1,0,31,8,10,4, +19,8,9,8,12,10,0,4,99,111,100,101,0,0,0,0, +13,9,10,0,12,12,0,2,73,70,0,0,13,10,12,0, +15,11,6,0,31,8,10,2,19,8,9,8,12,10,0,4, +106,117,109,112,0,0,0,0,13,9,10,0,15,10,7,0, +12,11,0,4,101,108,115,101,0,0,0,0,31,8,10,2, +19,8,9,8,12,10,0,4,106,117,109,112,0,0,0,0, +13,9,10,0,15,10,7,0,12,11,0,3,101,110,100,0, +31,8,10,2,19,8,9,8,12,10,0,3,116,97,103,0, +13,9,10,0,15,10,7,0,12,11,0,4,101,108,115,101, +0,0,0,0,31,8,10,2,19,8,9,8,12,10,0,2, +100,111,0,0,13,9,10,0,15,10,4,0,15,11,5,0, +31,8,10,2,19,8,9,8,15,5,8,0,12,10,0,3, +116,97,103,0,13,9,10,0,15,10,7,0,12,11,0,3, +101,110,100,0,31,8,10,2,19,8,9,8,12,10,0,8, +102,114,101,101,95,116,109,112,0,0,0,0,13,9,10,0, +15,10,6,0,31,8,10,1,19,8,9,8,12,10,0,8, +102,114,101,101,95,116,109,112,0,0,0,0,13,9,10,0, +15,10,1,0,31,8,10,1,19,8,9,8,20,5,0,0, +0,0,0,0,12,36,0,8,115,115,95,105,110,102,105,120, +0,0,0,0,14,36,35,0,16,36,0,26,44,7,0,0, +28,1,0,0,28,2,0,0,32,1,0,2,12,4,0,7, +103,101,116,95,116,109,112,0,13,3,4,0,15,4,1,0, +31,2,4,1,19,2,3,2,15,1,2,0,12,4,0,4, +99,111,100,101,0,0,0,0,13,3,4,0,12,6,0,4, +78,79,78,69,0,0,0,0,13,4,6,0,15,5,1,0, +31,2,4,2,19,2,3,2,20,1,0,0,0,0,0,0, +12,37,0,8,95,100,111,95,110,111,110,101,0,0,0,0, +14,37,36,0,16,37,2,41,44,33,0,0,28,2,0,0, +9,1,0,2,28,2,0,0,28,3,0,0,32,2,0,3, +12,5,0,1,61,0,0,0,27,4,5,1,15,3,4,0, +12,6,0,2,43,61,0,0,12,7,0,2,45,61,0,0, +12,8,0,2,42,61,0,0,12,9,0,2,47,61,0,0, +27,5,6,4,15,4,5,0,12,7,0,1,60,0,0,0, +12,8,0,1,62,0,0,0,12,9,0,2,60,61,0,0, +12,10,0,2,62,61,0,0,12,11,0,2,61,61,0,0, +12,12,0,2,33,61,0,0,27,6,7,6,15,5,6,0, +12,8,0,1,43,0,0,0,12,32,0,3,65,68,68,0, +13,9,32,0,12,10,0,1,42,0,0,0,12,32,0,3, +77,85,76,0,13,11,32,0,12,12,0,1,47,0,0,0, +12,32,0,3,68,73,86,0,13,13,32,0,12,14,0,2, +42,42,0,0,12,32,0,3,80,79,87,0,13,15,32,0, +12,16,0,1,45,0,0,0,12,32,0,3,83,85,66,0, +13,17,32,0,12,18,0,3,97,110,100,0,12,32,0,3, +65,78,68,0,13,19,32,0,12,20,0,2,111,114,0,0, +12,32,0,2,79,82,0,0,13,21,32,0,12,22,0,1, +37,0,0,0,12,32,0,3,77,79,68,0,13,23,32,0, +12,24,0,2,62,62,0,0,12,32,0,3,82,83,72,0, +13,25,32,0,12,26,0,2,60,60,0,0,12,32,0,3, +76,83,72,0,13,27,32,0,12,28,0,1,38,0,0,0, +12,32,0,3,65,78,68,0,13,29,32,0,12,30,0,1, +124,0,0,0,12,32,0,2,79,82,0,0,13,31,32,0, +26,7,8,24,15,6,7,0,12,8,0,3,118,97,108,0, +9,7,1,8,12,8,0,4,78,111,110,101,0,0,0,0, +23,7,7,8,21,7,0,0,18,0,0,11,12,9,0,8, +95,100,111,95,110,111,110,101,0,0,0,0,13,8,9,0, +15,9,2,0,31,7,9,1,19,7,8,7,20,7,0,0, +18,0,0,1,12,8,0,3,118,97,108,0,9,7,1,8, +12,8,0,4,84,114,117,101,0,0,0,0,23,7,7,8, +21,7,0,0,18,0,0,13,12,9,0,10,95,100,111,95, +110,117,109,98,101,114,0,0,13,8,9,0,12,9,0,1, +49,0,0,0,15,10,2,0,31,7,9,2,19,7,8,7, +20,7,0,0,18,0,0,1,12,8,0,3,118,97,108,0, +9,7,1,8,12,8,0,5,70,97,108,115,101,0,0,0, +23,7,7,8,21,7,0,0,18,0,0,13,12,9,0,10, +95,100,111,95,110,117,109,98,101,114,0,0,13,8,9,0, +12,9,0,1,48,0,0,0,15,10,2,0,31,7,9,2, +19,7,8,7,20,7,0,0,18,0,0,1,12,9,0,5, +105,116,101,109,115,0,0,0,9,8,1,9,15,7,8,0, +12,9,0,3,97,110,100,0,12,10,0,2,111,114,0,0, +27,8,9,2,12,10,0,3,118,97,108,0,9,9,1,10, +36,8,8,9,21,8,0,0,18,0,0,36,12,11,0,3, +105,110,116,0,13,10,11,0,12,12,0,3,118,97,108,0, +9,11,1,12,12,12,0,2,111,114,0,0,23,11,11,12, +31,9,11,1,19,9,10,9,15,8,9,0,12,11,0,8, +115,115,95,105,110,102,105,120,0,0,0,0,13,10,11,0, +15,11,8,0,12,17,0,3,118,97,108,0,9,16,1,17, +9,12,6,16,11,16,0,0,0,0,0,0,0,0,0,0, +9,13,7,16,11,16,0,0,0,0,0,0,0,0,240,63, +9,14,7,16,15,15,2,0,31,9,11,5,19,9,10,9, +20,9,0,0,18,0,0,1,12,11,0,3,118,97,108,0, +9,10,1,11,36,9,4,10,21,9,0,0,18,0,0,15, +12,11,0,7,105,109,97,110,97,103,101,0,13,10,11,0, +15,11,1,0,12,13,0,9,100,111,95,115,121,109,98,111, +108,0,0,0,13,12,13,0,31,9,11,2,19,9,10,9, +20,9,0,0,18,0,0,1,12,10,0,3,118,97,108,0, +9,9,1,10,12,10,0,2,105,115,0,0,23,9,9,10, +21,9,0,0,18,0,0,21,12,11,0,5,105,110,102,105, +120,0,0,0,13,10,11,0,12,15,0,2,69,81,0,0, +13,11,15,0,11,15,0,0,0,0,0,0,0,0,0,0, +9,12,7,15,11,15,0,0,0,0,0,0,0,0,240,63, +9,13,7,15,15,14,2,0,31,9,11,4,19,9,10,9, +20,9,0,0,18,0,0,1,12,10,0,3,118,97,108,0, +9,9,1,10,12,10,0,5,105,115,110,111,116,0,0,0, +23,9,9,10,21,9,0,0,18,0,0,21,12,11,0,5, +105,110,102,105,120,0,0,0,13,10,11,0,12,15,0,3, +67,77,80,0,13,11,15,0,11,15,0,0,0,0,0,0, +0,0,0,0,9,12,7,15,11,15,0,0,0,0,0,0, +0,0,240,63,9,13,7,15,15,14,2,0,31,9,11,4, +19,9,10,9,20,9,0,0,18,0,0,1,12,10,0,3, +118,97,108,0,9,9,1,10,12,10,0,3,110,111,116,0, +23,9,9,10,21,9,0,0,18,0,0,32,12,11,0,5, +105,110,102,105,120,0,0,0,13,10,11,0,12,15,0,2, +69,81,0,0,13,11,15,0,12,16,0,5,84,111,107,101, +110,0,0,0,13,15,16,0,12,19,0,3,112,111,115,0, +9,16,1,19,12,17,0,6,110,117,109,98,101,114,0,0, +11,18,0,0,0,0,0,0,0,0,0,0,31,12,16,3, +19,12,15,12,11,15,0,0,0,0,0,0,0,0,0,0, +9,13,7,15,15,14,2,0,31,9,11,4,19,9,10,9, +20,9,0,0,18,0,0,1,12,10,0,3,118,97,108,0, +9,9,1,10,12,10,0,2,105,110,0,0,23,9,9,10, +21,9,0,0,18,0,0,21,12,11,0,5,105,110,102,105, +120,0,0,0,13,10,11,0,12,15,0,3,72,65,83,0, +13,11,15,0,11,15,0,0,0,0,0,0,0,0,240,63, +9,12,7,15,11,15,0,0,0,0,0,0,0,0,0,0, +9,13,7,15,15,14,2,0,31,9,11,4,19,9,10,9, +20,9,0,0,18,0,0,1,12,10,0,3,118,97,108,0, +9,9,1,10,12,10,0,5,110,111,116,105,110,0,0,0, +23,9,9,10,21,9,0,0,18,0,0,51,12,11,0,5, +105,110,102,105,120,0,0,0,13,10,11,0,12,15,0,3, +72,65,83,0,13,11,15,0,11,15,0,0,0,0,0,0, +0,0,240,63,9,12,7,15,11,15,0,0,0,0,0,0, +0,0,0,0,9,13,7,15,15,14,2,0,31,9,11,4, +19,9,10,9,15,2,9,0,12,12,0,10,95,100,111,95, +110,117,109,98,101,114,0,0,13,11,12,0,12,12,0,1, +48,0,0,0,31,10,12,1,19,10,11,10,15,9,10,0, +12,12,0,4,99,111,100,101,0,0,0,0,13,11,12,0, +12,16,0,2,69,81,0,0,13,12,16,0,15,13,2,0, +15,14,2,0,12,17,0,8,102,114,101,101,95,116,109,112, +0,0,0,0,13,16,17,0,15,17,9,0,31,15,17,1, +19,15,16,15,31,10,12,4,19,10,11,10,20,2,0,0, +18,0,0,1,12,12,0,3,118,97,108,0,9,11,1,12, +36,10,3,11,21,10,0,0,18,0,0,18,12,12,0,10, +100,111,95,115,101,116,95,99,116,120,0,0,13,11,12,0, +11,14,0,0,0,0,0,0,0,0,0,0,9,12,7,14, +11,14,0,0,0,0,0,0,0,0,240,63,9,13,7,14, +31,10,12,2,19,10,11,10,20,10,0,0,18,0,0,118, +12,12,0,3,118,97,108,0,9,11,1,12,36,10,5,11, +21,10,0,0,18,0,0,91,11,12,0,0,0,0,0,0, +0,0,0,0,9,11,7,12,15,10,11,0,11,13,0,0, +0,0,0,0,0,0,240,63,9,12,7,13,15,11,12,0, +15,12,10,0,15,10,11,0,12,14,0,3,118,97,108,0, +9,13,1,14,15,11,13,0,12,14,0,1,62,0,0,0, +12,15,0,2,62,61,0,0,27,13,14,2,11,15,0,0, +0,0,0,0,0,0,0,0,9,14,11,15,36,13,13,14, +21,13,0,0,18,0,0,17,15,13,10,0,15,14,12,0, +12,16,0,1,60,0,0,0,11,19,0,0,0,0,0,0, +0,0,240,63,28,20,0,0,27,18,19,2,9,17,11,18, +1,16,16,17,15,15,16,0,15,12,13,0,15,10,14,0, +15,11,15,0,18,0,0,1,12,15,0,2,69,81,0,0, +13,14,15,0,15,13,14,0,12,15,0,1,60,0,0,0, +23,14,11,15,21,14,0,0,18,0,0,6,12,15,0,2, +76,84,0,0,13,14,15,0,15,13,14,0,18,0,0,1, +12,15,0,2,60,61,0,0,23,14,11,15,21,14,0,0, +18,0,0,6,12,15,0,2,76,69,0,0,13,14,15,0, +15,13,14,0,18,0,0,1,12,15,0,2,33,61,0,0, +23,14,11,15,21,14,0,0,18,0,0,6,12,15,0,2, +78,69,0,0,13,14,15,0,15,13,14,0,18,0,0,1, +12,16,0,5,105,110,102,105,120,0,0,0,13,15,16,0, +15,16,13,0,15,17,12,0,15,18,10,0,15,19,2,0, +31,14,16,4,19,14,15,14,20,14,0,0,18,0,0,22, +12,16,0,5,105,110,102,105,120,0,0,0,13,15,16,0, +12,21,0,3,118,97,108,0,9,20,1,21,9,16,6,20, +11,20,0,0,0,0,0,0,0,0,0,0,9,17,7,20, +11,20,0,0,0,0,0,0,0,0,240,63,9,18,7,20, +15,19,2,0,31,14,16,4,19,14,15,14,20,14,0,0, +18,0,0,1,0,0,0,0,12,38,0,9,100,111,95,115, +121,109,98,111,108,0,0,0,14,38,37,0,16,38,1,221, +44,34,0,0,28,2,0,0,9,1,0,2,28,3,0,0, +9,2,0,3,12,4,0,4,116,121,112,101,0,0,0,0, +9,3,1,4,12,4,0,4,110,97,109,101,0,0,0,0, +23,3,3,4,21,3,0,0,18,0,0,136,11,5,0,0, +0,0,0,0,0,0,240,63,11,7,0,0,0,0,0,0, +0,0,0,0,12,8,0,1,68,0,0,0,13,3,8,0, +12,8,0,8,95,103,108,111,98,97,108,115,0,0,0,0, +9,3,3,8,23,6,3,7,21,6,0,0,18,0,0,2, +18,0,0,16,12,8,0,1,68,0,0,0,13,3,8,0, +12,8,0,4,118,97,114,115,0,0,0,0,9,3,3,8, +12,9,0,3,118,97,108,0,9,8,1,9,36,3,3,8, +11,8,0,0,0,0,0,0,0,0,0,0,23,3,3,8, +23,4,3,5,21,4,0,0,18,0,0,2,18,0,0,12, +12,6,0,1,68,0,0,0,13,3,6,0,12,6,0,7, +103,108,111,98,97,108,115,0,9,3,3,6,12,7,0,3, +118,97,108,0,9,6,1,7,36,3,3,6,21,3,0,0, +18,0,0,48,12,6,0,9,100,111,95,115,116,114,105,110, +103,0,0,0,13,5,6,0,15,6,1,0,31,4,6,1, +19,4,5,4,15,3,4,0,12,7,0,2,100,111,0,0, +13,6,7,0,15,7,2,0,31,5,7,1,19,5,6,5, +15,4,5,0,12,7,0,4,99,111,100,101,0,0,0,0, +13,6,7,0,12,10,0,4,71,83,69,84,0,0,0,0, +13,7,10,0,15,8,3,0,15,9,4,0,31,5,7,3, +19,5,6,5,12,7,0,8,102,114,101,101,95,116,109,112, +0,0,0,0,13,6,7,0,15,7,3,0,31,5,7,1, +19,5,6,5,12,7,0,8,102,114,101,101,95,116,109,112, +0,0,0,0,13,6,7,0,15,7,4,0,31,5,7,1, +19,5,6,5,28,5,0,0,20,5,0,0,18,0,0,1, +12,8,0,8,100,111,95,108,111,99,97,108,0,0,0,0, +13,7,8,0,15,8,1,0,31,6,8,1,19,6,7,6, +15,5,6,0,12,8,0,2,100,111,0,0,13,7,8,0, +15,8,2,0,31,6,8,1,19,6,7,6,15,4,6,0, +12,8,0,4,99,111,100,101,0,0,0,0,13,7,8,0, +12,11,0,4,77,79,86,69,0,0,0,0,13,8,11,0, +15,9,5,0,15,10,4,0,31,6,8,3,19,6,7,6, +12,8,0,8,102,114,101,101,95,116,109,112,0,0,0,0, +13,7,8,0,15,8,4,0,31,6,8,1,19,6,7,6, +20,5,0,0,18,0,1,6,12,7,0,5,116,117,112,108, +101,0,0,0,12,8,0,4,108,105,115,116,0,0,0,0, +27,6,7,2,12,8,0,4,116,121,112,101,0,0,0,0, +9,7,1,8,36,6,6,7,21,6,0,0,18,0,0,248, +12,7,0,5,116,117,112,108,101,0,0,0,12,8,0,4, +108,105,115,116,0,0,0,0,27,6,7,2,12,8,0,4, +116,121,112,101,0,0,0,0,9,7,2,8,36,6,6,7, +21,6,0,0,18,0,0,128,11,7,0,0,0,0,0,0, +0,0,0,0,15,6,7,0,27,8,0,0,15,7,8,0, +15,8,6,0,15,6,7,0,12,10,0,5,105,116,101,109, +115,0,0,0,9,9,1,10,11,10,0,0,0,0,0,0, +0,0,0,0,42,7,9,10,18,0,0,54,12,13,0,5, +105,116,101,109,115,0,0,0,9,12,2,13,9,12,12,8, +15,11,12,0,12,15,0,7,103,101,116,95,116,109,112,0, +13,14,15,0,31,13,0,0,19,13,14,13,15,12,13,0, +12,15,0,6,97,112,112,101,110,100,0,0,9,14,6,15, +15,15,12,0,31,13,15,1,19,13,14,13,12,16,0,2, +100,111,0,0,13,15,16,0,15,16,11,0,31,14,16,1, +19,14,15,14,15,13,14,0,12,16,0,4,99,111,100,101, +0,0,0,0,13,15,16,0,12,19,0,4,77,79,86,69, +0,0,0,0,13,16,19,0,15,17,12,0,15,18,13,0, +31,14,16,3,19,14,15,14,12,16,0,8,102,114,101,101, +95,116,109,112,0,0,0,0,13,15,16,0,15,16,13,0, +31,14,16,1,19,14,15,14,11,15,0,0,0,0,0,0, +0,0,240,63,1,14,8,15,15,8,14,0,18,0,255,202, +11,9,0,0,0,0,0,0,0,0,0,0,15,8,9,0, +12,10,0,5,105,116,101,109,115,0,0,0,9,9,1,10, +11,10,0,0,0,0,0,0,0,0,0,0,42,7,9,10, +18,0,0,42,12,15,0,5,105,116,101,109,115,0,0,0, +9,14,2,15,9,14,14,8,15,11,14,0,9,14,6,8, +15,12,14,0,12,16,0,8,102,114,101,101,95,116,109,112, +0,0,0,0,13,15,16,0,12,18,0,10,100,111,95,115, +101,116,95,99,116,120,0,0,13,17,18,0,15,18,7,0, +12,21,0,5,84,111,107,101,110,0,0,0,13,20,21,0, +12,24,0,3,112,111,115,0,9,21,11,24,12,22,0,3, +114,101,103,0,15,23,12,0,31,19,21,3,19,19,20,19, +31,16,18,2,19,16,17,16,31,14,16,1,19,14,15,14, +11,15,0,0,0,0,0,0,0,0,240,63,1,14,8,15, +15,8,14,0,18,0,255,214,28,9,0,0,20,9,0,0, +18,0,0,1,12,14,0,2,100,111,0,0,13,10,14,0, +15,14,2,0,31,9,14,1,19,9,10,9,15,13,9,0, +12,14,0,6,117,110,95,116,109,112,0,0,13,10,14,0, +15,14,13,0,31,9,14,1,19,9,10,9,11,10,0,0, +0,0,0,0,0,0,0,0,15,9,10,0,12,16,0,5, +84,111,107,101,110,0,0,0,13,15,16,0,12,19,0,3, +112,111,115,0,9,16,2,19,12,17,0,3,114,101,103,0, +15,18,13,0,31,14,16,3,19,14,15,14,15,10,14,0, +15,8,9,0,15,12,10,0,12,14,0,5,105,116,101,109, +115,0,0,0,9,10,1,14,11,14,0,0,0,0,0,0, +0,0,0,0,42,9,10,14,18,0,0,54,12,17,0,8, +102,114,101,101,95,116,109,112,0,0,0,0,13,16,17,0, +12,19,0,10,100,111,95,115,101,116,95,99,116,120,0,0, +13,18,19,0,15,19,9,0,12,22,0,5,84,111,107,101, +110,0,0,0,13,21,22,0,12,26,0,3,112,111,115,0, +9,22,12,26,12,23,0,3,103,101,116,0,28,24,0,0, +15,26,12,0,12,29,0,5,84,111,107,101,110,0,0,0, +13,28,29,0,12,32,0,3,112,111,115,0,9,29,12,32, +12,30,0,6,110,117,109,98,101,114,0,0,12,33,0,3, +115,116,114,0,13,32,33,0,15,33,8,0,31,31,33,1, +19,31,32,31,31,27,29,3,19,27,28,27,27,25,26,2, +31,20,22,4,19,20,21,20,31,17,19,2,19,17,18,17, +31,15,17,1,19,15,16,15,11,16,0,0,0,0,0,0, +0,0,240,63,1,15,8,16,15,8,15,0,18,0,255,202, +12,15,0,8,102,114,101,101,95,114,101,103,0,0,0,0, +13,14,15,0,15,15,13,0,31,10,15,1,19,10,14,10, +28,10,0,0,20,10,0,0,18,0,0,1,12,15,0,2, +100,111,0,0,13,14,15,0,12,16,0,5,105,116,101,109, +115,0,0,0,9,15,1,16,11,16,0,0,0,0,0,0, +0,0,0,0,9,15,15,16,31,10,15,1,19,10,14,10, +15,13,10,0,12,16,0,2,100,111,0,0,13,15,16,0, +15,16,2,0,31,14,16,1,19,14,15,14,15,10,14,0, +12,16,0,2,100,111,0,0,13,15,16,0,12,17,0,5, +105,116,101,109,115,0,0,0,9,16,1,17,11,17,0,0, +0,0,0,0,0,0,240,63,9,16,16,17,31,14,16,1, +19,14,15,14,15,12,14,0,12,16,0,4,99,111,100,101, +0,0,0,0,13,15,16,0,12,20,0,3,83,69,84,0, +13,16,20,0,15,17,13,0,15,18,12,0,15,19,10,0, +31,14,16,4,19,14,15,14,12,16,0,8,102,114,101,101, +95,116,109,112,0,0,0,0,13,15,16,0,15,16,13,0, +31,14,16,1,19,14,15,14,12,16,0,8,102,114,101,101, +95,116,109,112,0,0,0,0,13,15,16,0,15,16,12,0, +31,14,16,1,19,14,15,14,20,10,0,0,0,0,0,0, +12,39,0,10,100,111,95,115,101,116,95,99,116,120,0,0, +14,39,38,0,16,39,0,152,44,19,0,0,28,2,0,0, +9,1,0,2,28,3,0,0,9,2,0,3,28,4,0,0, +9,3,0,4,11,4,0,0,0,0,0,0,0,0,0,0, +28,5,0,0,32,4,0,5,12,8,0,3,109,97,120,0, +13,7,8,0,15,8,4,0,12,11,0,3,108,101,110,0, +13,10,11,0,15,11,3,0,31,9,11,1,19,9,10,9, +31,6,8,2,19,6,7,6,15,5,6,0,11,7,0,0, +0,0,0,0,0,0,0,0,15,6,7,0,12,10,0,8, +103,101,116,95,116,109,112,115,0,0,0,0,13,9,10,0, +15,10,5,0,31,8,10,1,19,8,9,8,15,7,8,0, +15,8,6,0,15,6,7,0,11,9,0,0,0,0,0,0, +0,0,0,0,42,7,3,9,18,0,0,41,9,11,6,8, +15,10,11,0,12,14,0,2,100,111,0,0,13,13,14,0, +15,14,7,0,15,15,10,0,31,12,14,2,19,12,13,12, +15,11,12,0,35,12,10,11,21,12,0,0,18,0,0,22, +12,14,0,4,99,111,100,101,0,0,0,0,13,13,14,0, +12,17,0,4,77,79,86,69,0,0,0,0,13,14,17,0, +15,15,10,0,15,16,11,0,31,12,14,3,19,12,13,12, +12,14,0,8,102,114,101,101,95,116,109,112,0,0,0,0, +13,13,14,0,15,14,11,0,31,12,14,1,19,12,13,12, +18,0,0,1,11,13,0,0,0,0,0,0,0,0,240,63, +1,12,8,13,15,8,12,0,18,0,255,215,11,9,0,0, +0,0,0,0,0,0,0,0,12,14,0,3,108,101,110,0, +13,13,14,0,15,14,6,0,31,12,14,1,19,12,13,12, +23,9,9,12,21,9,0,0,18,0,0,20,12,13,0,4, +99,111,100,101,0,0,0,0,13,12,13,0,15,13,1,0, +15,14,2,0,11,15,0,0,0,0,0,0,0,0,0,0, +11,16,0,0,0,0,0,0,0,0,0,0,31,9,13,4, +19,9,12,9,11,9,0,0,0,0,0,0,0,0,0,0, +20,9,0,0,18,0,0,1,12,13,0,4,99,111,100,101, +0,0,0,0,13,12,13,0,15,13,1,0,15,14,2,0, +11,17,0,0,0,0,0,0,0,0,0,0,9,15,6,17, +12,18,0,3,108,101,110,0,13,17,18,0,15,18,3,0, +31,16,18,1,19,16,17,16,31,9,13,4,19,9,12,9, +12,13,0,9,102,114,101,101,95,116,109,112,115,0,0,0, +13,12,13,0,15,15,4,0,28,16,0,0,27,14,15,2, +9,13,6,14,31,9,13,1,19,9,12,9,11,12,0,0, +0,0,0,0,0,0,0,0,9,9,6,12,20,9,0,0, +0,0,0,0,12,40,0,10,109,97,110,97,103,101,95,115, +101,113,0,0,14,40,39,0,16,40,0,92,44,12,0,0, +28,2,0,0,9,1,0,2,27,3,0,0,15,2,3,0, +27,4,0,0,15,3,4,0,28,5,0,0,15,4,5,0, +28,6,0,0,15,5,6,0,15,6,2,0,15,2,3,0, +15,3,4,0,15,4,5,0,11,7,0,0,0,0,0,0, +0,0,0,0,42,5,1,7,18,0,0,65,11,10,0,0, +0,0,0,0,0,0,0,0,12,11,0,4,116,121,112,101, +0,0,0,0,9,8,5,11,12,11,0,6,115,121,109,98, +111,108,0,0,23,8,8,11,23,9,8,10,21,9,0,0, +18,0,0,2,18,0,0,7,12,11,0,3,118,97,108,0, +9,8,5,11,12,11,0,1,61,0,0,0,23,8,8,11, +21,8,0,0,18,0,0,9,12,10,0,6,97,112,112,101, +110,100,0,0,9,9,2,10,15,10,5,0,31,8,10,1, +19,8,9,8,18,0,0,33,12,9,0,4,116,121,112,101, +0,0,0,0,9,8,5,9,12,9,0,4,97,114,103,115, +0,0,0,0,23,8,8,9,21,8,0,0,18,0,0,3, +15,3,5,0,18,0,0,21,12,9,0,4,116,121,112,101, +0,0,0,0,9,8,5,9,12,9,0,5,110,97,114,103, +115,0,0,0,23,8,8,9,21,8,0,0,18,0,0,3, +15,4,5,0,18,0,0,9,12,10,0,6,97,112,112,101, +110,100,0,0,9,9,6,10,15,10,5,0,31,8,10,1, +19,8,9,8,18,0,0,1,18,0,255,191,15,8,6,0, +15,9,2,0,15,10,3,0,15,11,4,0,27,7,8,4, +20,7,0,0,0,0,0,0,12,41,0,8,112,95,102,105, +108,116,101,114,0,0,0,0,14,41,40,0,16,41,0,86, +44,21,0,0,28,2,0,0,9,1,0,2,12,4,0,5, +105,116,101,109,115,0,0,0,9,3,1,4,11,4,0,0, +0,0,0,0,0,0,0,0,42,2,3,4,18,0,0,73, +12,5,0,6,115,116,114,105,110,103,0,0,12,6,0,4, +116,121,112,101,0,0,0,0,10,2,6,5,12,8,0,7, +100,111,95,99,97,108,108,0,13,7,8,0,12,10,0,5, +84,111,107,101,110,0,0,0,13,9,10,0,12,14,0,3, +112,111,115,0,9,10,1,14,12,11,0,4,99,97,108,108, +0,0,0,0,28,12,0,0,12,17,0,5,84,111,107,101, +110,0,0,0,13,16,17,0,12,20,0,3,112,111,115,0, +9,17,1,20,12,18,0,4,110,97,109,101,0,0,0,0, +12,19,0,6,105,109,112,111,114,116,0,0,31,14,17,3, +19,14,16,14,15,15,2,0,27,13,14,2,31,8,10,4, +19,8,9,8,31,6,8,1,19,6,7,6,15,5,6,0, +12,6,0,4,110,97,109,101,0,0,0,0,12,7,0,4, +116,121,112,101,0,0,0,0,10,2,7,6,12,8,0,10, +100,111,95,115,101,116,95,99,116,120,0,0,13,7,8,0, +15,8,2,0,12,11,0,5,84,111,107,101,110,0,0,0, +13,10,11,0,12,14,0,3,112,111,115,0,9,11,1,14, +12,12,0,3,114,101,103,0,15,13,5,0,31,9,11,3, +19,9,10,9,31,6,8,2,19,6,7,6,18,0,255,183, +0,0,0,0,12,42,0,9,100,111,95,105,109,112,111,114, +116,0,0,0,14,42,41,0,16,42,0,222,44,23,0,0, +28,2,0,0,9,1,0,2,12,4,0,5,105,116,101,109, +115,0,0,0,9,3,1,4,11,4,0,0,0,0,0,0, +0,0,0,0,9,3,3,4,15,2,3,0,12,3,0,6, +115,116,114,105,110,103,0,0,12,4,0,4,116,121,112,101, +0,0,0,0,10,2,4,3,12,6,0,2,100,111,0,0, +13,5,6,0,12,8,0,5,84,111,107,101,110,0,0,0, +13,7,8,0,12,12,0,3,112,111,115,0,9,8,1,12, +12,9,0,4,99,97,108,108,0,0,0,0,28,10,0,0, +12,15,0,5,84,111,107,101,110,0,0,0,13,14,15,0, +12,18,0,3,112,111,115,0,9,15,1,18,12,16,0,4, +110,97,109,101,0,0,0,0,12,17,0,6,105,109,112,111, +114,116,0,0,31,12,15,3,19,12,14,12,15,13,2,0, +27,11,12,2,31,6,8,4,19,6,7,6,31,4,6,1, +19,4,5,4,15,3,4,0,12,6,0,5,105,116,101,109, +115,0,0,0,9,5,1,6,11,6,0,0,0,0,0,0, +0,0,240,63,9,5,5,6,15,4,5,0,12,6,0,3, +118,97,108,0,9,5,4,6,12,6,0,1,42,0,0,0, +23,5,5,6,21,5,0,0,18,0,0,71,12,7,0,8, +102,114,101,101,95,116,109,112,0,0,0,0,13,6,7,0, +12,9,0,2,100,111,0,0,13,8,9,0,12,11,0,5, +84,111,107,101,110,0,0,0,13,10,11,0,12,15,0,3, +112,111,115,0,9,11,1,15,12,12,0,4,99,97,108,108, +0,0,0,0,28,13,0,0,12,19,0,5,84,111,107,101, +110,0,0,0,13,18,19,0,12,22,0,3,112,111,115,0, +9,19,1,22,12,20,0,4,110,97,109,101,0,0,0,0, +12,21,0,5,109,101,114,103,101,0,0,0,31,15,19,3, +19,15,18,15,12,19,0,5,84,111,107,101,110,0,0,0, +13,18,19,0,12,22,0,3,112,111,115,0,9,19,1,22, +12,20,0,4,110,97,109,101,0,0,0,0,12,21,0,8, +95,95,100,105,99,116,95,95,0,0,0,0,31,16,19,3, +19,16,18,16,12,19,0,5,84,111,107,101,110,0,0,0, +13,18,19,0,12,22,0,3,112,111,115,0,9,19,1,22, +12,20,0,3,114,101,103,0,15,21,3,0,31,17,19,3, +19,17,18,17,27,14,15,3,31,9,11,4,19,9,10,9, +31,7,9,1,19,7,8,7,31,5,7,1,19,5,6,5, +18,0,0,79,12,5,0,6,115,116,114,105,110,103,0,0, +12,6,0,4,116,121,112,101,0,0,0,0,10,4,6,5, +12,7,0,8,102,114,101,101,95,116,109,112,0,0,0,0, +13,6,7,0,12,9,0,10,100,111,95,115,101,116,95,99, +116,120,0,0,13,8,9,0,12,12,0,5,84,111,107,101, +110,0,0,0,13,11,12,0,12,16,0,3,112,111,115,0, +9,12,1,16,12,13,0,3,103,101,116,0,28,14,0,0, +12,19,0,5,84,111,107,101,110,0,0,0,13,18,19,0, +12,22,0,3,112,111,115,0,9,19,1,22,12,20,0,4, +110,97,109,101,0,0,0,0,12,21,0,8,95,95,100,105, +99,116,95,95,0,0,0,0,31,16,19,3,19,16,18,16, +15,17,4,0,27,15,16,2,31,9,12,4,19,9,11,9, +12,12,0,5,84,111,107,101,110,0,0,0,13,11,12,0, +12,16,0,3,112,111,115,0,9,12,1,16,12,13,0,3, +103,101,116,0,28,14,0,0,12,19,0,5,84,111,107,101, +110,0,0,0,13,18,19,0,12,22,0,3,112,111,115,0, +9,19,1,22,12,20,0,3,114,101,103,0,15,21,3,0, +31,16,19,3,19,16,18,16,15,17,4,0,27,15,16,2, +31,10,12,4,19,10,11,10,31,7,9,2,19,7,8,7, +31,5,7,1,19,5,6,5,18,0,0,1,0,0,0,0, +12,43,0,7,100,111,95,102,114,111,109,0,14,43,42,0, +16,43,0,49,44,8,0,0,28,2,0,0,9,1,0,2, +12,3,0,5,105,116,101,109,115,0,0,0,9,2,1,3, +11,3,0,0,0,0,0,0,0,0,0,0,42,1,2,3, +18,0,0,36,12,5,0,1,68,0,0,0,13,4,5,0, +12,5,0,7,103,108,111,98,97,108,115,0,9,4,4,5, +12,6,0,3,118,97,108,0,9,5,1,6,36,4,4,5, +11,5,0,0,0,0,0,0,0,0,0,0,23,4,4,5, +21,4,0,0,18,0,0,18,12,6,0,1,68,0,0,0, +13,5,6,0,12,6,0,7,103,108,111,98,97,108,115,0, +9,5,5,6,12,6,0,6,97,112,112,101,110,100,0,0, +9,5,5,6,12,7,0,3,118,97,108,0,9,6,1,7, +31,4,6,1,19,4,5,4,18,0,0,1,18,0,255,220, +0,0,0,0,12,44,0,10,100,111,95,103,108,111,98,97, +108,115,0,0,14,44,43,0,16,44,0,70,44,13,0,0, +28,2,0,0,9,1,0,2,12,4,0,5,105,116,101,109, +115,0,0,0,9,3,1,4,11,4,0,0,0,0,0,0, +0,0,0,0,42,2,3,4,18,0,0,57,12,8,0,2, +100,111,0,0,13,7,8,0,12,9,0,5,105,116,101,109, +115,0,0,0,9,8,2,9,11,9,0,0,0,0,0,0, +0,0,0,0,9,8,8,9,31,6,8,1,19,6,7,6, +15,5,6,0,12,9,0,2,100,111,0,0,13,8,9,0, +12,10,0,5,105,116,101,109,115,0,0,0,9,9,2,10, +11,10,0,0,0,0,0,0,0,0,240,63,9,9,9,10, +31,7,9,1,19,7,8,7,15,6,7,0,12,9,0,4, +99,111,100,101,0,0,0,0,13,8,9,0,12,12,0,3, +68,69,76,0,13,9,12,0,15,10,5,0,15,11,6,0, +31,7,9,3,19,7,8,7,12,9,0,8,102,114,101,101, +95,116,109,112,0,0,0,0,13,8,9,0,15,9,5,0, +31,7,9,1,19,7,8,7,12,9,0,8,102,114,101,101, +95,116,109,112,0,0,0,0,13,8,9,0,15,9,6,0, +31,7,9,1,19,7,8,7,18,0,255,199,0,0,0,0, +12,45,0,6,100,111,95,100,101,108,0,0,14,45,44,0, +16,45,1,133,44,31,0,0,28,2,0,0,9,1,0,2, +28,2,0,0,28,3,0,0,32,2,0,3,12,5,0,7, +103,101,116,95,116,109,112,0,13,4,5,0,15,5,2,0, +31,3,5,1,19,3,4,3,15,2,3,0,12,5,0,5, +105,116,101,109,115,0,0,0,9,4,1,5,15,3,4,0, +12,7,0,2,100,111,0,0,13,6,7,0,11,8,0,0, +0,0,0,0,0,0,0,0,9,7,3,8,31,5,7,1, +19,5,6,5,15,4,5,0,12,7,0,8,112,95,102,105, +108,116,101,114,0,0,0,0,13,6,7,0,12,8,0,5, +105,116,101,109,115,0,0,0,9,7,1,8,11,9,0,0, +0,0,0,0,0,0,240,63,28,10,0,0,27,8,9,2, +9,7,7,8,31,5,7,1,19,5,6,5,11,8,0,0, +0,0,0,0,0,0,0,0,9,7,5,8,15,6,7,0, +11,9,0,0,0,0,0,0,0,0,240,63,9,8,5,9, +15,7,8,0,11,10,0,0,0,0,0,0,0,0,0,64, +9,9,5,10,15,8,9,0,11,11,0,0,0,0,0,0, +0,0,8,64,9,10,5,11,15,9,10,0,28,10,0,0, +15,5,10,0,11,12,0,0,0,0,0,0,0,0,240,63, +12,14,0,3,108,101,110,0,13,13,14,0,15,14,7,0, +31,10,14,1,19,10,13,10,11,13,0,0,0,0,0,0, +0,0,0,0,35,10,10,13,23,11,10,12,21,11,0,0, +18,0,0,2,18,0,0,3,28,13,0,0,35,10,9,13, +21,10,0,0,18,0,0,172,12,12,0,2,100,111,0,0, +13,11,12,0,12,14,0,5,84,111,107,101,110,0,0,0, +13,13,14,0,12,18,0,3,112,111,115,0,9,14,1,18, +12,15,0,4,100,105,99,116,0,0,0,0,28,16,0,0, +27,17,0,0,31,12,14,4,19,12,13,12,31,10,12,1, +19,10,11,10,15,5,10,0,12,12,0,6,117,110,95,116, +109,112,0,0,13,11,12,0,15,12,5,0,31,10,12,1, +19,10,11,10,11,11,0,0,0,0,0,0,0,0,0,0, +42,10,7,11,18,0,0,75,12,13,0,5,105,116,101,109, +115,0,0,0,9,12,10,13,11,13,0,0,0,0,0,0, +0,0,0,0,9,12,12,13,12,13,0,6,115,116,114,105, +110,103,0,0,12,14,0,4,116,121,112,101,0,0,0,0, +10,12,14,13,12,15,0,2,100,111,0,0,13,14,15,0, +12,16,0,5,105,116,101,109,115,0,0,0,9,15,10,16, +11,16,0,0,0,0,0,0,0,0,0,0,9,15,15,16, +31,13,15,1,19,13,14,13,15,12,13,0,12,16,0,2, +100,111,0,0,13,15,16,0,12,17,0,5,105,116,101,109, +115,0,0,0,9,16,10,17,11,17,0,0,0,0,0,0, +0,0,240,63,9,16,16,17,31,14,16,1,19,14,15,14, +15,13,14,0,15,14,12,0,15,12,13,0,12,16,0,4, +99,111,100,101,0,0,0,0,13,15,16,0,12,20,0,3, +83,69,84,0,13,16,20,0,15,17,5,0,15,18,14,0, +15,19,12,0,31,13,16,4,19,13,15,13,12,16,0,8, +102,114,101,101,95,116,109,112,0,0,0,0,13,15,16,0, +15,16,14,0,31,13,16,1,19,13,15,13,12,16,0,8, +102,114,101,101,95,116,109,112,0,0,0,0,13,15,16,0, +15,16,12,0,31,13,16,1,19,13,15,13,18,0,255,181, +21,9,0,0,18,0,0,63,12,15,0,8,102,114,101,101, +95,116,109,112,0,0,0,0,13,13,15,0,12,17,0,2, +100,111,0,0,13,16,17,0,12,19,0,5,84,111,107,101, +110,0,0,0,13,18,19,0,12,23,0,3,112,111,115,0, +9,19,1,23,12,20,0,4,99,97,108,108,0,0,0,0, +28,21,0,0,12,27,0,5,84,111,107,101,110,0,0,0, +13,26,27,0,12,30,0,3,112,111,115,0,9,27,1,30, +12,28,0,4,110,97,109,101,0,0,0,0,12,29,0,5, +109,101,114,103,101,0,0,0,31,23,27,3,19,23,26,23, +12,27,0,5,84,111,107,101,110,0,0,0,13,26,27,0, +12,30,0,3,112,111,115,0,9,27,1,30,12,28,0,3, +114,101,103,0,15,29,5,0,31,24,27,3,19,24,26,24, +12,26,0,5,105,116,101,109,115,0,0,0,9,25,9,26, +11,26,0,0,0,0,0,0,0,0,0,0,9,25,25,26, +27,22,23,3,31,17,19,4,19,17,18,17,31,15,17,1, +19,15,16,15,31,11,15,1,19,11,13,11,18,0,0,1, +18,0,0,1,12,15,0,10,109,97,110,97,103,101,95,115, +101,113,0,0,13,13,15,0,12,18,0,6,80,65,82,65, +77,83,0,0,13,15,18,0,15,16,2,0,15,17,6,0, +31,11,15,3,19,11,13,11,28,13,0,0,35,11,8,13, +21,11,0,0,18,0,0,56,12,16,0,10,95,100,111,95, +115,116,114,105,110,103,0,0,13,15,16,0,12,16,0,1, +42,0,0,0,31,13,16,1,19,13,15,13,15,11,13,0, +12,17,0,2,100,111,0,0,13,16,17,0,12,18,0,5, +105,116,101,109,115,0,0,0,9,17,8,18,11,18,0,0, +0,0,0,0,0,0,0,0,9,17,17,18,31,15,17,1, +19,15,16,15,15,13,15,0,15,14,11,0,15,12,13,0, +12,15,0,4,99,111,100,101,0,0,0,0,13,13,15,0, +12,19,0,3,83,69,84,0,13,15,19,0,15,16,2,0, +15,17,14,0,15,18,12,0,31,11,15,4,19,11,13,11, +12,15,0,8,102,114,101,101,95,116,109,112,0,0,0,0, +13,13,15,0,15,15,14,0,31,11,15,1,19,11,13,11, +12,15,0,8,102,114,101,101,95,116,109,112,0,0,0,0, +13,13,15,0,15,15,12,0,31,11,15,1,19,11,13,11, +18,0,0,1,28,13,0,0,35,11,5,13,21,11,0,0, +18,0,0,30,12,15,0,8,95,100,111,95,110,111,110,101, +0,0,0,0,13,13,15,0,31,11,0,0,19,11,13,11, +15,14,11,0,12,15,0,4,99,111,100,101,0,0,0,0, +13,13,15,0,12,19,0,3,83,69,84,0,13,15,19,0, +15,16,2,0,15,17,14,0,15,18,5,0,31,11,15,4, +19,11,13,11,12,15,0,8,102,114,101,101,95,116,109,112, +0,0,0,0,13,13,15,0,15,15,14,0,31,11,15,1, +19,11,13,11,18,0,0,1,12,15,0,4,99,111,100,101, +0,0,0,0,13,13,15,0,12,19,0,4,67,65,76,76, +0,0,0,0,13,15,19,0,15,16,2,0,15,17,4,0, +15,18,2,0,31,11,15,4,19,11,13,11,12,15,0,8, +102,114,101,101,95,116,109,112,0,0,0,0,13,13,15,0, +15,15,4,0,31,11,15,1,19,11,13,11,20,2,0,0, +0,0,0,0,12,46,0,7,100,111,95,99,97,108,108,0, +14,46,45,0,16,46,0,70,44,10,0,0,28,2,0,0, +9,1,0,2,28,2,0,0,28,3,0,0,32,2,0,3, +12,4,0,1,68,0,0,0,13,3,4,0,12,4,0,4, +118,97,114,115,0,0,0,0,9,3,3,4,12,5,0,3, +118,97,108,0,9,4,1,5,36,3,3,4,21,3,0,0, +18,0,0,12,12,5,0,8,100,111,95,108,111,99,97,108, +0,0,0,0,13,4,5,0,15,5,1,0,15,6,2,0, +31,3,5,2,19,3,4,3,20,3,0,0,18,0,0,1, +12,5,0,7,103,101,116,95,116,109,112,0,13,4,5,0, +15,5,2,0,31,3,5,1,19,3,4,3,15,2,3,0, +12,6,0,9,100,111,95,115,116,114,105,110,103,0,0,0, +13,5,6,0,15,6,1,0,31,4,6,1,19,4,5,4, +15,3,4,0,12,6,0,4,99,111,100,101,0,0,0,0, +13,5,6,0,12,9,0,4,71,71,69,84,0,0,0,0, +13,6,9,0,15,7,2,0,15,8,3,0,31,4,6,3, +19,4,5,4,12,6,0,8,102,114,101,101,95,116,109,112, +0,0,0,0,13,5,6,0,15,6,3,0,31,4,6,1, +19,4,5,4,20,2,0,0,0,0,0,0,12,47,0,7, +100,111,95,110,97,109,101,0,14,47,46,0,16,47,0,52, +44,7,0,0,28,2,0,0,9,1,0,2,28,2,0,0, +28,3,0,0,32,2,0,3,12,4,0,1,68,0,0,0, +13,3,4,0,12,4,0,4,118,97,114,115,0,0,0,0, +9,3,3,4,12,5,0,3,118,97,108,0,9,4,1,5, +36,3,3,4,11,4,0,0,0,0,0,0,0,0,0,0, +23,3,3,4,21,3,0,0,18,0,0,18,12,5,0,1, +68,0,0,0,13,4,5,0,12,5,0,4,118,97,114,115, +0,0,0,0,9,4,4,5,12,5,0,6,97,112,112,101, +110,100,0,0,9,4,4,5,12,6,0,3,118,97,108,0, +9,5,1,6,31,3,5,1,19,3,4,3,18,0,0,1, +12,5,0,7,103,101,116,95,114,101,103,0,13,4,5,0, +12,6,0,3,118,97,108,0,9,5,1,6,31,3,5,1, +19,3,4,3,20,3,0,0,0,0,0,0,12,48,0,8, +100,111,95,108,111,99,97,108,0,0,0,0,14,48,47,0, +16,48,1,229,44,25,0,0,28,2,0,0,9,1,0,2, +28,2,0,0,28,3,0,0,32,2,0,3,12,5,0,5, +105,116,101,109,115,0,0,0,9,4,1,5,15,3,4,0, +12,7,0,7,103,101,116,95,116,97,103,0,13,6,7,0, +31,5,0,0,19,5,6,5,15,4,5,0,12,8,0,3, +102,110,99,0,13,7,8,0,15,8,4,0,12,9,0,3, +101,110,100,0,31,6,8,2,19,6,7,6,15,5,6,0, +12,8,0,1,68,0,0,0,13,7,8,0,12,8,0,5, +98,101,103,105,110,0,0,0,9,7,7,8,31,6,0,0, +19,6,7,6,12,8,0,6,115,101,116,112,111,115,0,0, +13,7,8,0,12,9,0,3,112,111,115,0,9,8,1,9, +31,6,8,1,19,6,7,6,12,9,0,8,100,111,95,108, +111,99,97,108,0,0,0,0,13,8,9,0,12,11,0,5, +84,111,107,101,110,0,0,0,13,10,11,0,12,14,0,3, +112,111,115,0,9,11,1,14,12,12,0,4,110,97,109,101, +0,0,0,0,12,13,0,8,95,95,112,97,114,97,109,115, +0,0,0,0,31,9,11,3,19,9,10,9,31,7,9,1, +19,7,8,7,15,6,7,0,12,9,0,7,100,111,95,105, +110,102,111,0,13,8,9,0,11,10,0,0,0,0,0,0, +0,0,0,0,9,9,3,10,12,10,0,3,118,97,108,0, +9,9,9,10,31,7,9,1,19,7,8,7,12,9,0,8, +112,95,102,105,108,116,101,114,0,0,0,0,13,8,9,0, +11,10,0,0,0,0,0,0,0,0,240,63,9,9,3,10, +12,10,0,5,105,116,101,109,115,0,0,0,9,9,9,10, +31,7,9,1,19,7,8,7,11,10,0,0,0,0,0,0, +0,0,0,0,9,9,7,10,15,8,9,0,11,11,0,0, +0,0,0,0,0,0,240,63,9,10,7,11,15,9,10,0, +11,12,0,0,0,0,0,0,0,0,0,64,9,11,7,12, +15,10,11,0,11,13,0,0,0,0,0,0,0,0,8,64, +9,12,7,13,15,11,12,0,11,12,0,0,0,0,0,0, +0,0,0,0,42,7,8,12,18,0,0,39,12,16,0,8, +100,111,95,108,111,99,97,108,0,0,0,0,13,15,16,0, +15,16,7,0,31,14,16,1,19,14,15,14,15,13,14,0, +12,17,0,8,95,100,111,95,110,111,110,101,0,0,0,0, +13,16,17,0,31,15,0,0,19,15,16,15,15,14,15,0, +12,17,0,4,99,111,100,101,0,0,0,0,13,16,17,0, +12,21,0,3,71,69,84,0,13,17,21,0,15,18,13,0, +15,19,6,0,15,20,14,0,31,15,17,4,19,15,16,15, +12,17,0,8,102,114,101,101,95,116,109,112,0,0,0,0, +13,16,17,0,15,17,14,0,31,15,17,1,19,15,16,15, +18,0,255,217,11,12,0,0,0,0,0,0,0,0,0,0, +42,7,9,12,18,0,0,61,12,17,0,8,100,111,95,108, +111,99,97,108,0,0,0,0,13,16,17,0,12,18,0,5, +105,116,101,109,115,0,0,0,9,17,7,18,11,18,0,0, +0,0,0,0,0,0,0,0,9,17,17,18,31,15,17,1, +19,15,16,15,15,13,15,0,12,17,0,2,100,111,0,0, +13,16,17,0,12,19,0,5,105,116,101,109,115,0,0,0, +9,17,7,19,11,19,0,0,0,0,0,0,0,0,240,63, +9,17,17,19,15,18,13,0,31,15,17,2,19,15,16,15, +12,17,0,8,95,100,111,95,110,111,110,101,0,0,0,0, +13,16,17,0,31,15,0,0,19,15,16,15,15,14,15,0, +12,17,0,4,99,111,100,101,0,0,0,0,13,16,17,0, +12,21,0,4,73,71,69,84,0,0,0,0,13,17,21,0, +15,18,13,0,15,19,6,0,15,20,14,0,31,15,17,4, +19,15,16,15,12,17,0,8,102,114,101,101,95,116,109,112, +0,0,0,0,13,16,17,0,15,17,14,0,31,15,17,1, +19,15,16,15,18,0,255,195,28,15,0,0,35,12,10,15, +21,12,0,0,18,0,0,48,12,16,0,8,100,111,95,108, +111,99,97,108,0,0,0,0,13,15,16,0,12,17,0,5, +105,116,101,109,115,0,0,0,9,16,10,17,11,17,0,0, +0,0,0,0,0,0,0,0,9,16,16,17,31,12,16,1, +19,12,15,12,15,13,12,0,12,16,0,10,95,100,111,95, +115,116,114,105,110,103,0,0,13,15,16,0,12,16,0,1, +42,0,0,0,31,12,16,1,19,12,15,12,15,14,12,0, +12,16,0,4,99,111,100,101,0,0,0,0,13,15,16,0, +12,20,0,3,71,69,84,0,13,16,20,0,15,17,13,0, +15,18,6,0,15,19,14,0,31,12,16,4,19,12,15,12, +12,16,0,8,102,114,101,101,95,116,109,112,0,0,0,0, +13,15,16,0,15,16,14,0,31,12,16,1,19,12,15,12, +18,0,0,1,28,15,0,0,35,12,11,15,21,12,0,0, +18,0,0,64,12,17,0,8,100,111,95,108,111,99,97,108, +0,0,0,0,13,16,17,0,12,18,0,5,105,116,101,109, +115,0,0,0,9,17,11,18,11,18,0,0,0,0,0,0, +0,0,0,0,9,17,17,18,31,15,17,1,19,15,16,15, +15,12,15,0,12,17,0,4,99,111,100,101,0,0,0,0, +13,16,17,0,12,21,0,4,68,73,67,84,0,0,0,0, +13,17,21,0,15,18,12,0,11,19,0,0,0,0,0,0, +0,0,0,0,11,20,0,0,0,0,0,0,0,0,0,0, +31,15,17,4,19,15,16,15,12,17,0,8,95,100,111,95, +110,111,110,101,0,0,0,0,13,16,17,0,31,15,0,0, +19,15,16,15,15,14,15,0,12,17,0,4,99,111,100,101, +0,0,0,0,13,16,17,0,12,21,0,4,73,71,69,84, +0,0,0,0,13,17,21,0,15,18,12,0,15,19,6,0, +15,20,14,0,31,15,17,4,19,15,16,15,12,17,0,8, +102,114,101,101,95,116,109,112,0,0,0,0,13,16,17,0, +15,17,14,0,31,15,17,1,19,15,16,15,18,0,0,1, +12,17,0,8,102,114,101,101,95,116,109,112,0,0,0,0, +13,16,17,0,12,19,0,2,100,111,0,0,13,18,19,0, +11,20,0,0,0,0,0,0,0,0,0,64,9,19,3,20, +31,17,19,1,19,17,18,17,31,15,17,1,19,15,16,15, +12,17,0,1,68,0,0,0,13,16,17,0,12,17,0,3, +101,110,100,0,9,16,16,17,31,15,0,0,19,15,16,15, +12,17,0,3,116,97,103,0,13,16,17,0,15,17,4,0, +12,18,0,3,101,110,100,0,31,15,17,2,19,15,16,15, +28,16,0,0,23,15,2,16,21,15,0,0,18,0,0,64, +12,16,0,1,68,0,0,0,13,15,16,0,12,16,0,8, +95,103,108,111,98,97,108,115,0,0,0,0,9,15,15,16, +21,15,0,0,18,0,0,29,12,17,0,10,100,111,95,103, +108,111,98,97,108,115,0,0,13,16,17,0,12,19,0,5, +84,111,107,101,110,0,0,0,13,18,19,0,12,23,0,3, +112,111,115,0,9,19,1,23,11,20,0,0,0,0,0,0, +0,0,0,0,11,21,0,0,0,0,0,0,0,0,0,0, +11,24,0,0,0,0,0,0,0,0,0,0,9,23,3,24, +27,22,23,1,31,17,19,4,19,17,18,17,31,15,17,1, +19,15,16,15,18,0,0,1,12,17,0,10,100,111,95,115, +101,116,95,99,116,120,0,0,13,16,17,0,11,19,0,0, +0,0,0,0,0,0,0,0,9,17,3,19,12,20,0,5, +84,111,107,101,110,0,0,0,13,19,20,0,12,23,0,3, +112,111,115,0,9,20,1,23,12,21,0,3,114,101,103,0, +15,22,5,0,31,18,20,3,19,18,19,18,31,15,17,2, +19,15,16,15,15,6,15,0,18,0,0,34,12,18,0,9, +100,111,95,115,116,114,105,110,103,0,0,0,13,17,18,0, +11,19,0,0,0,0,0,0,0,0,0,0,9,18,3,19, +31,16,18,1,19,16,17,16,15,15,16,0,12,18,0,4, +99,111,100,101,0,0,0,0,13,17,18,0,12,22,0,3, +83,69,84,0,13,18,22,0,15,19,2,0,15,20,15,0, +15,21,5,0,31,16,18,4,19,16,17,16,12,18,0,8, +102,114,101,101,95,116,109,112,0,0,0,0,13,17,18,0, +15,18,15,0,31,16,18,1,19,16,17,16,18,0,0,1, +12,18,0,8,102,114,101,101,95,116,109,112,0,0,0,0, +13,17,18,0,15,18,5,0,31,16,18,1,19,16,17,16, +0,0,0,0,12,49,0,6,100,111,95,100,101,102,0,0, +14,49,48,0,16,49,3,36,44,44,0,0,28,2,0,0, +9,1,0,2,15,2,1,0,12,5,0,5,105,116,101,109, +115,0,0,0,9,4,1,5,15,3,4,0,28,5,0,0, +15,4,5,0,11,6,0,0,0,0,0,0,0,0,0,0, +9,5,3,6,12,6,0,4,116,121,112,101,0,0,0,0, +9,5,5,6,12,6,0,4,110,97,109,101,0,0,0,0, +23,5,5,6,21,5,0,0,18,0,0,10,11,7,0,0, +0,0,0,0,0,0,0,0,9,6,3,7,12,7,0,3, +118,97,108,0,9,6,6,7,15,5,6,0,18,0,0,34, +11,7,0,0,0,0,0,0,0,0,0,0,9,6,3,7, +12,7,0,5,105,116,101,109,115,0,0,0,9,6,6,7, +11,7,0,0,0,0,0,0,0,0,0,0,9,6,6,7, +12,7,0,3,118,97,108,0,9,6,6,7,15,5,6,0, +11,7,0,0,0,0,0,0,0,0,0,0,9,6,3,7, +12,7,0,5,105,116,101,109,115,0,0,0,9,6,6,7, +11,7,0,0,0,0,0,0,0,0,240,63,9,6,6,7, +12,7,0,3,118,97,108,0,9,6,6,7,15,4,6,0, +18,0,0,1,12,9,0,2,100,111,0,0,13,8,9,0, +12,11,0,5,84,111,107,101,110,0,0,0,13,10,11,0, +12,15,0,3,112,111,115,0,9,11,1,15,12,12,0,4, +100,105,99,116,0,0,0,0,11,13,0,0,0,0,0,0, +0,0,0,0,27,14,0,0,31,9,11,4,19,9,10,9, +31,7,9,1,19,7,8,7,15,6,7,0,12,10,0,10, +95,100,111,95,115,116,114,105,110,103,0,0,13,9,10,0, +15,10,5,0,31,8,10,1,19,8,9,8,15,7,8,0, +12,10,0,4,99,111,100,101,0,0,0,0,13,9,10,0, +12,13,0,4,71,83,69,84,0,0,0,0,13,10,13,0, +15,11,7,0,15,12,6,0,31,8,10,3,19,8,9,8, +12,10,0,8,102,114,101,101,95,116,109,112,0,0,0,0, +13,9,10,0,15,10,7,0,31,8,10,1,19,8,9,8, +11,9,0,0,0,0,0,0,0,0,0,0,15,8,9,0, +27,10,0,0,15,9,10,0,15,10,8,0,15,8,9,0, +21,4,0,0,18,0,0,78,12,12,0,6,97,112,112,101, +110,100,0,0,9,11,8,12,12,14,0,5,84,111,107,101, +110,0,0,0,13,13,14,0,12,18,0,3,112,111,115,0, +9,14,1,18,12,15,0,4,99,97,108,108,0,0,0,0, +28,16,0,0,12,21,0,5,84,111,107,101,110,0,0,0, +13,20,21,0,12,25,0,3,112,111,115,0,9,21,1,25, +12,22,0,3,103,101,116,0,28,23,0,0,12,28,0,5, +84,111,107,101,110,0,0,0,13,27,28,0,12,31,0,3, +112,111,115,0,9,28,1,31,12,29,0,4,110,97,109,101, +0,0,0,0,15,30,4,0,31,25,28,3,19,25,27,25, +12,28,0,5,84,111,107,101,110,0,0,0,13,27,28,0, +12,31,0,3,112,111,115,0,9,28,1,31,12,29,0,6, +115,116,114,105,110,103,0,0,12,30,0,7,95,95,110,101, +119,95,95,0,31,26,28,3,19,26,27,26,27,24,25,2, +31,18,21,4,19,18,20,18,12,21,0,5,84,111,107,101, +110,0,0,0,13,20,21,0,12,24,0,3,112,111,115,0, +9,21,1,24,12,22,0,4,110,97,109,101,0,0,0,0, +12,23,0,4,115,101,108,102,0,0,0,0,31,19,21,3, +19,19,20,19,27,17,18,2,31,12,14,4,19,12,13,12, +31,9,12,1,19,9,11,9,18,0,0,1,11,12,0,0, +0,0,0,0,0,0,240,63,9,11,3,12,12,12,0,5, +105,116,101,109,115,0,0,0,9,11,11,12,11,12,0,0, +0,0,0,0,0,0,0,0,42,9,11,12,18,0,0,190, +12,14,0,4,116,121,112,101,0,0,0,0,9,13,9,14, +12,14,0,3,100,101,102,0,35,13,13,14,21,13,0,0, +18,0,0,3,18,0,255,245,18,0,0,1,12,15,0,5, +105,116,101,109,115,0,0,0,9,14,9,15,11,15,0,0, +0,0,0,0,0,0,0,0,9,14,14,15,12,15,0,3, +118,97,108,0,9,14,14,15,15,13,14,0,12,15,0,8, +95,95,105,110,105,116,95,95,0,0,0,0,23,14,13,15, +21,14,0,0,18,0,0,6,11,14,0,0,0,0,0,0, +0,0,240,63,15,10,14,0,18,0,0,1,12,16,0,6, +100,111,95,100,101,102,0,0,13,15,16,0,15,16,9,0, +15,17,6,0,31,14,16,2,19,14,15,14,12,16,0,6, +97,112,112,101,110,100,0,0,9,15,8,16,12,18,0,5, +84,111,107,101,110,0,0,0,13,17,18,0,12,22,0,3, +112,111,115,0,9,18,9,22,12,19,0,6,115,121,109,98, +111,108,0,0,12,20,0,1,61,0,0,0,12,25,0,5, +84,111,107,101,110,0,0,0,13,24,25,0,12,29,0,3, +112,111,115,0,9,25,9,29,12,26,0,3,103,101,116,0, +28,27,0,0,12,32,0,5,84,111,107,101,110,0,0,0, +13,31,32,0,12,35,0,3,112,111,115,0,9,32,9,35, +12,33,0,4,110,97,109,101,0,0,0,0,12,34,0,4, +115,101,108,102,0,0,0,0,31,29,32,3,19,29,31,29, +12,32,0,5,84,111,107,101,110,0,0,0,13,31,32,0, +12,35,0,3,112,111,115,0,9,32,9,35,12,33,0,6, +115,116,114,105,110,103,0,0,15,34,13,0,31,30,32,3, +19,30,31,30,27,28,29,2,31,22,25,4,19,22,24,22, +12,25,0,5,84,111,107,101,110,0,0,0,13,24,25,0, +12,29,0,3,112,111,115,0,9,25,9,29,12,26,0,4, +99,97,108,108,0,0,0,0,28,27,0,0,12,33,0,5, +84,111,107,101,110,0,0,0,13,32,33,0,12,36,0,3, +112,111,115,0,9,33,9,36,12,34,0,4,110,97,109,101, +0,0,0,0,12,35,0,4,98,105,110,100,0,0,0,0, +31,29,33,3,19,29,32,29,12,33,0,5,84,111,107,101, +110,0,0,0,13,32,33,0,12,37,0,3,112,111,115,0, +9,33,9,37,12,34,0,3,103,101,116,0,28,35,0,0, +12,40,0,5,84,111,107,101,110,0,0,0,13,39,40,0, +12,43,0,3,112,111,115,0,9,40,9,43,12,41,0,4, +110,97,109,101,0,0,0,0,15,42,5,0,31,37,40,3, +19,37,39,37,12,40,0,5,84,111,107,101,110,0,0,0, +13,39,40,0,12,43,0,3,112,111,115,0,9,40,9,43, +12,41,0,6,115,116,114,105,110,103,0,0,15,42,13,0, +31,38,40,3,19,38,39,38,27,36,37,2,31,30,33,4, +19,30,32,30,12,33,0,5,84,111,107,101,110,0,0,0, +13,32,33,0,12,36,0,3,112,111,115,0,9,33,9,36, +12,34,0,4,110,97,109,101,0,0,0,0,12,35,0,4, +115,101,108,102,0,0,0,0,31,31,33,3,19,31,32,31, +27,28,29,3,31,23,25,4,19,23,24,23,27,21,22,2, +31,16,18,4,19,16,17,16,31,14,16,1,19,14,15,14, +18,0,255,66,12,14,0,6,100,111,95,100,101,102,0,0, +13,12,14,0,12,17,0,5,84,111,107,101,110,0,0,0, +13,16,17,0,12,21,0,3,112,111,115,0,9,17,1,21, +12,18,0,3,100,101,102,0,28,19,0,0,12,25,0,5, +84,111,107,101,110,0,0,0,13,24,25,0,12,28,0,3, +112,111,115,0,9,25,1,28,12,26,0,4,110,97,109,101, +0,0,0,0,12,27,0,7,95,95,110,101,119,95,95,0, +31,21,25,3,19,21,24,21,12,25,0,5,84,111,107,101, +110,0,0,0,13,24,25,0,12,29,0,3,112,111,115,0, +9,25,1,29,12,26,0,4,108,105,115,116,0,0,0,0, +28,27,0,0,12,31,0,5,84,111,107,101,110,0,0,0, +13,30,31,0,12,34,0,3,112,111,115,0,9,31,1,34, +12,32,0,4,110,97,109,101,0,0,0,0,12,33,0,4, +115,101,108,102,0,0,0,0,31,29,31,3,19,29,30,29, +27,28,29,1,31,22,25,4,19,22,24,22,12,25,0,5, +84,111,107,101,110,0,0,0,13,24,25,0,12,29,0,3, +112,111,115,0,9,25,1,29,12,26,0,10,115,116,97,116, +101,109,101,110,116,115,0,0,28,27,0,0,15,28,8,0, +31,23,25,4,19,23,24,23,27,20,21,3,31,14,17,4, +19,14,16,14,15,15,6,0,31,11,14,2,19,11,12,11, +12,14,0,7,103,101,116,95,116,97,103,0,13,12,14,0, +31,11,0,0,19,11,12,11,15,1,11,0,12,15,0,3, +102,110,99,0,13,14,15,0,15,15,1,0,12,16,0,3, +101,110,100,0,31,12,15,2,19,12,14,12,15,11,12,0, +12,15,0,1,68,0,0,0,13,14,15,0,12,15,0,5, +98,101,103,105,110,0,0,0,9,14,14,15,31,12,0,0, +19,12,14,12,12,16,0,8,100,111,95,108,111,99,97,108, +0,0,0,0,13,15,16,0,12,18,0,5,84,111,107,101, +110,0,0,0,13,17,18,0,12,21,0,3,112,111,115,0, +9,18,2,21,12,19,0,4,110,97,109,101,0,0,0,0, +12,20,0,8,95,95,112,97,114,97,109,115,0,0,0,0, +31,16,18,3,19,16,17,16,31,14,16,1,19,14,15,14, +15,12,14,0,12,17,0,8,100,111,95,108,111,99,97,108, +0,0,0,0,13,16,17,0,12,19,0,5,84,111,107,101, +110,0,0,0,13,18,19,0,12,22,0,3,112,111,115,0, +9,19,2,22,12,20,0,4,110,97,109,101,0,0,0,0, +12,21,0,4,115,101,108,102,0,0,0,0,31,17,19,3, +19,17,18,17,31,15,17,1,19,15,16,15,15,14,15,0, +12,17,0,4,99,111,100,101,0,0,0,0,13,16,17,0, +12,21,0,4,68,73,67,84,0,0,0,0,13,17,21,0, +15,18,14,0,11,19,0,0,0,0,0,0,0,0,0,0, +11,20,0,0,0,0,0,0,0,0,0,0,31,15,17,4, +19,15,16,15,12,17,0,8,102,114,101,101,95,116,109,112, +0,0,0,0,13,16,17,0,12,19,0,2,100,111,0,0, +13,18,19,0,12,21,0,5,84,111,107,101,110,0,0,0, +13,20,21,0,12,25,0,3,112,111,115,0,9,21,2,25, +12,22,0,4,99,97,108,108,0,0,0,0,28,23,0,0, +12,28,0,5,84,111,107,101,110,0,0,0,13,27,28,0, +12,32,0,3,112,111,115,0,9,28,2,32,12,29,0,3, +103,101,116,0,28,30,0,0,12,35,0,5,84,111,107,101, +110,0,0,0,13,34,35,0,12,38,0,3,112,111,115,0, +9,35,2,38,12,36,0,4,110,97,109,101,0,0,0,0, +15,37,5,0,31,32,35,3,19,32,34,32,12,35,0,5, +84,111,107,101,110,0,0,0,13,34,35,0,12,38,0,3, +112,111,115,0,9,35,2,38,12,36,0,6,115,116,114,105, +110,103,0,0,12,37,0,7,95,95,110,101,119,95,95,0, +31,33,35,3,19,33,34,33,27,31,32,2,31,25,28,4, +19,25,27,25,12,28,0,5,84,111,107,101,110,0,0,0, +13,27,28,0,12,31,0,3,112,111,115,0,9,28,2,31, +12,29,0,4,110,97,109,101,0,0,0,0,12,30,0,4, +115,101,108,102,0,0,0,0,31,26,28,3,19,26,27,26, +27,24,25,2,31,19,21,4,19,19,20,19,31,17,19,1, +19,17,18,17,31,15,17,1,19,15,16,15,21,10,0,0, +18,0,0,77,12,18,0,7,103,101,116,95,116,109,112,0, +13,17,18,0,31,16,0,0,19,16,17,16,15,15,16,0, +12,19,0,10,95,100,111,95,115,116,114,105,110,103,0,0, +13,18,19,0,12,19,0,8,95,95,105,110,105,116,95,95, +0,0,0,0,31,17,19,1,19,17,18,17,15,16,17,0, +12,19,0,4,99,111,100,101,0,0,0,0,13,18,19,0, +12,23,0,3,71,69,84,0,13,19,23,0,15,20,15,0, +15,21,14,0,15,22,16,0,31,17,19,4,19,17,18,17, +12,20,0,7,103,101,116,95,116,109,112,0,13,19,20,0, +31,18,0,0,19,18,19,18,15,17,18,0,12,20,0,4, +99,111,100,101,0,0,0,0,13,19,20,0,12,24,0,4, +67,65,76,76,0,0,0,0,13,20,24,0,15,21,17,0, +15,22,15,0,15,23,12,0,31,18,20,4,19,18,19,18, +12,20,0,8,102,114,101,101,95,116,109,112,0,0,0,0, +13,19,20,0,15,20,15,0,31,18,20,1,19,18,19,18, +12,20,0,8,102,114,101,101,95,116,109,112,0,0,0,0, +13,19,20,0,15,20,16,0,31,18,20,1,19,18,19,18, +12,20,0,8,102,114,101,101,95,116,109,112,0,0,0,0, +13,19,20,0,15,20,17,0,31,18,20,1,19,18,19,18, +18,0,0,1,12,20,0,4,99,111,100,101,0,0,0,0, +13,19,20,0,12,22,0,6,82,69,84,85,82,78,0,0, +13,20,22,0,15,21,14,0,31,18,20,2,19,18,19,18, +12,20,0,1,68,0,0,0,13,19,20,0,12,20,0,3, +101,110,100,0,9,19,19,20,31,18,0,0,19,18,19,18, +12,20,0,3,116,97,103,0,13,19,20,0,15,20,1,0, +12,21,0,3,101,110,100,0,31,18,20,2,19,18,19,18, +12,20,0,10,95,100,111,95,115,116,114,105,110,103,0,0, +13,19,20,0,12,20,0,8,95,95,99,97,108,108,95,95, +0,0,0,0,31,18,20,1,19,18,19,18,15,7,18,0, +12,20,0,4,99,111,100,101,0,0,0,0,13,19,20,0, +12,24,0,3,83,69,84,0,13,20,24,0,15,21,6,0, +15,22,7,0,15,23,11,0,31,18,20,4,19,18,19,18, +12,20,0,8,102,114,101,101,95,116,109,112,0,0,0,0, +13,19,20,0,15,20,6,0,31,18,20,1,19,18,19,18, +12,20,0,8,102,114,101,101,95,116,109,112,0,0,0,0, +13,19,20,0,15,20,7,0,31,18,20,1,19,18,19,18, +0,0,0,0,12,50,0,8,100,111,95,99,108,97,115,115, +0,0,0,0,14,50,49,0,16,50,0,123,44,10,0,0, +28,2,0,0,9,1,0,2,12,4,0,5,105,116,101,109, +115,0,0,0,9,3,1,4,15,2,3,0,12,5,0,9, +115,116,97,99,107,95,116,97,103,0,0,0,13,4,5,0, +31,3,0,0,19,3,4,3,15,1,3,0,12,5,0,3, +116,97,103,0,13,4,5,0,15,5,1,0,12,6,0,5, +98,101,103,105,110,0,0,0,31,3,5,2,19,3,4,3, +12,5,0,3,116,97,103,0,13,4,5,0,15,5,1,0, +12,6,0,8,99,111,110,116,105,110,117,101,0,0,0,0, +31,3,5,2,19,3,4,3,12,6,0,2,100,111,0,0, +13,5,6,0,11,7,0,0,0,0,0,0,0,0,0,0, +9,6,2,7,31,4,6,1,19,4,5,4,15,3,4,0, +12,6,0,4,99,111,100,101,0,0,0,0,13,5,6,0, +12,8,0,2,73,70,0,0,13,6,8,0,15,7,3,0, +31,4,6,2,19,4,5,4,12,6,0,8,102,114,101,101, +95,116,109,112,0,0,0,0,13,5,6,0,15,6,3,0, +31,4,6,1,19,4,5,4,12,6,0,4,106,117,109,112, +0,0,0,0,13,5,6,0,15,6,1,0,12,7,0,3, +101,110,100,0,31,4,6,2,19,4,5,4,12,6,0,8, +102,114,101,101,95,116,109,112,0,0,0,0,13,5,6,0, +12,8,0,2,100,111,0,0,13,7,8,0,11,9,0,0, +0,0,0,0,0,0,240,63,9,8,2,9,31,6,8,1, +19,6,7,6,31,4,6,1,19,4,5,4,12,6,0,4, +106,117,109,112,0,0,0,0,13,5,6,0,15,6,1,0, +12,7,0,5,98,101,103,105,110,0,0,0,31,4,6,2, +19,4,5,4,12,6,0,3,116,97,103,0,13,5,6,0, +15,6,1,0,12,7,0,5,98,114,101,97,107,0,0,0, +31,4,6,2,19,4,5,4,12,6,0,3,116,97,103,0, +13,5,6,0,15,6,1,0,12,7,0,3,101,110,100,0, +31,4,6,2,19,4,5,4,12,6,0,7,112,111,112,95, +116,97,103,0,13,5,6,0,31,4,0,0,19,4,5,4, +0,0,0,0,12,51,0,8,100,111,95,119,104,105,108,101, +0,0,0,0,14,51,50,0,16,51,0,156,44,14,0,0, +28,2,0,0,9,1,0,2,12,4,0,5,105,116,101,109, +115,0,0,0,9,3,1,4,15,2,3,0,12,6,0,8, +100,111,95,108,111,99,97,108,0,0,0,0,13,5,6,0, +11,7,0,0,0,0,0,0,0,0,0,0,9,6,2,7, +31,4,6,1,19,4,5,4,15,3,4,0,12,7,0,2, +100,111,0,0,13,6,7,0,11,8,0,0,0,0,0,0, +0,0,240,63,9,7,2,8,31,5,7,1,19,5,6,5, +15,4,5,0,12,8,0,10,95,100,111,95,110,117,109,98, +101,114,0,0,13,7,8,0,12,8,0,1,48,0,0,0, +31,6,8,1,19,6,7,6,15,5,6,0,12,9,0,9, +115,116,97,99,107,95,116,97,103,0,0,0,13,8,9,0, +31,7,0,0,19,7,8,7,15,6,7,0,12,9,0,3, +116,97,103,0,13,8,9,0,15,9,6,0,12,10,0,4, +108,111,111,112,0,0,0,0,31,7,9,2,19,7,8,7, +12,9,0,3,116,97,103,0,13,8,9,0,15,9,6,0, +12,10,0,8,99,111,110,116,105,110,117,101,0,0,0,0, +31,7,9,2,19,7,8,7,12,9,0,4,99,111,100,101, +0,0,0,0,13,8,9,0,12,13,0,4,73,84,69,82, +0,0,0,0,13,9,13,0,15,10,3,0,15,11,4,0, +15,12,5,0,31,7,9,4,19,7,8,7,12,9,0,4, +106,117,109,112,0,0,0,0,13,8,9,0,15,9,6,0, +12,10,0,3,101,110,100,0,31,7,9,2,19,7,8,7, +12,9,0,8,102,114,101,101,95,116,109,112,0,0,0,0, +13,8,9,0,12,11,0,2,100,111,0,0,13,10,11,0, +11,12,0,0,0,0,0,0,0,0,0,64,9,11,2,12, +31,9,11,1,19,9,10,9,31,7,9,1,19,7,8,7, +12,9,0,4,106,117,109,112,0,0,0,0,13,8,9,0, +15,9,6,0,12,10,0,4,108,111,111,112,0,0,0,0, +31,7,9,2,19,7,8,7,12,9,0,3,116,97,103,0, +13,8,9,0,15,9,6,0,12,10,0,5,98,114,101,97, +107,0,0,0,31,7,9,2,19,7,8,7,12,9,0,3, +116,97,103,0,13,8,9,0,15,9,6,0,12,10,0,3, +101,110,100,0,31,7,9,2,19,7,8,7,12,9,0,7, +112,111,112,95,116,97,103,0,13,8,9,0,31,7,0,0, +19,7,8,7,12,9,0,8,102,114,101,101,95,116,109,112, +0,0,0,0,13,8,9,0,15,9,4,0,31,7,9,1, +19,7,8,7,12,9,0,8,102,114,101,101,95,116,109,112, +0,0,0,0,13,8,9,0,15,9,5,0,31,7,9,1, +19,7,8,7,0,0,0,0,12,52,0,6,100,111,95,102, +111,114,0,0,14,52,51,0,16,52,0,159,44,18,0,0, +28,2,0,0,9,1,0,2,28,2,0,0,28,3,0,0, +32,2,0,3,12,4,0,5,99,111,109,112,58,0,0,0, +12,7,0,7,103,101,116,95,116,97,103,0,13,6,7,0, +31,5,0,0,19,5,6,5,1,4,4,5,15,3,4,0, +12,6,0,8,100,111,95,108,111,99,97,108,0,0,0,0, +13,5,6,0,12,8,0,5,84,111,107,101,110,0,0,0, +13,7,8,0,12,11,0,3,112,111,115,0,9,8,1,11, +12,9,0,4,110,97,109,101,0,0,0,0,15,10,3,0, +31,6,8,3,19,6,7,6,31,4,6,1,19,4,5,4, +15,2,4,0,12,6,0,4,99,111,100,101,0,0,0,0, +13,5,6,0,12,10,0,4,76,73,83,84,0,0,0,0, +13,6,10,0,15,7,2,0,11,8,0,0,0,0,0,0, +0,0,0,0,11,9,0,0,0,0,0,0,0,0,0,0, +31,4,6,4,19,4,5,4,12,7,0,5,84,111,107,101, +110,0,0,0,13,6,7,0,12,11,0,3,112,111,115,0, +9,7,1,11,12,8,0,3,103,101,116,0,28,9,0,0, +12,14,0,5,84,111,107,101,110,0,0,0,13,13,14,0, +12,17,0,3,112,111,115,0,9,14,1,17,12,15,0,3, +114,101,103,0,15,16,2,0,31,11,14,3,19,11,13,11, +12,14,0,5,84,111,107,101,110,0,0,0,13,13,14,0, +12,17,0,3,112,111,115,0,9,14,1,17,12,15,0,6, +115,121,109,98,111,108,0,0,12,16,0,4,78,111,110,101, +0,0,0,0,31,12,14,3,19,12,13,12,27,10,11,2, +31,5,7,4,19,5,6,5,15,4,5,0,12,8,0,5, +84,111,107,101,110,0,0,0,13,7,8,0,12,12,0,3, +112,111,115,0,9,8,1,12,12,9,0,6,115,121,109,98, +111,108,0,0,12,10,0,1,61,0,0,0,15,12,4,0, +12,14,0,5,105,116,101,109,115,0,0,0,9,13,1,14, +11,14,0,0,0,0,0,0,0,0,0,0,9,13,13,14, +27,11,12,2,31,6,8,4,19,6,7,6,15,5,6,0, +12,8,0,2,100,111,0,0,13,7,8,0,12,10,0,5, +84,111,107,101,110,0,0,0,13,9,10,0,12,14,0,3, +112,111,115,0,9,10,1,14,12,11,0,3,102,111,114,0, +28,12,0,0,12,17,0,5,105,116,101,109,115,0,0,0, +9,14,1,17,11,17,0,0,0,0,0,0,0,0,240,63, +9,14,14,17,12,17,0,5,105,116,101,109,115,0,0,0, +9,15,1,17,11,17,0,0,0,0,0,0,0,0,0,64, +9,15,15,17,15,16,5,0,27,13,14,3,31,8,10,4, +19,8,9,8,31,6,8,1,19,6,7,6,20,2,0,0, +0,0,0,0,12,53,0,7,100,111,95,99,111,109,112,0, +14,53,52,0,16,53,0,171,44,13,0,0,28,2,0,0, +9,1,0,2,12,4,0,5,105,116,101,109,115,0,0,0, +9,3,1,4,15,2,3,0,12,5,0,7,103,101,116,95, +116,97,103,0,13,4,5,0,31,3,0,0,19,3,4,3, +15,1,3,0,11,4,0,0,0,0,0,0,0,0,0,0, +15,3,4,0,11,5,0,0,0,0,0,0,0,0,0,0, +42,4,2,5,18,0,0,131,12,8,0,3,116,97,103,0, +13,7,8,0,15,8,1,0,15,9,3,0,31,6,8,2, +19,6,7,6,12,7,0,4,116,121,112,101,0,0,0,0, +9,6,4,7,12,7,0,4,101,108,105,102,0,0,0,0, +23,6,6,7,21,6,0,0,18,0,0,65,12,9,0,2, +100,111,0,0,13,8,9,0,12,10,0,5,105,116,101,109, +115,0,0,0,9,9,4,10,11,10,0,0,0,0,0,0, +0,0,0,0,9,9,9,10,31,7,9,1,19,7,8,7, +15,6,7,0,12,9,0,4,99,111,100,101,0,0,0,0, +13,8,9,0,12,11,0,2,73,70,0,0,13,9,11,0, +15,10,6,0,31,7,9,2,19,7,8,7,12,9,0,8, +102,114,101,101,95,116,109,112,0,0,0,0,13,8,9,0, +15,9,6,0,31,7,9,1,19,7,8,7,12,9,0,4, +106,117,109,112,0,0,0,0,13,8,9,0,15,9,1,0, +11,11,0,0,0,0,0,0,0,0,240,63,1,10,3,11, +31,7,9,2,19,7,8,7,12,9,0,8,102,114,101,101, +95,116,109,112,0,0,0,0,13,8,9,0,12,11,0,2, +100,111,0,0,13,10,11,0,12,12,0,5,105,116,101,109, +115,0,0,0,9,11,4,12,11,12,0,0,0,0,0,0, +0,0,240,63,9,11,11,12,31,9,11,1,19,9,10,9, +31,7,9,1,19,7,8,7,18,0,0,35,12,8,0,4, +116,121,112,101,0,0,0,0,9,7,4,8,12,8,0,4, +101,108,115,101,0,0,0,0,23,7,7,8,21,7,0,0, +18,0,0,22,12,9,0,8,102,114,101,101,95,116,109,112, +0,0,0,0,13,8,9,0,12,11,0,2,100,111,0,0, +13,10,11,0,12,12,0,5,105,116,101,109,115,0,0,0, +9,11,4,12,11,12,0,0,0,0,0,0,0,0,0,0, +9,11,11,12,31,9,11,1,19,9,10,9,31,7,9,1, +19,7,8,7,18,0,0,4,28,7,0,0,37,7,0,0, +18,0,0,1,12,9,0,4,106,117,109,112,0,0,0,0, +13,8,9,0,15,9,1,0,12,10,0,3,101,110,100,0, +31,7,9,2,19,7,8,7,11,8,0,0,0,0,0,0, +0,0,240,63,1,7,3,8,15,3,7,0,18,0,255,125, +12,8,0,3,116,97,103,0,13,7,8,0,15,8,1,0, +15,9,3,0,31,5,8,2,19,5,7,5,12,8,0,3, +116,97,103,0,13,7,8,0,15,8,1,0,12,9,0,3, +101,110,100,0,31,5,8,2,19,5,7,5,0,0,0,0, +12,54,0,5,100,111,95,105,102,0,0,0,14,54,53,0, +16,54,0,93,44,9,0,0,28,2,0,0,9,1,0,2, +12,4,0,5,105,116,101,109,115,0,0,0,9,3,1,4, +15,2,3,0,12,5,0,7,103,101,116,95,116,97,103,0, +13,4,5,0,31,3,0,0,19,3,4,3,15,1,3,0, +12,5,0,6,115,101,116,106,109,112,0,0,13,4,5,0, +15,5,1,0,12,6,0,6,101,120,99,101,112,116,0,0, +31,3,5,2,19,3,4,3,12,5,0,8,102,114,101,101, +95,116,109,112,0,0,0,0,13,4,5,0,12,7,0,2, +100,111,0,0,13,6,7,0,11,8,0,0,0,0,0,0, +0,0,0,0,9,7,2,8,31,5,7,1,19,5,6,5, +31,3,5,1,19,3,4,3,12,5,0,4,106,117,109,112, +0,0,0,0,13,4,5,0,15,5,1,0,12,6,0,3, +101,110,100,0,31,3,5,2,19,3,4,3,12,5,0,3, +116,97,103,0,13,4,5,0,15,5,1,0,12,6,0,6, +101,120,99,101,112,116,0,0,31,3,5,2,19,3,4,3, +12,5,0,8,102,114,101,101,95,116,109,112,0,0,0,0, +13,4,5,0,12,7,0,2,100,111,0,0,13,6,7,0, +11,8,0,0,0,0,0,0,0,0,240,63,9,7,2,8, +12,8,0,5,105,116,101,109,115,0,0,0,9,7,7,8, +11,8,0,0,0,0,0,0,0,0,240,63,9,7,7,8, +31,5,7,1,19,5,6,5,31,3,5,1,19,3,4,3, +12,5,0,3,116,97,103,0,13,4,5,0,15,5,1,0, +12,6,0,3,101,110,100,0,31,3,5,2,19,3,4,3, +0,0,0,0,12,55,0,6,100,111,95,116,114,121,0,0, +14,55,54,0,16,55,0,56,44,8,0,0,28,2,0,0, +9,1,0,2,12,3,0,5,105,116,101,109,115,0,0,0, +9,2,1,3,21,2,0,0,18,0,0,16,12,5,0,2, +100,111,0,0,13,4,5,0,12,6,0,5,105,116,101,109, +115,0,0,0,9,5,1,6,11,6,0,0,0,0,0,0, +0,0,0,0,9,5,5,6,31,3,5,1,19,3,4,3, +15,2,3,0,18,0,0,10,12,5,0,8,95,100,111,95, +110,111,110,101,0,0,0,0,13,4,5,0,31,3,0,0, +19,3,4,3,15,2,3,0,18,0,0,1,12,5,0,4, +99,111,100,101,0,0,0,0,13,4,5,0,12,7,0,6, +82,69,84,85,82,78,0,0,13,5,7,0,15,6,2,0, +31,3,5,2,19,3,4,3,12,5,0,8,102,114,101,101, +95,116,109,112,0,0,0,0,13,4,5,0,15,5,2,0, +31,3,5,1,19,3,4,3,28,3,0,0,20,3,0,0, +0,0,0,0,12,56,0,9,100,111,95,114,101,116,117,114, +110,0,0,0,14,56,55,0,16,56,0,56,44,8,0,0, +28,2,0,0,9,1,0,2,12,3,0,5,105,116,101,109, +115,0,0,0,9,2,1,3,21,2,0,0,18,0,0,16, +12,5,0,2,100,111,0,0,13,4,5,0,12,6,0,5, +105,116,101,109,115,0,0,0,9,5,1,6,11,6,0,0, +0,0,0,0,0,0,0,0,9,5,5,6,31,3,5,1, +19,3,4,3,15,2,3,0,18,0,0,10,12,5,0,8, +95,100,111,95,110,111,110,101,0,0,0,0,13,4,5,0, +31,3,0,0,19,3,4,3,15,2,3,0,18,0,0,1, +12,5,0,4,99,111,100,101,0,0,0,0,13,4,5,0, +12,7,0,5,82,65,73,83,69,0,0,0,13,5,7,0, +15,6,2,0,31,3,5,2,19,3,4,3,12,5,0,8, +102,114,101,101,95,116,109,112,0,0,0,0,13,4,5,0, +15,5,2,0,31,3,5,1,19,3,4,3,28,3,0,0, +20,3,0,0,0,0,0,0,12,57,0,8,100,111,95,114, +97,105,115,101,0,0,0,0,14,57,56,0,16,57,0,28, +44,10,0,0,28,2,0,0,9,1,0,2,12,4,0,5, +105,116,101,109,115,0,0,0,9,3,1,4,11,4,0,0, +0,0,0,0,0,0,0,0,42,2,3,4,18,0,0,15, +12,7,0,8,102,114,101,101,95,116,109,112,0,0,0,0, +13,6,7,0,12,9,0,2,100,111,0,0,13,8,9,0, +15,9,2,0,31,7,9,1,19,7,8,7,31,5,7,1, +19,5,6,5,18,0,255,241,0,0,0,0,12,58,0,13, +100,111,95,115,116,97,116,101,109,101,110,116,115,0,0,0, +14,58,57,0,16,58,0,33,44,9,0,0,28,2,0,0, +9,1,0,2,28,2,0,0,28,3,0,0,32,2,0,3, +12,5,0,7,103,101,116,95,116,109,112,0,13,4,5,0, +15,5,2,0,31,3,5,1,19,3,4,3,15,2,3,0, +12,5,0,10,109,97,110,97,103,101,95,115,101,113,0,0, +13,4,5,0,12,8,0,4,76,73,83,84,0,0,0,0, +13,5,8,0,15,6,2,0,12,8,0,5,105,116,101,109, +115,0,0,0,9,7,1,8,31,3,5,3,19,3,4,3, +20,2,0,0,0,0,0,0,12,59,0,7,100,111,95,108, +105,115,116,0,14,59,58,0,16,59,0,33,44,9,0,0, +28,2,0,0,9,1,0,2,28,2,0,0,28,3,0,0, +32,2,0,3,12,5,0,7,103,101,116,95,116,109,112,0, +13,4,5,0,15,5,2,0,31,3,5,1,19,3,4,3, +15,2,3,0,12,5,0,10,109,97,110,97,103,101,95,115, +101,113,0,0,13,4,5,0,12,8,0,4,68,73,67,84, +0,0,0,0,13,5,8,0,15,6,2,0,12,8,0,5, +105,116,101,109,115,0,0,0,9,7,1,8,31,3,5,3, +19,3,4,3,20,2,0,0,0,0,0,0,12,60,0,7, +100,111,95,100,105,99,116,0,14,60,59,0,16,60,0,32, +44,11,0,0,28,2,0,0,9,1,0,2,28,2,0,0, +28,3,0,0,32,2,0,3,12,5,0,5,105,116,101,109, +115,0,0,0,9,4,1,5,15,3,4,0,12,6,0,5, +105,110,102,105,120,0,0,0,13,5,6,0,12,10,0,3, +71,69,84,0,13,6,10,0,11,10,0,0,0,0,0,0, +0,0,0,0,9,7,3,10,11,10,0,0,0,0,0,0, +0,0,240,63,9,8,3,10,15,9,2,0,31,4,6,4, +19,4,5,4,20,4,0,0,0,0,0,0,12,61,0,6, +100,111,95,103,101,116,0,0,14,61,60,0,16,61,0,25, +44,7,0,0,28,2,0,0,9,1,0,2,12,4,0,4, +106,117,109,112,0,0,0,0,13,3,4,0,12,6,0,1, +68,0,0,0,13,4,6,0,12,6,0,6,116,115,116,97, +99,107,0,0,9,4,4,6,11,6,0,0,0,0,0,0, +0,0,240,191,9,4,4,6,12,5,0,5,98,114,101,97, +107,0,0,0,31,2,4,2,19,2,3,2,0,0,0,0, +12,62,0,8,100,111,95,98,114,101,97,107,0,0,0,0, +14,62,61,0,16,62,0,26,44,7,0,0,28,2,0,0, +9,1,0,2,12,4,0,4,106,117,109,112,0,0,0,0, +13,3,4,0,12,6,0,1,68,0,0,0,13,4,6,0, +12,6,0,6,116,115,116,97,99,107,0,0,9,4,4,6, +11,6,0,0,0,0,0,0,0,0,240,191,9,4,4,6, +12,5,0,8,99,111,110,116,105,110,117,101,0,0,0,0, +31,2,4,2,19,2,3,2,0,0,0,0,12,63,0,11, +100,111,95,99,111,110,116,105,110,117,101,0,14,63,62,0, +16,63,0,15,44,6,0,0,28,2,0,0,9,1,0,2, +12,4,0,4,99,111,100,101,0,0,0,0,13,3,4,0, +12,5,0,4,80,65,83,83,0,0,0,0,13,4,5,0, +31,2,4,1,19,2,3,2,0,0,0,0,12,64,0,7, +100,111,95,112,97,115,115,0,14,64,63,0,16,64,0,76, +44,11,0,0,12,1,0,1,63,0,0,0,28,2,0,0, +32,1,0,2,12,3,0,4,65,82,71,86,0,0,0,0, +13,2,3,0,12,3,0,6,45,110,111,112,111,115,0,0, +36,2,2,3,21,2,0,0,18,0,0,4,28,2,0,0, +20,2,0,0,18,0,0,1,12,4,0,4,99,111,100,101, +0,0,0,0,13,3,4,0,12,6,0,4,70,73,76,69, +0,0,0,0,13,4,6,0,12,7,0,8,102,114,101,101, +95,116,109,112,0,0,0,0,13,6,7,0,12,9,0,10, +95,100,111,95,115,116,114,105,110,103,0,0,13,8,9,0, +12,10,0,1,68,0,0,0,13,9,10,0,12,10,0,5, +102,110,97,109,101,0,0,0,9,9,9,10,31,7,9,1, +19,7,8,7,31,5,7,1,19,5,6,5,31,2,4,2, +19,2,3,2,12,4,0,4,99,111,100,101,0,0,0,0, +13,3,4,0,12,6,0,4,78,65,77,69,0,0,0,0, +13,4,6,0,12,7,0,8,102,114,101,101,95,116,109,112, +0,0,0,0,13,6,7,0,12,9,0,10,95,100,111,95, +115,116,114,105,110,103,0,0,13,8,9,0,15,9,1,0, +31,7,9,1,19,7,8,7,31,5,7,1,19,5,6,5, +31,2,4,2,19,2,3,2,0,0,0,0,12,65,0,7, +100,111,95,105,110,102,111,0,14,65,64,0,16,65,0,31, +44,8,0,0,28,2,0,0,9,1,0,2,12,4,0,7, +100,111,95,105,110,102,111,0,13,3,4,0,31,2,0,0, +19,2,3,2,12,4,0,8,102,114,101,101,95,116,109,112, +0,0,0,0,13,3,4,0,12,6,0,2,100,111,0,0, +13,5,6,0,12,7,0,5,105,116,101,109,115,0,0,0, +9,6,1,7,11,7,0,0,0,0,0,0,0,0,0,0, +9,6,6,7,31,4,6,1,19,4,5,4,31,2,4,1, +19,2,3,2,0,0,0,0,12,66,0,9,100,111,95,109, +111,100,117,108,101,0,0,0,14,66,65,0,16,66,0,12, +44,5,0,0,28,2,0,0,9,1,0,2,28,2,0,0, +28,3,0,0,32,2,0,3,12,4,0,3,118,97,108,0, +9,3,1,4,20,3,0,0,0,0,0,0,12,67,0,6, +100,111,95,114,101,103,0,0,14,67,66,0,12,67,0,4, +102,109,97,112,0,0,0,0,12,69,0,6,109,111,100,117, +108,101,0,0,12,103,0,9,100,111,95,109,111,100,117,108, +101,0,0,0,13,70,103,0,12,71,0,10,115,116,97,116, +101,109,101,110,116,115,0,0,12,103,0,13,100,111,95,115, +116,97,116,101,109,101,110,116,115,0,0,0,13,72,103,0, +12,73,0,3,100,101,102,0,12,103,0,6,100,111,95,100, +101,102,0,0,13,74,103,0,12,75,0,6,114,101,116,117, +114,110,0,0,12,103,0,9,100,111,95,114,101,116,117,114, +110,0,0,0,13,76,103,0,12,77,0,5,119,104,105,108, +101,0,0,0,12,103,0,8,100,111,95,119,104,105,108,101, +0,0,0,0,13,78,103,0,12,79,0,2,105,102,0,0, +12,103,0,5,100,111,95,105,102,0,0,0,13,80,103,0, +12,81,0,5,98,114,101,97,107,0,0,0,12,103,0,8, +100,111,95,98,114,101,97,107,0,0,0,0,13,82,103,0, +12,83,0,4,112,97,115,115,0,0,0,0,12,103,0,7, +100,111,95,112,97,115,115,0,13,84,103,0,12,85,0,8, +99,111,110,116,105,110,117,101,0,0,0,0,12,103,0,11, +100,111,95,99,111,110,116,105,110,117,101,0,13,86,103,0, +12,87,0,3,102,111,114,0,12,103,0,6,100,111,95,102, +111,114,0,0,13,88,103,0,12,89,0,5,99,108,97,115, +115,0,0,0,12,103,0,8,100,111,95,99,108,97,115,115, +0,0,0,0,13,90,103,0,12,91,0,5,114,97,105,115, +101,0,0,0,12,103,0,8,100,111,95,114,97,105,115,101, +0,0,0,0,13,92,103,0,12,93,0,3,116,114,121,0, +12,103,0,6,100,111,95,116,114,121,0,0,13,94,103,0, +12,95,0,6,105,109,112,111,114,116,0,0,12,103,0,9, +100,111,95,105,109,112,111,114,116,0,0,0,13,96,103,0, +12,97,0,7,103,108,111,98,97,108,115,0,12,103,0,10, +100,111,95,103,108,111,98,97,108,115,0,0,13,98,103,0, +12,99,0,3,100,101,108,0,12,103,0,6,100,111,95,100, +101,108,0,0,13,100,103,0,12,101,0,4,102,114,111,109, +0,0,0,0,12,103,0,7,100,111,95,102,114,111,109,0, +13,102,103,0,26,68,69,34,14,67,68,0,12,67,0,4, +114,109,97,112,0,0,0,0,12,69,0,4,108,105,115,116, +0,0,0,0,12,93,0,7,100,111,95,108,105,115,116,0, +13,70,93,0,12,71,0,5,116,117,112,108,101,0,0,0, +12,93,0,7,100,111,95,108,105,115,116,0,13,72,93,0, +12,73,0,4,100,105,99,116,0,0,0,0,12,93,0,7, +100,111,95,100,105,99,116,0,13,74,93,0,12,75,0,5, +115,108,105,99,101,0,0,0,12,93,0,7,100,111,95,108, +105,115,116,0,13,76,93,0,12,77,0,4,99,111,109,112, +0,0,0,0,12,93,0,7,100,111,95,99,111,109,112,0, +13,78,93,0,12,79,0,4,110,97,109,101,0,0,0,0, +12,93,0,7,100,111,95,110,97,109,101,0,13,80,93,0, +12,81,0,6,115,121,109,98,111,108,0,0,12,93,0,9, +100,111,95,115,121,109,98,111,108,0,0,0,13,82,93,0, +12,83,0,6,110,117,109,98,101,114,0,0,12,93,0,9, +100,111,95,110,117,109,98,101,114,0,0,0,13,84,93,0, +12,85,0,6,115,116,114,105,110,103,0,0,12,93,0,9, +100,111,95,115,116,114,105,110,103,0,0,0,13,86,93,0, +12,87,0,3,103,101,116,0,12,93,0,6,100,111,95,103, +101,116,0,0,13,88,93,0,12,89,0,4,99,97,108,108, +0,0,0,0,12,93,0,7,100,111,95,99,97,108,108,0, +13,90,93,0,12,91,0,3,114,101,103,0,12,93,0,6, +100,111,95,114,101,103,0,0,13,92,93,0,26,68,69,24, +14,67,68,0,16,67,0,110,44,9,0,0,28,2,0,0, +9,1,0,2,28,2,0,0,28,3,0,0,32,2,0,3, +12,4,0,3,112,111,115,0,9,3,1,4,21,3,0,0, +18,0,0,11,12,5,0,6,115,101,116,112,111,115,0,0, +13,4,5,0,12,6,0,3,112,111,115,0,9,5,1,6, +31,3,5,1,19,3,4,3,18,0,0,1,38,0,0,41, +12,4,0,4,114,109,97,112,0,0,0,0,13,3,4,0, +12,5,0,4,116,121,112,101,0,0,0,0,9,4,1,5, +36,3,3,4,21,3,0,0,18,0,0,16,12,5,0,4, +114,109,97,112,0,0,0,0,13,4,5,0,12,6,0,4, +116,121,112,101,0,0,0,0,9,5,1,6,9,4,4,5, +15,5,1,0,15,6,2,0,31,3,5,2,19,3,4,3, +20,3,0,0,18,0,0,1,12,5,0,4,102,109,97,112, +0,0,0,0,13,4,5,0,12,6,0,4,116,121,112,101, +0,0,0,0,9,5,1,6,9,4,4,5,15,5,1,0, +31,3,5,1,19,3,4,3,20,3,0,0,18,0,0,47, +12,4,0,1,68,0,0,0,13,3,4,0,12,4,0,5, +101,114,114,111,114,0,0,0,9,3,3,4,21,3,0,0, +18,0,0,4,28,3,0,0,37,3,0,0,18,0,0,1, +12,4,0,1,68,0,0,0,13,3,4,0,11,4,0,0, +0,0,0,0,0,0,240,63,12,5,0,5,101,114,114,111, +114,0,0,0,10,3,5,4,12,5,0,8,116,111,107,101, +110,105,122,101,0,0,0,0,13,4,5,0,12,5,0,7, +117,95,101,114,114,111,114,0,9,4,4,5,12,5,0,6, +101,110,99,111,100,101,0,0,12,8,0,1,68,0,0,0, +13,6,8,0,12,8,0,4,99,111,100,101,0,0,0,0, +9,6,6,8,12,8,0,3,112,111,115,0,9,7,1,8, +31,3,5,3,19,3,4,3,0,0,0,0,12,68,0,2, +100,111,0,0,14,68,67,0,16,68,0,109,44,12,0,0, +28,2,0,0,9,1,0,2,28,3,0,0,9,2,0,3, +28,4,0,0,9,3,0,4,12,6,0,5,84,111,107,101, +110,0,0,0,13,5,6,0,11,10,0,0,0,0,0,0, +0,0,240,63,11,11,0,0,0,0,0,0,0,0,240,63, +27,6,10,2,12,7,0,6,109,111,100,117,108,101,0,0, +12,8,0,6,109,111,100,117,108,101,0,0,15,10,3,0, +27,9,10,1,31,4,6,4,19,4,5,4,15,3,4,0, +12,6,0,8,116,111,107,101,110,105,122,101,0,0,0,0, +13,5,6,0,12,6,0,5,99,108,101,97,110,0,0,0, +9,5,5,6,15,6,2,0,31,4,6,1,19,4,5,4, +15,2,4,0,12,4,0,1,68,0,0,0,12,7,0,6, +68,83,116,97,116,101,0,0,13,6,7,0,15,7,2,0, +15,8,1,0,31,5,7,2,19,5,6,5,14,4,5,0, +12,6,0,1,68,0,0,0,13,5,6,0,12,6,0,5, +98,101,103,105,110,0,0,0,9,5,5,6,11,6,0,0, +0,0,0,0,0,0,240,63,31,4,6,1,19,4,5,4, +12,6,0,2,100,111,0,0,13,5,6,0,15,6,3,0, +31,4,6,1,19,4,5,4,12,6,0,1,68,0,0,0, +13,5,6,0,12,6,0,3,101,110,100,0,9,5,5,6, +31,4,0,0,19,4,5,4,12,6,0,8,109,97,112,95, +116,97,103,115,0,0,0,0,13,5,6,0,31,4,0,0, +19,4,5,4,12,6,0,1,68,0,0,0,13,5,6,0, +12,6,0,3,111,117,116,0,9,5,5,6,15,4,5,0, +12,5,0,1,68,0,0,0,28,6,0,0,14,5,6,0, +12,6,0,0,0,0,0,0,12,7,0,4,106,111,105,110, +0,0,0,0,9,6,6,7,15,7,4,0,31,5,7,1, +19,5,6,5,20,5,0,0,0,0,0,0,12,69,0,6, +101,110,99,111,100,101,0,0,14,69,68,0,0,0,0,0, +}; +unsigned char tp_py2bc[] = { +44,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0, +12,3,0,3,115,116,114,0,13,2,3,0,11,3,0,0, +0,0,0,0,0,0,240,63,31,1,3,1,19,1,2,1, +12,2,0,1,49,0,0,0,23,1,1,2,23,0,0,1, +21,0,0,0,18,0,0,23,12,2,0,6,105,109,112,111, +114,116,0,0,13,1,2,0,12,2,0,4,98,111,111,116, +0,0,0,0,31,0,2,1,19,0,1,0,12,3,0,5, +109,101,114,103,101,0,0,0,13,2,3,0,12,5,0,8, +95,95,100,105,99,116,95,95,0,0,0,0,13,3,5,0, +15,4,0,0,31,1,3,2,19,1,2,1,18,0,0,1, +12,2,0,6,105,109,112,111,114,116,0,0,13,1,2,0, +12,2,0,8,116,111,107,101,110,105,122,101,0,0,0,0, +31,0,2,1,19,0,1,0,12,1,0,8,116,111,107,101, +110,105,122,101,0,0,0,0,14,1,0,0,12,2,0,6, +105,109,112,111,114,116,0,0,13,1,2,0,12,2,0,5, +112,97,114,115,101,0,0,0,31,0,2,1,19,0,1,0, +12,1,0,5,112,97,114,115,101,0,0,0,14,1,0,0, +12,2,0,6,105,109,112,111,114,116,0,0,13,1,2,0, +12,2,0,6,101,110,99,111,100,101,0,0,31,0,2,1, +19,0,1,0,12,1,0,6,101,110,99,111,100,101,0,0, +14,1,0,0,16,0,0,49,44,11,0,0,28,2,0,0, +9,1,0,2,28,3,0,0,9,2,0,3,12,6,0,8, +116,111,107,101,110,105,122,101,0,0,0,0,13,5,6,0, +12,6,0,8,116,111,107,101,110,105,122,101,0,0,0,0, +9,5,5,6,15,6,1,0,31,4,6,1,19,4,5,4, +15,3,4,0,12,7,0,5,112,97,114,115,101,0,0,0, +13,6,7,0,12,7,0,5,112,97,114,115,101,0,0,0, +9,6,6,7,15,7,1,0,15,8,3,0,31,5,7,2, +19,5,6,5,15,4,5,0,12,8,0,6,101,110,99,111, +100,101,0,0,13,7,8,0,12,8,0,6,101,110,99,111, +100,101,0,0,9,7,7,8,15,8,2,0,15,9,1,0, +15,10,4,0,31,6,8,3,19,6,7,6,15,5,6,0, +20,5,0,0,0,0,0,0,12,1,0,8,95,99,111,109, +112,105,108,101,0,0,0,0,14,1,0,0,16,1,0,155, +44,12,0,0,28,2,0,0,9,1,0,2,12,3,0,7, +77,79,68,85,76,69,83,0,13,2,3,0,36,2,2,1, +21,2,0,0,18,0,0,8,12,3,0,7,77,79,68,85, +76,69,83,0,13,2,3,0,9,2,2,1,20,2,0,0, +18,0,0,1,12,4,0,3,46,112,121,0,1,3,1,4, +15,2,3,0,12,5,0,4,46,116,112,99,0,0,0,0, +1,4,1,5,15,3,4,0,12,6,0,6,101,120,105,115, +116,115,0,0,13,5,6,0,15,6,2,0,31,4,6,1, +19,4,5,4,21,4,0,0,18,0,0,64,11,6,0,0, +0,0,0,0,0,0,240,63,11,4,0,0,0,0,0,0, +0,0,0,0,12,9,0,6,101,120,105,115,116,115,0,0, +13,8,9,0,15,9,3,0,31,7,9,1,19,7,8,7, +23,4,4,7,23,5,4,6,21,5,0,0,18,0,0,2, +18,0,0,16,12,8,0,5,109,116,105,109,101,0,0,0, +13,7,8,0,15,8,3,0,31,4,8,1,19,4,7,4, +12,9,0,5,109,116,105,109,101,0,0,0,13,8,9,0, +15,9,2,0,31,7,9,1,19,7,8,7,25,4,4,7, +21,4,0,0,18,0,0,28,12,7,0,4,108,111,97,100, +0,0,0,0,13,6,7,0,15,7,2,0,31,5,7,1, +19,5,6,5,15,4,5,0,12,8,0,8,95,99,111,109, +112,105,108,101,0,0,0,0,13,7,8,0,15,8,4,0, +15,9,2,0,31,6,8,2,19,6,7,6,15,5,6,0, +12,8,0,4,115,97,118,101,0,0,0,0,13,7,8,0, +15,8,3,0,15,9,5,0,31,6,8,2,19,6,7,6, +18,0,0,1,18,0,0,1,11,6,0,0,0,0,0,0, +0,0,0,0,12,9,0,6,101,120,105,115,116,115,0,0, +13,8,9,0,15,9,3,0,31,7,9,1,19,7,8,7, +23,6,6,7,21,6,0,0,18,0,0,4,28,6,0,0, +37,6,0,0,18,0,0,1,12,8,0,4,108,111,97,100, +0,0,0,0,13,7,8,0,15,8,3,0,31,6,8,1, +19,6,7,6,15,5,6,0,12,8,0,8,95,95,110,97, +109,101,95,95,0,0,0,0,15,9,1,0,12,10,0,8, +95,95,99,111,100,101,95,95,0,0,0,0,15,11,5,0, +26,7,8,4,15,6,7,0,12,7,0,8,95,95,100,105, +99,116,95,95,0,0,0,0,10,6,7,6,12,8,0,7, +77,79,68,85,76,69,83,0,13,7,8,0,10,7,1,6, +12,9,0,4,101,120,101,99,0,0,0,0,13,8,9,0, +15,9,5,0,15,10,6,0,31,7,9,2,19,7,8,7, +20,6,0,0,0,0,0,0,12,2,0,7,95,105,109,112, +111,114,116,0,14,2,1,0,16,2,0,30,44,4,0,0, +12,2,0,8,66,85,73,76,84,73,78,83,0,0,0,0, +13,1,2,0,12,3,0,8,95,99,111,109,112,105,108,101, +0,0,0,0,13,2,3,0,12,3,0,7,99,111,109,112, +105,108,101,0,10,1,3,2,12,2,0,8,66,85,73,76, +84,73,78,83,0,0,0,0,13,1,2,0,12,3,0,7, +95,105,109,112,111,114,116,0,13,2,3,0,12,3,0,6, +105,109,112,111,114,116,0,0,10,1,3,2,0,0,0,0, +12,3,0,5,95,105,110,105,116,0,0,0,14,3,2,0, +16,3,0,51,44,10,0,0,28,2,0,0,9,1,0,2, +28,3,0,0,9,2,0,3,26,4,0,0,15,3,4,0, +12,4,0,8,95,95,110,97,109,101,95,95,0,0,0,0, +10,3,4,2,12,5,0,7,77,79,68,85,76,69,83,0, +13,4,5,0,10,4,2,3,12,7,0,4,108,111,97,100, +0,0,0,0,13,6,7,0,15,7,1,0,31,5,7,1, +19,5,6,5,15,4,5,0,12,8,0,8,95,99,111,109, +112,105,108,101,0,0,0,0,13,7,8,0,15,8,4,0, +15,9,1,0,31,6,8,2,19,6,7,6,15,5,6,0, +12,6,0,8,95,95,99,111,100,101,95,95,0,0,0,0, +10,3,6,5,12,8,0,4,101,120,101,99,0,0,0,0, +13,7,8,0,15,8,5,0,15,9,3,0,31,6,8,2, +19,6,7,6,20,3,0,0,0,0,0,0,12,4,0,12, +105,109,112,111,114,116,95,102,110,97,109,101,0,0,0,0, +14,4,3,0,16,4,0,24,44,6,0,0,12,3,0,12, +105,109,112,111,114,116,95,102,110,97,109,101,0,0,0,0, +13,2,3,0,12,5,0,4,65,82,71,86,0,0,0,0, +13,3,5,0,11,5,0,0,0,0,0,0,0,0,0,0, +9,3,3,5,12,4,0,8,95,95,109,97,105,110,95,95, +0,0,0,0,31,1,3,2,19,1,2,1,20,1,0,0, +0,0,0,0,12,5,0,6,116,105,110,121,112,121,0,0, +14,5,4,0,16,5,0,33,44,9,0,0,28,2,0,0, +9,1,0,2,28,3,0,0,9,2,0,3,12,6,0,4, +108,111,97,100,0,0,0,0,13,5,6,0,15,6,1,0, +31,4,6,1,19,4,5,4,15,3,4,0,12,7,0,8, +95,99,111,109,112,105,108,101,0,0,0,0,13,6,7,0, +15,7,3,0,15,8,1,0,31,5,7,2,19,5,6,5, +15,4,5,0,12,7,0,4,115,97,118,101,0,0,0,0, +13,6,7,0,15,7,2,0,15,8,4,0,31,5,7,2, +19,5,6,5,0,0,0,0,12,6,0,4,109,97,105,110, +0,0,0,0,14,6,5,0,12,7,0,8,95,95,110,97, +109,101,95,95,0,0,0,0,13,6,7,0,12,7,0,8, +95,95,109,97,105,110,95,95,0,0,0,0,23,6,6,7, +21,6,0,0,18,0,0,24,12,8,0,4,109,97,105,110, +0,0,0,0,13,7,8,0,12,10,0,4,65,82,71,86, +0,0,0,0,13,8,10,0,11,10,0,0,0,0,0,0, +0,0,240,63,9,8,8,10,12,10,0,4,65,82,71,86, +0,0,0,0,13,9,10,0,11,10,0,0,0,0,0,0, +0,0,0,64,9,9,9,10,31,6,8,2,19,6,7,6, +18,0,0,1,0,0,0,0, +}; diff --git a/programs/develop/tinypy/tinypy/boot.py b/programs/develop/tinypy/tinypy/boot.py new file mode 100644 index 0000000000..d4675defb8 --- /dev/null +++ b/programs/develop/tinypy/tinypy/boot.py @@ -0,0 +1,46 @@ +def _boot_init(): + global FTYPE + f = open('tp.h','r').read() + FTYPE = 'f' + if 'double tp_num' in f: FTYPE = 'd' + import sys + global ARGV + ARGV = sys.argv +_boot_init() + +def merge(a,b): + if isinstance(a,dict): + for k in b: a[k] = b[k] + else: + for k in b: setattr(a,k,b[k]) + +def number(v): + if type(v) is str and v[0:2] == '0x': + v = int(v[2:],16) + return float(v) + +def istype(v,t): + if t == 'string': return isinstance(v,str) + elif t == 'list': return (isinstance(v,list) or isinstance(v,tuple)) + elif t == 'dict': return isinstance(v,dict) + elif t == 'number': return (isinstance(v,float) or isinstance(v,int)) + raise '?' + +def fpack(v): + import struct + return struct.pack(FTYPE,v) + +def system(cmd): + import os + return os.system(cmd) + +def load(fname): + f = open(fname,'rb') + r = f.read() + f.close() + return r + +def save(fname,v): + f = open(fname,'wb') + f.write(v) + f.close() diff --git a/programs/develop/tinypy/tinypy/builtins.c b/programs/develop/tinypy/tinypy/builtins.c new file mode 100644 index 0000000000..ded28dbaea --- /dev/null +++ b/programs/develop/tinypy/tinypy/builtins.c @@ -0,0 +1,196 @@ +tp_obj tp_print(TP) { + int n = 0; + tp_obj e; + TP_LOOP(e) + if (n) { con_printf(" "); } + con_printf("%s",TP_CSTR(e)); + n += 1; + TP_END; + con_printf("\n"); + return tp_None; +} + +tp_obj tp_bind(TP) { + tp_obj r = TP_OBJ(); + tp_obj self = TP_OBJ(); + return tp_fnc_new(tp,r.fnc.ftype|2,r.fnc.val,self,r.fnc.info->globals); +} + +tp_obj tp_min(TP) { + tp_obj r = TP_OBJ(); + tp_obj e; + TP_LOOP(e) + if (tp_cmp(tp,r,e) > 0) { r = e; } + TP_END; + return r; +} + +tp_obj tp_syscall(TP) { + tp_obj r = TP_OBJ(); + int result; + asm("int $0x40":"=a"(result): + "a"((int)tp_get(tp, r, tp_string_n("eax", 3)).number.val), + "b"((int)tp_get(tp, r, tp_string_n("ebx", 3)).number.val), + "c"((int)tp_get(tp, r, tp_string_n("ecx", 3)).number.val), + "d"((int)tp_get(tp, r, tp_string_n("edx", 3)).number.val)); + return tp_number(result); +} + +tp_obj tp_max(TP) { + tp_obj r = TP_OBJ(); + tp_obj e; + TP_LOOP(e) + if (tp_cmp(tp,r,e) < 0) { r = e; } + TP_END; + return r; +} + +tp_obj tp_copy(TP) { + tp_obj r = TP_OBJ(); + int type = r.type; + if (type == TP_LIST) { + return _tp_list_copy(tp,r); + } else if (type == TP_DICT) { + return _tp_dict_copy(tp,r); + } + tp_raise(tp_None,"tp_copy(%s)",TP_CSTR(r)); +} + + +tp_obj tp_len_(TP) { + tp_obj e = TP_OBJ(); + return tp_len(tp,e); +} + + +tp_obj tp_assert(TP) { + int a = TP_NUM(); + if (a) { return tp_None; } + tp_raise(tp_None,"%s","assert failed"); +} + +tp_obj tp_range(TP) { + int a,b,c,i; + tp_obj r = tp_list(tp); + switch (tp->params.list.val->len) { + case 1: a = 0; b = TP_NUM(); c = 1; break; + case 2: + case 3: a = TP_NUM(); b = TP_NUM(); c = TP_DEFAULT(tp_number(1)).number.val; break; + default: return r; + } + if (c != 0) { + for (i=a; (c>0) ? ib; i+=c) { + _tp_list_append(tp,r.list.val,tp_number(i)); + } + } + return r; +} + + +tp_obj tp_system(TP) { + char const *s = TP_STR(); + int r = system(s); + return tp_number(r); +} + +tp_obj tp_istype(TP) { + tp_obj v = TP_OBJ(); + char const *t = TP_STR(); + if (strcmp("string",t) == 0) { return tp_number(v.type == TP_STRING); } + if (strcmp("list",t) == 0) { return tp_number(v.type == TP_LIST); } + if (strcmp("dict",t) == 0) { return tp_number(v.type == TP_DICT); } + if (strcmp("number",t) == 0) { return tp_number(v.type == TP_NUMBER); } + tp_raise(tp_None,"is_type(%s,%s)",TP_CSTR(v),t); +} + + +tp_obj tp_float(TP) { + tp_obj v = TP_OBJ(); + int ord = TP_DEFAULT(tp_number(0)).number.val; + int type = v.type; + if (type == TP_NUMBER) { return v; } + if (type == TP_STRING) { + if (strchr(TP_CSTR(v),'.')) { return tp_number(atof(TP_CSTR(v))); } + return(tp_number(strtol(TP_CSTR(v),0,ord))); + } + tp_raise(tp_None,"tp_float(%s)",TP_CSTR(v)); +} + + +tp_obj tp_save(TP) { + char const *fname = TP_STR(); + tp_obj v = TP_OBJ(); + FILE *f; + f = fopen(fname,"wb"); + if (!f) { tp_raise(tp_None,"tp_save(%s,...)",fname); } + fwrite(v.string.val,v.string.len,1,f); + fclose(f); + return tp_None; +} + +#define READ_BLK 1024 +tp_obj tp_load(TP) { + FILE *f; + long l = 0; + tp_obj r; + char *s; + char const *fname = TP_STR(); + long rd = 0; + long allocated = 32 * READ_BLK; + + + if (!(f = fopen(fname, "rb"))) { + tp_raise(tp_None,"tp_load(%s)",fname); + } + if (!(s = malloc(allocated))) + tp_raise(tp_None, "tp_load(%s): out of memory", fname); + rd = 0; + do { + if (l + READ_BLK < allocated) { + allocated += READ_BLK; + if (!(s = realloc(s, allocated))) { + tp_raise(tp_None, "tp_load(%s): out of memory", fname); + } + } + rd = fread(s + l, 1, READ_BLK, f); + l += rd; + } while (rd == READ_BLK); + r = tp_string_n(s, l); + fclose(f); + return tp_track(tp,r); +} + + +tp_obj tp_fpack(TP) { + tp_num v = TP_NUM(); + tp_obj r = tp_string_t(tp,sizeof(tp_num)); + *(tp_num*)r.string.val = v; + return tp_track(tp,r); +} + +tp_obj tp_abs(TP) { + return tp_number(fabs(tp_float(tp).number.val)); +} +tp_obj tp_int(TP) { + return tp_number((long)tp_float(tp).number.val); +} +tp_num _roundf(tp_num v) { + tp_num av = fabs(v); tp_num iv = (long)av; + av = (av-iv < 0.5?iv:iv+1); + return (v<0?-av:av); +} +tp_obj tp_round(TP) { + return tp_number(_roundf(tp_float(tp).number.val)); +} + +tp_obj tp_exists(TP) { + char const *s = TP_STR(); + struct stat stbuf; + return tp_number(!stat(s,&stbuf)); +} +tp_obj tp_mtime(TP) { + char const *s = TP_STR(); + struct stat stbuf; + if (!stat(s,&stbuf)) { return tp_number(stbuf.st_mtime); } + tp_raise(tp_None,"tp_mtime(%s)",s); +} diff --git a/programs/develop/tinypy/tinypy/dict.c b/programs/develop/tinypy/tinypy/dict.c new file mode 100644 index 0000000000..e666c39e70 --- /dev/null +++ b/programs/develop/tinypy/tinypy/dict.c @@ -0,0 +1,169 @@ +int tp_lua_hash(void const *v,int l) { + int i,step = (l>>5)+1; + int h = l + (l >= 4?*(int*)v:0); + for (i=l; i>=step; i-=step) { + h = h^((h<<5)+(h>>2)+((unsigned char *)v)[i-1]); + } + return h; +} +void _tp_dict_free(_tp_dict *self) { + tp_free(self->items); + tp_free(self); +} + +/* void _tp_dict_reset(_tp_dict *self) { + memset(self->items,0,self->alloc*sizeof(tp_item)); + self->len = 0; + self->used = 0; + self->cur = 0; + }*/ + +int tp_hash(TP,tp_obj v) { + switch (v.type) { + case TP_NONE: return 0; + case TP_NUMBER: return tp_lua_hash(&v.number.val,sizeof(tp_num)); + case TP_STRING: return tp_lua_hash(v.string.val,v.string.len); + case TP_DICT: return tp_lua_hash(&v.dict.val,sizeof(void*)); + case TP_LIST: { + int r = v.list.val->len; int n; for(n=0; nlen; n++) { + tp_obj vv = v.list.val->items[n]; r += vv.type != TP_LIST?tp_hash(tp,v.list.val->items[n]):tp_lua_hash(&vv.list.val,sizeof(void*)); } return r; + } + case TP_FNC: return tp_lua_hash(&v.fnc.info,sizeof(void*)); + case TP_DATA: return tp_lua_hash(&v.data.val,sizeof(void*)); + } + tp_raise(0,"tp_hash(%s)",TP_CSTR(v)); +} + +void _tp_dict_hash_set(TP,_tp_dict *self, int hash, tp_obj k, tp_obj v) { + tp_item item; + int i,idx = hash&self->mask; + for (i=idx; ialloc; i++) { + int n = i&self->mask; + if (self->items[n].used > 0) { continue; } + if (self->items[n].used == 0) { self->used += 1; } + item.used = 1; + item.hash = hash; + item.key = k; + item.val = v; + self->items[n] = item; + self->len += 1; + return; + } + tp_raise(,"_tp_dict_hash_set(%d,%d,%s,%s)",self,hash,TP_CSTR(k),TP_CSTR(v)); +} + +void _tp_dict_tp_realloc(TP,_tp_dict *self,int len) { + tp_item *items = self->items; + int i,alloc = self->alloc; + len = _tp_max(8,len); + + self->items = (tp_item*)tp_malloc(len*sizeof(tp_item)); + self->alloc = len; self->mask = len-1; + self->len = 0; self->used = 0; + + for (i=0; imask; + for (i=idx; ialloc; i++) { + int n = i&self->mask; + if (self->items[n].used == 0) { break; } + if (self->items[n].used < 0) { continue; } + if (self->items[n].hash != hash) { continue; } + if (tp_cmp(tp,self->items[n].key,k) != 0) { continue; } + return n; + } + return -1; +} +int _tp_dict_find(TP,_tp_dict *self,tp_obj k) { + return _tp_dict_hash_find(tp,self,tp_hash(tp,k),k); +} + +void _tp_dict_setx(TP,_tp_dict *self,tp_obj k, tp_obj v) { + int hash = tp_hash(tp,k); int n = _tp_dict_hash_find(tp,self,hash,k); + if (n == -1) { + if (self->len >= (self->alloc/2)) { + _tp_dict_tp_realloc(tp,self,self->alloc*2); + } else if (self->used >= (self->alloc*3/4)) { + _tp_dict_tp_realloc(tp,self,self->alloc); + } + _tp_dict_hash_set(tp,self,hash,k,v); + } else { + self->items[n].val = v; + } +} + +void _tp_dict_set(TP,_tp_dict *self,tp_obj k, tp_obj v) { + _tp_dict_setx(tp,self,k,v); + tp_grey(tp,k); tp_grey(tp,v); +} + +tp_obj _tp_dict_get(TP,_tp_dict *self,tp_obj k, const char *error) { + int n = _tp_dict_find(tp,self,k); + if (n < 0) { + tp_raise(tp_None,"%s: KeyError: %s\n",error,TP_CSTR(k)); + } + return self->items[n].val; +} + +void _tp_dict_del(TP,_tp_dict *self,tp_obj k, const char *error) { + int n = _tp_dict_find(tp,self,k); + if (n < 0) { tp_raise(,"%s: KeyError: %s\n",error,TP_CSTR(k)); } + self->items[n].used = -1; + self->len -= 1; +} + +_tp_dict *_tp_dict_new(void) { + _tp_dict *self = (_tp_dict*)tp_malloc(sizeof(_tp_dict)); + return self; +} +tp_obj _tp_dict_copy(TP,tp_obj rr) { + tp_obj obj = {TP_DICT}; + _tp_dict *o = rr.dict.val; + _tp_dict *r = _tp_dict_new(); + *r = *o; r->gci = 0; + r->items = (tp_item*)tp_malloc(sizeof(tp_item)*o->alloc); + memcpy(r->items,o->items,sizeof(tp_item)*o->alloc); + obj.dict.val = r; + return tp_track(tp,obj); +} + +int _tp_dict_next(TP,_tp_dict *self) { + if (!self->len) { tp_raise(0,"_tp_dict_next(...)",0); } + while (1) { + self->cur = ((self->cur + 1) & self->mask); + if (self->items[self->cur].used > 0) { + return self->cur; + } + } +} + +tp_obj tp_merge(TP) { + tp_obj self = TP_OBJ(); + tp_obj v = TP_OBJ(); + int i; for (i=0; ilen; i++) { + int n = _tp_dict_next(tp,v.dict.val); + _tp_dict_set(tp,self.dict.val, + v.dict.val->items[n].key,v.dict.val->items[n].val); + } + return tp_None; +} + +volatile tp_obj tp_dict(TP) { + tp_obj r = {TP_DICT}; + r.dict.val = _tp_dict_new(); + return tp ? tp_track(tp,r) : r; +} + +tp_obj tp_dict_n(TP,int n, tp_obj* argv) { + tp_obj r = tp_dict(tp); + int i; for (i=0; i 1: + self.vars,self.r2n,self.n2r,self._tmpi,self.mreg,self.snum,self._globals,self.lineno,self.globals,self.cregs,self.tmpc = self.stack.pop() + else: self.stack.pop() + + +def insert(v): D.out.append(v) +def write(v): + if istype(v,'list'): + insert(v) + return + for n in range(0,len(v),4): + insert(('data',v[n:n+4])) +def setpos(v): + if '-nopos' in ARGV: return + line,x = v + if line == D.lineno: return + text = D.lines[line-1] + D.lineno = line + val = text + "\0"*(4-len(text)%4) + code_16(POS,len(val)/4,line) + write(val) +def code(i,a=0,b=0,c=0): + if not istype(i,'number'): raise + if not istype(a,'number'): raise + if not istype(b,'number'): raise + if not istype(c,'number'): raise + write(('code',i,a,b,c)) +def code_16(i,a,b): + if b < 0: b += 0x8000 + code(i,a,(b&0xff00)>>8,(b&0xff)>>0) +def get_code16(i,a,b): + return ('code',i,a,(b&0xff00)>>8,(b&0xff)>>0) + +def _do_string(v,r=None): + r = get_tmp(r) + val = v + "\0"*(4-len(v)%4) + code_16(STRING,r,len(v)) + write(val) + return r +def do_string(t,r=None): + return _do_string(t.val,r) + +def _do_number(v,r=None): + r = get_tmp(r) + code(NUMBER,r,0,0) + write(fpack(number(v))) + return r +def do_number(t,r=None): + return _do_number(t.val,r) + +def get_tag(): + k = str(D._tagi) + D._tagi += 1 + return k +def stack_tag(): + k = get_tag() + D.tstack.append(k) + return k +def pop_tag(): + D.tstack.pop() + +def tag(*t): + t = D.snum+':'+':'.join([str(v) for v in t]) + insert(('tag',t)) +def jump(*t): + t = D.snum+':'+':'.join([str(v) for v in t]) + insert(('jump',t)) +def setjmp(*t): + t = D.snum+':'+':'.join([str(v) for v in t]) + insert(('setjmp',t)) +def fnc(*t): + t = D.snum+':'+':'.join([str(v) for v in t]) + r = get_reg(t) + insert(('fnc',r,t)) + return r + +def map_tags(): + tags = {} + out = [] + n = 0 + for item in D.out: + if item[0] == 'tag': + tags[item[1]] = n + continue + if item[0] == 'regs': + out.append(get_code16(REGS,item[1],0)) + n += 1 + continue + out.append(item) + n += 1 + for n in range(0,len(out)): + item = out[n] + if item[0] == 'jump': + out[n] = get_code16(JUMP,0,tags[item[1]]-n) + elif item[0] == 'setjmp': + out[n] = get_code16(SETJMP,0,tags[item[1]]-n) + elif item[0] == 'fnc': + out[n] = get_code16(DEF,item[1],tags[item[2]]-n) + for n in range(0,len(out)): + item = out[n] + if item[0] == 'data': + out[n] = item[1] + elif item[0] == 'code': + i,a,b,c = item[1:] + out[n] = chr(i)+chr(a)+chr(b)+chr(c) + else: + raise str(('huh?',item)) + if len(out[n]) != 4: + raise ('code '+str(n)+' is wrong length '+str(len(out[n]))) + D.out = out + +def get_tmp(r=None): + if r != None: return r + return get_tmps(1)[0] +def get_tmps(t): + rs = alloc(t) + regs = range(rs,rs+t) + for r in regs: + set_reg(r,"$"+str(D._tmpi)) + D._tmpi += 1 + D.tmpc += t #REG + return regs +def alloc(t): + s = ''.join(["01"[r in D.r2n] for r in range(0,min(256,D.mreg+t))]) + return s.index('0'*t) +def is_tmp(r): + if r is None: return False + return (D.r2n[r][0] == '$') +def un_tmp(r): + n = D.r2n[r] + free_reg(r) + set_reg(r,'*'+n) +def free_tmp(r): + if is_tmp(r): free_reg(r) + return r +def free_tmps(r): + for k in r: free_tmp(k) +def get_reg(n): + if n not in D.n2r: + set_reg(alloc(1),n) + return D.n2r[n] +#def get_clean_reg(n): + #if n in D.n2r: raise + #set_reg(D.mreg,n) + #return D.n2r[n] +def set_reg(r,n): + D.n2r[n] = r; D.r2n[r] = n + D.mreg = max(D.mreg,r+1) +def free_reg(r): + if is_tmp(r): D.tmpc -= 1 + n = D.r2n[r]; del D.r2n[r]; del D.n2r[n] + +def imanage(orig,fnc): + items = orig.items + orig.val = orig.val[:-1] + t = Token(orig.pos,'symbol','=',[items[0],orig]) + return fnc(t) + +def infix(i,tb,tc,r=None): + r = get_tmp(r) + b,c = do(tb,r),do(tc) + code(i,r,b,c) + if r != b: free_tmp(b) + free_tmp(c) + return r +def ss_infix(ss,i,tb,tc,r=None): + r = get_tmp(r) + r2 = get_tmp() + ss = _do_number(ss) + t = get_tag() + r = do(tb,r) + code(EQ,r2,r,ss) + code(IF,r2) + jump(t,'else') + jump(t,'end') + tag(t,'else') + r = do(tc,r) + tag(t,'end') + free_tmp(r2) #REG + free_tmp(ss) #REG + return r + +def _do_none(r=None): + r = get_tmp(r) + code(NONE,r) + return r + +def do_symbol(t,r=None): + sets = ['='] + isets = ['+=','-=','*=','/='] + cmps = ['<','>','<=','>=','==','!='] + metas = { + '+':ADD,'*':MUL,'/':DIV,'**':POW, + '-':SUB,'and':AND,'or':OR, + '%':MOD,'>>':RSH,'<<':LSH, + '&':AND,'|':OR, + } + if t.val == 'None': return _do_none(r) + if t.val == 'True': + return _do_number('1',r) + if t.val == 'False': + return _do_number('0',r) + items = t.items + + if t.val in ['and','or']: + ss = int(t.val == 'or') + return ss_infix(ss,metas[t.val],items[0],items[1],r) + if t.val in isets: + return imanage(t,do_symbol) + if t.val == 'is': + return infix(EQ,items[0],items[1],r) + if t.val == 'isnot': + return infix(CMP,items[0],items[1],r) + if t.val == 'not': + return infix(EQ,Token(t.pos,'number',0),items[0],r) + if t.val == 'in': + return infix(HAS,items[1],items[0],r) + if t.val == 'notin': + r = infix(HAS,items[1],items[0],r) + zero = _do_number('0') + code(EQ,r,r,free_tmp(zero)) + return r + if t.val in sets: + return do_set_ctx(items[0],items[1]); + elif t.val in cmps: + b,c = items[0],items[1] + v = t.val + if v[0] in ('>','>='): + b,c,v = c,b,'<'+v[1:] + cd = EQ + if v == '<': cd = LT + if v == '<=': cd = LE + if v == '!=': cd = NE + return infix(cd,b,c,r) + else: + return infix(metas[t.val],items[0],items[1],r) + +def do_set_ctx(k,v): + if k.type == 'name': + if (D._globals and k.val not in D.vars) or (k.val in D.globals): + c = do_string(k) + b = do(v) + code(GSET,c,b) + free_tmp(c) + free_tmp(b) + return + a = do_local(k) + b = do(v) + code(MOVE,a,b) + free_tmp(b) + return a + elif k.type in ('tuple','list'): + if v.type in ('tuple','list'): + n,tmps = 0,[] + for kk in k.items: + vv = v.items[n] + tmp = get_tmp(); tmps.append(tmp) + r = do(vv) + code(MOVE,tmp,r) + free_tmp(r) #REG + n+=1 + n = 0 + for kk in k.items: + vv = v.items[n] + tmp = tmps[n] + free_tmp(do_set_ctx(kk,Token(vv.pos,'reg',tmp))) #REG + n += 1 + return + + r = do(v); un_tmp(r) + n, tmp = 0, Token(v.pos,'reg',r) + for tt in k.items: + free_tmp(do_set_ctx(tt,Token(tmp.pos,'get',None,[tmp,Token(tmp.pos,'number',str(n))]))) #REG + n += 1 + free_reg(r) + return + r = do(k.items[0]) + rr = do(v) + tmp = do(k.items[1]) + code(SET,r,tmp,rr) + free_tmp(r) #REG + free_tmp(tmp) #REG + return rr + +def manage_seq(i,a,items,sav=0): + l = max(sav,len(items)) + n,tmps = 0,get_tmps(l) + for tt in items: + r = tmps[n] + b = do(tt,r) + if r != b: + code(MOVE,r,b) + free_tmp(b) + n +=1 + if not len(tmps): + code(i,a,0,0) + return 0 + code(i,a,tmps[0],len(items)) + free_tmps(tmps[sav:]) + return tmps[0] + +def p_filter(items): + a,b,c,d = [],[],None,None + for t in items: + if t.type == 'symbol' and t.val == '=': b.append(t) + elif t.type == 'args': c = t + elif t.type == 'nargs': d = t + else: a.append(t) + return a,b,c,d + +def do_import(t): + for mod in t.items: + mod.type = 'string' + v = do_call(Token(t.pos,'call',None,[ + Token(t.pos,'name','import'), + mod])) + mod.type = 'name' + do_set_ctx(mod,Token(t.pos,'reg',v)) +def do_from(t): + mod = t.items[0] + mod.type = 'string' + v = do(Token(t.pos,'call',None,[ + Token(t.pos,'name','import'), + mod])) + item = t.items[1] + if item.val == '*': + free_tmp(do(Token(t.pos,'call',None,[ + Token(t.pos,'name','merge'), + Token(t.pos,'name','__dict__'), + Token(t.pos,'reg',v)]))) #REG + else: + item.type = 'string' + free_tmp(do_set_ctx( + Token(t.pos,'get',None,[ Token(t.pos,'name','__dict__'),item]), + Token(t.pos,'get',None,[ Token(t.pos,'reg',v),item]) + )) #REG + + +def do_globals(t): + for t in t.items: + if t.val not in D.globals: + D.globals.append(t.val) +def do_del(tt): + for t in tt.items: + r = do(t.items[0]) + r2 = do(t.items[1]) + code(DEL,r,r2) + free_tmp(r); free_tmp(r2) #REG + +def do_call(t,r=None): + r = get_tmp(r) + items = t.items + fnc = do(items[0]) + a,b,c,d = p_filter(t.items[1:]) + e = None + if len(b) != 0 or d != None: + e = do(Token(t.pos,'dict',None,[])); un_tmp(e); + for p in b: + p.items[0].type = 'string' + t1,t2 = do(p.items[0]),do(p.items[1]) + code(SET,e,t1,t2) + free_tmp(t1); free_tmp(t2) #REG + if d: free_tmp(do(Token(t.pos,'call',None,[Token(t.pos,'name','merge'),Token(t.pos,'reg',e),d.items[0]]))) #REG + manage_seq(PARAMS,r,a) + if c != None: + t1,t2 = _do_string('*'),do(c.items[0]) + code(SET,r,t1,t2) + free_tmp(t1); free_tmp(t2) #REG + if e != None: + t1 = _do_none() + code(SET,r,t1,e) + free_tmp(t1) #REG + code(CALL,r,fnc,r) + free_tmp(fnc) #REG + return r + +def do_name(t,r=None): + if t.val in D.vars: + return do_local(t,r) + r = get_tmp(r) + c = do_string(t) + code(GGET,r,c) + free_tmp(c) + return r + +def do_local(t,r=None): + if t.val not in D.vars: + D.vars.append(t.val) + return get_reg(t.val) + +def do_def(tok,kls=None): + items = tok.items + + t = get_tag() + rf = fnc(t,'end') + + D.begin() + setpos(tok.pos) + r = do_local(Token(tok.pos,'name','__params')) + do_info(items[0].val) + a,b,c,d = p_filter(items[1].items) + for p in a: + v = do_local(p) + tmp = _do_none() + code(GET,v,r,tmp) + free_tmp(tmp) #REG + for p in b: + v = do_local(p.items[0]) + do(p.items[1],v) + tmp = _do_none() + code(IGET,v,r,tmp) + free_tmp(tmp) #REG + if c != None: + v = do_local(c.items[0]) + tmp = _do_string('*') + code(GET,v,r,tmp) + free_tmp(tmp) #REG + if d != None: + e = do_local(d.items[0]) + code(DICT,e,0,0) + tmp = _do_none() + code(IGET,e,r,tmp) + free_tmp(tmp) #REG + free_tmp(do(items[2])) #REG + D.end() + + tag(t,'end') + + if kls == None: + if D._globals: do_globals(Token(tok.pos,0,0,[items[0]])) + r = do_set_ctx(items[0],Token(tok.pos,'reg',rf)) + else: + rn = do_string(items[0]) + code(SET,kls,rn,rf) + free_tmp(rn) + + free_tmp(rf) + +def do_class(t): + tok = t + items = t.items + parent = None + if items[0].type == 'name': + name = items[0].val + else: + name = items[0].items[0].val + parent = items[0].items[1].val + + kls = do(Token(t.pos,'dict',0,[])) + ts = _do_string(name) + code(GSET,ts,kls) + free_tmp(ts) #REG + + init,_new = False,[] + if parent: + _new.append(Token(t.pos,'call',None,[ + Token(t.pos,'get',None,[ + Token(t.pos,'name',parent), + Token(t.pos,'string','__new__'), + ]), + Token(t.pos,'name','self'), + ])) + + for fc in items[1].items: + if fc.type != 'def': continue + fn = fc.items[0].val + if fn == '__init__': init = True + do_def(fc,kls) + _new.append(Token(fc.pos,'symbol','=',[ + Token(fc.pos,'get',None,[ + Token(fc.pos,'name','self'), + Token(fc.pos,'string',fn)]), + Token(fc.pos,'call',None,[ + Token(fc.pos,'name','bind'), + Token(fc.pos,'get',None,[ + Token(fc.pos,'name',name), + Token(fc.pos,'string',fn)]), + Token(fc.pos,'name','self')]) + ])) + + do_def(Token(t.pos,'def',None,[ + Token(t.pos,'name','__new__'), + Token(t.pos,'list',None,[Token(t.pos,'name','self')]), + Token(t.pos,'statements',None,_new)]),kls) + + t = get_tag() + rf = fnc(t,'end') + D.begin() + params = do_local(Token(tok.pos,'name','__params')) + + slf = do_local(Token(tok.pos,'name','self')) + code(DICT,slf,0,0) + + free_tmp(do(Token(tok.pos,'call',None,[ + Token(tok.pos,'get',None,[ + Token(tok.pos,'name',name), + Token(tok.pos,'string','__new__')]), + Token(tok.pos,'name','self')]))) #REG + + if init: + tmp = get_tmp() + t3 = _do_string('__init__') + code(GET,tmp,slf,t3) + t4 = get_tmp() + code(CALL,t4,tmp,params) + free_tmp(tmp) #REG + free_tmp(t3) #REG + free_tmp(t4) #REG + code(RETURN,slf) + + D.end() + tag(t,'end') + ts = _do_string('__call__') + code(SET,kls,ts,rf) + free_tmp(kls) #REG + free_tmp(ts) #REG + + + + +def do_while(t): + items = t.items + t = stack_tag() + tag(t,'begin') + tag(t,'continue') + r = do(items[0]) + code(IF,r) + free_tmp(r) #REG + jump(t,'end') + free_tmp(do(items[1])) #REG + jump(t,'begin') + tag(t,'break') + tag(t,'end') + pop_tag() + +def do_for(tok): + items = tok.items + + reg = do_local(items[0]) + itr = do(items[1]) + i = _do_number('0') + + t = stack_tag(); tag(t,'loop'); tag(t,'continue') + code(ITER,reg,itr,i); jump(t,'end') + free_tmp(do(items[2])) #REG + jump(t,'loop') + tag(t,'break'); tag(t,'end'); pop_tag() + + free_tmp(itr) #REG + free_tmp(i) + +def do_comp(t,r=None): + name = 'comp:'+get_tag() + r = do_local(Token(t.pos,'name',name)) + code(LIST,r,0,0) + key = Token(t.pos,'get',None,[ + Token(t.pos,'reg',r), + Token(t.pos,'symbol','None')]) + ap = Token(t.pos,'symbol','=',[key,t.items[0]]) + do(Token(t.pos,'for',None,[t.items[1],t.items[2],ap])) + return r + +def do_if(t): + items = t.items + t = get_tag() + n = 0 + for tt in items: + tag(t,n) + if tt.type == 'elif': + a = do(tt.items[0]); code(IF,a); free_tmp(a); + jump(t,n+1) + free_tmp(do(tt.items[1])) #REG + elif tt.type == 'else': + free_tmp(do(tt.items[0])) #REG + else: + raise + jump(t,'end') + n += 1 + tag(t,n) + tag(t,'end') + +def do_try(t): + items = t.items + t = get_tag() + setjmp(t,'except') + free_tmp(do(items[0])) #REG + jump(t,'end') + tag(t,'except') + free_tmp(do(items[1].items[1])) #REG + tag(t,'end') + +def do_return(t): + if t.items: r = do(t.items[0]) + else: r = _do_none() + code(RETURN,r) + free_tmp(r) + return +def do_raise(t): + if t.items: r = do(t.items[0]) + else: r = _do_none() + code(RAISE,r) + free_tmp(r) + return + +def do_statements(t): + for tt in t.items: free_tmp(do(tt)) + +def do_list(t,r=None): + r = get_tmp(r) + manage_seq(LIST,r,t.items) + return r + +def do_dict(t,r=None): + r = get_tmp(r) + manage_seq(DICT,r,t.items) + return r + +def do_get(t,r=None): + items = t.items + return infix(GET,items[0],items[1],r) + +def do_break(t): jump(D.tstack[-1],'break') +def do_continue(t): jump(D.tstack[-1],'continue') +def do_pass(t): code(PASS) + +def do_info(name='?'): + if '-nopos' in ARGV: return + code(FILE,free_tmp(_do_string(D.fname))) + code(NAME,free_tmp(_do_string(name))) +def do_module(t): + do_info() + free_tmp(do(t.items[0])) #REG +def do_reg(t,r=None): return t.val + +fmap = { + 'module':do_module,'statements':do_statements,'def':do_def, + 'return':do_return,'while':do_while,'if':do_if, + 'break':do_break,'pass':do_pass,'continue':do_continue,'for':do_for, + 'class':do_class,'raise':do_raise,'try':do_try,'import':do_import, + 'globals':do_globals,'del':do_del,'from':do_from, +} +rmap = { + 'list':do_list, 'tuple':do_list, 'dict':do_dict, 'slice':do_list, + 'comp':do_comp, 'name':do_name,'symbol':do_symbol,'number':do_number, + 'string':do_string,'get':do_get, 'call':do_call, 'reg':do_reg, +} + +def do(t,r=None): + if t.pos: setpos(t.pos) + try: + if t.type in rmap: + return rmap[t.type](t,r) + return fmap[t.type](t) + except: + if D.error: raise + D.error = True + tokenize.u_error('encode',D.code,t.pos) + +def encode(fname,s,t): + t = Token((1,1),'module','module',[t]) + global D + s = tokenize.clean(s) + D = DState(s,fname) + D.begin(True) + do(t) + D.end() + map_tags() + out = D.out; D = None + return ''.join(out) + diff --git a/programs/develop/tinypy/tinypy/gc.c b/programs/develop/tinypy/tinypy/gc.c new file mode 100644 index 0000000000..e90b01439a --- /dev/null +++ b/programs/develop/tinypy/tinypy/gc.c @@ -0,0 +1,152 @@ +/* tp_obj tp_track(TP,tp_obj v) { return v; } + void tp_grey(TP,tp_obj v) { } + void tp_full(TP) { } + void tp_gc_init(TP) { } + void tp_gc_deinit(TP) { } + void tp_delete(TP,tp_obj v) { }*/ + +void tp_grey(TP,tp_obj v) { + if (v.type < TP_STRING || (!v.gci.data) || *v.gci.data) { return; } + *v.gci.data = 1; + if (v.type == TP_STRING || v.type == TP_DATA) { + _tp_list_appendx(tp,tp->black,v); + return; + } + _tp_list_appendx(tp,tp->grey,v); +} + +void tp_follow(TP,tp_obj v) { + int type = v.type; + if (type == TP_LIST) { + int n; + for (n=0; nlen; n++) { + tp_grey(tp,v.list.val->items[n]); + } + } + if (type == TP_DICT) { + int i; + for (i=0; ilen; i++) { + int n = _tp_dict_next(tp,v.dict.val); + tp_grey(tp,v.dict.val->items[n].key); + tp_grey(tp,v.dict.val->items[n].val); + } + } + if (type == TP_FNC) { + tp_grey(tp,v.fnc.info->self); + tp_grey(tp,v.fnc.info->globals); + } +} + +void tp_reset(TP) { + int n; + _tp_list *tmp; + for (n=0; nblack->len; n++) { + *tp->black->items[n].gci.data = 0; + } + tmp = tp->white; + tp->white = tp->black; + tp->black = tmp; +} + +void tp_gc_init(TP) { + tp->white = _tp_list_new(); + tp->strings = _tp_dict_new(); + tp->grey = _tp_list_new(); + tp->black = _tp_list_new(); + tp->steps = 0; +} + +void tp_gc_deinit(TP) { + _tp_list_free(tp->white); + _tp_dict_free(tp->strings); + _tp_list_free(tp->grey); + _tp_list_free(tp->black); +} + +void tp_delete(TP,tp_obj v) { + int type = v.type; + if (type == TP_LIST) { + _tp_list_free(v.list.val); + return; + } else if (type == TP_DICT) { + _tp_dict_free(v.dict.val); + return; + } else if (type == TP_STRING) { + tp_free(v.string.info); + return; + } else if (type == TP_DATA) { + if (v.data.info->free) { + v.data.info->free(tp,v); + } + tp_free(v.data.info); + return; + } else if (type == TP_FNC) { + tp_free(v.fnc.info); + return; + } + tp_raise(,"tp_delete(%s)",TP_CSTR(v)); +} + +void tp_collect(TP) { + int n; + for (n=0; nwhite->len; n++) { + tp_obj r = tp->white->items[n]; + if (*r.gci.data) { continue; } + if (r.type == TP_STRING) { + /*this can't be moved into tp_delete, because tp_delete is + also used by tp_track_s to delete redundant strings*/ + _tp_dict_del(tp,tp->strings,r,"tp_collect"); + } + tp_delete(tp,r); + } + tp->white->len = 0; + tp_reset(tp); +} + +void _tp_gcinc(TP) { + tp_obj v; + if (!tp->grey->len) { + return; + } + v = _tp_list_pop(tp,tp->grey,tp->grey->len-1,"_tp_gcinc"); + tp_follow(tp,v); + _tp_list_appendx(tp,tp->black,v); +} + +void tp_full(TP) { + while (tp->grey->len) { + _tp_gcinc(tp); + } + tp_collect(tp); + tp_follow(tp,tp->root); +} + +void tp_gcinc(TP) { + tp->steps += 1; + if (tp->steps < TP_GCMAX || tp->grey->len > 0) { + _tp_gcinc(tp); _tp_gcinc(tp); + } + if (tp->steps < TP_GCMAX || tp->grey->len > 0) { return; } + tp->steps = 0; + tp_full(tp); + return; +} + +tp_obj tp_track(TP,tp_obj v) { + if (v.type == TP_STRING) { + int i = _tp_dict_find(tp,tp->strings,v); + if (i != -1) { + tp_delete(tp,v); + v = tp->strings->items[i].key; + tp_grey(tp,v); + return v; + } + _tp_dict_setx(tp,tp->strings,v,tp_True); + } + tp_gcinc(tp); + tp_grey(tp,v); + return v; +} + +/**/ + diff --git a/programs/develop/tinypy/tinypy/koconsole.c b/programs/develop/tinypy/tinypy/koconsole.c new file mode 100644 index 0000000000..f44185d035 --- /dev/null +++ b/programs/develop/tinypy/tinypy/koconsole.c @@ -0,0 +1,65 @@ +#include "kolibri.h" + +#define __stdcall __attribute__((stdcall)) +#define _cdecl __attribute__((cdecl)) +#define _stdcall __attribute__((stdcall)) + +void (* _stdcall con_init)(unsigned w_w, unsigned w_h, unsigned s_w, unsigned s_h, const char* t); +int (* _cdecl con_printf)(const char* format,...); +void (* _stdcall con_exit)(char bCloseWindow); +void (* __stdcall con_gets)(char* str, int n); + +void CONSOLE_INIT(const char title[]) +{ + kol_struct_import *imp; + + if (!(imp = kol_cofflib_load("/sys/lib/console.obj")) || + !(con_init = ( _stdcall void (*)(unsigned, unsigned, unsigned, unsigned, const char*)) + kol_cofflib_procload (imp, "con_init")) || + !(con_printf = ( _cdecl int (*)(const char*,...)) + kol_cofflib_procload (imp, "con_printf"))|| + !(con_gets = ( __stdcall void (*)(char*, int)) + kol_cofflib_procload (imp, "con_gets"))|| + !(con_exit = ( _stdcall void (*)(char)) + kol_cofflib_procload (imp, "con_exit"))) + { + kol_exit(); + } + con_init(-1, -1, -1, -1, title); +} +kol_struct_import* kol_cofflib_load(char *name) +{ + kol_struct_import* result; + asm ("int $0x40":"=a"(result):"a"(68), "b"(19), "c"(name)); + return result; +} + +void* kol_cofflib_procload (kol_struct_import *imp, char *name) +{ + int i; + for (i=0;;i++) + { + if ( NULL == ((imp+i) -> name)) + break; + else + if ( 0 == strcmp(name, (imp+i)->name) ) + return (imp+i)->data; + } + return NULL; +} + +void kol_board_puts(char *s) +{ + unsigned i; + i = 0; + while (*(s+i)) + { + asm ("int $0x40"::"a"(63), "b"(1), "c"(*(s+i))); + i++; + } +} + +void kol_exit() +{ + asm ("int $0x40"::"a"(-1)); +} diff --git a/programs/develop/tinypy/tinypy/kolibri.h b/programs/develop/tinypy/tinypy/kolibri.h new file mode 100644 index 0000000000..284a3934dd --- /dev/null +++ b/programs/develop/tinypy/tinypy/kolibri.h @@ -0,0 +1,92 @@ + +#define NULL ((void*)0) + +typedef struct +{ +unsigned p00 __attribute__((packed)); +unsigned p04 __attribute__((packed)); +unsigned p08 __attribute__((packed)); +unsigned p12 __attribute__((packed)); +unsigned p16 __attribute__((packed)); +char p20 __attribute__((packed)); +char *p21 __attribute__((packed)); +} kol_struct70 __attribute__((packed)); + + +typedef struct +{ +unsigned p00 __attribute__((packed)); +char p04 __attribute__((packed)); +char p05[3] __attribute__((packed)); +unsigned p08 __attribute__((packed)); +unsigned p12 __attribute__((packed)); +unsigned p16 __attribute__((packed)); +unsigned p20 __attribute__((packed)); +unsigned p24 __attribute__((packed)); +unsigned p28 __attribute__((packed)); +unsigned p32[2] __attribute__((packed)); +unsigned p40 __attribute__((packed)); +} kol_struct_BDVK __attribute__((packed)); + +typedef struct +{ +char *name __attribute__((packed)); +void *data __attribute__((packed)); +} kol_struct_import __attribute__((packed)); + + +void kol_exit(); +void kol_sleep(unsigned d); +void kol_wnd_define(unsigned x, unsigned y, unsigned w, unsigned h, unsigned c); +void kol_wnd_move(unsigned x, unsigned y); +void kol_wnd_caption(char *s); +void kol_event_mask(unsigned e); +unsigned kol_event_wait(); +unsigned kol_event_wait_time(unsigned time); +unsigned kol_event_check(); +void kol_paint_start(); +void kol_paint_end(); +void kol_paint_pixel(unsigned x, unsigned y, unsigned c); +void kol_paint_bar(unsigned x, unsigned y, unsigned w, unsigned h, unsigned c); +void kol_paint_line(unsigned x1, unsigned y1, unsigned x2, unsigned y2, unsigned c); +void kol_paint_string(unsigned x, unsigned y, char *s, unsigned c); +void kol_paint_image(unsigned x, unsigned y, unsigned w, unsigned h, char *d); +void kol_paint_image_pal(unsigned x, unsigned y, unsigned w, unsigned h, char *d, unsigned *palette); +unsigned kol_key_get(); +unsigned kol_key_control(); +void kol_key_lang_set(unsigned lang); +unsigned kol_key_lang_get(); +void kol_key_mode_set(unsigned mode); +unsigned kol_key_mode_get(); +void kol_btn_define(unsigned x, unsigned y, unsigned w, unsigned h, unsigned d, unsigned c); +unsigned kol_btn_get(); +void kol_btn_type(unsigned t); +unsigned kol_mouse_pos(); +unsigned kol_mouse_posw(); +unsigned kol_mouse_btn(); +void kol_board_putc(char c); +void kol_board_puts(char *s); +void kol_board_puti(int n); +int kol_file_70(kol_struct70 *k); +kol_struct_import* kol_cofflib_load(char *name); +void* kol_cofflib_procload (kol_struct_import *imp, char *name); +unsigned kol_cofflib_procnum (kol_struct_import *imp); +void kol_cofflib_procname (kol_struct_import *imp, char *name, unsigned n); +unsigned kol_system_end(unsigned param); +unsigned kol_system_cpufreq(); +unsigned kol_system_mem(); +unsigned kol_system_memfree(); +unsigned kol_system_time_get(); +unsigned kol_system_date_get(); +void kol_path_file2dir(char *dir, char *fname); +void kol_path_full(char *full, char *fname); +void kol_screen_wait_rr(); +void kol_screen_get_size(unsigned *w, unsigned *h); +unsigned kol_skin_height(); +unsigned kol_thread_start(unsigned start, unsigned stack); +unsigned kol_time_tick(); +unsigned kol_sound_speaker(char data[]); +unsigned kol_process_info(unsigned slot, char buf1k[]); +int kol_process_kill_pid(unsigned process); +void kol_get_kernel_ver(char buff16b[]); +int kol_kill_process(unsigned process); \ No newline at end of file diff --git a/programs/develop/tinypy/tinypy/list.c b/programs/develop/tinypy/tinypy/list.c new file mode 100644 index 0000000000..8f1d76c423 --- /dev/null +++ b/programs/develop/tinypy/tinypy/list.c @@ -0,0 +1,133 @@ +void _tp_list_realloc(_tp_list *self,int len) { + if (!len) { len=1; } + self->items = (tp_obj*)tp_realloc(self->items,len*sizeof(tp_obj)); + self->alloc = len; +} + +void _tp_list_set(TP,_tp_list *self,int k, tp_obj v, const char *error) { + if (k >= self->len) { tp_raise(,"%s: KeyError: %d\n",error,k); } + self->items[k] = v; + tp_grey(tp,v); +} +void _tp_list_free(_tp_list *self) { + tp_free(self->items); + tp_free(self); +} + +tp_obj _tp_list_get(TP,_tp_list *self,int k,const char *error) { + if (k >= self->len) { tp_raise(tp_None,"%s: KeyError: %d\n",error,k); } + return self->items[k]; +} +void _tp_list_insertx(TP,_tp_list *self, int n, tp_obj v) { + if (self->len >= self->alloc) { + _tp_list_realloc(self,self->alloc*2); + } + if (n < self->len) { memmove(&self->items[n+1],&self->items[n],sizeof(tp_obj)*(self->len-n)); } + self->items[n] = v; + self->len += 1; +} +void _tp_list_appendx(TP,_tp_list *self, tp_obj v) { + _tp_list_insertx(tp,self,self->len,v); +} +void _tp_list_insert(TP,_tp_list *self, int n, tp_obj v) { + _tp_list_insertx(tp,self,n,v); + tp_grey(tp,v); +} +void _tp_list_append(TP,_tp_list *self, tp_obj v) { + _tp_list_insert(tp,self,self->len,v); +} +tp_obj _tp_list_pop(TP,_tp_list *self, int n, const char *error) { + tp_obj r = _tp_list_get(tp,self,n,error); + if (n != self->len-1) { memmove(&self->items[n],&self->items[n+1],sizeof(tp_obj)*(self->len-(n+1))); } + self->len -= 1; + return r; +} + +int _tp_list_find(TP,_tp_list *self, tp_obj v) { + int n; + for (n=0; nlen; n++) { + if (tp_cmp(tp,v,self->items[n]) == 0) { + return n; + } + } + return -1; +} + +tp_obj tp_index(TP) { + tp_obj self = TP_OBJ(); + tp_obj v = TP_OBJ(); + int i = _tp_list_find(tp,self.list.val,v); + if (i < 0) { tp_raise(tp_None,"tp_index(%s,%s) - item not found",TP_CSTR(self),TP_CSTR(v)); } + return tp_number(i); +} + +_tp_list *_tp_list_new(void) { + return (_tp_list*)tp_malloc(sizeof(_tp_list)); +} + +tp_obj _tp_list_copy(TP, tp_obj rr) { + tp_obj val = {TP_LIST}; + _tp_list *o = rr.list.val; + _tp_list *r = _tp_list_new(); + *r = *o; r->gci = 0; + r->items = (tp_obj*)tp_malloc(sizeof(tp_obj)*o->alloc); + memcpy(r->items,o->items,sizeof(tp_obj)*o->alloc); + val.list.val = r; + return tp_track(tp,val); +} + +tp_obj tp_append(TP) { + tp_obj self = TP_OBJ(); + tp_obj v = TP_OBJ(); + _tp_list_append(tp,self.list.val,v); + return tp_None; +} + +tp_obj tp_pop(TP) { + tp_obj self = TP_OBJ(); + return _tp_list_pop(tp,self.list.val,self.list.val->len-1,"pop"); +} + +tp_obj tp_insert(TP) { + tp_obj self = TP_OBJ(); + int n = TP_NUM(); + tp_obj v = TP_OBJ(); + _tp_list_insert(tp,self.list.val,n,v); + return tp_None; +} + +tp_obj tp_extend(TP) { + tp_obj self = TP_OBJ(); + tp_obj v = TP_OBJ(); + int i; + for (i=0; ilen; i++) { + _tp_list_append(tp,self.list.val,v.list.val->items[i]); + } + return tp_None; +} + +tp_obj tp_list(TP) { + tp_obj r = {TP_LIST}; + r.list.val = _tp_list_new(); + return tp ? tp_track(tp,r) : r; +} + +tp_obj tp_list_n(TP,int n,tp_obj *argv) { + int i; + tp_obj r = tp_list(tp); _tp_list_realloc(r.list.val,n); + for (i=0; iitems, self.list.val->len, sizeof(tp_obj), (int(*)(const void*,const void*))_tp_sort_cmp); + return tp_None; +} + diff --git a/programs/develop/tinypy/tinypy/misc.c b/programs/develop/tinypy/tinypy/misc.c new file mode 100644 index 0000000000..74551cb128 --- /dev/null +++ b/programs/develop/tinypy/tinypy/misc.c @@ -0,0 +1,68 @@ +tp_obj *tp_ptr(tp_obj o) { + tp_obj *ptr = (tp_obj*)tp_malloc(sizeof(tp_obj)); *ptr = o; + return ptr; +} + +tp_obj _tp_dcall(TP,tp_obj fnc(TP)) { + return fnc(tp); +} +tp_obj _tp_tcall(TP,tp_obj fnc) { + if (fnc.fnc.ftype&2) { + _tp_list_insert(tp,tp->params.list.val,0,fnc.fnc.info->self); + } + return _tp_dcall(tp,(tp_obj (*)(tp_vm *))fnc.fnc.val); +} + +tp_obj tp_fnc_new(TP,int t, void *v, tp_obj s, tp_obj g) { + tp_obj r = {TP_FNC}; + _tp_fnc *info = (_tp_fnc*)tp_malloc(sizeof(_tp_fnc)); + info->self = s; + info->globals = g; + r.fnc.ftype = t; + r.fnc.info = info; + r.fnc.val = v; + return tp_track(tp,r); +} + +tp_obj tp_def(TP,void *v, tp_obj g) { + return tp_fnc_new(tp,1,v,tp_None,g); +} + +tp_obj tp_fnc(TP,tp_obj v(TP)) { + return tp_fnc_new(tp,0,v,tp_None,tp_None); +} + +tp_obj tp_method(TP,tp_obj self,tp_obj v(TP)) { + return tp_fnc_new(tp,2,v,self,tp_None); +} + +tp_obj tp_data(TP,int magic,void *v) { + tp_obj r = {TP_DATA}; + r.data.info = (_tp_data*)tp_malloc(sizeof(_tp_data)); + r.data.val = v; + r.data.magic = magic; + return tp_track(tp,r); +} + +tp_obj tp_params(TP) { + tp_obj r; + tp->params = tp->_params.list.val->items[tp->cur]; + r = tp->_params.list.val->items[tp->cur]; + r.list.val->len = 0; + return r; +} +tp_obj tp_params_n(TP,int n, tp_obj argv[]) { + tp_obj r = tp_params(tp); + int i; for (i=0; i",self.dict.val); + } else if(type == TP_LIST) { + return tp_printf(tp,"",self.list.val); + } else if (type == TP_NONE) { + return tp_string("None"); + } else if (type == TP_DATA) { + return tp_printf(tp,"",self.data.val); + } else if (type == TP_FNC) { + return tp_printf(tp,"",self.fnc.info); + } + return tp_string(""); +} + +int tp_bool(TP,tp_obj v) { + switch(v.type) { + case TP_NUMBER: return v.number.val != 0; + case TP_NONE: return 0; + case TP_STRING: return v.string.len != 0; + case TP_LIST: return v.list.val->len != 0; + case TP_DICT: return v.dict.val->len != 0; + } + return 1; +} + + +tp_obj tp_has(TP,tp_obj self, tp_obj k) { + int type = self.type; + if (type == TP_DICT) { + if (_tp_dict_find(tp,self.dict.val,k) != -1) { return tp_True; } + return tp_False; + } else if (type == TP_STRING && k.type == TP_STRING) { + char *p = strstr(TP_CSTR(self),TP_CSTR(k)); + return tp_number(p != 0); + } else if (type == TP_LIST) { + return tp_number(_tp_list_find(tp,self.list.val,k)!=-1); + } + tp_raise(tp_None,"tp_has(%s,%s)",TP_CSTR(self),TP_CSTR(k)); +} + +void tp_del(TP,tp_obj self, tp_obj k) { + int type = self.type; + if (type == TP_DICT) { + _tp_dict_del(tp,self.dict.val,k,"tp_del"); + return; + } + tp_raise(,"tp_del(%s,%s)",TP_CSTR(self),TP_CSTR(k)); +} + + +tp_obj tp_iter(TP,tp_obj self, tp_obj k) { + int type = self.type; + if (type == TP_LIST || type == TP_STRING) { return tp_get(tp,self,k); } + if (type == TP_DICT && k.type == TP_NUMBER) { + return self.dict.val->items[_tp_dict_next(tp,self.dict.val)].key; + } + tp_raise(tp_None,"tp_iter(%s,%s)",TP_CSTR(self),TP_CSTR(k)); +} + +tp_obj tp_get(TP,tp_obj self, tp_obj k) { + int type = self.type; + tp_obj r; + /*con_printf("tp_get %s %s\n", TP_CSTR(self), TP_CSTR(k));*/ + if (type == TP_DICT) { + return _tp_dict_get(tp,self.dict.val,k,"tp_get"); + } else if (type == TP_LIST) { + if (k.type == TP_NUMBER) { + int l = tp_len(tp,self).number.val; + int n = k.number.val; + n = (n<0?l+n:n); + return _tp_list_get(tp,self.list.val,n,"tp_get"); + } else if (k.type == TP_STRING) { + if (strcmp("append",TP_CSTR(k)) == 0) { + return tp_method(tp,self,tp_append); + } else if (strcmp("pop",TP_CSTR(k)) == 0) { + return tp_method(tp,self,tp_pop); + } else if (strcmp("index",TP_CSTR(k)) == 0) { + return tp_method(tp,self,tp_index); + } else if (strcmp("sort",TP_CSTR(k)) == 0) { + return tp_method(tp,self,tp_sort); + } else if (strcmp("extend",TP_CSTR(k)) == 0) { + return tp_method(tp,self,tp_extend); + } else if (strcmp("*",TP_CSTR(k)) == 0) { + tp_params_v(tp,1,self); + r = tp_copy(tp); + self.list.val->len=0; + return r; + } + } else if (k.type == TP_NONE) { + return _tp_list_pop(tp,self.list.val,0,"tp_get"); + } + } else if (type == TP_STRING) { + if (k.type == TP_NUMBER) { + int l = self.string.len; + int n = k.number.val; + n = (n<0?l+n:n); + if (n >= 0 && n < l) { return tp_string_n(tp->chars[(unsigned char)self.string.val[n]],1); } + } else if (k.type == TP_STRING) { + if (strcmp("join",TP_CSTR(k)) == 0) { + return tp_method(tp,self,tp_join); + } else if (strcmp("split",TP_CSTR(k)) == 0) { + return tp_method(tp,self,tp_split); + } else if (strcmp("index",TP_CSTR(k)) == 0) { + return tp_method(tp,self,tp_str_index); + } else if (strcmp("strip",TP_CSTR(k)) == 0) { + return tp_method(tp,self,tp_strip); + } else if (strcmp("replace",TP_CSTR(k)) == 0) { + return tp_method(tp,self,tp_replace); + } + } + } + + if (k.type == TP_LIST) { + int a,b,l; + tp_obj tmp; + l = tp_len(tp,self).number.val; + tmp = tp_get(tp,k,tp_number(0)); + if (tmp.type == TP_NUMBER) { a = tmp.number.val; } + else if(tmp.type == TP_NONE) { a = 0; } + else { tp_raise(tp_None,"%s is not a number",TP_CSTR(tmp)); } + tmp = tp_get(tp,k,tp_number(1)); + if (tmp.type == TP_NUMBER) { b = tmp.number.val; } + else if(tmp.type == TP_NONE) { b = l; } + else { tp_raise(tp_None,"%s is not a number",TP_CSTR(tmp)); } + a = _tp_max(0,(a<0?l+a:a)); b = _tp_min(l,(b<0?l+b:b)); + if (type == TP_LIST) { + return tp_list_n(tp,b-a,&self.list.val->items[a]); + } else if (type == TP_STRING) { + tp_obj r = tp_string_t(tp,b-a); + char *ptr = r.string.info->s; + memcpy(ptr,self.string.val+a,b-a); ptr[b-a]=0; + return tp_track(tp,r); + } + } + + + con_printf("Raising exception\n"); + tp_raise(tp_None,"tp_get(%s,%s)",TP_CSTR(self),TP_CSTR(k)); +} + +int tp_iget(TP,tp_obj *r, tp_obj self, tp_obj k) { + if (self.type == TP_DICT) { + int n = _tp_dict_find(tp,self.dict.val,k); + if (n == -1) { return 0; } + *r = self.dict.val->items[n].val; + tp_grey(tp,*r); + return 1; + } + if (self.type == TP_LIST && !self.list.val->len) { return 0; } + *r = tp_get(tp,self,k); tp_grey(tp,*r); + return 1; +} + +void tp_set(TP,tp_obj self, tp_obj k, tp_obj v) { + int type; + con_printf("vm is %x self is %x k is %x v is %x", tp, self, k, v); + type = self.type; + if (type == TP_DICT) { + _tp_dict_set(tp,self.dict.val,k,v); + return; + } else if (type == TP_LIST) { + if (k.type == TP_NUMBER) { + _tp_list_set(tp,self.list.val,k.number.val,v,"tp_set"); + return; + } else if (k.type == TP_NONE) { + _tp_list_append(tp,self.list.val,v); + return; + } else if (k.type == TP_STRING) { + if (strcmp("*",TP_CSTR(k)) == 0) { + tp_params_v(tp,2,self,v); tp_extend(tp); + return; + } + } + } + tp_raise(,"tp_set(%s,%s,%s)",TP_CSTR(self),TP_CSTR(k),TP_CSTR(v)); +} + +tp_obj tp_add(TP,tp_obj a, tp_obj b) { + if (a.type == TP_NUMBER && a.type == b.type) { + return tp_number(a.number.val+b.number.val); + } else if (a.type == TP_STRING && a.type == b.type) { + int al = a.string.len, bl = b.string.len; + tp_obj r = tp_string_t(tp,al+bl); + char *s = r.string.info->s; + memcpy(s,a.string.val,al); memcpy(s+al,b.string.val,bl); + return tp_track(tp,r); + } else if (a.type == TP_LIST && a.type == b.type) { + tp_obj r; + tp_params_v(tp,1,a); + r = tp_copy(tp); + tp_params_v(tp,2,r,b); + tp_extend(tp); + return r; + } + tp_raise(tp_None,"tp_add(%s,%s)",TP_CSTR(a),TP_CSTR(b)); +} + +tp_obj tp_mul(TP,tp_obj a, tp_obj b) { + if (a.type == TP_NUMBER && a.type == b.type) { + return tp_number(a.number.val*b.number.val); + } else if (a.type == TP_STRING && b.type == TP_NUMBER) { + int al = a.string.len; int n = b.number.val; + tp_obj r = tp_string_t(tp,al*n); + char *s = r.string.info->s; + int i; for (i=0; ilen); + } else if (type == TP_LIST) { + return tp_number(self.list.val->len); + } + tp_raise(tp_None,"tp_len(%s)",TP_CSTR(self)); +} + +int tp_cmp(TP,tp_obj a, tp_obj b) { + if (a.type != b.type) { return a.type-b.type; } + switch(a.type) { + case TP_NONE: return 0; + case TP_NUMBER: return _tp_sign(a.number.val-b.number.val); + case TP_STRING: { + int v = memcmp(a.string.val,b.string.val,_tp_min(a.string.len,b.string.len)); + if (v == 0) { v = a.string.len-b.string.len; } + return v; + } + case TP_LIST: { + int n,v; for(n=0;n<_tp_min(a.list.val->len,b.list.val->len);n++) { + tp_obj aa = a.list.val->items[n]; tp_obj bb = b.list.val->items[n]; + if (aa.type == TP_LIST && bb.type == TP_LIST) { v = aa.list.val-bb.list.val; } else { v = tp_cmp(tp,aa,bb); } + if (v) { return v; } } + return a.list.val->len-b.list.val->len; + } + case TP_DICT: return a.dict.val - b.dict.val; + case TP_FNC: return a.fnc.info - b.fnc.info; + case TP_DATA: return (char*)a.data.val - (char*)b.data.val; + } + tp_raise(0,"tp_cmp(%s,%s)",TP_CSTR(a),TP_CSTR(b)); +} + +#define TP_OP(name,expr) \ + tp_obj name(TP,tp_obj _a,tp_obj _b) { \ + if (_a.type == TP_NUMBER && _a.type == _b.type) { \ + tp_num a = _a.number.val; tp_num b = _b.number.val; \ + return tp_number(expr); \ + } \ + tp_raise(tp_None,"%s(%s,%s)",#name,TP_CSTR(_a),TP_CSTR(_b)); \ +} + +TP_OP(tp_and,((long)a)&((long)b)); +TP_OP(tp_or,((long)a)|((long)b)); +TP_OP(tp_mod,((long)a)%((long)b)); +TP_OP(tp_lsh,((long)a)<<((long)b)); +TP_OP(tp_rsh,((long)a)>>((long)b)); +TP_OP(tp_sub,a-b); +TP_OP(tp_div,a/b); +TP_OP(tp_pow,pow(a,b)); + + +/**/ diff --git a/programs/develop/tinypy/tinypy/parse.py b/programs/develop/tinypy/tinypy/parse.py new file mode 100644 index 0000000000..1b4f249b9f --- /dev/null +++ b/programs/develop/tinypy/tinypy/parse.py @@ -0,0 +1,408 @@ +import tokenize +from tokenize import Token +if '.' in str(1.0): + from boot import * + +def check(t,*vs): + if vs[0] == None: return True + if t.type in vs: return True + if t.type == 'symbol' and t.val in vs: return True + return False + +def tweak(k,v): + P.stack.append((k,dmap[k])) + if v: dmap[k] = omap[k] + else: dmap[k] = {'lbp':0,'nud':itself} +def restore(): + k,v = P.stack.pop() + dmap[k] = v + +def cpy(d): + r = {} + for k in d: r[k] = d[k] + return r + +class PData: + def __init__(self,s,tokens): + self.s = s + self.tokens = tokens + self.pos = 0 + self.token = None + self.stack = [] + def init(self): + global omap,dmap + omap = cpy(base_dmap) + dmap = cpy(base_dmap) + self.advance() + def advance(self,val=None): + if not check(self.token,val): + error('expected '+val,self.token) + if self.pos < len(self.tokens): + t = self.tokens[self.pos] + self.pos += 1 + else: + t = Token((0,0),'eof','eof') + self.token = do(t) + return t +def error(ctx,t): + print t + tokenize.u_error(ctx,P.s,t.pos) + +def nud(t): + #if 'nud' not in t: + # error('no nud',t) + return t.nud(t) +def led(t,left): + #if 'led' not in t: + # error('no led',t) + return t.led(t,left) +def get_lbp(t): + #if 'lbp' not in t: + # error('no lbp',t) + return t.lbp +def get_items(t): + #if 'items' not in t: + # error('no items',t) + return t.items + +def expression(rbp): + t = P.token + advance() + left = nud(t) + while rbp < get_lbp(P.token): + t = P.token + advance() + left = led(t,left) + return left + +def infix_led(t,left): + t.items = [left,expression(t.bp)] + return t +def infix_is(t,left): + if check(P.token,'not'): + t.val = 'isnot' + advance('not') + t.items = [left,expression(t.bp)] + return t +def infix_not(t,left): + advance('in') + t.val = 'notin' + t.items = [left,expression(t.bp)] + return t +def infix_tuple(t,left): + r = expression(t.bp) + if left.val == ',': + left.items.append(r) + return left + t.items = [left,r] + t.type = 'tuple' + return t +def lst(t): + if t == None: return [] + if check(t,',','tuple','statements'): + return get_items(t) + return [t] +def ilst(typ,t): + return Token(t.pos,typ,typ,lst(t)) + +def call_led(t,left): + r = Token(t.pos,'call','$',[left]) + while not check(P.token,')'): + tweak(',',0) + r.items.append(expression(0)) + if P.token.val == ',': advance(',') + restore() + advance(")") + return r +def get_led(t,left): + r = Token(t.pos,'get','.',[left]) + items = [left] + more = False + while not check(P.token,']'): + more = False + if check(P.token,':'): + items.append(Token(P.token.pos,'symbol','None')) + else: + items.append(expression(0)) + if check(P.token,':'): + advance(':') + more = True + if more: + items.append(Token(P.token.pos,'symbol','None')) + if len(items) > 2: + items = [left,Token(t.pos,'slice',':',items[1:])] + r.items = items + advance("]") + return r +def dot_led(t,left): + r = expression(t.bp) + r.type = 'string' + t.items = [left,r] + return t + +def itself(t): + return t +def paren_nud(t): + tweak(',',1) + r = expression(0) + restore() + advance(')') + return r +def list_nud(t): + t.type = 'list' + t.val = '[]' + t.items = [] + next = P.token + tweak(',',0) + while not check(P.token,'for',']'): + r = expression(0) + t.items.append(r) + if P.token.val == ',': advance(',') + if check(P.token,'for'): + t.type = 'comp' + advance('for') + tweak('in',0) + t.items.append(expression(0)) + advance('in') + t.items.append(expression(0)) + restore() + restore() + advance(']') + return t +def dict_nud(t): + t.type='dict' + t.val = '{}' + t.items = [] + tweak(',',0) + while not check(P.token,'}'): + t.items.append(expression(0)) + if check(P.token,':',','): advance() + restore() + advance('}') + return t + +def advance(t=None): + return P.advance(t) + +def block(): + items = [] + tok = P.token + + while check(P.token,'nl'): advance() + if check(P.token,'indent'): + advance('indent') + while not check(P.token,'dedent'): + items.append(expression(0)) + while check(P.token,';','nl'): advance() + advance('dedent') + else: + items.append(expression(0)) + while check(P.token,';'): + advance(';') + items.append(expression(0)) + while check(P.token,'nl'): advance() + + if len(items) > 1: + return Token(tok.pos,'statements',';',items) + return items.pop() + +def def_nud(t): + items = t.items = [] + items.append(P.token); advance() + advance('(') + r = Token(t.pos,'symbol','():',[]) + items.append(r) + while not check(P.token,')'): + tweak(',',0) + r.items.append(expression(0)) + if check(P.token,','): advance(',') + restore() + advance(')') + advance(':') + items.append(block()) + return t + + +def while_nud(t): + items = t.items = [] + items.append(expression(0)) + advance(':') + items.append(block()) + return t +def class_nud(t): + items = t.items = [] + items.append(expression(0)) + advance(':') + items.append(ilst('methods',block())) + return t + +def from_nud(t): + items = t.items = [] + items.append(expression(0)) + advance('import') + items.append(expression(0)) + return t + +def for_nud(t): + items = t.items = [] + tweak('in',0) + items.append(expression(0)) + advance('in') + items.append(expression(0)) + restore() + advance(':') + items.append(block()) + return t +def if_nud(t): + items = t.items = [] + a = expression(0) + advance(':') + b = block() + items.append(Token(t.pos,'elif','elif',[a,b])) + while check(P.token,'elif'): + tok = P.token + advance('elif') + a = expression(0) + advance(':') + b = block() + items.append(Token(tok.pos,'elif','elif',[a,b])) + if check(P.token,'else'): + tok = P.token + advance('else') + advance(':') + b = block() + items.append(Token(tok.pos,'else','else',[b])) + return t +def try_nud(t): + items = t.items = [] + advance(':') + b = block() + items.append(b) + while check(P.token,'except'): + tok = P.token + advance('except') + if not check(P.token,':'): a = expression(0) + else: a = Token(tok.pos,'symbol','None') + advance(':') + b = block() + items.append(Token(tok.pos,'except','except',[a,b])) + if check(P.token,'else'): + tok = P.token + advance('else') + advance(':') + b = block() + items.append(Token(tok.pos,'else','else',[b])) + return t +def prefix_nud(t): + #bp = 70 + #if 'bp' in t: bp = t['bp'] + bp = t.bp + t.items = [expression(bp)] + return t +def prefix_nud0(t): + if check(P.token,'nl',';','eof','dedent'): return t + return prefix_nud(t) +def prefix_nuds(t): + r = expression(0) + return ilst(t.type,r) + +def prefix_neg(t): + r = expression(50) + if r.type == 'number': + r.val = str(-float(r.val)) + return r + t.items = [Token(t.pos,'number','0'),r] + return t +def vargs_nud(t): + r = prefix_nud(t) + t.type = 'args' + t.val = '*' + return t +def nargs_nud(t): + r = prefix_nud(t) + t.type = 'nargs' + t.val = '**' + return t + + +base_dmap = { + ',':{'lbp':20,'bp':20,'led':infix_tuple}, + '+':{'lbp':50,'bp':50,'led':infix_led}, + '-':{'lbp':50,'nud':prefix_neg, + 'bp':50,'led':infix_led}, + 'not':{'lbp':35,'nud':prefix_nud,'bp':35, + 'bp':35,'led':infix_not }, + '%':{'lbp':60,'bp':60,'led':infix_led}, + '*':{'lbp':60,'nud':vargs_nud, + 'bp':60,'led':infix_led,}, + '**': {'lbp':65,'nud':nargs_nud, + 'bp':65,'led':infix_led,}, + '/':{'lbp':60,'bp':60,'led':infix_led}, + '(':{'lbp':70,'nud':paren_nud, + 'bp':80,'led':call_led,}, + '[':{'lbp':70,'nud':list_nud, + 'bp':80,'led':get_led,}, + '{':{'lbp':0,'nud':dict_nud,}, + '.':{'lbp':80,'bp':80,'led':dot_led,'type':'get',}, + 'break':{'lbp':0,'nud':itself,'type':'break'}, + 'pass':{'lbp':0,'nud':itself,'type':'pass'}, + 'continue':{'lbp':0,'nud':itself,'type':'continue'}, + 'eof':{'lbp':0,'type':'eof','val':'eof'}, + 'def':{'lbp':0,'nud':def_nud,'type':'def',}, + 'while':{'lbp':0,'nud':while_nud,'type':'while',}, + 'for':{'lbp':0,'nud':for_nud,'type':'for',}, + 'try':{'lbp':0,'nud':try_nud,'type':'try',}, + 'if':{'lbp':0,'nud':if_nud,'type':'if',}, + 'class':{'lbp':0,'nud':class_nud,'type':'class',}, + 'raise':{'lbp':0,'nud':prefix_nud0,'type':'raise','bp':20,}, + 'return':{'lbp':0,'nud':prefix_nud0,'type':'return','bp':10,}, + 'import':{'lbp':0,'nud':prefix_nuds,'type':'import','bp':20,}, + 'from':{'lbp':0,'nud':from_nud,'type':'from','bp':20,}, + 'del':{'lbp':0,'nud':prefix_nuds,'type':'del','bp':10,}, + 'global':{'lbp':0,'nud':prefix_nuds,'type':'globals','bp':20,}, + + '=':{ + 'lbp':10,'bp':9,'led':infix_led, + }, +} + +def i_infix(bp,led,*vs): + for v in vs: base_dmap[v] = {'lbp':bp,'bp':bp,'led':led} +i_infix(40,infix_led,'<','>','<=','>=','!=','==') +i_infix(40,infix_is,'is','in') +i_infix(10,infix_led,'+=','-=','*=','/=') +i_infix(31,infix_led,'and','&') +i_infix(30,infix_led,'or','|') +i_infix(36,infix_led,'<<','>>') +def i_terms(*vs): + for v in vs: base_dmap[v] = {'lbp':0,'nud':itself} +i_terms(')','}',']',';',':','nl','elif','else','True','False','None','name','string','number','indent','dedent','except') +base_dmap['nl']['val'] = 'nl' + +def gmap(t,v): + if v not in dmap: + error('unknown "%s"'%v,t) + return dmap[v] + +def do(t): + if t.type == 'symbol': r = gmap(t,t.val) + else: r = gmap(t,t.type) + merge(t,r) + return t +def do_module(): + tok = P.token + items = [] + while not check(P.token,'eof'): + items.append(block()) + if len(items) > 1: + return Token(tok.pos,'statements',';',items) + return items.pop() + +def parse(s,tokens,wrap=0): + global P + s = tokenize.clean(s) + P=PData(s,tokens); P.init() + r = do_module() + P = None + return r + diff --git a/programs/develop/tinypy/tinypy/py2bc.py b/programs/develop/tinypy/tinypy/py2bc.py new file mode 100644 index 0000000000..83d0827443 --- /dev/null +++ b/programs/develop/tinypy/tinypy/py2bc.py @@ -0,0 +1,56 @@ +print("Starting py2bc") +if not (str(1.0) == "1"): + from boot import * + +import tokenize,parse,encode + +def _compile(s,fname): + tokens = tokenize.tokenize(s) + t = parse.parse(s,tokens) + r = encode.encode(fname,s,t) + return r + +def _import(name): + if name in MODULES: + return MODULES[name] + py = name+".py" + tpc = name+".tpc" + print("CP") + if exists(py): + if not exists(tpc) or mtime(py) > mtime(tpc): + s = load(py) + code = _compile(s,py) + save(tpc,code) + if not exists(tpc): raise + code = load(tpc) + g = {'__name__':name,'__code__':code} + g['__dict__'] = g + MODULES[name] = g + exec(code,g) + return g +def _init(): + BUILTINS['compile'] = _compile + BUILTINS['import'] = _import + +def import_fname(fname,name): + g = {} + g['__name__'] = name + MODULES[name] = g + s = load(fname) + code = _compile(s,fname) + g['__code__'] = code + exec(code,g) + return g + +def tinypy(): + print("tinypy called") + return import_fname(ARGV[0],'__main__') + +def main(src,dest): + s = load(src) + r = _compile(s,src) + save(dest,r) + +if __name__ == '__main__': + print("Running main") + main(ARGV[1],ARGV[2]) diff --git a/programs/develop/tinypy/tinypy/string.c b/programs/develop/tinypy/tinypy/string.c new file mode 100644 index 0000000000..a23148eed1 --- /dev/null +++ b/programs/develop/tinypy/tinypy/string.c @@ -0,0 +1,165 @@ +#include + +tp_obj tp_string_t(TP, int n) { + tp_obj r = tp_string_n(0,n); + r.string.info = (_tp_string*)tp_malloc(sizeof(_tp_string)+n); + r.string.val = r.string.info->s; + return r; +} + +tp_obj tp_printf(TP, char const *fmt,...) { + int l; + tp_obj r; + char tmp[2000]; + char *s; + va_list arg; + va_start(arg, fmt); + l = vsnprintf(tmp, sizeof(tmp), fmt,arg); + r = tp_string_t(tp,l); + s = r.string.info->s; + va_end(arg); + va_start(arg, fmt); + vsprintf(s,fmt,arg); + va_end(arg); + return tp_track(tp,r); +} + +int _tp_str_index(tp_obj s, tp_obj k) { + int i=0; + while ((s.string.len - i) >= k.string.len) { + if (memcmp(s.string.val+i,k.string.val,k.string.len) == 0) { + return i; + } + i += 1; + } + return -1; +} + +tp_obj tp_join(TP) { + tp_obj delim = TP_OBJ(); + tp_obj val = TP_OBJ(); + int l=0,i; + tp_obj r; + char *s; + for (i=0; ilen; i++) { + if (i!=0) { l += delim.string.len; } + l += tp_str(tp,val.list.val->items[i]).string.len; + } + r = tp_string_t(tp,l); + s = r.string.info->s; + l = 0; + for (i=0; ilen; i++) { + tp_obj e; + if (i!=0) { + memcpy(s+l,delim.string.val,delim.string.len); l += delim.string.len; + } + e = tp_str(tp,val.list.val->items[i]); + memcpy(s+l,e.string.val,e.string.len); l += e.string.len; + } + return tp_track(tp,r); +} + +tp_obj tp_string_slice(TP,tp_obj s, int a, int b) { + tp_obj r = tp_string_t(tp,b-a); + char *m = r.string.info->s; + memcpy(m,s.string.val+a,b-a); + return tp_track(tp,r); +} + +tp_obj tp_split(TP) { + tp_obj v = TP_OBJ(); + tp_obj d = TP_OBJ(); + tp_obj r = tp_list(tp); + + int i; + while ((i=_tp_str_index(v,d))!=-1) { + _tp_list_append(tp,r.list.val,tp_string_slice(tp,v,0,i)); + v.string.val += i + d.string.len; v.string.len -= i + d.string.len; +/* tp_grey(tp,r); // should stop gc or something instead*/ + } + _tp_list_append(tp,r.list.val,tp_string_slice(tp,v,0,v.string.len)); +/* tp_grey(tp,r); // should stop gc or something instead*/ + return r; +} + + +tp_obj tp_find(TP) { + tp_obj s = TP_OBJ(); + tp_obj v = TP_OBJ(); + return tp_number(_tp_str_index(s,v)); +} + +tp_obj tp_str_index(TP) { + tp_obj s = TP_OBJ(); + tp_obj v = TP_OBJ(); + int n = _tp_str_index(s,v); + if (n >= 0) { return tp_number(n); } + tp_raise(tp_None,"tp_str_index(%s,%s)",s,v); +} + +tp_obj tp_str2(TP) { + tp_obj v = TP_OBJ(); + return tp_str(tp,v); +} + +tp_obj tp_chr(TP) { + int v = TP_NUM(); + return tp_string_n(tp->chars[(unsigned char)v],1); +} +tp_obj tp_ord(TP) { + char const *s = TP_STR(); + return tp_number((unsigned char)s[0]); +} + +tp_obj tp_strip(TP) { + char const *v = TP_STR(); + int i, l = strlen(v); int a = l, b = 0; + tp_obj r; + char *s; + for (i=0; is; + memcpy(s,v+a,b-a); + return tp_track(tp,r); +} + + +tp_obj tp_replace(TP) { + tp_obj s = TP_OBJ(); + tp_obj k = TP_OBJ(); + tp_obj v = TP_OBJ(); + tp_obj p = s; + int i,n = 0; + int c; + int l; + tp_obj rr; + char *r; + char *d; + tp_obj z; + while ((i = _tp_str_index(p,k)) != -1) { + n += 1; + p.string.val += i + k.string.len; p.string.len -= i + k.string.len; + } +/* fprintf(stderr,"ns: %d\n",n); */ + l = s.string.len + n * (v.string.len-k.string.len); + rr = tp_string_t(tp,l); + r = rr.string.info->s; + d = r; + z = p = s; + while ((i = _tp_str_index(p,k)) != -1) { + p.string.val += i; p.string.len -= i; + memcpy(d,z.string.val,c=(p.string.val-z.string.val)); d += c; + p.string.val += k.string.len; p.string.len -= k.string.len; + memcpy(d,v.string.val,v.string.len); d += v.string.len; + z = p; + } + memcpy(d,z.string.val,(s.string.val + s.string.len) - z.string.val); + + return tp_track(tp,rr); +} + diff --git a/programs/develop/tinypy/tinypy/test.py b/programs/develop/tinypy/tinypy/test.py new file mode 100644 index 0000000000..42409b84c8 --- /dev/null +++ b/programs/develop/tinypy/tinypy/test.py @@ -0,0 +1,2 @@ +if __name__=="__main__": + print("ok!") diff --git a/programs/develop/tinypy/tinypy/tests.py b/programs/develop/tinypy/tinypy/tests.py new file mode 100644 index 0000000000..00576bbf4a --- /dev/null +++ b/programs/develop/tinypy/tinypy/tests.py @@ -0,0 +1,750 @@ +# figure out if we're in python or tinypy (tinypy displays "1.0" as "1") +is_tinypy = (str(1.0) == "1") +if not is_tinypy: + from boot import * + +################################################################################ +RM = 'rm -f ' +VM = './vm ' +TINYPY = './tinypy ' +TMP = 'tmp.txt' +if '-mingw32' in ARGV or "-win" in ARGV: + RM = 'del ' + VM = 'vm ' + TINYPY = 'tinypy ' + TMP = 'tmp.txt' + #TMP = 'stdout.txt' +def system_rm(fname): + system(RM+fname) + +################################################################################ +#if not is_tinypy: + #v = chksize() + #assert (v < 65536) + +################################################################################ +def t_show(t): + if t.type == 'string': return '"'+t.val+'"' + if t.type == 'number': return t.val + if t.type == 'symbol': return t.val + if t.type == 'name': return '$'+t.val + return t.type +def t_tokenize(s,exp=''): + import tokenize + result = tokenize.tokenize(s) + res = ' '.join([t_show(t) for t in result]) + #print(s); print(exp); print(res) + assert(res == exp) + +if __name__ == '__main__': + t_tokenize("234",'234') + t_tokenize("234.234",'234.234') + t_tokenize("phil",'$phil') + t_tokenize("_phil234",'$_phil234') + t_tokenize("'phil'",'"phil"') + t_tokenize('"phil"','"phil"') + t_tokenize("'phil' x",'"phil" $x') + t_tokenize("#comment","") + t_tokenize("and","and") + t_tokenize("=","=") + t_tokenize("()","( )") + t_tokenize("(==)","( == )") + t_tokenize("phil=234","$phil = 234") + t_tokenize("a b","$a $b") + t_tokenize("a\nb","$a nl $b") + t_tokenize("a\n b","$a nl indent $b dedent") + t_tokenize("a\n b\n c", "$a nl indent $b nl indent $c dedent dedent") + t_tokenize("a\n b\n c", "$a nl indent $b nl $c dedent") + t_tokenize("a\n b\n \n c", "$a nl indent $b nl nl indent $c dedent dedent") + t_tokenize("a\n b\nc", "$a nl indent $b nl dedent $c") + t_tokenize("a\n b\n c\nd", "$a nl indent $b nl indent $c nl dedent dedent $d") + t_tokenize("(\n )","( )") + t_tokenize(" x","indent $x dedent") + t_tokenize(" #","") + t_tokenize("None","None") + + +################################################################################ + +def t_lisp(t): + if t.type == 'block': + return """{%s}"""%' '.join([t_lisp(tt) for tt in t.items]) + if t.type == 'statement': + return """%s;"""%' '.join([t_lisp(tt) for tt in t.items]) + if t.items == None: return t.val + args = ''.join([" "+t_lisp(tt) for tt in t.items]) + return "("+t.val+args+")" + +def t_parse(s,ex=''): + import tokenize, parse + r = '' + tokens = tokenize.tokenize(s) + tree = parse.parse(s,tokens) + r = t_lisp(tree) + #print(s); print(ex); print(r) + assert(r==ex) + +if __name__ == '__main__': + t_parse('2+4*3', '(+ 2 (* 4 3))') + t_parse('4*(2+3)', '(* 4 (+ 2 3))') + t_parse('(2+3)*4', '(* (+ 2 3) 4)') + t_parse('1<2', '(< 1 2)') + t_parse('x=3', '(= x 3)') + t_parse('x = 2*3', '(= x (* 2 3))') + t_parse('x = y', '(= x y)') + t_parse('2,3', '(, 2 3)') + t_parse('2,3,4', '(, 2 3 4)') + t_parse('[]', '([])') + t_parse('[1]', '([] 1)') + t_parse('[2,3,4]', '([] 2 3 4)') + t_parse('print(3)', '($ print 3)') + t_parse('print()', '($ print)') + t_parse('print(2,3)', '($ print 2 3)') + t_parse('def fnc():pass', '(def fnc (():) pass)') + t_parse('def fnc(x):pass', '(def fnc ((): x) pass)') + t_parse('def fnc(x,y):pass', '(def fnc ((): x y) pass)') + t_parse('x\ny\nz', '(; x y z)') + t_parse('return x', '(return x)') + t_parse('print(test(2,3))', '($ print ($ test 2 3))') + t_parse('x.y', '(. x y)') + t_parse('get(2).x', '(. ($ get 2) x)') + t_parse('{}', '({})') + t_parse('True', 'True') + t_parse('False', 'False') + t_parse('None', 'None') + t_parse('while 1:pass', '(while 1 pass)') + t_parse('for x in y:pass', '(for x y pass)') + t_parse('print("x")', '($ print x)') + t_parse('if 1: pass', '(if (elif 1 pass))') + t_parse('x = []', '(= x ([]))') + t_parse('x[1]', '(. x 1)') + t_parse('import sdl', '(import sdl)') + t_parse('2 is 3', '(is 2 3)') + t_parse('2 is not 3', '(isnot 2 3)') + t_parse('x is None', '(is x None)') + t_parse('2 is 3 or 4 is 5', '(or (is 2 3) (is 4 5))') + t_parse('e.x == 3 or e.x == 4', '(or (== (. e x) 3) (== (. e x) 4))') + t_parse('if 1==2: 3\nelif 4:5\nelse:6', '(if (elif (== 1 2) 3) (elif 4 5) (else 6))') + t_parse('x = y(2)*3 + y(4)*5', '(= x (+ (* ($ y 2) 3) (* ($ y 4) 5)))') + t_parse('x(1,2)+y(3,4)', '(+ ($ x 1 2) ($ y 3 4))') + t_parse('x(a,b,c[d])', '($ x a b (. c d))') + t_parse('x(1,2)*j+y(3,4)*k+z(5,6)*l', '(+ (+ (* ($ x 1 2) j) (* ($ y 3 4) k)) (* ($ z 5 6) l))') + t_parse('a = b.x/c * 2 - 1', '(= a (- (* (/ (. b x) c) 2) 1))') + t_parse('for x in y: z', '(for x y z)') + + t_parse('min(255,n*2)','($ min 255 (* n 2))') + t_parse('c = pal[i*8]','(= c (. pal (* i 8)))') + t_parse('{x:y,a:b}','({} x y a b)') + t_parse('x[1:2:3]','(. x (: 1 2 3))') + if is_tinypy: t_parse('x - -234','(- x -234)') + else: t_parse('x - -234','(- x -234.0)') + t_parse('x - -y','(- x (- 0 y))') + t_parse('x = ((y*4)-2)','(= x (- (* y 4) 2))') + + if is_tinypy: t_parse('print([1,2,"OK",4][-3:3][1])','($ print (. (. ([] 1 2 OK 4) (: -3 3)) 1))') + else: t_parse('print([1,2,"OK",4][-3:3][1])','($ print (. (. ([] 1 2 OK 4) (: -3.0 3)) 1))') + + t_parse('a,b = 1,2','(= (, a b) (, 1 2))') + t_parse('class C: pass','(class C (methods pass))') + t_parse('def test(*v): pass','(def test ((): (* v)) pass)') + t_parse('def test(**v): pass','(def test ((): (** v)) pass)') + t_parse('test(*v)','($ test (* v))') + t_parse('test(**v)','($ test (** v))') + t_parse('def test(x=y): pass','(def test ((): (= x y)) pass)') + t_parse('test(x=y)','($ test (= x y))') + t_parse('def test(y="K",x="Z"): pass','(def test ((): (= y K) (= x Z)) pass)') + t_parse('return x+y','(return (+ x y))') + t_parse('if "a" is not "b": pass','(if (elif (isnot a b) pass))') + t_parse('z = 0\nfor x in y: pass','(; (= z 0) (for x y pass))') + t_parse('for k in {"OK":0}: pass','(for k ({} OK 0) pass)') + t_parse('print(test(10,3,z=50000,*[200],**{"x":4000}))','($ print ($ test 10 3 (= z 50000) (* ([] 200)) (** ({} x 4000))))') + t_parse('x="OK";print(x)','(; (= x OK) ($ print x))') + t_parse('[(1,3)]','([] (, 1 3))') + t_parse('x[:]','(. x (: None None))') + t_parse('x[:1]','(. x (: None 1))') + t_parse('x[1:]','(. x (: 1 None))') + t_parse('return\nx','(; return x)') + t_parse('"""test"""','test') + t_parse('return a,b','(return (, a b))') + +################################################################################ + +def showerror(cmd, ss, ex, res): + print(cmd) + print("ss : '" + str(ss) + "'") + print("ex : '" + str(ex) + "'") + print("res: '" + str(res) + "'") + +def t_render(ss,ex,exact=True): + import tokenize, parse, encode + + if not istype(ss,'list'): ss =[ss] + n = 1 + for s in ss: + fname = 'tmp'+str(n)+'.tpc' + system_rm(fname) + tokens = tokenize.tokenize(s) + t = parse.parse(s,tokens) + r = encode.encode(fname,s,t) + f = save(fname,r) + n += 1 + system_rm('tmp.txt') + cmd = VM + fname + " > tmp.txt" + system(cmd) + res = load(TMP).strip() + #print(ss,ex,res) + if exact: + if res != ex: showerror(cmd, ss, ex, res) + assert(res == ex) + else: + if ex not in res: showerror(cmd, ss, ex, res) + assert(ex in res) + +def test_range(): + t_render("""print(str(range(4))[:5])"""," tmp.txt') + res = load(TMP).strip() + #print(ss,ex,res) + if exact: assert(res == ex) + else: assert(ex in res) + +is_boot = False +try: + assert(is_tinypy == True) + x = compile('x=3','') + is_boot = True +except: + pass + +if is_boot == True and __name__ == '__main__': + print("# t_boot") + t_boot(["def test(): print('OK')","import tmp1; tmp1.test()"],"OK") + diff --git a/programs/develop/tinypy/tinypy/tokenize.py b/programs/develop/tinypy/tinypy/tokenize.py new file mode 100644 index 0000000000..9a47b6ffbe --- /dev/null +++ b/programs/develop/tinypy/tinypy/tokenize.py @@ -0,0 +1,171 @@ +class Token: + def __init__(self,pos=(0,0),type='symbol',val=None,items=None): + self.pos,self.type,self.val,self.items=pos,type,val,items + +def u_error(ctx,s,i): + y,x = i + line = s.split('\n')[y-1] + p = '' + if y < 10: p += ' ' + if y < 100: p += ' ' + r = p + str(y) + ": " + line + "\n" + r += " "+" "*x+"^" +'\n' + raise 'error: '+ctx+'\n'+r + +ISYMBOLS = '`-=[];,./~!@$%^&*()+{}:<>?' +SYMBOLS = [ + 'def','class','yield','return','pass','and','or','not','in','import', + 'is','while','break','for','continue','if','else','elif','try', + 'except','raise','True','False','None','global','del','from', + '-','+','*','**','/','%','<<','>>', + '-=','+=','*=','/=','=','==','!=','<','>', + '<=','>=','[',']','{','}','(',')','.',':',',',';','&','|','!', + ] +B_BEGIN,B_END = ['[','(','{'],[']',')','}'] + +class TData: + def __init__(self): + self.y,self.yi,self.nl = 1,0,True + self.res,self.indent,self.braces = [],[0],0 + def add(self,t,v): self.res.append(Token(self.f,t,v)) + +def clean(s): + s = s.replace('\r\n','\n') + s = s.replace('\r','\n') + return s + +def tokenize(s): + s = clean(s) + try: return do_tokenize(s) + except: u_error('tokenize',s,T.f) + +def do_tokenize(s): + global T + T,i,l = TData(),0,len(s) + T.f = (T.y,i-T.yi+1) + while i < l: + c = s[i]; T.f = (T.y,i-T.yi+1) + if T.nl: T.nl = False; i = do_indent(s,i,l) + elif c == '\n': i = do_nl(s,i,l) + elif c in ISYMBOLS: i = do_symbol(s,i,l) + elif c >= '0' and c <= '9': i = do_number(s,i,l) + elif (c >= 'a' and c <= 'z') or \ + (c >= 'A' and c <= 'Z') or c == '_': i = do_name(s,i,l) + elif c=='"' or c=="'": i = do_string(s,i,l) + elif c=='#': i = do_comment(s,i,l) + elif c == '\\' and s[i+1] == '\n': + i += 2; T.y,T.yi = T.y+1,i + elif c == ' ' or c == '\t': i += 1 + else: u_error('tokenize',s,T.f) + indent(0) + r = T.res; T = None + return r + +def do_nl(s,i,l): + if not T.braces: + T.add('nl',None) + i,T.nl = i+1,True + T.y,T.yi = T.y+1,i + return i + +def do_indent(s,i,l): + v = 0 + while i T.indent[-1]: + T.indent.append(v) + T.add('indent',v) + elif v < T.indent[-1]: + n = T.indent.index(v) + while len(T.indent) > n+1: + v = T.indent.pop() + T.add('dedent',v) + + +def do_symbol(s,i,l): + symbols = [] + v,f,i = s[i],i,i+1 + if v in SYMBOLS: symbols.append(v) + while i '9') and (c < 'a' or c > 'f') and c != 'x': break + v,i = v+c,i+1 + if c == '.': + v,i = v+c,i+1 + while i '9': break + v,i = v+c,i+1 + T.add('number',v) + return i + +def do_name(s,i,l): + v,i =s[i],i+1 + while i 'z') and (c < 'A' or c > 'Z') and (c < '0' or c > '9') and c != '_': break + v,i = v+c,i+1 + if v in SYMBOLS: T.add('symbol',v) + else: T.add('name',v) + return i + +def do_string(s,i,l): + v,q,i = '',s[i],i+1 + if (l-i) >= 5 and s[i] == q and s[i+1] == q: # """ + i += 2 + while i +#include +#ifndef __USE_ISOC99 +#define __USE_ISOC99 +#endif +#include +#include +#include +#include +#include + +#ifdef __GNUC__ +#define tp_inline __inline__ +#endif + +#ifdef _MSC_VER +#define tp_inline __inline +#endif + +#ifndef tp_inline +#error "Unsuported compiler" +#endif + +#define tp_malloc(x) calloc((x),1) +#define tp_realloc(x,y) realloc(x,y) +#define tp_free(x) free(x) + +/* #include + #define tp_malloc(x) GC_MALLOC(x) + #define tp_realloc(x,y) GC_REALLOC(x,y) + #define tp_free(x)*/ + +enum { + TP_NONE,TP_NUMBER,TP_STRING,TP_DICT, + TP_LIST,TP_FNC,TP_DATA, +}; + +typedef double tp_num; + +typedef struct tp_number_ { + int type; + tp_num val; +} tp_number_; +typedef struct tp_string_ { + int type; + struct _tp_string *info; + char const *val; + int len; +} tp_string_; +typedef struct tp_list_ { + int type; + struct _tp_list *val; +} tp_list_; +typedef struct tp_dict_ { + int type; + struct _tp_dict *val; +} tp_dict_; +typedef struct tp_fnc_ { + int type; + struct _tp_fnc *info; + int ftype; + void *val; +} tp_fnc_; +typedef struct tp_data_ { + int type; + struct _tp_data *info; + void *val; + int magic; +} tp_data_; + +typedef union tp_obj { + int type; + tp_number_ number; + struct { int type; int *data; } gci; + tp_string_ string; + tp_dict_ dict; + tp_list_ list; + tp_fnc_ fnc; + tp_data_ data; +} tp_obj; + +typedef struct _tp_string { + int gci; + char s[1]; +} _tp_string; +typedef struct _tp_list { + int gci; + tp_obj *items; + int len; + int alloc; +} _tp_list; +typedef struct tp_item { + int used; + int hash; + tp_obj key; + tp_obj val; +} tp_item; +typedef struct _tp_dict { + int gci; + tp_item *items; + int len; + int alloc; + int cur; + int mask; + int used; +} _tp_dict; +typedef struct _tp_fnc { + int gci; + tp_obj self; + tp_obj globals; +} _tp_fnc; + + +typedef union tp_code { + unsigned char i; + struct { unsigned char i,a,b,c; } regs; + struct { char val[4]; } string; + struct { float val; } number; +} tp_code; + +typedef struct tp_frame_ { + tp_code *codes; + tp_code *cur; + tp_code *jmp; + tp_obj *regs; + tp_obj *ret_dest; + tp_obj fname; + tp_obj name; + tp_obj line; + tp_obj globals; + int lineno; + int cregs; +} tp_frame_; + +#define TP_GCMAX 4096 +#define TP_FRAMES 256 +/* #define TP_REGS_PER_FRAME 256*/ +#define TP_REGS 16384 +typedef struct tp_vm { + tp_obj builtins; + tp_obj modules; + tp_frame_ frames[TP_FRAMES]; + tp_obj _params; + tp_obj params; + tp_obj _regs; + tp_obj *regs; + tp_obj root; + jmp_buf buf; + int jmp; + tp_obj ex; + char chars[256][2]; + int cur; + /* gc*/ + _tp_list *white; + _tp_list *grey; + _tp_list *black; + _tp_dict *strings; + int steps; +} tp_vm; + +#define TP tp_vm *tp +typedef struct _tp_data { + int gci; + void (*free)(TP,tp_obj); +} _tp_data; + +/* NOTE: these are the few out of namespace items for convenience*/ +#define tp_True tp_number(1) +#define tp_False tp_number(0) +#define TP_CSTR(v) ((tp_str(tp,(v))).string.val) + +extern tp_obj tp_None; + +void tp_set(TP,tp_obj,tp_obj,tp_obj); +tp_obj tp_get(TP,tp_obj,tp_obj); +tp_obj tp_len(TP,tp_obj); +tp_obj tp_str(TP,tp_obj); +int tp_cmp(TP,tp_obj,tp_obj); +void _tp_raise(TP,tp_obj); +tp_obj tp_printf(TP,char const *fmt,...); +tp_obj tp_track(TP,tp_obj); +void tp_grey(TP,tp_obj); + +/* __func__ __VA_ARGS__ __FILE__ __LINE__ */ +#define tp_raise(r,fmt,...) { \ + _tp_raise(tp,tp_printf(tp,fmt,__VA_ARGS__)); \ + return r; \ +} +#define TP_OBJ() (tp_get(tp,tp->params,tp_None)) +tp_inline static tp_obj tp_type(TP,int t,tp_obj v) { + if (v.type != t) { tp_raise(tp_None,"_tp_type(%d,%s)",t,TP_CSTR(v)); } + return v; +} +#define TP_TYPE(t) tp_type(tp,t,TP_OBJ()) +#define TP_NUM() (TP_TYPE(TP_NUMBER).number.val) +#define TP_STR() (TP_CSTR(TP_TYPE(TP_STRING))) +#define TP_DEFAULT(d) (tp->params.list.val->len?tp_get(tp,tp->params,tp_None):(d)) +#define TP_LOOP(e) \ + int __l = tp->params.list.val->len; \ + int __i; for (__i=0; __i<__l; __i++) { \ + (e) = _tp_list_get(tp,tp->params.list.val,__i,"TP_LOOP"); +#define TP_END \ + } + +tp_inline static int _tp_min(int a, int b) { return (ab?a:b); } +tp_inline static int _tp_sign(tp_num v) { return (v<0?-1:(v>0?1:0)); } + +tp_inline static tp_obj tp_number(tp_num v) { + tp_obj val = {TP_NUMBER}; + val.number.val = v; + return val; +} + +tp_inline static tp_obj tp_string(char const *v) { + tp_obj val; + tp_string_ s = {TP_STRING, 0, v, 0}; + s.len = strlen(v); + val.string = s; + return val; +} + +tp_inline static tp_obj tp_string_n(char const *v,int n) { + tp_obj val; + tp_string_ s = {TP_STRING, 0,v,n}; + val.string = s; + return val; +} + +#endif diff --git a/programs/develop/tinypy/tinypy/tpmain.c b/programs/develop/tinypy/tinypy/tpmain.c new file mode 100644 index 0000000000..b20c786e0d --- /dev/null +++ b/programs/develop/tinypy/tinypy/tpmain.c @@ -0,0 +1,24 @@ +#include "tp.c" +/* INCLUDE */ +const char header[]="TinyPy for kolibriOS"; +const int argc = 2; +extern _stdcall void testmod_init(tp_vm *tp); +void main(void) { + char *argv[2]={"tpmain", "test.py"}; + + CONSOLE_INIT(header); + con_printf("TinyPy console, version 1.1.\n"); + con_printf("Enter program file:"); + if (!(argv[1] = malloc(256))) + con_printf("Memory error\n"); + con_gets(argv[1], 256); + argv[1][strlen(argv[1]) - 1] = '\0'; + con_printf("Running file %s\n", argv[1]); + tp_vm *tp = tp_init(argc, argv); + /* INIT */ + tp_call(tp,"py2bc","tinypy",tp_None); + tp_deinit(tp); + return; +} + +/**/ diff --git a/programs/develop/tinypy/tinypy/vm.c b/programs/develop/tinypy/tinypy/vm.c new file mode 100644 index 0000000000..c5fa0e2588 --- /dev/null +++ b/programs/develop/tinypy/tinypy/vm.c @@ -0,0 +1,380 @@ + +tp_vm *_tp_init(void) { + int i; + tp_vm *tp = (tp_vm*)tp_malloc(sizeof(tp_vm)); + tp->cur = 0; + tp->jmp = 0; + tp->ex = tp_None; + tp->root = tp_list(0); + for (i=0; i<256; i++) { tp->chars[i][0]=i; } + tp_gc_init(tp); + tp->_regs = tp_list(tp); + for (i=0; i_regs,tp_None,tp_None); } + tp->builtins = tp_dict(tp); + tp->modules = tp_dict(tp); + tp->_params = tp_list(tp); + for (i=0; i_params,tp_None,tp_list(tp)); } + tp_set(tp,tp->root,tp_None,tp->builtins); + tp_set(tp,tp->root,tp_None,tp->modules); + tp_set(tp,tp->root,tp_None,tp->_regs); + tp_set(tp,tp->root,tp_None,tp->_params); + tp_set(tp,tp->builtins,tp_string("MODULES"),tp->modules); + tp_set(tp,tp->modules,tp_string("BUILTINS"),tp->builtins); + tp_set(tp,tp->builtins,tp_string("BUILTINS"),tp->builtins); + tp->regs = tp->_regs.list.val->items; + tp_full(tp); + return tp; +} + +void tp_deinit(TP) { + while (tp->root.list.val->len) { + _tp_list_pop(tp,tp->root.list.val,0,"tp_deinit"); + } + tp_full(tp); tp_full(tp); + tp_delete(tp,tp->root); + tp_gc_deinit(tp); + tp_free(tp); +} + + +/* tp_frame_*/ +void tp_frame(TP,tp_obj globals,tp_code *codes,tp_obj *ret_dest) { + tp_frame_ f; + f.globals = globals; + f.codes = codes; + f.cur = f.codes; + f.jmp = 0; +/* fprintf(stderr,"tp->cur: %d\n",tp->cur);*/ + f.regs = (tp->cur <= 0?tp->regs:tp->frames[tp->cur].regs+tp->frames[tp->cur].cregs); + f.ret_dest = ret_dest; + f.lineno = 0; + f.line = tp_string(""); + f.name = tp_string("?"); + f.fname = tp_string("?"); + f.cregs = 0; +/* return f;*/ + if (f.regs+256 >= tp->regs+TP_REGS || tp->cur >= TP_FRAMES-1) { tp_raise(,"tp_frame: stack overflow %d",tp->cur); } + tp->cur += 1; + tp->frames[tp->cur] = f; +} + +void _tp_raise(TP,tp_obj e) { + if (!tp || !tp->jmp) { + con_printf("\nException:\n%s\n",TP_CSTR(e)); + exit(-1); + return; + } + if (e.type != TP_NONE) { tp->ex = e; } + tp_grey(tp,e); + longjmp(tp->buf,1); +} + +void tp_print_stack(TP) { + int i; + con_printf("\n"); + for (i=0; i<=tp->cur; i++) { + if (!tp->frames[i].lineno) { continue; } + con_printf("File \"%s\", line %d, in %s\n %s\n", + TP_CSTR(tp->frames[i].fname),tp->frames[i].lineno, + TP_CSTR(tp->frames[i].name),TP_CSTR(tp->frames[i].line)); + } + con_printf("\nException:\n%s\n",TP_CSTR(tp->ex)); +} + + + +void tp_handle(TP) { + int i; + for (i=tp->cur; i>=0; i--) { + if (tp->frames[i].jmp) { break; } + } + if (i >= 0) { + tp->cur = i; + tp->frames[i].cur = tp->frames[i].jmp; + tp->frames[i].jmp = 0; + return; + } + tp_print_stack(tp); + exit(-1); +} + +void _tp_call(TP,tp_obj *dest, tp_obj fnc, tp_obj params) { + /*con_printf("_tp_call %s %s\n",TP_CSTR(fnc), TP_CSTR(params));*/ + if (fnc.type == TP_DICT) { + _tp_call(tp,dest,tp_get(tp,fnc,tp_string("__call__")),params); + return; + } + if (fnc.type == TP_FNC && !(fnc.fnc.ftype&1)) { + *dest = _tp_tcall(tp,fnc); + tp_grey(tp,*dest); + return; + } + if (fnc.type == TP_FNC) { + tp_frame(tp,fnc.fnc.info->globals,(tp_code*)fnc.fnc.val,dest); + if ((fnc.fnc.ftype&2)) { + tp->frames[tp->cur].regs[0] = params; + _tp_list_insert(tp,params.list.val,0,fnc.fnc.info->self); + } else { + tp->frames[tp->cur].regs[0] = params; + } + return; + } + tp_params_v(tp,1,fnc); tp_print(tp); + tp_raise(,"tp_call: %s is not callable",TP_CSTR(fnc)); +} + + +void tp_return(TP, tp_obj v) { + tp_obj *dest = tp->frames[tp->cur].ret_dest; + if (dest) { *dest = v; tp_grey(tp,v); } +/* memset(tp->frames[tp->cur].regs,0,TP_REGS_PER_FRAME*sizeof(tp_obj)); + fprintf(stderr,"regs:%d\n",(tp->frames[tp->cur].cregs+1));*/ + memset(tp->frames[tp->cur].regs,0,tp->frames[tp->cur].cregs*sizeof(tp_obj)); + tp->cur -= 1; +} + +enum { + TP_IEOF,TP_IADD,TP_ISUB,TP_IMUL,TP_IDIV,TP_IPOW,TP_IAND,TP_IOR,TP_ICMP,TP_IGET,TP_ISET, + TP_INUMBER,TP_ISTRING,TP_IGGET,TP_IGSET,TP_IMOVE,TP_IDEF,TP_IPASS,TP_IJUMP,TP_ICALL, + TP_IRETURN,TP_IIF,TP_IDEBUG,TP_IEQ,TP_ILE,TP_ILT,TP_IDICT,TP_ILIST,TP_INONE,TP_ILEN, + TP_ILINE,TP_IPARAMS,TP_IIGET,TP_IFILE,TP_INAME,TP_INE,TP_IHAS,TP_IRAISE,TP_ISETJMP, + TP_IMOD,TP_ILSH,TP_IRSH,TP_IITER,TP_IDEL,TP_IREGS, + TP_ITOTAL +}; + +/* char *tp_strings[TP_ITOTAL] = { + "EOF","ADD","SUB","MUL","DIV","POW","AND","OR","CMP","GET","SET","NUM", + "STR","GGET","GSET","MOVE","DEF","PASS","JUMP","CALL","RETURN","IF","DEBUG", + "EQ","LE","LT","DICT","LIST","NONE","LEN","LINE","PARAMS","IGET","FILE", + "NAME","NE","HAS","RAISE","SETJMP","MOD","LSH","RSH","ITER","DEL","REGS", + };*/ + +#define VA ((int)e.regs.a) +#define VB ((int)e.regs.b) +#define VC ((int)e.regs.c) +#define RA regs[e.regs.a] +#define RB regs[e.regs.b] +#define RC regs[e.regs.c] +#define UVBC (unsigned short)(((VB<<8)+VC)) +#define SVBC (short)(((VB<<8)+VC)) +#define GA tp_grey(tp,RA) +#define SR(v) f->cur = cur; return(v); + +int tp_step(TP) { + tp_frame_ *f = &tp->frames[tp->cur]; + tp_obj *regs = f->regs; + tp_code *cur = f->cur; + while(1) { + tp_code e = *cur; +/* fprintf(stderr,"%2d.%4d: %-6s %3d %3d %3d\n",tp->cur,cur-f->codes,tp_strings[e.i],VA,VB,VC); + int i; for(i=0;i<16;i++) { fprintf(stderr,"%d: %s\n",i,TP_CSTR(regs[i])); }*/ + switch (e.i) { + case TP_IEOF: tp_return(tp,tp_None); SR(0); break; + case TP_IADD: RA = tp_add(tp,RB,RC); break; + case TP_ISUB: RA = tp_sub(tp,RB,RC); break; + case TP_IMUL: RA = tp_mul(tp,RB,RC); break; + case TP_IDIV: RA = tp_div(tp,RB,RC); break; + case TP_IPOW: RA = tp_pow(tp,RB,RC); break; + case TP_IAND: RA = tp_and(tp,RB,RC); break; + case TP_IOR: RA = tp_or(tp,RB,RC); break; + case TP_IMOD: RA = tp_mod(tp,RB,RC); break; + case TP_ILSH: RA = tp_lsh(tp,RB,RC); break; + case TP_IRSH: RA = tp_rsh(tp,RB,RC); break; + case TP_ICMP: RA = tp_number(tp_cmp(tp,RB,RC)); break; + case TP_INE: RA = tp_number(tp_cmp(tp,RB,RC)!=0); break; + case TP_IEQ: RA = tp_number(tp_cmp(tp,RB,RC)==0); break; + case TP_ILE: RA = tp_number(tp_cmp(tp,RB,RC)<=0); break; + case TP_ILT: RA = tp_number(tp_cmp(tp,RB,RC)<0); break; + case TP_IPASS: break; + case TP_IIF: if (tp_bool(tp,RA)) { cur += 1; } break; + case TP_IGET: RA = tp_get(tp,RB,RC); GA; break; + case TP_IITER: + if (RC.number.val < tp_len(tp,RB).number.val) { + RA = tp_iter(tp,RB,RC); GA; + RC.number.val += 1; + cur += 1; + } + break; + case TP_IHAS: RA = tp_has(tp,RB,RC); break; + case TP_IIGET: tp_iget(tp,&RA,RB,RC); break; + case TP_ISET: tp_set(tp,RA,RB,RC); break; + case TP_IDEL: tp_del(tp,RA,RB); break; + case TP_IMOVE: RA = RB; break; + case TP_INUMBER: + RA = tp_number(*(tp_num*)(*++cur).string.val); + cur += sizeof(tp_num)/4; + continue; + case TP_ISTRING: + RA = tp_string_n((*(cur+1)).string.val,UVBC); + cur += (UVBC/4)+1; + break; + case TP_IDICT: RA = tp_dict_n(tp,VC/2,&RB); break; + case TP_ILIST: RA = tp_list_n(tp,VC,&RB); break; + case TP_IPARAMS: RA = tp_params_n(tp,VC,&RB); break; + case TP_ILEN: RA = tp_len(tp,RB); break; + case TP_IJUMP: cur += SVBC; continue; break; + case TP_ISETJMP: f->jmp = cur+SVBC; break; + case TP_ICALL: _tp_call(tp,&RA,RB,RC); cur++; SR(0); break; + case TP_IGGET: + if (!tp_iget(tp,&RA,f->globals,RB)) { + RA = tp_get(tp,tp->builtins,RB); GA; + } + break; + case TP_IGSET: tp_set(tp,f->globals,RA,RB); break; + case TP_IDEF: + RA = tp_def(tp,(*(cur+1)).string.val,f->globals); + cur += SVBC; continue; + break; + case TP_IRETURN: tp_return(tp,RA); SR(0); break; + case TP_IRAISE: _tp_raise(tp,RA); SR(0); break; + case TP_IDEBUG: + tp_params_v(tp,3,tp_string("DEBUG:"),tp_number(VA),RA); tp_print(tp); + break; + case TP_INONE: RA = tp_None; break; + case TP_ILINE: + f->line = tp_string_n((*(cur+1)).string.val,VA*4-1); +/* fprintf(stderr,"%7d: %s\n",UVBC,f->line.string.val);*/ + cur += VA; f->lineno = UVBC; + break; + case TP_IFILE: f->fname = RA; break; + case TP_INAME: f->name = RA; break; + case TP_IREGS: f->cregs = VA; break; + default: tp_raise(0,"tp_step: invalid instruction %d",e.i); break; + } + cur += 1; + } + SR(0); +} + +void tp_run(TP,int cur) { + if (tp->jmp) { + tp_raise(,"tp_run(%d) called recusively",cur); + } + tp->jmp = 1; + if (setjmp(tp->buf)) + { + tp_handle(tp); + } + while (tp->cur >= cur && tp_step(tp) != -1); + tp->cur = cur-1; + tp->jmp = 0; +} + + +tp_obj tp_call(TP, const char *mod, const char *fnc, tp_obj params) { + tp_obj tmp; + tp_obj r = tp_None; + tmp = tp_get(tp,tp->modules,tp_string(mod)); + tmp = tp_get(tp,tmp,tp_string(fnc)); + _tp_call(tp,&r,tmp,params); + tp_run(tp,tp->cur); + return r; +} + +tp_obj tp_import(TP, char const *fname, char const *name, void *codes) { + tp_obj code = tp_None; + tp_obj g; + if (!((fname && strstr(fname,".tpc")) || codes)) { + return tp_call(tp,"py2bc","import_fname",tp_params_v(tp,2,tp_string(fname),tp_string(name))); + } + if (!codes) { + tp_params_v(tp,1,tp_string(fname)); + code = tp_load(tp); + /* We cast away the constness. */ + codes = (void *)code.string.val; + } else { + code = tp_data(tp,0,codes); + } + + g = tp_dict(tp); + tp_set(tp,g,tp_string("__name__"),tp_string(name)); + tp_set(tp,g,tp_string("__code__"),code); + tp_set(tp,g,tp_string("__dict__"),g); + tp_frame(tp,g,(tp_code*)codes,0); + tp_set(tp,tp->modules,tp_string(name),g); + if (!tp->jmp) { + tp_run(tp,tp->cur); + } + + return g; +} + + + +tp_obj tp_exec_(TP) { + tp_obj code = TP_OBJ(); + tp_obj globals = TP_OBJ(); + tp_frame(tp,globals,(tp_code*)code.string.val,0); + return tp_None; +} + + +tp_obj tp_import_(TP) { + tp_obj mod = TP_OBJ(); + char const *s; + tp_obj r; + + if (tp_has(tp,tp->modules,mod).number.val) { + return tp_get(tp,tp->modules,mod); + } + + s = TP_CSTR(mod); + r = tp_import(tp,TP_CSTR(tp_add(tp,mod,tp_string(".tpc"))),s,0); + return r; +} + +void tp_builtins(TP) { + struct {const char *s;void *f;} b[] = { + {"print",tp_print}, {"range",tp_range}, {"min",tp_min}, + {"max",tp_max}, {"bind",tp_bind}, {"copy",tp_copy}, + {"import",tp_import_}, {"len",tp_len_}, {"assert",tp_assert}, + {"str",tp_str2}, {"float",tp_float}, {"system",tp_system}, + {"istype",tp_istype}, {"chr",tp_chr}, {"save",tp_save}, + {"load",tp_load}, {"fpack",tp_fpack}, {"abs",tp_abs}, + {"int",tp_int}, {"exec",tp_exec_}, {"exists",tp_exists}, + {"mtime",tp_mtime}, {"number",tp_float}, {"round",tp_round}, + {"ord",tp_ord}, {"merge",tp_merge}, {"syscall", tp_syscall}, {0,0}, + }; + int i; for(i=0; b[i].s; i++) { + tp_set(tp,tp->builtins,tp_string(b[i].s),tp_fnc(tp,(tp_obj (*)(tp_vm *))b[i].f)); + } +} + + +void tp_args(TP,int argc, char *argv[]) { + tp_obj self = tp_list(tp); + int i; + for (i=1; ibuiltins,tp_string("ARGV"),self); +} + + +tp_obj tp_main(TP,char *fname, void *code) { + return tp_import(tp,fname,"__main__",code); +} +tp_obj tp_compile(TP, tp_obj text, tp_obj fname) { + return tp_call(tp,"BUILTINS","compile",tp_params_v(tp,2,text,fname)); +} + +tp_obj tp_exec(TP,tp_obj code, tp_obj globals) { + tp_obj r=tp_None; + tp_frame(tp,globals,(tp_code*)code.string.val,&r); + tp_run(tp,tp->cur); + return r; +} + +tp_obj tp_eval(TP, char *text, tp_obj globals) { + tp_obj code = tp_compile(tp,tp_string(text),tp_string("")); + return tp_exec(tp,code,globals); +} + +tp_vm *tp_init(int argc, char *argv[]) { + tp_vm *tp = _tp_init(); + tp_builtins(tp); + tp_args(tp,argc,argv); + tp_compiler(tp); + return tp; +} + + +/**/ diff --git a/programs/develop/tinypy/tinypy/vmmain.c b/programs/develop/tinypy/tinypy/vmmain.c new file mode 100644 index 0000000000..bd437e1ea2 --- /dev/null +++ b/programs/develop/tinypy/tinypy/vmmain.c @@ -0,0 +1,9 @@ +#define TP_COMPILER 0 +#include "tp.c" + +int main(int argc, char *argv[]) { + tp_vm *tp = tp_init(argc,argv); + tp_import(tp,argv[1],"__main__",0); + tp_deinit(tp); + return(0); +}