Bugfixes and architectural changes

Moved some folders around, starting to remove subdomain handling,
blueprints, custom css, removed digital ocean interface, fixed some bugs
This commit is contained in:
CodeKevin
2015-09-13 23:55:15 -04:00
parent 5f6e610f2d
commit 7d766372df
53 changed files with 1191 additions and 1151 deletions

View File

@@ -1,84 +0,0 @@
#submit-key{
display: none;
}
#chal > h1{
text-align: center
}
#chal > form{
width: 400px;
margin: 0 auto;
}
#chal > form > h3,h4{
text-align: center;
}
#chal > form > input{
display: none;
}
table{
width: 100%;
}
/*Not sure why foundation needs these two...*/
.top-bar input{
height: auto;
padding-top: 0.35rem;
padding-bottom: 0.35rem;
font-size: 0.75rem;
}
.top-bar .button{
padding-top: 0.45rem;
padding-bottom: 0.35rem;
margin-bottom: 0;
font-size: 0.75rem;
}
.dropdown{
background-color: #333 !important;
padding: 5px;
}
.dropdown button{
padding-top: 0.45rem;
padding-bottom: 0.35rem;
margin-bottom: 0;
font-size: 0.75rem;
}
#challenges button{
margin: 5px;
}
.row h1{
text-align: center;
}
.textbox{
height: 150px;
}
.chal-tag{
margin: 0 5px 0 5px;
}
#score-graph{
max-height: 400px;
}
#keys-pie-graph{
width: 400px;
max-height: 330px;
float: left;
}
#categories-pie-graph{
width: 600px;
float: left;
max-height: 330px;
}

View File

