Resolved Conflicts
Signed-off-by: Konrad <konrad@kola-entertainments.de>
This commit is contained in:
parent
1710ea49a0
commit
d59aee92e3
|
|
@ -744,6 +744,23 @@ issues.dependency.setting = Issues can have dependencies
|
||||||
issues.dependency.add_error_same_issue = You cannot make an issue depend on itself!
|
issues.dependency.add_error_same_issue = You cannot make an issue depend on itself!
|
||||||
issues.dependency.add_error_dep_not_exist = Dependend issue does not exist!
|
issues.dependency.add_error_dep_not_exist = Dependend issue does not exist!
|
||||||
issues.dependency.add_error_dep_exists = Dependency already exists!
|
issues.dependency.add_error_dep_exists = Dependency already exists!
|
||||||
|
issues.tracker = Time tracker
|
||||||
|
issues.start_tracking_short = Start
|
||||||
|
issues.start_tracking = Start time tracking
|
||||||
|
issues.start_tracking_history = `started working %s`
|
||||||
|
issues.tracking_already_started = `You have already started time tracking on this <a href="%s">issue</a>!`
|
||||||
|
issues.stop_tracking = Stop
|
||||||
|
issues.stop_tracking_history = `stopped working %s`
|
||||||
|
issues.add_time = Add time manually
|
||||||
|
issues.add_time_short = Add
|
||||||
|
issues.add_time_cancel = Cancel
|
||||||
|
issues.add_time_history = `added spent time %s`
|
||||||
|
issues.add_time_hours = Hours
|
||||||
|
issues.add_time_minutes = Minutes
|
||||||
|
issues.add_time_sum_to_small = No time was entered
|
||||||
|
issues.cancel_tracking = Cancel
|
||||||
|
issues.cancel_tracking_history = `cancelled time tracking %s`
|
||||||
|
issues.time_spent_total = Total time spent
|
||||||
|
|
||||||
|
|
||||||
pulls.desc = Pulls management your code review and merge requests
|
pulls.desc = Pulls management your code review and merge requests
|
||||||
|
|
|
||||||
|
|
@ -1823,12 +1823,45 @@ function cancelStopwatch() {
|
||||||
$("#cancel_stopwatch_form").submit();
|
$("#cancel_stopwatch_form").submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
function showAddDependencyModal() {
|
function timeAddManual() {
|
||||||
$('.tiny.modal')
|
$('.mini.modal')
|
||||||
.modal({
|
.modal({
|
||||||
duration: 200,
|
duration: 200,
|
||||||
onApprove: function() {
|
onApprove: function() {
|
||||||
$('#addDependencyForm').submit();
|
$('#add_time_manual_form').submit();
|
||||||
|
}
|
||||||
|
}).modal('show')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleStopwatch() {
|
||||||
|
$("#toggle_stopwatch_form").submit();
|
||||||
|
}
|
||||||
|
function cancelStopwatch() {
|
||||||
|
$("#cancel_stopwatch_form").submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteDependencyModal(id, type) {
|
||||||
|
$('.remove-dependency')
|
||||||
|
.modal({
|
||||||
|
closable: false,
|
||||||
|
duration: 200,
|
||||||
|
onApprove: function () {
|
||||||
|
$('#removeDependencyID').val(id);
|
||||||
|
$('#dependencyType').val(type);
|
||||||
|
$('#removeDependencyForm').submit();
|
||||||
|
}
|
||||||
|
}).modal('show')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showAddDependencyModal() {
|
||||||
|
$('.add-dependency')
|
||||||
|
.modal({
|
||||||
|
duration: 200,
|
||||||
|
onApprove: function() {
|
||||||
|
$('#addDependencyForm').submit();
|
||||||
|
|
||||||
}
|
}
|
||||||
}).modal('show')
|
}).modal('show')
|
||||||
;
|
;
|
||||||
|
|
|
||||||
45
public/vendor/plugins/autolink/autolink.js
vendored
45
public/vendor/plugins/autolink/autolink.js
vendored
|
|
@ -1,45 +0,0 @@
|
||||||
(function () {
|
|
||||||
var re = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-]*)?\??(?:[\-\+:=&;%@\.\w]*)#?(?:[\.\!\/\\\w]*))?)/g;
|
|
||||||
function textNodesUnder(node) {
|
|
||||||
var textNodes = [];
|
|
||||||
if(typeof document.createTreeWalker === 'function') {
|
|
||||||
// Efficient TreeWalker
|
|
||||||
var currentNode, walker;
|
|
||||||
walker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT, null, false);
|
|
||||||
while(currentNode = walker.nextNode()) {
|
|
||||||
textNodes.push(currentNode);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Less efficient recursive function
|
|
||||||
for(node = node.firstChild; node; node = node.nextSibling) {
|
|
||||||
if(node.nodeType === 3) {
|
|
||||||
textNodes.push(node);
|
|
||||||
} else {
|
|
||||||
textNodes = textNodes.concat(textNodesUnder(node));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return textNodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
function processNode(node) {
|
|
||||||
re.lastIndex = 0;
|
|
||||||
var results = re.exec(node.textContent);
|
|
||||||
if(results !== null) {
|
|
||||||
if($(node).parents().filter('code').length === 0) {
|
|
||||||
$(node).replaceWith(
|
|
||||||
$('<span />').html(
|
|
||||||
node.nodeValue.replace(re, '<a href="$1">$1</a>')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jQuery.fn.autolink = function () {
|
|
||||||
this.each(function () {
|
|
||||||
textNodesUnder(this).forEach(processNode);
|
|
||||||
});
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
401
public/vendor/plugins/gitgraph/gitgraph.js
vendored
401
public/vendor/plugins/gitgraph/gitgraph.js
vendored
|
|
@ -1,401 +0,0 @@
|
||||||
/*
|
|
||||||
* @license magnet:?xt=urn:btih:c80d50af7d3db9be66a4d0a86db0286e4fd33292&dn=bsd-3-clause.txt BSD 3-Clause
|
|
||||||
* Copyright (c) 2011, Terrence Lee <kill889@gmail.com>
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the <organization> nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
var gitGraph = function (canvas, rawGraphList, config) {
|
|
||||||
if (!canvas.getContext) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof config === "undefined") {
|
|
||||||
config = {
|
|
||||||
unitSize: 20,
|
|
||||||
lineWidth: 3,
|
|
||||||
nodeRadius: 4
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var flows = [];
|
|
||||||
var graphList = [];
|
|
||||||
|
|
||||||
var ctx = canvas.getContext("2d");
|
|
||||||
|
|
||||||
var init = function () {
|
|
||||||
var maxWidth = 0;
|
|
||||||
var i;
|
|
||||||
var l = rawGraphList.length;
|
|
||||||
var row;
|
|
||||||
var midStr;
|
|
||||||
|
|
||||||
for (i = 0; i < l; i++) {
|
|
||||||
midStr = rawGraphList[i].replace(/\s+/g, " ").replace(/^\s+|\s+$/g, "");
|
|
||||||
|
|
||||||
maxWidth = Math.max(midStr.replace(/(\_|\s)/g, "").length, maxWidth);
|
|
||||||
|
|
||||||
row = midStr.split("");
|
|
||||||
|
|
||||||
graphList.unshift(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas.width = maxWidth * config.unitSize;
|
|
||||||
canvas.height = graphList.length * config.unitSize;
|
|
||||||
|
|
||||||
ctx.lineWidth = config.lineWidth;
|
|
||||||
ctx.lineJoin = "round";
|
|
||||||
ctx.lineCap = "round";
|
|
||||||
};
|
|
||||||
|
|
||||||
var genRandomStr = function () {
|
|
||||||
var chars = "0123456789ABCDEF";
|
|
||||||
var stringLength = 6;
|
|
||||||
var randomString = '', rnum, i;
|
|
||||||
for (i = 0; i < stringLength; i++) {
|
|
||||||
rnum = Math.floor(Math.random() * chars.length);
|
|
||||||
randomString += chars.substring(rnum, rnum + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return randomString;
|
|
||||||
};
|
|
||||||
|
|
||||||
var findFlow = function (id) {
|
|
||||||
var i = flows.length;
|
|
||||||
|
|
||||||
while (i-- && flows[i].id !== id) {}
|
|
||||||
|
|
||||||
return i;
|
|
||||||
};
|
|
||||||
|
|
||||||
var findColomn = function (symbol, row) {
|
|
||||||
var i = row.length;
|
|
||||||
|
|
||||||
while (i-- && row[i] !== symbol) {}
|
|
||||||
|
|
||||||
return i;
|
|
||||||
};
|
|
||||||
|
|
||||||
var findBranchOut = function (row) {
|
|
||||||
if (!row) {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
var i = row.length;
|
|
||||||
|
|
||||||
while (i-- &&
|
|
||||||
!(row[i - 1] && row[i] === "/" && row[i - 1] === "|") &&
|
|
||||||
!(row[i - 2] && row[i] === "_" && row[i - 2] === "|")) {}
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
var genNewFlow = function () {
|
|
||||||
var newId;
|
|
||||||
|
|
||||||
do {
|
|
||||||
newId = genRandomStr();
|
|
||||||
} while (findFlow(newId) !== -1);
|
|
||||||
|
|
||||||
return {id:newId, color:"#" + newId};
|
|
||||||
};
|
|
||||||
|
|
||||||
//draw method
|
|
||||||
var drawLineRight = function (x, y, color) {
|
|
||||||
ctx.strokeStyle = color;
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(x, y + config.unitSize / 2);
|
|
||||||
ctx.lineTo(x + config.unitSize, y + config.unitSize / 2);
|
|
||||||
ctx.stroke();
|
|
||||||
};
|
|
||||||
|
|
||||||
var drawLineUp = function (x, y, color) {
|
|
||||||
ctx.strokeStyle = color;
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(x, y + config.unitSize / 2);
|
|
||||||
ctx.lineTo(x, y - config.unitSize / 2);
|
|
||||||
ctx.stroke();
|
|
||||||
};
|
|
||||||
|
|
||||||
var drawNode = function (x, y, color) {
|
|
||||||
ctx.strokeStyle = color;
|
|
||||||
|
|
||||||
drawLineUp(x, y, color);
|
|
||||||
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(x, y, config.nodeRadius, 0, Math.PI * 2, true);
|
|
||||||
ctx.fill();
|
|
||||||
};
|
|
||||||
|
|
||||||
var drawLineIn = function (x, y, color) {
|
|
||||||
ctx.strokeStyle = color;
|
|
||||||
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(x + config.unitSize, y + config.unitSize / 2);
|
|
||||||
ctx.lineTo(x, y - config.unitSize / 2);
|
|
||||||
ctx.stroke();
|
|
||||||
};
|
|
||||||
|
|
||||||
var drawLineOut = function (x, y, color) {
|
|
||||||
ctx.strokeStyle = color;
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(x, y + config.unitSize / 2);
|
|
||||||
ctx.lineTo(x + config.unitSize, y - config.unitSize / 2);
|
|
||||||
ctx.stroke();
|
|
||||||
};
|
|
||||||
|
|
||||||
var draw = function (graphList) {
|
|
||||||
var colomn, colomnIndex, prevColomn, condenseIndex;
|
|
||||||
var x, y;
|
|
||||||
var color;
|
|
||||||
var nodePos, outPos;
|
|
||||||
var tempFlow;
|
|
||||||
var prevRowLength = 0;
|
|
||||||
var flowSwapPos = -1;
|
|
||||||
var lastLinePos;
|
|
||||||
var i, k, l;
|
|
||||||
var condenseCurrentLength, condensePrevLength = 0, condenseNextLength = 0;
|
|
||||||
|
|
||||||
var inlineIntersect = false;
|
|
||||||
|
|
||||||
//initiate for first row
|
|
||||||
for (i = 0, l = graphList[0].length; i < l; i++) {
|
|
||||||
if (graphList[0][i] !== "_" && graphList[0][i] !== " ") {
|
|
||||||
flows.push(genNewFlow());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
y = canvas.height - config.unitSize * 0.5;
|
|
||||||
|
|
||||||
//iterate
|
|
||||||
for (i = 0, l = graphList.length; i < l; i++) {
|
|
||||||
x = config.unitSize * 0.5;
|
|
||||||
|
|
||||||
currentRow = graphList[i];
|
|
||||||
nextRow = graphList[i + 1];
|
|
||||||
prevRow = graphList[i - 1];
|
|
||||||
|
|
||||||
flowSwapPos = -1;
|
|
||||||
|
|
||||||
condenseCurrentLength = currentRow.filter(function (val) {
|
|
||||||
return (val !== " " && val !== "_")
|
|
||||||
}).length;
|
|
||||||
|
|
||||||
if (nextRow) {
|
|
||||||
condenseNextLength = nextRow.filter(function (val) {
|
|
||||||
return (val !== " " && val !== "_")
|
|
||||||
}).length;
|
|
||||||
} else {
|
|
||||||
condenseNextLength = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//pre process begin
|
|
||||||
//use last row for analysing
|
|
||||||
if (prevRow) {
|
|
||||||
if (!inlineIntersect) {
|
|
||||||
//intersect might happen
|
|
||||||
for (colomnIndex = 0; colomnIndex < prevRowLength; colomnIndex++) {
|
|
||||||
if (prevRow[colomnIndex + 1] &&
|
|
||||||
(prevRow[colomnIndex] === "/" && prevRow[colomnIndex + 1] === "|") ||
|
|
||||||
((prevRow[colomnIndex] === "_" && prevRow[colomnIndex + 1] === "|") &&
|
|
||||||
(prevRow[colomnIndex + 2] === "/"))) {
|
|
||||||
|
|
||||||
flowSwapPos = colomnIndex;
|
|
||||||
|
|
||||||
//swap two flow
|
|
||||||
tempFlow = {id:flows[flowSwapPos].id, color:flows[flowSwapPos].color};
|
|
||||||
|
|
||||||
flows[flowSwapPos].id = flows[flowSwapPos + 1].id;
|
|
||||||
flows[flowSwapPos].color = flows[flowSwapPos + 1].color;
|
|
||||||
|
|
||||||
flows[flowSwapPos + 1].id = tempFlow.id;
|
|
||||||
flows[flowSwapPos + 1].color = tempFlow.color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (condensePrevLength < condenseCurrentLength &&
|
|
||||||
((nodePos = findColomn("*", currentRow)) !== -1 &&
|
|
||||||
(findColomn("_", currentRow) === -1))) {
|
|
||||||
|
|
||||||
flows.splice(nodePos - 1, 0, genNewFlow());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prevRowLength > currentRow.length &&
|
|
||||||
(nodePos = findColomn("*", prevRow)) !== -1) {
|
|
||||||
|
|
||||||
if (findColomn("_", currentRow) === -1 &&
|
|
||||||
findColomn("/", currentRow) === -1 &&
|
|
||||||
findColomn("\\", currentRow) === -1) {
|
|
||||||
|
|
||||||
flows.splice(nodePos + 1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} //done with the previous row
|
|
||||||
|
|
||||||
prevRowLength = currentRow.length; //store for next round
|
|
||||||
colomnIndex = 0; //reset index
|
|
||||||
condenseIndex = 0;
|
|
||||||
condensePrevLength = 0;
|
|
||||||
while (colomnIndex < currentRow.length) {
|
|
||||||
colomn = currentRow[colomnIndex];
|
|
||||||
|
|
||||||
if (colomn !== " " && colomn !== "_") {
|
|
||||||
++condensePrevLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (colomn === " " &&
|
|
||||||
currentRow[colomnIndex + 1] &&
|
|
||||||
currentRow[colomnIndex + 1] === "_" &&
|
|
||||||
currentRow[colomnIndex - 1] &&
|
|
||||||
currentRow[colomnIndex - 1] === "|") {
|
|
||||||
|
|
||||||
currentRow.splice(colomnIndex, 1);
|
|
||||||
|
|
||||||
currentRow[colomnIndex] = "/";
|
|
||||||
colomn = "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
//create new flow only when no intersetc happened
|
|
||||||
if (flowSwapPos === -1 &&
|
|
||||||
colomn === "/" &&
|
|
||||||
currentRow[colomnIndex - 1] &&
|
|
||||||
currentRow[colomnIndex - 1] === "|") {
|
|
||||||
|
|
||||||
flows.splice(condenseIndex, 0, genNewFlow());
|
|
||||||
}
|
|
||||||
|
|
||||||
//change \ and / to | when it's in the last position of the whole row
|
|
||||||
if (colomn === "/" || colomn === "\\") {
|
|
||||||
if (!(colomn === "/" && findBranchOut(nextRow) === -1)) {
|
|
||||||
if ((lastLinePos = Math.max(findColomn("|", currentRow),
|
|
||||||
findColomn("*", currentRow))) !== -1 &&
|
|
||||||
(lastLinePos < colomnIndex - 1)) {
|
|
||||||
|
|
||||||
while (currentRow[++lastLinePos] === " ") {}
|
|
||||||
|
|
||||||
if (lastLinePos === colomnIndex) {
|
|
||||||
currentRow[colomnIndex] = "|";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (colomn === "*" &&
|
|
||||||
prevRow &&
|
|
||||||
prevRow[condenseIndex + 1] === "\\") {
|
|
||||||
flows.splice(condenseIndex + 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (colomn !== " ") {
|
|
||||||
++condenseIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
++colomnIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
condenseCurrentLength = currentRow.filter(function (val) {
|
|
||||||
return (val !== " " && val !== "_")
|
|
||||||
}).length;
|
|
||||||
|
|
||||||
//do some clean up
|
|
||||||
if (flows.length > condenseCurrentLength) {
|
|
||||||
flows.splice(condenseCurrentLength, flows.length - condenseCurrentLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
colomnIndex = 0;
|
|
||||||
|
|
||||||
//a little inline analysis and draw process
|
|
||||||
while (colomnIndex < currentRow.length) {
|
|
||||||
colomn = currentRow[colomnIndex];
|
|
||||||
prevColomn = currentRow[colomnIndex - 1];
|
|
||||||
|
|
||||||
if (currentRow[colomnIndex] === " ") {
|
|
||||||
currentRow.splice(colomnIndex, 1);
|
|
||||||
x += config.unitSize;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//inline interset
|
|
||||||
if ((colomn === "_" || colomn === "/") &&
|
|
||||||
currentRow[colomnIndex - 1] === "|" &&
|
|
||||||
currentRow[colomnIndex - 2] === "_") {
|
|
||||||
|
|
||||||
inlineIntersect = true;
|
|
||||||
|
|
||||||
tempFlow = flows.splice(colomnIndex - 2, 1)[0];
|
|
||||||
flows.splice(colomnIndex - 1, 0, tempFlow);
|
|
||||||
currentRow.splice(colomnIndex - 2, 1);
|
|
||||||
|
|
||||||
colomnIndex = colomnIndex - 1;
|
|
||||||
} else {
|
|
||||||
inlineIntersect = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
color = flows[colomnIndex].color;
|
|
||||||
|
|
||||||
switch (colomn) {
|
|
||||||
case "_" :
|
|
||||||
drawLineRight(x, y, color);
|
|
||||||
|
|
||||||
x += config.unitSize;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "*" :
|
|
||||||
drawNode(x, y, color);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "|" :
|
|
||||||
drawLineUp(x, y, color);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "/" :
|
|
||||||
if (prevColomn &&
|
|
||||||
(prevColomn === "/" ||
|
|
||||||
prevColomn === " ")) {
|
|
||||||
x -= config.unitSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
drawLineOut(x, y, color);
|
|
||||||
|
|
||||||
x += config.unitSize;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "\\" :
|
|
||||||
drawLineIn(x, y, color);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
++colomnIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
y -= config.unitSize;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
init();
|
|
||||||
draw(graphList);
|
|
||||||
};
|
|
||||||
// @end-license
|
|
||||||
|
|
@ -500,6 +500,19 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
m.Combo("/comments").Post(bindIgnErr(auth.CreateCommentForm{}), repo.NewComment)
|
m.Combo("/comments").Post(bindIgnErr(auth.CreateCommentForm{}), repo.NewComment)
|
||||||
|
m.Group("/times", func() {
|
||||||
|
m.Post("/add", bindIgnErr(auth.AddTimeManuallyForm{}), repo.AddTimeManually)
|
||||||
|
m.Group("/stopwatch", func() {
|
||||||
|
m.Post("/toggle", repo.IssueStopwatch)
|
||||||
|
m.Post("/cancel", repo.CancelStopwatch)
|
||||||
|
})
|
||||||
|
|
||||||
|
}, func(ctx *context.Context) {
|
||||||
|
if !ctx.Repo.CanUseTimetracker(repo.GetActionIssue(ctx), ctx.User) {
|
||||||
|
ctx.Handle(404, ctx.Req.RequestURI, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
m.Post("/labels", repo.UpdateIssueLabel, reqRepoWriter)
|
m.Post("/labels", repo.UpdateIssueLabel, reqRepoWriter)
|
||||||
|
|
@ -613,7 +626,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||||
m.Get("/*", repo.WikiRaw)
|
m.Get("/*", repo.WikiRaw)
|
||||||
}, repo.MustEnableWiki, context.CheckUnit(models.UnitTypeWiki), context.CheckUnit(models.UnitTypeWiki))
|
}, repo.MustEnableWiki, context.CheckUnit(models.UnitTypeWiki), context.CheckUnit(models.UnitTypeWiki))
|
||||||
|
|
||||||
m.Get("/archive/*", repo.MustBeNotBare, repo.Download, context.CheckUnit(models.UnitTypeCode))
|
m.Get("/archive/*", repo.MustBeNotBare, context.CheckUnit(models.UnitTypeCode), repo.Download)
|
||||||
|
|
||||||
m.Group("/pulls/:index", func() {
|
m.Group("/pulls/:index", func() {
|
||||||
m.Get("/commits", context.RepoRef(), repo.ViewPullCommits)
|
m.Get("/commits", context.RepoRef(), repo.ViewPullCommits)
|
||||||
|
|
@ -633,10 +646,11 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||||
m.Get("/src/*", repo.SetEditorconfigIfExists, repo.Home)
|
m.Get("/src/*", repo.SetEditorconfigIfExists, repo.Home)
|
||||||
m.Get("/forks", repo.Forks)
|
m.Get("/forks", repo.Forks)
|
||||||
}, context.RepoRef(), context.CheckUnit(models.UnitTypeCode))
|
}, context.RepoRef(), context.CheckUnit(models.UnitTypeCode))
|
||||||
m.Get("/commit/:sha([a-f0-9]{7,40})\\.:ext(patch|diff)", repo.MustBeNotBare, repo.RawDiff, context.CheckUnit(models.UnitTypeCode))
|
m.Get("/commit/:sha([a-f0-9]{7,40})\\.:ext(patch|diff)",
|
||||||
|
repo.MustBeNotBare, context.CheckUnit(models.UnitTypeCode), repo.RawDiff)
|
||||||
|
|
||||||
m.Get("/compare/:before([a-z0-9]{40})\\.\\.\\.:after([a-z0-9]{40})", repo.SetEditorconfigIfExists,
|
m.Get("/compare/:before([a-z0-9]{40})\\.\\.\\.:after([a-z0-9]{40})", repo.SetEditorconfigIfExists,
|
||||||
repo.SetDiffViewStyle, repo.MustBeNotBare, repo.CompareDiff, context.CheckUnit(models.UnitTypeCode))
|
repo.SetDiffViewStyle, repo.MustBeNotBare, context.CheckUnit(models.UnitTypeCode), repo.CompareDiff)
|
||||||
}, ignSignIn, context.RepoAssignment(), context.UnitTypes(), context.LoadRepoUnits())
|
}, ignSignIn, context.RepoAssignment(), context.UnitTypes(), context.LoadRepoUnits())
|
||||||
m.Group("/:username/:reponame", func() {
|
m.Group("/:username/:reponame", func() {
|
||||||
m.Get("/stars", repo.Stars)
|
m.Get("/stars", repo.Stars)
|
||||||
|
|
|
||||||
284
vendor/github.com/go-xorm/xorm/cache_lru.go
generated
vendored
284
vendor/github.com/go-xorm/xorm/cache_lru.go
generated
vendored
|
|
@ -1,284 +0,0 @@
|
||||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package xorm
|
|
||||||
|
|
||||||
import (
|
|
||||||
"container/list"
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/go-xorm/core"
|
|
||||||
)
|
|
||||||
|
|
||||||
// LRUCacher implments cache object facilities
|
|
||||||
type LRUCacher struct {
|
|
||||||
idList *list.List
|
|
||||||
sqlList *list.List
|
|
||||||
idIndex map[string]map[string]*list.Element
|
|
||||||
sqlIndex map[string]map[string]*list.Element
|
|
||||||
store core.CacheStore
|
|
||||||
mutex sync.Mutex
|
|
||||||
MaxElementSize int
|
|
||||||
Expired time.Duration
|
|
||||||
GcInterval time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewLRUCacher creates a cacher
|
|
||||||
func NewLRUCacher(store core.CacheStore, maxElementSize int) *LRUCacher {
|
|
||||||
return NewLRUCacher2(store, 3600*time.Second, maxElementSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewLRUCacher2 creates a cache include different params
|
|
||||||
func NewLRUCacher2(store core.CacheStore, expired time.Duration, maxElementSize int) *LRUCacher {
|
|
||||||
cacher := &LRUCacher{store: store, idList: list.New(),
|
|
||||||
sqlList: list.New(), Expired: expired,
|
|
||||||
GcInterval: core.CacheGcInterval, MaxElementSize: maxElementSize,
|
|
||||||
sqlIndex: make(map[string]map[string]*list.Element),
|
|
||||||
idIndex: make(map[string]map[string]*list.Element),
|
|
||||||
}
|
|
||||||
cacher.RunGC()
|
|
||||||
return cacher
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunGC run once every m.GcInterval
|
|
||||||
func (m *LRUCacher) RunGC() {
|
|
||||||
time.AfterFunc(m.GcInterval, func() {
|
|
||||||
m.RunGC()
|
|
||||||
m.GC()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// GC check ids lit and sql list to remove all element expired
|
|
||||||
func (m *LRUCacher) GC() {
|
|
||||||
m.mutex.Lock()
|
|
||||||
defer m.mutex.Unlock()
|
|
||||||
var removedNum int
|
|
||||||
for e := m.idList.Front(); e != nil; {
|
|
||||||
if removedNum <= core.CacheGcMaxRemoved &&
|
|
||||||
time.Now().Sub(e.Value.(*idNode).lastVisit) > m.Expired {
|
|
||||||
removedNum++
|
|
||||||
next := e.Next()
|
|
||||||
node := e.Value.(*idNode)
|
|
||||||
m.delBean(node.tbName, node.id)
|
|
||||||
e = next
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
removedNum = 0
|
|
||||||
for e := m.sqlList.Front(); e != nil; {
|
|
||||||
if removedNum <= core.CacheGcMaxRemoved &&
|
|
||||||
time.Now().Sub(e.Value.(*sqlNode).lastVisit) > m.Expired {
|
|
||||||
removedNum++
|
|
||||||
next := e.Next()
|
|
||||||
node := e.Value.(*sqlNode)
|
|
||||||
m.delIds(node.tbName, node.sql)
|
|
||||||
e = next
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetIds returns all bean's ids according to sql and parameter from cache
|
|
||||||
func (m *LRUCacher) GetIds(tableName, sql string) interface{} {
|
|
||||||
m.mutex.Lock()
|
|
||||||
defer m.mutex.Unlock()
|
|
||||||
if _, ok := m.sqlIndex[tableName]; !ok {
|
|
||||||
m.sqlIndex[tableName] = make(map[string]*list.Element)
|
|
||||||
}
|
|
||||||
if v, err := m.store.Get(sql); err == nil {
|
|
||||||
if el, ok := m.sqlIndex[tableName][sql]; !ok {
|
|
||||||
el = m.sqlList.PushBack(newSQLNode(tableName, sql))
|
|
||||||
m.sqlIndex[tableName][sql] = el
|
|
||||||
} else {
|
|
||||||
lastTime := el.Value.(*sqlNode).lastVisit
|
|
||||||
// if expired, remove the node and return nil
|
|
||||||
if time.Now().Sub(lastTime) > m.Expired {
|
|
||||||
m.delIds(tableName, sql)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
m.sqlList.MoveToBack(el)
|
|
||||||
el.Value.(*sqlNode).lastVisit = time.Now()
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
m.delIds(tableName, sql)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetBean returns bean according tableName and id from cache
|
|
||||||
func (m *LRUCacher) GetBean(tableName string, id string) interface{} {
|
|
||||||
m.mutex.Lock()
|
|
||||||
defer m.mutex.Unlock()
|
|
||||||
if _, ok := m.idIndex[tableName]; !ok {
|
|
||||||
m.idIndex[tableName] = make(map[string]*list.Element)
|
|
||||||
}
|
|
||||||
tid := genID(tableName, id)
|
|
||||||
if v, err := m.store.Get(tid); err == nil {
|
|
||||||
if el, ok := m.idIndex[tableName][id]; ok {
|
|
||||||
lastTime := el.Value.(*idNode).lastVisit
|
|
||||||
// if expired, remove the node and return nil
|
|
||||||
if time.Now().Sub(lastTime) > m.Expired {
|
|
||||||
m.delBean(tableName, id)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
m.idList.MoveToBack(el)
|
|
||||||
el.Value.(*idNode).lastVisit = time.Now()
|
|
||||||
} else {
|
|
||||||
el = m.idList.PushBack(newIDNode(tableName, id))
|
|
||||||
m.idIndex[tableName][id] = el
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// store bean is not exist, then remove memory's index
|
|
||||||
m.delBean(tableName, id)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// clearIds clears all sql-ids mapping on table tableName from cache
|
|
||||||
func (m *LRUCacher) clearIds(tableName string) {
|
|
||||||
if tis, ok := m.sqlIndex[tableName]; ok {
|
|
||||||
for sql, v := range tis {
|
|
||||||
m.sqlList.Remove(v)
|
|
||||||
m.store.Del(sql)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m.sqlIndex[tableName] = make(map[string]*list.Element)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClearIds clears all sql-ids mapping on table tableName from cache
|
|
||||||
func (m *LRUCacher) ClearIds(tableName string) {
|
|
||||||
m.mutex.Lock()
|
|
||||||
m.clearIds(tableName)
|
|
||||||
m.mutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *LRUCacher) clearBeans(tableName string) {
|
|
||||||
if tis, ok := m.idIndex[tableName]; ok {
|
|
||||||
for id, v := range tis {
|
|
||||||
m.idList.Remove(v)
|
|
||||||
tid := genID(tableName, id)
|
|
||||||
m.store.Del(tid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m.idIndex[tableName] = make(map[string]*list.Element)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClearBeans clears all beans in some table
|
|
||||||
func (m *LRUCacher) ClearBeans(tableName string) {
|
|
||||||
m.mutex.Lock()
|
|
||||||
m.clearBeans(tableName)
|
|
||||||
m.mutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// PutIds pus ids into table
|
|
||||||
func (m *LRUCacher) PutIds(tableName, sql string, ids interface{}) {
|
|
||||||
m.mutex.Lock()
|
|
||||||
if _, ok := m.sqlIndex[tableName]; !ok {
|
|
||||||
m.sqlIndex[tableName] = make(map[string]*list.Element)
|
|
||||||
}
|
|
||||||
if el, ok := m.sqlIndex[tableName][sql]; !ok {
|
|
||||||
el = m.sqlList.PushBack(newSQLNode(tableName, sql))
|
|
||||||
m.sqlIndex[tableName][sql] = el
|
|
||||||
} else {
|
|
||||||
el.Value.(*sqlNode).lastVisit = time.Now()
|
|
||||||
}
|
|
||||||
m.store.Put(sql, ids)
|
|
||||||
if m.sqlList.Len() > m.MaxElementSize {
|
|
||||||
e := m.sqlList.Front()
|
|
||||||
node := e.Value.(*sqlNode)
|
|
||||||
m.delIds(node.tbName, node.sql)
|
|
||||||
}
|
|
||||||
m.mutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// PutBean puts beans into table
|
|
||||||
func (m *LRUCacher) PutBean(tableName string, id string, obj interface{}) {
|
|
||||||
m.mutex.Lock()
|
|
||||||
var el *list.Element
|
|
||||||
var ok bool
|
|
||||||
|
|
||||||
if el, ok = m.idIndex[tableName][id]; !ok {
|
|
||||||
el = m.idList.PushBack(newIDNode(tableName, id))
|
|
||||||
m.idIndex[tableName][id] = el
|
|
||||||
} else {
|
|
||||||
el.Value.(*idNode).lastVisit = time.Now()
|
|
||||||
}
|
|
||||||
|
|
||||||
m.store.Put(genID(tableName, id), obj)
|
|
||||||
if m.idList.Len() > m.MaxElementSize {
|
|
||||||
e := m.idList.Front()
|
|
||||||
node := e.Value.(*idNode)
|
|
||||||
m.delBean(node.tbName, node.id)
|
|
||||||
}
|
|
||||||
m.mutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *LRUCacher) delIds(tableName, sql string) {
|
|
||||||
if _, ok := m.sqlIndex[tableName]; ok {
|
|
||||||
if el, ok := m.sqlIndex[tableName][sql]; ok {
|
|
||||||
delete(m.sqlIndex[tableName], sql)
|
|
||||||
m.sqlList.Remove(el)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m.store.Del(sql)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DelIds deletes ids
|
|
||||||
func (m *LRUCacher) DelIds(tableName, sql string) {
|
|
||||||
m.mutex.Lock()
|
|
||||||
m.delIds(tableName, sql)
|
|
||||||
m.mutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *LRUCacher) delBean(tableName string, id string) {
|
|
||||||
tid := genID(tableName, id)
|
|
||||||
if el, ok := m.idIndex[tableName][id]; ok {
|
|
||||||
delete(m.idIndex[tableName], id)
|
|
||||||
m.idList.Remove(el)
|
|
||||||
m.clearIds(tableName)
|
|
||||||
}
|
|
||||||
m.store.Del(tid)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DelBean deletes beans in some table
|
|
||||||
func (m *LRUCacher) DelBean(tableName string, id string) {
|
|
||||||
m.mutex.Lock()
|
|
||||||
m.delBean(tableName, id)
|
|
||||||
m.mutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
type idNode struct {
|
|
||||||
tbName string
|
|
||||||
id string
|
|
||||||
lastVisit time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
type sqlNode struct {
|
|
||||||
tbName string
|
|
||||||
sql string
|
|
||||||
lastVisit time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func genSQLKey(sql string, args interface{}) string {
|
|
||||||
return fmt.Sprintf("%v-%v", sql, args)
|
|
||||||
}
|
|
||||||
|
|
||||||
func genID(prefix string, id string) string {
|
|
||||||
return fmt.Sprintf("%v-%v", prefix, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newIDNode(tbName string, id string) *idNode {
|
|
||||||
return &idNode{tbName, id, time.Now()}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSQLNode(tbName, sql string) *sqlNode {
|
|
||||||
return &sqlNode{tbName, sql, time.Now()}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user