blob: 6835c8c491a69f41b11bd105934ff4373bd437c7 [file] [log] [blame]
// Generated by CoffeeScript 1.9.3
var API, APIVERSION, Chart, HTML, Row, WarbleLogin, WarbleLoginCallback, Widget, aSourceTypes, addSourceType, addSources, addorguser, addsources, affiliate, affiliation, affiliationWizard, altemail, app, badModal, bio, chartOnclick, chartToSvg, chartWrapperButtons, charts_donutchart, charts_gaugechart, charts_linechart, charts_linechart_stacked, charts_linked, charts_radarchart, ciexplorer, clientTypes, clientlist, cog, comShow, comstat, copyCSS, currentSources, dataTable, datepicker, datepickers, defaultOrgChanged, deleteNode, deletesource, doResetPass, donut, downloadBlob, explorer, fScreen, factors, fetch, fetchPhonebook, filterPerson, filterView, findWidget, forumexplorer, gauge, genColors, get, getResetToken, getSourceType, globArgs, hsl2rgb, imexplorer, inviteMember, isArray, isHash, issueexplorer, jsondump, keyValueForm, linechart, loadPageWidgets, logexplorer, login, mailexplorer, make5, makeClientType, makeOrg, manageviews, memberInvited, membershipList, messages, mk, modifyNode, multiviewexplorer, mvp, newview, nodeStatusSort, nodeVal, orgCreated, orgadmin, orglist, pageID, paragraph, patch, phonebook_cached, post, postPublishLink, preferences, pubWidget, publishWidget, publisher, publisherPublic, publisherWidget, put, pwReset, quickColors, radar, radarIndicators, rcollate, redirs, relationship, remail, remorguser, removeMember, renderAccountInfo, renderPhonebook, report, resetpw, rmview, rotateTable, rowZ, saveNodeValue, savedNodeValue, saveprefs, saveview, sendEmail, set, setDefaultOrg, setupPage, setupPhonebook, showClientType, showMore, showType, signout, signup, snap, sourceAdded, sourceTypes, sourceadd, sourceexplorer, sourcelist, sourceret, st, stackChart, subFilter, subFilterGlob, swi, switchChartType, tagList, theme, toFullscreen, toNormal, top5, treemap, trend, trendBox, txt, updateTimeseriesWidgets, updateWidgets, userAccount, validateLogin, validateSignup, viewJS, viewexplorer, widgetCache, widgetexplorer, worldmap, xdelete, xxCharts,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
signup = function(form) {
var err;
err = null;
if (form.name.value.length < 2) {
err = "Please enter your full name";
} else if (form.screenname.value.length < 1) {
err = "Please enter a screen name";
} else if (form.email.value.length < 6 || !form.email.value.match(/^[^\r\n\s @]+@[^\r\n\s @]+$/)) {
err = "Please enter a valid email address";
} else if (form.password.value.length < 1 || form.password.value !== form.password2.value) {
err = "Please enter your password and make sure it matches the re-type";
}
if (err) {
document.getElementById('signupmsg').innerHTML = "<h2>Error: " + err + "</h2>";
return false;
} else {
document.getElementById('signupmsg').innerHTML = "Creating account, hang on..!";
post('user-signup', {
action: 'create',
name: form.name.value,
password: form.password.value,
screenname: form.screenname.value,
email: form.email.value,
code: form.code.value
}, null, validateSignup);
return false;
}
};
validateSignup = function(json, state) {
if (json.created) {
return document.getElementById('signupmsg').innerHTML = "<span style='color: #060;'>Account created! Please check your inbox for verification instructions.</span>";
} else {
return document.getElementById('signupmsg').innerHTML = "<h2 style='font-size: 2rem; color: #830;'>Error: " + json.message + "</h2>";
}
};
login = function(form) {
if (form.username.value.length > 5 && form.password.value.length > 0) {
cog(document.getElementById('loginmsg'));
post('account', {
username: form.username.value,
password: form.password.value,
api: form.api.value
}, null, validateLogin);
}
return false;
};
validateLogin = function(json, state) {
if (json.loginRequired) {
return document.getElementById('loginmsg').innerHTML = json.error;
} else {
if (json.apiversion && json.apiversion >= 3) {
if (document.referrer && document.referrer.match(/https:\/\/(?:www)?\.snoot\.io\/dashboard/i)) {
return location.href = document.referrer;
} else {
return location.href = "/dashboard.html?page=default";
}
} else {
return location.href = "/api2.html?page=default";
}
}
};
doResetPass = function() {
var newpass, rtoken;
rtoken = get('rtoken').value;
newpass = get('newpass').value;
post('account', {
remail: remail,
rtoken: rtoken,
newpass: newpass
}, null, pwReset);
return false;
};
remail = "";
pwReset = function() {
return get('resetform').innerHTML = "Assuming you entered the right token, your password has now been reset!. <a href='login.html'>Log in</a>.";
};
getResetToken = function(json, state) {
var btn, form, newpw, p, token;
form = get('resetform');
form.innerHTML = "";
p = mk('p', {}, "A reset token has been sent to your email address. Please enter the reset token and your new preferred password below:");
app(form, p);
token = mk('input', {
type: 'text',
placeholder: 'Reset token',
autocomplete: 'off',
name: 'rtoken',
id: 'rtoken'
});
newpw = mk('input', {
type: 'password',
placeholder: 'New passord',
autocomplete: 'off',
name: 'newpass',
id: 'newpass'
});
app(form, token);
app(form, mk('br'));
app(form, newpw);
app(form, mk('br'));
btn = mk('input', {
type: 'button',
onclick: 'doResetPass()',
value: 'Reset your password'
});
form.setAttribute("onsubmit", "return doResetPass();");
return app(form, btn);
};
resetpw = function() {
var email;
email = get('email').value;
remail = email;
post('account', {
reset: email
}, null, getResetToken);
return false;
};
charts_donutchart = function(obj, data, maxN) {
var a, asDataArray, c, config, el, k, len, narr, others, q, v;
a = 0;
asDataArray = [];
if (data.counts) {
data = data.counts;
}
for (k in data) {
v = data[k];
asDataArray.push([k, v]);
a++;
}
asDataArray.sort((function(_this) {
return function(a, b) {
return b[1] - a[1];
};
})(this));
if (maxN && asDataArray.length > maxN) {
others = 0;
narr = asDataArray.slice(maxN, asDataArray.length - maxN);
asDataArray = asDataArray.slice(0, maxN);
for (q = 0, len = narr.length; q < len; q++) {
el = narr[q];
others += el[1];
}
asDataArray.push(['Others', others]);
asDataArray.sort((function(_this) {
return function(a, b) {
return b[1] - a[1];
};
})(this));
}
config = {
bindto: obj,
data: {
columns: asDataArray,
type: 'donut'
},
donut: {
width: 50
},
color: {
pattern: genColors(a + 1, 0.55, 0.475, true)
},
tooltip: {
format: {
value: (function(_this) {
return function(val) {
return d3.format(',')(val);
};
})(this)
}
}
};
c = c3.generate(config);
return [c, config];
};
charts_gaugechart = function(obj, data) {
var c, config;
if (data.gauge) {
data = data.gauge;
}
config = {
bindto: obj,
data: {
columns: [[data.key || 'value', data.value || data]],
type: 'gauge'
},
gauge: {
min: 0,
max: 100
},
color: {
pattern: ['#FF0000', '#F97600', '#F6C600', '#60B044'],
threshold: {
values: [25, 55, 80, 100]
}
},
tooltip: {
format: {
value: (function(_this) {
return function(val) {
return d3.format(',')(val);
};
})(this)
}
}
};
c = c3.generate(config);
return [c, config];
};
gauge = function(json, state) {
var gaugeChart, lmain;
lmain = new HTML('div');
state.widget.inject(lmain, true);
if (json.gauge && json.gauge.text) {
lmain.inject(new HTML('p', {}, json.gauge.text));
}
return gaugeChart = new Chart(lmain, 'gauge', json);
};
charts_linechart_stacked = (function(_this) {
return function(o, d) {
return charts_linechart(o, d, 'area-spline', true);
};
})(this);
charts_linechart = function(obj, data, options) {
var a, aa, asDataArray, asList, asTypes, axisData, c, config, dataPoint, dateFormat, el, k, key, len, len1, len2, linetype, ndate, q, ref, ref1, stacked, tmpArray, ts, u, v, val, xts, xx;
linetype = options && options.linetype ? options.linetype : 'line';
stacked = options && options.stacked ? options.stacked : false;
if (options && options.filled && linetype === "line") {
linetype = "area-spline";
}
a = 0;
asDataArray = [];
asList = [];
asTypes = [];
axisData = {
y: {
tick: {
format: d3.format('s')
}
}
};
if (data.timeseries && isArray(data.timeseries)) {
dateFormat = '%Y-%m-%d';
if (data.histogram && data.histogram === 'quarterly') {
dateFormat = (function(_this) {
return function(x) {
return "Q" + [1, 2, 3, 4][Math.floor(x.getMonth() / 3)] + ", " + x.getFullYear();
};
})(this);
}
if (data.histogram && data.histogram === 'monthly') {
dateFormat = '%b, %Y';
}
if (data.interval && data.interval === 'hour') {
dateFormat = '%Y-%m-%d %H:%M';
}
if (data.histogram && data.histogram === 'yearly') {
dateFormat = '%Y';
}
ts = [['x']];
xts = {};
ref = data.timeseries;
for (q = 0, len = ref.length; q < len; q++) {
el = ref[q];
axisData.x = {
type: 'timeseries',
tick: {
format: dateFormat
}
};
ndate = new Date(parseInt(el.date) * 1000.0);
ts[0].push(ndate);
for (k in el) {
v = el[k];
if (k !== 'date') {
if (k === 'deletions') {
v = -v;
}
if (xts[k] === void 0) {
xts[k] = [];
}
xts[k].push(v);
}
}
}
for (key in xts) {
val = xts[key];
xx = [key];
for (u = 0, len1 = val.length; u < len1; u++) {
el = val[u];
xx.push(el);
}
ts.push(xx);
asList.push(key);
asTypes[key] = linetype;
a++;
}
asDataArray = ts;
} else {
ref1 = data.counts;
for (k in ref1) {
v = ref1[k];
asList.push(k);
asTypes[k] = 'bar';
tmpArray = [k];
if (isArray(v)) {
for (aa = 0, len2 = v.length; aa < len2; aa++) {
dataPoint = v[aa];
tmpArray.push(dataPoint);
}
} else {
tmpArray.push(v);
}
asDataArray.push(tmpArray);
a++;
}
}
config = {
bindto: obj,
data: {
x: data.timeseries ? 'x' : null,
columns: asDataArray,
types: asTypes,
groups: stacked ? [asList] : [[]]
},
axis: axisData,
color: {
pattern: genColors(a + 1, 0.55, 0.475, true)
},
subchart: {
show: false
},
point: {
show: false
},
bar: {
width: {
ratio: 0.7
}
},
tooltip: {
format: {
value: (function(_this) {
return function(val) {
return d3.format(',')(val);
};
})(this)
}
}
};
c = c3.generate(config);
return [c, config];
};
charts_linked = function(obj, nodes, links, options) {
var avg, bb, defs, edges, force, g, gatherTargets, lTargets, lcolors, licolors, link, linked_zoom, lla, llcolors, llheight, llwidth, node, svg, tooltip, uptop, x;
llcolors = genColors(nodes.length + 1, 0.55, 0.475, true);
licolors = genColors(nodes.length + 1, 0.375, 0.35, true);
lla = 0;
obj.className = "chartChart linkedChart";
svg = d3.select(obj).append("svg").attr("width", "100%").attr("height", "600");
g = svg.append("g");
bb = obj.getBoundingClientRect();
llwidth = bb.width;
llheight = Math.max(600, bb.height);
tooltip = d3.select("body").append("div").attr("class", "link_tooltip").style("opacity", 0);
avg = links.length / nodes.length;
force = d3.layout.force().gravity(0.015).distance(llheight / 8).charge(-200 / Math.log10(nodes.length)).linkStrength(0.2 / avg).size([llwidth, llheight]);
edges = [];
links.forEach(function(e) {
var sourceNode, targetNode;
sourceNode = nodes.filter((function(_this) {
return function(n) {
return n.id === e.source;
};
})(this))[0];
targetNode = nodes.filter((function(_this) {
return function(n) {
return n.id === e.target;
};
})(this))[0];
return edges.push({
source: sourceNode,
target: targetNode,
s: e.source,
value: e.value,
name: e.name,
tooltip: e.tooltip
});
});
force.nodes(nodes).links(edges).start();
lcolors = {};
nodes.forEach(function(e) {
return lcolors[e.id] = licolors[lla++];
});
lla = 0;
link = g.selectAll(".link").data(edges).enter().append("path").attr("class", "link_link").attr("id", (function(_this) {
return function(d) {
return d.name;
};
})(this)).attr("data-source", (function(_this) {
return function(d) {
return d.source.id;
};
})(this)).attr("data-target", (function(_this) {
return function(d) {
return d.target.id;
};
})(this)).attr("style", (function(_this) {
return function(d) {
return "stroke-width: " + d.value + "; stroke: " + lcolors[d.s] + ";";
};
})(this)).on("mouseover", function(d) {
if (d.tooltip) {
tooltip.transition().duration(100).style("opacity", .9);
return tooltip.html(("<b>" + d.name + ":</b><br/>") + d.tooltip.replace("\n", "<br/>")).style("left", (d3.event.pageX + 20) + "px").style("top", (d3.event.pageY - 28) + "px");
}
}).on("mouseout", function(d) {
d3.select(this).style("stroke-opacity", "0.375");
return tooltip.transition().duration(200).style("opacity", 0);
});
defs = svg.append("defs");
nodes.forEach(function(n) {
if (n.gravatar) {
return defs.append("pattern").attr("id", "gravatar-" + n.id).attr("patternUnits", "userSpaceOnUse").attr("width", n.size * 2).attr("height", n.size * 2).attr("x", n.size).attr("y", n.size).append("image").attr("width", n.size * 2).attr("height", n.size * 2).attr("x", "0").attr("y", "0").attr("xlink:href", "https://secure.gravatar.com/avatar/" + n.gravatar + ".png?d=identicon");
} else {
return n.gravatar = false;
}
});
node = g.selectAll(".node").data(nodes).enter().append("g").attr("class", "link_node").attr("data-source", (function(_this) {
return function(d) {
return d.id;
};
})(this)).call(force.drag);
lTargets = [];
gatherTargets = function(d, e) {
if (e.source === d || e.target === d) {
lTargets.push(e.source.id);
lTargets.push(e.target.id);
return true;
}
return false;
};
uptop = svg.append("g");
x = null;
node.append("circle").attr("class", "link_node").attr("data-source", (function(_this) {
return function(d) {
return d.id;
};
})(this)).attr("data-color", (function(_this) {
return function(d) {
lla++;
return llcolors[lla - 1];
};
})(this)).style("fill", function(d) {
if (d.gravatar) {
return "url(#gravatar-" + d.id + ")";
} else {
return "" + (d3.select(this).attr('data-color'));
}
}).style("stroke", "black").attr("r", (function(_this) {
return function(d) {
return d.size;
};
})(this)).on("mouseover", function(d) {
lTargets.push(d.id);
d3.selectAll("path").style("stroke-opacity", "0.075");
d3.selectAll("path").filter((function(_this) {
return function(e) {
return gatherTargets(d, e);
};
})(this)).style("stroke-opacity", "1").style("z-index", "20");
d3.selectAll("path").filter((function(_this) {
return function(e) {
return e.source === d || e.target;
};
})(this)).each((function(_this) {
return function(o) {
x = d3.select(_this).insert("g", ":first-child").style("stroke", "red !important");
return x.append("use").attr("xlink:href", "#" + o.name);
};
})(this));
d3.selectAll("circle").filter((function(_this) {
return function(e) {
var ref;
return ref = e.id, indexOf.call(lTargets, ref) < 0;
};
})(this)).style("opacity", "0.2");
return d3.selectAll("text").filter((function(_this) {
return function(e) {
var ref;
return ref = e.id, indexOf.call(lTargets, ref) < 0;
};
})(this)).style("opacity", "0.2");
}).on("mouseout", function(d) {
lTargets = [];
if (x) {
x.selectAll("*").remove();
}
d3.selectAll("circle").style("opacity", null);
d3.selectAll("text").style("opacity", null);
return d3.selectAll("path").style("stroke-opacity", null);
});
node.append("a").attr("href", (function(_this) {
return function(d) {
if (!d.gravatar) {
return "#";
} else {
return "contributors.html?page=biography&email=" + d.id;
}
};
})(this)).append("text").attr("dx", 13).attr("dy", ".35em").text((function(_this) {
return function(d) {
return d.name;
};
})(this)).on("mouseover", function(d) {
if (d.tooltip) {
tooltip.transition().duration(100).style("opacity", .9);
return tooltip.html(("<b>" + d.name + ":</b><br/>") + d.tooltip.replace("\n", "<br/>")).style("left", (d3.event.pageX + 20) + "px").style("top", (d3.event.pageY - 28) + "px");
}
}).on("mouseout", function(d) {
return tooltip.transition().duration(200).style("opacity", 0);
});
force.on("tick", function() {
link.attr("d", function(d) {
var dr, dx, dy;
dx = d.target.x - d.source.x;
dy = d.target.y - d.source.y;
dr = Math.sqrt(dx * dx + dy * dy);
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
});
node.attr("cx", (function(_this) {
return function(d) {
return d.x = Math.max(d.size, Math.min(llwidth - d.size, d.x));
};
})(this)).attr("cy", (function(_this) {
return function(d) {
return d.y = Math.max(d.size, Math.min(llheight - d.size, d.y));
};
})(this));
return node.attr("transform", (function(_this) {
return function(d) {
return "translate(" + d.x + "," + d.y + ")";
};
})(this));
});
linked_zoom = function() {
var isShift;
isShift = !!window.event.shiftKey;
if (isShift) {
return g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
} else {
return g.attr("transform", "scale(" + d3.event.scale + ")");
}
};
svg.call(d3.behavior.zoom().center([llwidth / 2, llheight / 2]).scaleExtent([0.333, 4]).on("zoom", linked_zoom));
return [
{
svg: svg,
parent: obj,
force: force,
config: {},
resize: function(conf) {
var ns;
ns = "";
if (conf.height) {
ns += "height: " + conf.height + "px; ";
}
if (conf.width) {
ns += "width: " + conf.width + "px; ";
}
svg.attr("style", ns);
llwidth = parseInt(svg.style("width"));
llheight = parseInt(svg.style("height"));
force.size([llwidth, llheight]).distance(llheight / 4);
return force.nodes(nodes).links(edges).start();
}
}, {
linked: true
}
];
};
charts_radarchart = function(obj, data, options) {
var Format, LegendOptions, aa, ab, axes, axis, cfg, d, el, g, i, indicator, j, legend, len, len1, levelFactor, li, q, radius, rect, ref, ref1, ref2, ref3, series, tooltip, total, u;
cfg = {
radius: 5,
w: 360,
h: 360,
factor: 1,
factorLegend: .85,
levels: 4,
maxValue: 100,
radians: 2 * Math.PI,
opacityArea: 0.5,
ToRight: 5,
TranslateX: 30,
TranslateY: 30,
ExtraWidthX: 200,
ExtraWidthY: 100,
color: genColors(16, 0.55, 0.475, true)
};
LegendOptions = [];
d = data;
if (data.indicators && data.data) {
d = [];
ref = data.data;
for (i = q = 0, len = ref.length; q < len; i = ++q) {
el = ref[i];
li = [];
LegendOptions.push(el.name);
ref1 = data.indicators;
for (j = u = 0, len1 = ref1.length; u < len1; j = ++u) {
indicator = ref1[j];
li.push({
axis: indicator,
value: el.value[j]
});
}
d.push(li);
}
}
cfg.maxValue = Math.max(cfg.maxValue, d3.max(d, (function(_this) {
return function(i) {
return d3.max(i.map(function(o) {
return o.value;
}));
};
})(this)));
axes = d[0].map((function(_this) {
return function(i, j) {
return i.axis;
};
})(this));
total = axes.length;
radius = cfg.factor * Math.min(cfg.w / 2, cfg.h / 2);
Format = (function(_this) {
return function(edge) {
return Math.floor((edge / 24) + 0.5) + "↑ (" + (Math.pow(5, edge / 24)).pretty() + ")";
};
})(this);
d3.select(obj).select("svg").remove();
rect = obj.getBoundingClientRect();
g = d3.select(obj).append("svg").attr("preserveAspectRatio", "xMinYMin meet").attr("viewBox", "0 0 1000 500").append("g").attr("transform", "translate(" + cfg.TranslateX + "," + cfg.TranslateY + ")");
for (j = aa = 0, ref2 = cfg.levels; 0 <= ref2 ? aa < ref2 : aa > ref2; j = 0 <= ref2 ? ++aa : --aa) {
levelFactor = cfg.factor * radius * ((j + 1) / cfg.levels);
g.selectAll(".levels").data(axes).enter().append("svg:line").attr("x1", (function(_this) {
return function(d, i) {
return levelFactor * (1 - cfg.factor * Math.sin(i * cfg.radians / total));
};
})(this)).attr("y1", (function(_this) {
return function(d, i) {
return levelFactor * (1 - cfg.factor * Math.cos(i * cfg.radians / total));
};
})(this)).attr("x2", (function(_this) {
return function(d, i) {
return levelFactor * (1 - cfg.factor * Math.sin((i + 1) * cfg.radians / total));
};
})(this)).attr("y2", (function(_this) {
return function(d, i) {
return levelFactor * (1 - cfg.factor * Math.cos((i + 1) * cfg.radians / total));
};
})(this)).attr("class", "line").style("stroke", "grey").style("stroke-opacity", "0.75").style("stroke-width", "0.3px").attr("transform", "translate(" + (cfg.w / 2 - levelFactor) + ", " + (cfg.h / 2 - levelFactor) + ")");
}
for (j = ab = 0, ref3 = cfg.levels; 0 <= ref3 ? ab < ref3 : ab > ref3; j = 0 <= ref3 ? ++ab : --ab) {
levelFactor = cfg.factor * radius * ((j + 1) / cfg.levels);
g.selectAll(".levels").data([1]).enter().append("svg:text").attr("x", (function(_this) {
return function(d) {
return levelFactor * (1 - cfg.factor * Math.sin(0));
};
})(this)).attr("y", (function(_this) {
return function(d) {
return levelFactor * (1 - cfg.factor * Math.cos(0));
};
})(this)).attr("class", "legend").style("font-family", "sans-serif").style("font-size", "10px").attr("transform", "translate(" + (cfg.w / 2 - levelFactor + cfg.ToRight) + ", " + (cfg.h / 2 - levelFactor) + ")").attr("fill", "#737373").text(Format((j + 1) * cfg.maxValue / cfg.levels));
}
series = 0;
axis = g.selectAll(".axis").data(axes).enter().append("g").attr("class", "axis");
axis.append("line").attr("x1", cfg.w / 2).attr("y1", cfg.h / 2).attr("x2", (function(_this) {
return function(d, i) {
return cfg.w / 2 * (1 - cfg.factor * Math.sin(i * cfg.radians / total));
};
})(this)).attr("y2", (function(_this) {
return function(d, i) {
return cfg.h / 2 * (1 - cfg.factor * Math.cos(i * cfg.radians / total));
};
})(this)).attr("class", "line").style("stroke", "grey").style("stroke-width", "1px");
axis.append("text").attr("class", "legend").text((function(_this) {
return function(d) {
return d;
};
})(this)).style("font-family", "sans-serif").style("font-size", "11px").attr("text-anchor", "middle").attr("dy", "1.5em").attr("transform", (function(_this) {
return function(d, i) {
return "translate(0, -10)";
};
})(this)).attr("x", (function(_this) {
return function(d, i) {
return cfg.w / 2 * (1 - cfg.factorLegend * Math.sin(i * cfg.radians / total)) - 60 * Math.sin(i * cfg.radians / total);
};
})(this)).attr("y", (function(_this) {
return function(d, i) {
return cfg.h / 2 * (1 - Math.cos(i * cfg.radians / total)) - 20 * Math.cos(i * cfg.radians / total);
};
})(this));
d.forEach(function(y, x) {
var dataValues;
dataValues = [];
g.selectAll(".nodes").data(y, function(j, i) {
return dataValues.push([cfg.w / 2 * (1 - (parseFloat(Math.max(j.value, 0)) / cfg.maxValue) * cfg.factor * Math.sin(i * cfg.radians / total)), cfg.h / 2 * (1 - (parseFloat(Math.max(j.value, 0)) / cfg.maxValue) * cfg.factor * Math.cos(i * cfg.radians / total))]);
});
dataValues.push(dataValues[0]);
g.selectAll(".area").data([dataValues]).enter().append("polygon").attr("class", "radar-chart-serie" + series).style("stroke-width", "2px").style("stroke", cfg.color[series]).attr("points", function(d) {
var ac, len2, pt, str;
str = "";
for (ac = 0, len2 = d.length; ac < len2; ac++) {
pt = d[ac];
str = str + pt[0] + "," + pt[1] + " ";
}
return str;
}).style("fill", (function(_this) {
return function(j, i) {
return cfg.color[series];
};
})(this)).style("fill-opacity", cfg.opacityArea).on('mouseover', function(d) {
var z;
z = "polygon." + d3.select(this).attr("class");
g.selectAll("polygon").transition(200).style("fill-opacity", 0.1);
return g.selectAll(z).transition(200).style("fill-opacity", .7);
}).on('mouseout', function() {
return g.selectAll("polygon").transition(200).style("fill-opacity", cfg.opacityArea);
});
return series++;
});
series = 0;
d.forEach(function(y, x) {
g.selectAll(".nodes").data(y).enter().append("svg:circle").attr("class", "radar-chart-serie" + series).attr('r', cfg.radius).attr("alt", (function(_this) {
return function(j) {
return Math.max(j.value, 0);
};
})(this)).attr("cx", function(j, i) {
var dataValues;
dataValues = dataValues || [];
dataValues.push([cfg.w / 2 * (1 - (parseFloat(Math.max(j.value, 0)) / cfg.maxValue) * cfg.factor * Math.sin(i * cfg.radians / total)), cfg.h / 2 * (1 - (parseFloat(Math.max(j.value, 0)) / cfg.maxValue) * cfg.factor * Math.cos(i * cfg.radians / total))]);
return cfg.w / 2 * (1 - (Math.max(j.value, 0) / cfg.maxValue) * cfg.factor * Math.sin(i * cfg.radians / total));
}).attr("cy", function(j, i) {
return cfg.h / 2 * (1 - (Math.max(j.value, 0) / cfg.maxValue) * cfg.factor * Math.cos(i * cfg.radians / total));
}).attr("data-id", (function(_this) {
return function(j) {
return j.axis;
};
})(this)).style("fill", cfg.color[series]).style("fill-opacity", .9).on('mouseover', function(d) {
var newX, newY, z;
newX = parseFloat(d3.select(this).attr('cx')) - 10;
newY = parseFloat(d3.select(this).attr('cy')) - 5;
tooltip.attr('x', newX).attr('y', newY).text(Format(d.value)).transition(200).style('opacity', 1);
z = "polygon." + d3.select(this).attr("class");
g.selectAll("polygon").transition(200).style("fill-opacity", 0.1);
return g.selectAll(z).transition(200).style("fill-opacity", .7);
}).on('mouseout', function() {
tooltip.transition(200).style('opacity', 0);
return g.selectAll("polygon").transition(200).style("fill-opacity", cfg.opacityArea);
}).append("svg:title").text((function(_this) {
return function(j) {
return Math.max(j.value, 0);
};
})(this));
return series++;
});
tooltip = g.append('text').style('opacity', 0).style('font-family', 'sans-serif').style('font-size', '13px');
legend = g.append("g").attr("class", "legend").attr("height", 100).attr("width", 200).attr('transform', 'translate(90,20)');
legend.selectAll('rect').data(LegendOptions).enter().append("rect").attr("x", cfg.w - 65).attr("y", (function(_this) {
return function(d, i) {
return i * 20;
};
})(this)).attr("width", 10).attr("height", 10).style("fill", (function(_this) {
return function(d, i) {
return cfg.color[i];
};
})(this));
legend.selectAll('text').data(LegendOptions).enter().append("text").attr("x", cfg.w - 52).attr("y", (function(_this) {
return function(d, i) {
return i * 20 + 9;
};
})(this)).attr("font-size", "11px").attr("fill", "#737373").text((function(_this) {
return function(d) {
return d;
};
})(this));
g.resize = function() {
return true;
};
return [g, {}];
};
chartWrapperButtons = {
generic: [
{
id: 'download',
icon: 'fa fa-download',
title: "Export Image",
onclick: function(o) {
return chartToSvg(o);
}
}, {
id: 'svg',
icon: 'fa fa-archive',
title: "Export as SVG",
onclick: function(o) {
return chartToSvg(o, true);
}
}, {
id: 'dataview',
icon: 'fa fa-book',
title: "Data View",
onclick: function(o) {
return dataTable(o);
}
}, {
id: 'fullscreen',
icon: 'fa fa-plus-square',
title: "Switch to fullscreen",
onclick: function(o) {
return fScreen(o);
}
}
],
line: [
{
icon: 'fa fa-bar-chart',
title: "Show as Bar Chart",
onclick: function(o) {
return switchChartType(o, o.config, 'bar');
}
}, {
icon: 'fa fa-line-chart',
title: "Show as Line Chart",
onclick: function(o) {
return switchChartType(o, o.config, 'line');
}
}, {
icon: 'fa fa-area-chart',
title: "Show as Area Chart",
onclick: function(o) {
return switchChartType(o, o.config, 'area-spline');
}
}, {
icon: 'fa fa-bars',
title: "Stack values",
onclick: function(o) {
return stackChart(o, o.config, o.chartobj);
}
}, {
icon: 'fa fa-object-ungroup',
title: "Show sub-chart",
onclick: function(o) {
o.config.subchart = {
show: o.config.subchart && o.config.subchart.show ? false : true
};
return o.chartobj = c3.generate(o.config);
}
}
]
};
xxCharts = {};
fScreen = function(o) {
var bb, xclass;
xclass = o.main.getAttribute('class');
if (!xclass.match('chartModal')) {
o.main.className = "chartModal chartWrapper";
o.main.style.minHeight = "100% !important";
o.buttons['fullscreen'].childNodes[0].className = 'fa fa-minus-square';
o.buttons['fullscreen'].title = "Restore window";
o.main.childNodes[2].style.minHeight = (window.innerHeight - 60) + "px";
if (o.config.donut) {
o.config.donut.width = 120;
switchChartType(o, o.config, 'donut');
}
if (o.config.linked) {
bb = o.main.childNodes[2].getBoundingClientRect();
o.chartobj.resize({
height: bb.height
});
} else {
o.chartobj.resize({
height: 720
});
}
} else {
o.main.className = "chartWrapper";
o.main.childNodes[2].style.minHeight = "";
o.buttons['fullscreen'].title = "Switch to fullscreen";
o.buttons['fullscreen'].childNodes[0].className = 'fa fa-plus-square';
if (o.config.donut) {
o.config.donut.width = 50;
switchChartType(o, o.config, 'donut');
}
if (o.config.linked) {
bb = o.main.childNodes[2].getBoundingClientRect();
o.chartobj.resize({
height: bb.height
});
} else {
o.chartobj.resize({
height: 240
});
}
}
return true;
};
copyCSS = function(destination, source) {
var cd, child, containerElements, q, ref, ref1, results, st, style;
containerElements = ["svg", "g"];
if (destination.childNodes.length > 0) {
results = [];
for (cd = q = 0, ref = destination.childNodes.length - 1; 0 <= ref ? q <= ref : q >= ref; cd = 0 <= ref ? ++q : --q) {
child = destination.childNodes[cd];
if ((ref1 = child.tagName, indexOf.call(containerElements, ref1) >= 0)) {
copyCSS(child, source.childNodes[cd]);
continue;
}
style = source.childNodes[cd].currentStyle || window.getComputedStyle(source.childNodes[cd]);
if (style === "undefined" || style === null) {
continue;
}
results.push((function() {
var len, results1, u;
results1 = [];
for (u = 0, len = style.length; u < len; u++) {
st = style[u];
results1.push(child.style.setProperty(st, style.getPropertyValue(st)));
}
return results1;
})());
}
return results;
}
};
downloadBlob = function(name, uri) {
var blob, e, saveLink, url;
if (navigator.msSaveOrOpenBlob) {
return navigator.msSaveOrOpenBlob(uriToBlob(uri), name);
} else {
saveLink = document.createElement('a');
saveLink.download = name;
saveLink.style.display = 'none';
document.body.appendChild(saveLink);
try {
blob = uriToBlob(uri);
url = URL.createObjectURL(blob);
saveLink.href = url;
saveLink.onclick = function() {
return requestAnimationFrame(function() {
return URL.revokeObjectURL(url);
});
};
} catch (_error) {
e = _error;
console.warn('This browser does not support object URLs. Falling back to string URL.');
saveLink.href = uri;
}
saveLink.click();
return document.body.removeChild(saveLink);
}
};
chartToSvg = function(o, asSVG) {
var blob, doctype, img, rect, source, svgcopy, svgdiv, url;
doctype = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">';
svgdiv = o.chartdiv.getElementsByTagName('svg')[0];
svgcopy = svgdiv.cloneNode(true);
copyCSS(svgcopy, svgdiv);
rect = o.main.getBoundingClientRect();
svgcopy.setAttribute('xlink', 'http://www.w3.org/1999/xlink');
source = (new XMLSerializer()).serializeToString(svgcopy);
source = source.replace(/(\w+)?:?xlink=/g, 'xmlns:xlink=');
source = source.replace(/NS\d+:href/g, 'xlink:href');
blob = new Blob([doctype + source], {
type: 'image/svg+xml;charset=utf-8'
});
url = window.URL.createObjectURL(blob);
if (asSVG) {
return downloadBlob('chart.svg', url);
} else {
img = new HTML('img', {
width: rect.width,
height: rect.height,
src: url
});
img.onload = function() {
var canvas, canvasUrl, ctx;
canvas = new HTML('canvas', {
width: rect.width,
height: rect.height
});
document.getElementById('chartWrapperHiddenMaster').appendChild(canvas);
ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
canvasUrl = canvas.toDataURL("image/png");
return downloadBlob('chart.png', canvasUrl);
};
return document.getElementById('chartWrapperHiddenMaster').appendChild(img);
}
};
rotateTable = function(list) {
var arr, el, i, len, len1, newList, q, ref, u, x;
newList = [];
ref = list[0];
for (i = q = 0, len = ref.length; q < len; i = ++q) {
x = ref[i];
arr = [];
for (u = 0, len1 = list.length; u < len1; u++) {
el = list[u];
arr.push(el[i]);
}
newList.push(arr);
}
return newList;
};
dataTable = function(o) {
var arr, close, el, len, len1, modal, modalInner, myList, q, tbl, td, tr, u;
modal = new HTML('div', {
"class": "chartModal"
});
modalInner = new HTML('div', {
"class": "chartModalContent"
});
close = new HTML('span', {
"class": "chartModelClose",
onclick: "this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);"
}, "X");
modalInner.inject(close);
modal.inject(modalInner);
tbl = new HTML('table', {
border: "1"
});
myList = o.config.data.columns;
if (myList[0].length > myList.length) {
myList = rotateTable(myList);
}
for (q = 0, len = myList.length; q < len; q++) {
arr = myList[q];
tr = new HTML('tr');
for (u = 0, len1 = arr.length; u < len1; u++) {
el = arr[u];
if (el instanceof Date) {
el = el.toISOString().slice(0, 10);
}
td = new HTML('td', {}, String(el));
tr.inject(td);
}
tbl.inject(tr);
}
modalInner.inject(tbl);
return document.body.appendChild(modal);
};
chartOnclick = function(func, cid) {
var xchart;
xchart = xxCharts[cid];
return func(xchart);
};
switchChartType = function(o, config, type) {
var k, m, ref, v, xtype;
ref = config.data.types;
for (k in ref) {
v = ref[k];
xtype = type;
m = type.match(/^(.+)\*$/);
if (m) {
xtype = m[1] + v.split(/-/)[1] || v;
}
config.data.types[k] = xtype;
}
return o.chartobj = c3.generate(config);
};
stackChart = function(o, config, chart) {
var arr, k, ref, v;
arr = [];
ref = config.data.columns;
for (k in ref) {
v = ref[k];
arr.push(v[0]);
}
if (config.data.groups[0].length > 0) {
config.data.groups = [[]];
return chart.groups([[]]);
} else {
config.data.groups = [arr];
return chart.groups([arr]);
}
};
Chart = (function() {
function Chart(parent, type, data, options) {
var btn, btnDiv, btns, chartWrapperColors, chk, cid, el, hObj, i, id, inner, label, len, len1, q, ref, ref1, ref2, ref3, ref4, ref5, u;
cid = parseInt(Math.random() * 1000000).toString(16);
this.cid = cid;
xxCharts[cid] = this;
this.main = new HTML('div', {
"class": "chartWrapper"
});
this.main.xThis = this;
this.data = data;
this.toolbar = new HTML('div', {
"class": "chartToolbar"
});
this.main.inject(this.toolbar);
this.titlebar = new HTML('div', {
"class": "chartTitle"
}, options && options.title ? options.title : "");
this.main.inject(this.titlebar);
i = 0;
chartWrapperColors = genColors(16, 0.2, 0.75, true);
btns = chartWrapperButtons.generic.slice(0, 999);
if (type === 'line') {
ref = chartWrapperButtons.line;
for (q = 0, len = ref.length; q < len; q++) {
el = ref[q];
btns.push(el);
}
}
this.buttons = {};
for (u = 0, len1 = btns.length; u < len1; u++) {
btn = btns[u];
btnDiv = new HTML('div', {
title: btn.title,
"class": "chartToolButton",
style: {
background: chartWrapperColors[i]
}
});
inner = new HTML('i', {
"class": btn.icon
});
if (btn.id) {
this.buttons[btn.id] = btnDiv;
}
btnDiv.inject(inner);
this.toolbar.inject(btnDiv);
if (btn.onclick) {
(function(btn, btnDiv) {
return btnDiv.addEventListener('click', function() {
return chartOnclick(btn.onclick, cid);
});
})(btn, btnDiv);
}
i++;
}
this.chartdiv = new HTML('div', {
"class": "chartChart"
});
this.main.inject(this.chartdiv);
if (parent) {
parent.appendChild(this.main);
} else {
hObj = document.getElementById('chartWrapperHiddenMaster');
if (!hObj) {
hObj = new HTML('div', {
id: 'chartWrapperHiddenMaster',
style: {
visibility: "hidden"
}
});
document.body.appendChild(hObj);
}
hObj.appendChild(this.main);
}
if (type === 'line') {
ref1 = charts_linechart(this.chartdiv, data, options), this.chartobj = ref1[0], this.config = ref1[1];
}
if (type === 'donut') {
ref2 = charts_donutchart(this.chartdiv, data, 15), this.chartobj = ref2[0], this.config = ref2[1];
}
if (type === 'gauge') {
ref3 = charts_gaugechart(this.chartdiv, data), this.chartobj = ref3[0], this.config = ref3[1];
}
if (type === 'radar') {
ref4 = charts_radarchart(this.chartdiv, data), this.chartobj = ref4[0], this.config = ref4[1];
}
if (type === 'relationship') {
ref5 = charts_linked(this.chartdiv, data.nodes, data.links, options), this.chartobj = ref5[0], this.config = ref5[1];
}
if (data.distinguishable) {
id = Math.floor(Math.random() * 987654321).toString(16);
chk = document.createElement('input');
chk.setAttribute("type", "checkbox");
chk.setAttribute("id", id);
chk.style.marginLeft = '10px';
if (globArgs.distinguish && globArgs.distinguish === 'true') {
chk.checked = true;
}
chk.addEventListener("change", function() {
var distinguish;
distinguish = null;
if (this.checked) {
distinguish = 'true';
globArgs['distinguish'] = 'true';
}
updateWidgets('line', null, {
distinguish: distinguish
});
return updateWidgets('gauge', null, {
distinguish: distinguish
});
});
this.main.inject(mk('br'));
this.main.inject(chk);
label = document.createElement('label');
label.setAttribute("for", id);
label.setAttribute("title", "Check this box to distinguish between sub-categories in this chart");
chk.setAttribute("title", "Check this box to distinguish between sub-categories in this chart");
label.style.paddingLeft = '5px';
label.appendChild(document.createTextNode('Toggle category breakdown'));
this.main.inject(label);
}
if (data.relativeMode) {
id = Math.floor(Math.random() * 987654321).toString(16);
chk = document.createElement('input');
chk.setAttribute("type", "checkbox");
chk.setAttribute("id", id);
chk.style.marginLeft = '10px';
if (globArgs.relative && globArgs.relative === 'true') {
chk.checked = true;
}
chk.addEventListener("change", function() {
var relative;
relative = null;
if (this.checked) {
relative = 'true';
globArgs['relative'] = 'true';
}
updateWidgets('line', null, {
relative: relative
});
return updateWidgets('gauge', null, {
relative: relative
});
});
this.main.inject(mk('br'));
this.main.inject(chk);
label = document.createElement('label');
label.setAttribute("for", id);
label.setAttribute("title", "Check this box to use relative weighting");
chk.setAttribute("title", "Check this box to use relative weighting");
label.style.paddingLeft = '5px';
label.appendChild(document.createTextNode('Toggle relative/comparative mode'));
this.main.inject(label);
}
return this.main;
}
return Chart;
})();
hsl2rgb = function(h, s, l) {
var fract, min, sh, sv, switcher, v, vsf;
h = h % 1;
if (s > 1) {
s = 1;
}
if (l > 1) {
l = 1;
}
if (l <= 0.5) {
v = l * (1 + s);
} else {
v = l + s - l * s;
}
if (v === 0) {
return {
r: 0,
g: 0,
b: 0
};
}
min = 2 * l - v;
sv = (v - min) / v;
sh = (6 * h) % 6;
switcher = Math.floor(sh);
fract = sh - switcher;
vsf = v * sv * fract;
switch (switcher) {
case 0:
return {
r: v,
g: min + vsf,
b: min
};
case 1:
return {
r: v - vsf,
g: v,
b: min
};
case 2:
return {
r: min,
g: v,
b: min + vsf
};
case 3:
return {
r: min,
g: v - vsf,
b: v
};
case 4:
return {
r: min + vsf,
g: min,
b: v
};
case 5:
return {
r: v,
g: min,
b: v - vsf
};
}
return {
r: 0,
g: 0,
b: 0
};
};
genColors = function(numColors, saturation, lightness, hex) {
var baseHue, c, cls, h, i, q, ref;
cls = [];
baseHue = 1.02;
if (numColors <= 2) {
baseHue = 0.65;
}
for (i = q = 1, ref = numColors; 1 <= ref ? q <= ref : q >= ref; i = 1 <= ref ? ++q : --q) {
c = hsl2rgb(baseHue, saturation, lightness);
while (c.r > 0.8 && c.g > 0.8 && c.b > 0.8) {
baseHue -= 0.37;
if (baseHue < 0) {
baseHue += 1;
}
c = hsl2rgb(baseHue, saturation, lightness);
}
if (hex) {
h = "#" + ("00" + (~~(c.r * 255)).toString(16)).slice(-2) + ("00" + (~~(c.g * 255)).toString(16)).slice(-2) + ("00" + (~~(c.b * 255)).toString(16)).slice(-2);
cls.push(h);
} else {
cls.push({
r: parseInt(c.r * 255),
g: parseInt(c.g * 255),
b: parseInt(c.b * 255)
});
}
baseHue -= 0.37;
if (baseHue < 0) {
baseHue += 1;
}
}
return cls;
};
quickColors = function(num) {
var b, c, colors, g, pastel, ph, q, r, ref, x;
colors = [];
ph = 0;
for (x = q = 1, ref = num; 1 <= ref ? q <= ref : q >= ref; x = 1 <= ref ? ++q : --q) {
r = Math.random();
g = Math.random();
b = Math.random();
pastel = 0.7;
r = (pastel + r) / 2;
g = (pastel + g) / 2;
b = (pastel + b) / 2;
c = "#" + ("00" + (~~(r * 205)).toString(16)).slice(-2) + ("00" + (~~(g * 205)).toString(16)).slice(-2) + ("00" + (~~(b * 205)).toString(16)).slice(-2);
colors.push(c);
}
return colors;
};
datepickers = {};
updateTimeseriesWidgets = function(range) {
var from, to;
if (range) {
from = range[0];
to = range[1];
globArgs.from = from;
globArgs.to = to;
updateWidgets('line', null, {
to: to,
from: from
});
updateWidgets('top5', null, {
to: to,
from: from
});
updateWidgets('factors', null, {
to: to,
from: from
});
updateWidgets('trends', null, {
to: to,
from: from
});
updateWidgets('donut', null, {
to: to,
from: from
});
updateWidgets('gauge', null, {
to: to,
from: from
});
updateWidgets('radar', null, {
to: to,
from: from
});
updateWidgets('relationship', null, {
to: to,
from: from
});
updateWidgets('treemap', null, {
to: to,
from: from
});
updateWidgets('report', null, {
to: to,
from: from
});
updateWidgets('mvp', null, {
to: to,
from: from
});
updateWidgets('comstat', null, {
to: to,
from: from
});
updateWidgets('worldmap', null, {
to: to,
from: from
});
return updateWidgets('jsondump', null, {
to: to,
from: from
});
}
};
datepicker = function(widget) {
var cgroup, controls, datePickerOptions, div, fieldset, form, group, i, id, input, now, span;
div = document.createElement('div');
div.setAttribute("class", "well");
form = document.createElement('form');
div.appendChild(form);
fieldset = document.createElement('fieldset');
form.appendChild(fieldset);
cgroup = document.createElement('div');
cgroup.setAttribute("class", "control-group");
fieldset.appendChild(cgroup);
controls = document.createElement('div');
controls.setAttribute("class", "controls");
cgroup.appendChild(controls);
group = document.createElement('div');
group.setAttribute("class", "input-prepend input-group");
controls.appendChild(group);
span = document.createElement('span');
span.setAttribute("class", "add-on input-group-addon");
group.appendChild(span);
i = document.createElement('i');
i.setAttribute("class", "glyphicon glyphicon-calendar fa fa-calendar");
span.appendChild(i);
input = document.createElement('input');
input.setAttribute("type", "text");
input.style.width = "240px";
input.setAttribute("name", "date");
input.setAttribute("class", "form-control");
now = (globArgs.from ? moment(parseInt(globArgs.from) * 1000) : moment().subtract(6, 'months')).format('YYYY-MM-DD') + " to " + (globArgs.from ? moment(parseInt(globArgs.to) * 1000) : moment()).format('YYYY-MM-DD');
input.setAttribute("value", now);
id = Math.floor(Math.random() * 987654321).toString(16);
input.setAttribute("id", id);
group.appendChild(input);
widget.inject(div);
datePickerOptions = {
startDate: globArgs.from ? moment(new Date(globArgs.from * 1000)) : moment().subtract(6, 'months'),
endDate: globArgs.to ? moment(new Date(globArgs.to * 1000)) : moment(),
minDate: '1970-01-01',
maxDate: '2020-01-01',
dateLimit: {
days: 365
},
showDropdowns: true,
showWeekNumbers: true,
timePicker: false,
timePickerIncrement: 1,
timePicker12Hour: true,
ranges: {
'Today': [moment(), moment()],
'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
'Past Week': [moment().subtract(7, 'days'), moment().subtract(1, 'days')],
'Past 30 Days': [moment().subtract(30, 'days'), moment().subtract(1, 'days')],
'This Month': [moment().startOf('month'), moment().endOf('month')],
'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
'Last 3 Months': [moment().subtract(3, 'month'), moment()],
'Last 6 Months': [moment().subtract(6, 'month'), moment()],
'Last 12 Months': [moment().subtract(1, 'year'), moment()],
'Last 2 Years': [moment().subtract(2, 'year'), moment()],
'Last 5 Years': [moment().subtract(5, 'year'), moment()],
'Last 10 Years': [moment().subtract(10, 'year'), moment()],
'Last...Snoot Years': [moment(42300, 'X'), moment()]
},
opens: 'left',
buttonClasses: ['btn btn-default'],
applyClass: 'btn-small btn-primary',
cancelClass: 'btn-small',
format: 'YYYY-MM-DD',
separator: ' to ',
locale: {
applyLabel: 'Submit',
cancelLabel: 'Clear',
fromLabel: 'From',
toLabel: 'To',
customRangeLabel: 'Custom',
daysOfWeek: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
firstDay: 1
}
};
return $('#' + id).daterangepicker(datePickerOptions, function(start, end, label) {
console.log(start._d.getTime() / 1000);
return updateTimeseriesWidgets([Math.floor(start._d.getTime() / 1000), Math.floor(end._d.getTime() / 1000)]);
});
};
badModal = function(str) {
var btn, btndiv, modalBox, modalInner;
if (typeof str === 'object') {
str = str.message;
}
modalBox = new HTML('div', {
"class": "errorModal"
});
document.body.appendChild(modalBox);
modalInner = new HTML('div', {
"class": "errorModalInner"
}, txt(str));
modalBox.appendChild(modalInner);
btndiv = new HTML('div', {
style: {
textAlign: "center",
marginTop: "10px"
}
}, " ");
modalInner.inject(btndiv);
btn = new HTML('button', {
"class": "btn btn-lg btn-success",
onclick: "document.body.removeChild(this.parentNode.parentNode.parentNode);"
}, "Gotcha!");
btndiv.inject(btn);
return window.setTimeout(function() {
modalInner.style.visibility = "visible";
return modalInner.style.opacity = 1;
}, 10);
};
snap = badModal;
explorer = function(json, state) {
var ID, chk, ezURL, h, id, item, label, len, len1, list, m, opt, org, q, ref, ref1, ref2, ref3, slen, u;
org = json.organisation;
h = document.createElement('h2');
if (json.tag) {
org.name += " (Filter: " + json.tag + ")";
}
h.appendChild(document.createTextNode("Exploring " + org.name + ":"));
state.widget.inject(h, true);
list = document.createElement('select');
state.widget.inject(list);
opt = document.createElement('option');
opt.value = "";
slen = 0;
ref = json.sources;
for (q = 0, len = ref.length; q < len; q++) {
item = ref[q];
if (((ref1 = item.type) === 'git' || ref1 === 'svn' || ref1 === 'gerrit' || ref1 === 'github') && item.noclone !== true) {
slen++;
}
}
opt.text = "All " + slen + " repositories";
list.appendChild(opt);
json.sources.sort(function(a, b) {
if (a.sourceURL === b.sourceURL) {
return 0;
} else {
if (a.sourceURL > b.sourceURL) {
return 1;
} else {
return -1;
}
}
});
ref2 = json.sources;
for (u = 0, len1 = ref2.length; u < len1; u++) {
item = ref2[u];
if (((ref3 = item.type) === 'git' || ref3 === 'svn' || ref3 === 'gerrit' || ref3 === 'github') && item.noclone !== true) {
opt = document.createElement('option');
opt.value = item.sourceID;
ezURL = null;
m = item.sourceURL.match(/^([a-z]+:\/\/.+?)[\/?]([^\/?]+)$/i);
if (m && m.length === 3) {
ezURL = m[2] + " - (" + m[1] + ")";
}
opt.text = ezURL ? ezURL : item.sourceURL;
if (globArgs.source && globArgs.source === item.sourceID) {
opt.selected = 'selected';
}
list.appendChild(opt);
}
}
ID = Math.floor(Math.random() * 987654321).toString(16);
list.setAttribute('id', ID);
$("#" + ID).chosen().change(function() {
var source;
source = this.value;
if (source === "") {
source = null;
}
globArgs.source = source;
updateWidgets('donut', null, {
source: source
});
updateWidgets('gauge', null, {
source: source
});
updateWidgets('line', null, {
source: source
});
updateWidgets('contacts', null, {
source: source
});
updateWidgets('top5', null, {
source: source
});
updateWidgets('factors', null, {
source: source
});
updateWidgets('trends', null, {
source: source
});
updateWidgets('mvp', null, {
source: source
});
updateWidgets('comstat', null, {
source: source
});
return updateWidgets('jsondump', null, {
source: source
});
});
id = Math.floor(Math.random() * 987654321).toString(16);
chk = document.createElement('input');
chk.setAttribute("type", "checkbox");
chk.setAttribute("id", id);
chk.style.marginLeft = '10px';
if (globArgs.author && globArgs.author === 'true') {
chk.checked = true;
}
chk.addEventListener("change", function() {
var author, unique;
unique = null;
if (this.checked) {
author = 'true';
globArgs['author'] = 'true';
}
updateWidgets('donut', null, {
author: author
});
updateWidgets('gauge', null, {
author: author
});
updateWidgets('line', null, {
author: author
});
updateWidgets('contacts', null, {
author: author
});
updateWidgets('top5', null, {
author: author
});
updateWidgets('factors', null, {
author: author
});
updateWidgets('trends', null, {
author: author
});
updateWidgets('relationship', null, {
author: author
});
updateWidgets('mvp', null, {
author: author
});
updateWidgets('comstat', null, {
author: author
});
return updateWidgets('jsondump', null, {
author: author
});
});
state.widget.inject(chk);
label = document.createElement('label');
label.setAttribute("for", id);
label.setAttribute("title", "Check this box to authorships instead of committerships");
chk.setAttribute("title", "Check this box to authorships instead of committerships");
label.style.paddingLeft = '5px';
label.appendChild(document.createTextNode('Show authors'));
return state.widget.inject(label);
};
sourceexplorer = function(json, state) {
var ID, div, ezURL, h, item, len, len1, list, m, opt, org, q, ref, ref1, slen, u;
org = json.organisation;
h = document.createElement('h4');
if (json.tag) {
org.name += " (Filter: " + json.tag + ")";
}
h.appendChild(document.createTextNode("Exploring " + org.name + ":"));
state.widget.inject(h, true);
div = new HTML('div', {
"class": "form-group"
});
list = new HTML('select', {
"class": "form-control"
});
div.inject(list);
state.widget.inject(div);
opt = document.createElement('option');
opt.value = "";
slen = 0;
ref = json.sources;
for (q = 0, len = ref.length; q < len; q++) {
item = ref[q];
slen++;
}
opt.text = "All " + slen + " sources";
list.appendChild(opt);
json.sources.sort(function(a, b) {
if (a.sourceURL === b.sourceURL) {
return 0;
} else {
if (a.sourceURL > b.sourceURL) {
return 1;
} else {
return -1;
}
}
});
ref1 = json.sources;
for (u = 0, len1 = ref1.length; u < len1; u++) {
item = ref1[u];
if (true) {
opt = document.createElement('option');
opt.value = item.sourceID;
ezURL = null;
m = item.sourceURL.match(/^([a-z]+:\/\/.+?)[\/?]([^\/?]+)$/i);
if (m && m.length === 3) {
ezURL = m[2] + " - (" + m[1] + ")";
}
opt.text = ezURL ? ezURL : item.sourceURL;
if (globArgs.source && globArgs.source === item.sourceID) {
opt.selected = 'selected';
}
list.appendChild(opt);
}
}
ID = Math.floor(Math.random() * 987654321).toString(16);
list.setAttribute('id', ID);
return $("#" + ID).chosen().change(function() {
var source;
source = this.value;
if (source === "") {
source = null;
}
globArgs.source = source;
updateWidgets('donut', null, {
source: source
});
updateWidgets('gauge', null, {
source: source
});
updateWidgets('line', null, {
source: source
});
updateWidgets('contacts', null, {
source: source
});
updateWidgets('top5', null, {
source: source
});
updateWidgets('factors', null, {
source: source
});
updateWidgets('trends', null, {
source: source
});
updateWidgets('mvp', null, {
source: source
});
updateWidgets('comstat', null, {
source: source
});
return updateWidgets('jsondump', null, {
author: author
});
});
};
mailexplorer = function(json, state) {
var ID, ezURL, h, item, len, len1, list, m, opt, org, q, ref, ref1, ref2, ref3, slen, u;
org = json.organisation;
h = document.createElement('h4');
if (json.tag) {
org.name += " (Filter: " + json.tag + ")";
}
h.appendChild(document.createTextNode("Exploring " + org.name + ":"));
state.widget.inject(h, true);
list = document.createElement('select');
state.widget.inject(list);
opt = document.createElement('option');
opt.value = "";
slen = 0;
ref = json.sources;
for (q = 0, len = ref.length; q < len; q++) {
item = ref[q];
if ((ref1 = item.type) === 'mail' || ref1 === 'ponymail' || ref1 === 'pipermail' || ref1 === 'hyperkitty') {
slen++;
}
}
opt.text = "All " + slen + " mailing lists";
list.appendChild(opt);
json.sources.sort(function(a, b) {
if (a.sourceURL === b.sourceURL) {
return 0;
} else {
if (a.sourceURL > b.sourceURL) {
return 1;
} else {
return -1;
}
}
});
ref2 = json.sources;
for (u = 0, len1 = ref2.length; u < len1; u++) {
item = ref2[u];
if ((ref3 = item.type) === 'mail' || ref3 === 'ponymail' || ref3 === 'pipermail' || ref3 === 'hyperkitty') {
opt = document.createElement('option');
opt.value = item.sourceID;
ezURL = null;
m = item.sourceURL.match(/^([a-z]+:\/\/.+?)[\/?]([^\/?]+)$/i);
if (m && m.length === 3) {
ezURL = m[2] + " - (" + m[1] + ")";
}
opt.text = ezURL ? ezURL : item.sourceURL;
if (globArgs.source && globArgs.source === item.sourceID) {
opt.selected = 'selected';
}
list.appendChild(opt);
}
}
ID = Math.floor(Math.random() * 987654321).toString(16);
list.setAttribute('id', ID);
return $("#" + ID).chosen().change(function() {
var source;
source = this.value;
if (source === "") {
source = null;
}
globArgs.source = source;
updateWidgets('donut', null, {
source: source
});
updateWidgets('gauge', null, {
source: source
});
updateWidgets('line', null, {
source: source
});
updateWidgets('contacts', null, {
source: source
});
updateWidgets('top5', null, {
source: source
});
updateWidgets('factors', null, {
source: source
});
updateWidgets('trends', null, {
source: source
});
return updateWidgets('relationship', null, {
source: source
});
});
};
logexplorer = function(json, state) {
var ID, ezURL, h, item, len, len1, list, m, opt, org, q, ref, ref1, slen, u;
org = json.organisation;
h = document.createElement('h4');
if (json.tag) {
org.name += " (Filter: " + json.tag + ")";
}
h.appendChild(document.createTextNode("Exploring " + org.name + ":"));
state.widget.inject(h, true);
list = document.createElement('select');
state.widget.inject(list);
opt = document.createElement('option');
opt.value = "";
slen = 0;
ref = json.sources;
for (q = 0, len = ref.length; q < len; q++) {
item = ref[q];
if (item.type === 'stats') {
slen++;
}
}
opt.text = "All " + slen + " log files";
list.appendChild(opt);
json.sources.sort(function(a, b) {
if (a.sourceURL === b.sourceURL) {
return 0;
} else {
if (a.sourceURL > b.sourceURL) {
return 1;
} else {
return -1;
}
}
});
ref1 = json.sources;
for (u = 0, len1 = ref1.length; u < len1; u++) {
item = ref1[u];
if (item.type === 'stats') {
opt = document.createElement('option');
opt.value = item.sourceID;
ezURL = null;
m = item.sourceURL.match(/^([a-z]+:\/\/.+?)[\/?]([^\/?]+)$/i);
if (m && m.length === 3) {
ezURL = m[2] + " - (" + m[1] + ")";
}
opt.text = ezURL ? ezURL : item.sourceURL;
if (globArgs.source && globArgs.source === item.sourceID) {
opt.selected = 'selected';
}
list.appendChild(opt);
}
}
ID = Math.floor(Math.random() * 987654321).toString(16);
list.setAttribute('id', ID);
return $("#" + ID).chosen().change(function() {
var source;
source = this.value;
if (source === "") {
source = null;
}
globArgs.source = source;
updateWidgets('donut', null, {
source: source
});
updateWidgets('gauge', null, {
source: source
});
updateWidgets('line', null, {
source: source
});
updateWidgets('worldmap', null, {
source: source
});
updateWidgets('top5', null, {
source: source
});
updateWidgets('factors', null, {
source: source
});
return updateWidgets('trends', null, {
source: source
});
});
};
issueexplorer = function(json, state) {
var ID, ezURL, h, item, len, len1, list, m, n, opt, org, q, ref, ref1, ref2, ref3, slen, u;
org = json.organisation;
if (json.tag) {
org.name += " (Filter: " + json.tag + ")";
}
h = document.createElement('h4');
h.appendChild(document.createTextNode("Exploring " + org.name + ":"));
state.widget.inject(h, true);
list = document.createElement('select');
state.widget.inject(list);
opt = document.createElement('option');
opt.value = "";
slen = 0;
ref = json.sources;
for (q = 0, len = ref.length; q < len; q++) {
item = ref[q];
if ((ref1 = item.type) === 'jira' || ref1 === 'gerrit' || ref1 === 'github' || ref1 === 'bugzilla') {
slen++;
}
}
opt.text = "All " + slen + " issue tracker(s)";
list.appendChild(opt);
json.sources.sort(function(a, b) {
if (a.sourceURL === b.sourceURL) {
return 0;
} else {
if (a.sourceURL > b.sourceURL) {
return 1;
} else {
return -1;
}
}
});
ref2 = json.sources;
for (u = 0, len1 = ref2.length; u < len1; u++) {
item = ref2[u];
if ((ref3 = item.type) === 'jira' || ref3 === 'gerrit' || ref3 === 'github' || ref3 === 'bugzilla') {
opt = document.createElement('option');
opt.value = item.sourceID;
ezURL = null;
n = item.sourceURL.match(/^([a-z]+:\/\/.+?)\/([-.A-Z0-9]+)$/i);
m = item.sourceURL.match(/^([a-z]+:\/\/.+?)\s(.+)$/i);
if (n && n.length === 3) {
ezURL = n[2] + " - (" + n[1] + ")";
} else if (m && m.length === 3) {
ezURL = m[2] + " - (" + m[1] + ")";
}
opt.text = ezURL ? ezURL : item.sourceURL;
if (globArgs.source && globArgs.source === item.sourceID) {
opt.selected = 'selected';
}
list.appendChild(opt);
}
}
ID = Math.floor(Math.random() * 987654321).toString(16);
list.setAttribute('id', ID);
return $("#" + ID).chosen().change(function() {
var source;
source = this.value;
if (source === "") {
source = null;
}
globArgs.source = source;
updateWidgets('donut', null, {
source: source
});
updateWidgets('gauge', null, {
source: source
});
updateWidgets('line', null, {
source: source
});
updateWidgets('contacts', null, {
source: source
});
updateWidgets('top5', null, {
source: source
});
updateWidgets('factors', null, {
source: source
});
return updateWidgets('trends', null, {
source: source
});
});
};
forumexplorer = function(json, state) {
var ID, ezURL, h, item, len, len1, list, m, n, opt, org, q, ref, ref1, ref2, ref3, slen, u;
org = json.organisation;
if (json.tag) {
org.name += " (Filter: " + json.tag + ")";
}
h = document.createElement('h4');
h.appendChild(document.createTextNode("Exploring " + org.name + ":"));
state.widget.inject(h, true);
list = document.createElement('select');
state.widget.inject(list);
opt = document.createElement('option');
opt.value = "";
slen = 0;
ref = json.sources;
for (q = 0, len = ref.length; q < len; q++) {
item = ref[q];
if ((ref1 = item.type) === 'forum' || ref1 === 'discourse' || ref1 === 'askbot') {
slen++;
}
}
opt.text = "All " + slen + " forum(s)";
list.appendChild(opt);
json.sources.sort(function(a, b) {
if (a.sourceURL === b.sourceURL) {
return 0;
} else {
if (a.sourceURL > b.sourceURL) {
return 1;
} else {
return -1;
}
}
});
ref2 = json.sources;
for (u = 0, len1 = ref2.length; u < len1; u++) {
item = ref2[u];
if ((ref3 = item.type) === 'forum' || ref3 === 'discourse' || ref3 === 'askbot') {
opt = document.createElement('option');
opt.value = item.sourceID;
ezURL = null;
n = item.sourceURL.match(/^([a-z]+:\/\/.+?)\/([-.A-Z0-9]+)$/i);
m = item.sourceURL.match(/^([a-z]+:\/\/.+?)\s(.+)$/i);
if (n && n.length === 3) {
ezURL = n[2] + " - (" + n[1] + ")";
} else if (m && m.length === 3) {
ezURL = m[2] + " - (" + m[1] + ")";
}
opt.text = ezURL ? ezURL : item.sourceURL;
if (globArgs.source && globArgs.source === item.sourceID) {
opt.selected = 'selected';
}
list.appendChild(opt);
}
}
ID = Math.floor(Math.random() * 987654321).toString(16);
list.setAttribute('id', ID);
return $("#" + ID).chosen().change(function() {
var source;
source = this.value;
if (source === "") {
source = null;
}
globArgs.source = source;
updateWidgets('donut', null, {
source: source
});
updateWidgets('gauge', null, {
source: source
});
updateWidgets('line', null, {
source: source
});
updateWidgets('contacts', null, {
source: source
});
updateWidgets('top5', null, {
source: source
});
updateWidgets('factors', null, {
source: source
});
return updateWidgets('trends', null, {
source: source
});
});
};
imexplorer = function(json, state) {
var ID, ezURL, h, item, len, len1, list, m, n, opt, org, q, ref, ref1, ref2, ref3, slen, u;
org = json.organisation;
if (json.tag) {
org.name += " (Filter: " + json.tag + ")";
}
h = document.createElement('h4');
h.appendChild(document.createTextNode("Exploring " + org.name + ":"));
state.widget.inject(h, true);
list = document.createElement('select');
state.widget.inject(list);
opt = document.createElement('option');
opt.value = "";
slen = 0;
ref = json.sources;
for (q = 0, len = ref.length; q < len; q++) {
item = ref[q];
if ((ref1 = item.type) === 'irc' || ref1 === 'gitter') {
slen++;
}
}
opt.text = "All " + slen + " messaging sources";
list.appendChild(opt);
json.sources.sort(function(a, b) {
if (a.sourceURL === b.sourceURL) {
return 0;
} else {
if (a.sourceURL > b.sourceURL) {
return 1;
} else {
return -1;
}
}
});
ref2 = json.sources;
for (u = 0, len1 = ref2.length; u < len1; u++) {
item = ref2[u];
if ((ref3 = item.type) === 'irc' || ref3 === 'gitter') {
opt = document.createElement('option');
opt.value = item.sourceID;
ezURL = null;
n = item.sourceURL.match(/^([a-z]+:\/\/.+?)\/([#\S+]+)$/i);
m = item.sourceURL.match(/^([a-z]+:\/\/.+?)\s(.+)$/i);
if (n && n.length === 3) {
ezURL = n[2] + " - (" + n[1] + ")";
} else if (m && m.length === 3) {
ezURL = m[2] + " - (" + m[1] + ")";
}
opt.text = ezURL ? ezURL : item.sourceURL;
if (globArgs.source && globArgs.source === item.sourceID) {
opt.selected = 'selected';
}
list.appendChild(opt);
}
}
ID = Math.floor(Math.random() * 987654321).toString(16);
list.setAttribute('id', ID);
$("#" + ID).chosen().change(function() {
var source;
source = this.value;
if (source === "") {
source = null;
}
globArgs.source = source;
updateWidgets('donut', null, {
source: source
});
updateWidgets('gauge', null, {
source: source
});
updateWidgets('line', null, {
source: source
});
updateWidgets('contacts', null, {
source: source
});
updateWidgets('top5', null, {
source: source
});
updateWidgets('factors', null, {
source: source
});
return updateWidgets('trends', null, {
source: source
});
}, false);
return $('select').chosen();
};
ciexplorer = function(json, state) {
var ID, ezURL, h, item, len, len1, list, m, n, opt, org, q, ref, ref1, ref2, ref3, slen, u;
org = json.organisation;
if (json.tag) {
org.name += " (Filter: " + json.tag + ")";
}
h = document.createElement('h4');
h.appendChild(document.createTextNode("Exploring " + org.name + ":"));
state.widget.inject(h, true);
list = document.createElement('select');
state.widget.inject(list);
opt = document.createElement('option');
opt.value = "";
slen = 0;
ref = json.sources;
for (q = 0, len = ref.length; q < len; q++) {
item = ref[q];
if ((ref1 = item.type) === 'jenkins' || ref1 === 'travis' || ref1 === 'buildbot') {
slen++;
}
}
opt.text = "All " + slen + " CI Services";
list.appendChild(opt);
json.sources.sort(function(a, b) {
if (a.sourceURL === b.sourceURL) {
return 0;
} else {
if (a.sourceURL > b.sourceURL) {
return 1;
} else {
return -1;
}
}
});
ref2 = json.sources;
for (u = 0, len1 = ref2.length; u < len1; u++) {
item = ref2[u];
if ((ref3 = item.type) === 'jenkins' || ref3 === 'travis' || ref3 === 'buildbot') {
opt = document.createElement('option');
opt.value = item.sourceID;
ezURL = null;
n = item.sourceURL.match(/^([a-z]+:\/\/.+?)\/([#\S+]+)$/i);
m = item.sourceURL.match(/^([a-z]+:\/\/.+?)\s(.+)$/i);
if (n && n.length === 3) {
ezURL = n[2] + " - (" + n[1] + ")";
} else if (m && m.length === 3) {
ezURL = m[2] + " - (" + m[1] + ")";
}
opt.text = ezURL ? ezURL : item.sourceURL;
if (globArgs.source && globArgs.source === item.sourceID) {
opt.selected = 'selected';
}
list.appendChild(opt);
}
}
ID = Math.floor(Math.random() * 987654321).toString(16);
list.setAttribute('id', ID);
return $("#" + ID).chosen().change(function() {
var source;
source = this.value;
if (source === "") {
source = null;
}
globArgs.source = source;
updateWidgets('donut', null, {
source: source
});
updateWidgets('gauge', null, {
source: source
});
updateWidgets('line', null, {
source: source
});
updateWidgets('contacts', null, {
source: source
});
updateWidgets('top5', null, {
source: source
});
updateWidgets('factors', null, {
source: source
});
updateWidgets('trends', null, {
source: source
});
return updateWidgets('relationship', null, {
source: source
});
});
};
multiviewexplorer = function(json, state) {
var ID, h, item, k, list, opt, org, q, results, tName;
org = json.organisation;
h = document.createElement('h4');
h.appendChild(document.createTextNode("Select views to compare:"));
state.widget.inject(h, true);
results = [];
for (k = q = 1; q <= 3; k = ++q) {
tName = 'tag' + k;
list = document.createElement('select');
list.setAttribute("data", tName);
state.widget.inject(list);
opt = document.createElement('option');
opt.value = "";
opt.text = "(None)";
list.appendChild(opt);
opt = document.createElement('option');
opt.value = "---";
opt.text = "Entire organisation";
if (globArgs[tName] && globArgs[tName] === '---') {
opt.selected = 'selected';
}
list.appendChild(opt);
if (isArray(json.views)) {
json.views.sort(function(a, b) {
if (a.name === b.name) {
return 0;
} else {
if (a.name > b.name) {
return 1;
} else {
return -1;
}
}
});
}
results.push((function() {
var len, ref, results1, u;
ref = json.views;
results1 = [];
for (u = 0, len = ref.length; u < len; u++) {
item = ref[u];
opt = document.createElement('option');
opt.value = item.id;
opt.text = item.name;
if (globArgs[tName] && globArgs[tName] === item.id) {
opt.selected = 'selected';
}
list.appendChild(opt);
ID = Math.floor(Math.random() * 987654321).toString(16);
list.setAttribute('id', ID);
results1.push($("#" + ID).chosen().change(function() {
var source, x;
source = this.value;
if (source === "") {
source = null;
}
tName = this.getAttribute("data");
globArgs[tName] = source;
x = {};
x[tName] = source;
updateWidgets('donut', null, x);
updateWidgets('gauge', null, x);
updateWidgets('line', null, x);
updateWidgets('contacts', null, x);
updateWidgets('top5', null, x);
updateWidgets('factors', null, x);
updateWidgets('trends', null, x);
return updateWidgets('radar', null, x);
}));
}
return results1;
})());
}
return results;
};
subFilterGlob = null;
subFilter = function() {
var source, tName, x;
source = subFilterGlob;
if (source === "") {
source = null;
}
tName = 'subfilter';
globArgs[tName] = source;
x = {};
x[tName] = source;
updateWidgets('sourcepicker', null, x);
updateWidgets('repopicker', null, x);
updateWidgets('issuepicker', null, x);
updateWidgets('forumpicker', null, x);
updateWidgets('mailpicker', null, x);
updateWidgets('logpicker', null, x);
updateWidgets('donut', null, x);
updateWidgets('gauge', null, x);
updateWidgets('line', null, x);
updateWidgets('contacts', null, x);
updateWidgets('top5', null, x);
updateWidgets('factors', null, x);
updateWidgets('trends', null, x);
updateWidgets('radar', null, x);
updateWidgets('widget', null, x);
updateWidgets('relationship', null, x);
updateWidgets('treemap', null, x);
updateWidgets('report', null, x);
updateWidgets('mvp', null, x);
updateWidgets('comstat', null, x);
updateWidgets('worldmap', null, x);
updateWidgets('jsondump', null, x);
return $("a").each(function() {
var m, url;
url = $(this).attr('href');
if (url) {
m = url.match(/^(.+\?page=[-a-z]+.*?)(?:&subfilter=[^&]+)?(.*)$/);
if (m) {
if (source) {
return $(this).attr('href', m[1] + "&subfilter=" + source + m[2]);
} else {
return $(this).attr('href', "" + m[1] + m[2]);
}
}
}
});
};
viewexplorer = function(json, state) {
var ID, b, div, h, i, item, len, list, opt, org, q, rb, ref, source, tName;
org = json.organisation;
h = document.createElement('h4');
h.appendChild(document.createTextNode("Select a view to use:"));
state.widget.inject(h, true);
tName = 'view';
list = document.createElement('select');
list.setAttribute("data", tName);
state.widget.inject(list);
opt = document.createElement('option');
opt.value = "";
opt.text = "(None)";
list.appendChild(opt);
opt = document.createElement('option');
opt.value = "---";
opt.text = "Entire organisation";
if (globArgs[tName] && globArgs[tName] === '---') {
opt.selected = 'selected';
}
list.appendChild(opt);
if (isArray(json.views)) {
json.views.sort(function(a, b) {
if (a.name === b.name) {
return 0;
} else {
if (a.name > b.name) {
return 1;
} else {
return -1;
}
}
});
}
ref = json.views;
for (q = 0, len = ref.length; q < len; q++) {
item = ref[q];
opt = document.createElement('option');
opt.value = item.id;
opt.text = item.name;
if (globArgs[tName] && globArgs[tName] === item.id) {
opt.selected = 'selected';
}
list.appendChild(opt);
}
ID = Math.floor(Math.random() * 987654321).toString(16);
list.setAttribute('id', ID);
$("#" + ID).chosen().change(function() {
var source, x;
source = this.value;
if (source === "") {
source = null;
}
tName = this.getAttribute("data");
globArgs[tName] = source;
x = {};
x[tName] = source;
updateWidgets('sourcepicker', null, x);
updateWidgets('repopicker', null, x);
updateWidgets('issuepicker', null, x);
updateWidgets('mailpicker', null, x);
updateWidgets('logpicker', null, x);
updateWidgets('donut', null, x);
updateWidgets('gauge', null, x);
updateWidgets('line', null, x);
updateWidgets('contacts', null, x);
updateWidgets('top5', null, x);
updateWidgets('factors', null, x);
updateWidgets('trends', null, x);
updateWidgets('radar', null, x);
updateWidgets('widget', null, x);
updateWidgets('relationship', null, x);
updateWidgets('treemap', null, x);
updateWidgets('report', null, x);
updateWidgets('mvp', null, x);
updateWidgets('comstat', null, x);
updateWidgets('worldmap', null, x);
updateWidgets('jsondump', null, x);
return $("a").each(function() {
var m, url;
url = $(this).attr('href');
if (url) {
m = url.match(/^(.+\?page=[-a-z]+)(?:&view=[a-f0-9]+)?(.*)$/);
if (m) {
if (source) {
return $(this).attr('href', m[1] + "&view=" + source + m[2]);
} else {
return $(this).attr('href', "" + m[1] + m[2]);
}
}
}
});
});
state.widget.inject(new HTML('br'));
i = new HTML('input', {
id: 'subfilter',
size: 16,
type: 'text',
value: globArgs.subfilter,
onChange: 'subFilterGlob = this.value;',
placeholder: 'sub-filter'
});
b = new HTML('input', {
style: {
marginLeft: '10px'
},
"class": 'btn btn-small btn-success',
type: 'button',
onClick: 'subFilter();',
value: "sub-filter"
});
rb = new HTML('input', {
style: {
marginLeft: '10px'
},
"class": 'btn btn-small btn-danger',
type: 'button',
onClick: 'get("subfilter").value=""; subFilterGlob=""; subFilter();',
value: "reset"
});
state.widget.inject(i);
state.widget.inject(b);
state.widget.inject(rb);
if (globArgs.subfilter && globArgs.subfilter.length > 0) {
source = globArgs.subfilter;
$("a").each(function() {
var m, url;
url = $(this).attr('href');
if (url) {
m = url.match(/^(.+\?page=[-a-z]+.*?)(?:&subfilter=[a-f0-9]+)?(.*)$/);
if (m) {
if (source) {
return $(this).attr('href', m[1] + "&subfilter=" + source + m[2]);
} else {
return $(this).attr('href', "" + m[1] + m[2]);
}
}
}
});
}
if (globArgs.email) {
div = new HTML('div', {}, "Currently filtering results based on " + globArgs.email + ". - ");
div.inject(new HTML('a', {
href: 'javascript:void(filterPerson(null));'
}, "Reset filter"));
return state.widget.inject(div);
}
};
widgetexplorer = function(json, state) {
var h, key, list, opt, org, pwidgets, tName, value;
pwidgets = {
'languages': 'Code: Language breakdown',
'commit-history-year': "Code: Commit history (past year)",
'commit-history-all': "Code: Commit history (all time)",
'commit-top5-year': "Code: top 5 committers (past year)",
'commit-top5-all': "Code: top 5 committers (all time)",
'committer-count-year': "Code: Committers/Authors per month (past year)",
'committer-count-all': "Code: Committers/Authors per month (all time)",
'commit-lines-year': "Code: Lines changed (past year)",
'commit-lines-all': "Code: Lines changed (all time)",
'sloc-map': "Code: Language Treemap",
'repo-size-year': "Repos: top 15 by lines of code",
'repo-commits-year': "Repos: top 15 by number of commits (past year)",
'repo-commits-all': "Repos: top 15 by number of commits (all time)",
'evolution': "Code: Code evolution (all time)",
'evolution-extended': "Code: Code evolution (individual languages, all time)",
'issue-count-year': "Issues: Tickets opened/closed (past year)",
'issue-count-all': "Issues: Tickets opened/closed (all time)",
'issue-operators-year': "Issues: Ticket creators/closers (past year)",
'issue-operators-all': "Issues: Ticket creators/closers (all time)",
'issue-queue-all': "Issue queue size by ticket age",
'email-count-year': "Mail: Emails/threads/authors (past year)",
'email-count-all': "Mail: Emails/threads/authors (all time)",
'im-stats-year': "Online messaging activity (past year)",
'im-stats-all': "Online messaging activity (all time)",
'compare-commits-year': "Commits by Affiliation (past year)",
'compare-commits-all': "Commits by Affiliation (all time)",
'repo-relationship-year': "Repository relationships (past year)",
'repo-relationship-2year': "Repository relationships (past two years)",
'issue-relationship-year': "Issue tracker relationships (past year)",
'issue-relationship-2year': "Issue tracker relationships (past two years)",
'log-stats-year': "Downloads/Visits (past year)",
'log-stats-all': "Downloads/Visits (all time)",
'log-map-month': "Downloads/Visits per country (past month)",
'log-map-year': "Downloads/Visits per country (past year)",
'log-map-all': "Downloads/Visits per country (all time)"
};
org = json.organisation;
h = document.createElement('h4');
h.appendChild(document.createTextNode("Select a widget to use:"));
state.widget.inject(h, true);
tName = 'widget';
list = document.createElement('select');
list.setAttribute("data", tName);
state.widget.inject(list);
opt = document.createElement('option');
opt.value = "";
opt.text = "Select a widget type:";
list.appendChild(opt);
for (key in pwidgets) {
value = pwidgets[key];
opt = document.createElement('option');
opt.value = key;
opt.text = value;
if (globArgs[tName] && globArgs[tName] === key) {
opt.selected = 'selected';
}
list.appendChild(opt);
}
return list.addEventListener("change", function() {
var source, x;
source = this.value;
if (source === "") {
source = null;
}
tName = this.getAttribute("data");
globArgs[tName] = source;
x = {};
x[tName] = source;
updateWidgets('widget', null, x);
updateWidgets('donut', null, x);
updateWidgets('gauge', null, x);
updateWidgets('line', null, x);
updateWidgets('contacts', null, x);
updateWidgets('top5', null, x);
updateWidgets('factors', null, x);
updateWidgets('trends', null, x);
return updateWidgets('radar', null, x);
}, false);
};
keyValueForm = function(type, key, caption, placeholder) {
var div, inp, left, right;
div = new HTML('div', {
style: {
width: "100%",
margin: "10px",
paddingBottom: "10px"
}
});
left = new HTML('div', {
style: {
float: "left",
width: "300px",
fontWeight: "bold"
}
}, caption);
right = new HTML('div', {
style: {
float: "left",
width: "500px"
}
});
if (type === 'text') {
inp = new HTML('input', {
name: key,
id: key,
style: {
marginBottom: "10px"
},
"class": "form-control",
type: "text",
placeholder: placeholder
});
right.inject(inp);
}
if (type === 'textarea') {
inp = new HTML('textarea', {
name: key,
id: key,
style: {
marginBottom: "10px"
},
"class": "form-control",
placeholder: placeholder
});
right.inject(inp);
}
div.inject([left, right]);
return div;
};
orgCreated = function(json, state) {
if (json.okay) {
return location.reload();
}
};
setDefaultOrg = function(orgid) {
return patch('account', {
email: userAccount.email,
defaultOrganisation: orgid
}, {}, defaultOrgChanged);
};
defaultOrgChanged = function(json, state) {
return window.setTimeout(function() {
return location.reload();
}, 1000);
};
makeOrg = function() {
var orgdesc, orgid, orgname;
orgname = get('orgname').value;
orgdesc = get('orgdesc').value;
orgid = get('orgid').value;
if (orgid.length === 0) {
orgid = parseInt(Math.random() * 987654321).toString(16);
}
if (orgname.length === 0) {
alert("Please enter a name for the organisation!");
return;
}
if (orgdesc.length === 0) {
alert("Please enter a description of the organisation!");
return;
}
return put('org/list', {
id: orgid,
name: orgname,
desc: orgdesc
}, {}, orgCreated);
};
orglist = function(json, state) {
var btn, dbtn, div, fieldset, isDefault, items, legend, len, obj, odiv, org, q, ref;
items = [];
if (json.organisations.length === 0) {
obj = new HTML('div');
obj.inject(new HTML('h3', {}, "You don't seem to belong to any organisations just yet."));
if (userAccount.userlevel === 'admin') {
obj.inject("...but you can make one!");
}
state.widget.inject(obj, true);
} else {
odiv = new HTML('div');
ref = json.organisations;
for (q = 0, len = ref.length; q < len; q++) {
org = ref[q];
isDefault = org.id === userAccount.defaultOrganisation;
div = new HTML('div', {
"class": "orgItem " + (isDefault ? "orgSelected" : "")
});
div.inject(new HTML('h1', {}, org.name + (isDefault ? " (Current)" : "")));
div.inject(new HTML('p', {}, org.description || ""));
div.inject([new HTML('kbd', {}, "" + org.docCount.pretty()), " objects collected from ", new HTML('kbd', {}, "" + org.sourceCount.pretty()), " sources so far."]);
odiv.inject(div);
if (!isDefault) {
dbtn = new HTML('input', {
style: {
marginTop: "10px",
width: "120px"
},
"class": "btn btn-primary btn-block",
type: "button",
onclick: "setDefaultOrg('" + org.id + "');",
value: "Set as current"
});
div.inject(dbtn);
}
odiv.inject(new HTML('hr'));
}
state.widget.inject(odiv, true);
}
if (userAccount.userlevel === "admin") {
fieldset = new HTML('fieldset', {
style: {
float: "left",
margin: '30px'
}
});
legend = new HTML('legend', {}, "Create a new orgsanisation:");
fieldset.inject(legend);
fieldset.inject(keyValueForm('text', 'orgname', 'Name of the organisation:', 'Foo, inc.'));
fieldset.inject(keyValueForm('textarea', 'orgdesc', 'Description:', 'Foo, inc. is awesome and does stuff.'));
fieldset.inject(keyValueForm('text', 'orgid', 'Optional org ID:', 'demo, myorg etc'));
fieldset.inject(new HTML('p', {}, "You'll be able to add users and owners once the organisation has been created."));
btn = new HTML('input', {
style: {
width: "200px"
},
"class": "btn btn-primary btn-block",
type: "button",
onclick: "makeOrg();",
value: "Create organisation"
});
fieldset.inject(btn);
return state.widget.inject(fieldset);
}
};
inviteMember = function(eml, admin) {
return put('org/members', {
email: eml,
admin: admin
}, null, memberInvited);
};
removeMember = function(eml, admin) {
return xdelete('org/members', {
email: eml,
admin: admin
}, null, memberInvited);
};
memberInvited = function(json, state) {
return window.setTimeout(function() {
return location.reload();
}, 1000);
};
membershipList = function(json, state) {
var admin, admopt, alink, btn, delopt, dlink, eml, h, inp, isAdmin, len, list, member, q, ref, tr;
h = new HTML('h3', {}, "Invite a member to " + userAccount.defaultOrganisation);
state.widget.inject(h, true);
inp = new HTML('input', {
id: "email",
type: "text",
placeholder: "email@ddres"
});
btn = new HTML('input', {
type: 'button',
"class": 'btn btn-success',
value: "Invite member",
onclick: 'inviteMember(get("email").value, false);'
});
state.widget.inject(inp);
state.widget.inject(btn);
state.widget.inject(new HTML('hr'));
h = new HTML('h3', {}, "Current membership of " + userAccount.defaultOrganisation + ":");
state.widget.inject(h);
list = new HTML('table', {
style: {
margin: "20px",
border: "1px solid #666"
}
});
ref = json.members;
for (q = 0, len = ref.length; q < len; q++) {
member = ref[q];
tr = new HTML('tr', {
style: {
borderBottom: "1px solid #666"
}
});
eml = new HTML('td', {
style: {
padding: "5px"
}
}, member);
isAdmin = indexOf.call(json.admins, member) >= 0;
admin = new HTML('td', {
style: {
padding: "5px"
}
}, isAdmin ? "Admin" : "Member");
alink = new HTML('a', {
href: "javascript:void(inviteMember('" + member + "', true));"
}, "Make admin");
if (isAdmin) {
alink = new HTML('a', {
href: "javascript:void(inviteMember('" + member + "', false));"
}, "Remove as admin");
}
admopt = new HTML('td', {
style: {
padding: "5px"
}
}, alink);
dlink = new HTML('a', {
href: "javascript:void(removeMember('" + member + "'));"
}, "Remove from organisation");
delopt = new HTML('td', {
style: {
padding: "5px"
}
}, dlink);
tr.inject(eml);
tr.inject(admin);
tr.inject(admopt);
tr.inject(delopt);
list.inject(tr);
}
return state.widget.inject(list);
};
API = 2;
Number.prototype.pad = function(n) {
var str;
str = String(this);
if (str.length < n) {
str = "0".repeat(n - str.length) + str;
}
return str;
};
Number.prototype.pretty = function(fix) {
if (fix) {
return String(this.toFixed(fix)).replace(/(\d)(?=(\d{3})+\.)/g, '$1,');
}
return String(this.toFixed(0)).replace(/(\d)(?=(\d{3})+$)/g, '$1,');
};
fetch = function(url, xstate, callback, nocreds) {
var xmlHttp;
xmlHttp = null;
if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
} else {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
if (!nocreds) {
xmlHttp.withCredentials = true;
}
xmlHttp.open("GET", "api/" + url, true);
xmlHttp.send(null);
return xmlHttp.onreadystatechange = function(state) {
var e, js, mpart, response;
if (xmlHttp.readyState === 4 && xmlHttp.status === 500) {
if (snap) {
snap(xstate);
}
return;
}
if (xmlHttp.readyState === 4 && xmlHttp.status >= 400) {
js = JSON.parse(xmlHttp.responseText);
if (js.code === 403) {
mpart = location.href.match(/\/\/[^\/]+\/(.+)$/)[1];
location.href = "login.html?redirect=" + mpart;
}
badModal(js.reason);
return;
}
if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
if (callback) {
try {
response = JSON.parse(xmlHttp.responseText);
return callback(response, xstate);
} catch (_error) {
e = _error;
return callback(JSON.parse(xmlHttp.responseText), xstate);
}
}
}
};
};
put = function(url, json, xstate, callback, nocreds) {
var xmlHttp;
if (nocreds == null) {
nocreds = false;
}
xmlHttp = null;
if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
} else {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
if (!nocreds) {
xmlHttp.withCredentials = true;
}
xmlHttp.open("PUT", "api/" + url, true);
xmlHttp.send(JSON.stringify(json || {}));
return xmlHttp.onreadystatechange = function(state) {
var e, js, response;
if (xmlHttp.readyState === 4 && xmlHttp.status === 500) {
if (snap) {
snap(xstate);
}
return;
}
if (xmlHttp.readyState === 4 && xmlHttp.status >= 400) {
js = JSON.parse(xmlHttp.responseText);
badModal(js.reason);
return;
}
if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
if (callback) {
try {
response = JSON.parse(xmlHttp.responseText);
if (response && response.loginRequired) {
location.href = "/login.html";
return;
}
return callback(response, xstate);
} catch (_error) {
e = _error;
return callback(JSON.parse(xmlHttp.responseText), xstate);
}
}
}
};
};
patch = function(url, json, xstate, callback, nocreds) {
var xmlHttp;
if (nocreds == null) {
nocreds = false;
}
xmlHttp = null;
if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
} else {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
if (!nocreds) {
xmlHttp.withCredentials = true;
}
xmlHttp.open("PATCH", "api/" + url, true);
xmlHttp.send(JSON.stringify(json || {}));
return xmlHttp.onreadystatechange = function(state) {
var e, js, response;
if (xmlHttp.readyState === 4 && xmlHttp.status === 500) {
if (snap) {
snap(xstate);
}
return;
}
if (xmlHttp.readyState === 4 && xmlHttp.status >= 400) {
js = JSON.parse(xmlHttp.responseText);
badModal(js.reason);
return;
}
if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
if (callback) {
try {
response = JSON.parse(xmlHttp.responseText);
if (response && response.loginRequired) {
location.href = "/login.html";
return;
}
return callback(response, xstate);
} catch (_error) {
e = _error;
return callback(JSON.parse(xmlHttp.responseText), xstate);
}
}
}
};
};
xdelete = function(url, json, xstate, callback, nocreds) {
var xmlHttp;
if (nocreds == null) {
nocreds = false;
}
xmlHttp = null;
if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
} else {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
if (!nocreds) {
xmlHttp.withCredentials = true;
}
xmlHttp.open("DELETE", "api/" + url, true);
xmlHttp.send(JSON.stringify(json || {}));
return xmlHttp.onreadystatechange = function(state) {
var e, js, response;
if (xmlHttp.readyState === 4 && xmlHttp.status === 500) {
if (snap) {
snap(xstate);
}
return;
}
if (xmlHttp.readyState === 4 && xmlHttp.status >= 400) {
js = JSON.parse(xmlHttp.responseText);
badModal(js.reason);
return;
}
if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
if (callback) {
try {
response = JSON.parse(xmlHttp.responseText);
if (response && response.loginRequired) {
location.href = "/login.html";
return;
}
return callback(response, xstate);
} catch (_error) {
e = _error;
return callback(JSON.parse(xmlHttp.responseText), xstate);
}
}
}
};
};
post = function(url, json, xstate, callback, snap) {
var fdata, key, val, xmlHttp;
xmlHttp = null;
if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
} else {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlHttp.withCredentials = true;
for (key in json) {
val = json[key];
if (val.match) {
if (val.match(/^\d+$/)) {
json[key] = parseInt(val);
}
if (val === 'true') {
json[key] = true;
}
if (val === 'false') {
json[key] = false;
}
}
}
fdata = JSON.stringify(json);
xmlHttp.open("POST", "api/" + url, true);
xmlHttp.setRequestHeader("Content-type", "application/json");
xmlHttp.send(fdata);
return xmlHttp.onreadystatechange = function(state) {
var e, response;
if (xmlHttp.readyState === 4 && xmlHttp.status === 500) {
if (snap) {
snap(xstate);
}
}
if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
if (callback) {
try {
response = JSON.parse(xmlHttp.responseText);
if (xstate && xstate.widget) {
xstate.widget.json = response;
}
return callback(response, xstate);
} catch (_error) {
e = _error;
return callback(JSON.parse(xmlHttp.responseText), xstate);
}
}
}
};
};
mk = function(t, s, tt) {
var k, len, q, r, v;
r = document.createElement(t);
if (s) {
for (k in s) {
v = s[k];
if (v) {
r.setAttribute(k, v);
}
}
}
if (tt) {
if (typeof tt === "string") {
app(r, txt(tt));
} else {
if (isArray(tt)) {
for (q = 0, len = tt.length; q < len; q++) {
k = tt[q];
if (typeof k === "string") {
app(r, txt(k));
} else {
app(r, k);
}
}
} else {
app(r, tt);
}
}
}
return r;
};
app = function(a, b) {
var item, len, q, results;
if (isArray(b)) {
results = [];
for (q = 0, len = b.length; q < len; q++) {
item = b[q];
if (typeof item === "string") {
item = txt(item);
}
results.push(a.appendChild(item));
}
return results;
} else {
return a.appendChild(b);
}
};
set = function(a, b, c) {
return a.setAttribute(b, c);
};
txt = function(a) {
return document.createTextNode(a);
};
get = function(a) {
return document.getElementById(a);
};
swi = function(obj) {
var switchery;
return switchery = new Switchery(obj, {
color: '#26B99A'
});
};
cog = function(div, size) {
var i, idiv;
if (size == null) {
size = 200;
}
idiv = document.createElement('div');
idiv.setAttribute("class", "icon");
idiv.setAttribute("style", "text-align: center; vertical-align: middle; height: 500px;");
i = document.createElement('i');
i.setAttribute("class", "fa fa-spin fa-cog");
i.setAttribute("style", "font-size: " + size + "pt !important; color: #AAB;");
idiv.appendChild(i);
idiv.appendChild(document.createElement('br'));
idiv.appendChild(document.createTextNode('Loading, hang on tight..!'));
div.innerHTML = "";
return div.appendChild(idiv);
};
globArgs = {};
theme = {
color: [],
title: {
itemGap: 8,
textStyle: {
fontWeight: 'normal',
color: '#408829'
}
},
dataRange: {
color: ['#1f610a', '#97b58d']
},
toolbox: {
color: ['#408829', '#408829', '#408829', '#408829']
},
tooltip: {
backgroundColor: 'rgba(0,0,0,0.5)',
axisPointer: {
type: 'line',
lineStyle: {
color: '#408829',
type: 'dashed'
},
crossStyle: {
color: '#408829'
},
shadowStyle: {
color: 'rgba(200,200,200,0.3)'
}
}
},
dataZoom: {
dataBackgroundColor: '#eee',
fillerColor: 'rgba(64,136,41,0.2)',
handleColor: '#408829'
},
grid: {
borderWidth: 0
},
categoryAxis: {
axisLine: {
lineStyle: {
color: '#408829'
}
},
splitLine: {
lineStyle: {
color: ['#eee']
}
}
},
valueAxis: {
axisLine: {
lineStyle: {
color: '#408829'
}
},
splitArea: {
show: true,
areaStyle: {
color: ['rgba(250,250,250,0.1)', 'rgba(200,200,200,0.1)']
}
},
splitLine: {
lineStyle: {
color: ['#eee']
}
}
},
timeline: {
lineStyle: {
color: '#408829'
},
controlStyle: {
normal: {
color: '#408829'
},
emphasis: {
color: '#408829'
}
}
},
k: {
itemStyle: {
normal: {
color: '#68a54a',
color0: '#a9cba2',
lineStyle: {
width: 1,
color: '#408829',
color0: '#86b379'
}
}
}
},
map: {
itemStyle: {
normal: {
areaStyle: {
color: '#ddd'
},
label: {
textStyle: {
color: '#c12e34'
}
}
},
emphasis: {
areaStyle: {
color: '#99d2dd'
},
label: {
textStyle: {
color: '#c12e34'
}
}
}
}
},
force: {
itemStyle: {
normal: {
linkStyle: {
strokeColor: '#408829'
}
}
}
},
chord: {
padding: 4,
itemStyle: {
normal: {
lineStyle: {
width: 1,
color: 'rgba(128, 128, 128, 0.5)'
},
chordStyle: {
lineStyle: {
width: 1,
color: 'rgba(128, 128, 128, 0.5)'
}
}
},
emphasis: {
lineStyle: {
width: 1,
color: 'rgba(128, 128, 128, 0.5)'
},
chordStyle: {
lineStyle: {
width: 1,
color: 'rgba(128, 128, 128, 0.5)'
}
}
}
}
},
gauge: {
startAngle: 225,
endAngle: -45,
axisLine: {
show: true,
lineStyle: {
color: [[0.2, '#86b379'], [0.8, '#68a54a'], [1, '#408829']],
width: 8
}
},
axisTick: {
splitNumber: 10,
length: 12,
lineStyle: {
color: 'auto'
}
},
axisLabel: {
textStyle: {
color: 'auto'
}
},
splitLine: {
length: 18,
lineStyle: {
color: 'auto'
}
},
pointer: {
length: '90%',
color: 'auto'
},
title: {
textStyle: {
color: '#333'
}
},
detail: {
textStyle: {
color: 'auto'
}
}
},
textStyle: {
fontFamily: 'Arial, Verdana, sans-serif'
}
};
isArray = function(value) {
return value && typeof value === 'object' && value instanceof Array && typeof value.length === 'number' && typeof value.splice === 'function' && !(value.propertyIsEnumerable('length'));
};
/* isHash: function to detect if an object is a hash */
isHash = function(value) {
return value && typeof value === 'object' && !isArray(value);
};
HTML = (function() {
function HTML(type, params, children) {
/* create the raw element, or clone if passed an existing element */
var child, key, len, q, subkey, subval, val;
if (typeof type === 'object') {
this.element = type.cloneNode();
} else {
this.element = document.createElement(type);
}
/* If params have been passed, set them */
if (isHash(params)) {
for (key in params) {
val = params[key];
/* Standard string value? */
if (typeof val === "string" || typeof val === 'number') {
this.element.setAttribute(key, val);
} else if (isArray(val)) {
/* Are we passing a list of data to set? concatenate then */
this.element.setAttribute(key, val.join(" "));
} else if (isHash(val)) {
/* Are we trying to set multiple sub elements, like a style? */
for (subkey in val) {
subval = val[subkey];
if (!this.element[key]) {
throw "No such attribute, " + key + "!";
}
this.element[key][subkey] = subval;
}
}
}
}
/* If any children have been passed, add them to the element */
if (children) {
/* If string, convert to textNode using txt() */
if (typeof children === "string") {
this.element.inject(txt(children));
} else {
/* If children is an array of elems, iterate and add */
if (isArray(children)) {
for (q = 0, len = children.length; q < len; q++) {
child = children[q];
/* String? Convert via txt() then */
if (typeof child === "string") {
this.element.inject(txt(child));
} else {
/* Plain element, add normally */
this.element.inject(child);
}
}
} else {
/* Just a single element, add it */
this.element.inject(children);
}
}
}
return this.element;
}
return HTML;
})();
/**
* prototype injector for HTML elements:
* Example: mydiv.inject(otherdiv)
*/
HTMLElement.prototype.inject = function(child) {
var item, len, q;
if (isArray(child)) {
for (q = 0, len = child.length; q < len; q++) {
item = child[q];
if (typeof item === 'string') {
item = txt(item);
}
this.appendChild(item);
}
} else {
if (typeof child === 'string') {
child = txt(child);
}
this.appendChild(child);
}
return child;
};
Date.prototype.ISOBare = function() {
var M, d, h, m, y;
y = this.getFullYear();
m = (this.getMonth() + 1).pad(2);
d = this.getDate().pad(2);
h = this.getHours().pad(2);
M = this.getMinutes().pad(2);
return y + "-" + m + "-" + d + " " + h + ":" + M;
};
userAccount = {
foundation: "public"
};
pageID = 0;
APIVERSION = 3;
setupPage = function(json, state) {
var child, div, k, len, q, r, ref, results, row, v, widget;
$('#placeholder').remove();
if (json.error) {
div = document.getElementById('innercontents');
div.style.textAlign = 'center';
div.innerHTML = "<a style='color: #D44; font-size: 100pt;'><i class='fa fa-warning'></i></a><br/><h3>An error occurred:</h3><p style='font-size: 12pt;'>" + json.error + "</p>";
return;
}
document.title = json.title + " - Apache Warble";
ref = json.rows;
results = [];
for (q = 0, len = ref.length; q < len; q++) {
r = ref[q];
row = new Row();
results.push((function() {
var len1, ref1, ref2, ref3, ref4, ref5, results1, u;
ref1 = r.children;
results1 = [];
for (u = 0, len1 = ref1.length; u < len1; u++) {
child = ref1[u];
widget = new Widget(child.blocks || 3, child);
if (state.gargs) {
widget.args.eargs = widget.args.eargs || {};
ref2 = state.gargs;
for (k in ref2) {
v = ref2[k];
widget.args.eargs[k] = v;
}
}
widget.parent = row;
row.inject(widget);
if (child.eargs) {
ref3 = child.eargs;
for (k in ref3) {
v = ref3[k];
widget.args.eargs[k] = v;
}
}
if (child.wargs) {
widget.wargs = {};
ref4 = child.wargs;
for (k in ref4) {
v = ref4[k];
widget.wargs[k] = v;
}
}
if ((ref5 = child.type) !== 'views' && ref5 !== 'sourcelist') {
widget.args.eargs.quick = 'true';
}
switch (child.type) {
case 'datepicker':
results1.push(datepicker(widget));
break;
case 'sourcepicker':
results1.push(widget.load(sourceexplorer));
break;
case 'repopicker':
results1.push(widget.load(explorer));
break;
case 'mailpicker':
results1.push(widget.load(mailexplorer));
break;
case 'issuepicker':
results1.push(widget.load(issueexplorer));
break;
case 'forumpicker':
results1.push(widget.load(forumexplorer));
break;
case 'viewpicker':
results1.push(widget.load(viewexplorer));
break;
case 'logpicker':
results1.push(widget.load(logexplorer));
break;
case 'impicker':
results1.push(widget.load(imexplorer));
break;
case 'logpicker':
results1.push(widget.load(logexplorer));
break;
case 'cipicker':
results1.push(widget.load(ciexplorer));
break;
case 'widgetpicker':
results1.push(widget.load(widgetexplorer));
break;
case 'multiviewpicker':
results1.push(widget.load(multiviewexplorer));
break;
case 'donut':
results1.push(widget.load(donut));
break;
case 'gauge':
results1.push(widget.load(gauge));
break;
case 'widget':
results1.push(widget.load(publisher));
break;
case 'radar':
results1.push(widget.load(radar));
break;
case 'top5':
results1.push(widget.load(top5));
break;
case 'factors':
results1.push(widget.load(factors));
break;
case 'trends':
results1.push(widget.load(trend));
break;
case 'line':
results1.push(widget.load(linechart));
break;
case 'bio':
results1.push(widget.load(bio));
break;
case 'messages':
results1.push(widget.load(messages));
break;
case 'sourcelist':
results1.push(widget.load(sourcelist));
break;
case 'sourceadd':
results1.push(widget.load(sourceadd));
break;
case 'contacts':
results1.push(setupPhonebook(widget, child));
break;
case 'preferences':
results1.push(widget.load(preferences));
break;
case 'orgadmin':
results1.push(widget.load(orgadmin));
break;
case 'affiliations':
results1.push(widget.load(affiliation));
break;
case 'views':
results1.push(widget.load(manageviews));
break;
case 'paragraph':
results1.push(widget.load(paragraph));
break;
case 'relationship':
results1.push(widget.load(relationship));
break;
case 'treemap':
results1.push(widget.load(treemap));
break;
case 'report':
results1.push(widget.load(report));
break;
case 'mvp':
results1.push(widget.load(mvp));
break;
case 'comstat':
results1.push(widget.load(comstat));
break;
case 'worldmap':
results1.push(widget.load(worldmap));
break;
case 'orglist':
results1.push(widget.load(orglist));
break;
case 'membership':
results1.push(widget.load(membershipList));
break;
case 'jsondump':
results1.push(widget.load(jsondump));
break;
case 'clientlist':
results1.push(widget.load(clientlist));
break;
default:
results1.push(void 0);
}
}
return results1;
})());
}
return results;
};
loadPageWidgets = function(page, apiVersion) {
var col, i, idiv, m, ph;
if (!page) {
page = window.location.search.substr(1);
}
if (apiVersion) {
APIVERSION = apiVersion;
}
ph = document.createElement('div');
ph.setAttribute("class", "row");
ph.setAttribute("id", "placeholder");
col = document.createElement('div');
col.setAttribute("class", "col-md-12");
ph.appendChild(col);
idiv = document.createElement('div');
idiv.setAttribute("class", "icon");
idiv.setAttribute("style", "text-align: center; vertical-align: middle; height: 500px;");
i = document.createElement('i');
i.setAttribute("class", "fa fa-spin fa-cog");
i.setAttribute("style", "font-size: 240pt !important; color: #AAB;");
idiv.appendChild(i);
idiv.appendChild(document.createElement('br'));
idiv.appendChild(document.createTextNode('Loading, hang on tight..!'));
col.appendChild(idiv);
ph.appendChild(col);
document.getElementById('innercontents').innerHTML = "";
document.getElementById('innercontents').appendChild(ph);
while (page.match(/([^=]+)=([^=&]+)&?/)) {
m = page.match(/([^=]+)=([^&=]+)&?/);
if (m) {
console.log(m[1] + "=" + m[2]);
globArgs[m[1]] = unescape(m[2]);
page = page.replace(m[0], '');
}
}
if (globArgs.page) {
pageID = globArgs.page;
}
if (globArgs.view) {
$("a").each(function() {
var url;
url = $(this).attr('href');
m = url.match(/^(.+\?page=[-a-z]+)(?:&view=[a-f0-9]+)?(.*)$/);
if (m) {
if (globArgs.view) {
return $(this).attr('href', m[1] + "&view=" + globArgs.view + m[2]);
}
}
});
}
return fetch('session', null, renderAccountInfo);
};
renderAccountInfo = function(json, state) {
var div;
if (json.error) {
div = document.getElementById('innercontents');
div.style.textAlign = 'center';
div.innerHTML = "<a style='color: #D44; font-size: 100pt;'><i class='fa fa-warning'></i></a><br/><h3>An error occurred:</h3><p style='font-size: 12pt;'>" + json.error + "</p>";
if (json.loginRequired) {
return location.href = "/login.html";
}
} else {
userAccount = json;
return fetch('widgets/' + pageID, {
gargs: globArgs
}, setupPage);
}
};
phonebook_cached = {};
fetchPhonebook = function(args) {
var url, wargs;
if (args) {
wargs = JSON.stringify(args);
if (phonebook_cached[wargs]) {
renderPhonebook(phonebook_cached[wargs], args);
return;
}
}
args.widget.cog();
url = "people/";
return postJSON(url, args, args, renderPhonebook);
};
setupPhonebook = function(widget, w) {
return fetchPhonebook({
widget: widget,
w: w,
letter: 'a',
project: w.target || ""
});
};
renderPhonebook = function(json, state) {
var a, imgsrc, len, len1, letter, letters, li, people, person, q, rdiv, ref, row, tbl, u, ul, wargs;
wargs = JSON.stringify(state);
phonebook_cached[wargs] = json;
letters = "abcdefghijklmnopqrstuvwxyz".split("");
row = document.createElement('div');
row.setAttribute("class", "row");
rdiv = document.createElement('div');
rdiv.setAttribute("class", "col-md-12 col-sm-12 col-xs-12 text-center");
ul = document.createElement('ul');
ul.setAttribute("class", "pagination pagination-split");
for (q = 0, len = letters.length; q < len; q++) {
letter = letters[q];
li = document.createElement('li');
a = document.createElement('a');
a.setAttribute("href", "#");
a.addEventListener("click", function() {
state.letter = this.childNodes[0].data.toLowerCase();
return fetchPhonebook(state);
}, false);
a.appendChild(document.createTextNode(letter.toUpperCase()));
if (state.letter && letter === state.letter) {
li.setAttribute("class", "active");
}
li.appendChild(a);
ul.appendChild(li);
}
rdiv.appendChild(ul);
row.appendChild(rdiv);
state.widget.inject(row, true);
row = mk('table', {
"class": "display"
}, mk('thead', {}, mk('tr', {}, [mk('th', {}, 'Avatar'), mk('th', {}, 'Name'), mk('th', {}, 'Email')])));
people = [];
json.people.sort((function(_this) {
return function(a, b) {
if (a.name === b.name) {
return 0;
} else {
if (a.name > b.name) {
return 1;
} else {
return -1;
}
}
};
})(this));
a = 0;
ref = json.people;
for (u = 0, len1 = ref.length; u < len1; u++) {
person = ref[u];
a++;
imgsrc = document.createElement('img');
imgsrc.setAttribute("class", "img-circle img-responsive");
imgsrc.setAttribute("onshow", "this.src = 'https://secure.gravatar.com/avatar/" + person.md5 + ".png?d=identicon'");
people.push(["https://secure.gravatar.com/avatar/" + person.md5 + ".png?d=identicon", person.name, person.email]);
}
state.widget.inject(row);
return tbl = $(row).DataTable({
serverSide: true,
searching: false,
lengthMenu: [[25, 50, 100], [25, 50, 100]],
columnDefs: [
{
targets: 0,
data: "avatar",
render: function(data, type, full, meta) {
return '<img class="img-circle img-responsive" style="width: 24px; height: 24px;" src="' + full[0] + '"/>';
}
}, {
targets: 1,
data: "email",
render: function(data, type, full, meta) {
return '<a href="?page=people&email=' + full[2] + '">' + full[1] + "</a>";
}
}
],
ajax: function(data, callback, settings) {
var aa, i, out, ref1, ref2;
out = [];
for (i = aa = ref1 = data.start, ref2 = data.start + data.length; ref1 <= ref2 ? aa < ref2 : aa > ref2; i = ref1 <= ref2 ? ++aa : --aa) {
out.push(people[i]);
}
return setTimeout(function() {
return callback({
draw: data.draw,
data: out,
recordsTotal: people.length,
recordsFiltered: people.length
});
}, 50);
}
}, {
scrollY: 200,
scroller: {
loadingIndicator: true
}
});
/*
card = document.createElement('div')
card.setAttribute("class", "col-md-3 col-sm-4 col-xs-12 profile_details")
well = document.createElement('div')
well.setAttribute("class", "well profile_view")
well.style.width = "100%"
card.appendChild(well)
namecard = document.createElement('div')
namecard.setAttribute("class", "left col-xs-7")
img = document.createElement('div')
img.setAttribute("class", "right col-xs-5 text-center")
imgsrc = document.createElement('img')
imgsrc.setAttribute("class", "img-circle img-responsive")
imgsrc.setAttribute("src", "https://secure.gravatar.com/avatar/" + person.md5 + ".png?d=identicon")
img.appendChild(imgsrc)
well.appendChild(namecard)
well.appendChild(img)
a = document.createElement('a')
a.setAttribute('href', '?page=people&email=' + person.email)
name = document.createElement('h2')
name.appendChild(document.createTextNode(person.name))
a.appendChild(name)
namecard.appendChild(a)
namecard.appendChild(document.createTextNode(person.email))
groups = []
if person.tags
for tag in person.tags
if tag != '_untagged'
groups.push(tag)
if groups.length > 0
namecard.appendChild(mk('br'))
namecard.appendChild(txt("Part of: " + groups.join(", ")))
row.appendChild(card)
*/
};
addsources = function(form) {
var creds, json, len, line, lines, noclone, q, rv;
rv = get('retval');
cog(rv);
json = {
action: 'add',
sources: []
};
lines = form.sources.value.split(/\r?\n/g);
creds = null;
noclone = false;
if (form.noclone.checked) {
noclone = true;
}
if (form.auth.checked) {
creds = {
type: form.atype.value,
username: form.auser.value,
password: form.apass.value,
cookie: form.acookie.value
};
}
for (q = 0, len = lines.length; q < len; q++) {
line = lines[q];
if (line.length > 5) {
json.sources.push({
organisation: userAccount.organisation,
sourceURL: line,
type: form.stype.value,
creds: creds,
noclone: noclone
});
}
}
put('sources', json, null, sourceret);
return false;
};
redirs = function() {
return location.href = '?page=sources';
};
sourceret = function(json, state) {
var rv;
rv = get('retval');
if (json.completed) {
rv.style.fontSize = "20pt";
rv.style.color = "#383";
json.added = json.added || 0;
rv.innerHTML = json.added + " sources added";
if (json.updated && json.updated > 0) {
rv.innerHTML += ", " + json.updated + " updated.";
}
if (json.unknowns && json.unknowns > 0) {
rv.innerHTML += ", " + json.unknowns + " sources could not be added (unknown source type?)";
}
return window.setTimeout(redirs, 2000);
} else {
rv.style.fontSize = "20pt";
rv.style.color = "#843";
return rv.innerHTML = "<h2>Error: </h2>" + json.error;
}
};
deletesource = function(hash) {
var tr;
if (window.confirm("Are you sure you wish to delete this resource?\nNOTE: Not everything about this can be deleted. Due to the nature of especially git, the unique commit stats will NOT change when you delete a git resource until you force a complete reindex of everything.")) {
tr = get(hash);
tr.parentNode.removeChild(tr);
return xdelete('sources', {
id: hash
}, null, null);
}
};
sourceTypes = {};
getSourceType = function(main, t) {
var el, len, obj, q, ref, tbl, tbody, td, thead, tr;
if (!sourceTypes[t]) {
obj = new HTML('div', {
id: "source_" + t,
style: {
display: "none"
}
});
tbl = mk('table');
set(tbl, 'class', 'table table-striped');
thead = mk('thead');
tr = mk('tr');
ref = ['Source', 'Progress', 'Last Update', 'Status', 'Actions'];
for (q = 0, len = ref.length; q < len; q++) {
el = ref[q];
td = mk('th');
if (el.match(/Last/)) {
td.style.width = "200px";
td.style.textAlign = 'right';
}
if (el.match(/Status/)) {
td.style.width = "600px";
}
app(td, txt(el));
app(tr, td);
}
app(thead, tr);
app(tbl, thead);
tbody = new HTML('tbody');
app(tbl, tbody);
obj.inject(tbl);
main.inject(obj);
sourceTypes[t] = {
main: obj,
div: tbody,
count: 0
};
}
return sourceTypes[t];
};
sourcelist = function(json, state) {
var aa, ab, act, borked, cl, color, d, dbtn, desc, div, el, firstRun, h, ic, icons, img, item, lastException, lastFailure, lastUpdate, len, len1, len2, len3, lu, m, q, ref, ref1, ref2, ref3, ref4, ref5, retval, running, slist, source, sources, st, status, steps, t, tbody, u, vlist;
slist = mk('div');
vlist = new HTML('div');
if (json.sources) {
sources = json.sources;
for (q = 0, len = sources.length; q < len; q++) {
source = sources[q];
source.good = true;
source.running = false;
steps = ['sync', 'census', 'count', 'evolution'];
if (source.type === 'mail') {
steps = ['mail'];
}
if ((ref = source.type) === 'jira' || ref === 'bugzilla') {
steps = ['issues'];
}
if ((ref1 = source.type) === 'irc') {
steps = ['census'];
}
if (source.type === 'gerrit' || source.type === 'github') {
steps = ['issues', 'sync', 'census', 'count', 'evolution'];
}
for (u = 0, len1 = steps.length; u < len1; u++) {
item = steps[u];
if (source.steps) {
if (source.steps[item] && source.steps[item].good === false) {
source.good = false;
}
if (source.steps[item] && source.steps[item].running) {
source.running = true;
}
}
}
}
sources = sources.sort ? sources : [];
sources.sort(function(a, b) {
return (a.running === b.running ? (a.good === b.good ? (a.sourceURL > b.sourceURL ? 1 : -1) : (b.good === true ? -1 : 1)) : (b.running === true ? 1 : -1));
});
for (aa = 0, len2 = sources.length; aa < len2; aa++) {
source = sources[aa];
st = getSourceType(vlist, source.type);
tbody = st.div;
st.count++;
d = mk('tr');
set(d, 'id', source.sourceID);
set(d, 'scope', 'row');
t = mk('td');
t.style.color = "#369";
app(t, txt(source.sourceURL));
app(d, t);
lastUpdate = 0;
lastFailure = null;
lastException = null;
running = null;
firstRun = 0;
icons = {
sync: 'fa fa-download',
census: 'fa fa-users',
count: 'fa fa-sitemap',
evolution: 'fa fa-signal',
mail: 'fa fa-envelope',
issues: 'fa fa-feed'
};
t = new HTML('td', {
style: {
minWidth: "260px !important"
}
});
borked = false;
steps = ['sync', 'census', 'count', 'evolution'];
if ((ref2 = source.type) === 'mail' || ref2 === 'ponymail' || ref2 === 'pipermail' || ref2 === 'hyperkitty') {
steps = ['mail'];
}
if ((ref3 = source.type) === 'jira' || ref3 === 'bugzilla') {
steps = ['issues'];
}
if ((ref4 = source.type) === 'gerrit' || ref4 === 'gitlab' || ref4 === 'github') {
steps = ['sync', 'census', 'count', 'evolution', 'issues'];
}
if ((ref5 = source.type) === 'irc' || ref5 === 'stats') {
steps = ['census'];
}
for (ab = 0, len3 = steps.length; ab < len3; ab++) {
item = steps[ab];
color = "#394";
cl = icons[item];
if (!source.steps || !source.steps[item] || borked) {
color = "#777";
desc = item + ": This step hasn't completed yet";
} else {
if (source.steps[item].time > lastUpdate) {
lastUpdate = source.steps[item].time;
}
desc = source.steps[item].status;
if (source.steps[item].good === false) {
borked = true;
color = "#952";
lastFailure = source.steps[item].status;
lastException = source.steps[item].exception;
}
if (source.steps[item].running) {
cl += " fa-bubble";
running = source.steps[item].status;
color = "#359";
}
}
ic = mk('i');
ic.style.padding = "10px";
ic.style.fontSize = "20pt";
set(ic, 'class', cl);
set(ic, 'title', desc);
ic.style.color = color;
app(t, ic);
}
if (borked) {
set(t, 'data-steps-failure', 'true');
} else {
set(t, 'data-steps-failure', 'false');
}
t.style.minWidth = "260px";
app(d, t);
lu = "Unknown";
if (lastUpdate > 0) {
lu = "";
t = (new Date().getTime() / 1000) - lastUpdate;
h = Math.floor(t / 3600);
m = Math.floor((t % 3600) / 60);
if (h > 0) {
lu = h + " hour" + (h === 1 ? '' : 's') + ", ";
}
lu += m + " minute" + (m === 1 ? '' : 's') + " ago.";
}
t = mk('td');
t.style.textAlign = 'right';
t.style.color = "#963";
t.style.width = "200px !important";
app(t, txt(lu));
app(d, t);
status = mk('td');
status.style.width = "600px !important";
if (lastFailure) {
status.style.color = "#843";
app(status, txt(lastFailure));
if (lastException) {
app(status, mk('br'));
app(status, txt("Exception: " + lastException));
}
app(d, status);
} else {
if (lastUpdate === 0) {
app(status, txt("Source hasn't been processed yet..."));
} else {
if (running) {
app(status, txt(running));
} else {
app(status, txt("No errors detected."));
}
}
app(d, status);
}
act = mk('td');
dbtn = mk('button');
set(dbtn, 'class', 'btn btn-danger');
set(dbtn, 'onclick', 'deletesource("' + source.sourceID + '");');
dbtn.style.padding = "2px";
app(dbtn, txt("Delete"));
app(act, dbtn);
app(d, act);
tbody.inject(d);
}
for (t in sourceTypes) {
el = sourceTypes[t];
div = new HTML('div', {
"class": "sourceTypeIcon",
onclick: "showType('" + t + "');"
});
el.btn = div;
img = new HTML('img', {
src: "images/sourcetypes/" + t + ".png",
style: {
width: "32px",
margin: "2px",
cursor: "pointer"
},
title: t
});
div.inject(img);
div.inject(" " + t + ": " + el.count);
slist.inject(div);
}
}
state.widget.inject(slist, true);
state.widget.inject(vlist);
retval = mk('div');
set(retval, 'id', 'retval');
state.widget.inject(retval);
return showType(true);
};
showType = function(t) {
var el, results, st;
results = [];
for (st in sourceTypes) {
el = sourceTypes[st];
if (st === t || t === true) {
t = "blargh";
el.btn.className = "sourceTypeIcon selected";
results.push(el.main.style.display = "block");
} else {
el.btn.className = "sourceTypeIcon";
results.push(el.main.style.display = "none");
}
}
return results;
};
addSourceType = function(t) {
var el, results, st;
results = [];
for (st in aSourceTypes) {
el = aSourceTypes[st];
if (st === t) {
results.push(el.style.display = "block");
} else {
results.push(el.style.display = "none");
}
}
return results;
};
aSourceTypes = {};
st = {};
sourceadd = function(json, state) {
var abit, btn, div, el, k, lbl, len, obj, opt, q, ref, results, type, v;
div = new HTML('div', {
style: {
position: "relative"
}
});
div.inject(new HTML('h3', {}, "Source type:"));
st = json;
for (type in json) {
el = json[type];
aSourceTypes[type] = new HTML('form', {
style: {
float: "left",
background: "#FFE",
border: "2px solid #333",
margin: "20px",
borderRadius: "10px",
padding: "20px",
display: "none"
}
});
obj = aSourceTypes[type];
obj.inject(new HTML("h4", {}, el.title + ":"));
opt = new HTML('input', {
onclick: "addSourceType('" + type + "');",
type: "radio",
id: "type_" + type,
name: "type",
style: {
width: "16px",
height: "16px"
}
});
lbl = new HTML('label', {
'for': "type_" + type,
style: {
marginRight: "20px"
}
}, [
new HTML('img', {
src: "images/sourcetypes/" + type + ".png",
width: "32",
height: "32"
}), type
]);
div.inject(opt);
div.inject(lbl);
obj.inject(new HTML('p', {}, el.description || ""));
obj.inject(keyValueForm('textarea', 'source', 'Source URL/ID:', "For example: " + el.example + ". You can add multiple sources, one per line."));
if (el.optauth) {
obj.inject((el.authrequired ? "Required" : "Optional") + " authentication options:");
ref = el.optauth;
for (q = 0, len = ref.length; q < len; q++) {
abit = ref[q];
obj.inject(keyValueForm('text', "" + abit, abit));
}
}
btn = new HTML('input', {
"class": "btn btn-primary btn-block",
type: "button",
onclick: "addSources('" + type + "', this.form);",
value: "Add source(s)"
});
obj.inject(btn);
}
state.widget.inject(div, true);
results = [];
for (k in aSourceTypes) {
v = aSourceTypes[k];
results.push(state.widget.inject(v));
}
return results;
};
sourceAdded = function(json, state) {
return window.setTimeout(function() {
return location.reload();
}, 1000);
};
addSources = function(type, form) {
var el, js, jsa, len, len1, lineNo, q, re, ref, ref1, source, u;
jsa = [];
lineNo = 0;
re = new RegExp(st[type].regex);
ref = form.elements.namedItem('source').value.split(/\r?\n/);
for (q = 0, len = ref.length; q < len; q++) {
source = ref[q];
lineNo++;
if (!source.match(re)) {
alert("Source on line " + lineNo + " does not match the required source regex " + st[type].regex + "!");
return false;
}
js = {
type: type,
sourceURL: source
};
ref1 = form.elements;
for (u = 0, len1 = ref1.length; u < len1; u++) {
el = ref1[u];
if (el.name.length > 0 && el.name !== 'source') {
js[el.name] = el.value;
}
}
jsa.push(js);
}
return put('sources', {
sources: jsa
}, {}, sourceAdded);
};
WarbleLoginCallback = function(json, state) {
var m;
userAccount = json;
m = location.href.match(/\?redirect=(.+)$/);
if (m && !m[1].match(/:/)) {
return location.href = m[1];
} else {
return location.href = "/dashboard.html?page=frontpage";
}
};
WarbleLogin = function(user, password) {
put("session", {
username: user,
password: password
}, null, WarbleLoginCallback);
return false;
};
signout = function() {
return xdelete('session', {}, {}, function() {
return location.href = 'login.html';
});
};
clientTypes = {};
showClientType = function(t) {
var el, results;
results = [];
for (st in clientTypes) {
el = clientTypes[st];
if (st === t || t === true) {
t = "blargh";
el.btn.className = "sourceTypeIcon selected";
results.push(el.main.style.display = "block");
} else {
el.btn.className = "sourceTypeIcon";
results.push(el.main.style.display = "none");
}
}
return results;
};
makeClientType = function(main, t) {
var el, len, obj, q, ref, tbl, tbody, td, thead, tr;
if (!clientTypes[t]) {
obj = new HTML('div', {
id: "client_" + t,
style: {
display: "block"
}
});
tbl = mk('table');
set(tbl, 'class', 'table table-striped');
thead = mk('thead');
tr = mk('tr');
ref = ['ID', 'IP', 'Hostname / Fingerprint', 'Location', 'Verified', 'Enabled', 'Last Ping', 'Actions'];
for (q = 0, len = ref.length; q < len; q++) {
el = ref[q];
td = mk('th');
if (el.match(/Hostname/)) {
td.style.width = "200px";
}
if (el.match(/Location/)) {
td.style.minWidth = "300px";
}
if (el.match(/Actions/)) {
td.style.minWidth = "240px";
}
app(td, txt(el));
app(tr, td);
}
app(thead, tr);
app(tbl, thead);
tbody = new HTML('tbody');
app(tbl, tbody);
obj.inject(tbl);
main.inject(obj);
clientTypes[t] = {
main: obj,
div: tbody,
count: 0
};
}
return clientTypes[t];
};
modifyNode = function(id, stats) {
stats['id'] = id;
return post('node/modify', stats, {}, location.reload());
};
deleteNode = function(id, stats) {
if (confirm('Are you sure you wish to delete this node?')) {
return xdelete('node/modify', {
id: id
}, {}, location.reload());
}
};
nodeVal = function(id, obj, t) {
var ip, loc;
if (!document.getElementById("node_" + t + "_tmp_" + id)) {
loc = obj.innerText;
obj.innerHTML = "";
ip = new HTML('input', {
style: {
color: '#333',
width: '320px',
height: '24px',
padding: '0px'
},
data: loc,
id: "node_" + t + "_tmp_" + id,
type: 'text',
onkeydown: "saveNodeValue(" + id + ", this, event, '" + t + "');",
onblur: "savedNodeValue({}, {id: " + id + ", type: '" + t + "', " + t + ": this.getAttribute('data')});"
});
ip.value = loc;
app(obj, ip);
return ip.focus();
}
};
saveNodeValue = function(id, obj, e, t) {
var js, jsx, nval;
if (e.key === 'Enter') {
nval = obj.value;
js = {
id: id
};
jsx = {
id: id,
type: t
};
js[t] = nval;
jsx[t] = nval;
return post('node/modify', js, jsx, savedNodeValue);
} else if (e.key === 'Escape') {
js = {
id: id
};
jsx = {
id: id,
type: t
};
js[t] = obj.getAttribute('data');
jsx[t] = obj.getAttribute('data');
return savedNodeValue(js, jsx);
}
};
savedNodeValue = function(json, state) {
var obj;
obj = document.getElementById("node_" + state.type + "_" + state.id);
obj.innerHTML = "";
return app(obj, txt(state[state.type]));
};
nodeStatusSort = (function(_this) {
return function(a, b) {
if (a.enabled && !b.enabled) {
return -1;
}
if (b.enabled && !a.enabled) {
return 1;
}
if (a.verified && !b.verified) {
return -1;
}
if (b.verified && !a.verified) {
return 1;
}
return a.hostname.localeCompare(b.hostname);
};
})(this);
clientlist = function(json, state) {
var banner, btn, card, d, hn, len, line, lline, lp, q, retval, rline, slist, source, sources, vlist, vrf;
slist = mk('div');
vlist = new HTML('div');
if (json.nodes) {
sources = json.nodes;
sources = sources.sort ? sources : [];
sources.sort(nodeStatusSort);
for (q = 0, len = sources.length; q < len; q++) {
source = sources[q];
card = new HTML('div', {
"class": 'clientcard'
});
banner = new HTML('div', {
"class": 'banner'
});
rline = new HTML('div', {
style: {
float: 'right',
width: '300px',
textAlign: 'center'
}
});
lline = new HTML('div', {
style: {
float: 'left',
width: '500px',
textAlign: 'center'
}
});
hn = new HTML('span', {
title: 'Click to edit',
id: "node_hostname_" + source.id,
onclick: "nodeVal(" + source.id + ", this, 'hostname');"
}, txt(source.hostname || "(unknown)"));
lline.inject(hn);
vrf = [];
if (!source.verified) {
card.setAttribute('class', 'clientcard orange');
vrf = [
'Unverified Node', new HTML('button', {
"class": 'btn btn-sm btn-primary',
onclick: "modifyNode(" + source.id + ", {verified: true, enabled: true});"
}, "Verify + Enable")
];
rline.inject(vrf);
btn = new HTML('button', {
title: 'Delete node',
"class": 'btn btn-square btn-danger',
style: {
position: 'relative',
float: 'right',
display: 'inline-block'
},
onclick: "deleteNode(" + source.id + ");"
}, new HTML('i', {
"class": 'fa fa-trash'
}, ''));
rline.inject(btn);
}
if (source.verified) {
vrf = [];
card.setAttribute('class', 'clientcard green');
if (source.enabled) {
vrf = [
'Active', new HTML('button', {
"class": 'btn btn-sm btn-warning',
onclick: "modifyNode(" + source.id + ", {enabled: false});"
}, "Disable")
];
} else {
card.setAttribute('class', 'clientcard grey');
vrf = [
'Disabled', new HTML('button', {
"class": 'btn btn-sm btn-primary',
onclick: "modifyNode(" + source.id + ", {enabled: true});"
}, "Re-enable")
];
}
rline.inject(vrf);
btn = new HTML('button', {
title: 'Delete node',
"class": 'btn btn-square btn-danger',
style: {
position: 'relative',
float: 'right',
display: 'inline-block'
},
onclick: "deleteNode(" + source.id + ");"
}, new HTML('i', {
"class": 'fa fa-trash'
}, ''));
rline.inject(btn);
}
banner.inject(lline);
banner.inject(rline);
card.inject(banner);
vlist.inject(card);
d = new HTML('p');
card.inject(d);
line = new HTML('div', {
"class": 'clientcardline'
});
line.inject([new HTML('b', {}, "Node ID: "), txt(source.id)]);
d.inject(line);
line = new HTML('div', {
"class": 'clientcardline'
});
line.inject([new HTML('b', {}, "Node IP: "), txt(source.ip)]);
d.inject(line);
line = new HTML('div', {
"class": 'clientcardline'
});
line.inject([new HTML('b', {}, "Fingerprint: "), new HTML('kbd', {}, source.fingerprint)]);
d.inject(line);
line = new HTML('div', {
"class": 'clientcardline'
});
line.inject([
new HTML('b', {}, "Location: "), new HTML('span', {
title: 'Click to edit',
id: "node_location_" + source.id,
onclick: "nodeVal(" + source.id + ", this, 'location');"
}, txt(source.location || "(unknown)"))
]);
d.inject(line);
line = new HTML('div', {
"class": 'clientcardline'
});
line.inject([
new HTML('b', {}, "Notes: "), new HTML('span', {
title: 'Click to edit',
id: "node_description_" + source.id,
onclick: "nodeVal(" + source.id + ", this, 'description');"
}, txt(source.description || "(none)"))
]);
d.inject(line);
line = new HTML('div', {
"class": 'clientcardline'
});
lp = new Date(source.lastping * 1000.0);
line.inject([new HTML('b', {}, "Last Active: "), txt(moment(lp).fromNow() + " (" + lp.ISOBare() + ")")]);
d.inject(line);
}
}
state.widget.inject(slist, true);
state.widget.inject(vlist);
retval = mk('div');
set(retval, 'id', 'retval');
state.widget.inject(retval);
return showType(true);
};
orgadmin = function(json, state) {
var btn, div, h2, h4, id, inp, obj, pdiv, title;
if (globArgs.org && json.admin[globArgs.org]) {
pdiv = document.createElement('div');
id = globArgs.org;
title = json.admin[id];
h2 = mk('h2');
app(h2, txt("Editing: " + title));
app(pdiv, h2);
obj = mk('form');
h4 = mk('h4');
app(h4, txt("Invite a new user to this org:"));
app(obj, h4);
div = mk('div');
app(div, txt("Username (email): "));
inp = mk('input');
set(inp, 'type', 'text');
set(inp, 'name', 'who');
inp.style.width = "200px";
app(div, inp);
app(obj, div);
div = mk('div');
app(div, txt("Make administrator: "));
inp = mk('input');
set(inp, 'type', 'checkbox');
set(inp, 'name', 'admin');
set(inp, 'value', 'true');
app(div, inp);
app(obj, div);
btn = mk('input');
set(btn, 'type', 'button');
set(btn, 'onclick', 'addorguser(this.form)');
set(btn, 'value', "Add user");
app(obj, btn);
app(pdiv, obj);
obj = mk('form');
h4 = mk('h4');
app(h4, txt("Remove a user from the org:"));
app(obj, h4);
div = mk('div');
app(div, txt("Username (email): "));
inp = mk('input');
set(inp, 'type', 'text');
set(inp, 'name', 'who');
inp.style.width = "200px";
app(div, inp);
app(obj, div);
div = mk('div');
app(div, txt("Just remove admin privs (if any): "));
inp = mk('input');
set(inp, 'type', 'checkbox');
set(inp, 'name', 'admin');
set(inp, 'value', 'true');
app(div, inp);
app(obj, div);
btn = mk('input');
set(btn, 'type', 'button');
set(btn, 'onclick', 'remorguser(this.form)');
set(btn, 'value', "Remove user");
app(obj, btn);
app(pdiv, obj);
return state.widget.inject(pdiv, true);
} else {
return state.widget.inject(txt("You are not an admin of this organisation!"));
}
};
addorguser = function(form) {
var i, js, k, q, ref, v;
js = {
action: 'add',
org: globArgs.org
};
for (i = q = 0, ref = form.length - 1; 0 <= ref ? q <= ref : q >= ref; i = 0 <= ref ? ++q : --q) {
k = form[i].name;
v = form[i].value;
if (k === 'who') {
form[i].value = "";
}
if (k === 'admin') {
v = form[i].checked ? 'true' : 'false';
}
if (k === 'who' || k === 'admin') {
js[k] = v;
}
}
return postJSON("admin-org", js, null, function(a) {
return alert("User added!");
});
};
remorguser = function(form) {
var i, js, k, q, ref, v;
js = {
action: 'remove',
org: globArgs.org
};
for (i = q = 0, ref = form.length - 1; 0 <= ref ? q <= ref : q >= ref; i = 0 <= ref ? ++q : --q) {
k = form[i].name;
v = form[i].value;
if (k === 'who') {
form[i].value = "";
}
if (k === 'admin') {
v = form[i].checked ? 'true' : 'false';
}
if (k === 'who' || k === 'admin') {
js[k] = v;
}
}
return postJSON("admin-org", js, null, function(a) {
return alert("User removed!");
});
};
tagList = {};
affiliation = function(json, state) {
var a, btn, gdiv, group, groupname, groups, h3, h4, len, len1, members, ngroups, obj, p, pdiv, person, q, ref, ref1, u;
obj = mk('div');
groups = [];
ref = json.groups;
for (group in ref) {
members = ref[group];
groups.push(group);
}
groups.sort((function(_this) {
return function(a, b) {
return json.groups[b].length - json.groups[a].length;
};
})(this));
h3 = mk('h3');
ngroups = groups.length;
if (indexOf.call(groups, '_untagged') >= 0) {
ngroups--;
}
app(h3, txt("Found " + ngroups + " organisations/companies:"));
app(obj, h3);
btn = mk('input');
set(btn, 'type', 'button');
set(btn, 'class', 'btn btn-info');
set(btn, 'value', 'Group wizard');
set(btn, 'widget', state.widget.id);
btn.addEventListener("click", function() {
var w;
w = findWidget(this.getAttribute('widget'));
w.args.eargs = {
autogroup: true
};
w.callback = affiliationWizard;
return w.reload();
});
p = mk('p');
app(p, txt("You may use the "));
app(p, btn);
app(p, txt(" to quickly group people into companies etc."));
app(obj, p);
p = mk('p');
app(p, txt("NOTE: For certain charts (evolutions etc), only the 30 largest groups will be shown due to computational optimisations."));
app(obj, p);
for (q = 0, len = groups.length; q < len; q++) {
group = groups[q];
groupname = group.split(/\./)[0].replace(/^([a-z])/, (function(_this) {
return function(a) {
return a.toUpperCase();
};
})(this));
if (group === '_untagged') {
groupname = "People with no current affiliation";
}
h4 = mk('h4');
app(h4, txt(groupname + ": " + json.groups[group].length + " members"));
h4.style.fontSize = "14pt";
h4.setAttribute("onclick", "var a = get('people_" + group + "'); a.style.display = (a.style.display == 'block') ? 'none' : 'block';");
h4.style.display = "inline-block";
h4.style.cursor = 'se-resize';
app(obj, h4);
app(obj, mk('br'));
gdiv = mk('div');
gdiv.setAttribute("id", "people_" + group);
gdiv.style.border = "1px solid #999";
gdiv.style.display = "none";
ref1 = json.groups[group];
for (u = 0, len1 = ref1.length; u < len1; u++) {
person = ref1[u];
pdiv = mk('div');
set(pdiv, 'id', 'tag_' + group + '_' + person.id);
app(pdiv, txt(person.name + " - <" + person.email + "> - "));
a = mk('a');
set(a, 'href', 'javascript:void(0);');
set(a, 'onclick', "this.parentNode.parentNode.removeChild(this.parentNode); js = { untag: {} }; js.untag['" + person.id + "'] = '" + group + "'; postJSON('/api/2/affiliations', js, null, null, null);");
app(a, txt("Remove from group"));
app(pdiv, a);
app(gdiv, pdiv);
}
app(obj, gdiv);
}
return state.widget.inject(obj, true);
};
affiliationWizard = function(json, state) {
var a, btn, chk, gdiv, group, groupname, groups, h3, h4, id, label, len, len1, members, obj, p, person, q, ref, ref1, sp, u;
obj = mk('div');
groups = [];
ref = json.groups;
for (group in ref) {
members = ref[group];
groups.push(group);
}
groups.sort((function(_this) {
return function(a, b) {
return json.groups[b].length - json.groups[a].length;
};
})(this));
h3 = mk('h3');
app(h3, txt("Found " + groups.length + " possible organisations/companies:"));
app(obj, h3);
p = mk('p');
app(p, txt("Select a group or individuals within it to tag them as belonging to that group."));
app(obj, p);
for (q = 0, len = groups.length; q < len; q++) {
group = groups[q];
groupname = group.split(/\./)[0].replace(/^([a-z])/, (function(_this) {
return function(a) {
return a.toUpperCase();
};
})(this));
h4 = mk('h4');
app(h4, txt(groupname + ": " + json.groups[group].length + " members"));
h4.style.fontSize = "14pt";
h4.setAttribute("onclick", "var a = get('people_" + group + "'); a.style.display = (a.style.display == 'block') ? 'none' : 'block';");
id = Math.floor(Math.random() * 987654321).toString(16);
chk = document.createElement('input');
chk.setAttribute("type", "checkbox");
chk.setAttribute("id", group);
chk.style.marginLeft = '10px';
chk.style.color = "#090";
chk.style.fontSize = "16pt";
chk.setAttribute("class", "f");
chk.addEventListener("change", function() {
var len1, person, ref1, results, u;
group = this.getAttribute('id');
ref1 = json.groups[group];
results = [];
for (u = 0, len1 = ref1.length; u < len1; u++) {
person = ref1[u];
chk = get('tag_' + person.id);
results.push(chk.checked = this.checked);
}
return results;
});
app(obj, chk);
h4.style.display = "inline-block";
h4.style.cursor = 'se-resize';
app(obj, h4);
app(obj, mk('br'));
gdiv = mk('div');
gdiv.setAttribute("id", "people_" + group);
gdiv.style.border = "1px solid #999";
gdiv.style.display = "none";
ref1 = json.groups[group];
for (u = 0, len1 = ref1.length; u < len1; u++) {
person = ref1[u];
chk = document.createElement('input');
chk.setAttribute("type", "checkbox");
chk.setAttribute("id", 'tag_' + person.id);
chk.setAttribute("pid", person.id);
chk.setAttribute("value", group);
chk.style.marginLeft = '10px';
chk.style.color = "#369";
chk.style.fontSize = "10pt";
label = document.createElement('label');
label.setAttribute("for", 'tag_' + person.id);
label.setAttribute("title", "Check this box to tag this person as affiliated with " + groupname);
chk.setAttribute("title", "Check this box to tag this person as affiliated with " + groupname);
label.style.paddingLeft = '5px';
label.appendChild(document.createTextNode(person.name + " - <" + person.email + ">"));
app(gdiv, chk);
app(gdiv, label);
a = mk('a');
set(a, 'href', 'javascript:void(affiliate("' + person.id + '"));');
app(a, txt("Set a tag"));
app(gdiv, txt(" - "));
app(gdiv, a);
sp = mk('span');
set(sp, 'id', 'tags_' + person.id);
app(gdiv, sp);
app(gdiv, mk('br'));
}
app(obj, gdiv);
}
btn = mk('input');
set(btn, 'type', 'button');
set(btn, 'class', 'btn btn-info');
set(btn, 'value', 'Save changes');
set(btn, 'widget', state.widget.id);
btn.addEventListener("click", function() {
var w;
w = findWidget(this.getAttribute('widget'));
tagList = {};
$("[type=checkbox]").each(function() {
var pid, val;
pid = $(this).attr('pid');
val = $(this).attr('value');
if (pid && pid.length > 0 && ($(this).attr('checked') || $(this).is(':checked'))) {
return tagList[pid] = val;
}
});
w.args.eargs = {
tag: tagList
};
w.callback = affiliation;
return w.reload();
});
app(obj, btn);
return state.widget.inject(obj, true);
};
affiliate = function(hash) {
var tag, tags, tr;
tag = window.prompt("Please enter the tag with which you wish to associate this source, or type nothing to untag.");
if (tag === "") {
tag = null;
}
tr = get('tags_' + hash);
tags = {};
tags[hash] = tag;
if (tag) {
postJSON('affiliations', {
tag: tags
}, null, null);
return app(tr, txt("(Tagged as: " + tag + ") "));
}
};
altemail = function(hash) {
var tag, tags, tr;
tag = window.prompt("Please enter the alt email with which you wish to associate this source, or type nothing to clear alts.");
if (tag === "") {
tag = null;
}
tr = get('tags_' + hash);
tags = {};
tags[hash] = tag;
if (tag) {
postJSON('affiliations', {
altemail: tags
}, null, null);
return app(tr, txt("(Affiliated as: " + tag + ") "));
}
};
bio = function(json, state) {
var a, a2, bioInner, bioOuter, egroups, firstauthor, firstcommit, firstemail, groups, len, len1, namecard, obj, q, ref, ref1, sp, tag, u;
obj = document.createElement('div');
if (json.found) {
firstcommit = "Never";
if (json.bio.firstCommit) {
firstcommit = new Date(json.bio.firstCommit * 1000).toDateString();
}
firstauthor = "Never";
if (json.bio.firstAuthor) {
firstauthor = new Date(json.bio.firstAuthor * 1000).toDateString();
}
firstemail = "Never";
if (json.bio.firstEmail) {
firstemail = new Date(json.bio.firstEmail * 1000).toDateString();
}
bioOuter = new HTML('div', {
"class": 'media-event'
});
bioOuter.inject(new HTML('a', {
"class": 'pull-left bio-image'
}, new HTML('img', {
style: "width: 128px; height: 128px;",
src: 'https://secure.gravatar.com/avatar/' + json.bio.gravatar + '.png?d=identicon&size=128'
})));
bioInner = new HTML('div', {
"class": 'media-body bio-profile'
});
bioInner.inject(new HTML('h2', {}, json.bio.name));
bioInner.inject(new HTML('h3', {}, json.bio.email));
bioInner.inject(new HTML('hr', {}));
bioInner.inject(new HTML('div', {
"class": 'bio-fact'
}, [new HTML('strong', {}, 'First code commit'), new HTML('br'), new HTML('span', {}, firstcommit)]));
bioInner.inject(new HTML('div', {
"class": 'bio-fact'
}, [new HTML('strong', {}, 'First code authorship'), new HTML('br'), new HTML('span', {}, firstauthor)]));
bioInner.inject(new HTML('div', {
"class": 'bio-fact'
}, [new HTML('strong', {}, 'First email'), new HTML('br'), new HTML('span', {}, firstemail)]));
bioInner.inject(new HTML('div', {
"class": 'bio-fact'
}, [new HTML('strong', {}, 'Commits'), new HTML('br'), new HTML('span', {}, json.bio.commits.pretty())]));
bioInner.inject(new HTML('div', {
"class": 'bio-fact'
}, [new HTML('strong', {}, 'Emails'), new HTML('br'), new HTML('span', {}, json.bio.emails.pretty())]));
bioOuter.inject(bioInner);
obj.appendChild(bioOuter);
namecard = mk('h2');
groups = [];
if (json.bio.tags) {
ref = json.bio.tags;
for (q = 0, len = ref.length; q < len; q++) {
tag = ref[q];
if (tag !== '_untagged') {
groups.push(tag);
}
}
}
if (groups.length > 0) {
namecard.appendChild(mk('br'));
namecard.appendChild(txt("Part of: " + groups.join(", ")));
}
a = mk('a');
set(a, 'href', 'javascript:void(affiliate("' + json.bio.id + '"));');
app(a, txt("Set a tag"));
egroups = [];
if (json.bio.alts && json.bio.alts.length) {
ref1 = json.bio.alts;
for (u = 0, len1 = ref1.length; u < len1; u++) {
tag = ref1[u];
egroups.push(tag);
}
}
if (egroups.length > 0) {
namecard.appendChild(mk('br'));
namecard.appendChild(txt("Also known as: " + egroups.join(", ")));
}
a2 = mk('a');
a2.style.marginLeft = "8px";
set(a2, 'href', 'javascript:void(altemail("' + json.bio.id + '"));');
app(a2, txt("Add alt email"));
sp = mk('span');
set(sp, 'id', 'tags_' + json.bio.id);
app(obj, namecard);
app(obj, a);
app(obj, a2);
app(obj, sp);
} else {
obj.innerHTML = "Person not found :/";
}
return state.widget.inject(obj, true);
};
widgetCache = [];
findWidget = function(id) {
var len, q, w;
for (q = 0, len = widgetCache.length; q < len; q++) {
w = widgetCache[q];
if (w.id === id) {
return w;
}
}
return null;
};
toFullscreen = function(id) {
var CW, FSA, dobrk, ic, len, node, nxt, obj, q, ref, w;
obj = get(id);
FSA = get('FS_' + id);
FSA.innerHTML = "Pop back";
FSA.setAttribute("onclick", "toNormal('" + id + "');");
CW = get('CW_' + id);
CW.setAttribute("onclick", "toNormal('" + id + "');");
w = findWidget(id);
w.parent = obj.parentNode;
w.sibling = null;
nxt = null;
dobrk = false;
ref = w.parent.childNodes;
for (q = 0, len = ref.length; q < len; q++) {
node = ref[q];
if (dobrk) {
nxt = node;
break;
} else if (node === obj) {
dobrk = true;
}
}
w.sibling = nxt;
ic = get('innercontents');
app(ic, obj);
w.oldStyle = JSON.stringify(obj.style);
obj.style.width = "100%";
obj.style.height = "90%";
obj.style.background = "#EEE";
obj.style.position = "absolute";
obj.style.top = "10px";
obj.style.left = "10px";
obj.style.zIndex = "2000";
w.fullscreen = true;
w.reload(true);
$("html, body").animate({
scrollTop: 0
}, "fast");
return true;
};
toNormal = function(id) {
var CW, FSA, obj, w;
obj = get(id);
w = findWidget(id);
FSA = get('FS_' + id);
FSA.innerHTML = "Fullscreen";
FSA.setAttribute("onclick", "toFullscreen('" + id + "');");
CW = get('CW_' + id);
CW.setAttribute("onclick", "findWidget('" + id + "').kill();");
if (w.sibling) {
w.parent.insertBefore(obj, w.sibling);
} else {
app(w.parent, obj);
}
obj.style = JSON.parse(w.oldStyle);
w.fullscreen = false;
w.reload(true);
return true;
};
updateWidgets = function(type, target, eargs) {
var g, gargs, k, len, q, results, v, wargs, widget, wloc;
wargs = window.location.search;
wloc = "";
for (k in eargs) {
v = eargs[k];
globArgs[k] = v;
g = [];
for (k in globArgs) {
v = globArgs[k];
if (k && v) {
g.push(k + '=' + v);
}
}
gargs = "?" + g.join("&");
wloc = window.location.pathname + gargs;
}
if (wargs !== gargs) {
window.history.pushState({}, "", wloc);
console.log("pushed state " + wloc);
window.onpopstate = function(event) {
return loadPageWidgets();
};
}
results = [];
for (q = 0, len = widgetCache.length; q < len; q++) {
widget = widgetCache[q];
if (type === widget.args.type) {
widget.args.target = target && target || widget.args.target;
if (eargs) {
widget.args.eargs = widget.args.eargs && widget.args.eargs || {};
for (k in eargs) {
v = eargs[k];
widget.args.eargs[k] = v;
if (!v) {
delete widget.args.eargs[k];
}
}
}
switch (widget.args.type) {
case 'donut':
results.push(widget.load(donut));
break;
case 'gauge':
results.push(widget.load(gauge));
break;
case 'radar':
results.push(widget.load(radar));
break;
case 'paragraph':
results.push(widget.load(paragraph));
break;
case 'line':
results.push(widget.load(linechart));
break;
case 'top5':
results.push(widget.load(top5));
break;
case 'factors':
results.push(widget.load(factors));
break;
case 'trends':
results.push(widget.load(trend));
break;
case 'preferences':
results.push(widget.load(preferences));
break;
case 'messages':
results.push(widget.load(messages));
break;
case 'widget':
results.push(widget.load(publisher));
break;
case 'contacts':
results.push(fetchPhonebook({
widget: widget,
w: w,
letter: 'a',
project: target
}));
break;
case 'repopicker':
results.push(widget.load(explorer));
break;
case 'sourcepicker':
results.push(widget.load(sourceexplorer));
break;
case 'issuepicker':
results.push(widget.load(issueexplorer));
break;
case 'forumpicker':
results.push(widget.load(forumexplorer));
break;
case 'viewpicker':
results.push(widget.load(viewexplorer));
break;
case 'mailpicker':
results.push(widget.load(mailexplorer));
break;
case 'cipicker':
results.push(widget.load(ciexplorer));
break;
case 'logpicker':
results.push(widget.load(logexplorer));
break;
case 'relationship':
results.push(widget.load(relationship));
break;
case 'treemap':
results.push(widget.load(treemap));
break;
case 'report':
results.push(widget.load(report));
break;
case 'mvp':
results.push(widget.load(mvp));
break;
case 'comstat':
results.push(widget.load(comstat));
break;
case 'worldmap':
results.push(widget.load(worldmap));
break;
case 'jsondump':
results.push(widget.load(jsondump));
break;
default:
results.push(void 0);
}
} else {
results.push(void 0);
}
}
return results;
};
pubWidget = (function() {
function pubWidget(div1, wid, config1) {
this.div = div1;
this.wid = wid;
this.config = config1;
this.args = {};
fetch("publish/id=" + this.wid, {
config: this.config,
widget: this,
args: {}
}, publisherPublic, null, true);
}
pubWidget.prototype.inject = function(el, clear) {
if (clear) {
this.div.innerHTML = "";
}
return this.div.appendChild(el);
};
return pubWidget;
})();
Widget = (function() {
function Widget(blocks, args1, pub) {
var a, cldiv, i, li, t, tt, ul;
this.blocks = blocks;
this.args = args1;
this.id = Math.floor(Math.random() * 1000000).toString(16);
this.div = document.createElement('div');
this.div.setAttribute("id", this.id);
this.div.setAttribute("class", "x_panel snoot_widget");
this.div.style.float = 'left';
this.json = {};
if (this.blocks <= 2) {
this.div.setAttribute("class", "snoot_widget col-md-2 col-sm-4 col-xs-12");
} else if (this.blocks <= 3) {
this.div.setAttribute("class", "snoot_widget col-md-3 col-sm-6 col-xs-12");
} else if (this.blocks <= 4) {
this.div.setAttribute("class", "snoot_widget col-md-4 col-sm-8 col-xs-12");
} else if (this.blocks <= 6) {
this.div.setAttribute("class", "snoot_widget col-md-6 col-sm-12 col-xs-12");
} else if (this.blocks <= 9) {
this.div.setAttribute("class", "snoot_widget col-md-9 col-sm-12 col-xs-12");
} else {
this.div.setAttribute("class", "snoot_widget col-md-12 col-sm-12 col-xs-12");
}
if (!pub) {
t = document.createElement('div');
t.setAttribute("class", "x_title");
tt = document.createElement('h2');
tt.style.fontSize = "17pt";
tt.appendChild(document.createTextNode(this.args.name));
t.appendChild(tt);
ul = document.createElement('ul');
ul.setAttribute("class", "nav navbar-right panel_toolbox");
li = document.createElement('li');
this.collapse = document.createElement('a');
this.collapse.setAttribute("class", "collapse-link");
i = document.createElement('i');
i.setAttribute("class", "fa fa-chevron-up");
this.collapse.appendChild(i);
li.appendChild(this.collapse);
ul.appendChild(li);
this.collapse.addEventListener("click", function() {
var content, icon, id, panel;
id = this.parentNode.parentNode.parentNode.parentNode.getAttribute("id");
panel = $('#' + id);
icon = $(this).find('i');
content = panel.find('.x_content');
if (panel.attr('style')) {
content.slideToggle(200, function() {
return panel.removeAttr('style');
});
} else {
content.slideToggle(200);
panel.css('height', 'auto');
}
return icon.toggleClass('fa-chevron-up fa-chevron-down');
});
li = document.createElement('li');
a = document.createElement('a');
a.setAttribute("class", "close-link");
a.setAttribute("onclick", "findWidget('" + this.id + "').kill();");
i = document.createElement('i');
i.setAttribute("class", "fa fa-close");
a.appendChild(i);
a.setAttribute("id", "CW_" + this.id);
li.appendChild(a);
ul.appendChild(li);
t.appendChild(ul);
this.div.appendChild(t);
cldiv = document.createElement('div');
cldiv.setAttribute("classs", "clearfix");
this.div.appendChild(cldiv);
}
this.cdiv = document.createElement('div');
this.cdiv.style.width = "100%";
this.cdiv.setAttribute("id", "contents_" + this.id);
this.cdiv.setAttribute("class", "x_content");
this.div.appendChild(this.cdiv);
widgetCache.push(this);
}
Widget.prototype.cog = function(size) {
var i, idiv;
if (size == null) {
size = 100;
}
idiv = document.createElement('div');
idiv.setAttribute("class", "icon");
idiv.setAttribute("style", "text-align: center; vertical-align: middle; height: 500px;");
i = new HTML('div', {
"class": "spinwheel"
}, new HTML('div', {
"class": "spinwheel_md"
}, new HTML('div', {
"class": "spinwheel_sm"
})));
idiv.appendChild(i);
idiv.appendChild(document.createElement('br'));
idiv.appendChild(document.createTextNode('Loading, hang on tight..!'));
this.cdiv.innerHTML = "";
return this.cdiv.appendChild(idiv);
};
Widget.prototype.kill = function() {
return this.div.parentNode.removeChild(this.div);
};
Widget.prototype.inject = function(object, clear) {
if (clear) {
this.cdiv.innerHTML = "";
this.cdiv.style.textAlign = 'left';
}
return this.cdiv.appendChild(object);
};
Widget.prototype.snap = function(state) {
state.widget.cdiv.innerHTML = "<a style='color: #D44; font-size: 100pt;'><i class='fa fa-warning'></i></a><br/>Oh snap, something went wrong!";
return state.widget.cdiv.style.textAlign = 'center';
};
Widget.prototype.load = function(callback) {
var js, url;
this.cog();
this.callback = callback;
js = this.args.eargs;
url = this.args.source;
if (this.args.type === 'paragraph') {
return this.callback(this.args, {
widget: this,
eargs: this.args.eargs
});
} else {
if (this.args.method === 'get') {
return fetch(url, {
widget: this,
eargs: this.args.eargs
}, callback, this.snap);
} else {
return post(url, js, {
widget: this,
eargs: this.args.eargs
}, callback, this.snap);
}
}
};
Widget.prototype.reload = function(fakeit) {
var js, url;
this.cog();
js = this.args.eargs;
url = this.args.source;
if (fakeit && this.json) {
return this.callback(this.json, {
widget: this,
eargs: this.args.eargs
});
} else {
return post(url, js, {
widget: this,
eargs: this.args.eargs
}, this.callback, this.snap);
}
};
return Widget;
})();
rowZ = 100;
Row = (function() {
function Row() {
this.id = Math.floor(Math.random() * 987654321).toString(16);
this.div = document.createElement('div');
this.div.setAttribute("class", "row");
this.div.style.zIndex = rowZ;
rowZ--;
this.div.setAttribute("id", this.id);
this.cdiv = document.createElement('div');
this.cdiv.setAttribute("class", "col-md-12");
this.cdiv.setAttribute("id", "contents_" + this.id);
this.div.appendChild(this.cdiv);
document.getElementById('innercontents').appendChild(this.div);
}
Row.prototype.inject = function(object, clear) {
if (clear) {
this.cdiv.innerHTML = "";
}
if (object instanceof Widget) {
return this.cdiv.appendChild(object.div);
} else {
return this.cdiv.appendChild(object);
}
};
return Row;
})();
comShow = function(t) {
var len, q, row, rows;
rows = document.getElementsByTagName("tr");
for (q = 0, len = rows.length; q < len; q++) {
row = rows[q];
if ((row.getAttribute("id") || "foo").match("comstat_" + t + "_")) {
row.style.display = "table-row";
}
}
return document.getElementById("comstat_" + t + "_more").style.display = "none";
};
comstat = function(json, state) {
var aa, ab, chk, dstyle, hash, i, js, key, lb, len, len1, len2, len3, m, nl, notice, oemail, p, person, q, ref, ref1, ref2, ref3, repo, row, stbl, tb, tbl, tr, u, url, wh, widget;
if (json && json.stats) {
row = new Row();
p = new HTML('p', {}, globArgs.committersOnly === 'true' ? "You are currently only seeing stats for committers. To view statistics for all contributors (committers and authors), please uncheck the box below:" : "You are currently seeing stats for both committership and authorship of code. To view only committership stats, tick the box below:");
chk = new HTML('input', {
type: 'checkbox',
checked: globArgs.committersOnly === 'true' ? 'checked' : null,
id: 'comonly',
onchange: 'updateWidgets("comstat", null, { committersOnly: this.checked ? "true" : null });'
});
lb = new HTML('label', {
"for": 'comonly'
}, "Show only new committers, discard new authors.");
row.inject(p);
row.inject(chk);
row.inject(lb);
state.widget.inject(row.div, true);
if (json.stats.code.seen > 0) {
row = new Row();
js = {
alphaSort: true,
counts: {
"Regulars": json.stats.code.seen - json.stats.code.newcomers.length,
"Newcomers": json.stats.code.newcomers.length
}
};
widget = new Widget(4, {
name: "Code contributors this period",
representation: 'comstat'
});
widget.json = js;
widget.callback = donut;
widget.parent = state.widget;
row.inject(widget);
donut(js, {
widget: widget
});
nl = 0;
if (json.stats.code.newcomers.length && json.stats.code.newcomers.length >= 0) {
nl = json.stats.code.newcomers.length;
}
stbl = new Widget(6, {
name: "New code contributors (" + nl + ")"
});
tbl = mk('table', {
"class": "table table-striped"
});
tr = mk('tr', {}, [mk('th', {}, "Avatar"), mk('th', {}, "Name"), mk('th', {}, "Address"), mk('th', {}, "First commit")]);
app(tbl, tr);
tb = new HTML('tbody');
json.stats.code.newcomers.sort((function(_this) {
return function(a, b) {
return json.bios[b].code[0] - json.bios[a].code[0];
};
})(this));
dstyle = 'table-row';
ref = json.stats.code.newcomers;
for (i = q = 0, len = ref.length; q < len; i = ++q) {
person = ref[i];
oemail = person;
hash = json.bios[person].code[1].id.split('/')[1];
repo = json.bios[person].code[1].sourceURL;
wh = new Date(json.bios[person].code[0] * 1000.0).toDateString();
person = json.bios[person].bio;
if (i === 6) {
m = json.stats.code.newcomers.length - i;
tr = mk('tr', {
scope: 'row',
id: 'comstat_code_more'
}, [
mk('td', {
colspan: "3"
}, new HTML('a', {
href: 'javascript:void(comShow("code"));'
}, "+" + m + " more..."))
]);
tb.inject(tr);
dstyle = "none";
}
tr = new HTML('tr', {
scope: 'row',
id: "comstat_code_" + i,
style: {
display: dstyle
}
}, [
mk('td', {}, new HTML('img', {
style: {
width: '32px',
height: '32px'
},
"class": "img-circle img-responsive",
src: "https://secure.gravatar.com/avatar/" + person.md5 + ".png?d=identicon"
})), mk('td', {}, mk('a', {
href: "?page=people&email=" + oemail
}, person.name)), mk('td', {}, oemail), mk('td', {}, wh + " (" + repo + ")")
]);
tb.inject(tr);
}
app(tbl, tb);
stbl.inject(tbl);
row.inject(stbl);
if (json.stats.code.timeseries && json.stats.code.timeseries.length > 0) {
widget = new Widget(4, {
name: "New code contributors over time:",
representation: 'bars'
});
widget.parent = state.widget;
row.inject(widget);
js = {
widgetType: {
chartType: 'bar'
},
timeseries: json.stats.code.timeseries
};
widget.json = js;
widget.callback = linechart;
linechart(js, {
widget: widget
});
}
state.widget.inject(row.div);
}
if (json.stats.issues.seen > 0) {
row = new Row();
js = {
alphaSort: true,
counts: {
"Regulars": json.stats.issues.seen - json.stats.issues.newcomers.length,
"Newcomers": json.stats.issues.newcomers.length
}
};
widget = new Widget(4, {
name: "Issue contributors this period",
representation: 'comstat'
});
widget.json = js;
widget.parent = state.widget;
widget.callback = donut;
row.inject(widget);
donut(js, {
widget: widget
});
nl = 0;
if (json.stats.issues.newcomers.length && json.stats.issues.newcomers.length >= 0) {
nl = json.stats.issues.newcomers.length;
}
stbl = new Widget(6, {
name: "New issue contributors (" + nl + ")"
});
tbl = mk('table', {
"class": "table table-striped"
});
tr = mk('tr', {}, [mk('th', {}, "Avatar"), mk('th', {}, "Name"), mk('th', {}, "Address"), mk('th', {}, "First issue")]);
app(tbl, tr);
tb = new HTML('tbody');
json.stats.issues.newcomers.sort((function(_this) {
return function(a, b) {
return json.bios[b].issue[0] - json.bios[a].issue[0];
};
})(this));
dstyle = 'show';
ref1 = json.stats.issues.newcomers;
for (i = u = 0, len1 = ref1.length; u < len1; i = ++u) {
person = ref1[i];
oemail = person;
url = json.bios[person].issue[1].url;
key = json.bios[person].issue[1].key || url;
wh = new Date(json.bios[person].issue[0] * 1000.0).toDateString();
person = json.bios[person].bio;
if (i === 6) {
m = json.stats.issues.newcomers.length - i;
tr = mk('tr', {
scope: 'row',
id: 'comstat_issue_more'
}, [
mk('td', {
colspan: "3"
}, new HTML('a', {
href: 'javascript:void(comShow("issue"));'
}, "+" + m + " more..."))
]);
tb.inject(tr);
dstyle = "none";
}
tr = new HTML('tr', {
scope: 'row',
id: "comstat_issue_" + i,
style: {
display: dstyle
}
}, [
mk('td', {}, new HTML('img', {
style: {
width: '32px',
height: '32px'
},
"class": "img-circle img-responsive",
src: "https://secure.gravatar.com/avatar/" + person.md5 + ".png?d=identicon"
})), mk('td', {}, mk('a', {
href: "?page=people&email=" + oemail
}, person.name)), mk('td', {}, oemail), mk('td', {}, [
wh + " (", mk('a', {
href: url || "#"
}, txt(key)), ")"
])
]);
tb.inject(tr);
}
app(tbl, tb);
stbl.inject(tbl);
row.inject(stbl);
if (json.stats.issues.timeseries && json.stats.issues.timeseries.length > 0) {
widget = new Widget(6, {
name: "New issue contributors over time:",
representation: 'bars'
});
widget.parent = state.widget;
row.inject(widget);
js = {
widgetType: {
chartType: 'bar'
},
timeseries: json.stats.issues.timeseries
};
widget.json = js;
widget.callback = linechart;
linechart(js, {
widget: widget
});
}
state.widget.inject(row.div);
}
if (json.stats.converts) {
if (json.stats.converts.issue_to_code.length && json.stats.converts.issue_to_code.length > 0) {
row = new Row();
stbl = new Widget(6, {
name: "Previous issue contributors who are now contributing code:"
});
tbl = mk('table', {
"class": "table table-striped"
});
tr = mk('tr', {}, [mk('th', {}, "Avatar"), mk('th', {}, "Name"), mk('th', {}, "Address"), mk('th', {}, "Days from first issue to first code contribution:")]);
app(tbl, tr);
tb = new HTML('tbody');
ref2 = json.stats.converts.issue_to_code;
for (i = aa = 0, len2 = ref2.length; aa < len2; i = ++aa) {
person = ref2[i];
if (i > 20) {
break;
}
tr = mk('tr', {
scope: 'row'
}, [
mk('td', {}, new HTML('img', {
style: {
width: '32px',
height: '32px'
},
"class": "img-circle img-responsive",
src: "https://secure.gravatar.com/avatar/" + person.md5 + ".png?d=identicon"
})), mk('td', {}, mk('a', {
href: "?page=people&email=" + person.address
}, person.name)), mk('td', {}, person.address), mk('td', {
style: {
textAlign: 'right'
}
}, (Math.floor(person.tdiff / 86400.)).pretty())
]);
tb.inject(tr);
}
app(tbl, tb);
stbl.inject(tbl);
row.inject(stbl);
state.widget.inject(row.div);
}
if (json.stats.converts.email_to_code.length && json.stats.converts.email_to_code.length > 0) {
row = new Row();
stbl = new Widget(6, {
name: "Previous email authors who are now contributing code:"
});
tbl = mk('table', {
"class": "table table-striped"
});
tr = mk('tr', {}, [mk('th', {}, "Avatar"), mk('th', {}, "Name"), mk('th', {}, "Address"), mk('th', {}, "Days from first email to first code contribution:")]);
app(tbl, tr);
tb = new HTML('tbody');
ref3 = json.stats.converts.email_to_code;
for (i = ab = 0, len3 = ref3.length; ab < len3; i = ++ab) {
person = ref3[i];
if (i > 20) {
break;
}
tr = mk('tr', {
scope: 'row'
}, [
mk('td', {}, new HTML('img', {
style: {
width: '32px',
height: '32px'
},
"class": "img-circle img-responsive",
src: "https://secure.gravatar.com/avatar/" + person.md5 + ".png?d=identicon"
})), mk('td', {}, mk('a', {
href: "?page=people&email=" + person.address
}, person.name)), mk('td', {}, person.address), mk('td', {
style: {
textAlign: 'right'
}
}, (Math.floor(person.tdiff / 86400.)).pretty())
]);
tb.inject(tr);
}
app(tbl, tb);
stbl.inject(tbl);
row.inject(stbl);
return state.widget.inject(row.div);
}
}
} else {
notice = new HTML('h2', {}, "Community growth stats only works with user-defined views!");
p = new HTML('p', {}, "To see community growth stats, please create a view of the code, email, bugs you wish to view stats for, or select an existng view in the list above");
state.widget.inject(notice, true);
return state.widget.inject(p);
}
};
donut = function(json, state) {
var a, aa, blank, chartBox, code, comment, count, data, div, dt, dtl, el, item, l, lang, langs, len, len1, len2, q, ref, top, tot, ttot, u;
dt = [];
dtl = [];
l = 0;
tot = 0;
ttot = 0;
top = [];
if (json.counts) {
dtl = [];
dt = [];
a = 0;
ref = json.counts;
for (item in ref) {
count = ref[item];
dt.push({
name: item,
value: count
});
a++;
}
if (!json.alphaSort) {
dt.sort((function(_this) {
return function(a, b) {
return b.value - a.value;
};
})(this));
} else {
dt.sort((function(_this) {
return function(a, b) {
if (a.name > b.name) {
return 1;
} else {
return -1;
}
};
})(this));
}
for (q = 0, len = dt.length; q < len; q++) {
item = dt[q];
dtl.push(dt.name);
}
theme.color = genColors(a + 1, 0.55, 0.475, true);
}
if (state.widget.args.representation === 'commentcount') {
code = 0;
comment = 0;
blank = 0;
langs = json.languages;
for (lang in langs) {
data = langs[lang];
code += data.code;
comment += data.comment;
blank += data.blank || 0;
}
tot = code + comment;
dtl = ['Code', 'Comments'];
dt = [
{
name: 'Code',
value: code
}, {
name: 'Comments',
value: comment
}
];
if (blank > 0) {
dt.push({
name: "Blanks",
value: blank
});
}
theme.color = genColors(3, 0.6, 0.5, true);
}
if (state.widget.args.representation === 'sloccount' || (state.widget.args.representation !== 'commentcount' && json.languages)) {
langs = json.languages;
for (lang in langs) {
data = langs[lang];
tot += data.code;
top.push(lang);
}
top.sort((function(_this) {
return function(a, b) {
return langs[b].code - langs[a].code;
};
})(this));
for (u = 0, len1 = top.length; u < len1; u++) {
lang = top[u];
l++;
if (l > 250 || (langs[lang].code / tot) < 0.01) {
break;
}
ttot += langs[lang].code;
dt.push({
name: lang,
value: langs[lang].code
});
dtl.push(lang);
}
if (tot !== ttot) {
dtl.push('Other languages');
dt.push({
name: 'Other languages',
value: tot - ttot
});
}
theme.color = genColors(17, 0.6, 0.5, true);
}
data = {};
for (aa = 0, len2 = dt.length; aa < len2; aa++) {
el = dt[aa];
data[el.name] = el.value;
}
div = new HTML('div');
state.widget.inject(div, true);
return chartBox = new Chart(div, 'donut', data, 25);
};
factors = function(json, state) {
var direction, factor, h, h2, id, items, len, obj, pct, q, ref, t;
items = [];
if (json.factors) {
id = parseInt(Math.random() * 99999999).toString(16);
obj = new HTML('div', {
id: id
});
ref = json.factors;
for (q = 0, len = ref.length; q < len; q++) {
factor = ref[q];
h = new HTML('h1', {}, txt(factor.count.pretty()));
if (factor.previous) {
direction = factor.count - factor.previous;
pct = parseInt((direction / factor.previous) * 100);
if (direction < 0) {
h2 = new HTML('span', {
style: {
marginLeft: "8px",
fontSize: "14px",
color: 'red'
}
}, [
new HTML('i', {
"class": "fa fa-chevron-circle-down"
}), " " + pct + "% change since last period"
]);
h.inject(h2);
} else {
h2 = new HTML('span', {
style: {
marginLeft: "8px",
fontSize: "14px",
color: 'green'
}
}, [
new HTML('i', {
"class": "fa fa-chevron-circle-up"
}), " +" + pct + "% change since last period"
]);
h.inject(h2);
}
}
t = txt(factor.title);
obj.inject(new HTML('div', {}, [h, t]));
}
return state.widget.inject(obj, true);
}
};
jsondump = function(json, state) {
var pre;
pre = new HTML('pre', {
style: {
whiteSpace: 'pre-wrap'
}
});
pre.inject(JSON.stringify(json, null, 2));
return state.widget.inject(pre, true);
};
linechart = function(json, state) {
var aa, ab, cat, catdata, cats, catseries, chartBox, chk, dates, div, filled, from, histograms, id, item, key, label, len, len1, len2, len3, list, m, opt, point, q, range, ref, ref1, ref2, rv, stack, tName, to, type, u, val;
div = document.createElement('div');
if (json.text) {
div.inject(new HTML('p', {}, json.text));
}
cats = new Array();
dates = new Array();
catdata = {};
if (!isArray(json.timeseries) && !json.counts) {
div.innerHTML = "No data available";
state.widget.inject(div, true);
return;
}
if (json.timeseries) {
json.timeseries.sort((function(_this) {
return function(a, b) {
return a.date - b.date;
};
})(this));
ref = json.timeseries;
for (q = 0, len = ref.length; q < len; q++) {
point = ref[q];
for (key in point) {
val = point[key];
if (key !== 'date' && !(indexOf.call(cats, key) >= 0)) {
cats.push(key);
catdata[key] = new Array();
}
}
}
ref1 = json.timeseries;
for (u = 0, len1 = ref1.length; u < len1; u++) {
point = ref1[u];
m = moment(point.date * 1000);
rv = m.format("MMM, YYYY");
if (json.histogram === "daily" || json.interval === 'day') {
rv = m.format("MMMM DD, YYYY");
}
if (json.interval === 'year') {
rv = m.format("YYYY");
} else if (json.interval === 'quarter') {
rv = "Q" + m.format("Q, YYYY");
} else if (json.interval === 'week') {
rv = "Week " + m.format("W, YYYY");
}
dates.push(rv);
for (key in point) {
val = point[key];
if (key !== 'date') {
if (key === 'deletions') {
val = -val;
}
catdata[key].push(val);
}
}
for (aa = 0, len2 = cats.length; aa < len2; aa++) {
cat = cats[aa];
if (ref2 = !cat, indexOf.call(point, ref2) >= 0) {
catdata[cat].push(0);
}
}
}
}
catseries = [];
type = 'spline';
stack = false;
filled = true;
if (json.widgetType) {
if (json.widgetType.chartType) {
type = json.widgetType.chartType;
}
if (json.widgetType.stack) {
stack = json.widgetType.stack;
}
if (json.widgetType.nofill) {
filled = null;
}
}
if (state && state.config) {
if (state.config.charttype) {
if (state.config.charttype === 'line') {
type = 'line';
stack = false;
if (!state.config.fill) {
filled = null;
}
}
if (state.config.stack) {
stack = true;
}
}
}
if (!state.widget.div.style.height) {
div.style.minHeight = "280px";
} else {
div.style.minHeight = "100%";
}
if (state.widget.fullscreen) {
div.style.minHeight = "640px";
}
state.widget.inject(div, true);
range = "";
if (state.widget.args.daterangeRaw) {
from = new Date(state.widget.args.daterangeRaw[0] * 1000).toDateString();
to = new Date(state.widget.args.daterangeRaw[1] * 1000).toDateString();
range = "between " + from + " and " + to;
}
chartBox = new Chart(div, 'line', json, {
title: range,
stacked: stack,
linetype: type,
filled: filled
});
if (state.widget.args.source === 'git-evolution') {
id = Math.floor(Math.random() * 987654321).toString(16);
chk = document.createElement('input');
chk.setAttribute("type", "checkbox");
chk.setAttribute("id", id);
chk.style.marginLeft = '10px';
if (globArgs.extended && globArgs.extended === 'true') {
chk.checked = true;
}
chk.addEventListener("change", function() {
var extended;
extended = null;
if (this.checked) {
extended = 'true';
globArgs['extended'] = 'true';
}
return updateWidgets('line', null, {
extended: extended
});
});
state.widget.inject(mk('br'));
state.widget.inject(chk);
label = document.createElement('label');
label.setAttribute("for", id);
label.setAttribute("title", "Check this box to view evolutionary breakdown of languages");
chk.setAttribute("title", "Check this box to view evolutionary breakdown of languages");
label.style.paddingLeft = '5px';
label.appendChild(document.createTextNode('Toggle language breakdown'));
state.widget.inject(label);
if (globArgs.extended) {
id = Math.floor(Math.random() * 987654321).toString(16);
chk = document.createElement('input');
chk.setAttribute("type", "checkbox");
chk.setAttribute("id", id);
chk.style.marginLeft = '10px';
if (globArgs.codeonly && globArgs.codeonly === 'true') {
chk.checked = true;
}
chk.addEventListener("change", function() {
var codeonly;
codeonly = null;
if (this.checked) {
codeonly = 'true';
globArgs['codeonly'] = 'true';
}
return updateWidgets('line', null, {
codeonly: codeonly
});
});
state.widget.inject(chk);
label = document.createElement('label');
label.setAttribute("for", id);
label.setAttribute("title", "Check this box to show only programming languages (no docs/markups/build-configs)");
chk.setAttribute("title", "Check this box to show only programming languages (no docs/markups/build-configs)");
label.style.paddingLeft = '5px';
label.appendChild(document.createTextNode('Only show programming languages'));
state.widget.inject(label);
}
}
if ((!state["public"]) && json.interval) {
tName = 'interval';
list = document.createElement('select');
list.setAttribute("data", tName);
state.widget.inject(mk('br'));
state.widget.inject(txt("Select interval: "));
state.widget.inject(list);
histograms = ['day', 'week', 'month', 'quarter', 'year'];
if (state.widget.wargs && state.widget.wargs.histogram === 'hour') {
histograms.unshift('hour');
}
for (ab = 0, len3 = histograms.length; ab < len3; ab++) {
item = histograms[ab];
opt = document.createElement('option');
opt.value = item;
opt.text = item;
if ((globArgs[tName] && globArgs[tName] === item) || json.interval === item) {
opt.selected = 'selected';
}
list.appendChild(opt);
}
return list.addEventListener("change", function() {
var source, x;
source = this.value;
if (source === "") {
source = null;
}
tName = this.getAttribute("data");
globArgs[tName] = source;
x = {};
x[tName] = source;
return updateWidgets('line', null, x);
}, false);
}
};
worldmap = function(json, state) {
var cmax, ctotal, details, dt, dtl, echartMap, item, l, lmain, radius, ref, top, tot, ttot;
dt = [];
dtl = [];
l = 0;
tot = 0;
ttot = 0;
top = [];
cmax = 0;
ctotal = 0;
if (json.countries) {
ref = json.countries;
for (item in ref) {
details = ref[item];
dt.push({
name: details.name,
value: details.count
});
ctotal += details.count;
if (details.count > cmax) {
cmax = details.count;
}
}
}
lmain = document.createElement('div');
radius = ['30%', '50%'];
if (!state.widget.div.style.height) {
lmain.style.height = "500px";
} else {
lmain.style.height = "100%";
}
if (state.widget.fullscreen) {
lmain.style.height = "1000px";
radius = ['35%', '60%'];
theme.textStyle.fontSize = 20;
}
lmain.style.width = "100%";
state.widget.inject(lmain, true);
echartMap = echarts.init(lmain, theme);
echartMap.setOption({
title: {
text: "Worldwide distribution by country",
subtext: "(" + ctotal.pretty() + " in total from " + (json.numberOfCountries || 0) + " countries)"
},
calculable: true,
dataRange: {
min: 0,
max: cmax,
text: ['High', 'Low'],
realtime: false,
calculable: true,
color: ['orangered', 'yellow', 'lightskyblue']
},
toolbox: {
show: true,
feature: {
dataView: {
show: true,
title: 'Data view',
readOnly: false,
lang: ['Data View', 'Close', 'Update']
},
restore: {
show: true,
title: "Restore"
},
saveAsImage: {
show: true,
title: "Save Image"
}
}
},
tooltip: {
trigger: 'item',
formatter: function(params) {
return params.seriesName + '<br/>' + params.name + ' : ' + (params.value || 0).pretty();
}
},
series: [
{
name: state.widget.name,
type: 'map',
mapType: 'world',
mapLocation: {
y: 60
},
itemStyle: {
emphasis: {
label: {
show: true
}
}
},
data: dt
}
]
});
return theme.textStyle.fontSize = 12;
};
messages = function(json, state) {
var a, aa, ab, b, btn, div, el, form, h2, inp, item, items, len, len1, len2, len3, message, obj, pre, q, ref, ref1, ref2, reply, tbl, tbody, td, thead, tr, u;
if (isArray(json)) {
obj = document.createElement('form');
tbl = mk('table');
set(tbl, 'class', 'table table-striped');
thead = mk('thead');
tr = mk('tr');
ref = ['Date', 'Sender', 'Subject'];
for (q = 0, len = ref.length; q < len; q++) {
el = ref[q];
td = mk('th');
if (el.match(/(Date|Sender)/)) {
td.style.width = "20%";
}
app(td, txt(el));
app(tr, td);
}
app(thead, tr);
app(tbl, thead);
tbody = mk('tbody');
app(tbl, tbody);
for (u = 0, len1 = json.length; u < len1; u++) {
message = json[u];
tr = mk('tr');
if (message.read === false) {
tr.style.fontWeight = "bold";
tr.style.color = "#396";
}
td = mk('td');
a = mk('a');
set(a, 'href', '?page=messages&message=' + message.id);
app(a, txt(new Date(message.epoch * 1000).toString()));
app(td, a);
app(tr, td);
td = mk('td');
a = mk('a');
set(a, 'href', '?page=messages&message=' + message.id);
app(a, txt(message.senderName));
app(td, a);
app(tr, td);
td = mk('td');
a = mk('a');
set(a, 'href', '?page=messages&message=' + message.id);
app(a, txt(message.subject));
app(td, a);
app(tr, td);
app(tbody, tr);
}
app(obj, tbl);
items = {
recipient: 'Recipient ID',
subject: "Message subject",
body: "Message"
};
h2 = mk('h2');
app(h2, txt("Send a message:"));
app(obj, h2);
ref1 = ['recipient', 'subject', 'body'];
for (aa = 0, len2 = ref1.length; aa < len2; aa++) {
item = ref1[aa];
div = mk('div');
app(div, txt(items[item] + ": "));
if (item === 'body') {
inp = mk('textarea');
inp.style.width = "600px";
inp.style.height = "200px";
} else {
inp = mk('input');
set(inp, 'type', 'text');
inp.style.width = "200px";
}
set(inp, 'name', item);
app(div, inp);
app(obj, div);
}
btn = mk('input');
set(btn, 'type', 'button');
set(btn, 'onclick', 'sendEmail(this.form)');
set(btn, 'value', "Send message");
app(obj, btn);
return state.widget.inject(obj, true);
} else {
obj = mk('div');
b = mk('b');
app(b, txt("Sender: "));
app(obj, b);
app(obj, txt(json.senderName + ' (' + json.sender + ')'));
app(obj, mk('br'));
b = mk('b');
app(b, txt("Date: "));
app(obj, b);
app(obj, txt(new Date(json.epoch * 1000).toString()));
app(obj, mk('br'));
b = mk('b');
app(b, txt("Subject: "));
app(obj, b);
app(obj, txt(json.subject));
app(obj, mk('br'));
app(obj, mk('br'));
pre = mk('pre');
app(pre, txt(json.body));
app(obj, pre);
app(obj, mk('hr'));
form = mk('form');
items = {
recipient: 'Recipient ID',
subject: "Message subject",
body: "Message"
};
h2 = mk('h2');
app(h2, txt("Send a reply:"));
app(form, h2);
reply = {
recipient: json.sender,
subject: 'RE: ' + json.subject,
body: ''
};
ref2 = ['recipient', 'subject', 'body'];
for (ab = 0, len3 = ref2.length; ab < len3; ab++) {
item = ref2[ab];
div = mk('div');
app(div, txt(items[item] + ": "));
if (item === 'body') {
inp = mk('textarea');
inp.style.width = "600px";
inp.style.height = "200px";
} else {
inp = mk('input');
set(inp, 'type', 'text');
inp.style.width = "200px";
}
inp.value = reply[item];
set(inp, 'name', item);
app(div, inp);
app(form, div);
}
btn = mk('input');
set(btn, 'type', 'button');
set(btn, 'onclick', 'sendEmail(this.form)');
set(btn, 'value', "Send message");
app(form, btn);
app(obj, form);
return state.widget.inject(obj, true);
}
};
sendEmail = function(form) {
var i, js, k, q, ref, v;
js = {
action: 'send'
};
for (i = q = 0, ref = form.length - 1; 0 <= ref ? q <= ref : q >= ref; i = 0 <= ref ? ++q : --q) {
k = form[i].name;
v = form[i].value;
if (k === 'recipient' || k === 'subject' || k === 'body') {
js[k] = v;
}
}
return postJSON("messages", js, null, function(a) {
return alert("Mail sent!");
});
};
mvp = function(json, state) {
var aa, el, i, len, len1, len2, nlist, person, q, ref, ref1, ref2, tb, tbl, tr, u;
nlist = new HTML('select', {
name: 'size',
id: 'size'
});
ref = [10, 20, 50, 100, 200, 500, 1000, 2000];
for (q = 0, len = ref.length; q < len; q++) {
i = ref[q];
el = new HTML('option', {
value: i,
text: i + ""
});
if (globArgs.size && parseInt(globArgs.size) === i) {
el.selected = 'selected';
}
el.inject(txt(i + ""));
nlist.inject(el);
}
nlist.addEventListener("change", function() {
var n;
n = this.value;
if (n === "") {
n = null;
}
globArgs.size = n;
return updateWidgets('mvp', null, {
size: n
});
}, false);
state.widget.inject(new HTML('b', {}, "List size: "), true);
state.widget.inject(nlist);
nlist = new HTML('select', {
name: 'sort',
id: 'sort'
});
ref1 = ['commits', 'issues', 'emails'];
for (u = 0, len1 = ref1.length; u < len1; u++) {
i = ref1[u];
el = new HTML('option', {
value: i,
text: i
});
if (globArgs.sort && globArgs.sort === i) {
el.selected = 'selected';
}
el.inject(txt(i));
nlist.inject(el);
}
nlist.addEventListener("change", function() {
var n;
n = this.value;
if (n === "") {
n = null;
}
globArgs.sort = n;
return updateWidgets('mvp', null, {
sort: n
});
}, false);
state.widget.inject(new HTML('b', {}, " Sort by: "));
state.widget.inject(nlist);
tbl = mk('table', {
"class": "table table-striped"
});
tr = mk('tr', {}, [mk('th', {}, "Rank"), mk('th', {}, "Avatar"), mk('th', {}, "Name"), mk('th', {}, "Address"), mk('th', {}, globArgs.author ? "Authorings" : "Commits"), mk('th', {}, "Issues"), mk('th', {}, "Email")]);
app(tbl, tr);
tb = new HTML('tbody');
ref2 = json.sorted;
for (i = aa = 0, len2 = ref2.length; aa < len2; i = ++aa) {
person = ref2[i];
tr = mk('tr', {
scope: 'row'
}, [
mk('td', {}, (i + 1).pretty()), mk('td', {}, new HTML('img', {
style: {
width: '32px',
height: '32px'
},
"class": "img-circle img-responsive",
src: "https://secure.gravatar.com/avatar/" + person.md5 + ".png?d=identicon"
})), mk('td', {}, mk('a', {
href: "?page=people&email=" + person.address
}, person.name)), mk('td', {}, person.address), mk('td', {}, person.commits.pretty()), mk('td', {}, person.issues.pretty()), mk('td', {}, person.emails.pretty())
]);
tb.inject(tr);
}
app(tbl, tb);
return state.widget.inject(tbl);
};
paragraph = function(json, state) {
var len, lmain, p, para, q, ref, results, title;
lmain = mk('div');
state.widget.parent.inject(lmain, true);
if (json.title) {
title = mk('h1', {}, json.title);
app(lmain, title);
}
if (json.text) {
if (isArray(json.text)) {
ref = json.text;
results = [];
for (q = 0, len = ref.length; q < len; q++) {
p = ref[q];
para = mk('p', {
style: "font-size: 1.2rem;"
}, p);
results.push(app(lmain, para));
}
return results;
} else {
return app(lmain, mk('p', {
style: "font-size: 1.2rem;"
}, json.text));
}
}
};
preferences = function(json, state) {
var a, aobj, btn, desc, div, h1, h3, i, id, inp, item, items, len, len1, list, name, obj, opt, org, q, ref, ref1, ref2, u;
obj = document.createElement('form');
items = {
screenname: 'Screen name',
fullname: "Full name",
email: "Email address",
tag: "Organisation filter tag",
token: "API token"
};
desc = {
tag: "If set, only sources with this tag will be shown in your views."
};
ref = ['screenname', 'fullname', 'email', 'tag', 'token'];
for (q = 0, len = ref.length; q < len; q++) {
item = ref[q];
div = mk('div');
app(div, txt(items[item] + ": "));
inp = mk('input');
set(inp, 'type', 'text');
set(inp, 'name', item);
inp.style.width = "200px";
if (item === 'token') {
set(inp, "readonly", "readonly");
set(inp, "disabled", "disabled");
inp.style.width = "700px";
}
set(inp, 'value', json[item] ? json[item] : '');
app(div, inp);
if (desc[item]) {
i = mk('i');
i.style.fontSize = "9pt";
i.style.marginLeft = "20px";
app(i, txt(desc[item]));
app(div, i);
}
app(obj, div);
}
div = mk('div');
app(div, txt("Organisation to view: "));
list = mk('select');
set(list, 'name', 'organisation');
ref1 = json.orgs;
for (u = 0, len1 = ref1.length; u < len1; u++) {
org = ref1[u];
opt = mk('option');
opt.value = org;
opt.text = org;
if (org === json.organisation) {
opt.selected = 'selected';
}
app(list, opt);
}
app(div, list);
app(obj, div);
btn = mk('input');
set(btn, 'type', 'button');
set(btn, 'onclick', 'saveprefs(this.form)');
set(btn, 'value', "Save preferences");
app(obj, btn);
state.widget.inject(obj, true);
if (json.admin) {
aobj = mk('div');
app(aobj, mk('br'));
app(aobj, mk('br'));
h1 = mk('h2');
app(h1, txt("Organisation administration:"));
app(aobj, h1);
app(aobj, txt("If you are an organisation administrator, you may edit your organisation(s) by selecting the org you wish to edit below:"));
ref2 = json.admin;
for (id in ref2) {
name = ref2[id];
a = mk('a');
set(a, 'href', '?page=orgadmin&org=' + id);
h3 = mk('h4');
app(h3, txt("- " + name));
app(a, h3);
app(aobj, a);
}
return state.widget.inject(aobj);
}
};
saveprefs = function(form) {
var i, js, k, q, ref, v;
js = {
action: 'save'
};
for (i = q = 0, ref = form.length - 1; 0 <= ref ? q <= ref : q >= ref; i = 0 <= ref ? ++q : --q) {
k = form[i].name;
v = form[i].value;
if (k === 'screenname' || k === 'fullname' || k === 'email' || k === 'tag' || k === 'organisation') {
js[k] = v;
}
}
return postJSON("preferences", js, null, function(a) {
return alert("Preferences saved!");
});
};
viewJS = {};
publisherWidget = null;
publisherPublic = function(json, state) {
return publisher(json, state, true);
};
publisher = function(json, state, nolink) {
var div, link, twidget;
div = document.createElement('div');
state["public"] = true;
twidget = json.widget.replace(/(-\d?year|-all|-month)/, "");
if (twidget === 'repo-relationship' || twidget === 'issue-relationship' || twidget === 'mail-relationship') {
relationship(json, state);
}
if (twidget === 'languages' || twidget === 'compare-commits' || twidget === 'repo-size' || twidget === 'repo-commits') {
donut(json, state);
} else if (twidget === 'evolution' || twidget === 'evolution-extended' || twidget === 'commit-history' || twidget === 'committer-count' || twidget === 'issue-count' || twidget === 'issue-operators' || twidget === 'commit-lines' || twidget === 'email-count' || twidget === 'issue-queue' || twidget === 'file-age' || twidget === 'file-creation' || twidget === 'im-stats' || twidget === 'log-stats') {
linechart(json, state);
} else if (twidget === 'log-map') {
worldmap(json, state);
} else if (twidget === 'sloc-map') {
treemap(json, state);
} else if (twidget.match(/top/)) {
top5(json, state);
}
viewJS = JSON.stringify({
view: json.eview,
widget: json.widget
});
if (!nolink) {
link = mk('input', {
type: "button",
"class": "btn btn-success",
value: "Publish this widget",
onclick: "publishWidget();"
});
state.widget.inject(link);
return publisherWidget = state.widget;
} else {
if (!location.href.match(/snoot\.io/)) {
link = mk('a', {
href: "https://www.snoot.io/",
style: "font-size: 10px; margin-left: 60px; font-family: sans-serif;"
}, "Data courtesy of Snoot.io");
return state.widget.inject(link);
}
}
};
publishWidget = function() {
return postJSON("publish", {
publish: JSON.parse(viewJS)
}, null, postPublishLink);
};
postPublishLink = function(json, state) {
var added, pdiv;
if (json.id) {
pdiv = get('publishercode');
if (!pdiv) {
pdiv = mk('pre', {
id: "publishercode",
style: "padding: 5px; border: 1px dashed #333; background: #FFD;"
});
publisherWidget.inject(pdiv);
}
pdiv.innerHTML = "";
added = "";
if (json.type && json.type.match(/log-map/)) {
added = "\n<script src=\"https://www.snoot.io/js/worldmap.js\"></script>\n";
}
return app(pdiv, txt("Script code for publishing:\n\n<div class=\"snoot-widget\" data=\"" + json.id + ("\"></div>\n<script src=\"https://www.snoot.io/js/snoot.all.3.js\"></script>\n<script src=\"https://www.snoot.io/publish/bundle.js\"></script>" + added)));
} else {
return alert("Something broke :(");
}
};
radarIndicators = [];
radar = function(json, state) {
var chk, id, label, lmain, radarChart;
lmain = new HTML('div');
state.widget.inject(lmain, true);
radarChart = new Chart(lmain, 'radar', json.radar);
id = Math.floor(Math.random() * 987654321).toString(16);
chk = document.createElement('input');
chk.setAttribute("type", "checkbox");
chk.setAttribute("id", id);
chk.style.marginLeft = '10px';
if (globArgs.harmonize && globArgs.harmonize === 'true') {
chk.checked = true;
}
chk.addEventListener("change", function() {
var harmonize;
harmonize = null;
if (this.checked) {
harmonize = 'true';
globArgs['harmonize'] = 'true';
}
return updateWidgets('radar', null, {
harmonize: harmonize
});
});
state.widget.inject(mk('br'));
state.widget.inject(chk);
label = document.createElement('label');
label.setAttribute("for", id);
label.setAttribute("title", "Check this box to harmonize edges to organisational averages");
chk.setAttribute("title", "Check this box to harmonize edges to organisational averages");
label.style.paddingLeft = '5px';
label.appendChild(document.createTextNode('Harmonize edges'));
state.widget.inject(label);
id = Math.floor(Math.random() * 987654321).toString(16);
chk = document.createElement('input');
chk.setAttribute("type", "checkbox");
chk.setAttribute("id", id);
chk.style.marginLeft = '10px';
if (globArgs.relativize && globArgs.relativize === 'true') {
chk.checked = true;
}
chk.addEventListener("change", function() {
var relativize;
relativize = null;
if (this.checked) {
relativize = 'true';
globArgs['relativize'] = 'true';
}
return updateWidgets('radar', null, {
relativize: relativize
});
});
state.widget.inject(mk('br'));
state.widget.inject(chk);
label = document.createElement('label');
label.setAttribute("for", id);
label.setAttribute("title", "Check this box to force all areas to be relative to their own projects (and not the compared projects). This may help to display foucs areas.");
chk.setAttribute("title", "Check this box to force all areas to be relative to their own projects (and not the compared projects). This may help to display foucs areas.");
label.style.paddingLeft = '5px';
label.appendChild(document.createTextNode('Make all projects relative to themselves'));
return state.widget.inject(label);
};
relationship = function(json, state) {
var chart, div, i, id, invchk, invlbl, opt, q, sigsel;
div = document.createElement('div');
state.widget.inject(div, true);
chart = new Chart(div, 'relationship', json, {});
id = Math.floor(Math.random() * 987654321).toString(16);
invchk = new HTML('input', {
"class": "uniform",
style: {
marginRight: "10px"
},
id: "author_" + id,
type: 'checkbox',
checked: globArgs.author,
name: 'author',
value: 'true'
});
invchk.addEventListener("change", function() {
var author;
author = null;
if (this.checked) {
author = 'true';
globArgs['author'] = 'true';
}
return updateWidgets('relationship', null, {
author: author
});
});
invlbl = new HTML('label', {
"for": "author_" + id
}, "Inverse map (sender <-> recipient)");
state.widget.inject(invchk);
state.widget.inject(invlbl);
state.widget.inject(new HTML('br'));
state.widget.inject(new HTML('span', {}, "Minimum signal strength: "));
sigsel = new HTML('select', {
id: "signal_" + id
});
for (i = q = 1; q <= 5; i = ++q) {
opt = new HTML('option', {
value: i,
selected: String(i) === globArgs.links ? "selected" : null
}, String(i));
sigsel.inject(opt);
}
sigsel.addEventListener("change", function() {
var links;
links = null;
if (this.value) {
links = this.value;
globArgs['links'] = links;
}
return updateWidgets('relationship', null, {
links: links
});
});
return state.widget.inject(sigsel);
};
rcollate = function(list) {
var line, out;
out = "";
while (list.length > 2) {
line = list.shift();
out += line + ", ";
}
if (list.length > 1) {
out += list[0] + " and " + list[1];
} else {
return list[0];
}
return out;
};
report = function(json, state) {
var active, age, ageInMonths, ageInYears, carr, div, p, pct, rtext, stitle, title;
div = document.createElement('div');
state.widget.inject(div, true);
if (json.projectAge === 0) {
app(div, mk('h3', {}, "We were unable to determine the age of this project, sorry!"));
return;
}
ageInMonths = parseInt(json.projectAge / (86400 * 30.3));
ageInYears = parseInt(json.projectAge / (86400 * 365.25));
age = mk('h3', {}, "Estimated age of project: " + ageInMonths + " months (" + ageInYears + " years)");
app(div, age);
if (ageInYears >= 1) {
title = mk('h2', {}, "Long range trends:");
app(div, title);
stitle = mk('h3', {}, "Commits:");
carr = [];
if (ageInYears >= 5) {
pct = json.commits['5'].angle;
rtext = "a rapid decline in commits in the long term (5+ years)";
if (pct > -50) {
rtext = "a moderate decline in commits in the long term (5+ years)";
}
if (pct > -30) {
rtext = "a slow decline in commits in the long term (5+ years)";
}
if (pct > -10) {
rtext = "a steady rate of commits in the long term (5+ years)";
}
if (pct > 10) {
rtext = "a slow increase in commits in the long term (5+ years)";
}
if (pct > 30) {
rtext = "a moderate increase in commits in the long term (5+ years)";
}
if (pct > 50) {
rtext = "a strong increase in commits in the long term (5+ years)";
}
carr.push(rtext);
}
if (ageInYears >= 2) {
pct = json.commits['2'].angle;
rtext = "a rapid decline in commits in the medium term (2 years)";
if (pct > -50) {
rtext = "a moderate decline in commits in the medium term (2 years)";
}
if (pct > -30) {
rtext = "a slow decline in commits in the medium term (2 years)";
}
if (pct > -10) {
rtext = "a steady rate of commits in the medium term (2 years)";
}
if (pct > 10) {
rtext = "a slow increase in commits in the medium term (2 years)";
}
if (pct > 30) {
rtext = "a moderate increase in commits in the medium term (2 years)";
}
if (pct > 50) {
rtext = "a strong increase in commits in the medium term (2 years)";
}
carr.push(rtext);
}
if (ageInYears >= 1) {
pct = json.commits['1'].angle;
rtext = "a rapid decline in commits in the short term (past year)";
if (pct > -50) {
rtext = "a moderate decline in commits in the short term (past year)";
}
if (pct > -30) {
rtext = "a slow decline in commits in the short term (past year)";
}
if (pct > -10) {
rtext = "a steady rate of commits in the short term (past year)";
}
if (pct > 10) {
rtext = "a slow increase in commits in the short term (past year)";
}
if (pct > 30) {
rtext = "a moderate increase in commits in the short term (past year)";
}
if (pct > 50) {
rtext = "a strong increase in commits in the short term (past year)";
}
carr.push(rtext);
}
p = mk('p', {}, "This project has experienced " + rcollate(carr) + ".");
app(div, stitle);
app(div, p);
stitle = mk('h3', {}, "Contributors:");
carr = [];
if (ageInYears >= 5) {
pct = json.authors['5'].authors.angle;
rtext = "a rapid decline in contributors in the long term (5+ years)";
if (pct > -50) {
rtext = "a moderate decline in contributors in the long term (5+ years)";
}
if (pct > -30) {
rtext = "a slow decline in contributors in the long term (5+ years)";
}
if (pct > -10) {
rtext = "a steady rate of contributors in the long term (5+ years)";
}
if (pct > 10) {
rtext = "a slow increase in contributors in the long term (5+ years)";
}
if (pct > 30) {
rtext = "a moderate increase in contributors in the long term (5+ years)";
}
if (pct > 50) {
rtext = "a strong increase in contributors in the long term (5+ years)";
}
carr.push(rtext);
}
if (ageInYears >= 2) {
pct = json.authors['2'].authors.angle;
rtext = "a rapid decline in contributors in the medium term (2 years)";
if (pct > -50) {
rtext = "a moderate decline in contributors in the medium term (2 years)";
}
if (pct > -30) {
rtext = "a slow decline in contributors in the medium term (2 years)";
}
if (pct > -10) {
rtext = "a steady rate of contributors in the medium term (2 years)";
}
if (pct > 10) {
rtext = "a slow increase in contributors in the medium term (2 years)";
}
if (pct > 30) {
rtext = "a moderate increase in contributors in the medium term (2 years)";
}
if (pct > 50) {
rtext = "a strong increase in contributors in the medium term (2 years)";
}
carr.push(rtext);
}
if (ageInYears >= 1) {
pct = json.authors['1'].authors.angle;
rtext = "a rapid decline in contributors in the short term (past year)";
if (pct > -50) {
rtext = "a moderate decline in contributors in the short term (past year)";
}
if (pct > -30) {
rtext = "a slow decline in contributors in the short term (past year)";
}
if (pct > -10) {
rtext = "a steady rate of contributors in the short term (past year)";
}
if (pct > 10) {
rtext = "a slow increase in contributors in the short term (past year)";
}
if (pct > 30) {
rtext = "a moderate increase in contributors in the short term (past year)";
}
if (pct > 50) {
rtext = "a strong increase in contributors in the short term (past year)";
}
carr.push(rtext);
active = parseInt(json.authors['1'].authors.average);
carr.push("currently has " + active + " active contributors");
}
p = mk('p', {}, "The project has had " + rcollate(carr) + ".");
app(div, stitle);
return app(div, p);
}
};
make5 = function(obj, json, pos) {
var filter, fodder, i, idiv, item, k, left, len, q, ref, ref1, results, right, rightInner, t, title, v, what;
what = json.topN.denoter;
ref = json.topN.items.slice(pos, pos + 5);
results = [];
for (i = q = 0, len = ref.length; q < len; i = ++q) {
item = ref[i];
if (i === 5) {
break;
}
idiv = new HTML('div', {
"class": "media event"
});
left = new HTML('a', {
"class": "pull-left"
});
if (item.gravatar) {
left.inject(new HTML('img', {
"class": "img-circle img-reponsive",
src: "https://secure.gravatar.com/avatar/" + item.gravatar + ".png?d=identicon",
style: {
width: "32px",
height: "32px"
}
}));
} else if (json.topN.icon) {
left.inject(new HTML('i', {
"class": "fa fa-" + json.topN.icon,
style: {
fontSize: "28px"
}
}));
}
right = new HTML('div', {
"class": "media event"
});
rightInner = new HTML('div', {
"class": "media-body"
});
right.inject(rightInner);
if (item.email) {
title = new HTML('a', {
"class": "title",
href: "contributors.html?page=biography&email=" + item.email
}, txt(item.name));
rightInner.inject(title);
rightInner.inject(" - ");
filter = new HTML('a', {
"class": "title",
href: "javascript: void(filterPerson('" + item.email + "'));"
}, "[filter]");
rightInner.inject(filter);
} else if (item.url) {
if (item.title) {
item.tooltip = item.title;
if (item.title.length > 40) {
item.title = item.title.toString().substring(0, 40) + "...";
}
item.name += ": " + item.title;
}
item.url = item.url.replace(/([^:])(\/\/+)/g, '$1/');
title = new HTML('a', {
title: item.tooltip,
"class": "title",
href: item.url
}, txt(item.name));
rightInner.inject(title);
} else {
title = new HTML('a', {
"class": "title"
}, txt(item.name));
rightInner.inject(title);
}
fodder = new HTML('p', {});
fodder.inject(new HTML('b', {}, item.count.pretty()));
fodder.inject(txt(" " + what + " during this period"));
if (item.subcount) {
fodder.inject(new HTML('br'));
t = [];
ref1 = item.subcount;
for (k in ref1) {
v = ref1[k];
t.push(v.pretty() + " " + k);
}
fodder.inject(new HTML('small', {}, t.join(", ") + "."));
}
rightInner.inject(fodder);
idiv.inject(left);
idiv.inject(right);
results.push(obj.inject(idiv));
}
return results;
};
top5 = function(json, state) {
var id, items, nid, obj, pos, results;
items = [];
if (json.topN) {
id = parseInt(Math.random() * 99999999).toString(16);
obj = new HTML('div', {
id: id
});
make5(obj, json, 0);
state.widget.inject(obj, true);
pos = 5;
results = [];
while (pos < json.topN.items.length) {
nid = id + "_show_" + pos;
obj.inject(new HTML('a', {
style: {
cursor: 'pointer'
},
onclick: "this.style.display = 'none'; get('" + nid + "').style.display = 'block';"
}, "Show more..."));
obj = new HTML('div', {
id: nid,
style: {
display: 'none'
}
});
make5(obj, json, pos);
state.widget.inject(obj);
results.push(pos += 5);
}
return results;
}
};
showMore = function(id) {
var obj;
obj = document.getElementById(id);
if (obj) {
return obj.style.display = "block";
}
};
filterPerson = function(email) {
if (email === "") {
email = null;
}
updateWidgets('donut', null, {
email: email
});
updateWidgets('line', null, {
email: email
});
updateWidgets('contacts', null, {
email: email
});
updateWidgets('top5', null, {
email: email
});
updateWidgets('trends', null, {
email: email
});
updateWidgets('relationship', null, {
email: email
});
updateWidgets('viewpicker', null, {
email: email
});
return globArgs.email = email;
};
treemap = function(json, state) {
var catdata, cats, colors, dates, div, echartLine, filled, i, lang, ld, len, len1, option, project, q, range, rect, ref, stack, type, u;
div = document.createElement('div');
cats = new Array();
dates = new Array();
catdata = {};
filled = {
areaStyle: {
type: 'default'
}
};
if (json.widgetType) {
if (json.widgetType.chartType) {
type = json.widgetType.chartType;
}
if (json.widgetType.stack) {
stack = json.widgetType.stack;
}
if (json.widgetType.nofill) {
filled = null;
}
}
if (!json.widget.title || json.widget.title.length === 0) {
json.widget.title = 'Languages';
}
if (!state.widget.div.style.height) {
div.style.minHeight = "900px";
} else {
div.style.minHeight = "100%";
}
if (state.widget.fullscreen) {
div.style.minHeight = (window.innerHeight - 100) + "px";
}
state.widget.inject(div, true);
range = "";
rect = div.getBoundingClientRect();
theme.color = genColors(json.treemap.length + 1, 0.6, 0.5, true);
colors = genColors(json.treemap.length + 1, 0.6, 0.5, true);
theme.textStyle.fontSize = Math.max(12, window.innerHeight / 100);
echartLine = echarts.init(div, theme);
ld = [];
ref = json.treemap;
for (i = q = 0, len = ref.length; q < len; i = ++q) {
lang = ref[i];
ld.push(lang);
for (u = 0, len1 = lang.length; u < len1; u++) {
project = lang[u];
project.color = colors[i];
project.itemStyle = {
normal: {
color: colors[i]
}
};
}
}
option = {
title: {
text: json.widget.title,
left: 'center'
},
legend: [
{
x: 'center',
y: 'top',
data: ld
}
],
tooltip: {
show: true,
feature: {
saveAsImage: {
show: true,
title: "Save Image"
}
},
formatter: function(info) {
var aa, ref1, treePath, treePathInfo, value;
value = info.value;
treePathInfo = info.treePathInfo;
treePath = [];
for (i = aa = 1, ref1 = treePathInfo.length; 1 <= ref1 ? aa < ref1 : aa > ref1; i = 1 <= ref1 ? ++aa : --aa) {
treePath.push(treePathInfo[i].name);
}
return ['<div class="tooltip-title">' + treePath.join('/') + '</div>', 'Lines of Code: ' + value.pretty()].join('');
}
},
series: [
{
name: json.widget.title,
type: 'treemap',
visibleMin: 1000,
label: {
show: true,
formatter: '{b}'
},
itemStyle: {
normal: {
borderColor: '#fff'
}
},
levels: [
{
itemStyle: {
normal: {
borderColor: '#555',
borderWidth: 4,
gapWidth: 4
}
}
}, {
colorSaturation: [0.3, 0.6],
itemStyle: {
normal: {
borderColorSaturation: 0.7,
gapWidth: 2,
borderWidth: 2
}
}
}
],
data: json.treemap
}
]
};
return echartLine.setOption(option = option);
};
trendBox = function(icon, count, title, desc) {
var cdiv, codiv, div, h3, i, icons, idiv, p;
icons = {
comment: 'fa-comments-o',
down: 'fa-sort-amount-desc',
up: 'fa-sort-amount-asc',
check: 'fa-check-square-o',
caret: 'fa-caret-square-o-right',
spin: 'fa-spin fa-cog'
};
div = document.createElement('div');
div.setAttribute("class", "animated flipInY col-lg-3 col-md-3 col-sm-6 col-xs-12");
cdiv = document.createElement('div');
cdiv.setAttribute("class", "tile-stats");
cdiv.style.width = "100%";
idiv = document.createElement('div');
idiv.setAttribute("class", "icon");
i = document.createElement('i');
i.setAttribute("class", "fa " + (icons[icon] || 'fa-comments-o'));
idiv.appendChild(i);
cdiv.appendChild(idiv);
codiv = document.createElement('div');
codiv.setAttribute("class", "count");
codiv.appendChild(document.createTextNode(count));
cdiv.appendChild(codiv);
h3 = document.createElement('h4');
h3.appendChild(document.createTextNode(title));
cdiv.appendChild(h3);
p = document.createElement('p');
p.appendChild(document.createTextNode(desc));
cdiv.appendChild(p);
div.appendChild(cdiv);
return div;
};
trend = function(json, state) {
var data, diff, icon, key, linediff, ref, results, tb, wipe;
console.log(state.widget.args.source);
if (json.trends) {
wipe = true;
ref = json.trends;
results = [];
for (key in ref) {
data = ref[key];
linediff = "";
icon = 'up';
if (data.before > 0 && data.after > 0) {
diff = (data.after - data.before) / (data.before || 1);
if (diff >= 0) {
linediff = "Up " + Math.floor(diff * 100) + "% since last period";
} else {
linediff = "Down " + Math.floor(diff * 100) + "% since last period";
icon = 'check';
}
}
tb = trendBox(icon, data.after.pretty(), data.title, linediff);
state.widget.inject(tb, wipe);
results.push(wipe = false);
}
return results;
}
};
newview = [];
saveview = function(id) {
var publicView, view, viewname;
if (!id) {
if (get('viewname').value === '') {
alert('Please enter a name for this view!');
return;
}
newview = [];
$("[datatype=source]").each(function() {
var pid, sel;
pid = $(this).attr('id');
sel = $(this).attr('selected') || "blorp";
if (sel === "selected") {
return newview.push(pid);
}
});
viewname = get('viewname').value;
publicView = false;
if (get('public')) {
publicView = get('public').checked;
}
view = {
id: 'makeone',
name: viewname,
sources: newview,
"public": publicView
};
return put('views', view, null, function() {
return window.setTimeout(function() {
return location.href = '?page=views';
}, 1500);
});
} else {
view = {
id: id,
sources: newview
};
return patch('views', view, null, function() {
return window.setTimeout(function() {
return location.href = '?page=views';
}, 1500);
});
}
};
rmview = function(id) {
return xdelete('views', {
id: id
}, null, function() {
return window.setTimeout(function() {
return location.href = '?page=views';
}, 1500);
});
};
newview = [];
currentSources = {};
filterView = function(val) {
var me, re, results, source, url;
re = new RegExp(val, 'i');
newview = [];
results = [];
for (source in currentSources) {
url = currentSources[source];
me = get(source);
me.removeAttribute('selected');
me.style.background = "none";
me.style.color = "#000";
if (val.length > 0) {
me.style.display = 'none';
} else {
me.style.display = 'block';
}
if (val.length > 0 && url.match(re)) {
me.setAttribute("selected", "true");
me.style.background = "#4B8";
me.style.color = "#FFF";
results.push(me.style.display = 'block');
} else {
results.push(void 0);
}
}
return results;
};
manageviews = function(json, state) {
var aa, btn, h3, h4, inp, len, len1, len2, newdiv, noviews, obj, p, popdiv, q, ref, ref1, ref2, ref3, ref4, sdiv, source, u, view;
obj = mk('div');
p = mk('p');
app(p, txt("Views allow you to quickly set up a group of sources to view as a sub-organisation, much like tags, but faster."));
app(obj, p);
h3 = mk('h3');
noviews = json.views.length || 0;
app(h3, txt("You currently have " + noviews + " view" + (noviews === 1 ? '' : 's') + " in your database "));
btn = mk('input');
set(btn, 'type', 'button');
set(btn, 'class', 'btn btn-success');
set(btn, 'value', 'Create a new view');
set(btn, 'onclick', 'get("newdiv").style.display = "block"; this.style.display = "none";');
app(h3, btn);
app(obj, h3);
newdiv = mk('div');
set(newdiv, 'id', 'newdiv');
newdiv.style.display = "none";
json.sources.sort(function(a, b) {
return (a.type === b.type ? (a.sourceURL > b.sourceURL ? 1 : -1) : (b.type < a.type ? 1 : -1));
});
inp = mk('input');
set(inp, 'type', 'text');
set(inp, 'id', 'viewname');
app(newdiv, txt("Name your new view: "));
app(newdiv, inp);
app(newdiv, mk('br'));
if (userAccount.userlevel === 'admin' || (ref = userAccount.defaultOrganisation, indexOf.call(userAccount.ownerships, ref) >= 0)) {
inp = mk('input');
set(inp, 'type', 'checkbox');
set(inp, 'id', 'public');
app(newdiv, txt("Make view public (global): "));
app(newdiv, inp);
app(newdiv, mk('br'));
}
inp = mk('input');
set(inp, 'type', 'text');
set(inp, 'id', 'viewfilter');
set(inp, 'oninput', "filterView(this.value)");
app(newdiv, txt("Filter-select: "));
app(newdiv, inp);
app(newdiv, mk('i', {}, "You can use the filter-select to quickly mark sources based on a regex. Type in 'foo' to select all sources matching 'foo' etc."));
app(newdiv, mk('br'));
app(newdiv, txt("Select the sources you wish to add to this view below:"));
app(newdiv, mk('br'));
btn = mk('input');
set(btn, 'type', 'button');
set(btn, 'class', 'btn btn-danger');
set(btn, 'value', 'Save view');
set(btn, 'onclick', 'saveview();');
app(newdiv, btn);
ref1 = json.sources;
for (q = 0, len = ref1.length; q < len; q++) {
source = ref1[q];
currentSources[source.sourceID] = source.sourceURL;
sdiv = mk('div');
set(sdiv, 'id', source.sourceID);
set(sdiv, 'datatype', 'source');
sdiv.style.cursor = 'pointer';
sdiv.style.margin = "3px";
sdiv.style.border = "1px solid #666";
sdiv.style.color = "#000";
sdiv.addEventListener("click", function() {
var selected, w;
w = findWidget(this.getAttribute('widget'));
selected = this.getAttribute("selected");
if (selected && selected === "true") {
this.style.background = "none";
this.style.color = "#000";
set(this, 'selected', 'false');
} else {
this.style.background = "#4B8";
this.style.color = "#FFF";
set(this, 'selected', 'true');
}
return newview = [];
});
app(sdiv, txt(source.sourceURL));
app(newdiv, sdiv);
}
btn = mk('input');
set(btn, 'type', 'button');
set(btn, 'class', 'btn btn-danger');
set(btn, 'value', 'Save view');
set(btn, 'onclick', 'saveview();');
app(newdiv, btn);
app(obj, newdiv);
ref2 = json.views;
for (u = 0, len1 = ref2.length; u < len1; u++) {
view = ref2[u];
popdiv = mk('div');
popdiv.style.paddingLeft = "10px";
popdiv.style.margin = "3px";
popdiv.style.borderRadius = "4px";
h4 = mk('h4');
app(h4, txt(view.name + " - " + view.sourceList.length + " sources"));
popdiv.style.border = "1px solid #333";
popdiv.style.background = "#323234";
h4.style.display = "inline-block";
app(popdiv, h4);
btn = mk('input');
set(btn, 'type', 'button');
set(btn, 'class', 'btn btn-warning');
set(btn, 'value', 'Edit view');
set(btn, 'onclick', "get('" + view.id + "').style.display = (get('" + view.id + "').style.display == 'block') ? 'none' : 'block'");
btn.style.marginLeft = "20px";
btn.style.padding = "2px";
app(popdiv, btn);
btn = mk('input');
set(btn, 'type', 'button');
set(btn, 'class', 'btn btn-danger');
set(btn, 'value', 'Delete view');
set(btn, 'onclick', 'rmview("' + view.id + '");');
btn.style.marginLeft = "20px";
btn.style.padding = "2px";
app(popdiv, btn);
btn = mk('input');
set(btn, 'type', 'button');
set(btn, 'class', 'btn btn-success');
set(btn, 'value', 'Save changes');
set(btn, 'onclick', 'saveview("' + view.id + '");');
btn.style.marginLeft = "20px";
btn.style.padding = "2px";
app(popdiv, btn);
h4.style.color = "#FFA";
h4.style.cursor = 'pointer';
set(h4, 'onclick', "get('" + view.id + "').style.display = (get('" + view.id + "').style.display == 'block') ? 'none' : 'block'");
newdiv = mk('div');
set(newdiv, 'id', view.id);
newdiv.style.display = "none";
inp = mk('input');
set(inp, 'type', 'text');
set(inp, 'id', 'viewname');
app(newdiv, txt("Select the sources you wish to have in this view below:"));
ref3 = json.sources;
for (aa = 0, len2 = ref3.length; aa < len2; aa++) {
source = ref3[aa];
sdiv = mk('div');
set(sdiv, 'id', view.id + "_" + source.sourceID);
set(sdiv, 'datatype', view.id);
sdiv.style.cursor = 'pointer';
sdiv.style.margin = "3px";
sdiv.style.border = "1px solid #666";
sdiv.style.color = "#000";
if (ref4 = source.sourceID, indexOf.call(view.sourceList, ref4) >= 0) {
sdiv.style.background = "#4B8";
sdiv.style.color = "#FFF";
set(sdiv, 'selected', 'selected');
} else {
set(sdiv, 'selected', 'false');
}
sdiv.addEventListener("click", function() {
var selected, vid;
selected = this.getAttribute("selected");
vid = this.getAttribute("datatype");
if (selected && selected === "selected") {
this.style.background = "none";
this.style.color = "#000";
set(this, 'selected', 'false');
} else {
this.style.background = "#4B8";
this.style.color = "#FFF";
set(this, 'selected', 'selected');
}
newview = [];
return $("[datatype=" + vid + "]").each(function() {
var pid, sel;
pid = $(this).attr('id').split(/_/)[1];
sel = this.getAttribute("selected");
if (sel === 'selected') {
return newview.push(pid);
}
});
});
app(sdiv, txt(source.sourceURL));
app(newdiv, sdiv);
}
btn = mk('input');
set(btn, 'type', 'button');
set(btn, 'class', 'btn btn-success');
set(btn, 'value', 'Save view');
set(btn, 'onclick', 'saveview("' + view.id + '");');
app(newdiv, btn);
app(obj, popdiv);
app(obj, newdiv);
}
return state.widget.inject(obj, true);
};