@@ -1,216 +0,0 @@
function loadchal(id) {
// $('#chal *').show()
// $('#chal > h1').hide()
obj = $.grep(challenges['game'], function (e) {
return e.id == id;
})[0]
$('.chal-name').val(obj.name);
$('.chal-desc').html(obj.description);
$('.chal-value').val(obj.value);
$('.chal-category').val(obj.category);
$('.chal-id').val(obj.id);
//$('#update-challenge .chal-delete').attr({
// 'href': '/admin/chal/close/' + (id + 1)
//})
$('#update-challenge').foundation('reveal', 'open');
}
function submitkey(chal, key) {
$.post("/admin/chal/" + chal, {
key: key,
nonce: $('#nonce').val()
}, function (data) {
alert(data)
})
}
function loadkeys(chal){
$.get('/admin/keys/' + chal, function(data){
$('#keys-chal').val(chal);
keys = $.parseJSON(JSON.stringify(data));
keys = keys['keys'];
$('#current-keys').empty();
for(x=0; x<keys.length; x++){
$('#current-keys').append($("<input class='current-key' type='text'>").val(keys[x].key));
$('#current-keys').append('<input type="radio" name="key_type['+x+']" value="0">Static');
$('#current-keys').append('<input type="radio" name="key_type['+x+']" value="1">Regex');
$('#current-keys input[name="key_type['+x+']"][value="'+keys[x].type+'"]').prop('checked',true);
}
});
}
function updatekeys(){
keys = [];
vals = [];
chal = $('#keys-chal').val()
$('.current-key').each(function(){
keys.push($(this).val());
})
$('#current-keys > input[name*="key_type"]:checked').each(function(){
vals.push($(this).val());
})
$.post('/admin/keys/'+chal, {'keys':keys, 'vals':vals, 'nonce': $('#nonce').val()})
loadchal(chal)
}
function loadtags(chal){
$('#tags-chal').val(chal)
$('#current-tags').empty()
$('#chal-tags').empty()
$.get('/admin/tags/'+chal, function(data){
tags = $.parseJSON(JSON.stringify(data))
tags = tags['tags']
for (var i = 0; i < tags.length; i++) {
tag = "<span class='secondary label chal-tag'><span>"+tags[i].tag+"</span><a name='"+tags[i].id+"'' class='delete-tag'>&#215;</a></span>"
$('#current-tags').append(tag)
};
$('.delete-tag').click(function(e){
deletetag(e.target.name)
$(e.target).parent().remove()
});
});
}
function deletetag(tagid){
$.post('/admin/tags/'+tagid+'/delete', {'nonce': $('#nonce').val()});
}
function deletechal(chalid){
$.post('/admin/chal/delete', {'nonce':$('#nonce').val(), 'id':chalid});
}
function updatetags(){
tags = [];
chal = $('#tags-chal').val()
$('#chal-tags > span > span').each(function(i, e){
tags.push($(e).text())
});
$.post('/admin/tags/'+chal, {'tags':tags, 'nonce': $('#nonce').val()})
loadchal(chal)
}
function loadfiles(chal){
$('#update-files > form').attr('action', '/admin/files/'+chal)
$.get('/admin/files/' + chal, function(data){
$('#files-chal').val(chal)
files = $.parseJSON(JSON.stringify(data));
files = files['files']
$('#current-files').empty()
for(x=0; x<files.length; x++){
filename = files[x].file.split('/')
filename = filename[filename.length - 1]
$('#current-files').append('<div data-alert class="alert-box info radius">'+'<a href=/'+files[x].file+'>'+filename+'</a><a href="#" onclick="deletefile('+chal+','+files[x].id+', $(this))" value="'+files[x].id+'" style="float:right;">Delete</a></div>')
}
});
}
function deletefile(chal, file, elem){
$.post('/admin/files/' + chal,{
'nonce': $('#nonce').val(),
'method': 'delete',
'file': file
}, function (data){
if (data == "1") {
elem.parent().remove()
}
});
}
function loadchals(){
$('#challenges').empty();
$.post("/admin/chals", {
'nonce': $('#nonce').val()
}, function (data) {
categories = [];
challenges = $.parseJSON(JSON.stringify(data));
for (var i = challenges['game'].length - 1; i >= 0; i--) {
if ($.inArray(challenges['game'][i].category, categories) == -1) {
categories.push(challenges['game'][i].category)
$('#challenges').append($('<tr id="' + challenges['game'][i].category.replace(/ /g,"-") + '"><td class="large-2"><h3>' + challenges['game'][i].category + '</h3></td></tr>'))
}
};
for (var i = categories.length - 1; i >= 0; i--) {
$('#new-challenge select').append('<option value="' + categories[i] + '">' + categories[i] + '</option>');
$('#update-challenge select').append('<option value="' + categories[i] + '">' + categories[i] + '</option>');
};
for (var i = 0; i <= challenges['game'].length - 1; i++) {
$('#' + challenges['game'][i].category.replace(/ /g,"-")).append($('<button class="radius" value="' + challenges['game'][i].id + '">' + challenges['game'][i].value + '</button>'));
};
$('#challenges button').click(function (e) {
loadchal(this.value);
loadkeys(this.value);
loadtags(this.value);
loadfiles(this.value);
});
$('tr').append('<button class="radius create-challenge"><i class="fa fa-plus"></i></button>');
$('.create-challenge').click(function (e) {
$('#new-chal-category').val($($(this).siblings()[0]).text().trim())
$('#new-chal-title').text($($(this).siblings()[0]).text().trim())
$('#new-challenge').foundation('reveal', 'open');
});
});
}
$('#submit-key').click(function (e) {
submitkey($('#chalid').val(), $('#answer').val())
});
$('#submit-keys').click(function (e) {
if (confirm('Updating keys. Are you sure?')){
updatekeys()
}
});
$('#submit-tags').click(function (e) {
updatetags()
});
$('#delete-chal > form').submit(function(e){
e.preventDefault();
$.post('/admin/chal/delete', $(this).serialize(), function(data){
console.log(data)
if (data){
loadchals();
$('#delete-chal').foundation('reveal', 'close');
}
else {
alert('There was an error');
}
})
});
$(".tag-insert").keyup(function (e) {
if (e.keyCode == 13) {
tag = $('.tag-insert').val()
tag = tag.replace(/'/g, '');
if (tag.length > 0){
tag = "<span class='secondary label chal-tag'><span>"+tag+"</span><a onclick='$(this).parent().remove()'>&#215;</a></span>"
$('#chal-tags').append(tag)
}
$('.tag-insert').val("")
}
});
$('.create-category').click(function (e) {
$('#new-category').foundation('reveal', 'open');
});
count = 1;
$('#create-key').click(function (e) {
$('#current-keys').append("<input class='current-key' type='text' placeholder='Blank Key'>");
$('#current-keys').append('<input type="radio" name="key_type['+count+']" value="0">Static');
$('#current-keys').append('<input type="radio" name="key_type['+count+']" value="1">Regex');
count++;
});
$(function(){
loadchals();
})

View File

@@ -1,159 +0,0 @@
function teamid (){
loc = window.location.pathname
return loc.substring(loc.lastIndexOf('/')+1, loc.length);
}
function cumulativesum (arr) {
var result = arr.concat();
for (var i = 0; i < arr.length; i++){
result[i] = arr.slice(0, i + 1).reduce(function(p, i){ return p + i; });
}
return result
}
function scoregraph () {
var times = []
var scores = []
var teamname = $('#team-id').text()
$.get('/admin/solves/'+teamid(), function( data ) {
solves = $.parseJSON(JSON.stringify(data));
solves = solves['solves']
if (solves.length == 0)
return
for (var i = 0; i < solves.length; i++) {
times.push(solves[i].time * 1000)
scores.push(solves[i].value)
};
scores = cumulativesum(scores)
times.unshift('x1')
times.push( Math.round(new Date().getTime()) )
scores.unshift('data1')
scores.push( scores[scores.length-1] )
var chart = c3.generate({
bindto: "#score-graph",
data: {
xs: {
"data1": 'x1',
},
columns: [
times,
scores,
],
type: "area",
labels: true,
names : {
data1: teamname
}
},
axis : {
x : {
tick: {
format: function (x) {
return moment(x).local().format('LLL');
}
},
},
y:{
label: {
text: 'Score'
}
}
}
});
});
}
function adjust_times () {
$.each($(".solve-time"), function(i, e){
$(e).text( moment(parseInt(e.innerText)).local().format('LLL') )
})
$(".solve-time").css('color', "#222")
}
function keys_percentage_graph(){
// Solves and Fails pie chart
$.get('/admin/fails/'+teamid(), function(data){
res = $.parseJSON(JSON.stringify(data));
solves = res['solves']
fails = res['fails']
total = solves+fails
if (total == 0)
return
var chart = c3.generate({
bindto: '#keys-pie-graph',
data: {
columns: [
['Solves', solves],
['Fails', fails],
],
type : 'donut'
},
color: {
pattern: ["#00D140", "#CF2600"]
},
donut: {
title: "Solves vs Fails",
}
});
});
}
function category_breakdown_graph(){
$.get('/admin/solves/'+teamid(), function(data){
solves = $.parseJSON(JSON.stringify(data));
solves = solves['solves']
if (solves.length == 0)
return
categories = []
for (var i = 0; i < solves.length; i++) {
categories.push(solves[i].category)
};
keys = categories.filter(function(elem, pos) {
return categories.indexOf(elem) == pos;
})
data = []
for (var i = 0; i < keys.length; i++) {
temp = []
count = 0
for (var x = 0; x < categories.length; x++) {
if (categories[x] == keys[i]){
count++
}
};
temp.push(keys[i])
temp.push(count)
data.push(temp)
};
var chart = c3.generate({
bindto: '#categories-pie-graph',
data: {
columns: data,
type : 'donut',
labels: true
},
donut: {
title: "Category Breakdown"
}
});
});
}
category_breakdown_graph()
keys_percentage_graph()
adjust_times()
scoregraph()

View File

@@ -1,105 +0,0 @@
#chal > form{
width: 400px;
margin: 0 auto;
}
.reveal-modal{
text-align: center;
}
.chal-desc{
text-align: left;
}
table{
width: 100%;
}
/*Not sure why foundation needs these two...*/
.top-bar input{
height: auto;
padding-top: 0.35rem;
padding-bottom: 0.35rem;
font-size: 0.75rem;
}
.top-bar .button{
padding-top: 0.45rem;
padding-bottom: 0.35rem;
margin-bottom: 0;
font-size: 0.75rem;
}
.dropdown{
background-color: #333 !important;
padding: 5px;
}
.dropdown button{
padding-top: 0.45rem;
padding-bottom: 0.35rem;
margin-bottom: 0;
font-size: 0.75rem;
}
#challenges button{
margin: 8px;
}
.row > h1{
text-align: center;
}
#challenges{
line-height: 66px;
}
#score-graph{
max-height: 400px;
}
.dropdown{
padding: 20px;
}
.dropdown input{
margin: 5px auto;
width: 95%;
}
.dropdown button{
margin: 10px auto;
width: 100%;
}
#keys-pie-graph{
width: 50%;
max-height: 330px;
float: left;
}
#categories-pie-graph{
width: 50%;
float: left;
max-height: 330px;
}
.logo{
margin: 0 auto;
width: 500px;
padding: 50px;
display: block;
}
@media only screen and (min-width: 40.063em){
.top-bar .dropdown{
display: block;
padding: 0 15px 5px;
width: 200% !important;
}
}
.top-bar input{
padding: 10px;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="157.416px" height="53.664px" viewBox="0 0 157.416 53.664" enable-background="new 0 0 157.416 53.664"
xml:space="preserve">
<polyline fill="#BC3F48" points="105.276,22.799 130.825,27.542 129.688,33.668 123.296,39.467 117.555,40.987 108.229,38.598
105.183,29.467 "/>
<g>
<path d="M0,22.919v-0.12C0,10.919,8.879,1.08,21.239,1.08c7.62,0,12.18,2.7,16.379,6.66l-3.24,3.48c-3.54-3.36-7.5-5.76-13.2-5.76
c-9.299,0-16.259,7.56-16.259,17.219v0.12c0,9.72,7.02,17.339,16.259,17.339c5.76,0,9.54-2.22,13.56-6.06l3.12,3.06
c-4.38,4.44-9.18,7.379-16.799,7.379C8.939,44.518,0,34.979,0,22.919z"/>
<path d="M52.438,6.18H38.339V1.8h32.999V6.18h-14.1v37.619h-4.8V6.18z"/>
<path d="M73.319,1.8h30.179V6.18H78.059v15h22.739v4.32H78.059v18.299h-4.74V1.8z"/>
<path d="M128.143,28.319v-0.12c0-7.14-5.459-11.939-11.219-11.939c-6,0-10.92,4.44-10.92,11.939v0.12c0,7.32,5.1,12,10.92,12
C122.684,40.318,128.143,35.458,128.143,28.319z M102.264,28.379v-0.12c0-10.139,6.38-15.139,13.82-15.139
c5.76,0,9.479,2.12,11.879,5.6V0h4.62v43.798h-4.62v-6.24c-2.52,3.72-6.18,5.9-11.879,5.9
C108.644,43.458,102.264,38.579,102.264,28.379z"/>
</g>
<path fill="#BC3F48" d="M145.362,7.49C139.198,0.592,133.308,0,133.308,0v29.406c0,0,4.568-6.611,13.09-8.43
c5.713-1.219,8.5-3.59,11.019-6.273C157.416,14.703,151.106,13.916,145.362,7.49"/>
<path fill="#FFFFFF" d="M119.754,30.537c0.293-1.602-0.769-3.137-2.37-3.426c-1.602-0.293-3.135,0.769-3.428,2.37
c-0.223,1.221,0.346,2.402,1.34,3.021l-1.872,3.388l4.569,0.834l-0.557-3.831C118.585,32.662,119.534,31.757,119.754,30.537"/>
<path fill="#F2F2F2" d="M132.585,51.798c0,1.029-6.787,1.865-15.16,1.865c-8.374,0-15.162-0.836-15.162-1.865
s6.788-1.865,15.162-1.865C125.798,49.933,132.585,50.769,132.585,51.798"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,270 +0,0 @@
//http://stackoverflow.com/a/2648463 - wizardry!
String.prototype.format = String.prototype.f = function() {
var s = this,
i = arguments.length;
while (i--) {
s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]);
}
return s;
};
function htmlentities(string) {
return $('<div/>').text(string).html();
}
var challenges;
function loadchal(id) {
obj = $.grep(challenges['game'], function (e) {
return e.id == id;
})[0]
window.location.hash = obj.name
$('#chal-window .chal-name').text(obj.name)
$('#chal-window .chal-desc').html(marked(obj.description, {'gfm':true, 'breaks':true}))
for (var i = 0; i < obj.files.length; i++) {
filename = obj.files[i].split('/')
filename = filename[filename.length - 1]
$('#chal-window .chal-desc').append("<a href='"+obj.files[i]+"'>"+filename+"</a><br/>")
};
$('#chal-window .chal-value').text(obj.value)
$('#chal-window .chal-category').text(obj.category)
$('#chal-window #chal-id').val(obj.id)
$('#chal-window .chal-solves').text(obj.solves + " solves")
$('#answer').val("")
$('pre code').each(function(i, block) {
hljs.highlightBlock(block);
});
$('#chal-window').foundation('reveal', 'open');
}
function loadchalbyname(chalname) {
obj = $.grep(challenges['game'], function (e) {
return e.name == chalname;
})[0]
window.location.hash = obj.name
$('#chal-window .chal-name').text(obj.name)
$('#chal-window .chal-desc').html(marked(obj.description, {'gfm':true, 'breaks':true}))
for (var i = 0; i < obj.files.length; i++) {
filename = obj.files[i].split('/')
filename = filename[filename.length - 1]
$('#chal-window .chal-desc').append("<a href='"+obj.files[i]+"'>"+filename+"</a><br/>")
};
$('#chal-window .chal-value').text(obj.value)
$('#chal-window .chal-category').text(obj.category)
$('#chal-window #chal-id').val(obj.id)
$('#chal-window .chal-solves').text(obj.solves + " solves")
$('#answer').val("")
$('pre code').each(function(i, block) {
hljs.highlightBlock(block);
});
$('#chal-window').foundation('reveal', 'open');
}
$("#answer").keyup(function(event){
if(event.keyCode == 13){
$("#submit-key").click();
}
});
function submitkey(chal, key, nonce) {
$.post("/chal/" + chal, {
key: key,
nonce: nonce
}, function (data) {
if (data == -1){
window.location="/login"
return
}
else if (data == 0){ // Incorrect key
$('#submit-key').text('Incorrect, sorry')
$('#submit-key').css('background-color', 'red')
$('#submit-key').prop('disabled', true)
}
else if (data == 1){ // Challenge Solved
$('#submit-key').text('Correct!')
$('#submit-key').css('background-color', 'green')
$('#submit-key').prop('disabled', true)
$('#chal-window .chal-solves').text( (parseInt($('#chal-window .chal-solves').text().split(" ")[0]) + 1 + " solves") )
}
else if (data == 2){ // Challenge already solved
$('#submit-key').text('You already solved this')
$('#submit-key').prop('disabled', true)
}
else if (data == 3){ // Keys per minute too high
$('#submit-key').text("You're submitting keys too fast. Slow down.")
$('#submit-key').css('background-color', '#e18728')
$('#submit-key').prop('disabled', true)
}
else if (data == 4){ // too many incorrect solves
$('#submit-key').text('Too many attempts.')
$('#submit-key').css('background-color', 'red')
$('#submit-key').prop('disabled', true)
}
marktoomanyattempts()
marksolves()
updatesolves()
setTimeout(function(){
$('#submit-key').text('Submit')
$('#submit-key').prop('disabled', false)
$('#submit-key').css('background-color', '#007095')
}, 3000);
})
}
function marksolves() {
$.get('/solves', function (data) {
solves = $.parseJSON(JSON.stringify(data));
for (var i = solves['solves'].length - 1; i >= 0; i--) {
id = solves['solves'][i].chalid
$('#challenges button[value="' + id + '"]').addClass('secondary')
$('#challenges button[value="' + id + '"]').css('opacity', '0.3')
};
if (window.location.hash.length > 0){
loadchalbyname(window.location.hash.substring(1))
}
});
}
function marktoomanyattempts() {
$.get('/maxattempts', function (data) {
maxattempts = $.parseJSON(JSON.stringify(data));
for (var i = maxattempts['maxattempts'].length - 1; i >= 0; i--) {
id = maxattempts['maxattempts'][i].chalid
$('#challenges button[value="' + id + '"]').addClass('secondary')
$('#challenges button[value="' + id + '"]').css('background-color', '#FF9999')
};
if (window.location.hash.length > 0){
loadchalbyname(window.location.hash.substring(1))
}
});
}
function updatesolves(){
$.get('/chals/solves', function (data) {
solves = $.parseJSON(JSON.stringify(data));
chals = Object.keys(solves);
for (var i = 0; i < chals.length; i++) {
obj = $.grep(challenges['game'], function (e) {
return e.name == chals[i];
})[0]
obj.solves = solves[chals[i]]
};
});
}
function getsolves(id){
$.get('/chal/'+id+'/solves', function (data) {
var teams = data['teams'];
var box = $('#chal-solves-names');
box.empty();
for (var i = 0; i < teams.length; i++) {
var id = teams[i].id;
var name = teams[i].name;
var date = moment(teams[i].date).local().format('LLL');
box.append('<tr><td><a href="/team/{0}">{1}</td><td>{2}</td></tr>'.format(id, htmlentities(name), date));
};
});
}
function loadchals() {
$.get("/chals", function (data) {
categories = [];
challenges = $.parseJSON(JSON.stringify(data));
for (var i = challenges['game'].length - 1; i >= 0; i--) {
challenges['game'][i].solves = 0
if ($.inArray(challenges['game'][i].category, categories) == -1) {
categories.push(challenges['game'][i].category)
$('#challenges').append($('<tr id="' + challenges['game'][i].category.replace(/ /g,"-") + '"><td class="large-2"><h4>' + challenges['game'][i].category + '</h4></td></tr>'))
}
};
for (var i = 0; i <= challenges['game'].length - 1; i++) {
$('#' + challenges['game'][i].category.replace(/ /g,"-")).append($('<button value="' + challenges['game'][i].id + '">' + challenges['game'][i].value + '</button>'));
};
updatesolves()
marktoomanyattempts()
marksolves()
$('#challenges button').click(function (e) {
loadchal(this.value);
});
});
}
$('#submit-key').click(function (e) {
submitkey($('#chal-id').val(), $('#answer').val(), $('#nonce').val())
});
$('.chal-solves').click(function (e) {
getsolves($('#chal-id').val())
});
// $.distint(array)
// Unique elements in array
$.extend({
distinct : function(anArray) {
var result = [];
$.each(anArray, function(i,v){
if ($.inArray(v, result) == -1) result.push(v);
});
return result;
}
});
function colorhash (x) {
color = ""
for (var i = 20; i <= 60; i+=20){
x += i
x *= i
color += x.toString(16)
};
return "#" + color.substring(0, 6)
}
$(document).on('close', '[data-reveal]', function () {
window.location.hash = ""
});
// function solves_graph() {
// $.get('/graphs/solves', function(data){
// solves = $.parseJSON(JSON.stringify(data));
// chals = []
// counts = []
// colors = []
// i = 1
// $.each(solves, function(key, value){
// chals.push(key)
// counts.push(value)
// colors.push(colorhash(i++))
// });
// });
// }
function update(){
$('#challenges').empty()
loadchals()
solves_graph()
}
$(function() {
loadchals()
// solves_graph()
});
setInterval(update, 300000);

