You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@steve.apache.org by pi...@apache.org on 2016/01/11 11:03:45 UTC

svn commit: r1723997 [3/4] - in /steve/trunk/pysteve/www/htdocs/js: jquery-ui.js steve_ap.js steve_cop.js steve_dh.js steve_monitor.js steve_rest.js steve_stv.js

Modified: steve/trunk/pysteve/www/htdocs/js/steve_ap.js
URL: http://svn.apache.org/viewvc/steve/trunk/pysteve/www/htdocs/js/steve_ap.js?rev=1723997&r1=1723996&r2=1723997&view=diff
==============================================================================
--- steve/trunk/pysteve/www/htdocs/js/steve_ap.js (original)
+++ steve/trunk/pysteve/www/htdocs/js/steve_ap.js Mon Jan 11 10:03:45 2016
@@ -17,103 +17,103 @@
 
 function displayIssueAP(code, response, state) {
     election_data = response
-	var obj = document.getElementById('preloaderWrapper')
-	obj.setAttribute("id", "ynavote")
+    var obj = document.getElementById('preloaderWrapper')
+    obj.setAttribute("id", "ynavote")
     if (code != 200) {
         obj.innerHTML = "<h1>Could not load issue:</h1><h2>" + response.message + "</h2>";
     } else {
-		obj.innerHTML = ""
-		
-		var title = document.createElement('h2')
-		title.innerHTML = response.issue.title;
-		obj.appendChild(title)
-		
-		obj.appendChild(keyvaluepairText("nominatedby", "Put forward (nominated) by:", response.issue.nominatedby))
-		obj.appendChild(keyvaluepairText("seconds", "Seconded by:", response.issue.seconds.length > 0 ?  response.issue.seconds.join(", ") : "no-one" ))
-		
-		var desc = document.createElement('pre')
-		desc.setAttribute("class", "statement")
-		desc.innerHTML = response.issue.description
-		obj.appendChild(desc)
-		
-		var outer = document.createElement('div')
-		outer.setAttribute("class", "issueListItemWide")
-		
-		var byes = document.createElement('input')
-		byes.setAttribute("type", "button")
-		byes.setAttribute("value", "Binding Yes (+1)")
-		byes.setAttribute("class", "btn-green")
-		byes.setAttribute("style", "float: right;");
-		byes.setAttribute("onclick", "castSingleVote('by');")
-		
-		var yes = document.createElement('input')
-		yes.setAttribute("type", "button")
-		yes.setAttribute("value", "Yes (+1)")
-		yes.setAttribute("class", "btn-green")
-		yes.setAttribute("style", "float: right;");
-		yes.setAttribute("onclick", "castSingleVote('y');")
-		
-		var no = document.createElement('input')
-		no.setAttribute("type", "button")
-		no.setAttribute("value", "No  (-1)")
-		no.setAttribute("class", "btn-red")
-		no.setAttribute("style", " float: right;");
-		no.setAttribute("onclick", "castSingleVote('n');")
-		
-		var bno = document.createElement('input')
-		bno.setAttribute("type", "button")
-		bno.setAttribute("value", "Binding No (-1)")
-		bno.setAttribute("class", "btn-red")
-		bno.setAttribute("style", " float: right;");
-		bno.setAttribute("onclick", "castSingleVote('bn');")
-		
-		var abstain = document.createElement('input')
-		abstain.setAttribute("type", "button")
-		abstain.setAttribute("value", "Abstain (0)")
-		abstain.setAttribute("class", "btn-yellow")
-		abstain.setAttribute("style", "float: right;");
-		abstain.setAttribute("onclick", "castSingleVote('a');")
-		
-		var p = document.createElement('p')
-		p.innerHTML = "Cast your vote by clicking on the respective button below. You may recast your vote as many time as you like, should you reconsider."
-		
-		obj.appendChild(p)
-		outer.appendChild(bno)
-		outer.appendChild(no)
-		outer.appendChild(abstain)
-		outer.appendChild(yes)
-		outer.appendChild(byes)
-		
-		obj.appendChild(outer)
-	}
+        obj.innerHTML = ""
+        
+        var title = document.createElement('h2')
+        title.innerHTML = response.issue.title;
+        obj.appendChild(title)
+        
+        obj.appendChild(keyvaluepairText("nominatedby", "Put forward (nominated) by:", response.issue.nominatedby))
+        obj.appendChild(keyvaluepairText("seconds", "Seconded by:", response.issue.seconds.length > 0 ?  response.issue.seconds.join(", ") : "no-one" ))
+        
+        var desc = document.createElement('pre')
+        desc.setAttribute("class", "statement")
+        desc.innerHTML = response.issue.description
+        obj.appendChild(desc)
+        
+        var outer = document.createElement('div')
+        outer.setAttribute("class", "issueListItemWide")
+        
+        var byes = document.createElement('input')
+        byes.setAttribute("type", "button")
+        byes.setAttribute("value", "Binding Yes (+1)")
+        byes.setAttribute("class", "btn-green")
+        byes.setAttribute("style", "float: right;");
+        byes.setAttribute("onclick", "castSingleVote('by');")
+        
+        var yes = document.createElement('input')
+        yes.setAttribute("type", "button")
+        yes.setAttribute("value", "Yes (+1)")
+        yes.setAttribute("class", "btn-green")
+        yes.setAttribute("style", "float: right;");
+        yes.setAttribute("onclick", "castSingleVote('y');")
+        
+        var no = document.createElement('input')
+        no.setAttribute("type", "button")
+        no.setAttribute("value", "No  (-1)")
+        no.setAttribute("class", "btn-red")
+        no.setAttribute("style", " float: right;");
+        no.setAttribute("onclick", "castSingleVote('n');")
+        
+        var bno = document.createElement('input')
+        bno.setAttribute("type", "button")
+        bno.setAttribute("value", "Binding No (-1)")
+        bno.setAttribute("class", "btn-red")
+        bno.setAttribute("style", " float: right;");
+        bno.setAttribute("onclick", "castSingleVote('bn');")
+        
+        var abstain = document.createElement('input')
+        abstain.setAttribute("type", "button")
+        abstain.setAttribute("value", "Abstain (0)")
+        abstain.setAttribute("class", "btn-yellow")
+        abstain.setAttribute("style", "float: right;");
+        abstain.setAttribute("onclick", "castSingleVote('a');")
+        
+        var p = document.createElement('p')
+        p.innerHTML = "Cast your vote by clicking on the respective button below. You may recast your vote as many time as you like, should you reconsider."
+        
+        obj.appendChild(p)
+        outer.appendChild(bno)
+        outer.appendChild(no)
+        outer.appendChild(abstain)
+        outer.appendChild(yes)
+        outer.appendChild(byes)
+        
+        obj.appendChild(outer)
+    }
 }
 
 function loadIssue(election, issue, uid, callback) {
-	
-	var messages = ["Herding cats...", "Shaving yaks...", "Shooing some cows away...", "Fetching election data...", "Loading issues..."]
-	if (!election || !uid) {
-		var l = document.location.search.substr(1).split("/");
-		election = l[0];
-		issue = l.length > 1 ? l[l.length-2] : "";
-		uid = l.length > 2 ? l[l.length-1] : "";
-	}
-	if (step == -1) {
-		getJSON("/steve/voter/view/" + election + "/" + issue + "?uid=" + uid, [election, issue, uid], callback)
-	}
-	
-	var obj = document.getElementById('preloader');
-	step++;
-	if (!election_data && obj) {
-		if (step % 2 == 1) obj.innerHTML = messages[parseInt(Math.random()*messages.length-0.01)]
-	} else if (obj && (step % 2 == 1)) {
-		obj.innerHTML = "Ready..!"
-	}
-	if (step % 2 == 1) {
-		obj.style.transform = "translate(0,0)"
-	} else if (obj) {
-		obj.style.transform = "translate(0,-500%)"
-	}
-	if (!election_data|| (step % 2 == 0) ) {
-		window.setTimeout(loadElection, 750, election, uid, callback);
-	}
+    
+    var messages = ["Herding cats...", "Shaving yaks...", "Shooing some cows away...", "Fetching election data...", "Loading issues..."]
+    if (!election || !uid) {
+        var l = document.location.search.substr(1).split("/");
+        election = l[0];
+        issue = l.length > 1 ? l[l.length-2] : "";
+        uid = l.length > 2 ? l[l.length-1] : "";
+    }
+    if (step == -1) {
+        getJSON("/steve/voter/view/" + election + "/" + issue + "?uid=" + uid, [election, issue, uid], callback)
+    }
+    
+    var obj = document.getElementById('preloader');
+    step++;
+    if (!election_data && obj) {
+        if (step % 2 == 1) obj.innerHTML = messages[parseInt(Math.random()*messages.length-0.01)]
+    } else if (obj && (step % 2 == 1)) {
+        obj.innerHTML = "Ready..!"
+    }
+    if (step % 2 == 1) {
+        obj.style.transform = "translate(0,0)"
+    } else if (obj) {
+        obj.style.transform = "translate(0,-500%)"
+    }
+    if (!election_data|| (step % 2 == 0) ) {
+        window.setTimeout(loadElection, 750, election, uid, callback);
+    }
 }

