Revision: 6682
          
http://languagetool.svn.sourceforge.net/languagetool/?rev=6682&view=rev
Author:   gulp21-1
Date:     2012-04-05 07:31:06 +0000 (Thu, 05 Apr 2012)
Log Message:
-----------
ltdiff: show improved rules
  correct handling of rules which are/were commented out
  show examples on hover
  ltdiff.bash:
   do not start creating html files when javac failed
   do not move "changes" folder

Modified Paths:
--------------
    trunk/JLanguageTool/ltdiff/de.txt
    trunk/JLanguageTool/ltdiff/en.txt
    trunk/JLanguageTool/ltdiff/gen.txt
    trunk/JLanguageTool/ltdiff/ltdiff.bash
    trunk/JLanguageTool/ltdiff/ltdiff.css
    trunk/JLanguageTool/ltdiff/ltdiff.java

Removed Paths:
-------------
    trunk/JLanguageTool/ltdiff/ltdiff.class

Modified: trunk/JLanguageTool/ltdiff/de.txt
===================================================================
--- trunk/JLanguageTool/ltdiff/de.txt   2012-04-05 01:05:47 UTC (rev 6681)
+++ trunk/JLanguageTool/ltdiff/de.txt   2012-04-05 07:31:06 UTC (rev 6682)
@@ -3,3 +3,6 @@
 Keine neuen Regeln wurden hinzugefügt und keine Regeln wurden enternt.
 NEUE REGEL
 ENTFERNTE REGEL
+VERBESSERTE REGEL
+findet Fehler in:
+findet keinen Fehler in:

Modified: trunk/JLanguageTool/ltdiff/en.txt
===================================================================
--- trunk/JLanguageTool/ltdiff/en.txt   2012-04-05 01:05:47 UTC (rev 6681)
+++ trunk/JLanguageTool/ltdiff/en.txt   2012-04-05 07:31:06 UTC (rev 6682)
@@ -3,3 +3,6 @@
 No new rules have been added and no rules have been removed.
 NEW RULE
 REMOVED RULE
+IMPROVED RULE
+finds error in:
+does not find error in:

Modified: trunk/JLanguageTool/ltdiff/gen.txt
===================================================================
--- trunk/JLanguageTool/ltdiff/gen.txt  2012-04-05 01:05:47 UTC (rev 6681)
+++ trunk/JLanguageTool/ltdiff/gen.txt  2012-04-05 07:31:06 UTC (rev 6682)
@@ -3,3 +3,6 @@
 No new rules have been added and no rules have been removed.
 NEW RULE
 REMOVED RULE
+IMPROVED RULE
+finds error in:
+does not find error in:

Modified: trunk/JLanguageTool/ltdiff/ltdiff.bash
===================================================================
--- trunk/JLanguageTool/ltdiff/ltdiff.bash      2012-04-05 01:05:47 UTC (rev 
6681)
+++ trunk/JLanguageTool/ltdiff/ltdiff.bash      2012-04-05 07:31:06 UTC (rev 
6682)
@@ -1,12 +1,21 @@
 #!/bin/bash
