merge svghmi
authorEdouard Tisserant
Tue, 16 Feb 2021 11:47:52 +0100
branchsvghmi
changeset 3148 b8c0dfdf364b
parent 3147 910290aec533 (diff)
parent 3144 2af6afaccaf2 (current diff)
child 3149 d32e6246cd59
merge
svghmi/svghmi.js
--- a/svghmi/gen_index_xhtml.xslt	Tue Feb 16 09:38:28 2021 +0100
+++ b/svghmi/gen_index_xhtml.xslt	Tue Feb 16 11:47:52 2021 +0100
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:str="http://exslt.org/strings" xmlns:func="http://exslt.org/functions" 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: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" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:debug="debug" xmlns:preamble="preamble" xmlns:declarations="declarations" xmlns:definitions="definitions" xmlns:epilogue="epilogue" xmlns:ns="beremiz" version="1.0" extension-element-prefixes="ns func exsl regexp str dyn" exclude-result-prefixes="ns func exsl regexp str dyn debug preamble epilogue declarations definitions">
-  <xsl:output cdata-section-elements="xhtml:script" method="xml"/>
+<xsl:stylesheet xmlns:ns="beremiz" xmlns:definitions="definitions" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:func="http://exslt.org/functions" xmlns:epilogue="epilogue" xmlns:preamble="preamble" 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" xmlns:svg="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:str="http://exslt.org/strings" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:exsl="http://exslt.org/common" xmlns:declarations="declarations" xmlns:debug="debug" exclude-result-prefixes="ns func exsl regexp str dyn debug preamble epilogue declarations definitions" extension-element-prefixes="ns func exsl regexp str dyn" version="1.0">
+  <xsl:output method="xml" cdata-section-elements="xhtml:script"/>
   <xsl:variable name="svg" select="/svg:svg"/>
   <xsl:variable name="hmi_elements" select="//svg:*[starts-with(@inkscape:label, 'HMI:')]"/>
   <xsl:variable name="hmitree" select="ns:GetHMITree()"/>
@@ -1135,6 +1135,8 @@
 </xsl:text>
     <xsl:text>
 </xsl:text>
+    <xsl:text>
+</xsl:text>
     <xsl:text>let hmi_locals = {};
 </xsl:text>
     <xsl:text>var last_remote_index = hmitree_types.length - 1;
@@ -1206,6 +1208,8 @@
 </xsl:text>
     <xsl:text>var cache = hmitree_types.map(_ignored =&gt; undefined);
 </xsl:text>
+    <xsl:text>var updates = {};
+</xsl:text>
     <xsl:text>
 </xsl:text>
     <xsl:text>function page_local_index(varname, pagename){
@@ -1329,15 +1333,15 @@
 </xsl:text>
     <xsl:text>                /* flush updates pending because of inhibition */
 </xsl:text>
-    <xsl:text>                let inhibition = this.inhibit[index];
+    <xsl:text>                let inhibition = this.inhibit[i];
 </xsl:text>
     <xsl:text>                if(inhibition != undefined){
 </xsl:text>
     <xsl:text>                    clearTimeout(inhibition);
 </xsl:text>
-    <xsl:text>                    this.lastapply[index] = undefined;
-</xsl:text>
-    <xsl:text>                    this.unhinibit(index);
+    <xsl:text>                    this.lastapply[i] = undefined;
+</xsl:text>
+    <xsl:text>                    this.unhinibit(i);
 </xsl:text>
     <xsl:text>                }
 </xsl:text>
@@ -1665,7 +1669,7 @@
 </xsl:text>
   </xsl:template>
   <xsl:variable name="excluded_types" select="str:split('Page VarInit VarInitPersistent')"/>
-  <xsl:key name="TypesKey" match="widget" use="@type"/>
+  <xsl:key use="@type" name="TypesKey" match="widget"/>
   <declarations:hmi-classes/>
   <xsl:template match="declarations:hmi-classes">
     <xsl:text>
@@ -2876,7 +2880,7 @@
 </xsl:text>
     <xsl:text>        this.fields[index] = value;    
 </xsl:text>
-    <xsl:text>        this.element.textContent = this.args.length == 1 ? vsprintf(this.args[0],this.fields) : this.fields.join(' ');
+    <xsl:text>        this.request_animate();
 </xsl:text>
     <xsl:text>    }
 </xsl:text>
@@ -2885,11 +2889,22 @@
   </xsl:template>
   <xsl:template mode="widget_defs" match="widget[@type='Display']">
     <xsl:param name="hmi_element"/>
-    <xsl:if test="$hmi_element[not(self::svg:text)]">
+    <xsl:variable name="format">
+      <xsl:call-template name="defs_by_labels">
+        <xsl:with-param name="hmi_element" select="$hmi_element"/>
+        <xsl:with-param name="labels">
+          <xsl:text>format</xsl:text>
+        </xsl:with-param>
+        <xsl:with-param name="mandatory" select="'no'"/>
+      </xsl:call-template>
+    </xsl:variable>
+    <xsl:variable name="has_format" select="string-length($format)&gt;0"/>
+    <xsl:value-of select="$format"/>
+    <xsl:if test="$hmi_element[not(self::svg:text)] and not($has_format)">
       <xsl:message terminate="yes">
         <xsl:text>Display Widget id="</xsl:text>
         <xsl:value-of select="$hmi_element/@id"/>
-        <xsl:text>" is not a svg::text element</xsl:text>
+        <xsl:text>" must be a svg::text element itself or a group containing a svg:text element labelled "format"</xsl:text>
       </xsl:message>
     </xsl:if>
     <xsl:variable name="field_initializer">
@@ -2911,6 +2926,42 @@
     <xsl:value-of select="$field_initializer"/>
     <xsl:text>],
 </xsl:text>
+    <xsl:text>    animate: function(){
+</xsl:text>
+    <xsl:choose>
+      <xsl:when test="$has_format">
+        <xsl:text>      if(this.format_elt.getAttribute("lang")) {
+</xsl:text>
+        <xsl:text>          this.format = svg_text_to_multiline(this.format_elt);
+</xsl:text>
+        <xsl:text>          this.format_elt.removeAttribute("lang");
+</xsl:text>
+        <xsl:text>      }
+</xsl:text>
+        <xsl:text>      let str = vsprintf(this.format,this.fields);
+</xsl:text>
+        <xsl:text>      multiline_to_svg_text(this.format_elt, str);
+</xsl:text>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:text>      let str = this.args.length == 1 ? vsprintf(this.args[0],this.fields) : this.fields.join(' ');
+</xsl:text>
+        <xsl:text>      multiline_to_svg_text(this.element, str);
+</xsl:text>
+      </xsl:otherwise>
+    </xsl:choose>
+    <xsl:text>    },
+</xsl:text>
+    <xsl:text>    
+</xsl:text>
+    <xsl:if test="$has_format">
+      <xsl:text>    init: function() {
+</xsl:text>
+      <xsl:text>      this.format = svg_text_to_multiline(this.format_elt);
+</xsl:text>
+      <xsl:text>    },
+</xsl:text>
+    </xsl:if>
   </xsl:template>
   <preamble:display/>
   <xsl:template match="preamble:display">
@@ -5602,15 +5653,13 @@
 </xsl:text>
     <xsl:text>            case 0:
 </xsl:text>
-    <xsl:text>                if (Math.round(this.position) != value)
-</xsl:text>
-    <xsl:text>                    this.position = value;
+    <xsl:text>                this.position = value;
 </xsl:text>
     <xsl:text>                break;
 </xsl:text>
     <xsl:text>            case 1:
 </xsl:text>
-    <xsl:text>                this.range = value;
+    <xsl:text>                this.range = Math.max(1,value);
 </xsl:text>
     <xsl:text>                break;
 </xsl:text>