Modified: steve/trunk/pysteve/www/htdocs/js/steve_cop.js
URL: http://svn.apache.org/viewvc/steve/trunk/pysteve/www/htdocs/js/steve_cop.js?rev=1723997&r1=1723996&r2=1723997&view=diff
==============================================================================
--- steve/trunk/pysteve/www/htdocs/js/steve_cop.js (original)
+++ steve/trunk/pysteve/www/htdocs/js/steve_cop.js Mon Jan 11 10:03:45 2016
@@ -24,73 +24,73 @@ var chars;
 
 
 function loadIssue(election, issue, uid, callback) {
-	
-	var messages = ["Herding cats...", "Shaving yaks...", "Shooing some cows away...", "Fetching election data...", "Loading issues..."]
-	if (!election || !uid) {
-		var l = document.location.search.substr(1).split("/");
-		election = l[0];
-		issue = l.length > 1 ? l[l.length-2] : "";
-		uid = l.length > 2 ? l[l.length-1] : "";
-	}
-	if (step == -1) {
-		getJSON("/steve/voter/view/" + election + "/" + issue + "?uid=" + uid, [election, issue, uid], callback)
-	}
-	
-	var obj = document.getElementById('preloader');
-	step++;
-	if (!election_data && obj) {
-		if (step % 2 == 1) obj.innerHTML = messages[parseInt(Math.random()*messages.length-0.01)]
-	} else if (obj && (step % 2 == 1)) {
-		obj.innerHTML = "Ready..!"
-	}
-	if (step % 2 == 1) {
-		obj.style.transform = "translate(0,0)"
-	} else if (obj) {
-		obj.style.transform = "translate(0,-500%)"
-	}
-	if (!election_data|| (step % 2 == 0) ) {
-		window.setTimeout(loadElection, 750, election, uid, callback);
-	}
+    
+    var messages = ["Herding cats...", "Shaving yaks...", "Shooing some cows away...", "Fetching election data...", "Loading issues..."]
+    if (!election || !uid) {
+        var l = document.location.search.substr(1).split("/");
+        election = l[0];
+        issue = l.length > 1 ? l[l.length-2] : "";
+        uid = l.length > 2 ? l[l.length-1] : "";
+    }
+    if (step == -1) {
+        getJSON("/steve/voter/view/" + election + "/" + issue + "?uid=" + uid, [election, issue, uid], callback)
+    }
+    
+    var obj = document.getElementById('preloader');
+    step++;
+    if (!election_data && obj) {
+        if (step % 2 == 1) obj.innerHTML = messages[parseInt(Math.random()*messages.length-0.01)]
+    } else if (obj && (step % 2 == 1)) {
+        obj.innerHTML = "Ready..!"
+    }
+    if (step % 2 == 1) {
+        obj.style.transform = "translate(0,0)"
+    } else if (obj) {
+        obj.style.transform = "translate(0,-500%)"
+    }
+    if (!election_data|| (step % 2 == 0) ) {
+        window.setTimeout(loadElection, 750, election, uid, callback);
+    }
 }
 
 
 function drawCandidatesCOP() {
     var box = document.getElementById('candidates')
     box.innerHTML = "<h3>Candidates:</h3>"
-	var pname = null
-	var pli = null;
+    var pname = null
+    var pli = null;
     for (i in candidates) {
         var name = candidates[i]
-		if (pname != name['pname']) {
-			pname = name['pname']
-			var char = name['pletter']
-			pli = document.createElement('ol')
-			pli.setAttribute("class", "showList")
-			pli.style.marginTop = "20px"
-			var outer = document.createElement('div')
-			var inner = document.createElement('span')
-			inner.style.fontFamily = "monospace"
-			inner.style.fontWeigth = "bold"
-			inner.innerHTML = name['pname'];
-			outer.setAttribute("class", "ballotbox_clist_DH")
-			if (char == vote_COP) {
-				outer.setAttribute("class", "ballotbox_clist_selectedDH")
-			}
-			outer.setAttribute("id", name)
-			outer.setAttribute("onclick", "vote_COP = '"+char+"'; drawCandidatesCOP();")
-			outer.appendChild(inner)
-			outer.setAttribute("title", "Click to select "  + name + " as your preference")
-			pli.appendChild(outer)
-			box.appendChild(pli)
-			
-		}
+        if (pname != name['pname']) {
+            pname = name['pname']
+            var char = name['pletter']
+            pli = document.createElement('ol')
+            pli.setAttribute("class", "showList")
+            pli.style.marginTop = "20px"
+            var outer = document.createElement('div')
+            var inner = document.createElement('span')
+            inner.style.fontFamily = "monospace"
+            inner.style.fontWeigth = "bold"
+            inner.innerHTML = name['pname'];
+            outer.setAttribute("class", "ballotbox_clist_DH")
+            if (char == vote_COP) {
+                outer.setAttribute("class", "ballotbox_clist_selectedDH")
+            }
+            outer.setAttribute("id", name)
+            outer.setAttribute("onclick", "vote_COP = '"+char+"'; drawCandidatesCOP();")
+            outer.appendChild(inner)
+            outer.setAttribute("title", "Click to select "  + name + " as your preference")
+            pli.appendChild(outer)
+            box.appendChild(pli)
+            
+        }
         var char = name['letter']
         var li = document.createElement('li')
         var outer = document.createElement('div')
         var inner = document.createElement('span')
         inner.style.fontFamily = "monospace"
-		li.style.marginLeft = "30px"
-		li.style.marginBottom = "10px"
+        li.style.marginLeft = "30px"
+        li.style.marginBottom = "10px"
         inner.innerHTML = name['name'];
         outer.setAttribute("class", "ballotbox_clist_DH")
         if (char == vote_COP) {
@@ -135,8 +135,8 @@ function displayIssueCOP(code, response,
         
         var l = document.createElement('ol')
         l.setAttribute("id", "candidates")
-		l.setAttribute("type", "a")
-		l.setAttribute("class", "showList")
+        l.setAttribute("type", "a")
+        l.setAttribute("class", "showList")
         obj.appendChild(l)
         
         drawCandidatesCOP();

Modified: steve/trunk/pysteve/www/htdocs/js/steve_dh.js
URL: http://svn.apache.org/viewvc/steve/trunk/pysteve/www/htdocs/js/steve_dh.js?rev=1723997&r1=1723996&r2=1723997&view=diff
==============================================================================
--- steve/trunk/pysteve/www/htdocs/js/steve_dh.js (original)
+++ steve/trunk/pysteve/www/htdocs/js/steve_dh.js Mon Jan 11 10:03:45 2016
@@ -39,36 +39,35 @@ function shuffleCandidates() {
 }
 
 function loadIssue(election, issue, uid, callback) {
-	
-	var messages = ["Herding cats...", "Shaving yaks...", "Shooing some cows away...", "Fetching election data...", "Loading issues..."]
-	if (!election || !uid) {
-		var l = document.location.search.substr(1).split("/");
-		election = l[0];
-		issue = l.length > 1 ? l[l.length-2] : "";
-		uid = l.length > 2 ? l[l.length-1] : "";
-	}
-	if (step == -1) {
-		getJSON("/steve/voter/view/" + election + "/" + issue + "?uid=" + uid, [election, issue, uid], callback)
-	}
-	
-	var obj = document.getElementById('preloader');
-	step++;
-	if (!election_data && obj) {
-		if (step % 2 == 1) obj.innerHTML = messages[parseInt(Math.random()*messages.length-0.01)]
-	} else if (obj && (step % 2 == 1)) {
-		obj.innerHTML = "Ready..!"
-	}
-	if (step % 2 == 1) {
-		obj.style.transform = "translate(0,0)"
-	} else if (obj) {
-		obj.style.transform = "translate(0,-500%)"
-	}
-	if (!election_data|| (step % 2 == 0) ) {
-		window.setTimeout(loadElection, 750, election, uid, callback);
-	}
+    
+    var messages = ["Herding cats...", "Shaving yaks...", "Shooing some cows away...", "Fetching election data...", "Loading issues..."]
+    if (!election || !uid) {
+        var l = document.location.search.substr(1).split("/");
+        election = l[0];
+        issue = l.length > 1 ? l[l.length-2] : "";
+        uid = l.length > 2 ? l[l.length-1] : "";
+    }
+    if (step == -1) {
+        getJSON("/steve/voter/view/" + election + "/" + issue + "?uid=" + uid, [election, issue, uid], callback)
+    }
+    
+    var obj = document.getElementById('preloader');
+    step++;
+    if (!election_data && obj) {
+        if (step % 2 == 1) obj.innerHTML = messages[parseInt(Math.random()*messages.length-0.01)]
+    } else if (obj && (step % 2 == 1)) {
+        obj.innerHTML = "Ready..!"
+    }
+    if (step % 2 == 1) {
+        obj.style.transform = "translate(0,0)"
+    } else if (obj) {
+        obj.style.transform = "translate(0,-500%)"
+    }
+    if (!election_data|| (step % 2 == 0) ) {
+        window.setTimeout(loadElection, 750, election, uid, callback);
+    }
 }
 
-
 function drawCandidatesDH() {
     var box = document.getElementById('candidates')
     box.innerHTML = "<h3>Candidates:</h3>"
@@ -97,7 +96,7 @@ function drawCandidatesDH() {
             statement.setAttribute("class", "statement_marker")
             statement.setAttribute("title", "Click to read " + name + "'s statement")
             statement.innerHTML = "<a href='#statement_"+char+"'>Statement</a>"
-
+            
             li.appendChild(statement)
             
             var popup = document.createElement("div")
@@ -111,7 +110,7 @@ function drawCandidatesDH() {
             
             var popuph = document.createElement("div")
             popuph.setAttribute("class", "modal-header")
-            popuph.innerHTML = '<h2>Statement from ' + name + '</h2><a href="#close" class="btn-close" aria-hidden="true">×</a>'
+            popuph.innerHTML = '<h2>Statement from ' + name + '</h2><a href="#close" class="btn-close" aria-hidden="true">�</a>'
             
             var popupb = document.createElement("div")
             popupb.setAttribute("class", "modal-body")

Modified: steve/trunk/pysteve/www/htdocs/js/steve_monitor.js
URL: http://svn.apache.org/viewvc/steve/trunk/pysteve/www/htdocs/js/steve_monitor.js?rev=1723997&r1=1723996&r2=1723997&view=diff
==============================================================================
--- steve/trunk/pysteve/www/htdocs/js/steve_monitor.js (original)
+++ steve/trunk/pysteve/www/htdocs/js/steve_monitor.js Mon Jan 11 10:03:45 2016
@@ -17,26 +17,26 @@
 
 // Function for fetching JSON from the REST API
 function getJSON(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.onreadystatechange = function(state) {
-		if (xmlHttp.readyState == 4 && xmlHttp.status && xmlHttp.status >= 200) {
-			if (callback) {
-				window.setTimeout(callback, 0.01, xmlHttp.status, (xmlHttp.responseText && xmlHttp.responseText.length > 1) ? JSON.parse(xmlHttp.responseText) : null, xstate);
-			}
-		}
-	}
+    var xmlHttp = null;
+    if (window.XMLHttpRequest) {
+        xmlHttp = new XMLHttpRequest();
+    } else {
+        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
+    }
+    xmlHttp.open("GET", theUrl, true);
+    xmlHttp.send(null);
+    xmlHttp.onreadystatechange = function(state) {
+        if (xmlHttp.readyState == 4 && xmlHttp.status && xmlHttp.status >= 200) {
+            if (callback) {
+                window.setTimeout(callback, 0.01, xmlHttp.status, (xmlHttp.responseText && xmlHttp.responseText.length > 1) ? JSON.parse(xmlHttp.responseText) : null, xstate);
+            }
+        }
+    }
 }
 
 function getIssues() {
-	election = document.location.search.substr(1)
-	getJSON("/steve/admin/view/" + election, election, listIssues)
+    election = document.location.search.substr(1)
+    getJSON("/steve/admin/view/" + election, election, listIssues)
 }
 
 var ehash = null
@@ -51,164 +51,164 @@ var rigged = false
 var riggedIssues = {}
 
 function listIssues(code, response, election) {
-	if (code == 200) {
-		eid = election
-		issues = response.issues
-		basedata = response.base_data
-		document.getElementById('title').innerHTML += " " + basedata.title
-		var obj = document.getElementById('preloaderWrapper')
-		obj.innerHTML = ""
-		obj.setAttribute("id", "contents")
-		for (i in issues) {
-			window.setTimeout(showChanges, 1000, issues[i])
-		}
-	} else {
-		alert(response.message)
-	}
+    if (code == 200) {
+        eid = election
+        issues = response.issues
+        basedata = response.base_data
+        document.getElementById('title').innerHTML += " " + basedata.title
+        var obj = document.getElementById('preloaderWrapper')
+        obj.innerHTML = ""
+        obj.setAttribute("id", "contents")
+        for (i in issues) {
+            window.setTimeout(showChanges, 1000, issues[i])
+        }
+    } else {
+        alert(response.message)
+    }
 }
 
 function updateVotes(code, response, issue) {
-	if (code == 200) {
-		recasters[issue] = recasters[issue] ? recasters[issue] : {}
-		oldvotes[issue] = votes[issue] ? votes[issue] : {}
-		votes[issue] = response.votes
-		var is = {}
-		for (i in issues) {
-			if (issues[i].id == issue) {
-				is = issues[i]
-				break
-			}
-		}
-		if (is.hash && response.issue.hash != is.hash) {
-			riggedIssues[issue] = "WAS: " + JSON.stringify(is) + " - IS NOW: " + JSON.stringify(response.issue)
-		}
-		if (ehash == null) {
-			ehash = response.hash
-		}
-		if (ehash != response.hash) {
-			rigged = true
-		}
-		recasts[issue] = recasts[issue] ? recasts[issue] : 0
-	} else if (response.message == "Issue not found") {
-		var header = document.getElementById('issue_' + issue + "_header")
-		header.innerHTML = "<font color='red'><b>Issue deleted?: " + response.message + "</b></font>"
-	}
+    if (code == 200) {
+        recasters[issue] = recasters[issue] ? recasters[issue] : {}
+        oldvotes[issue] = votes[issue] ? votes[issue] : {}
+        votes[issue] = response.votes
+        var is = {}
+        for (i in issues) {
+            if (issues[i].id == issue) {
+                is = issues[i]
+                break
+            }
+        }
+        if (is.hash && response.issue.hash != is.hash) {
+            riggedIssues[issue] = "WAS: " + JSON.stringify(is) + " - IS NOW: " + JSON.stringify(response.issue)
+        }
+        if (ehash == null) {
+            ehash = response.hash
+        }
+        if (ehash != response.hash) {
+            rigged = true
+        }
+        recasts[issue] = recasts[issue] ? recasts[issue] : 0
+    } else if (response.message == "Issue not found") {
+        var header = document.getElementById('issue_' + issue + "_header")
+        header.innerHTML = "<font color='red'><b>Issue deleted?: " + response.message + "</b></font>"
+    }
 }
 
 function calcChanges(issue, oldv, newv) {
-	sinceLast = 0;
-	
-	
-	// Find new votes cast since last update
-	if (!oldv || !newv) {
-		return [0,0]
-	}
-	for (i in newv) {
-		if (!oldv[i]) {
-			sinceLast++;
-		} else if (oldv[i].timestamp != undefined && newv[i].timestamp != undefined && oldv[i].timestamp != newv[i].timestamp) {
-			recasts[issue]++;
-			recasters[issue][i] = (recasters[issue][i] ? recasters[issue][i] : 0) + 1
-		}
-	}
-	var nrc = 0;
-	for (i in recasters[issue]) nrc++;
-	
-	return [sinceLast, nrc]
+    sinceLast = 0;
+    
+    
+    // Find new votes cast since last update
+    if (!oldv || !newv) {
+        return [0,0]
+    }
+    for (i in newv) {
+        if (!oldv[i]) {
+            sinceLast++;
+        } else if (oldv[i].timestamp != undefined && newv[i].timestamp != undefined && oldv[i].timestamp != newv[i].timestamp) {
+            recasts[issue]++;
+            recasters[issue][i] = (recasters[issue][i] ? recasters[issue][i] : 0) + 1
+        }
+    }
+    var nrc = 0;
+    for (i in recasters[issue]) nrc++;
+    
+    return [sinceLast, nrc]
 }
 
 var timeouts = {}
 
 function showDetails(issueid, update) {
-	var obj = document.getElementById('issue_' + issueid + '_details')
-	if (obj.innerHTML.length > 0 && !update) {
-		obj.innerHTML = ""
-		window.clearTimeout(timeouts[issueid])
-	} else {
-		obj.innerHTML = ""
-		for (i in votes[issueid]) {
-			var rawvote = votes[issueid][i]
-			var vote = null
-			var nrc = recasters[issueid][i] ? recasters[issueid][i] : 0
-			var add = ""
-			if (rawvote.timestamp) {
-				vote = rawvote.vote
-				add = ". Cast at " + new Date(rawvote.timestamp*1000).toLocaleString()
-			} else {
-				vote = rawvote
-			}
-			if (nrc > 0) {
-				nrc = "Vote recast " + nrc + " time(s)"
-			} else {
-				nrc = "No recasts yet"
-			}
-			obj.innerHTML += "<b>" + i + ": </b> " + vote + " - " + nrc + add + "<br/>"
-		}
-		timeouts[issueid] = window.setTimeout(showDetails, 2500, issueid, true)
-	}
-	
+    var obj = document.getElementById('issue_' + issueid + '_details')
+    if (obj.innerHTML.length > 0 && !update) {
+        obj.innerHTML = ""
+        window.clearTimeout(timeouts[issueid])
+    } else {
+        obj.innerHTML = ""
+        for (i in votes[issueid]) {
+            var rawvote = votes[issueid][i]
+            var vote = null
+            var nrc = recasters[issueid][i] ? recasters[issueid][i] : 0
+            var add = ""
+            if (rawvote.timestamp) {
+                vote = rawvote.vote
+                add = ". Cast at " + new Date(rawvote.timestamp*1000).toLocaleString()
+            } else {
+                vote = rawvote
+            }
+            if (nrc > 0) {
+                nrc = "Vote recast " + nrc + " time(s)"
+            } else {
+                nrc = "No recasts yet"
+            }
+            obj.innerHTML += "<b>" + i + ": </b> " + vote + " - " + nrc + add + "<br/>"
+        }
+        timeouts[issueid] = window.setTimeout(showDetails, 2500, issueid, true)
+    }
+    
 }
 
 
 function showChanges(issue) {
-	var parent = document.getElementById('issue_' + issue.id)
-	var header = document.getElementById('issue_' + issue.id + "_header")
-	if (rigged) {
-		document.getElementById('title').innerHTML = "<font color='red'>ELECTION HAS BEEN CHANGED SINCE IT OPENED, POSSIBLE RIGGING ATTEMPT!</font>"
-	}
-	if (!parent) {
-		parent = document.createElement('div')
-		parent.setAttribute("id", "issue_" + issue.id)
-		parent.setAttribute("class", "monitor_issue")
-		document.getElementById('contents').appendChild(parent)
-		
-		parent.innerHTML = "<h3>Issue #" + issue.id + ": " + issue.title + "</h3>"
-		
-		header = document.createElement('div')
-		header.setAttribute("id", "issue_" + issue.id + "_header")
-		header.innerHTML = "Awaiting vote data...hang on!"
-		parent.appendChild(header)
-		
-		details = document.createElement('div')
-		details.setAttribute("id", "issue_" + issue.id + "_details")
-		details.setAttribute("class", "monitor_details")
-		parent.appendChild(details)
-		
-		window.setTimeout(showChanges, 2000, issue)
-	} else {
-		window.setTimeout(showChanges, 15000, issue)
-		numvotes = 0;
-		if (votes[issue.id]) {
-			for (i in votes[issue.id]) numvotes++;
-		}
-		if (numvotes > 0) {
-			var v = votes[issue.id]
-			var a = calcChanges(issue.id, oldvotes[issue.id], v)
-			sinceLast = a[0]
-			nrc = a[1]
-			header.innerHTML = ""
-			if (riggedIssues[issue.id] && riggedIssues[issue.id].length > 0) {
-				header.innerHTML += "<a href='#' onclick=\"alert(riggedIssues['" + issue.id + "']);\"><font color='red'>ISSUE POSSIBLY RIGGED! </font></a><br/> "
-			}
-			header.innerHTML += numvotes + " votes cast, " + sinceLast + " new votes cast since last update. " + recasts[issue.id] + " votes have been recast, split among " + nrc + " voters."
-			header.innerHTML += " <a href='javascript:void(showDetails(\"" + issue.id + "\"));'>Show details</a>"
-			header.innerHTML += " &nbsp; <a href='/steve/admin/monitor/" + eid + "/" + issue.id + "' target='_blank'>Get JSON</a>"
-		} else {
-			header.innerHTML = "No votes cast yet..!"
-		}
-	}
-	getJSON("/steve/admin/monitor/" + eid + "/" + issue.id, issue.id, updateVotes)
-	
-	
-	
+    var parent = document.getElementById('issue_' + issue.id)
+    var header = document.getElementById('issue_' + issue.id + "_header")
+    if (rigged) {
+        document.getElementById('title').innerHTML = "<font color='red'>ELECTION HAS BEEN CHANGED SINCE IT OPENED, POSSIBLE RIGGING ATTEMPT!</font>"
+    }
+    if (!parent) {
+        parent = document.createElement('div')
+        parent.setAttribute("id", "issue_" + issue.id)
+        parent.setAttribute("class", "monitor_issue")
+        document.getElementById('contents').appendChild(parent)
+        
+        parent.innerHTML = "<h3>Issue #" + issue.id + ": " + issue.title + "</h3>"
+        
+        header = document.createElement('div')
+        header.setAttribute("id", "issue_" + issue.id + "_header")
+        header.innerHTML = "Awaiting vote data...hang on!"
+        parent.appendChild(header)
+        
+        details = document.createElement('div')
+        details.setAttribute("id", "issue_" + issue.id + "_details")
+        details.setAttribute("class", "monitor_details")
+        parent.appendChild(details)
+        
+        window.setTimeout(showChanges, 2000, issue)
+    } else {
+        window.setTimeout(showChanges, 15000, issue)
+        numvotes = 0;
+        if (votes[issue.id]) {
+            for (i in votes[issue.id]) numvotes++;
+        }
+        if (numvotes > 0) {
+            var v = votes[issue.id]
+            var a = calcChanges(issue.id, oldvotes[issue.id], v)
+            sinceLast = a[0]
+            nrc = a[1]
+            header.innerHTML = ""
+            if (riggedIssues[issue.id] && riggedIssues[issue.id].length > 0) {
+                header.innerHTML += "<a href='#' onclick=\"alert(riggedIssues['" + issue.id + "']);\"><font color='red'>ISSUE POSSIBLY RIGGED! </font></a><br/> "
+            }
+            header.innerHTML += numvotes + " votes cast, " + sinceLast + " new votes cast since last update. " + recasts[issue.id] + " votes have been recast, split among " + nrc + " voters."
+            header.innerHTML += " <a href='javascript:void(showDetails(\"" + issue.id + "\"));'>Show details</a>"
+            header.innerHTML += " &nbsp; <a href='/steve/admin/monitor/" + eid + "/" + issue.id + "' target='_blank'>Get JSON</a>"
+        } else {
+            header.innerHTML = "No votes cast yet..!"
+        }
+    }
+    getJSON("/steve/admin/monitor/" + eid + "/" + issue.id, issue.id, updateVotes)
+    
+    
+    
 }
 
 
 function disableF5(e) {
-	if ((e.which || e.keyCode) == 116 || (e.which || e.keyCode) == 82) {
-		e.preventDefault();
-		alert("PLEASE...Do not refresh this page")
-	}
+    if ((e.which || e.keyCode) == 116 || (e.which || e.keyCode) == 82) {
+        e.preventDefault();
+        alert("PLEASE...Do not refresh this page")
+    }
 }
 
 window.onkeydown = disableF5
\ No newline at end of file