Skip to content

Instantly share code, notes, and snippets.

@artzub
Last active December 10, 2015 23:28
Show Gist options
  • Save artzub/4509035 to your computer and use it in GitHub Desktop.
Save artzub/4509035 to your computer and use it in GitHub Desktop.
Work with github api.
.idea/
*.iml
*.iws
/**
* User: ArtZub
* Date: 15.01.13
* Time: 2:13
*/
'use strict';
(function(window) {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame =
window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
})(window);
var ONE_SECOND = 1000,
ONE_MINUTE = 60 * ONE_SECOND,
ONE_HOUR = 60 * ONE_MINUTE,
ONE_DAY = 24 * ONE_HOUR,
PI_CIRCLE = 2 * Math.PI;
var ghcs = {
users: {},
states: {cur:0, max:0},
limits: {
commits : 100,
stepShow : 1,
stepType : ONE_DAY
},
settings : {
access : {
client_id : "c45417c5d6249959a91d",
client_secret : "4634b3aa7549c3d6306961e819e5ec9b355a6548"
},
cs : {
fileLife : 255 // number of steps of life a file
, userLife : 255 // number of steps of life a user
, edgeLife : 255 // number of steps of life a edge
, showCountExt : true // show table of file's extension
, onlyShownExt : true // show only extension which is shown
, showHistogram : true // displaying histogram of changed files
, showHalo : true // show a file's halo
, padding : 25 // padding around a user
, rateOpacity : .5 // rate of decrease of opacity
, rateFlash : 2.5 // rate of decrease of flash
, sizeFile : 2 // size of file
, sizeUser : 24 // size of user
, showPaddingCircle : false // show circle of padding
, useAvatar : true // show user's avatar
, showEdge : true // show a edge
, showFile : true // show a file
, showUser : true // show a user
, showLabel : true // show user name
, showFilename : true // show file name TODO: надо-ли?
, labelPattern : "%n <%e>" // pattern for label of user
, showCommitMessage : false // show commit message
, skipEmptyDate : true // skip empty date
}
},
asyncForEach: function(items, fn, time) {
if (!(items instanceof Array))
return;
var workArr = items.reverse().concat();
function loop() {
if (workArr.length > 0)
fn(workArr.shift(), workArr);
if (workArr.length > 0)
setTimeout(loop, time || 1);
}
loop();
},
imageHash : d3.map({})
};
(function(ghcs) {
ghcs.storage = sessionStorage;
if (ghcs.storage) {
Storage.prototype.set = function(key, value) {
this.setItem(key, JSON.stringify(value));
};
Storage.prototype.get = function(key) {
var res = this.getItem(key);
return res ? JSON.parse(res) : res;
};
Storage.prototype.setImageData = setImageData;
}
else {
ghcs.storage = d3.map({});
ghcs.storage.clear = function() {
var ks = ghcs.storage.keys,
l = ks.length;
while(--l > -1)
ghcs.storage.remove(ks[l]);
};
ghcs.storage.setImageData = setImageData;
}
var canvas = document.createElement("canvas"),
ctx = canvas.getContext("2d");
/**
* @param url {String}
* @param image {Image}
*/
function setImageData(url, image) {
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0, 0);
ghcs.storage.set(url, canvas.toDataURL("image/png"));
canvas.width = 0;
canvas.height = 0;
}
})(ghcs);
/**
* User: ArtZub
* Date: 15.01.13
* Time: 1:36
*/
'use strict';
var TYPE_REQUEST = {
repos : 1,
commits : 2
}
, TYPE_STATUS_FILE = {
removed : 0,
modified : 1,
added : 2,
renamed : 3
}
;
function makeUrl(url, type, limit) {
limit = limit || 0;
var sec = "client_id=" + ghcs.settings.access.client_id + "&client_secret=" + ghcs.settings.access.client_secret;
if (type == TYPE_REQUEST.repos) {
sec += (ghcs.rot ? "&per_page=100&type=" + ghcs.rot : "" );
}
else if(type == TYPE_REQUEST.commits) {
limit = limit < 0 ? ghcs.limits.commits : limit;
sec += "&per_page=" + (limit > 100 ? 100 : limit)
}
return url ? (url + (url.indexOf('?') === -1 ? '?' : '&') + sec) : url;
}
function crossUrl(url, rt) {
return url;
/*var result = url, arr = /(.*)?\?(.*)/.exec(url);
if (arr) {
result = "http://artzub.com/cross/?"
+ ( rt ? "rt=" + rt + "&" : "" )
+ "u=" + arr[1];
if (arr.length > 2)
result += "&d=" + encodeURIComponent(arr[2]);
}
return result;*/
}
function randTrue() {
return Math.round((Math.random() * 2) % 2);
}
function getDataFromRequest(req) {
return req && req.meta && req.meta.status == 200 && req.data ? req.data : (log(req) && null);
}
function parseCommit(org_commit, commit){
if (!commit || !org_commit || commit.sha != org_commit.sha)
return;
var s = commit.stats = {
f : {
m : 0,
a : 0,
d : 0
},
changes : 0,
additions : 0,
deletions : 0
};
commit.files = org_commit.files.map(function(f) {
if (TYPE_STATUS_FILE[f.status] == undefined)
console.log(f.status);
f.status = TYPE_STATUS_FILE[f.status];
if (f.changes > 0) {
s.changes += f.changes;
s.additions += f.additions;
s.deletions += f.deletions;
}
else if(f.status) {
commit.stats.changes++;
commit.stats.additions++;
}
else if(!f.status) {
commit.stats.changes -= commit.stats.changes ? 1 : 0;
commit.stats.additions -= commit.stats.additions ? 1 : 0;
}
(f.status == TYPE_STATUS_FILE.modified || f.status == TYPE_STATUS_FILE.renamed) && s.f.m++;
f.status == TYPE_STATUS_FILE.added && s.f.a++;
!f.status && s.f.d++;
return {
name : f.filename.toLowerCase(),
changes : f.changes || 0,
additions : f.additions || 0,
deletions : f.deletions || 0,
status : f.status
}
});
ghcs.repo.stats = ghcs.repo.stats || {};
ghcs.repo.stats.changes = d3.max([ghcs.repo.stats.changes || 0, commit.stats.deletions, commit.stats.additions]);
ghcs.repo.stats.files = d3.max([ghcs.repo.stats.files || 0, s.f.a + s.f.m, s.f.d]);
}
function upCommits() {
redrawStats();
updateStatus(ghcs.states.cur++);
ldrTop.show();
psBar.show();
checkCompleted();
}
function preloadImage(url) {
var ava, image;
image = ghcs.imageHash.get(url);
if (!image) {
image = new Image();
//ava = ghcs.storage.get(url);
//if (!ava) {
image.onerror = function () {
return console.log(this);
};
/*image.onload = (function (url) {
return function () {
if (url)
ghcs.storage.setImageData(url, this);
};
})(url);*/
image.src = crossUrl((url || (url = "https://secure.gravatar.com/avatar/" + Date.now() + Date.now() + "?d=identicon&f=y")) + "&s=48", "image");
/*}
else {
image.src = ava;
}*/
ghcs.imageHash.set(url, image);
}
return image;
}
function parseCommits(commits) {
ghcs.repo.commits = ghcs.repo.commits || d3.map({});
if (commits && commits.length) {
updateStatus(ghcs.states.cur);
psBar.show();
ldrTop.show();
commits.forEach(function(d, i) {
var obj = ghcs.repo.commits.get(d.sha);
if (!obj) {
obj = {
url : d.url,
sha : d.sha,
author : {
name : d.commit.author.name,
email : d.commit.author.email,
login : d.author && d.author.login ? d.author.login : d.commit.author.email
},
committer : {
name : d.commit.committer.name,
email : d.commit.committer.email,
login : d.committer && d.committer.login ? d.committer.login : d.commit.committer.email
},
date : Date.parse(d.commit.author.date),
avatar_url : (d.author && d.author.avatar_url ? d.author.avatar_url : null),
message : d.commit.message,
parents : d.parents
};
ghcs.repo.commits.set(obj.sha, obj);
obj.author.avatar = preloadImage(obj.avatar_url);
}
if (!obj.files) {
JSONP(makeUrl(obj.url), (function(c) {
ghcs.repo.dates.push(c.date);
ghcs.repo.dates.sort(d3.ascending);
return function(req) {
parseCommit(getDataFromRequest(req), ghcs.repo.commits.get(c.sha));
upCommits();
};
})(obj), {
onerror : function(err) {
console.log(err);
upCommits();
}
});
}
else {
upCommits();
}
});
}
else {
upCommits();
}
}
function clearUserRepos() {
if (ghcs.users.hasOwnProperty(ghcs.login) && ghcs.users[ghcs.login].hasOwnProperty("repos"))
delete ghcs.users[ghcs.login]["repos"]
}
function parseRepos(data) {
if (data) {
ghcs.users[ghcs.login] = ghcs.users[ghcs.login] || {};
ghcs.users[ghcs.login].repos = (ghcs.users[ghcs.login].repos || []).concat(
data.filter(function (d) {
return !d.private && !d.hasOwnProperty("nodeValue");
}).map(function (d) {
return {
x : (Math.random() * w) || 1,
y : (Math.random() * h) || 1,
nodeValue : {
id: d.id,
name: d.name,
url: d.url,
html_url: d.html_url,
commits_url : d.commits_url.replace(/{.*$/, ""),
size : d.size,
date : Date.parse(d.pushed_at || d.updated_at),
cdate : Date.parse(d.created_at),
desc : d.description,
lang : d.language || "Multi"
}
};
})
);
ghcs.states.cur = ghcs.users[ghcs.login].repos.length;
}
updateStatus(ghcs.states.cur, "loading ...");
ldrTop.show();
psBar.show();
checkCompleted();
redrawRepos();
}
function chSelect(e) {
if (e) {
ghcs.repo = e.nodeValue;
ghcs.repo.dates = [];
ghcs.repo.changes = [];
runBtn.enable();
curRep.setName(e);
}
else {
ghcs.repo = null;
runBtn.disable();
curRep.setName(null);
stepsBar.secondStep();
}
}
function chUser() {
if (ghcs.chUserTimer) {
clearTimeout(ghcs.chUserTimer);
delete ghcs.chUserTimer;
}
ghcs.chUserTimer = setTimeout((function (login) {
return function () {
if (login) {
stepsBar.firstStep();
curRep.setName(null);
vis.clearRepos();
userTxt.disable();
showBtn.disable();
runBtn.disable();
ghcs.login = login;
ghcs.repo = null;
redrawStats();
ghcs.states.complete = function() {
stepsBar.secondStep();
ldrTop.hide();
setTimeout(nextStepApplyParams, 500);
};
cbDlr.check();
if (!ghcs.users.hasOwnProperty(login) || !ghcs.users[login].hasOwnProperty("repos")) {
ldrTop.show();
JSONP(makeUrl("https://api.github.com/users/" + login), function (req) {
var data = getDataFromRequest(req);
if (!data) {
parseRepos(null);
return;
}
var u = ghcs.users[data.login] = {info: data};
u.info.avatar = new Image();//preloadeImage(u.info.avatar_url);
u.info.avatar.src = u.info.avatar_url;
ghcs.login = data.login;
ghcs.states.max = +u.info.public_repos;
ghcs.states.cur = 0;
updateStatus(ghcs.states.cur, "loading ...");
psBar.show();
if (data.repos_url)
JSONP(makeUrl(data.repos_url, TYPE_REQUEST.repos), function getAll(req) {
parseRepos(getDataFromRequest(req));
getNext(req, function(next) {
if (next) {
ldrTop.show();
JSONP(next, getAll);
}
});
divStat.updateInfo();
}, {
onerror : function(err) {
console.log(err);
}
});
else
parseRepos(null);
divStat.updateInfo();
});
}
else {
ghcs.states.max = ghcs.users[login].repos ? ghcs.users[login].repos.length : 0;
parseRepos(ghcs.users[login].repos);
}
divStat.updateInfo();
userTxt.enable();
}
}
})(userTxt.property("value")), 300);
}
function getNext(req, fn) {
var next;
if (req && req.meta && req.meta.Link) {
next = req.meta.Link.reduce(function (a, b) {
if (!a && b[1].rel == "next")
return b[0];
return a;
}, null);
}
fn && fn(next);
}
function analyseCommits() {
runBtn.disable();
ldrTop.show();
ghcs.states.max = ghcs.limits.commits;
ghcs.states.cur = 0;
ghcs.states.loaded = 0;
ghcs.states.complete = function() {
stepsBar.thirdStep();
runBtn.enable();
ldrTop.hide();
visBtn.enable();
if (ghcs.repo && ghcs.repo.commits)
ghcs.repo.commitsCount = ghcs.repo.commits.values().filter(function(d) {
return !!d.files;
}).length;
vis.redrawStat(ghcs.repo);
setTimeout(nextStepApplyParams, 500);
};
vis.layers.stat.toFront();
cbDlsr.check();
if (!ghcs.repo || !ghcs.repo.commits_url || ghcs.repo.loadedAll) {
updateStatus(ghcs.states.cur = ghcs.states.max);
checkCompleted();
return;
}
JSONP(makeUrl(ghcs.repo.commits_url, TYPE_REQUEST.commits, ghcs.limits.commits), function getAll(req) {
getNext(req, function(next) {
var l = req && req.data && req.data instanceof Array ? req.data.length : 0;
ghcs.states.loaded += l;
l = ghcs.states.max - ghcs.states.loaded;
if (next && l > 0) {
updateStatus(ghcs.states.cur);
psBar.show();
ldrTop.show();
JSONP(next.replace("per_page=100", "per_page=" + (l > 100 ? 100 : l)),
getAll, {
onerror : (function(len) {
return function() {
ghcs.states.max -= len;
};
})(l)
});
}
else {
if (!next)
ghcs.repo.loadedAll = true;
ghcs.states.max =
ghcs.states.loaded;
}
});
parseCommits(getDataFromRequest(req));
});
}
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
<script src="http://d3js.org/d3.v3.js"></script>
<script src="jsonp.js"></script>
<script src="ghcs.js"></script>
<script src="main.js"></script>
<script src="github.js"></script>
<script src="vis.js"></script>
<script src="stat.js"></script>
<script src="repo.js"></script>
<script src="langhg.js"></script>
<script src="show.js"></script>
</head>
<body onload="init()">
<header>
<div id="controls" class="popup">
<div class="row">
<ul class="steps sfirst">
<li style="z-index: 2" class="first">
<label><strong>1.</strong></label>
<input placeholder="User" type="text" id="user">
<button id="showBtn" title="Press for loading data about user repositories." class="btn" disabled="disabled">Show</button>
<div class="sub">
<div class="row">
<blockquote>Enter user's login of github.</blockquote>
<div class="row">
<ul class="setting">
<li class="field"><h1>Display:</h1>
<ul class="group">
<li class="field">
<input id="cb-dllh" type="checkbox" checked="checked">
<label for="cb-dllh">Layer histogram languages</label>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</li>
<li style="z-index: 1" class="second">
<label><strong>2.</strong></label>
<label id="curRep"><span>Select Repo...</span></label>
<button id="runBtn" title="Press for analyse repository." class="btn" disabled="disabled">Analyse</button>
<div class="sub">
<div class="row">
<blockquote>Click to repo in graph of repos.</blockquote>
<div class="row">
<ul class="setting">
<li class="field"><h1>Display:</h1>
<ul class="group">
<li class="field">
<input id="cb-dlr" type="checkbox" checked="checked">
<label for="cb-dlr">Layer repos</label>
</li>
<li class="field">
<input id="cb-dlsr" type="checkbox" checked="checked">
<label for="cb-dlsr">Layer stat repo</label>
</li>
</ul>
<ul class="group">
<li class="field">
<input id="cb-dlcmrs" type="checkbox" checked="checked">
<label for="cb-dlcmrs">Layer committers</label>
</li>
</ul>
</li>
<li class="field"><h1>Settings:</h1>
<ul class="group">
<li class="field">
<label for="txt-lc">Limit of commits</label>
<input id="txt-lc" type="number" value="100" max="10000000" min="0" step="1">
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</li>
<li class="third">
<label><strong>3.</strong></label>
<button id="visBtn" title="Press for dynamic visualization." class="btn" disabled="disabled"><span class="mono">►</span> Run</button>
<button id="visBtnPause" title="Pause" class="btn" style="display: none" disabled="disabled"><span class="mono">▌▌</span>Pause</button>
<button id="visBtnStop" title="Stop" class="btn" style="display: none" disabled="disabled"><span class="mono">■</span> Stop</button>
<button id="visBtnResume" title="Restart" class="btn" style="display: none" disabled="disabled"><span class="mini-icon mini-icon-history"></span> Restart</button>
<div class="sub">
<div class="row">
<blockquote>Select type visualization, change setting and press button run.</blockquote>
<div class="row">
<ul class="setting">
<li class="field"><h1>Display:</h1>
<ul class="group">
<li class="field">
<input id="cb-dlvml" type="checkbox" checked="checked">
<label for="cb-dlvml">Layer canvas</label>
</li>
</ul>
</li>
<li class="field"><h1>Type visualization:</h1>
<ul class="group">
<li class="field">
<input name="typeVis" id="rb_lacs" checked="checked" type="radio">
<label for="rb_lacs">Code_swarm</label>
</li>
<li class="field">
<input name="typeVis" id="rb_lag" type="radio">
<label for="rb_lag">Gource</label>
</li>
</ul>
</li>
<li class="field"><h1>Settings:</h1>
<ul class="setting" id="st-cs">
<li class="field"><h1>Code_swarm:</h1>
<ul class="setting">
<li class="field"><h1>The number of cycles of life element:</h1>
<ul class="group">
<li class="field">
<label for="n-cs-userLife">User</label>
<input data-ns="cs" id="n-cs-userLife" type="number" step="1" min="0" max="1000000">
</li>
<li class="field">
<input data-ns="cs" id="cb-cs-showUser" type="checkbox" checked="checked">
<label for="cb-cs-showUser">visible</label>
</li>
</ul>
<ul class="group">
<li class="field">
<label for="n-cs-fileLife">&nbsp;&nbsp;File</label>
<input data-ns="cs" id="n-cs-fileLife" type="number" step="1" min="0" max="1000000">
</li>
<li class="field">
<input data-ns="cs" id="cb-cs-showFile" type="checkbox" checked="checked">
<label for="cb-cs-showFile">visible</label>
</li>
</ul>
<ul class="group">
<li class="field">
<label for="n-cs-edgeLife">Edge</label>
<input data-ns="cs" id="n-cs-edgeLife" type="number" step="1" min="0" max="1000000">
</li>
<li class="field">
<input data-ns="cs" id="cb-cs-showEdge" type="checkbox">
<label for="cb-cs-showEdge">visible</label>
</li>
</ul>
</li>
</ul>
<ul class="setting">
<li class="field"><h1>Display:</h1>
<ul class="group">
<li class="field">
<input data-ns="cs" id="cb-cs-showCountExt" type="checkbox" checked="checked">
<label for="cb-cs-showCountExt">Legend extension</label>
</li>
</ul>
<ul class="group">
<li class="field">
<input data-ns="cs" id="cb-cs-showHistogram" type="checkbox" checked="checked">
<label for="cb-cs-showHistogram">Changes Histogram</label>
</li>
</ul>
<ul class="group">
<li class="field">
<input data-ns="cs" id="cb-cs-showCommitMessage" type="checkbox" checked="checked">
<label for="cb-cs-showCommitMessage">Commit Messages</label>
</li>
</ul>
<ul class="group">
<li class="field">
<input data-ns="cs" id="cb-cs-onlyShownExt" type="checkbox">
<label for="cb-cs-onlyShownExt">Only current commit extensions</label>
</li>
</ul>
<ul class="group">
<li class="field">
<input data-ns="cs" id="cb-cs-showLabel" type="checkbox" checked="checked">
<label for="cb-cs-showLabel">User's name</label>
</li>
<li class="field">
<input data-ns="cs" id="cb-cs-showHalo" type="checkbox" checked="checked">
<label for="cb-cs-showHalo">Halo</label>
</li>
</ul>
<ul class="group">
<!--<li class="field">
<input id="cb-cs-showFilename" type="checkbox" checked="checked">
<label for="cb-cs-showFilename">Show file's name</label>
</li>-->
</ul>
<ul class="group">
<li class="field">
<input data-ns="cs" id="cb-cs-showPaddingCircle" type="checkbox">
<label for="cb-cs-showPaddingCircle">Circle of padding</label>
</li>
</ul>
</li>
</ul>
<ul class="setting">
<li class="field"><h1>Rate of decrease of:</h1>
<ul class="group">
<li class="field">
<label for="n-cs-rateFlash">Flash</label>
<input data-ns="cs" id="n-cs-rateFlash" type="number" step="0.5" min="0" max="100">
</li>
</ul>
<ul class="group">
<li class="field">
<label for="n-cs-rateOpacity">Opacity</label>
<input data-ns="cs" id="n-cs-rateOpacity" type="number" step="0.5" min="0" max="100">
</li>
</ul>
</li>
</ul>
<ul class="setting">
<li class="field"><h1>Size of:</h1>
<ul class="group">
<li class="field">
<label for="n-cs-sizeUser">User</label>
<input data-ns="cs" id="n-cs-sizeUser" type="number" step="0.1" min="0.1" max="100">
</li>
</ul>
<ul class="group">
<li class="field">
<label for="n-cs-sizeFile">File (initial)</label>
<input data-ns="cs" id="n-cs-sizeFile" type="number" step="0.1" min="0.1" max="100">
</li>
</ul>
</li>
</ul>
<ul class="group">
<li class="field">
<label for="n-cs-padding">Padding around a user</label>
<input data-ns="cs" id="n-cs-padding" type="number" step="0.1" min="0" max="100">
</li>
</ul>
<ul class="group">
<li class="field">
<label for="txt-cs-labelPattern">Pattern for label of user</label>
<input data-ns="cs" id="txt-cs-labelPattern" type="text" value="%n <%e>">
<blockquote>%n - name; %e - email; %l - login</blockquote>
</li>
</ul>
<ul class="group">
<li class="field">
<input data-ns="cs" id="cb-cs-useAvatar" type="checkbox" checked="checked">
<label for="cb-cs-useAvatar">Use user's avatar</label>
</li>
</ul>
<ul class="group">
<li class="field">
<input data-ns="cs" id="cb-cs-skipEmptyDate" type="checkbox" checked="checked">
<label for="cb-cs-skipEmptyDate">Skip empty date</label>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
<div id="userInfo" class="popup tooltip">
<div class="row" id="divStat"></div>
</div>
</header>
<!--https://github.com/images/spinners/octocat-spinner-128.gif-->
<!--data:image/gif;base64,R0lGODlhgACAALMPAP38/LKxsfPy8svLy5eXl+fm5tjX1/Dv78/Ozr6+vtLR0fj399/f3+7t7e/u7gAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAAAPACwAAAAAgACAAAAE//DJSau9OOvNu/9gKHrKkJwoOgzI6L5wPJlBbd94Hpxy78cnnXCoS/yOyEuCyGziEoOkVOasWmvT7Gh57Q614AwjSvGaca0JIRDWMhAsBYV7NpcJeHYbCUf4yRN1ZkZqeIZ6ezElfowIBmWCXRWGlASJLwYsjY0UA0QsHnB0OYQSlZWIlySam38MkDYJaUA4k6eVqh1jra1yE0uASJ6pAbenqbkVmbytwbnGxskWfcybA4/S0NHSEtXNCK/cD9q3paqs3izh4oXkh6q73n/Y7BUJ7u978em+9RjF+JBN2Vftmj8O+NaEQccL1MEOCQUeYdis30MOAMlJ7EHRGr2LHf/uuTPnQx6cdSA/4EOiQN4AlClVuvuxrGDMFys5pitwEyc5kiNcwpxwoIFRBwcE+DvgwGgDBxlmwqjZ8GMFB1izGj0gTUDTrFgbaJDqoiMjixaegtXKNVFRtWsbKP2n0YVJDQLgrg3bVkvevWv7Xsi4LQTVZhu8Ao47t4IAAUybOp2MNWljCnn1LoY6lpyIdEMrRN6sFSpkyZpJo0aqtKhqrQi1GTaLAO2F13FT4wZ8dHdTjJ4/0HaGwbfx477FxoYGFMPhRi876EZOHbny5YU30LZdvLp379c3ED7V3IIBatA/fF9vXeatjRlKsOKOYTT7+6TDiyePaQVxvPgFSBr/CPnIwIBVHEwn4H2XcbDECA40+IKCC36nHwxJYZCZXDJU6GGEMXj1lGAUgLXVCx96eOEHb8F2QWpPSbhBih+uuIFrjFmgGGAkJkYhjd71iNd0PdpnYgg/AlmdjRlMd6GTIOyo5IJCZmCkixQQCUKSU1LH5AV/AXaZlCbKqCGXXSJXJQZaErXYlxZcmeZ9cF61WYl3foDmnMbVSYGcv03Qpgd78umbmWDqFt50iOpYqKG4rfniYnMtoGiUkFa4JaUSkIllB4Bm6h0Im7XlaVikihqgnxMM+ECoqapKJ6a8SQCrerLO+sGpgQIqqQW56uoBr8oB2qiOwbJH617Fcrpr/7LrRXnpq84OC+13y8Zla7UdhHntcb86Nq2xSH6L3LGOvbmtmOWamxy6mI27WLh2ursbqxMQuy5gIYRqr7bZHkntYiHw+m9gBav7gL7tHvwmvH/maTDErTpMGsUSuOptmQlbzKMIgyqKsQSPBotvltUOyqLHCBes6AIVEwwyy6iKAGh4N7tQcqYcirBZeAyLsPHBOs9bAaMu+AutC0Nn1aCCL+Bob9QK41lr1DsD+RQMUKbLrdBZ10ivBlCnxdvYGkgt6tYh9raWjLmNfGPY68X4g4gCI9tUhlJk1uWJU7TI2Ytod4qV0KutelThMOQl95BcOS600r7x3RNRRmWwYf9rMFTHuAtfPZ7vV5VpUJmIoHsn+qaSyS34p7f1OjN4YJytZ6kzstazB5S/drLLD4P6c4KHY0y301MoiC+FPprGau+7SeEvxdNv8FQDSdF7POw+KN8ws4lh1RqcBlO3Ops/j6y09WGZBiJmag//AG7nx6naCBRKat/CcuWVFIenGljN9iLA0vmgadwblvIaBRe1kMxW2duLUgAGMM38IH8oys+Q4lIahVFQYBbsAYV+Zzb5nak98xPYB8HSA9WQ0FEaJFuhlLPCAa6lQ6r53AUo5yO3maiGgQLi4JL2mh/gplv2sYyUaKjCJrKQajG8oAtfYCkXAZGJT4SQC+s3qSj/As+GVnRiVlKXHy4maouIC6MawTjG2ZFGhwp0IeO8hUU2BvGG0noNHFfmu2zV8Y5rPJx6uNSG+PEGYnTMmBgB2UYOIBB8e3jkD7u1yD/+cYhW4tIemcYl7DXPjpZUZBZPGKlkSDIua1qiKEG5SkEmqpOblMGedhevQIYyhaPMEppoKY3kaKiSrbwk+nDzwsARMl+mamAwl4nLNkImYi7EZD1O+T6SfcU+txQiao5WxpsYsmadUtAEgdnMvQjmZ9IEid9ati/epOYAV/IhJA3HLDO2YWP62d6hUMaWy9UHLtBME2b44s+5XUafvsxSLGNCzQottKAI7VNBeyCiiL7JIJMTvVvi6GS3jGbhNJS5l1Ms59FELOAx/lJiSVeakggAACH5BAkAAA8ALAAAAACAAIAAAAT/8MlJq7046827/2AoeoxinEM6nCczvnAsTwqipkiu74OtIqeZcChT/HbIpDL3MxCf0ItvSa0mVQZXdCvDWb9gXYpLHtXCaOuqzM4IGpVeen4tUAKDdlngaDgOFGd0gzkUCQGIeXpQfQ6OcBRyhGkDWhKImAEKi0IHfo6gAhRqNzoKgjeSSxWZmAmcMG+gs30UBkgqJgZ2HQwlRl46ThOtra+wII20s6ITPSkmvDK3OIrExa3IHbLLtIA0CpZQDAibE4fYrdbaFp7dy5DsD+nYx/IT7+8NzdoD9On3JOSD5yDgpX/Fhmn7NLARP4PzEGZSuIhbw30QLaCTqImTxXx+/zJm4IgIgZ6P+h6K1EjSXBmGA1d2aPny4jeZHEhSfAKzG0acHjb+29ITnkqgOSVCOXDxKNKk/+zNQEkr3tMQEqXGKDrL6lWsCHeOaIrBUwM/B5xqY3o2JAalMZiCVPsAXoObyPj09GoIodYQXEHhtRD4LiyzPulKdBmiYUE3gR8N3kLVmwa4IfiA3KCZrAUBAuS2Hf0prdM3kWdt8Csi8s8Mch2HDN3nrOOuttM+cHebrwWEIWJ3m2zhNm7jslPD4yC02F8Nrjsgn04due/fQz0Ir0qXgvLq4I1fx57u+YXUHsKrXz+e1T+xF/QuT7++PvX27usFt+2IeFn7APb2Af8262TWFgidBahgNyC4MkRogC0oITMgJGDeBg50B8J3E1aHHwgEmBRfWxpK1+GEJW6QAAEsBoABbv6ZeKKEH47E4o0EYFCUHylSMOOJNUaC45AFPpCgZR9U9qN9MV4QwJA4uljBdqAEOQGHS3oYApQ4EqYPglme2KQFXN7o5XAbhtmhlfOUSYBUR1bZo5FYqkndmBW4KaUEVD4CQp922semmznik0+agdIIopvevYNno4lKOOeTZUK6zJxKRqreoxKsWOYxC3DFZpya2rcol1KSWssHgJaq3qlQpvrlB64uOCijux1Ka60B3lppru8kwyuAbFLKJZ+OCjtsfcXiCuj/nEYua+qAzr4DrarSItdgtd1cm+16FXJ7KYJ1fjsLp52KSwu0D5RrriPQenossOMi+q540BoLJbJoKnuvgNv+2mpw/4qHlbq0ZFbwbehKQKgEqrIpgbvZvubBw9Fa29jCDbGrJ8Sisostxw07XOaeIbfGsU8jfDxxsgSvjGTAXFoTk8oy+ymCvkNSAKjEV+Zs8QcYQzyrCJma+0LRL3f7QqvfviBvrBVEBgNv/8JAaIGbXU1xlm4tjSsF2LJbQdKRGgbD1PueWVXJF2Dtatgw8Izjc1UNLYPcgfJIhN2FfiaZ2R6gpuZZcAfVs44la4Z0bV+DlNsiT+4pxBuAvGE2/20A6vbVBGZBdpYoiRtaXemN+R2LMn9o0J9eL6xHeIS1mY1YVxiuCnfkOpPhE7qRjfm63hpAbTAXShLfTtfQOWKkvbJzEZ0H6GkgC53aKbgF1HNyv4Efd0HIAe9VEcU89efHB+9u+I1c3ewZuMau8d8/UhAfKoXGISS3wR93QyNITZOEQyfQhA8jpKLXqpahwNY9aHpIk1/z7PcYSBwgLVQSRfnqgrt2JWwIAoTBRay3lyp1bYMb7AkIBwK0qrGQhFriYJUE0kEGzmCEMkgafvhzPBTW8IMxcAzqfOYYzrTFJz6coQx1ZsOrFXEIt9mGcEyTIP79UIlNHIHxWjjB9P+BIFRYvCITgSgC2fhPRziMYBjXOEbVjMUzUECb8qwnxgXW8TG0G8gQjWgTA7HRjn/EY+G+s0cOGK9326ijFQOZDA7pgW+JGeQfF9lGUEhSNh75Dt3coEgaMtKQHCqkH2UzJotQEpCVdB4MGcYOtFUpRlX0ZCpPKciz8ZCFooRBnYhnSlmi8pe1vBKW5sgJ62Aglkv8JS3RCLCMQJJBExBfL5N5ymUaCS+H3CRE0PYQ8P2hk9T05SPO4sK5POWZqwJZPjQITj36SB/BxInhZtbAvC3jgnZ5YTQj+Tl1KjFoaupmV3J5GIYQMVBkk0w/i2cx8sXwSgRdiSslFNGnOBQpPFxcaEJvuSa1afRykFOQbc74Ueux5YjiaYvnSsqJBYAGalRkqUxlEgEAIfkECQAADwAsAAAAAIAAgAAABP/wyUmrvTjrzbv/YCh6i2CeqLmMbOu+k3A4TV07eK7b9yHAwOBLZtMZj0hc8SBsOi+HYnJKNdZ8zyzsVu16czWteCT4mr3MsRojaFQa5ziy8ZsgFOtxGZ6WzOSAShQMAwgDeHlONGBvgYB1EgoIk4YGiUBRR5APVTxwczxUbhSFlIYDly1tSaMSZVZ8Jh4mM1I5fQ8GpqaHqSGLU5twPUFEwxW7uwOovhyrVbgzm01Eg6XJlAOWzRiZXa3c2NiF3BZndOUPy+LJzOlmcOkTCtfsk9rln50O0/L09tm2XXrWqZ88CQwMAaw0UN+UeAc1GKgnrtcagg8NRrRAcZxAMQ7/p2z88M8ePpCdcI3kMBHgySchj6BbCYKQyywxrWikuaGjMid/MvJksRCBEIwyh7pwiWiLKKUvXDKAUbDbkp2pat3I4DPbi6BzdspsoHIgMEZcAbrIeUsDW7JZuejMYLPi1BFdNCC1UvbJXiN9J7SsSOapXi8zK9BS4omLD4Nt2BrZALDpB8mJu32JJ4OGXMQ9fnj7xqGroRBgjwSmEOezI8/nONTFZpkD5g6vc8sBl8HkXQ6pd2CdIFm38R0eTBvtUNzD8eeGWXYd8PtwTN4aoGtPmrzdMtRyV1sIvv049gy6slkkYwPEq/LbQRT6DkRGiOLwH4GYiHf45fzPncdC/wK1xWCDfxwACB2CEiUQwIMY7AAXCwpCJ2AHAzyoYQAYXMfPLxVaKIKDG2q4HAXvqeYefiHGIR5HJW6YwHis3NeiiCDEuKEFb7l3o3YvVqCjhjwmESQFLP4Y2wcZDunOAykK98FfSjpy5ARDBjDjBOTRAEKXVQZy4QVZcjgBFSAkGeZmIJCoI5JGprnmcwyqk6VAbNVJ5ZxyXClBlswskNOYFkTJ52s5DrmloYJ8AOahcSSq46I1fgCpcYQKmaUfIll6aW6ZUuBmjJwmAcKnoLa56QNd+skJqo6EOkGTb7KaRJ1QwuoICAis2iWujOrqBQgK+Hqrj8LKQayxSACrZv+yOLha7JClamIjtF/gOm2tv16LbVUkMaviqd+SJp+4R6BWbichjFpitekiu26cqlKb6xwiPKtrZh24u+O9zYI4b8CS1voXv84MPG7BJW75wKC4SqDvp7JqOilx9H6pcFshbBujO2jmu3HFoq4KL3IjTDwnwv2aDLAVLOypKwtlNkKwCI+iyoIBWToscacjjJZsC/5q+OSr+LYgNMUOuFCzYsG4IHOVE7bwtM18wbB0mBC5UPSDPp8pYcQbbN0iHGRnYG+hSmCRRWRnV+2EuxnI3cErIuzhGqjE5EHkUXC1QXZnxrkNFQVRXBgZOq6aA0jjNBMQwImF6SNetHtQ6Ej/2iEQ4LnnYXeQOMzZecmqyLGqEcDnrJvJ3BQvYs5yBjkjJsYArOdOQOhQPGQbDlDKqRvnHOie+39As8GZrLWbkUUCxrPuKBXDDePDkSpX6kT0n3vLXQaviEZosIEQjwH3nrvuQc4bfMLZhyiazZ0X5lsAPfopUyEeWFDS0YYP6GCUrdCSrtRAjivokxx7hFI3MADvYX64nrVIR7qQCCGBBGgBu8AXEn3cBmmNquBkgIDBFxRnTFNLGgVRFq8XrA596lug79yir1GskIAjdFoJtZYXvdhiBzcMIQtzGLkECmFYzgDLY1JkwyHiUAc6NGIT8EOyCgjqiULE4gNH8EIY/8Jkg3nzoASCaLoWhqCL+PMLFQfnxCy6cYsgwKDnxDA1uzlDjCAsYxvh2AEEyDGDY2geyZg4xj02EYofQGMa1SA/Kd0Nj2Q8ZA48wIA/AjIPKezaYbQoST0icgP3k6MvUkiDFxGkk6gs5CcxgDtLcoOUpQSfIVX5xqZhoFiWvCQ3nsWyU9LSk7U8Xy51WQ54sGGWeeykLS2Qyximo5GrtE//OPlLZboCF4rkHk+mJoxFgCWVyfwlY3gjSqXIDxx7+kEkxakDXCTQmTSBG2AQJ4qYHCA4e0OZBEKpu8MpxiG8yV75KGA8ePpzNPT8EQXQaFB/cikzAhVTBbrn0BDA8i852Kxo/pRURY1eQG8KuoJHj+KZiI4FfiN9m1byyQobGC6liSgB4Yx0ApjalCYRAAAh+QQJAAAPACwAAAAAgACAAAAE//DJSau9OOvNu/9gKHqLYJ6ouYxs676TcDhNXTt4rtv3IcDA4Etm0xmPSFzxIGw6L4dicko11nzPLOxW7XpzNa14JPiavcyxGiNoVBrnOLLxm9DX4zI8LZnJ/0oUend4TjRgb4B/dRI7hIUvUUeMD1U8cHM8VG4UmGAOkC1tSZwSZVZ7Jh4mM1I5fA9+Rw2woR2HU5RwPUFEu4lTpbYao1WwM5RNRIJdj8MWks3Pdl5w0xVnzrae0teVX9besdybyZDkpA7m17iW63noc+/exe6Q9cGg4hrRm7Va+EjN29cJzZp4Rwh+6CdwDEIw/xQSe6hkoAuKNCxKtBBwVhaM2v82egDpRFZDkSO8COm4A6WLLhFHUBTmUmY5GPagLNGIp9WNDDMj3cQwi9Y0PVY0YLxIJaYEhEYhRYkXMgZFnhe6TPS3hqUOp7E2kRFLrNo6VkoucfFxlkuVDcZEPKxKweQmUDJouK3W4wdDskqDhbBrBGyjbBjN7O22dQqIubcUSf5Dk6hgD4TB8Ew8uTOiDhRHUvHguTTjDafkdUCalLTp13M+oKuBdcLUVwth6/68eoc6UTZApN4N+/GVXoYtcCZ+pvYDVSJ+A1nOvJqQAQzY2HBuuXpp7hYQDBiAQEF3vckzeH9d+cN4BPDFY5gt/cN62O03vI8PHzvHKelZdd//awFKwAB5/MVnXgWZ0RACdQNaBwKCCcKnHCnCRQhbgQ8oUGF/FyLBIYQansaBAR+Kl10MJ61GYolxuffhAAbUhWFuMJqWHwYUVkjBaLLlqCMIHs5YkIiPCWlabSgaSQ0StXmlpBwc9hiffw8sQFWGU5Y24Yw1PncjZl16KWOFNJoyZmRlTrbjBSmW14dj9rXp5pcpzpkECHbe+UGTH+p5BId9SvamBUUGGhaUXBb6B55oCmqEc8M5egYIBzrZIKWWPvpBppEuOolwLzrKIagJDiCpDtyVWqhzqPKnqqiTPtipYs5ZeeWquPF5KzghxIkArzkM9quEf8ZJLA4hVHos/5KQ+ihmbLY+26IHusK3oLM5cGctFdzFGSZLdGXA7bccSpAtAmE+QBV4rk55KI8zruhuEunS+q0D+SaaagETAFntvvNe4K+sNlIrF8HgPbDusCwq3Gy8JbKwbrtPJdGwvreyECeWTyLRwl+OtrDurD+uKQLJZYZjsbIVnFsfGRTrFhULClx8AVX5QlOzZy63gKKuIKcMRrkjsHwfHBtfwIB4CF9wCi1No7YYc8dpYcB7C+6c7ikiDPKzI3sUcqC9QLTBRBvg5eUZFjUxGIZ2tMXy0h89ixDA3iiP5QlYOPjgYEqKVN1BAnsnnsDKix0aiN0DU6ZG4pTzLRq+cPHLNv8IDWYjBuKVU45xBp3Pi8lzSXZmeAahVx4kneZa0waZZjrROuVdc9D5zDvT4EN6Yw/eBOi3BxB5a+bi4NehMi9ie/EBjK77W4EdImYyREjoxeoUQB/A4gsDyI8Oz9Gh9ubc0spJQnblfQHxt7MgJdKenO5uH7+P2lpr5Ajhfd8hsERjPqGEy+yvJfciHxC8ZzymXEY7clgfAg+owBcwEAZSEt58ICTBz1CwWBb8HxB2x6yJXK0dj/vg4BLiAgaCDwgq4YDbAneCCdrQg0Zo4QWbQBIWaAmHQExhDlnAwOg9oYdhq99hgrjCIeqNgblbCUjadkMhMlEfEyoiAJUBkq//KfEbTOwgCD9QxO+pgYSPW0UVm3hFEJTxhWNQ2g6wUg8xstGKY9wA/KAHRzVksIC9CeMS8VjCDZTRjKH4oxIMU8dB3vGRWMTAIQOwRTwocpHJEyQYCRnJCuxRhNegTlUauclH2rGTE5hkAKL4DMWwYY12PKUkDykROVbwAXuTQAnyEktHSpAtdchlKovYx338kRIESCYBKGkAqpniANCMQiOiCc1nFuBAAVAmASrAwEoSRGnCSIA2tfm9YTGgAHtIAzRpcE0JIG6cymygBPgYN1NcDRbwzGcys9k6feqTAp+0XD0FxBsJ+POgCD1o30JXzIGOI4/ZTKhEJ7rNYe6tP6EOtY0zKMpRhHIToxllXUdHmk95hnQEJE3pOE/qApWm1KQsbUFEXXpQmMYUCO+k6T69edMnJC6hF+2pUPcRAQAh+QQFAAAPACwAAAAAgACAAAAE//DJSau9OOvNu/9gKHqLYJ6ouYxs676TcDhNXTt4rtv3IcDA4Etm0xmPSFzxIGw6L4dicko11nzPLOxW7XpzNa14JPiavcyxGiNoVBrnOLLxm9DX4zI8LZnJ/0oUend4TjRgb4B/dRI7hIUvUUeMD1U8cHM8VG4UmGAOkC1tSZwSZVZ7Jh4mM1I5fA9+Rw2woR2HU5RwPUFEu4lTpbYao1WwM5RNRIJdj8MWks3Pdl5w0xVnzrae0teVX9besdybyZDkpA7m17iW63noc+/exe6Q9cGg4hrRm7Va+EjN29cJzZp4Rwh+6CdwDEIw/xQSe6hkoAuKNCxKtBBwVhaM2v82egDpRFZDkSO8COm4A6WLLhFHUBTmUmY5GPagLNGIp9WNDDMj3cQwi9Y0PVY0YLxIJaYEhEYhRYkXMgZFnhe6TPS3hqUOp7E2kRFLrNo6VkoucfFxlkuVDcZEPKxKweQmUDJouK3W4wdDskqDhbBrBGyjbBjN7O22dQqIubcUSf5Dk6hgD4TB8Ew8uTOiDhRHUvHguTTjDafkdUCalLTp13M+oKuBdcLUVwth6/68eoc6UTZApN4N+/GVXoYtcCZ+pvYDVSJ+A1nOvJoQLBfa0MZZ3bTz7IdiOkqeofvrygvdon8wW/oH87DX85ttbnhh4dThG/zg9V9mGiHkp9//aaCRopyB/A0IG3m2IVgQEgw+peB5+CVBiX2a8SfghHHJlsQxDnbwH4eAyJeVYxOM5iGJpZkITYgIRcgei95pGBs1SNTmFY1yyIhQHQtQJRyPpj1moSkhcjAikXGAMEUaGAbyHpOduYgNiiM6SeVkVjJzY5ZTbqlIlzEg+J+MYkpGJpJfHplgmoAM2WaOcsIpR4UehUXnm3Y2yWdr/zm3Y58Q4gmomysS6oWgZiIqmqLNCCqknkfI+A2kloQQJYCUJgTCkphy+mdLnRqhaahNnXrjpmviiKoV34G5qXuuvTpJCCqyRFcGs2Jq6YyFSjjLd8DaKqqRexZ732DG4vCr/64rHJaETba22uCNfSSZKKa7anAZm3mKMGiaLMQIzK0jgLolC14l81ALf8EJr7bfpruheeGUq+2sxApyL3NRtfDugbP8Cs2/5+njgnbJUoBKvxnEqx8cEIPHzXqn0FIxaosBHPATtymsnKWniKsXwpnsUUgb/SbAhlEsi6vuF9jVRAEBOPNqg18v/WGwCAgMgAADLiSA89EBeOuAD8dqCcjGHggdNAIGiBDA0VgTABenv6JsLdAIhB32AAMo8EHWWSettA/dvsilGAxILfbYAxDNAdpZc4DJc8hOBnUGcs899tl4H80xXmTO/EUWBgQueNUeFI70Brv4QB7KpDrh+P/cA4Qgec5l/RYFaq/9XYHggtcdwtWfU64EXrQ+J3GeizahAOqCj/A5AWpjYNJzdLTB9g9RdspJQnb9fEHcuA8+gtGf936BJ3uz14flt7bWGjlCbC72AJDrvnvnL1vxCYLak8o9EM1//8LuWussx/Gkpq8D++0HDQP0rSuVH/2fsV8OYHC79oEPCKzrn8461g4pCZBTnmqBArznviDAL36oMQlbhgNAB9bPVBKkoPOEcMEWBCmAH0Th/VgwNQParQkXJJ+mqCctD6pwgCPI39jC14QERs9kN4RgCnEYAhGOzWxa8KHkpLcaGl7KhlDEQQgap8OyqUGJkquTEIPYQSn/fmCCOkQAEtVwQZwxUX5R7GIXRaYB5lURAZDAYhY5wMEabjGKbMQAGKs4xkLIsXBnrEA91GjHNW6AimG04jD+CEheDfGOkMzjBAzQQj56o4yT44gTH2jIC5AtjDvcByYJ4DILnDCNhbSjJB9gRM5JhJF5m8AASlmCvBDyiULcoARmSQFKvlEk/FsiBQJAzAAkQAEMKMAB0rDMZeaymaaIAgMMkIBiMtGIB3TJ7iiAAGtaMwEHLEAB9qAPZzZAnLtMQDW9aUwKFBB1QrOZBIKJNemx857EVKc+97lOfHqTAm7kHA/licUK+POgCD2oDFnJuT7Kc5hYo0A/E0pRivZSSGiKfGgGcFZKCVT0oxalQEY1+oEBgPSk/uwoSVmA0pbec6UvmKhLQapSmLrApDNNaE1t2r2cWjOePC1E0NR5UH3CMahIJUgEAAAh+QQJAAAPACwBACoAeQBVAAAE//DJR8K8OOvNu/9gKD4BYRJjqq5si51w4s50vcK4Ze88n+C4nnDIAsaIyKTHeFI6nxOmCUpF/piyqpZXYm6/NikKTG6Jy2iVVJduewbSrHuuuRrp+Ez3nu+TpH59e0CBeWeFdIeIbmuLc42ObZCRaIqUZINBl2WWm1uZMJ6YgKJfoE2lW3ZAA6lacFiuWpOyT521Sbe4RKdTu06rOb9OusM8xcY2vWPJQ8GazUK00TtGbNQ9q3LYQxXcZa3fVgHX4hoODQ4CIgPk7uYd6egN6x0J7vjl8BIO/f7oBzbky7cPgwB5//rRy3Bv4LuCEhAmRCfQ4cN9Byb+q8fQIjmIEv8TNujg8SO8kP8WcmhX0lxGjf4+lNTX7CBMih8YzPyG8l9AEA09bjPW099IETNp4rqpMIWBpMmY9vs5gmXLXy+ZsgjqcVdWmEdZJFV6SSo6jmKTDi0rVaWLp2pFFfVpQ8HYTTalUq1h964jdGYdCEEwNsBaOnnbEunrN8+BuXSRMIaKGHLkJHALH9Zy0LLCvUoKu9v8pIFnhWifcN1J5jTOLVZZS2CgQIKAA6BVOMD9k4GBC1/BCiaTWegFBAOSK2BQIF2G4Rf6PRj+s0ABAwqSh5sA2W2Z1QQnFBiAoDzy8gYYMIjI73lY3wqQky8/4PeEm87nFMeHwcB88+YlV553AgQaYOCB2MUn338AIneBABp5N0dsJk3AYIMYBnhhhhjWd4FEDeSGB1cXMLAhhyimmOGDn1FyDwYqxihjg9tFJOIlJs6oo4zGZLfjjxzWuAt2AgK5o3bY0KadkUEqVxB2C56IonYDKGAfRBj4ZgCAVAaIAHZtRAAAIfkECQAADwAsAAAAAIAAgAAABP/wyUmrvTjrzbv/YCiOZGmeaKqubOu+cCzPdG3feK63AxHsQFqPQAwaX8Qk4chMBZTKplQ0hCan2M7TqvxlvxUFlwsuPxJjbsKc3aat7Omb640z59C63WjAR/dMfX5LgIGDhIVHg3qJQIONd36QR25vk0Zoc4yXOAh4m5w3n6FAlWOkO1VpqDt4rDqmcK84Ym+gszGuuDaqZLs2c7+8wcI0xMUzmXTIN7HMOW63zzJo0zEJAyoNDtzd3t/g4eLj5N8NNQYB6msn5e7v8O4CJwIO5xkJ6vrsI/H+//HujTjQYJsDDfoSqssGAqDDh+IEfiD4LQMDhQpBCDAIsePDAxr/OXbLMABjQhAiPaoMGCLlQQz5TEq7UG+lTX8gJ4LLIFMdyptA30nksLHihXQ9PxQNynRcTg8pMZSUCeJA06vhhm7YeSGmyZ9Yw3LTqsGqNww9Z1pwKZbpPA9LuaFNCpdtW6BPO4i8UCCt0rttwcq1gPSrTsBhG561oICuB8RhyWYwWmGq4ceQr0rGUHNwZccdMmvWuLiCV4yKRQfdTLM0hdMZ/6oOSnqkBdgnZc++GdK2adBEdwOt7fk18A1xhXfMS5Rj1+Mb7Cr39xau6wm49bWc3rFB9Q5xn1NNzd0h69a+jY8/XB7geQudX35eb709QObB009AAD26fX/ehWBW/3ETFIYRP5j9F893oV0nwUUyIQiegvDgx8FeF/i1HYXkvHcBhhZoWBWH5FiIHIi/0feBdBR6aMGABE5gGUYMbUhiNwGKwBVjIvZ2o34rUhZifxzASCIJyck3pIpVsThdCUYqmeJlAzmp2jYmuJRBY0SCZyVkDZgYpJBLUkkCRcphSU9BZE6ZmwpoirYNgybU41wG/L3ZwkZfrlSQmCgQdJ52solgJ5s3FbQNoCzQ+QEDnIX5wEaOIhflR5V+wQACNcKn6DyMbuVQqCnY40CmHRRgAKcDcKoBNwfYSUJHqGozVo4gMKDAAK0i4GunF4wlAakV9BnRDFkR+wCnvjbbLP+wFsBK6YgeuThCkjjWKoEBvTr764VyaUuBseSIO4J01nbrrasaFDWpi5c+9EK83Jj7ALfrPutfmAKQSm6HL6AbQr76tlvvAwQhB5S9UI2DqwcMqOsttMWOdVA9DPb75T3vMFxkOSMQXDAGML4rwEaxBhjfSDByXJGRyjbnMAkFSOzsAAZowJFBEtxzQKxRzmOOBEM/EJWtTpWAL8EUT5DkzjM/UHTRR6PAorUYiPxtBti64zKORHvzNZD9AHxCzVo3PQGi8IxtT9hgS92mjuXEnMHSIp/ItthTiw23sHI7KKA7Kyigta/gwRjryX4HDnjfgrN3LAs2r1vCAjv//bb/45vvSHeHHndQ+c1IZs65225L+YHXoXcQ8eEDQBpCfKhrnvq57tgNAt5M5+xj541DTna7VuoeAu/5DqAAccDHLXyMr35Zw66Hcyq7zI8Hr33kngp1A/LJL59f9s5vP3wFcZaYA/jJ+8616c/fTnyFO7C/bqvXw2d+8+Sfz6dQxlvB6O6HAPdRIC61O53mVNezPj0MCANcl4QkQDvbWZBzDDRa26bALNgdMCcIvODzXtIvCtALRxkMAvW0hqBtLGp/CcxKQSrmsNbVgFdMO6B0hAbDBXojLw5LoRRW6CwFIOiEe4NVlJJYNApmxYY6wKGzaHiX74hEUo3AoRFNmJkDOo4lgFJIAAJaCKZigdEMXQvLGQHxLz9Z41Bi+ZM1vKioRM1pju2yiqKMtcdY4VEECzjZCRcHxT++IgIAIfkEBQAADwAsAAAAAIAAgAAABP/wyUmrvTjrzbv/YCh6SWAGREqcQZKMcCzPkqneeI63dO/LKJ1wKHz9jshKkMhs3gLJKM1Jraak2FHCyiVmvxlFYEDpmnFGSUMAzhpYlOW5SxE4Gut2kmWqzM1QEw6Dd3l6NCV8PBN/dBQNhIOQhzFiiicUA0SLHAMlXhMHkZENB5QhiZcmaQ87rDFbNxWQo6SnHW+qfHErUp91tbWGtxcDuorEE7TBpA7JFanHcMnLzLbPD9KKZNgH1dZ3bMTaLK/Yd+CEw3oM5KvYGALfzOtf7e7wG97pd6Zg99rM5bswL5i/LPgGetgHrh6ShAo9yEvn0AfEiBILXkMSTZVAjBz/NKpDYkzaR5Ac+DnzYenYSZQp0x2cERCmDJHhEJnE4A2PgwPi4InCMwkDzgYzSh7LIKxUMjvfkGbAuRKGNg0anR7qGayihInWgqKSpgEsvZlSzDJDW0GUNakhcunaYIdfRQEC3BLdSwuo2AnyqA7aIFPEVQ1u7TrLW0gwKZ9AHzC0G/JtCKWqYqqU5Filz813OKitBYKsZtCoU1M+LewDZkUvlameTXsU3A04PZhmXbs36Ntl3/7F0HFaB9/IUQPH2nT4huIfEiefTu9DXUkOnJPAZJ26d2YgiLKFYSxE5++qtcdTr0EBAx/n0f/+EfkCgwEDEBigIV8++w5Q/YSB/wIIFJifAjH0J99y0X0WWjEFRohAfu+BoGB/DOozj0P3SRghfiCMduF042Ug4iBsGeDhh+aNuGCLXVmwIovduShfiTxVV0F+M3LjQXw2zmedRmJ1OCOCGQV5Y3hrUWAAjx762IF0SlKXIQbgUEBgj0xW+d2VF1A50gQzGtill979V0dBt0G54pBofocjQcyIU4CbH+4nUZzonTmKOEZGCYKYfPpmYZMPBCqhlLwV2huYFmT5gIpcfuColSHq+GSZh16KHKQVXGebBFuuyChhnn6aaYwPlCpojan2tmprrZaJwKyx0hYim6SWqeeeudaG6zWu5rlrsLPNacGJUhUb4f+vPyKb3rBjOmumn9LapeaarFo7YQjZKheCqMTaGgKh4bIK66iTlnkqXemqpOyymuJ5Lbbx2rYtBeiupOiHBYCbLzj7CmKNBHf2WOG6A0cyrwUaHWTvhNBG2/BG+A4S1MQIIDnoxQ6LwOwCZJorApCXghqmjr1WevLFXqGqbqITvwsgynzCEPGOZXp8bsMwnJgdzy6LMFm2MaC7nLc2L4TziEXpzPIElM5Y8bhPY/gwc+BZUHPTDXoadQyBBeOcqbfSl7VvkBQsGjpjWrApfj4fUbaNeGw9AldVeQ32BXWJ3Jh3RAnYhjxui+YU4iL3m1p9NvGLh4lEsaH3BbRdnmD/2zIEiKIGKEIFQ2+Jj0ALHqXzHTeWD2r+wNoqy9CV3iIpG3rMK7ONhdC4h2IZboO5vTYhpVs8M/AHlzWJPAtRF4XjBUMPfCl5dTD86j+IFLtsUwOusWSQkutb8Vx3lbjjfdOJzgN2/JWXY1KpRH6OksKIKP3BryEPUHmI74x08RuFZEbhOsr9TmTaY88yaKEGCRwAKGJiA7vY9Y3sgaOAEqCI8myjjt9N8BoV7MFRZjBCA6YmgGP6YCR6oMEZCE0SuIkPCmH4ABUSgj+FoQH60reswgnDhg8CIg9/lo4fqARA0vGLqGYYxGuQJmkttGBDYrCABWbQiVhc4egoMr+p/0QRaynMIg2fKAJtReGFkijdEq8Yxjbe8GU5PCNVtAKnMYqxiVqs4wW/sMMHAcuObsTjGz0AtyKC4Wj02JdZmMhINg6SLvA7BBqxA6A7NrKGAuQAIu+nh0lKQlmLdKQgRzlEbsmLGJ78pIksKUomlpJ9DmoIBuHzG+eEEpOBdKVROtO7NgiJXrlspShLycuIbDIYdfDHLYGoS/bNZIdjG8gkxQIJSABQmLgE5GOAc5QuZuGYfoRlWLI5SleGzGBdeaVC7nZOBzZkHg9syhQBY77Ihaoa3FQSNUkxy2dMhl9eAkY/7KnJdVxPXI/op01S6R2FElQNaNreQ4MTywXRcSCiPYBKRR/FOYzubig+9Ix4vOnRESwAL45TYklXipIIAAA7-->
<div id="ldrCont" class="popup" style="display: none"><img id="ldrTop" src="octocat-spinner-128.gif"></div>
<div id="about" class="popup" style="display: none;">
<div class="row">
<h1>The visualization the history of repositories from the Github</h1>
</div>
<div class="row">
</div>
<div class="row">
<hr>
Create by <a href="http://artzub.com">Artem Zubkov</a> (<a href="mailto:artzub@gmail.com" title="Write me...">artzub@gmail.com</a>)
<br />
Powered by <a href="http://d3js.org" title="Perfect javascript framework">D3.js</a>
</div>
</div>
<div id="tooltip" class="popup tooltip"></div>
<div id="layers">
<div id="canvas"></div>
<div id="svg"></div>
</div>
<footer>
<div id="statusBar" class="popup">
<ul>
<li class="progressBar">
<div class="meter orange" style="display: none">
<span id="progressBar" style="width: 0%"></span>
</div>
</li>
</ul>
</div>
<div id="console" class="popup"></div>
</footer>
</body>
</html>
/**
* repo https://github.com/artzub/JSONP
*/
(function(window) {
if (!window || !window.document)
return;
var seq = 0, // sequent
document = window.document;
/**
* JSONP
* @param {String} uri The URL you are requesting with the JSON data (you may include URL params).
* @param {Function} callback The callback function which you want to execute for JSON data (JSON response is first argument).
* @param {Object} params The params contains data about callback param's name, onload function and onerror function.
* Params have next structure:
* params = {
* callbackParam : '', default is callback
* onerror_callback : function() {},
* onload_callback : function() {},
* script_order : 'defer' | 'async' (is default)
*}
*/
window.JSONP = function(uri, callback, params) {
if (!arguments.length || arguments.length < 2)
return;
uri = uri || '';
callback = callback || function() {};
params = params || {};
params.callbackParam = params.callbackParam || 'callback'
uri += uri.indexOf('?') === -1 ? '?' : '&';
function clear() {
try {
delete window[id];
} catch(e) {
window[id] = null;
}
document.documentElement.removeChild(script);
}
function response() {
clear();
callback.apply(this, arguments);
}
function doError() {
clear();
params.onerror && params.onerror.apply(this, arguments);
}
function doLoad() {
params.onload && params.onload.apply(this, arguments);
}
var id = '_JSONP_' + seq++,
script = document.createElement('script');
window[id] = response;
params.script_order = params.script_order || 'async';
script.onload = doLoad;
script.onerror = doError;
script.setAttribute(params.script_order, params.script_order);
script.setAttribute('src', uri + params.callbackParam + '=' + id);
document.documentElement.insertBefore(
script,
document.documentElement.lastChild
);
}
})(window);
/**
* Created with IntelliJ IDEA.
* User: ArtZub
* Date: 23.01.13
* Time: 13:32
* To change this template use File | Settings | File Templates.
*/
'use strict';
(function(vis) {
vis.clearLangHg = function() {
vis.layers && vis.layers.repo && vis.layers.repo.langHg && vis.layers.repo.langHg.selectAll("*")
.transition()
.duration(750)
.ease("elastic")
.remove();
};
vis.redrawLangHg = function(data, layout) {
layout = layout || vis.layers.repo;
if (!data) {
vis.clearLangHg();
return;
}
data = data.sort(function(a, b) {
return d3.ascending(a.key, b.key);
});
var w_hg = w / 4,
h_hg = h / 6,
m = {left : 10, top : 10, right : 10, bottom : 10},
pos = {top : h - h_hg - m.bottom - m.top - margin.bottom, left : margin.left};
var x = d3.scale.ordinal()
.rangeRoundBands([0, 28 * data.length], .2)
.domain(data.map(function(d) { return d.key; }));
var xc = x.rangeBand() / 2;
var y = d3.scale.linear()
.domain([0, d3.max(data, function(d) { return d.values.length; })])
.range([h_hg, 0]);
if (layout.langHg && layout.langHg.empty())
layout.langHg = null;
layout.langHg = (layout.langHg || layout.insert("g", ":first-child"))
.attr("class", "langHg")
.attr("width", w_hg + m.left + m.right)
.attr("height", h_hg + m.top + m.bottom)
.attr("transform", "translate(" + pos.left + "," + pos.top + ")");
function mei(d) {
d._g
&& d._g.selectAll("circle")
.style("stroke", d3.rgb(colors.decolor).darker())
.style("fill", toRgba(colors.decolor, vis.forceRep.opt(vis.forceRep.radO(d))))
&& d._g.selectAll("text")
.style("fill", d3.rgb(colors.decolor).darker());
}
function moi(d) {
d._g
&& d._g.selectAll("circle")
.style("stroke", d3.rgb(vis.forceRep.colors(d.nodeValue.lang)))
.style("fill", toRgba(vis.forceRep.colors(d.nodeValue.lang), vis.forceRep.opt(vis.forceRep.radO(d))))
&& d._g.selectAll("text")
.style("fill", d3.rgb(vis.forceRep.colors(d.nodeValue.lang)).brighter());
}
function me(d) {
vis.forceRep.nodes().filter(function(k) {
return k.nodeValue.lang != d.key;
}).forEach(mei);
}
function mo(d) {
vis.forceRep.nodes().filter(function(k) {
return k.nodeValue.lang != d.key;
}).forEach(moi);
}
function appendItems(g) {
g.append("path")
.attr("class", "hLine")
.style("stroke", "rgba(255, 255, 255, .3)");
g.append("text")
.attr("class", "tLang")
.style("fill", function(d) { return d3.rgb(vis.forceRep.colors(d.key)); })
.attr("dy", ".33em")
.attr("dx", "-6px")
.attr("transform", "rotate(90)")
.style("text-anchor", "end")
.text(function(d) { return d.key; })
.each(function() {
var pr = d3.select(this.parentNode);
pr.insert("rect", ":first-child")
.attr("class", "barSelect")
.attr("fill", "rgba(244, 244, 244, .2)");
});
var gg = g.append("g")
.attr("class", "barChain");
gg.append("path")
.attr("class", "vLine")
.style("stroke", function(d) { return d3.rgb(vis.forceRep.colors(d.key)).darker(); })
.attr("d", "M0,0 L0,0");
gg.append("circle")
.style("fill", function(d) { return d3.rgb(vis.forceRep.colors(d.key)).darker(); })
.attr("r", 2);
var dg = gg.append("g")
.attr("class", "dCircle")
.attr("transform", "translate(" + [0 , 0] + ")");
dg.append("circle")
.style("fill", function(d) { return d3.rgb(vis.forceRep.colors(d.key)); })
.style("stoke", function(d) { return d3.rgb(vis.forceRep.colors(d.key)).darker(); })
;
dg.append("text")
.attr("text-anchor", "middle")
.attr("dy", ".32em")
.style("fill", function(d) { return d3.rgb(vis.forceRep.colors(d.key)).brighter(); })
;
}
var bar = layout.langHg.selectAll(".barLang")
.data(data, function(d) { return d.key; });
bar.exit().remove();
bar.enter()
.append("g")
.attr("transform", "translate(" + [0 , -xc * 2] + ")")
.attr("class", "barLang")
.on("mouseover", me)
.on("mouseout", mo)
.call(appendItems);
bar.transition()
.duration(3500)
.ease("elastic")
.attr("transform", function(d) { return "translate(" + [x(d.key) , -xc * 2] + ")"; })
bar.each(function(k) {
d3.select(this).selectAll("*")
.datum(k);
});
bar.selectAll("path.hLine")
.attr("d", "M0,0 L" + (xc * 2) + ",0");
bar.selectAll("text.tLang")
.attr("y", -xc)
.each(function(d) {
var pr = d3.select(this.parentNode);
pr.selectAll("rect.barSelect")
.attr("transform", "translate(" + [-xc * .2 , -(this.clientWidth + 6 + xc * .4) ] + ")")
.attr("width", xc * 2.4 )
.attr("height", (this.clientWidth + 6 + xc * .4) + h_hg - y(d.values.length) + xc * 2.4);
});
var gg = bar.selectAll("g.barChain")
.attr("transform", "translate(" + [x.rangeBand() / 2 , 0] + ")");
var dg = gg.selectAll("g.dCircle");
dg.selectAll("circle")
.attr("r", xc);
dg.selectAll("text")
.text(function(d) { return d.values.length; });
dg.transition()
.delay(100)
.duration(3500)
.ease("elastic")
.attr("transform", function(d) {
return "translate(" + [0 , h_hg - y(d.values.length) + xc] + ")";
});
gg.selectAll("path.vLine").transition()
.duration(3500)
.ease("elastic")
.attr("d", function(d) { return "M0,0 L0," + (h_hg - y(d.values.length) + xc); });
}
})(vis || (vis = {}));
/**
* User: ArtZub
* Date: 11.01.13
* Time: 21:41
*/
'use strict';
var timeFormat = (function() {
var fd = d3.time.format("%b %d, %Y");
return function(ms) {
return fd(new Date(ms));
}
})();
var log;
var cs, svg_cs, svg,
margin = {top: 20, right: 20, bottom: 20, left: 20},
w, h, stackLoad = 0,
psBar, runBtn, ldrTop, toolTip, showBtn, visBtn,
userTxt, curRep, divStat, stepsBar, cbDlr, cbDlsr;
function updateStatus(pos, label) {
pos = pos > ghcs.states.max ? ghcs.states.max : pos;
psBar.setPos((pos * 100 / (ghcs.states.max || 1)) + "%")
.setLabel(label || "Completed " + pos + " of " + ghcs.states.max + " commits ...");
}
d3.select(window).on("hashchange", applyParams);
function parseParams(hash) {
var params = {};
hash.replace(/^#/, "").split("&").forEach(function(item) {
var values = item.split("=");
var key = values[0].toLowerCase();
params[key] = values.length > 1 ? values[1] : "";
});
ghcs.params = params;
ghcs.params.climit = params.climit || ghcs.limits.commits;
}
function rewriteHash() {
var step,
hash = [];
if (this == showBtn.node() && ghcs.params) {
step = 0;
}
else if (this == runBtn.node() && ghcs.params) {
step = 1;
}
switch (step) {
case 1:
ghcs.params.repo = ghcs.repo ? ghcs.repo.name : null;
ghcs.params.repo && hash.push("repo=" + ghcs.params.repo);
ghcs.params.climit > 0 && hash.push("climit=" + ghcs.params.climit);
case 0:
ghcs.params.user && hash.push("user=" + ghcs.params.user);
ghcs.params.rot && hash.push("rot=" + ghcs.params.rot);
break;
}
document.location.hash = "#" + hash.join("&");
}
function applyParams() {
d3.event && d3.event.preventDefault();
parseParams(document.location.hash);
stackLoad = stackLoad-- < 1 ? 0 : stackLoad;
if (ghcs.rot != ghcs.params.rot || ghcs.login != ghcs.params.user) {
ghcs.rot = ghcs.params.rot;
userTxt.property("value", ghcs.params.user);
ghcs.user = null;
if (ghcs.params.repo)
stackLoad++;
chUser();
}
else if (ghcs.user && ghcs.user.repos) {
// && (!ghcs.repo || ghcs.repo.name != ghcs.params.repo || (ghcs.params.climit > 0 && ghcs.limits.commits != ghcs.params.climit))
var r;
ghcs.limits.commits = ghcs.params.climit || ghcs.limits.commits;
d3.select("#txt-lc").property("value", ghcs.limits.commits);
if (!ghcs.repo
|| ghcs.repo.name != ghcs.params.repo
|| !ghcs.repo.commits
|| (!ghcs.repo.loadedAll && ghcs.repo.commitsCount < ghcs.limits.commits)) {
if (ghcs.repo && ghcs.repo.name == ghcs.params.repo)
r = ghcs.repo;
else
r = ghcs.user.repos.reduce(function(a, b) {
if (!a && b.nodeValue.name == ghcs.params.repo)
a = b;
return a;
}, null)
;
}
if (r) {
if (ghcs.repo != r) {
vis.meRepo(r);
vis.clRepo(r);
vis.mlRepo(r);
}
}
analyseCommits();
}
}
function nextStepApplyParams() {
if (stackLoad)
applyParams();
}
function chRadio(d) {
switch(this.name) {
case "participation" : {
}
}
}
function chCheckbox(d) {
var ln;
d = d3.select(this);
switch(d.attr("id")) {
case "cb-dlr":
case "cb-dlsr":
ln = d.datum();
vis.layers[ln]
&& ((d.property("checked") && vis.layers[ln].show()) || vis.layers[ln].hide());
break;
case "cb-dllh":
vis.layers.repo
&& vis.layers.repo.langHg
&& vis.layers.repo.langHg.style("display", d.property("checked") ? null : "none");
break;
case "cb-dlvml":
d.property("checked") ? cs.show() : cs.hide();
break;
default :
(ln = d.datum()) && ln.ns
&& (ln.ns[ln.key] = d.property("checked"));
break;
}
}
function chValue(d) {
var ln;
d = d3.select(this);
(ln = d.datum()) && ln.ns
&& (ln.ns[ln.key] = d.property("value"));
}
function checkCompleted() {
if (ghcs.states.cur >= ghcs.states.max) {
psBar.setPos("100%").hide();
if (ghcs.states.complete)
ghcs.states.complete();
return true;
}
return false;
}
function redrawStats() {
if (ghcs.redrawStatsTimer) {
clearTimeout(ghcs.redrawStatsTimer);
ghcs.redrawStatsTimer = null;
}
ghcs.redrawStatsTimer = setTimeout(function () {
vis.redrawStat(ghcs.repo);
ghcs.redrawStatsTimer = null;
}, 100);
}
function runShow() {
if (ghcs.repo && ghcs.repo.commits) {
visBtn.disable();
vis.runShow(ghcs.repo);
}
}
function redrawRepos() {
if (ghcs.redrawReposTimer) {
clearTimeout(ghcs.redrawReposTimer);
ghcs.redrawReposTimer = null;
}
ghcs.redrawReposTimer = setTimeout(function () {
vis.redrawRepos(ghcs.users
&& ghcs.users[ghcs.login]
&& ghcs.users[ghcs.login].repos
? ghcs.users[ghcs.login].repos
: null
);
vis.redrawLangHg(ghcs.users
&& ghcs.users[ghcs.login]
&& ghcs.users[ghcs.login].repos
? d3.nest().key(function(d) { return d.nodeValue.lang; }).entries(ghcs.users[ghcs.login].repos)
: null);
ghcs.redrawReposTimer = null;
}, 100);
}
function init() {
log = (function () {
var logCont = d3.select("#console")
.append("ul");
return function (msg) {
logCont.append("li").text(msg instanceof Object ? JSON.stringify(msg) : msg);
}
})();
cs = d3.select("#canvas");
cs.hide = function() {
this.style("display", "none");
vis.inited && vis.layers.show.hide();
return this;
};
cs.show = function() {
this.style("display", null);
vis.inited && vis.layers.show.show();
return this;
};
svg_cs = d3.select("#svg");
svg = svg_cs.append("svg");
w = svg.property("clientWidth") || document.body.clientWidth;
h = svg.property("clientHeight")|| document.body.clientHeight;
svg.attr("width", w).attr("height", h);
d3.selectAll("input").datum(function() {
var obj = null;
if (this.dataset && this.dataset.ns) {
var reg = new RegExp("(cb|n|txt)-" + this.dataset.ns + "-");
obj = {
ns : ghcs.settings[this.dataset.ns],
key : this.id.replace(reg, "")
};
if (this.type == "checkbox") {
this.checked = obj.ns[obj.key];
}
else {
this.value = obj.ns[obj.key];
}
}
return obj;
});
d3.selectAll("input[type=checkbox]").on("change", chCheckbox);
d3.selectAll("input[type=number], input[type=text]").on("change", chValue);
psBar = d3.select("#progressBar");
psBar.pntNode = d3.select(psBar.node().parentNode);
psBar.show = function() {
this.pntNode.style("display", null);
return this;
};
psBar.hide = function() {
this.pntNode.style("display", "none");
return this;
};
psBar.setLabel = function(lbl) {
this.text(lbl);
return this;
};
psBar.setPos = function(pos) {
this.style("width", pos);
return this;
};
stepsBar = d3.select(".steps");
stepsBar.firstStep = function() {
this.attr("class", "steps sfirst");
return this;
};
stepsBar.secondStep = function() {
this.attr("class", "steps ssecond");
return this;
};
stepsBar.thirdStep = function() {
this.attr("class", "steps");
return this;
};
runBtn = d3.select("#runBtn");
showBtn = d3.select("#showBtn");
visBtn = d3.select("#visBtn");
userTxt = d3.select("#user").on("change", function() {
stepsBar.firstStep();
showBtn.disable();
if (this.value) {
if (this.value != ghcs.login)
showBtn.enable();
else
stepsBar.secondStep();
}
(ghcs.params || (ghcs.params = {})).user = this.value;
});
[runBtn, showBtn, userTxt, visBtn].forEach(function(item) {
item.enable = function () {
this.attr("disabled", null);
return this;
};
item.disable = function () {
this.attr("disabled", "disabled");
return this;
};
});
runBtn.on("click", rewriteHash);
showBtn.on("click", rewriteHash);
visBtn.on("click", runShow);
ldrTop = d3.select("#ldrTop");
ldrTop.pntNode = d3.select(ldrTop.node().parentNode);
ldrTop.show = function () {
this.pntNode.style("display", null);
return this;
};
ldrTop.hide = function () {
this.pntNode.style("display", "none");
return this;
};
toolTip = d3.select("#tooltip");
toolTip.show = function () {
this.style("display", "block");
return this;
};
toolTip.hide = function () {
this.style("display", null);
return this;
};
cbDlr = d3.select("#cb-dlr").datum("repo");
cbDlsr = d3.select("#cb-dlsr").datum("stat");
[cbDlr, cbDlsr].forEach(function(item) {
item.check = function() {
this.property("checked", true);
chCheckbox.apply(this.node());
};
item.uncheck = function() {
this.property("checked", false);
chCheckbox.apply(this.node());
};
item.trigger = function() {
this.property("checked", !this.property("checked"));
chCheckbox.apply(this.node());
};
});
d3.select("#txt-lc").on("change", function() {
(ghcs.params || (ghcs.params = {})).climit = +this.value;
if (ghcs.params.climit < 1)
ghcs.params.climit = ghcs.limits.commits;
});
initGraphics(svg);
curRep = d3.select("#curRep")
.on("mouseover", function(d) {
if (d) {
vis.meRepo(d);
vis.mtt(d, null, null, {pageX : d.x, pageY : d.y});
}
})
.on("mouseout", function(d) {
if (d)
vis.mlRepo(d);
});
curRep.setName = function(r) {
this.selectAll("*").remove();
this.datum(r);
if (!r)
this.append("span")
.text("Select Repo...");
else {
this.append("span")
.style("color", d3.rgb(vis.forceRep.colors(r.nodeValue.lang)).brighter())
.attr("class", "mega-icon mega-icon-public-repo");
this.append("strong")
.style("margin-right", "5px")
.style("text-shadow", "0 0 3px rgba(0, 0, 0, 1)")
.style("color", d3.rgb(vis.forceRep.colors(r.nodeValue.lang)).brighter())
.text((r.nodeValue.name || ""));
this.append("a")
.attr("target", "_blank")
.attr("title", "Go to Github")
.attr("href", (r.nodeValue.html_url || "#"))
.attr("class", "mega-icon mini-icon-link a-icon");
}
return this;
};
divStat = d3.select("#divStat");
divStat.updateInfo = function() {
var user;
if (ghcs.login && (user = ghcs.user = ghcs.users[ghcs.login]) && user.info) {
divStat.selectAll("*").remove();
user.info.avatar && divStat.node().appendChild(user.info.avatar);
divStat.append("ul")
.call(function(ul) {
(user.info.name || user.info.login) && ul.append("li").call(function(li) {
li.append("h1")
.text((user.info.name || user.info.login))
.append("a")
.attr("class", "a-icon")
.attr("target", "_blank")
.attr("title", "Go to GitHub")
.attr("href", user.info.html_url)
.append("span")
.attr("class", "mini-icon mini-icon-octocat")
;
li.append("hr");
});
user.info.location && ul.append("li")
.html("<span class='mini-icon mini-icon-location'></span><strong>" + user.info.location + "</strong>")
user.info.blog && ul.append("li")
.call(function(li) {
li.append("span")
.attr("class", "mini-icon mini-icon-link");
li.append("a")
.attr("target", "_blank")
.attr("href", user.info.blog)
.text(user.info.blog)
});
ul.append("li")
.call(function(li) {
li.append("span")
.attr("class", "mini-icon mini-icon-public-repo")
li.append("strong")
.text(user.info.public_repos)
});
user.info.updated_at && ul.append("li")
.call(function(li) {
li.append("span")
.attr("class", "mini-icon mini-icon-time");
li.append("strong")
.text(timeFormat(Date.parse(user.info.updated_at)))
});
})
}
};
applyParams();
}
/**
* User: ArtZub
* Date: 23.01.13
* Time: 13:29
*/
'use strict';
(function(vis) {
vis.mdRepo = function(d) {
};
vis.meRepo = function(d) {
vis.layers.repo.langHg
&& vis.layers.repo.langHg.style("pointer-events", "none");
vis.layers.repo.toFront();
d._tg = (d._g || (d._g = d3.select(this)));
d._tg.selectAll("circle")
.style("fill", d3.rgb(vis.forceRep.colors(d.nodeValue.lang)).brighter());
d._tg.selectAll("text")
.style("fill", function(d) {
return d3.rgb(vis.forceRep.colors(d.nodeValue.lang)).darker();
})
.style("visibility", "visible");
toolTip.selectAll("*").remove();
toolTip.append("h1")
.text(d.nodeValue.name);
toolTip.append("hr");
d.nodeValue.desc
&& toolTip.append("blockquote")
.text(d.nodeValue.desc)
&& toolTip.append("br")
;
toolTip.append("span")
.attr("class", "mini-icon mini-icon-time")
toolTip.append("strong")
.style("margin-left", "5px")
.text(timeFormat(d.nodeValue.date));
toolTip.append("br");
toolTip.append("span")
.text("Primary language: ")
.append("strong")
.style("color", vis.forceRep.colors(d.nodeValue.lang))
.style("text-shadow", "0 0 3px rgba(0, 0, 0, 0.8)")
.text(d.nodeValue.lang);
toolTip.show();
};
vis.mlRepo = function(d, i) {
if (vis.forceRep.selected && vis.forceRep.selected == d && i !== "deselect") {
vis.muRepo(d);
}
else {
var g = d._tg || d._g;
if (!g)
return;
g.selectAll("circle")
.style("fill", toRgba(vis.forceRep.colors(d.nodeValue.lang), vis.forceRep.opt(vis.forceRep.radO(d))));
g.selectAll("text")
.style("fill", function(d) {
return d3.rgb(vis.forceRep.colors(d.nodeValue.lang)).brighter();
})
.style("visibility", vis.forceRep.visible);
d._tg = null;
}
vis.layers.repo.langHg
&& vis.layers.repo.langHg.style("pointer-events", "all");
toolTip.hide();
};
vis.clRepo = function(d) {
if (vis.forceRep.selected && vis.forceRep.selected == d) {
vis.forceRep.selected = null;
d && (d.fixed = 4);
}
else {
if (vis.forceRep.selected) {
vis.forceRep.selected.fixed = 0;
vis.mlRepo(vis.forceRep.selected, "deselect");
toolTip.show();
vis.layers.repo.langHg
&& vis.layers.repo.langHg.style("pointer-events", "none");
}
vis.forceRep.selected = d;
d && (d.fixed = true);
}
chSelect(vis.forceRep.selected);
};
vis.muRepo = function(d){
};
vis.clearRepos = function() {
if (vis.forceRep) {
vis.forceRep.stop().nodes([]);
delete vis.forceRep;
}
vis.layers && vis.layers.repo && vis.layers.repo.selectAll("*")
.transition()
.duration(750)
.ease("elastic")
.remove();
vis.layers.repo.langHg = null;
};
vis.redrawRepos = function(data, layout) {
layout = layout || vis.layers.repo;
if (!data) {
vis.clearRepos();
return;
}
function tr(d) {
return "translate(" + [d.x, d.y] + ")";
}
vis.forceRep = vis.forceRep || d3.layout.force()
.size([w, h])
.friction(.99)
.gravity(.005)
.charge(function(d) { return -vis.forceRep.radius(vis.forceRep.rad(d)) / 2; })
.on("tick", tick)
;
vis.forceRep.dateNow = Date.now();
vis.forceRep.rad = vis.forceRep.rad || function (d) {
return d.nodeValue.cdate;
};
vis.forceRep.radO = vis.forceRep.radO || function (d) {
return d.nodeValue.date - vis.forceRep.dateNow;
};
data = data.sort(function(a, b) { return a.nodeValue.date - b.nodeValue.date; });
var kof = (h > w ? h : w) / (4 * ((Math.log(data.length || 1) / Math.log(1.5)) || 1));
var r = [kof / 5, kof];
(vis.forceRep.radius || (vis.forceRep.radius = d3.scale.linear()))
.range(r)
.domain(d3.extent(data, vis.forceRep.rad));
data.length == 1 && vis.forceRep.radius.domain([vis.forceRep.radius.domain()[0] - 1, vis.forceRep.radius.domain()[1]]);
(vis.forceRep.opt || (vis.forceRep.opt = d3.scale.log().range([.01,.9])))
.domain(
d3.extent(data, vis.forceRep.radO)
// [d3.min(data, vis.forceRep.radO), vis.forceRep.dateNow]
);
vis.forceRep.colors = vis.reposColors || (vis.reposColors = d3.scale.category20());
vis.forceRep.visible = vis.forceRep.visible || function(d) {
return this.clientWidth < vis.forceRep.radius(vis.forceRep.rad(d)) * 2.1 ? null : "hidden";
};
vis.forceRep.appCT = vis.forceRep.appCT || function(g) {
g.each(function(d) {
d._g = d3.select(this);
});
g.append("circle")
.attr("r", 0);
g.append("text")
.attr("text-anchor", "middle")
.attr("dy", ".31em")
.text(function(d) { return d.nodeValue.name; });
};
vis.forceRep.upCT = vis.forceRep.upCT || function(g) {
g.selectAll("circle")
.style("stroke-width", 1)
.style("stroke", function(d) { return d3.rgb(vis.forceRep.colors(d.nodeValue.lang)); })
.style("fill", function(d) { return toRgba(d3.rgb(vis.forceRep.colors(d.nodeValue.lang)), vis.forceRep.opt(vis.forceRep.radO(d))); })
.transition()
.duration(2500)
.ease("elastic")
.attr("r", function(d) { return vis.forceRep.radius(vis.forceRep.rad(d)); })
g.selectAll("text")
.style("fill", function(d) {
return d3.rgb(vis.forceRep.colors(d.nodeValue.lang)).brighter();
})
.style("visibility", vis.forceRep.visible);
};
vis.forceRep
.stop()
.nodes(data)
.start()
;
vis.forceRep.circle = layout.selectAll(".cRepo")
.data(data, function(d) { return d.nodeValue.id })
;
vis.forceRep.circle.enter()
.append("g")
.attr("class", "cRepo")
.attr("transform", tr)
.call(vis.forceRep.drag)
.on("mouseover.select", vis.meRepo)
.on("mouseout.select", vis.mlRepo)
.on("mousedown.select", vis.mdRepo)
.on("mouseup.select", vis.muRepo)
.on("mousemove.mtt", vis.mtt)
.on("click.select", vis.clRepo)
.call(vis.forceRep.appCT);
vis.forceRep.circle.call(vis.forceRep.upCT);
vis.forceRep.circle.exit().remove();
function tick(e) {
var quadtree = d3.geom.quadtree(vis.forceRep.nodes());
vis.forceRep.circle
.each(cluster(.025/*10 * e.alpha * e.alpha*/))
.each(collide(.5, quadtree))
.attr("transform", tr);
vis.forceRep.resume();
}
// Move d to be adjacent to the cluster node.
function cluster(alpha) {
vis.forceRep.cenralNodes = vis.forceRep.cenralNodes || {};
// Find the largest node for each cluster.
vis.forceRep.nodes().forEach(function(d, n) {
n = vis.forceRep.cenralNodes[d.nodeValue.lang];
(!n || vis.forceRep.radO(d) > vis.forceRep.radO(n)) &&
(vis.forceRep.cenralNodes[d.nodeValue.lang] = d);
});
return function(d) {
var node = vis.forceRep.cenralNodes[d.nodeValue.lang],
l,
r,
x,
y;
if (node == d) return;
x = d.x - node.x;
y = d.y - node.y;
l = Math.sqrt(x * x + y * y);
r = vis.forceRep.radius(vis.forceRep.rad(d)) + vis.forceRep.radius(vis.forceRep.rad(node)) * 1.5;
if (l != r) {
l = (l - r) / (l || 1) * (alpha || 1);
x *= l;
y *= l;
//if (!d.fixed) {
if (true) {
d.x -= x;
d.y -= y;
}
//if (!node.fixed) {
if (true) {
node.x += x;
node.y += y;
}
}
};
}
// Resolves collisions between d and all other circles.
function collide(alpha, quadtree) {
return function(d) {
var padding = vis.forceRep.radius.range()[1] / 2,
r = vis.forceRep.radius(vis.forceRep.rad(d)) + 3 * padding,
nx1 = d.x - r,
nx2 = d.x + r,
ny1 = d.y - r,
ny2 = d.y + r;
quadtree.visit(function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== d)) {
var x = d.x - quad.point.x,
y = d.y - quad.point.y,
l = Math.sqrt(x * x + y * y),
r = (vis.forceRep.radius(vis.forceRep.rad(d)) + vis.forceRep.radius(vis.forceRep.rad(quad.point))) * 1.02 /*+ (d.nodeValue.lang !== quad.point.nodeValue.lang) * padding*/;
if (l < r) {
l = (l - r) / (l || 1) * (alpha || 1);
x *= l;
y *= l;
//if (!d.fixed) {
if (true) {
d.x -= x;
d.y -= y;
}
//if (!quad.point.fixed) {
if (true) {
quad.point.x += x;
quad.point.y += y;
}
}
}
return x1 > nx2
|| x2 < nx1
|| y1 > ny2
|| y2 < ny1;
});
};
}
};
})(vis || (vis = {}));
/**
* User: ArtZub
* Date: 23.01.13
* Time: 15:00
*/
"use strict";
(function(vis) {
var _worker,
_data,
nodes,
dateRange,
authorHash,
filesHash,
extHash,
extMax,
_force,
_forceAuthor,
links,
lCom, lLeg, lHis,
canvas, ctx,
bufCanvas, bufCtx,
layer,
valid,
pause,
stop,
particle,
defImg,
lastEvent,
zoomScale,
xW,
yH,
setting,
rd3 = d3.random.irwinHall(8);
var extColor = d3.scale.category20(),
userColor = d3.scale.category20b();
var typeNode = {
author : 0,
file : 1
};
function reCalc(d) {
if (stop)
return;
lCom.showCommitMessage(d.message);
appendExtLegend(d.sha);
var l = d.nodes.length,
n, a, fn;
a = d.cuserNode ? d.cuserNode : d.userNode;
a.fixed = false;
if (!l)
console.log(d);
else {
a.alive = setting.userLife > 0 ? setting.userLife : 1;
a.opacity = 100;
a.flash = 100;
a.visible = true;
}
while(--l > -1) {
n = d.nodes[l];
if (n.fixed) {
n.x = xW(n.x);
n.y = yH(n.y);
}
n.size += 2;
n.fixed = false;
n.author = a.nodeValue.email;
n.visible = !!n.statuses[d.sha].status;
fn = n.nodeValue.name.toLowerCase();
if (n.visible) {
n.ext.now.indexOf(fn) < 0
&& n.ext.now.push(fn);
n.flash = 100;
n.alive = setting.fileLife > 0 ? setting.fileLife : 1;
n.opacity = 100;
}
else {
(fn = n.ext.now.indexOf(fn)) > -1
&& n.ext.now.splice(fn, 1);
n.alive = (setting.fileLife > 0 ? setting.fileLife : 1) * .2;
n.opacity = 50;
}
/*data.push(n);
if (d.cuserNode) {
links.push({
source : n,
target : d.cuserNode
});
}
links.push({
source : n,
target : d.userNode
});*/
}
updateLegend(d.sha);
_force.nodes(nodes.filter(function(d) {
return d.type != typeNode.author && (d.visible || d.opacity);
}).sort(sortBySize)
).start();
_forceAuthor.nodes(nodes.filter(function(d) {
return d.type == typeNode.author && (d.visible || d.opacity);
})).start();
}
function loop() {
if (pause)
return;
var dl, dr;
dl = dateRange[0];
dr = dl + ghcs.limits.stepShow * ghcs.limits.stepType;
dateRange[0] = dr;
var visTurn = _data.filter(function (d) {
return d.date >= dl && d.date < dr;
});
ghcs.asyncForEach(visTurn, reCalc, ONE_SECOND / (visTurn.length > 1 ? visTurn.length : ONE_SECOND));
//visTurn.forEach(reCalc);
updateStatus(ghcs.states.cur += ghcs.limits.stepShow * ghcs.limits.stepType, timeFormat(new Date(dr)));
if (dl >= dateRange[1]) {
if (_worker)
clearInterval(_worker);
} else {
if (!visTurn.length && setting.skipEmptyDate)
loop();
}
updateExtHistogram();
}
function run() {
if (_worker)
clearInterval(_worker);
anim();
_worker = setInterval(loop, ONE_SECOND);
}
function nr(d) {
return d.size > 0 ? d.size : 0;
}
function ncb(d) {
return d3.rgb(d.color).brighter().brighter();
}
function nc(d) {
return d.color;
}
function randomTrue() {
return Math.floor(rd3() * 8) % 2;
}
function radius(d) {
return Math.sqrt(d);
}
function node(d, type) {
var c = type == typeNode.file ? d.name : userColor(d.email),
ext, x, y,
w2 = w/2,
w5 = w/5,
h2 = h/2,
h5 = h/5;
if (type == typeNode.file) {
c = c && c.match(/.*(\.\w+)$/) ? c.replace(/.*(\.\w+)$/, "$1").toLowerCase() : "Mics";
ext = extHash.get(c);
if (!ext) {
ext = {
all : 0,
currents : {},
color : extColor(c),
now : []
};
extHash.set(c, ext);
}
ext.all++;
c = ext.color;
}
x = w * Math.random();
y = h * Math.random();
if (type == typeNode.author) {
if (randomTrue()) {
x = x > w5 && x < w2
? x / 5
: x > w2 && x < w - w5
? w - x / 5
: x
;
}
else {
y = y > h5 && y < h2
? y / 5
: y > h2 && y < h - h5
? h - y / 5
: y
;
}
}
return {
x : x,
y : y,
id : type + (type == typeNode.file ? d.name : d.email),
size : type != typeNode.file ? 24 : 2,
weight : type != typeNode.file ? 24 : 2,
fixed : true,
visible : false,
links : 0,
type : type,
color : c,
ext : ext,
author : type == typeNode.author ? d.email : null,
img : type == typeNode.author ? d.avatar : null,
nodeValue : d
}
}
function getAuthor(d) {
if (!d || !d.author)
return null;
var n = authorHash.get(d.author.email);
if (!n) {
n = node(d.author, typeNode.author);
authorHash.set(d.author.email, n);
}
return n;
}
function getFile(d) {
if (!d || !d.name)
return null;
var n = filesHash.get(d.name);
if (!n) {
n = node(d, typeNode.file);
n.links = 1;
filesHash.set(d.name, n);
}
return n;
}
function initNodes(data) {
var ns = [],
i, j, n, d, df;
authorHash = d3.map({});
filesHash = d3.map({});
extHash = d3.map({});
extMax = 0;
if (data) {
i = data.length;
while(--i > -1) {
d = data[i];
d.nodes = [];
if (!d) continue;
n = getAuthor(d);
d.userNode = n;
!n.inserted && (n.inserted = ns.push(n));
if (d.author.login != d.committer.login) {
n = getAuthor(d);
d.cuserNode = n;
!n.inserted && (n.inserted = ns.push(n));
/*links.push({
source : d.userNode,
target : d.cuserNode
})*/
}
if (!d.files) continue;
j = d.files.length;
while(--j > -1) {
df = d.files[j];
if (!df) continue;
n = getFile(df);
d.nodes.push(n);
n.size = 2;
n.statuses = n.statuses || {};
n.statuses[d.sha] = df;
n.ext.currents[d.sha] = (n.ext.currents[d.sha] || 0);
n.ext.currents[d.sha]++;
!n.inserted && (n.inserted = ns.push(n));
}
j = extHash.values().reduce(function(a, b) {
return a += b.currents[d.sha] || 0;
}, null);
extMax = j > extMax ? j : extMax;
}
}
return ns;
}
var tempCanvas, tempFileCanvas;
function setOpacity(img, a, f) {
if (!img || !img.width)
img = defImg;
return img;
}
function colorize(img, r, g, b, a) {
if (!img)
return img;
if (!tempFileCanvas) {
tempFileCanvas = document.createElement("canvas");
tempFileCanvas.width = img.width;
tempFileCanvas.height = img.height;
}
var imgCtx = tempFileCanvas.getContext("2d"), imgdata, i;
imgCtx.clearRect(0, 0, img.width, img.height);
imgCtx.save();
imgCtx.drawImage(img, 0, 0);
imgdata = imgCtx.getImageData(0, 0, img.width, img.height);
i = imgdata.data.length;
while((i -= 4) > -1) {
imgdata.data[i + 3] = imgdata.data[i] * a;
if (imgdata.data[i + 3]) {
imgdata.data[i] = r;
imgdata.data[i + 1] = g;
imgdata.data[i + 2] = b;
}
}
imgCtx.putImageData(imgdata, 0, 0);
imgCtx.restore();
return tempFileCanvas;
}
function blink(d, aliveCheck, i, l) {
d.flash = (d.flash -= setting.rateFlash) > 0 ? d.flash : 0;
!d.flash && aliveCheck
&& (d.alive = (d.alive-- > 0 ? d.alive : 0))
;
d.opacity = !d.alive
? ((d.opacity -= setting.rateOpacity) > 0 ? d.opacity : 0)
: d.opacity
;
d.visible && !d.opacity
&& (d.visible = false);
}
function sortBySize(a, b) {
return d3.descending(b.size, a.size);
}
function checkVisible(d, offsetx, offsety) {
var tx = lastEvent.translate[0]/lastEvent.scale,
ty = lastEvent.translate[1]/lastEvent.scale
;
offsetx = offsetx || 0;
if (!(offsetx instanceof Array))
offsetx = [offsetx, offsetx];
offsety = offsety || 0;
if (!(offsety instanceof Array))
offsety = [offsety, offsety];
return (
d.x + d.size > -tx + offsetx[0]
&& d.x - d.size < -tx + offsetx[1] + w/lastEvent.scale
&& d.y + d.size > -ty + offsety[0]
&& d.y - d.size < -ty + offsety[1] + h/lastEvent.scale
);
}
function redrawCanvas() {
bufCtx.save();
bufCtx.clearRect(0, 0, w, h);
bufCtx.translate(lastEvent.translate[0], lastEvent.translate[1]);
bufCtx.scale(lastEvent.scale, lastEvent.scale);
var n, l, i, j,
img,
d, d1, d2,
c, x, y, s;
if (setting.showFile) {
n = d3.nest()
.key(function(d) {
return d.opacity;
})
.key(function(d) {
return d.flash ? ncb(d) : d3.rgb(nc(d));
})
.entries(_force.nodes().filter(function(d) { return checkVisible(d) && (d.visible || d.alive); }));
l = n.length;
while(--l > -1) {
d1 = n[l];
i = d1.values.length;
while(--i > -1) {
d2 = d1.values[i];
j = d2.values.length;
c = d3.rgb(d2.key);
if (!setting.showHalo) {
bufCtx.beginPath();
bufCtx.strokeStyle = "none";
bufCtx.fillStyle = toRgba(c, d1.key * .01);
}
else
img = colorize(particle, c.r, c.g, c.b, d1.key * .01);
while(--j > -1) {
d = d2.values[j];
if (d.visible || d.alive) {
//blink(d, setting.fileLife > 0);
x = Math.floor(d.x);
y = Math.floor(d.y);
s = radius(nr(d)) * (setting.showHalo ? 8 : 1);
setting.showHalo
? bufCtx.drawImage(img, x - s / 2, y - s / 2, s, s)
: bufCtx.arc(x, y, s, 0, PI_CIRCLE, true)
;
}
}
if (!setting.showHalo) {
bufCtx.fill();
bufCtx.stroke();
bufCtx.closePath();
}
}
}
}
if (setting.showUser || setting.showLabel) {
n = _forceAuthor.nodes();
l = n.length;
while(--l > -1) {
d = n[l];
if (checkVisible(d) && (d.visible || d.opacity)) {
//blink(d, !d.links && setting.userLife > 0);
x = Math.floor(d.x);
y = Math.floor(d.y);
if (setting.showUser) {
c = d.flash ? ncb(d) : d3.rgb(nc(d));
bufCtx.save();
if (setting.showPaddingCircle) {
bufCtx.beginPath();
bufCtx.strokeStyle = "none";
bufCtx.fillStyle = toRgba("#ff0000", .1);
bufCtx.arc(x, y, nr(d) + setting.padding, 0, PI_CIRCLE, true);
bufCtx.fill();
bufCtx.stroke();
}
bufCtx.beginPath();
bufCtx.strokeStyle = "none";
bufCtx.fillStyle = setting.useAvatar ? "none" : toRgba(c, d.opacity * .01);
bufCtx.arc(x, y, nr(d), 0, PI_CIRCLE, true);
bufCtx.fill();
bufCtx.stroke();
if (setting.useAvatar && d.img) {
bufCtx.clip();
bufCtx.drawImage(setOpacity(d.img, d.opacity * .01, d.flash), x - nr(d), y - nr(d), nr(d) * 2, nr(d) * 2);
}
bufCtx.closePath();
bufCtx.restore();
}
if (setting.showLabel) {
c = d.flash ? "white" : "gray";
bufCtx.save();
bufCtx.fillStyle = toRgba(c, d.opacity * .01);
bufCtx.fillText(setting.labelPattern
.replace("%l", d.nodeValue.login)
.replace("%n", d.nodeValue.name != "unknown" ? d.nodeValue.name : d.nodeValue.login)
.replace("%e", d.nodeValue.email), x, y + nr(d) * 1.5);
bufCtx.restore();
}
}
}
}
bufCtx.restore();
}
function anim() {
requestAnimationFrame(anim);
lHis && lHis.style("display", setting.showHistogram ? null : "none");
lLeg && lLeg.style("display", setting.showCountExt ? null : "none");
if (valid)
return;
valid = true;
ctx.save();
ctx.clearRect(0, 0, w, h);
redrawCanvas();
ctx.drawImage(bufCanvas, 0, 0);
ctx.restore();
valid = false;
}
function tick() {
if (_force.nodes()) {
_force.nodes()
.forEach(cluster(0.025));
_forceAuthor.nodes(
_forceAuthor.nodes()
.filter(function(d, i) {
blink(d, !d.links && setting.userLife > 0, i, _forceAuthor.nodes().length);
if (d.visible && d.links === 0 && setting.userLife > 0) {
d.flash = 0;
d.alive = d.alive / 10;
}
return d.visible;
})
);
}
_forceAuthor.resume();
_force.resume();
}
// Move d to be adjacent to the cluster node.
function cluster(alpha) {
authorHash.forEach(function(k, d) {
d.links = 0;
});
return function(d, i) {
blink(d, setting.fileLife > 0, i, _force.nodes().length);
if (!d.author || !d.visible)
return;
var node = authorHash.get(d.author),
l,
r,
x,
y;
if (node == d) return;
node.links++;
x = d.x - node.x;
y = d.y - node.y;
l = Math.sqrt(x * x + y * y);
r = radius(nr(d)) / 2 + (nr(node) + setting.padding);
if (l != r) {
l = (l - r) / (l || 1) * (alpha || 1);
x *= l;
y *= l;
d.x -= x;
d.y -= y;
}
};
}
function appendExtLegend(sha){
if (!layer)
return;
var data = [],
w3 = w / 3,
ml = w * .01,
mb = 18,
h2 = (h / 2) - mb,
bw = 2,
i, ny
;
var y = d3.scale.linear()
.range([0, h2])
.domain([0, extMax]);
lHis = (lHis || layer.append("g"))
.attr("width", w3)
.attr("height", h2)
.attr("transform", "translate(" + [ ml , h - h2 - mb ] + ")");
if (!sha)
return;
ny = h2;
extHash.forEach(function(k, d) {
var obj = {
key : k,
h : y(d.currents[sha] || 0),
color : d.color
};
obj.y = ny -= obj.h;
data.push(obj);
});
updateExtHistogram();
var g = lHis.append("g")
.attr("class", "colStack")
.datum({ x : w3, w : bw })
.style("opacity", 0);
g.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("x", 0)
.attr("y", function(d) { return d.y; })
.attr("width", bw)
.attr("height", function(d) { return d.h; })
.attr("fill", function(d) { return d.color; })
;
g.style("opacity", 1)
.attr("transform", function(d) {
return "translate(" + [ d.x, 0] + ")";
});
}
function updateExtHistogram() {
if (!lHis || lHis.selectAll(".colStack").empty())
return;
lHis.selectAll(".colStack")
.attr("transform", function(d) {
return "translate(" + [ d.x -= d.w - 1, 0] + ")";
})
.filter(function(d) {
return d.x < 0;
})
.remove();
}
function initLegend() {
if (!layer)
return;
var mt = 48,
ml = w * .01,
h2 = h / 2 - mt,
w3 = w / 3
;
lLeg = (lLeg || layer.append("g"))
.attr("width", w3)
.attr("height", h2)
.attr("transform", "translate(" + [ml, mt] + ")");
lLeg.selectAll("*").remove();
var g = lLeg.selectAll(".gLeg")
.data(extHash.entries(), function(d) { return d.key; });
g.exit().remove();
g.enter().append("g")
.attr("class", "gLeg")
.attr("transform", function(d, i) {
return "translate(" + [0, i * 18] + ")";
})
.style("visibility", "hidden")
;
g.append("rect")
.attr("height", 16)
.style("fill", function(d) { return d.value.color; })
;
g.append("text")
.attr("class", "gttLeg")
.style("font-size", "13px")
.text(function(d) { return d.key.substr(1); })
.style("fill", function(d) { return d3.rgb(d.value.color).brighter().brighter(); })
;
g.append("text")
.attr("class", "gtLeg")
.style("font-size", "11px")
.attr("transform", "translate(" + [2, 12] + ")")
;
}
function sortLeg(b, a) {
return d3.ascending(a.value.now.length, b.value.now.length);
}
function sortLegK(b, a) {
return d3.ascending(a.key, b.key);
}
function updateLegend(sha) {
if (!lLeg || lLeg.empty())
return;
var g = lLeg.selectAll(".gLeg");
function wl(d) {
return d.value.now.length;
}
var wb = 9 * d3.max(g.data(), function(d) {
return ((wl(d) || "") + "").length;
});
g.selectAll("rect")
.attr("width", wb)
;
g.selectAll(".gttLeg")
.attr("transform", "translate(" + [wb + 2, 12] + ")")
;
g.selectAll(".gtLeg")
.text(wl)
;
g.sort(sortLegK).sort(sortLeg)
.style("visibility", function(d, i) {
return !wl(d) || i * 18 > lLeg.attr("height") ? "hidden" : "visible";
})
.transition()
.duration(500)
.attr("transform", function(d, i) {
return "translate(" + [0, i * 18] + ")";
})
;
}
vis.runShow = function(data, svg, params) {
if (_worker)
clearInterval(_worker);
_data = data && data.commits ? data.commits.values().sort(vis.sC) : null;
if (!_data || !_data.length)
return;
setting = ghcs.settings.cs;
vis.layers.repo && cbDlr.uncheck();
vis.layers.stat && cbDlsr.uncheck();
dateRange = d3.extent(data.dates);
layer = d3.select("#canvas");
layer.select("#mainCanvas").remove();
lastEvent = {
translate: [0, 0],
scale : 1
};
xW = d3.scale.linear()
.range([0, w])
.domain([0, w]);
yH = d3.scale.linear()
.range([0, h])
.domain([0, h]);
var zoom = d3.behavior.zoom()
.scaleExtent([.1, 8])
.scale(1)
.translate([0, 0])
.on("zoom", function() {
lastEvent.translate = d3.event.translate.slice(0);
lastEvent.scale = d3.event.scale;
var tl = lastEvent.translate[0] / lastEvent.scale,
tt = lastEvent.translate[1] / lastEvent.scale;
xW.range([-tl, -tl + w / lastEvent.scale])
.domain([0, w]);
yH.range([-tt, -tt + h / lastEvent.scale])
.domain([0, h]);
valid = false;
});
canvas = layer.append("canvas")
.text("This browser don't support element type of Canvas.")
.attr("id", "mainCanvas")
.attr("width", w)
.attr("height", h)
.call(zoom)
.node();
ctx = canvas.getContext("2d");
bufCanvas = document.createElement("canvas");
bufCanvas.width = w;
bufCanvas.height = h;
bufCtx = bufCanvas.getContext("2d");
bufCtx.font = "normal normal " + setting.sizeUser / 2 + "px Tahoma";
bufCtx.textAlign = "center";
layer = svg || vis.layers.show;
layer && layer.show && layer.show();
layer.append("g")
.call(zoom)
.append("rect")
.attr("width", w)
.attr("height", h)
.attr("x", 0)
.attr("y", 0)
.style("fill", "#ffffff")
.style("fill-opacity", 0);
lHis && lHis.selectAll("*").remove();
lCom = (
lCom || layer.append("g")
.attr("width", 10)
.attr("height", 14)
)
.attr("transform", "translate(" + [w/2, h - 18] + ")")
;
lCom.visible = !setting.showCommitMessage;
lCom.selectAll("text").remove();
lCom.showCommitMessage = lCom.showCommitMessage || function(text) {
if (setting.showCommitMessage && !lCom.visible) {
lCom.visible = true;
lCom.style("display", null);
}
else if (!setting.showCommitMessage && lCom.visible) {
lCom.visible = false;
lCom.style("display", "none");
}
lCom.append("text")
.attr("text-anchor", "middle")
.attr("class", "com-mess")
.attr("transform", "translate("+ [0, -lCom.node().childElementCount * 14] +")")
.text(text.split("\n")[0].substr(0, 100))
.transition()
.delay(500)
.duration(2000)
.style("fill-opacity", 1)
.duration(200)
.style("font-size", "11.2pt")
.transition()
.duration(1500)
.style("fill-opacity", .3)
.style("font-size", "11pt")
.each("end", function() {
lCom.selectAll("text").each(function(d, i) {
d3.select(this)
.attr("transform", "translate("+ [0, -i * 14] +")");
});
})
.remove();
};
psBar.show();
ghcs.states.cur = 0;
ghcs.states.max = dateRange[1] - dateRange[0];
updateStatus(ghcs.states.cur, timeFormat(new Date(dateRange[0])));
links = [];
nodes = initNodes(_data);
defImg = new Image();
defImg.src = "default.png";
particle = new Image();
particle.src = "particle.png";
_force = (_force || d3.layout.force()
.stop()
.size([w, h])
.friction(.75)
.gravity(0)
.charge(function(d) {return -3 * radius(nr(d)); } )
.on("tick", tick))
.nodes([])
;
zoomScale = d3.scale.linear()
.range([5, 1])
.domain([.1, 1]);
_forceAuthor = (_forceAuthor || d3.layout.force()
.stop()
.size([w, h])
.gravity(setting.padding * .001)
.charge(function(d) { return -(setting.padding + d.size) * 8
* (Math.sqrt(d.links / lastEvent.scale) || 1)
;
}))
.nodes([])
;
initLegend();
stop = false;
pause = false;
run();
_force.start();
_forceAuthor.start();
};
vis.pauseShow = function() {
pause = true;
};
vis.stopShow = function() {
stop = true;
if (_worker)
clearInterval(_worker);
};
vis.resumeShow = function() {
pause = false;
};
})(vis || (vis = {}));
/**
* User: ArtZub
* Date: 23.01.13
* Time: 12:54
*/
'use strict';
(function (vis) {
var textFormat = d3.format(",");
vis.meArc = function(d) {
vis.layers.stat.toFront();
if (!d._g)
return;
d._g.selectAll("path.bar")
.style({
"fill-opacity" : .6,
"stroke-width" : 1,
"stroke" : function() { return toRgba("#000000", 1); }
});
var self = d._g.node();
self.barDel && self.barDel
.transition()
.attr("d", self.delArc.startAngle(PIdiv2 + smallRad )
.endAngle(PIdiv2 * 3 - smallRad)())
;
self.barAdd && self.barAdd
.transition()
.attr("d", self.addArc.startAngle(-PIdiv2 + smallRad )
.endAngle(PIdiv2 - smallRad)())
;
d._g.selectAll("text.del, text.add")
.style("visibility", "visible");
toolTip.selectAll("*").remove();
toolTip.append("div").attr("class", "row")
.append("blockquote")
.text(d.message.split("\n")[0]);
toolTip.append("div").attr("class", "row userInfo open").call(function(div) {
div = div.append("div").attr("class", "statInfo");
div.node().appendChild(d.author.avatar);
div.append("ul").call(function(ul) {
(d.author.name || d.author.login) && ul.append("li").call(function(li) {
li.append("h1")
.text((d.author.name || d.author.login))
;
li.append("hr");
});
ul.append("li").call(function(li) {
li.append("span")
.attr("class", "mini-icon mini-icon-time");
li.append("strong")
.text(timeFormat(d.date))
});
d.files.length && ul.append("li")
.call(function(li) {
var stat = d.files.reduce(function(a, b) {
for(var key in TYPE_STATUS_FILE) {
if (TYPE_STATUS_FILE.hasOwnProperty(key)
&& b.status == TYPE_STATUS_FILE[key]) {
a[key] = (a[key] || 0);
a[key]++;
break;
}
}
return a;
}, {});
li = li.append("ul")
.attr("class", "setting");
li = li.append("li").attr("class", "field");
li.append("h1")
.text("Changed files:");
for(var key in stat) {
stat.hasOwnProperty(key)
&& li.append("ul")
.attr("class", "group")
.append("li")
.attr("class", "field")
.append("span")
.text(key + ": ")
.append("strong")
.text(stat[key]);
}
});
ul.append("li")
.call(function(li) {
li = li.append("ul")
.attr("class", "setting");
li = li.append("li").attr("class", "field");
li.append("h1")
.text("Changed lines:");
var stat = {changes : "", additions : " + ", deletions : " - "};
for(var key in stat) {
d.stats.hasOwnProperty(key)
&& li.append("ul")
.attr("class", "group")
.append("li")
.attr("class", "field")
.append("span")
.text(key + ": ")
.append("strong")
.style("color", d3.rgb(colors[key]).darker(.2))
.text(stat[key] + textFormat(d.stats[key]));
}
});
});
});
toolTip.show();
};
vis.mlArc = function(d) {
if (!d._g)
return;
d._g.selectAll("path.bar")
.style({
"fill-opacity" : .3,
"stroke" : null
});
var self = d._g.node();
if (!self)
return;
self.barDel && self.barDel
.transition()
.duration(750)
.ease("elastic")
.attr("d", self.delArc.startAngle(Math.PI - smallRad)
.endAngle(Math.PI + smallRad)())
;
self.barAdd && self.barAdd
.transition()
.duration(750)
.ease("elastic")
.attr("d", self.addArc.startAngle(- smallRad )
.endAngle(smallRad)())
;
d._g.selectAll("text.del")
.style("visibility", d.stats && d.stats.delTextVis ? d.stats.delTextVis : "hidden");
d._g.selectAll("text.add")
.style("visibility", d.stats && d.stats.addTextVis ? d.stats.addTextVis : "hidden");
toolTip.hide();
};
vis.mmArc = function(d) {
vis.mtt(d);
};
vis.clearStat = function() {
if (vis.layers && vis.layers.stat) {
vis.layers.stat.selectAll("*").remove();
vis.layers.stat.cont && (vis.layers.stat.cont = null);
}
};
vis.redrawStat = function(data, layout) {
layout = layout || vis.layers.stat;
var _commits = data && data.commits ? data.commits.values() : null;
if (!_commits || !_commits.length) {
vis.clearStat();
return;
}
var bd = d3.extent(data.dates);
var delta = (bd[1] - bd[0]) * 0.1;
delta = delta || ONE_DAY;
bd = [bd[0] - delta, bd[1] + delta];
var x = d3.time.scale()
.domain(d3.extent(bd))
.range([0, w - margin.left - margin.right])
;
var h6 = h/6;
var y = d3.scale.linear()
.range([2, h6 * 2])
.domain([0, data.stats.changes || 1]);
var sorted = _commits.slice(0).concat([
{ date : bd[0] + delta / 2, f : { d : 0, a : 0, m : 0 } },
{ date : bd[1] - delta / 2, f : { d : 0, a : 0, m : 0 } }
]).sort(vis.sC);
var layers =
[
{
color: colors.deletedFile,
values: sorted.map(function (d) {
return {t : 1, x: d.date, y0 : 0, y: (d.stats ? -d.stats.f.d : 0)}
})
},
{
color: colors.modifiedFile,
values: sorted.map(function (d) {
return {x: d.date, y0 : 0, y: (d.stats ? d.stats.f.m : 0)}
})
},
{
color: colors.addedFile,
values: sorted.map(function (d) {
return {x: d.date, y0: (d.stats ? d.stats.f.m : 0), y : (d.stats ? d.stats.f.a : 0)}
})
}
]
;
function interpolateSankey(points) {
var x0 = points[0][0], y0 = points[0][1], x1, y1, x2,
path = [x0, ",", y0],
i = 0,
n = points.length;
while (++i < n) {
x1 = points[i][0];
y1 = points[i][1];
x2 = (x0 + x1) / 2;
path.push("C", x2, ",", y0, " ", x2, ",", y1, " ", x1, ",", y1);
x0 = x1;
y0 = y1;
}
return path.join("");
}
var y1 = d3.scale.linear()
.range([h6 * 4.5, h6 * 3, h6 * 1.5])
.domain([-data.stats.files, 0, data.stats.files]),
area = d3.svg.area()
.interpolate(interpolateSankey /*true ? "linear" : "basis"*/)
.x(function(d) { return x(d.x); })
.y0(function(d) { return y1(d.y0); })
.y1(function(d) { return y1(d.y0 + d.y); })
;
var xAxis = d3.svg.axis()
.scale(x)
;
layout.cont = layout.cont || layout
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
;
layout.cont.selectAll("path.areaFile").remove();
layout.cont.selectAll("path.areaFile")
.data(layers)
.enter()
.insert("path", ":first-child")
.attr("class", "areaFile")
.style("fill-opacity",.1)
.style("fill", function(d) { return d.color; })
.transition()
.duration(750)
.attr("d", function(d) { return area(d.values); })
;
layout.cont.axis = layout.cont.axis || layout.cont.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + h/2 + ")")
;
layout.cont.axis
.selectAll("*").remove();
layout.cont.axis
.call(xAxis)
.selectAll("text")
.attr("y", 0)
.attr("x", 9)
.attr("dy", ".35em")
.attr("transform", "rotate(90)")
.style("text-anchor", "start")
;
layout.cont.points = layout.cont.points || layout.cont.append("g")
.attr("transform", "translate(0," + h/2 + ")")
;
var cData = layout.cont.points.selectAll("g.com")
.data(_commits, function(d) { return d.sha; });
cData.enter()
.append("g")
.attr("class", "com")
.on("mouseover", vis.meArc)
.on("mouseout", vis.mlArc)
.on("mousemove", vis.mmArc)
;
cData.each(function(d, g) {
g = d._g = d3.select(this);
g.transition()
.duration(1500)
.ease("elastic")
.attr("transform", "translate(" + [ x(d.date), 0] + ")");
this.center = this.center || g.append("circle")
.attr("r", 2)
.style("fill", colors.center)
;
if (!d.stats)
return;
var add = this.addArc = d3.svg.arc()
.innerRadius(1)
.outerRadius(1)
.startAngle(- smallRad )
.endAngle(smallRad)
;
var del = this.delArc = d3.svg.arc()
.innerRadius(1)
.outerRadius(1)
.startAngle(Math.PI - smallRad)
.endAngle(Math.PI + smallRad)
;
(this.barAdd || (
this.barAdd = g.append("path")
.attr("class", "bar")
.style({
"fill" : colors.additions,
"fill-opacity" : .3
})
.attr("d", add())
))
.transition()
.duration(750)
.ease("elastic")
.attr("d", add.outerRadius(y(d.stats.additions))())
;
(this.barDel || (
this.barDel = g.append("path")
.attr("class", "bar")
.style({
"fill" : colors.deletions,
"fill-opacity" : .3
})
.attr("d", del())
))
.transition()
.duration(750)
.ease("elastic")
.attr("d", del.outerRadius(y(d.stats.deletions))())
;
function sized(s, k) {
return s * (1 + k);
}
var addTop = this.addArcTop = d3.svg.arc()
.innerRadius(sized(y(d.stats.additions), .015))
.outerRadius(sized(y(d.stats.additions), .025))
.startAngle(- smallRad )
.endAngle(smallRad)
;
var delTop = this.delArcTop = d3.svg.arc()
.innerRadius(sized(y(d.stats.deletions), .015))
.outerRadius(sized(y(d.stats.deletions), .025))
.startAngle(Math.PI - smallRad)
.endAngle(Math.PI + smallRad)
;
(this.barAddTop || (
this.barAddTop = g.append("path")
.style("fill", toRgba(colors.additions))
))
.attr("d", addTop())
;
(this.barDelTop || (
this.barDelTop = g.append("path")
.style("fill", toRgba(colors.deletions))
))
.attr("d", delTop())
;
if (d.stats.additions) {
d.stats.addTextVis = sized(y(d.stats.additions), .029) > h6 / 2 ? "visible" : "hidden";
(this.labelAdd || (
this.labelAdd = g.append("text")
.attr("class", "add")
.attr("dy", "-.31em")
.attr("text-anchor", "middle")
.style("fill", colors.additions)
.text(" + " + textFormat(d.stats.additions))
))
.attr("transform", "translate(" + [0, -sized(y(d.stats.additions), .027)] + ")")
.attr("visibility", d.stats.addTextVis)
;
}
if (d.stats.deletions) {
d.stats.delTextVis = sized(y(d.stats.deletions), .029) > h6 / 2 ? "visible" : "hidden";
(this.labelDel || (
this.labelDel = g.append("text")
.attr("class", "del")
.attr("dy", ".93em")
.attr("text-anchor", "middle")
.style("fill", colors.deletions)
.text(" - " + textFormat(d.stats.deletions))
))
.attr("transform", "translate(" + [0, sized(y(d.stats.deletions), .027)] + ")")
//rotate(180)
.attr("visibility", d.stats.delTextVis)
;
}
});
cData.sort(function(a, b) {
return a.stats && b.stats ? d3.ascending(b.stats.changes, a.stats.changes) : 0;
});
cData.exit().remove();
};
})(vis || (vis = {}));
/* html5doctor.com Reset v1.6.1 - http://cssreset.com */
html,body,div,span,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,abbr,address,cite,code,del,dfn,em,img,ins,kbd,q,samp,small,strong,sub,sup,var,b,i,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent}body{line-height:1}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}nav ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}a{margin:0;padding:0;font-size:100%;vertical-align:baseline;background:transparent}ins{background-color:#ff9;color:#000;text-decoration:none}mark{background-color:#ff9;color:#000;font-style:italic;font-weight:bold}del{text-decoration:line-through}abbr[title],dfn[title]{border-bottom:1px dotted;cursor:help}table{border-collapse:collapse;border-spacing:0}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}input,select{vertical-align:middle}
/** взято с github.com */
@font-face {
font-family: 'Octicons Regular';
src: url(github_webfont.eot);
src: url(github_webfont_ie.eot) format("embedded-opentype"),
url(github_webfont.woff) format("woff"),
url(github_webfont.ttf) format("truetype"),
url(github_webfont.svg) format("svg");
font-weight: normal;
font-style: normal
}
.mini-icon, .mega-icon {
font-family: 'Octicons Regular';
font-weight: normal;
font-style: normal;
display: inline-block;
text-decoration: inherit;
line-height: 1;
-webkit-font-smoothing: antialiased;
line-height: 1;
text-decoration: none;
}
.mini-icon {
font-size: 16px;
width: 16px;
height: 16px;
}
.mega-icon {
font-size: 32px;
width: 32px;
height: 32px;
}
.mini-icon-octocat:before {
content: "\f008";
}
.mini-icon-public-repo:before {
content: "\f001";
}
.mini-icon-time:before {
content: "\f046";
}
.mini-icon-link:before {
content: "\f05c";
}
.mini-icon-location:before {
content: "\f060";
}
.mini-icon-history:before {
content: "\f07e";
}
.mega-icon-public-repo:before {
content: "\f201";
}
/** end */
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
}
body {
background: url('data:image/png;base64,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');
}
label {
color: #f9f9f9;
}
.popup {
position: absolute;
overflow: hidden;
z-index: 10;
}
#controls {
left: -1px;
top: -1px;
z-index: 11;
padding: 5px;
vertical-align: middle;
border-radius: 0 0 3px 0;
width: 100%;
}
#controls input,
#controls button,
#controls label {
display: inline-block;
}
input[type=text],
input[type=number] {
border: 1px solid #b9b9b9;
display: block;
padding: 5px;
font-size: 14px;
margin: 0;
outline: 0;
}
input[type=text]:hover,
input[type=number]:hover,
input[type=text]:focus,
input[type=number]:focus {
border-color: #000;
-webkit-box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3);
-moz-box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3);
-o-box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3);
-ms-box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3);
box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3);
}
#controls input {
font-family: sans-serif;
font-weight: bolder;
}
#console {
bottom: 0;
left: 0;
z-index: 100;
}
/* progress bar */
.meter {
overflow: hidden;
position: relative;
background: #555;
padding: 10px;
-webkit-box-shadow: inset 0 -1px 1px rgba(255, 255, 255, 0.3);
-moz-box-shadow: inset 0 -1px 1px rgba(255, 255, 255, 0.3);
box-shadow: inset 0 -1px 1px rgba(255, 255, 255, 0.3);
}
.meter > span {
display: block;
background-color: rgb(43, 194, 83);
/*background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, rgb(43, 194, 83)), color-stop(1, rgb(84, 240, 84)));
background-image: -moz-linear-gradient(center bottom, rgb(43, 194, 83) 37%, rgb(84, 240, 84) 69%);*/
-webkit-box-shadow: inset 0 2px 9px rgba(255, 255, 255, 0.3), inset 0 -2px 6px rgba(0, 0, 0, 0.4);
-moz-box-shadow: inset 0 2px 9px rgba(255, 255, 255, 0.3), inset 0 -2px 6px rgba(0, 0, 0, 0.4);
box-shadow: inset 0 2px 9px rgba(255, 255, 255, 0.3), inset 0 -2px 6px rgba(0, 0, 0, 0.4);
position: relative;
overflow: hidden;
min-height: 10px
}
.orange > span {
background-color: #f1a165;
background: rgb(241,161,101);
/*background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2YxYTE2NSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmMzZkMGEiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
background: -moz-linear-gradient(top, rgba(241,161,101,1) 0%, rgba(243,109,10,1) 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(241,161,101,1)), color-stop(100%,rgba(243,109,10,1)));
background: -webkit-linear-gradient(top, rgba(241,161,101,1) 0%,rgba(243,109,10,1) 100%);
background: -o-linear-gradient(top, rgba(241,161,101,1) 0%,rgba(243,109,10,1) 100%);
background: -ms-linear-gradient(top, rgba(241,161,101,1) 0%,rgba(243,109,10,1) 100%);
background: linear-gradient(to bottom, rgba(241,161,101,1) 0%,rgba(243,109,10,1) 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f1a165', endColorstr='#f36d0a',GradientType=0 );*/
}
.red > span {
background-color: #f0a3a3;
/*background-image: -moz-linear-gradient(top, #f0a3a3, #f42323);
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #f0a3a3), color-stop(1, #f42323));
background-image: -webkit-linear-gradient(#f0a3a3, #f42323);*/
}
.progressBar {
font-size: 11px;
width: 100%;
}
.progressBar .meter {
margin: 0;
padding: 1px;
}
/*.progressBar .meter > span*/
#progressBar {
text-align: right;
vertical-align: middle;
color: white;
text-shadow: 0 1px 1px black;
word-wrap: normal;
white-space: nowrap;
text-overflow: ellipsis;
}
/* end progress bar */
#statusBar {
bottom: 0;
left: 0;
z-index: 12;
width: 100%;
position: fixed;
border: 0;
border-top: 1px solid #CACACA;
background: rgb(239,239,239);
/*background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2VmZWZlZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQxJSIgc3RvcC1jb2xvcj0iI2RkZGRkZCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNjYWNhY2EiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
background: -moz-linear-gradient(top, rgba(239,239,239,1) 0%, rgba(221,221,221,1) 41%, rgba(202,202,202,1) 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(239,239,239,1)), color-stop(41%,rgba(221,221,221,1)), color-stop(100%,rgba(202,202,202,1)));
background: -webkit-linear-gradient(top, rgba(239,239,239,1) 0%,rgba(221,221,221,1) 41%,rgba(202,202,202,1) 100%);
background: -o-linear-gradient(top, rgba(239,239,239,1) 0%,rgba(221,221,221,1) 41%,rgba(202,202,202,1) 100%);
background: -ms-linear-gradient(top, rgba(239,239,239,1) 0%,rgba(221,221,221,1) 41%,rgba(202,202,202,1) 100%);
background: linear-gradient(to bottom, rgba(239,239,239,1) 0%,rgba(221,221,221,1) 41%,rgba(202,202,202,1) 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#efefef', endColorstr='#cacaca',GradientType=0 );*/
}
#statusBar ul {
padding: 2px 3px;
overflow: hidden;
margin: 0;
list-style: none;
}
#statusBar li {
display: block;
vertical-align: middle;
float: left;
margin-right: 2px;
border: 0;
border-right: 1px solid #444;
}
#statusBar li:last-child {
margin-right: 0;
border-right: 0;
}
#layers,
#canvas,
#svg,
canvas,
svg {
position: relative;
width: 100%;
height: 100%;
}
#svg, #canvas {
position: absolute;
top: 0;
left : 0;
}
#svg {
z-index: 1;
}
#canvas {
z-index: 0;
}
#layers {
background: rgba(224, 224, 224, .1);
}
.axis text {
font: 10px sans-serif;
fill: #ccc;
}
.axis line,
.axis path {
fill: none;
stroke: #ccc;
shape-rendering: crispEdges;
}
#ldrCont {
z-index: 100;
top: 0;
left: 0;
text-align: center;
width: 100%;
height: 100%;
}
#ldrCont > img {
display: inline-block;
position:relative;
top:49%;
width: 48px;
height: auto;
}
.lineFiles {
fill: none;
shape-rendering: crispEdges;
stroke-width: 2px;
}
.lineFiles .M {
stroke: rgba(255, 184, 119, .5);
}
.lineFiles .A {
stroke: rgba(165, 236, 110, .5);
}
.lineFiles .D {
stroke: rgba(255, 119, 255, .5);
}
.cRepo {
cursor: pointer;
}
.cRepo text {
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
pointer-events: none;
}
.cRepo:hover text {
text-shadow: 0 1px 2px rgba(255, 255, 255, 1);
}
.tooltip {
color: #f9f9f9;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
background: rgba(110, 130, 163, 0.7);
border: 1px dotted #8D9DB6;
padding: 5px;
border-radius: 3px;
}
#tooltip {
z-index: 50;
display: none;
max-width: 25%;
pointer-events: none;
}
/* http://xbreaker.github.com/plusstrap/base-css.html#buttons */
.btn {
display: inline-block;
*display: inline;
*zoom: 1;
padding: 0px 8px;
font-weight: bold;
margin-bottom: 0;
font-size: 11px;
line-height: 22px;
*line-height: 22px;
text-align: center;
vertical-align: middle;
cursor: default;
color: #333333;
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
background-color: #f3f3f3;
background-image: -moz-linear-gradient(top, #f5f5f5, #f1f1f1);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f1f1f1));
background-image: -webkit-linear-gradient(top, #f5f5f5, #f1f1f1);
background-image: -o-linear-gradient(top, #f5f5f5, #f1f1f1);
background-image: linear-gradient(to bottom, #f5f5f5, #f1f1f1);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff1f1f1', GradientType=0);
border-color: #e4e4e4;
*background-color: #f1f1f1;
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
border: 1px solid rgba(0, 0, 0, 0.1);
*border: 0;
border-bottom-color: rgba(0, 0, 0, 0.1);
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
*margin-left: .3em;
}
.btn:not(.active):hover {
background-color: #f5f5f5;
background-image: -moz-linear-gradient(top, #f9f9f9, #eeeeee);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f9f9f9), to(#eeeeee));
background-image: -webkit-linear-gradient(top, #f9f9f9, #eeeeee);
background-image: -o-linear-gradient(top, #f9f9f9, #eeeeee);
background-image: linear-gradient(to bottom, #f9f9f9, #eeeeee);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9f9f9', endColorstr='#ffeeeeee', GradientType=0);
}
.btn:hover,
.btn:active,
.btn.active,
.btn.disabled,
.btn[disabled] {
color: #333333;
background-color: #eeeeee;
*background-color: #e4e4e4;
-webkit-box-shadow: 0 1px 0px #dedede;
-moz-box-shadow: 0 1px 0px #dedede;
box-shadow: 0 1px 0px #dedede;
border-color: #cbcbcb;
}
.btn:active,
.btn.active {
background-color: #d8d8d8 \9;
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .2);
-moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .2);
box-shadow: inset 0 1px 2px rgba(0, 0, 0, .2);
}
.btn:first-child {
*margin-left: 0;
}
.btn:hover {
color: #333333;
text-decoration: none;
background-color: #e6e6e6;
*background-color: #d9d9d9;
-webkit-transition: background-position 0.1s linear;
-moz-transition: background-position 0.1s linear;
-o-transition: background-position 0.1s linear;
transition: background-position 0.1s linear;
}
.btn:focus {
outline: thin dotted #333;
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
.btn.active,
.btn:active {
background-color: #e6e6e6;
background-color: #d9d9d9 \9;
background-image: none;
outline: 0;
}
.btn.disabled,
.btn[disabled] {
cursor: default;
background-color: #e6e6e6;
background-image: none;
opacity: 0.65;
filter: alpha(opacity=65);
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
/** end **/
#controls .btn {
padding: 2px 8px;
margin: 0;
}
.row {
display: block;
max-width: 100%;
}
#divStat img,
.statInfo img {
float: left;
margin: 0 0 0 0;
padding: 1px;
background: #fff;
box-shadow: 0 1px 2px rgba(0,0,0,0.15);
}
#divStat ul,
.statInfo ul {
overflow: hidden;
padding: 0;
list-style: none;
}
#divStat li,
.statInfo li {
color: #ccc;
}
hr {
margin: 5px 0;
}
#divStat li strong,
#divStat li a,
.statInfo li strong,
.statInfo li a {
margin-left: 5px;
}
#divStat li strong,
#divStat h1,
.statInfo li strong,
.statInfo h1 {
color: #f9f9f9;
}
#curRep .a-icon,
#divStat .a-icon,
.statInfo .a-icon {
text-decoration: none;
color: rgba(172, 213, 229, 1);
}
#divStat a,
.statInfo a {
color: rgba(172, 213, 229, 1);
}
#curRep .a-icon:hover,
#divStat .a-icon:hover,
#divStat a:hover,
.statInfo .a-icon:hover,
.statInfo a:hover {
color: rgba(221, 246, 255, 1);
}
#curRep {
vertical-align: middle;
text-align: left;
}
#curRep .mega-icon {
font-size: 24px;
width: 24px;
height: inherit;
position: relative;
}
#curRep .mini-icon-link:before,
#curRep .mega-icon-public-repo:before {
position: absolute;
top: -16px;
}
#userInfo,
.userInfo {
right: -2px;
top: -2px;
padding: 7px 7px 5px 5px;
z-index: 52;
}
#userInfo ul,
.userInfo ul {
white-space: nowrap;
-webkit-transition: all .4s;
-moz-transition: all .4s;
-o-transition: all .4s;
transition: all .4s;
max-width: 0;
max-height: 0;
}
#userInfo img,
.userInfo img {
-webkit-transition: all .5s ease-in-out .4s;
-moz-transition: all .5s ease-in-out .4s;
-o-transition: all .5s ease-in-out .4s;
transition: all .5s ease-in-out .4s;
width : 48px;
height : auto;
}
#userInfo.open img,
#userInfo:hover img,
.userInfo.open img,
.userInfo:hover img {
-webkit-transition: all .5s;
-moz-transition: all .5s;
-o-transition: all .5s;
transition: all .5s;
margin-right: 10px;
width : 96px;
height : auto;
}
#userInfo.open ul,
#userInfo:hover ul,
.userInfo.open ul,
.userInfo:hover ul {
-webkit-transition: all .5s ease-in-out .5s;
-moz-transition: all .5s ease-in-out .5s;
-o-transition: all .5s ease-in-out .5s;
transition: all .5s ease-in-out .5s;
max-width: 960px;
max-height: 1280px;
}
/** stepbar */
.steps {
list-style: none;
margin: 0;
}
.steps > li {
display: block;
float: left;
position: relative;
padding: 4px;
border: 1px solid white;
border-right-style: dotted;
border-left-style: dotted;
margin-right: 1em;
background: #50617F;
padding-right: 2px;
margin-left: -17px;
padding-left: 24px;
/*text-align: right;*/
box-shadow: 2px 4px 5px rgba(0, 0, 0, .5);
}
.steps > li .sub {
text-align: left;
display: block;
overflow: hidden;
margin-left: -22px;
}
.steps > li:first-child .sub {
margin-left: 0;
}
.steps > li .sub {
max-height: 0;
max-width: 0;
-webkit-transition: max-height .7s ease-in-out .2s, max-width .2s ease-in-out .9s;
-moz-transition: max-height .7s ease-in-out .2s, max-width .2s ease-in-out .9s;
-o-transition: max-height .7s ease-in-out .2s, max-width .2s ease-in-out .9s;
transition: max-height .7s ease-in-out .2s, max-width .2s ease-in-out .9s;
}
.steps > li:hover .sub {
max-height: 960px;
max-width: 960px;
-webkit-transition: max-height .5s ease-in-out .3s, max-width .2s ease-in-out .1s;
-moz-transition: max-height .5s ease-in-out .3s, max-width .2s ease-in-out .1s;
-o-transition: max-height .5s ease-in-out .3s, max-width .2s ease-in-out .1s;
transition: max-height .5s ease-in-out .3s, max-width .2s ease-in-out .1s;
}
.steps > li:first-child {
border-radius: 5px 0 0 5px;
border-left: 1px solid #ffffff;
margin-left: 0;
padding-left: 4px;
}
.steps > li:hover {
border-right-style: solid;
border-left-style: solid;
}
.steps > li:after,
.steps > li:before {
width: 0;
height: 0;
content: "";
display: inline-block;
position: absolute;
}
.steps > li:after {
border: 1.248em solid transparent;
border-left-color: #ffffff;
top: -0.05em;
right: -2.45em;
z-index: 0;
}
.steps > li:before {
border: 1.13em solid transparent;
border-left-color: #50617F;
top: .02em;
right: -2.25em;
z-index: 1;
}
.steps.sfirst > li:not(.first) {
border-color: #ccc;
background: #858689;
}
.steps.sfirst > li:not(.first):after {
border-left-color: #ccc;
}
.steps.sfirst > li:not(.first):before {
border-left-color: #858689;
}
.steps.ssecond > li.third {
border-color: #ccc;
background: #858689;
}
.steps.ssecond > li.third:after {
border-left-color: #ccc;
}
.steps.ssecond > li.third:before {
border-left-color: #858689;
}
.steps > li > label {
vertical-align: middle;
}
.sub > div {
padding: 5px;
}
.sub blockquote {
padding: 3px;
margin: 2px 0;
background: rgba(255, 252, 196, .6);
border-left: 2px solid rgba(255, 252, 196, 1);
font-style: italic;
color: rgba(255, 252, 196, 1);
text-shadow: 0 1px 2px rgba(0, 0, 0, .5);
}
blockquote.green {
/*background: rgba(161, 237, 144, .3);
color: rgb(198, 244, 188);
border-left: 2px solid rgb(198, 244, 188);*/
background: rgba(198, 245, 188, .6);
color: rgb(31, 166, 31);
border-left: 2px solid rgb(31, 166, 31);
}
/** end stepbar */
.barLang circle,
.barLang path {
}
.barLang path {
fill: none;
stroke-width: 1px;
}
.barLang text {
pointer-events: none;
text-shadow : 0 0 3px rgba(0, 0, 0, 1);
}
.barLang .barSelect {
stroke: #000;
stroke-opacity: 0;
stroke-width: 1px;
fill: #f9f9f9;
fill-opacity: 0;
-webkit-transition: all 1.5s;
-moz-transition: all 1.5s;
-o-transition: all 1.5s;
transition: all 1.5s;
}
.barLang:hover .barSelect {
fill-opacity: .6;
stroke-opacity: .6;
-webkit-transition: all .5s;
-moz-transition: all .5s;
-o-transition: all .5s;
transition: all .5s;
}
.field {
padding: 3px;
}
.setting {
list-style: none;
text-shadow: 0 1px 2px rgba(0, 0, 0, .5);
}
.setting input {
padding: 0;
margin: 0;
}
.setting h1 {
color: rgba(0, 0, 0, .8);
text-shadow: 0 1px 1px rgba(255, 255, 255, .5);
}
.setting > li {
border: 1px dotted rgba(255, 255, 255, .5);
background: rgba(255, 255, 255, .2);
}
.setting > li .group {
list-style: none;
vertical-align: middle;
}
.group > li {
display: inline-block;
}
.com-mess {
font-size: 11pt;
font-family: Verdana,serif;
fill: #ffffff;
fill-opacity: .3;
}
.mono {
font-family: monospace;
font-size: 10pt;
}
#visBtnResume .mini-icon-history {
position: relative;
height: 0;
}
#visBtnResume .mini-icon-history:before {
position: absolute;
top: -12px;
left: 0;
}
.gtLeg, .gttLeg {
fill : #f9f9f9;
text-shadow: 0 1px 2px rgba(0, 0, 0, .5);
}
/**
* User: ArtZub
* Date: 15.01.13
* Time: 1:34
*/
'use strict';
var PIdiv2 = Math.PI / 2,
smallRad = PIdiv2 * (1 / 15),
TT_PAD = 8
;
var colors = {
additions : "#ddffdd",
deletions : "#ffdddd",
changes : "#FFF1DD",
center : "#FF6600",
stroked : "#f9f9f9",
addedFile : "#A5EC6E",
modifiedFile : "#FFB877",
deletedFile : "#FF77B5",
decolor : "#888888"
};
function toRgba(color, a) {
color = d3.rgb(color);
return "rgba(" + [color.r, color.g, color.b, a || 1] + ")";
}
var vis = {
sC : function(a, b) {
return d3.ascending(b.date, a.date);
},
mtt : function(d) {
if (toolTip) {
var e = d3.event;
if (arguments.length > 3)
e = arguments[3];
toolTip
.style("top", e.pageY > h / 2 ? (e.pageY - toolTip.node().clientHeight - TT_PAD) + "px" : (e.pageY + TT_PAD) + "px")
.style("left", e.pageX > w / 2 ? (e.pageX - toolTip.node().clientWidth - TT_PAD) + "px" : (e.pageX + TT_PAD) + "px")
;
}
}
};
function initGraphics(svg) {
vis.layers = (function(data) {
var ls = { _data : data };
svg.selectAll("g.layer")
.data(data, function(d) {return d.name})
.enter()
.append("g")
.each(function(d) {
ls[d.name] = d3.select(this).attr("class", "layer").attr("width", w).attr("height", h);
ls[d.name].getOrder = function() {
return d.order;
return this;
};
ls[d.name].toFront = function() {
d.order &&
vis.layers.ordering(this, 0);
return this;
};
ls[d.name].hide = function() {
ls[d.name].visible = false;
this.style("display", "none");
return this;
};
ls[d.name].show = function() {
ls[d.name].visible = true;
this.style("display", null);
return this;
};
ls[d.name].visible = true;
});
return ls;
})([
{name : "repo", order : 2},
{name : "stat", order : 1},
{name : "show", order : 0}
]);
vis.layers.ordering = function(layer, order) {
function s(a, b) {
return d3.ascending(b.order, a.order);
}
var _d = (layer instanceof Array || layer instanceof Object ? layer : this[layer]);
_d = _d ? (_d instanceof Array ? _d.datum() : _d) : null;
if (_d) {
this._data.forEach(function(d) {
_d != d && d.order >= order && d.order++;
});
_d.order = order;
svg.selectAll("g.layer").sort(s);
}
return this;
};
vis.resources = {
};
vis.inited = true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment