# HG changeset patch # User laurent # Date 1250070382 -7200 # Node ID b7cb57a2da08ec9a6933cad26bbb1eae1b4ffc61 # Parent ee802ef00ca5226bc6952623f16e301fedb4981a Adding new svgui support using twisted website HMI Updating svgui example diff -r ee802ef00ca5 -r b7cb57a2da08 plugins/python/modules/svgui/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/python/modules/svgui/README Wed Aug 12 11:46:22 2009 +0200 @@ -0,0 +1,1 @@ +SVGUI HMI \ No newline at end of file diff -r ee802ef00ca5 -r b7cb57a2da08 plugins/python/modules/svgui/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/python/modules/svgui/__init__.py Wed Aug 12 11:46:22 2009 +0200 @@ -0,0 +1,1 @@ +from svgui import * diff -r ee802ef00ca5 -r b7cb57a2da08 plugins/python/modules/svgui/livesvg.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/python/modules/svgui/livesvg.js Wed Aug 12 11:46:22 2009 +0200 @@ -0,0 +1,71 @@ +// import Nevow.Athena +// import Divmod.Base +function init() { + Nevow.Athena.Widget.fromAthenaID(1).callRemote('HMIexec', 'initClient'); +} + +function updateAttr(id, param, value) { + Nevow.Athena.Widget.fromAthenaID(1).callRemote('HMIexec', 'setattr', id, param, value); +} + +var svguiWidgets={}; + +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); + newState = json_parse(dataReceived.kwargs).state + svguiWidgets[dataReceived.back_id].updateState(newState); + //console.log("OBJET : " + dataReceived.back_id + " STATE : " + newState); + }, + + function SvguiButton(self,elt_back, args){ + var btn = new svguilib.button(self, elt_back, args.sele_id, args.toggle, args.state, args.active); + return btn; + }, + + function SvguiTextCtrl(self, elt_back, args){ + var txtCtrl = new svguilib.textControl(self, elt_back, args.state); + return txtCtrl; + }, + + function init(self, arg1){ + //console.log("Object received : " + arg1); + for (ind in arg1) { + gad = json_parse(arg1[ind]); + args = json_parse(gad.kwargs); + gadget = self[gad.__class__](gad.back_id, args); + svguiWidgets[gadget.back_elt.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); + } +); + +Divmod.Base.addLoadEvent(init); \ No newline at end of file diff -r ee802ef00ca5 -r b7cb57a2da08 plugins/python/modules/svgui/pous.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/python/modules/svgui/pous.xml Wed Aug 12 11:46:22 2009 +0200 @@ -0,0 +1,1061 @@ +<?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="LOLITECH" + productName="Beremiz" + productVersion="0.0" + creationDateTime="2008-12-14T16:53:26"/> + <contentHeader name="Beremiz non-standard POUs library" + modificationDateTime="2009-07-15T17:13:23"> + <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="Button_toggle" pouType="functionBlock"> + <interface> + <localVars> + <variable name="SVGUI_Command"> + <type> + <derived name="python_poll"/> + </type> + </variable> + </localVars> + <inputVars> + <variable name="back_id"> + <type> + <string/> + </type> + </variable> + <variable name="sele_id"> + <type> + <string/> + </type> + </variable> + <variable name="set_state"> + <type> + <BOOL/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="current_state"> + <type> + <BOOL/> + </type> + </variable> + </outputVars> + <localVars> + <variable name="GetButtonState"> + <type> + <derived name="GetBoolString"/> + </type> + </variable> + </localVars> + </interface> + <body> + <FBD> + <block localId="1" width="125" height="140" typeName="python_poll" instanceName="SVGUI_Command"> + <position x="872" y="137"/> + <inputVariables> + <variable formalParameter="TRIG"> + <connectionPointIn> + <relPosition x="0" y="50"/> + <connection refLocalId="10"> + <position x="872" y="187"/> + <position x="795" y="187"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="CODE"> + <connectionPointIn> + <relPosition x="0" y="110"/> + <connection refLocalId="2" formalParameter="OUT"> + <position x="872" y="247"/> + <position x="678" y="247"/> + <position x="678" y="80"/> + <position x="636" y="80"/> + </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="485" typeName="CONCAT"> + <position x="486" y="25"/> + <inputVariables> + <variable formalParameter="IN1"> + <connectionPointIn> + <relPosition x="0" y="55"/> + <connection refLocalId="3"> + <position x="486" y="80"/> + <position x="380" y="80"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN2"> + <connectionPointIn> + <relPosition x="0" y="120"/> + <connection refLocalId="11"> + <position x="486" y="145"/> + <position x="170" y="145"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN3"> + <connectionPointIn> + <relPosition x="0" y="185"/> + <connection refLocalId="5"> + <position x="486" y="210"/> + <position x="380" y="210"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN4"> + <connectionPointIn> + <relPosition x="0" y="250"/> + <connection refLocalId="12"> + <position x="486" y="275"/> + <position x="205" y="275"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN5"> + <connectionPointIn> + <relPosition x="0" y="315"/> + <connection refLocalId="7"> + <position x="486" y="340"/> + <position x="350" y="340"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN6"> + <connectionPointIn> + <relPosition x="0" y="385"/> + <connection refLocalId="28" formalParameter="CODE"> + <position x="486" y="410"/> + <position x="389" y="410"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN7"> + <connectionPointIn> + <relPosition x="0" y="450"/> + <connection refLocalId="9"> + <position x="486" y="475"/> + <position x="389" y="475"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="150" y="55"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <inVariable localId="3" height="30" width="291"> + <position x="89" y="65"/> + <connectionPointOut> + <relPosition x="291" y="15"/> + </connectionPointOut> + <expression>'int(SVGUI("SvguiButton","'</expression> + </inVariable> + <inVariable localId="5" height="30" width="140"> + <position x="240" y="195"/> + <connectionPointOut> + <relPosition x="140" y="15"/> + </connectionPointOut> + <expression>'",sele_id="'</expression> + </inVariable> + <inVariable localId="7" height="30" width="110"> + <position x="240" y="325"/> + <connectionPointOut> + <relPosition x="110" y="15"/> + </connectionPointOut> + <expression>'",state='</expression> + </inVariable> + <inVariable localId="9" height="30" width="290"> + <position x="99" y="460"/> + <connectionPointOut> + <relPosition x="290" y="15"/> + </connectionPointOut> + <expression>',toggle=True,active=True))'</expression> + </inVariable> + <inVariable localId="10" height="30" width="70"> + <position x="725" y="172"/> + <connectionPointOut> + <relPosition x="70" y="15"/> + </connectionPointOut> + <expression>BOOL#1</expression> + </inVariable> + <inVariable localId="11" height="35" width="85"> + <position x="85" y="130"/> + <connectionPointOut> + <relPosition x="85" y="15"/> + </connectionPointOut> + <expression>back_id</expression> + </inVariable> + <inVariable localId="12" height="35" width="85"> + <position x="120" y="260"/> + <connectionPointOut> + <relPosition x="85" y="15"/> + </connectionPointOut> + <expression>sele_id</expression> + </inVariable> + <inVariable localId="13" height="35" width="100"> + <position x="109" y="395"/> + <connectionPointOut> + <relPosition x="100" y="15"/> + </connectionPointOut> + <expression>set_state</expression> + </inVariable> + <block localId="25" width="145" height="45" typeName="STRING_TO_INT"> + <position x="1052" y="217"/> + <inputVariables> + <variable formalParameter="IN"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="1" formalParameter="RESULT"> + <position x="1052" y="247"/> + <position x="997" y="247"/> + </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="1247" y="217"/> + <inputVariables> + <variable formalParameter="IN"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="25" formalParameter="OUT"> + <position x="1247" y="247"/> + <position x="1197" y="247"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="125" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <outVariable localId="27" height="35" width="145"> + <position x="1402" y="232"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="26" formalParameter="OUT"> + <position x="1402" y="247"/> + <position x="1372" y="247"/> + </connection> + </connectionPointIn> + <expression>current_state</expression> + </outVariable> + <block localId="28" width="140" height="40" typeName="GetBoolString" instanceName="GetButtonState"> + <position x="249" y="380"/> + <inputVariables> + <variable formalParameter="VALUE"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="13"> + <position x="249" y="410"/> + <position x="209" y="410"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="CODE"> + <connectionPointOut> + <relPosition x="140" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + </FBD> + </body> + </pou> + <pou name="TextCtrl" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="back_id"> + <type> + <string/> + </type> + </variable> + <variable name="state"> + <type> + <string/> + </type> + </variable> + </inputVars> + <localVars> + <variable name="SVGUI_TEXTCTRL"> + <type> + <derived name="python_poll"/> + </type> + </variable> + </localVars> + <outputVars> + <variable name="code"> + <type> + <string/> + </type> + </variable> + </outputVars> + </interface> + <body> + <FBD> + <block localId="1" width="265" height="230" typeName="CONCAT"> + <position x="549" y="125"/> + <inputVariables> + <variable formalParameter="IN1"> + <connectionPointIn> + <relPosition x="0" y="40"/> + <connection refLocalId="2"> + <position x="549" y="165"/> + <position x="361" y="165"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN2"> + <connectionPointIn> + <relPosition x="0" y="85"/> + <connection refLocalId="3"> + <position x="549" y="210"/> + <position x="160" y="210"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN3"> + <connectionPointIn> + <relPosition x="0" y="125"/> + <connection refLocalId="5"> + <position x="549" y="250"/> + <position x="195" y="250"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN4"> + <connectionPointIn> + <relPosition x="0" y="165"/> + <connection refLocalId="4"> + <position x="549" y="290"/> + <position x="140" y="290"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN5"> + <connectionPointIn> + <relPosition x="0" y="210"/> + <connection refLocalId="6"> + <position x="549" y="335"/> + <position x="125" y="335"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="265" y="40"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <inVariable localId="2" height="30" width="286"> + <position x="75" y="150"/> + <connectionPointOut> + <relPosition x="286" y="15"/> + </connectionPointOut> + <expression>'SVGUI("SvguiTextCtrl","'</expression> + </inVariable> + <inVariable localId="3" height="35" width="85"> + <position x="75" y="195"/> + <connectionPointOut> + <relPosition x="85" y="15"/> + </connectionPointOut> + <expression>back_id</expression> + </inVariable> + <inVariable localId="4" height="35" width="65"> + <position x="75" y="275"/> + <connectionPointOut> + <relPosition x="65" y="15"/> + </connectionPointOut> + <expression>state</expression> + </inVariable> + <inVariable localId="5" height="30" width="120"> + <position x="75" y="235"/> + <connectionPointOut> + <relPosition x="120" y="15"/> + </connectionPointOut> + <expression>'",state="'</expression> + </inVariable> + <inVariable localId="6" height="30" width="50"> + <position x="75" y="320"/> + <connectionPointOut> + <relPosition x="50" y="15"/> + </connectionPointOut> + <expression>'")'</expression> + </inVariable> + <block localId="7" width="125" height="115" typeName="python_poll" 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="814" 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> + <outVariable localId="8" height="35" width="55"> + <position x="1084" y="150"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="7" formalParameter="RESULT"> + <position x="1084" y="165"/> + <position x="1034" y="165"/> + </connection> + </connectionPointIn> + <expression>code</expression> + </outVariable> + <inVariable localId="9" height="30" width="70"> + <position x="799" y="70"/> + <connectionPointOut> + <relPosition x="70" y="15"/> + </connectionPointOut> + <expression>BOOL#1</expression> + </inVariable> + </FBD> + </body> + </pou> + <pou name="Button" pouType="functionBlock"> + <interface> + <localVars> + <variable name="SVGUI_Command"> + <type> + <derived name="python_poll"/> + </type> + </variable> + </localVars> + <inputVars> + <variable name="back_id"> + <type> + <string/> + </type> + </variable> + <variable name="sele_id"> + <type> + <string/> + </type> + </variable> + <variable name="set_state"> + <type> + <BOOL/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="current_state"> + <type> + <BOOL/> + </type> + </variable> + </outputVars> + <localVars> + <variable name="GetButtonState"> + <type> + <derived name="GetBoolString"/> + </type> + </variable> + </localVars> + </interface> + <body> + <FBD> + <block localId="1" width="125" height="140" typeName="python_poll" instanceName="SVGUI_Command"> + <position x="827" y="168"/> + <inputVariables> + <variable formalParameter="TRIG"> + <connectionPointIn> + <relPosition x="0" y="50"/> + <connection refLocalId="10"> + <position x="827" y="218"/> + <position x="766" y="218"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="CODE"> + <connectionPointIn> + <relPosition x="0" y="110"/> + <connection refLocalId="2" formalParameter="OUT"> + <position x="827" y="278"/> + <position x="679" y="278"/> + <position x="679" y="80"/> + <position x="649" y="80"/> + </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="485" typeName="CONCAT"> + <position x="499" y="25"/> + <inputVariables> + <variable formalParameter="IN1"> + <connectionPointIn> + <relPosition x="0" y="55"/> + <connection refLocalId="3"> + <position x="499" y="80"/> + <position x="378" y="80"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN2"> + <connectionPointIn> + <relPosition x="0" y="120"/> + <connection refLocalId="11"> + <position x="499" y="145"/> + <position x="170" y="145"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN3"> + <connectionPointIn> + <relPosition x="0" y="185"/> + <connection refLocalId="5"> + <position x="499" y="210"/> + <position x="380" y="210"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN4"> + <connectionPointIn> + <relPosition x="0" y="250"/> + <connection refLocalId="12"> + <position x="499" y="275"/> + <position x="205" y="275"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN5"> + <connectionPointIn> + <relPosition x="0" y="315"/> + <connection refLocalId="7"> + <position x="499" y="340"/> + <position x="348" y="340"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN6"> + <connectionPointIn> + <relPosition x="0" y="385"/> + <connection refLocalId="28" formalParameter="CODE"> + <position x="499" y="410"/> + <position x="369" y="410"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN7"> + <connectionPointIn> + <relPosition x="0" y="450"/> + <connection refLocalId="9"> + <position x="499" y="475"/> + <position x="275" y="475"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="150" y="55"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <inVariable localId="3" height="30" width="290"> + <position x="88" y="65"/> + <connectionPointOut> + <relPosition x="290" y="15"/> + </connectionPointOut> + <expression>'int(SVGUI("SvguiButton","'</expression> + </inVariable> + <inVariable localId="5" height="30" width="140"> + <position x="240" y="195"/> + <connectionPointOut> + <relPosition x="140" y="15"/> + </connectionPointOut> + <expression>'",sele_id="'</expression> + </inVariable> + <inVariable localId="7" height="30" width="110"> + <position x="238" y="325"/> + <connectionPointOut> + <relPosition x="110" y="15"/> + </connectionPointOut> + <expression>'",state='</expression> + </inVariable> + <inVariable localId="9" height="30" width="180"> + <position x="225" y="460"/> + <connectionPointOut> + <relPosition x="180" y="15"/> + </connectionPointOut> + <expression>',active=True))'</expression> + </inVariable> + <inVariable localId="10" height="30" width="70"> + <position x="696" y="203"/> + <connectionPointOut> + <relPosition x="70" y="15"/> + </connectionPointOut> + <expression>BOOL#1</expression> + </inVariable> + <inVariable localId="11" height="35" width="85"> + <position x="85" y="130"/> + <connectionPointOut> + <relPosition x="85" y="15"/> + </connectionPointOut> + <expression>back_id</expression> + </inVariable> + <inVariable localId="12" height="35" width="85"> + <position x="120" y="260"/> + <connectionPointOut> + <relPosition x="85" y="15"/> + </connectionPointOut> + <expression>sele_id</expression> + </inVariable> + <inVariable localId="13" height="35" width="100"> + <position x="62" y="395"/> + <connectionPointOut> + <relPosition x="100" y="15"/> + </connectionPointOut> + <expression>set_state</expression> + </inVariable> + <block localId="25" width="145" height="45" typeName="STRING_TO_INT"> + <position x="1014" y="248"/> + <inputVariables> + <variable formalParameter="IN"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="1" formalParameter="RESULT"> + <position x="1014" y="278"/> + <position x="952" y="278"/> + </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="1209" y="248"/> + <inputVariables> + <variable formalParameter="IN"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="25" formalParameter="OUT"> + <position x="1209" y="278"/> + <position x="1159" y="278"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="125" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <outVariable localId="27" height="35" width="145"> + <position x="1364" y="263"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="26" formalParameter="OUT"> + <position x="1364" y="278"/> + <position x="1334" y="278"/> + </connection> + </connectionPointIn> + <expression>current_state</expression> + </outVariable> + <block localId="28" width="140" height="40" typeName="GetBoolString" instanceName="GetButtonState"> + <position x="229" y="380"/> + <inputVariables> + <variable formalParameter="VALUE"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="13"> + <position x="229" y="410"/> + <position x="162" y="410"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="CODE"> + <connectionPointOut> + <relPosition x="140" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + </FBD> + </body> + </pou> + <pou name="Button_led" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="back_id"> + <type> + <string/> + </type> + </variable> + <variable name="sele_id"> + <type> + <string/> + </type> + </variable> + </inputVars> + <inputVars> + <variable name="state"> + <type> + <BOOL/> + </type> + </variable> + </inputVars> + <localVars> + <variable name="SVGUI_Command_LED"> + <type> + <derived name="python_poll"/> + </type> + </variable> + <variable name="GetLEDState"> + <type> + <derived name="GetBoolString"/> + </type> + </variable> + </localVars> + </interface> + <body> + <FBD> + <inVariable localId="1" height="30" width="244"> + <position x="51" y="110"/> + <connectionPointOut> + <relPosition x="244" y="15"/> + </connectionPointOut> + <expression>'SVGUI("SvguiButton","'</expression> + </inVariable> + <inVariable localId="2" height="30" width="140"> + <position x="50" y="255"/> + <connectionPointOut> + <relPosition x="140" y="15"/> + </connectionPointOut> + <expression>'",sele_id="'</expression> + </inVariable> + <inVariable localId="3" height="35" width="85"> + <position x="50" y="185"/> + <connectionPointOut> + <relPosition x="85" y="15"/> + </connectionPointOut> + <expression>back_id</expression> + </inVariable> + <inVariable localId="4" height="35" width="85"> + <position x="50" y="325"/> + <connectionPointOut> + <relPosition x="85" y="15"/> + </connectionPointOut> + <expression>sele_id</expression> + </inVariable> + <inVariable localId="5" height="30" width="165"> + <position x="50" y="545"/> + <connectionPointOut> + <relPosition x="165" y="15"/> + </connectionPointOut> + <expression>',toggle=True)'</expression> + </inVariable> + <inVariable localId="6" height="30" width="120"> + <position x="50" y="400"/> + <connectionPointOut> + <relPosition x="120" y="15"/> + </connectionPointOut> + <expression>'", state='</expression> + </inVariable> + <inVariable localId="9" height="35" width="65"> + <position x="52" y="470"/> + <connectionPointOut> + <relPosition x="65" y="15"/> + </connectionPointOut> + <expression>state</expression> + </inVariable> + <block localId="10" width="80" height="530" typeName="CONCAT"> + <position x="503" y="70"/> + <inputVariables> + <variable formalParameter="IN1"> + <connectionPointIn> + <relPosition x="0" y="55"/> + <connection refLocalId="1"> + <position x="503" y="125"/> + <position x="295" y="125"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN2"> + <connectionPointIn> + <relPosition x="0" y="130"/> + <connection refLocalId="3"> + <position x="503" y="200"/> + <position x="135" y="200"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN3"> + <connectionPointIn> + <relPosition x="0" y="200"/> + <connection refLocalId="2"> + <position x="503" y="270"/> + <position x="190" y="270"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN4"> + <connectionPointIn> + <relPosition x="0" y="270"/> + <connection refLocalId="4"> + <position x="503" y="340"/> + <position x="135" y="340"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN5"> + <connectionPointIn> + <relPosition x="0" y="345"/> + <connection refLocalId="6"> + <position x="503" y="415"/> + <position x="170" y="415"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN6"> + <connectionPointIn> + <relPosition x="0" y="415"/> + <connection refLocalId="28" formalParameter="CODE"> + <position x="503" y="485"/> + <position x="368" y="485"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN7"> + <connectionPointIn> + <relPosition x="0" y="490"/> + <connection refLocalId="5"> + <position x="503" y="560"/> + <position x="215" y="560"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="80" y="55"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <block localId="11" width="125" height="65" typeName="python_poll" instanceName="SVGUI_Command_LED"> + <position x="753" y="135"/> + <inputVariables> + <variable formalParameter="TRIG"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="12"> + <position x="753" y="165"/> + <position x="715" y="165"/> + <position x="715" y="90"/> + <position x="698" y="90"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="CODE"> + <connectionPointIn> + <relPosition x="0" y="55"/> + <connection refLocalId="10" formalParameter="OUT"> + <position x="753" y="190"/> + <position x="658" y="190"/> + <position x="658" y="125"/> + <position x="583" y="125"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="ACK"> + <connectionPointOut> + <relPosition x="125" y="30"/> + </connectionPointOut> + </variable> + <variable formalParameter="RESULT"> + <connectionPointOut> + <relPosition x="125" y="55"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <inVariable localId="12" height="30" width="70"> + <position x="628" y="75"/> + <connectionPointOut> + <relPosition x="70" y="15"/> + </connectionPointOut> + <expression>BOOL#1</expression> + </inVariable> + <block localId="28" width="140" height="40" typeName="GetBoolString" instanceName="GetLEDState"> + <position x="228" y="455"/> + <inputVariables> + <variable formalParameter="VALUE"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="9"> + <position x="228" y="485"/> + <position x="117" y="485"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="CODE"> + <connectionPointOut> + <relPosition x="140" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + </FBD> + </body> + </pou> + </pous> + </types> + <instances> + <configurations/> + </instances> +</project> diff -r ee802ef00ca5 -r b7cb57a2da08 plugins/python/modules/svgui/pyjs/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/python/modules/svgui/pyjs/__init__.py Wed Aug 12 11:46:22 2009 +0200 @@ -0,0 +1,2 @@ +from pyjs import * + diff -r ee802ef00ca5 -r b7cb57a2da08 plugins/python/modules/svgui/pyjs/build.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/python/modules/svgui/pyjs/build.py Wed Aug 12 11:46:22 2009 +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() + diff -r ee802ef00ca5 -r b7cb57a2da08 plugins/python/modules/svgui/pyjs/jsonrpc/README.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/python/modules/svgui/pyjs/jsonrpc/README.txt Wed Aug 12 11:46:22 2009 +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 + diff -r ee802ef00ca5 -r b7cb57a2da08 plugins/python/modules/svgui/pyjs/jsonrpc/django/jsonrpc.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/python/modules/svgui/pyjs/jsonrpc/django/jsonrpc.py Wed Aug 12 11:46:22 2009 +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 + diff -r ee802ef00ca5 -r b7cb57a2da08 plugins/python/modules/svgui/pyjs/jsonrpc/jsonrpc.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/python/modules/svgui/pyjs/jsonrpc/jsonrpc.py Wed Aug 12 11:46:22 2009 +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() + diff -r ee802ef00ca5 -r b7cb57a2da08 plugins/python/modules/svgui/pyjs/jsonrpc/web2py/jsonrpc.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/python/modules/svgui/pyjs/jsonrpc/web2py/jsonrpc.py Wed Aug 12 11:46:22 2009 +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 + diff -r ee802ef00ca5 -r b7cb57a2da08 plugins/python/modules/svgui/pyjs/lib/_pyjs.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/python/modules/svgui/pyjs/lib/_pyjs.js Wed Aug 12 11:46:22 2009 +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; + diff -r ee802ef00ca5 -r b7cb57a2da08 plugins/python/modules/svgui/pyjs/lib/json.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/python/modules/svgui/pyjs/lib/json.js Wed Aug 12 11:46:22 2009 +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; + }; +}()); diff -r ee802ef00ca5 -r b7cb57a2da08 plugins/python/modules/svgui/pyjs/lib/pyjslib.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/python/modules/svgui/pyjs/lib/pyjslib.py Wed Aug 12 11:46:22 2009 +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); ") + diff -r ee802ef00ca5 -r b7cb57a2da08 plugins/python/modules/svgui/pyjs/lib/sys.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/python/modules/svgui/pyjs/lib/sys.py Wed Aug 12 11:46:22 2009 +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; + """) diff -r ee802ef00ca5 -r b7cb57a2da08 plugins/python/modules/svgui/pyjs/pyjs.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/python/modules/svgui/pyjs/pyjs.py Wed Aug 12 11:46:22 2009 +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() + diff -r ee802ef00ca5 -r b7cb57a2da08 plugins/python/modules/svgui/svgui.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/python/modules/svgui/svgui.py Wed Aug 12 11:46:22 2009 +0200 @@ -0,0 +1,105 @@ +import wx +import os, sys + +from plugger import opjimg +from plugins.python import PythonCodeTemplate + +from pyjs import translate + +from docutils import * + +class RootClass: + + PluginMethods = [ + {"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 PluginPath(self): + return os.path.join(self.PlugParent.PluginPath(), "modules", self.PlugType) + + def _getSVGpath(self): + # define name for IEC raw code file + return os.path.join(self.PlugPath(), "gui.svg") + + def _getSVGUIserverpath(self): + return os.path.join(os.path.dirname(__file__), "svgui_server.py") + + def PlugGenerate_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(): + print "SVGUI start" + website.LoadHMI(%(svgui_class)s, %(jsmodules)s) + +def _runtime_%(location)s_cleanup(): + print "SVGUI stop" + 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.GetPlugRoot().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.logger.write_error("No such SVG file: %s\n"%svgpath) + dialog.Destroy() + + def _StartInkscape(self): + svgfile = self._getSVGpath() + if not os.path.isfile(svgfile): + svgfile = None + open_svg(svgfile) diff -r ee802ef00ca5 -r b7cb57a2da08 plugins/python/modules/svgui/svgui_server.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/python/modules/svgui/svgui_server.py Wed Aug 12 11:46:22 2009 +0200 @@ -0,0 +1,84 @@ +#!/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={} + +class SvguiWidget: + + def __init__(self, classname, back_id, **kwargs): + self.classname = classname + self.back_id = back_id + self.attrs = kwargs.copy() + self.lastattrs = kwargs.copy() + self.inhibit = False + self.changed = False + + def setattr(self, attrname, value): + self.attrs[attrname] = value + + def getattr(self, attrname): + return self.args.get(attrname, None) + + def update(self, **kwargs): + for attrname, value in kwargs.iteritems(): + if self.lastattrs.get(attrname, None) != value: + self.changed = True + self.attrs[attrname] = value + self.lastattrs[attrname] = value + interface = website.getHMI() + if interface is not None and self.changed and not self.inhibit: + self.changed = False + interface.sendData(self) + + return self.attrs["state"] + +def convert_to_builtin_type(obj): + # Convert objects to a dictionary of their representation + d = { '__class__':obj.classname, + 'back_id':obj.back_id, + 'kwargs':json.dumps(obj.attrs), + } + return d + +def dataToSend(): + gadgets = [] + for gadget in svguiWidgets.values(): + gadgets.append(unicode(json.dumps(gadget, default=convert_to_builtin_type, indent=2), 'ascii')) + return gadgets + + +class SVGUI_HMI(athena.LiveElement): + jsClass = u"LiveSVGPage.LiveSVGWidget" + + docFactory = loaders.stan(tags.div(render=tags.directive('liveElement'))[ + tags.xml(loaders.xmlfile(os.path.join(WorkingDir, svgfile))), + ]) + + def sendData(self,data): + objDefer = self.callRemote('receiveData',unicode(json.dumps(data, default=convert_to_builtin_type, indent=2), 'ascii')) + + def initClient(self): + self.callRemote('init', dataToSend()) + + def setattr(self, id, attrname, value): + svguiWidgets[id].setattr(attrname, value) + +def SVGUI(*args, **kwargs): + classname, back_id = args + gad = svguiWidgets.get(back_id, None) + if gad is None: + gad = SvguiWidget(classname, back_id, **kwargs) + svguiWidgets[back_id] = gad + gadget = [unicode(json.dumps(gad, default=convert_to_builtin_type, indent=2), 'ascii')] + interface = website.getHMI() + if interface is not None: + interface.callRemote('init', gadget) + + return gad.update(**kwargs) diff -r ee802ef00ca5 -r b7cb57a2da08 plugins/python/modules/svgui/svguilib.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/python/modules/svgui/svguilib.py Wed Aug 12 11:46:22 2009 +0200 @@ -0,0 +1,106 @@ + +class button: + + def __init__(self, parent, back_id, sele_id, toggle, state, active): + self.parent = parent + self.back_elt = getSVGElementById(back_id) + self.sele_elt = getSVGElementById(sele_id) + self.toggle = toggle + self.state = state + self.active = active + self.dragging = False + if toggle: + self.up = not 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("visibility", "hidden") + self.back_elt.setAttribute("visibility", "visible") + else: + self.sele_elt.setAttribute("visibility", "visible") + self.back_elt.setAttribute("visibility", "hidden") + + def updateState(self, value): + self.up = not value + 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.back_elt.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.back_elt.id, 'state', self.state) + elif not self.toggle: + self.up = True + self.state = False + updateAttr(self.back_elt.id, 'state', self.state) + self.updateElements() + self.dragging = False + +class textControl: + + def __init__(self, parent, back_id, state): + self.parent = parent + self.back_elt = getSVGElementById(back_id) + self.state = state + self.setValue(self.state) + + def handleEvent(self, evt): + pass + + def getValue(self): + return self.back_elt.firstChild.firstChild.textContent + + def setValue(self, value): + self.back_elt.firstChild.firstChild.textContent = value + + def updateState(self, value): + self.setValue(value) + \ No newline at end of file diff -r ee802ef00ca5 -r b7cb57a2da08 tests/linux/test_svgui/beremiz.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/linux/test_svgui/beremiz.xml Wed Aug 12 11:46:22 2009 +0200 @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<BeremizRoot URI_location="LOCAL://"> + <TargetType> + <Linux CFLAGS="-fPIC" LDFLAGS="-fPIC"/> + </TargetType> +</BeremizRoot> diff -r ee802ef00ca5 -r b7cb57a2da08 tests/linux/test_svgui/plc.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/linux/test_svgui/plc.xml Wed Aug 12 11:46:22 2009 +0200 @@ -0,0 +1,914 @@ +<?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="LOLITECH" + productName="Beremiz" + productVersion="0.0" + creationDateTime="2008-12-14T16:21:19"/> + <contentHeader name="Beremiz Python Support Tests" + modificationDateTime="2009-08-10T16:18:56"> + <coordinateInfo> + <pageSize x="1024" y="1024"/> + <fbd> + <scaling x="5" y="5"/> + </fbd> + <ld> + <scaling x="5" y="5"/> + </ld> + <sfc> + <scaling x="5" y="5"/> + </sfc> + </coordinateInfo> + </contentHeader> + <types> + <dataTypes/> + <pous> + <pou name="main_pytest" pouType="program"> + <interface> + <localVars> + <variable name="counter"> + <type> + <INT/> + </type> + </variable> + <variable name="DigitalBit0"> + <type> + <BOOL/> + </type> + </variable> + <variable name="DigitalBit1"> + <type> + <BOOL/> + </type> + </variable> + <variable name="DigitalBit2"> + <type> + <BOOL/> + </type> + </variable> + <variable name="DigitalBit3"> + <type> + <BOOL/> + </type> + </variable> + <variable name="DigitalBit4"> + <type> + <BOOL/> + </type> + </variable> + <variable name="DigitalBit5"> + <type> + <BOOL/> + </type> + </variable> + <variable name="DigitalBit6"> + <type> + <BOOL/> + </type> + </variable> + <variable name="DigitalBit7"> + <type> + <BOOL/> + </type> + </variable> + <variable name="Texte_compteur"> + <type> + <derived name="TextCtrl"/> + </type> + </variable> + <variable name="Start_Stop"> + <type> + <derived name="Button_toggle"/> + </type> + </variable> + <variable name="Temoin"> + <type> + <derived name="Button_led"/> + </type> + </variable> + <variable name="Btn1"> + <type> + <derived name="Button"/> + </type> + </variable> + <variable name="Btn2"> + <type> + <derived name="Button"/> + </type> + </variable> + <variable name="Btn3"> + <type> + <derived name="Button"/> + </type> + </variable> + <variable name="Btn4"> + <type> + <derived name="Button"/> + </type> + </variable> + <variable name="Btn5"> + <type> + <derived name="Button"/> + </type> + </variable> + <variable name="Btn6"> + <type> + <derived name="Button"/> + </type> + </variable> + <variable name="Btn7"> + <type> + <derived name="Button"/> + </type> + </variable> + <variable name="Btn8"> + <type> + <derived name="Button"/> + </type> + </variable> + </localVars> + </interface> + <body> + <FBD> + <block localId="32" width="80" height="80" typeName="ADD"> + <position x="150" y="400"/> + <inputVariables> + <variable formalParameter="EN"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="49" formalParameter="current_state"> + <position x="150" y="430"/> + <position x="140" y="430"/> + <position x="140" y="272"/> + <position x="485" y="272"/> + <position x="485" y="150"/> + <position x="425" y="150"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN1"> + <connectionPointIn> + <relPosition x="0" y="50"/> + <connection refLocalId="39"> + <position x="150" y="450"/> + <position x="105" y="450"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN2"> + <connectionPointIn> + <relPosition x="0" y="70"/> + <connection refLocalId="33"> + <position x="150" y="470"/> + <position x="140" y="470"/> + <position x="140" y="500"/> + <position x="345" y="500"/> + <position x="345" y="530"/> + <position x="335" y="530"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="ENO"> + <connectionPointOut> + <relPosition x="80" y="30"/> + </connectionPointOut> + </variable> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="80" y="50"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <inOutVariable localId="33" height="35" width="85"> + <position x="250" y="515"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="32" formalParameter="OUT"> + <position x="250" y="530"/> + <position x="240" y="530"/> + <position x="240" y="450"/> + <position x="230" y="450"/> + </connection> + </connectionPointIn> + <connectionPointOut> + <relPosition x="85" y="15"/> + </connectionPointOut> + <expression>counter</expression> + </inOutVariable> + <inVariable localId="39" height="30" width="60"> + <position x="45" y="435"/> + <connectionPointOut> + <relPosition x="60" y="15"/> + </connectionPointOut> + <expression>INT#1</expression> + </inVariable> + <inVariable localId="41" height="30" width="120"> + <position x="20" y="120"/> + <connectionPointOut> + <relPosition x="120" y="15"/> + </connectionPointOut> + <expression>'stop_back'</expression> + </inVariable> + <inVariable localId="42" height="30" width="120"> + <position x="20" y="170"/> + <connectionPointOut> + <relPosition x="120" y="15"/> + </connectionPointOut> + <expression>'stop_sele'</expression> + </inVariable> + <inVariable localId="46" height="30" width="180"> + <position x="385" y="340"/> + <connectionPointOut> + <relPosition x="180" y="15"/> + </connectionPointOut> + <expression>'text_compteur'</expression> + </inVariable> + <block localId="47" width="130" height="65" typeName="TextCtrl" instanceName="Texte_compteur"> + <position x="715" y="395"/> + <inputVariables> + <variable formalParameter="back_id"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="46"> + <position x="715" y="425"/> + <position x="630" y="425"/> + <position x="630" y="355"/> + <position x="565" y="355"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="state"> + <connectionPointIn> + <relPosition x="0" y="55"/> + <connection refLocalId="83" formalParameter="OUT"> + <position x="715" y="450"/> + <position x="540" y="450"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="code"> + <connectionPointOut> + <relPosition x="130" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <block localId="49" width="240" height="125" typeName="Button_toggle" instanceName="Start_Stop"> + <position x="185" y="115"/> + <inputVariables> + <variable formalParameter="back_id"> + <connectionPointIn> + <relPosition x="0" y="35"/> + <connection refLocalId="41"> + <position x="185" y="150"/> + <position x="160" y="150"/> + <position x="160" y="135"/> + <position x="140" y="135"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="sele_id"> + <connectionPointIn> + <relPosition x="0" y="70"/> + <connection refLocalId="42"> + <position x="185" y="185"/> + <position x="140" y="185"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="set_state"> + <connectionPointIn> + <relPosition x="0" y="105"/> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="current_state"> + <connectionPointOut> + <relPosition x="240" y="35"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <block localId="50" width="115" height="135" typeName="Button_led" instanceName="Temoin"> + <position x="660" y="20"/> + <inputVariables> + <variable formalParameter="back_id"> + <connectionPointIn> + <relPosition x="0" y="40"/> + <connection refLocalId="51"> + <position x="660" y="60"/> + <position x="632" y="60"/> + <position x="632" y="55"/> + <position x="615" y="55"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="sele_id"> + <connectionPointIn> + <relPosition x="0" y="75"/> + <connection refLocalId="52"> + <position x="660" y="95"/> + <position x="625" y="95"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="state"> + <connectionPointIn> + <relPosition x="0" y="115"/> + <connection refLocalId="49" formalParameter="current_state"> + <position x="660" y="135"/> + <position x="545" y="135"/> + <position x="545" y="150"/> + <position x="425" y="150"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables/> + </block> + <inVariable localId="51" height="30" width="110"> + <position x="505" y="40"/> + <connectionPointOut> + <relPosition x="110" y="15"/> + </connectionPointOut> + <expression>'led_stop'</expression> + </inVariable> + <inVariable localId="52" height="30" width="120"> + <position x="505" y="80"/> + <connectionPointOut> + <relPosition x="120" y="15"/> + </connectionPointOut> + <expression>'led_start'</expression> + </inVariable> + <block localId="53" width="235" height="135" typeName="Button" instanceName="Btn1"> + <position x="180" y="620"/> + <inputVariables> + <variable formalParameter="back_id"> + <connectionPointIn> + <relPosition x="0" y="40"/> + <connection refLocalId="54"> + <position x="180" y="660"/> + <position x="130" y="660"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="sele_id"> + <connectionPointIn> + <relPosition x="0" y="75"/> + <connection refLocalId="55"> + <position x="180" y="695"/> + <position x="130" y="695"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="set_state"> + <connectionPointIn> + <relPosition x="0" y="115"/> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="current_state"> + <connectionPointOut> + <relPosition x="235" y="40"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <inVariable localId="54" height="30" width="120"> + <position x="10" y="645"/> + <connectionPointOut> + <relPosition x="120" y="15"/> + </connectionPointOut> + <expression>'btn1_back'</expression> + </inVariable> + <inVariable localId="55" height="30" width="120"> + <position x="10" y="680"/> + <connectionPointOut> + <relPosition x="120" y="15"/> + </connectionPointOut> + <expression>'btn1_sele'</expression> + </inVariable> + <block localId="56" width="240" height="85" typeName="Button" instanceName="Btn2"> + <position x="180" y="785"/> + <inputVariables> + <variable formalParameter="back_id"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="63"> + <position x="180" y="815"/> + <position x="130" y="815"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="sele_id"> + <connectionPointIn> + <relPosition x="0" y="50"/> + <connection refLocalId="67"> + <position x="180" y="835"/> + <position x="155" y="835"/> + <position x="155" y="855"/> + <position x="130" y="855"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="set_state"> + <connectionPointIn> + <relPosition x="0" y="70"/> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="current_state"> + <connectionPointOut> + <relPosition x="240" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <block localId="57" width="240" height="85" typeName="Button" instanceName="Btn3"> + <position x="180" y="895"/> + <inputVariables> + <variable formalParameter="back_id"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="66"> + <position x="180" y="925"/> + <position x="140" y="925"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="sele_id"> + <connectionPointIn> + <relPosition x="0" y="50"/> + <connection refLocalId="65"> + <position x="180" y="945"/> + <position x="157" y="945"/> + <position x="157" y="965"/> + <position x="140" y="965"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="set_state"> + <connectionPointIn> + <relPosition x="0" y="70"/> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="current_state"> + <connectionPointOut> + <relPosition x="240" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <block localId="58" width="240" height="85" typeName="Button" instanceName="Btn4"> + <position x="180" y="1005"/> + <inputVariables> + <variable formalParameter="back_id"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="69"> + <position x="180" y="1035"/> + <position x="140" y="1035"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="sele_id"> + <connectionPointIn> + <relPosition x="0" y="50"/> + <connection refLocalId="70"> + <position x="180" y="1055"/> + <position x="160" y="1055"/> + <position x="160" y="1075"/> + <position x="140" y="1075"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="set_state"> + <connectionPointIn> + <relPosition x="0" y="70"/> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="current_state"> + <connectionPointOut> + <relPosition x="240" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <block localId="59" width="240" height="85" typeName="Button" instanceName="Btn5"> + <position x="180" y="1115"/> + <inputVariables> + <variable formalParameter="back_id"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="72"> + <position x="180" y="1145"/> + <position x="140" y="1145"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="sele_id"> + <connectionPointIn> + <relPosition x="0" y="50"/> + <connection refLocalId="73"> + <position x="180" y="1165"/> + <position x="160" y="1165"/> + <position x="160" y="1185"/> + <position x="140" y="1185"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="set_state"> + <connectionPointIn> + <relPosition x="0" y="70"/> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="current_state"> + <connectionPointOut> + <relPosition x="240" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <block localId="60" width="240" height="85" typeName="Button" instanceName="Btn6"> + <position x="180" y="1230"/> + <inputVariables> + <variable formalParameter="back_id"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="75"> + <position x="180" y="1260"/> + <position x="160" y="1260"/> + <position x="160" y="1255"/> + <position x="140" y="1255"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="sele_id"> + <connectionPointIn> + <relPosition x="0" y="50"/> + <connection refLocalId="76"> + <position x="180" y="1280"/> + <position x="160" y="1280"/> + <position x="160" y="1300"/> + <position x="140" y="1300"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="set_state"> + <connectionPointIn> + <relPosition x="0" y="70"/> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="current_state"> + <connectionPointOut> + <relPosition x="240" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <block localId="61" width="240" height="85" typeName="Button" instanceName="Btn7"> + <position x="180" y="1345"/> + <inputVariables> + <variable formalParameter="back_id"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="78"> + <position x="180" y="1375"/> + <position x="160" y="1375"/> + <position x="160" y="1370"/> + <position x="140" y="1370"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="sele_id"> + <connectionPointIn> + <relPosition x="0" y="50"/> + <connection refLocalId="79"> + <position x="180" y="1395"/> + <position x="160" y="1395"/> + <position x="160" y="1415"/> + <position x="140" y="1415"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="set_state"> + <connectionPointIn> + <relPosition x="0" y="70"/> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="current_state"> + <connectionPointOut> + <relPosition x="240" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <block localId="62" width="240" height="85" typeName="Button" instanceName="Btn8"> + <position x="180" y="1455"/> + <inputVariables> + <variable formalParameter="back_id"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="81"> + <position x="180" y="1485"/> + <position x="140" y="1485"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="sele_id"> + <connectionPointIn> + <relPosition x="0" y="50"/> + <connection refLocalId="82"> + <position x="180" y="1505"/> + <position x="160" y="1505"/> + <position x="160" y="1525"/> + <position x="140" y="1525"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="set_state"> + <connectionPointIn> + <relPosition x="0" y="70"/> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="current_state"> + <connectionPointOut> + <relPosition x="240" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <inVariable localId="63" height="30" width="120"> + <position x="10" y="800"/> + <connectionPointOut> + <relPosition x="120" y="15"/> + </connectionPointOut> + <expression>'btn2_back'</expression> + </inVariable> + <inVariable localId="65" height="35" width="125"> + <position x="15" y="950"/> + <connectionPointOut> + <relPosition x="125" y="15"/> + </connectionPointOut> + <expression>'btn3_sele'</expression> + </inVariable> + <inVariable localId="66" height="35" width="125"> + <position x="15" y="910"/> + <connectionPointOut> + <relPosition x="125" y="15"/> + </connectionPointOut> + <expression>'btn3_back'</expression> + </inVariable> + <inVariable localId="67" height="30" width="120"> + <position x="10" y="840"/> + <connectionPointOut> + <relPosition x="120" y="15"/> + </connectionPointOut> + <expression>'btn2_sele'</expression> + </inVariable> + <inVariable localId="69" height="35" width="125"> + <position x="15" y="1020"/> + <connectionPointOut> + <relPosition x="125" y="15"/> + </connectionPointOut> + <expression>'btn4_back'</expression> + </inVariable> + <inVariable localId="70" height="35" width="125"> + <position x="15" y="1060"/> + <connectionPointOut> + <relPosition x="125" y="15"/> + </connectionPointOut> + <expression>'btn4_sele'</expression> + </inVariable> + <inVariable localId="72" height="35" width="125"> + <position x="15" y="1130"/> + <connectionPointOut> + <relPosition x="125" y="15"/> + </connectionPointOut> + <expression>'btn5_back'</expression> + </inVariable> + <inVariable localId="73" height="35" width="125"> + <position x="15" y="1170"/> + <connectionPointOut> + <relPosition x="125" y="15"/> + </connectionPointOut> + <expression>'btn5_sele'</expression> + </inVariable> + <inVariable localId="75" height="35" width="125"> + <position x="15" y="1240"/> + <connectionPointOut> + <relPosition x="125" y="15"/> + </connectionPointOut> + <expression>'btn6_back'</expression> + </inVariable> + <inVariable localId="76" height="35" width="125"> + <position x="15" y="1285"/> + <connectionPointOut> + <relPosition x="125" y="15"/> + </connectionPointOut> + <expression>'btn6_sele'</expression> + </inVariable> + <inVariable localId="78" height="35" width="125"> + <position x="15" y="1355"/> + <connectionPointOut> + <relPosition x="125" y="15"/> + </connectionPointOut> + <expression>'btn7_back'</expression> + </inVariable> + <inVariable localId="79" height="35" width="125"> + <position x="15" y="1400"/> + <connectionPointOut> + <relPosition x="125" y="15"/> + </connectionPointOut> + <expression>'btn7_sele'</expression> + </inVariable> + <inVariable localId="81" height="35" width="125"> + <position x="15" y="1470"/> + <connectionPointOut> + <relPosition x="125" y="15"/> + </connectionPointOut> + <expression>'btn8_back'</expression> + </inVariable> + <inVariable localId="82" height="35" width="125"> + <position x="15" y="1510"/> + <connectionPointOut> + <relPosition x="125" y="15"/> + </connectionPointOut> + <expression>'btn8_sele'</expression> + </inVariable> + <block localId="83" width="145" height="60" typeName="INT_TO_STRING"> + <position x="395" y="400"/> + <inputVariables> + <variable formalParameter="EN"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="32" formalParameter="ENO"> + <position x="395" y="430"/> + <position x="230" y="430"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN"> + <connectionPointIn> + <relPosition x="0" y="50"/> + <connection refLocalId="33"> + <position x="395" y="450"/> + <position x="365" y="450"/> + <position x="365" y="530"/> + <position x="335" y="530"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="ENO"> + <connectionPointOut> + <relPosition x="145" y="30"/> + </connectionPointOut> + </variable> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="145" y="50"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <outVariable localId="84" height="35" width="125"> + <position x="505" y="645"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="53" formalParameter="current_state"> + <position x="505" y="660"/> + <position x="415" y="660"/> + </connection> + </connectionPointIn> + <expression>DigitalBit0</expression> + </outVariable> + <outVariable localId="85" height="35" width="125"> + <position x="505" y="800"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="56" formalParameter="current_state"> + <position x="505" y="815"/> + <position x="420" y="815"/> + </connection> + </connectionPointIn> + <expression>DigitalBit1</expression> + </outVariable> + <outVariable localId="91" height="35" width="125"> + <position x="515" y="1470"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="62" formalParameter="current_state"> + <position x="515" y="1485"/> + <position x="420" y="1485"/> + </connection> + </connectionPointIn> + <expression>DigitalBit7</expression> + </outVariable> + <outVariable localId="90" height="35" width="125"> + <position x="515" y="1360"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="61" formalParameter="current_state"> + <position x="515" y="1375"/> + <position x="420" y="1375"/> + </connection> + </connectionPointIn> + <expression>DigitalBit6</expression> + </outVariable> + <outVariable localId="89" height="35" width="125"> + <position x="510" y="1245"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="60" formalParameter="current_state"> + <position x="510" y="1260"/> + <position x="420" y="1260"/> + </connection> + </connectionPointIn> + <expression>DigitalBit5</expression> + </outVariable> + <outVariable localId="88" height="35" width="125"> + <position x="510" y="1130"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="59" formalParameter="current_state"> + <position x="510" y="1145"/> + <position x="420" y="1145"/> + </connection> + </connectionPointIn> + <expression>DigitalBit4</expression> + </outVariable> + <outVariable localId="87" height="35" width="125"> + <position x="505" y="1020"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="58" formalParameter="current_state"> + <position x="505" y="1035"/> + <position x="420" y="1035"/> + </connection> + </connectionPointIn> + <expression>DigitalBit3</expression> + </outVariable> + <outVariable localId="86" height="35" width="125"> + <position x="505" y="910"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="57" formalParameter="current_state"> + <position x="505" y="925"/> + <position x="420" y="925"/> + </connection> + </connectionPointIn> + <expression>DigitalBit2</expression> + </outVariable> + </FBD> + </body> + </pou> + </pous> + </types> + <instances> + <configurations> + <configuration name="conf_pytest"> + <resource name="res_pytest"> + <task name="pytest_task" interval="t#100ms" priority="0"/> + <pouInstance name="pytest_instance" typeName="main_pytest"/> + </resource> + </configuration> + </configurations> + </instances> +</project> diff -r ee802ef00ca5 -r b7cb57a2da08 tests/linux/test_svgui/python@python/baseplugin.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/linux/test_svgui/python@python/baseplugin.xml Wed Aug 12 11:46:22 2009 +0200 @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<BaseParams Name="python" IEC_Channel="0"/> diff -r ee802ef00ca5 -r b7cb57a2da08 tests/linux/test_svgui/python@python/python.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/linux/test_svgui/python@python/python.xml Wed Aug 12 11:46:22 2009 +0200 @@ -0,0 +1,8 @@ +<?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> diff -r ee802ef00ca5 -r b7cb57a2da08 tests/linux/test_svgui/python@python/svgui@svgui/baseplugin.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/linux/test_svgui/python@python/svgui@svgui/baseplugin.xml Wed Aug 12 11:46:22 2009 +0200 @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<BaseParams Name="svgui" IEC_Channel="0"/> diff -r ee802ef00ca5 -r b7cb57a2da08 tests/linux/test_svgui/python@python/svgui@svgui/gui.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/linux/test_svgui/python@python/svgui@svgui/gui.svg Wed Aug 12 11:46:22 2009 +0200 @@ -0,0 +1,1505 @@ +<?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="540" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.46" + version="1.0" + sodipodi:docname="interface.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="0.7" + inkscape:cx="207.4416" + inkscape:cy="170.01518" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1161" + inkscape:window-height="726" + inkscape:window-x="0" + inkscape:window-y="25" /> + <defs + id="defs4"> + <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 + gradientTransform="translate(64.28571,-10)" + gradientUnits="userSpaceOnUse" + y2="78.880234" + x2="-50.287159" + y1="27.45166" + x1="-50.287159" + id="linearGradient3459" + xlink:href="#linearGradient3453" + inkscape:collect="always" /> + <filter + id="filter3493" + inkscape:collect="always"> + <feGaussianBlur + id="feGaussianBlur3495" + stdDeviation="1.05" + inkscape:collect="always" /> + </filter> + <linearGradient + gradientUnits="userSpaceOnUse" + y2="76.489952" + x2="96.68087" + y1="43.13879" + x1="96.68087" + id="linearGradient3503" + xlink:href="#linearGradient3497" + inkscape:collect="always" /> + <linearGradient + y2="78.880234" + x2="-50.287159" + y1="27.45166" + x1="-50.287159" + gradientTransform="translate(64.28571,-10)" + gradientUnits="userSpaceOnUse" + id="linearGradient3611" + xlink:href="#linearGradient3453" + 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" /> + <linearGradient + y2="76.489952" + x2="96.68087" + y1="43.13879" + x1="96.68087" + gradientUnits="userSpaceOnUse" + id="linearGradient3635" + xlink:href="#linearGradient3497" + 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="135.03291" + x2="235.86555" + y1="62.306999" + x1="230.31479" + gradientUnits="userSpaceOnUse" + id="linearGradient3702" + xlink:href="#linearGradient3679" + inkscape:collect="always" /> + <linearGradient + y2="74.0345" + x2="222.50246" + y1="102.89583" + x1="223.57851" + gradientTransform="translate(-1.3119965,1.110878)" + gradientUnits="userSpaceOnUse" + id="linearGradient3704" + xlink:href="#linearGradient3687" + 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" /> + <filter + inkscape:collect="always" + id="filter3282"> + <feGaussianBlur + inkscape:collect="always" + stdDeviation="0.75741138" + id="feGaussianBlur3284" /> + </filter> + <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" /> + </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" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Calque 1" + inkscape:groupmode="layer" + id="layer1"> + <rect + style="opacity:1;fill:#666666;fill-opacity:0.98823529;stroke:#cccccc;stroke-width:0.59655923;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3845" + width="307.1463" + height="281.43201" + x="6.9151816" + y="247.25655" + ry="8.4459238" /> + <rect + ry="23.307579" + y="11.523975" + x="10.336278" + height="220.73647" + width="300.55594" + id="rect3700" + style="opacity:1;fill:#7e5dff;fill-opacity:1;stroke:#000000;stroke-width:1.46953177;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + style="opacity:0.21556887;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 219.70636,167.30129 C 219.7842,167.0237 219.8329,166.27935 219.81458,165.64717 L 219.78129,164.49777 L 220.47332,164.74491 C 221.41383,165.0808 222.40712,165.06885 222.91147,164.7156 C 223.14153,164.55445 223.32977,164.5071 223.32977,164.61038 C 223.32977,164.71366 223.24507,164.8505 223.14156,164.91448 C 222.80123,165.12481 222.94478,166.07269 223.42387,166.77867 C 223.68266,167.16002 223.89439,167.54362 223.89439,167.63111 C 223.89439,167.71861 222.92025,167.79375 221.72962,167.7981 L 219.56485,167.80601 L 219.70636,167.30129 z M 238.3202,167.70263 C 238.2492,167.63163 238.44729,167.33953 238.76041,167.05354 L 239.32973,166.53355 L 238.93728,165.5358 C 237.80747,162.66347 237.31045,161.65523 236.50764,160.60717 C 235.30555,159.03784 235.26099,158.93754 234.64292,156.41003 C 234.34387,155.18709 233.79933,153.484 233.43284,152.62538 C 232.60418,150.684 232.46851,150.08316 232.74299,149.57029 C 233.06007,148.97781 232.80853,148.88099 232.269,149.38785 C 231.90727,149.72768 231.79581,150.02727 231.78442,150.69038 C 231.7744,151.27422 231.60641,151.81971 231.26283,152.38417 C 230.3964,153.8076 230.01096,153.58375 230.59915,151.99871 C 230.76723,151.54575 230.97442,150.83637 231.05956,150.42231 C 231.1447,150.00825 231.27353,149.42402 231.34585,149.12403 L 231.47733,148.57859 L 230.50901,148.70704 C 229.24894,148.87419 229.19826,148.49434 230.38764,147.79732 C 230.85346,147.52433 231.23422,147.24102 231.23378,147.16775 C 231.23334,147.09448 230.98003,146.6534 230.67087,146.18758 C 229.96874,145.12966 230.29638,144.9186 231.16664,145.86822 C 231.50692,146.23953 231.97024,146.64229 232.19624,146.76324 C 232.5743,146.96557 232.59732,146.9476 232.4844,146.53831 C 232.2286,145.61118 232.12699,142.12658 232.32838,141.18838 C 232.51412,140.32316 233.0295,135.3695 233.10047,133.76743 C 233.11648,133.40606 233.28588,132.60146 233.47692,131.97943 C 233.66795,131.35741 233.88626,130.4765 233.96205,130.02186 C 234.17129,128.76669 235.59682,125.15866 236.66149,123.18955 C 237.72819,121.21667 239.32762,117.50795 239.32762,117.00737 C 239.32762,116.82671 239.20058,116.63014 239.0453,116.57055 C 238.53535,116.37487 238.73048,116.03694 239.2833,116.15836 C 239.72053,116.25439 239.92968,116.14407 240.59298,115.46752 C 241.59523,114.44527 241.89526,113.57592 242.25609,110.64852 C 242.41602,109.35111 242.60132,108.20148 242.66788,108.09378 C 242.73444,107.98609 242.87823,107.26026 242.98741,106.48084 L 243.18592,105.0637 L 244.0869,105.00605 C 244.74471,104.96396 245.27154,105.07826 246.0388,105.42952 C 247.38375,106.04526 247.7457,106.0346 248.75685,105.34944 C 249.21236,105.04078 249.69302,104.7867 249.82498,104.78481 C 249.95694,104.78293 250.1454,104.56965 250.2438,104.31086 C 250.38079,103.95055 250.5575,103.84034 250.99823,103.84034 C 251.56942,103.84034 253.48172,102.9965 253.59821,102.69306 C 253.63162,102.60603 254.13979,102.26151 254.72747,101.92746 C 255.31516,101.59341 256.30416,100.96839 256.92525,100.53852 C 257.54634,100.10866 258.95927,99.311845 260.06509,98.767833 C 261.17092,98.22382 262.11814,97.668055 262.17004,97.532805 C 262.29844,97.198206 261.91818,95.952875 261.50103,95.341832 C 261.11569,94.777386 261.08027,94.618049 261.34017,94.618049 C 261.43928,94.618049 261.79922,95.179164 262.14006,95.864978 C 262.48089,96.550787 262.85239,97.147631 262.9656,97.191292 C 263.07882,97.234958 263.62122,97.093402 264.17094,96.876725 C 264.72066,96.660047 265.74209,96.362511 266.44078,96.215534 C 267.3432,96.025706 267.98652,95.743661 268.66195,95.241744 C 269.55092,94.581135 269.59307,94.513414 269.31,94.200625 C 269.03241,93.893898 269.03221,93.807341 269.30752,93.159857 C 270.67954,89.933212 271.47704,87.280929 271.89766,84.545814 C 272.09963,83.232437 272.08824,82.871946 271.80964,81.761043 C 271.54066,80.68856 271.51048,79.982895 271.62047,77.338516 C 271.73637,74.552238 271.71608,74.162821 271.44323,73.93637 C 271.09522,73.647553 271.04775,73.039951 271.31771,72.329901 C 271.41814,72.065734 271.59154,71.115532 271.70303,70.218338 C 271.96689,68.094931 272.10277,67.844859 272.9104,67.996369 C 273.3205,68.073308 273.73854,68.009073 274.1236,67.80995 C 274.7507,67.485661 274.90181,67.139394 274.41622,67.139394 C 273.92218,67.139394 272.82641,66.178274 272.4263,65.394001 C 272.10575,64.765669 272.05552,64.344688 272.09532,62.620038 C 272.13319,60.978686 272.08146,60.494064 271.82688,60.105527 C 271.23934,59.20883 271.52348,57.164265 272.23565,57.164265 C 272.50253,57.164265 272.62137,56.98606 272.70633,56.458477 C 273.02138,54.502098 274.36008,53.228779 274.48719,54.764583 C 274.51932,55.152765 274.62088,55.470372 274.71287,55.470372 C 274.80488,55.470372 275.10625,55.173941 275.38259,54.811639 C 275.8359,54.217311 276.40048,53.932303 276.40787,54.294062 C 276.41803,54.791698 276.73116,54.901954 277.31177,54.612309 C 278.09481,54.221677 278.57406,54.324463 278.55295,54.878507 C 278.54104,55.191095 278.61886,55.283661 278.83527,55.214309 C 279.92802,54.864103 279.94279,54.86526 280.0823,55.312011 C 280.25513,55.865429 280.50045,56.028472 281.16581,56.03212 C 281.66433,56.03485 281.68547,56.069383 281.56892,56.690652 C 281.45839,57.279825 281.49718,57.365794 281.95155,57.538546 C 282.3849,57.703303 282.44033,57.807577 282.33923,58.267885 C 282.26732,58.595285 282.34719,59.119705 282.54381,59.611099 L 282.86636,60.417222 L 282.36472,60.782648 C 282.08881,60.983628 281.86307,61.312211 281.86307,61.512828 C 281.86307,61.716414 281.66107,61.969617 281.40591,62.085876 C 281.15107,62.201987 280.69034,62.779007 280.36484,63.389713 C 280.04368,63.992262 279.44122,64.776025 279.02603,65.131412 L 278.27114,65.77757 L 278.32617,67.351298 L 278.38118,68.925019 L 279.03992,69.246532 C 279.40222,69.42336 279.87843,69.572108 280.09816,69.577082 C 280.66524,69.589915 281.97528,71.085578 282.62809,72.465493 C 283.28514,73.854366 283.30992,74.223499 282.78367,74.783663 C 282.36093,75.233647 281.98587,76.745293 281.66835,79.278937 C 281.56457,80.107058 281.30339,81.318606 281.08795,81.971258 C 280.84936,82.694065 280.73118,83.429742 280.78561,83.853363 C 281.65866,90.647241 281.94764,92.745033 282.17238,93.920172 C 282.27241,94.443253 282.27901,94.445401 283.61241,94.390693 L 284.95195,94.335733 L 285.28335,93.407665 C 285.64643,92.390881 286.1919,91.662939 286.1919,92.195179 C 286.1919,92.356185 286.06731,92.901893 285.91503,93.407866 C 285.57933,94.523329 285.66058,94.62856 287.09081,94.930831 C 288.67244,95.2651 289.78114,95.230165 291.64428,94.78736 C 293.16948,94.424871 293.43687,94.288108 294.86391,93.140523 C 295.71987,92.452186 296.76215,91.646012 297.18008,91.349025 C 297.59801,91.052039 298.16789,90.565043 298.44648,90.266821 C 298.72506,89.968593 299.08235,89.724587 299.24046,89.724587 C 299.9175,89.724587 300.68086,91.085596 300.68856,92.306432 C 300.69674,93.603043 301.00781,94.47289 301.68525,95.093512 C 302.4107,95.758111 302.75438,96.905456 302.75438,98.662718 C 302.75438,99.220851 302.83908,99.729845 302.94259,99.793822 C 303.20762,99.957622 303.19985,112.30979 302.93472,112.30979 C 302.82688,112.30979 302.55682,112.47918 302.3346,112.6862 C 302.11238,112.89324 301.81343,113.06263 301.67026,113.06263 C 301.51564,113.06263 301.4239,113.23454 301.44427,113.4861 C 301.49994,114.17336 301.45304,114.25136 301.14025,113.99177 C 300.89439,113.78773 300.81431,113.79184 300.67261,114.01578 C 300.41176,114.42801 300.46012,114.5942 300.87228,114.70198 C 301.07931,114.75613 301.2487,114.86092 301.2487,114.93487 C 301.2487,115.18099 300.40829,115.52279 299.93626,115.46865 C 299.53412,115.42252 299.46966,115.49208 299.46259,115.97988 C 299.45397,116.57416 298.88475,117.39146 298.47947,117.39146 C 298.17947,117.39146 297.15636,118.44852 297.00999,118.90972 C 296.94973,119.09955 296.60838,119.43537 296.25142,119.65599 C 295.89446,119.8766 295.6024,120.12695 295.6024,120.21234 C 295.6024,120.29772 295.41872,120.31954 295.19423,120.26084 C 294.86415,120.17452 294.81015,120.21684 294.91192,120.48206 C 294.98114,120.66244 295.03777,120.8772 295.03777,120.95932 C 295.03777,121.04143 295.2734,121.15573 295.56139,121.21333 C 296.27891,121.35683 297.1239,123.03776 296.47852,123.03776 C 296.33929,123.03776 296.07207,122.86837 295.88472,122.66134 C 295.69735,122.45431 295.44897,122.28492 295.33274,122.28492 C 295.21652,122.28492 294.97438,122.11318 294.79466,121.90328 C 294.53284,121.59749 294.39359,121.5614 294.09409,121.72169 C 293.61877,121.97608 293.61962,122.21779 294.09672,122.47312 C 294.58316,122.73346 294.57998,123.03776 294.09081,123.03776 C 293.88053,123.03776 293.65973,123.1648 293.60016,123.32007 C 293.54056,123.47534 293.29503,123.60238 293.05452,123.60238 C 292.74432,123.60238 292.59974,123.72547 292.55708,124.02586 C 292.51803,124.30081 292.36484,124.45179 292.12029,124.45633 C 291.91313,124.46019 291.63963,124.52762 291.5125,124.6062 C 291.38537,124.68477 291.10223,124.65319 290.8833,124.53603 C 290.49655,124.32904 290.48341,124.14058 290.80183,123.36712 C 290.90424,123.11834 290.84577,123.03776 290.56282,123.03776 C 290.3465,123.03776 290.14662,123.19681 290.08978,123.41418 C 289.96523,123.89046 289.57968,123.90788 289.57968,123.43722 C 289.57968,123.04984 289.07757,122.53609 288.88609,122.72756 C 288.61914,122.99451 288.74052,124.03925 289.06179,124.23988 C 289.48817,124.50616 289.48839,124.78717 289.0621,124.65452 C 288.88095,124.59815 288.624,124.62039 288.4911,124.70394 C 288.11006,124.94348 288.44108,125.49203 289.03882,125.61158 C 289.33629,125.67107 289.57968,125.78547 289.57968,125.86581 C 289.57968,126.13302 288.17359,125.99445 287.82174,125.69256 C 287.50366,125.41965 287.45332,125.42554 287.20538,125.76461 C 286.97227,126.08341 286.88214,126.10056 286.54533,125.89022 C 286.029,125.56778 285.95918,125.67705 286.21415,126.40845 C 286.33419,126.75279 286.61902,127.09032 286.87014,127.18579 C 287.11764,127.27989 287.27244,127.46127 287.22009,127.59583 C 287.10693,127.88667 286.25046,128.30764 285.77189,128.30764 C 285.43691,128.30764 285.02248,129.01131 285.18995,129.29574 C 285.23566,129.37338 285.17632,129.4369 285.05807,129.4369 C 284.93981,129.4369 284.87559,129.53448 284.91535,129.65375 C 285.0007,129.9098 286.75653,130.3932 286.75653,130.16064 C 286.75653,130.07313 286.67184,130.00153 286.56832,130.00153 C 286.4648,130.00153 286.38011,129.87449 286.38011,129.71921 C 286.38011,129.35198 286.59614,129.36297 287.30472,129.76626 C 287.67849,129.97899 287.88383,130.24432 287.8846,130.51552 C 287.88542,130.80592 288.03089,130.97182 288.35632,131.0535 C 288.97289,131.20825 288.95395,131.4345 288.31093,131.59589 C 287.90818,131.69697 287.738,131.63952 287.53513,131.33397 C 287.18639,130.80876 286.86331,130.84083 286.59614,131.42721 C 286.33033,132.0106 286.44447,132.2572 286.92246,132.1322 C 287.21055,132.05686 287.2907,132.16368 287.3542,132.70763 C 287.41938,133.26589 287.34704,133.43853 286.91377,133.75887 C 286.62864,133.96967 286.30918,134.14215 286.20386,134.14215 C 286.09854,134.14215 285.88045,134.34348 285.71922,134.58955 C 285.48093,134.95322 285.46768,135.1283 285.64844,135.52503 C 285.82335,135.90891 285.81877,136.07581 285.62701,136.30687 C 285.4232,136.55246 285.44182,136.64369 285.7405,136.86309 C 286.0848,137.116 286.0777,137.14658 285.54501,137.70415 C 285.24097,138.02239 285.04753,138.28276 285.11515,138.28276 C 285.46711,138.28276 286.56832,137.61454 286.56832,137.40096 C 286.56832,137.26486 286.68224,137.1535 286.82147,137.1535 C 287.23995,137.1535 287.75733,136.45128 287.61364,136.07831 C 287.4907,135.75918 287.47457,135.75883 287.29915,136.0713 C 287.08145,136.45907 286.56832,136.51259 286.56832,136.14752 C 286.56832,136.00829 286.72587,135.7518 286.91842,135.57755 C 287.5253,135.02833 288.79894,135.78729 288.55582,136.55327 C 288.48858,136.76514 288.55931,137.00957 288.72849,137.14998 C 288.98755,137.36498 289.13407,137.90635 288.9332,137.90635 C 288.88818,137.90635 288.62699,137.82105 288.35277,137.71679 C 287.56168,137.41602 287.45422,137.68843 288.06148,138.45517 C 288.48705,138.99249 288.57022,139.21695 288.40497,139.38219 C 288.10639,139.68077 288.46722,139.64695 288.8739,139.33824 C 289.05504,139.20072 289.20326,138.91231 289.20326,138.69732 C 289.20326,138.3557 289.28629,138.3199 289.86199,138.41333 C 290.38078,138.49751 290.52073,138.45738 290.52073,138.2244 C 290.52073,137.81722 290.88353,137.62855 291.14881,137.89777 C 291.31545,138.0669 291.29564,138.17317 291.06581,138.34313 C 290.88577,138.47627 290.77779,138.79914 290.79824,139.14312 C 290.84172,139.874 291.02186,140.16487 291.43101,140.16487 C 291.6089,140.16487 291.92151,140.28172 292.12569,140.42455 C 292.32988,140.56738 292.66633,140.71695 292.87335,140.75693 C 293.17805,140.81575 293.10442,140.90547 292.48698,141.22772 C 291.79324,141.58979 291.67682,141.60102 291.201,141.35171 C 290.91325,141.20094 290.53661,141.13411 290.36401,141.20321 C 290.12453,141.29907 290.20531,141.38043 290.70504,141.54674 C 291.31436,141.7495 291.36015,141.82009 291.36378,142.56235 C 291.36623,143.06472 291.27279,143.3965 291.11137,143.45851 C 290.94849,143.52109 290.88415,143.75513 290.93485,144.10055 C 291.0077,144.59699 290.95723,144.65345 290.35284,144.75153 C 289.88952,144.82671 289.59087,144.76825 289.35698,144.55658 C 289.05001,144.27878 289.01331,144.27924 288.90474,144.56218 C 288.71044,145.06851 288.94369,145.39619 289.43195,145.30285 C 289.69724,145.25214 290.05652,145.36162 290.31701,145.57254 L 290.7555,145.92762 L 290.07438,146.66928 C 289.27947,147.53486 289.24011,147.69113 289.81495,147.69925 C 290.47218,147.70854 290.89715,148.13931 290.89715,148.79622 C 290.89715,149.27095 290.81947,149.38715 290.50214,149.38715 C 290.28488,149.38715 289.85657,149.65538 289.55034,149.9832 L 288.99355,150.57924 L 289.46921,150.9713 C 289.91272,151.33686 289.92471,151.38881 289.64658,151.73978 C 289.42802,152.01558 289.32362,152.05006 289.25603,151.86877 C 289.20529,151.73269 288.9475,151.53912 288.68316,151.43861 C 288.25938,151.27749 288.13767,151.33458 287.65404,151.9213 C 287.04369,152.66177 286.46171,152.77218 285.72241,152.28778 C 285.10799,151.8852 284.19278,152.09209 283.44556,152.80248 C 282.91898,153.30311 282.83957,153.32675 282.61071,153.05099 C 282.43538,152.83972 282.42034,152.70735 282.56169,152.61943 C 282.67383,152.54969 282.79542,152.23853 282.83191,151.92799 L 282.89822,151.36336 L 281.81798,151.42087 C 280.58648,151.48641 279.78637,151.21673 280.562,150.99752 C 280.81177,150.92694 281.19746,150.78043 281.41909,150.67197 C 281.69237,150.53822 281.93137,150.53593 282.16175,150.66486 C 282.43665,150.8187 282.5489,150.76348 282.75025,150.37537 C 283.02695,149.84203 282.94098,149.60986 282.57341,149.89778 C 282.44151,150.00109 282.15699,150.12863 281.94114,150.18119 C 281.61216,150.26129 281.56244,150.20481 281.63371,149.83195 C 281.68204,149.57917 281.62802,149.38715 281.50859,149.38715 C 281.39301,149.38715 281.29844,149.51419 281.29844,149.66947 C 281.29844,149.82474 281.2198,149.95179 281.12367,149.95179 C 280.92187,149.95179 280.35739,149.42196 280.3574,149.23255 C 280.35741,148.96709 281.62002,148.11164 282.19976,147.98431 C 282.53216,147.9113 282.80412,147.73625 282.80412,147.59531 C 282.80412,147.17511 282.4272,147.07075 282.07166,147.39252 C 281.62992,147.79227 281.29844,147.77328 281.29844,147.34821 C 281.29844,146.82149 281.08296,146.71855 280.70203,147.06329 C 280.37217,147.36181 280.35739,147.33306 280.35739,146.39259 C 280.35739,145.85216 280.44403,145.24811 280.54993,145.05025 C 280.70277,144.76465 280.66397,144.64148 280.36171,144.45272 C 279.81979,144.11428 279.86656,143.70497 280.43096,143.84663 C 280.89377,143.96278 281.26652,143.67145 280.92509,143.46044 C 280.5504,143.22886 280.7422,142.97465 281.25139,143.02794 C 281.71078,143.07603 281.76497,143.02385 281.73344,142.56385 C 281.703,142.11986 281.75695,142.05944 282.10986,142.14225 C 282.33643,142.19542 282.64885,142.15618 282.80412,142.05503 C 283.04574,141.89766 283.02382,141.8092 282.65211,141.44148 C 282.22042,141.01441 282.21609,141.01409 281.9382,141.38823 C 281.65128,141.77454 280.82666,141.81803 280.46091,141.46615 C 280.36257,141.37153 280.10162,141.29413 279.88103,141.29413 C 279.47598,141.29413 279.15803,140.84164 278.97371,140.00291 C 278.90124,139.67314 278.96995,139.53407 279.24031,139.46338 C 279.84686,139.30476 279.67451,138.90232 279.03992,138.99546 C 278.61917,139.05721 278.47529,139.00378 278.47529,138.78576 C 278.47529,138.62485 278.55998,138.44085 278.6635,138.37687 C 278.89271,138.23522 278.91559,137.52993 278.69098,137.52993 C 278.40509,137.52993 277.53424,136.61569 277.53424,136.31555 C 277.53424,135.97088 277.90794,135.9161 277.91657,136.25951 C 277.91983,136.3889 278.13562,136.65 278.3961,136.83971 C 278.75572,137.10164 278.93116,137.13366 279.12502,136.97277 C 279.26796,136.85414 279.5963,136.81508 279.87099,136.88403 C 280.28023,136.98674 280.34126,136.95405 280.23881,136.68706 C 280.15609,136.47151 279.97106,136.39466 279.67227,136.45177 C 279.42824,136.49843 279.08026,136.42401 278.89899,136.28641 C 278.59141,136.05293 278.59574,136.03582 278.9637,136.03023 C 279.43045,136.02314 279.98097,135.47045 279.98097,135.00895 C 279.98097,134.82914 279.88882,134.50984 279.77619,134.29939 C 279.58509,133.94231 279.61148,133.92555 280.17134,134.04851 C 280.72194,134.16945 280.7608,134.14726 280.64384,133.77873 C 280.57373,133.55788 280.32964,133.17567 280.10139,132.92939 C 279.76147,132.56262 279.6194,132.51867 279.31611,132.68653 C 278.76855,132.98956 278.4776,133.44025 278.58949,133.81204 C 278.72688,134.26852 278.2671,135.45962 277.95351,135.45962 C 277.69803,135.45962 277.15782,135.02152 277.15782,134.81433 C 277.15782,134.75517 277.31309,134.70677 277.50288,134.70677 C 278.01229,134.70677 278.08954,134.54797 277.87688,133.93794 C 277.71111,133.46241 277.59085,133.38931 276.97424,133.38931 C 276.57151,133.38931 276.16121,133.5118 276.02856,133.67162 C 275.8997,133.82689 275.67759,133.95394 275.53499,133.95394 C 275.39239,133.95394 275.27572,134.11627 275.27572,134.31467 C 275.27572,134.51308 275.16986,134.71244 275.04046,134.7577 C 274.56294,134.92473 275.47355,135.64534 276.10217,135.59789 C 276.6659,135.55533 276.68647,135.58002 276.66466,136.27274 C 276.63469,137.22443 276.34302,137.51431 275.85749,137.07492 C 275.65499,136.89166 275.53037,136.63474 275.58055,136.50398 C 275.71875,136.14381 274.4026,136.24092 274.1073,136.61267 C 273.97357,136.78103 273.59775,136.96771 273.27216,137.0275 C 272.79119,137.11583 272.66213,137.06724 272.58399,136.76844 C 272.50825,136.47879 272.58402,136.40067 272.94072,136.40067 C 273.18982,136.40067 273.39362,136.31597 273.39362,136.21246 C 273.39362,136.10894 273.26912,136.02424 273.11693,136.02424 C 272.91694,136.02424 272.85173,135.83594 272.88167,135.34492 C 272.93278,134.5069 272.3982,134.02678 272.00392,134.5566 C 271.85632,134.75494 271.61773,134.8383 271.37745,134.77547 C 271.16401,134.71965 270.93247,134.76605 270.86292,134.87859 C 270.79337,134.99112 270.46621,135.08915 270.13589,135.09642 C 269.33171,135.11414 268.67293,135.378 269.06479,135.52542 C 269.22007,135.58385 269.59895,135.65646 269.90675,135.68679 C 270.37726,135.73315 270.49826,135.85611 270.6665,136.45885 C 270.77655,136.85316 270.99012,137.25211 271.14109,137.34542 C 271.37542,137.49024 271.36695,137.55062 271.08322,137.75809 C 270.89567,137.89524 270.73206,138.28798 270.70772,138.65952 C 270.68399,139.02164 270.58872,139.37289 270.49599,139.44008 C 270.21404,139.6444 270.53359,140.16487 270.94099,140.16487 C 271.15127,140.16487 271.32331,140.07446 271.32331,139.96397 C 271.32331,139.84636 271.48508,139.81442 271.71355,139.88694 C 271.97901,139.97119 272.18561,139.90001 272.35962,139.66436 C 272.55194,139.40391 272.66963,139.37129 272.83376,139.53298 C 273.08092,139.77645 272.79404,140.47705 272.29714,140.84344 C 271.91778,141.12316 272.14488,141.70459 272.56981,141.54152 C 272.83138,141.44115 272.86832,141.49982 272.77301,141.86427 C 272.70895,142.10925 272.7279,142.3988 272.81513,142.50769 C 272.90236,142.6166 273.03259,142.98096 273.10453,143.31738 C 273.20504,143.78745 273.17184,143.92906 272.9611,143.92906 C 272.51107,143.92906 272.16056,144.46533 272.43307,144.73693 C 272.61134,144.91462 272.73363,144.86824 272.99347,144.52438 L 273.32584,144.08453 L 273.9344,144.59661 C 274.41955,145.00484 274.53139,145.22764 274.48588,145.69519 C 274.4323,146.24549 274.3767,146.2854 273.58493,146.34171 C 272.67931,146.40612 272.42378,146.62207 272.54423,147.22117 C 272.58603,147.42907 272.67239,148.00146 272.73615,148.49316 C 272.8418,149.30803 272.81772,149.38715 272.46411,149.38715 C 271.98984,149.38715 271.95898,149.67662 272.40552,149.93671 C 272.67924,150.09614 272.63341,150.12951 272.13431,150.13427 C 271.804,150.13742 271.49081,150.20946 271.43834,150.29435 C 271.27461,150.55926 271.25384,152.09119 271.4066,152.63378 C 271.529,153.0685 271.49484,153.15136 271.19315,153.15136 C 270.9956,153.15136 270.72175,153.25722 270.58459,153.38662 C 270.38508,153.57483 270.31796,153.57483 270.24895,153.38662 C 270.14322,153.09827 269.69709,153.07781 269.52671,153.3535 C 269.35582,153.63001 270.17587,154.46883 270.61708,154.46883 C 271.21082,154.46883 270.91725,155.09498 270.23127,155.29172 C 269.69951,155.44423 269.57304,155.41314 269.33341,155.07101 C 268.97974,154.56608 268.46413,154.71506 268.66704,155.26356 C 268.80903,155.64739 268.68723,156.40327 268.21732,158.05467 C 268.08323,158.52592 268.0188,159.14838 268.07415,159.43791 C 268.15831,159.8782 268.1167,159.95327 267.8199,159.89665 C 267.44083,159.82435 267.19892,158.98587 267.55713,158.98587 C 267.67395,158.98587 267.71152,158.89199 267.64061,158.77725 C 267.4219,158.42337 266.62234,159.58323 266.82455,159.96105 C 267.11246,160.49903 267.01707,161.02364 266.6077,161.15357 C 266.1244,161.30696 266.22813,161.69473 266.77397,161.77505 C 267.26106,161.84672 267.2955,162.12525 266.87476,162.59016 C 266.58965,162.9052 266.58965,162.93919 266.87476,163.04859 C 267.26856,163.1997 267.2714,163.75961 266.88001,164.08443 C 266.62342,164.29739 266.53941,164.28378 266.32831,163.99508 C 266.19134,163.80778 266.12046,163.54723 266.17078,163.41609 C 266.22806,163.26683 266.04002,163.13321 265.668,163.05881 C 264.89936,162.90508 264.57681,163.10653 265.14112,163.38787 C 265.7993,163.71601 265.76869,164.13506 265.02771,164.94043 C 264.65989,165.34022 264.39772,165.77048 264.44513,165.89655 C 264.49253,166.02263 264.45032,166.17585 264.35132,166.23703 C 264.25233,166.29821 264.17067,166.53383 264.16986,166.76063 C 264.16828,167.20329 263.19614,167.82341 263.07474,167.4592 C 262.98262,167.18285 262.65658,167.22172 262.71271,167.50236 C 262.77888,167.83326 261.40039,167.91961 261.01661,167.60862 C 260.75741,167.39858 260.73643,167.40385 260.87766,167.64352 C 261.01795,167.88159 260.99698,167.88774 260.74388,167.68272 C 260.4986,167.48404 260.4232,167.48404 260.33133,167.68272 C 260.24312,167.87351 260.1954,167.87552 260.10964,167.69208 C 260.03041,167.52261 259.90126,167.51135 259.64008,167.65113 C 259.11808,167.9305 254.15833,167.86327 254.31762,167.57899 C 254.39425,167.44221 254.34536,167.44872 254.18617,167.59647 C 254.04481,167.72769 253.45687,167.83174 252.85678,167.83174 C 252.16363,167.83174 251.75274,167.74803 251.70185,167.59647 C 251.64043,167.41354 251.50862,167.42207 251.1093,167.63482 C 250.68973,167.85836 250.56783,167.86329 250.44329,167.66178 C 250.34101,167.49629 250.25009,167.48107 250.16699,167.61553 C 250.09185,167.73711 249.38467,167.80326 248.36915,167.78372 C 247.37862,167.76466 246.73988,167.67917 246.80467,167.57433 C 246.86669,167.47398 246.81205,167.46027 246.67866,167.54271 C 246.32216,167.76304 243.46824,167.84551 243.46824,167.63548 C 243.46824,167.53639 243.67997,167.45531 243.93876,167.45531 C 244.23153,167.45531 244.40928,167.34866 244.40928,167.173 C 244.40928,166.99733 244.23153,166.89068 243.93876,166.89068 C 243.66335,166.89068 243.46824,166.78259 243.46824,166.63001 C 243.46824,166.48664 243.25374,166.2288 242.9916,166.05703 C 242.52,165.74804 242.512,165.7518 242.23623,166.41181 C 241.90301,167.20932 241.44692,167.28744 241.36337,166.56131 C 241.32141,166.19659 241.1828,166.02651 240.89402,165.98539 C 240.26257,165.89547 240.03702,165.47805 240.03702,164.39931 C 240.03702,163.85542 239.91975,163.243 239.77643,163.03836 C 239.6331,162.83373 239.51582,162.53459 239.51582,162.37359 C 239.51582,162.2126 239.34643,161.93584 239.13941,161.75858 C 238.93237,161.58131 238.75044,161.20254 238.73512,160.91686 C 238.70953,160.43974 238.67643,160.12471 238.60265,159.65568 C 238.58732,159.55825 238.46101,159.63413 238.32196,159.82428 C 238.07934,160.1561 238.04376,160.15187 237.43837,159.7191 C 237.09143,159.4711 236.60722,159.05644 236.36235,158.79766 C 235.95733,158.36963 235.93524,158.36443 236.1177,158.74012 C 236.22802,158.96726 236.39801,159.20239 236.49546,159.26261 C 237.14954,159.66686 239.14016,163.76982 240.00541,166.49712 C 240.34099,167.55492 240.33704,167.83174 239.98635,167.83174 C 239.83108,167.83174 239.70403,167.74704 239.70403,167.64352 C 239.70403,167.54001 239.51347,167.45661 239.28056,167.45819 C 238.93812,167.46053 238.91111,167.49599 239.13941,167.64352 C 239.36181,167.78725 239.31854,167.82658 238.93551,167.82885 C 238.6681,167.83044 238.39121,167.77364 238.3202,167.70263 z M 263.14726,166.04973 C 263.45419,165.81758 263.46362,165.77244 263.20627,165.76741 C 263.0378,165.76412 262.79452,165.88847 262.66566,166.04374 C 262.36535,166.40558 262.67174,166.40939 263.14726,166.04973 z M 269.91174,152.0221 C 269.84776,151.91858 269.75807,151.83388 269.71242,151.83388 C 269.66677,151.83388 269.62942,151.91858 269.62942,152.0221 C 269.62942,152.12561 269.71911,152.21031 269.82874,152.21031 C 269.93837,152.21031 269.97571,152.12561 269.91174,152.0221 z M 284.3098,151.63457 C 284.3098,151.53716 284.18276,151.45746 284.02748,151.45746 C 283.73644,151.45746 283.65357,151.67955 283.86553,151.8915 C 284.01589,152.04187 284.3098,151.8719 284.3098,151.63457 z M 285.43906,151.45746 C 285.43906,151.35395 285.35437,151.26926 285.25085,151.26926 C 285.14733,151.26926 285.06264,151.35395 285.06264,151.45746 C 285.06264,151.56098 285.14733,151.64567 285.25085,151.64567 C 285.35437,151.64567 285.43906,151.56098 285.43906,151.45746 z M 270.38226,151.09215 C 270.38226,150.77663 270.04847,150.69851 269.93736,150.98802 C 269.87182,151.15885 269.93795,151.26926 270.10585,151.26926 C 270.25788,151.26926 270.38226,151.18956 270.38226,151.09215 z M 288.54452,147.88148 C 288.48055,147.77796 288.34351,147.69327 288.24,147.69327 C 288.13648,147.69327 288.10413,147.77796 288.16811,147.88148 C 288.23208,147.98499 288.36912,148.06968 288.47264,148.06968 C 288.57615,148.06968 288.6085,147.98499 288.54452,147.88148 z M 281.94913,144.85711 C 281.7878,144.59606 281.67486,144.64473 281.67486,144.97533 C 281.67486,145.13671 281.76094,145.21555 281.86614,145.15053 C 281.97135,145.08552 282.00869,144.95347 281.94913,144.85711 z M 284.49801,142.80916 C 284.49801,142.71078 284.35191,142.54853 284.17335,142.44861 C 283.99478,142.34867 283.84656,142.11156 283.84398,141.92168 C 283.83648,141.37115 283.49818,141.52267 283.45301,142.09679 C 283.42809,142.41365 283.53241,142.68741 283.71979,142.79685 C 284.11892,143.02997 284.49801,143.03596 284.49801,142.80916 z M 285.99824,142.05431 C 286.15051,141.95802 286.21202,141.81614 286.13492,141.73904 C 286.05781,141.66193 285.85156,141.74202 285.67657,141.91701 C 285.3364,142.25718 285.54003,142.3441 285.99824,142.05431 z M 271.1351,141.58755 C 271.1351,141.25021 270.82414,141.04324 270.56134,141.20567 C 270.42642,141.28904 270.43371,141.41166 270.58438,141.5932 C 270.86876,141.93585 271.1351,141.93312 271.1351,141.58755 z M 285.45091,140.70735 C 285.61283,140.40479 285.57249,140.35307 285.17447,140.35307 C 284.65127,140.35307 284.41338,140.61389 284.56831,141.01765 C 284.69833,141.35647 285.19742,141.181 285.45091,140.70735 z M 270.20406,139.2916 C 270.3535,138.89855 270.32483,138.71946 270.06682,138.43437 C 269.74645,138.08036 269.73503,138.08145 269.42266,138.49557 C 269.17403,138.82519 269.14796,139.01221 269.30314,139.35281 C 269.5671,139.93213 269.97096,139.90469 270.20406,139.2916 z M 290.14431,139.41202 C 290.14431,139.30851 290.01727,139.22381 289.86199,139.22381 C 289.70672,139.22381 289.57968,139.30851 289.57968,139.41202 C 289.57968,139.51554 289.70672,139.60024 289.86199,139.60024 C 290.01727,139.60024 290.14431,139.51554 290.14431,139.41202 z M 287.88579,139.03561 C 287.88579,138.93209 287.73757,138.84869 287.55643,138.85028 C 287.27494,138.85274 287.26811,138.87969 287.50937,139.03561 C 287.86456,139.26515 287.88579,139.26515 287.88579,139.03561 z M 268.50016,138.87876 C 268.50016,138.61391 268.28829,138.49187 268.01232,138.59777 C 267.86776,138.65324 267.79634,138.77445 267.85361,138.86712 C 267.98498,139.07967 268.50016,139.08895 268.50016,138.87876 z M 270.14667,137.48189 C 270.0295,137.13039 269.69103,137.11879 269.35505,137.45477 C 269.10772,137.7021 269.09014,137.80569 269.27601,137.92057 C 269.57363,138.1045 270.24196,137.76777 270.14667,137.48189 z M 281.1319,135.49165 C 281.73594,135.0282 282.20373,134.87306 282.33867,135.09142 C 282.54326,135.42245 282.84927,135.27617 282.74958,134.89498 C 282.69545,134.68796 282.7258,134.51857 282.81704,134.51857 C 283.05055,134.51857 282.80511,133.3562 282.49597,132.99807 C 282.12279,132.56573 282.18178,132.01022 282.63066,131.72988 C 282.93608,131.53914 283.08147,131.5351 283.29394,131.71143 C 283.70711,132.05433 283.80767,131.79634 283.55696,131.03668 C 283.43281,130.66051 283.37639,130.30757 283.43158,130.25238 C 283.61979,130.06417 283.93338,130.39922 283.93338,130.78852 C 283.93338,131.11495 283.97908,131.13895 284.21994,130.93905 C 284.56967,130.6488 284.41958,130.02628 283.90066,129.61473 C 283.57882,129.35949 283.56122,129.25705 283.76306,128.81405 C 284.02015,128.24981 283.9114,128.01537 283.47097,128.18437 C 283.31124,128.24567 283.18054,128.49984 283.18054,128.74921 C 283.18054,129.36478 282.71137,129.70847 281.94181,129.65665 C 281.28785,129.6126 280.16918,130.06285 280.16918,130.3701 C 280.16918,130.46398 279.99979,130.59455 279.79276,130.66026 C 279.58573,130.72597 279.41634,130.85872 279.41634,130.95526 C 279.41634,131.0518 279.58573,131.13079 279.79276,131.13079 C 279.99979,131.13079 280.16918,131.04609 280.16918,130.94258 C 280.16918,130.69976 281.05221,130.69644 281.20193,130.93868 C 281.26459,131.04007 281.21852,131.30486 281.09957,131.52713 C 280.83769,132.01645 281.1349,132.82468 281.57672,132.82468 C 281.75669,132.82468 281.86307,132.99948 281.86307,133.2952 C 281.86307,133.55399 281.78222,133.76572 281.68339,133.76572 C 281.58457,133.76572 281.44695,134.06827 281.37758,134.43805 C 281.29159,134.89639 281.11499,135.16226 280.8227,135.27339 C 280.58689,135.36304 280.33838,135.52632 280.27046,135.63622 C 280.06971,135.96104 280.64622,135.86429 281.1319,135.49165 z M 281.60911,130.47808 C 281.46766,130.10944 281.86057,129.88291 282.06944,130.21268 C 282.30574,130.58574 282.27706,130.75437 281.97731,130.75437 C 281.83312,130.75437 281.66743,130.63004 281.60911,130.47808 z M 274.38843,134.70971 C 274.47109,134.39364 274.39639,134.33036 273.94063,134.33036 C 273.31461,134.33036 273.26839,134.44466 273.70109,134.92278 C 274.05311,135.31175 274.24669,135.25174 274.38843,134.70971 z M 284.68622,134.80973 C 284.68622,134.65934 284.58804,134.3208 284.46804,134.05743 L 284.24987,133.57859 L 284.02759,134.00153 C 283.84894,134.34144 283.86054,134.48911 284.08672,134.75383 C 284.42907,135.15451 284.68622,135.17848 284.68622,134.80973 z M 271.93373,133.81508 C 271.98278,133.52915 272.0863,133.14698 272.16378,132.96584 C 272.28484,132.68275 272.19601,132.63646 271.53166,132.63646 C 270.83988,132.63646 270.75868,132.68421 270.75868,133.091 C 270.75868,133.54843 271.49124,134.55332 271.72113,134.41124 C 271.78901,134.36928 271.88467,134.10102 271.93373,133.81508 z M 270.57048,133.75394 C 270.57048,133.49175 269.87167,133.19217 269.54895,133.31601 C 269.25972,133.42701 269.14409,133.97049 269.36311,134.18951 C 269.51297,134.33937 270.57048,133.95786 270.57048,133.75394 z M 286.75653,133.38931 C 286.75653,133.28579 286.62949,133.2011 286.47421,133.2011 C 286.31894,133.2011 286.1919,133.28579 286.1919,133.38931 C 286.1919,133.49282 286.31894,133.57751 286.47421,133.57751 C 286.62949,133.57751 286.75653,133.49282 286.75653,133.38931 z M 285.59272,132.77602 C 285.64364,132.33488 285.58383,132.26005 285.18035,132.26005 C 284.9208,132.26005 284.65609,132.17535 284.59212,132.07184 C 284.40383,131.76719 283.93214,131.84961 284.05353,132.16594 C 284.11312,132.32121 284.27066,132.44826 284.40364,132.44826 C 284.53661,132.44826 284.69997,132.66562 284.76665,132.93128 C 284.92985,133.58156 285.51238,133.47207 285.59272,132.77602 z M 283.74517,132.77763 C 283.74517,132.55722 283.47099,132.61205 283.39228,132.8482 C 283.35346,132.96466 283.41698,133.02818 283.53344,132.98936 C 283.64989,132.95054 283.74517,132.85526 283.74517,132.77763 z M 278.80858,132.60118 C 278.69225,132.2522 278.28708,132.19431 278.28708,132.52668 C 278.28708,132.69058 278.42118,132.82468 278.58508,132.82468 C 278.74898,132.82468 278.84956,132.7241 278.80858,132.60118 z M 275.96536,131.02403 C 276.13122,130.59179 275.77847,130.33907 275.20884,130.48204 C 274.59992,130.63487 274.58027,130.78853 275.13457,131.06305 C 275.7362,131.36102 275.83788,131.35624 275.96536,131.02403 z M 277.53424,131.02557 C 277.53424,130.97992 277.4022,130.94258 277.24082,130.94258 C 277.07944,130.94258 277.0006,131.02865 277.06561,131.13385 C 277.17304,131.30768 277.53424,131.22423 277.53424,131.02557 z M 278.56356,130.76381 C 278.62433,130.66549 278.50228,130.49312 278.29236,130.38077 C 277.99533,130.22181 277.91066,130.23363 277.91066,130.43406 C 277.91066,130.89786 278.3451,131.11728 278.56356,130.76381 z M 273.86415,129.4369 C 273.92901,129.33194 273.78822,129.24996 273.54589,129.25157 C 273.19626,129.25388 273.1665,129.29011 273.39362,129.4369 C 273.74383,129.66322 273.72427,129.66322 273.86415,129.4369 z M 284.68622,127.5548 C 284.68622,127.45128 284.55918,127.36659 284.40391,127.36659 C 284.24863,127.36659 284.12159,127.45128 284.12159,127.5548 C 284.12159,127.65831 284.24863,127.74301 284.40391,127.74301 C 284.55918,127.74301 284.68622,127.65831 284.68622,127.5548 z M 283.18054,126.99016 C 283.18054,126.88665 282.98998,126.80791 282.75707,126.81519 C 282.353,126.82781 282.35084,126.83583 282.71002,126.99016 C 282.91705,127.07913 283.10761,127.15787 283.13349,127.16515 C 283.15937,127.17242 283.18054,127.09368 283.18054,126.99016 z M 292.36754,123.04952 C 292.41459,122.90836 292.34402,122.83779 292.20285,122.88484 C 292.06699,122.93013 291.91878,123.07834 291.87349,123.2142 C 291.82644,123.35536 291.89701,123.42594 292.03817,123.37889 C 292.17404,123.3336 292.32225,123.18538 292.36754,123.04952 z M 286.00369,122.74433 C 286.00369,122.58295 285.919,122.50325 285.81548,122.56723 C 285.71197,122.63121 285.62727,122.76325 285.62727,122.86066 C 285.62727,122.95806 285.71197,123.03776 285.81548,123.03776 C 285.919,123.03776 286.00369,122.90572 286.00369,122.74433 z M 281.48665,122.04553 C 281.48665,121.78896 280.9063,121.66072 280.69617,121.87085 C 280.58587,121.98116 280.54729,122.20606 280.61044,122.37064 C 280.70671,122.62151 280.78678,122.63145 281.10596,122.43212 C 281.31534,122.30136 281.48665,122.12739 281.48665,122.04553 z M 295.88472,119.08535 C 295.82074,118.98183 295.73105,118.89714 295.6854,118.89714 C 295.63975,118.89714 295.6024,118.98183 295.6024,119.08535 C 295.6024,119.18886 295.69209,119.27356 295.80172,119.27356 C 295.91134,119.27356 295.94869,119.18886 295.88472,119.08535 z M 302.86809,110.10224 C 302.80555,110.0397 302.76106,110.15086 302.76924,110.34926 C 302.77827,110.56852 302.82287,110.61311 302.88295,110.46298 C 302.93732,110.32711 302.93063,110.16478 302.86809,110.10224 z M 241.31625,167.66364 C 241.26726,167.58437 241.39091,167.53157 241.59103,167.54631 C 242.09136,167.58317 242.2164,167.74669 241.76998,167.78031 C 241.56942,167.79542 241.36525,167.74292 241.31625,167.66364 z M 264.73596,167.64352 C 264.73596,167.40771 264.9357,167.40771 265.30059,167.64352 C 265.52889,167.79106 265.50187,167.82652 265.15944,167.82885 C 264.92652,167.83044 264.73596,167.74704 264.73596,167.64352 z M 298.32371,166.50174 C 298.25547,166.39134 298.24484,166.25582 298.30008,166.20058 C 298.43489,166.06576 298.80197,166.30331 298.80197,166.52537 C 298.80197,166.7659 298.47704,166.74984 298.32371,166.50174 z M 302.28591,165.01191 C 302.22307,164.91023 302.39499,164.50793 302.66796,164.11791 C 303.05767,163.56111 303.13507,163.50986 303.0283,163.87932 C 302.66612,165.13262 302.50882,165.37259 302.28591,165.01191 z M 268.1386,163.42448 C 268.13043,163.22608 268.17491,163.11491 268.23746,163.17745 C 268.3,163.23999 268.30668,163.40233 268.25231,163.53819 C 268.19223,163.68834 268.14763,163.64374 268.1386,163.42448 z M 209.8819,153.80282 C 209.63825,153.61848 209.30564,153.56415 208.89379,153.64141 C 208.11698,153.78714 208.10887,153.61191 208.8376,152.42758 C 209.14814,151.92287 209.40222,151.27933 209.40222,150.99749 C 209.40222,150.71565 209.46575,150.51599 209.54339,150.55382 C 209.62102,150.59165 209.91123,150.73651 210.18828,150.87573 C 210.63732,151.10137 210.76557,151.08339 211.36937,150.71023 C 212.2335,150.17616 212.6925,150.29963 212.38138,150.98245 C 212.19352,151.39479 212.22251,151.52426 212.59046,151.91592 C 213.13744,152.49815 212.95798,152.77493 212.03348,152.77493 C 211.62961,152.77493 211.2111,152.8808 211.10347,153.01019 C 210.99584,153.13959 210.75959,153.43339 210.57848,153.66308 C 210.28051,154.04096 210.21422,154.05425 209.8819,153.80282 z M 281.80684,152.09134 C 281.54218,151.82668 281.68605,151.64567 282.16107,151.64567 C 282.46634,151.64567 282.61813,151.73323 282.56895,151.88093 C 282.47835,152.15303 282.00047,152.28496 281.80684,152.09134 z M 277.73731,150.24978 C 277.72914,150.05138 277.77362,149.94021 277.83616,150.00276 C 277.8987,150.0653 277.90539,150.22763 277.85102,150.36349 C 277.79094,150.51363 277.74634,150.46904 277.73731,150.24978 z M 227.94091,149.29888 C 228.52518,148.81996 229.16428,148.67445 229.16428,149.02034 C 229.16428,149.22542 228.0415,149.76428 227.61759,149.76264 C 227.48487,149.76213 227.63036,149.55344 227.94091,149.29888 z M 291.53442,149.11677 C 291.38613,148.73034 291.59498,148.20168 291.83687,148.35118 C 291.94112,148.41561 292.02641,148.62771 292.02641,148.82253 C 292.02641,149.2862 291.67914,149.4939 291.53442,149.11677 z M 299.55481,149.01074 C 299.55481,148.90722 299.6395,148.82253 299.74302,148.82253 C 299.84653,148.82253 299.93123,148.90722 299.93123,149.01074 C 299.93123,149.11425 299.84653,149.19894 299.74302,149.19894 C 299.6395,149.19894 299.55481,149.11425 299.55481,149.01074 z M 294.28493,147.89258 C 294.28493,147.79518 294.36962,147.66314 294.47314,147.59916 C 294.57666,147.53518 294.66135,147.61488 294.66135,147.77626 C 294.66135,147.93765 294.57666,148.06968 294.47314,148.06968 C 294.36962,148.06968 294.28493,147.98999 294.28493,147.89258 z M 299.17839,146.56401 C 299.17839,146.46049 299.26309,146.3758 299.3666,146.3758 C 299.47011,146.3758 299.55481,146.46049 299.55481,146.56401 C 299.55481,146.66752 299.47011,146.75222 299.3666,146.75222 C 299.26309,146.75222 299.17839,146.66752 299.17839,146.56401 z M 302.82244,146.4699 C 302.76286,146.31463 302.76166,146.06366 302.81978,145.91219 C 302.88173,145.75076 302.72379,145.47817 302.43812,145.25346 C 302.16913,145.04187 302.06756,144.8728 302.21142,144.8761 C 302.70676,144.88747 303.03727,145.34324 303.06011,146.04643 C 303.08432,146.79147 303.00207,146.938 302.82244,146.4699 z M 277.91066,146.27507 C 277.91066,146.21967 278.04501,145.96931 278.2092,145.71871 C 278.5615,145.18104 278.38086,144.66992 278.01525,145.16992 C 277.62697,145.70092 277.33499,145.32649 277.64803,144.699 C 277.84147,144.31124 278.02121,144.18143 278.27335,144.24736 C 278.51562,144.31071 278.66661,144.21577 278.75215,143.94627 C 278.82213,143.72579 279.03708,143.55264 279.24082,143.55264 C 279.74472,143.55264 279.7338,144.41129 279.22644,144.68281 C 278.95048,144.8305 278.87828,145.00453 278.95919,145.32694 C 279.04104,145.65302 278.95659,145.84819 278.6367,146.07225 C 278.19856,146.37913 277.91066,146.45956 277.91066,146.27507 z M 276.50098,145.24961 C 276.43596,145.1444 276.5148,145.05832 276.67619,145.05832 C 277.00679,145.05832 277.05546,145.17127 276.79441,145.3326 C 276.69804,145.39216 276.56601,145.35481 276.50098,145.24961 z M 302.56617,143.27033 C 302.56617,143.11506 302.69321,142.98802 302.84848,142.98802 C 303.00376,142.98802 303.1308,143.11506 303.1308,143.27033 C 303.1308,143.4256 303.00376,143.55264 302.84848,143.55264 C 302.69321,143.55264 302.56617,143.4256 302.56617,143.27033 z M 227.95926,142.81895 C 227.50945,142.34945 227.46723,142.21632 227.65622,141.86319 C 227.77698,141.63754 227.83062,141.33521 227.77542,141.19134 C 227.72021,141.04747 227.74365,140.88736 227.82751,140.83553 C 228.03204,140.70912 228.41143,141.57117 228.41143,142.1623 C 228.41143,142.42302 228.49911,142.80016 228.60627,143.00039 C 228.89361,143.53729 228.55705,143.44291 227.95926,142.81895 z M 292.30289,142.97857 C 292.12405,142.68919 292.36901,142.50249 292.61058,142.74405 C 292.74575,142.87923 292.74899,142.9845 292.62045,143.06395 C 292.51506,143.12908 292.37216,143.09065 292.30289,142.97857 z M 301.62512,142.91405 C 301.62512,142.87336 301.75216,142.79133 301.90743,142.73175 C 302.06271,142.67216 302.18975,142.70545 302.18975,142.80571 C 302.18975,142.90598 302.06271,142.98802 301.90743,142.98802 C 301.75216,142.98802 301.62512,142.95473 301.62512,142.91405 z M 278.56939,141.67054 C 278.50542,141.56703 278.62747,141.48233 278.84061,141.48233 C 279.05375,141.48233 279.22813,141.56703 279.22813,141.67054 C 279.22813,141.77406 279.10609,141.85876 278.95692,141.85876 C 278.80776,141.85876 278.63337,141.77406 278.56939,141.67054 z M 293.6594,140.46586 C 293.59842,140.30694 293.62367,140.13048 293.71552,140.07372 C 293.96161,139.92162 294.17028,140.3548 293.95474,140.57033 C 293.83427,140.69081 293.73182,140.65457 293.6594,140.46586 z M 302.8641,140.56654 C 302.78302,140.43536 302.76751,140.2772 302.82964,140.21508 C 302.99808,140.04664 303.18174,140.29437 303.09076,140.56731 C 303.02701,140.75856 302.98268,140.75841 302.8641,140.56654 z M 277.20487,139.93526 C 276.5546,139.62148 276.70045,139.41263 277.53099,139.46824 C 278.27355,139.51797 279.08845,139.97666 278.43422,139.97666 C 278.26671,139.97666 278.01686,140.01332 277.879,140.05813 C 277.74114,140.10294 277.43779,140.04765 277.20487,139.93526 z M 271.44305,139.12863 C 271.37749,138.9578 271.44363,138.8474 271.61154,138.8474 C 271.91594,138.8474 271.98519,139.1415 271.71945,139.30573 C 271.62679,139.363 271.5024,139.28331 271.44305,139.12863 z M 301.34281,138.65919 C 301.27883,138.55567 301.40087,138.47098 301.61401,138.47098 C 301.82715,138.47098 302.00154,138.55567 302.00154,138.65919 C 302.00154,138.7627 301.8795,138.8474 301.73033,138.8474 C 301.58117,138.8474 301.40678,138.7627 301.34281,138.65919 z M 302.76924,137.2633 C 302.76106,137.06489 302.80555,136.95373 302.86809,137.01627 C 302.93063,137.07881 302.93732,137.24114 302.88295,137.37701 C 302.82287,137.52715 302.77827,137.48255 302.76924,137.2633 z M 288.90081,135.91474 C 288.96364,135.75101 289.01505,135.58162 289.01505,135.53833 C 289.01505,135.41077 289.69395,135.44841 289.82899,135.58346 C 290.027,135.78146 289.56866,136.21246 289.16008,136.21246 C 288.89681,136.21246 288.82029,136.12459 288.90081,135.91474 z M 279.03992,134.89498 C 279.03992,134.79147 279.12462,134.70677 279.22813,134.70677 C 279.33165,134.70677 279.41634,134.79147 279.41634,134.89498 C 279.41634,134.9985 279.33165,135.0832 279.22813,135.0832 C 279.12462,135.0832 279.03992,134.9985 279.03992,134.89498 z M 288.47005,134.9111 C 288.15531,134.71181 288.32847,134.14215 288.70378,134.14215 C 289.05592,134.14215 289.4555,134.63911 289.30246,134.88674 C 289.15502,135.1253 288.82365,135.13499 288.47005,134.9111 z M 276.30578,134.32211 C 276.15559,134.0791 276.57352,133.54314 276.80273,133.6848 C 276.89451,133.74153 276.96961,133.95233 276.96961,134.15325 C 276.96961,134.539 276.5118,134.65545 276.30578,134.32211 z M 302.75438,133.96504 C 302.75438,133.85542 302.83908,133.76572 302.94259,133.76572 C 303.0461,133.76572 303.1308,133.80307 303.1308,133.84872 C 303.1308,133.89437 303.0461,133.98406 302.94259,134.04804 C 302.83908,134.11202 302.75438,134.07467 302.75438,133.96504 z M 288.07557,133.01767 C 287.86062,132.8819 287.84663,132.78856 288.01587,132.61931 C 288.28162,132.35357 288.88903,132.54402 288.78368,132.86006 C 288.68103,133.168 288.40935,133.22847 288.07557,133.01767 z M 289.20326,131.05291 C 289.20326,130.90596 289.30825,130.75074 289.43656,130.70797 C 289.58327,130.65906 289.64693,130.36397 289.60807,129.9129 C 289.55586,129.30699 289.5951,129.21433 289.86068,129.31624 C 290.03361,129.3826 290.30428,129.4369 290.46216,129.4369 C 290.66284,129.4369 290.70753,129.536 290.61069,129.76626 C 290.5345,129.94742 290.45515,130.26158 290.43436,130.4644 C 290.38756,130.92093 289.20326,131.48707 289.20326,131.05291 z M 286.75653,128.68406 C 286.75653,128.58054 286.84123,128.49585 286.94474,128.49585 C 287.04826,128.49585 287.13295,128.58054 287.13295,128.68406 C 287.13295,128.78757 287.04826,128.87227 286.94474,128.87227 C 286.84123,128.87227 286.75653,128.78757 286.75653,128.68406 z M 288.78475,127.84943 C 288.53045,127.49951 288.51381,127.38254 288.70772,127.30813 C 289.06167,127.1723 289.29503,127.39465 289.31231,127.88416 C 289.33125,128.42096 289.19352,128.4119 288.78475,127.84943 z M 291.11673,125.6727 C 291.21146,125.38849 291.51412,125.3592 291.60294,125.62564 C 291.64607,125.75504 291.5402,125.8609 291.36768,125.8609 C 291.19515,125.8609 291.08222,125.77621 291.11673,125.6727 z M 292.40283,125.67861 C 292.40283,125.57834 292.52987,125.54505 292.68515,125.60463 C 292.84042,125.66422 292.96746,125.74626 292.96746,125.78694 C 292.96746,125.82762 292.84042,125.8609 292.68515,125.8609 C 292.52987,125.8609 292.40283,125.77887 292.40283,125.67861 z M 294.09672,124.00185 C 294.09672,123.76118 294.65013,123.34022 294.78682,123.47691 C 294.92352,123.61361 294.50256,124.16702 294.26188,124.16702 C 294.17104,124.16702 294.09672,124.09269 294.09672,124.00185 z M 297.39843,120.22761 C 297.25924,120.0024 297.6133,119.77925 297.86399,119.93419 C 298.07447,120.06428 297.93629,120.40282 297.67271,120.40282 C 297.58141,120.40282 297.45799,120.32397 297.39843,120.22761 z M 298.04913,119.27356 C 298.04913,119.06443 298.1746,118.89714 298.33145,118.89714 C 298.48829,118.89714 298.61376,119.06443 298.61376,119.27356 C 298.61376,119.48268 298.48829,119.64998 298.33145,119.64998 C 298.1746,119.64998 298.04913,119.48268 298.04913,119.27356 z M 301.85395,114.89768 C 302.16545,113.98707 302.7478,113.66692 302.70983,114.42715 C 302.68517,114.921 302.2384,115.50936 301.88805,115.50936 C 301.69605,115.50936 301.68885,115.38028 301.85395,114.89768 z M 225.39251,114.36595 C 225.21313,114.03078 225.0747,113.99377 224.41651,114.10496 C 223.71817,114.22295 223.66252,114.20316 223.7946,113.88385 C 224.22201,112.85046 224.42583,111.87466 224.33334,111.30467 C 224.19302,110.43999 224.48924,110.32019 225.09277,110.99755 C 225.64304,111.61514 226.01186,111.67804 226.71755,111.27463 C 227.28327,110.95124 228.22323,110.90799 228.22323,111.20537 C 228.22323,111.32254 228.04415,111.70816 227.82528,112.0623 C 227.54859,112.51 227.46114,112.8752 227.53826,113.26083 C 227.63998,113.76945 227.60538,113.81546 227.12106,113.81546 C 226.75036,113.81546 226.51789,113.95571 226.34112,114.28599 C 226.03465,114.85865 225.67253,114.88917 225.39251,114.36595 z M 240.59803,103.88584 C 240.31336,103.70935 240.08046,103.4941 240.08046,103.40751 C 240.08046,103.32092 240.33454,103.431 240.64508,103.65213 C 240.95563,103.87326 241.20972,104.09076 241.20972,104.13547 C 241.20972,104.25549 241.16441,104.23699 240.59803,103.88584 z M 236.35013,99.779158 C 235.60833,99.144197 235.36942,98.758667 235.71775,98.758667 C 235.94685,98.758667 237.44551,100.07742 237.44551,100.27901 C 237.44551,100.59649 237.14456,100.45916 236.35013,99.779158 z M 239.19847,95.944886 C 238.49157,95.51386 238.27936,95.1606 238.0128,93.971147 C 237.84445,93.219927 237.87006,92.963761 238.18462,92.252643 C 238.5741,91.372162 239.01973,91.087607 240.29136,90.907391 C 240.8823,90.823641 241.07742,90.90534 241.76063,91.522586 C 242.8781,92.532146 243.15359,93.266375 242.79562,94.280967 C 242.45191,95.255139 242.04733,95.723545 241.26281,96.055602 C 240.43691,96.405168 239.90671,96.376728 239.19847,95.944886 z M 235.78443,95.123499 C 235.55936,94.883911 235.37379,94.523963 235.37205,94.323605 C 235.37031,94.123247 234.99735,93.324103 234.54324,92.54774 C 233.6329,90.991399 233.60055,90.589195 234.46754,91.606691 C 235.249,92.523789 236.76766,95.559098 236.44505,95.559098 C 236.30679,95.559098 236.00951,95.36308 235.78443,95.123499 z M 232.17425,94.72156 C 231.60568,94.359859 230.8864,93.941458 230.57585,93.791772 C 230.06553,93.5458 228.76476,92.359529 229.00535,92.359529 C 229.20167,92.359529 232.37218,94.188194 233.00143,94.664349 C 233.19682,94.812211 233.32324,95.033539 233.28236,95.156189 C 233.23474,95.299032 232.83644,95.142806 232.17425,94.72156 z M 259.93618,94.805568 C 259.87197,94.70167 259.61289,94.668508 259.36044,94.731863 C 258.85223,94.859416 258.74382,94.511415 259.09017,93.864261 C 259.21632,93.628541 259.21632,93.472962 259.09017,93.395001 C 258.47382,93.01407 259.31916,92.537611 260.1918,92.774088 C 260.7236,92.918199 260.80988,93.016011 260.7378,93.39306 C 260.69072,93.639356 260.71819,93.947655 260.79885,94.078163 C 260.87951,94.208672 260.86374,94.468227 260.7638,94.654963 C 260.5657,95.025118 260.1218,95.105899 259.93618,94.805568 z M 261.39359,94.006367 C 261.28971,93.876971 261.21581,93.432329 261.22939,93.018262 C 261.25,92.389897 261.3241,92.255482 261.67755,92.205283 C 261.99623,92.160018 262.10102,92.238775 262.10102,92.523543 C 262.10102,92.731663 262.01221,92.956827 261.90367,93.023915 C 261.76855,93.107425 261.77519,93.228853 261.92473,93.409043 C 262.15597,93.687673 262.04208,94.241627 261.75356,94.241627 C 261.65947,94.241627 261.49748,94.135762 261.39359,94.006367 z M 260.72082,92.234053 C 260.48859,92.001826 260.59282,91.41848 260.86655,91.41848 C 261.22287,91.41848 261.3774,91.687964 261.23455,92.060227 C 261.11274,92.377666 260.9272,92.440446 260.72082,92.234053 z M 227.37628,91.24849 C 227.06574,91.053087 226.38818,90.50703 225.8706,90.035021 C 225.00373,89.244474 224.96664,89.176739 225.40008,89.17573 C 225.70415,89.175018 226.26268,89.527159 226.97893,90.17115 C 228.1465,91.220929 228.39249,91.887896 227.37628,91.24849 z M 232.59036,90.254021 C 232.24342,89.604952 231.88923,89.215845 230.77506,88.259752 C 230.37903,87.919907 230.10901,87.587857 230.17502,87.521855 C 230.24102,87.455847 230.48525,87.577216 230.71775,87.791559 C 230.95025,88.005901 231.4741,88.337958 231.88187,88.529455 C 232.46965,88.805504 232.7126,89.082368 233.05451,89.865749 C 233.41383,90.689025 233.43783,90.853847 233.19836,90.853847 C 233.0403,90.853847 232.76669,90.58393 232.59036,90.254021 z M 287.25867,90.258788 C 287.13184,89.773797 287.44535,89.107251 287.75218,89.209526 C 288.00272,89.293043 288.23843,90.083118 288.1164,90.430375 C 287.98022,90.817904 287.37312,90.696457 287.25867,90.258788 z M 288.86683,89.877508 C 288.40282,89.413494 288.69895,88.862262 289.29033,89.089199 C 289.46949,89.157949 289.5756,89.369723 289.54258,89.592643 C 289.47329,90.06035 289.1753,90.185975 288.86683,89.877508 z M 286.06153,88.577889 C 285.73539,88.251744 285.98354,87.842489 286.50744,87.842489 C 286.87989,87.842489 286.95911,87.925289 286.91078,88.26404 C 286.84314,88.738138 286.38945,88.905806 286.06153,88.577889 z M 287.91716,88.595327 C 288.0119,88.311122 288.31455,88.281834 288.40337,88.548278 C 288.4465,88.677674 288.34063,88.783538 288.16811,88.783538 C 287.99558,88.783538 287.88265,88.698844 287.91716,88.595327 z M 288.82684,88.507845 C 288.82684,88.138396 289.43824,87.826959 289.76593,88.029484 C 289.98094,88.162373 289.98335,88.241615 289.7798,88.486882 C 289.46978,88.860432 288.82684,88.874578 288.82684,88.507845 z M 287.949,87.547521 C 287.79213,87.138739 288.19037,86.754309 288.47541,87.039355 C 288.71633,87.280269 288.56708,87.842489 288.26221,87.842489 C 288.1522,87.842489 288.01125,87.709756 287.949,87.547521 z M 201.40331,82.660883 C 200.7165,82.097912 200.47473,82.085034 199.84801,82.578006 C 199.13935,83.13544 199.01536,82.812885 199.42831,81.486106 C 199.64576,80.787426 199.74807,80.083876 199.68098,79.748456 C 199.55566,79.121877 199.67716,79.072136 200.36815,79.467142 C 201.03292,79.847167 201.34645,79.816061 202.53801,79.251887 C 203.76154,78.672571 204.22172,78.827264 203.6898,79.639066 C 203.29788,80.237217 203.29399,80.848693 203.67941,81.274577 C 203.95879,81.583284 203.92659,81.632863 203.20889,81.999007 C 202.69893,82.25917 202.43846,82.51802 202.43846,82.764645 C 202.43846,83.259759 202.09149,83.224979 201.40331,82.660883 z M 227.94091,82.572612 C 227.87694,82.469095 227.91428,82.3844 228.02391,82.3844 C 228.13353,82.3844 228.22323,82.469095 228.22323,82.572612 C 228.22323,82.676122 228.18588,82.760823 228.14023,82.760823 C 228.09458,82.760823 228.00489,82.676122 227.94091,82.572612 z M 242.61862,77.436638 C 242.29094,76.914171 242.11866,76.824425 241.34821,76.77484 C 240.24851,76.704065 240.19155,76.39843 241.11561,75.526927 C 241.62962,75.042157 241.77434,74.757913 241.77434,74.233201 C 241.77434,73.443113 242.04782,73.200505 242.49199,73.596538 C 242.66662,73.75224 243.36884,73.938472 244.05248,74.010385 C 245.71636,74.185408 245.88939,74.307566 245.38383,74.95027 C 245.01167,75.423398 245.00325,75.50293 245.26026,76.118035 C 245.60273,76.937683 245.50061,77.114523 244.68483,77.114523 C 244.20635,77.114523 243.96256,77.235064 243.73324,77.585044 C 243.32843,78.202878 243.07831,78.169573 242.61862,77.436638 z M 204.32056,70.400598 C 202.68357,69.694661 201.567,68.339694 200.82534,66.159135 C 200.27051,64.52786 200.26522,64.297923 200.75011,62.888552 C 201.47312,60.787079 203.4628,59.401188 205.30901,59.713103 C 206.68239,59.945136 207.44087,60.301979 208.88923,61.397468 C 210.79678,62.840286 211.27644,63.921242 210.8077,65.72089 C 210.35904,67.443424 209.53637,68.622909 207.83259,69.986408 C 207.02899,70.62952 206.8073,70.713574 205.95049,70.700029 C 205.41633,70.691582 204.68286,70.556843 204.32056,70.400598 z M 200.27405,39.735698 C 200.01496,39.536446 199.67763,39.480341 199.19184,39.555702 C 198.58663,39.649581 198.48605,39.614497 198.48605,39.309523 C 198.48605,39.113912 198.61654,38.64156 198.77602,38.25986 C 199.03718,37.634827 199.03718,37.508096 198.77602,36.984594 C 198.44753,36.326114 198.40312,36.011281 198.66125,36.170813 C 198.75762,36.230365 198.89101,36.190832 198.95768,36.082955 C 199.03213,35.962498 199.29689,36.070239 199.64386,36.3622 C 200.22354,36.849965 201.36364,37.018073 201.59152,36.649374 C 201.65549,36.545857 201.79922,36.461163 201.91093,36.461163 C 202.27394,36.461163 201.91084,38.873069 201.45503,39.489597 C 200.9973,40.108692 200.80985,40.14776 200.27405,39.735698 z M 269.88239,30.607758 C 269.55354,30.278916 269.41927,30.248735 269.08384,30.428253 C 268.42261,30.782127 268.31182,30.488957 268.72817,29.487114 C 269.07026,28.663947 269.09169,28.44725 268.89569,27.793065 C 268.5348,26.588509 268.8765,26.367912 269.89724,27.146473 C 270.49022,27.598761 270.54506,27.606704 271.1961,27.334678 C 272.33952,26.856932 273.06206,27.031366 272.35847,27.615293 C 271.98226,27.927519 272.00153,28.362595 272.40552,28.677421 C 272.71232,28.916517 272.69799,28.963062 272.19623,29.356903 C 271.89996,29.589447 271.37631,30.054968 271.03256,30.391391 C 270.6888,30.727814 270.37833,31.003074 270.34262,31.003074 C 270.30692,31.003074 270.09981,30.825186 269.88239,30.607758 z M 289.53759,24.644019 C 288.248,23.704445 287.92186,22.287926 288.68878,20.957331 C 289.12861,20.194235 289.88211,19.707265 291.22575,19.317764 C 291.91442,19.118124 292.07145,19.128266 292.36195,19.391159 C 292.55718,19.567844 292.86533,19.652726 293.09423,19.592869 C 293.43892,19.502729 293.5054,19.593846 293.61435,20.305785 C 294.13125,23.683287 293.95968,24.187378 292.09387,24.773033 C 290.50776,25.270895 290.38982,25.264938 289.53759,24.644019 z" + id="path3837" /> + <g + transform="translate(-127.27923,-40.406102)" + id="g3695"> + <rect + style="opacity:1;fill:url(#linearGradient3702);fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3677" + width="163.64471" + height="53.538086" + x="148.49243" + y="62.806999" + ry="17.172594" /> + <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;opacity:1;fill:url(#linearGradient3704);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold" + xml:space="preserve"><tspan + y="102.99694" + x="154.30698" + id="tspan3191" + sodipodi:role="line" + style="fill:url(#linearGradient3704);fill-opacity:1">Default</tspan></text> + </g> + <g + id="stop_back" + transform="translate(0.286069,64.064558)"> + <rect + y="27.45166" + x="28.284271" + height="60" + width="150" + id="rect2391" + style="opacity:1;fill:#008000;fill-opacity:1;stroke:#004600;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <path + id="text3505" + d="M 71.749548,45.419324 L 71.749548,50.974012 C 70.308122,50.329501 68.901873,49.843173 67.530798,49.515027 C 66.159689,49.186924 64.864768,49.022862 63.646033,49.02284 C 62.028833,49.022862 60.833522,49.245518 60.060095,49.690809 C 59.286649,50.136142 58.89993,50.827547 58.899939,51.765027 C 58.89993,52.468171 59.157742,53.018951 59.673376,53.417371 C 60.20071,53.804107 61.149928,54.138091 62.521033,54.419324 L 65.403845,54.999402 C 68.321796,55.585355 70.396012,56.475979 71.626501,57.671277 C 72.856947,58.866602 73.472181,60.565819 73.472205,62.768934 C 73.472181,65.66347 72.610854,67.819718 70.88822,69.237684 C 69.177264,70.643934 66.558126,71.347058 63.030798,71.347059 C 61.366725,71.347058 59.696804,71.188855 58.021033,70.872449 C 56.345245,70.556043 54.669466,70.087294 52.993689,69.466199 L 52.993689,63.753309 C 54.669466,64.64394 56.286652,65.317767 57.845251,65.774793 C 59.415555,66.22011 60.927272,66.442766 62.380408,66.442762 C 63.856956,66.442766 64.987815,66.196673 65.772986,65.70448 C 66.558126,65.212299 66.950703,64.509174 66.95072,63.595105 C 66.950703,62.774801 66.681172,62.141989 66.142126,61.696668 C 65.614767,61.251365 64.554221,60.852928 62.960486,60.501355 L 60.341345,59.921277 C 57.716338,59.358789 55.794465,58.462305 54.57572,57.231824 C 53.368686,56.00137 52.765171,54.343169 52.765173,52.257215 C 52.765171,49.643955 53.60892,47.634191 55.296423,46.227918 C 56.983916,44.821694 59.409695,44.11857 62.573767,44.118543 C 64.015159,44.11857 65.49758,44.229898 67.021033,44.452527 C 68.544452,44.663491 70.120622,44.985756 71.749548,45.419324 M 86.022986,45.559949 L 86.022986,51.149793 L 92.509314,51.149793 L 92.509314,55.649793 L 86.022986,55.649793 L 86.022986,63.999402 C 86.022976,64.913471 86.204616,65.534564 86.567908,65.862684 C 86.931178,66.179094 87.65188,66.337297 88.730017,66.337293 L 91.964392,66.337293 L 91.964392,70.837293 L 86.567908,70.837293 C 84.083525,70.837293 82.319855,70.321668 81.276892,69.290418 C 80.245638,68.247452 79.730013,66.483782 79.730017,63.999402 L 79.730017,55.649793 L 76.601111,55.649793 L 76.601111,51.149793 L 79.730017,51.149793 L 79.730017,45.559949 L 86.022986,45.559949 M 105.20072,61.977918 C 103.88821,61.977927 102.89798,62.200583 102.23002,62.645887 C 101.57376,63.091207 101.24563,63.747456 101.24564,64.614637 C 101.24563,65.411517 101.50931,66.03847 102.03666,66.495496 C 102.57571,66.940812 103.31985,67.163468 104.26908,67.163465 C 105.45266,67.163468 106.44875,66.741594 107.25736,65.89784 C 108.06594,65.042377 108.47024,63.975972 108.47025,62.698621 L 108.47025,61.977918 L 105.20072,61.977918 M 114.81595,59.604871 L 114.81595,70.837293 L 108.47025,70.837293 L 108.47025,67.919324 C 107.62649,69.114638 106.67727,69.987684 105.62259,70.538465 C 104.5679,71.077527 103.28469,71.347058 101.77299,71.347059 C 99.733917,71.347058 98.075715,70.755262 96.798376,69.571668 C 95.532749,68.376358 94.899937,66.829484 94.899939,64.931043 C 94.899937,62.622457 95.690952,60.9291 97.272986,59.850965 C 98.86673,58.772852 101.36282,58.23379 104.76127,58.233777 L 108.47025,58.233777 L 108.47025,57.74159 C 108.47024,56.74551 108.07766,56.018948 107.29252,55.561902 C 106.50735,55.093168 105.28274,54.858793 103.61869,54.858777 C 102.27102,54.858793 101.01712,54.993559 99.856967,55.263074 C 98.696809,55.532621 97.618685,55.936917 96.622595,56.475965 L 96.622595,51.677137 C 97.970247,51.349031 99.323764,51.102938 100.68314,50.938855 C 102.04251,50.763094 103.40188,50.675204 104.76127,50.675184 C 108.31203,50.675204 110.87258,51.378328 112.44291,52.784559 C 114.02492,54.179106 114.81593,56.452542 114.81595,59.604871 M 135.32963,56.511121 C 134.77883,56.253323 134.22805,56.065823 133.67728,55.948621 C 133.1382,55.81973 132.59328,55.755277 132.04252,55.755262 C 130.42532,55.755277 129.17727,56.276761 128.29838,57.319715 C 127.43118,58.350977 126.99759,59.833398 126.9976,61.76698 L 126.9976,70.837293 L 120.70463,70.837293 L 120.70463,51.149793 L 126.9976,51.149793 L 126.9976,54.384168 C 127.80618,53.095123 128.73196,52.157624 129.77494,51.571668 C 130.82961,50.974032 132.08938,50.675204 133.55424,50.675184 C 133.76516,50.675204 133.99367,50.686922 134.23978,50.71034 C 134.48586,50.722079 134.84328,50.757235 135.31205,50.815809 L 135.32963,56.511121 M 145.36674,45.559949 L 145.36674,51.149793 L 151.85306,51.149793 L 151.85306,55.649793 L 145.36674,55.649793 L 145.36674,63.999402 C 145.36673,64.913471 145.54837,65.534564 145.91166,65.862684 C 146.27493,66.179094 146.99563,66.337297 148.07377,66.337293 L 151.30814,66.337293 L 151.30814,70.837293 L 145.91166,70.837293 C 143.42727,70.837293 141.6636,70.321668 140.62064,69.290418 C 139.58939,68.247452 139.07376,66.483782 139.07377,63.999402 L 139.07377,55.649793 L 135.94486,55.649793 L 135.94486,51.149793 L 139.07377,51.149793 L 139.07377,45.559949 L 145.36674,45.559949" + 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:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:inherit;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold" /> + <rect + transform="matrix(0.9845239,0,0,0.9404762,89.413075,12.253075)" + ry="0" + style="opacity:0.656;fill:url(#linearGradient3459);fill-opacity:1;stroke:none;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter3493)" + id="rect3443" + width="150" + height="60" + x="-61.001446" + y="17.45166" /> + <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;opacity:1;fill:url(#linearGradient3635);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:inherit;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold" + xml:space="preserve"><tspan + style="fill:url(#linearGradient3635);fill-opacity:1;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none" + y="68.857597" + x="151.45537" + id="tspan2395" + sodipodi:role="line">Start</tspan></text> + </g> + <g + transform="translate(-7.1060996e-2,64.064558)" + id="stop_sele" + style="fill:#aaffaa"> + <rect + y="27.45166" + x="28.284271" + height="60" + width="150" + id="rect2399" + style="opacity:1;fill:#d40000;fill-opacity:1;stroke:#460000;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <rect + transform="matrix(0.9845239,0,0,0.9404762,89.399683,12.179511)" + ry="0" + style="opacity:0.656;fill:url(#linearGradient3611);fill-opacity:1;stroke:none;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter3493)" + id="rect3606" + width="150" + height="60" + x="-61.001446" + y="17.45166" /> + <text + xml:space="preserve" + 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;opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:inherit;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold" + x="149.02681" + y="65.85762" + id="text3629" + sodipodi:linespacing="100%"><tspan + sodipodi:role="line" + id="tspan3631" + x="149.02681" + y="65.85762" + style="fill:#000000;fill-opacity:1;stroke:none;stroke-opacity:1">Stop</tspan></text> + <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;opacity:1;fill:url(#linearGradient3627);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:inherit;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold" + xml:space="preserve"><tspan + style="fill:url(#linearGradient3627);fill-opacity:1;stroke:#000000;stroke-opacity:1" + y="66.643318" + x="147.74109" + id="tspan2403" + sodipodi:role="line">Stop</tspan></text> + </g> + <g + transform="translate(-174.42209,-117.52177)" + id="led_start"> + <path + transform="translate(42.282829,64.376725)" + d="M 369.71585,101.69787 A 17.67767,17.67767 0 1 1 334.36051,101.69787 A 17.67767,17.67767 0 1 1 369.71585,101.69787 z" + sodipodi:ry="17.67767" + sodipodi:rx="17.67767" + sodipodi:cy="101.69787" + sodipodi:cx="352.03818" + id="pathLed" + style="fill:#00a000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + sodipodi:type="arc" /> + <path + sodipodi:type="arc" + style="fill:url(#radialGradient3667);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path3637" + 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 334.36051,101.69787 A 17.67767,17.67767 0 1 1 369.71585,101.69787 z" + transform="matrix(0.8261431,0,0,0.7784811,103.21328,86.631883)" /> + </g> + <g + transform="translate(-202.76944,-75.680942)" + id="led_stop"> + <path + sodipodi:type="arc" + style="fill:#aa0000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + 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 334.36051,101.69787 A 17.67767,17.67767 0 1 1 369.71585,101.69787 z" + transform="translate(70.630181,22.535893)" /> + <path + transform="matrix(0.9090863,0,0,0.9090863,102.31059,31.95276)" + d="M 369.71585,101.69787 A 17.67767,17.67767 0 1 1 334.36051,101.69787 A 17.67767,17.67767 0 1 1 369.71585,101.69787 z" + sodipodi:ry="17.67767" + sodipodi:rx="17.67767" + sodipodi:cy="101.69787" + sodipodi:cx="352.03818" + id="path3657" + style="fill:url(#radialGradient3675);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + sodipodi:type="arc" /> + </g> + <rect + ry="10.442315" + y="258.65915" + x="21.174957" + height="258.62674" + width="278.62677" + id="rect3847" + style="opacity:1;fill:#cccccc;fill-opacity:0.98823529;stroke:#cccccc;stroke-width:0.54468107;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <g + id="g3711" + transform="translate(-85.548344,-33.843)"> + <g + transform="translate(93.215391,172.26837)" + id="btn8_back"> + <g + id="g3374"> + <rect + transform="matrix(0.9865021,0,0,0.9851426,-29.297383,20.381906)" + ry="8.4908352" + y="284.95181" + x="145.96704" + height="70.205612" + width="77.276665" + id="rect3376" + style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3282)" /> + <rect + style="fill:#999999;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3378" + width="76.771591" + height="68.690376" + x="115.15739" + y="300.60916" + ry="8.307579" /> + <rect + ry="6.4750247" + y="308.1853" + x="121.6041" + height="53.53809" + width="63.639606" + id="rect3380" + style="opacity:0.66167662;fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <rect + style="opacity:0.66167662;fill:url(#linearGradient3550);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3382" + width="63.639606" + height="53.53809" + x="121.6041" + y="308.1853" + ry="6.4750247" /> + <text + id="text3384" + y="352.05981" + x="138.20212" + style="font-size:46.92830658px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" + xml:space="preserve"><tspan + y="352.05981" + x="138.20212" + id="tspan3386" + sodipodi:role="line">8</tspan></text> + </g> + </g> + <g + transform="translate(0,172.26837)" + id="btn7_back"> + <g + id="g3390"> + <rect + style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3282)" + id="rect3392" + width="77.276665" + height="70.205612" + x="145.96704" + y="284.95181" + ry="8.4908352" + transform="matrix(0.9865021,0,0,0.9851426,-29.297383,20.381906)" /> + <rect + ry="8.307579" + y="300.60916" + x="115.15739" + height="68.690376" + width="76.771591" + id="rect3394" + style="fill:#999999;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <rect + style="opacity:0.66167662;fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3396" + width="63.639606" + height="53.53809" + x="121.6041" + y="308.1853" + ry="6.4750247" /> + <rect + ry="6.4750247" + y="308.1853" + x="121.6041" + height="53.53809" + width="63.639606" + id="rect3398" + style="opacity:0.66167662;fill:url(#linearGradient3548);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <text + xml:space="preserve" + style="font-size:46.92830658px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" + x="138.20212" + y="352.05981" + id="text3400"><tspan + sodipodi:role="line" + id="tspan3402" + x="138.20212" + y="352.05981">7</tspan></text> + </g> + </g> + <g + transform="translate(186.43078,86.134184)" + id="btn6_back"> + <g + id="g3406"> + <rect + transform="matrix(0.9865021,0,0,0.9851426,-29.297383,20.381906)" + ry="8.4908352" + y="284.95181" + x="145.96704" + height="70.205612" + width="77.276665" + id="rect3408" + style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3282)" /> + <rect + style="fill:#999999;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3410" + width="76.771591" + height="68.690376" + x="115.15739" + y="300.60916" + ry="8.307579" /> + <rect + ry="6.4750247" + y="308.1853" + x="121.6041" + height="53.53809" + width="63.639606" + id="rect3412" + style="opacity:0.66167662;fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <rect + style="opacity:0.66167662;fill:url(#linearGradient3546);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3414" + width="63.639606" + height="53.53809" + x="121.6041" + y="308.1853" + ry="6.4750247" /> + <text + id="text3416" + y="352.05981" + x="138.20212" + style="font-size:46.92830658px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" + xml:space="preserve"><tspan + y="352.05981" + x="138.20212" + id="tspan3418" + sodipodi:role="line">6</tspan></text> + </g> + </g> + <g + transform="translate(93.215391,86.134184)" + id="btn5_back"> + <g + id="g3422"> + <rect + style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3282)" + id="rect3424" + width="77.276665" + height="70.205612" + x="145.96704" + y="284.95181" + ry="8.4908352" + transform="matrix(0.9865021,0,0,0.9851426,-29.297383,20.381906)" /> + <rect + ry="8.307579" + y="300.60916" + x="115.15739" + height="68.690376" + width="76.771591" + id="rect3426" + style="fill:#999999;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <rect + style="opacity:0.66167662;fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3428" + width="63.639606" + height="53.53809" + x="121.6041" + y="308.1853" + ry="6.4750247" /> + <rect + ry="6.4750247" + y="308.1853" + x="121.6041" + height="53.53809" + width="63.639606" + id="rect3430" + style="opacity:0.66167662;fill:url(#linearGradient3544);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <text + xml:space="preserve" + style="font-size:46.92830658px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" + x="138.20212" + y="352.05981" + id="text3432"><tspan + sodipodi:role="line" + id="tspan3434" + x="138.20212" + y="352.05981">5</tspan></text> + </g> + </g> + <g + transform="translate(0,86.134184)" + id="btn4_back"> + <g + id="g3438"> + <rect + transform="matrix(0.9865021,0,0,0.9851426,-29.297383,20.381906)" + ry="8.4908352" + y="284.95181" + x="145.96704" + height="70.205612" + width="77.276665" + id="rect3440" + style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3282)" /> + <rect + style="fill:#999999;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3442" + width="76.771591" + height="68.690376" + x="115.15739" + y="300.60916" + ry="8.307579" /> + <rect + ry="6.4750247" + y="308.1853" + x="121.6041" + height="53.53809" + width="63.639606" + id="rect3444" + style="opacity:0.66167662;fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <rect + style="opacity:0.66167662;fill:url(#linearGradient3542);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3446" + width="63.639606" + height="53.53809" + x="121.6041" + y="308.1853" + ry="6.4750247" /> + <text + id="text3448" + y="352.05981" + x="138.20212" + style="font-size:46.92830658px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" + xml:space="preserve"><tspan + y="352.05981" + x="138.20212" + id="tspan3450" + sodipodi:role="line">4</tspan></text> + </g> + </g> + <g + transform="translate(186.43078,0)" + id="btn3_back"> + <g + id="g3454"> + <rect + style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3282)" + id="rect3456" + width="77.276665" + height="70.205612" + x="145.96704" + y="284.95181" + ry="8.4908352" + transform="matrix(0.9865021,0,0,0.9851426,-29.297383,20.381906)" /> + <rect + ry="8.307579" + y="300.60916" + x="115.15739" + height="68.690376" + width="76.771591" + id="rect3458" + style="fill:#999999;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <rect + style="opacity:0.66167662;fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3460" + width="63.639606" + height="53.53809" + x="121.6041" + y="308.1853" + ry="6.4750247" /> + <rect + ry="6.4750247" + y="308.1853" + x="121.6041" + height="53.53809" + width="63.639606" + id="rect3462" + style="opacity:0.66167662;fill:url(#linearGradient3540);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <text + xml:space="preserve" + style="font-size:46.92830658px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" + x="138.20212" + y="352.05981" + id="text3464"><tspan + sodipodi:role="line" + id="tspan3466" + x="138.20212" + y="352.05981">3</tspan></text> + </g> + </g> + <g + transform="translate(93.215391,0)" + id="btn2_back"> + <g + id="g3470"> + <rect + transform="matrix(0.9865021,0,0,0.9851426,-29.297383,20.381906)" + ry="8.4908352" + y="284.95181" + x="145.96704" + height="70.205612" + width="77.276665" + id="rect3472" + style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3282)" /> + <rect + style="fill:#999999;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3474" + width="76.771591" + height="68.690376" + x="115.15739" + y="300.60916" + ry="8.307579" /> + <rect + ry="6.4750247" + y="308.1853" + x="121.6041" + height="53.53809" + width="63.639606" + id="rect3476" + style="opacity:0.66167662;fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <rect + style="opacity:0.66167662;fill:url(#linearGradient3538);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3478" + width="63.639606" + height="53.53809" + x="121.6041" + y="308.1853" + ry="6.4750247" /> + <text + id="text3480" + y="352.05981" + x="138.20212" + style="font-size:46.92830658px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" + xml:space="preserve"><tspan + y="352.05981" + x="138.20212" + id="tspan3482" + sodipodi:role="line">2</tspan></text> + </g> + </g> + <g + id="btn1_back"> + <g + id="g3486"> + <rect + style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3282)" + id="rect3488" + width="77.276665" + height="70.205612" + x="145.96704" + y="284.95181" + ry="8.4908352" + transform="matrix(0.9865021,0,0,0.9851426,-29.297383,20.381906)" /> + <rect + ry="8.307579" + y="300.60916" + x="115.15739" + height="68.690376" + width="76.771591" + id="rect3490" + style="fill:#999999;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <rect + style="opacity:0.66167662;fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3492" + width="63.639606" + height="53.53809" + x="121.6041" + y="308.1853" + ry="6.4750247" /> + <rect + ry="6.4750247" + y="308.1853" + x="121.6041" + height="53.53809" + width="63.639606" + id="rect3494" + style="opacity:0.66167662;fill:url(#linearGradient3536);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <text + xml:space="preserve" + style="font-size:46.92830658px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" + x="138.20212" + y="352.05981" + id="text3496"><tspan + sodipodi:role="line" + id="tspan3498" + x="138.20212" + y="352.05981">1</tspan></text> + </g> + </g> + </g> + <g + id="g3777" + transform="translate(-384.28572,268.57142)"> + <g + id="btn8_sele" + transform="translate(311.39817,-21.175851)"> + <g + id="g3566"> + <rect + style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3282)" + id="rect3568" + width="77.276665" + height="70.205612" + x="145.96704" + y="284.95181" + ry="8.4908352" + transform="matrix(0.9866385,0,0,0.9745014,51.2371,-85.940146)" /> + <rect + ry="8.307579" + y="191.51268" + x="194.95944" + height="68.690376" + width="76.771591" + id="rect3570" + style="opacity:1;fill:#999999;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <rect + style="opacity:0.66167662;fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3572" + width="63.639606" + height="53.53809" + x="201.40616" + y="199.08882" + ry="6.4750247" /> + <rect + transform="scale(-1,-1)" + ry="6.4750247" + y="-252.62691" + x="-265.04575" + height="53.53809" + width="63.639606" + id="rect3574" + style="opacity:0.66167662;fill:url(#linearGradient3709);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <text + xml:space="preserve" + style="font-size:46.92830658px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" + x="218.00417" + y="242.96333" + id="text3576"><tspan + sodipodi:role="line" + id="tspan3578" + x="218.00417" + y="242.96333">8</tspan></text> + </g> + </g> + <g + transform="translate(218.19294,-21.175851)" + id="btn7_sele"> + <g + id="g3582"> + <rect + transform="matrix(0.9866385,0,0,0.9745014,51.2371,-85.940146)" + ry="8.4908352" + y="284.95181" + x="145.96704" + height="70.205612" + width="77.276665" + id="rect3584" + style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3282)" /> + <rect + style="opacity:1;fill:#999999;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3586" + width="76.771591" + height="68.690376" + x="194.95944" + y="191.51268" + ry="8.307579" /> + <rect + ry="6.4750247" + y="199.08882" + x="201.40616" + height="53.53809" + width="63.639606" + id="rect3588" + style="opacity:0.66167662;fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <rect + style="opacity:0.66167662;fill:url(#linearGradient3707);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3590" + width="63.639606" + height="53.53809" + x="-265.04575" + y="-252.62691" + ry="6.4750247" + transform="scale(-1,-1)" /> + <text + id="text3592" + y="242.96333" + x="218.00417" + style="font-size:46.92830658px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" + xml:space="preserve"><tspan + y="242.96333" + x="218.00417" + id="tspan3594" + sodipodi:role="line">7</tspan></text> + </g> + </g> + <g + id="btn6_sele" + transform="translate(404.60341,-106.55242)"> + <g + id="g3598"> + <rect + style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3282)" + id="rect3600" + width="77.276665" + height="70.205612" + x="145.96704" + y="284.95181" + ry="8.4908352" + transform="matrix(0.9866385,0,0,0.9745014,51.2371,-85.940146)" /> + <rect + ry="8.307579" + y="191.51268" + x="194.95944" + height="68.690376" + width="76.771591" + id="rect3602" + style="opacity:1;fill:#999999;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <rect + style="opacity:0.66167662;fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3604" + width="63.639606" + height="53.53809" + x="201.40616" + y="199.08882" + ry="6.4750247" /> + <rect + transform="scale(-1,-1)" + ry="6.4750247" + y="-252.62691" + x="-265.04575" + height="53.53809" + width="63.639606" + id="rect3607" + style="opacity:0.66167662;fill:url(#linearGradient3705);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <text + xml:space="preserve" + style="font-size:46.92830658px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" + x="218.00417" + y="242.96333" + id="text3609"><tspan + sodipodi:role="line" + id="tspan3611" + x="218.00417" + y="242.96333">6</tspan></text> + </g> + </g> + <g + transform="translate(311.39817,-106.55242)" + id="btn5_sele"> + <g + id="g3615"> + <rect + transform="matrix(0.9866385,0,0,0.9745014,51.2371,-85.940146)" + ry="8.4908352" + y="284.95181" + x="145.96704" + height="70.205612" + width="77.276665" + id="rect3617" + style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3282)" /> + <rect + style="opacity:1;fill:#999999;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3619" + width="76.771591" + height="68.690376" + x="194.95944" + y="191.51268" + ry="8.307579" /> + <rect + ry="6.4750247" + y="199.08882" + x="201.40616" + height="53.53809" + width="63.639606" + id="rect3621" + style="opacity:0.66167662;fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <rect + style="opacity:0.66167662;fill:url(#linearGradient3703);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3623" + width="63.639606" + height="53.53809" + x="-265.04575" + y="-252.62691" + ry="6.4750247" + transform="scale(-1,-1)" /> + <text + id="text3625" + y="242.96333" + x="218.00417" + style="font-size:46.92830658px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" + xml:space="preserve"><tspan + y="242.96333" + x="218.00417" + id="tspan3627" + sodipodi:role="line">5</tspan></text> + </g> + </g> + <g + id="btn4_sele" + transform="translate(218.19294,-106.55242)"> + <g + id="g3631"> + <rect + style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3282)" + id="rect3633" + width="77.276665" + height="70.205612" + x="145.96704" + y="284.95181" + ry="8.4908352" + transform="matrix(0.9866385,0,0,0.9745014,51.2371,-85.940146)" /> + <rect + ry="8.307579" + y="191.51268" + x="194.95944" + height="68.690376" + width="76.771591" + id="rect3635" + style="opacity:1;fill:#999999;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <rect + style="opacity:0.66167662;fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3637" + width="63.639606" + height="53.53809" + x="201.40616" + y="199.08882" + ry="6.4750247" /> + <rect + transform="scale(-1,-1)" + ry="6.4750247" + y="-252.62691" + x="-265.04575" + height="53.53809" + width="63.639606" + id="rect3639" + style="opacity:0.66167662;fill:url(#linearGradient3700);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <text + xml:space="preserve" + style="font-size:46.92830658px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" + x="218.00417" + y="242.96333" + id="text3641"><tspan + sodipodi:role="line" + id="tspan3643" + x="218.00417" + y="242.96333">4</tspan></text> + </g> + </g> + <g + transform="translate(404.60341,-191.92899)" + id="btn3_sele"> + <g + id="g3647"> + <rect + transform="matrix(0.9866385,0,0,0.9745014,51.2371,-85.940146)" + ry="8.4908352" + y="284.95181" + x="145.96704" + height="70.205612" + width="77.276665" + id="rect3649" + style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3282)" /> + <rect + style="opacity:1;fill:#999999;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3651" + width="76.771591" + height="68.690376" + x="194.95944" + y="191.51268" + ry="8.307579" /> + <rect + ry="6.4750247" + y="199.08882" + x="201.40616" + height="53.53809" + width="63.639606" + id="rect3653" + style="opacity:0.66167662;fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <rect + style="opacity:0.66167662;fill:url(#linearGradient3698);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3655" + width="63.639606" + height="53.53809" + x="-265.04575" + y="-252.62691" + ry="6.4750247" + transform="scale(-1,-1)" /> + <text + id="text3657" + y="242.96333" + x="218.00417" + style="font-size:46.92830658px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" + xml:space="preserve"><tspan + y="242.96333" + x="218.00417" + id="tspan3659" + sodipodi:role="line">3</tspan></text> + </g> + </g> + <g + id="btn2_sele" + transform="translate(311.39817,-191.92899)"> + <g + id="g3663"> + <rect + style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3282)" + id="rect3665" + width="77.276665" + height="70.205612" + x="145.96704" + y="284.95181" + ry="8.4908352" + transform="matrix(0.9866385,0,0,0.9745014,51.2371,-85.940146)" /> + <rect + ry="8.307579" + y="191.51268" + x="194.95944" + height="68.690376" + width="76.771591" + id="rect3667" + style="opacity:1;fill:#999999;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <rect + style="opacity:0.66167662;fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3669" + width="63.639606" + height="53.53809" + x="201.40616" + y="199.08882" + ry="6.4750247" /> + <rect + transform="scale(-1,-1)" + ry="6.4750247" + y="-252.62691" + x="-265.04575" + height="53.53809" + width="63.639606" + id="rect3671" + style="opacity:0.66167662;fill:url(#linearGradient3696);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <text + xml:space="preserve" + style="font-size:46.92830658px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" + x="218.00417" + y="242.96333" + id="text3673"><tspan + sodipodi:role="line" + id="tspan3675" + x="218.00417" + y="242.96333">2</tspan></text> + </g> + </g> + <g + transform="translate(218.19294,-191.92899)" + id="btn1_sele"> + <g + id="g3679"> + <rect + transform="matrix(0.9866385,0,0,0.9745014,51.2371,-85.940146)" + ry="8.4908352" + y="284.95181" + x="145.96704" + height="70.205612" + width="77.276665" + id="rect3681" + style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3282)" /> + <rect + style="opacity:1;fill:#999999;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3683" + width="76.771591" + height="68.690376" + x="194.95944" + y="191.51268" + ry="8.307579" /> + <rect + ry="6.4750247" + y="199.08882" + x="201.40616" + height="53.53809" + width="63.639606" + id="rect3685" + style="opacity:0.66167662;fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <rect + style="opacity:0.66167662;fill:url(#linearGradient3694);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3687" + width="63.639606" + height="53.53809" + x="-265.04575" + y="-252.62691" + ry="6.4750247" + transform="scale(-1,-1)" /> + <text + id="text3689" + y="242.96333" + x="218.00417" + style="font-size:46.92830658px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" + xml:space="preserve"><tspan + y="242.96333" + x="218.00417" + id="tspan3691" + sodipodi:role="line">1</tspan></text> + </g> + </g> + </g> + </g> +</svg> diff -r ee802ef00ca5 -r b7cb57a2da08 tests/linux/test_svgui/python@python/svgui@svgui/python.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/linux/test_svgui/python@python/svgui@svgui/python.xml Wed Aug 12 11:46:22 2009 +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>