Revision: 4117
          http://vexi.svn.sourceforge.net/vexi/?rev=4117&view=rev
Author:   mkpg2
Date:     2011-05-09 21:05:47 +0000 (Mon, 09 May 2011)

Log Message:
-----------
Improve. Reimplement numfield to use vexi.js.Decimal.

Modified Paths:
--------------
    trunk/org.vexi-vexi.widgets/src_main/org/vexi/lib/text/edit.t
    trunk/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/numfield.t
    trunk/org.vexi-vexi.widgets/src_main/vexi/util/sync.t
    trunk/org.vexi-vexi.widgets/src_test/test/lib/text/edit.t
    trunk/org.vexi-vexi.widgets/src_test/test/util/sync.t
    trunk/org.vexi-vexi.widgets/src_test/test/widget/numfield.t

Added Paths:
-----------
    trunk/org.vexi-vexi.widgets/src_poke/poke/
    trunk/org.vexi-vexi.widgets/src_poke/poke/widgets/
    trunk/org.vexi-vexi.widgets/src_poke/poke/widgets/poke_numfield.t

Removed Paths:
-------------
    trunk/org.vexi-vexi.widgets/src_poke/poke/widgets/numfield.t
    trunk/org.vexi-vexi.widgets/src_poke/widgets/

Modified: trunk/org.vexi-vexi.widgets/src_main/org/vexi/lib/text/edit.t
===================================================================
--- trunk/org.vexi-vexi.widgets/src_main/org/vexi/lib/text/edit.t       
2011-05-09 20:13:23 UTC (rev 4116)
+++ trunk/org.vexi-vexi.widgets/src_main/org/vexi/lib/text/edit.t       
2011-05-09 21:05:47 UTC (rev 4117)
@@ -1741,7 +1741,7 @@
             return cWord ? cindex+cPos : cindex;
         }
         