-javac ltdiff.java -Xlint:deprecation
-
 if [ ! $# -eq 2 ]; then
   echo Usage: ./ltdiff.bash old_branch new_branch
   echo e.g. ./ltdiff.bash V_1_6 V_1_7
   exit -1
 fi
 
+
+javac ltdiff.java -Xlint:deprecation
+
+if [ ! $? -eq 0 ]; then
+  echo javac failed
+  exit 1
+fi
+
+oldv=`echo $1 | sed "s/_/./g" | sed "s/V.//g"`
+newv=`echo $2 | sed "s/_/./g" | sed "s/V.//g"`
+
 i=1
 while read line
 do
@@ -16,6 +25,8 @@
 
 cat changes_a.html | sed "s/1title/${string[1]}/g" | sed 
"s/2intro/${string[2]}/g" | sed "s/3nothing/${string[3]}/g" > changes.html
 
+rm -r changes~
+mv changes changes~
 mkdir changes
 
 for l in `ls -d ../src/rules/*/ -l | awk -F / '{print $(NF-1)}'`
@@ -27,8 +38,13 @@
   
   wget 
http://languagetool.svn.sourceforge.net/viewvc/languagetool/branches/$1/src/rules/$l/grammar.xml
 -O old
   wget 
http://languagetool.svn.sourceforge.net/viewvc/languagetool/branches/$2/src/rules/$l/grammar.xml
 -O new
-  diff -c old new > grammar_$l.xml.diff
   
+  # remove xml comments
+  gawk -v RS='<!--|-->' 'NR%2' old > old~
+  gawk -v RS='<!--|-->' 'NR%2' new > new~
+  mv old~ old
+  mv new~ new
+  
   java ltdiff $l
   
   # read translated strings
@@ -47,10 +63,11 @@
   
   new_count=`grep "4NEWRULE" changes_$l.html | wc -l`
   removed_count=`grep "5REMOVEDRULE" changes_$l.html | wc -l`
+  improved_count=`grep "6IMPROVEDRULE" changes_$l.html | wc -l`
   
   mv changes_$l.html changes_$l.html~
   cat changes_a.html | sed "s/1title/${string[1]}/g" | sed 
"s/2intro/${string[2]}/g" | sed "s/3nothing/${string[3]}/g" > changes_$l.html
-  cat changes_$l.html~ | sed "s/4NEWRULE/${string[4]}/g" | sed 
"s/5REMOVEDRULE/${string[5]}/g" >> changes_$l.html
+  cat changes_$l.html~ | sed "s/4NEWRULE/${string[4]}/g" | sed 
"s/5REMOVEDRULE/${string[5]}/g" | sed "s/6IMPROVEDRULE/${string[6]}/g" | sed 
"s/7FINDERR/${string[7]}/g" | sed "s/8FINDNOTERR/${string[8]}/g" >> 
changes_$l.html
   cat changes_b.html >> changes_$l.html
   
   if [ ! $new_count -eq 0 ]; then
@@ -59,21 +76,21 @@
   if [ ! $removed_count -eq 0 ]; then
     removed_count="<b>$removed_count</b>"
   fi
-  echo "<tr class=\"lang\"><td><a 
href=\"changes_$l.html\">$l</a></td><td>$new_count new rules, $removed_count 
rules removed</td></tr>" >> changes.html
+  if [ ! $improved_count -eq 0 ]; then
+    improved_count="<b>$improved_count</b>"
+  fi
+  echo "<tr class=\"lang\"><td><a 
href=\"changes_$l.html\">$l</a></td><td>$new_count new, $improved_count 
improved, $removed_count removed</td></tr>" >> changes.html
   
   rm changes_$l.html~
   rm old
   rm new
-  rm grammar_$l.xml.diff
   
   mv changes_$l.html changes
 done
 
-cat changes_b.html >> changes.html
+cat changes_b.html | sed "s\</div>\</div><div class=\"gray\">new: The rule did 
not exist in version $oldv, but does in version $newv. Examples of errors which 
the new rule can detect are shown while hovering over its name.<br/>improved: 
The rule in version $newv has more examples than the rule in version $oldv. The 
new examples are shown while hovering over the name of the rule.<br>removed: 
The rule did exist in version $oldv, but does not exist in version $newv. 
Usually this means that the error is now detected by a more general 
rule.</div>\g" >> changes.html
 
 mv changes.html changes/index.html
 cp ltdiff.css changes
-rm -r ../website/www/changes
-mv -i changes ../website/www
 
 exit 0

Deleted: trunk/JLanguageTool/ltdiff/ltdiff.class
===================================================================
(Binary files differ)

Modified: trunk/JLanguageTool/ltdiff/ltdiff.css
===================================================================
--- trunk/JLanguageTool/ltdiff/ltdiff.css       2012-04-05 01:05:47 UTC (rev 
6681)
+++ trunk/JLanguageTool/ltdiff/ltdiff.css       2012-04-05 07:31:06 UTC (rev 
6682)
@@ -10,42 +10,101 @@
   border-spacing: 0px 5px;
 }
 
