beremiz

Parents 3edd2f19bce2
Children 25054c592dc4
refactoring - library support is not anymore attached to configtree nodes, but handles by project controller
  • +0 -39
    ConfigTreeNode.py
  • +27 -0
    POULibrary.py
  • +48 -14
    ProjectController.py
  • +6 -3
    features.py
  • +118 -0
    py_ext/PythonFileCTNMixin.py
  • +2 -0
    py_ext/__init__.py
  • +0 -13
    py_ext/modules/__init__.py
  • +0 -1
    py_ext/modules/svgui/README
  • +0 -1
    py_ext/modules/svgui/__init__.py
  • +0 -59
    py_ext/modules/svgui/livesvg.js
  • +0 -1428
    py_ext/modules/svgui/pous.xml
  • +0 -2
    py_ext/modules/svgui/pyjs/__init__.py
  • +0 -724
    py_ext/modules/svgui/pyjs/build.py
  • +0 -12
    py_ext/modules/svgui/pyjs/jsonrpc/README.txt
  • +0 -226
    py_ext/modules/svgui/pyjs/jsonrpc/django/jsonrpc.py
  • +0 -43
    py_ext/modules/svgui/pyjs/jsonrpc/jsonrpc.py
  • +0 -11
    py_ext/modules/svgui/pyjs/jsonrpc/web2py/jsonrpc.py
  • +0 -160
    py_ext/modules/svgui/pyjs/lib/_pyjs.js
  • +0 -293
    py_ext/modules/svgui/pyjs/lib/json.js
  • +0 -1365
    py_ext/modules/svgui/pyjs/lib/pyjslib.py
  • +0 -59
    py_ext/modules/svgui/pyjs/lib/sys.py
  • +0 -1777
    py_ext/modules/svgui/pyjs/pyjs.py
  • +0 -112
    py_ext/modules/svgui/svgui.py
  • +0 -130
    py_ext/modules/svgui/svgui_server.py
  • +0 -117
    py_ext/modules/svgui/svguilib.py
  • +0 -1
    py_ext/modules/wxglade_hmi/README
  • +0 -1
    py_ext/modules/wxglade_hmi/__init__.py
  • +0 -124
    py_ext/modules/wxglade_hmi/wxglade_hmi.py
  • +4 -4
    py_ext/plc_python.c
  • +21 -160
    py_ext/py_ext.py
  • +1 -0
    svgui/README
  • +1 -0
    svgui/__init__.py
  • +59 -0
    svgui/livesvg.js
  • +1428 -0
    svgui/pous.xml
  • +2 -0
    svgui/pyjs/__init__.py
  • +724 -0
    svgui/pyjs/build.py
  • +12 -0
    svgui/pyjs/jsonrpc/README.txt
  • +226 -0
    svgui/pyjs/jsonrpc/django/jsonrpc.py
  • +43 -0
    svgui/pyjs/jsonrpc/jsonrpc.py
  • +11 -0
    svgui/pyjs/jsonrpc/web2py/jsonrpc.py
  • +160 -0
    svgui/pyjs/lib/_pyjs.js
  • +293 -0
    svgui/pyjs/lib/json.js
  • +1365 -0
    svgui/pyjs/lib/pyjslib.py
  • +59 -0
    svgui/pyjs/lib/sys.py
  • +1777 -0
    svgui/pyjs/pyjs.py
  • +116 -0
    svgui/svgui.py
  • +130 -0
    svgui/svgui_server.py
  • +117 -0
    svgui/svguilib.py
  • +5 -4
    targets/toolchain_gcc.py
  • +4 -4
    tests/python/beremiz.xml
  • +1 -1
    tests/python/plc.xml
  • +1 -1
    tests/python/python@py_ext/py_ext.xml
  • +0 -2
    tests/svgui/python@py_ext/baseconfnode.xml
  • +0 -8
    tests/svgui/python@py_ext/py_ext.xml
  • +0 -2
    tests/svgui/python@py_ext/svgui@svgui/baseconfnode.xml
  • +0 -723
    tests/svgui/python@py_ext/svgui@svgui/gui.svg
  • +0 -4
    tests/svgui/python@py_ext/svgui@svgui/py_ext.xml
  • +2 -0
    tests/svgui/svgui@svgui/baseconfnode.xml
  • +723 -0
    tests/svgui/svgui@svgui/gui.svg
  • +4 -0
    tests/svgui/svgui@svgui/py_ext.xml
  • +2 -0
    tests/wxGlade/HMIFrame@wxglade_hmi/baseconfnode.xml
  • +34 -0
    tests/wxGlade/HMIFrame@wxglade_hmi/hmi.wxg
  • +4 -0
    tests/wxGlade/HMIFrame@wxglade_hmi/py_ext.xml
  • +0 -2
    tests/wxGlade/python@py_ext/HMIFrame@wxglade_hmi/baseconfnode.xml
  • +0 -34
    tests/wxGlade/python@py_ext/HMIFrame@wxglade_hmi/hmi.wxg
  • +0 -4
    tests/wxGlade/python@py_ext/HMIFrame@wxglade_hmi/py_ext.xml
  • +0 -2
    tests/wxGlade/python@py_ext/baseconfnode.xml
  • +0 -4
    tests/wxGlade/python@py_ext/py_ext.xml
  • +1 -1
    util/misc.py
  • +1 -0
    wxglade_hmi/README
  • +1 -0
    wxglade_hmi/__init__.py
  • +127 -0
    wxglade_hmi/wxglade_hmi.py
  • --- a/ConfigTreeNode.py Wed May 09 00:39:54 2012 +0200
    +++ b/ConfigTreeNode.py Sat May 12 11:21:10 2012 +0200
    @@ -61,7 +61,6 @@
    self._View = None
    # copy ConfNodeMethods so that it can be later customized
    self.ConfNodeMethods = [dic.copy() for dic in self.ConfNodeMethods]
    - self.LoadSTLibrary()
    def ConfNodeBaseXmlFilePath(self, CTNName=None):
    return os.path.join(self.CTNPath(CTNName), "baseconfnode.xml")
    @@ -69,9 +68,6 @@
    def ConfNodeXmlFilePath(self, CTNName=None):
    return os.path.join(self.CTNPath(CTNName), "confnode.xml")
    - def ConfNodeLibraryFilePath(self):
    - return os.path.join(self.ConfNodePath(), "pous.xml")
    -
    def ConfNodePath(self):
    return os.path.join(self.CTNParent.ConfNodePath(), self.CTNType)
    @@ -252,32 +248,6 @@
    return LocationCFilesAndCFLAGS, LDFLAGS, extra_files
    - def ConfNodeTypesFactory(self):
    - if self.LibraryControler is not None:
    - return [{"name" : self.CTNType, "types": self.LibraryControler.Project}]
    - return []
    -
    - def ParentsTypesFactory(self):
    - return self.CTNParent.ParentsTypesFactory() + self.ConfNodeTypesFactory()
    -
    - def ConfNodesTypesFactory(self):
    - list = self.ConfNodeTypesFactory()
    - for CTNChild in self.IterChildren():
    - list += CTNChild.ConfNodesTypesFactory()
    - return list
    -
    - def STLibraryFactory(self):
    - if self.LibraryControler is not None:
    - program, errors, warnings = self.LibraryControler.GenerateProgram()
    - return program + "\n"
    - return ""
    -
    - def ConfNodesSTLibraryFactory(self):
    - program = self.STLibraryFactory()
    - for CTNChild in self.IECSortedChildren():
    - program += CTNChild.ConfNodesSTLibraryFactory()
    - return program
    -
    def IterChildren(self):
    for CTNType, Children in self.Children.items():
    for CTNInstance in Children:
    @@ -563,15 +533,6 @@
    child.ClearChildren()
    self.Children = {}
    - def LoadSTLibrary(self):
    - # Get library blocks if plcopen library exist
    - library_path = self.ConfNodeLibraryFilePath()
    - if os.path.isfile(library_path):
    - self.LibraryControler = PLCControler()
    - self.LibraryControler.OpenXMLFile(library_path)
    - self.LibraryControler.ClearConfNodeTypes()
    - self.LibraryControler.AddConfNodeTypesList(self.ParentsTypesFactory())
    -
    def LoadXMLParams(self, CTNName = None):
    methode_name = os.path.join(self.CTNPath(CTNName), "methods.py")
    if os.path.isfile(methode_name):
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/POULibrary.py Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,27 @@
    +from PLCControler import PLCControler
    +
    +class POULibrary:
    + def __init__(self, TypeStack):
    + self.LibraryControler = PLCControler()
    + self.LibraryControler.OpenXMLFile(self.GetLibraryPath())
    + self.LibraryControler.ClearConfNodeTypes()
    + self.LibraryControler.AddConfNodeTypesList(TypeStack)
    + self.program = None;
    +
    + def GetSTCode(self):
    + if not self.program:
    + self.program = self.LibraryControler.GenerateProgram()[0]+"\n"
    + return self.program
    +
    + def GetName():
    + raise Exception("Not implemented")
    +
    + def GetTypes(self):
    + return {"name" : self.GetName(), "types": self.LibraryControler.Project}
    +
    + def GetLibraryPath(self):
    + raise Exception("Not implemented")
    +
    + def Generate_C(self, buildpath, varlist, IECCFLAGS):
    + # Pure python or IEC libs doesn't produce C code
    + return ((""), [], False), ""
    --- a/ProjectController.py Wed May 09 00:39:54 2012 +0200
    +++ b/ProjectController.py Sat May 12 11:21:10 2012 +0200
    @@ -1,5 +1,5 @@
    """
    -Base definitions for beremiz confnodes
    +Beremiz Project Controller
    """
    import os,sys,traceback
    @@ -61,7 +61,8 @@
    </xsd:element>
    </xsd:sequence>
    <xsd:attribute name="URI_location" type="xsd:string" use="optional" default=""/>
    - <xsd:attribute name="Enable_ConfNodes" type="xsd:boolean" use="optional" default="true"/>
    + <xsd:attribute name="Disable_Extensions" type="xsd:boolean" use="optional" default="false"/>
    + """+"\n".join(['<xsd:attribute name="Enable_'+lib.rsplit('.',1)[-1]+'" type="xsd:boolean" use="optional" default="true"/>' for lib in features.libraries])+"""
    </xsd:complexType>
    </xsd:element>
    </xsd:schema>
    @@ -84,10 +85,6 @@
    self.DebugTimer=None
    self.ResetIECProgramsAndVariables()
    -
    - #This method are not called here... but in NewProject and OpenProject
    - #self._AddParamsMembers()
    - #self.Children = {}
    # In both new or load scenario, no need to save
    self.ChangesToSave = False
    @@ -104,7 +101,15 @@
    self.previous_plcstate = None
    # copy ConfNodeMethods so that it can be later customized
    self.ConfNodeMethods = [dic.copy() for dic in self.ConfNodeMethods]
    - self.LoadSTLibrary()
    +
    + def LoadLibraries(self):
    + self.Libraries = []
    + TypeStack=[]
    + for clsname in features.libraries:
    + if getattr(self.BeremizRoot, "Enable_"+clsname.rsplit('.',1)[-1]):
    + Lib = GetClassImporter(clsname)()(TypeStack)
    + TypeStack.append(Lib.GetTypes())
    + self.Libraries.append(Lib)
    def __del__(self):
    if self.DebugTimer:
    @@ -132,9 +137,6 @@
    self.logger = logger
    - def ConfNodeLibraryFilePath(self):
    - return os.path.join(os.path.split(__file__)[0], "pous.xml")
    -
    def CTNTestModified(self):
    return self.ChangesToSave or not self.ProjectIsSaved()
    @@ -311,12 +313,31 @@
    self._setBuildPath(self.BuildPath)
    return True
    return False
    +
    + def GetLibrariesTypes(self):
    + self.LoadLibraries()
    + return [ lib.GetTypes() for lib in self.Libraries ]
    +
    + def GetLibrariesSTCode(self):
    + return "\n".join([ lib.GetSTCode() for lib in self.Libraries ])
    +
    + def GetLibrariesCCode(self, buildpath):
    + self.GetIECProgramsAndVariables()
    + LibIECCflags = '"-I%s"'%os.path.abspath(self.GetIECLibPath())
    + LocatedCCodeAndFlags=[]
    + Extras=[]
    + for lib in self.Libraries:
    + res=lib.Generate_C(buildpath,self._VariablesList,LibIECCflags)
    + LocatedCCodeAndFlags.append(res[:2])
    + if len(res)>2:
    + Extras.append(res[2:])
    + return map(list,zip(*LocatedCCodeAndFlags))+[tuple(Extras)]
    # Update PLCOpenEditor ConfNode Block types from loaded confnodes
    def RefreshConfNodesBlockLists(self):
    if getattr(self, "Children", None) is not None:
    self.ClearConfNodeTypes()
    - self.AddConfNodeTypesList(self.ConfNodesTypesFactory())
    + self.AddConfNodeTypesList(self.GetLibrariesTypes())
    if self.AppFrame is not None:
    self.AppFrame.RefreshLibraryPanel()
    self.AppFrame.RefreshEditor()
    @@ -449,7 +470,7 @@
    return False
    plc_file = open(self._getIECcodepath(), "w")
    # Add ST Library from confnodes
    - plc_file.write(self.ConfNodesSTLibraryFactory())
    + plc_file.write(self.GetLibrariesSTCode())
    if os.path.isfile(self._getIECrawcodepath()):
    plc_file.write(open(self._getIECrawcodepath(), "r").read())
    plc_file.write("\n")
    @@ -708,7 +729,7 @@
    [loc for loc,Cfiles,DoCalls in self.LocationCFilesAndCFLAGS if loc and DoCalls])
    # Generate main, based on template
    - if self.BeremizRoot.getEnable_ConfNodes():
    + if not self.BeremizRoot.getDisable_Extensions():
    plc_main_code = targets.code("plc_common_main") % {
    "calls_prototypes":"\n".join([(
    "int __init_%(s)s(int argc,char **argv);\n"+
    @@ -774,7 +795,7 @@
    # Generate C code and compilation params from confnode hierarchy
    try:
    - self.LocationCFilesAndCFLAGS, self.LDFLAGS, ExtraFiles = self._Generate_C(
    + CTNLocationCFilesAndCFLAGS, CTNLDFLAGS, CTNExtraFiles = self._Generate_C(
    buildpath,
    self.PLCGeneratedLocatedVars)
    except Exception, exc:
    @@ -783,6 +804,19 @@
    self.ResetBuildMD5()
    return False
    + # Generate C code and compilation params from liraries
    + try:
    + LibCFilesAndCFLAGS, LibLDFLAGS, LibExtraFiles = self.GetLibrariesCCode(buildpath)
    + except Exception, exc:
    + self.logger.write_error(_("Runtime extensions C code generation failed !\n"))
    + self.logger.write_error(traceback.format_exc())
    + self.ResetBuildMD5()
    + return False
    +
    + self.LocationCFilesAndCFLAGS = CTNLocationCFilesAndCFLAGS + LibCFilesAndCFLAGS
    + self.LDFLAGS = CTNLDFLAGS + LibLDFLAGS
    + ExtraFiles = CTNExtraFiles + LibExtraFiles
    +
    # Get temporary directory path
    extrafilespath = self._getExtraFilesPath()
    # Remove old directory
    --- a/features.py Wed May 09 00:39:54 2012 +0200
    +++ b/features.py Sat May 12 11:21:10 2012 +0200
    @@ -1,7 +1,10 @@
    -from os import listdir, path
    +libraries = ['py_ext.PythonLibrary',
    + 'svgui.SVGUILibrary']
    catalog = [
    ('canfestival', _('CANopen support'), _('Map located variables over CANopen'), 'canfestival.canfestival.RootClass'),
    - ('c_ext', _('C extention'), _('Extend project with C code accessing located variables'), 'c_ext.c_ext.RootClass'),
    - ('py_ext', _('Python extention'), _('Extend project with Pyhon code executed asynchronously'), 'py_ext.py_ext.RootClass')]
    + ('c_ext', _('C extention'), _('Add C code accessing located variables synchronously'), 'c_ext.c_ext.RootClass'),
    + ('py_ext', _('Python file'), _('Add Python code executed asynchronously'), 'py_ext.PythonFile'),
    + ('wxglade_hmi', _('WxGlade GUI'), _('Add a simple WxGlade based GUI.'), 'wxglade_hmi.WxGladeHMI'),
    + ('svgui', _('SVGUI'), _('Experimental web based HMI'), 'svgui.SVGUI')]
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/py_ext/PythonFileCTNMixin.py Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,118 @@
    +import os
    +from util import opjimg
    +from PLCControler import UndoBuffer
    +from PythonEditor import PythonEditor
    +
    +from xml.dom import minidom
    +from xmlclass import *
    +import cPickle
    +
    +PythonClasses = GenerateClassesFromXSD(os.path.join(os.path.dirname(__file__), "py_ext_xsd.xsd"))
    +
    +class PythonFileCTNMixin:
    +
    + EditorType = PythonEditor
    +
    + def __init__(self):
    +
    + self.ConfNodeMethods.insert(0,
    + {"bitmap" : opjimg("editPYTHONcode"),
    + "name" : _("Edit Python File"),
    + "tooltip" : _("Edit Python File"),
    + "method" : "_OpenView"},
    + )
    +
    + filepath = self.PythonFileName()
    +
    + self.PythonCode = PythonClasses["Python"]()
    + if os.path.isfile(filepath):
    + xmlfile = open(filepath, 'r')
    + tree = minidom.parse(xmlfile)
    + xmlfile.close()
    +
    + for child in tree.childNodes:
    + if child.nodeType == tree.ELEMENT_NODE and child.nodeName == "Python":
    + self.PythonCode.loadXMLTree(child, ["xmlns", "xmlns:xsi", "xsi:schemaLocation"])
    + self.CreatePythonBuffer(True)
    + else:
    + self.CreatePythonBuffer(False)
    + self.OnCTNSave()
    +
    + def PythonFileName(self):
    + return os.path.join(self.CTNPath(), "py_ext.xml")
    +
    + def GetFilename(self):
    + if self.PythonBuffer.IsCurrentSaved():
    + return "py_ext"
    + else:
    + return "~py_ext~"
    +
    + def SetPythonCode(self, text):
    + self.PythonCode.settext(text)
    +
    + def GetPythonCode(self):
    + return self.PythonCode.gettext()
    +
    + def CTNTestModified(self):
    + return self.ChangesToSave or not self.PythonIsSaved()
    +
    + def OnCTNSave(self):
    + filepath = self.PythonFileName()
    +
    + text = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
    + extras = {"xmlns":"http://www.w3.org/2001/XMLSchema",
    + "xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance",
    + "xsi:schemaLocation" : "py_ext_xsd.xsd"}
    + text += self.PythonCode.generateXMLText("Python", 0, extras)
    +
    + xmlfile = open(filepath,"w")
    + xmlfile.write(text.encode("utf-8"))
    + xmlfile.close()
    +
    + self.MarkPythonAsSaved()
    + return True
    +
    +#-------------------------------------------------------------------------------
    +# Current Buffering Management Functions
    +#-------------------------------------------------------------------------------
    +
    + """
    + Return a copy of the project
    + """
    + def Copy(self, model):
    + return cPickle.loads(cPickle.dumps(model))
    +
    + def CreatePythonBuffer(self, saved):
    + self.Buffering = False
    + self.PythonBuffer = UndoBuffer(cPickle.dumps(self.PythonCode), saved)
    +
    + def BufferPython(self):
    + self.PythonBuffer.Buffering(cPickle.dumps(self.PythonCode))
    +
    + def StartBuffering(self):
    + self.Buffering = True
    +
    + def EndBuffering(self):
    + if self.Buffering:
    + self.PythonBuffer.Buffering(cPickle.dumps(self.PythonCode))
    + self.Buffering = False
    +
    + def MarkPythonAsSaved(self):
    + self.EndBuffering()
    + self.PythonBuffer.CurrentSaved()
    +
    + def PythonIsSaved(self):
    + return self.PythonBuffer.IsCurrentSaved() and not self.Buffering
    +
    + def LoadPrevious(self):
    + self.EndBuffering()
    + self.PythonCode = cPickle.loads(self.PythonBuffer.Previous())
    +
    + def LoadNext(self):
    + self.PythonCode = cPickle.loads(self.PythonBuffer.Next())
    +
    + def GetBufferState(self):
    + first = self.PythonBuffer.IsFirst() and not self.Buffering
    + last = self.PythonBuffer.IsLast()
    + return not first, not last
    +
    --- a/py_ext/__init__.py Wed May 09 00:39:54 2012 +0200
    +++ b/py_ext/__init__.py Sat May 12 11:21:10 2012 +0200
    @@ -1,1 +1,3 @@
    from py_ext import *
    +from PythonEditor import PythonEditor
    +from PythonFileCTNMixin import PythonFileCTNMixin
    --- a/py_ext/modules/__init__.py Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,13 +0,0 @@
    -from os import listdir, path
    -
    -_base_path = path.split(__file__)[0]
    -
    -__all__ = [name for name in listdir(_base_path) if path.isdir(path.join(_base_path, name)) and name.upper() != "CVS" or name.endswith(".py") and not name.startswith("__")]
    -
    -helps = []
    -for name in __all__:
    - helpfilename = path.join(_base_path, name, "README")
    - if path.isfile(helpfilename):
    - helps.append(open(helpfilename).readline().strip())
    - else:
    - helps.append(name)
    --- a/py_ext/modules/svgui/README Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,1 +0,0 @@
    -SVGUI HMI
    \ No newline at end of file
    --- a/py_ext/modules/svgui/__init__.py Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,1 +0,0 @@
    -from svgui import *
    --- a/py_ext/modules/svgui/livesvg.js Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,59 +0,0 @@
    -// import Nevow.Athena
    -// import Divmod.Base
    -
    -function updateAttr(id, param, value) {
    - Nevow.Athena.Widget.fromAthenaID(1).callRemote('HMIexec', 'setattr', id, param, value);
    -}
    -
    -var svguiWidgets = new Array();
    -
    -var currentObject = null;
    -function setCurrentObject(obj) {
    - currentObject = obj;
    -}
    -function isCurrentObject(obj) {
    - return currentObject == obj;
    -}
    -
    -function getSVGElementById(id) {
    - return document.getElementById(id);
    -}
    -
    -function blockSVGElementDrag(element) {
    - element.addEventListener("draggesture", function(event){event.stopPropagation()}, true);
    -}
    -
    -LiveSVGPage.LiveSVGWidget = Nevow.Athena.Widget.subclass('LiveSVGPage.LiveSVGWidget');
    -LiveSVGPage.LiveSVGWidget.methods(
    -
    - function handleEvent(self, evt) {
    - if (currentObject != null) {
    - currentObject.handleEvent(evt);
    - }
    - },
    -
    - function receiveData(self, data){
    - dataReceived = json_parse(data);
    - gadget = svguiWidgets[dataReceived.id]
    - if (gadget) {
    - gadget.updateValues(json_parse(dataReceived.kwargs));
    - }
    - //console.log("OBJET : " + dataReceived.back_id + " STATE : " + newState);
    - },
    -
    - function init(self, arg1){
    - //console.log("Object received : " + arg1);
    - for (ind in arg1) {
    - gad = json_parse(arg1[ind]);
    - args = json_parse(gad.kwargs);
    - gadget = new svguilib[gad.__class__](self, gad.id, args);
    - svguiWidgets[gadget.id]=gadget;
    - //console.log('GADGET :' + gadget);
    - }
    - var elements = document.getElementsByTagName("svg");
    - for (var i = 0; i < elements.length; i++) {
    - elements[i].addEventListener("mouseup", self, false);
    - }
    - //console.log("SVGUIWIDGETS : " + svguiWidgets);
    - }
    -);
    --- a/py_ext/modules/svgui/pous.xml Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,1428 +0,0 @@
    -<?xml version="1.0" encoding="UTF-8"?>
    -<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    - xmlns="http://www.plcopen.org/xml/tc6.xsd"
    - xmlns:xhtml="http://www.w3.org/1999/xhtml"
    - xsi:schemaLocation="http://www.plcopen.org/xml/tc6.xsd">
    - <fileHeader companyName="Beremiz"
    - productName="Beremiz"
    - productVersion="0.0"
    - creationDateTime="2008-12-14T16:53:26"/>
    - <contentHeader name="Beremiz non-standard POUs library"
    - modificationDateTime="2009-08-12T15:35:33">
    - <coordinateInfo>
    - <fbd>
    - <scaling x="0" y="0"/>
    - </fbd>
    - <ld>
    - <scaling x="0" y="0"/>
    - </ld>
    - <sfc>
    - <scaling x="0" y="0"/>
    - </sfc>
    - </coordinateInfo>
    - </contentHeader>
    - <types>
    - <dataTypes/>
    - <pous>
    - <pou name="GetBoolString" pouType="functionBlock">
    - <interface>
    - <inputVars>
    - <variable name="VALUE">
    - <type>
    - <BOOL/>
    - </type>
    - </variable>
    - </inputVars>
    - <outputVars>
    - <variable name="CODE">
    - <type>
    - <string/>
    - </type>
    - </variable>
    - </outputVars>
    - </interface>
    - <body>
    - <ST>
    -<![CDATA[IF VALUE THEN
    - CODE := 'True';
    -ELSE
    - CODE := 'False';
    -END_IF;]]>
    - </ST>
    - </body>
    - </pou>
    - <pou name="TextCtrl" pouType="functionBlock">
    - <interface>
    - <localVars>
    - <variable name="ID">
    - <type>
    - <string/>
    - </type>
    - </variable>
    - </localVars>
    - <inputVars>
    - <variable name="back_id">
    - <type>
    - <string/>
    - </type>
    - </variable>
    - <variable name="set_text">
    - <type>
    - <BOOL/>
    - </type>
    - </variable>
    - <variable name="text">
    - <type>
    - <string/>
    - </type>
    - </variable>
    - </inputVars>
    - <localVars>
    - <variable name="SVGUI_TEXTCTRL">
    - <type>
    - <derived name="python_eval"/>
    - </type>
    - </variable>
    - <variable name="setstate_Command">
    - <type>
    - <derived name="python_eval"/>
    - </type>
    - </variable>
    - </localVars>
    - </interface>
    - <body>
    - <FBD>
    - <block localId="1" width="193" height="160" typeName="CONCAT">
    - <position x="626" y="122"/>
    - <inputVariables>
    - <variable formalParameter="IN1">
    - <connectionPointIn>
    - <relPosition x="0" y="43"/>
    - <connection refLocalId="2">
    - <position x="626" y="165"/>
    - <position x="535" y="165"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN2">
    - <connectionPointIn>
    - <relPosition x="0" y="89"/>
    - <connection refLocalId="3">
    - <position x="626" y="211"/>
    - <position x="535" y="211"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN3">
    - <connectionPointIn>
    - <relPosition x="0" y="135"/>
    - <connection refLocalId="6">
    - <position x="626" y="257"/>
    - <position x="532" y="257"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="OUT">
    - <connectionPointOut>
    - <relPosition x="193" y="43"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <inVariable localId="2" height="30" width="460">
    - <position x="75" y="150"/>
    - <connectionPointOut>
    - <relPosition x="460" y="15"/>
    - </connectionPointOut>
    - <expression>'createSVGUIControl("textControl", back_id="'</expression>
    - </inVariable>
    - <inVariable localId="3" height="35" width="85">
    - <position x="450" y="196"/>
    - <connectionPointOut>
    - <relPosition x="85" y="15"/>
    - </connectionPointOut>
    - <expression>back_id</expression>
    - </inVariable>
    - <inVariable localId="6" height="30" width="50">
    - <position x="482" y="242"/>
    - <connectionPointOut>
    - <relPosition x="50" y="15"/>
    - </connectionPointOut>
    - <expression>'")'</expression>
    - </inVariable>
    - <block localId="7" width="125" height="115" typeName="python_eval" instanceName="SVGUI_TEXTCTRL">
    - <position x="909" y="75"/>
    - <inputVariables>
    - <variable formalParameter="TRIG">
    - <connectionPointIn>
    - <relPosition x="0" y="45"/>
    - <connection refLocalId="9">
    - <position x="909" y="120"/>
    - <position x="886" y="120"/>
    - <position x="886" y="85"/>
    - <position x="869" y="85"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="CODE">
    - <connectionPointIn>
    - <relPosition x="0" y="90"/>
    - <connection refLocalId="1" formalParameter="OUT">
    - <position x="909" y="165"/>
    - <position x="819" y="165"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="ACK">
    - <connectionPointOut>
    - <relPosition x="125" y="45"/>
    - </connectionPointOut>
    - </variable>
    - <variable formalParameter="RESULT">
    - <connectionPointOut>
    - <relPosition x="125" y="90"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <inVariable localId="9" height="30" width="70">
    - <position x="799" y="70"/>
    - <connectionPointOut>
    - <relPosition x="70" y="15"/>
    - </connectionPointOut>
    - <expression>BOOL#1</expression>
    - </inVariable>
    - <outVariable localId="10" height="30" width="30">
    - <position x="1094" y="150"/>
    - <connectionPointIn>
    - <relPosition x="0" y="15"/>
    - <connection refLocalId="7" formalParameter="RESULT">
    - <position x="1094" y="165"/>
    - <position x="1034" y="165"/>
    - </connection>
    - </connectionPointIn>
    - <expression>ID</expression>
    - </outVariable>
    - <connector name="CREATED" localId="11" height="30" width="110">
    - <position x="1096" y="105"/>
    - <connectionPointIn>
    - <relPosition x="0" y="15"/>
    - <connection refLocalId="7" formalParameter="ACK">
    - <position x="1096" y="120"/>
    - <position x="1034" y="120"/>
    - </connection>
    - </connectionPointIn>
    - </connector>
    - <block localId="4" width="125" height="140" typeName="python_eval" instanceName="setstate_Command">
    - <position x="957" y="472"/>
    - <inputVariables>
    - <variable formalParameter="TRIG">
    - <connectionPointIn>
    - <relPosition x="0" y="50"/>
    - <connection refLocalId="31" formalParameter="OUT">
    - <position x="957" y="522"/>
    - <position x="909" y="522"/>
    - <position x="909" y="444"/>
    - <position x="857" y="444"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="CODE">
    - <connectionPointIn>
    - <relPosition x="0" y="110"/>
    - <connection refLocalId="12" formalParameter="OUT">
    - <position x="957" y="582"/>
    - <position x="822" y="582"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="ACK">
    - <connectionPointOut>
    - <relPosition x="125" y="50"/>
    - </connectionPointOut>
    - </variable>
    - <variable formalParameter="RESULT">
    - <connectionPointOut>
    - <relPosition x="125" y="110"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <continuation name="CREATED" localId="5" height="30" width="110">
    - <position x="589" y="429"/>
    - <connectionPointOut>
    - <relPosition x="110" y="15"/>
    - </connectionPointOut>
    - </continuation>
    - <block localId="12" width="186" height="288" typeName="CONCAT">
    - <position x="636" y="536"/>
    - <inputVariables>
    - <variable formalParameter="IN1">
    - <connectionPointIn>
    - <relPosition x="0" y="46"/>
    - <connection refLocalId="14">
    - <position x="636" y="582"/>
    - <position x="526" y="582"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN2">
    - <connectionPointIn>
    - <relPosition x="0" y="99"/>
    - <connection refLocalId="8">
    - <position x="636" y="635"/>
    - <position x="526" y="635"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN3">
    - <connectionPointIn>
    - <relPosition x="0" y="152"/>
    - <connection refLocalId="15">
    - <position x="636" y="688"/>
    - <position x="527" y="688"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN4">
    - <connectionPointIn>
    - <relPosition x="0" y="205"/>
    - <connection refLocalId="32">
    - <position x="636" y="741"/>
    - <position x="528" y="741"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN5">
    - <connectionPointIn>
    - <relPosition x="0" y="258"/>
    - <connection refLocalId="16">
    - <position x="636" y="794"/>
    - <position x="528" y="794"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="OUT">
    - <connectionPointOut>
    - <relPosition x="186" y="46"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <inVariable localId="8" height="30" width="53">
    - <position x="473" y="620"/>
    - <connectionPointOut>
    - <relPosition x="53" y="15"/>
    - </connectionPointOut>
    - <expression>ID</expression>
    - </inVariable>
    - <inVariable localId="13" height="35" width="100">
    - <position x="599" y="469"/>
    - <connectionPointOut>
    - <relPosition x="100" y="17"/>
    - </connectionPointOut>
    - <expression>set_text</expression>
    - </inVariable>
    - <inVariable localId="14" height="30" width="120">
    - <position x="406" y="567"/>
    - <connectionPointOut>
    - <relPosition x="120" y="15"/>
    - </connectionPointOut>
    - <expression>'setAttr('</expression>
    - </inVariable>
    - <inVariable localId="15" height="30" width="122">
    - <position x="405" y="673"/>
    - <connectionPointOut>
    - <relPosition x="122" y="15"/>
    - </connectionPointOut>
    - <expression>',"text","'</expression>
    - </inVariable>
    - <inVariable localId="16" height="30" width="50">
    - <position x="478" y="779"/>
    - <connectionPointOut>
    - <relPosition x="50" y="15"/>
    - </connectionPointOut>
    - <expression>'")'</expression>
    - </inVariable>
    - <block localId="31" width="75" height="105" typeName="AND">
    - <position x="782" y="403"/>
    - <inputVariables>
    - <variable formalParameter="IN1">
    - <connectionPointIn>
    - <relPosition x="0" y="41"/>
    - <connection refLocalId="5">
    - <position x="782" y="444"/>
    - <position x="699" y="444"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN2">
    - <connectionPointIn>
    - <relPosition x="0" y="83"/>
    - <connection refLocalId="13">
    - <position x="782" y="486"/>
    - <position x="699" y="486"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="OUT">
    - <connectionPointOut>
    - <relPosition x="75" y="41"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <inVariable localId="32" height="30" width="90">
    - <position x="438" y="726"/>
    - <connectionPointOut>
    - <relPosition x="90" y="15"/>
    - </connectionPointOut>
    - <expression>text</expression>
    - </inVariable>
    - </FBD>
    - </body>
    - </pou>
    - <pou name="Button" pouType="functionBlock">
    - <interface>
    - <localVars>
    - <variable name="ID">
    - <type>
    - <string/>
    - </type>
    - </variable>
    - </localVars>
    - <inputVars>
    - <variable name="back_id">
    - <type>
    - <string/>
    - </type>
    - </variable>
    - <variable name="sele_id">
    - <type>
    - <string/>
    - </type>
    - </variable>
    - <variable name="toggle">
    - <type>
    - <BOOL/>
    - </type>
    - </variable>
    - <variable name="set_state">
    - <type>
    - <BOOL/>
    - </type>
    - </variable>
    - <variable name="state_in">
    - <type>
    - <BOOL/>
    - </type>
    - </variable>
    - </inputVars>
    - <outputVars>
    - <variable name="state_out">
    - <type>
    - <BOOL/>
    - </type>
    - </variable>
    - </outputVars>
    - <localVars>
    - <variable name="init_Command">
    - <type>
    - <derived name="python_eval"/>
    - </type>
    - </variable>
    - <variable name="GetButtonState">
    - <type>
    - <derived name="GetBoolString"/>
    - </type>
    - </variable>
    - <variable name="setstate_Command">
    - <type>
    - <derived name="python_eval"/>
    - </type>
    - </variable>
    - <variable name="getstate_Command">
    - <type>
    - <derived name="python_poll"/>
    - </type>
    - </variable>
    - <variable name="GetButtonToggle">
    - <type>
    - <derived name="GetBoolString"/>
    - </type>
    - </variable>
    - </localVars>
    - </interface>
    - <body>
    - <FBD>
    - <block localId="1" width="125" height="140" typeName="python_eval" instanceName="init_Command">
    - <position x="838" y="32"/>
    - <inputVariables>
    - <variable formalParameter="TRIG">
    - <connectionPointIn>
    - <relPosition x="0" y="50"/>
    - <connection refLocalId="10">
    - <position x="838" y="82"/>
    - <position x="781" y="82"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="CODE">
    - <connectionPointIn>
    - <relPosition x="0" y="110"/>
    - <connection refLocalId="2" formalParameter="OUT">
    - <position x="838" y="142"/>
    - <position x="641" y="142"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="ACK">
    - <connectionPointOut>
    - <relPosition x="125" y="50"/>
    - </connectionPointOut>
    - </variable>
    - <variable formalParameter="RESULT">
    - <connectionPointOut>
    - <relPosition x="125" y="110"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <block localId="2" width="150" height="442" typeName="CONCAT">
    - <position x="491" y="92"/>
    - <inputVariables>
    - <variable formalParameter="IN1">
    - <connectionPointIn>
    - <relPosition x="0" y="50"/>
    - <connection refLocalId="3">
    - <position x="491" y="142"/>
    - <position x="433" y="142"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN2">
    - <connectionPointIn>
    - <relPosition x="0" y="110"/>
    - <connection refLocalId="11">
    - <position x="491" y="202"/>
    - <position x="431" y="202"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN3">
    - <connectionPointIn>
    - <relPosition x="0" y="170"/>
    - <connection refLocalId="5">
    - <position x="491" y="262"/>
    - <position x="431" y="262"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN4">
    - <connectionPointIn>
    - <relPosition x="0" y="230"/>
    - <connection refLocalId="12">
    - <position x="491" y="322"/>
    - <position x="430" y="322"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN5">
    - <connectionPointIn>
    - <relPosition x="0" y="290"/>
    - <connection refLocalId="23">
    - <position x="491" y="382"/>
    - <position x="463" y="382"/>
    - <position x="463" y="370"/>
    - <position x="430" y="370"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN6">
    - <connectionPointIn>
    - <relPosition x="0" y="350"/>
    - <connection refLocalId="24" formalParameter="CODE">
    - <position x="491" y="442"/>
    - <position x="429" y="442"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN7">
    - <connectionPointIn>
    - <relPosition x="0" y="410"/>
    - <connection refLocalId="9">
    - <position x="491" y="502"/>
    - <position x="430" y="502"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="OUT">
    - <connectionPointOut>
    - <relPosition x="150" y="50"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <inVariable localId="3" height="30" width="400">
    - <position x="33" y="127"/>
    - <connectionPointOut>
    - <relPosition x="400" y="15"/>
    - </connectionPointOut>
    - <expression>'createSVGUIControl("button",back_id="'</expression>
    - </inVariable>
    - <inVariable localId="5" height="30" width="140">
    - <position x="291" y="247"/>
    - <connectionPointOut>
    - <relPosition x="140" y="15"/>
    - </connectionPointOut>
    - <expression>'",sele_id="'</expression>
    - </inVariable>
    - <inVariable localId="9" height="30" width="180">
    - <position x="250" y="487"/>
    - <connectionPointOut>
    - <relPosition x="180" y="15"/>
    - </connectionPointOut>
    - <expression>',active=True)'</expression>
    - </inVariable>
    - <inVariable localId="10" height="30" width="70">
    - <position x="711" y="67"/>
    - <connectionPointOut>
    - <relPosition x="70" y="15"/>
    - </connectionPointOut>
    - <expression>BOOL#1</expression>
    - </inVariable>
    - <inVariable localId="11" height="35" width="85">
    - <position x="346" y="187"/>
    - <connectionPointOut>
    - <relPosition x="85" y="15"/>
    - </connectionPointOut>
    - <expression>back_id</expression>
    - </inVariable>
    - <inVariable localId="12" height="35" width="85">
    - <position x="345" y="307"/>
    - <connectionPointOut>
    - <relPosition x="85" y="15"/>
    - </connectionPointOut>
    - <expression>sele_id</expression>
    - </inVariable>
    - <inVariable localId="13" height="35" width="100">
    - <position x="452" y="639"/>
    - <connectionPointOut>
    - <relPosition x="100" y="15"/>
    - </connectionPointOut>
    - <expression>set_state</expression>
    - </inVariable>
    - <block localId="28" width="140" height="40" typeName="GetBoolString" instanceName="GetButtonState">
    - <position x="239" y="897"/>
    - <inputVariables>
    - <variable formalParameter="VALUE">
    - <connectionPointIn>
    - <relPosition x="0" y="30"/>
    - <connection refLocalId="32">
    - <position x="239" y="927"/>
    - <position x="181" y="927"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="CODE">
    - <connectionPointOut>
    - <relPosition x="140" y="30"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <outVariable localId="29" height="30" width="53">
    - <position x="1015" y="127"/>
    - <connectionPointIn>
    - <relPosition x="0" y="15"/>
    - <connection refLocalId="1" formalParameter="RESULT">
    - <position x="1015" y="142"/>
    - <position x="963" y="142"/>
    - </connection>
    - </connectionPointIn>
    - <expression>ID</expression>
    - </outVariable>
    - <block localId="4" width="125" height="140" typeName="python_eval" instanceName="setstate_Command">
    - <position x="810" y="640"/>
    - <inputVariables>
    - <variable formalParameter="TRIG">
    - <connectionPointIn>
    - <relPosition x="0" y="50"/>
    - <connection refLocalId="31" formalParameter="OUT">
    - <position x="810" y="690"/>
    - <position x="762" y="690"/>
    - <position x="762" y="612"/>
    - <position x="710" y="612"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="CODE">
    - <connectionPointIn>
    - <relPosition x="0" y="110"/>
    - <connection refLocalId="7" formalParameter="OUT">
    - <position x="810" y="750"/>
    - <position x="643" y="750"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="ACK">
    - <connectionPointOut>
    - <relPosition x="125" y="50"/>
    - </connectionPointOut>
    - </variable>
    - <variable formalParameter="RESULT">
    - <connectionPointOut>
    - <relPosition x="125" y="110"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <connector name="CREATED" localId="30" height="30" width="110">
    - <position x="1014" y="67"/>
    - <connectionPointIn>
    - <relPosition x="0" y="15"/>
    - <connection refLocalId="1" formalParameter="ACK">
    - <position x="1014" y="82"/>
    - <position x="963" y="82"/>
    - </connection>
    - </connectionPointIn>
    - </connector>
    - <continuation name="CREATED" localId="6" height="30" width="110">
    - <position x="442" y="597"/>
    - <connectionPointOut>
    - <relPosition x="110" y="15"/>
    - </connectionPointOut>
    - </continuation>
    - <block localId="31" width="75" height="105" typeName="AND">
    - <position x="635" y="571"/>
    - <inputVariables>
    - <variable formalParameter="IN1">
    - <connectionPointIn>
    - <relPosition x="0" y="41"/>
    - <connection refLocalId="6">
    - <position x="635" y="612"/>
    - <position x="552" y="612"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN2">
    - <connectionPointIn>
    - <relPosition x="0" y="83"/>
    - <connection refLocalId="13">
    - <position x="635" y="654"/>
    - <position x="552" y="654"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="OUT">
    - <connectionPointOut>
    - <relPosition x="75" y="41"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <inVariable localId="32" height="30" width="90">
    - <position x="91" y="912"/>
    - <connectionPointOut>
    - <relPosition x="90" y="15"/>
    - </connectionPointOut>
    - <expression>state_in</expression>
    - </inVariable>
    - <outVariable localId="33" height="30" width="100">
    - <position x="1334" y="1184"/>
    - <connectionPointIn>
    - <relPosition x="0" y="15"/>
    - <connection refLocalId="26" formalParameter="OUT">
    - <position x="1334" y="1199"/>
    - <position x="1286" y="1199"/>
    - </connection>
    - </connectionPointIn>
    - <expression>state_out</expression>
    - </outVariable>
    - <block localId="7" width="150" height="319" typeName="CONCAT">
    - <position x="493" y="701"/>
    - <inputVariables>
    - <variable formalParameter="IN1">
    - <connectionPointIn>
    - <relPosition x="0" y="49"/>
    - <connection refLocalId="14">
    - <position x="493" y="750"/>
    - <position x="379" y="750"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN2">
    - <connectionPointIn>
    - <relPosition x="0" y="108"/>
    - <connection refLocalId="8">
    - <position x="493" y="809"/>
    - <position x="435" y="809"/>
    - <position x="435" y="803"/>
    - <position x="379" y="803"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN3">
    - <connectionPointIn>
    - <relPosition x="0" y="167"/>
    - <connection refLocalId="15">
    - <position x="493" y="868"/>
    - <position x="435" y="868"/>
    - <position x="435" y="855"/>
    - <position x="379" y="855"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN4">
    - <connectionPointIn>
    - <relPosition x="0" y="226"/>
    - <connection refLocalId="28" formalParameter="CODE">
    - <position x="493" y="927"/>
    - <position x="379" y="927"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN5">
    - <connectionPointIn>
    - <relPosition x="0" y="285"/>
    - <connection refLocalId="16">
    - <position x="493" y="986"/>
    - <position x="377" y="986"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="OUT">
    - <connectionPointOut>
    - <relPosition x="150" y="49"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <inVariable localId="8" height="30" width="53">
    - <position x="326" y="788"/>
    - <connectionPointOut>
    - <relPosition x="53" y="15"/>
    - </connectionPointOut>
    - <expression>ID</expression>
    - </inVariable>
    - <inVariable localId="14" height="30" width="120">
    - <position x="259" y="735"/>
    - <connectionPointOut>
    - <relPosition x="120" y="15"/>
    - </connectionPointOut>
    - <expression>'setAttr('</expression>
    - </inVariable>
    - <inVariable localId="15" height="30" width="122">
    - <position x="257" y="840"/>
    - <connectionPointOut>
    - <relPosition x="122" y="15"/>
    - </connectionPointOut>
    - <expression>',"state",'</expression>
    - </inVariable>
    - <inVariable localId="16" height="30" width="41">
    - <position x="336" y="971"/>
    - <connectionPointOut>
    - <relPosition x="41" y="15"/>
    - </connectionPointOut>
    - <expression>')'</expression>
    - </inVariable>
    - <block localId="17" width="125" height="140" typeName="python_poll" instanceName="getstate_Command">
    - <position x="801" y="1089"/>
    - <inputVariables>
    - <variable formalParameter="TRIG">
    - <connectionPointIn>
    - <relPosition x="0" y="50"/>
    - <connection refLocalId="18">
    - <position x="801" y="1139"/>
    - <position x="763" y="1139"/>
    - <position x="763" y="1099"/>
    - <position x="720" y="1099"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="CODE">
    - <connectionPointIn>
    - <relPosition x="0" y="110"/>
    - <connection refLocalId="22" formalParameter="OUT">
    - <position x="801" y="1199"/>
    - <position x="643" y="1199"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="ACK">
    - <connectionPointOut>
    - <relPosition x="125" y="50"/>
    - </connectionPointOut>
    - </variable>
    - <variable formalParameter="RESULT">
    - <connectionPointOut>
    - <relPosition x="125" y="110"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <block localId="25" width="145" height="45" typeName="STRING_TO_INT">
    - <position x="966" y="1169"/>
    - <inputVariables>
    - <variable formalParameter="IN">
    - <connectionPointIn>
    - <relPosition x="0" y="30"/>
    - <connection refLocalId="17" formalParameter="RESULT">
    - <position x="966" y="1199"/>
    - <position x="926" y="1199"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="OUT">
    - <connectionPointOut>
    - <relPosition x="145" y="30"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <block localId="26" width="125" height="45" typeName="INT_TO_BOOL">
    - <position x="1161" y="1169"/>
    - <inputVariables>
    - <variable formalParameter="IN">
    - <connectionPointIn>
    - <relPosition x="0" y="30"/>
    - <connection refLocalId="25" formalParameter="OUT">
    - <position x="1161" y="1199"/>
    - <position x="1111" y="1199"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="OUT">
    - <connectionPointOut>
    - <relPosition x="125" y="30"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <continuation name="CREATED" localId="18" height="30" width="110">
    - <position x="610" y="1084"/>
    - <connectionPointOut>
    - <relPosition x="110" y="15"/>
    - </connectionPointOut>
    - </continuation>
    - <inVariable localId="19" height="30" width="53">
    - <position x="383" y="1238"/>
    - <connectionPointOut>
    - <relPosition x="53" y="15"/>
    - </connectionPointOut>
    - <expression>ID</expression>
    - </inVariable>
    - <inVariable localId="20" height="30" width="150">
    - <position x="286" y="1184"/>
    - <connectionPointOut>
    - <relPosition x="150" y="15"/>
    - </connectionPointOut>
    - <expression>'int(getAttr('</expression>
    - </inVariable>
    - <inVariable localId="21" height="30" width="190">
    - <position x="246" y="1292"/>
    - <connectionPointOut>
    - <relPosition x="190" y="15"/>
    - </connectionPointOut>
    - <expression>',"state",False))'</expression>
    - </inVariable>
    - <block localId="22" width="150" height="183" typeName="CONCAT">
    - <position x="493" y="1152"/>
    - <inputVariables>
    - <variable formalParameter="IN1">
    - <connectionPointIn>
    - <relPosition x="0" y="47"/>
    - <connection refLocalId="20">
    - <position x="493" y="1199"/>
    - <position x="436" y="1199"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN2">
    - <connectionPointIn>
    - <relPosition x="0" y="101"/>
    - <connection refLocalId="19">
    - <position x="493" y="1253"/>
    - <position x="436" y="1253"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN3">
    - <connectionPointIn>
    - <relPosition x="0" y="155"/>
    - <connection refLocalId="21">
    - <position x="493" y="1307"/>
    - <position x="483" y="1307"/>
    - <position x="483" y="1307"/>
    - <position x="436" y="1307"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="OUT">
    - <connectionPointOut>
    - <relPosition x="150" y="47"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <inVariable localId="23" height="30" width="130">
    - <position x="300" y="355"/>
    - <connectionPointOut>
    - <relPosition x="130" y="15"/>
    - </connectionPointOut>
    - <expression>'",toggle='</expression>
    - </inVariable>
    - <block localId="24" width="140" height="40" typeName="GetBoolString" instanceName="GetButtonToggle">
    - <position x="289" y="412"/>
    - <inputVariables>
    - <variable formalParameter="VALUE">
    - <connectionPointIn>
    - <relPosition x="0" y="30"/>
    - <connection refLocalId="27">
    - <position x="289" y="442"/>
    - <position x="220" y="442"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="CODE">
    - <connectionPointOut>
    - <relPosition x="140" y="30"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <inVariable localId="27" height="30" width="90">
    - <position x="130" y="427"/>
    - <connectionPointOut>
    - <relPosition x="90" y="15"/>
    - </connectionPointOut>
    - <expression>toggle</expression>
    - </inVariable>
    - </FBD>
    - </body>
    - </pou>
    - <pou name="Led" pouType="functionBlock">
    - <interface>
    - <localVars>
    - <variable name="ID">
    - <type>
    - <string/>
    - </type>
    - </variable>
    - </localVars>
    - <inputVars>
    - <variable name="back_id">
    - <type>
    - <string/>
    - </type>
    - </variable>
    - <variable name="sele_id">
    - <type>
    - <string/>
    - </type>
    - </variable>
    - <variable name="state_in">
    - <type>
    - <BOOL/>
    - </type>
    - </variable>
    - </inputVars>
    - <localVars>
    - <variable name="init_Command">
    - <type>
    - <derived name="python_eval"/>
    - </type>
    - </variable>
    - <variable name="setstate_Command">
    - <type>
    - <derived name="python_poll"/>
    - </type>
    - </variable>
    - <variable name="GetLedState">
    - <type>
    - <derived name="GetBoolString"/>
    - </type>
    - </variable>
    - </localVars>
    - </interface>
    - <body>
    - <FBD>
    - <block localId="1" width="125" height="140" typeName="python_eval" instanceName="init_Command">
    - <position x="810" y="30"/>
    - <inputVariables>
    - <variable formalParameter="TRIG">
    - <connectionPointIn>
    - <relPosition x="0" y="50"/>
    - <connection refLocalId="10">
    - <position x="810" y="80"/>
    - <position x="753" y="80"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="CODE">
    - <connectionPointIn>
    - <relPosition x="0" y="110"/>
    - <connection refLocalId="2" formalParameter="OUT">
    - <position x="810" y="140"/>
    - <position x="640" y="140"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="ACK">
    - <connectionPointOut>
    - <relPosition x="125" y="50"/>
    - </connectionPointOut>
    - </variable>
    - <variable formalParameter="RESULT">
    - <connectionPointOut>
    - <relPosition x="125" y="110"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <block localId="2" width="150" height="322" typeName="CONCAT">
    - <position x="490" y="90"/>
    - <inputVariables>
    - <variable formalParameter="IN1">
    - <connectionPointIn>
    - <relPosition x="0" y="50"/>
    - <connection refLocalId="3">
    - <position x="490" y="140"/>
    - <position x="415" y="140"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN2">
    - <connectionPointIn>
    - <relPosition x="0" y="110"/>
    - <connection refLocalId="11">
    - <position x="490" y="200"/>
    - <position x="415" y="200"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN3">
    - <connectionPointIn>
    - <relPosition x="0" y="170"/>
    - <connection refLocalId="5">
    - <position x="490" y="260"/>
    - <position x="415" y="260"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN4">
    - <connectionPointIn>
    - <relPosition x="0" y="230"/>
    - <connection refLocalId="12">
    - <position x="490" y="320"/>
    - <position x="414" y="320"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN5">
    - <connectionPointIn>
    - <relPosition x="0" y="290"/>
    - <connection refLocalId="9">
    - <position x="490" y="380"/>
    - <position x="414" y="380"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="OUT">
    - <connectionPointOut>
    - <relPosition x="150" y="50"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <inVariable localId="3" height="30" width="400">
    - <position x="15" y="125"/>
    - <connectionPointOut>
    - <relPosition x="400" y="15"/>
    - </connectionPointOut>
    - <expression>'createSVGUIControl("button",back_id="'</expression>
    - </inVariable>
    - <block localId="4" width="125" height="140" typeName="python_poll" instanceName="setstate_Command">
    - <position x="782" y="536"/>
    - <inputVariables>
    - <variable formalParameter="TRIG">
    - <connectionPointIn>
    - <relPosition x="0" y="50"/>
    - <connection refLocalId="6">
    - <position x="782" y="586"/>
    - <position x="653" y="586"/>
    - <position x="653" y="552"/>
    - <position x="602" y="552"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="CODE">
    - <connectionPointIn>
    - <relPosition x="0" y="110"/>
    - <connection refLocalId="7" formalParameter="OUT">
    - <position x="782" y="646"/>
    - <position x="615" y="646"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="ACK">
    - <connectionPointOut>
    - <relPosition x="125" y="50"/>
    - </connectionPointOut>
    - </variable>
    - <variable formalParameter="RESULT">
    - <connectionPointOut>
    - <relPosition x="125" y="110"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <inVariable localId="5" height="30" width="140">
    - <position x="275" y="245"/>
    - <connectionPointOut>
    - <relPosition x="140" y="15"/>
    - </connectionPointOut>
    - <expression>'",sele_id="'</expression>
    - </inVariable>
    - <continuation name="CREATED" localId="6" height="30" width="110">
    - <position x="492" y="537"/>
    - <connectionPointOut>
    - <relPosition x="110" y="15"/>
    - </connectionPointOut>
    - </continuation>
    - <block localId="7" width="150" height="319" typeName="CONCAT">
    - <position x="465" y="597"/>
    - <inputVariables>
    - <variable formalParameter="IN1">
    - <connectionPointIn>
    - <relPosition x="0" y="49"/>
    - <connection refLocalId="14">
    - <position x="465" y="646"/>
    - <position x="351" y="646"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN2">
    - <connectionPointIn>
    - <relPosition x="0" y="108"/>
    - <connection refLocalId="8">
    - <position x="465" y="705"/>
    - <position x="407" y="705"/>
    - <position x="407" y="699"/>
    - <position x="351" y="699"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN3">
    - <connectionPointIn>
    - <relPosition x="0" y="167"/>
    - <connection refLocalId="15">
    - <position x="465" y="764"/>
    - <position x="407" y="764"/>
    - <position x="407" y="751"/>
    - <position x="351" y="751"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN4">
    - <connectionPointIn>
    - <relPosition x="0" y="226"/>
    - <connection refLocalId="28" formalParameter="CODE">
    - <position x="465" y="823"/>
    - <position x="351" y="823"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - <variable formalParameter="IN5">
    - <connectionPointIn>
    - <relPosition x="0" y="285"/>
    - <connection refLocalId="16">
    - <position x="465" y="882"/>
    - <position x="407" y="882"/>
    - <position x="407" y="883"/>
    - <position x="351" y="883"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="OUT">
    - <connectionPointOut>
    - <relPosition x="150" y="49"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <inVariable localId="8" height="30" width="53">
    - <position x="298" y="684"/>
    - <connectionPointOut>
    - <relPosition x="53" y="15"/>
    - </connectionPointOut>
    - <expression>ID</expression>
    - </inVariable>
    - <inVariable localId="9" height="30" width="300">
    - <position x="124" y="365"/>
    - <connectionPointOut>
    - <relPosition x="300" y="15"/>
    - </connectionPointOut>
    - <expression>'",toggle=True,active=False)'</expression>
    - </inVariable>
    - <inVariable localId="10" height="30" width="70">
    - <position x="683" y="65"/>
    - <connectionPointOut>
    - <relPosition x="70" y="15"/>
    - </connectionPointOut>
    - <expression>BOOL#1</expression>
    - </inVariable>
    - <inVariable localId="11" height="35" width="85">
    - <position x="330" y="185"/>
    - <connectionPointOut>
    - <relPosition x="85" y="15"/>
    - </connectionPointOut>
    - <expression>back_id</expression>
    - </inVariable>
    - <inVariable localId="12" height="35" width="85">
    - <position x="329" y="305"/>
    - <connectionPointOut>
    - <relPosition x="85" y="15"/>
    - </connectionPointOut>
    - <expression>sele_id</expression>
    - </inVariable>
    - <inVariable localId="14" height="30" width="120">
    - <position x="231" y="631"/>
    - <connectionPointOut>
    - <relPosition x="120" y="15"/>
    - </connectionPointOut>
    - <expression>'setAttr('</expression>
    - </inVariable>
    - <inVariable localId="15" height="30" width="122">
    - <position x="229" y="736"/>
    - <connectionPointOut>
    - <relPosition x="122" y="15"/>
    - </connectionPointOut>
    - <expression>',"state",'</expression>
    - </inVariable>
    - <inVariable localId="16" height="30" width="41">
    - <position x="310" y="868"/>
    - <connectionPointOut>
    - <relPosition x="41" y="15"/>
    - </connectionPointOut>
    - <expression>')'</expression>
    - </inVariable>
    - <block localId="28" width="140" height="40" typeName="GetBoolString" instanceName="GetLedState">
    - <position x="211" y="793"/>
    - <inputVariables>
    - <variable formalParameter="VALUE">
    - <connectionPointIn>
    - <relPosition x="0" y="30"/>
    - <connection refLocalId="32">
    - <position x="211" y="823"/>
    - <position x="153" y="823"/>
    - </connection>
    - </connectionPointIn>
    - </variable>
    - </inputVariables>
    - <inOutVariables/>
    - <outputVariables>
    - <variable formalParameter="CODE">
    - <connectionPointOut>
    - <relPosition x="140" y="30"/>
    - </connectionPointOut>
    - </variable>
    - </outputVariables>
    - </block>
    - <outVariable localId="29" height="30" width="53">
    - <position x="987" y="125"/>
    - <connectionPointIn>
    - <relPosition x="0" y="15"/>
    - <connection refLocalId="1" formalParameter="RESULT">
    - <position x="987" y="140"/>
    - <position x="935" y="140"/>
    - </connection>
    - </connectionPointIn>
    - <expression>ID</expression>
    - </outVariable>
    - <connector name="CREATED" localId="30" height="30" width="110">
    - <position x="986" y="65"/>
    - <connectionPointIn>
    - <relPosition x="0" y="15"/>
    - <connection refLocalId="1" formalParameter="ACK">
    - <position x="986" y="80"/>
    - <position x="935" y="80"/>
    - </connection>
    - </connectionPointIn>
    - </connector>
    - <inVariable localId="32" height="30" width="90">
    - <position x="63" y="808"/>
    - <connectionPointOut>
    - <relPosition x="90" y="15"/>
    - </connectionPointOut>
    - <expression>state_in</expression>
    - </inVariable>
    - </FBD>
    - </body>
    - </pou>
    - </pous>
    - </types>
    - <instances>
    - <configurations/>
    - </instances>
    -</project>
    --- a/py_ext/modules/svgui/pyjs/__init__.py Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,2 +0,0 @@
    -from pyjs import *
    -
    --- a/py_ext/modules/svgui/pyjs/build.py Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,724 +0,0 @@
    -#!/usr/bin/env python
    -
    -import sys
    -import os
    -import shutil
    -from copy import copy
    -from os.path import join, dirname, basename, abspath, split, isfile, isdir
    -from optparse import OptionParser
    -import pyjs
    -from cStringIO import StringIO
    -try:
    - # Python 2.5 and above
    - from hashlib import md5
    -except:
    - import md5
    -import re
    -
    -usage = """
    - usage: %prog [options] <application module name or path>
    -
    -This is the command line builder for the pyjamas project, which can
    -be used to build Ajax applications from Python.
    -For more information, see the website at http://pyjs.org/
    -"""
    -
    -# GWT1.2 Impl | GWT1.2 Output | Pyjamas 0.2 Platform | Pyjamas 0.2 Output
    -# -------------+-----------------------+----------------------+----------------------
    -# IE6 | ie6 | IE6 | ie6
    -# Opera | opera | Opera | opera
    -# Safari | safari | Safari | safari
    -# -- | gecko1_8 | Mozilla | mozilla
    -# -- | gecko | OldMoz | oldmoz
    -# Standard | all | (default code) | all
    -# Mozilla | gecko1_8, gecko | -- | --
    -# Old | safari, gecko, opera | -- | --
    -
    -version = "%prog pyjamas version 2006-08-19"
    -
    -# these names in lowercase need match the strings
    -# returned by "provider$user.agent" in order to be selected corretly
    -app_platforms = ['IE6', 'Opera', 'OldMoz', 'Safari', 'Mozilla']
    -
    -# usually defaults to e.g. /usr/share/pyjamas
    -_data_dir = os.path.join(pyjs.prefix, "share/pyjamas")
    -
    -
    -# .cache.html files produces look like this
    -CACHE_HTML_PAT=re.compile('^[a-z]*.[0-9a-f]{32}\.cache\.html$')
    -
    -# ok these are the three "default" library directories, containing
    -# the builtins (str, List, Dict, ord, round, len, range etc.)
    -# the main pyjamas libraries (pyjamas.ui, pyjamas.Window etc.)
    -# and the contributed addons
    -
    -for p in ["library/builtins",
    - "library",
    - "addons"]:
    - p = os.path.join(_data_dir, p)
    - if os.path.isdir(p):
    - pyjs.path.append(p)
    -
    -
    -def read_boilerplate(data_dir, filename):
    - return open(join(data_dir, "builder/boilerplate", filename)).read()
    -
    -def copy_boilerplate(data_dir, filename, output_dir):
    - filename = join(data_dir, "builder/boilerplate", filename)
    - shutil.copy(filename, output_dir)
    -
    -
    -# taken and modified from python2.4
    -def copytree_exists(src, dst, symlinks=False):
    - if not os.path.exists(src):
    - return
    -
    - names = os.listdir(src)
    - try:
    - os.mkdir(dst)
    - except:
    - pass
    -
    - errors = []
    - for name in names:
    - if name.startswith('CVS'):
    - continue
    - if name.startswith('.git'):
    - continue
    - if name.startswith('.svn'):
    - continue
    -
    - srcname = os.path.join(src, name)
    - dstname = os.path.join(dst, name)
    - try:
    - if symlinks and os.path.islink(srcname):
    - linkto = os.readlink(srcname)
    - os.symlink(linkto, dstname)
    - elif isdir(srcname):
    - copytree_exists(srcname, dstname, symlinks)
    - else:
    - shutil.copy2(srcname, dstname)
    - except (IOError, os.error), why:
    - errors.append((srcname, dstname, why))
    - if errors:
    - print errors
    -
    -def check_html_file(source_file, dest_path):
    - """ Checks if a base HTML-file is available in the PyJamas
    - output directory.
    - If the HTML-file isn't available, it will be created.
    -
    - If a CSS-file with the same name is available
    - in the output directory, a reference to this CSS-file
    - is included.
    -
    - If no CSS-file is found, this function will look for a special
    - CSS-file in the output directory, with the name
    - "pyjamas_default.css", and if found it will be referenced
    - in the generated HTML-file.
    -
    - [thank you to stef mientki for contributing this function]
    - """
    -
    - base_html = """\
    -<html>
    - <!-- auto-generated html - you should consider editing and
    - adapting this to suit your requirements
    - -->
    - <head>
    - <meta name="pygwt:module" content="%(modulename)s">
    - %(css)s
    - <title>%(title)s</title>
    - </head>
    - <body bgcolor="white">
    - <script language="javascript" src="pygwt.js"></script>
    - </body>
    -</html>
    -"""
    -
    - filename = os.path.split ( source_file )[1]
    - mod_name = os.path.splitext ( filename )[0]
    - file_name = os.path.join ( dest_path, mod_name + '.html' )
    -
    - # if html file in output directory exists, leave it alone.
    - if os.path.exists ( file_name ):
    - return 0
    -
    - if os.path.exists (
    - os.path.join ( dest_path, mod_name + '.css' ) ) :
    - css = "<link rel='stylesheet' href='" + mod_name + ".css'>"
    - elif os.path.exists (
    - os.path.join ( dest_path, 'pyjamas_default.css' ) ) :
    - css = "<link rel='stylesheet' href='pyjamas_default.css'>"
    -
    - else:
    - css = ''
    -
    - title = 'PyJamas Auto-Generated HTML file ' + mod_name
    -
    - base_html = base_html % {'modulename': mod_name, 'title': title, 'css': css}
    -
    - fh = open (file_name, 'w')
    - fh.write (base_html)
    - fh.close ()
    -
    - return 1
    -
    -
    -def build(app_name, output, js_includes=(), debug=False, dynamic=0,
    - data_dir=None, cache_buster=False, optimize=False):
    -
    - # make sure the output directory is always created in the current working
    - # directory or at the place given if it is an absolute path.
    - output = os.path.abspath(output)
    - msg = "Building '%(app_name)s' to output directory '%(output)s'" % locals()
    - if debug:
    - msg += " with debugging statements"
    - print msg
    -
    - # check the output directory
    - if os.path.exists(output) and not os.path.isdir(output):
    - print >>sys.stderr, "Output destination %s exists and is not a directory" % output
    - return
    - if not os.path.isdir(output):
    - try:
    - print "Creating output directory"
    - os.mkdir(output)
    - except StandardError, e:
    - print >>sys.stderr, "Exception creating output directory %s: %s" % (output, e)
    -
    - ## public dir
    - for p in pyjs.path:
    - pub_dir = join(p, 'public')
    - if isdir(pub_dir):
    - print "Copying: public directory of library %r" % p
    - copytree_exists(pub_dir, output)
    -
    - ## AppName.html - can be in current or public directory
    - html_input_filename = app_name + ".html"
    - html_output_filename = join(output, basename(html_input_filename))
    - if os.path.isfile(html_input_filename):
    - if not os.path.isfile(html_output_filename) or \
    - os.path.getmtime(html_input_filename) > \
    - os.path.getmtime(html_output_filename):
    - try:
    - shutil.copy(html_input_filename, html_output_filename)
    - except:
    - print >>sys.stderr, "Warning: Missing module HTML file %s" % html_input_filename
    -
    - print "Copying: %(html_input_filename)s" % locals()
    -
    - if check_html_file(html_input_filename, output):
    - print >>sys.stderr, "Warning: Module HTML file %s has been auto-generated" % html_input_filename
    -
    - ## pygwt.js
    -
    - print "Copying: pygwt.js"
    -
    - pygwt_js_template = read_boilerplate(data_dir, "pygwt.js")
    - pygwt_js_output = open(join(output, "pygwt.js"), "w")
    -
    - print >>pygwt_js_output, pygwt_js_template
    -
    - pygwt_js_output.close()
    -
    - ## Images
    -
    - print "Copying: Images and History"
    - copy_boilerplate(data_dir, "corner_dialog_topleft_black.png", output)
    - copy_boilerplate(data_dir, "corner_dialog_topright_black.png", output)
    - copy_boilerplate(data_dir, "corner_dialog_bottomright_black.png", output)
    - copy_boilerplate(data_dir, "corner_dialog_bottomleft_black.png", output)
    - copy_boilerplate(data_dir, "corner_dialog_edge_black.png", output)
    - copy_boilerplate(data_dir, "corner_dialog_topleft.png", output)
    - copy_boilerplate(data_dir, "corner_dialog_topright.png", output)
    - copy_boilerplate(data_dir, "corner_dialog_bottomright.png", output)
    - copy_boilerplate(data_dir, "corner_dialog_bottomleft.png", output)
    - copy_boilerplate(data_dir, "corner_dialog_edge.png", output)
    - copy_boilerplate(data_dir, "tree_closed.gif", output)
    - copy_boilerplate(data_dir, "tree_open.gif", output)
    - copy_boilerplate(data_dir, "tree_white.gif", output)
    - copy_boilerplate(data_dir, "history.html", output)
    -
    -
    - ## all.cache.html
    - app_files = generateAppFiles(data_dir, js_includes, app_name, debug,
    - output, dynamic, cache_buster, optimize)
    -
    - ## AppName.nocache.html
    -
    - print "Creating: %(app_name)s.nocache.html" % locals()
    -
    - home_nocache_html_template = read_boilerplate(data_dir, "home.nocache.html")
    - home_nocache_html_output = open(join(output, app_name + ".nocache.html"),
    - "w")
    -
    - # the selector templ is added to the selectScript function
    - select_tmpl = """O(["true","%s"],"%s");"""
    - script_selectors = StringIO()
    -
    - for platform, file_prefix in app_files:
    - print >> script_selectors, select_tmpl % (platform, file_prefix)
    -
    - print >>home_nocache_html_output, home_nocache_html_template % dict(
    - app_name = app_name,
    - script_selectors = script_selectors.getvalue(),
    - )
    -
    - home_nocache_html_output.close()
    -
    - print "Done. You can run your app by opening '%(html_output_filename)s' in a browser" % locals()
    -
    -
    -def generateAppFiles(data_dir, js_includes, app_name, debug, output, dynamic,
    - cache_buster, optimize):
    -
    - all_cache_html_template = read_boilerplate(data_dir, "all.cache.html")
    - mod_cache_html_template = read_boilerplate(data_dir, "mod.cache.html")
    -
    - # clean out the old ones first
    - for name in os.listdir(output):
    - if CACHE_HTML_PAT.match(name):
    - p = join(output, name)
    - print "Deleting existing app file %s" % p
    - os.unlink(p)
    -
    - app_files = []
    - tmpl = read_boilerplate(data_dir, "all.cache.html")
    - parser = pyjs.PlatformParser("platform")
    - app_headers = ''
    - scripts = ['<script type="text/javascript" src="%s"></script>'%script \
    - for script in js_includes]
    - app_body = '\n'.join(scripts)
    -
    - mod_code = {}
    - mod_libs = {}
    - modules = {}
    - app_libs = {}
    - early_app_libs = {}
    - app_code = {}
    - overrides = {}
    - pover = {}
    - app_modnames = {}
    - mod_levels = {}
    -
    - # First, generate all the code.
    - # Second, (dynamic only), post-analyse the places where modules
    - # haven't changed
    - # Third, write everything out.
    -
    - for platform in app_platforms:
    -
    - mod_code[platform] = {}
    - mod_libs[platform] = {}
    - modules[platform] = []
    - pover[platform] = {}
    - app_libs[platform] = ''
    - early_app_libs[platform] = ''
    - app_code[platform] = {}
    - app_modnames[platform] = {}
    -
    - # Application.Platform.cache.html
    -
    - parser.setPlatform(platform)
    - app_translator = pyjs.AppTranslator(
    - parser=parser, dynamic=dynamic, optimize=optimize)
    - early_app_libs[platform], appcode = \
    - app_translator.translate(None, is_app=False,
    - debug=debug,
    - library_modules=['dynamicajax.js',
    - '_pyjs.js', 'sys',
    - 'pyjslib'])
    - pover[platform].update(app_translator.overrides.items())
    - for mname, name in app_translator.overrides.items():
    - pd = overrides.setdefault(mname, {})
    - pd[platform] = name
    -
    - print appcode
    - #mod_code[platform][app_name] = appcode
    -
    - # platform.Module.cache.js
    -
    - modules_done = ['pyjslib', 'sys', '_pyjs.js']
    - #modules_to_do = [app_name] + app_translator.library_modules
    - modules_to_do = [app_name] + app_translator.library_modules
    -
    - dependencies = {}
    -
    - deps = map(pyjs.strip_py, modules_to_do)
    - for d in deps:
    - sublist = add_subdeps(dependencies, d)
    - modules_to_do += sublist
    - deps = uniquify(deps)
    - #dependencies[app_name] = deps
    -
    - modules[platform] = modules_done + modules_to_do
    -
    - while modules_to_do:
    -
    - #print "modules to do", modules_to_do
    -
    - mn = modules_to_do.pop()
    - mod_name = pyjs.strip_py(mn)
    -
    - if mod_name in modules_done:
    - continue
    -
    - modules_done.append(mod_name)
    -
    - mod_cache_name = "%s.%s.cache.js" % (platform.lower(), mod_name)
    -
    - parser.setPlatform(platform)
    - mod_translator = pyjs.AppTranslator(parser=parser, optimize=optimize)
    - mod_libs[platform][mod_name], mod_code[platform][mod_name] = \
    - mod_translator.translate(mod_name,
    - is_app=False,
    - debug=debug)
    - pover[platform].update(mod_translator.overrides.items())
    - for mname, name in mod_translator.overrides.items():
    - pd = overrides.setdefault(mname, {})
    - pd[platform] = name
    -
    - mods = mod_translator.library_modules
    - modules_to_do += mods
    - modules[platform] += mods
    -
    - deps = map(pyjs.strip_py, mods)
    - sd = subdeps(mod_name)
    - if len(sd) > 1:
    - deps += sd[:-1]
    - while mod_name in deps:
    - deps.remove(mod_name)
    -
    - #print
    - #print
    - #print "modname preadd:", mod_name, deps
    - #print
    - #print
    - for d in deps:
    - sublist = add_subdeps(dependencies, d)
    - modules_to_do += sublist
    - modules_to_do += add_subdeps(dependencies, mod_name)
    - #print "modname:", mod_name, deps
    - deps = uniquify(deps)
    - #print "modname:", mod_name, deps
    - dependencies[mod_name] = deps
    -
    - # work out the dependency ordering of the modules
    -
    - mod_levels[platform] = make_deps(None, dependencies, modules_done)
    -
    - # now write everything out
    -
    - for platform in app_platforms:
    -
    - early_app_libs_ = early_app_libs[platform]
    - app_libs_ = app_libs[platform]
    - app_code_ = app_code[platform]
    - #modules_ = filter_mods(app_name, modules[platform])
    - mods = flattenlist(mod_levels[platform])
    - mods.reverse()
    - modules_ = filter_mods(None, mods)
    -
    - for mod_name in modules_:
    -
    - mod_code_ = mod_code[platform][mod_name]
    -
    - mod_name = pyjs.strip_py(mod_name)
    -
    - override_name = "%s.%s" % (platform.lower(), mod_name)
    - if pover[platform].has_key(override_name):
    - mod_cache_name = "%s.cache.js" % (override_name)
    - else:
    - mod_cache_name = "%s.cache.js" % (mod_name)
    -
    - print "Creating: " + mod_cache_name
    -
    - modlevels = make_deps(None, dependencies, dependencies[mod_name])
    -
    - modnames = []
    -
    - for md in modlevels:
    - mnames = map(lambda x: "'%s'" % x, md)
    - mnames = "new pyjslib.List([\n\t\t\t%s])" % ',\n\t\t\t'.join(mnames)
    - modnames.append(mnames)
    -
    - modnames.reverse()
    - modnames = "new pyjslib.List([\n\t\t%s\n\t])" % ',\n\t\t'.join(modnames)
    -
    - # convert the overrides
    -
    - overnames = map(lambda x: "'%s': '%s'" % x, pover[platform].items())
    - overnames = "new pyjslib.Dict({\n\t\t%s\n\t})" % ',\n\t\t'.join(overnames)
    -
    - if dynamic:
    - mod_cache_html_output = open(join(output, mod_cache_name), "w")
    - else:
    - mod_cache_html_output = StringIO()
    -
    - print >>mod_cache_html_output, mod_cache_html_template % dict(
    - mod_name = mod_name,
    - app_name = app_name,
    - modnames = modnames,
    - overrides = overnames,
    - mod_libs = mod_libs[platform][mod_name],
    - dynamic = dynamic,
    - mod_code = mod_code_,
    - )
    -
    - if dynamic:
    - mod_cache_html_output.close()
    - else:
    - mod_cache_html_output.seek(0)
    - app_libs_ += mod_cache_html_output.read()
    -
    - # write out the dependency ordering of the modules
    -
    - app_modnames = []
    -
    - for md in mod_levels[platform]:
    - mnames = map(lambda x: "'%s'" % x, md)
    - mnames = "new pyjslib.List([\n\t\t\t%s])" % ',\n\t\t\t'.join(mnames)
    - app_modnames.append(mnames)
    -
    - app_modnames.reverse()
    - app_modnames = "new pyjslib.List([\n\t\t%s\n\t])" % ',\n\t\t'.join(app_modnames)
    -
    - # convert the overrides
    -
    - overnames = map(lambda x: "'%s': '%s'" % x, pover[platform].items())
    - overnames = "new pyjslib.Dict({\n\t\t%s\n\t})" % ',\n\t\t'.join(overnames)
    -
    - #print "platform names", platform, overnames
    - #print pover
    -
    - # now write app.allcache including dependency-ordered list of
    - # library modules
    -
    - file_contents = all_cache_html_template % dict(
    - app_name = app_name,
    - early_app_libs = early_app_libs_,
    - app_libs = app_libs_,
    - app_code = app_code_,
    - app_body = app_body,
    - overrides = overnames,
    - platform = platform.lower(),
    - dynamic = dynamic,
    - app_modnames = app_modnames,
    - app_headers = app_headers
    - )
    - if cache_buster:
    - digest = md5.new(file_contents).hexdigest()
    - file_name = "%s.%s.%s" % (platform.lower(), app_name, digest)
    - else:
    - file_name = "%s.%s" % (platform.lower(), app_name)
    - file_name += ".cache.html"
    - out_path = join(output, file_name)
    - out_file = open(out_path, 'w')
    - out_file.write(file_contents)
    - out_file.close()
    - app_files.append((platform.lower(), file_name))
    - print "Created app file %s:%s: %s" % (
    - app_name, platform, out_path)
    -
    - return app_files
    -
    -def flattenlist(ll):
    - res = []
    - for l in ll:
    - res += l
    - return res
    -
    -# creates sub-dependencies e.g. pyjamas.ui.Widget
    -# creates pyjamas.ui.Widget, pyjamas.ui and pyjamas.
    -def subdeps(m):
    - d = []
    - m = m.split(".")
    - for i in range(0, len(m)):
    - d.append('.'.join(m[:i+1]))
    - return d
    -
    -import time
    -
    -def add_subdeps(deps, mod_name):
    - sd = subdeps(mod_name)
    - if len(sd) == 1:
    - return []
    - #print "subdeps", mod_name, sd
    - #print "deps", deps
    - res = []
    - for i in range(0, len(sd)-1):
    - parent = sd[i]
    - child = sd[i+1]
    - l = deps.get(child, [])
    - l.append(parent)
    - deps[child] = l
    - if parent not in res:
    - res.append(parent)
    - #print deps
    - return res
    -
    -# makes unique and preserves list order
    -def uniquify(md):
    - res = []
    - for m in md:
    - if m not in res:
    - res.append(m)
    - return res
    -
    -def filter_mods(app_name, md):
    - while 'sys' in md:
    - md.remove('sys')
    - while 'pyjslib' in md:
    - md.remove('pyjslib')
    - while app_name in md:
    - md.remove(app_name)
    - md = filter(lambda x: not x.endswith('.js'), md)
    - md = map(pyjs.strip_py, md)
    -
    - return uniquify(md)
    -
    -def filter_deps(app_name, deps):
    -
    - res = {}
    - for (k, l) in deps.items():
    - mods = filter_mods(k, l)
    - while k in mods:
    - mods.remove(k)
    - res[k] = mods
    - return res
    -
    -def has_nodeps(mod, deps):
    - if not deps.has_key(mod) or not deps[mod]:
    - return True
    - return False
    -
    -def nodeps_list(mod_list, deps):
    - res = []
    - for mod in mod_list:
    - if has_nodeps(mod, deps):
    - res.append(mod)
    - return res
    -
    -# this function takes a dictionary of dependent modules and
    -# creates a list of lists. the first list will be modules
    -# that have no dependencies; the second list will be those
    -# modules that have the first list as dependencies; the
    -# third will be those modules that have the first and second...
    -# etc.
    -
    -
    -def make_deps(app_name, deps, mod_list):
    - print "Calculating Dependencies ..."
    - mod_list = filter_mods(app_name, mod_list)
    - deps = filter_deps(app_name, deps)
    -
    - if not mod_list:
    - return []
    -
    - #print mod_list
    - #print deps
    -
    - ordered_deps = []
    - last_len = -1
    - while deps:
    - l_deps = len(deps)
    - #print l_deps
    - if l_deps==last_len:
    - for m, dl in deps.items():
    - for d in dl:
    - if m in deps.get(d, []):
    - raise Exception('Circular Imports found: \n%s %s -> %s %s'
    - % (m, dl, d, deps[d]))
    - #raise Exception('Could not calculate dependencies: \n%s' % deps)
    - break
    - last_len = l_deps
    - #print "modlist", mod_list
    - nodeps = nodeps_list(mod_list, deps)
    - #print "nodeps", nodeps
    - mod_list = filter(lambda x: x not in nodeps, mod_list)
    - newdeps = {}
    - for k in deps.keys():
    - depslist = deps[k]
    - depslist = filter(lambda x: x not in nodeps, depslist)
    - if depslist:
    - newdeps[k] = depslist
    - #print "newdeps", newdeps
    - deps = newdeps
    - ordered_deps.append(nodeps)
    - #time.sleep(0)
    -
    - if mod_list:
    - ordered_deps.append(mod_list) # last dependencies - usually the app(s)
    -
    - ordered_deps.reverse()
    -
    - return ordered_deps
    -
    -def main():
    - global app_platforms
    -
    - parser = OptionParser(usage = usage, version = version)
    - parser.add_option("-o", "--output", dest="output",
    - help="directory to which the webapp should be written")
    - parser.add_option("-j", "--include-js", dest="js_includes", action="append",
    - help="javascripts to load into the same frame as the rest of the script")
    - parser.add_option("-I", "--library_dir", dest="library_dirs",
    - action="append", help="additional paths appended to PYJSPATH")
    - parser.add_option("-D", "--data_dir", dest="data_dir",
    - help="path for data directory")
    - parser.add_option("-m", "--dynamic-modules", action="store_true",
    - dest="dynamic", default=False,
    - help="Split output into separate dynamically-loaded modules (experimental)")
    - parser.add_option("-P", "--platforms", dest="platforms",
    - help="platforms to build for, comma-separated")
    - parser.add_option("-d", "--debug", action="store_true", dest="debug")
    - parser.add_option("-O", "--optimize", action="store_true",
    - dest="optimize", default=False,
    - help="Optimize generated code (removes all print statements)",
    - )
    - parser.add_option("-c", "--cache_buster", action="store_true",
    - dest="cache_buster",
    - help="Enable browser cache-busting (MD5 hash added to output filenames)")
    -
    - parser.set_defaults(output = "output", js_includes=[], library_dirs=[],
    - platforms=(','.join(app_platforms)),
    - data_dir=os.path.join(sys.prefix, "share/pyjamas"),
    - dynamic=False,
    - cache_buster=False,
    - debug=False)
    - (options, args) = parser.parse_args()
    - if len(args) != 1:
    - parser.error("incorrect number of arguments")
    -
    - data_dir = abspath(options.data_dir)
    -
    - app_path = args[0]
    - if app_path.endswith('.py'):
    - app_path = abspath(app_path)
    - if not isfile(app_path):
    - parser.error("Application file not found %r" % app_path)
    - app_path, app_name = split(app_path)
    - app_name = app_name[:-3]
    - pyjs.path.append(app_path)
    - elif os.path.sep in app_path:
    - parser.error("Not a valid module declaration %r" % app_path)
    - else:
    - app_name = app_path
    -
    - for d in options.library_dirs:
    - pyjs.path.append(abspath(d))
    -
    - if options.platforms:
    - app_platforms = options.platforms.split(',')
    -
    - # this is mostly for getting boilerplate stuff
    - data_dir = os.path.abspath(options.data_dir)
    -
    - build(app_name, options.output, options.js_includes,
    - options.debug, options.dynamic and 1 or 0, data_dir,
    - options.cache_buster, options.optimize)
    -
    -if __name__ == "__main__":
    - main()
    -
    --- a/py_ext/modules/svgui/pyjs/jsonrpc/README.txt Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,12 +0,0 @@
    -These classes are intended for use server-side.
    -
    -e.g. in a django view.py :
    -
    - from pyjs.jsonrpc.django import JSONService, jsonremote
    -
    - jsonservice = JSONRPCService()
    -
    - @jsonremote(jsonservice)
    - def test(request, echo_param):
    - return "echoing the param back: %s" % echo_param
    -
    --- a/py_ext/modules/svgui/pyjs/jsonrpc/django/jsonrpc.py Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,226 +0,0 @@
    -# jsonrpc.py
    -# original code: http://trac.pyworks.org/pyjamas/wiki/DjangoWithPyJamas
    -# also from: http://www.pimentech.fr/technologies/outils
    -from django.utils import simplejson
    -from django.http import HttpResponse
    -import sys
    -
    -from pyjs.jsonrpc import JSONRPCServiceBase
    -# JSONRPCService and jsonremote are used in combination to drastically
    -# simplify the provision of JSONRPC services. use as follows:
    -#
    -# jsonservice = JSONRPCService()
    -#
    -# @jsonremote(jsonservice)
    -# def test(request, echo_param):
    -# return "echoing the param back: %s" % echo_param
    -#
    -# dump jsonservice into urlpatterns:
    -# (r'^service1/$', 'djangoapp.views.jsonservice'),
    -
    -class JSONRPCService(JSONRPCServiceBase):
    -
    - def __call__(self, request, extra=None):
    - return self.process(request.raw_post_data)
    -
    -def jsonremote(service):
    - """Make JSONRPCService a decorator so that you can write :
    -
    - from jsonrpc import JSONRPCService
    - chatservice = JSONRPCService()
    -
    - @jsonremote(chatservice)
    - def login(request, user_name):
    - (...)
    - """
    - def remotify(func):
    - if isinstance(service, JSONRPCService):
    - service.add_method(func.__name__, func)
    - else:
    - emsg = 'Service "%s" not found' % str(service.__name__)
    - raise NotImplementedError, emsg
    - return func
    - return remotify
    -
    -
    -# FormProcessor provides a mechanism for turning Django Forms into JSONRPC
    -# Services. If you have an existing Django app which makes prevalent
    -# use of Django Forms it will save you rewriting the app.
    -# use as follows. in djangoapp/views.py :
    -#
    -# class SimpleForm(forms.Form):
    -# testfield = forms.CharField(max_length=100)
    -#
    -# class SimpleForm2(forms.Form):
    -# testfield = forms.CharField(max_length=20)
    -#
    -# processor = FormProcessor({'processsimpleform': SimpleForm,
    -# 'processsimpleform2': SimpleForm2})
    -#
    -# this will result in a JSONRPC service being created with two
    -# RPC functions. dump "processor" into urlpatterns to make it
    -# part of the app:
    -# (r'^formsservice/$', 'djangoapp.views.processor'),
    -
    -from django import forms
    -
    -def builderrors(form):
    - d = {}
    - for error in form.errors.keys():
    - if error not in d:
    - d[error] = []
    - for errorval in form.errors[error]:
    - d[error].append(unicode(errorval))
    - return d
    -
    -
    -# contains the list of arguments in each field
    -field_names = {
    - 'CharField': ['max_length', 'min_length'],
    - 'IntegerField': ['max_value', 'min_value'],
    - 'FloatField': ['max_value', 'min_value'],
    - 'DecimalField': ['max_value', 'min_value', 'max_digits', 'decimal_places'],
    - 'DateField': ['input_formats'],
    - 'DateTimeField': ['input_formats'],
    - 'TimeField': ['input_formats'],
    - 'RegexField': ['max_length', 'min_length'], # sadly we can't get the expr
    - 'EmailField': ['max_length', 'min_length'],
    - 'URLField': ['max_length', 'min_length', 'verify_exists', 'user_agent'],
    - 'ChoiceField': ['choices'],
    - 'FilePathField': ['path', 'match', 'recursive', 'choices'],
    - 'IPAddressField': ['max_length', 'min_length'],
    - }
    -
    -def describe_field_errors(field):
    - res = {}
    - field_type = field.__class__.__name__
    - msgs = {}
    - for n, m in field.error_messages.items():
    - msgs[n] = unicode(m)
    - res['error_messages'] = msgs
    - if field_type in ['ComboField', 'MultiValueField', 'SplitDateTimeField']:
    - res['fields'] = map(describe_field, field.fields)
    - return res
    -
    -def describe_fields_errors(fields, field_names):
    - res = {}
    - if not field_names:
    - field_names = fields.keys()
    - for name in field_names:
    - field = fields[name]
    - res[name] = describe_field_errors(field)
    - return res
    -
    -def describe_field(field):
    - res = {}
    - field_type = field.__class__.__name__
    - for fname in field_names.get(field_type, []) + \
    - ['help_text', 'label', 'initial', 'required']:
    - res[fname] = getattr(field, fname)
    - if field_type in ['ComboField', 'MultiValueField', 'SplitDateTimeField']:
    - res['fields'] = map(describe_field, field.fields)
    - return res
    -
    -def describe_fields(fields, field_names):
    - res = {}
    - if not field_names:
    - field_names = fields.keys()
    - for name in field_names:
    - field = fields[name]
    - res[name] = describe_field(field)
    - return res
    -
    -class FormProcessor(JSONRPCService):
    - def __init__(self, forms, _formcls=None):
    -
    - if _formcls is None:
    - JSONRPCService.__init__(self)
    - for k in forms.keys():
    - s = FormProcessor({}, forms[k])
    - self.add_method(k, s.__process)
    - else:
    - JSONRPCService.__init__(self, forms)
    - self.formcls = _formcls
    -
    - def __process(self, request, params, command=None):
    -
    - f = self.formcls(params)
    -
    - if command is None: # just validate
    - if not f.is_valid():
    - return {'success':False, 'errors': builderrors(f)}
    - return {'success':True}
    -
    - elif command.has_key('describe_errors'):
    - field_names = command['describe_errors']
    - return describe_fields_errors(f.fields, field_names)
    -
    - elif command.has_key('describe'):
    - field_names = command['describe']
    - return describe_fields(f.fields, field_names)
    -
    - elif command.has_key('save'):
    - if not f.is_valid():
    - return {'success':False, 'errors': builderrors(f)}
    - instance = f.save() # XXX: if you want more, over-ride save.
    - return {'success': True, 'instance': json_convert(instance) }
    -
    - elif command.has_key('html'):
    - return {'success': True, 'html': f.as_table()}
    -
    - return "unrecognised command"
    -
    -
    -
    -
    -# The following is incredibly convenient for saving vast amounts of
    -# coding, avoiding doing silly things like this:
    -# jsonresult = {'field1': djangoobject.field1,
    -# 'field2': djangoobject.date.strftime('%Y.%M'),
    -# ..... }
    -#
    -# The date/time flatten function is there because JSONRPC doesn't
    -# support date/time objects or formats, so conversion to a string
    -# is the most logical choice. pyjamas, being python, can easily
    -# be used to parse the string result at the other end.
    -#
    -# use as follows:
    -#
    -# jsonservice = JSONRPCService()
    -#
    -# @jsonremote(jsonservice)
    -# def list_some_model(request, start=0, count=10):
    -# l = SomeDjangoModelClass.objects.filter()
    -# res = json_convert(l[start:end])
    -#
    -# @jsonremote(jsonservice)
    -# def list_another_model(request, start=0, count=10):
    -# l = AnotherDjangoModelClass.objects.filter()
    -# res = json_convert(l[start:end])
    -#
    -# dump jsonservice into urlpatterns to make the two RPC functions,
    -# list_some_model and list_another_model part of the django app:
    -# (r'^service1/$', 'djangoapp.views.jsonservice'),
    -
    -from django.core.serializers import serialize
    -import datetime
    -from datetime import date
    -
    -def dict_datetimeflatten(item):
    - d = {}
    - for k, v in item.items():
    - k = str(k)
    - if isinstance(v, datetime.date):
    - d[k] = str(v)
    - elif isinstance(v, dict):
    - d[k] = dict_datetimeflatten(v)
    - else:
    - d[k] = v
    - return d
    -
    -def json_convert(l, fields=None):
    - res = []
    - for item in serialize('python', l, fields=fields):
    - res.append(dict_datetimeflatten(item))
    - return res
    -
    --- a/py_ext/modules/svgui/pyjs/jsonrpc/jsonrpc.py Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,43 +0,0 @@
    -import gluon.contrib.simplejson as simplejson
    -import types
    -import sys
    -
    -class JSONRPCServiceBase:
    -
    - def __init__(self):
    - self.methods={}
    -
    - def response(self, id, result):
    - return simplejson.dumps({'version': '1.1', 'id':id,
    - 'result':result, 'error':None})
    - def error(self, id, code, message):
    - return simplejson.dumps({'id': id,
    - 'version': '1.1',
    - 'error': {'name': 'JSONRPCError',
    - 'code': code,
    - 'message': message
    - }
    - })
    -
    - def add_method(self, name, method):
    - self.methods[name] = method
    -
    - def process(self, data):
    - data = simplejson.loads(data)
    - id, method, params = data["id"], data["method"], data["params"]
    - if method in self.methods:
    - try:
    - result =self.methods[method](*params)
    - return self.response(id, result)
    - except BaseException:
    - etype, eval, etb = sys.exc_info()
    - return self.error(id, 100, '%s: %s' %(etype.__name__, eval))
    - except:
    - etype, eval, etb = sys.exc_info()
    - return self.error(id, 100, 'Exception %s: %s' %(etype, eval))
    - else:
    - return self.error(id, 100, 'method "%s" does not exist' % method)
    -
    - def listmethods(self):
    - return self.methods.keys()
    -
    --- a/py_ext/modules/svgui/pyjs/jsonrpc/web2py/jsonrpc.py Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,11 +0,0 @@
    -from pyjs.jsonrpc import JSONRPCServiceBase
    -
    -class JSONRPCService(JSONRPCServiceBase):
    -
    - def serve(self):
    - return self.process(request.body.read())
    -
    - def __call__(self,func):
    - self.methods[func.__name__]=func
    - return func
    -
    --- a/py_ext/modules/svgui/pyjs/lib/_pyjs.js Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,160 +0,0 @@
    -function pyjs_extend(klass, base) {
    - function klass_object_inherit() {}
    - klass_object_inherit.prototype = base.prototype;
    - klass_object = new klass_object_inherit();
    - for (var i in base.prototype.__class__) {
    - v = base.prototype.__class__[i];
    - if (typeof v == "function" && (v.class_method || v.static_method || v.unbound_method))
    - {
    - klass_object[i] = v;
    - }
    - }
    -
    - function klass_inherit() {}
    - klass_inherit.prototype = klass_object;
    - klass.prototype = new klass_inherit();
    - klass_object.constructor = klass;
    - klass.prototype.__class__ = klass_object;
    -
    - for (var i in base.prototype) {
    - v = base.prototype[i];
    - if (typeof v == "function" && v.instance_method)
    - {
    - klass.prototype[i] = v;
    - }
    - }
    -}
    -
    -/* creates a class, derived from bases, with methods and variables */
    -function pyjs_type(clsname, bases, methods)
    -{
    - var fn_cls = function() {};
    - fn_cls.__name__ = clsname;
    - var fn = function() {
    - var instance = new fn_cls();
    - if(instance.__init__) instance.__init__.apply(instance, arguments);
    - return instance;
    - }
    - fn_cls.__initialize__ = function() {
    - if (fn_cls.__was_initialized__) return;
    - fn_cls.__was_initialized__ = true;
    - fn_cls.__extend_baseclasses();
    - fn_cls.prototype.__class__.__new__ = fn;
    - fn_cls.prototype.__class__.__name__ = clsname;
    - }
    - fn_cls.__extend_baseclasses = function() {
    - var bi;
    - for (bi in fn_cls.__baseclasses)
    - {
    - var b = fn_cls.__baseclasses[bi];
    - if (b.__was_initialized__)
    - {
    - continue;
    - }
    - b.__initialize__();
    - }
    - for (bi in fn_cls.__baseclasses)
    - {
    - var b = fn_cls.__baseclasses[bi];
    - pyjs_extend(fn_cls, b);
    - }
    - }
    - if (!bases) {
    - bases = [pyjslib.__Object];
    - }
    - fn_cls.__baseclasses = bases;
    -
    - fn_cls.__initialize__();
    -
    - for (k in methods) {
    - var mth = methods[k];
    - var mtype = typeof mth;
    - if (mtype == "function" ) {
    - fn_cls.prototype[k] = mth;
    - fn_cls.prototype.__class__[k] = function () {
    - return fn_cls.prototype[k].call.apply(
    - fn_cls.prototype[k], arguments);
    - };
    - fn_cls.prototype.__class__[k].unbound_method = true;
    - fn_cls.prototype.instance_method = true;
    - fn_cls.prototype.__class__[k].__name__ = k;
    - fn_cls.prototype[k].__name__ = k;
    - } else {
    - fn_cls.prototype.__class__[k] = mth;
    - }
    - }
    - return fn;
    -}
    -function pyjs_kwargs_call(obj, func, star_args, args)
    -{
    - var call_args;
    -
    - if (star_args)
    - {
    - if (!pyjslib.isIteratable(star_args))
    - {
    - throw (pyjslib.TypeError(func.__name__ + "() arguments after * must be a sequence" + pyjslib.repr(star_args)));
    - }
    - call_args = Array();
    - var __i = star_args.__iter__();
    - var i = 0;
    - try {
    - while (true) {
    - call_args[i]=__i.next();
    - i++;
    - }
    - } catch (e) {
    - if (e != pyjslib.StopIteration) {
    - throw e;
    - }
    - }
    -
    - if (args)
    - {
    - var n = star_args.length;
    - for (var i=0; i < args.length; i++) {
    - call_args[n+i]=args[i];
    - }
    - }
    - }
    - else
    - {
    - call_args = args;
    - }
    - return func.apply(obj, call_args);
    -}
    -
    -function pyjs_kwargs_function_call(func, star_args, args)
    -{
    - return pyjs_kwargs_call(null, func, star_args, args);
    -}
    -
    -function pyjs_kwargs_method_call(obj, method_name, star_args, args)
    -{
    - var method = obj[method_name];
    - if (method.parse_kwargs)
    - {
    - args = method.parse_kwargs.apply(null, args);
    - }
    - return pyjs_kwargs_call(obj, method, star_args, args);
    -}
    -
    -//String.prototype.__getitem__ = String.prototype.charAt;
    -//String.prototype.upper = String.prototype.toUpperCase;
    -//String.prototype.lower = String.prototype.toLowerCase;
    -//String.prototype.find=pyjslib.String_find;
    -//String.prototype.join=pyjslib.String_join;
    -//String.prototype.isdigit=pyjslib.String_isdigit;
    -//String.prototype.__iter__=pyjslib.String___iter__;
    -//
    -//String.prototype.__replace=String.prototype.replace;
    -//String.prototype.replace=pyjslib.String_replace;
    -//
    -//String.prototype.split=pyjslib.String_split;
    -//String.prototype.strip=pyjslib.String_strip;
    -//String.prototype.lstrip=pyjslib.String_lstrip;
    -//String.prototype.rstrip=pyjslib.String_rstrip;
    -//String.prototype.startswith=pyjslib.String_startswith;
    -
    -var str = String;
    -
    --- a/py_ext/modules/svgui/pyjs/lib/json.js Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,293 +0,0 @@
    -json_parse = (function () {
    -
    -// This is a function that can parse a JSON text, producing a JavaScript
    -// data structure. It is a simple, recursive descent parser. It does not use
    -// eval or regular expressions, so it can be used as a model for implementing
    -// a JSON parser in other languages.
    -
    -// We are defining the function inside of another function to avoid creating
    -// global variables.
    -
    - var at, // The index of the current character
    - ch, // The current character
    - escapee = {
    - '"': '"',
    - '\\': '\\',
    - '/': '/',
    - b: '\b',
    - f: '\f',
    - n: '\n',
    - r: '\r',
    - t: '\t'
    - },
    - text,
    -
    - error = function (m) {
    -
    -// Call error when something is wrong.
    -
    - throw {
    - name: 'SyntaxError',
    - message: m,
    - at: at,
    - text: text
    - };
    - },
    -
    - next = function (c) {
    -
    -// If a c parameter is provided, verify that it matches the current character.
    -
    - if (c && c !== ch) {
    - error("Expected '" + c + "' instead of '" + ch + "'");
    - }
    -
    -// Get the next character. When there are no more characters,
    -// return the empty string.
    -
    - ch = text.charAt(at);
    - at += 1;
    - return ch;
    - },
    -
    - number = function () {
    -
    -// Parse a number value.
    -
    - var number,
    - string = '';
    -
    - if (ch === '-') {
    - string = '-';
    - next('-');
    - }
    - while (ch >= '0' && ch <= '9') {
    - string += ch;
    - next();
    - }
    - if (ch === '.') {
    - string += '.';
    - while (next() && ch >= '0' && ch <= '9') {
    - string += ch;
    - }
    - }
    - if (ch === 'e' || ch === 'E') {
    - string += ch;
    - next();
    - if (ch === '-' || ch === '+') {
    - string += ch;
    - next();
    - }
    - while (ch >= '0' && ch <= '9') {
    - string += ch;
    - next();
    - }
    - }
    - number = +string;
    - if (isNaN(number)) {
    - error("Bad number");
    - } else {
    - return number;
    - }
    - },
    -
    - string = function () {
    -
    -// Parse a string value.
    -
    - var hex,
    - i,
    - string = '',
    - uffff;
    -
    -// When parsing for string values, we must look for " and \ characters.
    -
    - if (ch === '"') {
    - while (next()) {
    - if (ch === '"') {
    - next();
    - return string;
    - } else if (ch === '\\') {
    - next();
    - if (ch === 'u') {
    - uffff = 0;
    - for (i = 0; i < 4; i += 1) {
    - hex = parseInt(next(), 16);
    - if (!isFinite(hex)) {
    - break;
    - }
    - uffff = uffff * 16 + hex;
    - }
    - string += String.fromCharCode(uffff);
    - } else if (typeof escapee[ch] === 'string') {
    - string += escapee[ch];
    - } else {
    - break;
    - }
    - } else {
    - string += ch;
    - }
    - }
    - }
    - error("Bad string");
    - },
    -
    - white = function () {
    -
    -// Skip whitespace.
    -
    - while (ch && ch <= ' ') {
    - next();
    - }
    - },
    -
    - word = function () {
    -
    -// true, false, or null.
    -
    - switch (ch) {
    - case 't':
    - next('t');
    - next('r');
    - next('u');
    - next('e');
    - return true;
    - case 'f':
    - next('f');
    - next('a');
    - next('l');
    - next('s');
    - next('e');
    - return false;
    - case 'n':
    - next('n');
    - next('u');
    - next('l');
    - next('l');
    - return null;
    - }
    - error("Unexpected '" + ch + "'");
    - },
    -
    - value, // Place holder for the value function.
    -
    - array = function () {
    -
    -// Parse an array value.
    -
    - var array = [];
    -
    - if (ch === '[') {
    - next('[');
    - white();
    - if (ch === ']') {
    - next(']');
    - return array; // empty array
    - }
    - while (ch) {
    - array.push(value());
    - white();
    - if (ch === ']') {
    - next(']');
    - return array;
    - }
    - next(',');
    - white();
    - }
    - }
    - error("Bad array");
    - },
    -
    - object = function () {
    -
    -// Parse an object value.
    -
    - var key,
    - object = {};
    -
    - if (ch === '{') {
    - next('{');
    - white();
    - if (ch === '}') {
    - next('}');
    - return object; // empty object
    - }
    - while (ch) {
    - key = string();
    - white();
    - next(':');
    - if (Object.hasOwnProperty.call(object, key)) {
    - error('Duplicate key "' + key + '"');
    - }
    - object[key] = value();
    - white();
    - if (ch === '}') {
    - next('}');
    - return object;
    - }
    - next(',');
    - white();
    - }
    - }
    - error("Bad object");
    - };
    -
    - value = function () {
    -
    -// Parse a JSON value. It could be an object, an array, a string, a number,
    -// or a word.
    -
    - white();
    - switch (ch) {
    - case '{':
    - return object();
    - case '[':
    - return array();
    - case '"':
    - return string();
    - case '-':
    - return number();
    - default:
    - return ch >= '0' && ch <= '9' ? number() : word();
    - }
    - };
    -
    -// Return the json_parse function. It will have access to all of the above
    -// functions and variables.
    -
    - return function (source, reviver) {
    - var result;
    -
    - text = source;
    - at = 0;
    - ch = ' ';
    - result = value();
    - white();
    - if (ch) {
    - error("Syntax error");
    - }
    -
    -// If there is a reviver function, we recursively walk the new structure,
    -// passing each name/value pair to the reviver function for possible
    -// transformation, starting with a temporary root object that holds the result
    -// in an empty key. If there is not a reviver function, we simply return the
    -// result.
    -
    - return typeof reviver === 'function' ? (function walk(holder, key) {
    - var k, v, value = holder[key];
    - if (value && typeof value === 'object') {
    - for (k in value) {
    - if (Object.hasOwnProperty.call(value, k)) {
    - v = walk(value, k);
    - if (v !== undefined) {
    - value[k] = v;
    - } else {
    - delete value[k];
    - }
    - }
    - }
    - }
    - return reviver.call(holder, key, value);
    - }({'': result}, '')) : result;
    - };
    -}());
    --- a/py_ext/modules/svgui/pyjs/lib/pyjslib.py Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,1365 +0,0 @@
    -# Copyright 2006 James Tauber and contributors
    -#
    -# Licensed under the Apache License, Version 2.0 (the "License");
    -# you may not use this file except in compliance with the License.
    -# You may obtain a copy of the License at
    -#
    -# http://www.apache.org/licenses/LICENSE-2.0
    -#
    -# Unless required by applicable law or agreed to in writing, software
    -# distributed under the License is distributed on an "AS IS" BASIS,
    -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    -# See the License for the specific language governing permissions and
    -# limitations under the License.
    -
    -
    -# iteration from Bob Ippolito's Iteration in JavaScript
    -
    -from __pyjamas__ import JS
    -
    -# must declare import _before_ importing sys
    -
    -def import_module(path, parent_module, module_name, dynamic=1, async=False):
    - """
    - """
    -
    - JS("""
    - var cache_file;
    -
    - if (module_name == "sys" || module_name == 'pyjslib')
    - {
    - /*module_load_request[module_name] = 1;*/
    - return;
    - }
    -
    - if (path == null)
    - {
    - path = './';
    - }
    -
    - var override_name = sys.platform + "." + module_name;
    - if (((sys.overrides != null) &&
    - (sys.overrides.has_key(override_name))))
    - {
    - cache_file = sys.overrides.__getitem__(override_name) ;
    - }
    - else
    - {
    - cache_file = module_name ;
    - }
    -
    - cache_file = (path + cache_file + '.cache.js' ) ;
    -
    - //alert("cache " + cache_file + " " + module_name + " " + parent_module);
    -
    - /* already loaded? */
    - if (module_load_request[module_name])
    - {
    - if (module_load_request[module_name] >= 3 && parent_module != null)
    - {
    - //onload_fn = parent_module + '.' + module_name + ' = ' + module_name + ';';
    - //pyjs_eval(onload_fn); /* set up the parent-module namespace */
    - }
    - return;
    - }
    - if (typeof (module_load_request[module_name]) == 'undefined')
    - {
    - module_load_request[module_name] = 1;
    - }
    -
    - /* following a load, this first executes the script
    - * "preparation" function MODULENAME_loaded_fn()
    - * and then sets up the loaded module in the namespace
    - * of the parent.
    - */
    -
    - onload_fn = ''; // module_name + "_loaded_fn();"
    -
    - if (parent_module != null)
    - {
    - //onload_fn += parent_module + '.' + module_name + ' = ' + module_name + ';';
    - /*pmod = parent_module + '.' + module_name;
    - onload_fn += 'alert("' + pmod + '"+' + pmod+');';*/
    - }
    -
    -
    - if (dynamic)
    - {
    - /* this one tacks the script onto the end of the DOM
    - */
    -
    - pyjs_load_script(cache_file, onload_fn, async);
    -
    - /* this one actually RUNS the script (eval) into the page.
    - my feeling is that this would be better for non-async
    - but i can't get it to work entirely yet.
    - */
    - /*pyjs_ajax_eval(cache_file, onload_fn, async);*/
    - }
    - else
    - {
    - if (module_name != "pyjslib" &&
    - module_name != "sys")
    - pyjs_eval(onload_fn);
    - }
    -
    - """)
    -
    -JS("""
    -function import_wait(proceed_fn, parent_mod, dynamic) {
    -
    - var data = '';
    - var element = $doc.createElement("div");
    - $doc.body.appendChild(element);
    - function write_dom(txt) {
    - element.innerHTML = txt + '<br />';
    - }
    -
    - var timeoutperiod = 1;
    - if (dynamic)
    - var timeoutperiod = 1;
    -
    - var wait = function() {
    -
    - var status = '';
    - for (l in module_load_request)
    - {
    - var m = module_load_request[l];
    - if (l == "sys" || l == 'pyjslib')
    - continue;
    - status += l + m + " ";
    - }
    -
    - //write_dom( " import wait " + wait_count + " " + status + " parent_mod " + parent_mod);
    - wait_count += 1;
    -
    - if (status == '')
    - {
    - setTimeout(wait, timeoutperiod);
    - return;
    - }
    -
    - for (l in module_load_request)
    - {
    - var m = module_load_request[l];
    - if (l == "sys" || l == 'pyjslib')
    - {
    - module_load_request[l] = 4;
    - continue;
    - }
    - if ((parent_mod != null) && (l == parent_mod))
    - {
    - if (m == 1)
    - {
    - setTimeout(wait, timeoutperiod);
    - return;
    - }
    - if (m == 2)
    - {
    - /* cheat and move app on to next stage */
    - module_load_request[l] = 3;
    - }
    - }
    - if (m == 1 || m == 2)
    - {
    - setTimeout(wait, timeoutperiod);
    - return;
    - }
    - if (m == 3)
    - {
    - //alert("waited for module " + l + ": loaded");
    - module_load_request[l] = 4;
    - mod_fn = modules[l];
    - }
    - }
    - //alert("module wait done");
    -
    - if (proceed_fn.importDone)
    - proceed_fn.importDone(proceed_fn);
    - else
    - proceed_fn();
    - }
    -
    - wait();
    -}
    -""")
    -
    -class Object:
    - pass
    -
    -object = Object
    -
    -class Modload:
    -
    - def __init__(self, path, app_modlist, app_imported_fn, dynamic,
    - parent_mod):
    - self.app_modlist = app_modlist
    - self.app_imported_fn = app_imported_fn
    - self.path = path
    - self.idx = 0;
    - self.dynamic = dynamic
    - self.parent_mod = parent_mod
    -
    - def next(self):
    -
    - for i in range(len(self.app_modlist[self.idx])):
    - app = self.app_modlist[self.idx][i]
    - import_module(self.path, self.parent_mod, app, self.dynamic, True);
    - self.idx += 1
    -
    - if self.idx >= len(self.app_modlist):
    - import_wait(self.app_imported_fn, self.parent_mod, self.dynamic)
    - else:
    - import_wait(getattr(self, "next"), self.parent_mod, self.dynamic)
    -
    -def get_module(module_name):
    - ev = "__mod = %s;" % module_name
    - JS("pyjs_eval(ev);")
    - return __mod
    -
    -def preload_app_modules(path, app_modnames, app_imported_fn, dynamic,
    - parent_mod=None):
    -
    - loader = Modload(path, app_modnames, app_imported_fn, dynamic, parent_mod)
    - loader.next()
    -
    -import sys
    -
    -class BaseException:
    -
    - name = "BaseException"
    -
    - def __init__(self, *args):
    - self.args = args
    -
    - def __str__(self):
    - if len(self.args) is 0:
    - return ''
    - elif len(self.args) is 1:
    - return repr(self.args[0])
    - return repr(self.args)
    -
    - def toString(self):
    - return str(self)
    -
    -class Exception(BaseException):
    -
    - name = "Exception"
    -
    -class TypeError(BaseException):
    - name = "TypeError"
    -
    -class StandardError(Exception):
    - name = "StandardError"
    -
    -class LookupError(StandardError):
    - name = "LookupError"
    -
    - def toString(self):
    - return self.name + ": " + self.args[0]
    -
    -class KeyError(LookupError):
    - name = "KeyError"
    -
    -class AttributeError(StandardError):
    -
    - name = "AttributeError"
    -
    - def toString(self):
    - return "AttributeError: %s of %s" % (self.args[1], self.args[0])
    -
    -JS("""
    -pyjslib.StopIteration = function () { };
    -pyjslib.StopIteration.prototype = new Error();
    -pyjslib.StopIteration.name = 'StopIteration';
    -pyjslib.StopIteration.message = 'StopIteration';
    -
    -pyjslib.String_find = function(sub, start, end) {
    - var pos=this.indexOf(sub, start);
    - if (pyjslib.isUndefined(end)) return pos;
    -
    - if (pos + sub.length>end) return -1;
    - return pos;
    -}
    -
    -pyjslib.String_join = function(data) {
    - var text="";
    -
    - if (pyjslib.isArray(data)) {
    - return data.join(this);
    - }
    - else if (pyjslib.isIteratable(data)) {
    - var iter=data.__iter__();
    - try {
    - text+=iter.next();
    - while (true) {
    - var item=iter.next();
    - text+=this + item;
    - }
    - }
    - catch (e) {
    - if (e != pyjslib.StopIteration) throw e;
    - }
    - }
    -
    - return text;
    -}
    -
    -pyjslib.String_isdigit = function() {
    - return (this.match(/^\d+$/g) != null);
    -}
    -
    -pyjslib.String_replace = function(old, replace, count) {
    - var do_max=false;
    - var start=0;
    - var new_str="";
    - var pos=0;
    -
    - if (!pyjslib.isString(old)) return this.__replace(old, replace);
    - if (!pyjslib.isUndefined(count)) do_max=true;
    -
    - while (start<this.length) {
    - if (do_max && !count--) break;
    -
    - pos=this.indexOf(old, start);
    - if (pos<0) break;
    -
    - new_str+=this.substring(start, pos) + replace;
    - start=pos+old.length;
    - }
    - if (start<this.length) new_str+=this.substring(start);
    -
    - return new_str;
    -}
    -
    -pyjslib.String_split = function(sep, maxsplit) {
    - var items=new pyjslib.List();
    - var do_max=false;
    - var subject=this;
    - var start=0;
    - var pos=0;
    -
    - if (pyjslib.isUndefined(sep) || pyjslib.isNull(sep)) {
    - sep=" ";
    - subject=subject.strip();
    - subject=subject.replace(/\s+/g, sep);
    - }
    - else if (!pyjslib.isUndefined(maxsplit)) do_max=true;
    -
    - if (subject.length == 0) {
    - return items;
    - }
    -
    - while (start<subject.length) {
    - if (do_max && !maxsplit--) break;
    -
    - pos=subject.indexOf(sep, start);
    - if (pos<0) break;
    -
    - items.append(subject.substring(start, pos));
    - start=pos+sep.length;
    - }
    - if (start<=subject.length) items.append(subject.substring(start));
    -
    - return items;
    -}
    -
    -pyjslib.String___iter__ = function() {
    - var i = 0;
    - var s = this;
    - return {
    - 'next': function() {
    - if (i >= s.length) {
    - throw pyjslib.StopIteration;
    - }
    - return s.substring(i++, i, 1);
    - },
    - '__iter__': function() {
    - return this;
    - }
    - };
    -}
    -
    -pyjslib.String_strip = function(chars) {
    - return this.lstrip(chars).rstrip(chars);
    -}
    -
    -pyjslib.String_lstrip = function(chars) {
    - if (pyjslib.isUndefined(chars)) return this.replace(/^\s+/, "");
    -
    - return this.replace(new RegExp("^[" + chars + "]+"), "");
    -}
    -
    -pyjslib.String_rstrip = function(chars) {
    - if (pyjslib.isUndefined(chars)) return this.replace(/\s+$/, "");
    -
    - return this.replace(new RegExp("[" + chars + "]+$"), "");
    -}
    -
    -pyjslib.String_startswith = function(prefix, start) {
    - if (pyjslib.isUndefined(start)) start = 0;
    -
    - if (this.substring(start, prefix.length) == prefix) return true;
    - return false;
    -}
    -
    -pyjslib.abs = Math.abs;
    -
    -""")
    -
    -class Class:
    - def __init__(self, name):
    - self.name = name
    -
    - def __str___(self):
    - return self.name
    -
    -def eq(a,b):
    - JS("""
    - if (pyjslib.hasattr(a, "__cmp__")) {
    - return a.__cmp__(b) == 0;
    - } else if (pyjslib.hasattr(b, "__cmp__")) {
    - return b.__cmp__(a) == 0;
    - }
    - return a == b;
    - """)
    -
    -def cmp(a,b):
    - if hasattr(a, "__cmp__"):
    - return a.__cmp__(b)
    - elif hasattr(b, "__cmp__"):
    - return -b.__cmp__(a)
    - if a > b:
    - return 1
    - elif b > a:
    - return -1
    - else:
    - return 0
    -
    -def bool(v):
    - # this needs to stay in native code without any dependencies here,
    - # because this is used by if and while, we need to prevent
    - # recursion
    - JS("""
    - if (!v) return false;
    - switch(typeof v){
    - case 'boolean':
    - return v;
    - case 'object':
    - if (v.__nonzero__){
    - return v.__nonzero__();
    - }else if (v.__len__){
    - return v.__len__()>0;
    - }
    - return true;
    - }
    - return Boolean(v);
    - """)
    -
    -class List:
    - def __init__(self, data=None):
    - JS("""
    - this.l = [];
    - this.extend(data);
    - """)
    -
    - def append(self, item):
    - JS(""" this.l[this.l.length] = item;""")
    -
    - def extend(self, data):
    - JS("""
    - if (pyjslib.isArray(data)) {
    - n = this.l.length;
    - for (var i=0; i < data.length; i++) {
    - this.l[n+i]=data[i];
    - }
    - }
    - else if (pyjslib.isIteratable(data)) {
    - var iter=data.__iter__();
    - var i=this.l.length;
    - try {
    - while (true) {
    - var item=iter.next();
    - this.l[i++]=item;
    - }
    - }
    - catch (e) {
    - if (e != pyjslib.StopIteration) throw e;
    - }
    - }
    - """)
    -
    - def remove(self, value):
    - JS("""
    - var index=this.index(value);
    - if (index<0) return false;
    - this.l.splice(index, 1);
    - return true;
    - """)
    -
    - def index(self, value, start=0):
    - JS("""
    - var length=this.l.length;
    - for (var i=start; i<length; i++) {
    - if (this.l[i]==value) {
    - return i;
    - }
    - }
    - return -1;
    - """)
    -
    - def insert(self, index, value):
    - JS(""" var a = this.l; this.l=a.slice(0, index).concat(value, a.slice(index));""")
    -
    - def pop(self, index = -1):
    - JS("""
    - if (index<0) index = this.l.length + index;
    - var a = this.l[index];
    - this.l.splice(index, 1);
    - return a;
    - """)
    -
    - def __cmp__(self, l):
    - if not isinstance(l, List):
    - return -1
    - ll = len(self) - len(l)
    - if ll != 0:
    - return ll
    - for x in range(len(l)):
    - ll = cmp(self.__getitem__(x), l[x])
    - if ll != 0:
    - return ll
    - return 0
    -
    - def slice(self, lower, upper):
    - JS("""
    - if (upper==null) return pyjslib.List(this.l.slice(lower));
    - return pyjslib.List(this.l.slice(lower, upper));
    - """)
    -
    - def __getitem__(self, index):
    - JS("""
    - if (index<0) index = this.l.length + index;
    - return this.l[index];
    - """)
    -
    - def __setitem__(self, index, value):
    - JS(""" this.l[index]=value;""")
    -
    - def __delitem__(self, index):
    - JS(""" this.l.splice(index, 1);""")
    -
    - def __len__(self):
    - JS(""" return this.l.length;""")
    -
    - def __contains__(self, value):
    - return self.index(value) >= 0
    -
    - def __iter__(self):
    - JS("""
    - var i = 0;
    - var l = this.l;
    - return {
    - 'next': function() {
    - if (i >= l.length) {
    - throw pyjslib.StopIteration;
    - }
    - return l[i++];
    - },
    - '__iter__': function() {
    - return this;
    - }
    - };
    - """)
    -
    - def reverse(self):
    - JS(""" this.l.reverse();""")
    -
    - def sort(self, compareFunc=None, keyFunc=None, reverse=False):
    - if not compareFunc:
    - global cmp
    - compareFunc = cmp
    - if keyFunc and reverse:
    - def thisSort1(a,b):
    - return -compareFunc(keyFunc(a), keyFunc(b))
    - self.l.sort(thisSort1)
    - elif keyFunc:
    - def thisSort2(a,b):
    - return compareFunc(keyFunc(a), keyFunc(b))
    - self.l.sort(thisSort2)
    - elif reverse:
    - def thisSort3(a,b):
    - return -compareFunc(a, b)
    - self.l.sort(thisSort3)
    - else:
    - self.l.sort(compareFunc)
    -
    - def getArray(self):
    - """
    - Access the javascript Array that is used internally by this list
    - """
    - return self.l
    -
    - def __str__(self):
    - return repr(self)
    -
    -list = List
    -
    -class Tuple:
    - def __init__(self, data=None):
    - JS("""
    - this.l = [];
    - this.extend(data);
    - """)
    -
    - def append(self, item):
    - JS(""" this.l[this.l.length] = item;""")
    -
    - def extend(self, data):
    - JS("""
    - if (pyjslib.isArray(data)) {
    - n = this.l.length;
    - for (var i=0; i < data.length; i++) {
    - this.l[n+i]=data[i];
    - }
    - }
    - else if (pyjslib.isIteratable(data)) {
    - var iter=data.__iter__();
    - var i=this.l.length;
    - try {
    - while (true) {
    - var item=iter.next();
    - this.l[i++]=item;
    - }
    - }
    - catch (e) {
    - if (e != pyjslib.StopIteration) throw e;
    - }
    - }
    - """)
    -
    - def remove(self, value):
    - JS("""
    - var index=this.index(value);
    - if (index<0) return false;
    - this.l.splice(index, 1);
    - return true;
    - """)
    -
    - def index(self, value, start=0):
    - JS("""
    - var length=this.l.length;
    - for (var i=start; i<length; i++) {
    - if (this.l[i]==value) {
    - return i;
    - }
    - }
    - return -1;
    - """)
    -
    - def insert(self, index, value):
    - JS(""" var a = this.l; this.l=a.slice(0, index).concat(value, a.slice(index));""")
    -
    - def pop(self, index = -1):
    - JS("""
    - if (index<0) index = this.l.length + index;
    - var a = this.l[index];
    - this.l.splice(index, 1);
    - return a;
    - """)
    -
    - def __cmp__(self, l):
    - if not isinstance(l, Tuple):
    - return -1
    - ll = len(self) - len(l)
    - if ll != 0:
    - return ll
    - for x in range(len(l)):
    - ll = cmp(self.__getitem__(x), l[x])
    - if ll != 0:
    - return ll
    - return 0
    -
    - def slice(self, lower, upper):
    - JS("""
    - if (upper==null) return pyjslib.Tuple(this.l.slice(lower));
    - return pyjslib.Tuple(this.l.slice(lower, upper));
    - """)
    -
    - def __getitem__(self, index):
    - JS("""
    - if (index<0) index = this.l.length + index;
    - return this.l[index];
    - """)
    -
    - def __setitem__(self, index, value):
    - JS(""" this.l[index]=value;""")
    -
    - def __delitem__(self, index):
    - JS(""" this.l.splice(index, 1);""")
    -
    - def __len__(self):
    - JS(""" return this.l.length;""")
    -
    - def __contains__(self, value):
    - return self.index(value) >= 0
    -
    - def __iter__(self):
    - JS("""
    - var i = 0;
    - var l = this.l;
    - return {
    - 'next': function() {
    - if (i >= l.length) {
    - throw pyjslib.StopIteration;
    - }
    - return l[i++];
    - },
    - '__iter__': function() {
    - return this;
    - }
    - };
    - """)
    -
    - def reverse(self):
    - JS(""" this.l.reverse();""")
    -
    - def sort(self, compareFunc=None, keyFunc=None, reverse=False):
    - if not compareFunc:
    - global cmp
    - compareFunc = cmp
    - if keyFunc and reverse:
    - def thisSort1(a,b):
    - return -compareFunc(keyFunc(a), keyFunc(b))
    - self.l.sort(thisSort1)
    - elif keyFunc:
    - def thisSort2(a,b):
    - return compareFunc(keyFunc(a), keyFunc(b))
    - self.l.sort(thisSort2)
    - elif reverse:
    - def thisSort3(a,b):
    - return -compareFunc(a, b)
    - self.l.sort(thisSort3)
    - else:
    - self.l.sort(compareFunc)
    -
    - def getArray(self):
    - """
    - Access the javascript Array that is used internally by this list
    - """
    - return self.l
    -
    - def __str__(self):
    - return repr(self)
    -
    -tuple = Tuple
    -
    -
    -class Dict:
    - def __init__(self, data=None):
    - JS("""
    - this.d = {};
    -
    - if (pyjslib.isArray(data)) {
    - for (var i in data) {
    - var item=data[i];
    - this.__setitem__(item[0], item[1]);
    - //var sKey=pyjslib.hash(item[0]);
    - //this.d[sKey]=item[1];
    - }
    - }
    - else if (pyjslib.isIteratable(data)) {
    - var iter=data.__iter__();
    - try {
    - while (true) {
    - var item=iter.next();
    - this.__setitem__(item.__getitem__(0), item.__getitem__(1));
    - }
    - }
    - catch (e) {
    - if (e != pyjslib.StopIteration) throw e;
    - }
    - }
    - else if (pyjslib.isObject(data)) {
    - for (var key in data) {
    - this.__setitem__(key, data[key]);
    - }
    - }
    - """)
    -
    - def __setitem__(self, key, value):
    - JS("""
    - var sKey = pyjslib.hash(key);
    - this.d[sKey]=[key, value];
    - """)
    -
    - def __getitem__(self, key):
    - JS("""
    - var sKey = pyjslib.hash(key);
    - var value=this.d[sKey];
    - if (pyjslib.isUndefined(value)){
    - throw pyjslib.KeyError(key);
    - }
    - return value[1];
    - """)
    -
    - def __nonzero__(self):
    - JS("""
    - for (var i in this.d){
    - return true;
    - }
    - return false;
    - """)
    -
    - def __len__(self):
    - JS("""
    - var size=0;
    - for (var i in this.d) size++;
    - return size;
    - """)
    -
    - def has_key(self, key):
    - return self.__contains__(key)
    -
    - def __delitem__(self, key):
    - JS("""
    - var sKey = pyjslib.hash(key);
    - delete this.d[sKey];
    - """)
    -
    - def __contains__(self, key):
    - JS("""
    - var sKey = pyjslib.hash(key);
    - return (pyjslib.isUndefined(this.d[sKey])) ? false : true;
    - """)
    -
    - def keys(self):
    - JS("""
    - var keys=new pyjslib.List();
    - for (var key in this.d) {
    - keys.append(this.d[key][0]);
    - }
    - return keys;
    - """)
    -
    - def values(self):
    - JS("""
    - var values=new pyjslib.List();
    - for (var key in this.d) values.append(this.d[key][1]);
    - return values;
    - """)
    -
    - def items(self):
    - JS("""
    - var items = new pyjslib.List();
    - for (var key in this.d) {
    - var kv = this.d[key];
    - items.append(new pyjslib.List(kv))
    - }
    - return items;
    - """)
    -
    - def __iter__(self):
    - return self.keys().__iter__()
    -
    - def iterkeys(self):
    - return self.__iter__()
    -
    - def itervalues(self):
    - return self.values().__iter__();
    -
    - def iteritems(self):
    - return self.items().__iter__();
    -
    - def setdefault(self, key, default_value):
    - if not self.has_key(key):
    - self[key] = default_value
    -
    - def get(self, key, default_=None):
    - if not self.has_key(key):
    - return default_
    - return self[key]
    -
    - def update(self, d):
    - for k,v in d.iteritems():
    - self[k] = v
    -
    - def getObject(self):
    - """
    - Return the javascript Object which this class uses to store
    - dictionary keys and values
    - """
    - return self.d
    -
    - def copy(self):
    - return Dict(self.items())
    -
    - def __str__(self):
    - return repr(self)
    -
    -dict = Dict
    -
    -# taken from mochikit: range( [start,] stop[, step] )
    -def range():
    - JS("""
    - var start = 0;
    - var stop = 0;
    - var step = 1;
    -
    - if (arguments.length == 2) {
    - start = arguments[0];
    - stop = arguments[1];
    - }
    - else if (arguments.length == 3) {
    - start = arguments[0];
    - stop = arguments[1];
    - step = arguments[2];
    - }
    - else if (arguments.length>0) stop = arguments[0];
    -
    - return {
    - 'next': function() {
    - if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) throw pyjslib.StopIteration;
    - var rval = start;
    - start += step;
    - return rval;
    - },
    - '__iter__': function() {
    - return this;
    - }
    - }
    - """)
    -
    -def slice(object, lower, upper):
    - JS("""
    - if (pyjslib.isString(object)) {
    - if (lower < 0) {
    - lower = object.length + lower;
    - }
    - if (upper < 0) {
    - upper = object.length + upper;
    - }
    - if (pyjslib.isNull(upper)) upper=object.length;
    - return object.substring(lower, upper);
    - }
    - if (pyjslib.isObject(object) && object.slice)
    - return object.slice(lower, upper);
    -
    - return null;
    - """)
    -
    -def str(text):
    - JS("""
    - if (pyjslib.hasattr(text,"__str__")) {
    - return text.__str__();
    - }
    - return String(text);
    - """)
    -
    -def ord(x):
    - if(isString(x) and len(x) is 1):
    - JS("""
    - return x.charCodeAt(0);
    - """)
    - else:
    - JS("""
    - throw pyjslib.TypeError();
    - """)
    - return None
    -
    -def chr(x):
    - JS("""
    - return String.fromCharCode(x)
    - """)
    -
    -def is_basetype(x):
    - JS("""
    - var t = typeof(x);
    - return t == 'boolean' ||
    - t == 'function' ||
    - t == 'number' ||
    - t == 'string' ||
    - t == 'undefined'
    - ;
    - """)
    -
    -def get_pyjs_classtype(x):
    - JS("""
    - if (pyjslib.hasattr(x, "__class__"))
    - if (pyjslib.hasattr(x.__class__, "__new__"))
    - var src = x.__class__.__name__;
    - return src;
    - return null;
    - """)
    -
    -def repr(x):
    - """ Return the string representation of 'x'.
    - """
    - JS("""
    - if (x === null)
    - return "null";
    -
    - if (x === undefined)
    - return "undefined";
    -
    - var t = typeof(x);
    -
    - //alert("repr typeof " + t + " : " + x);
    -
    - if (t == "boolean")
    - return x.toString();
    -
    - if (t == "function")
    - return "<function " + x.toString() + ">";
    -
    - if (t == "number")
    - return x.toString();
    -
    - if (t == "string") {
    - if (x.indexOf("'") == -1)
    - return "'" + x + "'";
    - if (x.indexOf('"') == -1)
    - return '"' + x + '"';
    - var s = x.replace(new RegExp('"', "g"), '\\\\"');
    - return '"' + s + '"';
    - };
    -
    - if (t == "undefined")
    - return "undefined";
    -
    - // If we get here, x is an object. See if it's a Pyjamas class.
    -
    - if (!pyjslib.hasattr(x, "__init__"))
    - return "<" + x.toString() + ">";
    -
    - // Handle the common Pyjamas data types.
    -
    - var constructor = "UNKNOWN";
    -
    - constructor = pyjslib.get_pyjs_classtype(x);
    -
    - //alert("repr constructor: " + constructor);
    -
    - if (constructor == "Tuple") {
    - var contents = x.getArray();
    - var s = "(";
    - for (var i=0; i < contents.length; i++) {
    - s += pyjslib.repr(contents[i]);
    - if (i < contents.length - 1)
    - s += ", ";
    - };
    - s += ")"
    - return s;
    - };
    -
    - if (constructor == "List") {
    - var contents = x.getArray();
    - var s = "[";
    - for (var i=0; i < contents.length; i++) {
    - s += pyjslib.repr(contents[i]);
    - if (i < contents.length - 1)
    - s += ", ";
    - };
    - s += "]"
    - return s;
    - };
    -
    - if (constructor == "Dict") {
    - var keys = new Array();
    - for (var key in x.d)
    - keys.push(key);
    -
    - var s = "{";
    - for (var i=0; i<keys.length; i++) {
    - var key = keys[i]
    - s += pyjslib.repr(key) + ": " + pyjslib.repr(x.d[key]);
    - if (i < keys.length-1)
    - s += ", "
    - };
    - s += "}";
    - return s;
    - };
    -
    - // If we get here, the class isn't one we know -> return the class name.
    - // Note that we replace underscores with dots so that the name will
    - // (hopefully!) look like the original Python name.
    -
    - //var s = constructor.replace(new RegExp('_', "g"), '.');
    - return "<" + constructor + " object>";
    - """)
    -
    -def float(text):
    - JS("""
    - return parseFloat(text);
    - """)
    -
    -def int(text, radix=0):
    - JS("""
    - return parseInt(text, radix);
    - """)
    -
    -def len(object):
    - JS("""
    - if (object==null) return 0;
    - if (pyjslib.isObject(object) && object.__len__) return object.__len__();
    - return object.length;
    - """)
    -
    -def isinstance(object_, classinfo):
    - if pyjslib.isUndefined(object_):
    - return False
    - if not pyjslib.isObject(object_):
    -
    - return False
    - if _isinstance(classinfo, Tuple):
    - for ci in classinfo:
    - if isinstance(object_, ci):
    - return True
    - return False
    - else:
    - return _isinstance(object_, classinfo)
    -
    -def _isinstance(object_, classinfo):
    - if not pyjslib.isObject(object_):
    - return False
    - JS("""
    - if (object_.__class__){
    - var res = object_ instanceof classinfo.constructor;
    - return res;
    - }
    - return false;
    - """)
    -
    -def getattr(obj, name, default_):
    - JS("""
    - if ((!pyjslib.isObject(obj))||(pyjslib.isUndefined(obj[name]))){
    - if (pyjslib.isUndefined(default_)){
    - throw pyjslib.AttributeError(obj, name);
    - }else{
    - return default_;
    - }
    - }
    - if (!pyjslib.isFunction(obj[name])) return obj[name];
    - var fnwrap = function() {
    - var args = [];
    - for (var i = 0; i < arguments.length; i++) {
    - args.push(arguments[i]);
    - }
    - return obj[name].apply(obj,args);
    - }
    - fnwrap.__name__ = name;
    - return fnwrap;
    - """)
    -
    -def setattr(obj, name, value):
    - JS("""
    - if (!pyjslib.isObject(obj)) return null;
    -
    - obj[name] = value;
    -
    - """)
    -
    -def hasattr(obj, name):
    - JS("""
    - if (!pyjslib.isObject(obj)) return false;
    - if (pyjslib.isUndefined(obj[name])) return false;
    -
    - return true;
    - """)
    -
    -def dir(obj):
    - JS("""
    - var properties=new pyjslib.List();
    - for (property in obj) properties.append(property);
    - return properties;
    - """)
    -
    -def filter(obj, method, sequence=None):
    - # object context is LOST when a method is passed, hence object must be passed separately
    - # to emulate python behaviour, should generate this code inline rather than as a function call
    - items = []
    - if sequence is None:
    - sequence = method
    - method = obj
    -
    - for item in sequence:
    - if method(item):
    - items.append(item)
    - else:
    - for item in sequence:
    - if method.call(obj, item):
    - items.append(item)
    -
    - return items
    -
    -
    -def map(obj, method, sequence=None):
    - items = []
    -
    - if sequence is None:
    - sequence = method
    - method = obj
    -
    - for item in sequence:
    - items.append(method(item))
    - else:
    - for item in sequence:
    - items.append(method.call(obj, item))
    -
    - return items
    -
    -
    -def enumerate(sequence):
    - enumeration = []
    - nextIndex = 0
    - for item in sequence:
    - enumeration.append([nextIndex, item])
    - nextIndex = nextIndex + 1
    - return enumeration
    -
    -
    -def min(*sequence):
    - minValue = None
    - for item in sequence:
    - if minValue is None:
    - minValue = item
    - elif item < minValue:
    - minValue = item
    - return minValue
    -
    -
    -def max(*sequence):
    - maxValue = None
    - for item in sequence:
    - if maxValue is None:
    - maxValue = item
    - elif item > maxValue:
    - maxValue = item
    - return maxValue
    -
    -
    -next_hash_id = 0
    -
    -def hash(obj):
    - JS("""
    - if (obj == null) return null;
    -
    - if (obj.$H) return obj.$H;
    - if (obj.__hash__) return obj.__hash__();
    - if (obj.constructor == String || obj.constructor == Number || obj.constructor == Date) return obj;
    -
    - obj.$H = ++pyjslib.next_hash_id;
    - return obj.$H;
    - """)
    -
    -
    -# type functions from Douglas Crockford's Remedial Javascript: http://www.crockford.com/javascript/remedial.html
    -def isObject(a):
    - JS("""
    - return (a != null && (typeof a == 'object')) || pyjslib.isFunction(a);
    - """)
    -
    -def isFunction(a):
    - JS("""
    - return typeof a == 'function';
    - """)
    -
    -def isString(a):
    - JS("""
    - return typeof a == 'string';
    - """)
    -
    -def isNull(a):
    - JS("""
    - return typeof a == 'object' && !a;
    - """)
    -
    -def isArray(a):
    - JS("""
    - return pyjslib.isObject(a) && a.constructor == Array;
    - """)
    -
    -def isUndefined(a):
    - JS("""
    - return typeof a == 'undefined';
    - """)
    -
    -def isIteratable(a):
    - JS("""
    - return pyjslib.isString(a) || (pyjslib.isObject(a) && a.__iter__);
    - """)
    -
    -def isNumber(a):
    - JS("""
    - return typeof a == 'number' && isFinite(a);
    - """)
    -
    -def toJSObjects(x):
    - """
    - Convert the pyjs pythonic List and Dict objects into javascript Object and Array
    - objects, recursively.
    - """
    - if isArray(x):
    - JS("""
    - var result = [];
    - for(var k=0; k < x.length; k++) {
    - var v = x[k];
    - var tv = pyjslib.toJSObjects(v);
    - result.push(tv);
    - }
    - return result;
    - """)
    - if isObject(x):
    - if isinstance(x, Dict):
    - JS("""
    - var o = x.getObject();
    - var result = {};
    - for (var i in o) {
    - result[o[i][0].toString()] = o[i][1];
    - }
    - return pyjslib.toJSObjects(result)
    - """)
    - elif isinstance(x, List):
    - return toJSObjects(x.l)
    - elif hasattr(x, '__class__'):
    - # we do not have a special implementation for custom
    - # classes, just pass it on
    - return x
    - if isObject(x):
    - JS("""
    - var result = {};
    - for(var k in x) {
    - var v = x[k];
    - var tv = pyjslib.toJSObjects(v)
    - result[k] = tv;
    - }
    - return result;
    - """)
    - return x
    -
    -def printFunc(objs):
    - JS("""
    - if ($wnd.console==undefined) return;
    - var s = "";
    - for(var i=0; i < objs.length; i++) {
    - if(s != "") s += " ";
    - s += objs[i];
    - }
    - console.debug(s)
    - """)
    -
    -def type(clsname, bases=None, methods=None):
    - """ creates a class, derived from bases, with methods and variables
    - """
    -
    - JS(" var mths = {}; ")
    - if methods:
    - for k in methods.keys():
    - mth = methods[k]
    - JS(" mths[k] = mth; ")
    -
    - JS(" var bss = null; ")
    - if bases:
    - JS("bss = bases.l;")
    - JS(" return pyjs_type(clsname, bss, mths); ")
    -
    --- a/py_ext/modules/svgui/pyjs/lib/sys.py Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,59 +0,0 @@
    -# the platform name (PyV8, smjs, Mozilla, IE6, Opera, Safari etc.)
    -platform = '' # to be updated by app, on compile
    -
    -# a dictionary of module override names (platform-specific)
    -overrides = None # to be updated by app, on compile
    -
    -# the remote path for loading modules
    -loadpath = None
    -
    -stacktrace = None
    -
    -appname = None
    -
    -def setloadpath(lp):
    - global loadpath
    - loadpath = lp
    -
    -def setappname(an):
    - global appname
    - appname = an
    -
    -def getloadpath():
    - global loadpath
    - return loadpath
    -
    -def addoverride(module_name, path):
    - global overrides
    - overrides[module_name] = path
    -
    -def addstack(linedebug):
    - JS("""
    - if (pyjslib.bool((sys.stacktrace === null))) {
    - sys.stacktrace = new pyjslib.List([]);
    - }
    - sys.stacktrace.append(linedebug);
    - """)
    -def popstack():
    - JS("""
    - sys.stacktrace.pop()
    - """)
    -
    -def printstack():
    - JS("""
    - var res = '';
    -
    - var __l = sys.stacktrace.__iter__();
    - try {
    - while (true) {
    - var l = __l.next();
    - res += ( l + '\\n' ) ;
    - }
    - } catch (e) {
    - if (e != pyjslib.StopIteration) {
    - throw e;
    - }
    - }
    -
    - return res;
    - """)
    --- a/py_ext/modules/svgui/pyjs/pyjs.py Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,1777 +0,0 @@
    -#!/usr/bin/env python
    -# Copyright 2006 James Tauber and contributors
    -#
    -# Licensed under the Apache License, Version 2.0 (the "License");
    -# you may not use this file except in compliance with the License.
    -# You may obtain a copy of the License at
    -#
    -# http://www.apache.org/licenses/LICENSE-2.0
    -#
    -# Unless required by applicable law or agreed to in writing, software
    -# distributed under the License is distributed on an "AS IS" BASIS,
    -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    -# See the License for the specific language governing permissions and
    -# limitations under the License.
    -
    -
    -import sys
    -from types import StringType
    -import compiler
    -from compiler import ast
    -import os
    -import copy
    -
    -# the standard location for builtins (e.g. pyjslib) can be
    -# over-ridden by changing this. it defaults to sys.prefix
    -# so that on a system-wide install of pyjamas the builtins
    -# can be found in e.g. {sys.prefix}/share/pyjamas
    -#
    -# over-rides can be done by either explicitly modifying
    -# pyjs.prefix or by setting an environment variable, PYJSPREFIX.
    -
    -prefix = sys.prefix
    -
    -if os.environ.has_key('PYJSPREFIX'):
    - prefix = os.environ['PYJSPREFIX']
    -
    -# pyjs.path is the list of paths, just like sys.path, from which
    -# library modules will be searched for, for compile purposes.
    -# obviously we don't want to use sys.path because that would result
    -# in compiling standard python modules into javascript!
    -
    -path = [os.path.abspath('')]
    -
    -if os.environ.has_key('PYJSPATH'):
    - for p in os.environ['PYJSPATH'].split(os.pathsep):
    - p = os.path.abspath(p)
    - if os.path.isdir(p):
    - path.append(p)
    -
    -# this is the python function used to wrap native javascript
    -NATIVE_JS_FUNC_NAME = "JS"
    -
    -UU = ""
    -
    -PYJSLIB_BUILTIN_FUNCTIONS=("cmp",
    - "map",
    - "filter",
    - "dir",
    - "getattr",
    - "setattr",
    - "hasattr",
    - "int",
    - "float",
    - "str",
    - "repr",
    - "range",
    - "len",
    - "hash",
    - "abs",
    - "ord",
    - "chr",
    - "enumerate",
    - "min",
    - "max",
    - "bool",
    - "type",
    - "isinstance")
    -
    -PYJSLIB_BUILTIN_CLASSES=("BaseException",
    - "Exception",
    - "StandardError",
    - "StopIteration",
    - "AttributeError",
    - "TypeError",
    - "KeyError",
    - "LookupError",
    - "list",
    - "dict",
    - "object",
    - "tuple",
    - )
    -
    -def pyjs_builtin_remap(name):
    - # XXX HACK!
    - if name == 'list':
    - name = 'List'
    - if name == 'object':
    - name = '__Object'
    - if name == 'dict':
    - name = 'Dict'
    - if name == 'tuple':
    - name = 'Tuple'
    - return name
    -
    -# XXX: this is a hack: these should be dealt with another way
    -# however, console is currently the only global name which is causing
    -# problems.
    -PYJS_GLOBAL_VARS=("console")
    -
    -# This is taken from the django project.
    -# Escape every ASCII character with a value less than 32.
    -JS_ESCAPES = (
    - ('\\', r'\x5C'),
    - ('\'', r'\x27'),
    - ('"', r'\x22'),
    - ('>', r'\x3E'),
    - ('<', r'\x3C'),
    - ('&', r'\x26'),
    - (';', r'\x3B')
    - ) + tuple([('%c' % z, '\\x%02X' % z) for z in range(32)])
    -
    -def escapejs(value):
    - """Hex encodes characters for use in JavaScript strings."""
    - for bad, good in JS_ESCAPES:
    - value = value.replace(bad, good)
    - return value
    -
    -def uuprefix(name, leave_alone=0):
    - name = name.split(".")
    - name = name[:leave_alone] + map(lambda x: "__%s" % x, name[leave_alone:])
    - return '.'.join(name)
    -
    -class Klass:
    -
    - klasses = {}
    -
    - def __init__(self, name, name_):
    - self.name = name
    - self.name_ = name_
    - self.klasses[name] = self
    - self.functions = set()
    -
    - def set_base(self, base_name):
    - self.base = self.klasses.get(base_name)
    -
    - def add_function(self, function_name):
    - self.functions.add(function_name)
    -
    -
    -class TranslationError(Exception):
    - def __init__(self, message, node):
    - self.message = "line %s:\n%s\n%s" % (node.lineno, message, node)
    -
    - def __str__(self):
    - return self.message
    -
    -def strip_py(name):
    - return name
    -
    -def mod_var_name_decl(raw_module_name):
    - """ function to get the last component of the module e.g.
    - pyjamas.ui.DOM into the "namespace". i.e. doing
    - "import pyjamas.ui.DOM" actually ends up with _two_
    - variables - one pyjamas.ui.DOM, the other just "DOM".
    - but "DOM" is actually local, hence the "var" prefix.
    -
    - for PyV8, this might end up causing problems - we'll have
    - to see: gen_mod_import and mod_var_name_decl might have
    - to end up in a library-specific module, somewhere.
    - """
    - name = raw_module_name.split(".")
    - if len(name) == 1:
    - return ''
    - child_name = name[-1]
    - return "var %s = %s;\n" % (child_name, raw_module_name)
    -
    -def gen_mod_import(parentName, importName, dynamic=1):
    - #pyjs_ajax_eval("%(n)s.cache.js", null, true);
    - return """
    - pyjslib.import_module(sys.loadpath, '%(p)s', '%(n)s', %(d)d, false);
    - """ % ({'p': parentName, 'd': dynamic, 'n': importName}) + \
    - mod_var_name_decl(importName)
    -
    -class Translator:
    -
    - def __init__(self, mn, module_name, raw_module_name, src, debug, mod, output,
    - dynamic=0, optimize=False,
    - findFile=None):
    -
    - if module_name:
    - self.module_prefix = module_name + "."
    - else:
    - self.module_prefix = ""
    - self.raw_module_name = raw_module_name
    - src = src.replace("\r\n", "\n")
    - src = src.replace("\n\r", "\n")
    - src = src.replace("\r", "\n")
    - self.src = src.split("\n")
    - self.debug = debug
    - self.imported_modules = []
    - self.imported_modules_as = []
    - self.imported_js = set()
    - self.top_level_functions = set()
    - self.top_level_classes = set()
    - self.top_level_vars = set()
    - self.local_arg_stack = [[]]
    - self.output = output
    - self.imported_classes = {}
    - self.method_imported_globals = set()
    - self.method_self = None
    - self.nextTupleAssignID = 1
    - self.dynamic = dynamic
    - self.optimize = optimize
    - self.findFile = findFile
    -
    - if module_name.find(".") >= 0:
    - vdec = ''
    - else:
    - vdec = 'var '
    - print >>self.output, UU+"%s%s = function (__mod_name__) {" % (vdec, module_name)
    -
    - print >>self.output, " if("+module_name+".__was_initialized__) return;"
    - print >>self.output, " "+UU+module_name+".__was_initialized__ = true;"
    - print >>self.output, UU+"if (__mod_name__ == null) __mod_name__ = '%s';" % (mn)
    - print >>self.output, UU+"%s.__name__ = __mod_name__;" % (raw_module_name)
    -
    - decl = mod_var_name_decl(raw_module_name)
    - if decl:
    - print >>self.output, decl
    -
    -
    - if self.debug:
    - haltException = self.module_prefix + "HaltException"
    - print >>self.output, haltException + ' = function () {'
    - print >>self.output, ' this.message = "Program Halted";'
    - print >>self.output, ' this.name = "' + haltException + '";'
    - print >>self.output, '}'
    - print >>self.output, ''
    - print >>self.output, haltException + ".prototype.__str__ = function()"
    - print >>self.output, '{'
    - print >>self.output, 'return this.message ;'
    - print >>self.output, '}'
    -
    - print >>self.output, haltException + ".prototype.toString = function()"
    - print >>self.output, '{'
    - print >>self.output, 'return this.name + ": \\"" + this.message + "\\"";'
    - print >>self.output, '}'
    -
    - isHaltFunction = self.module_prefix + "IsHaltException"
    - print >>self.output, """
    - %s = function (s) {
    - var suffix="HaltException";
    - if (s.length < suffix.length) {
    - //alert(s + " " + suffix);
    - return false;
    - } else {
    - var ss = s.substring(s.length, (s.length - suffix.length));
    - //alert(s + " " + suffix + " " + ss);
    - return ss == suffix;
    - }
    - }
    - """ % isHaltFunction
    - for child in mod.node:
    - if isinstance(child, ast.Function):
    - self.top_level_functions.add(child.name)
    - elif isinstance(child, ast.Class):
    - self.top_level_classes.add(child.name)
    -
    - for child in mod.node:
    - if isinstance(child, ast.Function):
    - self._function(child, False)
    - elif isinstance(child, ast.Class):
    - self._class(child)
    - elif isinstance(child, ast.Import):
    - importName = child.names[0][0]
    - if importName == '__pyjamas__': # special module to help make pyjamas modules loadable in the python interpreter
    - pass
    - elif importName.endswith('.js'):
    - self.imported_js.add(importName)
    - else:
    - self.add_imported_module(strip_py(importName))
    - elif isinstance(child, ast.From):
    - if child.modname == '__pyjamas__': # special module to help make pyjamas modules loadable in the python interpreter
    - pass
    - else:
    - self.add_imported_module(child.modname)
    - self._from(child)
    - elif isinstance(child, ast.Discard):
    - self._discard(child, None)
    - elif isinstance(child, ast.Assign):
    - self._assign(child, None, True)
    - elif isinstance(child, ast.AugAssign):
    - self._augassign(child, None)
    - elif isinstance(child, ast.If):
    - self._if(child, None)
    - elif isinstance(child, ast.For):
    - self._for(child, None)
    - elif isinstance(child, ast.While):
    - self._while(child, None)
    - elif isinstance(child, ast.Subscript):
    - self._subscript_stmt(child, None)
    - elif isinstance(child, ast.Global):
    - self._global(child, None)
    - elif isinstance(child, ast.Printnl):
    - self._print(child, None)
    - elif isinstance(child, ast.Print):
    - self._print(child, None)
    - elif isinstance(child, ast.TryExcept):
    - self._tryExcept(child, None)
    - elif isinstance(child, ast.Raise):
    - self._raise(child, None)
    - elif isinstance(child, ast.Stmt):
    - self._stmt(child, None)
    - else:
    - raise TranslationError("unsupported type (in __init__)", child)
    -
    - # Initialize all classes for this module
    - #print >> self.output, "__"+self.modpfx()+\
    - # "classes_initialize = function() {\n"
    - #for className in self.top_level_classes:
    - # print >> self.output, "\t"+UU+self.modpfx()+"__"+className+"_initialize();"
    - #print >> self.output, "};\n"
    -
    - print >> self.output, "return this;\n"
    - print >> self.output, "}; /* end %s */ \n" % module_name
    -
    - def module_imports(self):
    - return self.imported_modules + self.imported_modules_as
    -
    - def add_local_arg(self, varname):
    - local_vars = self.local_arg_stack[-1]
    - if varname not in local_vars:
    - local_vars.append(varname)
    -
    - def add_imported_module(self, importName):
    -
    - if importName in self.imported_modules:
    - return
    - self.imported_modules.append(importName)
    - name = importName.split(".")
    - if len(name) != 1:
    - # add the name of the module to the namespace,
    - # but don't add the short name to imported_modules
    - # because then the short name would be attempted to be
    - # added to the dependencies, and it's half way up the
    - # module import directory structure!
    - child_name = name[-1]
    - self.imported_modules_as.append(child_name)
    - print >> self.output, gen_mod_import(self.raw_module_name,
    - strip_py(importName),
    - self.dynamic)
    -
    - def _default_args_handler(self, node, arg_names, current_klass,
    - output=None):
    - if len(node.defaults):
    - output = output or self.output
    - default_pos = len(arg_names) - len(node.defaults)
    - if arg_names and arg_names[0] == self.method_self:
    - default_pos -= 1
    - for default_node in node.defaults:
    - if isinstance(default_node, ast.Const):
    - default_value = self._const(default_node)
    - elif isinstance(default_node, ast.Name):
    - default_value = self._name(default_node, current_klass)
    - elif isinstance(default_node, ast.UnarySub):
    - default_value = self._unarysub(default_node, current_klass)
    - else:
    - raise TranslationError("unsupported type (in _method)", default_node)
    -
    - default_name = arg_names[default_pos]
    - default_pos += 1
    - print >> output, " if (typeof %s == 'undefined') %s=%s;" % (default_name, default_name, default_value)
    -
    - def _varargs_handler(self, node, varargname, arg_names, current_klass):
    - print >>self.output, " var", varargname, '= new pyjslib.Tuple();'
    - print >>self.output, " for(var __va_arg="+str(len(arg_names))+"; __va_arg < arguments.length; __va_arg++) {"
    - print >>self.output, " var __arg = arguments[__va_arg];"
    - print >>self.output, " "+varargname+".append(__arg);"
    - print >>self.output, " }"
    -
    - def _kwargs_parser(self, node, function_name, arg_names, current_klass):
    - if len(node.defaults) or node.kwargs:
    - default_pos = len(arg_names) - len(node.defaults)
    - if arg_names and arg_names[0] == self.method_self:
    - default_pos -= 1
    - print >>self.output, function_name+'.parse_kwargs = function (', ", ".join(["__kwargs"]+arg_names), ") {"
    - for default_node in node.defaults:
    - default_value = self.expr(default_node, current_klass)
    -# if isinstance(default_node, ast.Const):
    -# default_value = self._const(default_node)
    -# elif isinstance(default_node, ast.Name):
    -# default_value = self._name(default_node)
    -# elif isinstance(default_node, ast.UnarySub):
    -# default_value = self._unarysub(default_node, current_klass)
    -# else:
    -# raise TranslationError("unsupported type (in _method)", default_node)
    -
    - default_name = arg_names[default_pos]
    - print >>self.output, " if (typeof %s == 'undefined')"%(default_name)
    - print >>self.output, " %s=__kwargs.%s;"% (default_name, default_name)
    - default_pos += 1
    -
    - #self._default_args_handler(node, arg_names, current_klass)
    - if node.kwargs: arg_names += ["pyjslib.Dict(__kwargs)"]
    - print >>self.output, " var __r = "+"".join(["[", ", ".join(arg_names), "]"])+";"
    - if node.varargs:
    - self._varargs_handler(node, "__args", arg_names, current_klass)
    - print >>self.output, " __r.push.apply(__r, __args.getArray())"
    - print >>self.output, " return __r;"
    - print >>self.output, "};"
    -
    - def _function(self, node, local=False):
    - if local:
    - function_name = node.name
    - self.add_local_arg(function_name)
    - else:
    - function_name = UU + self.modpfx() + node.name
    -
    - arg_names = list(node.argnames)
    - normal_arg_names = list(arg_names)
    - if node.kwargs: kwargname = normal_arg_names.pop()
    - if node.varargs: varargname = normal_arg_names.pop()
    - declared_arg_names = list(normal_arg_names)
    - if node.kwargs: declared_arg_names.append(kwargname)
    -
    - function_args = "(" + ", ".join(declared_arg_names) + ")"
    - print >>self.output, "%s = function%s {" % (function_name, function_args)
    - self._default_args_handler(node, normal_arg_names, None)
    -
    - local_arg_names = normal_arg_names + declared_arg_names
    -
    - if node.varargs:
    - self._varargs_handler(node, varargname, declared_arg_names, None)
    - local_arg_names.append(varargname)
    -
    - # stack of local variable names for this function call
    - self.local_arg_stack.append(local_arg_names)
    -
    - for child in node.code:
    - self._stmt(child, None)
    -
    - # remove the top local arg names
    - self.local_arg_stack.pop()
    -
    - # we need to return null always, so it is not undefined
    - lastStmt = [p for p in node.code][-1]
    - if not isinstance(lastStmt, ast.Return):
    - if not self._isNativeFunc(lastStmt):
    - print >>self.output, " return null;"
    -
    - print >>self.output, "};"
    - print >>self.output, "%s.__name__ = '%s';\n" % (function_name, node.name)
    -
    -
    - self._kwargs_parser(node, function_name, normal_arg_names, None)
    -
    -
    - def _return(self, node, current_klass):
    - expr = self.expr(node.value, current_klass)
    - # in python a function call always returns None, so we do it
    - # here too
    - print >>self.output, " return " + expr + ";"
    -
    -
    - def _break(self, node, current_klass):
    - print >>self.output, " break;"
    -
    -
    - def _continue(self, node, current_klass):
    - print >>self.output, " continue;"
    -
    -
    - def _callfunc(self, v, current_klass):
    -
    - if isinstance(v.node, ast.Name):
    - if v.node.name in self.top_level_functions:
    - call_name = self.modpfx() + v.node.name
    - elif v.node.name in self.top_level_classes:
    - call_name = self.modpfx() + v.node.name
    - elif self.imported_classes.has_key(v.node.name):
    - call_name = self.imported_classes[v.node.name] + '.' + v.node.name
    - elif v.node.name in PYJSLIB_BUILTIN_FUNCTIONS:
    - call_name = 'pyjslib.' + v.node.name
    - elif v.node.name in PYJSLIB_BUILTIN_CLASSES:
    - name = pyjs_builtin_remap(v.node.name)
    - call_name = 'pyjslib.' + name
    - elif v.node.name == "callable":
    - call_name = "pyjslib.isFunction"
    - else:
    - call_name = v.node.name
    - call_args = []
    - elif isinstance(v.node, ast.Getattr):
    - attr_name = v.node.attrname
    -
    - if isinstance(v.node.expr, ast.Name):
    - call_name = self._name2(v.node.expr, current_klass, attr_name)
    - call_args = []
    - elif isinstance(v.node.expr, ast.Getattr):
    - call_name = self._getattr2(v.node.expr, current_klass, attr_name)
    - call_args = []
    - elif isinstance(v.node.expr, ast.CallFunc):
    - call_name = self._callfunc(v.node.expr, current_klass) + "." + v.node.attrname
    - call_args = []
    - elif isinstance(v.node.expr, ast.Subscript):
    - call_name = self._subscript(v.node.expr, current_klass) + "." + v.node.attrname
    - call_args = []
    - elif isinstance(v.node.expr, ast.Const):
    - call_name = self.expr(v.node.expr, current_klass) + "." + v.node.attrname
    - call_args = []
    - else:
    - raise TranslationError("unsupported type (in _callfunc)", v.node.expr)
    - else:
    - raise TranslationError("unsupported type (in _callfunc)", v.node)
    -
    - call_name = strip_py(call_name)
    -
    - kwargs = []
    - star_arg_name = None
    - if v.star_args:
    - star_arg_name = self.expr(v.star_args, current_klass)
    -
    - for ch4 in v.args:
    - if isinstance(ch4, ast.Keyword):
    - kwarg = ch4.name + ":" + self.expr(ch4.expr, current_klass)
    - kwargs.append(kwarg)
    - else:
    - arg = self.expr(ch4, current_klass)
    - call_args.append(arg)
    -
    - if kwargs:
    - fn_args = ", ".join(['{' + ', '.join(kwargs) + '}']+call_args)
    - else:
    - fn_args = ", ".join(call_args)
    -
    - if kwargs or star_arg_name:
    - if not star_arg_name:
    - star_arg_name = 'null'
    - try: call_this, method_name = call_name.rsplit(".", 1)
    - except ValueError:
    - # Must be a function call ...
    - return ("pyjs_kwargs_function_call("+call_name+", "
    - + star_arg_name
    - + ", ["+fn_args+"]"
    - + ")" )
    - else:
    - return ("pyjs_kwargs_method_call("+call_this+", '"+method_name+"', "
    - + star_arg_name
    - + ", ["+fn_args+"]"
    - + ")")
    - else:
    - return call_name + "(" + ", ".join(call_args) + ")"
    -
    - def _print(self, node, current_klass):
    - if self.optimize:
    - return
    - call_args = []
    - for ch4 in node.nodes:
    - arg = self.expr(ch4, current_klass)
    - call_args.append(arg)
    -
    - print >>self.output, "pyjslib.printFunc([", ', '.join(call_args), "],", int(isinstance(node, ast.Printnl)), ");"
    -
    - def _tryExcept(self, node, current_klass):
    - if len(node.handlers) != 1:
    - raise TranslationError("except statements in this form are" +
    - " not supported", node)
    -
    - expr = node.handlers[0][0]
    - as_ = node.handlers[0][1]
    - if as_:
    - errName = as_.name
    - else:
    - errName = 'err'
    -
    - # XXX TODO: check that this should instead be added as a _separate_
    - # local scope, temporary to the function. oh dearie me.
    - self.add_local_arg(errName)
    -
    - print >>self.output, " try {"
    - for stmt in node.body.nodes:
    - self._stmt(stmt, current_klass)
    - print >> self.output, " } catch(%s) {" % errName
    - if expr:
    - l = []
    - if isinstance(expr, ast.Tuple):
    - for x in expr.nodes:
    - l.append("(%(err)s.__name__ == %(expr)s.__name__)" % dict (err=errName, expr=self.expr(x, current_klass)))
    - else:
    - l = [ " (%(err)s.__name__ == %(expr)s.__name__) " % dict (err=errName, expr=self.expr(expr, current_klass)) ]
    - print >> self.output, " if(%s) {" % '||\n\t\t'.join(l)
    - for stmt in node.handlers[0][2]:
    - self._stmt(stmt, current_klass)
    - if expr:
    - #print >> self.output, "} else { throw(%s); } " % errName
    - print >> self.output, "}"
    - if node.else_ != None:
    - print >>self.output, " } finally {"
    - for stmt in node.else_:
    - self._stmt(stmt, current_klass)
    - print >>self.output, " }"
    -
    - # XXX: change use_getattr to True to enable "strict" compilation
    - # but incurring a 100% performance penalty. oops.
    - def _getattr(self, v, current_klass, use_getattr=False):
    - attr_name = v.attrname
    - if isinstance(v.expr, ast.Name):
    - obj = self._name(v.expr, current_klass, return_none_for_module=True)
    - if obj == None and v.expr.name in self.module_imports():
    - # XXX TODO: distinguish between module import classes
    - # and variables. right now, this is a hack to get
    - # the sys module working.
    - #if v.expr.name == 'sys':
    - return v.expr.name+'.'+attr_name
    - #return v.expr.name+'.__'+attr_name+'.prototype.__class__'
    - if not use_getattr or attr_name == '__class__' or \
    - attr_name == '__name__':
    - return obj + "." + attr_name
    - return "pyjslib.getattr(%s, '%s')" % (obj, attr_name)
    - elif isinstance(v.expr, ast.Getattr):
    - return self._getattr(v.expr, current_klass) + "." + attr_name
    - elif isinstance(v.expr, ast.Subscript):
    - return self._subscript(v.expr, self.modpfx()) + "." + attr_name
    - elif isinstance(v.expr, ast.CallFunc):
    - return self._callfunc(v.expr, self.modpfx()) + "." + attr_name
    - else:
    - raise TranslationError("unsupported type (in _getattr)", v.expr)
    -
    -
    - def modpfx(self):
    - return strip_py(self.module_prefix)
    -
    - def _name(self, v, current_klass, top_level=False,
    - return_none_for_module=False):
    -
    - if v.name == 'ilikesillynamesfornicedebugcode':
    - print top_level, current_klass, repr(v)
    - print self.top_level_vars
    - print self.top_level_functions
    - print self.local_arg_stack
    - print "error..."
    -
    - local_var_names = None
    - las = len(self.local_arg_stack)
    - if las > 0:
    - local_var_names = self.local_arg_stack[-1]
    -
    - if v.name == "True":
    - return "true"
    - elif v.name == "False":
    - return "false"
    - elif v.name == "None":
    - return "null"
    - elif v.name == '__name__' and current_klass is None:
    - return self.modpfx() + v.name
    - elif v.name == self.method_self:
    - return "this"
    - elif v.name in self.top_level_functions:
    - return UU+self.modpfx() + v.name
    - elif v.name in self.method_imported_globals:
    - return UU+self.modpfx() + v.name
    - elif not current_klass and las == 1 and v.name in self.top_level_vars:
    - return UU+self.modpfx() + v.name
    - elif v.name in local_var_names:
    - return v.name
    - elif self.imported_classes.has_key(v.name):
    - return UU+self.imported_classes[v.name] + '.__' + v.name + ".prototype.__class__"
    - elif v.name in self.top_level_classes:
    - return UU+self.modpfx() + "__" + v.name + ".prototype.__class__"
    - elif v.name in self.module_imports() and return_none_for_module:
    - return None
    - elif v.name in PYJSLIB_BUILTIN_CLASSES:
    - return "pyjslib." + pyjs_builtin_remap( v.name )
    - elif current_klass:
    - if v.name not in local_var_names and \
    - v.name not in self.top_level_vars and \
    - v.name not in PYJS_GLOBAL_VARS and \
    - v.name not in self.top_level_functions:
    -
    - cls_name = current_klass
    - if hasattr(cls_name, "name"):
    - cls_name_ = cls_name.name_
    - cls_name = cls_name.name
    - else:
    - cls_name_ = current_klass + "_" # XXX ???
    - name = UU+cls_name_ + ".prototype.__class__." \
    - + v.name
    - if v.name == 'listener':
    - name = 'listener+' + name
    - return name
    -
    - return v.name
    -
    - def _name2(self, v, current_klass, attr_name):
    - obj = v.name
    -
    - if obj in self.method_imported_globals:
    - call_name = UU+self.modpfx() + obj + "." + attr_name
    - elif self.imported_classes.has_key(obj):
    - #attr_str = ""
    - #if attr_name != "__init__":
    - attr_str = ".prototype.__class__." + attr_name
    - call_name = UU+self.imported_classes[obj] + '.__' + obj + attr_str
    - elif obj in self.module_imports():
    - call_name = obj + "." + attr_name
    - elif obj[0] == obj[0].upper(): # XXX HACK ALERT
    - call_name = UU + self.modpfx() + "__" + obj + ".prototype.__class__." + attr_name
    - else:
    - call_name = UU+self._name(v, current_klass) + "." + attr_name
    -
    - return call_name
    -
    -
    - def _getattr2(self, v, current_klass, attr_name):
    - if isinstance(v.expr, ast.Getattr):
    - call_name = self._getattr2(v.expr, current_klass, v.attrname + "." + attr_name)
    - elif isinstance(v.expr, ast.Name) and v.expr.name in self.module_imports():
    - call_name = UU+v.expr.name + '.__' +v.attrname+".prototype.__class__."+attr_name
    - else:
    - obj = self.expr(v.expr, current_klass)
    - call_name = obj + "." + v.attrname + "." + attr_name
    -
    - return call_name
    -
    -
    - def _class(self, node):
    - """
    - Handle a class definition.
    -
    - In order to translate python semantics reasonably well, the following
    - structure is used:
    -
    - A special object is created for the class, which inherits attributes
    - from the superclass, or Object if there's no superclass. This is the
    - class object; the object which you refer to when specifying the
    - class by name. Static, class, and unbound methods are copied
    - from the superclass object.
    -
    - A special constructor function is created with the same name as the
    - class, which is used to create instances of that class.
    -
    - A javascript class (e.g. a function with a prototype attribute) is
    - created which is the javascript class of created instances, and
    - which inherits attributes from the class object. Bound methods are
    - copied from the superclass into this class rather than inherited,
    - because the class object contains unbound, class, and static methods
    - that we don't necessarily want to inherit.
    -
    - The type of a method can now be determined by inspecting its
    - static_method, unbound_method, class_method, or instance_method
    - attribute; only one of these should be true.
    -
    - Much of this work is done in pyjs_extend, is pyjslib.py
    - """
    - class_name = self.modpfx() + uuprefix(node.name, 1)
    - class_name_ = self.modpfx() + uuprefix(node.name)
    - current_klass = Klass(class_name, class_name_)
    - init_method = None
    - for child in node.code:
    - if isinstance(child, ast.Function):
    - current_klass.add_function(child.name)
    - if child.name == "__init__":
    - init_method = child
    -
    -
    - if len(node.bases) == 0:
    - base_class = "pyjslib.__Object"
    - elif len(node.bases) == 1:
    - if isinstance(node.bases[0], ast.Name):
    - if self.imported_classes.has_key(node.bases[0].name):
    - base_class_ = self.imported_classes[node.bases[0].name] + '.__' + node.bases[0].name
    - base_class = self.imported_classes[node.bases[0].name] + '.' + node.bases[0].name
    - else:
    - base_class_ = self.modpfx() + "__" + node.bases[0].name
    - base_class = self.modpfx() + node.bases[0].name
    - elif isinstance(node.bases[0], ast.Getattr):
    - # the bases are not in scope of the class so do not
    - # pass our class to self._name
    - base_class_ = self._name(node.bases[0].expr, None) + \
    - ".__" + node.bases[0].attrname
    - base_class = self._name(node.bases[0].expr, None) + \
    - "." + node.bases[0].attrname
    - else:
    - raise TranslationError("unsupported type (in _class)", node.bases[0])
    -
    - current_klass.set_base(base_class)
    - else:
    - raise TranslationError("more than one base (in _class)", node)
    -
    - print >>self.output, UU+class_name_ + " = function () {"
    - # call superconstructor
    - #if base_class:
    - # print >>self.output, " __" + base_class + ".call(this);"
    - print >>self.output, "}"
    -
    - if not init_method:
    - init_method = ast.Function([], "__init__", ["self"], [], 0, None, [])
    - #self._method(init_method, current_klass, class_name)
    -
    - # Generate a function which constructs the object
    - clsfunc = ast.Function([],
    - node.name,
    - init_method.argnames[1:],
    - init_method.defaults,
    - init_method.flags,
    - None,
    - [ast.Discard(ast.CallFunc(ast.Name("JS"), [ast.Const(
    -# I attempted lazy initialization, but then you can't access static class members
    -# " if(!__"+base_class+".__was_initialized__)"+
    -# " __" + class_name + "_initialize();\n" +
    - " var instance = new " + UU + class_name_ + "();\n" +
    - " if(instance.__init__) instance.__init__.apply(instance, arguments);\n" +
    - " return instance;"
    - )]))])
    -
    - self._function(clsfunc, False)
    - print >>self.output, UU+class_name_ + ".__initialize__ = function () {"
    - print >>self.output, " if("+UU+class_name_+".__was_initialized__) return;"
    - print >>self.output, " "+UU+class_name_+".__was_initialized__ = true;"
    - cls_obj = UU+class_name_ + '.prototype.__class__'
    -
    - if class_name == "pyjslib.__Object":
    - print >>self.output, " "+cls_obj+" = {};"
    - else:
    - if base_class and base_class not in ("object", "pyjslib.__Object"):
    - print >>self.output, " if(!"+UU+base_class_+".__was_initialized__)"
    - print >>self.output, " "+UU+base_class_+".__initialize__();"
    - print >>self.output, " pyjs_extend(" + UU+class_name_ + ", "+UU+base_class_+");"
    - else:
    - print >>self.output, " pyjs_extend(" + UU+class_name_ + ", "+UU+"pyjslib.__Object);"
    -
    - print >>self.output, " "+cls_obj+".__new__ = "+UU+class_name+";"
    - print >>self.output, " "+cls_obj+".__name__ = '"+UU+node.name+"';"
    -
    - for child in node.code:
    - if isinstance(child, ast.Pass):
    - pass
    - elif isinstance(child, ast.Function):
    - self._method(child, current_klass, class_name, class_name_)
    - elif isinstance(child, ast.Assign):
    - self.classattr(child, current_klass)
    - elif isinstance(child, ast.Discard) and isinstance(child.expr, ast.Const):
    - # Probably a docstring, turf it
    - pass
    - else:
    - raise TranslationError("unsupported type (in _class)", child)
    - print >>self.output, "}"
    -
    - print >> self.output, class_name_+".__initialize__();"
    -
    -
    - def classattr(self, node, current_klass):
    - self._assign(node, current_klass, True)
    -
    - def _raise(self, node, current_klass):
    - if node.expr2:
    - raise TranslationError("More than one expression unsupported",
    - node)
    - print >> self.output, "throw (%s);" % self.expr(
    - node.expr1, current_klass)
    -
    - def _method(self, node, current_klass, class_name, class_name_):
    - # reset global var scope
    - self.method_imported_globals = set()
    -
    - arg_names = list(node.argnames)
    -
    - classmethod = False
    - staticmethod = False
    - if node.decorators:
    - for d in node.decorators:
    - if d.name == "classmethod":
    - classmethod = True
    - elif d.name == "staticmethod":
    - staticmethod = True
    -
    - if staticmethod:
    - staticfunc = ast.Function([], class_name_+"."+node.name, node.argnames, node.defaults, node.flags, node.doc, node.code, node.lineno)
    - self._function(staticfunc, True)
    - print >>self.output, " " + UU+class_name_ + ".prototype.__class__." + node.name + " = " + class_name_+"."+node.name+";";
    - print >>self.output, " " + UU+class_name_ + ".prototype.__class__." + node.name + ".static_method = true;";
    - return
    - else:
    - if len(arg_names) == 0:
    - raise TranslationError("methods must take an argument 'self' (in _method)", node)
    - self.method_self = arg_names[0]
    -
    - #if not classmethod and arg_names[0] != "self":
    - # raise TranslationError("first arg not 'self' (in _method)", node)
    -
    - normal_arg_names = arg_names[1:]
    - if node.kwargs: kwargname = normal_arg_names.pop()
    - if node.varargs: varargname = normal_arg_names.pop()
    - declared_arg_names = list(normal_arg_names)
    - if node.kwargs: declared_arg_names.append(kwargname)
    -
    - function_args = "(" + ", ".join(declared_arg_names) + ")"
    -
    - if classmethod:
    - fexpr = UU + class_name_ + ".prototype.__class__." + node.name
    - else:
    - fexpr = UU + class_name_ + ".prototype." + node.name
    - print >>self.output, " "+fexpr + " = function" + function_args + " {"
    -
    - # default arguments
    - self._default_args_handler(node, normal_arg_names, current_klass)
    -
    - local_arg_names = normal_arg_names + declared_arg_names
    -
    - if node.varargs:
    - self._varargs_handler(node, varargname, declared_arg_names, current_klass)
    - local_arg_names.append(varargname)
    -
    -
    - # stack of local variable names for this function call
    - self.local_arg_stack.append(local_arg_names)
    -
    - for child in node.code:
    - self._stmt(child, current_klass)
    -
    - # remove the top local arg names
    - self.local_arg_stack.pop()
    -
    - print >>self.output, " };"
    -
    - self._kwargs_parser(node, fexpr, normal_arg_names, current_klass)
    -
    - if classmethod:
    - # Have to create a version on the instances which automatically passes the
    - # class as "self"
    - altexpr = UU + class_name_ + ".prototype." + node.name
    - print >>self.output, " "+altexpr + " = function() {"
    - print >>self.output, " return " + fexpr + ".apply(this.__class__, arguments);"
    - print >>self.output, " };"
    - print >>self.output, " "+fexpr+".class_method = true;"
    - print >>self.output, " "+altexpr+".instance_method = true;"
    - else:
    - # For instance methods, we need an unbound version in the class object
    - altexpr = UU + class_name_ + ".prototype.__class__." + node.name
    - print >>self.output, " "+altexpr + " = function() {"
    - print >>self.output, " return " + fexpr + ".call.apply("+fexpr+", arguments);"
    - print >>self.output, " };"
    - print >>self.output, " "+altexpr+".unbound_method = true;"
    - print >>self.output, " "+fexpr+".instance_method = true;"
    - print >>self.output, " "+altexpr+".__name__ = '%s';" % node.name
    -
    - print >>self.output, UU + class_name_ + ".prototype.%s.__name__ = '%s';" % \
    - (node.name, node.name)
    -
    - if node.kwargs or len(node.defaults):
    - print >>self.output, " "+altexpr + ".parse_kwargs = " + fexpr + ".parse_kwargs;"
    -
    - self.method_self = None
    - self.method_imported_globals = set()
    -
    - def _isNativeFunc(self, node):
    - if isinstance(node, ast.Discard):
    - if isinstance(node.expr, ast.CallFunc):
    - if isinstance(node.expr.node, ast.Name) and \
    - node.expr.node.name == NATIVE_JS_FUNC_NAME:
    - return True
    - return False
    -
    - def _stmt(self, node, current_klass):
    - debugStmt = self.debug and not self._isNativeFunc(node)
    - if debugStmt:
    - print >>self.output, ' try {'
    -
    - if isinstance(node, ast.Return):
    - self._return(node, current_klass)
    - elif isinstance(node, ast.Break):
    - self._break(node, current_klass)
    - elif isinstance(node, ast.Continue):
    - self._continue(node, current_klass)
    - elif isinstance(node, ast.Assign):
    - self._assign(node, current_klass)
    - elif isinstance(node, ast.AugAssign):
    - self._augassign(node, current_klass)
    - elif isinstance(node, ast.Discard):
    - self._discard(node, current_klass)
    - elif isinstance(node, ast.If):
    - self._if(node, current_klass)
    - elif isinstance(node, ast.For):
    - self._for(node, current_klass)
    - elif isinstance(node, ast.While):
    - self._while(node, current_klass)
    - elif isinstance(node, ast.Subscript):
    - self._subscript_stmt(node, current_klass)
    - elif isinstance(node, ast.Global):
    - self._global(node, current_klass)
    - elif isinstance(node, ast.Pass):
    - pass
    - elif isinstance(node, ast.Function):
    - self._function(node, True)
    - elif isinstance(node, ast.Printnl):
    - self._print(node, current_klass)
    - elif isinstance(node, ast.Print):
    - self._print(node, current_klass)
    - elif isinstance(node, ast.TryExcept):
    - self._tryExcept(node, current_klass)
    - elif isinstance(node, ast.Raise):
    - self._raise(node, current_klass)
    - else:
    - raise TranslationError("unsupported type (in _stmt)", node)
    -
    - if debugStmt:
    -
    - lt = self.get_line_trace(node)
    -
    - haltException = self.module_prefix + "HaltException"
    - isHaltFunction = self.module_prefix + "IsHaltException"
    -
    - print >>self.output, ' } catch (__err) {'
    - print >>self.output, ' if (' + isHaltFunction + '(__err.name)) {'
    - print >>self.output, ' throw __err;'
    - print >>self.output, ' } else {'
    - print >>self.output, " st = sys.printstack() + "\
    - + '"%s"' % lt + "+ '\\n' ;"
    - print >>self.output, ' alert("' + "Error in " \
    - + lt + '"' \
    - + '+"\\n"+__err.name+": "+__err.message'\
    - + '+"\\n\\nStack trace:\\n"' \
    - + '+st' \
    - + ');'
    - print >>self.output, ' debugger;'
    -
    - print >>self.output, ' throw new ' + self.module_prefix + "HaltException();"
    - print >>self.output, ' }'
    - print >>self.output, ' }'
    -
    -
    - def get_line_trace(self, node):
    - lineNum = "Unknown"
    - srcLine = ""
    - if hasattr(node, "lineno"):
    - if node.lineno != None:
    - lineNum = node.lineno
    - srcLine = self.src[min(lineNum, len(self.src))-1]
    - srcLine = srcLine.replace('\\', '\\\\')
    - srcLine = srcLine.replace('"', '\\"')
    - srcLine = srcLine.replace("'", "\\'")
    -
    - return self.raw_module_name + ".py, line " \
    - + str(lineNum) + ":"\
    - + "\\n" \
    - + " " + srcLine
    -
    - def _augassign(self, node, current_klass):
    - v = node.node
    - if isinstance(v, ast.Getattr):
    - # XXX HACK! don't allow += on return result of getattr.
    - # TODO: create a temporary variable or something.
    - lhs = self._getattr(v, current_klass, False)
    - else:
    - lhs = self._name(node.node, current_klass)
    - op = node.op
    - rhs = self.expr(node.expr, current_klass)
    - print >>self.output, " " + lhs + " " + op + " " + rhs + ";"
    -
    -
    - def _assign(self, node, current_klass, top_level = False):
    - if len(node.nodes) != 1:
    - tempvar = '__temp'+str(node.lineno)
    - tnode = ast.Assign([ast.AssName(tempvar, "OP_ASSIGN", node.lineno)], node.expr, node.lineno)
    - self._assign(tnode, current_klass, top_level)
    - for v in node.nodes:
    - tnode2 = ast.Assign([v], ast.Name(tempvar, node.lineno), node.lineno)
    - self._assign(tnode2, current_klass, top_level)
    - return
    -
    - local_var_names = None
    - if len(self.local_arg_stack) > 0:
    - local_var_names = self.local_arg_stack[-1]
    -
    - def _lhsFromAttr(v, current_klass):
    - attr_name = v.attrname
    - if isinstance(v.expr, ast.Name):
    - obj = v.expr.name
    - lhs = self._name(v.expr, current_klass) + "." + attr_name
    - elif isinstance(v.expr, ast.Getattr):
    - lhs = self._getattr(v, current_klass)
    - elif isinstance(v.expr, ast.Subscript):
    - lhs = self._subscript(v.expr, current_klass) + "." + attr_name
    - else:
    - raise TranslationError("unsupported type (in _assign)", v.expr)
    - return lhs
    -
    - def _lhsFromName(v, top_level, current_klass):
    - if top_level:
    - if current_klass:
    - lhs = UU+current_klass.name_ + ".prototype.__class__." \
    - + v.name
    - else:
    - self.top_level_vars.add(v.name)
    - vname = self.modpfx() + v.name
    - if not self.modpfx() and v.name not in\
    - self.method_imported_globals:
    - lhs = "var " + vname
    - else:
    - lhs = UU + vname
    - self.add_local_arg(v.name)
    - else:
    - if v.name in local_var_names:
    - lhs = v.name
    - elif v.name in self.method_imported_globals:
    - lhs = self.modpfx() + v.name
    - else:
    - lhs = "var " + v.name
    - self.add_local_arg(v.name)
    - return lhs
    -
    - dbg = 0
    - v = node.nodes[0]
    - if isinstance(v, ast.AssAttr):
    - lhs = _lhsFromAttr(v, current_klass)
    - if v.flags == "OP_ASSIGN":
    - op = "="
    - else:
    - raise TranslationError("unsupported flag (in _assign)", v)
    -
    - elif isinstance(v, ast.AssName):
    - lhs = _lhsFromName(v, top_level, current_klass)
    - if v.flags == "OP_ASSIGN":
    - op = "="
    - else:
    - raise TranslationError("unsupported flag (in _assign)", v)
    - elif isinstance(v, ast.Subscript):
    - if v.flags == "OP_ASSIGN":
    - obj = self.expr(v.expr, current_klass)
    - if len(v.subs) != 1:
    - raise TranslationError("must have one sub (in _assign)", v)
    - idx = self.expr(v.subs[0], current_klass)
    - value = self.expr(node.expr, current_klass)
    - print >>self.output, " " + obj + ".__setitem__(" + idx + ", " + value + ");"
    - return
    - else:
    - raise TranslationError("unsupported flag (in _assign)", v)
    - elif isinstance(v, (ast.AssList, ast.AssTuple)):
    - uniqueID = self.nextTupleAssignID
    - self.nextTupleAssignID += 1
    - tempName = "__tupleassign" + str(uniqueID) + "__"
    - print >>self.output, " var " + tempName + " = " + \
    - self.expr(node.expr, current_klass) + ";"
    - for index,child in enumerate(v.getChildNodes()):
    - rhs = tempName + ".__getitem__(" + str(index) + ")"
    -
    - if isinstance(child, ast.AssAttr):
    - lhs = _lhsFromAttr(child, current_klass)
    - elif isinstance(child, ast.AssName):
    - lhs = _lhsFromName(child, top_level, current_klass)
    - elif isinstance(child, ast.Subscript):
    - if child.flags == "OP_ASSIGN":
    - obj = self.expr(child.expr, current_klass)
    - if len(child.subs) != 1:
    - raise TranslationError("must have one sub " +
    - "(in _assign)", child)
    - idx = self.expr(child.subs[0], current_klass)
    - value = self.expr(node.expr, current_klass)
    - print >>self.output, " " + obj + ".__setitem__(" \
    - + idx + ", " + rhs + ");"
    - continue
    - print >>self.output, " " + lhs + " = " + rhs + ";"
    - return
    - else:
    - raise TranslationError("unsupported type (in _assign)", v)
    -
    - rhs = self.expr(node.expr, current_klass)
    - if dbg:
    - print "b", repr(node.expr), rhs
    - print >>self.output, " " + lhs + " " + op + " " + rhs + ";"
    -
    -
    - def _discard(self, node, current_klass):
    -
    - if isinstance(node.expr, ast.CallFunc):
    - debugStmt = self.debug and not self._isNativeFunc(node)
    - if debugStmt and isinstance(node.expr.node, ast.Name) and \
    - node.expr.node.name == 'import_wait':
    - debugStmt = False
    - if debugStmt:
    - st = self.get_line_trace(node)
    - print >>self.output, "sys.addstack('%s');\n" % st
    - if isinstance(node.expr.node, ast.Name) and node.expr.node.name == NATIVE_JS_FUNC_NAME:
    - if len(node.expr.args) != 1:
    - raise TranslationError("native javascript function %s must have one arg" % NATIVE_JS_FUNC_NAME, node.expr)
    - if not isinstance(node.expr.args[0], ast.Const):
    - raise TranslationError("native javascript function %s must have constant arg" % NATIVE_JS_FUNC_NAME, node.expr)
    - raw_js = node.expr.args[0].value
    - print >>self.output, raw_js
    - else:
    - expr = self._callfunc(node.expr, current_klass)
    - print >>self.output, " " + expr + ";"
    -
    - if debugStmt:
    - print >>self.output, "sys.popstack();\n"
    -
    - elif isinstance(node.expr, ast.Const):
    - if node.expr.value is not None: # Empty statements generate ignore None
    - print >>self.output, self._const(node.expr)
    - else:
    - raise TranslationError("unsupported type (in _discard)", node.expr)
    -
    -
    - def _if(self, node, current_klass):
    - for i in range(len(node.tests)):
    - test, consequence = node.tests[i]
    - if i == 0:
    - keyword = "if"
    - else:
    - keyword = "else if"
    -
    - self._if_test(keyword, test, consequence, current_klass)
    -
    - if node.else_:
    - keyword = "else"
    - test = None
    - consequence = node.else_
    -
    - self._if_test(keyword, test, consequence, current_klass)
    -
    -
    - def _if_test(self, keyword, test, consequence, current_klass):
    - if test:
    - expr = self.expr(test, current_klass)
    -
    - print >>self.output, " " + keyword + " (pyjslib.bool(" + expr + ")) {"
    - else:
    - print >>self.output, " " + keyword + " {"
    -
    - if isinstance(consequence, ast.Stmt):
    - for child in consequence.nodes:
    - self._stmt(child, current_klass)
    - else:
    - raise TranslationError("unsupported type (in _if_test)", consequence)
    -
    - print >>self.output, " }"
    -
    -
    - def _from(self, node):
    - for name in node.names:
    - # look up "hack" in AppTranslator as to how findFile gets here
    - module_name = node.modname + "." + name[0]
    - try:
    - ff = self.findFile(module_name + ".py")
    - except Exception:
    - ff = None
    - if ff:
    - self.add_imported_module(module_name)
    - else:
    - self.imported_classes[name[0]] = node.modname
    -
    -
    - def _compare(self, node, current_klass):
    - lhs = self.expr(node.expr, current_klass)
    -
    - if len(node.ops) != 1:
    - raise TranslationError("only one ops supported (in _compare)", node)
    -
    - op = node.ops[0][0]
    - rhs_node = node.ops[0][1]
    - rhs = self.expr(rhs_node, current_klass)
    -
    - if op == "==":
    - return "pyjslib.eq(%s, %s)" % (lhs, rhs)
    - if op == "in":
    - return rhs + ".__contains__(" + lhs + ")"
    - elif op == "not in":
    - return "!" + rhs + ".__contains__(" + lhs + ")"
    - elif op == "is":
    - op = "==="
    - elif op == "is not":
    - op = "!=="
    -
    - return "(" + lhs + " " + op + " " + rhs + ")"
    -
    -
    - def _not(self, node, current_klass):
    - expr = self.expr(node.expr, current_klass)
    -
    - return "!(" + expr + ")"
    -
    - def _or(self, node, current_klass):
    - expr = "("+(") || (".join([self.expr(child, current_klass) for child in node.nodes]))+')'
    - return expr
    -
    - def _and(self, node, current_klass):
    - expr = "("+(") && (".join([self.expr(child, current_klass) for child in node.nodes]))+")"
    - return expr
    -
    - def _for(self, node, current_klass):
    - assign_name = ""
    - assign_tuple = ""
    -
    - # based on Bob Ippolito's Iteration in Javascript code
    - if isinstance(node.assign, ast.AssName):
    - assign_name = node.assign.name
    - self.add_local_arg(assign_name)
    - if node.assign.flags == "OP_ASSIGN":
    - op = "="
    - elif isinstance(node.assign, ast.AssTuple):
    - op = "="
    - i = 0
    - for child in node.assign:
    - child_name = child.name
    - if assign_name == "":
    - assign_name = "temp_" + child_name
    - self.add_local_arg(child_name)
    - assign_tuple += """
    - var %(child_name)s %(op)s %(assign_name)s.__getitem__(%(i)i);
    - """ % locals()
    - i += 1
    - else:
    - raise TranslationError("unsupported type (in _for)", node.assign)
    -
    - if isinstance(node.list, ast.Name):
    - list_expr = self._name(node.list, current_klass)
    - elif isinstance(node.list, ast.Getattr):
    - list_expr = self._getattr(node.list, current_klass)
    - elif isinstance(node.list, ast.CallFunc):
    - list_expr = self._callfunc(node.list, current_klass)
    - else:
    - raise TranslationError("unsupported type (in _for)", node.list)
    -
    - lhs = "var " + assign_name
    - iterator_name = "__" + assign_name
    -
    - print >>self.output, """
    - var %(iterator_name)s = %(list_expr)s.__iter__();
    - try {
    - while (true) {
    - %(lhs)s %(op)s %(iterator_name)s.next();
    - %(assign_tuple)s
    - """ % locals()
    - for node in node.body.nodes:
    - self._stmt(node, current_klass)
    - print >>self.output, """
    - }
    - } catch (e) {
    - if (e.__name__ != pyjslib.StopIteration.__name__) {
    - throw e;
    - }
    - }
    - """ % locals()
    -
    -
    - def _while(self, node, current_klass):
    - test = self.expr(node.test, current_klass)
    - print >>self.output, " while (pyjslib.bool(" + test + ")) {"
    - if isinstance(node.body, ast.Stmt):
    - for child in node.body.nodes:
    - self._stmt(child, current_klass)
    - else:
    - raise TranslationError("unsupported type (in _while)", node.body)
    - print >>self.output, " }"
    -
    -
    - def _const(self, node):
    - if isinstance(node.value, int):
    - return str(node.value)
    - elif isinstance(node.value, float):
    - return str(node.value)
    - elif isinstance(node.value, basestring):
    - v = node.value
    - if isinstance(node.value, unicode):
    - v = v.encode('utf-8')
    - return "String('%s')" % escapejs(v)
    - elif node.value is None:
    - return "null"
    - else:
    - raise TranslationError("unsupported type (in _const)", node)
    -
    - def _unaryadd(self, node, current_klass):
    - return self.expr(node.expr, current_klass)
    -
    - def _unarysub(self, node, current_klass):
    - return "-" + self.expr(node.expr, current_klass)
    -
    - def _add(self, node, current_klass):
    - return self.expr(node.left, current_klass) + " + " + self.expr(node.right, current_klass)
    -
    - def _sub(self, node, current_klass):
    - return self.expr(node.left, current_klass) + " - " + self.expr(node.right, current_klass)
    -
    - def _div(self, node, current_klass):
    - return self.expr(node.left, current_klass) + " / " + self.expr(node.right, current_klass)
    -
    - def _mul(self, node, current_klass):
    - return self.expr(node.left, current_klass) + " * " + self.expr(node.right, current_klass)
    -
    - def _mod(self, node, current_klass):
    - if isinstance(node.left, ast.Const) and isinstance(node.left.value, StringType):
    - self.imported_js.add("sprintf.js") # Include the sprintf functionality if it is used
    - return "sprintf("+self.expr(node.left, current_klass) + ", " + self.expr(node.right, current_klass)+")"
    - return self.expr(node.left, current_klass) + " % " + self.expr(node.right, current_klass)
    -
    - def _invert(self, node, current_klass):
    - return "~" + self.expr(node.expr, current_klass)
    -
    - def _bitand(self, node, current_klass):
    - return " & ".join([self.expr(child, current_klass) for child in node.nodes])
    -
    - def _bitshiftleft(self, node, current_klass):
    - return self.expr(node.left, current_klass) + " << " + self.expr(node.right, current_klass)
    -
    - def _bitshiftright(self, node, current_klass):
    - return self.expr(node.left, current_klass) + " >>> " + self.expr(node.right, current_klass)
    -
    - def _bitxor(self,node, current_klass):
    - return " ^ ".join([self.expr(child, current_klass) for child in node.nodes])
    -
    - def _bitor(self, node, current_klass):
    - return " | ".join([self.expr(child, current_klass) for child in node.nodes])
    -
    - def _subscript(self, node, current_klass):
    - if node.flags == "OP_APPLY":
    - if len(node.subs) == 1:
    - return self.expr(node.expr, current_klass) + ".__getitem__(" + self.expr(node.subs[0], current_klass) + ")"
    - else:
    - raise TranslationError("must have one sub (in _subscript)", node)
    - else:
    - raise TranslationError("unsupported flag (in _subscript)", node)
    -
    - def _subscript_stmt(self, node, current_klass):
    - if node.flags == "OP_DELETE":
    - print >>self.output, " " + self.expr(node.expr, current_klass) + ".__delitem__(" + self.expr(node.subs[0], current_klass) + ");"
    - else:
    - raise TranslationError("unsupported flag (in _subscript)", node)
    -
    - def _list(self, node, current_klass):
    - return "new pyjslib.List([" + ", ".join([self.expr(x, current_klass) for x in node.nodes]) + "])"
    -
    - def _dict(self, node, current_klass):
    - items = []
    - for x in node.items:
    - key = self.expr(x[0], current_klass)
    - value = self.expr(x[1], current_klass)
    - items.append("[" + key + ", " + value + "]")
    - return "new pyjslib.Dict([" + ", ".join(items) + "])"
    -
    - def _tuple(self, node, current_klass):
    - return "new pyjslib.Tuple([" + ", ".join([self.expr(x, current_klass) for x in node.nodes]) + "])"
    -
    - def _lambda(self, node, current_klass):
    - if node.varargs:
    - raise TranslationError("varargs are not supported in Lambdas", node)
    - if node.kwargs:
    - raise TranslationError("kwargs are not supported in Lambdas", node)
    - res = cStringIO.StringIO()
    - arg_names = list(node.argnames)
    - function_args = ", ".join(arg_names)
    - for child in node.getChildNodes():
    - expr = self.expr(child, None)
    - print >> res, "function (%s){" % function_args
    - self._default_args_handler(node, arg_names, None,
    - output=res)
    - print >> res, 'return %s;}' % expr
    - return res.getvalue()
    -
    - def _slice(self, node, current_klass):
    - if node.flags == "OP_APPLY":
    - lower = "null"
    - upper = "null"
    - if node.lower != None:
    - lower = self.expr(node.lower, current_klass)
    - if node.upper != None:
    - upper = self.expr(node.upper, current_klass)
    - return "pyjslib.slice(" + self.expr(node.expr, current_klass) + ", " + lower + ", " + upper + ")"
    - else:
    - raise TranslationError("unsupported flag (in _slice)", node)
    -
    - def _global(self, node, current_klass):
    - for name in node.names:
    - self.method_imported_globals.add(name)
    -
    - def expr(self, node, current_klass):
    - if isinstance(node, ast.Const):
    - return self._const(node)
    - # @@@ not sure if the parentheses should be here or in individual operator functions - JKT
    - elif isinstance(node, ast.Mul):
    - return " ( " + self._mul(node, current_klass) + " ) "
    - elif isinstance(node, ast.Add):
    - return " ( " + self._add(node, current_klass) + " ) "
    - elif isinstance(node, ast.Sub):
    - return " ( " + self._sub(node, current_klass) + " ) "
    - elif isinstance(node, ast.Div):
    - return " ( " + self._div(node, current_klass) + " ) "
    - elif isinstance(node, ast.Mod):
    - return self._mod(node, current_klass)
    - elif isinstance(node, ast.UnaryAdd):
    - return self._unaryadd(node, current_klass)
    - elif isinstance(node, ast.UnarySub):
    - return self._unarysub(node, current_klass)
    - elif isinstance(node, ast.Not):
    - return self._not(node, current_klass)
    - elif isinstance(node, ast.Or):
    - return self._or(node, current_klass)
    - elif isinstance(node, ast.And):
    - return self._and(node, current_klass)
    - elif isinstance(node, ast.Invert):
    - return self._invert(node, current_klass)
    - elif isinstance(node, ast.Bitand):
    - return "("+self._bitand(node, current_klass)+")"
    - elif isinstance(node,ast.LeftShift):
    - return self._bitshiftleft(node, current_klass)
    - elif isinstance(node, ast.RightShift):
    - return self._bitshiftright(node, current_klass)
    - elif isinstance(node, ast.Bitxor):
    - return "("+self._bitxor(node, current_klass)+")"
    - elif isinstance(node, ast.Bitor):
    - return "("+self._bitor(node, current_klass)+")"
    - elif isinstance(node, ast.Compare):
    - return self._compare(node, current_klass)
    - elif isinstance(node, ast.CallFunc):
    - return self._callfunc(node, current_klass)
    - elif isinstance(node, ast.Name):
    - return self._name(node, current_klass)
    - elif isinstance(node, ast.Subscript):
    - return self._subscript(node, current_klass)
    - elif isinstance(node, ast.Getattr):
    - return self._getattr(node, current_klass)
    - elif isinstance(node, ast.List):
    - return self._list(node, current_klass)
    - elif isinstance(node, ast.Dict):
    - return self._dict(node, current_klass)
    - elif isinstance(node, ast.Tuple):
    - return self._tuple(node, current_klass)
    - elif isinstance(node, ast.Slice):
    - return self._slice(node, current_klass)
    - elif isinstance(node, ast.Lambda):
    - return self._lambda(node, current_klass)
    - else:
    - raise TranslationError("unsupported type (in expr)", node)
    -
    -
    -
    -import cStringIO
    -
    -def translate(file_name, module_name, debug=False):
    - f = file(file_name, "r")
    - src = f.read()
    - f.close()
    - output = cStringIO.StringIO()
    - mod = compiler.parseFile(file_name)
    - t = Translator(module_name, module_name, module_name, src, debug, mod, output)
    - return output.getvalue()
    -
    -
    -class PlatformParser:
    - def __init__(self, platform_dir = "", verbose=True):
    - self.platform_dir = platform_dir
    - self.parse_cache = {}
    - self.platform = ""
    - self.verbose = verbose
    -
    - def setPlatform(self, platform):
    - self.platform = platform
    -
    - def parseModule(self, module_name, file_name):
    -
    - importing = False
    - if not self.parse_cache.has_key(file_name):
    - importing = True
    - mod = compiler.parseFile(file_name)
    - self.parse_cache[file_name] = mod
    - else:
    - mod = self.parse_cache[file_name]
    -
    - override = False
    - platform_file_name = self.generatePlatformFilename(file_name)
    - if self.platform and os.path.isfile(platform_file_name):
    - mod = copy.deepcopy(mod)
    - mod_override = compiler.parseFile(platform_file_name)
    - self.merge(mod, mod_override)
    - override = True
    -
    - if self.verbose:
    - if override:
    - print "Importing %s (Platform %s)" % (module_name, self.platform)
    - elif importing:
    - print "Importing %s" % (module_name)
    -
    - return mod, override
    -
    - def generatePlatformFilename(self, file_name):
    - (module_name, extension) = os.path.splitext(os.path.basename(file_name))
    - platform_file_name = module_name + self.platform + extension
    -
    - return os.path.join(os.path.dirname(file_name), self.platform_dir, platform_file_name)
    -
    - def merge(self, tree1, tree2):
    - for child in tree2.node:
    - if isinstance(child, ast.Function):
    - self.replaceFunction(tree1, child.name, child)
    - elif isinstance(child, ast.Class):
    - self.replaceClassMethods(tree1, child.name, child)
    -
    - return tree1
    -
    - def replaceFunction(self, tree, function_name, function_node):
    - # find function to replace
    - for child in tree.node:
    - if isinstance(child, ast.Function) and child.name == function_name:
    - self.copyFunction(child, function_node)
    - return
    - raise TranslationError("function not found: " + function_name, function_node)
    -
    - def replaceClassMethods(self, tree, class_name, class_node):
    - # find class to replace
    - old_class_node = None
    - for child in tree.node:
    - if isinstance(child, ast.Class) and child.name == class_name:
    - old_class_node = child
    - break
    -
    - if not old_class_node:
    - raise TranslationError("class not found: " + class_name, class_node)
    -
    - # replace methods
    - for function_node in class_node.code:
    - if isinstance(function_node, ast.Function):
    - found = False
    - for child in old_class_node.code:
    - if isinstance(child, ast.Function) and child.name == function_node.name:
    - found = True
    - self.copyFunction(child, function_node)
    - break
    -
    - if not found:
    - raise TranslationError("class method not found: " + class_name + "." + function_node.name, function_node)
    -
    - def copyFunction(self, target, source):
    - target.code = source.code
    - target.argnames = source.argnames
    - target.defaults = source.defaults
    - target.doc = source.doc # @@@ not sure we need to do this any more
    -
    -def dotreplace(fname):
    - path, ext = os.path.splitext(fname)
    - return path.replace(".", "/") + ext
    -
    -class AppTranslator:
    -
    - def __init__(self, library_dirs=[], parser=None, dynamic=False,
    - optimize=False, verbose=True):
    - self.extension = ".py"
    - self.optimize = optimize
    - self.library_modules = []
    - self.overrides = {}
    - self.library_dirs = path + library_dirs
    - self.dynamic = dynamic
    - self.verbose = verbose
    -
    - if not parser:
    - self.parser = PlatformParser()
    - else:
    - self.parser = parser
    -
    - self.parser.dynamic = dynamic
    -
    - def findFile(self, file_name):
    - if os.path.isfile(file_name):
    - return file_name
    -
    - for library_dir in self.library_dirs:
    - file_name = dotreplace(file_name)
    - full_file_name = os.path.join(
    - os.path.abspath(os.path.dirname(__file__)), library_dir, file_name)
    - if os.path.isfile(full_file_name):
    - return full_file_name
    -
    - fnameinit, ext = os.path.splitext(file_name)
    - fnameinit = fnameinit + "/__init__.py"
    -
    - full_file_name = os.path.join(
    - os.path.abspath(os.path.dirname(__file__)), library_dir, fnameinit)
    - if os.path.isfile(full_file_name):
    - return full_file_name
    -
    - raise Exception("file not found: " + file_name)
    -
    - def _translate(self, module_name, is_app=True, debug=False,
    - imported_js=set()):
    - if module_name not in self.library_modules:
    - self.library_modules.append(module_name)
    -
    - file_name = self.findFile(module_name + self.extension)
    -
    - output = cStringIO.StringIO()
    -
    - f = file(file_name, "r")
    - src = f.read()
    - f.close()
    -
    - mod, override = self.parser.parseModule(module_name, file_name)
    - if override:
    - override_name = "%s.%s" % (self.parser.platform.lower(),
    - module_name)
    - self.overrides[override_name] = override_name
    - if is_app:
    - mn = '__main__'
    - else:
    - mn = module_name
    - t = Translator(mn, module_name, module_name,
    - src, debug, mod, output, self.dynamic, self.optimize,
    - self.findFile)
    -
    - module_str = output.getvalue()
    - imported_js.update(set(t.imported_js))
    - imported_modules_str = ""
    - for module in t.imported_modules:
    - if module not in self.library_modules:
    - self.library_modules.append(module)
    - #imported_js.update(set(t.imported_js))
    - #imported_modules_str += self._translate(
    - # module, False, debug=debug, imported_js=imported_js)
    -
    - return imported_modules_str + module_str
    -
    -
    - def translate(self, module_name, is_app=True, debug=False,
    - library_modules=[]):
    - app_code = cStringIO.StringIO()
    - lib_code = cStringIO.StringIO()
    - imported_js = set()
    - self.library_modules = []
    - self.overrides = {}
    - for library in library_modules:
    - if library.endswith(".js"):
    - imported_js.add(library)
    - continue
    - self.library_modules.append(library)
    - if self.verbose:
    - print 'Including LIB', library
    - print >> lib_code, '\n//\n// BEGIN LIB '+library+'\n//\n'
    - print >> lib_code, self._translate(
    - library, False, debug=debug, imported_js=imported_js)
    -
    - print >> lib_code, "/* initialize static library */"
    - print >> lib_code, "%s%s();\n" % (UU, library)
    -
    - print >> lib_code, '\n//\n// END LIB '+library+'\n//\n'
    - if module_name:
    - print >> app_code, self._translate(
    - module_name, is_app, debug=debug, imported_js=imported_js)
    - for js in imported_js:
    - path = self.findFile(js)
    - if os.path.isfile(path):
    - if self.verbose:
    - print 'Including JS', js
    - print >> lib_code, '\n//\n// BEGIN JS '+js+'\n//\n'
    - print >> lib_code, file(path).read()
    - print >> lib_code, '\n//\n// END JS '+js+'\n//\n'
    - else:
    - print >>sys.stderr, 'Warning: Unable to find imported javascript:', js
    - return lib_code.getvalue(), app_code.getvalue()
    -
    -usage = """
    - usage: %s file_name [module_name]
    -"""
    -
    -def main():
    - import sys
    - if len(sys.argv)<2:
    - print >> sys.stderr, usage % sys.argv[0]
    - sys.exit(1)
    - file_name = os.path.abspath(sys.argv[1])
    - if not os.path.isfile(file_name):
    - print >> sys.stderr, "File not found %s" % file_name
    - sys.exit(1)
    - if len(sys.argv) > 2:
    - module_name = sys.argv[2]
    - else:
    - module_name = None
    - print translate(file_name, module_name),
    -
    -if __name__ == "__main__":
    - main()
    -
    --- a/py_ext/modules/svgui/svgui.py Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,112 +0,0 @@
    -import wx
    -import os, sys, shutil
    -
    -from ConfigTreeNode import opjimg
    -from py_ext import PythonCodeTemplate
    -
    -from pyjs import translate
    -
    -from docutils import *
    -
    -class RootClass:
    -
    - ConfNodeMethods = [
    - {"bitmap" : os.path.join("images","ImportSVG"),
    - "name" : _("Import SVG"),
    - "tooltip" : _("Import SVG"),
    - "method" : "_ImportSVG"},
    - {"bitmap" : os.path.join("images","ImportSVG"),
    - "name" : _("Inkscape"),
    - "tooltip" : _("Create HMI"),
    - "method" : "_StartInkscape"},
    - ]
    -
    - def ConfNodePath(self):
    - return os.path.join(self.CTNParent.ConfNodePath(), "modules", self.CTNType)
    -
    - def _getSVGpath(self):
    - # define name for IEC raw code file
    - return os.path.join(self.CTNPath(), "gui.svg")
    -
    - def _getSVGUIserverpath(self):
    - return os.path.join(os.path.dirname(__file__), "svgui_server.py")
    -
    - def CTNGenerate_C(self, buildpath, locations):
    - """
    - Return C code generated by iec2c compiler
    - when _generate_softPLC have been called
    - @param locations: ignored
    - @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
    - """
    -
    - current_location = self.GetCurrentLocation()
    - # define a unique name for the generated C file
    - location_str = "_".join(map(lambda x:str(x), current_location))
    -
    - res = ([], "", False)
    -
    - svgfile=self._getSVGpath()
    - if os.path.exists(svgfile):
    - res += (("gui.svg", file(svgfile,"rb")),)
    -
    - svguiserverfile = open(self._getSVGUIserverpath(), 'r')
    - svguiservercode = svguiserverfile.read()
    - svguiserverfile.close()
    -
    - svguilibpath = os.path.join(self._getBuildPath(), "svguilib.js")
    - svguilibfile = open(svguilibpath, 'w')
    - svguilibfile.write(translate(os.path.join(os.path.dirname(__file__), "pyjs", "lib", "sys.py"), "sys"))
    - svguilibfile.write(open(os.path.join(os.path.dirname(__file__), "pyjs", "lib", "_pyjs.js"), 'r').read())
    - svguilibfile.write(translate(os.path.join(os.path.dirname(__file__), "pyjs", "lib", "pyjslib.py"), "pyjslib"))
    - svguilibfile.write(translate(os.path.join(os.path.dirname(__file__), "svguilib.py"), "svguilib"))
    - svguilibfile.write("pyjslib();\nsvguilib();\n")
    - svguilibfile.write(open(os.path.join(os.path.dirname(__file__), "pyjs", "lib", "json.js"), 'r').read())
    - svguilibfile.write(open(os.path.join(os.path.dirname(__file__), "livesvg.js"), 'r').read())
    - svguilibfile.close()
    - jsmodules = {"LiveSVGPage": "svguilib.js"}
    - res += (("svguilib.js", file(svguilibpath,"rb")),)
    -
    - runtimefile_path = os.path.join(buildpath, "runtime_%s.py"%location_str)
    - runtimefile = open(runtimefile_path, 'w')
    - runtimefile.write(svguiservercode % {"svgfile" : "gui.svg"})
    - runtimefile.write("""
    -def _runtime_%(location)s_begin():
    - website.LoadHMI(%(svgui_class)s, %(jsmodules)s)
    -
    -def _runtime_%(location)s_cleanup():
    - website.UnLoadHMI()
    -
    -""" % {"location": location_str,
    - "svgui_class": "SVGUI_HMI",
    - "jsmodules" : str(jsmodules),
    - })
    - runtimefile.close()
    -
    - res += (("runtime_%s.py"%location_str, file(runtimefile_path,"rb")),)
    -
    - return res
    -
    - def _ImportSVG(self):
    - dialog = wx.FileDialog(self.GetCTRoot().AppFrame, _("Choose a SVG file"), os.getcwd(), "", _("SVG files (*.svg)|*.svg|All files|*.*"), wx.OPEN)
    - if dialog.ShowModal() == wx.ID_OK:
    - svgpath = dialog.GetPath()
    - if os.path.isfile(svgpath):
    - shutil.copy(svgpath, self._getSVGpath())
    - else:
    - self.GetCTRoot().logger.write_error(_("No such SVG file: %s\n")%svgpath)
    - dialog.Destroy()
    -
    - def _StartInkscape(self):
    - svgfile = self._getSVGpath()
    - open_inkscape = True
    - if not self.GetCTRoot().CheckProjectPathPerm():
    - dialog = wx.MessageDialog(self.GetCTRoot().AppFrame,
    - _("You don't have write permissions.\nOpen Inkscape anyway ?"),
    - _("Open Inkscape"),
    - wx.YES_NO|wx.ICON_QUESTION)
    - open_inkscape = dialog.ShowModal() == wx.ID_YES
    - dialog.Destroy()
    - if open_inkscape:
    - if not os.path.isfile(svgfile):
    - svgfile = None
    - open_svg(svgfile)
    --- a/py_ext/modules/svgui/svgui_server.py Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,130 +0,0 @@
    -#!/usr/bin/python
    -# -*- coding: utf-8 -*-
    -
    -import os
    -
    -from nevow import rend, appserver, inevow, tags, loaders, athena
    -import simplejson as json
    -
    -svgfile = '%(svgfile)s'
    -
    -svguiWidgets = {}
    -
    -currentId = 0
    -def getNewId():
    - global currentId
    - currentId += 1
    - return currentId
    -
    -class SvguiWidget:
    -
    - def __init__(self, classname, id, **kwargs):
    - self.classname = classname
    - self.id = id
    - self.attrs = kwargs.copy()
    - self.inputs = {}
    - self.outputs = {}
    - self.inhibit = False
    - self.changed = False
    -
    - def setinput(self, attrname, value):
    - self.inputs[attrname] = value
    -
    - def getinput(self, attrname, default=None):
    - if not self.inputs.has_key(attrname):
    - self.inputs[attrname] = default
    - return self.inputs[attrname]
    -
    - def setoutput(self, attrname, value):
    - if self.outputs.get(attrname) != value:
    - self.outputs[attrname] = value
    - self.changed = True
    - self.RefreshInterface()
    -
    - def updateoutputs(self, **kwargs):
    - for attrname, value in kwargs.iteritems():
    - if self.outputs.get(attrname) != value:
    - self.outputs[attrname] = value
    - self.changed = True
    - self.RefreshInterface()
    -
    - def RefreshInterface(self):
    - interface = website.getHMI()
    - if isinstance(interface, SVGUI_HMI) and self.changed and not self.inhibit:
    - self.changed = False
    - d = interface.sendData(self)
    - if d is not None:
    - self.inhibit = True
    - d.addCallback(self.InterfaceRefreshed)
    -
    - def InterfaceRefreshed(self, result):
    - self.inhibit = False
    - if self.changed:
    - self.RefreshInterface()
    -
    -def get_object_init_state(obj):
    - # Convert objects to a dictionary of their representation
    - attrs = obj.attrs.copy()
    - attrs.update(obj.inputs)
    - d = { '__class__': obj.classname,
    - 'id': obj.id,
    - 'kwargs': json.dumps(attrs),
    - }
    - return d
    -
    -def get_object_current_state(obj):
    - # Convert objects to a dictionary of their representation
    - d = { '__class__': obj.classname,
    - 'id': obj.id,
    - 'kwargs': json.dumps(obj.outputs),
    - }
    - return d
    -
    -class SVGUI_HMI(website.PLCHMI):
    - jsClass = u"LiveSVGPage.LiveSVGWidget"
    -
    - docFactory = loaders.stan(tags.div(render=tags.directive('liveElement'))[
    - tags.xml(loaders.xmlfile(os.path.join(WorkingDir, svgfile))),
    - ])
    -
    - def HMIinitialisation(self):
    - gadgets = []
    - for gadget in svguiWidgets.values():
    - gadgets.append(unicode(json.dumps(gadget, default=get_object_init_state, indent=2), 'ascii'))
    - d = self.callRemote('init', gadgets)
    - d.addCallback(self.HMIinitialised)
    -
    - def sendData(self,data):
    - if self.initialised:
    - return self.callRemote('receiveData',unicode(json.dumps(data, default=get_object_current_state, indent=2), 'ascii'))
    - return None
    -
    - def setattr(self, id, attrname, value):
    - svguiWidgets[id].setinput(attrname, value)
    -
    -def createSVGUIControl(*args, **kwargs):
    - id = getNewId()
    - gad = SvguiWidget(args[0], id, **kwargs)
    - svguiWidgets[id] = gad
    - gadget = [unicode(json.dumps(gad, default=get_object_init_state, indent=2), 'ascii')]
    - interface = website.getHMI()
    - if isinstance(interface, SVGUI_HMI) and interface.initialised:
    - interface.callRemote('init', gadget)
    - return id
    -
    -def setAttr(id, attrname, value):
    - gad = svguiWidgets.get(id, None)
    - if gad is not None:
    - gad.setoutput(attrname, value)
    -
    -def updateAttr(id, **kwargs):
    - gad = svguiWidgets.get(id, None)
    - if gad is not None:
    - gad.updateoutput(**kwargs)
    -
    -def getAttr(id, attrname, default=None):
    - gad = svguiWidgets.get(id, None)
    - if gad is not None:
    - return gad.getinput(attrname, default)
    - return default
    -
    --- a/py_ext/modules/svgui/svguilib.py Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,117 +0,0 @@
    -
    -class button:
    -
    - def __init__(self, parent, id, args):
    - self.parent = parent
    - self.id = id
    - self.back_elt = getSVGElementById(args.back_id)
    - self.sele_elt = getSVGElementById(args.sele_id)
    - self.toggle = args.toggle
    - self.active = args.active
    - if args.state != undefined:
    - self.state = args.state
    - else:
    - self.state = False
    - self.dragging = False
    - if self.toggle:
    - self.up = not self.state
    - else:
    - self.up = True
    -
    - # Add event on each element of the button
    - if self.active:
    - self.back_elt.addEventListener("mouseup", self, False)
    - self.back_elt.addEventListener("mousedown", self, False)
    - self.back_elt.addEventListener("mouseover", self, False)
    - self.back_elt.addEventListener("mouseout", self, False)
    -
    - self.sele_elt.addEventListener("mouseup", self, False)
    - self.sele_elt.addEventListener("mousedown", self, False)
    - self.sele_elt.addEventListener("mouseover", self, False)
    - self.sele_elt.addEventListener("mouseout", self, False)
    -
    - blockSVGElementDrag(self.back_elt)
    - blockSVGElementDrag(self.sele_elt)
    -
    - self.updateElements()
    -
    - # method to display the current state of interface
    - def updateElements(self):
    - if self.up:
    - self.sele_elt.setAttribute("display", "none")
    - self.back_elt.removeAttribute("display")
    - else:
    - self.sele_elt.removeAttribute("display")
    - self.back_elt.setAttribute("display", "none")
    -
    - def updateValues(self, values):
    - if values.state != self.state:
    - self.state = values.state
    - self.up = not self.state
    - updateAttr(self.id, 'state', self.state)
    - self.updateElements()
    -
    - def handleEvent(self, evt):
    - # Quand le bouton de la souris est presse
    - if evt.type == "mousedown":
    - evt.stopPropagation()
    - setCurrentObject(self)
    -
    - self.dragging = True
    -
    - if self.toggle:
    - self.up = self.state
    - else:
    - self.up = False
    - self.state = True
    - updateAttr(self.id, 'state', self.state)
    - self.updateElements()
    -
    - if isCurrentObject(self) and self.dragging:
    - # Quand le bouton est survole
    - if evt.type == "mouseover" and self.toggle:
    - self.up = self.state
    - self.updateElements()
    -
    - # Quand le curseur quitte la zone du bouton
    - elif evt.type == "mouseout" and self.toggle:
    - self.up = not self.state
    - self.updateElements()
    -
    - # Quand le bouton de la souris est relache
    - elif evt.type == "mouseup":
    - evt.stopPropagation()
    - if self.toggle and self.up == self.state:
    - self.state = not self.state
    - updateAttr(self.id, 'state', self.state)
    - elif not self.toggle:
    - self.up = True
    - self.state = False
    - updateAttr(self.id, 'state', self.state)
    - self.updateElements()
    - self.dragging = False
    -
    -class textControl:
    -
    - def __init__(self, parent, id, args):
    - self.parent = parent
    - self.id = id
    - self.back_elt = getSVGElementById(args.back_id)
    - if args.text != undefined:
    - self.text = args.text
    - else:
    - self.text = ""
    - self.updateElements()
    -
    - def updateValues(self, values):
    - if values.text != self.value:
    - self.text = values.text
    - updateAttr(self.id, 'text', self.text)
    - self.updateElements()
    -
    - def updateElements(self):
    - self.back_elt.firstChild.firstChild.textContent = self.text
    -
    - def handleEvent(self, evt):
    - pass
    -
    \ No newline at end of file
    --- a/py_ext/modules/wxglade_hmi/README Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,1 +0,0 @@
    -WxGlade HMI
    \ No newline at end of file
    --- a/py_ext/modules/wxglade_hmi/__init__.py Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,1 +0,0 @@
    -from wxglade_hmi import *
    --- a/py_ext/modules/wxglade_hmi/wxglade_hmi.py Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,124 +0,0 @@
    -import wx
    -import os, sys
    -from xml.dom import minidom
    -
    -from ConfigTreeNode import opjimg
    -from py_ext import PythonCodeTemplate
    -
    -class RootClass(PythonCodeTemplate):
    -
    - ConfNodeMethods = [
    - {"bitmap" : opjimg("editWXGLADE"),
    - "name" : _("WXGLADE GUI"),
    - "tooltip" : _("Edit a WxWidgets GUI with WXGlade"),
    - "method" : "_editWXGLADE"},
    - ]
    -
    - def _getWXGLADEpath(self):
    - # define name for IEC raw code file
    - return os.path.join(self.CTNPath(), "hmi.wxg")
    -
    - def launch_wxglade(self, options, wait=False):
    - from wxglade import __file__ as fileName
    - path = os.path.dirname(fileName)
    - glade = os.path.join(path, 'wxglade.py')
    - if wx.Platform == '__WXMSW__':
    - glade = "\"%s\""%glade
    - mode = {False:os.P_NOWAIT, True:os.P_WAIT}[wait]
    - os.spawnv(mode, sys.executable, ["\"%s\""%sys.executable] + [glade] + options)
    -
    -
    - def CTNGenerate_C(self, buildpath, locations):
    - """
    - Return C code generated by iec2c compiler
    - when _generate_softPLC have been called
    - @param locations: ignored
    - @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
    - """
    -
    - current_location = self.GetCurrentLocation()
    - # define a unique name for the generated C file
    - location_str = "_".join(map(lambda x:str(x), current_location))
    -
    - runtimefile_path = os.path.join(buildpath, "runtime_%s.py"%location_str)
    - runtimefile = open(runtimefile_path, 'w')
    -
    - hmi_frames = {}
    -
    - wxgfile_path=self._getWXGLADEpath()
    - if os.path.exists(wxgfile_path):
    - wxgfile = open(wxgfile_path, 'r')
    - wxgtree = minidom.parse(wxgfile)
    - wxgfile.close()
    -
    - for node in wxgtree.childNodes[1].childNodes:
    - if node.nodeType == wxgtree.ELEMENT_NODE:
    - hmi_frames[node._attrs["name"].value] = node._attrs["class"].value
    -
    - hmipyfile_path=os.path.join(self._getBuildPath(), "hmi.py")
    - if wx.Platform == '__WXMSW__':
    - wxgfile_path = "\"%s\""%wxgfile_path
    - wxghmipyfile_path = "\"%s\""%hmipyfile_path
    - else:
    - wxghmipyfile_path = hmipyfile_path
    - self.launch_wxglade(['-o', wxghmipyfile_path, '-g', 'python', wxgfile_path], wait=True)
    -
    - hmipyfile = open(hmipyfile_path, 'r')
    - runtimefile.write(hmipyfile.read())
    - hmipyfile.close()
    -
    - runtimefile.write(self.GetPythonCode())
    - runtimefile.write("""
    -%(declare)s
    -
    -def _runtime_%(location)s_begin():
    - global %(global)s
    -
    - def OnCloseFrame(evt):
    - wx.MessageBox(_("Please stop PLC to close"))
    -
    - %(init)s
    -
    -def _runtime_%(location)s_cleanup():
    - global %(global)s
    -
    - %(cleanup)s
    -
    -""" % {"location": location_str,
    - "declare": "\n".join(map(lambda x:"%s = None" % x, hmi_frames.keys())),
    - "global": ",".join(hmi_frames.keys()),
    - "init": "\n".join(map(lambda x: """
    - %(name)s = %(class)s(None)
    - %(name)s.Bind(wx.EVT_CLOSE, OnCloseFrame)
    - %(name)s.Show()
    -""" % {"name": x[0], "class": x[1]},
    - hmi_frames.items())),
    - "cleanup": "\n ".join(map(lambda x:"%s.Destroy()" % x, hmi_frames.keys()))})
    - runtimefile.close()
    -
    - return [], "", False, ("runtime_%s.py"%location_str, file(runtimefile_path,"rb"))
    -
    - def _editWXGLADE(self):
    - wxg_filename = self._getWXGLADEpath()
    - open_wxglade = True
    - if not self.GetCTRoot().CheckProjectPathPerm():
    - dialog = wx.MessageDialog(self.GetCTRoot().AppFrame,
    - _("You don't have write permissions.\nOpen wxGlade anyway ?"),
    - _("Open wxGlade"),
    - wx.YES_NO|wx.ICON_QUESTION)
    - open_wxglade = dialog.ShowModal() == wx.ID_YES
    - dialog.Destroy()
    - if open_wxglade:
    - if not os.path.exists(wxg_filename):
    - hmi_name = self.BaseParams.getName()
    - open(wxg_filename,"w").write("""<?xml version="1.0"?>
    - <application path="" name="" class="" option="0" language="python" top_window="%(name)s" encoding="UTF-8" use_gettext="0" overwrite="0" use_new_namespace="1" for_version="2.8" is_template="0">
    - <object class="%(class)s" name="%(name)s" base="EditFrame">
    - <style>wxDEFAULT_FRAME_STYLE</style>
    - <title>frame_1</title>
    - </object>
    - </application>
    - """ % {"name": hmi_name, "class": "Class_%s" % hmi_name})
    - if wx.Platform == '__WXMSW__':
    - wxg_filename = "\"%s\""%wxg_filename
    - self.launch_wxglade([wxg_filename])
    --- a/py_ext/plc_python.c Wed May 09 00:39:54 2012 +0200
    +++ b/py_ext/plc_python.c Sat May 12 11:21:10 2012 +0200
    @@ -43,7 +43,7 @@
    void UnLockPython(void);
    void LockPython(void);
    -int __init_%(location)s()
    +int __init_py_ext()
    {
    int i;
    /* Initialize cursors */
    @@ -55,13 +55,13 @@
    return 0;
    }
    -void __cleanup_%(location)s()
    +void __cleanup_py_ext()
    {
    PythonState = PYTHON_FINISHED;
    UnBlockPythonCommands();
    }
    -void __retrieve_%(location)s()
    +void __retrieve_py_ext()
    {
    /* Check Python thread is not being
    * modifying internal python_eval data */
    @@ -72,7 +72,7 @@
    * and python_eval will no do anything */
    }
    -void __publish_%(location)s()
    +void __publish_py_ext()
    {
    if(PythonState & PYTHON_LOCKED_BY_PLC){
    /* If runnig PLC did push something in the fifo*/
    --- a/py_ext/py_ext.py Wed May 09 00:39:54 2012 +0200
    +++ b/py_ext/py_ext.py Sat May 12 11:21:10 2012 +0200
    @@ -1,185 +1,46 @@
    -import wx
    import os
    -import modules
    -from ConfigTreeNode import ConfigTreeNode, opjimg
    -from PLCControler import UndoBuffer
    -from PythonEditor import PythonEditor
    -
    -from xml.dom import minidom
    -from xmlclass import *
    -import cPickle
    -
    -PythonClasses = GenerateClassesFromXSD(os.path.join(os.path.dirname(__file__), "py_ext_xsd.xsd"))
    -
    -class PythonCodeTemplate:
    -
    - EditorType = PythonEditor
    -
    - def __init__(self):
    -
    - self.ConfNodeMethods.insert(0,
    - {"bitmap" : opjimg("editPYTHONcode"),
    - "name" : _("Edit Python File"),
    - "tooltip" : _("Edit Python File"),
    - "method" : "_OpenView"},
    - )
    -
    - filepath = self.PythonFileName()
    -
    - self.PythonCode = PythonClasses["Python"]()
    - if os.path.isfile(filepath):
    - xmlfile = open(filepath, 'r')
    - tree = minidom.parse(xmlfile)
    - xmlfile.close()
    -
    - for child in tree.childNodes:
    - if child.nodeType == tree.ELEMENT_NODE and child.nodeName == "Python":
    - self.PythonCode.loadXMLTree(child, ["xmlns", "xmlns:xsi", "xsi:schemaLocation"])
    - self.CreatePythonBuffer(True)
    - else:
    - self.CreatePythonBuffer(False)
    - self.OnCTNSave()
    -
    - def ConfNodePath(self):
    - return os.path.join(self.CTNParent.ConfNodePath(), "modules", self.CTNType)
    -
    - def PythonFileName(self):
    - return os.path.join(self.CTNPath(), "py_ext.xml")
    -
    - def GetFilename(self):
    - if self.PythonBuffer.IsCurrentSaved():
    - return "py_ext"
    - else:
    - return "~py_ext~"
    -
    - def SetPythonCode(self, text):
    - self.PythonCode.settext(text)
    -
    - def GetPythonCode(self):
    - return self.PythonCode.gettext()
    -
    - def CTNTestModified(self):
    - return self.ChangesToSave or not self.PythonIsSaved()
    -
    - def OnCTNSave(self):
    - filepath = self.PythonFileName()
    -
    - text = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
    - extras = {"xmlns":"http://www.w3.org/2001/XMLSchema",
    - "xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance",
    - "xsi:schemaLocation" : "py_ext_xsd.xsd"}
    - text += self.PythonCode.generateXMLText("Python", 0, extras)
    +from POULibrary import POULibrary
    +from PythonFileCTNMixin import PythonFileCTNMixin
    - xmlfile = open(filepath,"w")
    - xmlfile.write(text.encode("utf-8"))
    - xmlfile.close()
    -
    - self.MarkPythonAsSaved()
    - return True
    -
    -#-------------------------------------------------------------------------------
    -# Current Buffering Management Functions
    -#-------------------------------------------------------------------------------
    -
    - """
    - Return a copy of the project
    - """
    - def Copy(self, model):
    - return cPickle.loads(cPickle.dumps(model))
    -
    - def CreatePythonBuffer(self, saved):
    - self.Buffering = False
    - self.PythonBuffer = UndoBuffer(cPickle.dumps(self.PythonCode), saved)
    +class PythonLibrary(POULibrary):
    + def GetName(self):
    + return "Python"
    - def BufferPython(self):
    - self.PythonBuffer.Buffering(cPickle.dumps(self.PythonCode))
    -
    - def StartBuffering(self):
    - self.Buffering = True
    -
    - def EndBuffering(self):
    - if self.Buffering:
    - self.PythonBuffer.Buffering(cPickle.dumps(self.PythonCode))
    - self.Buffering = False
    -
    - def MarkPythonAsSaved(self):
    - self.EndBuffering()
    - self.PythonBuffer.CurrentSaved()
    -
    - def PythonIsSaved(self):
    - return self.PythonBuffer.IsCurrentSaved() and not self.Buffering
    -
    - def LoadPrevious(self):
    - self.EndBuffering()
    - self.PythonCode = cPickle.loads(self.PythonBuffer.Previous())
    -
    - def LoadNext(self):
    - self.PythonCode = cPickle.loads(self.PythonBuffer.Next())
    -
    - def GetBufferState(self):
    - first = self.PythonBuffer.IsFirst() and not self.Buffering
    - last = self.PythonBuffer.IsLast()
    - return not first, not last
    + def GetLibraryPath(self):
    + return os.path.join(os.path.split(__file__)[0], "pous.xml")
    -def _GetClassFunction(name):
    - def GetRootClass():
    - __import__("py_ext.modules." + name)
    - return getattr(modules, name).RootClass
    - return GetRootClass
    -
    -class RootClass(PythonCodeTemplate):
    -
    - # For root object, available Children Types are modules of the modules packages.
    - CTNChildrenTypes = [(name, _GetClassFunction(name), help) for name, help in zip(modules.__all__,modules.helps)]
    -
    - def ConfNodePath(self):
    - return os.path.join(self.CTNParent.ConfNodePath(), self.CTNType)
    -
    - def CTNGenerate_C(self, buildpath, locations):
    - """
    - Generate C code
    - @param current_location: Tupple containing confnode IEC location : %I0.0.4.5 => (0,0,4,5)
    - @param locations: List of complete variables locations \
    - [{"IEC_TYPE" : the IEC type (i.e. "INT", "STRING", ...)
    - "NAME" : name of the variable (generally "__IW0_1_2" style)
    - "DIR" : direction "Q","I" or "M"
    - "SIZE" : size "X", "B", "W", "D", "L"
    - "LOC" : tuple of interger for IEC location (0,1,2,...)
    - }, ...]
    - @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
    - """
    - current_location = self.GetCurrentLocation()
    - # define a unique name for the generated C file
    - location_str = "_".join(map(lambda x:str(x), current_location))
    -
    - ctr = self.GetCTRoot()
    - ctr.GetIECProgramsAndVariables()
    + def Generate_C(self, buildpath, varlist, IECCFLAGS):
    plc_python_filepath = os.path.join(os.path.split(__file__)[0], "plc_python.c")
    plc_python_file = open(plc_python_filepath, 'r')
    plc_python_code = plc_python_file.read()
    plc_python_file.close()
    python_eval_fb_list = []
    - for v in ctr._VariablesList:
    + for v in varlist:
    if v["vartype"] == "FB" and v["type"] in ["PYTHON_EVAL","PYTHON_POLL"]:
    python_eval_fb_list.append(v)
    python_eval_fb_count = max(1, len(python_eval_fb_list))
    # prepare python code
    - plc_python_code = plc_python_code % {
    - "python_eval_fb_count": python_eval_fb_count,
    - "location": location_str}
    + plc_python_code = plc_python_code % { "python_eval_fb_count": python_eval_fb_count }
    - Gen_Pythonfile_path = os.path.join(buildpath, "python_%s.c"%location_str)
    + Gen_Pythonfile_path = os.path.join(buildpath, "py_ext.c")
    pythonfile = open(Gen_Pythonfile_path,'w')
    pythonfile.write(plc_python_code)
    pythonfile.close()
    + return (["py_ext"], [(Gen_Pythonfile_path, IECCFLAGS)], True), ""
    +
    +class PythonFile(PythonFileCTNMixin):
    + def CTNGenerate_C(self, buildpath, locations):
    + current_location = self.GetCurrentLocation()
    + # define a unique name for the generated C file
    + location_str = "_".join(map(lambda x:str(x), current_location))
    +
    runtimefile_path = os.path.join(buildpath, "runtime_%s.py"%location_str)
    runtimefile = open(runtimefile_path, 'w')
    runtimefile.write(self.GetPythonCode())
    runtimefile.close()
    - matiec_flags = '"-I%s"'%os.path.abspath(self.GetCTRoot().GetIECLibPath())
    -
    - return [(Gen_Pythonfile_path, matiec_flags)], "", True, ("runtime_%s.py"%location_str, file(runtimefile_path,"rb"))
    + return [], "", False, ("runtime_%s.py"%location_str, file(runtimefile_path,"rb"))
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/svgui/README Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,1 @@
    +SVGUI HMI
    \ No newline at end of file
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/svgui/__init__.py Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,1 @@
    +from svgui import *
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/svgui/livesvg.js Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,59 @@
    +// import Nevow.Athena
    +// import Divmod.Base
    +
    +function updateAttr(id, param, value) {
    + Nevow.Athena.Widget.fromAthenaID(1).callRemote('HMIexec', 'setattr', id, param, value);
    +}
    +
    +var svguiWidgets = new Array();
    +
    +var currentObject = null;
    +function setCurrentObject(obj) {
    + currentObject = obj;
    +}
    +function isCurrentObject(obj) {
    + return currentObject == obj;
    +}
    +
    +function getSVGElementById(id) {
    + return document.getElementById(id);
    +}
    +
    +function blockSVGElementDrag(element) {
    + element.addEventListener("draggesture", function(event){event.stopPropagation()}, true);
    +}
    +
    +LiveSVGPage.LiveSVGWidget = Nevow.Athena.Widget.subclass('LiveSVGPage.LiveSVGWidget');
    +LiveSVGPage.LiveSVGWidget.methods(
    +
    + function handleEvent(self, evt) {
    + if (currentObject != null) {
    + currentObject.handleEvent(evt);
    + }
    + },
    +
    + function receiveData(self, data){
    + dataReceived = json_parse(data);
    + gadget = svguiWidgets[dataReceived.id]
    + if (gadget) {
    + gadget.updateValues(json_parse(dataReceived.kwargs));
    + }
    + //console.log("OBJET : " + dataReceived.back_id + " STATE : " + newState);
    + },
    +
    + function init(self, arg1){
    + //console.log("Object received : " + arg1);
    + for (ind in arg1) {
    + gad = json_parse(arg1[ind]);
    + args = json_parse(gad.kwargs);
    + gadget = new svguilib[gad.__class__](self, gad.id, args);
    + svguiWidgets[gadget.id]=gadget;
    + //console.log('GADGET :' + gadget);
    + }
    + var elements = document.getElementsByTagName("svg");
    + for (var i = 0; i < elements.length; i++) {
    + elements[i].addEventListener("mouseup", self, false);
    + }
    + //console.log("SVGUIWIDGETS : " + svguiWidgets);
    + }
    +);
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/svgui/pous.xml Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,1428 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    + xmlns="http://www.plcopen.org/xml/tc6.xsd"
    + xmlns:xhtml="http://www.w3.org/1999/xhtml"
    + xsi:schemaLocation="http://www.plcopen.org/xml/tc6.xsd">
    + <fileHeader companyName="Beremiz"
    + productName="Beremiz"
    + productVersion="0.0"
    + creationDateTime="2008-12-14T16:53:26"/>
    + <contentHeader name="Beremiz non-standard POUs library"
    + modificationDateTime="2009-08-12T15:35:33">
    + <coordinateInfo>
    + <fbd>
    + <scaling x="0" y="0"/>
    + </fbd>
    + <ld>
    + <scaling x="0" y="0"/>
    + </ld>
    + <sfc>
    + <scaling x="0" y="0"/>
    + </sfc>
    + </coordinateInfo>
    + </contentHeader>
    + <types>
    + <dataTypes/>
    + <pous>
    + <pou name="GetBoolString" pouType="functionBlock">
    + <interface>
    + <inputVars>
    + <variable name="VALUE">
    + <type>
    + <BOOL/>
    + </type>
    + </variable>
    + </inputVars>
    + <outputVars>
    + <variable name="CODE">
    + <type>
    + <string/>
    + </type>
    + </variable>
    + </outputVars>
    + </interface>
    + <body>
    + <ST>
    +<![CDATA[IF VALUE THEN
    + CODE := 'True';
    +ELSE
    + CODE := 'False';
    +END_IF;]]>
    + </ST>
    + </body>
    + </pou>
    + <pou name="TextCtrl" pouType="functionBlock">
    + <interface>
    + <localVars>
    + <variable name="ID">
    + <type>
    + <string/>
    + </type>
    + </variable>
    + </localVars>
    + <inputVars>
    + <variable name="back_id">
    + <type>
    + <string/>
    + </type>
    + </variable>
    + <variable name="set_text">
    + <type>
    + <BOOL/>
    + </type>
    + </variable>
    + <variable name="text">
    + <type>
    + <string/>
    + </type>
    + </variable>
    + </inputVars>
    + <localVars>
    + <variable name="SVGUI_TEXTCTRL">
    + <type>
    + <derived name="python_eval"/>
    + </type>
    + </variable>
    + <variable name="setstate_Command">
    + <type>
    + <derived name="python_eval"/>
    + </type>
    + </variable>
    + </localVars>
    + </interface>
    + <body>
    + <FBD>
    + <block localId="1" width="193" height="160" typeName="CONCAT">
    + <position x="626" y="122"/>
    + <inputVariables>
    + <variable formalParameter="IN1">
    + <connectionPointIn>
    + <relPosition x="0" y="43"/>
    + <connection refLocalId="2">
    + <position x="626" y="165"/>
    + <position x="535" y="165"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN2">
    + <connectionPointIn>
    + <relPosition x="0" y="89"/>
    + <connection refLocalId="3">
    + <position x="626" y="211"/>
    + <position x="535" y="211"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN3">
    + <connectionPointIn>
    + <relPosition x="0" y="135"/>
    + <connection refLocalId="6">
    + <position x="626" y="257"/>
    + <position x="532" y="257"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="OUT">
    + <connectionPointOut>
    + <relPosition x="193" y="43"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <inVariable localId="2" height="30" width="460">
    + <position x="75" y="150"/>
    + <connectionPointOut>
    + <relPosition x="460" y="15"/>
    + </connectionPointOut>
    + <expression>'createSVGUIControl("textControl", back_id="'</expression>
    + </inVariable>
    + <inVariable localId="3" height="35" width="85">
    + <position x="450" y="196"/>
    + <connectionPointOut>
    + <relPosition x="85" y="15"/>
    + </connectionPointOut>
    + <expression>back_id</expression>
    + </inVariable>
    + <inVariable localId="6" height="30" width="50">
    + <position x="482" y="242"/>
    + <connectionPointOut>
    + <relPosition x="50" y="15"/>
    + </connectionPointOut>
    + <expression>'")'</expression>
    + </inVariable>
    + <block localId="7" width="125" height="115" typeName="python_eval" instanceName="SVGUI_TEXTCTRL">
    + <position x="909" y="75"/>
    + <inputVariables>
    + <variable formalParameter="TRIG">
    + <connectionPointIn>
    + <relPosition x="0" y="45"/>
    + <connection refLocalId="9">
    + <position x="909" y="120"/>
    + <position x="886" y="120"/>
    + <position x="886" y="85"/>
    + <position x="869" y="85"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="CODE">
    + <connectionPointIn>
    + <relPosition x="0" y="90"/>
    + <connection refLocalId="1" formalParameter="OUT">
    + <position x="909" y="165"/>
    + <position x="819" y="165"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="ACK">
    + <connectionPointOut>
    + <relPosition x="125" y="45"/>
    + </connectionPointOut>
    + </variable>
    + <variable formalParameter="RESULT">
    + <connectionPointOut>
    + <relPosition x="125" y="90"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <inVariable localId="9" height="30" width="70">
    + <position x="799" y="70"/>
    + <connectionPointOut>
    + <relPosition x="70" y="15"/>
    + </connectionPointOut>
    + <expression>BOOL#1</expression>
    + </inVariable>
    + <outVariable localId="10" height="30" width="30">
    + <position x="1094" y="150"/>
    + <connectionPointIn>
    + <relPosition x="0" y="15"/>
    + <connection refLocalId="7" formalParameter="RESULT">
    + <position x="1094" y="165"/>
    + <position x="1034" y="165"/>
    + </connection>
    + </connectionPointIn>
    + <expression>ID</expression>
    + </outVariable>
    + <connector name="CREATED" localId="11" height="30" width="110">
    + <position x="1096" y="105"/>
    + <connectionPointIn>
    + <relPosition x="0" y="15"/>
    + <connection refLocalId="7" formalParameter="ACK">
    + <position x="1096" y="120"/>
    + <position x="1034" y="120"/>
    + </connection>
    + </connectionPointIn>
    + </connector>
    + <block localId="4" width="125" height="140" typeName="python_eval" instanceName="setstate_Command">
    + <position x="957" y="472"/>
    + <inputVariables>
    + <variable formalParameter="TRIG">
    + <connectionPointIn>
    + <relPosition x="0" y="50"/>
    + <connection refLocalId="31" formalParameter="OUT">
    + <position x="957" y="522"/>
    + <position x="909" y="522"/>
    + <position x="909" y="444"/>
    + <position x="857" y="444"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="CODE">
    + <connectionPointIn>
    + <relPosition x="0" y="110"/>
    + <connection refLocalId="12" formalParameter="OUT">
    + <position x="957" y="582"/>
    + <position x="822" y="582"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="ACK">
    + <connectionPointOut>
    + <relPosition x="125" y="50"/>
    + </connectionPointOut>
    + </variable>
    + <variable formalParameter="RESULT">
    + <connectionPointOut>
    + <relPosition x="125" y="110"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <continuation name="CREATED" localId="5" height="30" width="110">
    + <position x="589" y="429"/>
    + <connectionPointOut>
    + <relPosition x="110" y="15"/>
    + </connectionPointOut>
    + </continuation>
    + <block localId="12" width="186" height="288" typeName="CONCAT">
    + <position x="636" y="536"/>
    + <inputVariables>
    + <variable formalParameter="IN1">
    + <connectionPointIn>
    + <relPosition x="0" y="46"/>
    + <connection refLocalId="14">
    + <position x="636" y="582"/>
    + <position x="526" y="582"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN2">
    + <connectionPointIn>
    + <relPosition x="0" y="99"/>
    + <connection refLocalId="8">
    + <position x="636" y="635"/>
    + <position x="526" y="635"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN3">
    + <connectionPointIn>
    + <relPosition x="0" y="152"/>
    + <connection refLocalId="15">
    + <position x="636" y="688"/>
    + <position x="527" y="688"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN4">
    + <connectionPointIn>
    + <relPosition x="0" y="205"/>
    + <connection refLocalId="32">
    + <position x="636" y="741"/>
    + <position x="528" y="741"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN5">
    + <connectionPointIn>
    + <relPosition x="0" y="258"/>
    + <connection refLocalId="16">
    + <position x="636" y="794"/>
    + <position x="528" y="794"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="OUT">
    + <connectionPointOut>
    + <relPosition x="186" y="46"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <inVariable localId="8" height="30" width="53">
    + <position x="473" y="620"/>
    + <connectionPointOut>
    + <relPosition x="53" y="15"/>
    + </connectionPointOut>
    + <expression>ID</expression>
    + </inVariable>
    + <inVariable localId="13" height="35" width="100">
    + <position x="599" y="469"/>
    + <connectionPointOut>
    + <relPosition x="100" y="17"/>
    + </connectionPointOut>
    + <expression>set_text</expression>
    + </inVariable>
    + <inVariable localId="14" height="30" width="120">
    + <position x="406" y="567"/>
    + <connectionPointOut>
    + <relPosition x="120" y="15"/>
    + </connectionPointOut>
    + <expression>'setAttr('</expression>
    + </inVariable>
    + <inVariable localId="15" height="30" width="122">
    + <position x="405" y="673"/>
    + <connectionPointOut>
    + <relPosition x="122" y="15"/>
    + </connectionPointOut>
    + <expression>',"text","'</expression>
    + </inVariable>
    + <inVariable localId="16" height="30" width="50">
    + <position x="478" y="779"/>
    + <connectionPointOut>
    + <relPosition x="50" y="15"/>
    + </connectionPointOut>
    + <expression>'")'</expression>
    + </inVariable>
    + <block localId="31" width="75" height="105" typeName="AND">
    + <position x="782" y="403"/>
    + <inputVariables>
    + <variable formalParameter="IN1">
    + <connectionPointIn>
    + <relPosition x="0" y="41"/>
    + <connection refLocalId="5">
    + <position x="782" y="444"/>
    + <position x="699" y="444"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN2">
    + <connectionPointIn>
    + <relPosition x="0" y="83"/>
    + <connection refLocalId="13">
    + <position x="782" y="486"/>
    + <position x="699" y="486"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="OUT">
    + <connectionPointOut>
    + <relPosition x="75" y="41"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <inVariable localId="32" height="30" width="90">
    + <position x="438" y="726"/>
    + <connectionPointOut>
    + <relPosition x="90" y="15"/>
    + </connectionPointOut>
    + <expression>text</expression>
    + </inVariable>
    + </FBD>
    + </body>
    + </pou>
    + <pou name="Button" pouType="functionBlock">
    + <interface>
    + <localVars>
    + <variable name="ID">
    + <type>
    + <string/>
    + </type>
    + </variable>
    + </localVars>
    + <inputVars>
    + <variable name="back_id">
    + <type>
    + <string/>
    + </type>
    + </variable>
    + <variable name="sele_id">
    + <type>
    + <string/>
    + </type>
    + </variable>
    + <variable name="toggle">
    + <type>
    + <BOOL/>
    + </type>
    + </variable>
    + <variable name="set_state">
    + <type>
    + <BOOL/>
    + </type>
    + </variable>
    + <variable name="state_in">
    + <type>
    + <BOOL/>
    + </type>
    + </variable>
    + </inputVars>
    + <outputVars>
    + <variable name="state_out">
    + <type>
    + <BOOL/>
    + </type>
    + </variable>
    + </outputVars>
    + <localVars>
    + <variable name="init_Command">
    + <type>
    + <derived name="python_eval"/>
    + </type>
    + </variable>
    + <variable name="GetButtonState">
    + <type>
    + <derived name="GetBoolString"/>
    + </type>
    + </variable>
    + <variable name="setstate_Command">
    + <type>
    + <derived name="python_eval"/>
    + </type>
    + </variable>
    + <variable name="getstate_Command">
    + <type>
    + <derived name="python_poll"/>
    + </type>
    + </variable>
    + <variable name="GetButtonToggle">
    + <type>
    + <derived name="GetBoolString"/>
    + </type>
    + </variable>
    + </localVars>
    + </interface>
    + <body>
    + <FBD>
    + <block localId="1" width="125" height="140" typeName="python_eval" instanceName="init_Command">
    + <position x="838" y="32"/>
    + <inputVariables>
    + <variable formalParameter="TRIG">
    + <connectionPointIn>
    + <relPosition x="0" y="50"/>
    + <connection refLocalId="10">
    + <position x="838" y="82"/>
    + <position x="781" y="82"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="CODE">
    + <connectionPointIn>
    + <relPosition x="0" y="110"/>
    + <connection refLocalId="2" formalParameter="OUT">
    + <position x="838" y="142"/>
    + <position x="641" y="142"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="ACK">
    + <connectionPointOut>
    + <relPosition x="125" y="50"/>
    + </connectionPointOut>
    + </variable>
    + <variable formalParameter="RESULT">
    + <connectionPointOut>
    + <relPosition x="125" y="110"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <block localId="2" width="150" height="442" typeName="CONCAT">
    + <position x="491" y="92"/>
    + <inputVariables>
    + <variable formalParameter="IN1">
    + <connectionPointIn>
    + <relPosition x="0" y="50"/>
    + <connection refLocalId="3">
    + <position x="491" y="142"/>
    + <position x="433" y="142"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN2">
    + <connectionPointIn>
    + <relPosition x="0" y="110"/>
    + <connection refLocalId="11">
    + <position x="491" y="202"/>
    + <position x="431" y="202"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN3">
    + <connectionPointIn>
    + <relPosition x="0" y="170"/>
    + <connection refLocalId="5">
    + <position x="491" y="262"/>
    + <position x="431" y="262"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN4">
    + <connectionPointIn>
    + <relPosition x="0" y="230"/>
    + <connection refLocalId="12">
    + <position x="491" y="322"/>
    + <position x="430" y="322"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN5">
    + <connectionPointIn>
    + <relPosition x="0" y="290"/>
    + <connection refLocalId="23">
    + <position x="491" y="382"/>
    + <position x="463" y="382"/>
    + <position x="463" y="370"/>
    + <position x="430" y="370"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN6">
    + <connectionPointIn>
    + <relPosition x="0" y="350"/>
    + <connection refLocalId="24" formalParameter="CODE">
    + <position x="491" y="442"/>
    + <position x="429" y="442"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN7">
    + <connectionPointIn>
    + <relPosition x="0" y="410"/>
    + <connection refLocalId="9">
    + <position x="491" y="502"/>
    + <position x="430" y="502"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="OUT">
    + <connectionPointOut>
    + <relPosition x="150" y="50"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <inVariable localId="3" height="30" width="400">
    + <position x="33" y="127"/>
    + <connectionPointOut>
    + <relPosition x="400" y="15"/>
    + </connectionPointOut>
    + <expression>'createSVGUIControl("button",back_id="'</expression>
    + </inVariable>
    + <inVariable localId="5" height="30" width="140">
    + <position x="291" y="247"/>
    + <connectionPointOut>
    + <relPosition x="140" y="15"/>
    + </connectionPointOut>
    + <expression>'",sele_id="'</expression>
    + </inVariable>
    + <inVariable localId="9" height="30" width="180">
    + <position x="250" y="487"/>
    + <connectionPointOut>
    + <relPosition x="180" y="15"/>
    + </connectionPointOut>
    + <expression>',active=True)'</expression>
    + </inVariable>
    + <inVariable localId="10" height="30" width="70">
    + <position x="711" y="67"/>
    + <connectionPointOut>
    + <relPosition x="70" y="15"/>
    + </connectionPointOut>
    + <expression>BOOL#1</expression>
    + </inVariable>
    + <inVariable localId="11" height="35" width="85">
    + <position x="346" y="187"/>
    + <connectionPointOut>
    + <relPosition x="85" y="15"/>
    + </connectionPointOut>
    + <expression>back_id</expression>
    + </inVariable>
    + <inVariable localId="12" height="35" width="85">
    + <position x="345" y="307"/>
    + <connectionPointOut>
    + <relPosition x="85" y="15"/>
    + </connectionPointOut>
    + <expression>sele_id</expression>
    + </inVariable>
    + <inVariable localId="13" height="35" width="100">
    + <position x="452" y="639"/>
    + <connectionPointOut>
    + <relPosition x="100" y="15"/>
    + </connectionPointOut>
    + <expression>set_state</expression>
    + </inVariable>
    + <block localId="28" width="140" height="40" typeName="GetBoolString" instanceName="GetButtonState">
    + <position x="239" y="897"/>
    + <inputVariables>
    + <variable formalParameter="VALUE">
    + <connectionPointIn>
    + <relPosition x="0" y="30"/>
    + <connection refLocalId="32">
    + <position x="239" y="927"/>
    + <position x="181" y="927"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="CODE">
    + <connectionPointOut>
    + <relPosition x="140" y="30"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <outVariable localId="29" height="30" width="53">
    + <position x="1015" y="127"/>
    + <connectionPointIn>
    + <relPosition x="0" y="15"/>
    + <connection refLocalId="1" formalParameter="RESULT">
    + <position x="1015" y="142"/>
    + <position x="963" y="142"/>
    + </connection>
    + </connectionPointIn>
    + <expression>ID</expression>
    + </outVariable>
    + <block localId="4" width="125" height="140" typeName="python_eval" instanceName="setstate_Command">
    + <position x="810" y="640"/>
    + <inputVariables>
    + <variable formalParameter="TRIG">
    + <connectionPointIn>
    + <relPosition x="0" y="50"/>
    + <connection refLocalId="31" formalParameter="OUT">
    + <position x="810" y="690"/>
    + <position x="762" y="690"/>
    + <position x="762" y="612"/>
    + <position x="710" y="612"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="CODE">
    + <connectionPointIn>
    + <relPosition x="0" y="110"/>
    + <connection refLocalId="7" formalParameter="OUT">
    + <position x="810" y="750"/>
    + <position x="643" y="750"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="ACK">
    + <connectionPointOut>
    + <relPosition x="125" y="50"/>
    + </connectionPointOut>
    + </variable>
    + <variable formalParameter="RESULT">
    + <connectionPointOut>
    + <relPosition x="125" y="110"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <connector name="CREATED" localId="30" height="30" width="110">
    + <position x="1014" y="67"/>
    + <connectionPointIn>
    + <relPosition x="0" y="15"/>
    + <connection refLocalId="1" formalParameter="ACK">
    + <position x="1014" y="82"/>
    + <position x="963" y="82"/>
    + </connection>
    + </connectionPointIn>
    + </connector>
    + <continuation name="CREATED" localId="6" height="30" width="110">
    + <position x="442" y="597"/>
    + <connectionPointOut>
    + <relPosition x="110" y="15"/>
    + </connectionPointOut>
    + </continuation>
    + <block localId="31" width="75" height="105" typeName="AND">
    + <position x="635" y="571"/>
    + <inputVariables>
    + <variable formalParameter="IN1">
    + <connectionPointIn>
    + <relPosition x="0" y="41"/>
    + <connection refLocalId="6">
    + <position x="635" y="612"/>
    + <position x="552" y="612"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN2">
    + <connectionPointIn>
    + <relPosition x="0" y="83"/>
    + <connection refLocalId="13">
    + <position x="635" y="654"/>
    + <position x="552" y="654"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="OUT">
    + <connectionPointOut>
    + <relPosition x="75" y="41"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <inVariable localId="32" height="30" width="90">
    + <position x="91" y="912"/>
    + <connectionPointOut>
    + <relPosition x="90" y="15"/>
    + </connectionPointOut>
    + <expression>state_in</expression>
    + </inVariable>
    + <outVariable localId="33" height="30" width="100">
    + <position x="1334" y="1184"/>
    + <connectionPointIn>
    + <relPosition x="0" y="15"/>
    + <connection refLocalId="26" formalParameter="OUT">
    + <position x="1334" y="1199"/>
    + <position x="1286" y="1199"/>
    + </connection>
    + </connectionPointIn>
    + <expression>state_out</expression>
    + </outVariable>
    + <block localId="7" width="150" height="319" typeName="CONCAT">
    + <position x="493" y="701"/>
    + <inputVariables>
    + <variable formalParameter="IN1">
    + <connectionPointIn>
    + <relPosition x="0" y="49"/>
    + <connection refLocalId="14">
    + <position x="493" y="750"/>
    + <position x="379" y="750"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN2">
    + <connectionPointIn>
    + <relPosition x="0" y="108"/>
    + <connection refLocalId="8">
    + <position x="493" y="809"/>
    + <position x="435" y="809"/>
    + <position x="435" y="803"/>
    + <position x="379" y="803"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN3">
    + <connectionPointIn>
    + <relPosition x="0" y="167"/>
    + <connection refLocalId="15">
    + <position x="493" y="868"/>
    + <position x="435" y="868"/>
    + <position x="435" y="855"/>
    + <position x="379" y="855"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN4">
    + <connectionPointIn>
    + <relPosition x="0" y="226"/>
    + <connection refLocalId="28" formalParameter="CODE">
    + <position x="493" y="927"/>
    + <position x="379" y="927"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN5">
    + <connectionPointIn>
    + <relPosition x="0" y="285"/>
    + <connection refLocalId="16">
    + <position x="493" y="986"/>
    + <position x="377" y="986"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="OUT">
    + <connectionPointOut>
    + <relPosition x="150" y="49"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <inVariable localId="8" height="30" width="53">
    + <position x="326" y="788"/>
    + <connectionPointOut>
    + <relPosition x="53" y="15"/>
    + </connectionPointOut>
    + <expression>ID</expression>
    + </inVariable>
    + <inVariable localId="14" height="30" width="120">
    + <position x="259" y="735"/>
    + <connectionPointOut>
    + <relPosition x="120" y="15"/>
    + </connectionPointOut>
    + <expression>'setAttr('</expression>
    + </inVariable>
    + <inVariable localId="15" height="30" width="122">
    + <position x="257" y="840"/>
    + <connectionPointOut>
    + <relPosition x="122" y="15"/>
    + </connectionPointOut>
    + <expression>',"state",'</expression>
    + </inVariable>
    + <inVariable localId="16" height="30" width="41">
    + <position x="336" y="971"/>
    + <connectionPointOut>
    + <relPosition x="41" y="15"/>
    + </connectionPointOut>
    + <expression>')'</expression>
    + </inVariable>
    + <block localId="17" width="125" height="140" typeName="python_poll" instanceName="getstate_Command">
    + <position x="801" y="1089"/>
    + <inputVariables>
    + <variable formalParameter="TRIG">
    + <connectionPointIn>
    + <relPosition x="0" y="50"/>
    + <connection refLocalId="18">
    + <position x="801" y="1139"/>
    + <position x="763" y="1139"/>
    + <position x="763" y="1099"/>
    + <position x="720" y="1099"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="CODE">
    + <connectionPointIn>
    + <relPosition x="0" y="110"/>
    + <connection refLocalId="22" formalParameter="OUT">
    + <position x="801" y="1199"/>
    + <position x="643" y="1199"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="ACK">
    + <connectionPointOut>
    + <relPosition x="125" y="50"/>
    + </connectionPointOut>
    + </variable>
    + <variable formalParameter="RESULT">
    + <connectionPointOut>
    + <relPosition x="125" y="110"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <block localId="25" width="145" height="45" typeName="STRING_TO_INT">
    + <position x="966" y="1169"/>
    + <inputVariables>
    + <variable formalParameter="IN">
    + <connectionPointIn>
    + <relPosition x="0" y="30"/>
    + <connection refLocalId="17" formalParameter="RESULT">
    + <position x="966" y="1199"/>
    + <position x="926" y="1199"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="OUT">
    + <connectionPointOut>
    + <relPosition x="145" y="30"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <block localId="26" width="125" height="45" typeName="INT_TO_BOOL">
    + <position x="1161" y="1169"/>
    + <inputVariables>
    + <variable formalParameter="IN">
    + <connectionPointIn>
    + <relPosition x="0" y="30"/>
    + <connection refLocalId="25" formalParameter="OUT">
    + <position x="1161" y="1199"/>
    + <position x="1111" y="1199"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="OUT">
    + <connectionPointOut>
    + <relPosition x="125" y="30"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <continuation name="CREATED" localId="18" height="30" width="110">
    + <position x="610" y="1084"/>
    + <connectionPointOut>
    + <relPosition x="110" y="15"/>
    + </connectionPointOut>
    + </continuation>
    + <inVariable localId="19" height="30" width="53">
    + <position x="383" y="1238"/>
    + <connectionPointOut>
    + <relPosition x="53" y="15"/>
    + </connectionPointOut>
    + <expression>ID</expression>
    + </inVariable>
    + <inVariable localId="20" height="30" width="150">
    + <position x="286" y="1184"/>
    + <connectionPointOut>
    + <relPosition x="150" y="15"/>
    + </connectionPointOut>
    + <expression>'int(getAttr('</expression>
    + </inVariable>
    + <inVariable localId="21" height="30" width="190">
    + <position x="246" y="1292"/>
    + <connectionPointOut>
    + <relPosition x="190" y="15"/>
    + </connectionPointOut>
    + <expression>',"state",False))'</expression>
    + </inVariable>
    + <block localId="22" width="150" height="183" typeName="CONCAT">
    + <position x="493" y="1152"/>
    + <inputVariables>
    + <variable formalParameter="IN1">
    + <connectionPointIn>
    + <relPosition x="0" y="47"/>
    + <connection refLocalId="20">
    + <position x="493" y="1199"/>
    + <position x="436" y="1199"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN2">
    + <connectionPointIn>
    + <relPosition x="0" y="101"/>
    + <connection refLocalId="19">
    + <position x="493" y="1253"/>
    + <position x="436" y="1253"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN3">
    + <connectionPointIn>
    + <relPosition x="0" y="155"/>
    + <connection refLocalId="21">
    + <position x="493" y="1307"/>
    + <position x="483" y="1307"/>
    + <position x="483" y="1307"/>
    + <position x="436" y="1307"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="OUT">
    + <connectionPointOut>
    + <relPosition x="150" y="47"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <inVariable localId="23" height="30" width="130">
    + <position x="300" y="355"/>
    + <connectionPointOut>
    + <relPosition x="130" y="15"/>
    + </connectionPointOut>
    + <expression>'",toggle='</expression>
    + </inVariable>
    + <block localId="24" width="140" height="40" typeName="GetBoolString" instanceName="GetButtonToggle">
    + <position x="289" y="412"/>
    + <inputVariables>
    + <variable formalParameter="VALUE">
    + <connectionPointIn>
    + <relPosition x="0" y="30"/>
    + <connection refLocalId="27">
    + <position x="289" y="442"/>
    + <position x="220" y="442"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="CODE">
    + <connectionPointOut>
    + <relPosition x="140" y="30"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <inVariable localId="27" height="30" width="90">
    + <position x="130" y="427"/>
    + <connectionPointOut>
    + <relPosition x="90" y="15"/>
    + </connectionPointOut>
    + <expression>toggle</expression>
    + </inVariable>
    + </FBD>
    + </body>
    + </pou>
    + <pou name="Led" pouType="functionBlock">
    + <interface>
    + <localVars>
    + <variable name="ID">
    + <type>
    + <string/>
    + </type>
    + </variable>
    + </localVars>
    + <inputVars>
    + <variable name="back_id">
    + <type>
    + <string/>
    + </type>
    + </variable>
    + <variable name="sele_id">
    + <type>
    + <string/>
    + </type>
    + </variable>
    + <variable name="state_in">
    + <type>
    + <BOOL/>
    + </type>
    + </variable>
    + </inputVars>
    + <localVars>
    + <variable name="init_Command">
    + <type>
    + <derived name="python_eval"/>
    + </type>
    + </variable>
    + <variable name="setstate_Command">
    + <type>
    + <derived name="python_poll"/>
    + </type>
    + </variable>
    + <variable name="GetLedState">
    + <type>
    + <derived name="GetBoolString"/>
    + </type>
    + </variable>
    + </localVars>
    + </interface>
    + <body>
    + <FBD>
    + <block localId="1" width="125" height="140" typeName="python_eval" instanceName="init_Command">
    + <position x="810" y="30"/>
    + <inputVariables>
    + <variable formalParameter="TRIG">
    + <connectionPointIn>
    + <relPosition x="0" y="50"/>
    + <connection refLocalId="10">
    + <position x="810" y="80"/>
    + <position x="753" y="80"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="CODE">
    + <connectionPointIn>
    + <relPosition x="0" y="110"/>
    + <connection refLocalId="2" formalParameter="OUT">
    + <position x="810" y="140"/>
    + <position x="640" y="140"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="ACK">
    + <connectionPointOut>
    + <relPosition x="125" y="50"/>
    + </connectionPointOut>
    + </variable>
    + <variable formalParameter="RESULT">
    + <connectionPointOut>
    + <relPosition x="125" y="110"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <block localId="2" width="150" height="322" typeName="CONCAT">
    + <position x="490" y="90"/>
    + <inputVariables>
    + <variable formalParameter="IN1">
    + <connectionPointIn>
    + <relPosition x="0" y="50"/>
    + <connection refLocalId="3">
    + <position x="490" y="140"/>
    + <position x="415" y="140"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN2">
    + <connectionPointIn>
    + <relPosition x="0" y="110"/>
    + <connection refLocalId="11">
    + <position x="490" y="200"/>
    + <position x="415" y="200"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN3">
    + <connectionPointIn>
    + <relPosition x="0" y="170"/>
    + <connection refLocalId="5">
    + <position x="490" y="260"/>
    + <position x="415" y="260"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN4">
    + <connectionPointIn>
    + <relPosition x="0" y="230"/>
    + <connection refLocalId="12">
    + <position x="490" y="320"/>
    + <position x="414" y="320"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN5">
    + <connectionPointIn>
    + <relPosition x="0" y="290"/>
    + <connection refLocalId="9">
    + <position x="490" y="380"/>
    + <position x="414" y="380"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="OUT">
    + <connectionPointOut>
    + <relPosition x="150" y="50"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <inVariable localId="3" height="30" width="400">
    + <position x="15" y="125"/>
    + <connectionPointOut>
    + <relPosition x="400" y="15"/>
    + </connectionPointOut>
    + <expression>'createSVGUIControl("button",back_id="'</expression>
    + </inVariable>
    + <block localId="4" width="125" height="140" typeName="python_poll" instanceName="setstate_Command">
    + <position x="782" y="536"/>
    + <inputVariables>
    + <variable formalParameter="TRIG">
    + <connectionPointIn>
    + <relPosition x="0" y="50"/>
    + <connection refLocalId="6">
    + <position x="782" y="586"/>
    + <position x="653" y="586"/>
    + <position x="653" y="552"/>
    + <position x="602" y="552"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="CODE">
    + <connectionPointIn>
    + <relPosition x="0" y="110"/>
    + <connection refLocalId="7" formalParameter="OUT">
    + <position x="782" y="646"/>
    + <position x="615" y="646"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="ACK">
    + <connectionPointOut>
    + <relPosition x="125" y="50"/>
    + </connectionPointOut>
    + </variable>
    + <variable formalParameter="RESULT">
    + <connectionPointOut>
    + <relPosition x="125" y="110"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <inVariable localId="5" height="30" width="140">
    + <position x="275" y="245"/>
    + <connectionPointOut>
    + <relPosition x="140" y="15"/>
    + </connectionPointOut>
    + <expression>'",sele_id="'</expression>
    + </inVariable>
    + <continuation name="CREATED" localId="6" height="30" width="110">
    + <position x="492" y="537"/>
    + <connectionPointOut>
    + <relPosition x="110" y="15"/>
    + </connectionPointOut>
    + </continuation>
    + <block localId="7" width="150" height="319" typeName="CONCAT">
    + <position x="465" y="597"/>
    + <inputVariables>
    + <variable formalParameter="IN1">
    + <connectionPointIn>
    + <relPosition x="0" y="49"/>
    + <connection refLocalId="14">
    + <position x="465" y="646"/>
    + <position x="351" y="646"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN2">
    + <connectionPointIn>
    + <relPosition x="0" y="108"/>
    + <connection refLocalId="8">
    + <position x="465" y="705"/>
    + <position x="407" y="705"/>
    + <position x="407" y="699"/>
    + <position x="351" y="699"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN3">
    + <connectionPointIn>
    + <relPosition x="0" y="167"/>
    + <connection refLocalId="15">
    + <position x="465" y="764"/>
    + <position x="407" y="764"/>
    + <position x="407" y="751"/>
    + <position x="351" y="751"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN4">
    + <connectionPointIn>
    + <relPosition x="0" y="226"/>
    + <connection refLocalId="28" formalParameter="CODE">
    + <position x="465" y="823"/>
    + <position x="351" y="823"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + <variable formalParameter="IN5">
    + <connectionPointIn>
    + <relPosition x="0" y="285"/>
    + <connection refLocalId="16">
    + <position x="465" y="882"/>
    + <position x="407" y="882"/>
    + <position x="407" y="883"/>
    + <position x="351" y="883"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="OUT">
    + <connectionPointOut>
    + <relPosition x="150" y="49"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <inVariable localId="8" height="30" width="53">
    + <position x="298" y="684"/>
    + <connectionPointOut>
    + <relPosition x="53" y="15"/>
    + </connectionPointOut>
    + <expression>ID</expression>
    + </inVariable>
    + <inVariable localId="9" height="30" width="300">
    + <position x="124" y="365"/>
    + <connectionPointOut>
    + <relPosition x="300" y="15"/>
    + </connectionPointOut>
    + <expression>'",toggle=True,active=False)'</expression>
    + </inVariable>
    + <inVariable localId="10" height="30" width="70">
    + <position x="683" y="65"/>
    + <connectionPointOut>
    + <relPosition x="70" y="15"/>
    + </connectionPointOut>
    + <expression>BOOL#1</expression>
    + </inVariable>
    + <inVariable localId="11" height="35" width="85">
    + <position x="330" y="185"/>
    + <connectionPointOut>
    + <relPosition x="85" y="15"/>
    + </connectionPointOut>
    + <expression>back_id</expression>
    + </inVariable>
    + <inVariable localId="12" height="35" width="85">
    + <position x="329" y="305"/>
    + <connectionPointOut>
    + <relPosition x="85" y="15"/>
    + </connectionPointOut>
    + <expression>sele_id</expression>
    + </inVariable>
    + <inVariable localId="14" height="30" width="120">
    + <position x="231" y="631"/>
    + <connectionPointOut>
    + <relPosition x="120" y="15"/>
    + </connectionPointOut>
    + <expression>'setAttr('</expression>
    + </inVariable>
    + <inVariable localId="15" height="30" width="122">
    + <position x="229" y="736"/>
    + <connectionPointOut>
    + <relPosition x="122" y="15"/>
    + </connectionPointOut>
    + <expression>',"state",'</expression>
    + </inVariable>
    + <inVariable localId="16" height="30" width="41">
    + <position x="310" y="868"/>
    + <connectionPointOut>
    + <relPosition x="41" y="15"/>
    + </connectionPointOut>
    + <expression>')'</expression>
    + </inVariable>
    + <block localId="28" width="140" height="40" typeName="GetBoolString" instanceName="GetLedState">
    + <position x="211" y="793"/>
    + <inputVariables>
    + <variable formalParameter="VALUE">
    + <connectionPointIn>
    + <relPosition x="0" y="30"/>
    + <connection refLocalId="32">
    + <position x="211" y="823"/>
    + <position x="153" y="823"/>
    + </connection>
    + </connectionPointIn>
    + </variable>
    + </inputVariables>
    + <inOutVariables/>
    + <outputVariables>
    + <variable formalParameter="CODE">
    + <connectionPointOut>
    + <relPosition x="140" y="30"/>
    + </connectionPointOut>
    + </variable>
    + </outputVariables>
    + </block>
    + <outVariable localId="29" height="30" width="53">
    + <position x="987" y="125"/>
    + <connectionPointIn>
    + <relPosition x="0" y="15"/>
    + <connection refLocalId="1" formalParameter="RESULT">
    + <position x="987" y="140"/>
    + <position x="935" y="140"/>
    + </connection>
    + </connectionPointIn>
    + <expression>ID</expression>
    + </outVariable>
    + <connector name="CREATED" localId="30" height="30" width="110">
    + <position x="986" y="65"/>
    + <connectionPointIn>
    + <relPosition x="0" y="15"/>
    + <connection refLocalId="1" formalParameter="ACK">
    + <position x="986" y="80"/>
    + <position x="935" y="80"/>
    + </connection>
    + </connectionPointIn>
    + </connector>
    + <inVariable localId="32" height="30" width="90">
    + <position x="63" y="808"/>
    + <connectionPointOut>
    + <relPosition x="90" y="15"/>
    + </connectionPointOut>
    + <expression>state_in</expression>
    + </inVariable>
    + </FBD>
    + </body>
    + </pou>
    + </pous>
    + </types>
    + <instances>
    + <configurations/>
    + </instances>
    +</project>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/svgui/pyjs/__init__.py Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,2 @@
    +from pyjs import *
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/svgui/pyjs/build.py Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,724 @@
    +#!/usr/bin/env python
    +
    +import sys
    +import os
    +import shutil
    +from copy import copy
    +from os.path import join, dirname, basename, abspath, split, isfile, isdir
    +from optparse import OptionParser
    +import pyjs
    +from cStringIO import StringIO
    +try:
    + # Python 2.5 and above
    + from hashlib import md5
    +except:
    + import md5
    +import re
    +
    +usage = """
    + usage: %prog [options] <application module name or path>
    +
    +This is the command line builder for the pyjamas project, which can
    +be used to build Ajax applications from Python.
    +For more information, see the website at http://pyjs.org/
    +"""
    +
    +# GWT1.2 Impl | GWT1.2 Output | Pyjamas 0.2 Platform | Pyjamas 0.2 Output
    +# -------------+-----------------------+----------------------+----------------------
    +# IE6 | ie6 | IE6 | ie6
    +# Opera | opera | Opera | opera
    +# Safari | safari | Safari | safari
    +# -- | gecko1_8 | Mozilla | mozilla
    +# -- | gecko | OldMoz | oldmoz
    +# Standard | all | (default code) | all
    +# Mozilla | gecko1_8, gecko | -- | --
    +# Old | safari, gecko, opera | -- | --
    +
    +version = "%prog pyjamas version 2006-08-19"
    +
    +# these names in lowercase need match the strings
    +# returned by "provider$user.agent" in order to be selected corretly
    +app_platforms = ['IE6', 'Opera', 'OldMoz', 'Safari', 'Mozilla']
    +
    +# usually defaults to e.g. /usr/share/pyjamas
    +_data_dir = os.path.join(pyjs.prefix, "share/pyjamas")
    +
    +
    +# .cache.html files produces look like this
    +CACHE_HTML_PAT=re.compile('^[a-z]*.[0-9a-f]{32}\.cache\.html$')
    +
    +# ok these are the three "default" library directories, containing
    +# the builtins (str, List, Dict, ord, round, len, range etc.)
    +# the main pyjamas libraries (pyjamas.ui, pyjamas.Window etc.)
    +# and the contributed addons
    +
    +for p in ["library/builtins",
    + "library",
    + "addons"]:
    + p = os.path.join(_data_dir, p)
    + if os.path.isdir(p):
    + pyjs.path.append(p)
    +
    +
    +def read_boilerplate(data_dir, filename):
    + return open(join(data_dir, "builder/boilerplate", filename)).read()
    +
    +def copy_boilerplate(data_dir, filename, output_dir):
    + filename = join(data_dir, "builder/boilerplate", filename)
    + shutil.copy(filename, output_dir)
    +
    +
    +# taken and modified from python2.4
    +def copytree_exists(src, dst, symlinks=False):
    + if not os.path.exists(src):
    + return
    +
    + names = os.listdir(src)
    + try:
    + os.mkdir(dst)
    + except:
    + pass
    +
    + errors = []
    + for name in names:
    + if name.startswith('CVS'):
    + continue
    + if name.startswith('.git'):
    + continue
    + if name.startswith('.svn'):
    + continue
    +
    + srcname = os.path.join(src, name)
    + dstname = os.path.join(dst, name)
    + try:
    + if symlinks and os.path.islink(srcname):
    + linkto = os.readlink(srcname)
    + os.symlink(linkto, dstname)
    + elif isdir(srcname):
    + copytree_exists(srcname, dstname, symlinks)
    + else:
    + shutil.copy2(srcname, dstname)
    + except (IOError, os.error), why:
    + errors.append((srcname, dstname, why))
    + if errors:
    + print errors
    +
    +def check_html_file(source_file, dest_path):
    + """ Checks if a base HTML-file is available in the PyJamas
    + output directory.
    + If the HTML-file isn't available, it will be created.
    +
    + If a CSS-file with the same name is available
    + in the output directory, a reference to this CSS-file
    + is included.
    +
    + If no CSS-file is found, this function will look for a special
    + CSS-file in the output directory, with the name
    + "pyjamas_default.css", and if found it will be referenced
    + in the generated HTML-file.
    +
    + [thank you to stef mientki for contributing this function]
    + """
    +
    + base_html = """\
    +<html>
    + <!-- auto-generated html - you should consider editing and
    + adapting this to suit your requirements
    + -->
    + <head>
    + <meta name="pygwt:module" content="%(modulename)s">
    + %(css)s
    + <title>%(title)s</title>
    + </head>
    + <body bgcolor="white">
    + <script language="javascript" src="pygwt.js"></script>
    + </body>
    +</html>
    +"""
    +
    + filename = os.path.split ( source_file )[1]
    + mod_name = os.path.splitext ( filename )[0]
    + file_name = os.path.join ( dest_path, mod_name + '.html' )
    +
    + # if html file in output directory exists, leave it alone.
    + if os.path.exists ( file_name ):
    + return 0
    +
    + if os.path.exists (
    + os.path.join ( dest_path, mod_name + '.css' ) ) :
    + css = "<link rel='stylesheet' href='" + mod_name + ".css'>"
    + elif os.path.exists (
    + os.path.join ( dest_path, 'pyjamas_default.css' ) ) :
    + css = "<link rel='stylesheet' href='pyjamas_default.css'>"
    +
    + else:
    + css = ''
    +
    + title = 'PyJamas Auto-Generated HTML file ' + mod_name
    +
    + base_html = base_html % {'modulename': mod_name, 'title': title, 'css': css}
    +
    + fh = open (file_name, 'w')
    + fh.write (base_html)
    + fh.close ()
    +
    + return 1
    +
    +
    +def build(app_name, output, js_includes=(), debug=False, dynamic=0,
    + data_dir=None, cache_buster=False, optimize=False):
    +
    + # make sure the output directory is always created in the current working
    + # directory or at the place given if it is an absolute path.
    + output = os.path.abspath(output)
    + msg = "Building '%(app_name)s' to output directory '%(output)s'" % locals()
    + if debug:
    + msg += " with debugging statements"
    + print msg
    +
    + # check the output directory
    + if os.path.exists(output) and not os.path.isdir(output):
    + print >>sys.stderr, "Output destination %s exists and is not a directory" % output
    + return
    + if not os.path.isdir(output):
    + try:
    + print "Creating output directory"
    + os.mkdir(output)
    + except StandardError, e:
    + print >>sys.stderr, "Exception creating output directory %s: %s" % (output, e)
    +
    + ## public dir
    + for p in pyjs.path:
    + pub_dir = join(p, 'public')
    + if isdir(pub_dir):
    + print "Copying: public directory of library %r" % p
    + copytree_exists(pub_dir, output)
    +
    + ## AppName.html - can be in current or public directory
    + html_input_filename = app_name + ".html"
    + html_output_filename = join(output, basename(html_input_filename))
    + if os.path.isfile(html_input_filename):
    + if not os.path.isfile(html_output_filename) or \
    + os.path.getmtime(html_input_filename) > \
    + os.path.getmtime(html_output_filename):
    + try:
    + shutil.copy(html_input_filename, html_output_filename)
    + except:
    + print >>sys.stderr, "Warning: Missing module HTML file %s" % html_input_filename
    +
    + print "Copying: %(html_input_filename)s" % locals()
    +
    + if check_html_file(html_input_filename, output):
    + print >>sys.stderr, "Warning: Module HTML file %s has been auto-generated" % html_input_filename
    +
    + ## pygwt.js
    +
    + print "Copying: pygwt.js"
    +
    + pygwt_js_template = read_boilerplate(data_dir, "pygwt.js")
    + pygwt_js_output = open(join(output, "pygwt.js"), "w")
    +
    + print >>pygwt_js_output, pygwt_js_template
    +
    + pygwt_js_output.close()
    +
    + ## Images
    +
    + print "Copying: Images and History"
    + copy_boilerplate(data_dir, "corner_dialog_topleft_black.png", output)
    + copy_boilerplate(data_dir, "corner_dialog_topright_black.png", output)
    + copy_boilerplate(data_dir, "corner_dialog_bottomright_black.png", output)
    + copy_boilerplate(data_dir, "corner_dialog_bottomleft_black.png", output)
    + copy_boilerplate(data_dir, "corner_dialog_edge_black.png", output)
    + copy_boilerplate(data_dir, "corner_dialog_topleft.png", output)
    + copy_boilerplate(data_dir, "corner_dialog_topright.png", output)
    + copy_boilerplate(data_dir, "corner_dialog_bottomright.png", output)
    + copy_boilerplate(data_dir, "corner_dialog_bottomleft.png", output)
    + copy_boilerplate(data_dir, "corner_dialog_edge.png", output)
    + copy_boilerplate(data_dir, "tree_closed.gif", output)
    + copy_boilerplate(data_dir, "tree_open.gif", output)
    + copy_boilerplate(data_dir, "tree_white.gif", output)
    + copy_boilerplate(data_dir, "history.html", output)
    +
    +
    + ## all.cache.html
    + app_files = generateAppFiles(data_dir, js_includes, app_name, debug,
    + output, dynamic, cache_buster, optimize)
    +
    + ## AppName.nocache.html
    +
    + print "Creating: %(app_name)s.nocache.html" % locals()
    +
    + home_nocache_html_template = read_boilerplate(data_dir, "home.nocache.html")
    + home_nocache_html_output = open(join(output, app_name + ".nocache.html"),
    + "w")
    +
    + # the selector templ is added to the selectScript function
    + select_tmpl = """O(["true","%s"],"%s");"""
    + script_selectors = StringIO()
    +
    + for platform, file_prefix in app_files:
    + print >> script_selectors, select_tmpl % (platform, file_prefix)
    +
    + print >>home_nocache_html_output, home_nocache_html_template % dict(
    + app_name = app_name,
    + script_selectors = script_selectors.getvalue(),
    + )
    +
    + home_nocache_html_output.close()
    +
    + print "Done. You can run your app by opening '%(html_output_filename)s' in a browser" % locals()
    +
    +
    +def generateAppFiles(data_dir, js_includes, app_name, debug, output, dynamic,
    + cache_buster, optimize):
    +
    + all_cache_html_template = read_boilerplate(data_dir, "all.cache.html")
    + mod_cache_html_template = read_boilerplate(data_dir, "mod.cache.html")
    +
    + # clean out the old ones first
    + for name in os.listdir(output):
    + if CACHE_HTML_PAT.match(name):
    + p = join(output, name)
    + print "Deleting existing app file %s" % p
    + os.unlink(p)
    +
    + app_files = []
    + tmpl = read_boilerplate(data_dir, "all.cache.html")
    + parser = pyjs.PlatformParser("platform")
    + app_headers = ''
    + scripts = ['<script type="text/javascript" src="%s"></script>'%script \
    + for script in js_includes]
    + app_body = '\n'.join(scripts)
    +
    + mod_code = {}
    + mod_libs = {}
    + modules = {}
    + app_libs = {}
    + early_app_libs = {}
    + app_code = {}
    + overrides = {}
    + pover = {}
    + app_modnames = {}
    + mod_levels = {}
    +
    + # First, generate all the code.
    + # Second, (dynamic only), post-analyse the places where modules
    + # haven't changed
    + # Third, write everything out.
    +
    + for platform in app_platforms:
    +
    + mod_code[platform] = {}
    + mod_libs[platform] = {}
    + modules[platform] = []
    + pover[platform] = {}
    + app_libs[platform] = ''
    + early_app_libs[platform] = ''
    + app_code[platform] = {}
    + app_modnames[platform] = {}
    +
    + # Application.Platform.cache.html
    +
    + parser.setPlatform(platform)
    + app_translator = pyjs.AppTranslator(
    + parser=parser, dynamic=dynamic, optimize=optimize)
    + early_app_libs[platform], appcode = \
    + app_translator.translate(None, is_app=False,
    + debug=debug,
    + library_modules=['dynamicajax.js',
    + '_pyjs.js', 'sys',
    + 'pyjslib'])
    + pover[platform].update(app_translator.overrides.items())
    + for mname, name in app_translator.overrides.items():
    + pd = overrides.setdefault(mname, {})
    + pd[platform] = name
    +
    + print appcode
    + #mod_code[platform][app_name] = appcode
    +
    + # platform.Module.cache.js
    +
    + modules_done = ['pyjslib', 'sys', '_pyjs.js']
    + #modules_to_do = [app_name] + app_translator.library_modules
    + modules_to_do = [app_name] + app_translator.library_modules
    +
    + dependencies = {}
    +
    + deps = map(pyjs.strip_py, modules_to_do)
    + for d in deps:
    + sublist = add_subdeps(dependencies, d)
    + modules_to_do += sublist
    + deps = uniquify(deps)
    + #dependencies[app_name] = deps
    +
    + modules[platform] = modules_done + modules_to_do
    +
    + while modules_to_do:
    +
    + #print "modules to do", modules_to_do
    +
    + mn = modules_to_do.pop()
    + mod_name = pyjs.strip_py(mn)
    +
    + if mod_name in modules_done:
    + continue
    +
    + modules_done.append(mod_name)
    +
    + mod_cache_name = "%s.%s.cache.js" % (platform.lower(), mod_name)
    +
    + parser.setPlatform(platform)
    + mod_translator = pyjs.AppTranslator(parser=parser, optimize=optimize)
    + mod_libs[platform][mod_name], mod_code[platform][mod_name] = \
    + mod_translator.translate(mod_name,
    + is_app=False,
    + debug=debug)
    + pover[platform].update(mod_translator.overrides.items())
    + for mname, name in mod_translator.overrides.items():
    + pd = overrides.setdefault(mname, {})
    + pd[platform] = name
    +
    + mods = mod_translator.library_modules
    + modules_to_do += mods
    + modules[platform] += mods
    +
    + deps = map(pyjs.strip_py, mods)
    + sd = subdeps(mod_name)
    + if len(sd) > 1:
    + deps += sd[:-1]
    + while mod_name in deps:
    + deps.remove(mod_name)
    +
    + #print
    + #print
    + #print "modname preadd:", mod_name, deps
    + #print
    + #print
    + for d in deps:
    + sublist = add_subdeps(dependencies, d)
    + modules_to_do += sublist
    + modules_to_do += add_subdeps(dependencies, mod_name)
    + #print "modname:", mod_name, deps
    + deps = uniquify(deps)
    + #print "modname:", mod_name, deps
    + dependencies[mod_name] = deps
    +
    + # work out the dependency ordering of the modules
    +
    + mod_levels[platform] = make_deps(None, dependencies, modules_done)
    +
    + # now write everything out
    +
    + for platform in app_platforms:
    +
    + early_app_libs_ = early_app_libs[platform]
    + app_libs_ = app_libs[platform]
    + app_code_ = app_code[platform]
    + #modules_ = filter_mods(app_name, modules[platform])
    + mods = flattenlist(mod_levels[platform])
    + mods.reverse()
    + modules_ = filter_mods(None, mods)
    +
    + for mod_name in modules_:
    +
    + mod_code_ = mod_code[platform][mod_name]
    +
    + mod_name = pyjs.strip_py(mod_name)
    +
    + override_name = "%s.%s" % (platform.lower(), mod_name)
    + if pover[platform].has_key(override_name):
    + mod_cache_name = "%s.cache.js" % (override_name)
    + else:
    + mod_cache_name = "%s.cache.js" % (mod_name)
    +
    + print "Creating: " + mod_cache_name
    +
    + modlevels = make_deps(None, dependencies, dependencies[mod_name])
    +
    + modnames = []
    +
    + for md in modlevels:
    + mnames = map(lambda x: "'%s'" % x, md)
    + mnames = "new pyjslib.List([\n\t\t\t%s])" % ',\n\t\t\t'.join(mnames)
    + modnames.append(mnames)
    +
    + modnames.reverse()
    + modnames = "new pyjslib.List([\n\t\t%s\n\t])" % ',\n\t\t'.join(modnames)
    +
    + # convert the overrides
    +
    + overnames = map(lambda x: "'%s': '%s'" % x, pover[platform].items())
    + overnames = "new pyjslib.Dict({\n\t\t%s\n\t})" % ',\n\t\t'.join(overnames)
    +
    + if dynamic:
    + mod_cache_html_output = open(join(output, mod_cache_name), "w")
    + else:
    + mod_cache_html_output = StringIO()
    +
    + print >>mod_cache_html_output, mod_cache_html_template % dict(
    + mod_name = mod_name,
    + app_name = app_name,
    + modnames = modnames,
    + overrides = overnames,
    + mod_libs = mod_libs[platform][mod_name],
    + dynamic = dynamic,
    + mod_code = mod_code_,
    + )
    +
    + if dynamic:
    + mod_cache_html_output.close()
    + else:
    + mod_cache_html_output.seek(0)
    + app_libs_ += mod_cache_html_output.read()
    +
    + # write out the dependency ordering of the modules
    +
    + app_modnames = []
    +
    + for md in mod_levels[platform]:
    + mnames = map(lambda x: "'%s'" % x, md)
    + mnames = "new pyjslib.List([\n\t\t\t%s])" % ',\n\t\t\t'.join(mnames)
    + app_modnames.append(mnames)
    +
    + app_modnames.reverse()
    + app_modnames = "new pyjslib.List([\n\t\t%s\n\t])" % ',\n\t\t'.join(app_modnames)
    +
    + # convert the overrides
    +
    + overnames = map(lambda x: "'%s': '%s'" % x, pover[platform].items())
    + overnames = "new pyjslib.Dict({\n\t\t%s\n\t})" % ',\n\t\t'.join(overnames)
    +
    + #print "platform names", platform, overnames
    + #print pover
    +
    + # now write app.allcache including dependency-ordered list of
    + # library modules
    +
    + file_contents = all_cache_html_template % dict(
    + app_name = app_name,
    + early_app_libs = early_app_libs_,
    + app_libs = app_libs_,
    + app_code = app_code_,
    + app_body = app_body,
    + overrides = overnames,
    + platform = platform.lower(),
    + dynamic = dynamic,
    + app_modnames = app_modnames,
    + app_headers = app_headers
    + )
    + if cache_buster:
    + digest = md5.new(file_contents).hexdigest()
    + file_name = "%s.%s.%s" % (platform.lower(), app_name, digest)
    + else:
    + file_name = "%s.%s" % (platform.lower(), app_name)
    + file_name += ".cache.html"
    + out_path = join(output, file_name)
    + out_file = open(out_path, 'w')
    + out_file.write(file_contents)
    + out_file.close()
    + app_files.append((platform.lower(), file_name))
    + print "Created app file %s:%s: %s" % (
    + app_name, platform, out_path)
    +
    + return app_files
    +
    +def flattenlist(ll):
    + res = []
    + for l in ll:
    + res += l
    + return res
    +
    +# creates sub-dependencies e.g. pyjamas.ui.Widget
    +# creates pyjamas.ui.Widget, pyjamas.ui and pyjamas.
    +def subdeps(m):
    + d = []
    + m = m.split(".")
    + for i in range(0, len(m)):
    + d.append('.'.join(m[:i+1]))
    + return d
    +
    +import time
    +
    +def add_subdeps(deps, mod_name):
    + sd = subdeps(mod_name)
    + if len(sd) == 1:
    + return []
    + #print "subdeps", mod_name, sd
    + #print "deps", deps
    + res = []
    + for i in range(0, len(sd)-1):
    + parent = sd[i]
    + child = sd[i+1]
    + l = deps.get(child, [])
    + l.append(parent)
    + deps[child] = l
    + if parent not in res:
    + res.append(parent)
    + #print deps
    + return res
    +
    +# makes unique and preserves list order
    +def uniquify(md):
    + res = []
    + for m in md:
    + if m not in res:
    + res.append(m)
    + return res
    +
    +def filter_mods(app_name, md):
    + while 'sys' in md:
    + md.remove('sys')
    + while 'pyjslib' in md:
    + md.remove('pyjslib')
    + while app_name in md:
    + md.remove(app_name)
    + md = filter(lambda x: not x.endswith('.js'), md)
    + md = map(pyjs.strip_py, md)
    +
    + return uniquify(md)
    +
    +def filter_deps(app_name, deps):
    +
    + res = {}
    + for (k, l) in deps.items():
    + mods = filter_mods(k, l)
    + while k in mods:
    + mods.remove(k)
    + res[k] = mods
    + return res
    +
    +def has_nodeps(mod, deps):
    + if not deps.has_key(mod) or not deps[mod]:
    + return True
    + return False
    +
    +def nodeps_list(mod_list, deps):
    + res = []
    + for mod in mod_list:
    + if has_nodeps(mod, deps):
    + res.append(mod)
    + return res
    +
    +# this function takes a dictionary of dependent modules and
    +# creates a list of lists. the first list will be modules
    +# that have no dependencies; the second list will be those
    +# modules that have the first list as dependencies; the
    +# third will be those modules that have the first and second...
    +# etc.
    +
    +
    +def make_deps(app_name, deps, mod_list):
    + print "Calculating Dependencies ..."
    + mod_list = filter_mods(app_name, mod_list)
    + deps = filter_deps(app_name, deps)
    +
    + if not mod_list:
    + return []
    +
    + #print mod_list
    + #print deps
    +
    + ordered_deps = []
    + last_len = -1
    + while deps:
    + l_deps = len(deps)
    + #print l_deps
    + if l_deps==last_len:
    + for m, dl in deps.items():
    + for d in dl:
    + if m in deps.get(d, []):
    + raise Exception('Circular Imports found: \n%s %s -> %s %s'
    + % (m, dl, d, deps[d]))
    + #raise Exception('Could not calculate dependencies: \n%s' % deps)
    + break
    + last_len = l_deps
    + #print "modlist", mod_list
    + nodeps = nodeps_list(mod_list, deps)
    + #print "nodeps", nodeps
    + mod_list = filter(lambda x: x not in nodeps, mod_list)
    + newdeps = {}
    + for k in deps.keys():
    + depslist = deps[k]
    + depslist = filter(lambda x: x not in nodeps, depslist)
    + if depslist:
    + newdeps[k] = depslist
    + #print "newdeps", newdeps
    + deps = newdeps
    + ordered_deps.append(nodeps)
    + #time.sleep(0)
    +
    + if mod_list:
    + ordered_deps.append(mod_list) # last dependencies - usually the app(s)
    +
    + ordered_deps.reverse()
    +
    + return ordered_deps
    +
    +def main():
    + global app_platforms
    +
    + parser = OptionParser(usage = usage, version = version)
    + parser.add_option("-o", "--output", dest="output",
    + help="directory to which the webapp should be written")
    + parser.add_option("-j", "--include-js", dest="js_includes", action="append",
    + help="javascripts to load into the same frame as the rest of the script")
    + parser.add_option("-I", "--library_dir", dest="library_dirs",
    + action="append", help="additional paths appended to PYJSPATH")
    + parser.add_option("-D", "--data_dir", dest="data_dir",
    + help="path for data directory")
    + parser.add_option("-m", "--dynamic-modules", action="store_true",
    + dest="dynamic", default=False,
    + help="Split output into separate dynamically-loaded modules (experimental)")
    + parser.add_option("-P", "--platforms", dest="platforms",
    + help="platforms to build for, comma-separated")
    + parser.add_option("-d", "--debug", action="store_true", dest="debug")
    + parser.add_option("-O", "--optimize", action="store_true",
    + dest="optimize", default=False,
    + help="Optimize generated code (removes all print statements)",
    + )
    + parser.add_option("-c", "--cache_buster", action="store_true",
    + dest="cache_buster",
    + help="Enable browser cache-busting (MD5 hash added to output filenames)")
    +
    + parser.set_defaults(output = "output", js_includes=[], library_dirs=[],
    + platforms=(','.join(app_platforms)),
    + data_dir=os.path.join(sys.prefix, "share/pyjamas"),
    + dynamic=False,
    + cache_buster=False,
    + debug=False)
    + (options, args) = parser.parse_args()
    + if len(args) != 1:
    + parser.error("incorrect number of arguments")
    +
    + data_dir = abspath(options.data_dir)
    +
    + app_path = args[0]
    + if app_path.endswith('.py'):
    + app_path = abspath(app_path)
    + if not isfile(app_path):
    + parser.error("Application file not found %r" % app_path)
    + app_path, app_name = split(app_path)
    + app_name = app_name[:-3]
    + pyjs.path.append(app_path)
    + elif os.path.sep in app_path:
    + parser.error("Not a valid module declaration %r" % app_path)
    + else:
    + app_name = app_path
    +
    + for d in options.library_dirs:
    + pyjs.path.append(abspath(d))
    +
    + if options.platforms:
    + app_platforms = options.platforms.split(',')
    +
    + # this is mostly for getting boilerplate stuff
    + data_dir = os.path.abspath(options.data_dir)
    +
    + build(app_name, options.output, options.js_includes,
    + options.debug, options.dynamic and 1 or 0, data_dir,
    + options.cache_buster, options.optimize)
    +
    +if __name__ == "__main__":
    + main()
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/svgui/pyjs/jsonrpc/README.txt Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,12 @@
    +These classes are intended for use server-side.
    +
    +e.g. in a django view.py :
    +
    + from pyjs.jsonrpc.django import JSONService, jsonremote
    +
    + jsonservice = JSONRPCService()
    +
    + @jsonremote(jsonservice)
    + def test(request, echo_param):
    + return "echoing the param back: %s" % echo_param
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/svgui/pyjs/jsonrpc/django/jsonrpc.py Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,226 @@
    +# jsonrpc.py
    +# original code: http://trac.pyworks.org/pyjamas/wiki/DjangoWithPyJamas
    +# also from: http://www.pimentech.fr/technologies/outils
    +from django.utils import simplejson
    +from django.http import HttpResponse
    +import sys
    +
    +from pyjs.jsonrpc import JSONRPCServiceBase
    +# JSONRPCService and jsonremote are used in combination to drastically
    +# simplify the provision of JSONRPC services. use as follows:
    +#
    +# jsonservice = JSONRPCService()
    +#
    +# @jsonremote(jsonservice)
    +# def test(request, echo_param):
    +# return "echoing the param back: %s" % echo_param
    +#
    +# dump jsonservice into urlpatterns:
    +# (r'^service1/$', 'djangoapp.views.jsonservice'),
    +
    +class JSONRPCService(JSONRPCServiceBase):
    +
    + def __call__(self, request, extra=None):
    + return self.process(request.raw_post_data)
    +
    +def jsonremote(service):
    + """Make JSONRPCService a decorator so that you can write :
    +
    + from jsonrpc import JSONRPCService
    + chatservice = JSONRPCService()
    +
    + @jsonremote(chatservice)
    + def login(request, user_name):
    + (...)
    + """
    + def remotify(func):
    + if isinstance(service, JSONRPCService):
    + service.add_method(func.__name__, func)
    + else:
    + emsg = 'Service "%s" not found' % str(service.__name__)
    + raise NotImplementedError, emsg
    + return func
    + return remotify
    +
    +
    +# FormProcessor provides a mechanism for turning Django Forms into JSONRPC
    +# Services. If you have an existing Django app which makes prevalent
    +# use of Django Forms it will save you rewriting the app.
    +# use as follows. in djangoapp/views.py :
    +#
    +# class SimpleForm(forms.Form):
    +# testfield = forms.CharField(max_length=100)
    +#
    +# class SimpleForm2(forms.Form):
    +# testfield = forms.CharField(max_length=20)
    +#
    +# processor = FormProcessor({'processsimpleform': SimpleForm,
    +# 'processsimpleform2': SimpleForm2})
    +#
    +# this will result in a JSONRPC service being created with two
    +# RPC functions. dump "processor" into urlpatterns to make it
    +# part of the app:
    +# (r'^formsservice/$', 'djangoapp.views.processor'),
    +
    +from django import forms
    +
    +def builderrors(form):
    + d = {}
    + for error in form.errors.keys():
    + if error not in d:
    + d[error] = []
    + for errorval in form.errors[error]:
    + d[error].append(unicode(errorval))
    + return d
    +
    +
    +# contains the list of arguments in each field
    +field_names = {
    + 'CharField': ['max_length', 'min_length'],
    + 'IntegerField': ['max_value', 'min_value'],
    + 'FloatField': ['max_value', 'min_value'],
    + 'DecimalField': ['max_value', 'min_value', 'max_digits', 'decimal_places'],
    + 'DateField': ['input_formats'],
    + 'DateTimeField': ['input_formats'],
    + 'TimeField': ['input_formats'],
    + 'RegexField': ['max_length', 'min_length'], # sadly we can't get the expr
    + 'EmailField': ['max_length', 'min_length'],
    + 'URLField': ['max_length', 'min_length', 'verify_exists', 'user_agent'],
    + 'ChoiceField': ['choices'],
    + 'FilePathField': ['path', 'match', 'recursive', 'choices'],
    + 'IPAddressField': ['max_length', 'min_length'],
    + }
    +
    +def describe_field_errors(field):
    + res = {}
    + field_type = field.__class__.__name__
    + msgs = {}
    + for n, m in field.error_messages.items():
    + msgs[n] = unicode(m)
    + res['error_messages'] = msgs
    + if field_type in ['ComboField', 'MultiValueField', 'SplitDateTimeField']:
    + res['fields'] = map(describe_field, field.fields)
    + return res
    +
    +def describe_fields_errors(fields, field_names):
    + res = {}
    + if not field_names:
    + field_names = fields.keys()
    + for name in field_names:
    + field = fields[name]
    + res[name] = describe_field_errors(field)
    + return res
    +
    +def describe_field(field):
    + res = {}
    + field_type = field.__class__.__name__
    + for fname in field_names.get(field_type, []) + \
    + ['help_text', 'label', 'initial', 'required']:
    + res[fname] = getattr(field, fname)
    + if field_type in ['ComboField', 'MultiValueField', 'SplitDateTimeField']:
    + res['fields'] = map(describe_field, field.fields)
    + return res
    +
    +def describe_fields(fields, field_names):
    + res = {}
    + if not field_names:
    + field_names = fields.keys()
    + for name in field_names:
    + field = fields[name]
    + res[name] = describe_field(field)
    + return res
    +
    +class FormProcessor(JSONRPCService):
    + def __init__(self, forms, _formcls=None):
    +
    + if _formcls is None:
    + JSONRPCService.__init__(self)
    + for k in forms.keys():
    + s = FormProcessor({}, forms[k])
    + self.add_method(k, s.__process)
    + else:
    + JSONRPCService.__init__(self, forms)
    + self.formcls = _formcls
    +
    + def __process(self, request, params, command=None):
    +
    + f = self.formcls(params)
    +
    + if command is None: # just validate
    + if not f.is_valid():
    + return {'success':False, 'errors': builderrors(f)}
    + return {'success':True}
    +
    + elif command.has_key('describe_errors'):
    + field_names = command['describe_errors']
    + return describe_fields_errors(f.fields, field_names)
    +
    + elif command.has_key('describe'):
    + field_names = command['describe']
    + return describe_fields(f.fields, field_names)
    +
    + elif command.has_key('save'):
    + if not f.is_valid():
    + return {'success':False, 'errors': builderrors(f)}
    + instance = f.save() # XXX: if you want more, over-ride save.
    + return {'success': True, 'instance': json_convert(instance) }
    +
    + elif command.has_key('html'):
    + return {'success': True, 'html': f.as_table()}
    +
    + return "unrecognised command"
    +
    +
    +
    +
    +# The following is incredibly convenient for saving vast amounts of
    +# coding, avoiding doing silly things like this:
    +# jsonresult = {'field1': djangoobject.field1,
    +# 'field2': djangoobject.date.strftime('%Y.%M'),
    +# ..... }
    +#
    +# The date/time flatten function is there because JSONRPC doesn't
    +# support date/time objects or formats, so conversion to a string
    +# is the most logical choice. pyjamas, being python, can easily
    +# be used to parse the string result at the other end.
    +#
    +# use as follows:
    +#
    +# jsonservice = JSONRPCService()
    +#
    +# @jsonremote(jsonservice)
    +# def list_some_model(request, start=0, count=10):
    +# l = SomeDjangoModelClass.objects.filter()
    +# res = json_convert(l[start:end])
    +#
    +# @jsonremote(jsonservice)
    +# def list_another_model(request, start=0, count=10):
    +# l = AnotherDjangoModelClass.objects.filter()
    +# res = json_convert(l[start:end])
    +#
    +# dump jsonservice into urlpatterns to make the two RPC functions,
    +# list_some_model and list_another_model part of the django app:
    +# (r'^service1/$', 'djangoapp.views.jsonservice'),
    +
    +from django.core.serializers import serialize
    +import datetime
    +from datetime import date
    +
    +def dict_datetimeflatten(item):
    + d = {}
    + for k, v in item.items():
    + k = str(k)
    + if isinstance(v, datetime.date):
    + d[k] = str(v)
    + elif isinstance(v, dict):
    + d[k] = dict_datetimeflatten(v)
    + else:
    + d[k] = v
    + return d
    +
    +def json_convert(l, fields=None):
    + res = []
    + for item in serialize('python', l, fields=fields):
    + res.append(dict_datetimeflatten(item))
    + return res
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/svgui/pyjs/jsonrpc/jsonrpc.py Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,43 @@
    +import gluon.contrib.simplejson as simplejson
    +import types
    +import sys
    +
    +class JSONRPCServiceBase:
    +
    + def __init__(self):
    + self.methods={}
    +
    + def response(self, id, result):
    + return simplejson.dumps({'version': '1.1', 'id':id,
    + 'result':result, 'error':None})
    + def error(self, id, code, message):
    + return simplejson.dumps({'id': id,
    + 'version': '1.1',
    + 'error': {'name': 'JSONRPCError',
    + 'code': code,
    + 'message': message
    + }
    + })
    +
    + def add_method(self, name, method):
    + self.methods[name] = method
    +
    + def process(self, data):
    + data = simplejson.loads(data)
    + id, method, params = data["id"], data["method"], data["params"]
    + if method in self.methods:
    + try:
    + result =self.methods[method](*params)
    + return self.response(id, result)
    + except BaseException:
    + etype, eval, etb = sys.exc_info()
    + return self.error(id, 100, '%s: %s' %(etype.__name__, eval))
    + except:
    + etype, eval, etb = sys.exc_info()
    + return self.error(id, 100, 'Exception %s: %s' %(etype, eval))
    + else:
    + return self.error(id, 100, 'method "%s" does not exist' % method)
    +
    + def listmethods(self):
    + return self.methods.keys()
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/svgui/pyjs/jsonrpc/web2py/jsonrpc.py Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,11 @@
    +from pyjs.jsonrpc import JSONRPCServiceBase
    +
    +class JSONRPCService(JSONRPCServiceBase):
    +
    + def serve(self):
    + return self.process(request.body.read())
    +
    + def __call__(self,func):
    + self.methods[func.__name__]=func
    + return func
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/svgui/pyjs/lib/_pyjs.js Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,160 @@
    +function pyjs_extend(klass, base) {
    + function klass_object_inherit() {}
    + klass_object_inherit.prototype = base.prototype;
    + klass_object = new klass_object_inherit();
    + for (var i in base.prototype.__class__) {
    + v = base.prototype.__class__[i];
    + if (typeof v == "function" && (v.class_method || v.static_method || v.unbound_method))
    + {
    + klass_object[i] = v;
    + }
    + }
    +
    + function klass_inherit() {}
    + klass_inherit.prototype = klass_object;
    + klass.prototype = new klass_inherit();
    + klass_object.constructor = klass;
    + klass.prototype.__class__ = klass_object;
    +
    + for (var i in base.prototype) {
    + v = base.prototype[i];
    + if (typeof v == "function" && v.instance_method)
    + {
    + klass.prototype[i] = v;
    + }
    + }
    +}
    +
    +/* creates a class, derived from bases, with methods and variables */
    +function pyjs_type(clsname, bases, methods)
    +{
    + var fn_cls = function() {};
    + fn_cls.__name__ = clsname;
    + var fn = function() {
    + var instance = new fn_cls();
    + if(instance.__init__) instance.__init__.apply(instance, arguments);
    + return instance;
    + }
    + fn_cls.__initialize__ = function() {
    + if (fn_cls.__was_initialized__) return;
    + fn_cls.__was_initialized__ = true;
    + fn_cls.__extend_baseclasses();
    + fn_cls.prototype.__class__.__new__ = fn;
    + fn_cls.prototype.__class__.__name__ = clsname;
    + }
    + fn_cls.__extend_baseclasses = function() {
    + var bi;
    + for (bi in fn_cls.__baseclasses)
    + {
    + var b = fn_cls.__baseclasses[bi];
    + if (b.__was_initialized__)
    + {
    + continue;
    + }
    + b.__initialize__();
    + }
    + for (bi in fn_cls.__baseclasses)
    + {
    + var b = fn_cls.__baseclasses[bi];
    + pyjs_extend(fn_cls, b);
    + }
    + }
    + if (!bases) {
    + bases = [pyjslib.__Object];
    + }
    + fn_cls.__baseclasses = bases;
    +
    + fn_cls.__initialize__();
    +
    + for (k in methods) {
    + var mth = methods[k];
    + var mtype = typeof mth;
    + if (mtype == "function" ) {
    + fn_cls.prototype[k] = mth;
    + fn_cls.prototype.__class__[k] = function () {
    + return fn_cls.prototype[k].call.apply(
    + fn_cls.prototype[k], arguments);
    + };
    + fn_cls.prototype.__class__[k].unbound_method = true;
    + fn_cls.prototype.instance_method = true;
    + fn_cls.prototype.__class__[k].__name__ = k;
    + fn_cls.prototype[k].__name__ = k;
    + } else {
    + fn_cls.prototype.__class__[k] = mth;
    + }
    + }
    + return fn;
    +}
    +function pyjs_kwargs_call(obj, func, star_args, args)
    +{
    + var call_args;
    +
    + if (star_args)
    + {
    + if (!pyjslib.isIteratable(star_args))
    + {
    + throw (pyjslib.TypeError(func.__name__ + "() arguments after * must be a sequence" + pyjslib.repr(star_args)));
    + }
    + call_args = Array();
    + var __i = star_args.__iter__();
    + var i = 0;
    + try {
    + while (true) {
    + call_args[i]=__i.next();
    + i++;
    + }
    + } catch (e) {
    + if (e != pyjslib.StopIteration) {
    + throw e;
    + }
    + }
    +
    + if (args)
    + {
    + var n = star_args.length;
    + for (var i=0; i < args.length; i++) {
    + call_args[n+i]=args[i];
    + }
    + }
    + }
    + else
    + {
    + call_args = args;
    + }
    + return func.apply(obj, call_args);
    +}
    +
    +function pyjs_kwargs_function_call(func, star_args, args)
    +{
    + return pyjs_kwargs_call(null, func, star_args, args);
    +}
    +
    +function pyjs_kwargs_method_call(obj, method_name, star_args, args)
    +{
    + var method = obj[method_name];
    + if (method.parse_kwargs)
    + {
    + args = method.parse_kwargs.apply(null, args);
    + }
    + return pyjs_kwargs_call(obj, method, star_args, args);
    +}
    +
    +//String.prototype.__getitem__ = String.prototype.charAt;
    +//String.prototype.upper = String.prototype.toUpperCase;
    +//String.prototype.lower = String.prototype.toLowerCase;
    +//String.prototype.find=pyjslib.String_find;
    +//String.prototype.join=pyjslib.String_join;
    +//String.prototype.isdigit=pyjslib.String_isdigit;
    +//String.prototype.__iter__=pyjslib.String___iter__;
    +//
    +//String.prototype.__replace=String.prototype.replace;
    +//String.prototype.replace=pyjslib.String_replace;
    +//
    +//String.prototype.split=pyjslib.String_split;
    +//String.prototype.strip=pyjslib.String_strip;
    +//String.prototype.lstrip=pyjslib.String_lstrip;
    +//String.prototype.rstrip=pyjslib.String_rstrip;
    +//String.prototype.startswith=pyjslib.String_startswith;
    +
    +var str = String;
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/svgui/pyjs/lib/json.js Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,293 @@
    +json_parse = (function () {
    +
    +// This is a function that can parse a JSON text, producing a JavaScript
    +// data structure. It is a simple, recursive descent parser. It does not use
    +// eval or regular expressions, so it can be used as a model for implementing
    +// a JSON parser in other languages.
    +
    +// We are defining the function inside of another function to avoid creating
    +// global variables.
    +
    + var at, // The index of the current character
    + ch, // The current character
    + escapee = {
    + '"': '"',
    + '\\': '\\',
    + '/': '/',
    + b: '\b',
    + f: '\f',
    + n: '\n',
    + r: '\r',
    + t: '\t'
    + },
    + text,
    +
    + error = function (m) {
    +
    +// Call error when something is wrong.
    +
    + throw {
    + name: 'SyntaxError',
    + message: m,
    + at: at,
    + text: text
    + };
    + },
    +
    + next = function (c) {
    +
    +// If a c parameter is provided, verify that it matches the current character.
    +
    + if (c && c !== ch) {
    + error("Expected '" + c + "' instead of '" + ch + "'");
    + }
    +
    +// Get the next character. When there are no more characters,
    +// return the empty string.
    +
    + ch = text.charAt(at);
    + at += 1;
    + return ch;
    + },
    +
    + number = function () {
    +
    +// Parse a number value.
    +
    + var number,
    + string = '';
    +
    + if (ch === '-') {
    + string = '-';
    + next('-');
    + }
    + while (ch >= '0' && ch <= '9') {
    + string += ch;
    + next();
    + }
    + if (ch === '.') {
    + string += '.';
    + while (next() && ch >= '0' && ch <= '9') {
    + string += ch;
    + }
    + }
    + if (ch === 'e' || ch === 'E') {
    + string += ch;
    + next();
    + if (ch === '-' || ch === '+') {
    + string += ch;
    + next();
    + }
    + while (ch >= '0' && ch <= '9') {
    + string += ch;
    + next();
    + }
    + }
    + number = +string;
    + if (isNaN(number)) {
    + error("Bad number");
    + } else {
    + return number;
    + }
    + },
    +
    + string = function () {
    +
    +// Parse a string value.
    +
    + var hex,
    + i,
    + string = '',
    + uffff;
    +
    +// When parsing for string values, we must look for " and \ characters.
    +
    + if (ch === '"') {
    + while (next()) {
    + if (ch === '"') {
    + next();
    + return string;
    + } else if (ch === '\\') {
    + next();
    + if (ch === 'u') {
    + uffff = 0;
    + for (i = 0; i < 4; i += 1) {
    + hex = parseInt(next(), 16);
    + if (!isFinite(hex)) {
    + break;
    + }
    + uffff = uffff * 16 + hex;
    + }
    + string += String.fromCharCode(uffff);
    + } else if (typeof escapee[ch] === 'string') {
    + string += escapee[ch];
    + } else {
    + break;
    + }
    + } else {
    + string += ch;
    + }
    + }
    + }
    + error("Bad string");
    + },
    +
    + white = function () {
    +
    +// Skip whitespace.
    +
    + while (ch && ch <= ' ') {
    + next();
    + }
    + },
    +
    + word = function () {
    +
    +// true, false, or null.
    +
    + switch (ch) {
    + case 't':
    + next('t');
    + next('r');
    + next('u');
    + next('e');
    + return true;
    + case 'f':
    + next('f');
    + next('a');
    + next('l');
    + next('s');
    + next('e');
    + return false;
    + case 'n':
    + next('n');
    + next('u');
    + next('l');
    + next('l');
    + return null;
    + }
    + error("Unexpected '" + ch + "'");
    + },
    +
    + value, // Place holder for the value function.
    +
    + array = function () {
    +
    +// Parse an array value.
    +
    + var array = [];
    +
    + if (ch === '[') {
    + next('[');
    + white();
    + if (ch === ']') {
    + next(']');
    + return array; // empty array
    + }
    + while (ch) {
    + array.push(value());
    + white();
    + if (ch === ']') {
    + next(']');
    + return array;
    + }
    + next(',');
    + white();
    + }
    + }
    + error("Bad array");
    + },
    +
    + object = function () {
    +
    +// Parse an object value.
    +
    + var key,
    + object = {};
    +
    + if (ch === '{') {
    + next('{');
    + white();
    + if (ch === '}') {
    + next('}');
    + return object; // empty object
    + }
    + while (ch) {
    + key = string();
    + white();
    + next(':');
    + if (Object.hasOwnProperty.call(object, key)) {
    + error('Duplicate key "' + key + '"');
    + }
    + object[key] = value();
    + white();
    + if (ch === '}') {
    + next('}');
    + return object;
    + }
    + next(',');
    + white();
    + }
    + }
    + error("Bad object");
    + };
    +
    + value = function () {
    +
    +// Parse a JSON value. It could be an object, an array, a string, a number,
    +// or a word.
    +
    + white();
    + switch (ch) {
    + case '{':
    + return object();
    + case '[':
    + return array();
    + case '"':
    + return string();
    + case '-':
    + return number();
    + default:
    + return ch >= '0' && ch <= '9' ? number() : word();
    + }
    + };
    +
    +// Return the json_parse function. It will have access to all of the above
    +// functions and variables.
    +
    + return function (source, reviver) {
    + var result;
    +
    + text = source;
    + at = 0;
    + ch = ' ';
    + result = value();
    + white();
    + if (ch) {
    + error("Syntax error");
    + }
    +
    +// If there is a reviver function, we recursively walk the new structure,
    +// passing each name/value pair to the reviver function for possible
    +// transformation, starting with a temporary root object that holds the result
    +// in an empty key. If there is not a reviver function, we simply return the
    +// result.
    +
    + return typeof reviver === 'function' ? (function walk(holder, key) {
    + var k, v, value = holder[key];
    + if (value && typeof value === 'object') {
    + for (k in value) {
    + if (Object.hasOwnProperty.call(value, k)) {
    + v = walk(value, k);
    + if (v !== undefined) {
    + value[k] = v;
    + } else {
    + delete value[k];
    + }
    + }
    + }
    + }
    + return reviver.call(holder, key, value);
    + }({'': result}, '')) : result;
    + };
    +}());
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/svgui/pyjs/lib/pyjslib.py Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,1365 @@
    +# Copyright 2006 James Tauber and contributors
    +#
    +# Licensed under the Apache License, Version 2.0 (the "License");
    +# you may not use this file except in compliance with the License.
    +# You may obtain a copy of the License at
    +#
    +# http://www.apache.org/licenses/LICENSE-2.0
    +#
    +# Unless required by applicable law or agreed to in writing, software
    +# distributed under the License is distributed on an "AS IS" BASIS,
    +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +# See the License for the specific language governing permissions and
    +# limitations under the License.
    +
    +
    +# iteration from Bob Ippolito's Iteration in JavaScript
    +
    +from __pyjamas__ import JS
    +
    +# must declare import _before_ importing sys
    +
    +def import_module(path, parent_module, module_name, dynamic=1, async=False):
    + """
    + """
    +
    + JS("""
    + var cache_file;
    +
    + if (module_name == "sys" || module_name == 'pyjslib')
    + {
    + /*module_load_request[module_name] = 1;*/
    + return;
    + }
    +
    + if (path == null)
    + {
    + path = './';
    + }
    +
    + var override_name = sys.platform + "." + module_name;
    + if (((sys.overrides != null) &&
    + (sys.overrides.has_key(override_name))))
    + {
    + cache_file = sys.overrides.__getitem__(override_name) ;
    + }
    + else
    + {
    + cache_file = module_name ;
    + }
    +
    + cache_file = (path + cache_file + '.cache.js' ) ;
    +
    + //alert("cache " + cache_file + " " + module_name + " " + parent_module);
    +
    + /* already loaded? */
    + if (module_load_request[module_name])
    + {
    + if (module_load_request[module_name] >= 3 && parent_module != null)
    + {
    + //onload_fn = parent_module + '.' + module_name + ' = ' + module_name + ';';
    + //pyjs_eval(onload_fn); /* set up the parent-module namespace */
    + }
    + return;
    + }
    + if (typeof (module_load_request[module_name]) == 'undefined')
    + {
    + module_load_request[module_name] = 1;
    + }
    +
    + /* following a load, this first executes the script
    + * "preparation" function MODULENAME_loaded_fn()
    + * and then sets up the loaded module in the namespace
    + * of the parent.
    + */
    +
    + onload_fn = ''; // module_name + "_loaded_fn();"
    +
    + if (parent_module != null)
    + {
    + //onload_fn += parent_module + '.' + module_name + ' = ' + module_name + ';';
    + /*pmod = parent_module + '.' + module_name;
    + onload_fn += 'alert("' + pmod + '"+' + pmod+');';*/
    + }
    +
    +
    + if (dynamic)
    + {
    + /* this one tacks the script onto the end of the DOM
    + */
    +
    + pyjs_load_script(cache_file, onload_fn, async);
    +
    + /* this one actually RUNS the script (eval) into the page.
    + my feeling is that this would be better for non-async
    + but i can't get it to work entirely yet.
    + */
    + /*pyjs_ajax_eval(cache_file, onload_fn, async);*/
    + }
    + else
    + {
    + if (module_name != "pyjslib" &&
    + module_name != "sys")
    + pyjs_eval(onload_fn);
    + }
    +
    + """)
    +
    +JS("""
    +function import_wait(proceed_fn, parent_mod, dynamic) {
    +
    + var data = '';
    + var element = $doc.createElement("div");
    + $doc.body.appendChild(element);
    + function write_dom(txt) {
    + element.innerHTML = txt + '<br />';
    + }
    +
    + var timeoutperiod = 1;
    + if (dynamic)
    + var timeoutperiod = 1;
    +
    + var wait = function() {
    +
    + var status = '';
    + for (l in module_load_request)
    + {
    + var m = module_load_request[l];
    + if (l == "sys" || l == 'pyjslib')
    + continue;
    + status += l + m + " ";
    + }
    +
    + //write_dom( " import wait " + wait_count + " " + status + " parent_mod " + parent_mod);
    + wait_count += 1;
    +
    + if (status == '')
    + {
    + setTimeout(wait, timeoutperiod);
    + return;
    + }
    +
    + for (l in module_load_request)
    + {
    + var m = module_load_request[l];
    + if (l == "sys" || l == 'pyjslib')
    + {
    + module_load_request[l] = 4;
    + continue;
    + }
    + if ((parent_mod != null) && (l == parent_mod))
    + {
    + if (m == 1)
    + {
    + setTimeout(wait, timeoutperiod);
    + return;
    + }
    + if (m == 2)
    + {
    + /* cheat and move app on to next stage */
    + module_load_request[l] = 3;
    + }
    + }
    + if (m == 1 || m == 2)
    + {
    + setTimeout(wait, timeoutperiod);
    + return;
    + }
    + if (m == 3)
    + {
    + //alert("waited for module " + l + ": loaded");
    + module_load_request[l] = 4;
    + mod_fn = modules[l];
    + }
    + }
    + //alert("module wait done");
    +
    + if (proceed_fn.importDone)
    + proceed_fn.importDone(proceed_fn);
    + else
    + proceed_fn();
    + }
    +
    + wait();
    +}
    +""")
    +
    +class Object:
    + pass
    +
    +object = Object
    +
    +class Modload:
    +
    + def __init__(self, path, app_modlist, app_imported_fn, dynamic,
    + parent_mod):
    + self.app_modlist = app_modlist
    + self.app_imported_fn = app_imported_fn
    + self.path = path
    + self.idx = 0;
    + self.dynamic = dynamic
    + self.parent_mod = parent_mod
    +
    + def next(self):
    +
    + for i in range(len(self.app_modlist[self.idx])):
    + app = self.app_modlist[self.idx][i]
    + import_module(self.path, self.parent_mod, app, self.dynamic, True);
    + self.idx += 1
    +
    + if self.idx >= len(self.app_modlist):
    + import_wait(self.app_imported_fn, self.parent_mod, self.dynamic)
    + else:
    + import_wait(getattr(self, "next"), self.parent_mod, self.dynamic)
    +
    +def get_module(module_name):
    + ev = "__mod = %s;" % module_name
    + JS("pyjs_eval(ev);")
    + return __mod
    +
    +def preload_app_modules(path, app_modnames, app_imported_fn, dynamic,
    + parent_mod=None):
    +
    + loader = Modload(path, app_modnames, app_imported_fn, dynamic, parent_mod)
    + loader.next()
    +
    +import sys
    +
    +class BaseException:
    +
    + name = "BaseException"
    +
    + def __init__(self, *args):
    + self.args = args
    +
    + def __str__(self):
    + if len(self.args) is 0:
    + return ''
    + elif len(self.args) is 1:
    + return repr(self.args[0])
    + return repr(self.args)
    +
    + def toString(self):
    + return str(self)
    +
    +class Exception(BaseException):
    +
    + name = "Exception"
    +
    +class TypeError(BaseException):
    + name = "TypeError"
    +
    +class StandardError(Exception):
    + name = "StandardError"
    +
    +class LookupError(StandardError):
    + name = "LookupError"
    +
    + def toString(self):
    + return self.name + ": " + self.args[0]
    +
    +class KeyError(LookupError):
    + name = "KeyError"
    +
    +class AttributeError(StandardError):
    +
    + name = "AttributeError"
    +
    + def toString(self):
    + return "AttributeError: %s of %s" % (self.args[1], self.args[0])
    +
    +JS("""
    +pyjslib.StopIteration = function () { };
    +pyjslib.StopIteration.prototype = new Error();
    +pyjslib.StopIteration.name = 'StopIteration';
    +pyjslib.StopIteration.message = 'StopIteration';
    +
    +pyjslib.String_find = function(sub, start, end) {
    + var pos=this.indexOf(sub, start);
    + if (pyjslib.isUndefined(end)) return pos;
    +
    + if (pos + sub.length>end) return -1;
    + return pos;
    +}
    +
    +pyjslib.String_join = function(data) {
    + var text="";
    +
    + if (pyjslib.isArray(data)) {
    + return data.join(this);
    + }
    + else if (pyjslib.isIteratable(data)) {
    + var iter=data.__iter__();
    + try {
    + text+=iter.next();
    + while (true) {
    + var item=iter.next();
    + text+=this + item;
    + }
    + }
    + catch (e) {
    + if (e != pyjslib.StopIteration) throw e;
    + }
    + }
    +
    + return text;
    +}
    +
    +pyjslib.String_isdigit = function() {
    + return (this.match(/^\d+$/g) != null);
    +}
    +
    +pyjslib.String_replace = function(old, replace, count) {
    + var do_max=false;
    + var start=0;
    + var new_str="";
    + var pos=0;
    +
    + if (!pyjslib.isString(old)) return this.__replace(old, replace);
    + if (!pyjslib.isUndefined(count)) do_max=true;
    +
    + while (start<this.length) {
    + if (do_max && !count--) break;
    +
    + pos=this.indexOf(old, start);
    + if (pos<0) break;
    +
    + new_str+=this.substring(start, pos) + replace;
    + start=pos+old.length;
    + }
    + if (start<this.length) new_str+=this.substring(start);
    +
    + return new_str;
    +}
    +
    +pyjslib.String_split = function(sep, maxsplit) {
    + var items=new pyjslib.List();
    + var do_max=false;
    + var subject=this;
    + var start=0;
    + var pos=0;
    +
    + if (pyjslib.isUndefined(sep) || pyjslib.isNull(sep)) {
    + sep=" ";
    + subject=subject.strip();
    + subject=subject.replace(/\s+/g, sep);
    + }
    + else if (!pyjslib.isUndefined(maxsplit)) do_max=true;
    +
    + if (subject.length == 0) {
    + return items;
    + }
    +
    + while (start<subject.length) {
    + if (do_max && !maxsplit--) break;
    +
    + pos=subject.indexOf(sep, start);
    + if (pos<0) break;
    +
    + items.append(subject.substring(start, pos));
    + start=pos+sep.length;
    + }
    + if (start<=subject.length) items.append(subject.substring(start));
    +
    + return items;
    +}
    +
    +pyjslib.String___iter__ = function() {
    + var i = 0;
    + var s = this;
    + return {
    + 'next': function() {
    + if (i >= s.length) {
    + throw pyjslib.StopIteration;
    + }
    + return s.substring(i++, i, 1);
    + },
    + '__iter__': function() {
    + return this;
    + }
    + };
    +}
    +
    +pyjslib.String_strip = function(chars) {
    + return this.lstrip(chars).rstrip(chars);
    +}
    +
    +pyjslib.String_lstrip = function(chars) {
    + if (pyjslib.isUndefined(chars)) return this.replace(/^\s+/, "");
    +
    + return this.replace(new RegExp("^[" + chars + "]+"), "");
    +}
    +
    +pyjslib.String_rstrip = function(chars) {
    + if (pyjslib.isUndefined(chars)) return this.replace(/\s+$/, "");
    +
    + return this.replace(new RegExp("[" + chars + "]+$"), "");
    +}
    +
    +pyjslib.String_startswith = function(prefix, start) {
    + if (pyjslib.isUndefined(start)) start = 0;
    +
    + if (this.substring(start, prefix.length) == prefix) return true;
    + return false;
    +}
    +
    +pyjslib.abs = Math.abs;
    +
    +""")
    +
    +class Class:
    + def __init__(self, name):
    + self.name = name
    +
    + def __str___(self):
    + return self.name
    +
    +def eq(a,b):
    + JS("""
    + if (pyjslib.hasattr(a, "__cmp__")) {
    + return a.__cmp__(b) == 0;
    + } else if (pyjslib.hasattr(b, "__cmp__")) {
    + return b.__cmp__(a) == 0;
    + }
    + return a == b;
    + """)
    +
    +def cmp(a,b):
    + if hasattr(a, "__cmp__"):
    + return a.__cmp__(b)
    + elif hasattr(b, "__cmp__"):
    + return -b.__cmp__(a)
    + if a > b:
    + return 1
    + elif b > a:
    + return -1
    + else:
    + return 0
    +
    +def bool(v):
    + # this needs to stay in native code without any dependencies here,
    + # because this is used by if and while, we need to prevent
    + # recursion
    + JS("""
    + if (!v) return false;
    + switch(typeof v){
    + case 'boolean':
    + return v;
    + case 'object':
    + if (v.__nonzero__){
    + return v.__nonzero__();
    + }else if (v.__len__){
    + return v.__len__()>0;
    + }
    + return true;
    + }
    + return Boolean(v);
    + """)
    +
    +class List:
    + def __init__(self, data=None):
    + JS("""
    + this.l = [];
    + this.extend(data);
    + """)
    +
    + def append(self, item):
    + JS(""" this.l[this.l.length] = item;""")
    +
    + def extend(self, data):
    + JS("""
    + if (pyjslib.isArray(data)) {
    + n = this.l.length;
    + for (var i=0; i < data.length; i++) {
    + this.l[n+i]=data[i];
    + }
    + }
    + else if (pyjslib.isIteratable(data)) {
    + var iter=data.__iter__();
    + var i=this.l.length;
    + try {
    + while (true) {
    + var item=iter.next();
    + this.l[i++]=item;
    + }
    + }
    + catch (e) {
    + if (e != pyjslib.StopIteration) throw e;
    + }
    + }
    + """)
    +
    + def remove(self, value):
    + JS("""
    + var index=this.index(value);
    + if (index<0) return false;
    + this.l.splice(index, 1);
    + return true;
    + """)
    +
    + def index(self, value, start=0):
    + JS("""
    + var length=this.l.length;
    + for (var i=start; i<length; i++) {
    + if (this.l[i]==value) {
    + return i;
    + }
    + }
    + return -1;
    + """)
    +
    + def insert(self, index, value):
    + JS(""" var a = this.l; this.l=a.slice(0, index).concat(value, a.slice(index));""")
    +
    + def pop(self, index = -1):
    + JS("""
    + if (index<0) index = this.l.length + index;
    + var a = this.l[index];
    + this.l.splice(index, 1);
    + return a;
    + """)
    +
    + def __cmp__(self, l):
    + if not isinstance(l, List):
    + return -1
    + ll = len(self) - len(l)
    + if ll != 0:
    + return ll
    + for x in range(len(l)):
    + ll = cmp(self.__getitem__(x), l[x])
    + if ll != 0:
    + return ll
    + return 0
    +
    + def slice(self, lower, upper):
    + JS("""
    + if (upper==null) return pyjslib.List(this.l.slice(lower));
    + return pyjslib.List(this.l.slice(lower, upper));
    + """)
    +
    + def __getitem__(self, index):
    + JS("""
    + if (index<0) index = this.l.length + index;
    + return this.l[index];
    + """)
    +
    + def __setitem__(self, index, value):
    + JS(""" this.l[index]=value;""")
    +
    + def __delitem__(self, index):
    + JS(""" this.l.splice(index, 1);""")
    +
    + def __len__(self):
    + JS(""" return this.l.length;""")
    +
    + def __contains__(self, value):
    + return self.index(value) >= 0
    +
    + def __iter__(self):
    + JS("""
    + var i = 0;
    + var l = this.l;
    + return {
    + 'next': function() {
    + if (i >= l.length) {
    + throw pyjslib.StopIteration;
    + }
    + return l[i++];
    + },
    + '__iter__': function() {
    + return this;
    + }
    + };
    + """)
    +
    + def reverse(self):
    + JS(""" this.l.reverse();""")
    +
    + def sort(self, compareFunc=None, keyFunc=None, reverse=False):
    + if not compareFunc:
    + global cmp
    + compareFunc = cmp
    + if keyFunc and reverse:
    + def thisSort1(a,b):
    + return -compareFunc(keyFunc(a), keyFunc(b))
    + self.l.sort(thisSort1)
    + elif keyFunc:
    + def thisSort2(a,b):
    + return compareFunc(keyFunc(a), keyFunc(b))
    + self.l.sort(thisSort2)
    + elif reverse:
    + def thisSort3(a,b):
    + return -compareFunc(a, b)
    + self.l.sort(thisSort3)
    + else:
    + self.l.sort(compareFunc)
    +
    + def getArray(self):
    + """
    + Access the javascript Array that is used internally by this list
    + """
    + return self.l
    +
    + def __str__(self):
    + return repr(self)
    +
    +list = List
    +
    +class Tuple:
    + def __init__(self, data=None):
    + JS("""
    + this.l = [];
    + this.extend(data);
    + """)
    +
    + def append(self, item):
    + JS(""" this.l[this.l.length] = item;""")
    +
    + def extend(self, data):
    + JS("""
    + if (pyjslib.isArray(data)) {
    + n = this.l.length;
    + for (var i=0; i < data.length; i++) {
    + this.l[n+i]=data[i];
    + }
    + }
    + else if (pyjslib.isIteratable(data)) {
    + var iter=data.__iter__();
    + var i=this.l.length;
    + try {
    + while (true) {
    + var item=iter.next();
    + this.l[i++]=item;
    + }
    + }
    + catch (e) {
    + if (e != pyjslib.StopIteration) throw e;
    + }
    + }
    + """)
    +
    + def remove(self, value):
    + JS("""
    + var index=this.index(value);
    + if (index<0) return false;
    + this.l.splice(index, 1);
    + return true;
    + """)
    +
    + def index(self, value, start=0):
    + JS("""
    + var length=this.l.length;
    + for (var i=start; i<length; i++) {
    + if (this.l[i]==value) {
    + return i;
    + }
    + }
    + return -1;
    + """)
    +
    + def insert(self, index, value):
    + JS(""" var a = this.l; this.l=a.slice(0, index).concat(value, a.slice(index));""")
    +
    + def pop(self, index = -1):
    + JS("""
    + if (index<0) index = this.l.length + index;
    + var a = this.l[index];
    + this.l.splice(index, 1);
    + return a;
    + """)
    +
    + def __cmp__(self, l):
    + if not isinstance(l, Tuple):
    + return -1
    + ll = len(self) - len(l)
    + if ll != 0:
    + return ll
    + for x in range(len(l)):
    + ll = cmp(self.__getitem__(x), l[x])
    + if ll != 0:
    + return ll
    + return 0
    +
    + def slice(self, lower, upper):
    + JS("""
    + if (upper==null) return pyjslib.Tuple(this.l.slice(lower));
    + return pyjslib.Tuple(this.l.slice(lower, upper));
    + """)
    +
    + def __getitem__(self, index):
    + JS("""
    + if (index<0) index = this.l.length + index;
    + return this.l[index];
    + """)
    +
    + def __setitem__(self, index, value):
    + JS(""" this.l[index]=value;""")
    +
    + def __delitem__(self, index):
    + JS(""" this.l.splice(index, 1);""")
    +
    + def __len__(self):
    + JS(""" return this.l.length;""")
    +
    + def __contains__(self, value):
    + return self.index(value) >= 0
    +
    + def __iter__(self):
    + JS("""
    + var i = 0;
    + var l = this.l;
    + return {
    + 'next': function() {
    + if (i >= l.length) {
    + throw pyjslib.StopIteration;
    + }
    + return l[i++];
    + },
    + '__iter__': function() {
    + return this;
    + }
    + };
    + """)
    +
    + def reverse(self):
    + JS(""" this.l.reverse();""")
    +
    + def sort(self, compareFunc=None, keyFunc=None, reverse=False):
    + if not compareFunc:
    + global cmp
    + compareFunc = cmp
    + if keyFunc and reverse:
    + def thisSort1(a,b):
    + return -compareFunc(keyFunc(a), keyFunc(b))
    + self.l.sort(thisSort1)
    + elif keyFunc:
    + def thisSort2(a,b):
    + return compareFunc(keyFunc(a), keyFunc(b))
    + self.l.sort(thisSort2)
    + elif reverse:
    + def thisSort3(a,b):
    + return -compareFunc(a, b)
    + self.l.sort(thisSort3)
    + else:
    + self.l.sort(compareFunc)
    +
    + def getArray(self):
    + """
    + Access the javascript Array that is used internally by this list
    + """
    + return self.l
    +
    + def __str__(self):
    + return repr(self)
    +
    +tuple = Tuple
    +
    +
    +class Dict:
    + def __init__(self, data=None):
    + JS("""
    + this.d = {};
    +
    + if (pyjslib.isArray(data)) {
    + for (var i in data) {
    + var item=data[i];
    + this.__setitem__(item[0], item[1]);
    + //var sKey=pyjslib.hash(item[0]);
    + //this.d[sKey]=item[1];
    + }
    + }
    + else if (pyjslib.isIteratable(data)) {
    + var iter=data.__iter__();
    + try {
    + while (true) {
    + var item=iter.next();
    + this.__setitem__(item.__getitem__(0), item.__getitem__(1));
    + }
    + }
    + catch (e) {
    + if (e != pyjslib.StopIteration) throw e;
    + }
    + }
    + else if (pyjslib.isObject(data)) {
    + for (var key in data) {
    + this.__setitem__(key, data[key]);
    + }
    + }
    + """)
    +
    + def __setitem__(self, key, value):
    + JS("""
    + var sKey = pyjslib.hash(key);
    + this.d[sKey]=[key, value];
    + """)
    +
    + def __getitem__(self, key):
    + JS("""
    + var sKey = pyjslib.hash(key);
    + var value=this.d[sKey];
    + if (pyjslib.isUndefined(value)){
    + throw pyjslib.KeyError(key);
    + }
    + return value[1];
    + """)
    +
    + def __nonzero__(self):
    + JS("""
    + for (var i in this.d){
    + return true;
    + }
    + return false;
    + """)
    +
    + def __len__(self):
    + JS("""
    + var size=0;
    + for (var i in this.d) size++;
    + return size;
    + """)
    +
    + def has_key(self, key):
    + return self.__contains__(key)
    +
    + def __delitem__(self, key):
    + JS("""
    + var sKey = pyjslib.hash(key);
    + delete this.d[sKey];
    + """)
    +
    + def __contains__(self, key):
    + JS("""
    + var sKey = pyjslib.hash(key);
    + return (pyjslib.isUndefined(this.d[sKey])) ? false : true;
    + """)
    +
    + def keys(self):
    + JS("""
    + var keys=new pyjslib.List();
    + for (var key in this.d) {
    + keys.append(this.d[key][0]);
    + }
    + return keys;
    + """)
    +
    + def values(self):
    + JS("""
    + var values=new pyjslib.List();
    + for (var key in this.d) values.append(this.d[key][1]);
    + return values;
    + """)
    +
    + def items(self):
    + JS("""
    + var items = new pyjslib.List();
    + for (var key in this.d) {
    + var kv = this.d[key];
    + items.append(new pyjslib.List(kv))
    + }
    + return items;
    + """)
    +
    + def __iter__(self):
    + return self.keys().__iter__()
    +
    + def iterkeys(self):
    + return self.__iter__()
    +
    + def itervalues(self):
    + return self.values().__iter__();
    +
    + def iteritems(self):
    + return self.items().__iter__();
    +
    + def setdefault(self, key, default_value):
    + if not self.has_key(key):
    + self[key] = default_value
    +
    + def get(self, key, default_=None):
    + if not self.has_key(key):
    + return default_
    + return self[key]
    +
    + def update(self, d):
    + for k,v in d.iteritems():
    + self[k] = v
    +
    + def getObject(self):
    + """
    + Return the javascript Object which this class uses to store
    + dictionary keys and values
    + """
    + return self.d
    +
    + def copy(self):
    + return Dict(self.items())
    +
    + def __str__(self):
    + return repr(self)
    +
    +dict = Dict
    +
    +# taken from mochikit: range( [start,] stop[, step] )
    +def range():
    + JS("""
    + var start = 0;
    + var stop = 0;
    + var step = 1;
    +
    + if (arguments.length == 2) {
    + start = arguments[0];
    + stop = arguments[1];
    + }
    + else if (arguments.length == 3) {
    + start = arguments[0];
    + stop = arguments[1];
    + step = arguments[2];
    + }
    + else if (arguments.length>0) stop = arguments[0];
    +
    + return {
    + 'next': function() {
    + if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) throw pyjslib.StopIteration;
    + var rval = start;
    + start += step;
    + return rval;
    + },
    + '__iter__': function() {
    + return this;
    + }
    + }
    + """)
    +
    +def slice(object, lower, upper):
    + JS("""
    + if (pyjslib.isString(object)) {
    + if (lower < 0) {
    + lower = object.length + lower;
    + }
    + if (upper < 0) {
    + upper = object.length + upper;
    + }
    + if (pyjslib.isNull(upper)) upper=object.length;
    + return object.substring(lower, upper);
    + }
    + if (pyjslib.isObject(object) && object.slice)
    + return object.slice(lower, upper);
    +
    + return null;
    + """)
    +
    +def str(text):
    + JS("""
    + if (pyjslib.hasattr(text,"__str__")) {
    + return text.__str__();
    + }
    + return String(text);
    + """)
    +
    +def ord(x):
    + if(isString(x) and len(x) is 1):
    + JS("""
    + return x.charCodeAt(0);
    + """)
    + else:
    + JS("""
    + throw pyjslib.TypeError();
    + """)
    + return None
    +
    +def chr(x):
    + JS("""
    + return String.fromCharCode(x)
    + """)
    +
    +def is_basetype(x):
    + JS("""
    + var t = typeof(x);
    + return t == 'boolean' ||
    + t == 'function' ||
    + t == 'number' ||
    + t == 'string' ||
    + t == 'undefined'
    + ;
    + """)
    +
    +def get_pyjs_classtype(x):
    + JS("""
    + if (pyjslib.hasattr(x, "__class__"))
    + if (pyjslib.hasattr(x.__class__, "__new__"))
    + var src = x.__class__.__name__;
    + return src;
    + return null;
    + """)
    +
    +def repr(x):
    + """ Return the string representation of 'x'.
    + """
    + JS("""
    + if (x === null)
    + return "null";
    +
    + if (x === undefined)
    + return "undefined";
    +
    + var t = typeof(x);
    +
    + //alert("repr typeof " + t + " : " + x);
    +
    + if (t == "boolean")
    + return x.toString();
    +
    + if (t == "function")
    + return "<function " + x.toString() + ">";
    +
    + if (t == "number")
    + return x.toString();
    +
    + if (t == "string") {
    + if (x.indexOf("'") == -1)
    + return "'" + x + "'";
    + if (x.indexOf('"') == -1)
    + return '"' + x + '"';
    + var s = x.replace(new RegExp('"', "g"), '\\\\"');
    + return '"' + s + '"';
    + };
    +
    + if (t == "undefined")
    + return "undefined";
    +
    + // If we get here, x is an object. See if it's a Pyjamas class.
    +
    + if (!pyjslib.hasattr(x, "__init__"))
    + return "<" + x.toString() + ">";
    +
    + // Handle the common Pyjamas data types.
    +
    + var constructor = "UNKNOWN";
    +
    + constructor = pyjslib.get_pyjs_classtype(x);
    +
    + //alert("repr constructor: " + constructor);
    +
    + if (constructor == "Tuple") {
    + var contents = x.getArray();
    + var s = "(";
    + for (var i=0; i < contents.length; i++) {
    + s += pyjslib.repr(contents[i]);
    + if (i < contents.length - 1)
    + s += ", ";
    + };
    + s += ")"
    + return s;
    + };
    +
    + if (constructor == "List") {
    + var contents = x.getArray();
    + var s = "[";
    + for (var i=0; i < contents.length; i++) {
    + s += pyjslib.repr(contents[i]);
    + if (i < contents.length - 1)
    + s += ", ";
    + };
    + s += "]"
    + return s;
    + };
    +
    + if (constructor == "Dict") {
    + var keys = new Array();
    + for (var key in x.d)
    + keys.push(key);
    +
    + var s = "{";
    + for (var i=0; i<keys.length; i++) {
    + var key = keys[i]
    + s += pyjslib.repr(key) + ": " + pyjslib.repr(x.d[key]);
    + if (i < keys.length-1)
    + s += ", "
    + };
    + s += "}";
    + return s;
    + };
    +
    + // If we get here, the class isn't one we know -> return the class name.
    + // Note that we replace underscores with dots so that the name will
    + // (hopefully!) look like the original Python name.
    +
    + //var s = constructor.replace(new RegExp('_', "g"), '.');
    + return "<" + constructor + " object>";
    + """)
    +
    +def float(text):
    + JS("""
    + return parseFloat(text);
    + """)
    +
    +def int(text, radix=0):
    + JS("""
    + return parseInt(text, radix);
    + """)
    +
    +def len(object):
    + JS("""
    + if (object==null) return 0;
    + if (pyjslib.isObject(object) && object.__len__) return object.__len__();
    + return object.length;
    + """)
    +
    +def isinstance(object_, classinfo):
    + if pyjslib.isUndefined(object_):
    + return False
    + if not pyjslib.isObject(object_):
    +
    + return False
    + if _isinstance(classinfo, Tuple):
    + for ci in classinfo:
    + if isinstance(object_, ci):
    + return True
    + return False
    + else:
    + return _isinstance(object_, classinfo)
    +
    +def _isinstance(object_, classinfo):
    + if not pyjslib.isObject(object_):
    + return False
    + JS("""
    + if (object_.__class__){
    + var res = object_ instanceof classinfo.constructor;
    + return res;
    + }
    + return false;
    + """)
    +
    +def getattr(obj, name, default_):
    + JS("""
    + if ((!pyjslib.isObject(obj))||(pyjslib.isUndefined(obj[name]))){
    + if (pyjslib.isUndefined(default_)){
    + throw pyjslib.AttributeError(obj, name);
    + }else{
    + return default_;
    + }
    + }
    + if (!pyjslib.isFunction(obj[name])) return obj[name];
    + var fnwrap = function() {
    + var args = [];
    + for (var i = 0; i < arguments.length; i++) {
    + args.push(arguments[i]);
    + }
    + return obj[name].apply(obj,args);
    + }
    + fnwrap.__name__ = name;
    + return fnwrap;
    + """)
    +
    +def setattr(obj, name, value):
    + JS("""
    + if (!pyjslib.isObject(obj)) return null;
    +
    + obj[name] = value;
    +
    + """)
    +
    +def hasattr(obj, name):
    + JS("""
    + if (!pyjslib.isObject(obj)) return false;
    + if (pyjslib.isUndefined(obj[name])) return false;
    +
    + return true;
    + """)
    +
    +def dir(obj):
    + JS("""
    + var properties=new pyjslib.List();
    + for (property in obj) properties.append(property);
    + return properties;
    + """)
    +
    +def filter(obj, method, sequence=None):
    + # object context is LOST when a method is passed, hence object must be passed separately
    + # to emulate python behaviour, should generate this code inline rather than as a function call
    + items = []
    + if sequence is None:
    + sequence = method
    + method = obj
    +
    + for item in sequence:
    + if method(item):
    + items.append(item)
    + else:
    + for item in sequence:
    + if method.call(obj, item):
    + items.append(item)
    +
    + return items
    +
    +
    +def map(obj, method, sequence=None):
    + items = []
    +
    + if sequence is None:
    + sequence = method
    + method = obj
    +
    + for item in sequence:
    + items.append(method(item))
    + else:
    + for item in sequence:
    + items.append(method.call(obj, item))
    +
    + return items
    +
    +
    +def enumerate(sequence):
    + enumeration = []
    + nextIndex = 0
    + for item in sequence:
    + enumeration.append([nextIndex, item])
    + nextIndex = nextIndex + 1
    + return enumeration
    +
    +
    +def min(*sequence):
    + minValue = None
    + for item in sequence:
    + if minValue is None:
    + minValue = item
    + elif item < minValue:
    + minValue = item
    + return minValue
    +
    +
    +def max(*sequence):
    + maxValue = None
    + for item in sequence:
    + if maxValue is None:
    + maxValue = item
    + elif item > maxValue:
    + maxValue = item
    + return maxValue
    +
    +
    +next_hash_id = 0
    +
    +def hash(obj):
    + JS("""
    + if (obj == null) return null;
    +
    + if (obj.$H) return obj.$H;
    + if (obj.__hash__) return obj.__hash__();
    + if (obj.constructor == String || obj.constructor == Number || obj.constructor == Date) return obj;
    +
    + obj.$H = ++pyjslib.next_hash_id;
    + return obj.$H;
    + """)
    +
    +
    +# type functions from Douglas Crockford's Remedial Javascript: http://www.crockford.com/javascript/remedial.html
    +def isObject(a):
    + JS("""
    + return (a != null && (typeof a == 'object')) || pyjslib.isFunction(a);
    + """)
    +
    +def isFunction(a):
    + JS("""
    + return typeof a == 'function';
    + """)
    +
    +def isString(a):
    + JS("""
    + return typeof a == 'string';
    + """)
    +
    +def isNull(a):
    + JS("""
    + return typeof a == 'object' && !a;
    + """)
    +
    +def isArray(a):
    + JS("""
    + return pyjslib.isObject(a) && a.constructor == Array;
    + """)
    +
    +def isUndefined(a):
    + JS("""
    + return typeof a == 'undefined';
    + """)
    +
    +def isIteratable(a):
    + JS("""
    + return pyjslib.isString(a) || (pyjslib.isObject(a) && a.__iter__);
    + """)
    +
    +def isNumber(a):
    + JS("""
    + return typeof a == 'number' && isFinite(a);
    + """)
    +
    +def toJSObjects(x):
    + """
    + Convert the pyjs pythonic List and Dict objects into javascript Object and Array
    + objects, recursively.
    + """
    + if isArray(x):
    + JS("""
    + var result = [];
    + for(var k=0; k < x.length; k++) {
    + var v = x[k];
    + var tv = pyjslib.toJSObjects(v);
    + result.push(tv);
    + }
    + return result;
    + """)
    + if isObject(x):
    + if isinstance(x, Dict):
    + JS("""
    + var o = x.getObject();
    + var result = {};
    + for (var i in o) {
    + result[o[i][0].toString()] = o[i][1];
    + }
    + return pyjslib.toJSObjects(result)
    + """)
    + elif isinstance(x, List):
    + return toJSObjects(x.l)
    + elif hasattr(x, '__class__'):
    + # we do not have a special implementation for custom
    + # classes, just pass it on
    + return x
    + if isObject(x):
    + JS("""
    + var result = {};
    + for(var k in x) {
    + var v = x[k];
    + var tv = pyjslib.toJSObjects(v)
    + result[k] = tv;
    + }
    + return result;
    + """)
    + return x
    +
    +def printFunc(objs):
    + JS("""
    + if ($wnd.console==undefined) return;
    + var s = "";
    + for(var i=0; i < objs.length; i++) {
    + if(s != "") s += " ";
    + s += objs[i];
    + }
    + console.debug(s)
    + """)
    +
    +def type(clsname, bases=None, methods=None):
    + """ creates a class, derived from bases, with methods and variables
    + """
    +
    + JS(" var mths = {}; ")
    + if methods:
    + for k in methods.keys():
    + mth = methods[k]
    + JS(" mths[k] = mth; ")
    +
    + JS(" var bss = null; ")
    + if bases:
    + JS("bss = bases.l;")
    + JS(" return pyjs_type(clsname, bss, mths); ")
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/svgui/pyjs/lib/sys.py Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,59 @@
    +# the platform name (PyV8, smjs, Mozilla, IE6, Opera, Safari etc.)
    +platform = '' # to be updated by app, on compile
    +
    +# a dictionary of module override names (platform-specific)
    +overrides = None # to be updated by app, on compile
    +
    +# the remote path for loading modules
    +loadpath = None
    +
    +stacktrace = None
    +
    +appname = None
    +
    +def setloadpath(lp):
    + global loadpath
    + loadpath = lp
    +
    +def setappname(an):
    + global appname
    + appname = an
    +
    +def getloadpath():
    + global loadpath
    + return loadpath
    +
    +def addoverride(module_name, path):
    + global overrides
    + overrides[module_name] = path
    +
    +def addstack(linedebug):
    + JS("""
    + if (pyjslib.bool((sys.stacktrace === null))) {
    + sys.stacktrace = new pyjslib.List([]);
    + }
    + sys.stacktrace.append(linedebug);
    + """)
    +def popstack():
    + JS("""
    + sys.stacktrace.pop()
    + """)
    +
    +def printstack():
    + JS("""
    + var res = '';
    +
    + var __l = sys.stacktrace.__iter__();
    + try {
    + while (true) {
    + var l = __l.next();
    + res += ( l + '\\n' ) ;
    + }
    + } catch (e) {
    + if (e != pyjslib.StopIteration) {
    + throw e;
    + }
    + }
    +
    + return res;
    + """)
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/svgui/pyjs/pyjs.py Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,1777 @@
    +#!/usr/bin/env python
    +# Copyright 2006 James Tauber and contributors
    +#
    +# Licensed under the Apache License, Version 2.0 (the "License");
    +# you may not use this file except in compliance with the License.
    +# You may obtain a copy of the License at
    +#
    +# http://www.apache.org/licenses/LICENSE-2.0
    +#
    +# Unless required by applicable law or agreed to in writing, software
    +# distributed under the License is distributed on an "AS IS" BASIS,
    +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +# See the License for the specific language governing permissions and
    +# limitations under the License.
    +
    +
    +import sys
    +from types import StringType
    +import compiler
    +from compiler import ast
    +import os
    +import copy
    +
    +# the standard location for builtins (e.g. pyjslib) can be
    +# over-ridden by changing this. it defaults to sys.prefix
    +# so that on a system-wide install of pyjamas the builtins
    +# can be found in e.g. {sys.prefix}/share/pyjamas
    +#
    +# over-rides can be done by either explicitly modifying
    +# pyjs.prefix or by setting an environment variable, PYJSPREFIX.
    +
    +prefix = sys.prefix
    +
    +if os.environ.has_key('PYJSPREFIX'):
    + prefix = os.environ['PYJSPREFIX']
    +
    +# pyjs.path is the list of paths, just like sys.path, from which
    +# library modules will be searched for, for compile purposes.
    +# obviously we don't want to use sys.path because that would result
    +# in compiling standard python modules into javascript!
    +
    +path = [os.path.abspath('')]
    +
    +if os.environ.has_key('PYJSPATH'):
    + for p in os.environ['PYJSPATH'].split(os.pathsep):
    + p = os.path.abspath(p)
    + if os.path.isdir(p):
    + path.append(p)
    +
    +# this is the python function used to wrap native javascript
    +NATIVE_JS_FUNC_NAME = "JS"
    +
    +UU = ""
    +
    +PYJSLIB_BUILTIN_FUNCTIONS=("cmp",
    + "map",
    + "filter",
    + "dir",
    + "getattr",
    + "setattr",
    + "hasattr",
    + "int",
    + "float",
    + "str",
    + "repr",
    + "range",
    + "len",
    + "hash",
    + "abs",
    + "ord",
    + "chr",
    + "enumerate",
    + "min",
    + "max",
    + "bool",
    + "type",
    + "isinstance")
    +
    +PYJSLIB_BUILTIN_CLASSES=("BaseException",
    + "Exception",
    + "StandardError",
    + "StopIteration",
    + "AttributeError",
    + "TypeError",
    + "KeyError",
    + "LookupError",
    + "list",
    + "dict",
    + "object",
    + "tuple",
    + )
    +
    +def pyjs_builtin_remap(name):
    + # XXX HACK!
    + if name == 'list':
    + name = 'List'
    + if name == 'object':
    + name = '__Object'
    + if name == 'dict':
    + name = 'Dict'
    + if name == 'tuple':
    + name = 'Tuple'
    + return name
    +
    +# XXX: this is a hack: these should be dealt with another way
    +# however, console is currently the only global name which is causing
    +# problems.
    +PYJS_GLOBAL_VARS=("console")
    +
    +# This is taken from the django project.
    +# Escape every ASCII character with a value less than 32.
    +JS_ESCAPES = (
    + ('\\', r'\x5C'),
    + ('\'', r'\x27'),
    + ('"', r'\x22'),
    + ('>', r'\x3E'),
    + ('<', r'\x3C'),
    + ('&', r'\x26'),
    + (';', r'\x3B')
    + ) + tuple([('%c' % z, '\\x%02X' % z) for z in range(32)])
    +
    +def escapejs(value):
    + """Hex encodes characters for use in JavaScript strings."""
    + for bad, good in JS_ESCAPES:
    + value = value.replace(bad, good)
    + return value
    +
    +def uuprefix(name, leave_alone=0):
    + name = name.split(".")
    + name = name[:leave_alone] + map(lambda x: "__%s" % x, name[leave_alone:])
    + return '.'.join(name)
    +
    +class Klass:
    +
    + klasses = {}
    +
    + def __init__(self, name, name_):
    + self.name = name
    + self.name_ = name_
    + self.klasses[name] = self
    + self.functions = set()
    +
    + def set_base(self, base_name):
    + self.base = self.klasses.get(base_name)
    +
    + def add_function(self, function_name):
    + self.functions.add(function_name)
    +
    +
    +class TranslationError(Exception):
    + def __init__(self, message, node):
    + self.message = "line %s:\n%s\n%s" % (node.lineno, message, node)
    +
    + def __str__(self):
    + return self.message
    +
    +def strip_py(name):
    + return name
    +
    +def mod_var_name_decl(raw_module_name):
    + """ function to get the last component of the module e.g.
    + pyjamas.ui.DOM into the "namespace". i.e. doing
    + "import pyjamas.ui.DOM" actually ends up with _two_
    + variables - one pyjamas.ui.DOM, the other just "DOM".
    + but "DOM" is actually local, hence the "var" prefix.
    +
    + for PyV8, this might end up causing problems - we'll have
    + to see: gen_mod_import and mod_var_name_decl might have
    + to end up in a library-specific module, somewhere.
    + """
    + name = raw_module_name.split(".")
    + if len(name) == 1:
    + return ''
    + child_name = name[-1]
    + return "var %s = %s;\n" % (child_name, raw_module_name)
    +
    +def gen_mod_import(parentName, importName, dynamic=1):
    + #pyjs_ajax_eval("%(n)s.cache.js", null, true);
    + return """
    + pyjslib.import_module(sys.loadpath, '%(p)s', '%(n)s', %(d)d, false);
    + """ % ({'p': parentName, 'd': dynamic, 'n': importName}) + \
    + mod_var_name_decl(importName)
    +
    +class Translator:
    +
    + def __init__(self, mn, module_name, raw_module_name, src, debug, mod, output,
    + dynamic=0, optimize=False,
    + findFile=None):
    +
    + if module_name:
    + self.module_prefix = module_name + "."
    + else:
    + self.module_prefix = ""
    + self.raw_module_name = raw_module_name
    + src = src.replace("\r\n", "\n")
    + src = src.replace("\n\r", "\n")
    + src = src.replace("\r", "\n")
    + self.src = src.split("\n")
    + self.debug = debug
    + self.imported_modules = []
    + self.imported_modules_as = []
    + self.imported_js = set()
    + self.top_level_functions = set()
    + self.top_level_classes = set()
    + self.top_level_vars = set()
    + self.local_arg_stack = [[]]
    + self.output = output
    + self.imported_classes = {}
    + self.method_imported_globals = set()
    + self.method_self = None
    + self.nextTupleAssignID = 1
    + self.dynamic = dynamic
    + self.optimize = optimize
    + self.findFile = findFile
    +
    + if module_name.find(".") >= 0:
    + vdec = ''
    + else:
    + vdec = 'var '
    + print >>self.output, UU+"%s%s = function (__mod_name__) {" % (vdec, module_name)
    +
    + print >>self.output, " if("+module_name+".__was_initialized__) return;"
    + print >>self.output, " "+UU+module_name+".__was_initialized__ = true;"
    + print >>self.output, UU+"if (__mod_name__ == null) __mod_name__ = '%s';" % (mn)
    + print >>self.output, UU+"%s.__name__ = __mod_name__;" % (raw_module_name)
    +
    + decl = mod_var_name_decl(raw_module_name)
    + if decl:
    + print >>self.output, decl
    +
    +
    + if self.debug:
    + haltException = self.module_prefix + "HaltException"
    + print >>self.output, haltException + ' = function () {'
    + print >>self.output, ' this.message = "Program Halted";'
    + print >>self.output, ' this.name = "' + haltException + '";'
    + print >>self.output, '}'
    + print >>self.output, ''
    + print >>self.output, haltException + ".prototype.__str__ = function()"
    + print >>self.output, '{'
    + print >>self.output, 'return this.message ;'
    + print >>self.output, '}'
    +
    + print >>self.output, haltException + ".prototype.toString = function()"
    + print >>self.output, '{'
    + print >>self.output, 'return this.name + ": \\"" + this.message + "\\"";'
    + print >>self.output, '}'
    +
    + isHaltFunction = self.module_prefix + "IsHaltException"
    + print >>self.output, """
    + %s = function (s) {
    + var suffix="HaltException";
    + if (s.length < suffix.length) {
    + //alert(s + " " + suffix);
    + return false;
    + } else {
    + var ss = s.substring(s.length, (s.length - suffix.length));
    + //alert(s + " " + suffix + " " + ss);
    + return ss == suffix;
    + }
    + }
    + """ % isHaltFunction
    + for child in mod.node:
    + if isinstance(child, ast.Function):
    + self.top_level_functions.add(child.name)
    + elif isinstance(child, ast.Class):
    + self.top_level_classes.add(child.name)
    +
    + for child in mod.node:
    + if isinstance(child, ast.Function):
    + self._function(child, False)
    + elif isinstance(child, ast.Class):
    + self._class(child)
    + elif isinstance(child, ast.Import):
    + importName = child.names[0][0]
    + if importName == '__pyjamas__': # special module to help make pyjamas modules loadable in the python interpreter
    + pass
    + elif importName.endswith('.js'):
    + self.imported_js.add(importName)
    + else:
    + self.add_imported_module(strip_py(importName))
    + elif isinstance(child, ast.From):
    + if child.modname == '__pyjamas__': # special module to help make pyjamas modules loadable in the python interpreter
    + pass
    + else:
    + self.add_imported_module(child.modname)
    + self._from(child)
    + elif isinstance(child, ast.Discard):
    + self._discard(child, None)
    + elif isinstance(child, ast.Assign):
    + self._assign(child, None, True)
    + elif isinstance(child, ast.AugAssign):
    + self._augassign(child, None)
    + elif isinstance(child, ast.If):
    + self._if(child, None)
    + elif isinstance(child, ast.For):
    + self._for(child, None)
    + elif isinstance(child, ast.While):
    + self._while(child, None)
    + elif isinstance(child, ast.Subscript):
    + self._subscript_stmt(child, None)
    + elif isinstance(child, ast.Global):
    + self._global(child, None)
    + elif isinstance(child, ast.Printnl):
    + self._print(child, None)
    + elif isinstance(child, ast.Print):
    + self._print(child, None)
    + elif isinstance(child, ast.TryExcept):
    + self._tryExcept(child, None)
    + elif isinstance(child, ast.Raise):
    + self._raise(child, None)
    + elif isinstance(child, ast.Stmt):
    + self._stmt(child, None)
    + else:
    + raise TranslationError("unsupported type (in __init__)", child)
    +
    + # Initialize all classes for this module
    + #print >> self.output, "__"+self.modpfx()+\
    + # "classes_initialize = function() {\n"
    + #for className in self.top_level_classes:
    + # print >> self.output, "\t"+UU+self.modpfx()+"__"+className+"_initialize();"
    + #print >> self.output, "};\n"
    +
    + print >> self.output, "return this;\n"
    + print >> self.output, "}; /* end %s */ \n" % module_name
    +
    + def module_imports(self):
    + return self.imported_modules + self.imported_modules_as
    +
    + def add_local_arg(self, varname):
    + local_vars = self.local_arg_stack[-1]
    + if varname not in local_vars:
    + local_vars.append(varname)
    +
    + def add_imported_module(self, importName):
    +
    + if importName in self.imported_modules:
    + return
    + self.imported_modules.append(importName)
    + name = importName.split(".")
    + if len(name) != 1:
    + # add the name of the module to the namespace,
    + # but don't add the short name to imported_modules
    + # because then the short name would be attempted to be
    + # added to the dependencies, and it's half way up the
    + # module import directory structure!
    + child_name = name[-1]
    + self.imported_modules_as.append(child_name)
    + print >> self.output, gen_mod_import(self.raw_module_name,
    + strip_py(importName),
    + self.dynamic)
    +
    + def _default_args_handler(self, node, arg_names, current_klass,
    + output=None):
    + if len(node.defaults):
    + output = output or self.output
    + default_pos = len(arg_names) - len(node.defaults)
    + if arg_names and arg_names[0] == self.method_self:
    + default_pos -= 1
    + for default_node in node.defaults:
    + if isinstance(default_node, ast.Const):
    + default_value = self._const(default_node)
    + elif isinstance(default_node, ast.Name):
    + default_value = self._name(default_node, current_klass)
    + elif isinstance(default_node, ast.UnarySub):
    + default_value = self._unarysub(default_node, current_klass)
    + else:
    + raise TranslationError("unsupported type (in _method)", default_node)
    +
    + default_name = arg_names[default_pos]
    + default_pos += 1
    + print >> output, " if (typeof %s == 'undefined') %s=%s;" % (default_name, default_name, default_value)
    +
    + def _varargs_handler(self, node, varargname, arg_names, current_klass):
    + print >>self.output, " var", varargname, '= new pyjslib.Tuple();'
    + print >>self.output, " for(var __va_arg="+str(len(arg_names))+"; __va_arg < arguments.length; __va_arg++) {"
    + print >>self.output, " var __arg = arguments[__va_arg];"
    + print >>self.output, " "+varargname+".append(__arg);"
    + print >>self.output, " }"
    +
    + def _kwargs_parser(self, node, function_name, arg_names, current_klass):
    + if len(node.defaults) or node.kwargs:
    + default_pos = len(arg_names) - len(node.defaults)
    + if arg_names and arg_names[0] == self.method_self:
    + default_pos -= 1
    + print >>self.output, function_name+'.parse_kwargs = function (', ", ".join(["__kwargs"]+arg_names), ") {"
    + for default_node in node.defaults:
    + default_value = self.expr(default_node, current_klass)
    +# if isinstance(default_node, ast.Const):
    +# default_value = self._const(default_node)
    +# elif isinstance(default_node, ast.Name):
    +# default_value = self._name(default_node)
    +# elif isinstance(default_node, ast.UnarySub):
    +# default_value = self._unarysub(default_node, current_klass)
    +# else:
    +# raise TranslationError("unsupported type (in _method)", default_node)
    +
    + default_name = arg_names[default_pos]
    + print >>self.output, " if (typeof %s == 'undefined')"%(default_name)
    + print >>self.output, " %s=__kwargs.%s;"% (default_name, default_name)
    + default_pos += 1
    +
    + #self._default_args_handler(node, arg_names, current_klass)
    + if node.kwargs: arg_names += ["pyjslib.Dict(__kwargs)"]
    + print >>self.output, " var __r = "+"".join(["[", ", ".join(arg_names), "]"])+";"
    + if node.varargs:
    + self._varargs_handler(node, "__args", arg_names, current_klass)
    + print >>self.output, " __r.push.apply(__r, __args.getArray())"
    + print >>self.output, " return __r;"
    + print >>self.output, "};"
    +
    + def _function(self, node, local=False):
    + if local:
    + function_name = node.name
    + self.add_local_arg(function_name)
    + else:
    + function_name = UU + self.modpfx() + node.name
    +
    + arg_names = list(node.argnames)
    + normal_arg_names = list(arg_names)
    + if node.kwargs: kwargname = normal_arg_names.pop()
    + if node.varargs: varargname = normal_arg_names.pop()
    + declared_arg_names = list(normal_arg_names)
    + if node.kwargs: declared_arg_names.append(kwargname)
    +
    + function_args = "(" + ", ".join(declared_arg_names) + ")"
    + print >>self.output, "%s = function%s {" % (function_name, function_args)
    + self._default_args_handler(node, normal_arg_names, None)
    +
    + local_arg_names = normal_arg_names + declared_arg_names
    +
    + if node.varargs:
    + self._varargs_handler(node, varargname, declared_arg_names, None)
    + local_arg_names.append(varargname)
    +
    + # stack of local variable names for this function call
    + self.local_arg_stack.append(local_arg_names)
    +
    + for child in node.code:
    + self._stmt(child, None)
    +
    + # remove the top local arg names
    + self.local_arg_stack.pop()
    +
    + # we need to return null always, so it is not undefined
    + lastStmt = [p for p in node.code][-1]
    + if not isinstance(lastStmt, ast.Return):
    + if not self._isNativeFunc(lastStmt):
    + print >>self.output, " return null;"
    +
    + print >>self.output, "};"
    + print >>self.output, "%s.__name__ = '%s';\n" % (function_name, node.name)
    +
    +
    + self._kwargs_parser(node, function_name, normal_arg_names, None)
    +
    +
    + def _return(self, node, current_klass):
    + expr = self.expr(node.value, current_klass)
    + # in python a function call always returns None, so we do it
    + # here too
    + print >>self.output, " return " + expr + ";"
    +
    +
    + def _break(self, node, current_klass):
    + print >>self.output, " break;"
    +
    +
    + def _continue(self, node, current_klass):
    + print >>self.output, " continue;"
    +
    +
    + def _callfunc(self, v, current_klass):
    +
    + if isinstance(v.node, ast.Name):
    + if v.node.name in self.top_level_functions:
    + call_name = self.modpfx() + v.node.name
    + elif v.node.name in self.top_level_classes:
    + call_name = self.modpfx() + v.node.name
    + elif self.imported_classes.has_key(v.node.name):
    + call_name = self.imported_classes[v.node.name] + '.' + v.node.name
    + elif v.node.name in PYJSLIB_BUILTIN_FUNCTIONS:
    + call_name = 'pyjslib.' + v.node.name
    + elif v.node.name in PYJSLIB_BUILTIN_CLASSES:
    + name = pyjs_builtin_remap(v.node.name)
    + call_name = 'pyjslib.' + name
    + elif v.node.name == "callable":
    + call_name = "pyjslib.isFunction"
    + else:
    + call_name = v.node.name
    + call_args = []
    + elif isinstance(v.node, ast.Getattr):
    + attr_name = v.node.attrname
    +
    + if isinstance(v.node.expr, ast.Name):
    + call_name = self._name2(v.node.expr, current_klass, attr_name)
    + call_args = []
    + elif isinstance(v.node.expr, ast.Getattr):
    + call_name = self._getattr2(v.node.expr, current_klass, attr_name)
    + call_args = []
    + elif isinstance(v.node.expr, ast.CallFunc):
    + call_name = self._callfunc(v.node.expr, current_klass) + "." + v.node.attrname
    + call_args = []
    + elif isinstance(v.node.expr, ast.Subscript):
    + call_name = self._subscript(v.node.expr, current_klass) + "." + v.node.attrname
    + call_args = []
    + elif isinstance(v.node.expr, ast.Const):
    + call_name = self.expr(v.node.expr, current_klass) + "." + v.node.attrname
    + call_args = []
    + else:
    + raise TranslationError("unsupported type (in _callfunc)", v.node.expr)
    + else:
    + raise TranslationError("unsupported type (in _callfunc)", v.node)
    +
    + call_name = strip_py(call_name)
    +
    + kwargs = []
    + star_arg_name = None
    + if v.star_args:
    + star_arg_name = self.expr(v.star_args, current_klass)
    +
    + for ch4 in v.args:
    + if isinstance(ch4, ast.Keyword):
    + kwarg = ch4.name + ":" + self.expr(ch4.expr, current_klass)
    + kwargs.append(kwarg)
    + else:
    + arg = self.expr(ch4, current_klass)
    + call_args.append(arg)
    +
    + if kwargs:
    + fn_args = ", ".join(['{' + ', '.join(kwargs) + '}']+call_args)
    + else:
    + fn_args = ", ".join(call_args)
    +
    + if kwargs or star_arg_name:
    + if not star_arg_name:
    + star_arg_name = 'null'
    + try: call_this, method_name = call_name.rsplit(".", 1)
    + except ValueError:
    + # Must be a function call ...
    + return ("pyjs_kwargs_function_call("+call_name+", "
    + + star_arg_name
    + + ", ["+fn_args+"]"
    + + ")" )
    + else:
    + return ("pyjs_kwargs_method_call("+call_this+", '"+method_name+"', "
    + + star_arg_name
    + + ", ["+fn_args+"]"
    + + ")")
    + else:
    + return call_name + "(" + ", ".join(call_args) + ")"
    +
    + def _print(self, node, current_klass):
    + if self.optimize:
    + return
    + call_args = []
    + for ch4 in node.nodes:
    + arg = self.expr(ch4, current_klass)
    + call_args.append(arg)
    +
    + print >>self.output, "pyjslib.printFunc([", ', '.join(call_args), "],", int(isinstance(node, ast.Printnl)), ");"
    +
    + def _tryExcept(self, node, current_klass):
    + if len(node.handlers) != 1:
    + raise TranslationError("except statements in this form are" +
    + " not supported", node)
    +
    + expr = node.handlers[0][0]
    + as_ = node.handlers[0][1]
    + if as_:
    + errName = as_.name
    + else:
    + errName = 'err'
    +
    + # XXX TODO: check that this should instead be added as a _separate_
    + # local scope, temporary to the function. oh dearie me.
    + self.add_local_arg(errName)
    +
    + print >>self.output, " try {"
    + for stmt in node.body.nodes:
    + self._stmt(stmt, current_klass)
    + print >> self.output, " } catch(%s) {" % errName
    + if expr:
    + l = []
    + if isinstance(expr, ast.Tuple):
    + for x in expr.nodes:
    + l.append("(%(err)s.__name__ == %(expr)s.__name__)" % dict (err=errName, expr=self.expr(x, current_klass)))
    + else:
    + l = [ " (%(err)s.__name__ == %(expr)s.__name__) " % dict (err=errName, expr=self.expr(expr, current_klass)) ]
    + print >> self.output, " if(%s) {" % '||\n\t\t'.join(l)
    + for stmt in node.handlers[0][2]:
    + self._stmt(stmt, current_klass)
    + if expr:
    + #print >> self.output, "} else { throw(%s); } " % errName
    + print >> self.output, "}"
    + if node.else_ != None:
    + print >>self.output, " } finally {"
    + for stmt in node.else_:
    + self._stmt(stmt, current_klass)
    + print >>self.output, " }"
    +
    + # XXX: change use_getattr to True to enable "strict" compilation
    + # but incurring a 100% performance penalty. oops.
    + def _getattr(self, v, current_klass, use_getattr=False):
    + attr_name = v.attrname
    + if isinstance(v.expr, ast.Name):
    + obj = self._name(v.expr, current_klass, return_none_for_module=True)
    + if obj == None and v.expr.name in self.module_imports():
    + # XXX TODO: distinguish between module import classes
    + # and variables. right now, this is a hack to get
    + # the sys module working.
    + #if v.expr.name == 'sys':
    + return v.expr.name+'.'+attr_name
    + #return v.expr.name+'.__'+attr_name+'.prototype.__class__'
    + if not use_getattr or attr_name == '__class__' or \
    + attr_name == '__name__':
    + return obj + "." + attr_name
    + return "pyjslib.getattr(%s, '%s')" % (obj, attr_name)
    + elif isinstance(v.expr, ast.Getattr):
    + return self._getattr(v.expr, current_klass) + "." + attr_name
    + elif isinstance(v.expr, ast.Subscript):
    + return self._subscript(v.expr, self.modpfx()) + "." + attr_name
    + elif isinstance(v.expr, ast.CallFunc):
    + return self._callfunc(v.expr, self.modpfx()) + "." + attr_name
    + else:
    + raise TranslationError("unsupported type (in _getattr)", v.expr)
    +
    +
    + def modpfx(self):
    + return strip_py(self.module_prefix)
    +
    + def _name(self, v, current_klass, top_level=False,
    + return_none_for_module=False):
    +
    + if v.name == 'ilikesillynamesfornicedebugcode':
    + print top_level, current_klass, repr(v)
    + print self.top_level_vars
    + print self.top_level_functions
    + print self.local_arg_stack
    + print "error..."
    +
    + local_var_names = None
    + las = len(self.local_arg_stack)
    + if las > 0:
    + local_var_names = self.local_arg_stack[-1]
    +
    + if v.name == "True":
    + return "true"
    + elif v.name == "False":
    + return "false"
    + elif v.name == "None":
    + return "null"
    + elif v.name == '__name__' and current_klass is None:
    + return self.modpfx() + v.name
    + elif v.name == self.method_self:
    + return "this"
    + elif v.name in self.top_level_functions:
    + return UU+self.modpfx() + v.name
    + elif v.name in self.method_imported_globals:
    + return UU+self.modpfx() + v.name
    + elif not current_klass and las == 1 and v.name in self.top_level_vars:
    + return UU+self.modpfx() + v.name
    + elif v.name in local_var_names:
    + return v.name
    + elif self.imported_classes.has_key(v.name):
    + return UU+self.imported_classes[v.name] + '.__' + v.name + ".prototype.__class__"
    + elif v.name in self.top_level_classes:
    + return UU+self.modpfx() + "__" + v.name + ".prototype.__class__"
    + elif v.name in self.module_imports() and return_none_for_module:
    + return None
    + elif v.name in PYJSLIB_BUILTIN_CLASSES:
    + return "pyjslib." + pyjs_builtin_remap( v.name )
    + elif current_klass:
    + if v.name not in local_var_names and \
    + v.name not in self.top_level_vars and \
    + v.name not in PYJS_GLOBAL_VARS and \
    + v.name not in self.top_level_functions:
    +
    + cls_name = current_klass
    + if hasattr(cls_name, "name"):
    + cls_name_ = cls_name.name_
    + cls_name = cls_name.name
    + else:
    + cls_name_ = current_klass + "_" # XXX ???
    + name = UU+cls_name_ + ".prototype.__class__." \
    + + v.name
    + if v.name == 'listener':
    + name = 'listener+' + name
    + return name
    +
    + return v.name
    +
    + def _name2(self, v, current_klass, attr_name):
    + obj = v.name
    +
    + if obj in self.method_imported_globals:
    + call_name = UU+self.modpfx() + obj + "." + attr_name
    + elif self.imported_classes.has_key(obj):
    + #attr_str = ""
    + #if attr_name != "__init__":
    + attr_str = ".prototype.__class__." + attr_name
    + call_name = UU+self.imported_classes[obj] + '.__' + obj + attr_str
    + elif obj in self.module_imports():
    + call_name = obj + "." + attr_name
    + elif obj[0] == obj[0].upper(): # XXX HACK ALERT
    + call_name = UU + self.modpfx() + "__" + obj + ".prototype.__class__." + attr_name
    + else:
    + call_name = UU+self._name(v, current_klass) + "." + attr_name
    +
    + return call_name
    +
    +
    + def _getattr2(self, v, current_klass, attr_name):
    + if isinstance(v.expr, ast.Getattr):
    + call_name = self._getattr2(v.expr, current_klass, v.attrname + "." + attr_name)
    + elif isinstance(v.expr, ast.Name) and v.expr.name in self.module_imports():
    + call_name = UU+v.expr.name + '.__' +v.attrname+".prototype.__class__."+attr_name
    + else:
    + obj = self.expr(v.expr, current_klass)
    + call_name = obj + "." + v.attrname + "." + attr_name
    +
    + return call_name
    +
    +
    + def _class(self, node):
    + """
    + Handle a class definition.
    +
    + In order to translate python semantics reasonably well, the following
    + structure is used:
    +
    + A special object is created for the class, which inherits attributes
    + from the superclass, or Object if there's no superclass. This is the
    + class object; the object which you refer to when specifying the
    + class by name. Static, class, and unbound methods are copied
    + from the superclass object.
    +
    + A special constructor function is created with the same name as the
    + class, which is used to create instances of that class.
    +
    + A javascript class (e.g. a function with a prototype attribute) is
    + created which is the javascript class of created instances, and
    + which inherits attributes from the class object. Bound methods are
    + copied from the superclass into this class rather than inherited,
    + because the class object contains unbound, class, and static methods
    + that we don't necessarily want to inherit.
    +
    + The type of a method can now be determined by inspecting its
    + static_method, unbound_method, class_method, or instance_method
    + attribute; only one of these should be true.
    +
    + Much of this work is done in pyjs_extend, is pyjslib.py
    + """
    + class_name = self.modpfx() + uuprefix(node.name, 1)
    + class_name_ = self.modpfx() + uuprefix(node.name)
    + current_klass = Klass(class_name, class_name_)
    + init_method = None
    + for child in node.code:
    + if isinstance(child, ast.Function):
    + current_klass.add_function(child.name)
    + if child.name == "__init__":
    + init_method = child
    +
    +
    + if len(node.bases) == 0:
    + base_class = "pyjslib.__Object"
    + elif len(node.bases) == 1:
    + if isinstance(node.bases[0], ast.Name):
    + if self.imported_classes.has_key(node.bases[0].name):
    + base_class_ = self.imported_classes[node.bases[0].name] + '.__' + node.bases[0].name
    + base_class = self.imported_classes[node.bases[0].name] + '.' + node.bases[0].name
    + else:
    + base_class_ = self.modpfx() + "__" + node.bases[0].name
    + base_class = self.modpfx() + node.bases[0].name
    + elif isinstance(node.bases[0], ast.Getattr):
    + # the bases are not in scope of the class so do not
    + # pass our class to self._name
    + base_class_ = self._name(node.bases[0].expr, None) + \
    + ".__" + node.bases[0].attrname
    + base_class = self._name(node.bases[0].expr, None) + \
    + "." + node.bases[0].attrname
    + else:
    + raise TranslationError("unsupported type (in _class)", node.bases[0])
    +
    + current_klass.set_base(base_class)
    + else:
    + raise TranslationError("more than one base (in _class)", node)
    +
    + print >>self.output, UU+class_name_ + " = function () {"
    + # call superconstructor
    + #if base_class:
    + # print >>self.output, " __" + base_class + ".call(this);"
    + print >>self.output, "}"
    +
    + if not init_method:
    + init_method = ast.Function([], "__init__", ["self"], [], 0, None, [])
    + #self._method(init_method, current_klass, class_name)
    +
    + # Generate a function which constructs the object
    + clsfunc = ast.Function([],
    + node.name,
    + init_method.argnames[1:],
    + init_method.defaults,
    + init_method.flags,
    + None,
    + [ast.Discard(ast.CallFunc(ast.Name("JS"), [ast.Const(
    +# I attempted lazy initialization, but then you can't access static class members
    +# " if(!__"+base_class+".__was_initialized__)"+
    +# " __" + class_name + "_initialize();\n" +
    + " var instance = new " + UU + class_name_ + "();\n" +
    + " if(instance.__init__) instance.__init__.apply(instance, arguments);\n" +
    + " return instance;"
    + )]))])
    +
    + self._function(clsfunc, False)
    + print >>self.output, UU+class_name_ + ".__initialize__ = function () {"
    + print >>self.output, " if("+UU+class_name_+".__was_initialized__) return;"
    + print >>self.output, " "+UU+class_name_+".__was_initialized__ = true;"
    + cls_obj = UU+class_name_ + '.prototype.__class__'
    +
    + if class_name == "pyjslib.__Object":
    + print >>self.output, " "+cls_obj+" = {};"
    + else:
    + if base_class and base_class not in ("object", "pyjslib.__Object"):
    + print >>self.output, " if(!"+UU+base_class_+".__was_initialized__)"
    + print >>self.output, " "+UU+base_class_+".__initialize__();"
    + print >>self.output, " pyjs_extend(" + UU+class_name_ + ", "+UU+base_class_+");"
    + else:
    + print >>self.output, " pyjs_extend(" + UU+class_name_ + ", "+UU+"pyjslib.__Object);"
    +
    + print >>self.output, " "+cls_obj+".__new__ = "+UU+class_name+";"
    + print >>self.output, " "+cls_obj+".__name__ = '"+UU+node.name+"';"
    +
    + for child in node.code:
    + if isinstance(child, ast.Pass):
    + pass
    + elif isinstance(child, ast.Function):
    + self._method(child, current_klass, class_name, class_name_)
    + elif isinstance(child, ast.Assign):
    + self.classattr(child, current_klass)
    + elif isinstance(child, ast.Discard) and isinstance(child.expr, ast.Const):
    + # Probably a docstring, turf it
    + pass
    + else:
    + raise TranslationError("unsupported type (in _class)", child)
    + print >>self.output, "}"
    +
    + print >> self.output, class_name_+".__initialize__();"
    +
    +
    + def classattr(self, node, current_klass):
    + self._assign(node, current_klass, True)
    +
    + def _raise(self, node, current_klass):
    + if node.expr2:
    + raise TranslationError("More than one expression unsupported",
    + node)
    + print >> self.output, "throw (%s);" % self.expr(
    + node.expr1, current_klass)
    +
    + def _method(self, node, current_klass, class_name, class_name_):
    + # reset global var scope
    + self.method_imported_globals = set()
    +
    + arg_names = list(node.argnames)
    +
    + classmethod = False
    + staticmethod = False
    + if node.decorators:
    + for d in node.decorators:
    + if d.name == "classmethod":
    + classmethod = True
    + elif d.name == "staticmethod":
    + staticmethod = True
    +
    + if staticmethod:
    + staticfunc = ast.Function([], class_name_+"."+node.name, node.argnames, node.defaults, node.flags, node.doc, node.code, node.lineno)
    + self._function(staticfunc, True)
    + print >>self.output, " " + UU+class_name_ + ".prototype.__class__." + node.name + " = " + class_name_+"."+node.name+";";
    + print >>self.output, " " + UU+class_name_ + ".prototype.__class__." + node.name + ".static_method = true;";
    + return
    + else:
    + if len(arg_names) == 0:
    + raise TranslationError("methods must take an argument 'self' (in _method)", node)
    + self.method_self = arg_names[0]
    +
    + #if not classmethod and arg_names[0] != "self":
    + # raise TranslationError("first arg not 'self' (in _method)", node)
    +
    + normal_arg_names = arg_names[1:]
    + if node.kwargs: kwargname = normal_arg_names.pop()
    + if node.varargs: varargname = normal_arg_names.pop()
    + declared_arg_names = list(normal_arg_names)
    + if node.kwargs: declared_arg_names.append(kwargname)
    +
    + function_args = "(" + ", ".join(declared_arg_names) + ")"
    +
    + if classmethod:
    + fexpr = UU + class_name_ + ".prototype.__class__." + node.name
    + else:
    + fexpr = UU + class_name_ + ".prototype." + node.name
    + print >>self.output, " "+fexpr + " = function" + function_args + " {"
    +
    + # default arguments
    + self._default_args_handler(node, normal_arg_names, current_klass)
    +
    + local_arg_names = normal_arg_names + declared_arg_names
    +
    + if node.varargs:
    + self._varargs_handler(node, varargname, declared_arg_names, current_klass)
    + local_arg_names.append(varargname)
    +
    +
    + # stack of local variable names for this function call
    + self.local_arg_stack.append(local_arg_names)
    +
    + for child in node.code:
    + self._stmt(child, current_klass)
    +
    + # remove the top local arg names
    + self.local_arg_stack.pop()
    +
    + print >>self.output, " };"
    +
    + self._kwargs_parser(node, fexpr, normal_arg_names, current_klass)
    +
    + if classmethod:
    + # Have to create a version on the instances which automatically passes the
    + # class as "self"
    + altexpr = UU + class_name_ + ".prototype." + node.name
    + print >>self.output, " "+altexpr + " = function() {"
    + print >>self.output, " return " + fexpr + ".apply(this.__class__, arguments);"
    + print >>self.output, " };"
    + print >>self.output, " "+fexpr+".class_method = true;"
    + print >>self.output, " "+altexpr+".instance_method = true;"
    + else:
    + # For instance methods, we need an unbound version in the class object
    + altexpr = UU + class_name_ + ".prototype.__class__." + node.name
    + print >>self.output, " "+altexpr + " = function() {"
    + print >>self.output, " return " + fexpr + ".call.apply("+fexpr+", arguments);"
    + print >>self.output, " };"
    + print >>self.output, " "+altexpr+".unbound_method = true;"
    + print >>self.output, " "+fexpr+".instance_method = true;"
    + print >>self.output, " "+altexpr+".__name__ = '%s';" % node.name
    +
    + print >>self.output, UU + class_name_ + ".prototype.%s.__name__ = '%s';" % \
    + (node.name, node.name)
    +
    + if node.kwargs or len(node.defaults):
    + print >>self.output, " "+altexpr + ".parse_kwargs = " + fexpr + ".parse_kwargs;"
    +
    + self.method_self = None
    + self.method_imported_globals = set()
    +
    + def _isNativeFunc(self, node):
    + if isinstance(node, ast.Discard):
    + if isinstance(node.expr, ast.CallFunc):
    + if isinstance(node.expr.node, ast.Name) and \
    + node.expr.node.name == NATIVE_JS_FUNC_NAME:
    + return True
    + return False
    +
    + def _stmt(self, node, current_klass):
    + debugStmt = self.debug and not self._isNativeFunc(node)
    + if debugStmt:
    + print >>self.output, ' try {'
    +
    + if isinstance(node, ast.Return):
    + self._return(node, current_klass)
    + elif isinstance(node, ast.Break):
    + self._break(node, current_klass)
    + elif isinstance(node, ast.Continue):
    + self._continue(node, current_klass)
    + elif isinstance(node, ast.Assign):
    + self._assign(node, current_klass)
    + elif isinstance(node, ast.AugAssign):
    + self._augassign(node, current_klass)
    + elif isinstance(node, ast.Discard):
    + self._discard(node, current_klass)
    + elif isinstance(node, ast.If):
    + self._if(node, current_klass)
    + elif isinstance(node, ast.For):
    + self._for(node, current_klass)
    + elif isinstance(node, ast.While):
    + self._while(node, current_klass)
    + elif isinstance(node, ast.Subscript):
    + self._subscript_stmt(node, current_klass)
    + elif isinstance(node, ast.Global):
    + self._global(node, current_klass)
    + elif isinstance(node, ast.Pass):
    + pass
    + elif isinstance(node, ast.Function):
    + self._function(node, True)
    + elif isinstance(node, ast.Printnl):
    + self._print(node, current_klass)
    + elif isinstance(node, ast.Print):
    + self._print(node, current_klass)
    + elif isinstance(node, ast.TryExcept):
    + self._tryExcept(node, current_klass)
    + elif isinstance(node, ast.Raise):
    + self._raise(node, current_klass)
    + else:
    + raise TranslationError("unsupported type (in _stmt)", node)
    +
    + if debugStmt:
    +
    + lt = self.get_line_trace(node)
    +
    + haltException = self.module_prefix + "HaltException"
    + isHaltFunction = self.module_prefix + "IsHaltException"
    +
    + print >>self.output, ' } catch (__err) {'
    + print >>self.output, ' if (' + isHaltFunction + '(__err.name)) {'
    + print >>self.output, ' throw __err;'
    + print >>self.output, ' } else {'
    + print >>self.output, " st = sys.printstack() + "\
    + + '"%s"' % lt + "+ '\\n' ;"
    + print >>self.output, ' alert("' + "Error in " \
    + + lt + '"' \
    + + '+"\\n"+__err.name+": "+__err.message'\
    + + '+"\\n\\nStack trace:\\n"' \
    + + '+st' \
    + + ');'
    + print >>self.output, ' debugger;'
    +
    + print >>self.output, ' throw new ' + self.module_prefix + "HaltException();"
    + print >>self.output, ' }'
    + print >>self.output, ' }'
    +
    +
    + def get_line_trace(self, node):
    + lineNum = "Unknown"
    + srcLine = ""
    + if hasattr(node, "lineno"):
    + if node.lineno != None:
    + lineNum = node.lineno
    + srcLine = self.src[min(lineNum, len(self.src))-1]
    + srcLine = srcLine.replace('\\', '\\\\')
    + srcLine = srcLine.replace('"', '\\"')
    + srcLine = srcLine.replace("'", "\\'")
    +
    + return self.raw_module_name + ".py, line " \
    + + str(lineNum) + ":"\
    + + "\\n" \
    + + " " + srcLine
    +
    + def _augassign(self, node, current_klass):
    + v = node.node
    + if isinstance(v, ast.Getattr):
    + # XXX HACK! don't allow += on return result of getattr.
    + # TODO: create a temporary variable or something.
    + lhs = self._getattr(v, current_klass, False)
    + else:
    + lhs = self._name(node.node, current_klass)
    + op = node.op
    + rhs = self.expr(node.expr, current_klass)
    + print >>self.output, " " + lhs + " " + op + " " + rhs + ";"
    +
    +
    + def _assign(self, node, current_klass, top_level = False):
    + if len(node.nodes) != 1:
    + tempvar = '__temp'+str(node.lineno)
    + tnode = ast.Assign([ast.AssName(tempvar, "OP_ASSIGN", node.lineno)], node.expr, node.lineno)
    + self._assign(tnode, current_klass, top_level)
    + for v in node.nodes:
    + tnode2 = ast.Assign([v], ast.Name(tempvar, node.lineno), node.lineno)
    + self._assign(tnode2, current_klass, top_level)
    + return
    +
    + local_var_names = None
    + if len(self.local_arg_stack) > 0:
    + local_var_names = self.local_arg_stack[-1]
    +
    + def _lhsFromAttr(v, current_klass):
    + attr_name = v.attrname
    + if isinstance(v.expr, ast.Name):
    + obj = v.expr.name
    + lhs = self._name(v.expr, current_klass) + "." + attr_name
    + elif isinstance(v.expr, ast.Getattr):
    + lhs = self._getattr(v, current_klass)
    + elif isinstance(v.expr, ast.Subscript):
    + lhs = self._subscript(v.expr, current_klass) + "." + attr_name
    + else:
    + raise TranslationError("unsupported type (in _assign)", v.expr)
    + return lhs
    +
    + def _lhsFromName(v, top_level, current_klass):
    + if top_level:
    + if current_klass:
    + lhs = UU+current_klass.name_ + ".prototype.__class__." \
    + + v.name
    + else:
    + self.top_level_vars.add(v.name)
    + vname = self.modpfx() + v.name
    + if not self.modpfx() and v.name not in\
    + self.method_imported_globals:
    + lhs = "var " + vname
    + else:
    + lhs = UU + vname
    + self.add_local_arg(v.name)
    + else:
    + if v.name in local_var_names:
    + lhs = v.name
    + elif v.name in self.method_imported_globals:
    + lhs = self.modpfx() + v.name
    + else:
    + lhs = "var " + v.name
    + self.add_local_arg(v.name)
    + return lhs
    +
    + dbg = 0
    + v = node.nodes[0]
    + if isinstance(v, ast.AssAttr):
    + lhs = _lhsFromAttr(v, current_klass)
    + if v.flags == "OP_ASSIGN":
    + op = "="
    + else:
    + raise TranslationError("unsupported flag (in _assign)", v)
    +
    + elif isinstance(v, ast.AssName):
    + lhs = _lhsFromName(v, top_level, current_klass)
    + if v.flags == "OP_ASSIGN":
    + op = "="
    + else:
    + raise TranslationError("unsupported flag (in _assign)", v)
    + elif isinstance(v, ast.Subscript):
    + if v.flags == "OP_ASSIGN":
    + obj = self.expr(v.expr, current_klass)
    + if len(v.subs) != 1:
    + raise TranslationError("must have one sub (in _assign)", v)
    + idx = self.expr(v.subs[0], current_klass)
    + value = self.expr(node.expr, current_klass)
    + print >>self.output, " " + obj + ".__setitem__(" + idx + ", " + value + ");"
    + return
    + else:
    + raise TranslationError("unsupported flag (in _assign)", v)
    + elif isinstance(v, (ast.AssList, ast.AssTuple)):
    + uniqueID = self.nextTupleAssignID
    + self.nextTupleAssignID += 1
    + tempName = "__tupleassign" + str(uniqueID) + "__"
    + print >>self.output, " var " + tempName + " = " + \
    + self.expr(node.expr, current_klass) + ";"
    + for index,child in enumerate(v.getChildNodes()):
    + rhs = tempName + ".__getitem__(" + str(index) + ")"
    +
    + if isinstance(child, ast.AssAttr):
    + lhs = _lhsFromAttr(child, current_klass)
    + elif isinstance(child, ast.AssName):
    + lhs = _lhsFromName(child, top_level, current_klass)
    + elif isinstance(child, ast.Subscript):
    + if child.flags == "OP_ASSIGN":
    + obj = self.expr(child.expr, current_klass)
    + if len(child.subs) != 1:
    + raise TranslationError("must have one sub " +
    + "(in _assign)", child)
    + idx = self.expr(child.subs[0], current_klass)
    + value = self.expr(node.expr, current_klass)
    + print >>self.output, " " + obj + ".__setitem__(" \
    + + idx + ", " + rhs + ");"
    + continue
    + print >>self.output, " " + lhs + " = " + rhs + ";"
    + return
    + else:
    + raise TranslationError("unsupported type (in _assign)", v)
    +
    + rhs = self.expr(node.expr, current_klass)
    + if dbg:
    + print "b", repr(node.expr), rhs
    + print >>self.output, " " + lhs + " " + op + " " + rhs + ";"
    +
    +
    + def _discard(self, node, current_klass):
    +
    + if isinstance(node.expr, ast.CallFunc):
    + debugStmt = self.debug and not self._isNativeFunc(node)
    + if debugStmt and isinstance(node.expr.node, ast.Name) and \
    + node.expr.node.name == 'import_wait':
    + debugStmt = False
    + if debugStmt:
    + st = self.get_line_trace(node)
    + print >>self.output, "sys.addstack('%s');\n" % st
    + if isinstance(node.expr.node, ast.Name) and node.expr.node.name == NATIVE_JS_FUNC_NAME:
    + if len(node.expr.args) != 1:
    + raise TranslationError("native javascript function %s must have one arg" % NATIVE_JS_FUNC_NAME, node.expr)
    + if not isinstance(node.expr.args[0], ast.Const):
    + raise TranslationError("native javascript function %s must have constant arg" % NATIVE_JS_FUNC_NAME, node.expr)
    + raw_js = node.expr.args[0].value
    + print >>self.output, raw_js
    + else:
    + expr = self._callfunc(node.expr, current_klass)
    + print >>self.output, " " + expr + ";"
    +
    + if debugStmt:
    + print >>self.output, "sys.popstack();\n"
    +
    + elif isinstance(node.expr, ast.Const):
    + if node.expr.value is not None: # Empty statements generate ignore None
    + print >>self.output, self._const(node.expr)
    + else:
    + raise TranslationError("unsupported type (in _discard)", node.expr)
    +
    +
    + def _if(self, node, current_klass):
    + for i in range(len(node.tests)):
    + test, consequence = node.tests[i]
    + if i == 0:
    + keyword = "if"
    + else:
    + keyword = "else if"
    +
    + self._if_test(keyword, test, consequence, current_klass)
    +
    + if node.else_:
    + keyword = "else"
    + test = None
    + consequence = node.else_
    +
    + self._if_test(keyword, test, consequence, current_klass)
    +
    +
    + def _if_test(self, keyword, test, consequence, current_klass):
    + if test:
    + expr = self.expr(test, current_klass)
    +
    + print >>self.output, " " + keyword + " (pyjslib.bool(" + expr + ")) {"
    + else:
    + print >>self.output, " " + keyword + " {"
    +
    + if isinstance(consequence, ast.Stmt):
    + for child in consequence.nodes:
    + self._stmt(child, current_klass)
    + else:
    + raise TranslationError("unsupported type (in _if_test)", consequence)
    +
    + print >>self.output, " }"
    +
    +
    + def _from(self, node):
    + for name in node.names:
    + # look up "hack" in AppTranslator as to how findFile gets here
    + module_name = node.modname + "." + name[0]
    + try:
    + ff = self.findFile(module_name + ".py")
    + except Exception:
    + ff = None
    + if ff:
    + self.add_imported_module(module_name)
    + else:
    + self.imported_classes[name[0]] = node.modname
    +
    +
    + def _compare(self, node, current_klass):
    + lhs = self.expr(node.expr, current_klass)
    +
    + if len(node.ops) != 1:
    + raise TranslationError("only one ops supported (in _compare)", node)
    +
    + op = node.ops[0][0]
    + rhs_node = node.ops[0][1]
    + rhs = self.expr(rhs_node, current_klass)
    +
    + if op == "==":
    + return "pyjslib.eq(%s, %s)" % (lhs, rhs)
    + if op == "in":
    + return rhs + ".__contains__(" + lhs + ")"
    + elif op == "not in":
    + return "!" + rhs + ".__contains__(" + lhs + ")"
    + elif op == "is":
    + op = "==="
    + elif op == "is not":
    + op = "!=="
    +
    + return "(" + lhs + " " + op + " " + rhs + ")"
    +
    +
    + def _not(self, node, current_klass):
    + expr = self.expr(node.expr, current_klass)
    +
    + return "!(" + expr + ")"
    +
    + def _or(self, node, current_klass):
    + expr = "("+(") || (".join([self.expr(child, current_klass) for child in node.nodes]))+')'
    + return expr
    +
    + def _and(self, node, current_klass):
    + expr = "("+(") && (".join([self.expr(child, current_klass) for child in node.nodes]))+")"
    + return expr
    +
    + def _for(self, node, current_klass):
    + assign_name = ""
    + assign_tuple = ""
    +
    + # based on Bob Ippolito's Iteration in Javascript code
    + if isinstance(node.assign, ast.AssName):
    + assign_name = node.assign.name
    + self.add_local_arg(assign_name)
    + if node.assign.flags == "OP_ASSIGN":
    + op = "="
    + elif isinstance(node.assign, ast.AssTuple):
    + op = "="
    + i = 0
    + for child in node.assign:
    + child_name = child.name
    + if assign_name == "":
    + assign_name = "temp_" + child_name
    + self.add_local_arg(child_name)
    + assign_tuple += """
    + var %(child_name)s %(op)s %(assign_name)s.__getitem__(%(i)i);
    + """ % locals()
    + i += 1
    + else:
    + raise TranslationError("unsupported type (in _for)", node.assign)
    +
    + if isinstance(node.list, ast.Name):
    + list_expr = self._name(node.list, current_klass)
    + elif isinstance(node.list, ast.Getattr):
    + list_expr = self._getattr(node.list, current_klass)
    + elif isinstance(node.list, ast.CallFunc):
    + list_expr = self._callfunc(node.list, current_klass)
    + else:
    + raise TranslationError("unsupported type (in _for)", node.list)
    +
    + lhs = "var " + assign_name
    + iterator_name = "__" + assign_name
    +
    + print >>self.output, """
    + var %(iterator_name)s = %(list_expr)s.__iter__();
    + try {
    + while (true) {
    + %(lhs)s %(op)s %(iterator_name)s.next();
    + %(assign_tuple)s
    + """ % locals()
    + for node in node.body.nodes:
    + self._stmt(node, current_klass)
    + print >>self.output, """
    + }
    + } catch (e) {
    + if (e.__name__ != pyjslib.StopIteration.__name__) {
    + throw e;
    + }
    + }
    + """ % locals()
    +
    +
    + def _while(self, node, current_klass):
    + test = self.expr(node.test, current_klass)
    + print >>self.output, " while (pyjslib.bool(" + test + ")) {"
    + if isinstance(node.body, ast.Stmt):
    + for child in node.body.nodes:
    + self._stmt(child, current_klass)
    + else:
    + raise TranslationError("unsupported type (in _while)", node.body)
    + print >>self.output, " }"
    +
    +
    + def _const(self, node):
    + if isinstance(node.value, int):
    + return str(node.value)
    + elif isinstance(node.value, float):
    + return str(node.value)
    + elif isinstance(node.value, basestring):
    + v = node.value
    + if isinstance(node.value, unicode):
    + v = v.encode('utf-8')
    + return "String('%s')" % escapejs(v)
    + elif node.value is None:
    + return "null"
    + else:
    + raise TranslationError("unsupported type (in _const)", node)
    +
    + def _unaryadd(self, node, current_klass):
    + return self.expr(node.expr, current_klass)
    +
    + def _unarysub(self, node, current_klass):
    + return "-" + self.expr(node.expr, current_klass)
    +
    + def _add(self, node, current_klass):
    + return self.expr(node.left, current_klass) + " + " + self.expr(node.right, current_klass)
    +
    + def _sub(self, node, current_klass):
    + return self.expr(node.left, current_klass) + " - " + self.expr(node.right, current_klass)
    +
    + def _div(self, node, current_klass):
    + return self.expr(node.left, current_klass) + " / " + self.expr(node.right, current_klass)
    +
    + def _mul(self, node, current_klass):
    + return self.expr(node.left, current_klass) + " * " + self.expr(node.right, current_klass)
    +
    + def _mod(self, node, current_klass):
    + if isinstance(node.left, ast.Const) and isinstance(node.left.value, StringType):
    + self.imported_js.add("sprintf.js") # Include the sprintf functionality if it is used
    + return "sprintf("+self.expr(node.left, current_klass) + ", " + self.expr(node.right, current_klass)+")"
    + return self.expr(node.left, current_klass) + " % " + self.expr(node.right, current_klass)
    +
    + def _invert(self, node, current_klass):
    + return "~" + self.expr(node.expr, current_klass)
    +
    + def _bitand(self, node, current_klass):
    + return " & ".join([self.expr(child, current_klass) for child in node.nodes])
    +
    + def _bitshiftleft(self, node, current_klass):
    + return self.expr(node.left, current_klass) + " << " + self.expr(node.right, current_klass)
    +
    + def _bitshiftright(self, node, current_klass):
    + return self.expr(node.left, current_klass) + " >>> " + self.expr(node.right, current_klass)
    +
    + def _bitxor(self,node, current_klass):
    + return " ^ ".join([self.expr(child, current_klass) for child in node.nodes])
    +
    + def _bitor(self, node, current_klass):
    + return " | ".join([self.expr(child, current_klass) for child in node.nodes])
    +
    + def _subscript(self, node, current_klass):
    + if node.flags == "OP_APPLY":
    + if len(node.subs) == 1:
    + return self.expr(node.expr, current_klass) + ".__getitem__(" + self.expr(node.subs[0], current_klass) + ")"
    + else:
    + raise TranslationError("must have one sub (in _subscript)", node)
    + else:
    + raise TranslationError("unsupported flag (in _subscript)", node)
    +
    + def _subscript_stmt(self, node, current_klass):
    + if node.flags == "OP_DELETE":
    + print >>self.output, " " + self.expr(node.expr, current_klass) + ".__delitem__(" + self.expr(node.subs[0], current_klass) + ");"
    + else:
    + raise TranslationError("unsupported flag (in _subscript)", node)
    +
    + def _list(self, node, current_klass):
    + return "new pyjslib.List([" + ", ".join([self.expr(x, current_klass) for x in node.nodes]) + "])"
    +
    + def _dict(self, node, current_klass):
    + items = []
    + for x in node.items:
    + key = self.expr(x[0], current_klass)
    + value = self.expr(x[1], current_klass)
    + items.append("[" + key + ", " + value + "]")
    + return "new pyjslib.Dict([" + ", ".join(items) + "])"
    +
    + def _tuple(self, node, current_klass):
    + return "new pyjslib.Tuple([" + ", ".join([self.expr(x, current_klass) for x in node.nodes]) + "])"
    +
    + def _lambda(self, node, current_klass):
    + if node.varargs:
    + raise TranslationError("varargs are not supported in Lambdas", node)
    + if node.kwargs:
    + raise TranslationError("kwargs are not supported in Lambdas", node)
    + res = cStringIO.StringIO()
    + arg_names = list(node.argnames)
    + function_args = ", ".join(arg_names)
    + for child in node.getChildNodes():
    + expr = self.expr(child, None)
    + print >> res, "function (%s){" % function_args
    + self._default_args_handler(node, arg_names, None,
    + output=res)
    + print >> res, 'return %s;}' % expr
    + return res.getvalue()
    +
    + def _slice(self, node, current_klass):
    + if node.flags == "OP_APPLY":
    + lower = "null"
    + upper = "null"
    + if node.lower != None:
    + lower = self.expr(node.lower, current_klass)
    + if node.upper != None:
    + upper = self.expr(node.upper, current_klass)
    + return "pyjslib.slice(" + self.expr(node.expr, current_klass) + ", " + lower + ", " + upper + ")"
    + else:
    + raise TranslationError("unsupported flag (in _slice)", node)
    +
    + def _global(self, node, current_klass):
    + for name in node.names:
    + self.method_imported_globals.add(name)
    +
    + def expr(self, node, current_klass):
    + if isinstance(node, ast.Const):
    + return self._const(node)
    + # @@@ not sure if the parentheses should be here or in individual operator functions - JKT
    + elif isinstance(node, ast.Mul):
    + return " ( " + self._mul(node, current_klass) + " ) "
    + elif isinstance(node, ast.Add):
    + return " ( " + self._add(node, current_klass) + " ) "
    + elif isinstance(node, ast.Sub):
    + return " ( " + self._sub(node, current_klass) + " ) "
    + elif isinstance(node, ast.Div):
    + return " ( " + self._div(node, current_klass) + " ) "
    + elif isinstance(node, ast.Mod):
    + return self._mod(node, current_klass)
    + elif isinstance(node, ast.UnaryAdd):
    + return self._unaryadd(node, current_klass)
    + elif isinstance(node, ast.UnarySub):
    + return self._unarysub(node, current_klass)
    + elif isinstance(node, ast.Not):
    + return self._not(node, current_klass)
    + elif isinstance(node, ast.Or):
    + return self._or(node, current_klass)
    + elif isinstance(node, ast.And):
    + return self._and(node, current_klass)
    + elif isinstance(node, ast.Invert):
    + return self._invert(node, current_klass)
    + elif isinstance(node, ast.Bitand):
    + return "("+self._bitand(node, current_klass)+")"
    + elif isinstance(node,ast.LeftShift):
    + return self._bitshiftleft(node, current_klass)
    + elif isinstance(node, ast.RightShift):
    + return self._bitshiftright(node, current_klass)
    + elif isinstance(node, ast.Bitxor):
    + return "("+self._bitxor(node, current_klass)+")"
    + elif isinstance(node, ast.Bitor):
    + return "("+self._bitor(node, current_klass)+")"
    + elif isinstance(node, ast.Compare):
    + return self._compare(node, current_klass)
    + elif isinstance(node, ast.CallFunc):
    + return self._callfunc(node, current_klass)
    + elif isinstance(node, ast.Name):
    + return self._name(node, current_klass)
    + elif isinstance(node, ast.Subscript):
    + return self._subscript(node, current_klass)
    + elif isinstance(node, ast.Getattr):
    + return self._getattr(node, current_klass)
    + elif isinstance(node, ast.List):
    + return self._list(node, current_klass)
    + elif isinstance(node, ast.Dict):
    + return self._dict(node, current_klass)
    + elif isinstance(node, ast.Tuple):
    + return self._tuple(node, current_klass)
    + elif isinstance(node, ast.Slice):
    + return self._slice(node, current_klass)
    + elif isinstance(node, ast.Lambda):
    + return self._lambda(node, current_klass)
    + else:
    + raise TranslationError("unsupported type (in expr)", node)
    +
    +
    +
    +import cStringIO
    +
    +def translate(file_name, module_name, debug=False):
    + f = file(file_name, "r")
    + src = f.read()
    + f.close()
    + output = cStringIO.StringIO()
    + mod = compiler.parseFile(file_name)
    + t = Translator(module_name, module_name, module_name, src, debug, mod, output)
    + return output.getvalue()
    +
    +
    +class PlatformParser:
    + def __init__(self, platform_dir = "", verbose=True):
    + self.platform_dir = platform_dir
    + self.parse_cache = {}
    + self.platform = ""
    + self.verbose = verbose
    +
    + def setPlatform(self, platform):
    + self.platform = platform
    +
    + def parseModule(self, module_name, file_name):
    +
    + importing = False
    + if not self.parse_cache.has_key(file_name):
    + importing = True
    + mod = compiler.parseFile(file_name)
    + self.parse_cache[file_name] = mod
    + else:
    + mod = self.parse_cache[file_name]
    +
    + override = False
    + platform_file_name = self.generatePlatformFilename(file_name)
    + if self.platform and os.path.isfile(platform_file_name):
    + mod = copy.deepcopy(mod)
    + mod_override = compiler.parseFile(platform_file_name)
    + self.merge(mod, mod_override)
    + override = True
    +
    + if self.verbose:
    + if override:
    + print "Importing %s (Platform %s)" % (module_name, self.platform)
    + elif importing:
    + print "Importing %s" % (module_name)
    +
    + return mod, override
    +
    + def generatePlatformFilename(self, file_name):
    + (module_name, extension) = os.path.splitext(os.path.basename(file_name))
    + platform_file_name = module_name + self.platform + extension
    +
    + return os.path.join(os.path.dirname(file_name), self.platform_dir, platform_file_name)
    +
    + def merge(self, tree1, tree2):
    + for child in tree2.node:
    + if isinstance(child, ast.Function):
    + self.replaceFunction(tree1, child.name, child)
    + elif isinstance(child, ast.Class):
    + self.replaceClassMethods(tree1, child.name, child)
    +
    + return tree1
    +
    + def replaceFunction(self, tree, function_name, function_node):
    + # find function to replace
    + for child in tree.node:
    + if isinstance(child, ast.Function) and child.name == function_name:
    + self.copyFunction(child, function_node)
    + return
    + raise TranslationError("function not found: " + function_name, function_node)
    +
    + def replaceClassMethods(self, tree, class_name, class_node):
    + # find class to replace
    + old_class_node = None
    + for child in tree.node:
    + if isinstance(child, ast.Class) and child.name == class_name:
    + old_class_node = child
    + break
    +
    + if not old_class_node:
    + raise TranslationError("class not found: " + class_name, class_node)
    +
    + # replace methods
    + for function_node in class_node.code:
    + if isinstance(function_node, ast.Function):
    + found = False
    + for child in old_class_node.code:
    + if isinstance(child, ast.Function) and child.name == function_node.name:
    + found = True
    + self.copyFunction(child, function_node)
    + break
    +
    + if not found:
    + raise TranslationError("class method not found: " + class_name + "." + function_node.name, function_node)
    +
    + def copyFunction(self, target, source):
    + target.code = source.code
    + target.argnames = source.argnames
    + target.defaults = source.defaults
    + target.doc = source.doc # @@@ not sure we need to do this any more
    +
    +def dotreplace(fname):
    + path, ext = os.path.splitext(fname)
    + return path.replace(".", "/") + ext
    +
    +class AppTranslator:
    +
    + def __init__(self, library_dirs=[], parser=None, dynamic=False,
    + optimize=False, verbose=True):
    + self.extension = ".py"
    + self.optimize = optimize
    + self.library_modules = []
    + self.overrides = {}
    + self.library_dirs = path + library_dirs
    + self.dynamic = dynamic
    + self.verbose = verbose
    +
    + if not parser:
    + self.parser = PlatformParser()
    + else:
    + self.parser = parser
    +
    + self.parser.dynamic = dynamic
    +
    + def findFile(self, file_name):
    + if os.path.isfile(file_name):
    + return file_name
    +
    + for library_dir in self.library_dirs:
    + file_name = dotreplace(file_name)
    + full_file_name = os.path.join(
    + os.path.abspath(os.path.dirname(__file__)), library_dir, file_name)
    + if os.path.isfile(full_file_name):
    + return full_file_name
    +
    + fnameinit, ext = os.path.splitext(file_name)
    + fnameinit = fnameinit + "/__init__.py"
    +
    + full_file_name = os.path.join(
    + os.path.abspath(os.path.dirname(__file__)), library_dir, fnameinit)
    + if os.path.isfile(full_file_name):
    + return full_file_name
    +
    + raise Exception("file not found: " + file_name)
    +
    + def _translate(self, module_name, is_app=True, debug=False,
    + imported_js=set()):
    + if module_name not in self.library_modules:
    + self.library_modules.append(module_name)
    +
    + file_name = self.findFile(module_name + self.extension)
    +
    + output = cStringIO.StringIO()
    +
    + f = file(file_name, "r")
    + src = f.read()
    + f.close()
    +
    + mod, override = self.parser.parseModule(module_name, file_name)
    + if override:
    + override_name = "%s.%s" % (self.parser.platform.lower(),
    + module_name)
    + self.overrides[override_name] = override_name
    + if is_app:
    + mn = '__main__'
    + else:
    + mn = module_name
    + t = Translator(mn, module_name, module_name,
    + src, debug, mod, output, self.dynamic, self.optimize,
    + self.findFile)
    +
    + module_str = output.getvalue()
    + imported_js.update(set(t.imported_js))
    + imported_modules_str = ""
    + for module in t.imported_modules:
    + if module not in self.library_modules:
    + self.library_modules.append(module)
    + #imported_js.update(set(t.imported_js))
    + #imported_modules_str += self._translate(
    + # module, False, debug=debug, imported_js=imported_js)
    +
    + return imported_modules_str + module_str
    +
    +
    + def translate(self, module_name, is_app=True, debug=False,
    + library_modules=[]):
    + app_code = cStringIO.StringIO()
    + lib_code = cStringIO.StringIO()
    + imported_js = set()
    + self.library_modules = []
    + self.overrides = {}
    + for library in library_modules:
    + if library.endswith(".js"):
    + imported_js.add(library)
    + continue
    + self.library_modules.append(library)
    + if self.verbose:
    + print 'Including LIB', library
    + print >> lib_code, '\n//\n// BEGIN LIB '+library+'\n//\n'
    + print >> lib_code, self._translate(
    + library, False, debug=debug, imported_js=imported_js)
    +
    + print >> lib_code, "/* initialize static library */"
    + print >> lib_code, "%s%s();\n" % (UU, library)
    +
    + print >> lib_code, '\n//\n// END LIB '+library+'\n//\n'
    + if module_name:
    + print >> app_code, self._translate(
    + module_name, is_app, debug=debug, imported_js=imported_js)
    + for js in imported_js:
    + path = self.findFile(js)
    + if os.path.isfile(path):
    + if self.verbose:
    + print 'Including JS', js
    + print >> lib_code, '\n//\n// BEGIN JS '+js+'\n//\n'
    + print >> lib_code, file(path).read()
    + print >> lib_code, '\n//\n// END JS '+js+'\n//\n'
    + else:
    + print >>sys.stderr, 'Warning: Unable to find imported javascript:', js
    + return lib_code.getvalue(), app_code.getvalue()
    +
    +usage = """
    + usage: %s file_name [module_name]
    +"""
    +
    +def main():
    + import sys
    + if len(sys.argv)<2:
    + print >> sys.stderr, usage % sys.argv[0]
    + sys.exit(1)
    + file_name = os.path.abspath(sys.argv[1])
    + if not os.path.isfile(file_name):
    + print >> sys.stderr, "File not found %s" % file_name
    + sys.exit(1)
    + if len(sys.argv) > 2:
    + module_name = sys.argv[2]
    + else:
    + module_name = None
    + print translate(file_name, module_name),
    +
    +if __name__ == "__main__":
    + main()
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/svgui/svgui.py Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,116 @@
    +import wx
    +import os, sys, shutil
    +
    +from pyjs import translate
    +
    +from POULibrary import POULibrary
    +from docutils import *
    +
    +class SVGUILibrary(POULibrary):
    + def GetName(self):
    + return "SVGUI"
    + def GetLibraryPath(self):
    + return os.path.join(os.path.split(__file__)[0], "pous.xml")
    +
    +class SVGUI:
    +
    + ConfNodeMethods = [
    + {"bitmap" : os.path.join("images","ImportSVG"),
    + "name" : _("Import SVG"),
    + "tooltip" : _("Import SVG"),
    + "method" : "_ImportSVG"},
    + {"bitmap" : os.path.join("images","ImportSVG"),
    + "name" : _("Inkscape"),
    + "tooltip" : _("Create HMI"),
    + "method" : "_StartInkscape"},
    + ]
    +
    + def ConfNodePath(self):
    + return os.path.join(os.path.dirname(__file__))
    +
    + def _getSVGpath(self):
    + # define name for IEC raw code file
    + return os.path.join(self.CTNPath(), "gui.svg")
    +
    + def _getSVGUIserverpath(self):
    + return os.path.join(os.path.dirname(__file__), "svgui_server.py")
    +
    + def CTNGenerate_C(self, buildpath, locations):
    + """
    + Return C code generated by iec2c compiler
    + when _generate_softPLC have been called
    + @param locations: ignored
    + @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
    + """
    +
    + current_location = self.GetCurrentLocation()
    + # define a unique name for the generated C file
    + location_str = "_".join(map(lambda x:str(x), current_location))
    +
    + res = ([], "", False)
    +
    + svgfile=self._getSVGpath()
    + if os.path.exists(svgfile):
    + res += (("gui.svg", file(svgfile,"rb")),)
    +
    + svguiserverfile = open(self._getSVGUIserverpath(), 'r')
    + svguiservercode = svguiserverfile.read()
    + svguiserverfile.close()
    +
    + svguilibpath = os.path.join(self._getBuildPath(), "svguilib.js")
    + svguilibfile = open(svguilibpath, 'w')
    + svguilibfile.write(translate(os.path.join(os.path.dirname(__file__), "pyjs", "lib", "sys.py"), "sys"))
    + svguilibfile.write(open(os.path.join(os.path.dirname(__file__), "pyjs", "lib", "_pyjs.js"), 'r').read())
    + svguilibfile.write(translate(os.path.join(os.path.dirname(__file__), "pyjs", "lib", "pyjslib.py"), "pyjslib"))
    + svguilibfile.write(translate(os.path.join(os.path.dirname(__file__), "svguilib.py"), "svguilib"))
    + svguilibfile.write("pyjslib();\nsvguilib();\n")
    + svguilibfile.write(open(os.path.join(os.path.dirname(__file__), "pyjs", "lib", "json.js"), 'r').read())
    + svguilibfile.write(open(os.path.join(os.path.dirname(__file__), "livesvg.js"), 'r').read())
    + svguilibfile.close()
    + jsmodules = {"LiveSVGPage": "svguilib.js"}
    + res += (("svguilib.js", file(svguilibpath,"rb")),)
    +
    + runtimefile_path = os.path.join(buildpath, "runtime_%s.py"%location_str)
    + runtimefile = open(runtimefile_path, 'w')
    + runtimefile.write(svguiservercode % {"svgfile" : "gui.svg"})
    + runtimefile.write("""
    +def _runtime_%(location)s_begin():
    + website.LoadHMI(%(svgui_class)s, %(jsmodules)s)
    +
    +def _runtime_%(location)s_cleanup():
    + website.UnLoadHMI()
    +
    +""" % {"location": location_str,
    + "svgui_class": "SVGUI_HMI",
    + "jsmodules" : str(jsmodules),
    + })
    + runtimefile.close()
    +
    + res += (("runtime_%s.py"%location_str, file(runtimefile_path,"rb")),)
    +
    + return res
    +
    + def _ImportSVG(self):
    + dialog = wx.FileDialog(self.GetCTRoot().AppFrame, _("Choose a SVG file"), os.getcwd(), "", _("SVG files (*.svg)|*.svg|All files|*.*"), wx.OPEN)
    + if dialog.ShowModal() == wx.ID_OK:
    + svgpath = dialog.GetPath()
    + if os.path.isfile(svgpath):
    + shutil.copy(svgpath, self._getSVGpath())
    + else:
    + self.GetCTRoot().logger.write_error(_("No such SVG file: %s\n")%svgpath)
    + dialog.Destroy()
    +
    + def _StartInkscape(self):
    + svgfile = self._getSVGpath()
    + open_inkscape = True
    + if not self.GetCTRoot().CheckProjectPathPerm():
    + dialog = wx.MessageDialog(self.GetCTRoot().AppFrame,
    + _("You don't have write permissions.\nOpen Inkscape anyway ?"),
    + _("Open Inkscape"),
    + wx.YES_NO|wx.ICON_QUESTION)
    + open_inkscape = dialog.ShowModal() == wx.ID_YES
    + dialog.Destroy()
    + if open_inkscape:
    + if not os.path.isfile(svgfile):
    + svgfile = None
    + open_svg(svgfile)
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/svgui/svgui_server.py Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,130 @@
    +#!/usr/bin/python
    +# -*- coding: utf-8 -*-
    +
    +import os
    +
    +from nevow import rend, appserver, inevow, tags, loaders, athena
    +import simplejson as json
    +
    +svgfile = '%(svgfile)s'
    +
    +svguiWidgets = {}
    +
    +currentId = 0
    +def getNewId():
    + global currentId
    + currentId += 1
    + return currentId
    +
    +class SvguiWidget:
    +
    + def __init__(self, classname, id, **kwargs):
    + self.classname = classname
    + self.id = id
    + self.attrs = kwargs.copy()
    + self.inputs = {}
    + self.outputs = {}
    + self.inhibit = False
    + self.changed = False
    +
    + def setinput(self, attrname, value):
    + self.inputs[attrname] = value
    +
    + def getinput(self, attrname, default=None):
    + if not self.inputs.has_key(attrname):
    + self.inputs[attrname] = default
    + return self.inputs[attrname]
    +
    + def setoutput(self, attrname, value):
    + if self.outputs.get(attrname) != value:
    + self.outputs[attrname] = value
    + self.changed = True
    + self.RefreshInterface()
    +
    + def updateoutputs(self, **kwargs):
    + for attrname, value in kwargs.iteritems():
    + if self.outputs.get(attrname) != value:
    + self.outputs[attrname] = value
    + self.changed = True
    + self.RefreshInterface()
    +
    + def RefreshInterface(self):
    + interface = website.getHMI()
    + if isinstance(interface, SVGUI_HMI) and self.changed and not self.inhibit:
    + self.changed = False
    + d = interface.sendData(self)
    + if d is not None:
    + self.inhibit = True
    + d.addCallback(self.InterfaceRefreshed)
    +
    + def InterfaceRefreshed(self, result):
    + self.inhibit = False
    + if self.changed:
    + self.RefreshInterface()
    +
    +def get_object_init_state(obj):
    + # Convert objects to a dictionary of their representation
    + attrs = obj.attrs.copy()
    + attrs.update(obj.inputs)
    + d = { '__class__': obj.classname,
    + 'id': obj.id,
    + 'kwargs': json.dumps(attrs),
    + }
    + return d
    +
    +def get_object_current_state(obj):
    + # Convert objects to a dictionary of their representation
    + d = { '__class__': obj.classname,
    + 'id': obj.id,
    + 'kwargs': json.dumps(obj.outputs),
    + }
    + return d
    +
    +class SVGUI_HMI(website.PLCHMI):
    + jsClass = u"LiveSVGPage.LiveSVGWidget"
    +
    + docFactory = loaders.stan(tags.div(render=tags.directive('liveElement'))[
    + tags.xml(loaders.xmlfile(os.path.join(WorkingDir, svgfile))),
    + ])
    +
    + def HMIinitialisation(self):
    + gadgets = []
    + for gadget in svguiWidgets.values():
    + gadgets.append(unicode(json.dumps(gadget, default=get_object_init_state, indent=2), 'ascii'))
    + d = self.callRemote('init', gadgets)
    + d.addCallback(self.HMIinitialised)
    +
    + def sendData(self,data):
    + if self.initialised:
    + return self.callRemote('receiveData',unicode(json.dumps(data, default=get_object_current_state, indent=2), 'ascii'))
    + return None
    +
    + def setattr(self, id, attrname, value):
    + svguiWidgets[id].setinput(attrname, value)
    +
    +def createSVGUIControl(*args, **kwargs):
    + id = getNewId()
    + gad = SvguiWidget(args[0], id, **kwargs)
    + svguiWidgets[id] = gad
    + gadget = [unicode(json.dumps(gad, default=get_object_init_state, indent=2), 'ascii')]
    + interface = website.getHMI()
    + if isinstance(interface, SVGUI_HMI) and interface.initialised:
    + interface.callRemote('init', gadget)
    + return id
    +
    +def setAttr(id, attrname, value):
    + gad = svguiWidgets.get(id, None)
    + if gad is not None:
    + gad.setoutput(attrname, value)
    +
    +def updateAttr(id, **kwargs):
    + gad = svguiWidgets.get(id, None)
    + if gad is not None:
    + gad.updateoutput(**kwargs)
    +
    +def getAttr(id, attrname, default=None):
    + gad = svguiWidgets.get(id, None)
    + if gad is not None:
    + return gad.getinput(attrname, default)
    + return default
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/svgui/svguilib.py Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,117 @@
    +
    +class button:
    +
    + def __init__(self, parent, id, args):
    + self.parent = parent
    + self.id = id
    + self.back_elt = getSVGElementById(args.back_id)
    + self.sele_elt = getSVGElementById(args.sele_id)
    + self.toggle = args.toggle
    + self.active = args.active
    + if args.state != undefined:
    + self.state = args.state
    + else:
    + self.state = False
    + self.dragging = False
    + if self.toggle:
    + self.up = not self.state
    + else:
    + self.up = True
    +
    + # Add event on each element of the button
    + if self.active:
    + self.back_elt.addEventListener("mouseup", self, False)
    + self.back_elt.addEventListener("mousedown", self, False)
    + self.back_elt.addEventListener("mouseover", self, False)
    + self.back_elt.addEventListener("mouseout", self, False)
    +
    + self.sele_elt.addEventListener("mouseup", self, False)
    + self.sele_elt.addEventListener("mousedown", self, False)
    + self.sele_elt.addEventListener("mouseover", self, False)
    + self.sele_elt.addEventListener("mouseout", self, False)
    +
    + blockSVGElementDrag(self.back_elt)
    + blockSVGElementDrag(self.sele_elt)
    +
    + self.updateElements()
    +
    + # method to display the current state of interface
    + def updateElements(self):
    + if self.up:
    + self.sele_elt.setAttribute("display", "none")
    + self.back_elt.removeAttribute("display")
    + else:
    + self.sele_elt.removeAttribute("display")
    + self.back_elt.setAttribute("display", "none")
    +
    + def updateValues(self, values):
    + if values.state != self.state:
    + self.state = values.state
    + self.up = not self.state
    + updateAttr(self.id, 'state', self.state)
    + self.updateElements()
    +
    + def handleEvent(self, evt):
    + # Quand le bouton de la souris est presse
    + if evt.type == "mousedown":
    + evt.stopPropagation()
    + setCurrentObject(self)
    +
    + self.dragging = True
    +
    + if self.toggle:
    + self.up = self.state
    + else:
    + self.up = False
    + self.state = True
    + updateAttr(self.id, 'state', self.state)
    + self.updateElements()
    +
    + if isCurrentObject(self) and self.dragging:
    + # Quand le bouton est survole
    + if evt.type == "mouseover" and self.toggle:
    + self.up = self.state
    + self.updateElements()
    +
    + # Quand le curseur quitte la zone du bouton
    + elif evt.type == "mouseout" and self.toggle:
    + self.up = not self.state
    + self.updateElements()
    +
    + # Quand le bouton de la souris est relache
    + elif evt.type == "mouseup":
    + evt.stopPropagation()
    + if self.toggle and self.up == self.state:
    + self.state = not self.state
    + updateAttr(self.id, 'state', self.state)
    + elif not self.toggle:
    + self.up = True
    + self.state = False
    + updateAttr(self.id, 'state', self.state)
    + self.updateElements()
    + self.dragging = False
    +
    +class textControl:
    +
    + def __init__(self, parent, id, args):
    + self.parent = parent
    + self.id = id
    + self.back_elt = getSVGElementById(args.back_id)
    + if args.text != undefined:
    + self.text = args.text
    + else:
    + self.text = ""
    + self.updateElements()
    +
    + def updateValues(self, values):
    + if values.text != self.value:
    + self.text = values.text
    + updateAttr(self.id, 'text', self.text)
    + self.updateElements()
    +
    + def updateElements(self):
    + self.back_elt.firstChild.firstChild.textContent = self.text
    +
    + def handleEvent(self, evt):
    + pass
    +
    \ No newline at end of file
    --- a/targets/toolchain_gcc.py Wed May 09 00:39:54 2012 +0200
    +++ b/targets/toolchain_gcc.py Sat May 12 11:21:10 2012 +0200
    @@ -100,10 +100,11 @@
    objs = []
    relink = False
    for Location, CFilesAndCFLAGS, DoCalls in self.CTRInstance.LocationCFilesAndCFLAGS:
    - if Location:
    - self.CTRInstance.logger.write(_("ConfNode : ") + self.CTRInstance.GetChildByIECLocation(Location).GetCurrentName() + " " + str(Location)+"\n")
    - else:
    - self.CTRInstance.logger.write(_("PLC :\n"))
    + if CFilesAndCFLAGS:
    + if Location :
    + self.CTRInstance.logger.write(".".join(map(str,Location))+" :\n")
    + else:
    + self.CTRInstance.logger.write(_("PLC :\n"))
    for CFile, CFLAGS in CFilesAndCFLAGS:
    if CFile.endswith(".c"):
    --- a/tests/python/beremiz.xml Wed May 09 00:39:54 2012 +0200
    +++ b/tests/python/beremiz.xml Sat May 12 11:21:10 2012 +0200
    @@ -1,4 +1,4 @@
    -<?xml version="1.0" encoding="UTF-8"?>
    -<BeremizRoot URI_location="LOCAL://">
    - <TargetType/>
    -</BeremizRoot>
    +<?xml version="1.0" encoding="UTF-8"?>
    +<BeremizRoot URI_location="LOCAL://" Enable_SVGUILibrary="false">
    + <TargetType/>
    +</BeremizRoot>
    --- a/tests/python/plc.xml Wed May 09 00:39:54 2012 +0200
    +++ b/tests/python/plc.xml Sat May 12 11:21:10 2012 +0200
    @@ -8,7 +8,7 @@
    productVersion="0.0"
    creationDateTime="2008-12-14T16:21:19"/>
    <contentHeader name="Beremiz Python Support Tests"
    - modificationDateTime="2009-12-06T12:55:54">
    + modificationDateTime="2012-05-12T10:42:17">
    <coordinateInfo>
    <pageSize x="1024" y="1024"/>
    <fbd>
    --- a/tests/python/python@py_ext/py_ext.xml Wed May 09 00:39:54 2012 +0200
    +++ b/tests/python/python@py_ext/py_ext.xml Sat May 12 11:21:10 2012 +0200
    @@ -1,5 +1,5 @@
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    -<Python xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="python_xsd.xsd">
    +<Python xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="py_ext_xsd.xsd">
    <![CDATA[import time,sys
    def myprintfunc(arg):
    print arg
    --- a/tests/svgui/python@py_ext/baseconfnode.xml Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,2 +0,0 @@
    -<?xml version="1.0" encoding="UTF-8"?>
    -<BaseParams Name="python" IEC_Channel="0"/>
    --- a/tests/svgui/python@py_ext/py_ext.xml Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,8 +0,0 @@
    -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    -<Python xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="python_xsd.xsd">
    -<![CDATA[import time,sys
    -def myprintfunc(arg):
    - print arg
    - sys.stdout.flush()
    - return arg]]>
    -</Python>
    --- a/tests/svgui/python@py_ext/svgui@svgui/baseconfnode.xml Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,2 +0,0 @@
    -<?xml version="1.0" encoding="UTF-8"?>
    -<BaseParams Name="svgui" IEC_Channel="0"/>
    --- a/tests/svgui/python@py_ext/svgui@svgui/gui.svg Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,723 +0,0 @@
    -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    -<!-- Created with Inkscape (http://www.inkscape.org/) -->
    -
    -<svg
    - xmlns:dc="http://purl.org/dc/elements/1.1/"
    - xmlns:cc="http://creativecommons.org/ns#"
    - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    - xmlns:svg="http://www.w3.org/2000/svg"
    - xmlns="http://www.w3.org/2000/svg"
    - xmlns:xlink="http://www.w3.org/1999/xlink"
    - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
    - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
    - width="320"
    - height="250"
    - id="svg2"
    - sodipodi:version="0.32"
    - inkscape:version="0.47pre4 "
    - version="1.0"
    - sodipodi:docname="gui.svg"
    - inkscape:output_extension="org.inkscape.output.svg.inkscape">
    - <sodipodi:namedview
    - id="base"
    - pagecolor="#ffffff"
    - bordercolor="#666666"
    - borderopacity="1.0"
    - inkscape:pageopacity="0.0"
    - inkscape:pageshadow="2"
    - inkscape:zoom="1.4"
    - inkscape:cx="200.66323"
    - inkscape:cy="178.08292"
    - inkscape:document-units="px"
    - inkscape:current-layer="layer1"
    - showgrid="false"
    - inkscape:window-width="1071"
    - inkscape:window-height="805"
    - inkscape:window-x="106"
    - inkscape:window-y="16"
    - inkscape:window-maximized="0" />
    - <defs
    - id="defs4">
    - <linearGradient
    - id="linearGradient3770">
    - <stop
    - style="stop-color:#008000;stop-opacity:1;"
    - offset="0"
    - id="stop3772" />
    - <stop
    - style="stop-color:#00fb00;stop-opacity:1;"
    - offset="1"
    - id="stop3774" />
    - </linearGradient>
    - <linearGradient
    - id="linearGradient3708">
    - <stop
    - style="stop-color:#d40000;stop-opacity:1;"
    - offset="0"
    - id="stop3710" />
    - <stop
    - style="stop-color:#ff5c5c;stop-opacity:1;"
    - offset="1"
    - id="stop3712" />
    - </linearGradient>
    - <linearGradient
    - id="linearGradient4202">
    - <stop
    - id="stop4204"
    - offset="0"
    - style="stop-color:#f6edda;stop-opacity:1;" />
    - <stop
    - id="stop4206"
    - offset="1"
    - style="stop-color:#e6e6e6;stop-opacity:1;" />
    - </linearGradient>
    - <linearGradient
    - id="linearGradient4192">
    - <stop
    - style="stop-color:#faf4e9;stop-opacity:1;"
    - offset="0"
    - id="stop4194" />
    - <stop
    - style="stop-color:#f1f1f1;stop-opacity:1;"
    - offset="1"
    - id="stop4196" />
    - </linearGradient>
    - <linearGradient
    - id="linearGradient3302">
    - <stop
    - style="stop-color:#ff0000;stop-opacity:0;"
    - offset="0"
    - id="stop3304" />
    - <stop
    - id="stop3310"
    - offset="0.43817073"
    - style="stop-color:#ff0000;stop-opacity:0.49803922;" />
    - <stop
    - style="stop-color:#ff0000;stop-opacity:1;"
    - offset="0.68879533"
    - id="stop3312" />
    - <stop
    - style="stop-color:#ff0000;stop-opacity:0;"
    - offset="1"
    - id="stop3306" />
    - </linearGradient>
    - <linearGradient
    - id="linearGradient3687">
    - <stop
    - id="stop3689"
    - offset="0"
    - style="stop-color:#23d5ff;stop-opacity:1;" />
    - <stop
    - id="stop3691"
    - offset="1"
    - style="stop-color:#b1ffff;stop-opacity:1;" />
    - </linearGradient>
    - <linearGradient
    - id="linearGradient3679">
    - <stop
    - id="stop3681"
    - offset="0"
    - style="stop-color:#00b5ff;stop-opacity:1;" />
    - <stop
    - id="stop3683"
    - offset="1"
    - style="stop-color:#005bff;stop-opacity:1;" />
    - </linearGradient>
    - <linearGradient
    - id="linearGradient3659">
    - <stop
    - id="stop3661"
    - offset="0"
    - style="stop-color:#ff0030;stop-opacity:1;" />
    - <stop
    - style="stop-color:#e20000;stop-opacity:0.83211678;"
    - offset="0.60000002"
    - id="stop3669" />
    - <stop
    - id="stop3663"
    - offset="1"
    - style="stop-color:#ffffff;stop-opacity:0;" />
    - </linearGradient>
    - <linearGradient
    - id="linearGradient3639">
    - <stop
    - id="stop3641"
    - offset="0"
    - style="stop-color:#ffff00;stop-opacity:1;" />
    - <stop
    - style="stop-color:#8fff00;stop-opacity:0.49803922;"
    - offset="0.80000001"
    - id="stop3647" />
    - <stop
    - id="stop3643"
    - offset="1"
    - style="stop-color:#ffffff;stop-opacity:0;" />
    - </linearGradient>
    - <linearGradient
    - id="linearGradient3621">
    - <stop
    - id="stop3623"
    - offset="0"
    - style="stop-color:#ff8080;stop-opacity:1;" />
    - <stop
    - id="stop3625"
    - offset="1"
    - style="stop-color:#aa0000;stop-opacity:1;" />
    - </linearGradient>
    - <linearGradient
    - id="linearGradient3613"
    - inkscape:collect="always">
    - <stop
    - id="stop3615"
    - offset="0"
    - style="stop-color:#000000;stop-opacity:1;" />
    - <stop
    - id="stop3617"
    - offset="1"
    - style="stop-color:#000000;stop-opacity:0;" />
    - </linearGradient>
    - <linearGradient
    - id="linearGradient3497">
    - <stop
    - id="stop3499"
    - offset="0"
    - style="stop-color:#00cd00;stop-opacity:1;" />
    - <stop
    - id="stop3501"
    - offset="1"
    - style="stop-color:#007900;stop-opacity:1;" />
    - </linearGradient>
    - <linearGradient
    - id="linearGradient3453">
    - <stop
    - id="stop3455"
    - offset="0"
    - style="stop-color:#000000;stop-opacity:1;" />
    - <stop
    - id="stop3457"
    - offset="1"
    - style="stop-color:#ffffff;stop-opacity:0;" />
    - </linearGradient>
    - <linearGradient
    - id="linearGradient3173">
    - <stop
    - style="stop-color:#ffffff;stop-opacity:1;"
    - offset="0"
    - id="stop3175" />
    - <stop
    - id="stop3181"
    - offset="0.5"
    - style="stop-color:#ffffff;stop-opacity:0;" />
    - <stop
    - style="stop-color:#ff0000;stop-opacity:0;"
    - offset="1"
    - id="stop3177" />
    - </linearGradient>
    - <inkscape:perspective
    - sodipodi:type="inkscape:persp3d"
    - inkscape:vp_x="0 : 526.18109 : 1"
    - inkscape:vp_y="0 : 1000 : 0"
    - inkscape:vp_z="744.09448 : 526.18109 : 1"
    - inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
    - id="perspective10" />
    - <inkscape:perspective
    - sodipodi:type="inkscape:persp3d"
    - inkscape:vp_x="0 : 526.18109 : 1"
    - inkscape:vp_y="0 : 1000 : 0"
    - inkscape:vp_z="744.09448 : 526.18109 : 1"
    - inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
    - id="perspective2619" />
    - <linearGradient
    - gradientUnits="userSpaceOnUse"
    - y2="76.489952"
    - x2="96.68087"
    - y1="43.13879"
    - x1="96.68087"
    - id="linearGradient3503"
    - xlink:href="#linearGradient3497"
    - inkscape:collect="always" />
    - <linearGradient
    - gradientUnits="userSpaceOnUse"
    - y2="57.028084"
    - x2="146.58875"
    - y1="57.028084"
    - x1="56.098511"
    - id="linearGradient3619"
    - xlink:href="#linearGradient3613"
    - inkscape:collect="always" />
    - <linearGradient
    - gradientUnits="userSpaceOnUse"
    - y2="81.670944"
    - x2="102.30303"
    - y1="40.599514"
    - x1="101.45565"
    - id="linearGradient3627"
    - xlink:href="#linearGradient3621"
    - inkscape:collect="always" />
    - <linearGradient
    - gradientTransform="translate(-18,26)"
    - y2="81.670944"
    - x2="102.30303"
    - y1="40.599514"
    - x1="101.45565"
    - gradientUnits="userSpaceOnUse"
    - id="linearGradient3633"
    - xlink:href="#linearGradient3621"
    - inkscape:collect="always" />
    - <radialGradient
    - r="17.67767"
    - fy="101.69787"
    - fx="352.03818"
    - cy="101.69787"
    - cx="352.03818"
    - gradientUnits="userSpaceOnUse"
    - id="radialGradient3667"
    - xlink:href="#linearGradient3639"
    - inkscape:collect="always" />
    - <radialGradient
    - r="17.67767"
    - fy="101.69787"
    - fx="352.03818"
    - cy="101.69787"
    - cx="352.03818"
    - gradientUnits="userSpaceOnUse"
    - id="radialGradient3675"
    - xlink:href="#linearGradient3659"
    - inkscape:collect="always" />
    - <linearGradient
    - gradientTransform="translate(-1.3119965,1.110878)"
    - gradientUnits="userSpaceOnUse"
    - y2="74.0345"
    - x2="222.50246"
    - y1="102.89583"
    - x1="223.57851"
    - id="linearGradient3693"
    - xlink:href="#linearGradient3687"
    - inkscape:collect="always" />
    - <linearGradient
    - y2="116.84509"
    - x2="312.63715"
    - y1="62.306999"
    - x1="277.45764"
    - gradientUnits="userSpaceOnUse"
    - id="linearGradient3702"
    - xlink:href="#linearGradient4202"
    - inkscape:collect="always" />
    - <linearGradient
    - y2="66.89164"
    - x2="223.21674"
    - y1="102.89583"
    - x1="223.57851"
    - gradientTransform="translate(-1.3119965,1.110878)"
    - gradientUnits="userSpaceOnUse"
    - id="linearGradient3704"
    - xlink:href="#linearGradient3613"
    - inkscape:collect="always" />
    - <inkscape:perspective
    - sodipodi:type="inkscape:persp3d"
    - inkscape:vp_x="0 : 526.18109 : 1"
    - inkscape:vp_y="0 : 1000 : 0"
    - inkscape:vp_z="744.09448 : 526.18109 : 1"
    - inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
    - id="perspective3767" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3302"
    - id="linearGradient3308"
    - x1="255.95412"
    - y1="328.07761"
    - x2="258.63916"
    - y2="328.07761"
    - gradientUnits="userSpaceOnUse"
    - gradientTransform="translate(-25.178571,-3.0357143)" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3613"
    - id="linearGradient3536"
    - gradientUnits="userSpaceOnUse"
    - gradientTransform="translate(5.555838,16.162441)"
    - x1="147.86807"
    - y1="287.98224"
    - x2="147.86807"
    - y2="341.01526" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3613"
    - id="linearGradient3538"
    - gradientUnits="userSpaceOnUse"
    - gradientTransform="translate(5.555838,16.162441)"
    - x1="147.86807"
    - y1="287.98224"
    - x2="147.86807"
    - y2="341.01526" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3613"
    - id="linearGradient3540"
    - gradientUnits="userSpaceOnUse"
    - gradientTransform="translate(5.555838,16.162441)"
    - x1="147.86807"
    - y1="287.98224"
    - x2="147.86807"
    - y2="341.01526" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3613"
    - id="linearGradient3542"
    - gradientUnits="userSpaceOnUse"
    - gradientTransform="translate(5.555838,16.162441)"
    - x1="147.86807"
    - y1="287.98224"
    - x2="147.86807"
    - y2="341.01526" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3613"
    - id="linearGradient3544"
    - gradientUnits="userSpaceOnUse"
    - gradientTransform="translate(5.555838,16.162441)"
    - x1="147.86807"
    - y1="287.98224"
    - x2="147.86807"
    - y2="341.01526" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3613"
    - id="linearGradient3546"
    - gradientUnits="userSpaceOnUse"
    - gradientTransform="translate(5.555838,16.162441)"
    - x1="147.86807"
    - y1="287.98224"
    - x2="147.86807"
    - y2="341.01526" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3613"
    - id="linearGradient3548"
    - gradientUnits="userSpaceOnUse"
    - gradientTransform="translate(5.555838,16.162441)"
    - x1="147.86807"
    - y1="287.98224"
    - x2="147.86807"
    - y2="341.01526" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3613"
    - id="linearGradient3550"
    - gradientUnits="userSpaceOnUse"
    - gradientTransform="translate(5.555838,16.162441)"
    - x1="147.86807"
    - y1="287.98224"
    - x2="147.86807"
    - y2="341.01526" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3613"
    - id="linearGradient3694"
    - gradientUnits="userSpaceOnUse"
    - gradientTransform="translate(-381.09403,-544.64978)"
    - x1="147.86807"
    - y1="287.98224"
    - x2="147.86807"
    - y2="341.01526" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3613"
    - id="linearGradient3696"
    - gradientUnits="userSpaceOnUse"
    - gradientTransform="translate(-381.09403,-544.64978)"
    - x1="147.86807"
    - y1="287.98224"
    - x2="147.86807"
    - y2="341.01526" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3613"
    - id="linearGradient3698"
    - gradientUnits="userSpaceOnUse"
    - gradientTransform="translate(-381.09403,-544.64978)"
    - x1="147.86807"
    - y1="287.98224"
    - x2="147.86807"
    - y2="341.01526" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3613"
    - id="linearGradient3700"
    - gradientUnits="userSpaceOnUse"
    - gradientTransform="translate(-381.09403,-544.64978)"
    - x1="147.86807"
    - y1="287.98224"
    - x2="147.86807"
    - y2="341.01526" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3613"
    - id="linearGradient3703"
    - gradientUnits="userSpaceOnUse"
    - gradientTransform="translate(-381.09403,-544.64978)"
    - x1="147.86807"
    - y1="287.98224"
    - x2="147.86807"
    - y2="341.01526" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3613"
    - id="linearGradient3705"
    - gradientUnits="userSpaceOnUse"
    - gradientTransform="translate(-381.09403,-544.64978)"
    - x1="147.86807"
    - y1="287.98224"
    - x2="147.86807"
    - y2="341.01526" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3613"
    - id="linearGradient3707"
    - gradientUnits="userSpaceOnUse"
    - gradientTransform="translate(-381.09403,-544.64978)"
    - x1="147.86807"
    - y1="287.98224"
    - x2="147.86807"
    - y2="341.01526" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3613"
    - id="linearGradient3709"
    - gradientUnits="userSpaceOnUse"
    - gradientTransform="translate(-381.09403,-544.64978)"
    - x1="147.86807"
    - y1="287.98224"
    - x2="147.86807"
    - y2="341.01526" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient4192"
    - id="linearGradient4200"
    - x1="9.601512"
    - y1="10.789209"
    - x2="311.62698"
    - y2="232.99521"
    - gradientUnits="userSpaceOnUse" />
    - <inkscape:perspective
    - id="perspective3695"
    - inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
    - inkscape:vp_z="1 : 0.5 : 1"
    - inkscape:vp_y="0 : 1000 : 0"
    - inkscape:vp_x="0 : 0.5 : 1"
    - sodipodi:type="inkscape:persp3d" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3708"
    - id="linearGradient3714"
    - x1="87.808205"
    - y1="244.84967"
    - x2="32.786144"
    - y2="103.0031"
    - gradientUnits="userSpaceOnUse" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3708"
    - id="linearGradient3722"
    - x1="73.120178"
    - y1="183.3553"
    - x2="52.375767"
    - y2="141.61852"
    - gradientUnits="userSpaceOnUse" />
    - <inkscape:perspective
    - id="perspective3732"
    - inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
    - inkscape:vp_z="1 : 0.5 : 1"
    - inkscape:vp_y="0 : 1000 : 0"
    - inkscape:vp_x="0 : 0.5 : 1"
    - sodipodi:type="inkscape:persp3d" />
    - <inkscape:perspective
    - id="perspective3757"
    - inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
    - inkscape:vp_z="1 : 0.5 : 1"
    - inkscape:vp_y="0 : 1000 : 0"
    - inkscape:vp_x="0 : 0.5 : 1"
    - sodipodi:type="inkscape:persp3d" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3770"
    - id="linearGradient3776"
    - x1="149.16222"
    - y1="143.01329"
    - x2="-2.1779096"
    - y2="0.84358346"
    - gradientUnits="userSpaceOnUse" />
    - <linearGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3770"
    - id="linearGradient3784"
    - x1="96.563065"
    - y1="81.798767"
    - x2="56.660259"
    - y2="47.094559"
    - gradientUnits="userSpaceOnUse" />
    - <radialGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3621"
    - id="radialGradient3792"
    - cx="352.03818"
    - cy="101.69787"
    - fx="352.03818"
    - fy="101.69787"
    - r="18.67767"
    - gradientUnits="userSpaceOnUse" />
    - <radialGradient
    - inkscape:collect="always"
    - xlink:href="#linearGradient3497"
    - id="radialGradient3800"
    - cx="352.03818"
    - cy="101.69787"
    - fx="352.03818"
    - fy="101.69787"
    - r="18.67767"
    - gradientUnits="userSpaceOnUse" />
    - </defs>
    - <metadata
    - id="metadata7">
    - <rdf:RDF>
    - <cc:Work
    - rdf:about="">
    - <dc:format>image/svg+xml</dc:format>
    - <dc:type
    - rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
    - <dc:title></dc:title>
    - </cc:Work>
    - </rdf:RDF>
    - </metadata>
    - <g
    - inkscape:label="Calque 1"
    - inkscape:groupmode="layer"
    - id="layer1"
    - style="display:inline">
    - <rect
    - ry="23.307579"
    - y="11.523975"
    - x="10.336278"
    - height="220.73647"
    - width="300.55594"
    - id="rect3700"
    - style="fill:url(#linearGradient4200);fill-opacity:1;stroke:#000000;stroke-width:1.46953177;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
    - <g
    - transform="translate(-127.27923,-40.406102)"
    - id="g3695">
    - <rect
    - style="fill:url(#linearGradient3702);fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 2;stroke-dashoffset:0"
    - id="rect3677"
    - width="163.64471"
    - height="53.538086"
    - x="148.49243"
    - y="62.806999"
    - ry="5.029737" />
    - <text
    - sodipodi:linespacing="125%"
    - id="text_compteur"
    - y="102.99694"
    - x="154.30698"
    - style="font-size:36px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:#655fdb;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans Bold"
    - xml:space="preserve"><tspan
    - y="102.99694"
    - x="154.30698"
    - id="tspan3191"
    - sodipodi:role="line"
    - style="font-size:36px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#655fdb;fill-opacity:1;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans Bold">Default</tspan></text>
    - </g>
    - <g
    - id="stop_back"
    - transform="translate(-33.11078,95.2077)">
    - <path
    - sodipodi:type="star"
    - style="color:#000000;fill:url(#linearGradient3776);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient3784);stroke-width:3.80890393;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
    - id="path3747"
    - sodipodi:sides="3"
    - sodipodi:cx="103.21429"
    - sodipodi:cy="127.14286"
    - sodipodi:r1="91.508057"
    - sodipodi:r2="45.754028"
    - sodipodi:arg1="0"
    - sodipodi:arg2="1.0471976"
    - inkscape:flatsided="true"
    - inkscape:rounded="0"
    - inkscape:randomized="0"
    - d="m 194.72234,127.14286 -137.262082,79.2483 0,-158.496601 137.262082,79.248301 z"
    - transform="matrix(0.78762818,0,0,0.78762818,26.492161,-44.168468)" />
    - <text
    - sodipodi:linespacing="100%"
    - id="text2393"
    - y="68.857597"
    - x="151.45537"
    - style="font-size:36px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:end;text-decoration:none;line-height:100%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:end;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:inherit;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans Bold"
    - xml:space="preserve"><tspan
    - style="font-size:36px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:end;text-decoration:none;line-height:100%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:end;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:inherit;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans Bold"
    - y="68.857597"
    - x="151.45537"
    - id="tspan2395"
    - sodipodi:role="line">Start</tspan></text>
    - </g>
    - <g
    - transform="translate(-18.07106,94.06456)"
    - id="stop_sele"
    - style="fill:#aaffaa">
    - <path
    - sodipodi:type="star"
    - style="color:#000000;fill:url(#linearGradient3714);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient3722);stroke-width:3.94511151;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
    - id="path3685"
    - sodipodi:sides="8"
    - sodipodi:cx="83.571426"
    - sodipodi:cy="224.28571"
    - sodipodi:r1="94.724358"
    - sodipodi:r2="87.513893"
    - sodipodi:arg1="0"
    - sodipodi:arg2="0.39269908"
    - inkscape:flatsided="true"
    - inkscape:rounded="0"
    - inkscape:randomized="0"
    - d="m 178.29578,224.28571 -27.74412,66.98023 -66.980234,27.74412 -66.980235,-27.74412 -27.744122,-66.98023 27.744122,-66.98024 66.980235,-27.74412 66.980234,27.74412 27.74412,66.98024 z"
    - transform="matrix(0.70255013,-0.29100577,0.29100577,0.70255013,-13.216048,-76.13621)" />
    - <text
    - sodipodi:linespacing="100%"
    - id="text2401"
    - y="66.643318"
    - x="147.74109"
    - style="font-size:36px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:end;text-decoration:none;line-height:100%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:end;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:inherit;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans Bold"
    - xml:space="preserve"><tspan
    - style="font-size:36px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:end;line-height:100%;writing-mode:lr-tb;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans Bold"
    - y="66.643318"
    - x="147.74109"
    - id="tspan2403"
    - sodipodi:role="line">Stop</tspan></text>
    - </g>
    - <g
    - transform="matrix(2.0899173,0,0,2.0899173,-577.84265,-204.88668)"
    - id="led_start">
    - <path
    - transform="translate(42.282829,64.376725)"
    - d="m 369.71585,101.69787 a 17.67767,17.67767 0 1 1 -35.35534,0 17.67767,17.67767 0 1 1 35.35534,0 z"
    - sodipodi:ry="17.67767"
    - sodipodi:rx="17.67767"
    - sodipodi:cy="101.69787"
    - sodipodi:cx="352.03818"
    - id="pathLed"
    - style="fill:url(#radialGradient3800);fill-opacity:1;stroke:#000000;stroke-width:0.47848782;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
    - sodipodi:type="arc" />
    - </g>
    - <g
    - transform="matrix(2.0899173,0,0,2.0899173,-637.08625,-59.866062)"
    - id="led_stop">
    - <path
    - sodipodi:type="arc"
    - style="fill:url(#radialGradient3792);fill-opacity:1;stroke:#000000;stroke-width:0.47848782;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
    - id="path_led"
    - sodipodi:cx="352.03818"
    - sodipodi:cy="101.69787"
    - sodipodi:rx="17.67767"
    - sodipodi:ry="17.67767"
    - d="m 369.71585,101.69787 a 17.67767,17.67767 0 1 1 -35.35534,0 17.67767,17.67767 0 1 1 35.35534,0 z"
    - transform="translate(70.630181,-5.0138784)" />
    - </g>
    - </g>
    -</svg>
    --- a/tests/svgui/python@py_ext/svgui@svgui/py_ext.xml Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,4 +0,0 @@
    -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    -<Python xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="python_xsd.xsd">
    -<![CDATA[]]>
    -</Python>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/tests/svgui/svgui@svgui/baseconfnode.xml Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,2 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +<BaseParams Name="svgui" IEC_Channel="0"/>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/tests/svgui/svgui@svgui/gui.svg Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,723 @@
    +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    +
    +<svg
    + xmlns:dc="http://purl.org/dc/elements/1.1/"
    + xmlns:cc="http://creativecommons.org/ns#"
    + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    + xmlns:svg="http://www.w3.org/2000/svg"
    + xmlns="http://www.w3.org/2000/svg"
    + xmlns:xlink="http://www.w3.org/1999/xlink"
    + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
    + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
    + width="320"
    + height="250"
    + id="svg2"
    + sodipodi:version="0.32"
    + inkscape:version="0.47pre4 "
    + version="1.0"
    + sodipodi:docname="gui.svg"
    + inkscape:output_extension="org.inkscape.output.svg.inkscape">
    + <sodipodi:namedview
    + id="base"
    + pagecolor="#ffffff"
    + bordercolor="#666666"
    + borderopacity="1.0"
    + inkscape:pageopacity="0.0"
    + inkscape:pageshadow="2"
    + inkscape:zoom="1.4"
    + inkscape:cx="200.66323"
    + inkscape:cy="178.08292"
    + inkscape:document-units="px"
    + inkscape:current-layer="layer1"
    + showgrid="false"
    + inkscape:window-width="1071"
    + inkscape:window-height="805"
    + inkscape:window-x="106"
    + inkscape:window-y="16"
    + inkscape:window-maximized="0" />
    + <defs
    + id="defs4">
    + <linearGradient
    + id="linearGradient3770">
    + <stop
    + style="stop-color:#008000;stop-opacity:1;"
    + offset="0"
    + id="stop3772" />
    + <stop
    + style="stop-color:#00fb00;stop-opacity:1;"
    + offset="1"
    + id="stop3774" />
    + </linearGradient>
    + <linearGradient
    + id="linearGradient3708">
    + <stop
    + style="stop-color:#d40000;stop-opacity:1;"
    + offset="0"
    + id="stop3710" />
    + <stop
    + style="stop-color:#ff5c5c;stop-opacity:1;"
    + offset="1"
    + id="stop3712" />
    + </linearGradient>
    + <linearGradient
    + id="linearGradient4202">
    + <stop
    + id="stop4204"
    + offset="0"
    + style="stop-color:#f6edda;stop-opacity:1;" />
    + <stop
    + id="stop4206"
    + offset="1"
    + style="stop-color:#e6e6e6;stop-opacity:1;" />
    + </linearGradient>
    + <linearGradient
    + id="linearGradient4192">
    + <stop
    + style="stop-color:#faf4e9;stop-opacity:1;"
    + offset="0"
    + id="stop4194" />
    + <stop
    + style="stop-color:#f1f1f1;stop-opacity:1;"
    + offset="1"
    + id="stop4196" />
    + </linearGradient>
    + <linearGradient
    + id="linearGradient3302">
    + <stop
    + style="stop-color:#ff0000;stop-opacity:0;"
    + offset="0"
    + id="stop3304" />
    + <stop
    + id="stop3310"
    + offset="0.43817073"
    + style="stop-color:#ff0000;stop-opacity:0.49803922;" />
    + <stop
    + style="stop-color:#ff0000;stop-opacity:1;"
    + offset="0.68879533"
    + id="stop3312" />
    + <stop
    + style="stop-color:#ff0000;stop-opacity:0;"
    + offset="1"
    + id="stop3306" />
    + </linearGradient>
    + <linearGradient
    + id="linearGradient3687">
    + <stop
    + id="stop3689"
    + offset="0"
    + style="stop-color:#23d5ff;stop-opacity:1;" />
    + <stop
    + id="stop3691"
    + offset="1"
    + style="stop-color:#b1ffff;stop-opacity:1;" />
    + </linearGradient>
    + <linearGradient
    + id="linearGradient3679">
    + <stop
    + id="stop3681"
    + offset="0"
    + style="stop-color:#00b5ff;stop-opacity:1;" />
    + <stop
    + id="stop3683"
    + offset="1"
    + style="stop-color:#005bff;stop-opacity:1;" />
    + </linearGradient>
    + <linearGradient
    + id="linearGradient3659">
    + <stop
    + id="stop3661"
    + offset="0"
    + style="stop-color:#ff0030;stop-opacity:1;" />
    + <stop
    + style="stop-color:#e20000;stop-opacity:0.83211678;"
    + offset="0.60000002"
    + id="stop3669" />
    + <stop
    + id="stop3663"
    + offset="1"
    + style="stop-color:#ffffff;stop-opacity:0;" />
    + </linearGradient>
    + <linearGradient
    + id="linearGradient3639">
    + <stop
    + id="stop3641"
    + offset="0"
    + style="stop-color:#ffff00;stop-opacity:1;" />
    + <stop
    + style="stop-color:#8fff00;stop-opacity:0.49803922;"
    + offset="0.80000001"
    + id="stop3647" />
    + <stop
    + id="stop3643"
    + offset="1"
    + style="stop-color:#ffffff;stop-opacity:0;" />
    + </linearGradient>
    + <linearGradient
    + id="linearGradient3621">
    + <stop
    + id="stop3623"
    + offset="0"
    + style="stop-color:#ff8080;stop-opacity:1;" />
    + <stop
    + id="stop3625"
    + offset="1"
    + style="stop-color:#aa0000;stop-opacity:1;" />
    + </linearGradient>
    + <linearGradient
    + id="linearGradient3613"
    + inkscape:collect="always">
    + <stop
    + id="stop3615"
    + offset="0"
    + style="stop-color:#000000;stop-opacity:1;" />
    + <stop
    + id="stop3617"
    + offset="1"
    + style="stop-color:#000000;stop-opacity:0;" />
    + </linearGradient>
    + <linearGradient
    + id="linearGradient3497">
    + <stop
    + id="stop3499"
    + offset="0"
    + style="stop-color:#00cd00;stop-opacity:1;" />
    + <stop
    + id="stop3501"
    + offset="1"
    + style="stop-color:#007900;stop-opacity:1;" />
    + </linearGradient>
    + <linearGradient
    + id="linearGradient3453">
    + <stop
    + id="stop3455"
    + offset="0"
    + style="stop-color:#000000;stop-opacity:1;" />
    + <stop
    + id="stop3457"
    + offset="1"
    + style="stop-color:#ffffff;stop-opacity:0;" />
    + </linearGradient>
    + <linearGradient
    + id="linearGradient3173">
    + <stop
    + style="stop-color:#ffffff;stop-opacity:1;"
    + offset="0"
    + id="stop3175" />
    + <stop
    + id="stop3181"
    + offset="0.5"
    + style="stop-color:#ffffff;stop-opacity:0;" />
    + <stop
    + style="stop-color:#ff0000;stop-opacity:0;"
    + offset="1"
    + id="stop3177" />
    + </linearGradient>
    + <inkscape:perspective
    + sodipodi:type="inkscape:persp3d"
    + inkscape:vp_x="0 : 526.18109 : 1"
    + inkscape:vp_y="0 : 1000 : 0"
    + inkscape:vp_z="744.09448 : 526.18109 : 1"
    + inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
    + id="perspective10" />
    + <inkscape:perspective
    + sodipodi:type="inkscape:persp3d"
    + inkscape:vp_x="0 : 526.18109 : 1"
    + inkscape:vp_y="0 : 1000 : 0"
    + inkscape:vp_z="744.09448 : 526.18109 : 1"
    + inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
    + id="perspective2619" />
    + <linearGradient
    + gradientUnits="userSpaceOnUse"
    + y2="76.489952"
    + x2="96.68087"
    + y1="43.13879"
    + x1="96.68087"
    + id="linearGradient3503"
    + xlink:href="#linearGradient3497"
    + inkscape:collect="always" />
    + <linearGradient
    + gradientUnits="userSpaceOnUse"
    + y2="57.028084"
    + x2="146.58875"
    + y1="57.028084"
    + x1="56.098511"
    + id="linearGradient3619"
    + xlink:href="#linearGradient3613"
    + inkscape:collect="always" />
    + <linearGradient
    + gradientUnits="userSpaceOnUse"
    + y2="81.670944"
    + x2="102.30303"
    + y1="40.599514"
    + x1="101.45565"
    + id="linearGradient3627"
    + xlink:href="#linearGradient3621"
    + inkscape:collect="always" />
    + <linearGradient
    + gradientTransform="translate(-18,26)"
    + y2="81.670944"
    + x2="102.30303"
    + y1="40.599514"
    + x1="101.45565"
    + gradientUnits="userSpaceOnUse"
    + id="linearGradient3633"
    + xlink:href="#linearGradient3621"
    + inkscape:collect="always" />
    + <radialGradient
    + r="17.67767"
    + fy="101.69787"
    + fx="352.03818"
    + cy="101.69787"
    + cx="352.03818"
    + gradientUnits="userSpaceOnUse"
    + id="radialGradient3667"
    + xlink:href="#linearGradient3639"
    + inkscape:collect="always" />
    + <radialGradient
    + r="17.67767"
    + fy="101.69787"
    + fx="352.03818"
    + cy="101.69787"
    + cx="352.03818"
    + gradientUnits="userSpaceOnUse"
    + id="radialGradient3675"
    + xlink:href="#linearGradient3659"
    + inkscape:collect="always" />
    + <linearGradient
    + gradientTransform="translate(-1.3119965,1.110878)"
    + gradientUnits="userSpaceOnUse"
    + y2="74.0345"
    + x2="222.50246"
    + y1="102.89583"
    + x1="223.57851"
    + id="linearGradient3693"
    + xlink:href="#linearGradient3687"
    + inkscape:collect="always" />
    + <linearGradient
    + y2="116.84509"
    + x2="312.63715"
    + y1="62.306999"
    + x1="277.45764"
    + gradientUnits="userSpaceOnUse"
    + id="linearGradient3702"
    + xlink:href="#linearGradient4202"
    + inkscape:collect="always" />
    + <linearGradient
    + y2="66.89164"
    + x2="223.21674"
    + y1="102.89583"
    + x1="223.57851"
    + gradientTransform="translate(-1.3119965,1.110878)"
    + gradientUnits="userSpaceOnUse"
    + id="linearGradient3704"
    + xlink:href="#linearGradient3613"
    + inkscape:collect="always" />
    + <inkscape:perspective
    + sodipodi:type="inkscape:persp3d"
    + inkscape:vp_x="0 : 526.18109 : 1"
    + inkscape:vp_y="0 : 1000 : 0"
    + inkscape:vp_z="744.09448 : 526.18109 : 1"
    + inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
    + id="perspective3767" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3302"
    + id="linearGradient3308"
    + x1="255.95412"
    + y1="328.07761"
    + x2="258.63916"
    + y2="328.07761"
    + gradientUnits="userSpaceOnUse"
    + gradientTransform="translate(-25.178571,-3.0357143)" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3613"
    + id="linearGradient3536"
    + gradientUnits="userSpaceOnUse"
    + gradientTransform="translate(5.555838,16.162441)"
    + x1="147.86807"
    + y1="287.98224"
    + x2="147.86807"
    + y2="341.01526" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3613"
    + id="linearGradient3538"
    + gradientUnits="userSpaceOnUse"
    + gradientTransform="translate(5.555838,16.162441)"
    + x1="147.86807"
    + y1="287.98224"
    + x2="147.86807"
    + y2="341.01526" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3613"
    + id="linearGradient3540"
    + gradientUnits="userSpaceOnUse"
    + gradientTransform="translate(5.555838,16.162441)"
    + x1="147.86807"
    + y1="287.98224"
    + x2="147.86807"
    + y2="341.01526" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3613"
    + id="linearGradient3542"
    + gradientUnits="userSpaceOnUse"
    + gradientTransform="translate(5.555838,16.162441)"
    + x1="147.86807"
    + y1="287.98224"
    + x2="147.86807"
    + y2="341.01526" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3613"
    + id="linearGradient3544"
    + gradientUnits="userSpaceOnUse"
    + gradientTransform="translate(5.555838,16.162441)"
    + x1="147.86807"
    + y1="287.98224"
    + x2="147.86807"
    + y2="341.01526" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3613"
    + id="linearGradient3546"
    + gradientUnits="userSpaceOnUse"
    + gradientTransform="translate(5.555838,16.162441)"
    + x1="147.86807"
    + y1="287.98224"
    + x2="147.86807"
    + y2="341.01526" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3613"
    + id="linearGradient3548"
    + gradientUnits="userSpaceOnUse"
    + gradientTransform="translate(5.555838,16.162441)"
    + x1="147.86807"
    + y1="287.98224"
    + x2="147.86807"
    + y2="341.01526" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3613"
    + id="linearGradient3550"
    + gradientUnits="userSpaceOnUse"
    + gradientTransform="translate(5.555838,16.162441)"
    + x1="147.86807"
    + y1="287.98224"
    + x2="147.86807"
    + y2="341.01526" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3613"
    + id="linearGradient3694"
    + gradientUnits="userSpaceOnUse"
    + gradientTransform="translate(-381.09403,-544.64978)"
    + x1="147.86807"
    + y1="287.98224"
    + x2="147.86807"
    + y2="341.01526" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3613"
    + id="linearGradient3696"
    + gradientUnits="userSpaceOnUse"
    + gradientTransform="translate(-381.09403,-544.64978)"
    + x1="147.86807"
    + y1="287.98224"
    + x2="147.86807"
    + y2="341.01526" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3613"
    + id="linearGradient3698"
    + gradientUnits="userSpaceOnUse"
    + gradientTransform="translate(-381.09403,-544.64978)"
    + x1="147.86807"
    + y1="287.98224"
    + x2="147.86807"
    + y2="341.01526" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3613"
    + id="linearGradient3700"
    + gradientUnits="userSpaceOnUse"
    + gradientTransform="translate(-381.09403,-544.64978)"
    + x1="147.86807"
    + y1="287.98224"
    + x2="147.86807"
    + y2="341.01526" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3613"
    + id="linearGradient3703"
    + gradientUnits="userSpaceOnUse"
    + gradientTransform="translate(-381.09403,-544.64978)"
    + x1="147.86807"
    + y1="287.98224"
    + x2="147.86807"
    + y2="341.01526" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3613"
    + id="linearGradient3705"
    + gradientUnits="userSpaceOnUse"
    + gradientTransform="translate(-381.09403,-544.64978)"
    + x1="147.86807"
    + y1="287.98224"
    + x2="147.86807"
    + y2="341.01526" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3613"
    + id="linearGradient3707"
    + gradientUnits="userSpaceOnUse"
    + gradientTransform="translate(-381.09403,-544.64978)"
    + x1="147.86807"
    + y1="287.98224"
    + x2="147.86807"
    + y2="341.01526" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3613"
    + id="linearGradient3709"
    + gradientUnits="userSpaceOnUse"
    + gradientTransform="translate(-381.09403,-544.64978)"
    + x1="147.86807"
    + y1="287.98224"
    + x2="147.86807"
    + y2="341.01526" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient4192"
    + id="linearGradient4200"
    + x1="9.601512"
    + y1="10.789209"
    + x2="311.62698"
    + y2="232.99521"
    + gradientUnits="userSpaceOnUse" />
    + <inkscape:perspective
    + id="perspective3695"
    + inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
    + inkscape:vp_z="1 : 0.5 : 1"
    + inkscape:vp_y="0 : 1000 : 0"
    + inkscape:vp_x="0 : 0.5 : 1"
    + sodipodi:type="inkscape:persp3d" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3708"
    + id="linearGradient3714"
    + x1="87.808205"
    + y1="244.84967"
    + x2="32.786144"
    + y2="103.0031"
    + gradientUnits="userSpaceOnUse" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3708"
    + id="linearGradient3722"
    + x1="73.120178"
    + y1="183.3553"
    + x2="52.375767"
    + y2="141.61852"
    + gradientUnits="userSpaceOnUse" />
    + <inkscape:perspective
    + id="perspective3732"
    + inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
    + inkscape:vp_z="1 : 0.5 : 1"
    + inkscape:vp_y="0 : 1000 : 0"
    + inkscape:vp_x="0 : 0.5 : 1"
    + sodipodi:type="inkscape:persp3d" />
    + <inkscape:perspective
    + id="perspective3757"
    + inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
    + inkscape:vp_z="1 : 0.5 : 1"
    + inkscape:vp_y="0 : 1000 : 0"
    + inkscape:vp_x="0 : 0.5 : 1"
    + sodipodi:type="inkscape:persp3d" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3770"
    + id="linearGradient3776"
    + x1="149.16222"
    + y1="143.01329"
    + x2="-2.1779096"
    + y2="0.84358346"
    + gradientUnits="userSpaceOnUse" />
    + <linearGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3770"
    + id="linearGradient3784"
    + x1="96.563065"
    + y1="81.798767"
    + x2="56.660259"
    + y2="47.094559"
    + gradientUnits="userSpaceOnUse" />
    + <radialGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3621"
    + id="radialGradient3792"
    + cx="352.03818"
    + cy="101.69787"
    + fx="352.03818"
    + fy="101.69787"
    + r="18.67767"
    + gradientUnits="userSpaceOnUse" />
    + <radialGradient
    + inkscape:collect="always"
    + xlink:href="#linearGradient3497"
    + id="radialGradient3800"
    + cx="352.03818"
    + cy="101.69787"
    + fx="352.03818"
    + fy="101.69787"
    + r="18.67767"
    + gradientUnits="userSpaceOnUse" />
    + </defs>
    + <metadata
    + id="metadata7">
    + <rdf:RDF>
    + <cc:Work
    + rdf:about="">
    + <dc:format>image/svg+xml</dc:format>
    + <dc:type
    + rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
    + <dc:title></dc:title>
    + </cc:Work>
    + </rdf:RDF>
    + </metadata>
    + <g
    + inkscape:label="Calque 1"
    + inkscape:groupmode="layer"
    + id="layer1"
    + style="display:inline">
    + <rect
    + ry="23.307579"
    + y="11.523975"
    + x="10.336278"
    + height="220.73647"
    + width="300.55594"
    + id="rect3700"
    + style="fill:url(#linearGradient4200);fill-opacity:1;stroke:#000000;stroke-width:1.46953177;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
    + <g
    + transform="translate(-127.27923,-40.406102)"
    + id="g3695">
    + <rect
    + style="fill:url(#linearGradient3702);fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 2;stroke-dashoffset:0"
    + id="rect3677"
    + width="163.64471"
    + height="53.538086"
    + x="148.49243"
    + y="62.806999"
    + ry="5.029737" />
    + <text
    + sodipodi:linespacing="125%"
    + id="text_compteur"
    + y="102.99694"
    + x="154.30698"
    + style="font-size:36px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:#655fdb;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans Bold"
    + xml:space="preserve"><tspan
    + y="102.99694"
    + x="154.30698"
    + id="tspan3191"
    + sodipodi:role="line"
    + style="font-size:36px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#655fdb;fill-opacity:1;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans Bold">Default</tspan></text>
    + </g>
    + <g
    + id="stop_back"
    + transform="translate(-33.11078,95.2077)">
    + <path
    + sodipodi:type="star"
    + style="color:#000000;fill:url(#linearGradient3776);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient3784);stroke-width:3.80890393;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
    + id="path3747"
    + sodipodi:sides="3"
    + sodipodi:cx="103.21429"
    + sodipodi:cy="127.14286"
    + sodipodi:r1="91.508057"
    + sodipodi:r2="45.754028"
    + sodipodi:arg1="0"
    + sodipodi:arg2="1.0471976"
    + inkscape:flatsided="true"
    + inkscape:rounded="0"
    + inkscape:randomized="0"
    + d="m 194.72234,127.14286 -137.262082,79.2483 0,-158.496601 137.262082,79.248301 z"
    + transform="matrix(0.78762818,0,0,0.78762818,26.492161,-44.168468)" />
    + <text
    + sodipodi:linespacing="100%"
    + id="text2393"
    + y="68.857597"
    + x="151.45537"
    + style="font-size:36px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:end;text-decoration:none;line-height:100%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:end;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:inherit;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans Bold"
    + xml:space="preserve"><tspan
    + style="font-size:36px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:end;text-decoration:none;line-height:100%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:end;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:inherit;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans Bold"
    + y="68.857597"
    + x="151.45537"
    + id="tspan2395"
    + sodipodi:role="line">Start</tspan></text>
    + </g>
    + <g
    + transform="translate(-18.07106,94.06456)"
    + id="stop_sele"
    + style="fill:#aaffaa">
    + <path
    + sodipodi:type="star"
    + style="color:#000000;fill:url(#linearGradient3714);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient3722);stroke-width:3.94511151;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
    + id="path3685"
    + sodipodi:sides="8"
    + sodipodi:cx="83.571426"
    + sodipodi:cy="224.28571"
    + sodipodi:r1="94.724358"
    + sodipodi:r2="87.513893"
    + sodipodi:arg1="0"
    + sodipodi:arg2="0.39269908"
    + inkscape:flatsided="true"
    + inkscape:rounded="0"
    + inkscape:randomized="0"
    + d="m 178.29578,224.28571 -27.74412,66.98023 -66.980234,27.74412 -66.980235,-27.74412 -27.744122,-66.98023 27.744122,-66.98024 66.980235,-27.74412 66.980234,27.74412 27.74412,66.98024 z"
    + transform="matrix(0.70255013,-0.29100577,0.29100577,0.70255013,-13.216048,-76.13621)" />
    + <text
    + sodipodi:linespacing="100%"
    + id="text2401"
    + y="66.643318"
    + x="147.74109"
    + style="font-size:36px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:end;text-decoration:none;line-height:100%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:end;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:inherit;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans Bold"
    + xml:space="preserve"><tspan
    + style="font-size:36px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:end;line-height:100%;writing-mode:lr-tb;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans Bold"
    + y="66.643318"
    + x="147.74109"
    + id="tspan2403"
    + sodipodi:role="line">Stop</tspan></text>
    + </g>
    + <g
    + transform="matrix(2.0899173,0,0,2.0899173,-577.84265,-204.88668)"
    + id="led_start">
    + <path
    + transform="translate(42.282829,64.376725)"
    + d="m 369.71585,101.69787 a 17.67767,17.67767 0 1 1 -35.35534,0 17.67767,17.67767 0 1 1 35.35534,0 z"
    + sodipodi:ry="17.67767"
    + sodipodi:rx="17.67767"
    + sodipodi:cy="101.69787"
    + sodipodi:cx="352.03818"
    + id="pathLed"
    + style="fill:url(#radialGradient3800);fill-opacity:1;stroke:#000000;stroke-width:0.47848782;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
    + sodipodi:type="arc" />
    + </g>
    + <g
    + transform="matrix(2.0899173,0,0,2.0899173,-637.08625,-59.866062)"
    + id="led_stop">
    + <path
    + sodipodi:type="arc"
    + style="fill:url(#radialGradient3792);fill-opacity:1;stroke:#000000;stroke-width:0.47848782;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
    + id="path_led"
    + sodipodi:cx="352.03818"
    + sodipodi:cy="101.69787"
    + sodipodi:rx="17.67767"
    + sodipodi:ry="17.67767"
    + d="m 369.71585,101.69787 a 17.67767,17.67767 0 1 1 -35.35534,0 17.67767,17.67767 0 1 1 35.35534,0 z"
    + transform="translate(70.630181,-5.0138784)" />
    + </g>
    + </g>
    +</svg>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/tests/svgui/svgui@svgui/py_ext.xml Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,4 @@
    +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<Python xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="python_xsd.xsd">
    +<![CDATA[]]>
    +</Python>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/tests/wxGlade/HMIFrame@wxglade_hmi/baseconfnode.xml Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,2 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +<BaseParams Name="HMIFrame" IEC_Channel="0"/>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/tests/wxGlade/HMIFrame@wxglade_hmi/hmi.wxg Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,34 @@
    +<?xml version="1.0"?>
    +<!-- generated by wxGlade 0.6.3 on Fri Aug 7 18:16:44 2009 -->
    +
    +<application path="" name="" class="" option="0" language="python" top_window="HMIFrame" encoding="UTF-8" use_gettext="0" overwrite="0" use_new_namespace="1" for_version="2.8" is_template="0">
    + <object class="Class_HMIFrame" name="HMIFrame" base="EditFrame">
    + <style>wxDEFAULT_FRAME_STYLE</style>
    + <title>HMIFrame</title>
    + <object class="wxBoxSizer" name="sizer_1" base="EditBoxSizer">
    + <orient>wxVERTICAL</orient>
    + <object class="sizeritem">
    + <border>0</border>
    + <option>0</option>
    + <object class="wxSpinCtrl" name="spin_ctrl_1" base="EditSpinCtrl">
    + <range>0, 10000</range>
    + </object>
    + </object>
    + <object class="sizeritem">
    + <border>0</border>
    + <option>0</option>
    + <object class="wxCheckBox" name="checkbox_1" base="EditCheckBox">
    + <label>checkbox_1</label>
    + </object>
    + </object>
    + <object class="sizeritem">
    + <border>0</border>
    + <option>0</option>
    + <object class="wxStaticText" name="label_1" base="EditStaticText">
    + <attribute>1</attribute>
    + <label>GUI modifiée !</label>
    + </object>
    + </object>
    + </object>
    + </object>
    +</application>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/tests/wxGlade/HMIFrame@wxglade_hmi/py_ext.xml Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,4 @@
    +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<Python xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="python_xsd.xsd">
    +<![CDATA[]]>
    +</Python>
    --- a/tests/wxGlade/python@py_ext/HMIFrame@wxglade_hmi/baseconfnode.xml Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,2 +0,0 @@
    -<?xml version="1.0" encoding="UTF-8"?>
    -<BaseParams Name="HMIFrame" IEC_Channel="0"/>
    --- a/tests/wxGlade/python@py_ext/HMIFrame@wxglade_hmi/hmi.wxg Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,34 +0,0 @@
    -<?xml version="1.0"?>
    -<!-- generated by wxGlade 0.6.3 on Fri Aug 7 18:16:44 2009 -->
    -
    -<application path="" name="" class="" option="0" language="python" top_window="HMIFrame" encoding="UTF-8" use_gettext="0" overwrite="0" use_new_namespace="1" for_version="2.8" is_template="0">
    - <object class="Class_HMIFrame" name="HMIFrame" base="EditFrame">
    - <style>wxDEFAULT_FRAME_STYLE</style>
    - <title>HMIFrame</title>
    - <object class="wxBoxSizer" name="sizer_1" base="EditBoxSizer">
    - <orient>wxVERTICAL</orient>
    - <object class="sizeritem">
    - <border>0</border>
    - <option>0</option>
    - <object class="wxSpinCtrl" name="spin_ctrl_1" base="EditSpinCtrl">
    - <range>0, 10000</range>
    - </object>
    - </object>
    - <object class="sizeritem">
    - <border>0</border>
    - <option>0</option>
    - <object class="wxCheckBox" name="checkbox_1" base="EditCheckBox">
    - <label>checkbox_1</label>
    - </object>
    - </object>
    - <object class="sizeritem">
    - <border>0</border>
    - <option>0</option>
    - <object class="wxStaticText" name="label_1" base="EditStaticText">
    - <attribute>1</attribute>
    - <label>GUI modifiée !</label>
    - </object>
    - </object>
    - </object>
    - </object>
    -</application>
    --- a/tests/wxGlade/python@py_ext/HMIFrame@wxglade_hmi/py_ext.xml Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,4 +0,0 @@
    -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    -<Python xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="python_xsd.xsd">
    -<![CDATA[]]>
    -</Python>
    --- a/tests/wxGlade/python@py_ext/baseconfnode.xml Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,2 +0,0 @@
    -<?xml version="1.0" encoding="UTF-8"?>
    -<BaseParams Name="python" IEC_Channel="0"/>
    --- a/tests/wxGlade/python@py_ext/py_ext.xml Wed May 09 00:39:54 2012 +0200
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,4 +0,0 @@
    -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    -<Python xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="python_xsd.xsd">
    -<![CDATA[]]>
    -</Python>
    --- a/util/misc.py Wed May 09 00:39:54 2012 +0200
    +++ b/util/misc.py Sat May 12 11:21:10 2012 +0200
    @@ -25,5 +25,5 @@
    return reduce(getattr, classpath.split('.')[1:], mod)
    return fac
    else:
    - return lambda:classpath
    + return lambda:classpath
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/wxglade_hmi/README Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,1 @@
    +WxGlade HMI
    \ No newline at end of file
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/wxglade_hmi/__init__.py Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,1 @@
    +from wxglade_hmi import *
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/wxglade_hmi/wxglade_hmi.py Sat May 12 11:21:10 2012 +0200
    @@ -0,0 +1,127 @@
    +import wx
    +import os, sys
    +from xml.dom import minidom
    +
    +from util import opjimg
    +from py_ext import PythonFileCTNMixin
    +
    +class WxGladeHMI(PythonFileCTNMixin):
    +
    + ConfNodeMethods = [
    + {"bitmap" : opjimg("editWXGLADE"),
    + "name" : _("WXGLADE GUI"),
    + "tooltip" : _("Edit a WxWidgets GUI with WXGlade"),
    + "method" : "_editWXGLADE"},
    + ]
    +
    + def ConfNodePath(self):
    + return os.path.join(os.path.dirname(__file__))
    +
    + def _getWXGLADEpath(self):
    + # define name for IEC raw code file
    + return os.path.join(self.CTNPath(), "hmi.wxg")
    +
    + def launch_wxglade(self, options, wait=False):
    + from wxglade import __file__ as fileName
    + path = os.path.dirname(fileName)
    + glade = os.path.join(path, 'wxglade.py')
    + if wx.Platform == '__WXMSW__':
    + glade = "\"%s\""%glade
    + mode = {False:os.P_NOWAIT, True:os.P_WAIT}[wait]
    + os.spawnv(mode, sys.executable, ["\"%s\""%sys.executable] + [glade] + options)
    +
    +
    + def CTNGenerate_C(self, buildpath, locations):
    + """
    + Return C code generated by iec2c compiler
    + when _generate_softPLC have been called
    + @param locations: ignored
    + @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
    + """
    +
    + current_location = self.GetCurrentLocation()
    + # define a unique name for the generated C file
    + location_str = "_".join(map(lambda x:str(x), current_location))
    +
    + runtimefile_path = os.path.join(buildpath, "runtime_%s.py"%location_str)
    + runtimefile = open(runtimefile_path, 'w')
    +
    + hmi_frames = {}
    +
    + wxgfile_path=self._getWXGLADEpath()
    + if os.path.exists(wxgfile_path):
    + wxgfile = open(wxgfile_path, 'r')
    + wxgtree = minidom.parse(wxgfile)
    + wxgfile.close()
    +
    + for node in wxgtree.childNodes[1].childNodes:
    + if node.nodeType == wxgtree.ELEMENT_NODE:
    + hmi_frames[node._attrs["name"].value] = node._attrs["class"].value
    +
    + hmipyfile_path=os.path.join(self._getBuildPath(), "hmi.py")
    + if wx.Platform == '__WXMSW__':
    + wxgfile_path = "\"%s\""%wxgfile_path
    + wxghmipyfile_path = "\"%s\""%hmipyfile_path
    + else:
    + wxghmipyfile_path = hmipyfile_path
    + self.launch_wxglade(['-o', wxghmipyfile_path, '-g', 'python', wxgfile_path], wait=True)
    +
    + hmipyfile = open(hmipyfile_path, 'r')
    + runtimefile.write(hmipyfile.read())
    + hmipyfile.close()
    +
    + runtimefile.write(self.GetPythonCode())
    + runtimefile.write("""
    +%(declare)s
    +
    +def _runtime_%(location)s_begin():
    + global %(global)s
    +
    + def OnCloseFrame(evt):
    + wx.MessageBox(_("Please stop PLC to close"))
    +
    + %(init)s
    +
    +def _runtime_%(location)s_cleanup():
    + global %(global)s
    +
    + %(cleanup)s
    +
    +""" % {"location": location_str,
    + "declare": "\n".join(map(lambda x:"%s = None" % x, hmi_frames.keys())),
    + "global": ",".join(hmi_frames.keys()),
    + "init": "\n".join(map(lambda x: """
    + %(name)s = %(class)s(None)
    + %(name)s.Bind(wx.EVT_CLOSE, OnCloseFrame)
    + %(name)s.Show()
    +""" % {"name": x[0], "class": x[1]},
    + hmi_frames.items())),
    + "cleanup": "\n ".join(map(lambda x:"%s.Destroy()" % x, hmi_frames.keys()))})
    + runtimefile.close()
    +
    + return [], "", False, ("runtime_%s.py"%location_str, file(runtimefile_path,"rb"))
    +
    + def _editWXGLADE(self):
    + wxg_filename = self._getWXGLADEpath()
    + open_wxglade = True
    + if not self.GetCTRoot().CheckProjectPathPerm():
    + dialog = wx.MessageDialog(self.GetCTRoot().AppFrame,
    + _("You don't have write permissions.\nOpen wxGlade anyway ?"),
    + _("Open wxGlade"),
    + wx.YES_NO|wx.ICON_QUESTION)
    + open_wxglade = dialog.ShowModal() == wx.ID_YES
    + dialog.Destroy()
    + if open_wxglade:
    + if not os.path.exists(wxg_filename):
    + hmi_name = self.BaseParams.getName()
    + open(wxg_filename,"w").write("""<?xml version="1.0"?>
    + <application path="" name="" class="" option="0" language="python" top_window="%(name)s" encoding="UTF-8" use_gettext="0" overwrite="0" use_new_namespace="1" for_version="2.8" is_template="0">
    + <object class="%(class)s" name="%(name)s" base="EditFrame">
    + <style>wxDEFAULT_FRAME_STYLE</style>
    + <title>frame_1</title>
    + </object>
    + </application>
    + """ % {"name": hmi_name, "class": "Class_%s" % hmi_name})
    + if wx.Platform == '__WXMSW__':
    + wxg_filename = "\"%s\""%wxg_filename
    + self.launch_wxglade([wxg_filename])