Author: humbedooh
Date: Sun Mar  8 11:22:24 2015
New Revision: 1664972

URL: http://svn.apache.org/r1664972
Log:
lint

Modified:
    comdev/reporter.apache.org/site/render.js

Modified: comdev/reporter.apache.org/site/render.js
URL: 
http://svn.apache.org/viewvc/comdev/reporter.apache.org/site/render.js?rev=1664972&r1=1664971&r2=1664972&view=diff
==============================================================================
--- comdev/reporter.apache.org/site/render.js (original)
+++ comdev/reporter.apache.org/site/render.js Sun Mar  8 11:22:24 2015
@@ -4,146 +4,147 @@ var templates = {}
 var nproject = null;
 
 // Function for async fetching of a single JSON file with JS callback
+
 function GetAsyncJSON(theUrl, xstate, callback) {
-    var xmlHttp = null;
-    if (window.XMLHttpRequest) {
-       xmlHttp = new XMLHttpRequest();
-    } else {
-       xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
-    }
-    xmlHttp.open("GET", theUrl, true);
-    xmlHttp.send(null);
-    xmlHttp.onprogress = function(state) {
-       var s = parseInt(xmlHttp.getResponseHeader('Content-Length'))
-       if (document.getElementById('pct')) {
-           document.getElementById('pct').innerHTML = "<p style='text-align: 
center;'><b><i>Loading: " + parseInt((100 * (xmlHttp.responseText.length/s))) + 
"% done</i></b></p>";
-       }
-    }
-    xmlHttp.onreadystatechange = function(state) {
-       
-       if (xmlHttp.readyState == 4 && xmlHttp.status == 200 || xmlHttp.status 
== 404) {
-           if (callback) {
-               if (xmlHttp.status == 404) {
-                   callback({}, xstate);
-               } else {
-                       if (document.getElementById('pct')) {
-                               document.getElementById('pct').innerHTML = "<p 
style='text-align: center;'><b><i>Loading: 100% done</i></b></p>";
+       var xmlHttp = null;
+       if (window.XMLHttpRequest) {
+               xmlHttp = new XMLHttpRequest();
+       } else {
+               xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
+       }
+       xmlHttp.open("GET", theUrl, true);
+       xmlHttp.send(null);
+       xmlHttp.onprogress = function(state) {
+               var s = parseInt(xmlHttp.getResponseHeader('Content-Length'))
+               if (document.getElementById('pct')) {
+                       document.getElementById('pct').innerHTML = "<p 
style='text-align: center;'><b><i>Loading: " + parseInt((100 * 
(xmlHttp.responseText.length / s))) + "% done</i></b></p>";
+               }
+       }
+       xmlHttp.onreadystatechange = function(state) {
+
+               if (xmlHttp.readyState == 4 && xmlHttp.status == 200 || 
xmlHttp.status == 404) {
+                       if (callback) {
+                               if (xmlHttp.status == 404) {
+                                       callback({}, xstate);
+                               } else {
+                                       if (document.getElementById('pct')) {
+                                               
document.getElementById('pct').innerHTML = "<p style='text-align: 
center;'><b><i>Loading: 100% done</i></b></p>";
+                                       }
+                                       window.setTimeout(callback, 0.05, 
JSON.parse(xmlHttp.responseText), xstate);
+                               }
                        }
-                       window.setTimeout(callback, 0.05, 
JSON.parse(xmlHttp.responseText), xstate);
                }
-           }
        }
-    }
 }
 
 
 function makeSelect(name, arr, sarr) {
-    var sel = document.createElement('select');
-    sel.setAttribute("name", name)
-    for (i in arr) {
+       var sel = document.createElement('select');
+       sel.setAttribute("name", name)
+       for (i in arr) {
                var val = arr[i];
                var opt = document.createElement('option')
                opt.setAttribute("value", val)
                opt.innerHTML = val
                sel.appendChild(opt);
-    }
-    return sel
+       }
+       return sel
 }
 
 function getWednesdays(mo, y) {
-    var d = new Date();
-    if (mo) {
-       d.setMonth(mo);
-    }
-    if (y) {
-       d.setFullYear(y, d.getMonth(), d.getDay())
-    }
-    var month = d.getMonth(),
-       wednesdays = [];
-    
-    d.setDate(1);
-
-    // Get the first Monday in the month
-    while (d.getDay() !== 3) {
-        d.setDate(d.getDate() + 1);
-    }
-
-    // Get all the other Mondays in the month
-    while (d.getMonth() === month) {
-        wednesdays.push(new Date(d.getTime()));
-        d.setDate(d.getDate() + 7);
-    }
+       var d = new Date();
+       if (mo) {
+               d.setMonth(mo);
+       }
+       if (y) {
+               d.setFullYear(y, d.getMonth(), d.getDay())
+       }
+       var month = d.getMonth(),
+               wednesdays = [];
+
+       d.setDate(1);
+
+       // Get the first Monday in the month
+       while (d.getDay() !== 3) {
+               d.setDate(d.getDate() + 1);
+       }
 
-    return wednesdays;
+       // Get all the other Mondays in the month
+       while (d.getMonth() === month) {
+               wednesdays.push(new Date(d.getTime()));
+               d.setDate(d.getDate() + 7);
+       }
+
+       return wednesdays;
 }
 
 function setReportDate(json, x) {
-    var pmc = x[0]
-    var reportdate = x[1]
+       var pmc = x[0]
+       var reportdate = x[1]
        var fullname = (x[2] ? x[2] : "Unknown").replace(/Apache /, "")
-    var m = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 
'August', 'September', 'October', 'November', 'December']
-    var today = new Date()
+       var m = ['January', 'February', 'March', 'April', 'May', 'June', 
'July', 'August', 'September', 'October', 'November', 'December']
+       var today = new Date()
 
-    var dates = []
+       var dates = []
        if (!json[pmc]) {
                pmc = fullname
        }
-    for (i in json[pmc]) {
+       for (i in json[pmc]) {
                tm = 0;
                sm = json[pmc][i]
                for (x in m) {
                        if (m[x] == sm) {
-                       tm = x;
+                               tm = x;
                        }
                }
                dates.push(getWednesdays(tm)[2])
-               }
-               var ny = today.getFullYear() + 1;
-               for (i in json[pmc]) {
-                       tm = 0;
-                       sm = json[pmc][i]
-                       for (x in m) {
-                               if (m[x] == sm) {
+       }
+       var ny = today.getFullYear() + 1;
+       for (i in json[pmc]) {
+               tm = 0;
+               sm = json[pmc][i]
+               for (x in m) {
+                       if (m[x] == sm) {
                                tm = x;
-                               }
                        }
-                       dates.push(getWednesdays(tm)[2], ny)
                }
-               var nextdate = dates[0];
-               while (nextdate < today) {
+               dates.push(getWednesdays(tm)[2], ny)
+       }
+       var nextdate = dates[0];
+       while (nextdate < today) {
                nextdate = dates.shift();
-    }
-    reportdate.innerHTML += "<b>Next report date: " + (nextdate ? 
nextdate.toDateString() : "Unknown(?)") + "</b>"
+       }
+       reportdate.innerHTML += "<b>Next report date: " + (nextdate ? 
nextdate.toDateString() : "Unknown(?)") + "</b>"
 }
- 
+
 function buildPanel(pmc, title) {
-    var parent = document.getElementById('tab_' + pmc);
-    
-    var toc = document.getElementById('toc_' + pmc);
-    if (!toc) {
-       toc = document.createElement('cl')
-       toc.setAttribute("class", "sub-nav")
-       toc.setAttribute("id", "toc_" + pmc)
-       if (parent.firstChild.nextSibling) {
-           parent.insertBefore(toc, parent.firstChild.nextSibling);
-       } else {
-           parent.appendChild(toc)
+       var parent = document.getElementById('tab_' + pmc);
+
+       var toc = document.getElementById('toc_' + pmc);
+       if (!toc) {
+               toc = document.createElement('cl')
+               toc.setAttribute("class", "sub-nav")
+               toc.setAttribute("id", "toc_" + pmc)
+               if (parent.firstChild.nextSibling) {
+                       parent.insertBefore(toc, parent.firstChild.nextSibling);
+               } else {
+                       parent.appendChild(toc)
+               }
        }
-    }
-    var linkname = title.toLowerCase().replace(/[^a-z0-9]+/, "")
-    var li = document.createElement('dd');
-    li.setAttribute("role", "menu-item")
-    li.innerHTML = "<a href='#" + linkname + "_" + pmc + "'>" + title + "</a>"
-    toc.appendChild(li)
-    
-    var div = document.createElement('div');
-    div.setAttribute("id", linkname + "_" + pmc);
-    parent.appendChild(div)
-    
-    var titlebox = document.createElement('div');
-    titlebox.innerHTML = "<h3 style='background: #666; color: #EEE; border: 
1px solid #66A; margin-top: 30px;'>" + title + " &nbsp; &nbsp; <small> 
<b>&uarr;</b> <a href='#tab_" + pmc + "'>Back to top</a></small></h3>"
-    div.appendChild(titlebox);
-    return div;
+       var linkname = title.toLowerCase().replace(/[^a-z0-9]+/, "")
+       var li = document.createElement('dd');
+       li.setAttribute("role", "menu-item")
+       li.innerHTML = "<a href='#" + linkname + "_" + pmc + "'>" + title + 
"</a>"
+       toc.appendChild(li)
+
+       var div = document.createElement('div');
+       div.setAttribute("id", linkname + "_" + pmc);
+       parent.appendChild(div)
+
+       var titlebox = document.createElement('div');
+       titlebox.innerHTML = "<h3 style='background: #666; color: #EEE; border: 
1px solid #66A; margin-top: 30px;'>" + title + " &nbsp; &nbsp; <small> 
<b>&uarr;</b> <a href='#tab_" + pmc + "'>Back to top</a></small></h3>"
+       div.appendChild(titlebox);
+       return div;
 }
 
 function addLine(pmc, line) {
@@ -155,373 +156,371 @@ function addLine(pmc, line) {
                var len = 0;
                var out = ""
                for (i in words) {
-                       len += words[i].replace(/<.+?>/, "").length + (i == 
words.length-1 ? 0 : 1)
+                       len += words[i].replace(/<.+?>/, "").length + (i == 
words.length - 1 ? 0 : 1)
                        if (len >= 80) {
                                out += "\n   "
-                               len = words[i].replace(/<.+?>/, "").length + (i 
== words.length-1 ? 0 : 1)
+                               len = words[i].replace(/<.+?>/, "").length + (i 
== words.length - 1 ? 0 : 1)
                        }
                        out += words[i] + " "
                }
                templates[pmc] += out + "\n"
-    }
+       }
 }
 
 function renderFrontPage(json) {
-    jsdata = json
-    var container = document.getElementById('contents')
-    container.innerHTML = "<h2 style='text-align: center; margin-bottom: 
10px;' class='hide-for-small-only'>Apache Project Report Helper</h2>Click on a 
project name to view statistics:"
-    var top = document.createElement('div');
-    container.appendChild(top)
-    
-    
-    var panellist = document.createElement('ul');
-    panellist.style.background = "#AAA"
-    panellist.style.textAlign = "center"
-    panellist.style.margin = "0 auto"
+       jsdata = json
+       var container = document.getElementById('contents')
+       container.innerHTML = "<h2 style='text-align: center; margin-bottom: 
10px;' class='hide-for-small-only'>Apache Project Report Helper</h2>Click on a 
project name to view statistics:"
+       var top = document.createElement('div');
+       container.appendChild(top)
+
+
+       var panellist = document.createElement('ul');
+       panellist.style.background = "#AAA"
+       panellist.style.textAlign = "center"
+       panellist.style.margin = "0 auto"
        panellist.style.paddingLeft = "5px"
-    //panellist.setAttribute("class", "tabs")
-    panellist.setAttribute("id", "tabs");
-    panellist.setAttribute("data-tab", "")
-    panellist.setAttribute("role", "tablist")
-    container.appendChild(panellist)
-    
-    var pcontainer = document.createElement('div');
-    pcontainer.setAttribute("id", "tabcontents")
-    pcontainer.setAttribute("style", "text-align: left !important; margin: 0 
auto; width: 1000px; border-radius: 5px; border: 2px solid #666; height: 100%; 
overflow: scroll !important; overflow-y: scroll !important; ")
-    container.appendChild(pcontainer)
-    
-    var sproject = document.location.search.substr(1);
-    for (i in json.pmcs) {
-       
-       var pmc = json.pmcs[i]
-       templates[pmc] = "Report from the " + (json.pdata[pmc].name ? 
json.pdata[pmc].name : pmc) + " project [" + (json.pdata[pmc].chair ? 
json.pdata[pmc].chair : "Put your name here") + "]\n\n"
-       
-       addLine(pmc, "## Description:")
-       if (json.pdata[pmc].shortdesc) {
-           addLine(pmc, "   " + json.pdata[pmc].shortdesc)
-       } else {
-           addLine(pmc, " - <font color='red'>Description goes here</font>")
-       }
-       addLine(pmc)
-       
-       addLine(pmc, "## Activity:")
-       addLine(pmc, " - <font color='red'>TODO - the PMC <b><u>MUST</u></b> 
provide this information</font>")
-       addLine(pmc)
+       //panellist.setAttribute("class", "tabs")
+       panellist.setAttribute("id", "tabs");
+       panellist.setAttribute("data-tab", "")
+       panellist.setAttribute("role", "tablist")
+       container.appendChild(panellist)
+
+       var pcontainer = document.createElement('div');
+       pcontainer.setAttribute("id", "tabcontents")
+       pcontainer.setAttribute("style", "text-align: left !important; margin: 
0 auto; width: 1000px; border-radius: 5px; border: 2px solid #666; height: 
100%; overflow: scroll !important; overflow-y: scroll !important; ")
+       container.appendChild(pcontainer)
+
+       var sproject = document.location.search.substr(1);
+       for (i in json.pmcs) {
+
+               var pmc = json.pmcs[i]
+               templates[pmc] = "Report from the " + (json.pdata[pmc].name ? 
json.pdata[pmc].name : pmc) + " project [" + (json.pdata[pmc].chair ? 
json.pdata[pmc].chair : "Put your name here") + "]\n\n"
+
+               addLine(pmc, "## Description:")
+               if (json.pdata[pmc].shortdesc) {
+                       addLine(pmc, "   " + json.pdata[pmc].shortdesc)
+               } else {
+                       addLine(pmc, " - <font color='red'>Description goes 
here</font>")
+               }
+               addLine(pmc)
 
-       addLine(pmc, "## Issues:")
-       addLine(pmc, " - <font color='red'>TODO - list any issues that require 
board attention, \n  or say \"there are no issues requiring board attention at 
this time\"</font>")
-       addLine(pmc)
-    
-       var obj = document.createElement('div');
-       obj.setAttribute("id", "tab_" + pmc)
-       obj.style = "padding: 10px; text-align: left !important;"
-       obj.setAttribute("aria-hidden", "true")
-       var title = document.createElement('h2')
-       title.innerHTML =json.pdata[pmc].name ? json.pdata[pmc].name : pmc
-       obj.appendChild(title)
-       
-       pcontainer.appendChild(obj)
-       
-       
-       
-       // Report date
-       
-       var mo = new Date().getMonth();
-       var reportdate = buildPanel(pmc, "Report date")
-       if (json.pdata[pmc].chair) {
-           reportdate.innerHTML += "<b>Project Chair: </b>" + 
json.pdata[pmc].chair + "<br/>"
-       }
-       GetAsyncJSON("reportingcycles.json?" + Math.random(), [pmc, reportdate, 
json.pdata[pmc].name], setReportDate)
-       
-       
-       // PMC + Committer changes
-       
-       var mo = new Date().getMonth() - 3;
-       var after = new Date();
-       after.setMonth(mo);
-       
-       var changes = buildPanel(pmc, "PMC/Committership changes");
-       
-       var c = 0;
-       for (i in json.changes[pmc].committer) c++;
-       for (i in json.changes[pmc].pmc) c++;
-       var nc = 0;
-       var np = 0;
-       var ncn = null;
-       var npn = null;
-       addLine(pmc, "## PMC/Committership changes:")
-       addLine(pmc)
-       addLine(pmc, " - Currently " + json.count[pmc][1] + " committers and " 
+ json.count[pmc][0] + " PMC members in the project.")
-       if (c == 0) {
-           changes.innerHTML += "<font color='red'><b>No new changes to the 
PMC or committer base detected</b></font>"
-           addLine(pmc, " - No new changes to the PMC or committership since 
last report.")
-           addLine(pmc)
-       }
-       else {
-           changes.innerHTML += "<h5>Changes within the last 3 months:</h5>"
-           var l = 0;
-           for (i in json.changes[pmc].pmc) {
-               var entry = json.changes[pmc].pmc[i];
-               if (entry[1] > np) {
-                   np = entry[1]
-                   npn = entry[0];
-               }
-               if (entry[1] > after.getTime()/1000) {
-                   l++;
-                   changes.innerHTML += "&rarr; " + entry[0] + " was added to 
the PMC on " + new Date(entry[1]*1000).toDateString() + "<br/>";
-                   addLine(pmc, " - " + entry[0] + " was added to the PMC on " 
+ new Date(entry[1]*1000).toDateString())
-               }
-           }
-           if (l == 0) {
-                       addLine(pmc, " - No new PMC members added in the last 3 
months")
-               changes.innerHTML += "&rarr; <font color='red'><b>No new PMC 
members in the last 3 months.</b></font><br/>";
-           }
-           for (i in json.changes[pmc].committer) {
-               var entry = json.changes[pmc].committer[i];
-               if (entry[1] > nc) {
-                   nc = entry[1]
-                   ncn = entry[0];
-               }
-               if (entry[1] > after.getTime()/1000) {
-                   l++;
-                   changes.innerHTML += "&rarr; " + entry[0] + " was added as 
a committer on " + new Date(entry[1]*1000).toDateString() + "<br/>";
-                   addLine(pmc, " - " + entry[0] + " was added as a committer 
on " + new Date(entry[1]*1000).toDateString())
-               }
-           }
-           if (l == 0) {
-                       changes.innerHTML += "&rarr; <font color='red'><b>No 
new committers in the last 3 months.</b></font><br/>";
-                       addLine(pmc, " - No new committers added in the last 3 
months")
-           }
-           if (npn) {
-               if (np < after.getTime()/1000) {
-                   addLine(pmc, " - Last PMC addition was " + npn + " at " + 
new Date(np*1000).toDateString())
-               }
-               changes.innerHTML += "&rarr; " + "<b>Latest PMC addition: </b>" 
+ new Date(np*1000).toDateString() + " (" + npn +  ")<br/>"
-           }
-           if (ncn) {
-               if (nc < after.getTime()/1000) {
-                   addLine(pmc, " - Last committer addition was " + ncn + " at 
" + new Date(nc*1000).toDateString())
-               }
-               changes.innerHTML += "&rarr; " + "<b>Latest committer addition: 
</b>" + new Date(nc*1000).toDateString() + " (" + ncn +  ")<br/>"
-           }
-               changes.innerHTML += "&rarr; " + "<b>Currently " + 
json.count[pmc][1] + " committers and " + json.count[pmc][0] + " PMC members."
-           addLine(pmc)
-       }
-       
-       // Release data
-       
-       var releases = buildPanel(pmc, "Releases")
-       addLine(pmc, "## Releases:")
-       addLine(pmc)
-       var nr = 0;
-       var lr = null;
-       var lrn = 0;
-       var tr = 0
-       for (version in json.releases[pmc]) {
-           tr++;
-           var date = parseInt(json.releases[pmc][version])
-           if (date > lrn) {
-               lrn = date
-               lr = version
-           }
-           if (date >= after.getTime()/1000) {
-                       err = ""
-                       if (new Date(date*1000) > new Date()) {
-                               err = " (<font color='red'>This seems 
wrong?!</font>)"
-                       }
-               releases.innerHTML += "&rarr; " + "<b>" + version + " was 
released on </b>" + new Date(date*1000).toDateString() + err + "<br/>"
-               addLine(pmc, " - " + version + " was released on " + new 
Date(date*1000).toDateString() + err)
-               nr++;
-           }
-       }
-       
-       if (nr == 0) {
-           if (lr) {
-               releases.innerHTML += "&rarr; " + "<b>Latest release was " + lr 
+ ", released on </b>" + new Date(lrn*1000).toDateString() + "<br/>"
-               addLine(pmc, " - Last release was " + lr + " on " + new 
Date(lrn*1000).toDateString())
-           } else {
-               releases.innerHTML += "No release data could be found.<br/>"
-               addLine(pmc, " - <font color='red'>No release data could be 
found [FIX!]</font>")
-           }
-       }
-       releases.innerHTML += "<i>(A total of " + (tr-nr) + " older release(s) 
were found for " + pmc + " in our db)</i><br/>"
-       releases.innerHTML += "<br/><a href='addrelease.html?" + pmc + "'>Add a 
release</a> - <a href='javascript:void(0);' onclick=\"$('#dialog_" + pmc + 
"').dialog({minWidth: 450, minHeight: 240});\">Fetch releases from 
JIRA</a><br/>"
-       
-       if (tr > 0) {
-               var div = renderReleaseChart(json.releases[pmc], pmc, releases);
-               releases.appendChild(div)
-       }
-       
-       
-       addLine(pmc)
-       
-       var mlbox = buildPanel(pmc, "Mailing lists");
-       
-       var ul = document.createElement('ul')
-       ul.style.textAlign = "left;"
-       mlbox.appendChild(ul)
-       var prev = ""
-       var f = 0
-       addLine(pmc, "## Mailing list activity:")
-       addLine(pmc)
-       var first = ['users', 'dev', 'commits', 'private', 'bugs', 
'modules-dev'];
-       
-       
-       for (i in first) {
-           
-               ml = pmc + ".apache.org-" + first[i]
-           if (ml != prev && ml.search("infra") < 0 && json.mail[pmc] && 
json.mail[pmc][ml]) {
-                       f++;
-                       prev = ml
-                       var d = ml.split(".org-");
-                       var mlname = d[1] + "@" + d[0] + ".org"
-                       var lookup = d[0].split(/\./)[0] + "-" + d[1]
-                       
-                       var x = renderChart(json.mail[pmc], ml, obj, 
(json.delivery[pmc] && json.delivery[pmc][lookup]) ? 
json.delivery[pmc][lookup].weekly : {})
-                       var total = x[0]
-                       var diff = x[1]
-                       var div = x[2]
-                       
-                       add = ""
-                       if (json.delivery[pmc] && json.delivery[pmc][lookup]) {
-                               add = ":\n    " + 
json.delivery[pmc][lookup].quarterly[0] + " emails sent to list (" + 
json.delivery[pmc][lookup].quarterly[1] + " in previous quarter)";
-                       }
-                       var text = "Currently: " + total + " subscribers <font 
color='green'>(up " + diff + " in the last 3 months)</font>"
-                       if (diff < 0) {
-                               text = "Currently: " + total + " subscribers 
<font color='red'>(down " + diff + " in the last 3 months)</font>"
-                               if (d[1] != "private" && d[1] != "security" && 
d[1] != "commits") {
-                               addLine(pmc, " - " + mlname + ": " + total + " 
subscribers (down " + diff + " in the last 3 months)" + add)
+               addLine(pmc, "## Activity:")
+               addLine(pmc, " - <font color='red'>TODO - the PMC 
<b><u>MUST</u></b> provide this information</font>")
+               addLine(pmc)
+
+               addLine(pmc, "## Issues:")
+               addLine(pmc, " - <font color='red'>TODO - list any issues that 
require board attention, \n  or say \"there are no issues requiring board 
attention at this time\"</font>")
+               addLine(pmc)
+
+               var obj = document.createElement('div');
+               obj.setAttribute("id", "tab_" + pmc)
+               obj.style = "padding: 10px; text-align: left !important;"
+               obj.setAttribute("aria-hidden", "true")
+               var title = document.createElement('h2')
+               title.innerHTML = json.pdata[pmc].name ? json.pdata[pmc].name : 
pmc
+               obj.appendChild(title)
+
+               pcontainer.appendChild(obj)
+
+
+
+               // Report date
+
+               var mo = new Date().getMonth();
+               var reportdate = buildPanel(pmc, "Report date")
+               if (json.pdata[pmc].chair) {
+                       reportdate.innerHTML += "<b>Project Chair: </b>" + 
json.pdata[pmc].chair + "<br/>"
+               }
+               GetAsyncJSON("reportingcycles.json?" + Math.random(), [pmc, 
reportdate, json.pdata[pmc].name], setReportDate)
+
+
+               // PMC + Committer changes
+
+               var mo = new Date().getMonth() - 3;
+               var after = new Date();
+               after.setMonth(mo);
+
+               var changes = buildPanel(pmc, "PMC/Committership changes");
+
+               var c = 0;
+               for (i in json.changes[pmc].committer) c++;
+               for (i in json.changes[pmc].pmc) c++;
+               var nc = 0;
+               var np = 0;
+               var ncn = null;
+               var npn = null;
+               addLine(pmc, "## PMC/Committership changes:")
+               addLine(pmc)
+               addLine(pmc, " - Currently " + json.count[pmc][1] + " 
committers and " + json.count[pmc][0] + " PMC members in the project.")
+               if (c == 0) {
+                       changes.innerHTML += "<font color='red'><b>No new 
changes to the PMC or committer base detected</b></font>"
+                       addLine(pmc, " - No new changes to the PMC or 
committership since last report.")
+                       addLine(pmc)
+               } else {
+                       changes.innerHTML += "<h5>Changes within the last 3 
months:</h5>"
+                       var l = 0;
+                       for (i in json.changes[pmc].pmc) {
+                               var entry = json.changes[pmc].pmc[i];
+                               if (entry[1] > np) {
+                                       np = entry[1]
+                                       npn = entry[0];
                                }
-                       } else {
-                               if (d[1] != "private" && d[1] != "security" && 
d[1] != "commits") {
-                               addLine(pmc, " - " + mlname + ": " + total + " 
subscribers (up " + diff + " in the last 3 months)" + add)
+                               if (entry[1] > after.getTime() / 1000) {
+                                       l++;
+                                       changes.innerHTML += "&rarr; " + 
entry[0] + " was added to the PMC on " + new Date(entry[1] * 
1000).toDateString() + "<br/>";
+                                       addLine(pmc, " - " + entry[0] + " was 
added to the PMC on " + new Date(entry[1] * 1000).toDateString())
                                }
                        }
-                       
-                       if (json.delivery[pmc] && json.delivery[pmc][lookup]) {
-                               text += " (" + 
json.delivery[pmc][lookup].quarterly[0] + " emails sent in the past 3 months, " 
+ json.delivery[pmc][lookup].quarterly[1] + " in the previous cycle)"
-                       }
-                       
-                       var p = document.createElement('li');
-                       p.innerHTML = "<h5>" + mlname + ":</h5>" + text
-                       p.appendChild(div)
-                       ul.appendChild(p)
-           }
-       }
-       
-       for (ml in json.mail[pmc]) {
-               var skip = false
-               for (i in first) {
-                       xml = pmc + ".apache.org-" + first[i]
-                       if (ml.search(xml) == 0) {
-                               skip = true
-                       }
-               }
-               if (!skip) {
-                               
-                       f++;
-                       if (ml != prev && ml.search("infra") < 0) {
-                       prev = ml
-                       var d = ml.split(".org-");
-                       var mlname = d[1] + "@" + d[0] + ".org"
-                       var lookup = d[0].split(/\./)[0] + "-" + d[1]
-                       var x = renderChart(json.mail[pmc], ml, obj, 
(json.delivery[pmc] && json.delivery[pmc][lookup]) ? 
json.delivery[pmc][lookup].weekly : {})
-                       var total = x[0]
-                       var diff = x[1]
-                       var div = x[2]
-                       
-                       add = ""
-                       if (json.delivery[pmc] && json.delivery[pmc][lookup]) {
-                               add = ":\n    " + 
json.delivery[pmc][lookup].quarterly[0] + " emails sent to list (" + 
json.delivery[pmc][lookup].quarterly[1] + " in previous quarter)";
-                       }
-                       var text = "Currently: " + total + " subscribers <font 
color='green'>(up " + diff + " in the last 3 months)</font>"
-                       if (diff < 0) {
-                               text = "Currently: " + total + " subscribers 
<font color='red'>(down " + diff + " in the last 3 months)</font>"
-                               if (d[1] != "private" && d[1] != "security" && 
d[1] != "commits") {
-                               addLine(pmc, " - " + mlname + ": " + total + " 
subscribers (down " + diff + " in the last 3 months)" + add)
+                       if (l == 0) {
+                               addLine(pmc, " - No new PMC members added in 
the last 3 months")
+                               changes.innerHTML += "&rarr; <font 
color='red'><b>No new PMC members in the last 3 months.</b></font><br/>";
+                       }
+                       for (i in json.changes[pmc].committer) {
+                               var entry = json.changes[pmc].committer[i];
+                               if (entry[1] > nc) {
+                                       nc = entry[1]
+                                       ncn = entry[0];
+                               }
+                               if (entry[1] > after.getTime() / 1000) {
+                                       l++;
+                                       changes.innerHTML += "&rarr; " + 
entry[0] + " was added as a committer on " + new Date(entry[1] * 
1000).toDateString() + "<br/>";
+                                       addLine(pmc, " - " + entry[0] + " was 
added as a committer on " + new Date(entry[1] * 1000).toDateString())
+                               }
+                       }
+                       if (l == 0) {
+                               changes.innerHTML += "&rarr; <font 
color='red'><b>No new committers in the last 3 months.</b></font><br/>";
+                               addLine(pmc, " - No new committers added in the 
last 3 months")
+                       }
+                       if (npn) {
+                               if (np < after.getTime() / 1000) {
+                                       addLine(pmc, " - Last PMC addition was 
" + npn + " at " + new Date(np * 1000).toDateString())
                                }
+                               changes.innerHTML += "&rarr; " + "<b>Latest PMC 
addition: </b>" + new Date(np * 1000).toDateString() + " (" + npn + ")<br/>"
+                       }
+                       if (ncn) {
+                               if (nc < after.getTime() / 1000) {
+                                       addLine(pmc, " - Last committer 
addition was " + ncn + " at " + new Date(nc * 1000).toDateString())
+                               }
+                               changes.innerHTML += "&rarr; " + "<b>Latest 
committer addition: </b>" + new Date(nc * 1000).toDateString() + " (" + ncn + 
")<br/>"
+                       }
+                       changes.innerHTML += "&rarr; " + "<b>Currently " + 
json.count[pmc][1] + " committers and " + json.count[pmc][0] + " PMC members."
+                       addLine(pmc)
+               }
+
+               // Release data
+
+               var releases = buildPanel(pmc, "Releases")
+               addLine(pmc, "## Releases:")
+               addLine(pmc)
+               var nr = 0;
+               var lr = null;
+               var lrn = 0;
+               var tr = 0
+               for (version in json.releases[pmc]) {
+                       tr++;
+                       var date = parseInt(json.releases[pmc][version])
+                       if (date > lrn) {
+                               lrn = date
+                               lr = version
+                       }
+                       if (date >= after.getTime() / 1000) {
+                               err = ""
+                               if (new Date(date * 1000) > new Date()) {
+                                       err = " (<font color='red'>This seems 
wrong?!</font>)"
+                               }
+                               releases.innerHTML += "&rarr; " + "<b>" + 
version + " was released on </b>" + new Date(date * 1000).toDateString() + err 
+ "<br/>"
+                               addLine(pmc, " - " + version + " was released 
on " + new Date(date * 1000).toDateString() + err)
+                               nr++;
+                       }
+               }
+
+               if (nr == 0) {
+                       if (lr) {
+                               releases.innerHTML += "&rarr; " + "<b>Latest 
release was " + lr + ", released on </b>" + new Date(lrn * 1000).toDateString() 
+ "<br/>"
+                               addLine(pmc, " - Last release was " + lr + " on 
" + new Date(lrn * 1000).toDateString())
                        } else {
-                               if (d[1] != "private" && d[1] != "security" && 
d[1] != "commits") {
-                               addLine(pmc, " - " + mlname + ": " + total + " 
subscribers (up " + diff + " in the last 3 months)" + add)
+                               releases.innerHTML += "No release data could be 
found.<br/>"
+                               addLine(pmc, " - <font color='red'>No release 
data could be found [FIX!]</font>")
+                       }
+               }
+               releases.innerHTML += "<i>(A total of " + (tr - nr) + " older 
release(s) were found for " + pmc + " in our db)</i><br/>"
+               releases.innerHTML += "<br/><a href='addrelease.html?" + pmc + 
"'>Add a release</a> - <a href='javascript:void(0);' onclick=\"$('#dialog_" + 
pmc + "').dialog({minWidth: 450, minHeight: 240});\">Fetch releases from 
JIRA</a><br/>"
+
+               if (tr > 0) {
+                       var div = renderReleaseChart(json.releases[pmc], pmc, 
releases);
+                       releases.appendChild(div)
+               }
+
+
+               addLine(pmc)
+
+               var mlbox = buildPanel(pmc, "Mailing lists");
+
+               var ul = document.createElement('ul')
+               ul.style.textAlign = "left;"
+               mlbox.appendChild(ul)
+               var prev = ""
+               var f = 0
+               addLine(pmc, "## Mailing list activity:")
+               addLine(pmc)
+               var first = ['users', 'dev', 'commits', 'private', 'bugs', 
'modules-dev'];
+
+
+               for (i in first) {
+
+                       ml = pmc + ".apache.org-" + first[i]
+                       if (ml != prev && ml.search("infra") < 0 && 
json.mail[pmc] && json.mail[pmc][ml]) {
+                               f++;
+                               prev = ml
+                               var d = ml.split(".org-");
+                               var mlname = d[1] + "@" + d[0] + ".org"
+                               var lookup = d[0].split(/\./)[0] + "-" + d[1]
+
+                               var x = renderChart(json.mail[pmc], ml, obj, 
(json.delivery[pmc] && json.delivery[pmc][lookup]) ? 
json.delivery[pmc][lookup].weekly : {})
+                               var total = x[0]
+                               var diff = x[1]
+                               var div = x[2]
+
+                               add = ""
+                               if (json.delivery[pmc] && 
json.delivery[pmc][lookup]) {
+                                       add = ":\n    " + 
json.delivery[pmc][lookup].quarterly[0] + " emails sent to list (" + 
json.delivery[pmc][lookup].quarterly[1] + " in previous quarter)";
+                               }
+                               var text = "Currently: " + total + " 
subscribers <font color='green'>(up " + diff + " in the last 3 months)</font>"
+                               if (diff < 0) {
+                                       text = "Currently: " + total + " 
subscribers <font color='red'>(down " + diff + " in the last 3 months)</font>"
+                                       if (d[1] != "private" && d[1] != 
"security" && d[1] != "commits") {
+                                               addLine(pmc, " - " + mlname + 
": " + total + " subscribers (down " + diff + " in the last 3 months)" + add)
+                                       }
+                               } else {
+                                       if (d[1] != "private" && d[1] != 
"security" && d[1] != "commits") {
+                                               addLine(pmc, " - " + mlname + 
": " + total + " subscribers (up " + diff + " in the last 3 months)" + add)
+                                       }
                                }
+
+                               if (json.delivery[pmc] && 
json.delivery[pmc][lookup]) {
+                                       text += " (" + 
json.delivery[pmc][lookup].quarterly[0] + " emails sent in the past 3 months, " 
+ json.delivery[pmc][lookup].quarterly[1] + " in the previous cycle)"
+                               }
+
+                               var p = document.createElement('li');
+                               p.innerHTML = "<h5>" + mlname + ":</h5>" + text
+                               p.appendChild(div)
+                               ul.appendChild(p)
                        }
-                       
-                       if (json.delivery[pmc] && json.delivery[pmc][lookup]) {
-                               text += " (" + 
json.delivery[pmc][lookup].quarterly[0] + " emails sent in the past 3 months, " 
+ json.delivery[pmc][lookup].quarterly[1] + " in the previous cycle)"
-                       }
-                       
-                       var p = document.createElement('li');
-                       p.innerHTML = "<h5>" + mlname + ":</h5>" + text
-                       p.appendChild(div)
-                       ul.appendChild(p)
+               }
+
+               for (ml in json.mail[pmc]) {
+                       var skip = false
+                       for (i in first) {
+                               xml = pmc + ".apache.org-" + first[i]
+                               if (ml.search(xml) == 0) {
+                                       skip = true
+                               }
                        }
+                       if (!skip) {
+
+                               f++;
+                               if (ml != prev && ml.search("infra") < 0) {
+                                       prev = ml
+                                       var d = ml.split(".org-");
+                                       var mlname = d[1] + "@" + d[0] + ".org"
+                                       var lookup = d[0].split(/\./)[0] + "-" 
+ d[1]
+                                       var x = renderChart(json.mail[pmc], ml, 
obj, (json.delivery[pmc] && json.delivery[pmc][lookup]) ? 
json.delivery[pmc][lookup].weekly : {})
+                                       var total = x[0]
+                                       var diff = x[1]
+                                       var div = x[2]
+
+                                       add = ""
+                                       if (json.delivery[pmc] && 
json.delivery[pmc][lookup]) {
+                                               add = ":\n    " + 
json.delivery[pmc][lookup].quarterly[0] + " emails sent to list (" + 
json.delivery[pmc][lookup].quarterly[1] + " in previous quarter)";
+                                       }
+                                       var text = "Currently: " + total + " 
subscribers <font color='green'>(up " + diff + " in the last 3 months)</font>"
+                                       if (diff < 0) {
+                                               text = "Currently: " + total + 
" subscribers <font color='red'>(down " + diff + " in the last 3 months)</font>"
+                                               if (d[1] != "private" && d[1] 
!= "security" && d[1] != "commits") {
+                                                       addLine(pmc, " - " + 
mlname + ": " + total + " subscribers (down " + diff + " in the last 3 months)" 
+ add)
+                                               }
+                                       } else {
+                                               if (d[1] != "private" && d[1] 
!= "security" && d[1] != "commits") {
+                                                       addLine(pmc, " - " + 
mlname + ": " + total + " subscribers (up " + diff + " in the last 3 months)" + 
add)
+                                               }
+                                       }
+
+                                       if (json.delivery[pmc] && 
json.delivery[pmc][lookup]) {
+                                               text += " (" + 
json.delivery[pmc][lookup].quarterly[0] + " emails sent in the past 3 months, " 
+ json.delivery[pmc][lookup].quarterly[1] + " in the previous cycle)"
+                                       }
+
+                                       var p = document.createElement('li');
+                                       p.innerHTML = "<h5>" + mlname + 
":</h5>" + text
+                                       p.appendChild(div)
+                                       ul.appendChild(p)
+                               }
+                       }
+               }
+               addLine(pmc)
+
+               // Add btn for nav
+               if (f > 0) {
+                       var btn = document.createElement('li');
+                       btn.setAttribute("id", "btn_" + pmc)
+                       btn.setAttribute("class", "tab-title")
+                       btn.setAttribute("onclick", 
"$('#tabcontents').animate({scrollTop: -99999}, 500)");
+                       btn.innerHTML = "<a href='#' name='tab_" + pmc + "'>" + 
pmc + "</a>"
+                       panellist.appendChild(btn)
+                       if (sproject && sproject == pmc) {
+                               $('#btn_' + pmc).click();
+                               $('#' + pmc).addClass("active");
+                       }
+
+               }
+
+
+
+
+               if (json.jira[pmc][0] > 0 || json.jira[pmc][1] > 0) {
+                       renderJIRA(pmc)
                }
+
+
+               // Reporting example
+               var template = buildPanel(pmc, "Report template");
+               template.innerHTML += "<pre style='border: 2px dotted #444; 
padding: 10px; background: #FFD;' contenteditable='true'>" + templates[pmc] + 
"</pre>"
+
+               // Fetch from JIRA dialog
+               var dialog = document.createElement('div');
+               dialog.setAttribute("id", "dialog_" + pmc);
+               dialog.setAttribute("title", "Fetch data from JIRA")
+               dialog.setAttribute("style", "display: none;")
+               dialog.innerHTML = "<form><b>JIRA Project:</b><input 
type='text' name='jira' placeholder='FOO'><br/><b>Optional prepend:</b> <input 
name='prepend' type='text' placeholder='Foo'/><br><input type='button' 
value='Fetch from JIRA' onclick='fetchJIRA(\"" + pmc + "\", 
this.form[\"jira\"].value, this.form[\"prepend\"].value);'></form><p>If you 
have multiple JIRA projects and they only have the version number in their 
release versions, please enter the component name in the 'prepend' field.</p>"
+               document.getElementById('tab_' + pmc).appendChild(dialog)
+
        }
-       addLine(pmc)
-       
-       // Add btn for nav
-       if (f > 0) {
-           var btn = document.createElement('li');
-           btn.setAttribute("id", "btn_" + pmc)
-           btn.setAttribute("class", "tab-title")
-           btn.setAttribute("onclick", "$('#tabcontents').animate({scrollTop: 
-99999}, 500)");
-           btn.innerHTML = "<a href='#' name='tab_" + pmc + "'>" + pmc + "</a>"
-           panellist.appendChild(btn)
-           if (sproject && sproject == pmc) {
-               $('#btn_'+pmc).click();
-               $('#' + pmc).addClass("active");
-           }
-           
-       }
-       
-       
-       
-       
-       if (json.jira[pmc][0] > 0 || json.jira[pmc][1] > 0) {
-           renderJIRA(pmc)
-       }
-       
-       
-       // Reporting example
-       var template = buildPanel(pmc, "Report template");
-       template.innerHTML += "<pre style='border: 2px dotted #444; padding: 
10px; background: #FFD;' contenteditable='true'>" + templates[pmc] + "</pre>"
-       
-       // Fetch from JIRA dialog
-       var dialog = document.createElement('div');
-       dialog.setAttribute("id", "dialog_" + pmc);
-       dialog.setAttribute("title", "Fetch data from JIRA")
-       dialog.setAttribute("style", "display: none;")
-       dialog.innerHTML = "<form><b>JIRA Project:</b><input type='text' 
name='jira' placeholder='FOO'><br/><b>Optional prepend:</b> <input 
name='prepend' type='text' placeholder='Foo'/><br><input type='button' 
value='Fetch from JIRA' onclick='fetchJIRA(\"" + pmc + "\", 
this.form[\"jira\"].value, this.form[\"prepend\"].value);'></form><p>If you 
have multiple JIRA projects and they only have the version number in their 
release versions, please enter the component name in the 'prepend' field.</p>"
-       document.getElementById('tab_' + pmc).appendChild(dialog)
-       
-    }
-    if (json.pmcs.length == 0) {
-       container.innerHTML = "You are not a member of any top level project 
PMC, sorry!"
-    }
-    
+       if (json.pmcs.length == 0) {
+               container.innerHTML = "You are not a member of any top level 
project PMC, sorry!"
+       }
+
        $("#tabcontents").find("[id^='tab']").hide();
-    
-    
-    
-    $('#tabs a').click(function(e) {
-        e.preventDefault();
-        if ($(this).closest("li").attr("id") == "current"){
-         return;       
-        }
-        else{             
-          $("#tabcontents").find("[id^='tab_']").hide();
-          $("#tabs li").attr("id","");
-          $(this).parent().attr("id","current");
-          $('#' + $(this).attr('name')).fadeIn();
-        }
-    });
-       
+
+
+
+       $('#tabs a').click(function(e) {
+               e.preventDefault();
+               if ($(this).closest("li").attr("id") == "current") {
+                       return;
+               } else {
+                       $("#tabcontents").find("[id^='tab_']").hide();
+                       $("#tabs li").attr("id", "");
+                       $(this).parent().attr("id", "current");
+                       $('#' + $(this).attr('name')).fadeIn();
+               }
+       });
+
        var project = nproject ? nproject : document.location.search.substr(1);
-       
-    if (project && project.length > 0) {
-      $("#tabcontents #tab_" + project).fadeIn();
-         $("#tabs #btn_" + project).attr('id', 'current');
-    }
+
+       if (project && project.length > 0) {
+               $("#tabcontents #tab_" + project).fadeIn();
+               $("#tabs #btn_" + project).attr('id', 'current');
+       }
        if (json.all && json.all.length > 0) {
                var btn = document.createElement('li');
                btn.setAttribute("style", "margin-left: 48px;")
@@ -536,61 +535,61 @@ function renderFrontPage(json) {
                sel.setAttribute("onchange", "location.href = '/?' + 
this.value;")
                btn.appendChild(sel)
                panellist.appendChild(btn)
-               
+
        }
-       
-       
-       
+
+
+
 }
 
 
 function renderJIRA(pmc) {
-    var obj = buildPanel(pmc, "JIRA Statistics")
- 
-    addLine(pmc, "## JIRA activity:")
-    addLine(pmc)
-    addLine(pmc, " - " + jsdata.jira[pmc][0] + " JIRA tickets created in the 
last 3 months");
-    addLine(pmc, " - " + jsdata.jira[pmc][1] + " JIRA tickets closed/resolved 
in the last 3 months");
-    addLine(pmc)
-    obj.innerHTML += jsdata.jira[pmc][0] + " JIRA tickets created in the last 
3 months<br/>";
-    obj.innerHTML += jsdata.jira[pmc][1] + " JIRA tickets closed/resolved in 
the last 3 months<br/>";
+       var obj = buildPanel(pmc, "JIRA Statistics")
+
+       addLine(pmc, "## JIRA activity:")
+       addLine(pmc)
+       addLine(pmc, " - " + jsdata.jira[pmc][0] + " JIRA tickets created in 
the last 3 months");
+       addLine(pmc, " - " + jsdata.jira[pmc][1] + " JIRA tickets 
closed/resolved in the last 3 months");
+       addLine(pmc)
+       obj.innerHTML += jsdata.jira[pmc][0] + " JIRA tickets created in the 
last 3 months<br/>";
+       obj.innerHTML += jsdata.jira[pmc][1] + " JIRA tickets closed/resolved 
in the last 3 months<br/>";
        if (jsdata.keys[pmc]) {
                obj.innerHTML += "Keys used: <kbd>" + jsdata.keys[pmc].join(", 
") + "</kbd>"
        }
-    
+
 }
 
 
 function renderChart(json, name, container, delivery) {
-    
-    var chartDiv = document.createElement('div')
-    chartDiv.setAttribute("id", name + "_chart")
-    var dates = []
+
+       var chartDiv = document.createElement('div')
+       chartDiv.setAttribute("id", name + "_chart")
+       var dates = []
        var noweekly = 0;
-    for (date in json[name]) {
-       dates.push(date)
-    }
+       for (date in json[name]) {
+               dates.push(date)
+       }
        for (date in delivery) noweekly++;
-    var d = name.split(".org-");
-    var mlname = d[1] + "@" + d[0] + ".org"
-    dates.sort();
-    var cu = 0;
-    narr = []
-    hitFirst = false
-    
-    var dp = new Date();
-    dp.setMonth(dp.getMonth() - 3);
-       
+       var d = name.split(".org-");
+       var mlname = d[1] + "@" + d[0] + ".org"
+       dates.sort();
+       var cu = 0;
+       narr = []
+       hitFirst = false
+
+       var dp = new Date();
+       dp.setMonth(dp.getMonth() - 3);
+
        var odp = new Date();
-    odp.setMonth(odp.getMonth() - 6);
+       odp.setMonth(odp.getMonth() - 6);
        if (dp.getMonth() - 6 < 0) {
                odp.setYear(odp.getYear() - 1)
        }
 
-    difference = 0
-    for (i in dates) {
+       difference = 0
+       for (i in dates) {
                var date = dates[i];
-               var dateString = new Date(parseInt(date)*1000);
+               var dateString = new Date(parseInt(date) * 1000);
                if (dateString > dp) {
                        difference += json[name][date]
                }
@@ -606,19 +605,19 @@ function renderChart(json, name, contain
                        }
                }
 
-    }
-    
-    var data = new google.visualization.DataTable();
-        data.addColumn('date', 'Date');
-        data.addColumn('number', "List members");
-               if (noweekly > 0) {
-                       data.addColumn('number', "Emails sent per week");
-               }
-               
-        data.addRows(narr);
+       }
+
+       var data = new google.visualization.DataTable();
+       data.addColumn('date', 'Date');
+       data.addColumn('number', "List members");
+       if (noweekly > 0) {
+               data.addColumn('number', "Emails sent per week");
+       }
+
+       data.addRows(narr);
 
-    
-    var options = {
+
+       var options = {
                title: 'Mailing list stats for ' + mlname,
                backgroundColor: 'transparent',
                width: 900,
@@ -631,41 +630,64 @@ function renderChart(json, name, contain
                        format: "#"
                },
                vAxes: (noweekly > 0) ? [
-               
-               {title: 'Emails per week', titleTextStyle: {color: '#DD0000'}},
-               {title: 'Subscribers', titleTextStyle: {color: '#0000DD'}},
-               ] : [
-               {title: 'Subscribers', titleTextStyle: {color: '#0000DD'}},
+
+                       {
+                               title: 'Emails per week',
+                               titleTextStyle: {
+                                       color: '#DD0000'
+                               }
+                       }, {
+                               title: 'Subscribers',
+                               titleTextStyle: {
+                                       color: '#0000DD'
+                               }
+                       },
+               ] : [{
+                               title: 'Subscribers',
+                               titleTextStyle: {
+                                       color: '#0000DD'
+                               }
+                       },
                ],
                series: {
-                 0: {type: "line", pointSize:4, lineWidth: 2, targetAxisIndex: 
(noweekly > 0) ? 1 : null},
-                 1: {type: "bars", targetAxisIndex: (noweekly > 0) ? 0 : [0,1]}
-                 },
-                 seriesType: "bars",
-               tooltip: {isHtml: true},
-         };
-
-    var chart = new google.visualization.ComboChart(chartDiv);
-    
-    chart.draw(data, options);
-    return [cu, difference, chartDiv];
+                       0: {
+                               type: "line",
+                               pointSize: 4,
+                               lineWidth: 2,
+                               targetAxisIndex: (noweekly > 0) ? 1 : null
+                       },
+                       1: {
+                               type: "bars",
+                               targetAxisIndex: (noweekly > 0) ? 0 : [0, 1]
+                       }
+               },
+               seriesType: "bars",
+               tooltip: {
+                       isHtml: true
+               },
+       };
+
+       var chart = new google.visualization.ComboChart(chartDiv);
+
+       chart.draw(data, options);
+       return [cu, difference, chartDiv];
 
 }
 
 
 
 function renderReleaseChart(releases, name, container) {
-    
-       
-    var chartDiv;
+
+
+       var chartDiv;
        if (document.getElementById(name + "_releasechart")) {
                chartDiv = document.getElementById(name + "_releasechart")
        } else {
                chartDiv = document.createElement('div')
                chartDiv.setAttribute("id", name + "_releasechart")
        }
-    
-    var narr = []
+
+       var narr = []
        var maxLen = 1;
        for (version in releases) {
                var x = version.match(/(\d+)\.(\d+)/)
@@ -673,51 +695,56 @@ function renderReleaseChart(releases, na
                        maxLen = x[2].length;
                }
        }
-    for (version in releases) {
-               if (new Date(releases[version]*1000).getFullYear() >= 1999 ) {
+       for (version in releases) {
+               if (new Date(releases[version] * 1000).getFullYear() >= 1999) {
                        var major = parseFloat(version) ? parseFloat(version) : 
1
                        var x = version.match(/(\d+)\.(\d+)/)
                        if (x) {
-                               while (x[2].length < maxLen) { x[2] = "0" + 
x[2] }
+                               while (x[2].length < maxLen) {
+                                       x[2] = "0" + x[2]
+                               }
                                major = parseFloat(x[1] + "." + x[2])
                        }
-                       narr.push([new Date(releases[version]*1000), major , 
version + " - " + new Date(releases[version]*1000).toDateString()])
+                       narr.push([new Date(releases[version] * 1000), major, 
version + " - " + new Date(releases[version] * 1000).toDateString()])
                }
-               
-    }
-    
-    var data = new google.visualization.DataTable();
-       
+
+       }
+
+       var data = new google.visualization.DataTable();
+
        data.addColumn('datetime', 'Date');
        data.addColumn('number', 'Version')
        data.addColumn('string', 'tooltip');
        data.setColumnProperty(2, 'role', 'tooltip');
-       
+
        data.addRows(narr);
 
-    
-    var options = {
-      title: 'Release timeline for ' + name,
-      height: 240,
-      width: 800,
-      backgroundColor: 'transparent',
-         series: [
-               {pointSize: 15},
-       ],
-         pointShape: { type: 'star', sides: 5 }
-    };
 
-    var chart = new google.visualization.ScatterChart(chartDiv);
+       var options = {
+               title: 'Release timeline for ' + name,
+               height: 240,
+               width: 800,
+               backgroundColor: 'transparent',
+               series: [{
+                               pointSize: 15
+                       },
+               ],
+               pointShape: {
+                       type: 'star',
+                       sides: 5
+               }
+       };
+
+       var chart = new google.visualization.ScatterChart(chartDiv);
        chartDiv.style.marginLeft = "50px";
-    
-    chart.draw(data, options);
-    return chartDiv
+
+       chart.draw(data, options);
+       return chartDiv
 }
 
-function fetchJIRA(pmc, project, prepend ) {
+function fetchJIRA(pmc, project, prepend) {
        if (project && project.length > 1) {
-               GetAsyncJSON("/jiraversions.py?project=" + pmc + "&jiraname=" + 
project + "&prepend=" + prepend, null,
-                function(json) {
+               GetAsyncJSON("/jiraversions.py?project=" + pmc + "&jiraname=" + 
project + "&prepend=" + prepend, null, function(json) {
                        if (json && json.versions) {
                                var n = 0;
                                for (version in json.versions) {
@@ -728,11 +755,11 @@ function fetchJIRA(pmc, project, prepend
                                var nproject = pmc
                                alert("Fetched " + n + " releases from JIRA!")
                                renderFrontPage(jsdata)
-                               
+
                        } else {
                                alert("Couldn't find any release data :(")
                        }
                })
        }
-       
+
 }
\ No newline at end of file


Reply via email to