View File

@@ -1,114 +0,0 @@
//http://stackoverflow.com/a/2648463 - wizardry!
String.prototype.format = String.prototype.f = function() {
var s = this,
i = arguments.length;
while (i--) {
s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]);
}
return s;
};
function htmlentities(string) {
return $('<div/>').text(string).html();
}
function updatescores () {
$.get('/scores', function( data ) {
teams = $.parseJSON(JSON.stringify(data));
$('#scoreboard > tbody').empty()
for (var i = 0; i < teams['teams'].length; i++) {
row = "<tr><td>{0}</td><td><a href='/team/{1}'>{2}</a></td><td>{3}</td></tr>".format(i+1, teams['teams'][i].id, htmlentities(teams['teams'][i].name), teams['teams'][i].score)
$('#scoreboard > tbody').append(row)
};
});
}
function cumulativesum (arr) {
var result = arr.concat();
for (var i = 0; i < arr.length; i++){
result[i] = arr.slice(0, i + 1).reduce(function(p, i){ return p + i; });
}
return result
}
function UTCtoDate(utc){
var d = new Date(0)
d.setUTCSeconds(utc)
return d;
}
function scoregraph () {
var times = []
var scores = []
$.get('/top/10', function( data ) {
scores = $.parseJSON(JSON.stringify(data));
scores = scores['scores']
if (Object.keys(scores).length == 0 ){
return;
}
$('#score-graph').show()
teams = Object.keys(scores)
xs_data = {}
column_data = []
for (var i = 0; i < teams.length; i++) {
times = []
team_scores = []
for (var x = 0; x < scores[teams[i]].length; x++) {
times.push(scores[teams[i]][x].time)
team_scores.push(scores[teams[i]][x].value)
};
team_scores = cumulativesum(team_scores)
times.unshift("x"+i)
// times.push( Math.round(new Date().getTime()/1000) )
team_scores.unshift(teams[i])
// team_scores.push( team_scores[team_scores.length-1] )
xs_data[teams[i]] = "x"+i
column_data.push(times)
column_data.push(team_scores)
};
var chart = c3.generate({
bindto: "#score-graph",
data: {
xs: xs_data,
columns: column_data,
type: "step"
// labels: true
},
axis : {
x : {
tick: {
count: 10,
format: function (x) {
return moment(x*1000).local().format('LLL');
}
},
},
y:{
label: {
text: 'Score'
}
}
},
zoom : {
enabled: true
}
});
});
}
function update(){
updatescores()
scoregraph()
}
setInterval(update, 300000); // Update scores every 5 minutes
scoregraph()