-        thisbox.setCusrorCharIndex = function(index) {
+        thisbox.setCursorCharIndex = function(index) {
             var curindex = 0;
             var numblocks = numchildren;
             for (var i=0; numblocks>i; i++) {

Modified: trunk/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/numfield.t
===================================================================
--- trunk/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/numfield.t 
2011-05-09 20:13:23 UTC (rev 4116)
+++ trunk/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/numfield.t 
2011-05-09 21:05:47 UTC (rev 4117)
@@ -1,6 +1,6 @@
 <!-- Copyright 2009 - see COPYING for details [LGPL] -->
 
-<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns="org.vexi.lib" 
xmlns:decimal="vexi.util.decimal">
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns="org.vexi.lib" 
xmlns:sync="vexi.util.sync">
     <meta:doc>
         <author>Mike Goodwin</author>
     </meta:doc>
@@ -9,170 +9,155 @@
     <role.tooltipable />
     <text.field />
     <ui:box>
-        
+        thisbox.v_edit;     // abstract
         thisbox.enabled = true;        
-        
-        // TBD - separate out min/max/decimalPlaces validity and have in a 
separate template ??
-        thisbox.restrict = false;  // restrict means ignore any input that 
breaches its min/max
+      
         thisbox.minvalue;
         thisbox.maxvalue;
-        thisbox.decimalPlaces;     // 0 for an integer, null for unlimited
+        thisbox.scale;       // number of decimal places, if positive. If 
negative, number of trailing 0's
         
         // value and the v_edit.text are synchronized
-        thisbox.decimal = new decimal("");
-        thisbox.v_edit;
+        thisbox.value;
         
+        thisbox.validateText = static.validateTextFunc;
+        
         KeyPressed ++= static.keypressEvent;
-        decimalPlaces ++= static.decimalPlacesWrite;
-        maxvalue   ++= static.maxvalueWrite;
-        minvalue   ++= static.minvalueWrite;
-        number     ++= static.numberRead;
-        number     ++= static.valueWrite;
-        value      ++= static.valueRead;
-        value      ++= static.valueWrite;
+        scale      ++= static.scale;
+        maxvalue   ++= static.limitvalueWrite;
+        minvalue   ++= static.limitvalueWrite;
         
+        const Decimal = vexi.js.Decimal;
+        
+        thisbox.validateNumber = function(d){
+            if(d==null) return null;
+            var d0 = d;
+
+               
+               if(maxvalue!=null){
+                if(0>Decimal.compare(maxvalue, d)){
+                       d = maxvalue;
+                   }
+               }
+               
+               if(minvalue!=null){
+                   if(0 > Decimal.compare(d, minvalue)){
+                       d = minvalue;
+                   }
+               }
+               
+               if(scale!=null){
+                d = d.round(scale);
+            }
+            return d;
+        };
+
+                            
+        thisbox.focused ++= function(v){
+            if(!v){
+                // trigger value setting
+                v_edit.text = v_edit.text;
+            }
+            cascade = v;
+        };
+        
+        thisbox.value ++= function(v){
+            cascade = validateNumber(Decimal.cast(v));
+        };
+
+        
+        thisbox.text2decimal = function(v){
+            var d = Decimal.tryParseString(v);
+            if(d!=null){
+                d = validateNumber(d);
+            }
+            return d;
+        };
+        
+        var decimal2text= function(d){
+            if(d==null) return "";
+            return d+"";
+        };
+        
+        thisbox.v_edit ++= function(v){
+            cascade = v;        
+            sync..syncTransform(thisbox, v, "value", "text", decimal2text, 
text2decimal);
+            thisbox[trapname] --= callee;
+        };
+        
+        
     </ui:box>
+
+    var Decimal = vexi.js.Decimal;
     
-    var modifyVal = function(val,i,key) {
-        switch (key) {
-        case "delete":
-            return val.attemptRemove(i);
-        case "back_space":
-            return val.attemptRemove(i-1);
-        //case "escape": ...
-        case "left": case "right": case "up": case "down": 
-        case "home": case "end":
-            return null;
-        }
-        return val.attemptInsert(i,key);
-    };
-    
     /** fire action or filter key in case of password fields */
     static.keypressEvent = function(v) {
         var t = trapee;
         var e = t.v_edit;
-        if (e.select) {
-            cascade = v;
-            try { t.value = e.text; }
-            catch(e) { if (vexi.debug) vexi.log.info(e); }
+        var txt0 = e.text;
+
+        
+        switch(v){
+        // Handle '-' specially. Toggles sign.
+        case '-': {
+            var cpos = e.getCursorCharIndex();
+            if(txt0.length==0 or txt0.charAt(0)!='-'){
+                e.text = '-'+txt0;
+                cpos++;
+            }else{
+                e.text = txt0.substring(1);
+                if(cpos!=0) cpos--;
+            }
+            e.setCursorCharIndex(cpos);
             return;
         }
-        var val = t.decimal;
-        var txt = e.text;
-        var cpos = e.getCursorCharIndex();
-        
-        var prev = val;
-        val = modifyVal(val, cpos, v);
-        if (val==null) {
-            cascade = v;
+        case "ENTER":
+        case "enter": {
+            var cpos = e.getCursorCharIndex();
+            t.value = t.text2decimal(e.text);
+            cpos = vexi.math.max(e.text.length, cpos);
+            e.setCursorCharIndex(cpos);
             return;
         }
-        
-        var newvalid = true;
-        if ((t.minvalue and (0>val.compareTo(t.minvalue)))
-                || (t.maxvalue and (val.compareTo(t.maxvalue)>0))
-                || (t.decimalPlaces and (val.after > t.decimalPlaces))) {
-            if (trapee.restrict) {
-                return;
+        case ".": {
+            var cpos = e.getCursorCharIndex();
+            cascade = v;
+            // If invalid revert ...        
+            if(e.text.indexOf(".")!=e.text.lastIndexOf(".")){
+                e.text = txt0;
+                e.setCursorCharIndex(cpos);
             }
-            newvalid = false;
-        } else {
-            t.decimal = val;
+            return;
         }
+        case "C-a": case "C-x": case "C-v":  
+        case "LEFT": case "RIGHT": case "UP": case "DOWN": 
+        case "left": case "right": case "up": case "down": 
+        case "HOME": case "END": 
+        case "home": case "end": 
+        case "BACK_SPACE": case "DELETE":
+        case "back_space": case "delete":
         
-        cascade = v;
-        if (t.valid!=newvalid) {
-            t.valid = newvalid;
+        case "0": case "1": case "2": case "3": case "4":
+        case "5": case "6": case "7": case "8": case "9": 
+            // Due to possibility of selection, not just editing a single char
+            // let the text widget handle this and correct as necessary
+            cascade = v;
         }
     }
+
     
     /** constrain value to min */
-    static.minvalueWrite = function(v) {
-        if (v!=null and !(v instanceof decimal)) {
-            v = new decimal(v);
-        }
+    static.limitvalueWrite = function(v) {
+        v = Decimal.cast(v);
         cascade = v;
         // constrain/set validity
         trapee.value = trapee.value; 
     }
     
     /** constrain value to max */
-    static.maxvalueWrite = function(v) {
-        if (v!=null and !(v instanceof decimal)) {
-            v = new decimal(v);
-        }
+    static.scale = function(v) {
         cascade = v;
         // constrain/set validity
         trapee.value = trapee.value; 
     }
     
-    /** constrain value to max */
-    static.decimalPlacesWrite = function(v) {
-        cascade = v;
-        // constrain/set validity
-        trapee.value = trapee.value; 
-    }
-    
-    /** return value as a number */
-    static.numberRead = function() {
-        var r = trapee.decimal.canonical;
-        if (trapee.decimalPlaces and trapee.decimalPlaces==0) {
-            return vexi.string.parseInt(r);
-        }
-        return vexi.string.parseFloat(r);
-    }
-    
-    /** parse and return value as a string */
-    static.valueRead = function() {
-        // FIXME: decimal is returning haywire numbers after edits
-        var r = trapee.decimal.canonical;
-        var v = new decimal(r);
-        var dpsActual = v.after;
-        var dpsWanted = trapee.decimalPlaces;
-        if (dpsWanted==null || dpsActual==dpsWanted) {
-            return r;
-        }
-        if (dpsWanted>dpsActual) {
-            if (dpsActual==0) {
-                r += '.';
-            }
-            var addzeros = dpsWanted-dpsActual;
-            while ((addzeros--)>0) {
-                r += '0';
-            }
-        } else {
-            r = v.truncate(dpsWanted).canonical;
-        }
-        return r;
-    }
-    
-    /** verify the user-set value */
-    static.valueWrite = function(v) {
-        var t = trapee;
-        if (!(v instanceof decimal)) {
-            v = new decimal(v);
-        }
-        v.assertValid();
-        
-        if (t.restrict) {
-            if (t.minvalue and (0>v.compareTo(t.minvalue))) {
-                v = t.minvalue;
-            } else if (t.maxvalue and (v.compareTo(t.maxvalue)>0)) { 
-                v = t.maxvalue;
-            }
-            if (t.decimalPlaces and (v.after > t.decimalPlaces)) {
-                v = v.truncate(t.decimalPlaces);
-            }
-        } else if ((t.minvalue and (0>v.compareTo(t.minvalue))) ||
-                (t.maxvalue and (v.compareTo(t.maxvalue)>0)) ||
-                (t.decimalPlaces and (v.after > t.decimalPlaces))) {
-            t.valid = false;
-        }
-        t.decimal = v;
-        if (t.v_edit.text != v.canonical) {
-            t.v_edit.text = v.canonical;
-        }
-        return;
-    }
-    
 </vexi>

Modified: trunk/org.vexi-vexi.widgets/src_main/vexi/util/sync.t
===================================================================
--- trunk/org.vexi-vexi.widgets/src_main/vexi/util/sync.t       2011-05-09 
20:13:23 UTC (rev 4116)
+++ trunk/org.vexi-vexi.widgets/src_main/vexi/util/sync.t       2011-05-09 
21:05:47 UTC (rev 4117)
@@ -56,7 +56,7 @@
             cascade = v;
             if (fromB) return;
             fromA = true;
-            try { b[kb] = v; } 
+            try { b[kb] = trapee[trapname]; } 
             finally { fromA = false; }
         };
         
@@ -64,7 +64,7 @@
             cascade = v;
             if (fromA) return;
             fromB = true;
-            try { a[ka] = v; } 
+            try { a[ka] = trapee[trapname]; } 
             finally { fromB = false; }
         };
         
@@ -97,7 +97,7 @@
             cascade = v;
             if (fromB) return;
             fromA = true;
-            try { b[kb] = a2b(v); } 
+            try { b[kb] = a2b(trapee[trapname]); } 
             finally { fromA = false; }
         };
         
@@ -105,7 +105,7 @@
             cascade = v;
             if (fromA) return;
             fromB = true;
-            try { a[ka] = b2a(v); } 
+            try { a[ka] = b2a(trapee[trapname]); } 
             finally { fromB = false; }
         };
         

Deleted: trunk/org.vexi-vexi.widgets/src_poke/poke/widgets/numfield.t
===================================================================
--- trunk/org.vexi-vexi.widgets/src_poke/widgets/numfield.t     2011-04-04 
12:31:07 UTC (rev 4104)
+++ trunk/org.vexi-vexi.widgets/src_poke/poke/widgets/numfield.t        
2011-05-09 21:05:47 UTC (rev 4117)
@@ -1,37 +0,0 @@
-<vexi xmlns:ui="vexi://ui" xmlns:w="vexi.widget">
-    <w:surface />
-    <ui:box orient="vertical">
-        <ui:box shrink="true">
-            <w:check id="restrict" text="restrict"/>
-            <w:check id="three_dp" text="3dp"/>
-            <w:check id="positive" text="positive"/>
-        </ui:box>
-        <w:numfield id="numfield" />
-        
-        $restrict.selected ++= function(v) {
-            cascade = v;
-            $positive.enabled = $three_dp.enabled = v;
-            $numfield.restrict = v;
-        };
-        
-        $positive.selected ++= function(v) {
-            cascade = v;
-            $numfield.minvalue = v?"0":null;
-        };
-        
-        $three_dp.selected ++= function(v) {
-            cascade = v;
-            $numfield.decimalPlaces = v?3:null;
-        };
-        
-        $restrict.selected = false;
-        
-        $numfield.value ++= function(v) {
-            cascade = v;
-            vexi.log.info(v);
-        };
-        
-        vexi.ui.frame = thisbox;
-        
-    </ui:box>
-</vexi>

Added: trunk/org.vexi-vexi.widgets/src_poke/poke/widgets/poke_numfield.t
===================================================================
--- trunk/org.vexi-vexi.widgets/src_poke/poke/widgets/poke_numfield.t           
                (rev 0)
+++ trunk/org.vexi-vexi.widgets/src_poke/poke/widgets/poke_numfield.t   
2011-05-09 21:05:47 UTC (rev 4117)
@@ -0,0 +1,36 @@
+<vexi xmlns:ui="vexi://ui" xmlns:w="vexi.widget">
+    <w:surface />
+    <ui:box orient="vertical">
+        <ui:box shrink="true">
+            <w:check id="three_dp" text="3dp"/>
+            <w:check id="positive" text="positive"/>
+            <w:check id="maximum" text="max==100"/>
+        </ui:box>
+        <w:numfield id="numfield" />
+        $three_dp.selected ++= function(v) {
+            cascade = v;
+            $numfield.scale = v?3:null;
+        };
+        
+        $positive.selected ++= function(v) {
+            cascade = v;
+            $numfield.minvalue = v?0:null;
+        };
+        
+        $maximum.selected ++= function(v) {
+            cascade = v;
+            $numfield.maxvalue = v?100:null;
+        };
+        
+        $numfield.value ++= function(v) {
+            cascade = v;
+            vexi.log.info("Value: "+v);
+        };
+        
+        
+        $numfield.value = "300.00";
+       
+        vexi.ui.frame = thisbox;
+        
+    </ui:box>
+</vexi>

Modified: trunk/org.vexi-vexi.widgets/src_test/test/lib/text/edit.t
===================================================================
--- trunk/org.vexi-vexi.widgets/src_test/test/lib/text/edit.t   2011-05-09 
20:13:23 UTC (rev 4116)
+++ trunk/org.vexi-vexi.widgets/src_test/test/lib/text/edit.t   2011-05-09 
21:05:47 UTC (rev 4117)
@@ -35,13 +35,13 @@
     suite.setCursorPosition = function() {
         var b1 = .edit(vexi.box);
         b1.text = "sausage and beans";
-        b1.setCusrorPosition(3);
+        b1.setCursorCharIndex(3);
         assertEq(3, b1.getCursorPosition());
-        b1.setCusrorPosition(7);
+        b1.setCursorCharIndex(7);
         assertEq(7, b1.getCursorPosition());
-        b1.setCusrorPosition(10);
+        b1.setCursorCharIndex(10);
         assertEq(10, b1.getCursorPosition());
-        b1.setCusrorPosition(17);
+        b1.setCursorCharIndex(17);
         assertEq(17, b1.getCursorPosition());
     };    
 

Modified: trunk/org.vexi-vexi.widgets/src_test/test/util/sync.t
===================================================================
--- trunk/org.vexi-vexi.widgets/src_test/test/util/sync.t       2011-05-09 
20:13:23 UTC (rev 4116)
+++ trunk/org.vexi-vexi.widgets/src_test/test/util/sync.t       2011-05-09 
21:05:47 UTC (rev 4117)
@@ -2,45 +2,74 @@
     <meta:doc>
         <author>Charles Goodwin</author>
     </meta:doc>
+
+    var assertEq = .test.vunit..assertEq;
+    var assertObjEq = .test.vunit..assertObjectEquals;
+  
+
+        /// Quick Suite
+    var suite = {};
+
+
+    suite.testBasic = function() {
+        var a = {x: "a"};
+        var b = {y: "b"};
+        var token = sync..sync(a, b, "x", "y");
+        
+        assertEq("a",a.x);
+        assertEq("b",b.y);
+        a.x = "c";
+        assertEq("c",a.x);
+        assertEq("c",b.y);
+        
+        sync..unsync(token);
+        a.x = "d";
+        assertEq("d",a.x);
+        assertEq("c",b.y);
+    };
     
-    <ui:box>
-        var assertEq = .test.vunit..assertEq;
-        var assertObjEq = .test.vunit..assertObjectEquals;
+    suite.testTransform = function() {
+        var a = {x: "a.b"};
+        var b = {y: []};
+        var a2b = function(s){ return s.split("."); };
+        var b2a = function(a){ return a.join("."); };
+        var token = sync..syncTransform(a, b, "x", "y", a2b, b2a);
         
-        { // normal
-            var a = {x: "a"};
-            var b = {y: "b"};
-            var token = sync..sync(a, b, "x", "y");
-            
-            assertEq("a",a.x);
-            assertEq("b",b.y);
-            a.x = "c";
-            assertEq("c",a.x);
-            assertEq("c",b.y);
-            
-            sync..unsync(token);
-            a.x = "d";
-            assertEq("d",a.x);
-            assertEq("c",b.y);
-        }
+        assertObjEq("a.b",a.x);
+        assertObjEq([],b.y);
+        a.x = a.x;
+        assertObjEq(["a","b"],b.y);
+        b.y = ["c","d"];
+        assertEq("c.d",a.x);
         
-        { // transform
-            var a = {x: "a.b"};
-            var b = {y: []};
-            var a2b = function(s){ return s.split("."); };
-            var b2a = function(a){ return a.join("."); };
-            var token = sync..syncTransform(a, b, "x", "y", a2b, b2a);
-            
-            assertObjEq("a.b",a.x);
-            assertObjEq([],b.y);
-            a.x = a.x;
-            assertObjEq(["a","b"],b.y);
-            b.y = ["c","d"];
-            assertEq("c.d",a.x);
-            
-            sync..unsync(token);
-            a.x = "e.f";
-            assertObjEq(["c","d"],b.y);
-        }
-    </ui:box>
+        sync..unsync(token);
+        a.x = "e.f";
+        assertObjEq(["c","d"],b.y);  
+    };
+    
+    
+    suite.testChain = function() {
+        var a = {v: 0};
+        var b = {v: null};
+        var c = {v: null};
+        
+        var a2b = sync..sync(a, b, "v", "v");
+        var b2c = sync..sync(b, c, "v", "v");
+        
+        a.v = 1;
+        assertEq(1,a.v);
+        assertEq(1,b.v);
+        assertEq(1,c.v);
+        
+        b.v = 2;
+        assertEq(2,a.v);
+        assertEq(2,b.v);
+        assertEq(2,c.v);
+    };
+  
+    static.test = suite;    
+    
+    
+    <ui:box/>
+        
 </vexi>
\ No newline at end of file

Modified: trunk/org.vexi-vexi.widgets/src_test/test/widget/numfield.t
===================================================================
--- trunk/org.vexi-vexi.widgets/src_test/test/widget/numfield.t 2011-05-09 
20:13:23 UTC (rev 4116)
+++ trunk/org.vexi-vexi.widgets/src_test/test/widget/numfield.t 2011-05-09 
21:05:47 UTC (rev 4117)
@@ -3,6 +3,8 @@
         <author>Charles Goodwin</author>
     </meta:doc>
 
+    const Decimal = vexi.js.Decimal;
+
     /// Quick Suite
     var suite = {};
 
@@ -14,20 +16,27 @@
         /**
         *  basic numfield value write tests
         */
-        var b = .numfield(vexi.box);
-        b.decimalPlaces = 2;
+        var b = new .numfield();
+        b.scale = 2;
         b.value = "1.00";
-        assertEq("1.00",b.value);
+        assertEq("1.00",b.value+"");
         b.value = "1.000";
-        assertEq("1.00",b.value);
+        assertEq("1.00",b.value+"");
         b.value = "1.0";
-        assertEq("1.00",b.value);
-        b.number = 2;
-        assertEq("2.00",b.value);
+        assertEq("1.00",b.value+"");
+        b.value = new Decimal(21.2);
+        assertEq("21.20",b.value+"");
+        b.scale = 4;
+        assertEq("21.2000",b.value+"");
+        b.scale = -1;
+        assertEq("20",b.value+"");
         
-        assertExceptionThrown(function() { b.value = "sausage"; });
     };
     
+//    suite.testException = function() {
+//        assertExceptionThrown(function() { b.value = "sausage"; });
+//    };
+    
     suite.testInteraction1 = function() {
         /**
         *  test numfield focusable and
@@ -36,16 +45,17 @@
         var focusmodel = { setFocus:function(t, f) { return true; } };
         var fmsurface = { focus:focusmodel };
         var b1 = .numfield(vexi.box);
-        b1.decimalPlaces = 2;
+        b1.scale = 2;
         b1.surface ++= function() { return fmsurface; }
         b1.value = "1.00";
         b1.focused = true;
+//        FIXME
         assertEq(true,b1.v_edit.select);
         b1.KeyPressed = "2";
         b1.KeyPressed = ".";
         b1.KeyPressed = "0";
         b1.focused = false;
-        assertEq("2.00",b1.value);
+        assertEq("2.00",b1.value+"");
     };    
 
     suite.testInteraction2 = function() {
@@ -55,31 +65,36 @@
         */
         var b2 = .numfield(vexi.box);
         b2.surface ++= function() { return fmsurface; }
-        b2.decimalPlaces = 2;
+        b2.scale = 2;
         b2.KeyPressed = "1";
         b2.KeyPressed = ".";
         b2.KeyPressed = "0";
-        assertEq("1.00",b2.value);
+        b2.KeyPressed = "enter";
+        assertEq("1.00",b2.value+"");
         b2.KeyPressed = "C-a";
         b2.KeyPressed = "delete";
         b2.KeyPressed = "2";
-        assertEq("2.00",b2.value);
+        b2.KeyPressed = "enter";
+        assertEq("2.00",b2.value+"");
         b2.KeyPressed = "C-a";
         b2.KeyPressed = "delete";
         b2.KeyPressed = "3";
         b2.KeyPressed = "0";
         b2.KeyPressed = "0";
-        assertEq("300.00",b2.value);
+        b2.KeyPressed = "enter";
+        assertEq("300.00",b2.value+"");
         b2.KeyPressed = "C-a";
         b2.KeyPressed = "delete";
         b2.KeyPressed = "1";
         b2.KeyPressed = ".";
         b2.KeyPressed = "2";
         b2.KeyPressed = "delete";
-        assertEq("1.20",b2.value);
+        b2.KeyPressed = "enter";
+        assertEq("1.20",b2.value+"");
         b2.KeyPressed = "back_space";
         b2.KeyPressed = "5";
-        assertEq("1.50",b2.value);
+        b2.KeyPressed = "enter";
+        assertEq("1.50",b2.value+"");
     };    
 
     static.test = suite;


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
WhatsUp Gold - Download Free Network Management Software
The most intuitive, comprehensive, and cost-effective network 
management toolset available today.  Delivers lowest initial 
acquisition cost and overall TCO of any competing solution.
http://p.sf.net/sfu/whatsupgold-sd
_______________________________________________
Vexi-svn mailing list
Vexi-svn@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vexi-svn

Reply via email to