-td {
-  background-image: -webkit-linear-gradient(top left, #f0ffe1, rgba(240, 255, 
225, 0));
-  background-image: -moz-linear-gradient(top left, #f0ffe1, rgba(240, 255, 
225, 0));
-  background-image: -o-linear-gradient(top left, #f0ffe1, rgba(240, 255, 225, 
0));
-  background-image: -ms-linear-gradient(top left, #f0ffe1, rgba(240, 255, 225, 
0));
-  background-image: linear-gradient(top left, #f0ffe1, rgba(240, 255, 225, 0));
+tr {
   padding: 0px 5px;
   font-size: 14px;
 }
 
+td:first-child, span {
+  font-size: 12px;
+  padding-right: 5px;
+}
+
 td:first-child {
-  background-image: -webkit-linear-gradient(top left, #5ba622, #f0ffe1);
-  background-image: -moz-linear-gradient(top left, #5ba622, #f0ffe1);
-  background-image: -o-linear-gradient(top left, #5ba622, #f0ffe1);
-  background-image: -ms-linear-gradient(top left, #5ba622, #f0ffe1);
-  background-image: linear-gradient(top left, #5ba622, #f0ffe1);
-  font-size: 12px;
+  vertical-align: top;
+  white-space: nowrap;
+}
+
+tr:not([class="lang"]) > td:first-child {
   text-shadow: 1px 1px 1.5px white;
+  text-align: right;
 }
 
+span {
+  padding-bottom: 2px;
+}
+
+.new > td {
+  background-image: -webkit-linear-gradient(left, #f0ffe1, rgba(240, 255, 225, 
0));
+  background-image: -moz-linear-gradient(left, #f0ffe1, rgba(240, 255, 225, 
0));
+  background-image: -o-linear-gradient(left, #f0ffe1, rgba(240, 255, 225, 0));
+  background-image: -ms-linear-gradient(left, #f0ffe1, rgba(240, 255, 225, 0));
+  background-image: linear-gradient(left, #f0ffe1, rgba(240, 255, 225, 0));
+}
+
+.new > td:first-child {
+  background-image: -webkit-linear-gradient(left, #5ba622, #f0ffe1);
+  background-image: -moz-linear-gradient(left, #5ba622, #f0ffe1);
+  background-image: -o-linear-gradient(left, #5ba622, #f0ffe1);
+  background-image: -ms-linear-gradient(left, #5ba622, #f0ffe1);
+  background-image: linear-gradient(left, #5ba622, #f0ffe1);
+}
+
+td:last-child > div {
+  max-height: 0px;
+  opacity: 0;
+  visibility: hidden;
+  overflow: hidden;
+  -webkit-transition: .5s linear .2s;
+  -moz-transition: .5s linear .2s;
+  -o-transition: .5s linear .2s;
+  -ms-transition: .5s linear .2s;
+  transition: .5s linear .2s;
+}
+
+td:last-child:hover > div {
+  max-height: 1000px;
+  visibility: visible;
+  opacity: 1;
+  -webkit-transition: 1.5s linear .2s;
+  -moz-transition: 1.5s linear .2s;
+  -o-transition: 1.5s linear .2s;
+  -ms-transition: 1.5s linear .2s;
+  transition: 1.5s linear .2s;
+}
+
 .removed > td {
-  background-image: -webkit-linear-gradient(top left, #ffc8c8, rgba(255, 200, 
200, 0));
-  background-image: -moz-linear-gradient(top left, #ffc8c8, rgba(255, 200, 
200, 0));
-  background-image: -o-linear-gradient(top left, #ffc8c8, rgba(255, 200, 200, 
0));
-  background-image: -ms-linear-gradient(top left, #ffc8c8, rgba(255, 200, 200, 
0));
-  background-image: linear-gradient(top left, #ffc8c8, rgba(255, 200, 200, 0));
+  background-image: -webkit-linear-gradient(left, #ffc8c8, rgba(255, 200, 200, 
0));
+  background-image: -moz-linear-gradient(left, #ffc8c8, rgba(255, 200, 200, 
0));
+  background-image: -o-linear-gradient(left, #ffc8c8, rgba(255, 200, 200, 0));
+  background-image: -ms-linear-gradient(left, #ffc8c8, rgba(255, 200, 200, 0));
+  background-image: linear-gradient(left, #ffc8c8, rgba(255, 200, 200, 0));
 }
 
 .removed > td:first-child {
-  background-image: -webkit-linear-gradient(top left, #ca0000, #ffc8c8);
-  background-image: -moz-linear-gradient(top left, #ca0000, #ffc8c8);
-  background-image: -o-linear-gradient(top left, #ca0000, #ffc8c8);
-  background-image: -ms-linear-gradient(top left, #ca0000, #ffc8c8);
-  background-image: linear-gradient(top left, #ca0000, #ffc8c8);
+  background-image: -webkit-linear-gradient(left, #ca0000, #ffc8c8);
+  background-image: -moz-linear-gradient(left, #ca0000, #ffc8c8);
+  background-image: -o-linear-gradient(left, #ca0000, #ffc8c8);
+  background-image: -ms-linear-gradient(left, #ca0000, #ffc8c8);
+  background-image: linear-gradient(left, #ca0000, #ffc8c8);
 }
 
+.modified > td {
+  background-image: -webkit-linear-gradient(left, #ffedcf, rgba(255, 237, 207, 
0));
+  background-image: -moz-linear-gradient(left, #ffedcf, rgba(255, 237, 207, 
0));
+  background-image: -o-linear-gradient(left, #ffedcf, rgba(255, 237, 207, 0));
+  background-image: -ms-linear-gradient(left, #ffedcf, rgba(255, 237, 207, 0));
+  background-image: linear-gradient(left, #ffedcf, rgba(255, 237, 207, 0));
+}
+
+.modified > td:first-child {
+  background-image: -webkit-linear-gradient(left, #ffa300, #ffedcf);
+  background-image: -moz-linear-gradient(left, #ffa300, #ffedcf);
+  background-image: -o-linear-gradient(left, #ffa300, #ffedcf);
+  background-image: -ms-linear-gradient(left, #ffa300, #ffedcf);
+  background-image: linear-gradient(left, #ffa300, #ffedcf);
+}
+
 .lang > td {
   background-image: none;
 }
@@ -54,10 +113,15 @@
   display: block !important;
 }
 
-.nothing_new:last-child > td {
-  background-image: -webkit-linear-gradient(top left, rgba(0, 0, 0, .4), 
rgba(0, 0, 0, 0));
-  background-image: -moz-linear-gradient(top left, rgba(0, 0, 0, .4), rgba(0, 
0, 0, 0));
-  background-image: -o-linear-gradient(top left, rgba(0, 0, 0, .4), rgba(0, 0, 
0, 0));
-  background-image: -ms-linear-gradient(top left, rgba(0, 0, 0, .4), rgba(0, 
0, 0, 0));
-  background-image: linear-gradient(top left, rgba(0, 0, 0, .4), rgba(0, 0, 0, 
0));
+.nothing_new:last-child > td:first-child {
+  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .4), rgba(0, 
0, 0, 0));
+  background-image: -moz-linear-gradient(left, rgba(0, 0, 0, .4), rgba(0, 0, 
0, 0));
+  background-image: -o-linear-gradient(left, rgba(0, 0, 0, .4), rgba(0, 0, 0, 
0));
+  background-image: -ms-linear-gradient(left, rgba(0, 0, 0, .4), rgba(0, 0, 0, 
0));
+  background-image: linear-gradient(left, rgba(0, 0, 0, .4), rgba(0, 0, 0, 0));
 }
+
+.gray {
+  font-size: 12px;
+  color: gray;
+}

Modified: trunk/JLanguageTool/ltdiff/ltdiff.java
===================================================================
--- trunk/JLanguageTool/ltdiff/ltdiff.java      2012-04-05 01:05:47 UTC (rev 
6681)
+++ trunk/JLanguageTool/ltdiff/ltdiff.java      2012-04-05 07:31:06 UTC (rev 
6682)
@@ -1,5 +1,3 @@
-// TODO collapse + counter, changed rules, new rules which are commented out
-
 import java.util.ArrayList;
 import java.io.File;
 import java.io.BufferedReader;
@@ -12,60 +10,121 @@
 import java.util.Collections;
 import java.util.Comparator;
 
+class rule implements Comparable<rule> {
+  public String id;
+  public String name;
+  public ArrayList<String> correct = new ArrayList<String>();
+  public ArrayList<String> incorrect = new ArrayList<String>();
+  
+  public int numberOfExamples() {
+    return correct.size()+incorrect.size();
+  }
+  
+  public String examples(boolean all) {
+    
+    String s = "<div>";
+    
+    for (int i=0; i<incorrect.size(); i++) {
+      s += "<span>7FINDERR</span>" + incorrect.get(i) + "<br/>";
+    }
+    
+    if (all) {
+      for (int i=0; i<correct.size(); i++) {
+      s += "<span>8FINDNOTERR</span>" + correct.get(i) + "<br/>";
+      }
+    }
+    
+    s = s.substring(0,s.length()-5) + "</div>";
+        
+    return s;
+    
+  }
+  
+  @Override
+  public int compareTo(rule r) {
+    return this.name.compareTo(r.name);
+  }
+}
+
 public class ltdiff {
   
   public static void main(String[] args) {
     
     String lang = args[0];
     
-    ArrayList<String[]> rules_added = new ArrayList<String[]>();
-    ArrayList<String[]> rules_removed = new ArrayList<String[]>();
+    ArrayList<rule> old_rules = new ArrayList<rule>(); // rules in old 
grammar.xml
+    ArrayList<rule> new_rules = new ArrayList<rule>(); // rules in new 
grammar.xml
+    ArrayList<rule> modified_rules = new ArrayList<rule>();
     
-    // keep every added and removed rule in mind
-    
     try {
-    
-      BufferedReader in = new BufferedReader(new 
FileReader("grammar_"+lang+".xml.diff"));
-      String line;
       
-      // loop through all lines
-      while((line = in.readLine()) != null) {
-        if(line.contains("id=\"") && line.contains("name=\"")) {
-          String[] r = new String[2];
-          r[0] = line; // id
-          r[1] = line; // name
+      for (int i=0; i<2; i++) {
+        
+        ArrayList<rule> rules;
+        
+        if(i==0)
+          rules = old_rules;
+        else
+          rules = new_rules;
+      
+        BufferedReader in = new BufferedReader(new FileReader(i==0 ? "old" : 
"new"));
+        String line;
+        
+        rule r = new rule();
+        
+        // loop through all lines
+        while ((line = in.readLine()) != null) {
+        
+          if (line.contains("id=\"") && line.contains("rule")) {
+            
+            if (!line.contains("name=\"")) // merge with the following line if 
the name is there (e.g. sk)
+              line += in.readLine();
+            
+            if (r.correct.size() > 0) {
+              rules.add(r);
+              r = new rule();
+            }
+            
+            r.id = line;
+            r.name = line;
+            
+            r.id = r.id.replaceAll(".*id=\"","").replaceAll("\".*","");
+            r.name= r.name.replaceAll(".*name=\"","").replaceAll("\".*","");
+            
+            for (int j = 0; j < rules.size(); j++) { // ensure that the name 
is unique
+              if (r.name.equals(rules.get(j).name)) {
+                r.name += " ";
+              }
+            }
+            
+          } else if (line.contains("type=\"correct\"")) {
+            
+            while (!line.contains("</example>")) // merge with the following 
line(s) if the example continues there
+              line += in.readLine();
+            
r.correct.add(line.replaceAll("marker","b").replaceAll(".*<example.*?>","").replaceAll("</example>.*",""));
+            
+          } else if (line.contains("type=\"incorrect\"")) {
           
-          r[0] = r[0].replaceAll(".*id=\"","").replaceAll("\".*","");
+            while (!line.contains("</example>"))
+              line += in.readLine();
+            
r.incorrect.add(line.replaceAll("marker","b").replaceAll(".*<example.*?>","").replaceAll("</example>.*",""));
+            
+          }
           
-          r[1] = r[1].replaceAll(".*name=\"","").replaceAll("\".*","");
-          
-          if(line.startsWith("+"))
-            rules_added.add(r);
-          else if(line.startsWith("-"))
-            rules_removed.add(r);
-        }
-      } // while(readLine)
+        } // while(readLine)
+        
+        in.close();
+        
+      }
       
-      in.close();
-      
     } catch (IOException e) {
-      System.err.println("Error: " + e.getMessage());
+      System.err.println("Error 1: " + e.getMessage());
     }
     
-    // sort by rule name
+    // sort rules by name
+    Collections.sort(old_rules);
+    Collections.sort(new_rules);
     
-    Collections.sort(rules_added, new Comparator<String[]>() {
-      public int compare(String[] strings, String[] otherStrings) {
-        return strings[1].compareTo(otherStrings[1]);
-      }
-    });
-    
-    Collections.sort(rules_removed, new Comparator<String[]>() {
-      public int compare(String[] strings, String[] otherStrings) {
-        return strings[1].compareTo(otherStrings[1]);
-      }
-    });
-    
     // create html file containing the tr elements
     
     try {
@@ -73,24 +132,80 @@
       FileWriter fstream = new FileWriter("changes_"+lang+".html");
       BufferedWriter out = new BufferedWriter(fstream);
     
-      for (int j = 0; j < rules_added.size(); j++) {
-        boolean ignore = false;
-        for(int k = 0; k < rules_removed.size(); k++)
-          if(rules_removed.get(k)[0].equals(rules_added.get(j)[0])) ignore = 
true;
-        if(!ignore) out.write("<tr class=\"new\"><td>4NEWRULE</td><td>" + 
rules_added.get(j)[1] + "</td></tr>\n");
+      for (int i = 0; i < new_rules.size(); i++) {
+      
+        boolean found = false;
+        
+        for (int j = 0; j < old_rules.size() && !found; j++) {
+        
+          if (new_rules.get(i).id.equals(old_rules.get(j).id) || 
new_rules.get(i).name.equals(old_rules.get(j).name)) {
+            
+            found = true;
+            
+            if (new_rules.get(i).numberOfExamples() > 
old_rules.get(j).numberOfExamples()) { // if the new rules has more examples, 
it is considered to be improved
+            
+              rule r = new_rules.get(i);
+              
+              for (int k = 0; k < r.correct.size(); k++) { // remove examples 
which already exist in old rule
+              
+                for (int l = 0; l < old_rules.get(j).correct.size(); l++) {
+                
+                  if 
(r.correct.get(k).equals(old_rules.get(j).correct.get(l))) {
+                  
+                    r.correct.remove(k);
+                    if (k>0) k--;
+                    
+                  } // if examples equal
+                  
+                } // for each old correct example
+                
+              } // for each new correct example
+              
+              for (int k = 0; k < r.incorrect.size(); k++) { // remove 
examples which already exist in old rule
+              
+                for (int l = 0; l < old_rules.get(j).incorrect.size(); l++) {
+                
+                  if 
(r.incorrect.get(k).equals(old_rules.get(j).incorrect.get(l))) {
+                  
+                    r.incorrect.remove(k);
+                    if (k>0) k--;
+                    
+                  } // if examples equal
+                  
+                } // for each old incorrect example
+                
+              } // for each new incorrect example
+              
+              modified_rules.add(r);
+              
+            } // if new rules has more examples
+            
+          } // if new rule is not new
+          
+        } // for each old rule
+        
+        if (!found)
+          out.write("<tr class=\"new\"><td>4NEWRULE</td><td>" + 
new_rules.get(i).name + new_rules.get(i).examples(false) + "</td></tr>\n");
+        
+      } // for each new rule
+      
+      for (int i=0; i < modified_rules.size(); i++) {
+        out.write("<tr class=\"modified\"><td>6IMPROVEDRULE</td><td>" + 
modified_rules.get(i).name + modified_rules.get(i).examples(true) + 
"</td></tr>\n");
       }
       
-      for (int j = 0; j < rules_removed.size(); j++) {
-        boolean ignore = false;
-        for(int k = 0; k < rules_added.size(); k++)
-          if(rules_added.get(k)[0].equals(rules_removed.get(j)[0])) ignore = 
true;
-        if(!ignore) out.write("<tr 
class=\"removed\"><td>5REMOVEDRULE</td><td>" + rules_removed.get(j)[1] + 
"</td></tr>\n");
+      for (int i = 0; i < old_rules.size(); i++) {
+        boolean found = false;
+        for (int j = 0; j < new_rules.size(); j++)
+          if (new_rules.get(j).id.equals(old_rules.get(i).id) || 
new_rules.get(j).name.equals(old_rules.get(i).name))
+            found = true;
+        if (!found)
+          out.write("<tr class=\"removed\"><td>5REMOVEDRULE</td><td>" + 
old_rules.get(i).name + "</td></tr>\n");
       }
       
       out.close();
       
     } catch (Exception e) {
-      System.err.println("Error: " + e.getMessage());
+      System.err.println("Error 2: " + e.getMessage());
     }
     
     System.exit(0);

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


------------------------------------------------------------------------------
Better than sec? Nothing is better than sec when it comes to
monitoring Big Data applications. Try Boundary one-second 
resolution app monitoring today. Free.
http://p.sf.net/sfu/Boundary-dev2dev
_______________________________________________
Languagetool-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/languagetool-cvs

Reply via email to