View File

@@ -1,168 +0,0 @@
function teamid (){
loc = window.location.pathname
return loc.substring(loc.lastIndexOf('/')+1, loc.length);
}
function colorhash (x) {
color = ""
for (var i = 20; i <= 60; i+=20){
x += i
x *= i
color += x.toString(16)
};
return "#" + color.substring(0, 6)
}
function cumulativesum (arr) {
var result = arr.concat();
for (var i = 0; i < arr.length; i++){
result[i] = arr.slice(0, i + 1).reduce(function(p, i){ return p + i; });
}
return result
}
function scoregraph () {
var times = []
var scores = []
var teamname = $('#team-id').text()
$.get('/solves/'+teamid(), function( data ) {
solves = $.parseJSON(JSON.stringify(data));
solves = solves['solves']
console.log(solves)
if (solves.length == 0)
return
for (var i = 0; i < solves.length; i++) {
times.push(solves[i].time * 1000)
scores.push(solves[i].value)
};
scores = cumulativesum(scores)
times.unshift('x1')
// times.push( Math.round(new Date().getTime()) )
scores.unshift('data1')
// scores.push( scores[scores.length-1] )
console.log(scores)
var chart = c3.generate({
bindto: "#score-graph",
data: {
xs: {
"data1": 'x1',
},
columns: [
times,
scores,
],
type: "area-step",
colors: {
data1: colorhash(teamid()),
},
labels: true,
names : {
data1: teamname
}
},
axis : {
x : {
tick: {
format: function (x) {
return moment(x).local().format('M/D h:mm:ss');
}
},
},
y:{
label: {
text: 'Score'
}
}
},
zoom : {
enabled: true
}
});
});
}
function keys_percentage_graph(){
// Solves and Fails pie chart
$.get('/fails/'+teamid(), function(data){
res = $.parseJSON(JSON.stringify(data));
solves = res['solves']
fails = res['fails']
total = solves+fails
if (total == 0)
return
var chart = c3.generate({
bindto: '#keys-pie-graph',
data: {
columns: [
['Solves', solves],
['Fails', fails],
],
type : 'donut'
},
color: {
pattern: ["#00D140", "#CF2600"]
},
donut: {
title: "Solves vs Fails",
}
});
});
}
function category_breakdown_graph(){
$.get('/solves/'+teamid(), function(data){
solves = $.parseJSON(JSON.stringify(data));
solves = solves['solves']
if (solves.length == 0)
return
categories = []
for (var i = 0; i < solves.length; i++) {
categories.push(solves[i].category)
};
keys = categories.filter(function(elem, pos) {
return categories.indexOf(elem) == pos;
})
data = []
for (var i = 0; i < keys.length; i++) {
temp = []
count = 0
for (var x = 0; x < categories.length; x++) {
if (categories[x] == keys[i]){
count++
}
};
temp.push(keys[i])
temp.push(count)
data.push(temp)
};
var chart = c3.generate({
bindto: '#categories-pie-graph',
data: {
columns: data,
type : 'donut',
labels: true
},
donut: {
title: "Category Breakdown",
}
});
});
}
category_breakdown_graph()
keys_percentage_graph()
scoregraph()