@@ -5688,9 +5737,9 @@
 </xsl:text>
     <xsl:text>    apply_position(position){
 </xsl:text>
-    <xsl:text>        this.position = Math.max(Math.min(position, this.range), 0);
-</xsl:text>
-    <xsl:text>        this.apply_hmi_value(0, Math.round(this.position));
+    <xsl:text>        this.position = Math.round(Math.max(Math.min(position, this.range), 0));
+</xsl:text>
+    <xsl:text>        this.apply_hmi_value(0, this.position);
 </xsl:text>
     <xsl:text>    }
 </xsl:text>
@@ -5726,6 +5775,8 @@
 </xsl:text>
     <xsl:text>        svg_root.addEventListener("pointermove", this.bound_drag, true);
 </xsl:text>
+    <xsl:text>        this.dragpos = this.position;
+</xsl:text>
     <xsl:text>    }
 </xsl:text>
     <xsl:text>
@@ -5750,7 +5801,9 @@
 </xsl:text>
     <xsl:text>        let movement = point.matrixTransform(this.invctm).y;
 </xsl:text>
-    <xsl:text>        this.apply_position(this.position + movement * units / pixels);
+    <xsl:text>        this.dragpos += movement * units / pixels;
+</xsl:text>
+    <xsl:text>        this.apply_position(this.dragpos);
 </xsl:text>
     <xsl:text>    }
 </xsl:text>
@@ -6653,7 +6706,7 @@
     <xsl:comment>
       <xsl:apply-templates select="document('')/*/debug:*"/>
     </xsl:comment>
-    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <html xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/1999/xhtml">
       <head/>
       <body style="margin:0;overflow:hidden;user-select:none;touch-action:none;">
         <xsl:copy-of select="$result_svg"/>
@@ -6694,14 +6747,10 @@
 </xsl:text>
           <xsl:text>
 </xsl:text>
-          <xsl:text>var updates = {};
-</xsl:text>
           <xsl:text>var need_cache_apply = [];
 </xsl:text>
           <xsl:text>
 </xsl:text>
