text: "use strict";
  // Transcrypt'ed from Python, 2017-08-14 18:42:30
  function geo () {
     var __symbols__ = ['__py3.5__', '__esv5__'];
      var __all__ = {};
      var __world__ = __all__;
      
      // Nested object creator, part of the nesting may already exist and have attributes
      var __nest__ = function (headObject, tailNames, value) {
          // In some cases this will be a global object, e.g. 'window'
          var current = headObject;
          
          if (tailNames != '') {  // Split on empty string doesn't give empty list
              // Find the last already created object in tailNames
              var tailChain = tailNames.split ('.');
              var firstNewIndex = tailChain.length;
              for (var index = 0; index < tailChain.length; index++) {
                  if (!current.hasOwnProperty (tailChain [index])) {
                      firstNewIndex = index;
                      break;
                  }
                  current = current [tailChain [index]];
              }
              
              // Create the rest of the objects, if any
              for (var index = firstNewIndex; index < tailChain.length; index++) {
                  current [tailChain [index]] = {};
                  current = current [tailChain [index]];
              }
          }
          
          // Insert it new attributes, it may have been created earlier and have other attributes
          for (var attrib in value) {
              current [attrib] = value [attrib];          
          }       
      };
      __all__.__nest__ = __nest__;
      
      // Initialize module if not yet done and return its globals
      var __init__ = function (module) {
          if (!module.__inited__) {
              module.__all__.__init__ (module.__all__);
              module.__inited__ = true;
          }
          return module.__all__;
      };
      __all__.__init__ = __init__;
      
      
      
      
      // Since we want to assign functions, a = b.f should make b.f produce a bound function
      // So __get__ should be called by a property rather then a function
      // Factory __get__ creates one of three curried functions for func
      // Which one is produced depends on what's to the left of the dot of the corresponding JavaScript property
      var __get__ = function (self, func, quotedFuncName) {
          if (self) {
              if (self.hasOwnProperty ('__class__') || typeof self == 'string' || self instanceof String) {           // Object before the dot
                  if (quotedFuncName) {                                   // Memoize call since fcall is on, by installing bound function in instance
                      Object.defineProperty (self, quotedFuncName, {      // Will override the non-own property, next time it will be called directly
                          value: function () {                            // So next time just call curry function that calls function
                              var args = [] .slice.apply (arguments);
                              return func.apply (null, [self] .concat (args));
                          },              
                          writable: true,
                          enumerable: true,
                          configurable: true
                      });
                  }
                  return function () {                                    // Return bound function, code dupplication for efficiency if no memoizing
                      var args = [] .slice.apply (arguments);             // So multilayer search prototype, apply __get__, call curry func that calls func
                      return func.apply (null, [self] .concat (args));
                  };
              }
              else {                                                      // Class before the dot
                  return func;                                            // Return static method
              }
          }
          else {                                                          // Nothing before the dot
              return func;                                                // Return free function
          }
      }
      __all__.__get__ = __get__;
          
      // Mother of all metaclasses        
      var py_metatype = {
          __name__: 'type',
          __bases__: [],
          
          // Overridable class creation worker
          __new__: function (meta, name, bases, attribs) {
              // Create the class cls, a functor, which the class creator function will return
              var cls = function () {                     // If cls is called with arg0, arg1, etc, it calls its __new__ method with [arg0, arg1, etc]
                  var args = [] .slice.apply (arguments); // It has a __new__ method, not yet but at call time, since it is copied from the parent in the loop below
                  return cls.__new__ (args);              // Each Python class directly or indirectly derives from object, which has the __new__ method
              };                                          // If there are no bases in the Python source, the compiler generates [object] for this parameter
              
              // Copy all methods, including __new__, properties and static attributes from base classes to new cls object
              // The new class object will simply be the prototype of its instances
              // JavaScript prototypical single inheritance will do here, since any object has only one class
              // This has nothing to do with Python multiple inheritance, that is implemented explictly in the copy loop below
              for (var index = bases.length - 1; index >= 0; index--) {   // Reversed order, since class vars of first base should win
                  var base = bases [index];
                  for (var attrib in base) {
                      var descrip = Object.getOwnPropertyDescriptor (base, attrib);
                      Object.defineProperty (cls, attrib, descrip);
                  }           
              }
              
              // Add class specific attributes to the created cls object
              cls.__metaclass__ = meta;
              cls.__name__ = name;
              cls.__bases__ = bases;
              
              // Add own methods, properties and own static attributes to the created cls object
              for (var attrib in attribs) {
                  var descrip = Object.getOwnPropertyDescriptor (attribs, attrib);
                  Object.defineProperty (cls, attrib, descrip);
              }
              // Return created cls object
              return cls;
          }
      };
      py_metatype.__metaclass__ = py_metatype;
      __all__.py_metatype = py_metatype;
      
      // Mother of all classes
      var object = {
          __init__: function (self) {},
          
          __metaclass__: py_metatype, // By default, all classes have metaclass type, since they derive from object
          __name__: 'object',
          __bases__: [],
              
          // Object creator function, is inherited by all classes (so could be global)
          __new__: function (args) {  // Args are just the constructor args       
              // In JavaScript the Python class is the prototype of the Python object
              // In this way methods and static attributes will be available both with a class and an object before the dot
              // The descriptor produced by __get__ will return the right method flavor
              var instance = Object.create (this, {__class__: {value: this, enumerable: true}});
              
  
              // Call constructor
              this.__init__.apply (null, [instance] .concat (args));
  
              // Return constructed instance
              return instance;
          }   
      };
      __all__.object = object;
      
      // Class creator facade function, calls class creation worker
      var __class__ = function (name, bases, attribs, meta) {         // Parameter meta is optional
          if (meta == undefined) {
              meta = bases [0] .__metaclass__;
          }
                  
          return meta.__new__ (meta, name, bases, attribs);
      }
      __all__.__class__ = __class__;
      
      // Define __pragma__ to preserve '<all>' and '</all>', since it's never generated as a function, must be done early, so here
      var __pragma__ = function () {};
      __all__.__pragma__ = __pragma__;
      
      	__nest__ (
  		__all__,
  		'org.transcrypt.__base__', {
  			__all__: {
  				__inited__: false,
  				__init__: function (__all__) {
  					var __Envir__ = __class__ ('__Envir__', [object], {
  						get __init__ () {return __get__ (this, function (self) {
  							self.interpreter_name = 'python';
  							self.transpiler_name = 'transcrypt';
  							self.transpiler_version = '3.6.45';
  							self.target_subdir = '__javascript__';
  						});}
  					});
  					var __envir__ = __Envir__ ();
  					__pragma__ ('<all>')
  						__all__.__Envir__ = __Envir__;
  						__all__.__envir__ = __envir__;
  					__pragma__ ('</all>')
  				}
  			}
  		}
  	);
  	__nest__ (
  		__all__,
  		'org.transcrypt.__standard__', {
  			__all__: {
  				__inited__: false,
  				__init__: function (__all__) {
  					var Exception = __class__ ('Exception', [object], {
  						get __init__ () {return __get__ (this, function (self) {
  							var kwargs = dict ();
  							if (arguments.length) {
  								var __ilastarg0__ = arguments.length - 1;
  								if (arguments [__ilastarg0__] && arguments [__ilastarg0__].hasOwnProperty ("__kwargtrans__")) {
  									var __allkwargs0__ = arguments [__ilastarg0__--];
  									for (var __attrib0__ in __allkwargs0__) {
  										switch (__attrib0__) {
  											case 'self': var self = __allkwargs0__ [__attrib0__]; break;
  											default: kwargs [__attrib0__] = __allkwargs0__ [__attrib0__];
  										}
  									}
  									delete kwargs.__kwargtrans__;
  								}
  								var args = tuple ([].slice.apply (arguments).slice (1, __ilastarg0__ + 1));
  							}
  							else {
  								var args = tuple ();
  							}
  							self.__args__ = args;
  							try {
  								self.stack = kwargs.error.stack;
  							}
  							catch (__except0__) {
  								self.stack = 'No stack trace available';
  							}
  						});},
  						get __repr__ () {return __get__ (this, function (self) {
  							if (len (self.__args__)) {
  								return '{}{}'.format (self.__class__.__name__, repr (tuple (self.__args__)));
  							}
  							else {
  								return '{}()'.format (self.__class__.__name__);
  							}
  						});},
  						get __str__ () {return __get__ (this, function (self) {
  							if (len (self.__args__) > 1) {
  								return str (tuple (self.__args__));
  							}
  							else if (len (self.__args__)) {
  								return str (self.__args__ [0]);
  							}
  							else {
  								return '';
  							}
  						});}
  					});
  					var IterableError = __class__ ('IterableError', [Exception], {
  						get __init__ () {return __get__ (this, function (self, error) {
  							Exception.__init__ (self, "Can't iterate over non-iterable", __kwargtrans__ ({error: error}));
  						});}
  					});
  					var StopIteration = __class__ ('StopIteration', [Exception], {
  						get __init__ () {return __get__ (this, function (self, error) {
  							Exception.__init__ (self, 'Iterator exhausted', __kwargtrans__ ({error: error}));
  						});}
  					});
  					var ValueError = __class__ ('ValueError', [Exception], {
  						get __init__ () {return __get__ (this, function (self, error) {
  							Exception.__init__ (self, 'Erroneous value', __kwargtrans__ ({error: error}));
  						});}
  					});
  					var KeyError = __class__ ('KeyError', [Exception], {
  						get __init__ () {return __get__ (this, function (self, error) {
  							Exception.__init__ (self, 'Invalid key', __kwargtrans__ ({error: error}));
  						});}
  					});
  					var AssertionError = __class__ ('AssertionError', [Exception], {
  						get __init__ () {return __get__ (this, function (self, message, error) {
  							if (message) {
  								Exception.__init__ (self, message, __kwargtrans__ ({error: error}));
  							}
  							else {
  								Exception.__init__ (self, __kwargtrans__ ({error: error}));
  							}
  						});}
  					});
  					var NotImplementedError = __class__ ('NotImplementedError', [Exception], {
  						get __init__ () {return __get__ (this, function (self, message, error) {
  							Exception.__init__ (self, message, __kwargtrans__ ({error: error}));
  						});}
  					});
  					var IndexError = __class__ ('IndexError', [Exception], {
  						get __init__ () {return __get__ (this, function (self, message, error) {
  							Exception.__init__ (self, message, __kwargtrans__ ({error: error}));
  						});}
  					});
  					var AttributeError = __class__ ('AttributeError', [Exception], {
  						get __init__ () {return __get__ (this, function (self, message, error) {
  							Exception.__init__ (self, message, __kwargtrans__ ({error: error}));
  						});}
  					});
  					var Warning = __class__ ('Warning', [Exception], {
  					});
  					var UserWarning = __class__ ('UserWarning', [Warning], {
  					});
  					var DeprecationWarning = __class__ ('DeprecationWarning', [Warning], {
  					});
  					var RuntimeWarning = __class__ ('RuntimeWarning', [Warning], {
  					});
  					var __sort__ = function (iterable, key, reverse) {
  						if (typeof key == 'undefined' || (key != null && key .hasOwnProperty ("__kwargtrans__"))) {;
  							var key = null;
  						};
  						if (typeof reverse == 'undefined' || (reverse != null && reverse .hasOwnProperty ("__kwargtrans__"))) {;
  							var reverse = false;
  						};
  						if (arguments.length) {
  							var __ilastarg0__ = arguments.length - 1;
  							if (arguments [__ilastarg0__] && arguments [__ilastarg0__].hasOwnProperty ("__kwargtrans__")) {
  								var __allkwargs0__ = arguments [__ilastarg0__--];
  								for (var __attrib0__ in __allkwargs0__) {
  									switch (__attrib0__) {
  										case 'iterable': var iterable = __allkwargs0__ [__attrib0__]; break;
  										case 'key': var key = __allkwargs0__ [__attrib0__]; break;
  										case 'reverse': var reverse = __allkwargs0__ [__attrib0__]; break;
  									}
  								}
  							}
  						}
  						else {
  						}
  						if (key) {
  							iterable.sort ((function __lambda__ (a, b) {
  								if (arguments.length) {
  									var __ilastarg0__ = arguments.length - 1;
  									if (arguments [__ilastarg0__] && arguments [__ilastarg0__].hasOwnProperty ("__kwargtrans__")) {
  										var __allkwargs0__ = arguments [__ilastarg0__--];
  										for (var __attrib0__ in __allkwargs0__) {
  											switch (__attrib0__) {
  												case 'a': var a = __allkwargs0__ [__attrib0__]; break;
  												case 'b': var b = __allkwargs0__ [__attrib0__]; break;
  											}
  										}
  									}
  								}
  								else {
  								}
  								return (key (a) > key (b) ? 1 : -(1));
  							}));
  						}
  						else {
  							iterable.sort ();
  						}
  						if (reverse) {
  							iterable.reverse ();
  						}
  					};
  					var sorted = function (iterable, key, reverse) {
  						if (typeof key == 'undefined' || (key != null && key .hasOwnProperty ("__kwargtrans__"))) {;
  							var key = null;
  						};
  						if (typeof reverse == 'undefined' || (reverse != null && reverse .hasOwnProperty ("__kwargtrans__"))) {;
  							var reverse = false;
  						};
  						if (arguments.length) {
  							var __ilastarg0__ = arguments.length - 1;
  							if (arguments [__ilastarg0__] && arguments [__ilastarg0__].hasOwnProperty ("__kwargtrans__")) {
  								var __allkwargs0__ = arguments [__ilastarg0__--];
  								for (var __attrib0__ in __allkwargs0__) {
  									switch (__attrib0__) {
  										case 'iterable': var iterable = __allkwargs0__ [__attrib0__]; break;
  										case 'key': var key = __allkwargs0__ [__attrib0__]; break;
  										case 'reverse': var reverse = __allkwargs0__ [__attrib0__]; break;
  									}
  								}
  							}
  						}
  						else {
  						}
  						if (py_typeof (iterable) == dict) {
  							var result = copy (iterable.py_keys ());
  						}
  						else {
  							var result = copy (iterable);
  						}
  						__sort__ (result, key, reverse);
  						return result;
  					};
  					var map = function (func, iterable) {
  						return function () {
  							var __accu0__ = [];
  							var __iterable0__ = iterable;
  							for (var __index0__ = 0; __index0__ < __iterable0__.length; __index0__++) {
  								var item = __iterable0__ [__index0__];
  								__accu0__.append (func (item));
  							}
  							return __accu0__;
  						} ();
  					};
  					var filter = function (func, iterable) {
  						if (func == null) {
  							var func = bool;
  						}
  						return function () {
  							var __accu0__ = [];
  							var __iterable0__ = iterable;
  							for (var __index0__ = 0; __index0__ < __iterable0__.length; __index0__++) {
  								var item = __iterable0__ [__index0__];
  								if (func (item)) {
  									__accu0__.append (item);
  								}
  							}
  							return __accu0__;
  						} ();
  					};
  					var __Terminal__ = __class__ ('__Terminal__', [object], {
  						get __init__ () {return __get__ (this, function (self) {
  							self.buffer = '';
  							try {
  								self.element = document.getElementById ('__terminal__');
  							}
  							catch (__except0__) {
  								self.element = null;
  							}
  							if (self.element) {
  								self.element.style.overflowX = 'auto';
  								self.element.style.boxSizing = 'border-box';
  								self.element.style.padding = '5px';
  								self.element.innerHTML = '_';
  							}
  						});},
  						get print () {return __get__ (this, function (self) {
  							var sep = ' ';
  							var end = '\n';
  							if (arguments.length) {
  								var __ilastarg0__ = arguments.length - 1;
  								if (arguments [__ilastarg0__] && arguments [__ilastarg0__].hasOwnProperty ("__kwargtrans__")) {
  									var __allkwargs0__ = arguments [__ilastarg0__--];
  									for (var __attrib0__ in __allkwargs0__) {
  										switch (__attrib0__) {
  											case 'self': var self = __allkwargs0__ [__attrib0__]; break;
  											case 'sep': var sep = __allkwargs0__ [__attrib0__]; break;
  											case 'end': var end = __allkwargs0__ [__attrib0__]; break;
  										}
  									}
  								}
  								var args = tuple ([].slice.apply (arguments).slice (1, __ilastarg0__ + 1));
  							}
  							else {
  								var args = tuple ();
  							}
  							self.buffer = '{}{}{}'.format (self.buffer, sep.join (function () {
  								var __accu0__ = [];
  								var __iterable0__ = args;
  								for (var __index0__ = 0; __index0__ < __iterable0__.length; __index0__++) {
  									var arg = __iterable0__ [__index0__];
  									__accu0__.append (str (arg));
  								}
  								return __accu0__;
  							} ()), end).__getslice__ (-(4096), null, 1);
  							if (self.element) {
  								self.element.innerHTML = self.buffer.py_replace ('\n', '<br>');
  								self.element.scrollTop = self.element.scrollHeight;
  							}
  							else {
  								console.log (sep.join (function () {
  									var __accu0__ = [];
  									var __iterable0__ = args;
  									for (var __index0__ = 0; __index0__ < __iterable0__.length; __index0__++) {
  										var arg = __iterable0__ [__index0__];
  										__accu0__.append (str (arg));
  									}
  									return __accu0__;
  								} ()));
  							}
  						});},
  						get input () {return __get__ (this, function (self, question) {
  							if (arguments.length) {
  								var __ilastarg0__ = arguments.length - 1;
  								if (arguments [__ilastarg0__] && arguments [__ilastarg0__].hasOwnProperty ("__kwargtrans__")) {
  									var __allkwargs0__ = arguments [__ilastarg0__--];
  									for (var __attrib0__ in __allkwargs0__) {
  										switch (__attrib0__) {
  											case 'self': var self = __allkwargs0__ [__attrib0__]; break;
  											case 'question': var question = __allkwargs0__ [__attrib0__]; break;
  										}
  									}
  								}
  							}
  							else {
  							}
  							self.print ('{}'.format (question), __kwargtrans__ ({end: ''}));
  							var answer = window.prompt ('\n'.join (self.buffer.py_split ('\n').__getslice__ (-(16), null, 1)));
  							self.print (answer);
  							return answer;
  						});}
  					});
  					var __terminal__ = __Terminal__ ();
  					__pragma__ ('<all>')
  						__all__.AssertionError = AssertionError;
  						__all__.AttributeError = AttributeError;
  						__all__.DeprecationWarning = DeprecationWarning;
  						__all__.Exception = Exception;
  						__all__.IndexError = IndexError;
  						__all__.IterableError = IterableError;
  						__all__.KeyError = KeyError;
  						__all__.NotImplementedError = NotImplementedError;
  						__all__.RuntimeWarning = RuntimeWarning;
  						__all__.StopIteration = StopIteration;
  						__all__.UserWarning = UserWarning;
  						__all__.ValueError = ValueError;
  						__all__.Warning = Warning;
  						__all__.__Terminal__ = __Terminal__;
  						__all__.__sort__ = __sort__;
  						__all__.__terminal__ = __terminal__;
  						__all__.filter = filter;
  						__all__.map = map;
  						__all__.sorted = sorted;
  					__pragma__ ('</all>')
  				}
  			}
  		}
  	);
      var __call__ = function (/* <callee>, <this>, <params>* */) {   // Needed for __base__ and __standard__ if global 'opov' switch is on
          var args = [] .slice.apply (arguments);
          if (typeof args [0] == 'object' && '__call__' in args [0]) {        // Overloaded
              return args [0] .__call__ .apply (args [1], args.slice (2));
          }
          else {                                                              // Native
              return args [0] .apply (args [1], args.slice (2));
          }
      };
      __all__.__call__ = __call__;
  
      // Initialize non-nested modules __base__ and __standard__ and make its names available directly and via __all__
      // They can't do that itself, because they're regular Python modules
      // The compiler recognizes their names and generates them inline rather than nesting them
      // In this way it isn't needed to import them everywhere
  
      // __base__
  
      __nest__ (__all__, '', __init__ (__all__.org.transcrypt.__base__));
      var __envir__ = __all__.__envir__;
  
      // __standard__
  
      __nest__ (__all__, '', __init__ (__all__.org.transcrypt.__standard__));
  
      var Exception = __all__.Exception;
      var IterableError = __all__.IterableError;
      var StopIteration = __all__.StopIteration;
      var ValueError = __all__.ValueError;
      var KeyError = __all__.KeyError;
      var AssertionError = __all__.AssertionError;
      var NotImplementedError = __all__.NotImplementedError;
      var IndexError = __all__.IndexError;
      var AttributeError = __all__.AttributeError;
  
      // Warnings Exceptions
      var Warning = __all__.Warning;
      var UserWarning = __all__.UserWarning;
      var DeprecationWarning = __all__.DeprecationWarning;
      var RuntimeWarning = __all__.RuntimeWarning;
  
      var __sort__ = __all__.__sort__;
      var sorted = __all__.sorted;
  
      var map = __all__.map;
      var filter = __all__.filter;
  
      __all__.print = __all__.__terminal__.print;
      __all__.input = __all__.__terminal__.input;
  
      var __terminal__ = __all__.__terminal__;
      var print = __all__.print;
      var input = __all__.input;
  
      // Complete __envir__, that was created in __base__, for non-stub mode
      __envir__.executor_name = __envir__.transpiler_name;
  
      // Make make __main__ available in browser
      var __main__ = {__file__: ''};
      __all__.main = __main__;
  
      // Define current exception, there's at most one exception in the air at any time
      var __except__ = null;
      __all__.__except__ = __except__;
      
       // Creator of a marked dictionary, used to pass **kwargs parameter
      var __kwargtrans__ = function (anObject) {
          anObject.__kwargtrans__ = null; // Removable marker
          anObject.constructor = Object;
          return anObject;
      }
      __all__.__kwargtrans__ = __kwargtrans__;
  
      // 'Oneshot' dict promotor, used to enrich __all__ and help globals () return a true dict
      var __globals__ = function (anObject) {
          if (isinstance (anObject, dict)) {  // Don't attempt to promote (enrich) again, since it will make a copy
              return anObject;
          }
          else {
              return dict (anObject)
          }
      }
      __all__.__globals__ = __globals__
      
      // Partial implementation of super () .<methodName> (<params>)
      var __super__ = function (aClass, methodName) {        
          // Lean and fast, no C3 linearization, only call first implementation encountered
          // Will allow __super__ ('<methodName>') (self, <params>) rather than only <className>.<methodName> (self, <params>)
          
          for (var index = 0; index < aClass.__bases__.length; index++) {
              var base = aClass.__bases__ [index];
              if (methodName in base) {
                 return base [methodName];
              }
          }
  
          throw new Exception ('Superclass method not found');    // !!! Improve!
      }
      __all__.__super__ = __super__
          
      // Python property installer function, no member since that would bloat classes
      var property = function (getter, setter) {  // Returns a property descriptor rather than a property
          if (!setter) {  // ??? Make setter optional instead of dummy?
              setter = function () {};
          }
          return {get: function () {return getter (this)}, set: function (value) {setter (this, value)}, enumerable: true};
      }
      __all__.property = property;
      
      // Conditional JavaScript property installer function, prevents redefinition of properties if multiple Transcrypt apps are on one page
      var __setProperty__ = function (anObject, name, descriptor) {
          if (!anObject.hasOwnProperty (name)) {
              Object.defineProperty (anObject, name, descriptor);
          }
      }
      __all__.__setProperty__ = __setProperty__
      
      // Assert function, call to it only generated when compiling with --dassert option
      function assert (condition, message) {  // Message may be undefined
          if (!condition) {
              throw AssertionError (message, new Error ());
          }
      }
  
      __all__.assert = assert;
  
      var __merge__ = function (object0, object1) {
          var result = {};
          for (var attrib in object0) {
              result [attrib] = object0 [attrib];
          }
          for (var attrib in object1) {
              result [attrib] = object1 [attrib];
          }
          return result;
      };
      __all__.__merge__ = __merge__;
  
      // Manipulating attributes by name
      
      var dir = function (obj) {
          var aList = [];
          for (var aKey in obj) {
              aList.push (aKey);
          }
          aList.sort ();
          return aList;
      };
      __all__.dir = dir;
  
      var setattr = function (obj, name, value) {
          obj [name] = value;
      };
      __all__.setattr = setattr;
  
      var getattr = function (obj, name) {
          return obj [name];
      };
      __all__.getattr= getattr;
  
      var hasattr = function (obj, name) {
          try {
              return name in obj;
          }
          catch (exception) {
              return false;
          }
      };
      __all__.hasattr = hasattr;
  
      var delattr = function (obj, name) {
          delete obj [name];
      };
      __all__.delattr = (delattr);
  
      // The __in__ function, used to mimic Python's 'in' operator
      // In addition to CPython's semantics, the 'in' operator is also allowed to work on objects, avoiding a counterintuitive separation between Python dicts and JavaScript objects
      // In general many Transcrypt compound types feature a deliberate blend of Python and JavaScript facilities, facilitating efficient integration with JavaScript libraries
      // If only Python objects and Python dicts are dealt with in a certain context, the more pythonic 'hasattr' is preferred for the objects as opposed to 'in' for the dicts
      var __in__ = function (element, container) {
          if (py_typeof (container) == dict) {        // Currently only implemented as an augmented JavaScript object
              return container.hasOwnProperty (element);
          }
          else {                                      // Parameter 'element' itself is an array, string or a plain, non-dict JavaScript object
              return (
                  container.indexOf ?                 // If it has an indexOf
                  container.indexOf (element) > -1 :  // it's an array or a string,
                  container.hasOwnProperty (element)  // else it's a plain, non-dict JavaScript object
              );
          }
      };
      __all__.__in__ = __in__;
  
      // Find out if an attribute is special
      var __specialattrib__ = function (attrib) {
          return (attrib.startswith ('__') && attrib.endswith ('__')) || attrib == 'constructor' || attrib.startswith ('py_');
      };
      __all__.__specialattrib__ = __specialattrib__;
  
      // Len function for any object
      var len = function (anObject) {
          if (anObject) {
              var l = anObject.length;
              if (l == undefined) {
                  var result = 0;
                  for (var attrib in anObject) {
                      if (!__specialattrib__ (attrib)) {
                          result++;
                      }
                  }
                  return result;
              }
              else {
                  return l;
              }
          }
          else {
              return 0;
          }
      };
      __all__.len = len;
  
      // General conversions
  
      function __i__ (any) {  //  Conversion to iterable
          return py_typeof (any) == dict ? any.py_keys () : any;
      }
  
      function __t__ (any) {  // Conversion to truthyness, __ ([1, 2, 3]) returns [1, 2, 3], needed for nonempty selection: l = list1 or list2]
          return (['boolean', 'number'] .indexOf (typeof any) >= 0 || any instanceof Function || len (any)) ? any : false;
          // JavaScript functions have a length attribute, denoting the number of parameters
          // Python objects are JavaScript functions, but their length doesn't matter, only their existence
          // By the term 'any instanceof Function' we make sure that Python objects aren't rejected when their length equals zero
      }
      __all__.__t__ = __t__;
  
      var bool = function (any) {     // Always truly returns a bool, rather than something truthy or falsy
          return !!__t__ (any);
      };
      bool.__name__ = 'bool';         // So it can be used as a type with a name
      __all__.bool = bool;
  
      var float = function (any) {
          if (any == 'inf') {
              return Infinity;
          }
          else if (any == '-inf') {
              return -Infinity;
          }
          else if (isNaN (parseFloat (any))) {    // Call to parseFloat needed to exclude '', ' ' etc.
              throw ValueError (new Error ());
          }
          else {
              return +any;
          }
      };
      float.__name__ = 'float';
      __all__.float = float;
  
      var int = function (any) {
          return float (any) | 0
      };
      int.__name__ = 'int';
      __all__.int = int;
  
      var py_typeof = function (anObject) {
          var aType = typeof anObject;
          if (aType == 'object') {    // Directly trying '__class__ in anObject' turns out to wreck anObject in Chrome if its a primitive
              try {
                  return anObject.__class__;
              }
              catch (exception) {
                  return aType;
              }
          }
          else {
              return (    // Odly, the braces are required here
                  aType == 'boolean' ? bool :
                  aType == 'string' ? str :
                  aType == 'number' ? (anObject % 1 == 0 ? int : float) :
                  null
              );
          }
      };
      __all__.py_typeof = py_typeof;
  
      var isinstance = function (anObject, classinfo) {
          function isA (queryClass) {
              if (queryClass == classinfo) {
                  return true;
              }
              for (var index = 0; index < queryClass.__bases__.length; index++) {
                  if (isA (queryClass.__bases__ [index], classinfo)) {
                      return true;
                  }
              }
              return false;
          }
  
          if (classinfo instanceof Array) {   // Assume in most cases it isn't, then making it recursive rather than two functions saves a call
              for (var index = 0; index < classinfo.length; index++) {
                  var aClass = classinfo [index];
                  if (isinstance (anObject, aClass)) {
                      return true;
                  }
              }
              return false;
          }
  
          try {                   // Most frequent use case first
              return '__class__' in anObject ? isA (anObject.__class__) : anObject instanceof classinfo;
          }
          catch (exception) {     // Using isinstance on primitives assumed rare
              var aType = py_typeof (anObject);
              return aType == classinfo || (aType == bool && classinfo == int);
          }
      };
      __all__.isinstance = isinstance;
  
      var callable = function (anObject) {
          if ( typeof anObject == 'object' && '__call__' in anObject ) {
              return true;
          }
          else {
              return typeof anObject === 'function';
          }
      };
      __all__.callable = callable;
  
      // Repr function uses __repr__ method, then __str__, then toString
      var repr = function (anObject) {
          try {
              return anObject.__repr__ ();
          }
          catch (exception) {
              try {
                  return anObject.__str__ ();
              }
              catch (exception) { // anObject has no __repr__ and no __str__
                  try {
                      if (anObject == null) {
                          return 'None';
                      }
                      else if (anObject.constructor == Object) {
                          var result = '{';
                          var comma = false;
                          for (var attrib in anObject) {
                              if (!__specialattrib__ (attrib)) {
                                  if (attrib.isnumeric ()) {
                                      var attribRepr = attrib;                // If key can be interpreted as numerical, we make it numerical
                                  }                                           // So we accept that '1' is misrepresented as 1
                                  else {
                                      var attribRepr = '\'' + attrib + '\'';  // Alpha key in dict
                                  }
  
                                  if (comma) {
                                      result += ', ';
                                  }
                                  else {
                                      comma = true;
                                  }
                                  result += attribRepr + ': ' + repr (anObject [attrib]);
                              }
                          }
                          result += '}';
                          return result;
                      }
                      else {
                          return typeof anObject == 'boolean' ? anObject.toString () .capitalize () : anObject.toString ();
                      }
                  }
                  catch (exception) {
                      console.log ('ERROR: Could not evaluate repr (<object of type ' + typeof anObject + '>)');
                      console.log (exception);
                      return '???';
                  }
              }
          }
      };
      __all__.repr = repr;
  
      // Char from Unicode or ASCII
      var chr = function (charCode) {
          return String.fromCharCode (charCode);
      };
      __all__.chr = chr;
  
      // Unicode or ASCII from char
      var ord = function (aChar) {
          return aChar.charCodeAt (0);
      };
      __all__.ord = ord;
  
      // Maximum of n numbers
      var max = Math.max;
      __all__.max = max;
  
      // Minimum of n numbers
      var min = Math.min;
      __all__.min = min;
  
      // Absolute value
      var abs = Math.abs;
      __all__.abs = abs;
  
      // Bankers rounding
      var round = function (number, ndigits) {
          if (ndigits) {
              var scale = Math.pow (10, ndigits);
              number *= scale;
          }
  
          var rounded = Math.round (number);
          if (rounded - number == 0.5 && rounded % 2) {   // Has rounded up to odd, should have rounded down to even
              rounded -= 1;
          }
  
          if (ndigits) {
              rounded /= scale;
          }
  
          return rounded;
      };
      __all__.round = round;
  
      // BEGIN unified iterator model
  
      function __jsUsePyNext__ () {       // Add as 'next' method to make Python iterator JavaScript compatible
          try {
              var result = this.__next__ ();
              return {value: result, done: false};
          }
          catch (exception) {
              return {value: undefined, done: true};
          }
      }
  
      function __pyUseJsNext__ () {       // Add as '__next__' method to make JavaScript iterator Python compatible
          var result = this.next ();
          if (result.done) {
              throw StopIteration (new Error ());
          }
          else {
              return result.value;
          }
      }
  
      function py_iter (iterable) {                   // Alias for Python's iter function, produces a universal iterator / iterable, usable in Python and JavaScript
          if (typeof iterable == 'string' || '__iter__' in iterable) {    // JavaScript Array or string or Python iterable (string has no 'in')
              var result = iterable.__iter__ ();                          // Iterator has a __next__
              result.next = __jsUsePyNext__;                              // Give it a next
          }
          else if ('selector' in iterable) {                              // Assume it's a JQuery iterator
              var result = list (iterable) .__iter__ ();                  // Has a __next__
              result.next = __jsUsePyNext__;                              // Give it a next
          }
          else if ('next' in iterable) {                                  // It's a JavaScript iterator already,  maybe a generator, has a next and may have a __next__
              var result = iterable
              if (! ('__next__' in result)) {                             // If there's no danger of recursion
                  result.__next__ = __pyUseJsNext__;                      // Give it a __next__
              }
          }
          else if (Symbol.iterator in iterable) {                         // It's a JavaScript iterable such as a typed array, but not an iterator
              var result = iterable [Symbol.iterator] ();                 // Has a next
              result.__next__ = __pyUseJsNext__;                          // Give it a __next__
          }
          else {
              throw IterableError (new Error ()); // No iterator at all
          }
          result [Symbol.iterator] = function () {return result;};
          return result;
      }
  
      function py_next (iterator) {               // Called only in a Python context, could receive Python or JavaScript iterator
          try {                                   // Primarily assume Python iterator, for max speed
              var result = iterator.__next__ ();
          }
          catch (exception) {                     // JavaScript iterators are the exception here
              var result = iterator.next ();
              if (result.done) {
                  throw StopIteration (new Error ());
              }
              else {
                  return result.value;
              }
          }
          if (result == undefined) {
              throw StopIteration (new Error ());
          }
          else {
              return result;
          }
      }
  
      function __PyIterator__ (iterable) {
          this.iterable = iterable;
          this.index = 0;
      }
  
      __PyIterator__.prototype.__next__ = function () {
          if (this.index < this.iterable.length) {
              return this.iterable [this.index++];
          }
          else {
              throw StopIteration (new Error ());
          }
      };
  
      function __JsIterator__ (iterable) {
          this.iterable = iterable;
          this.index = 0;
      }
  
      __JsIterator__.prototype.next = function () {
          if (this.index < this.iterable.py_keys.length) {
              return {value: this.index++, done: false};
          }
          else {
              return {value: undefined, done: true};
          }
      };
  
      // END unified iterator model
  
      // Reversed function for arrays
      var py_reversed = function (iterable) {
          iterable = iterable.slice ();
          iterable.reverse ();
          return iterable;
      };
      __all__.py_reversed = py_reversed;
  
      // Zip method for arrays and strings
      var zip = function () {
          var args = [] .slice.call (arguments);
          for (var i = 0; i < args.length; i++) {
              if (typeof args [i] == 'string') {
                  args [i] = args [i] .split ('');
              }
              else if (!Array.isArray (args [i])) {
                  args [i] = Array.from (args [i]);
              }
          }
          var shortest = args.length == 0 ? [] : args.reduce (    // Find shortest array in arguments
              function (array0, array1) {
                  return array0.length < array1.length ? array0 : array1;
              }
          );
          return shortest.map (                   // Map each element of shortest array
              function (current, index) {         // To the result of this function
                  return args.map (               // Map each array in arguments
                      function (current) {        // To the result of this function
                          return current [index]; // Namely it's index't entry
                      }
                  );
              }
          );
      };
      __all__.zip = zip;
  
      // Range method, returning an array
      function range (start, stop, step) {
          if (stop == undefined) {
              // one param defined
              stop = start;
              start = 0;
          }
          if (step == undefined) {
              step = 1;
          }
          if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) {
              return [];
          }
          var result = [];
          for (var i = start; step > 0 ? i < stop : i > stop; i += step) {
              result.push(i);
          }
          return result;
      };
      __all__.range = range;
  
      // Any, all and sum
  
      function any (iterable) {
          for (var index = 0; index < iterable.length; index++) {
              if (bool (iterable [index])) {
                  return true;
              }
          }
          return false;
      }
      function all (iterable) {
          for (var index = 0; index < iterable.length; index++) {
              if (! bool (iterable [index])) {
                  return false;
              }
          }
          return true;
      }
      function sum (iterable) {
          var result = 0;
          for (var index = 0; index < iterable.length; index++) {
              result += iterable [index];
          }
          return result;
      }
  
      __all__.any = any;
      __all__.all = all;
      __all__.sum = sum;
  
      // Enumerate method, returning a zipped list
      function enumerate (iterable) {
          return zip (range (len (iterable)), iterable);
      }
      __all__.enumerate = enumerate;
  
      // Shallow and deepcopy
  
      function copy (anObject) {
          if (anObject == null || typeof anObject == "object") {
              return anObject;
          }
          else {
              var result = {};
              for (var attrib in obj) {
                  if (anObject.hasOwnProperty (attrib)) {
                      result [attrib] = anObject [attrib];
                  }
              }
              return result;
          }
      }
      __all__.copy = copy;
  
      function deepcopy (anObject) {
          if (anObject == null || typeof anObject == "object") {
              return anObject;
          }
          else {
              var result = {};
              for (var attrib in obj) {
                  if (anObject.hasOwnProperty (attrib)) {
                      result [attrib] = deepcopy (anObject [attrib]);
                  }
              }
              return result;
          }
      }
      __all__.deepcopy = deepcopy;
  
      // List extensions to Array
  
      function list (iterable) {                                      // All such creators should be callable without new
          var instance = iterable ? [] .slice.apply (iterable) : [];  // Spread iterable, n.b. array.slice (), so array before dot
          // Sort is the normal JavaScript sort, Python sort is a non-member function
          return instance;
      }
      __all__.list = list;
      Array.prototype.__class__ = list;   // All arrays are lists (not only if constructed by the list ctor), unless constructed otherwise
      list.__name__ = 'list';
  
      /*
      Array.from = function (iterator) { // !!! remove
          result = [];
          for (item of iterator) {
              result.push (item);
          }
          return result;
      }
      */
  
      Array.prototype.__iter__ = function () {return new __PyIterator__ (this);};
  
      Array.prototype.__getslice__ = function (start, stop, step) {
          if (start < 0) {
              start = this.length + start;
          }
  
          if (stop == null) {
              stop = this.length;
          }
          else if (stop < 0) {
              stop = this.length + stop;
          }
          else if (stop > this.length) {
              stop = this.length;
          }
  
          var result = list ([]);
          for (var index = start; index < stop; index += step) {
              result.push (this [index]);
          }
  
          return result;
      };
  
      Array.prototype.__setslice__ = function (start, stop, step, source) {
          if (start < 0) {
              start = this.length + start;
          }
  
          if (stop == null) {
              stop = this.length;
          }
          else if (stop < 0) {
              stop = this.length + stop;
          }
  
          if (step == null) { // Assign to 'ordinary' slice, replace subsequence
              Array.prototype.splice.apply (this, [start, stop - start] .concat (source));
          }
          else {              // Assign to extended slice, replace designated items one by one
              var sourceIndex = 0;
              for (var targetIndex = start; targetIndex < stop; targetIndex += step) {
                  this [targetIndex] = source [sourceIndex++];
              }
          }
      };
  
      Array.prototype.__repr__ = function () {
          if (this.__class__ == set && !this.length) {
              return 'set()';
          }
  
          var result = !this.__class__ || this.__class__ == list ? '[' : this.__class__ == tuple ? '(' : '{';
  
          for (var index = 0; index < this.length; index++) {
              if (index) {
                  result += ', ';
              }
              result += repr (this [index]);
          }
  
          if (this.__class__ == tuple && this.length == 1) {
              result += ',';
          }
  
          result += !this.__class__ || this.__class__ == list ? ']' : this.__class__ == tuple ? ')' : '}';;
          return result;
      };
  
      Array.prototype.__str__ = Array.prototype.__repr__;
  
      Array.prototype.append = function (element) {
          this.push (element);
      };
  
      Array.prototype.clear = function () {
          this.length = 0;
      };
  
      Array.prototype.extend = function (aList) {
          this.push.apply (this, aList);
      };
  
      Array.prototype.insert = function (index, element) {
          this.splice (index, 0, element);
      };
  
      Array.prototype.remove = function (element) {
          var index = this.indexOf (element);
          if (index == -1) {
              throw ValueError (new Error ());
          }
          this.splice (index, 1);
      };
  
      Array.prototype.index = function (element) {
          return this.indexOf (element);
      };
  
      Array.prototype.py_pop = function (index) {
          if (index == undefined) {
              return this.pop ();  // Remove last element
          }
          else {
              return this.splice (index, 1) [0];
          }
      };
  
      Array.prototype.py_sort = function () {
          __sort__.apply  (null, [this].concat ([] .slice.apply (arguments)));    // Can't work directly with arguments
          // Python params: (iterable, key = None, reverse = False)
          // py_sort is called with the Transcrypt kwargs mechanism, and just passes the params on to __sort__
          // __sort__ is def'ed with the Transcrypt kwargs mechanism
      };
  
      Array.prototype.__add__ = function (aList) {
          return list (this.concat (aList));
      };
  
      Array.prototype.__mul__ = function (scalar) {
          var result = this;
          for (var i = 1; i < scalar; i++) {
              result = result.concat (this);
          }
          return result;
      };
  
      Array.prototype.__rmul__ = Array.prototype.__mul__;
  
      // Tuple extensions to Array
  
      function tuple (iterable) {
          var instance = iterable ? [] .slice.apply (iterable) : [];
          instance.__class__ = tuple; // Not all arrays are tuples
          return instance;
      }
      __all__.tuple = tuple;
      tuple.__name__ = 'tuple';
  
      // Set extensions to Array
      // N.B. Since sets are unordered, set operations will occasionally alter the 'this' array by sorting it
  
      function set (iterable) {
          var instance = [];
          if (iterable) {
              for (var index = 0; index < iterable.length; index++) {
                  instance.add (iterable [index]);
              }
  
  
          }
          instance.__class__ = set;   // Not all arrays are sets
          return instance;
      }
      __all__.set = set;
      set.__name__ = 'set';
  
      Array.prototype.__bindexOf__ = function (element) { // Used to turn O (n^2) into O (n log n)
      // Since sorting is lex, compare has to be lex. This also allows for mixed lists
  
          element += '';
  
          var mindex = 0;
          var maxdex = this.length - 1;
  
          while (mindex <= maxdex) {
              var index = (mindex + maxdex) / 2 | 0;
              var middle = this [index] + '';
  
              if (middle < element) {
                  mindex = index + 1;
              }
              else if (middle > element) {
                  maxdex = index - 1;
              }
              else {
                  return index;
              }
          }
  
          return -1;
      };
  
      Array.prototype.add = function (element) {
          if (this.indexOf (element) == -1) { // Avoid duplicates in set
              this.push (element);
          }
      };
  
      Array.prototype.discard = function (element) {
          var index = this.indexOf (element);
          if (index != -1) {
              this.splice (index, 1);
          }
      };
  
      Array.prototype.isdisjoint = function (other) {
          this.sort ();
          for (var i = 0; i < other.length; i++) {
              if (this.__bindexOf__ (other [i]) != -1) {
                  return false;
              }
          }
          return true;
      };
  
      Array.prototype.issuperset = function (other) {
          this.sort ();
          for (var i = 0; i < other.length; i++) {
              if (this.__bindexOf__ (other [i]) == -1) {
                  return false;
              }
          }
          return true;
      };
  
      Array.prototype.issubset = function (other) {
          return set (other.slice ()) .issuperset (this); // Sort copy of 'other', not 'other' itself, since it may be an ordered sequence
      };
  
      Array.prototype.union = function (other) {
          var result = set (this.slice () .sort ());
          for (var i = 0; i < other.length; i++) {
              if (result.__bindexOf__ (other [i]) == -1) {
                  result.push (other [i]);
              }
          }
          return result;
      };
  
      Array.prototype.intersection = function (other) {
          this.sort ();
          var result = set ();
          for (var i = 0; i < other.length; i++) {
              if (this.__bindexOf__ (other [i]) != -1) {
                  result.push (other [i]);
              }
          }
          return result;
      };
  
      Array.prototype.difference = function (other) {
          var sother = set (other.slice () .sort ());
          var result = set ();
          for (var i = 0; i < this.length; i++) {
              if (sother.__bindexOf__ (this [i]) == -1) {
                  result.push (this [i]);
              }
          }
          return result;
      };
  
      Array.prototype.symmetric_difference = function (other) {
          return this.union (other) .difference (this.intersection (other));
      };
  
      Array.prototype.py_update = function () {   // O (n)
          var updated = [] .concat.apply (this.slice (), arguments) .sort ();
          this.clear ();
          for (var i = 0; i < updated.length; i++) {
              if (updated [i] != updated [i - 1]) {
                  this.push (updated [i]);
              }
          }
      };
  
      Array.prototype.__eq__ = function (other) { // Also used for list
          if (this.length != other.length) {
              return false;
          }
          if (this.__class__ == set) {
              this.sort ();
              other.sort ();
          }
          for (var i = 0; i < this.length; i++) {
              if (this [i] != other [i]) {
                  return false;
              }
          }
          return true;
      };
  
      Array.prototype.__ne__ = function (other) { // Also used for list
          return !this.__eq__ (other);
      };
  
      Array.prototype.__le__ = function (other) {
          return this.issubset (other);
      };
  
      Array.prototype.__ge__ = function (other) {
          return this.issuperset (other);
      };
  
      Array.prototype.__lt__ = function (other) {
          return this.issubset (other) && !this.issuperset (other);
      };
  
      Array.prototype.__gt__ = function (other) {
          return this.issuperset (other) && !this.issubset (other);
      };
  
      // String extensions
  
      function str (stringable) {
          try {
              return stringable.__str__ ();
          }
          catch (exception) {
              try {
                  return repr (stringable);
              }
              catch (exception) {
                  return String (stringable); // No new, so no permanent String object but a primitive in a temporary 'just in time' wrapper
              }
          }
      };
      __all__.str = str;
  
      String.prototype.__class__ = str;   // All strings are str
      str.__name__ = 'str';
  
      String.prototype.__iter__ = function () {new __PyIterator__ (this);};
  
      String.prototype.__repr__ = function () {
          return (this.indexOf ('\'') == -1 ? '\'' + this + '\'' : '"' + this + '"') .py_replace ('\t', '\\t') .py_replace ('\n', '\\n');
      };
  
      String.prototype.__str__ = function () {
          return this;
      };
  
      String.prototype.capitalize = function () {
          return this.charAt (0).toUpperCase () + this.slice (1);
      };
  
      String.prototype.endswith = function (suffix) {
          return suffix == '' || this.slice (-suffix.length) == suffix;
      };
  
      String.prototype.find  = function (sub, start) {
          return this.indexOf (sub, start);
      };
  
      String.prototype.__getslice__ = function (start, stop, step) {
          if (start < 0) {
              start = this.length + start;
          }
  
          if (stop == null) {
              stop = this.length;
          }
          else if (stop < 0) {
              stop = this.length + stop;
          }
  
          var result = '';
          if (step == 1) {
              result = this.substring (start, stop);
          }
          else {
              for (var index = start; index < stop; index += step) {
                  result = result.concat (this.charAt(index));
              }
          }
          return result;
      }
  
      // Since it's worthwhile for the 'format' function to be able to deal with *args, it is defined as a property
      // __get__ will produce a bound function if there's something before the dot
      // Since a call using *args is compiled to e.g. <object>.<function>.apply (null, args), the function has to be bound already
      // Otherwise it will never be, because of the null argument
      // Using 'this' rather than 'null' contradicts the requirement to be able to pass bound functions around
      // The object 'before the dot' won't be available at call time in that case, unless implicitly via the function bound to it
      // While for Python methods this mechanism is generated by the compiler, for JavaScript methods it has to be provided manually
      // Call memoizing is unattractive here, since every string would then have to hold a reference to a bound format method
      __setProperty__ (String.prototype, 'format', {
          get: function () {return __get__ (this, function (self) {
              var args = tuple ([] .slice.apply (arguments).slice (1));
              var autoIndex = 0;
              return self.replace (/\{(\w*)\}/g, function (match, key) {
                  if (key == '') {
                      key = autoIndex++;
                  }
                  if (key == +key) {  // So key is numerical
                      return args [key] == undefined ? match : str (args [key]);
                  }
                  else {              // Key is a string
                      for (var index = 0; index < args.length; index++) {
                          // Find first 'dict' that has that key and the right field
                          if (typeof args [index] == 'object' && args [index][key] != undefined) {
                              return str (args [index][key]); // Return that field field
                          }
                      }
                      return match;
                  }
              });
          });},
          enumerable: true
      });
  
      String.prototype.isalnum = function () {
          return /^[0-9a-zA-Z]{1,}$/.test(this)
      }
  
      String.prototype.isalpha = function () {
          return /^[a-zA-Z]{1,}$/.test(this)
      }
  
      String.prototype.isdecimal = function () {
          return /^[0-9]{1,}$/.test(this)
      }
  
      String.prototype.isdigit = function () {
          return this.isdecimal()
      }
  
      String.prototype.islower = function () {
          return /^[a-z]{1,}$/.test(this)
      }
  
      String.prototype.isupper = function () {
          return /^[A-Z]{1,}$/.test(this)
      }
  
      String.prototype.isspace = function () {
          return /^[\s]{1,}$/.test(this)
      }
  
      String.prototype.isnumeric = function () {
          return !isNaN (parseFloat (this)) && isFinite (this);
      };
  
      String.prototype.join = function (strings) {
          return strings.join (this);
      };
  
      String.prototype.lower = function () {
          return this.toLowerCase ();
      };
  
      String.prototype.py_replace = function (old, aNew, maxreplace) {
          return this.split (old, maxreplace) .join (aNew);
      };
  
      String.prototype.lstrip = function () {
          return this.replace (/^\s*/g, '');
      };
  
      String.prototype.rfind = function (sub, start) {
          return this.lastIndexOf (sub, start);
      };
  
      String.prototype.rsplit = function (sep, maxsplit) {    // Combination of general whitespace sep and positive maxsplit neither supported nor checked, expensive and rare
          if (sep == undefined || sep == null) {
              sep = /\s+/;
              var stripped = this.strip ();
          }
          else {
              var stripped = this;
          }
  
          if (maxsplit == undefined || maxsplit == -1) {
              return stripped.split (sep);
          }
          else {
              var result = stripped.split (sep);
              if (maxsplit < result.length) {
                  var maxrsplit = result.length - maxsplit;
                  return [result.slice (0, maxrsplit) .join (sep)] .concat (result.slice (maxrsplit));
              }
              else {
                  return result;
              }
          }
      };
  
      String.prototype.rstrip = function () {
          return this.replace (/\s*$/g, '');
      };
  
      String.prototype.py_split = function (sep, maxsplit) {  // Combination of general whitespace sep and positive maxsplit neither supported nor checked, expensive and rare
          if (sep == undefined || sep == null) {
              sep = /\s+/;
              var stripped = this.strip ();
          }
          else {
              var stripped = this;
          }
  
          if (maxsplit == undefined || maxsplit == -1) {
              return stripped.split (sep);
          }
          else {
              var result = stripped.split (sep);
              if (maxsplit < result.length) {
                  return result.slice (0, maxsplit).concat ([result.slice (maxsplit).join (sep)]);
              }
              else {
                  return result;
              }
          }
      };
  
      String.prototype.startswith = function (prefix) {
          return this.indexOf (prefix) == 0;
      };
  
      String.prototype.strip = function () {
          return this.trim ();
      };
  
      String.prototype.upper = function () {
          return this.toUpperCase ();
      };
  
      String.prototype.__mul__ = function (scalar) {
          var result = this;
          for (var i = 1; i < scalar; i++) {
              result = result + this;
          }
          return result;
      };
  
      String.prototype.__rmul__ = String.prototype.__mul__;
  
      // Dict extensions to object
  
      function __keys__ () {
          var keys = [];
          for (var attrib in this) {
              if (!__specialattrib__ (attrib)) {
                  keys.push (attrib);
              }
          }
          return keys;
      }
  
      function __items__ () {
          var items = [];
          for (var attrib in this) {
              if (!__specialattrib__ (attrib)) {
                  items.push ([attrib, this [attrib]]);
              }
          }
          return items;
      }
  
      function __del__ (key) {
          delete this [key];
      }
  
      function __clear__ () {
          for (var attrib in this) {
              delete this [attrib];
          }
      }
  
      function __getdefault__ (aKey, aDefault) {  // Each Python object already has a function called __get__, so we call this one __getdefault__
          var result = this [aKey];
          return result == undefined ? (aDefault == undefined ? null : aDefault) : result;
      }
  
      function __setdefault__ (aKey, aDefault) {
          var result = this [aKey];
          if (result != undefined) {
              return result;
          }
          var val = aDefault == undefined ? null : aDefault;
          this [aKey] = val;
          return val;
      }
  
      function __pop__ (aKey, aDefault) {
          var result = this [aKey];
          if (result != undefined) {
              delete this [aKey];
              return result;
          } else {
              // Identify check because user could pass None
              if ( aDefault === undefined ) {
                  throw KeyError (aKey, new Error());
              }
          }
          return aDefault;
      }
      
      function __popitem__ () {
          var aKey = Object.keys (this) [0];
          if (aKey == null) {
              throw KeyError (aKey, new Error ());
          }
          var result = tuple ([aKey, this [aKey]]);
          delete this [aKey];
          return result;
      }
      
      function __update__ (aDict) {
          for (var aKey in aDict) {
              this [aKey] = aDict [aKey];
          }
      }
      
      function __values__ () {
          var values = [];
          for (var attrib in this) {
              if (!__specialattrib__ (attrib)) {
                  values.push (this [attrib]);
              }
          }
          return values;
  
      }
      
      function __dgetitem__ (aKey) {
          return this [aKey];
      }
      
      function __dsetitem__ (aKey, aValue) {
          this [aKey] = aValue;
      }
  
      function dict (objectOrPairs) {
          var instance = {};
          if (!objectOrPairs || objectOrPairs instanceof Array) { // It's undefined or an array of pairs
              if (objectOrPairs) {
                  for (var index = 0; index < objectOrPairs.length; index++) {
                      var pair = objectOrPairs [index];
                      if ( !(pair instanceof Array) || pair.length != 2) {
                          throw ValueError(
                              "dict update sequence element #" + index +
                              " has length " + pair.length +
                              "; 2 is required", new Error());
                      }
                      var key = pair [0];
                      var val = pair [1];
                      if (!(objectOrPairs instanceof Array) && objectOrPairs instanceof Object) {
                           // User can potentially pass in an object
                           // that has a hierarchy of objects. This
                           // checks to make sure that these objects
                           // get converted to dict objects instead of
                           // leaving them as js objects.
                           
                           if (!isinstance (objectOrPairs, dict)) {
                               val = dict (val);
                           }
                      }
                      instance [key] = val;
                  }
              }
          }
          else {
              if (isinstance (objectOrPairs, dict)) {
                  // Passed object is a dict already so we need to be a little careful
                  // N.B. - this is a shallow copy per python std - so
                  // it is assumed that children have already become
                  // python objects at some point.
                  
                  var aKeys = objectOrPairs.py_keys ();
                  for (var index = 0; index < aKeys.length; index++ ) {
                      var key = aKeys [index];
                      instance [key] = objectOrPairs [key];
                  }
              } else if (objectOrPairs instanceof Object) {
                  // Passed object is a JavaScript object but not yet a dict, don't copy it
                  instance = objectOrPairs;
              } else {
                  // We have already covered Array so this indicates
                  // that the passed object is not a js object - i.e.
                  // it is an int or a string, which is invalid.
                  
                  throw ValueError ("Invalid type of object for dict creation", new Error ());
              }
          }
  
          // Trancrypt interprets e.g. {aKey: 'aValue'} as a Python dict literal rather than a JavaScript object literal
          // So dict literals rather than bare Object literals will be passed to JavaScript libraries
          // Some JavaScript libraries call all enumerable callable properties of an object that's passed to them
          // So the properties of a dict should be non-enumerable
          __setProperty__ (instance, '__class__', {value: dict, enumerable: false, writable: true});
          __setProperty__ (instance, 'py_keys', {value: __keys__, enumerable: false});
          __setProperty__ (instance, '__iter__', {value: function () {new __PyIterator__ (this.py_keys ());}, enumerable: false});
          __setProperty__ (instance, Symbol.iterator, {value: function () {new __JsIterator__ (this.py_keys ());}, enumerable: false});
          __setProperty__ (instance, 'py_items', {value: __items__, enumerable: false});
          __setProperty__ (instance, 'py_del', {value: __del__, enumerable: false});
          __setProperty__ (instance, 'py_clear', {value: __clear__, enumerable: false});
          __setProperty__ (instance, 'py_get', {value: __getdefault__, enumerable: false});
          __setProperty__ (instance, 'py_setdefault', {value: __setdefault__, enumerable: false});
          __setProperty__ (instance, 'py_pop', {value: __pop__, enumerable: false});
          __setProperty__ (instance, 'py_popitem', {value: __popitem__, enumerable: false});
          __setProperty__ (instance, 'py_update', {value: __update__, enumerable: false});
          __setProperty__ (instance, 'py_values', {value: __values__, enumerable: false});
          __setProperty__ (instance, '__getitem__', {value: __dgetitem__, enumerable: false});    // Needed since compound keys necessarily
          __setProperty__ (instance, '__setitem__', {value: __dsetitem__, enumerable: false});    // trigger overloading to deal with slices
          return instance;
      }
  
      __all__.dict = dict;
      dict.__name__ = 'dict';
      
      // Docstring setter
  
      function __setdoc__ (docString) {
          this.__doc__ = docString;
          return this;
      }
  
      // Python classes, methods and functions are all translated to JavaScript functions
      __setProperty__ (Function.prototype, '__setdoc__', {value: __setdoc__, enumerable: false});
  
      // General operator overloading, only the ones that make most sense in matrix and complex operations
  
      var __neg__ = function (a) {
          if (typeof a == 'object' && '__neg__' in a) {
              return a.__neg__ ();
          }
          else {
              return -a;
          }
      };
      __all__.__neg__ = __neg__;
  
      var __matmul__ = function (a, b) {
          return a.__matmul__ (b);
      };
      __all__.__matmul__ = __matmul__;
  
      var __pow__ = function (a, b) {
          if (typeof a == 'object' && '__pow__' in a) {
              return a.__pow__ (b);
          }
          else if (typeof b == 'object' && '__rpow__' in b) {
              return b.__rpow__ (a);
          }
          else {
              return Math.pow (a, b);
          }
      };
      __all__.pow = __pow__;
  
      var __jsmod__ = function (a, b) {
          if (typeof a == 'object' && '__mod__' in a) {
              return a.__mod__ (b);
          }
          else if (typeof b == 'object' && '__rpow__' in b) {
              return b.__rmod__ (a);
          }
          else {
              return a % b;
          }
      };
      __all__.__jsmod__ = __jsmod__;
      
      var __mod__ = function (a, b) {
          if (typeof a == 'object' && '__mod__' in a) {
              return a.__mod__ (b);
          }
          else if (typeof b == 'object' && '__rpow__' in b) {
              return b.__rmod__ (a);
          }
          else {
              return ((a % b) + b) % b;
          }
      };
      __all__.mod = __mod__;
  
      // Overloaded binary arithmetic
      
      var __mul__ = function (a, b) {
          if (typeof a == 'object' && '__mul__' in a) {
              return a.__mul__ (b);
          }
          else if (typeof b == 'object' && '__rmul__' in b) {
              return b.__rmul__ (a);
          }
          else if (typeof a == 'string') {
              return a.__mul__ (b);
          }
          else if (typeof b == 'string') {
              return b.__rmul__ (a);
          }
          else {
              return a * b;
          }
      };
      __all__.__mul__ = __mul__;
  
      var __div__ = function (a, b) {
          if (typeof a == 'object' && '__div__' in a) {
              return a.__div__ (b);
          }
          else if (typeof b == 'object' && '__rdiv__' in b) {
              return b.__rdiv__ (a);
          }
          else {
              return a / b;
          }
      };
      __all__.__div__ = __div__;
  
      var __add__ = function (a, b) {
          if (typeof a == 'object' && '__add__' in a) {
              return a.__add__ (b);
          }
          else if (typeof b == 'object' && '__radd__' in b) {
              return b.__radd__ (a);
          }
          else {
              return a + b;
          }
      };
      __all__.__add__ = __add__;
  
      var __sub__ = function (a, b) {
          if (typeof a == 'object' && '__sub__' in a) {
              return a.__sub__ (b);
          }
          else if (typeof b == 'object' && '__rsub__' in b) {
              return b.__rsub__ (a);
          }
          else {
              return a - b;
          }
      };
      __all__.__sub__ = __sub__;
  
      // Overloaded binary bitwise
      
      var __lshift__ = function (a, b) {
          if (typeof a == 'object' && '__lshift__' in a) {
              return a.__lshift__ (b);
          }
          else if (typeof b == 'object' && '__rlshift__' in b) {
              return b.__rlshift__ (a);
          }
          else {
              return a << b;
          }
      };
      __all__.__lshift__ = __lshift__;
  
      var __rshift__ = function (a, b) {
          if (typeof a == 'object' && '__rshift__' in a) {
              return a.__rshift__ (b);
          }
          else if (typeof b == 'object' && '__rrshift__' in b) {
              return b.__rrshift__ (a);
          }
          else {
              return a >> b;
          }
      };
      __all__.__rshift__ = __rshift__;
  
      var __or__ = function (a, b) {
          if (typeof a == 'object' && '__or__' in a) {
              return a.__or__ (b);
          }
          else if (typeof b == 'object' && '__ror__' in b) {
              return b.__ror__ (a);
          }
          else {
              return a | b;
          }
      };
      __all__.__or__ = __or__;
  
      var __xor__ = function (a, b) {
          if (typeof a == 'object' && '__xor__' in a) {
              return a.__xor__ (b);
          }
          else if (typeof b == 'object' && '__rxor__' in b) {
              return b.__rxor__ (a);
          }
          else {
              return a ^ b;
          }
      };
      __all__.__xor__ = __xor__;
  
      var __and__ = function (a, b) {
          if (typeof a == 'object' && '__and__' in a) {
              return a.__and__ (b);
          }
          else if (typeof b == 'object' && '__rand__' in b) {
              return b.__rand__ (a);
          }
          else {
              return a & b;
          }
      };
      __all__.__and__ = __and__;    
          
      // Overloaded binary compare
      
      var __eq__ = function (a, b) {
          if (typeof a == 'object' && '__eq__' in a) {
              return a.__eq__ (b);
          }
          else {
              return a == b;
          }
      };
      __all__.__eq__ = __eq__;
  
      var __ne__ = function (a, b) {
          if (typeof a == 'object' && '__ne__' in a) {
              return a.__ne__ (b);
          }
          else {
              return a != b
          }
      };
      __all__.__ne__ = __ne__;
  
      var __lt__ = function (a, b) {
          if (typeof a == 'object' && '__lt__' in a) {
              return a.__lt__ (b);
          }
          else {
              return a < b;
          }
      };
      __all__.__lt__ = __lt__;
  
      var __le__ = function (a, b) {
          if (typeof a == 'object' && '__le__' in a) {
              return a.__le__ (b);
          }
          else {
              return a <= b;
          }
      };
      __all__.__le__ = __le__;
  
      var __gt__ = function (a, b) {
          if (typeof a == 'object' && '__gt__' in a) {
              return a.__gt__ (b);
          }
          else {
              return a > b;
          }
      };
      __all__.__gt__ = __gt__;
  
      var __ge__ = function (a, b) {
          if (typeof a == 'object' && '__ge__' in a) {
              return a.__ge__ (b);
          }
          else {
              return a >= b;
          }
      };
      __all__.__ge__ = __ge__;
      
      // Overloaded augmented general
      
      var __imatmul__ = function (a, b) {
          if ('__imatmul__' in a) {
              return a.__imatmul__ (b);
          }
          else {
              return a.__matmul__ (b);
          }
      };
      __all__.__imatmul__ = __imatmul__;
  
      var __ipow__ = function (a, b) {
          if (typeof a == 'object' && '__pow__' in a) {
              return a.__ipow__ (b);
          }
          else if (typeof a == 'object' && '__ipow__' in a) {
              return a.__pow__ (b);
          }
          else if (typeof b == 'object' && '__rpow__' in b) {
              return b.__rpow__ (a);
          }
          else {
              return Math.pow (a, b);
          }
      };
      __all__.ipow = __ipow__;
  
      var __ijsmod__ = function (a, b) {
          if (typeof a == 'object' && '__imod__' in a) {
              return a.__ismod__ (b);
          }
          else if (typeof a == 'object' && '__mod__' in a) {
              return a.__mod__ (b);
          }
          else if (typeof b == 'object' && '__rpow__' in b) {
              return b.__rmod__ (a);
          }
          else {
              return a % b;
          }
      };
      __all__.ijsmod__ = __ijsmod__;
      
      var __imod__ = function (a, b) {
          if (typeof a == 'object' && '__imod__' in a) {
              return a.__imod__ (b);
          }
          else if (typeof a == 'object' && '__mod__' in a) {
              return a.__mod__ (b);
          }
          else if (typeof b == 'object' && '__rpow__' in b) {
              return b.__rmod__ (a);
          }
          else {
              return ((a % b) + b) % b;
          }
      };
      __all__.imod = __imod__;
      
      // Overloaded augmented arithmetic
      
      var __imul__ = function (a, b) {
          if (typeof a == 'object' && '__imul__' in a) {
              return a.__imul__ (b);
          }
          else if (typeof a == 'object' && '__mul__' in a) {
              return a = a.__mul__ (b);
          }
          else if (typeof b == 'object' && '__rmul__' in b) {
              return a = b.__rmul__ (a);
          }
          else if (typeof a == 'string') {
              return a = a.__mul__ (b);
          }
          else if (typeof b == 'string') {
              return a = b.__rmul__ (a);
          }
          else {
              return a *= b;
          }
      };
      __all__.__imul__ = __imul__;
  
      var __idiv__ = function (a, b) {
          if (typeof a == 'object' && '__idiv__' in a) {
              return a.__idiv__ (b);
          }
          else if (typeof a == 'object' && '__div__' in a) {
              return a = a.__div__ (b);
          }
          else if (typeof b == 'object' && '__rdiv__' in b) {
              return a = b.__rdiv__ (a);
          }
          else {
              return a /= b;
          }
      };
      __all__.__idiv__ = __idiv__;
  
      var __iadd__ = function (a, b) {
          if (typeof a == 'object' && '__iadd__' in a) {
              return a.__iadd__ (b);
          }
          else if (typeof a == 'object' && '__add__' in a) {
              return a = a.__add__ (b);
          }
          else if (typeof b == 'object' && '__radd__' in b) {
              return a = b.__radd__ (a);
          }
          else {
              return a += b;
          }
      };
      __all__.__iadd__ = __iadd__;
  
      var __isub__ = function (a, b) {
          if (typeof a == 'object' && '__isub__' in a) {
              return a.__isub__ (b);
          }
          else if (typeof a == 'object' && '__sub__' in a) {
              return a = a.__sub__ (b);
          }
          else if (typeof b == 'object' && '__rsub__' in b) {
              return a = b.__rsub__ (a);
          }
          else {
              return a -= b;
          }
      };
      __all__.__isub__ = __isub__;
  
      // Overloaded augmented bitwise
      
      var __ilshift__ = function (a, b) {
          if (typeof a == 'object' && '__ilshift__' in a) {
              return a.__ilshift__ (b);
          }
          else if (typeof a == 'object' && '__lshift__' in a) {
              return a = a.__lshift__ (b);
          }
          else if (typeof b == 'object' && '__rlshift__' in b) {
              return a = b.__rlshift__ (a);
          }
          else {
              return a <<= b;
          }
      };
      __all__.__ilshift__ = __ilshift__;
  
      var __irshift__ = function (a, b) {
          if (typeof a == 'object' && '__irshift__' in a) {
              return a.__irshift__ (b);
          }
          else if (typeof a == 'object' && '__rshift__' in a) {
              return a = a.__rshift__ (b);
          }
          else if (typeof b == 'object' && '__rrshift__' in b) {
              return a = b.__rrshift__ (a);
          }
          else {
              return a >>= b;
          }
      };
      __all__.__irshift__ = __irshift__;
  
      var __ior__ = function (a, b) {
          if (typeof a == 'object' && '__ior__' in a) {
              return a.__ior__ (b);
          }
          else if (typeof a == 'object' && '__or__' in a) {
              return a = a.__or__ (b);
          }
          else if (typeof b == 'object' && '__ror__' in b) {
              return a = b.__ror__ (a);
          }
          else {
              return a |= b;
          }
      };
      __all__.__ior__ = __ior__;
  
      var __ixor__ = function (a, b) {
          if (typeof a == 'object' && '__ixor__' in a) {
              return a.__ixor__ (b);
          }
          else if (typeof a == 'object' && '__xor__' in a) {
              return a = a.__xor__ (b);
          }
          else if (typeof b == 'object' && '__rxor__' in b) {
              return a = b.__rxor__ (a);
          }
          else {
              return a ^= b;
          }
      };
      __all__.__ixor__ = __ixor__;
  
      var __iand__ = function (a, b) {
          if (typeof a == 'object' && '__iand__' in a) {
              return a.__iand__ (b);
          }
          else if (typeof a == 'object' && '__and__' in a) {
              return a = a.__and__ (b);
          }
          else if (typeof b == 'object' && '__rand__' in b) {
              return a = b.__rand__ (a);
          }
          else {
              return a &= b;
          }
      };
      __all__.__iand__ = __iand__;
      
      // Indices and slices
  
      var __getitem__ = function (container, key) {                           // Slice c.q. index, direct generated call to runtime switch
          if (typeof container == 'object' && '__getitem__' in container) {
              return container.__getitem__ (key);                             // Overloaded on container
          }
          else {
              return container [key];                                         // Container must support bare JavaScript brackets
          }
      };
      __all__.__getitem__ = __getitem__;
  
      var __setitem__ = function (container, key, value) {                    // Slice c.q. index, direct generated call to runtime switch
          if (typeof container == 'object' && '__setitem__' in container) {
              container.__setitem__ (key, value);                             // Overloaded on container
          }
          else {
              container [key] = value;                                        // Container must support bare JavaScript brackets
          }
      };
      __all__.__setitem__ = __setitem__;
  
      var __getslice__ = function (container, lower, upper, step) {           // Slice only, no index, direct generated call to runtime switch
          if (typeof container == 'object' && '__getitem__' in container) {
              return container.__getitem__ ([lower, upper, step]);            // Container supports overloaded slicing c.q. indexing
          }
          else {
              return container.__getslice__ (lower, upper, step);             // Container only supports slicing injected natively in prototype
          }
      };
      __all__.__getslice__ = __getslice__;
  
      var __setslice__ = function (container, lower, upper, step, value) {    // Slice, no index, direct generated call to runtime switch
          if (typeof container == 'object' && '__setitem__' in container) {
              container.__setitem__ ([lower, upper, step], value);            // Container supports overloaded slicing c.q. indexing
          }
          else {
              container.__setslice__ (lower, upper, step, value);             // Container only supports slicing injected natively in prototype
          }
      };
      __all__.__setslice__ = __setslice__;
  
  	__nest__ (
  		__all__,
  		'math', {
  			__all__: {
  				__inited__: false,
  				__init__: function (__all__) {
  					var pi = Math.PI;
  					var e = Math.E;
  					var exp = Math.exp;
  					var expm1 = function (x) {
  						return Math.exp (x) - 1;
  					};
  					var log = function (x, base) {
  						return (base === undefined ? Math.log (x) : Math.log (x) / Math.log (base));
  					};
  					var log1p = function (x) {
  						return Math.log (x + 1);
  					};
  					var log2 = function (x) {
  						return Math.log (x) / Math.LN2;
  					};
  					var log10 = function (x) {
  						return Math.log (x) / Math.LN10;
  					};
  					var pow = Math.pow;
  					var sqrt = Math.sqrt;
  					var sin = Math.sin;
  					var cos = Math.cos;
  					var tan = Math.tan;
  					var asin = Math.asin;
  					var acos = Math.acos;
  					var atan = Math.atan;
  					var atan2 = Math.atan2;
  					var hypot = Math.hypot;
  					var degrees = function (x) {
  						return (x * 180) / Math.PI;
  					};
  					var radians = function (x) {
  						return (x * Math.PI) / 180;
  					};
  					var sinh = Math.sinh;
  					var cosh = Math.cosh;
  					var tanh = Math.tanh;
  					var asinh = Math.asinh;
  					var acosh = Math.acosh;
  					var atanh = Math.atanh;
  					var floor = Math.floor;
  					var ceil = Math.ceil;
  					var trunc = Math.trunc;
  					var isnan = isNaN;
  					var inf = Infinity;
  					var nan = NaN;
  					__pragma__ ('<all>')
  						__all__.acos = acos;
  						__all__.acosh = acosh;
  						__all__.asin = asin;
  						__all__.asinh = asinh;
  						__all__.atan = atan;
  						__all__.atan2 = atan2;
  						__all__.atanh = atanh;
  						__all__.ceil = ceil;
  						__all__.cos = cos;
  						__all__.cosh = cosh;
  						__all__.degrees = degrees;
  						__all__.e = e;
  						__all__.exp = exp;
  						__all__.expm1 = expm1;
  						__all__.floor = floor;
  						__all__.hypot = hypot;
  						__all__.inf = inf;
  						__all__.isnan = isnan;
  						__all__.log = log;
  						__all__.log10 = log10;
  						__all__.log1p = log1p;
  						__all__.log2 = log2;
  						__all__.nan = nan;
  						__all__.pi = pi;
  						__all__.pow = pow;
  						__all__.radians = radians;
  						__all__.sin = sin;
  						__all__.sinh = sinh;
  						__all__.sqrt = sqrt;
  						__all__.tan = tan;
  						__all__.tanh = tanh;
  						__all__.trunc = trunc;
  					__pragma__ ('</all>')
  				}
  			}
  		}
  	);
  	__nest__ (
  		__all__,
  		'random', {
  			__all__: {
  				__inited__: false,
  				__init__: function (__all__) {
  					var _array = function () {
  						var __accu0__ = [];
  						for (var i = 0; i < 624; i++) {
  							__accu0__.append (0);
  						}
  						return __accu0__;
  					} ();
  					var _index = 0;
  					var _bitmask1 = Math.pow (2, 32) - 1;
  					var _bitmask2 = Math.pow (2, 31);
  					var _bitmask3 = Math.pow (2, 31) - 1;
  					var _fill_array = function () {
  						for (var i = 0; i < 624; i++) {
  							var y = (_array [i] & _bitmask2) + (_array [__mod__ (i + 1, 624)] & _bitmask3);
  							_array [i] = _array [__mod__ (i + 397, 624)] ^ y >> 1;
  							if (__mod__ (y, 2) != 0) {
  								_array [i] ^= 2567483615;
  							}
  						}
  					};
  					var _random_integer = function () {
  						if (_index == 0) {
  							_fill_array ();
  						}
  						var y = _array [_index];
  						y ^= y >> 11;
  						y ^= y << 7 & 2636928640;
  						y ^= y << 15 & 4022730752;
  						y ^= y >> 18;
  						_index = __mod__ (_index + 1, 624);
  						return y;
  					};
  					var seed = function (x) {
  						if (typeof x == 'undefined' || (x != null && x .hasOwnProperty ("__kwargtrans__"))) {;
  							var x = int (_bitmask3 * Math.random ());
  						};
  						_array [0] = x;
  						for (var i = 1; i < 624; i++) {
  							_array [i] = (1812433253 * _array [i - 1] ^ (_array [i - 1] >> 30) + i) & _bitmask1;
  						}
  					};
  					var randint = function (a, b) {
  						return a + __mod__ (_random_integer (), (b - a) + 1);
  					};
  					var choice = function (seq) {
  						return seq [randint (0, len (seq) - 1)];
  					};
  					var random = function () {
  						return _random_integer () / _bitmask3;
  					};
  					seed ();
  					__pragma__ ('<all>')
  						__all__._array = _array;
  						__all__._bitmask1 = _bitmask1;
  						__all__._bitmask2 = _bitmask2;
  						__all__._bitmask3 = _bitmask3;
  						__all__._fill_array = _fill_array;
  						__all__._index = _index;
  						__all__._random_integer = _random_integer;
  						__all__.choice = choice;
  						__all__.randint = randint;
  						__all__.random = random;
  						__all__.seed = seed;
  					__pragma__ ('</all>')
  				}
  			}
  		}
  	);
  	__nest__ (
  		__all__,
  		'time', {
  			__all__: {
  				__inited__: false,
  				__init__: function (__all__) {
  					var __date = new Date (0);
  					var __now = new Date ();
  					var __weekdays = list ([]);
  					var __weekdays_long = list ([]);
  					var __d = new Date (1467662339080);
  					for (var i = 0; i < 7; i++) {
  						var __iterable0__ = tuple ([tuple ([__weekdays, 'short']), tuple ([__weekdays_long, 'long'])]);
  						for (var __index0__ = 0; __index0__ < __iterable0__.length; __index0__++) {
  							var __left0__ = __iterable0__ [__index0__];
  							var l = __left0__ [0];
  							var s = __left0__ [1];
  							l.append (__d.toLocaleString (window.navigator.language, dict ({'weekday': s})).lower ());
  						}
  						__d.setDate (__d.getDate () + 1);
  					}
  					var __months = list ([]);
  					var __months_long = list ([]);
  					var __d = new Date (946681200000.0);
  					for (var i = 0; i < 12; i++) {
  						var __iterable0__ = tuple ([tuple ([__months, 'short']), tuple ([__months_long, 'long'])]);
  						for (var __index0__ = 0; __index0__ < __iterable0__.length; __index0__++) {
  							var __left0__ = __iterable0__ [__index0__];
  							var l = __left0__ [0];
  							var s = __left0__ [1];
  							l.append (__d.toLocaleString (window.navigator.language, dict ({'month': s})).lower ());
  						}
  						__d.setMonth (__d.getMonth () + 1);
  					}
  					var __lu = dict ({'Y': 0, 'm': 1, 'd': 2, 'H': 3, 'M': 4, 'S': 5});
  					var _lsplit = function (s, sep, maxsplit) {
  						if (maxsplit == 0) {
  							return list ([s]);
  						}
  						var py_split = s.py_split (sep);
  						if (!(maxsplit)) {
  							return py_split;
  						}
  						var ret = py_split.slice (0, maxsplit, 1);
  						if (len (ret) == len (py_split)) {
  							return ret;
  						}
  						ret.append (sep.join (py_split.__getslice__ (maxsplit, null, 1)));
  						return ret;
  					};
  					var _local_time_tuple = function (jd) {
  						var res = tuple ([jd.getFullYear (), jd.getMonth () + 1, jd.getDate (), jd.getHours (), jd.getMinutes (), jd.getSeconds (), (jd.getDay () > 0 ? jd.getDay () - 1 : 6), _day_of_year (jd, true), _daylight_in_effect (jd), jd.getMilliseconds ()]);
  						return res;
  					};
  					var _utc_time_tuple = function (jd) {
  						var res = tuple ([jd.getUTCFullYear (), jd.getUTCMonth () + 1, jd.getUTCDate (), jd.getUTCHours (), jd.getUTCMinutes (), jd.getUTCSeconds (), jd.getUTCDay () - 1, _day_of_year (jd, false), 0, jd.getUTCMilliseconds ()]);
  						return res;
  					};
  					var _day_of_year = function (jd, local) {
  						var day_offs = 0;
  						if (jd.getHours () + (jd.getTimezoneOffset () * 60) / 3600 < 0) {
  							var day_offs = -(1);
  						}
  						var was = jd.getTime ();
  						var cur = jd.setHours (23);
  						jd.setUTCDate (1);
  						jd.setUTCMonth (0);
  						jd.setUTCHours (0);
  						jd.setUTCMinutes (0);
  						jd.setUTCSeconds (0);
  						var res = round ((cur - jd) / 86400000);
  						if (!(local)) {
  							res += day_offs;
  						}
  						if (res == 0) {
  							var res = 365;
  							jd.setTime (jd.getTime () - 86400);
  							var last_year = jd.getUTCFullYear ();
  							if (_is_leap (last_year)) {
  								var res = 366;
  							}
  						}
  						jd.setTime (was);
  						return res;
  					};
  					var _is_leap = function (year) {
  						return __mod__ (year, 4) == 0 && (__mod__ (year, 100) != 0 || __mod__ (year, 400) == 0);
  					};
  					var __jan_jun_tz = function (t, func) {
  						var was = t.getTime ();
  						t.setDate (1);
  						var res = list ([]);
  						var __iterable0__ = tuple ([0, 6]);
  						for (var __index0__ = 0; __index0__ < __iterable0__.length; __index0__++) {
  							var m = __iterable0__ [__index0__];
  							t.setMonth (m);
  							if (!(func)) {
  								res.append (t.getTimezoneOffset ());
  							}
  							else {
  								res.append (func (t));
  							}
  						}
  						t.setTime (was);
  						return res;
  					};
  					var _daylight = function (t) {
  						var jj = __jan_jun_tz (t);
  						if (jj [0] != jj [1]) {
  							return 1;
  						}
  						return 0;
  					};
  					var _daylight_in_effect = function (t) {
  						var jj = __jan_jun_tz (t);
  						if (min (jj [0], jj [1]) == t.getTimezoneOffset ()) {
  							return 1;
  						}
  						return 0;
  					};
  					var _timezone = function (t) {
  						var jj = __jan_jun_tz (t);
  						return max (jj [0], jj [1]);
  					};
  					var __tzn = function (t) {
  						try {
  							return str (t).py_split ('(') [1].py_split (')') [0];
  						}
  						catch (__except0__) {
  							return 'n.a.';
  						}
  					};
  					var _tzname = function (t) {
  						var cn = __tzn (t);
  						var ret = list ([cn, cn]);
  						var jj = __jan_jun_tz (t, __tzn);
  						var ind = 0;
  						if (!(_daylight_in_effect (t))) {
  							var ind = 1;
  						}
  						var __iterable0__ = jj;
  						for (var __index0__ = 0; __index0__ < __iterable0__.length; __index0__++) {
  							var i = __iterable0__ [__index0__];
  							if (i != cn) {
  								ret [ind] = i;
  							}
  						}
  						return tuple (ret);
  					};
  					var altzone = __now.getTimezoneOffset ();
  					if (!(_daylight_in_effect (__now))) {
  						var _jj = __jan_jun_tz (__now);
  						var altzone = (altzone == _jj [1] ? _jj [0] : _jj [1]);
  					}
  					var altzone = altzone * 60;
  					var timezone = _timezone (__now) * 60;
  					var daylight = _daylight (__now);
  					var tzname = _tzname (__now);
  					var time = function () {
  						return Date.now () / 1000;
  					};
  					var asctime = function (t) {
  						return strftime ('%a %b %d %H:%M:%S %Y', t);
  					};
  					var mktime = function (t) {
  						var d = new Date (t [0], t [1] - 1, t [2], t [3], t [4], t [5], 0);
  						return (d - 0) / 1000;
  					};
  					var ctime = function (seconds) {
  						if (!(seconds)) {
  							var seconds = time ();
  						}
  						return asctime (localtime (seconds));
  					};
  					var localtime = function (seconds) {
  						if (!(seconds)) {
  							var seconds = time ();
  						}
  						return gmtime (seconds, true);
  					};
  					var gmtime = function (seconds, localtime) {
  						if (!(seconds)) {
  							var seconds = time ();
  						}
  						var millis = seconds * 1000;
  						__date.setTime (millis);
  						if (localtime) {
  							var t = _local_time_tuple (__date);
  						}
  						else {
  							var t = _utc_time_tuple (__date);
  						}
  						return t.__getslice__ (0, 9, 1);
  					};
  					var strptime = function (string, format) {
  						if (!(format)) {
  							var format = '%a %b %d %H:%M:%S %Y';
  						}
  						var __left0__ = tuple ([string, format]);
  						var ts = __left0__ [0];
  						var fmt = __left0__ [1];
  						var get_next = function (fmt) {
  							var get_sep = function (fmt) {
  								var res = list ([]);
  								if (!(fmt)) {
  									return tuple (['', '']);
  								}
  								for (var i = 0; i < len (fmt) - 1; i++) {
  									var c = fmt [i];
  									if (c == '%') {
  										break;
  									}
  									res.append (c);
  								}
  								return tuple ([''.join (res), fmt.__getslice__ (i, null, 1)]);
  							};
  							var __left0__ = tuple ([null, null, null]);
  							var d = __left0__ [0];
  							var sep = __left0__ [1];
  							var f = __left0__ [2];
  							if (fmt) {
  								if (fmt [0] == '%') {
  									var d = fmt [1];
  									var __left0__ = get_sep (fmt.__getslice__ (2, null, 1));
  									var sep = __left0__ [0];
  									var f = __left0__ [1];
  								}
  								else {
  									var __left0__ = get_sep (fmt);
  									var sep = __left0__ [0];
  									var f = __left0__ [1];
  								}
  							}
  							return tuple ([d, sep, f]);
  						};
  						var dir_val = dict ({});
  						while (ts) {
  							var __left0__ = get_next (fmt);
  							var d = __left0__ [0];
  							var sep = __left0__ [1];
  							var fmt = __left0__ [2];
  							if (sep == '') {
  								var lv = null;
  								if (d) {
  									var l = -(1);
  									if (d == 'Y') {
  										var l = 4;
  									}
  									else if (d == 'a') {
  										var l = len (__weekdays [0]);
  									}
  									else if (d == 'A') {
  										var l = len (__weekdays_long [0]);
  									}
  									else if (d == 'b') {
  										var l = len (__months [0]);
  									}
  									else if (__in__ (d, tuple (['d', 'm', 'H', 'M', 'S']))) {
  										var l = 2;
  									}
  									if (l > -(1)) {
  										var lv = list ([ts.__getslice__ (0, l, 1), ts.__getslice__ (l, null, 1)]);
  									}
  								}
  								if (!(lv)) {
  									var lv = list ([ts, '']);
  								}
  							}
  							else {
  								var lv = _lsplit (ts, sep, 1);
  							}
  							if (d == null) {
  								var ts = lv [1];
  								continue;
  							}
  							var __left0__ = tuple ([lv [1], lv [0]]);
  							var ts = __left0__ [0];
  							dir_val [d] = __left0__ [1];
  							if (fmt == '') {
  								break;
  							}
  						}
  						var t = list ([1900, 1, 1, 0, 0, 0, 0, 1, -(1)]);
  						var ignore_keys = list ([]);
  						var have_weekday = false;
  						var __iterable0__ = dir_val.py_items ();
  						for (var __index0__ = 0; __index0__ < __iterable0__.length; __index0__++) {
  							var __left0__ = __iterable0__ [__index0__];
  							var d = __left0__ [0];
  							var v = __left0__ [1];
  							if (__in__ (d, ignore_keys)) {
  								continue;
  							}
  							if (d == 'p') {
  								continue;
  							}
  							if (__in__ (d, __lu.py_keys ())) {
  								t [__lu [d]] = int (v);
  								continue;
  							}
  							if (__in__ (d, tuple (['a', 'A', 'b', 'B']))) {
  								var v = v.lower ();
  							}
  							if (d == 'm') {
  								ignore_keys.append ('b');
  								ignore_keys.append ('B');
  							}
  							if (d == 'a') {
  								if (!(__in__ (v, __weekdays))) {
  									var __except0__ = ValueError ('Weekday unknown in your locale');
  									__except0__.__cause__ = null;
  									throw __except0__;
  								}
  								var have_weekday = true;
  								t [6] = __weekdays.index (v);
  							}
  							else if (d == 'A') {
  								if (!(__in__ (v, __weekdays_long))) {
  									var __except0__ = ValueError ('Weekday unknown in your locale');
  									__except0__.__cause__ = null;
  									throw __except0__;
  								}
  								var have_weekday = true;
  								t [6] = __weekdays_long.index (v);
  							}
  							else if (d == 'b') {
  								if (!(__in__ (v, __months))) {
  									var __except0__ = ValueError ('Month unknown in your locale');
  									__except0__.__cause__ = null;
  									throw __except0__;
  								}
  								t [1] = __months.index (v) + 1;
  							}
  							else if (d == 'B') {
  								if (!(__in__ (v, __months_long))) {
  									var __except0__ = ValueError ('Month unknown in your locale');
  									__except0__.__cause__ = null;
  									throw __except0__;
  								}
  								t [1] = __months_long.index (v) + 1;
  							}
  							else if (d == 'I') {
  								var ampm = dir_val ['p'] || 'am';
  								var ampm = ampm.lower ();
  								var v = int (v);
  								if (v == 12) {
  									var v = 0;
  								}
  								else if (v > 12) {
  									var __except0__ = ValueError (((("time data '" + string) + "' does not match format '") + format) + "'");
  									__except0__.__cause__ = null;
  									throw __except0__;
  								}
  								if (ampm == 'pm') {
  									v += 12;
  								}
  								t [__lu ['H']] = v;
  							}
  							else if (d == 'y') {
  								t [0] = 2000 + int (v);
  							}
  							else if (d == 'Z') {
  								if (__in__ (v.lower (), list (['gmt', 'utc']))) {
  									t [-(1)] = 0;
  								}
  							}
  						}
  						var __date = new Date (0);
  						__date.setUTCFullYear (t [0]);
  						__date.setUTCMonth (t [1] - 1);
  						__date.setUTCDate (t [2]);
  						__date.setUTCHours (t [3]);
  						t [7] = _day_of_year (__date);
  						if (!(have_weekday)) {
  							t [6] = __date.getUTCDay () - 1;
  						}
  						return t;
  					};
  					var strftime = function (format, t) {
  						var zf2 = function (v) {
  							if (v < 10) {
  								return '0' + str (v);
  							}
  							return v;
  						};
  						if (!(t)) {
  							var t = localtime ();
  						}
  						var f = format;
  						var __iterable0__ = __lu.py_keys ();
  						for (var __index0__ = 0; __index0__ < __iterable0__.length; __index0__++) {
  							var d = __iterable0__ [__index0__];
  							var k = '%' + d;
  							if (!(__in__ (k, f))) {
  								continue;
  							}
  							var v = zf2 (t [__lu [d]]);
  							var f = f.py_replace (k, v);
  						}
  						var __iterable0__ = tuple ([tuple (['b', __months, 1]), tuple (['B', __months_long, 1]), tuple (['a', __weekdays, 6]), tuple (['A', __weekdays_long, 6])]);
  						for (var __index0__ = 0; __index0__ < __iterable0__.length; __index0__++) {
  							var __left0__ = __iterable0__ [__index0__];
  							var d = __left0__ [0];
  							var l = __left0__ [1];
  							var pos = __left0__ [2];
  							var p = t [pos];
  							if (pos == 1) {
  								var p = p - 1;
  							}
  							var v = l [p].capitalize ();
  							var f = f.py_replace ('%' + d, v);
  						}
  						if (__in__ ('%p', f)) {
  							if (t [3] > 11) {
  								var ap = 'PM';
  							}
  							else {
  								var ap = 'AM';
  							}
  							var f = f.py_replace ('%p', ap);
  						}
  						if (__in__ ('%y', f)) {
  							var f = f.py_replace ('%y', str (t [0]).__getslice__ (-(2), null, 1));
  						}
  						if (__in__ ('%I', f)) {
  							var v = t [3];
  							if (v == 0) {
  								var v = 12;
  							}
  							else if (v > 12) {
  								var v = v - 12;
  							}
  							var f = f.py_replace ('%I', zf2 (v));
  						}
  						return f;
  					};
  					__pragma__ ('<all>')
  						__all__.__d = __d;
  						__all__.__date = __date;
  						__all__.__jan_jun_tz = __jan_jun_tz;
  						__all__.__lu = __lu;
  						__all__.__months = __months;
  						__all__.__months_long = __months_long;
  						__all__.__now = __now;
  						__all__.__tzn = __tzn;
  						__all__.__weekdays = __weekdays;
  						__all__.__weekdays_long = __weekdays_long;
  						__all__._day_of_year = _day_of_year;
  						__all__._daylight = _daylight;
  						__all__._daylight_in_effect = _daylight_in_effect;
  						__all__._is_leap = _is_leap;
  						__all__._jj = _jj;
  						__all__._local_time_tuple = _local_time_tuple;
  						__all__._lsplit = _lsplit;
  						__all__._timezone = _timezone;
  						__all__._tzname = _tzname;
  						__all__._utc_time_tuple = _utc_time_tuple;
  						__all__.altzone = altzone;
  						__all__.asctime = asctime;
  						__all__.ctime = ctime;
  						__all__.daylight = daylight;
  						__all__.gmtime = gmtime;
  						__all__.i = i;
  						__all__.l = l;
  						__all__.localtime = localtime;
  						__all__.mktime = mktime;
  						__all__.s = s;
  						__all__.strftime = strftime;
  						__all__.strptime = strptime;
  						__all__.time = time;
  						__all__.timezone = timezone;
  						__all__.tzname = tzname;
  					__pragma__ ('</all>')
  				}
  			}
  		}
  	);
  	(function () {
  		var time = {};
  		__nest__ (time, '', __init__ (__world__.time));
  		var PI = __init__ (__world__.math).PI;
  		var sin = __init__ (__world__.math).sin;
  		var cos = __init__ (__world__.math).cos;
  		var atan2 = __init__ (__world__.math).atan2;
  		var acos = __init__ (__world__.math).acos;
  		var floor = __init__ (__world__.math).floor;
  		var randint = __init__ (__world__.random).randint;
  		var Geo = __class__ ('Geo', [object], {
  			get __init__ () {return __get__ (this, function (self) {
  				self.ctx = document.getElementById ('myCanvas').getContext ('2d');
  				self.W = 0.98 * max (document.documentElement.clientWidth, window.innerWidth || 0);
  				self.H = 0.6 * max (document.documentElement.clientHeight, window.innerHeight || 0);
  				self.ctx.canvas.width = self.W;
  				self.ctx.canvas.height = self.H;
  				self.grdnt = null;
  				self.generateRainbow ();
  				self.ctx.strokeStyle = 'red';
  				self.ctx.font = '30px Arial';
  				self.diptxt = document.querySelector ('.diptxt');
  				self.logtxt = document.querySelector ('.logtxt');
  				self.logtxt.innerHTML = '';
  				self.xrs = list ([]);
  				self.yrs = list ([]);
  				self.zcrs = list ([]);
  				self.zsrs = list ([]);
  				self.xs = list ([]);
  				self.ys = list ([]);
  				self.zs = list ([]);
  				var __left0__ = 0.0;
  				self.xadj = __left0__;
  				self.yadj = __left0__;
  				self.zadj = __left0__;
  				self.g = null;
  				self.h = null;
  				self.m = null;
  				self.stk = 0.0;
  				self.stk180 = null;
  				self.dip = 0.0;
  				self.cpoints = list (['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW']);
  				var __left0__ = null;
  				self.latitude = __left0__;
  				self.longitude = __left0__;
  				self.altitude = __left0__;
  				window.addEventListener ('deviceorientation', self.handleOrientation);
  				document.addEventListener ('deviceready', self.onDeviceReady, false);
  			});},
  			get generateRainbow () {return __get__ (this, function (self) {
  				var rand_hex = function () {
  					var ix = list (['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']);
  					var xx = '';
  					var num = randint (16, 255);
  					var __iterable0__ = tuple ([1, 0]);
  					for (var __index0__ = 0; __index0__ < __iterable0__.length; __index0__++) {
  						var i = __iterable0__ [__index0__];
  						xx += ix [__mod__ (int (num / Math.pow (16, i)), 16)];
  					}
  					return xx;
  				};
  				self.grdnt = self.ctx.createLinearGradient (0, -(0.5) * self.H, 0, 0.5 * self.H);
  				for (var i = 0; i < 6; i++) {
  					var clr = '#{}{}{}'.format (rand_hex (), rand_hex (), rand_hex ());
  					self.grdnt.addColorStop (i / 6.0, clr);
  				}
  				self.ctx.fillStyle = self.grdnt;
  			});},
  			get logReading () {return __get__ (this, function (self) {
  				self.logtxt.innerHTML += ' strike: {} {} dip: {}\n...{} lat: {} lon: {} alt {}'.format (round (self.stk, 1), self.stk180, round (self.dip, 1), time.strftime ('%d %b %Y %H:%M:%S'), self.latitude, self.longitude, self.altitude);
  				self.generateRainbow ();
  			});},
  			get calibrate () {return __get__ (this, function (self) {
  				self.xadj = self.medianMean (self.xrs, 0.0);
  				self.yadj = self.medianMean (self.yrs, 0.0);
  				self.zadj = atan2 (self.medianMean (self.zsrs, -(1.0)), self.medianMean (self.zcrs, 0.0)) + 0.5 * PI;
  			});},
  			get medianMean () {return __get__ (this, function (self, arr, val) {
  				var NUM = 25;
  				var END = 3;
  				arr.append (val);
  				if (len (arr) > NUM) {
  					delete arr [0];
  				}
  				else if (len (arr) < 2 * END + 1) {
  					return val;
  				}
  				var newarr = sorted (arr.__getslice__ (0, null, 1));
  				return sum (newarr.__getslice__ (END, -(END), 1)) / (newarr.length - 2 * END);
  			});},
  			get dot () {return __get__ (this, function (self, a, b) {
  				return (a [0] * b [0] + a [1] * b [1]) + a [2] * b [2];
  			});},
  			get cross () {return __get__ (this, function (self, a, b) {
  				return list ([a [1] * b [2] - a [2] * b [1], a [2] * b [0] - a [0] * b [2], a [0] * b [1] - a [1] * b [0]]);
  			});},
  			get norm () {return __get__ (this, function (self, a) {
  				var mag = Math.pow ((a [0] * a [0] + a [1] * a [1]) + a [2] * a [2], 0.5);
  				return list ([a [0] / mag, a [1] / mag, a [2] / mag]);
  			});},
  			get taitBryan () {return __get__ (this, function (self, a, x, y, z) {
  				x *= -(PI) / 180.0;
  				y *= -(PI) / 180.0;
  				z *= PI / 180.0;
  				var sx = sin (x);
  				var cx = cos (x);
  				var sy = sin (y);
  				var cy = cos (y);
  				var sz = sin (z);
  				var cz = cos (z);
  				return list ([((cy * cz) * a [0] + (-(cy) * sz) * a [1]) + sy * a [2], ((cx * sz + (cz * sx) * sy) * a [0] + (cx * cz - (sx * sy) * sz) * a [1]) + (-(cy) * sx) * a [2], ((sx * sz - (cx * cz) * sy) * a [0] + (cz * sx + (cx * sy) * sz) * a [1]) + (cx * cy) * a [2]]);
  			});},
  			get handleOrientation () {return __get__ (this, function (self, event) {
  				var x = self.medianMean (self.xrs, event.beta) - self.xadj;
  				var y = self.medianMean (self.yrs, event.gamma) - self.yadj;
  				var a = (event.alpha * PI) / 180.0;
  				var z = atan2 (self.medianMean (self.zsrs, sin (a)), self.medianMean (self.zcrs, cos (a))) - self.zadj;
  				var z = __mod__ (630.0 - (z * 180.0) / PI, 360.0);
  				self.m = self.taitBryan (list ([0, -(1), 0]), x, y, z);
  				self.g = self.taitBryan (list ([0, 0, 1]), x, y, z);
  				self.h = self.norm (list ([-(self.g [1]), self.g [0], 0]));
  				self.dip = Math.pow ((self.g [0] * self.g [0] + self.g [1] * self.g [1]) / ((Math.pow (self.g [0], 2) + Math.pow (self.g [1], 2)) + Math.pow (self.g [2], 2)), 0.5);
  				self.dip = 90.0 - (acos (self.dip) * 180.0) / PI;
  				self.stk = __mod__ (450.0 - (atan2 (self.dot (self.m, self.h), self.dot (self.m, self.cross (self.g, self.h))) * 180.0) / PI, 360.0);
  				self.stk180 = '({} {})'.format (round ((self.stk < 180.0 ? self.stk : self.stk - 180.0), 1), self.cpoints [__mod__ (floor ((self.stk + 112.5) / 45.0), 8)]);
  				self.diptxt.innerHTML = '- strike: {} {}\n- dip: {}'.format (round (self.stk, 1), self.stk180, round (self.dip, 1));
  				var x = max (-(90), min (90, x));
  				x += 90;
  				y += 90;
  				var ngl = atan2 (-(self.h [1]), -(self.h [0]));
  				self.ctx.setTransform (1, 0, 0, 1, 0, 0);
  				self.ctx.clearRect (0, 0, self.W, self.H);
  				self.ctx.translate (self.W / 2, self.H / 2);
  				self.ctx.rotate (-(ngl));
  				self.ctx.beginPath ();
  				self.ctx.moveTo (-(self.W), 0);
  				self.ctx.lineTo (-(25), 0);
  				self.ctx.lineTo (-(10), 2.25 * self.dip);
  				self.ctx.lineTo (-(22), 2.0 * self.dip);
  				self.ctx.lineTo (-(3), 5.0 * self.dip);
  				self.ctx.lineTo (8, 2.5 * self.dip);
  				self.ctx.lineTo (18, 2.75 * self.dip);
  				self.ctx.lineTo (25, 0);
  				self.ctx.lineTo (self.W, 0);
  				self.ctx.lineTo (self.W, -(self.H));
  				self.ctx.lineTo (-(self.W), -(self.H));
  				self.ctx.closePath ();
  				self.ctx.fill ();
  				self.ctx.fillText ('Jilly Bean - Strikingly Dippy', -(200), 0.5 * self.H);
  				var ngl = (PI * (z + 180.0)) / 180.0;
  				var offx = self.W * (0.1 + (0.8 * y) / 180);
  				var offy = self.H * (0.1 + (0.8 * x) / 180);
  				self.ctx.setTransform (1, 0, 0, 1, 0, 0);
  				self.ctx.translate (offx, offy);
  				self.ctx.rotate (-(ngl));
  				self.ctx.beginPath ();
  				self.ctx.moveTo (0, 50);
  				self.ctx.lineTo (-(20), -(50));
  				self.ctx.lineTo (20, -(50));
  				self.ctx.closePath ();
  				self.ctx.fill ();
  				self.ctx.stroke ();
  			});},
  			get onSuccess () {return __get__ (this, function (self, position) {
  				self.latitude = position.coords.latitude;
  				self.longitude = position.coords.longitude;
  				self.altitude = position.coords.altitude;
  			});},
  			get onError () {return __get__ (this, function (self, error) {
  				alert ((((('code: ' + error.code) + '\n') + 'message: ') + error.message) + '\n');
  			});},
  			get onDeviceReady () {return __get__ (this, function (self) {
  				console.log ('navigator.geolocation works well');
  				self.watchId = navigator.geolocation.watchPosition (self.onSuccess, self.onError, dict ([[maximumAge, 60000], [timeout, 10000], [enableHighAccuracy, py_true]]));
  			});}
  		});
  		var geo = Geo ();
  		__pragma__ ('<use>' +
  			'math' +
  			'random' +
  			'time' +
  		'</use>')
  		__pragma__ ('<all>')
  			__all__.Geo = Geo;
  			__all__.PI = PI;
  			__all__.acos = acos;
  			__all__.atan2 = atan2;
  			__all__.cos = cos;
  			__all__.floor = floor;
  			__all__.geo = geo;
  			__all__.randint = randint;
  			__all__.sin = sin;
  		__pragma__ ('</all>')
  	}) ();
     return __all__;
  }
  window ['geo'] = geo ();
  