refactoring - library support is not anymore attached to configtree nodes, but handles by project controller
authorEdouard Tisserant
Sat, 12 May 2012 11:21:10 +0200
changeset 728 e0424e96e3fd
parent 727 3edd2f19bce2
child 729 25054c592dc4
refactoring - library support is not anymore attached to configtree nodes, but handles by project controller
ConfigTreeNode.py
POULibrary.py
ProjectController.py
features.py
py_ext/PythonFileCTNMixin.py
py_ext/__init__.py
py_ext/modules/__init__.py
py_ext/modules/svgui/README
py_ext/modules/svgui/__init__.py
py_ext/modules/svgui/livesvg.js
py_ext/modules/svgui/pous.xml
py_ext/modules/svgui/pyjs/__init__.py
py_ext/modules/svgui/pyjs/build.py
py_ext/modules/svgui/pyjs/jsonrpc/README.txt
py_ext/modules/svgui/pyjs/jsonrpc/django/jsonrpc.py
py_ext/modules/svgui/pyjs/jsonrpc/jsonrpc.py
py_ext/modules/svgui/pyjs/jsonrpc/web2py/jsonrpc.py
py_ext/modules/svgui/pyjs/lib/_pyjs.js
py_ext/modules/svgui/pyjs/lib/json.js
py_ext/modules/svgui/pyjs/lib/pyjslib.py
py_ext/modules/svgui/pyjs/lib/sys.py
py_ext/modules/svgui/pyjs/pyjs.py
py_ext/modules/svgui/svgui.py
py_ext/modules/svgui/svgui_server.py
py_ext/modules/svgui/svguilib.py
py_ext/modules/wxglade_hmi/README
py_ext/modules/wxglade_hmi/__init__.py
py_ext/modules/wxglade_hmi/wxglade_hmi.py
py_ext/plc_python.c
py_ext/py_ext.py
svgui/README
svgui/__init__.py
svgui/livesvg.js
svgui/pous.xml
svgui/pyjs/__init__.py
svgui/pyjs/build.py
svgui/pyjs/jsonrpc/README.txt
svgui/pyjs/jsonrpc/django/jsonrpc.py
svgui/pyjs/jsonrpc/jsonrpc.py
svgui/pyjs/jsonrpc/web2py/jsonrpc.py
svgui/pyjs/lib/_pyjs.js
svgui/pyjs/lib/json.js
svgui/pyjs/lib/pyjslib.py
svgui/pyjs/lib/sys.py
svgui/pyjs/pyjs.py
svgui/svgui.py
svgui/svgui_server.py
svgui/svguilib.py
targets/toolchain_gcc.py
tests/python/beremiz.xml
tests/python/plc.xml
tests/python/python@py_ext/py_ext.xml
tests/svgui/python@py_ext/baseconfnode.xml
tests/svgui/python@py_ext/py_ext.xml
tests/svgui/python@py_ext/svgui@svgui/baseconfnode.xml
tests/svgui/python@py_ext/svgui@svgui/gui.svg
tests/svgui/python@py_ext/svgui@svgui/py_ext.xml
tests/svgui/svgui@svgui/baseconfnode.xml
tests/svgui/svgui@svgui/gui.svg
tests/svgui/svgui@svgui/py_ext.xml
tests/wxGlade/HMIFrame@wxglade_hmi/baseconfnode.xml
tests/wxGlade/HMIFrame@wxglade_hmi/hmi.wxg
tests/wxGlade/HMIFrame@wxglade_hmi/py_ext.xml
tests/wxGlade/python@py_ext/HMIFrame@wxglade_hmi/baseconfnode.xml
tests/wxGlade/python@py_ext/HMIFrame@wxglade_hmi/hmi.wxg
tests/wxGlade/python@py_ext/HMIFrame@wxglade_hmi/py_ext.xml
tests/wxGlade/python@py_ext/baseconfnode.xml
tests/wxGlade/python@py_ext/py_ext.xml
util/misc.py
wxglade_hmi/README
wxglade_hmi/__init__.py
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 POULibrary import POULibrary
+from PythonFileCTNMixin import PythonFileCTNMixin
 
-from xml.dom import minidom
-from xmlclass import *
-import cPickle
+class PythonLibrary(POULibrary):
+    def GetName(self):
+        return "Python"
 
-PythonClasses = GenerateClassesFromXSD(os.path.join(os.path.dirname(__file__), "py_ext_xsd.xsd")) 
+    def GetLibraryPath(self):
+        return os.path.join(os.path.split(__file__)[0], "pous.xml") 
 
-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)
-
-        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
-
-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])