-          <xsl:text>
-</xsl:text>
           <xsl:text>function dispatch_value(index, value) {
 </xsl:text>
           <xsl:text>    let widgets = subscribers(index);
@@ -6982,6 +7031,8 @@
 </xsl:text>
           <xsl:text>    NODE: (truth) =&gt; new Int16Array([truth]),
 </xsl:text>
+          <xsl:text>    REAL: (number) =&gt; new Float32Array([number]),
+</xsl:text>
           <xsl:text>    STRING: (str) =&gt; {
 </xsl:text>
           <xsl:text>        // beremiz default string max size is 128
@@ -7102,7 +7153,19 @@
 </xsl:text>
           <xsl:text>
 </xsl:text>
-          <xsl:text>var translated = false;
+          <xsl:text>function svg_text_to_multiline(elt) {
+</xsl:text>
+          <xsl:text>    return(Array.prototype.map.call(elt.children, x=&gt;x.textContent).join("\n")); 
+</xsl:text>
+          <xsl:text>}
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>function multiline_to_svg_text(elt, str) {
+</xsl:text>
+          <xsl:text>    str.split('\n').map((line,i) =&gt; {elt.children[i].textContent = line;});
+</xsl:text>
+          <xsl:text>}
 </xsl:text>
           <xsl:text>
 </xsl:text>
@@ -7116,350 +7179,352 @@
 </xsl:text>
           <xsl:text>
 </xsl:text>
-          <xsl:text>    if (!translated) {
-</xsl:text>
-          <xsl:text>        translated = true;
-</xsl:text>
-          <xsl:text>        for (let translation of translations) {
-</xsl:text>
-          <xsl:text>            let [objs] = translation;
-</xsl:text>
-          <xsl:text>            translation.push(Array.prototype.map.call(objs[0].children, x=&gt;x.textContent).join("\n")); 
+          <xsl:text>    for (let translation of translations) {
+</xsl:text>
+          <xsl:text>        let [objs, msgs, orig] = translation;
+</xsl:text>
+          <xsl:text>        let msg = langnum == 0 ? orig : msgs[langnum - 1];
+</xsl:text>
+          <xsl:text>        for (let obj of objs) {
+</xsl:text>
+          <xsl:text>            multiline_to_svg_text(obj, msg);
+</xsl:text>
+          <xsl:text>            obj.setAttribute("lang",langnum);
 </xsl:text>
           <xsl:text>        }
 </xsl:text>
           <xsl:text>    }
 </xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>    for (let translation of translations) {
-</xsl:text>
-          <xsl:text>        let [objs, msgs, orig] = translation;
-</xsl:text>
-          <xsl:text>        let msg = langnum == 0 ? orig : msgs[langnum - 1];
-</xsl:text>
-          <xsl:text>        for (let obj of objs) {
-</xsl:text>
-          <xsl:text>            msg.split('\n').map((line,i) =&gt; {obj.children[i].textContent = line;});
+          <xsl:text>    current_lang = langnum;
+</xsl:text>
+          <xsl:text>}
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>// backup original texts
+</xsl:text>
+          <xsl:text>for (let translation of translations) {
+</xsl:text>
+          <xsl:text>    let [objs] = translation;
+</xsl:text>
+          <xsl:text>    translation.push(svg_text_to_multiline(objs[0])); 
+</xsl:text>
+          <xsl:text>}
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>var lang_local_index = hmi_local_index("lang");
+</xsl:text>
+          <xsl:text>subscribers(lang_local_index).add({
+</xsl:text>
+          <xsl:text>    indexes: [lang_local_index],
+</xsl:text>
+          <xsl:text>    new_hmi_value: function(index, value, oldval) {
+</xsl:text>
+          <xsl:text>        switch_langnum(value);
+</xsl:text>
+          <xsl:text>        switch_page();
+</xsl:text>
+          <xsl:text>    }
+</xsl:text>
+          <xsl:text>});
+</xsl:text>
+          <xsl:text>var current_lang = 0;
+</xsl:text>
+          <xsl:text>switch_langnum(cache[lang_local_index]);
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>function update_subscriptions() {
+</xsl:text>
+          <xsl:text>    let delta = [];
+</xsl:text>
+          <xsl:text>    for(let index in subscriptions){
+</xsl:text>
+          <xsl:text>        let widgets = subscribers(index);
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>        // periods are in ms
+</xsl:text>
+          <xsl:text>        let previous_period = get_subscription_period(index);
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>        // subscribing with a zero period is unsubscribing
+</xsl:text>
+          <xsl:text>        let new_period = 0;
+</xsl:text>
+          <xsl:text>        if(widgets.size &gt; 0) {
+</xsl:text>
+          <xsl:text>            let maxfreq = 0;
+</xsl:text>
+          <xsl:text>            for(let widget of widgets){
+</xsl:text>
+          <xsl:text>                let wf = widget.frequency;
+</xsl:text>
+          <xsl:text>                if(wf != undefined &amp;&amp; maxfreq &lt; wf)
+</xsl:text>
+          <xsl:text>                    maxfreq = wf;
+</xsl:text>
+          <xsl:text>            }
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>            if(maxfreq != 0)
+</xsl:text>
+          <xsl:text>                new_period = 1000/maxfreq;
 </xsl:text>
           <xsl:text>        }
 </xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>        if(previous_period != new_period) {
+</xsl:text>
+          <xsl:text>            set_subscription_period(index, new_period);
+</xsl:text>
+          <xsl:text>            if(index &lt;= last_remote_index){
+</xsl:text>
+          <xsl:text>                delta.push(
+</xsl:text>
+          <xsl:text>                    new Uint8Array([2]), /* subscribe = 2 */
+</xsl:text>
+          <xsl:text>                    new Uint32Array([index]),
+</xsl:text>
+          <xsl:text>                    new Uint16Array([new_period]));
+</xsl:text>
+          <xsl:text>            }
+</xsl:text>
+          <xsl:text>        }
+</xsl:text>
           <xsl:text>    }
 </xsl:text>
-          <xsl:text>    current_lang = langnum;
+          <xsl:text>    send_blob(delta);
+</xsl:text>
+          <xsl:text>};
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>function send_hmi_value(index, value) {
+</xsl:text>
+          <xsl:text>    if(index &gt; last_remote_index){
+</xsl:text>
+          <xsl:text>        updates[index] = value;
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>        if(persistent_indexes.has(index)){
+</xsl:text>
+          <xsl:text>            let varname = persistent_indexes.get(index);
+</xsl:text>
+          <xsl:text>            document.cookie = varname+"="+value+"; max-age=3153600000";
+</xsl:text>
+          <xsl:text>        }
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>        requestHMIAnimation();
+</xsl:text>
+          <xsl:text>        return;
+</xsl:text>
+          <xsl:text>    }
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>    let iectype = hmitree_types[index];
+</xsl:text>
+          <xsl:text>    let tobinary = typedarray_types[iectype];
+</xsl:text>
+          <xsl:text>    send_blob([
+</xsl:text>
+          <xsl:text>        new Uint8Array([0]),  /* setval = 0 */
+</xsl:text>
+          <xsl:text>        new Uint32Array([index]),
+</xsl:text>
+          <xsl:text>        tobinary(value)]);
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>    // DON'T DO THAT unless read_iterator in svghmi.c modifies wbuf as well, not only rbuf
+</xsl:text>
+          <xsl:text>    // cache[index] = value;
+</xsl:text>
+          <xsl:text>};
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>function apply_hmi_value(index, new_val) {
+</xsl:text>
+          <xsl:text>    let old_val = cache[index]
+</xsl:text>
+          <xsl:text>    if(new_val != undefined &amp;&amp; old_val != new_val)
+</xsl:text>
+          <xsl:text>        send_hmi_value(index, new_val);
+</xsl:text>
+          <xsl:text>    return new_val;
 </xsl:text>
           <xsl:text>}
 </xsl:text>
-          <xsl:text>var lang_local_index = hmi_local_index("lang");
-</xsl:text>
-          <xsl:text>subscribers(lang_local_index).add({
-</xsl:text>
-          <xsl:text>    indexes: [lang_local_index],
-</xsl:text>
-          <xsl:text>    new_hmi_value: function(index, value, oldval) {
-</xsl:text>
-          <xsl:text>        switch_langnum(value);
+          <xsl:text>
+</xsl:text>
+          <xsl:text>const quotes = {"'":null, '"':null};
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>function eval_operation_string(old_val, opstr) {
+</xsl:text>
+          <xsl:text>    let op = opstr[0];
+</xsl:text>
+          <xsl:text>    let given_val;
+</xsl:text>
+          <xsl:text>    if(opstr.length &lt; 2) 
+</xsl:text>
+          <xsl:text>        return undefined;
+</xsl:text>
+          <xsl:text>    if(opstr[1] in quotes){
+</xsl:text>
+          <xsl:text>        if(opstr.length &lt; 3) 
+</xsl:text>
+          <xsl:text>            return undefined;
+</xsl:text>
+          <xsl:text>        if(opstr[opstr.length-1] == opstr[1]){
+</xsl:text>
+          <xsl:text>            given_val = opstr.slice(2,opstr.length-1);
+</xsl:text>
+          <xsl:text>        }
+</xsl:text>
+          <xsl:text>    } else {
+</xsl:text>
+          <xsl:text>        given_val = Number(opstr.slice(1));
 </xsl:text>
           <xsl:text>    }
 </xsl:text>
-          <xsl:text>});
-</xsl:text>
-          <xsl:text>var current_lang = 0;
-</xsl:text>
-          <xsl:text>switch_langnum(cache[lang_local_index]);
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>function update_subscriptions() {
-</xsl:text>
-          <xsl:text>    let delta = [];
-</xsl:text>
-          <xsl:text>    for(let index in subscriptions){
-</xsl:text>
-          <xsl:text>        let widgets = subscribers(index);
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>        // periods are in ms
-</xsl:text>
-          <xsl:text>        let previous_period = get_subscription_period(index);
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>        // subscribing with a zero period is unsubscribing
-</xsl:text>
-          <xsl:text>        let new_period = 0;
-</xsl:text>
-          <xsl:text>        if(widgets.size &gt; 0) {
-</xsl:text>
-          <xsl:text>            let maxfreq = 0;
-</xsl:text>
-          <xsl:text>            for(let widget of widgets){
-</xsl:text>
-          <xsl:text>                let wf = widget.frequency;
-</xsl:text>
-          <xsl:text>                if(wf != undefined &amp;&amp; maxfreq &lt; wf)
-</xsl:text>
-          <xsl:text>                    maxfreq = wf;
-</xsl:text>
-          <xsl:text>            }
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>            if(maxfreq != 0)
-</xsl:text>
-          <xsl:text>                new_period = 1000/maxfreq;
-</xsl:text>
-          <xsl:text>        }
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>        if(previous_period != new_period) {
-</xsl:text>
-          <xsl:text>            set_subscription_period(index, new_period);
-</xsl:text>
-          <xsl:text>            if(index &lt;= last_remote_index){
-</xsl:text>
-          <xsl:text>                delta.push(
-</xsl:text>
-          <xsl:text>                    new Uint8Array([2]), /* subscribe = 2 */
-</xsl:text>
-          <xsl:text>                    new Uint32Array([index]),
-</xsl:text>
-          <xsl:text>                    new Uint16Array([new_period]));
-</xsl:text>
-          <xsl:text>            }
-</xsl:text>
-          <xsl:text>        }
+          <xsl:text>    let new_val;
+</xsl:text>
+          <xsl:text>    switch(op){
+</xsl:text>
+          <xsl:text>      case "=":
+</xsl:text>
+          <xsl:text>        new_val = given_val;
+</xsl:text>
+          <xsl:text>        break;
+</xsl:text>
+          <xsl:text>      case "+":
+</xsl:text>
+          <xsl:text>        new_val = old_val + given_val;
+</xsl:text>
+          <xsl:text>        break;
+</xsl:text>
+          <xsl:text>      case "-":
+</xsl:text>
+          <xsl:text>        new_val = old_val - given_val;
+</xsl:text>
+          <xsl:text>        break;
+</xsl:text>
+          <xsl:text>      case "*":
+</xsl:text>
+          <xsl:text>        new_val = old_val * given_val;
+</xsl:text>
+          <xsl:text>        break;
+</xsl:text>
+          <xsl:text>      case "/":
+</xsl:text>
+          <xsl:text>        new_val = old_val / given_val;
+</xsl:text>
+          <xsl:text>        break;
 </xsl:text>
           <xsl:text>    }
 </xsl:text>
-          <xsl:text>    send_blob(delta);
+          <xsl:text>    return new_val;
+</xsl:text>
+          <xsl:text>}
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>var current_visible_page;
+</xsl:text>
+          <xsl:text>var current_subscribed_page;
+</xsl:text>
+          <xsl:text>var current_page_index;
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>function prepare_svg() {
+</xsl:text>
+          <xsl:text>    // prevents context menu from appearing on right click and long touch
+</xsl:text>
+          <xsl:text>    document.body.addEventListener('contextmenu', e =&gt; {
+</xsl:text>
+          <xsl:text>        e.preventDefault();
+</xsl:text>
+          <xsl:text>    });
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>    for(let eltid in detachable_elements){
+</xsl:text>
+          <xsl:text>        let [element,parent] = detachable_elements[eltid];
+</xsl:text>
+          <xsl:text>        parent.removeChild(element);
+</xsl:text>
+          <xsl:text>    }
 </xsl:text>
           <xsl:text>};
 </xsl:text>
           <xsl:text>
 </xsl:text>
-          <xsl:text>function send_hmi_value(index, value) {
-</xsl:text>
-          <xsl:text>    if(index &gt; last_remote_index){
-</xsl:text>
-          <xsl:text>        updates[index] = value;
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>        if(persistent_indexes.has(index)){
-</xsl:text>
-          <xsl:text>            let varname = persistent_indexes.get(index);
-</xsl:text>
-          <xsl:text>            document.cookie = varname+"="+value+"; max-age=3153600000";
-</xsl:text>
-          <xsl:text>        }
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>        requestHMIAnimation();
-</xsl:text>
-          <xsl:text>        return;
+          <xsl:text>function switch_page(page_name, page_index) {
+</xsl:text>
+          <xsl:text>    if(current_subscribed_page != current_visible_page){
+</xsl:text>
+          <xsl:text>        /* page switch already going */
+</xsl:text>
+          <xsl:text>        /* TODO LOG ERROR */
+</xsl:text>
+          <xsl:text>        return false;
 </xsl:text>
           <xsl:text>    }
 </xsl:text>
           <xsl:text>
 </xsl:text>
-          <xsl:text>    let iectype = hmitree_types[index];
-</xsl:text>
-          <xsl:text>    let tobinary = typedarray_types[iectype];
-</xsl:text>
-          <xsl:text>    send_blob([
-</xsl:text>
-          <xsl:text>        new Uint8Array([0]),  /* setval = 0 */
-</xsl:text>
-          <xsl:text>        new Uint32Array([index]),
-</xsl:text>
-          <xsl:text>        tobinary(value)]);
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>    // DON'T DO THAT unless read_iterator in svghmi.c modifies wbuf as well, not only rbuf
-</xsl:text>
-          <xsl:text>    // cache[index] = value;
-</xsl:text>
-          <xsl:text>};
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>function apply_hmi_value(index, new_val) {
-</xsl:text>
-          <xsl:text>    let old_val = cache[index]
-</xsl:text>
-          <xsl:text>    if(new_val != undefined &amp;&amp; old_val != new_val)
-</xsl:text>
-          <xsl:text>        send_hmi_value(index, new_val);
-</xsl:text>
-          <xsl:text>    return new_val;
-</xsl:text>
-          <xsl:text>}
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>const quotes = {"'":null, '"':null};
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>function eval_operation_string(old_val, opstr) {
-</xsl:text>
-          <xsl:text>    let op = opstr[0];
-</xsl:text>
-          <xsl:text>    let given_val;
-</xsl:text>
-          <xsl:text>    if(opstr.length &lt; 2) 
-</xsl:text>
-          <xsl:text>        return undefined;
-</xsl:text>
-          <xsl:text>    if(opstr[1] in quotes){
-</xsl:text>
-          <xsl:text>        if(opstr.length &lt; 3) 
-</xsl:text>
-          <xsl:text>            return undefined;
-</xsl:text>
-          <xsl:text>        if(opstr[opstr.length-1] == opstr[1]){
-</xsl:text>
-          <xsl:text>            given_val = opstr.slice(2,opstr.length-1);
-</xsl:text>
-          <xsl:text>        }
-</xsl:text>
-          <xsl:text>    } else {
-</xsl:text>
-          <xsl:text>        given_val = Number(opstr.slice(1));
+          <xsl:text>    if(page_name == undefined)
+</xsl:text>
+          <xsl:text>        page_name = current_subscribed_page;
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>    let old_desc = page_desc[current_subscribed_page];
+</xsl:text>
+          <xsl:text>    let new_desc = page_desc[page_name];
+</xsl:text>
+          <xsl:text>
+</xsl:text>
+          <xsl:text>    if(new_desc == undefined){
+</xsl:text>
+          <xsl:text>        /* TODO LOG ERROR */
+</xsl:text>
+          <xsl:text>        return false;
 </xsl:text>
           <xsl:text>    }
 </xsl:text>
-          <xsl:text>    let new_val;
-</xsl:text>
-          <xsl:text>    switch(op){
-</xsl:text>
-          <xsl:text>      case "=":
-</xsl:text>
-          <xsl:text>        new_val = given_val;
-</xsl:text>
-          <xsl:text>        break;
-</xsl:text>
-          <xsl:text>      case "+":
-</xsl:text>
-          <xsl:text>        new_val = old_val + given_val;
-</xsl:text>
-          <xsl:text>        break;
-</xsl:text>
-          <xsl:text>      case "-":
-</xsl:text>
-          <xsl:text>        new_val = old_val - given_val;
-</xsl:text>
-          <xsl:text>        break;
-</xsl:text>
-          <xsl:text>      case "*":
-</xsl:text>
-          <xsl:text>        new_val = old_val * given_val;
-</xsl:text>
-          <xsl:text>        break;
-</xsl:text>
-          <xsl:text>      case "/":
-</xsl:text>
-          <xsl:text>        new_val = old_val / given_val;
-</xsl:text>
-          <xsl:text>        break;
+          <xsl:text>
+</xsl:text>
+          <xsl:text>    if(page_index == undefined){
+</xsl:text>
+          <xsl:text>        page_index = new_desc.page_index;
 </xsl:text>
           <xsl:text>    }
 </xsl:text>
-          <xsl:text>    return new_val;
-</xsl:text>
-          <xsl:text>}
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>var current_visible_page;
-</xsl:text>
-          <xsl:text>var current_subscribed_page;
-</xsl:text>
-          <xsl:text>var current_page_index;
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>function prepare_svg() {
-</xsl:text>
-          <xsl:text>    // prevents context menu from appearing on right click and long touch
-</xsl:text>
-          <xsl:text>    document.body.addEventListener('contextmenu', e =&gt; {
-</xsl:text>
-          <xsl:text>        e.preventDefault();
-</xsl:text>
-          <xsl:text>    });
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>    for(let eltid in detachable_elements){
-</xsl:text>
-          <xsl:text>        let [element,parent] = detachable_elements[eltid];
-</xsl:text>
-          <xsl:text>        parent.removeChild(element);
+          <xsl:text>
+</xsl:text>
+          <xsl:text>    if(old_desc){
+</xsl:text>
+          <xsl:text>        old_desc.widgets.map(([widget,relativeness])=&gt;widget.unsub());
 </xsl:text>
           <xsl:text>    }
 </xsl:text>
-          <xsl:text>};
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>function switch_page(page_name, page_index) {
-</xsl:text>
-          <xsl:text>    if(current_subscribed_page != current_visible_page){
-</xsl:text>
-          <xsl:text>        /* page switch already going */
-</xsl:text>
-          <xsl:text>        /* TODO LOG ERROR */
-</xsl:text>
-          <xsl:text>        return false;
-</xsl:text>
-          <xsl:text>    }
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>    if(page_name == undefined)
-</xsl:text>
-          <xsl:text>        page_name = current_subscribed_page;
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>    let old_desc = page_desc[current_subscribed_page];
-</xsl:text>
-          <xsl:text>    let new_desc = page_desc[page_name];
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>    if(new_desc == undefined){
-</xsl:text>
-          <xsl:text>        /* TODO LOG ERROR */
-</xsl:text>
-          <xsl:text>        return false;
-</xsl:text>
-          <xsl:text>    }
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>    if(page_index == undefined){
-</xsl:text>
-          <xsl:text>        page_index = new_desc.page_index;
-</xsl:text>
-          <xsl:text>    }
-</xsl:text>
-          <xsl:text>
-</xsl:text>
-          <xsl:text>    if(old_desc){
-</xsl:text>
-          <xsl:text>        old_desc.widgets.map(([widget,relativeness])=&gt;widget.unsub());
-</xsl:text>
-          <xsl:text>    }
-</xsl:text>
           <xsl:text>    const new_offset = page_index == undefined ? 0 : page_index - new_desc.page_index;
 </xsl:text>
           <xsl:text>
@@ -7488,8 +7553,6 @@
 </xsl:text>
           <xsl:text>    requestHMIAnimation();
 </xsl:text>
-          <xsl:text>
-</xsl:text>
           <xsl:text>    jump_history.push([page_name, page_index]);
 </xsl:text>
           <xsl:text>    if(jump_history.length &gt; 42)
--- a/svghmi/svghmi.js	Tue Feb 16 09:38:28 2021 +0100
+++ b/svghmi/svghmi.js	Tue Feb 16 11:47:52 2021 +0100
@@ -142,6 +142,7 @@
     INT: (number) => new Int16Array([number]),
     BOOL: (truth) => new Int16Array([truth]),
     NODE: (truth) => new Int16Array([truth]),
+    REAL: (number) => new Float32Array([number]),
     STRING: (str) => {
         // beremiz default string max size is 128
         str = str.slice(0,128);
--- a/tests/svghmi_i18n/svghmi_0@svghmi/messages.pot	Tue Feb 16 09:38:28 2021 +0100
+++ b/tests/svghmi_i18n/svghmi_0@svghmi/messages.pot	Tue Feb 16 11:47:52 2021 +0100
@@ -5,7 +5,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2021-02-14 19:05+CET\n"
+"POT-Creation-Date: 2021-02-15 14:45+CET\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -19,7 +19,7 @@
 msgid "height is %d meters"
 msgstr ""
 
-#:svghmi.svg: formatfortext:text5271
+#:svghmi.svg: format:text5271
 msgid "This is an integer value : %d"
 msgstr ""
 
--- a/tests/svghmi_i18n/svghmi_0@svghmi/svghmi.svg	Tue Feb 16 09:38:28 2021 +0100
+++ b/tests/svghmi_i18n/svghmi_0@svghmi/svghmi.svg	Tue Feb 16 11:47:52 2021 +0100
@@ -2415,16 +2415,16 @@
      inkscape:pageopacity="0"
      inkscape:pageshadow="2"
      inkscape:document-units="px"
-     inkscape:current-layer="g436"
+     inkscape:current-layer="hmi0"
      showgrid="false"
      units="px"
      inkscape:zoom="0.70710678"
-     inkscape:cx="575.80285"
-     inkscape:cy="308.66839"
-     inkscape:window-width="1939"
-     inkscape:window-height="844"
-     inkscape:window-x="3325"
-     inkscape:window-y="554"
+     inkscape:cx="535.49777"
+     inkscape:cy="380.79328"
+     inkscape:window-width="1600"
+     inkscape:window-height="836"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
      inkscape:window-maximized="0"
      showguides="true"
      inkscape:guide-bbox="true"
@@ -2447,9 +2447,9 @@
      inkscape:label="HMI:Page:Home" />
   <g
      id="g5275"
-     inkscape:label="#HMI:Display@/TARGETPRESSURE">
+     inkscape:label="HMI:Display@/TARGETPRESSURE">
     <text
-       inkscape:label="_formatfortext"
+       inkscape:label="_format"
        id="text5271"
        y="430.74841"
        x="440.99014"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/svghmi_real/beremiz.xml	Tue Feb 16 11:47:52 2021 +0100
@@ -0,0 +1,5 @@
+<?xml version='1.0' encoding='utf-8'?>
+<BeremizRoot xmlns:xsd="http://www.w3.org/2001/XMLSchema" URI_location="PYRO://127.0.0.1:61284">
+  <TargetType/>
+  <Libraries Enable_SVGHMI_Library="true"/>
+</BeremizRoot>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/svghmi_real/plc.xml	Tue Feb 16 11:47:52 2021 +0100
@@ -0,0 +1,97 @@
+<?xml version='1.0' encoding='utf-8'?>
+<project xmlns:ns1="http://www.plcopen.org/xml/tc6_0201" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.plcopen.org/xml/tc6_0201">
+  <fileHeader companyName="Unknown" productName="Unnamed" productVersion="1" creationDateTime="2019-08-06T14:23:42"/>
+  <contentHeader name="Unnamed" modificationDateTime="2021-02-16T10:38:12">
+    <coordinateInfo>
+      <fbd>
+        <scaling x="5" y="5"/>
+      </fbd>
+      <ld>
+        <scaling x="0" y="0"/>
+      </ld>
+      <sfc>
+        <scaling x="0" y="0"/>
+      </sfc>
+    </coordinateInfo>
+  </contentHeader>
+  <types>
+    <dataTypes/>
+    <pous>
+      <pou name="MainStuff" pouType="program">
+        <interface>
+          <localVars>
+            <variable name="var0">
+              <type>
+                <derived name="HMI_REAL"/>
+              </type>
+            </variable>
+            <variable name="var1">
+              <type>
+                <derived name="HMI_INT"/>
+              </type>
+            </variable>
+          </localVars>
+        </interface>
+        <body>
+          <FBD>
+            <inVariable localId="5" executionOrderId="0" height="30" width="125" negated="false">
+              <position x="240" y="45"/>
+              <connectionPointOut>
+                <relPosition x="125" y="15"/>
+              </connectionPointOut>
+              <expression>var0</expression>
+            </inVariable>
+            <outVariable localId="10" executionOrderId="0" height="25" width="85" negated="false">
+              <position x="720" y="70"/>
+              <connectionPointIn>
+                <relPosition x="0" y="10"/>
+                <connection refLocalId="11" formalParameter="OUT">
+                  <position x="720" y="80"/>
+                  <position x="667" y="80"/>
+                  <position x="667" y="75"/>
+                  <position x="605" y="75"/>
+                </connection>
+              </connectionPointIn>
+              <expression>var1</expression>
+            </outVariable>
+            <block localId="11" typeName="REAL_TO_INT" executionOrderId="0" height="40" width="100">
+              <position x="505" y="45"/>
+              <inputVariables>
+                <variable formalParameter="IN">
+                  <connectionPointIn>
+                    <relPosition x="0" y="30"/>
+                    <connection refLocalId="5">
+                      <position x="505" y="75"/>
+                      <position x="445" y="75"/>
+                      <position x="445" y="60"/>
+                      <position x="365" y="60"/>
+                    </connection>
+                  </connectionPointIn>
+                </variable>
+              </inputVariables>
+              <inOutVariables/>
+              <outputVariables>
+                <variable formalParameter="OUT">
+                  <connectionPointOut>
+                    <relPosition x="100" y="30"/>
+                  </connectionPointOut>
+                </variable>
+              </outputVariables>
+            </block>
+          </FBD>
+        </body>
+      </pou>
+    </pous>
+  </types>
+  <instances>
+    <configurations>
+      <configuration name="config">
+        <resource name="resource1">
+          <task name="task0" priority="0" interval="T#20ms">
+            <pouInstance name="instance0" typeName="MainStuff"/>
+          </task>
+        </resource>
+      </configuration>
+    </configurations>
+  </instances>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/svghmi_real/svghmi_0@svghmi/baseconfnode.xml	Tue Feb 16 11:47:52 2021 +0100
@@ -0,0 +1,2 @@
+<?xml version='1.0' encoding='utf-8'?>
+<BaseParams xmlns:xsd="http://www.w3.org/2001/XMLSchema" IEC_Channel="0" Name="svghmi_0"/>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/svghmi_real/svghmi_0@svghmi/confnode.xml	Tue Feb 16 11:47:52 2021 +0100
@@ -0,0 +1,2 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SVGHMI xmlns:xsd="http://www.w3.org/2001/XMLSchema" OnWatchdog="echo Watchdog for {name} !" OnStart="chromium http://127.0.0.1:{port}/{name}" OnStop="echo Closing {name}" WatchdogInitial="10" WatchdogInterval="5"/>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/svghmi_real/svghmi_0@svghmi/svghmi.svg	Tue Feb 16 11:47:52 2021 +0100
@@ -0,0 +1,647 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+   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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
+   sodipodi:docname="svghmi.svg"
+   id="hmi0"
+   version="1.1"
+   viewBox="0 0 1280 720"
+   height="720"
+   width="1280">
+  <metadata
+     id="metadata4542">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs2">
+    <linearGradient
+       id="linearGradient34303"
+       osb:paint="solid">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop34301" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient20537"
+       osb:paint="solid">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop20535" />
+    </linearGradient>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:document-units="px"
+     inkscape:current-layer="hmi0"
+     showgrid="false"
+     units="px"
+     inkscape:zoom="0.64"
+     inkscape:cx="544.00649"
+     inkscape:cy="385.16049"
+     inkscape:window-width="1600"
+     inkscape:window-height="836"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
+     inkscape:window-maximized="0"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:snap-global="true"
+     inkscape:snap-bbox="true"
+     inkscape:bbox-nodes="true" />
+  <g
+     inkscape:label="HMI:Keypad:HMI_INT:HMI_REAL"
+     id="g2432"
+     style="fill-rule:evenodd;stroke-width:0.47631353"
+     transform="matrix(3.3549332,0,0,3.14525,-181.87457,2336.0198)">
+    <path
+       sodipodi:nodetypes="ccccc"
+       inkscape:label="Background"
+       inkscape:connector-curvature="0"
+       id="path2136"
+       d="M 54.211099,1.2654702 H 435.73881 V 230.18209 H 54.211099 Z"
+       style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.6;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.16776976;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+    <rect
+       ry="3.8152773"
+       rx="3.8152773"
+       y="15.77106"
+       x="64.024963"
+       height="30.150299"
+       width="361.89996"
+       id="rect2426"
+       style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#fffff5;fill-opacity:1;fill-rule:nonzero;stroke:#202326;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       inkscape:label="Field" />
+    <text
+       id="text2430"
+       y="37.408375"
+       x="72.50132"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:19.0763855px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.47690967px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       xml:space="preserve"
+       inkscape:label="Value"><tspan
+         style="text-align:start;text-anchor:start;stroke-width:0.47690967px"
+         y="37.408375"
+         x="72.50132"
+         id="tspan2428"
+         sodipodi:role="line">number</tspan></text>
+    <g
+       style="fill-rule:evenodd;stroke-width:0.13585199"
+       inkscape:label="Enter"
+       id="g4947"
+       transform="matrix(1.6700128,0,0,1.6700128,-826.83854,-145.60855)">
+      <path
+         style="opacity:1;vector-effect:none;fill:#4f4c4d;fill-opacity:1;stroke:none;stroke-width:0.10074362;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="path193"
+         d="m 750,175 c 0,-2 -1,-3 -3,-3 h -20 c -1,0 -3,1 -3,3 v 43 c 0,1 2,2 3,2 h 20 c 2,0 3,-1 3,-2 z"
+         inkscape:connector-curvature="0" />
+      <path
+         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m -1244.2949,1166.5938 v 15.791 h -38.6875 v -2.9981 l -6.9199,4 6.9199,4 v -2.998 h 40.6836 v -17.7949 z"
+         transform="matrix(0.28557246,0,0,0.28557246,1098.7155,-140.51013)"
+         id="path6545-4"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       style="fill-rule:evenodd;stroke-width:0.13585199"
+       inkscape:label="Keys"
+       id="g4993"
+       transform="matrix(1.6700128,0,0,1.6700128,-826.83854,-145.60855)">
+      <g
+         style="stroke-width:0.13585199"
+         inkscape:label="7"
+         id="g4892">
+        <path
+           inkscape:connector-curvature="0"
+           d="m 638,120 h 20 c 2,0 3,2 3,3 v 18 c 0,2 -1,3 -3,3 h -20 c -1,0 -3,-1 -3,-3 v -18 c 0,-1 2,-3 3,-3 z"
+           id="path163"
+           style="opacity:1;vector-effect:none;fill:#d3d2d2;fill-opacity:1;stroke:none;stroke-width:0.10074359;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+        <text
+           style="font-weight:normal;font-size:9.28803921px;font-family:Arial;fill:#2b2828;stroke-width:0.10514989"
+           id="text331"
+           y="129.38269"
+           x="636.4165"
+           transform="scale(1.0007154,0.99928514)">7</text>
+      </g>
+      <g
+         style="stroke-width:0.13585199"
+         inkscape:label="4"
+         id="g4907">
+        <path
+           inkscape:connector-curvature="0"
+           d="m 638,146 h 20 c 2,0 3,1 3,3 v 18 c 0,2 -1,3 -3,3 h -20 c -1,0 -3,-1 -3,-3 v -18 c 0,-2 2,-3 3,-3 z"
+           id="path169"
+           style="opacity:1;vector-effect:none;fill:#d3d2d2;fill-opacity:1;stroke:none;stroke-width:0.10074359;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+        <text
+           style="font-weight:normal;font-size:9.28803921px;font-family:Arial;fill:#2b2828;stroke-width:0.10514989"
+           id="text335"
+           y="154.10822"
+           x="636.4165"
+           transform="scale(1.0007154,0.99928514)">4</text>
+      </g>
+      <g
+         style="stroke-width:0.13585199"
+         inkscape:label="1"
+         id="g4922">
+        <path
+           inkscape:connector-curvature="0"
+           d="m 638,172 h 20 c 2,0 3,1 3,3 v 17 c 0,1 -1,3 -3,3 h -20 c -1,0 -3,-2 -3,-3 v -17 c 0,-2 2,-3 3,-3 z"
+           id="path175"
+           style="opacity:1;vector-effect:none;fill:#d3d2d2;fill-opacity:1;stroke:none;stroke-width:0.10074359;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+        <text
+           style="font-weight:normal;font-size:9.28803921px;font-family:Arial;fill:#2b2828;stroke-width:0.10514989"
+           id="text339"
+           y="179.82285"
+           x="636.4165"
+           transform="scale(1.0007154,0.99928514)">1</text>
+      </g>
+      <g
+         style="stroke-width:0.13585199"
+         inkscape:label="8"
+         id="g4897">
+        <path
+           inkscape:connector-curvature="0"
+           d="m 668,120 h 19 c 2,0 3,2 3,3 v 18 c 0,2 -1,3 -3,3 h -19 c -1,0 -3,-1 -3,-3 v -18 c 0,-1 2,-3 3,-3 z"
+           id="path165"
+           style="opacity:1;vector-effect:none;fill:#d3d2d2;fill-opacity:1;stroke:none;stroke-width:0.10074359;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+        <text
+           style="font-weight:normal;font-size:9.28803921px;font-family:Arial;fill:#2b2828;stroke-width:0.10514989"
+           id="text347"
+           y="129.38269"
+           x="667.07562"
+           transform="scale(1.0007154,0.99928514)">8</text>
+      </g>
+      <g
+         style="stroke-width:0.13585199"
+         inkscape:label="5"
+         id="g4912">
+        <path
+           inkscape:connector-curvature="0"
+           d="m 668,146 h 19 c 2,0 3,1 3,3 v 18 c 0,2 -1,3 -3,3 h -19 c -1,0 -3,-1 -3,-3 v -18 c 0,-2 2,-3 3,-3 z"
+           id="path171"
+           style="opacity:1;vector-effect:none;fill:#d3d2d2;fill-opacity:1;stroke:none;stroke-width:0.10074359;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+        <text
+           style="font-weight:normal;font-size:9.28803921px;font-family:Arial;fill:#2b2828;stroke-width:0.10514989"
+           id="text351"
+           y="154.10822"
+           x="667.07562"
+           transform="scale(1.0007154,0.99928514)">5</text>
+      </g>
+      <g
+         style="stroke-width:0.13585199"
+         inkscape:label="2"
+         id="g4927">
+        <path
+           inkscape:connector-curvature="0"
+           d="m 668,172 h 19 c 2,0 3,1 3,3 v 17 c 0,1 -1,3 -3,3 h -19 c -1,0 -3,-2 -3,-3 v -17 c 0,-2 2,-3 3,-3 z"
+           id="path177"
+           style="opacity:1;vector-effect:none;fill:#d3d2d2;fill-opacity:1;stroke:none;stroke-width:0.10074359;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+        <text
+           style="font-weight:normal;font-size:9.28803921px;font-family:Arial;fill:#2b2828;stroke-width:0.10514989"
+           id="text355"
+           y="179.82285"
+           x="667.07562"
+           transform="scale(1.0007154,0.99928514)">2</text>
+      </g>
+      <g
+         style="stroke-width:0.13585199"
+         inkscape:label="9"
+         id="g4902">
+        <path
+           inkscape:connector-curvature="0"
+           d="m 697,120 h 20 c 2,0 3,2 3,3 v 18 c 0,2 -1,3 -3,3 h -20 c -1,0 -3,-1 -3,-3 v -18 c 0,-1 2,-3 3,-3 z"
+           id="path167"
+           style="opacity:1;vector-effect:none;fill:#d3d2d2;fill-opacity:1;stroke:none;stroke-width:0.10074359;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+        <text
+           style="font-weight:normal;font-size:9.28803921px;font-family:Arial;fill:#2b2828;stroke-width:0.10514989"
+           id="text363"
+           y="129.38269"
+           x="695.75708"
+           transform="scale(1.0007154,0.99928514)">9</text>
+      </g>
+      <g
+         style="stroke-width:0.13585199"
+         inkscape:label="6"
+         id="g4917">
+        <path
+           inkscape:connector-curvature="0"
+           d="m 697,146 h 20 c 2,0 3,1 3,3 v 18 c 0,2 -1,3 -3,3 h -20 c -1,0 -3,-1 -3,-3 v -18 c 0,-2 2,-3 3,-3 z"
+           id="path173"
+           style="opacity:1;vector-effect:none;fill:#d3d2d2;fill-opacity:1;stroke:none;stroke-width:0.10074359;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+        <text
+           style="font-weight:normal;font-size:9.28803921px;font-family:Arial;fill:#2b2828;stroke-width:0.10514989"
+           id="text367"
+           y="154.10822"
+           x="695.75708"
+           transform="scale(1.0007154,0.99928514)">6</text>
+      </g>
+      <g
+         style="stroke-width:0.13585199"
+         inkscape:label="3"
+         id="g4932">
+        <path
+           inkscape:connector-curvature="0"
+           d="m 697,172 h 20 c 2,0 3,1 3,3 v 17 c 0,1 -1,3 -3,3 h -20 c -1,0 -3,-2 -3,-3 v -17 c 0,-2 2,-3 3,-3 z"
+           id="path179"
+           style="opacity:1;vector-effect:none;fill:#d3d2d2;fill-opacity:1;stroke:none;stroke-width:0.10074359;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+        <text
+           style="font-weight:normal;font-size:9.28803921px;font-family:Arial;fill:#2b2828;stroke-width:0.10514989"
+           id="text371"
+           y="179.82285"
+           x="695.75708"
+           transform="scale(1.0007154,0.99928514)">3</text>
+      </g>
+      <g
+         style="stroke-width:0.13585199"
+         inkscape:label="0"
+         id="g4937">
+        <path
+           inkscape:connector-curvature="0"
+           d="m 638,220 c -1,0 -3,-1 -3,-2 v -19 c 0,-1 2,-2 3,-2 h 49 c 2,0 3,1 3,2 v 19 c 0,1 -1,2 -3,2 z"
+           id="path373"
+           style="opacity:1;vector-effect:none;fill:#d3d2d2;fill-opacity:1;stroke:none;stroke-width:0.10074359;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+        <text
+           style="font-weight:normal;font-size:9.28803921px;font-family:Arial;fill:#2b2828;stroke-width:0.10514989"
+           id="text377"
+           y="205.53712"
+           x="636.4165"
+           transform="scale(1.0007154,0.99928514)">0</text>
+      </g>
+    </g>
+    <g
+       id="g3113"
+       inkscape:label="Esc"
+       transform="translate(-318.22576)">
+      <path
+         style="opacity:1;vector-effect:none;fill:#4f4c4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.16824313;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="path167-3"
+         d="m 387.26079,54.792986 h 33.40019 c 3.34,0 5.01006,3.34003 5.01006,5.010045 v 30.060225 c 0,3.340029 -1.67006,5.010032 -5.01006,5.010032 h -33.40019 c -1.67006,0 -5.01007,-1.670003 -5.01007,-5.010032 V 59.803031 c 0,-1.670015 3.34001,-5.010045 5.01007,-5.010045 z"
+         inkscape:connector-curvature="0" />
+      <text
+         x="394.42801"
+         y="78.632088"
+         id="text469-4"
+         style="font-weight:normal;font-size:10.63882256px;font-family:Arial;fill:#ffffff;fill-rule:evenodd;stroke-width:0.36866826"
+         transform="scale(1.0007154,0.99928511)">Esc</text>
+    </g>
+    <g
+       id="g3109"
+       inkscape:label="BackSpace"
+       transform="translate(0,-43.420332)">
+      <path
+         style="opacity:1;vector-effect:none;fill:#d3d2d2;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.16824308;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="path173-1"
+         d="m 387.26079,98.213318 h 33.40019 c 3.34,0 5.01006,1.670013 5.01006,5.010032 v 30.06024 c 0,3.34002 -1.67006,5.01003 -5.01006,5.01003 h -33.40019 c -1.67006,0 -5.01007,-1.67001 -5.01007,-5.01003 v -30.06024 c 0,-3.340019 3.34001,-5.010032 5.01007,-5.010032 z"
+         inkscape:connector-curvature="0" />
+      <path
+         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2b2828;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m -1278.9668,1041.3047 -6.9199,4 6.9199,4 v -3 h 33.416 v -1.9981 h -33.416 z"
+         transform="matrix(0.47690966,0,0,0.47690966,1008.0304,-380.26227)"
+         id="path11623-1-0-2"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       id="g787"
+       inkscape:label="Sign"
+       style="fill-rule:evenodd;stroke-width:0.13585199"
+       transform="matrix(1.6700128,0,0,1.6700128,-678.20742,-102.18822)">
+      <path
+         style="opacity:1;vector-effect:none;fill:#d3d2d2;fill-opacity:1;stroke:none;stroke-width:0.10074359;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="path781"
+         d="m 638,120 h 20 c 2,0 3,2 3,3 v 18 c 0,2 -1,3 -3,3 h -20 c -1,0 -3,-1 -3,-3 v -18 c 0,-1 2,-3 3,-3 z"
+         inkscape:connector-curvature="0" />
+      <text
+         x="642.1239"
+         y="135.09822"
+         id="text783"
+         style="font-weight:normal;font-size:9.28803921px;font-family:Arial;fill:#2b2828;stroke-width:0.10514989"
+         transform="scale(1.0007154,0.99928514)">+/-</text>
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.31375408px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.30784383px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="252.9579"
+       y="12.333653"
+       id="text509"
+       transform="scale(0.96824589,1.0327955)"
+       inkscape:label="Info"><tspan
+         sodipodi:role="line"
+         id="tspan507"
+         x="252.9579"
+         y="12.333653"
+         style="stroke-width:0.30784383px">information</tspan></text>
+    <g
+       transform="matrix(1.6700128,0,0,1.6700128,-826.83854,-145.60856)"
+       style="fill-rule:evenodd;stroke-width:0.13585199"
+       id="g4942"
+       inkscape:label="NumDot">
+      <path
+         inkscape:connector-curvature="0"
+         d="m 697,197 h 20 c 2,0 3,1 3,2 v 19 c 0,1 -1,2 -3,2 h -20 c -1,0 -3,-1 -3,-2 v -19 c 0,-1 2,-2 3,-2 z"
+         id="path181"
+         style="opacity:1;vector-effect:none;fill:#d3d2d2;fill-opacity:1;stroke:none;stroke-width:0.10074359;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         style="font-weight:normal;font-size:6.96602964px;font-family:Arial;fill:#2b2828;stroke-width:0.10514989"
+         id="text771"
+         y="204.54802"
+         x="696.7464"
+         transform="scale(1.0007154,0.99928514)">.</text>
+    </g>
+  </g>
+  <rect
+     style="color:#000000;fill:#ffffff"
+     id="page0"
+     width="1280"
+     height="720"
+     x="0"
+     y="0"
+     inkscape:label="HMI:Page:Home"
+     sodipodi:insensitive="true" />
+  <g
+     id="g4490"
+     inkscape:label="HMI:Input@/VAR0"
+     transform="translate(220,-220)">
+    <rect
+       style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="rect4452"
+       width="165.96402"
+       height="78.240181"
+       x="207.3945"
+       y="501.87585"
+       rx="7"
+       ry="7"
+       inkscape:label="edit" />
+    <text
+       id="text4456"
+       y="551.66504"
+       x="289.30231"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       xml:space="preserve"
+       inkscape:label="value"><tspan
+         y="551.66504"
+         x="289.30231"
+         id="tspan4454"
+         sodipodi:role="line">1234</tspan></text>
+    <g
+       id="g4464"
+       inkscape:label="-1"
+       transform="translate(-414.79908,-17.189114)">
+      <rect
+         style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         id="rect4458"
+         width="99.578415"
+         height="88.909302"
+         x="392.38638"
+         y="513.73041"
+         rx="7"
+         ry="7" />
+      <text
+         xml:space="preserve"
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         x="441.65189"
+         y="566.1087"
+         id="text4462"><tspan
+           sodipodi:role="line"
+           id="tspan4460"
+           x="441.65189"
+           y="566.1087">-1</tspan></text>
+    </g>
+    <g
+       transform="translate(-534.79908,-17.189114)"
+       inkscape:label="-10"
+       id="g4472">
+      <rect
+         ry="7"
+         rx="7"
+         y="513.73041"
+         x="392.38638"
+         height="88.909302"
+         width="99.578415"
+         id="rect4466"
+         style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+      <text
+         id="text4470"
+         y="566.1087"
+         x="441.65189"
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         xml:space="preserve"><tspan
+           y="566.1087"
+           x="441.65189"
+           id="tspan4468"
+           sodipodi:role="line">-10</tspan></text>
+    </g>
+    <g
+       transform="translate(111.20092,-17.189114)"
+       inkscape:label="+1"
+       id="g4480">
+      <rect
+         ry="7"
+         rx="7"
+         y="513.73041"
+         x="392.38638"
+         height="88.909302"
+         width="99.578415"
+         id="rect4474"
+         style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+      <text
+         id="text4478"
+         y="566.1087"
+         x="441.65189"
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         xml:space="preserve"><tspan
+           y="566.1087"
+           x="441.65189"
+           id="tspan4476"
+           sodipodi:role="line">+1</tspan></text>
+    </g>
+    <g
+       id="g4488"
+       inkscape:label="+10"
+       transform="translate(231.20092,-17.189114)">
+      <rect
+         style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         id="rect4482"
+         width="99.578415"
+         height="88.909302"
+         x="392.38638"
+         y="513.73041"
+         rx="7"
+         ry="7" />
+      <text
+         xml:space="preserve"
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         x="441.65189"
+         y="566.1087"
+         id="text4486"><tspan
+           sodipodi:role="line"
+           id="tspan4484"
+           x="441.65189"
+           y="566.1087">+10</tspan></text>
+    </g>
+    <g
+       id="g154"
+       inkscape:label="+0.1"
+       transform="translate(-8.7991028,-17.189114)">
+      <rect
+         style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         id="rect148"
+         width="99.578415"
+         height="88.909302"
+         x="392.38638"
+         y="513.73041"
+         rx="7"
+         ry="7" />
+      <text
+         xml:space="preserve"
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         x="441.65189"
+         y="566.1087"
+         id="text152"><tspan
+           sodipodi:role="line"
+           id="tspan150"
+           x="441.65189"
+           y="566.1087">+.1</tspan></text>
+    </g>
+    <g
+       transform="translate(-294.79907,-17.189114)"
+       inkscape:label="-0.1"
+       id="g162">
+      <rect
+         ry="7"
+         rx="7"
+         y="513.73041"
+         x="392.38638"
+         height="88.909302"
+         width="99.578415"
+         id="rect156"
+         style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+      <text
+         id="text160"
+         y="566.1087"
+         x="441.65189"
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         xml:space="preserve"><tspan
+           y="566.1087"
+           x="441.65189"
+           id="tspan158"
+           sodipodi:role="line">-.1</tspan></text>
+    </g>
+  </g>
+  <g
+     id="g170"
+     inkscape:label="HMI:Display@/VAR0"
+     transform="translate(-400)">
+    <text
+       id="text166"
+       y="96.5625"
+       x="595.3125"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       xml:space="preserve"
+       inkscape:label="format"><tspan
+         y="96.5625"
+         x="595.3125"
+         id="tspan164"
+         sodipodi:role="line">%.2f</tspan></text>
+  </g>
+  <g
+     inkscape:label="HMI:Display@/VAR1"
+     id="g3879"
+     transform="translate(-400,80)">
+    <text
+       inkscape:label="format"
+       xml:space="preserve"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="595.3125"
+       y="96.5625"
+       id="text3877"><tspan
+         sodipodi:role="line"
+         id="tspan3875"
+         x="595.3125"
+         y="96.5625">%d</tspan></text>
+  </g>
+  <g
+     inkscape:label="HMI:Display@/VAR0"
+     id="g3885"
+     transform="translate(-140)">
+    <text
+       inkscape:label="format"
+       xml:space="preserve"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="595.3125"
+       y="96.5625"
+       id="text3883"><tspan
+         sodipodi:role="line"
+         id="tspan3881"
+         x="595.3125"
+         y="96.5625">temp: %.2f℃</tspan></text>
+  </g>
+  <g
+     transform="translate(220)"
+     id="g3895"
+     inkscape:label="HMI:Display@/VAR0">
+    <text
+       id="text3893"
+       y="96.5625"
+       x="595.3125"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       xml:space="preserve"
+       inkscape:label="format"><tspan
+         y="96.5625"
+         x="595.3125"
+         id="tspan3891"
+         sodipodi:role="line">ratio: %.2f%%</tspan></text>
+  </g>
+  <g
+     transform="translate(-220,80)"
+     id="g3901"
+     inkscape:label="HMI:Display@/VAR1">
+    <text
+       id="text3899"
+       y="96.5625"
+       x="655.3125"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       xml:space="preserve"
+       inkscape:label="format"><tspan
+         y="96.5625"
+         x="655.3125"
+         id="tspan3897"
+         sodipodi:role="line">padded: %'04d</tspan></text>
+  </g>
+  <g
+     transform="translate(-140,440)"
+     id="g3907"
+     inkscape:label="HMI:Display@/VAR1@/VAR0">
+    <text
+       id="text3905"
+       y="96.5625"
+       x="595.3125"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       xml:space="preserve"
+       inkscape:label="format"><tspan
+         y="96.5625"
+         x="595.3125"
+         id="tspan3903"
+         sodipodi:role="line">this way, %d and %.3f are together</tspan></text>
+  </g>
+</svg>