diff --git a/CREDITS.md b/CREDITS.md
index ae0694c..51a1ac3 100644
--- a/CREDITS.md
+++ b/CREDITS.md
@@ -19,3 +19,5 @@ Nuno Teixeira, [@nmatpt](https://github.com/nmatpt)
Mikko Rantanen, [@Rantanen](https://github.com/Rantanen)
Wolfgang Illmeyer, [@escitalopram](https://github.com/escitalopram)
+
+Jameskmonger, [@Jameskmonger](https://github.com/Jameskmonger)
diff --git a/bower.json b/bower.json
index fbb29e1..5eb1372 100644
--- a/bower.json
+++ b/bower.json
@@ -1,6 +1,6 @@
{
"name": "diff2html",
- "version": "1.3.2",
+ "version": "2.0.0-beta1",
"homepage": "http://rtfpessoa.github.io/diff2html/",
"description": "Fast Diff to colorized HTML",
"keywords": [
@@ -28,6 +28,7 @@
"url": "git://github.com/rtfpessoa/diff2html.git"
},
"main": [
+ "./dist/diff2html-templates.js",
"./dist/diff2html.js",
"./dist/diff2html-ui.js",
"./dist/diff2html.css"
diff --git a/circle.yml b/circle.yml
index 100709f..addc8c7 100644
--- a/circle.yml
+++ b/circle.yml
@@ -2,6 +2,7 @@ test:
override:
- nvm install 0.12 && npm test
- nvm install 4 && npm test
+ - nvm install 5 && npm test
post:
- npm install
- istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec
diff --git a/dist/diff2html-templates.js b/dist/diff2html-templates.js
new file mode 100644
index 0000000..5407890
--- /dev/null
+++ b/dist/diff2html-templates.js
@@ -0,0 +1,171 @@
+(function() {(window.nunjucksPrecompiled = window.nunjucksPrecompiled || {})["line-by-line/column-line-number.html"] = (function() {
+function root(env, context, frame, runtime, cb) {
+var lineno = null;
+var colno = null;
+var output = "";
+try {
+var parentTemplate = null;
+output += "
\n \n \n ";
+output += runtime.suppressValue((lineno = 3, colno = 73, runtime.callWrap(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "utils")),"escape"), "utils[\"escape\"]", context, [runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "block")),"header")])), env.opts.autoescape);
+output += "
\n \n \n";
+if(parentTemplate) {
+parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);
+} else {
+cb(null, output);
+}
+;
+} catch (e) {
+ cb(runtime.handleError(e, lineno, colno));
+}
+}
+return {
+root: root
+};
+
+})();
+})();
+(function() {(window.nunjucksPrecompiled = window.nunjucksPrecompiled || {})["line-by-line/empty-diff.html"] = (function() {
+function root(env, context, frame, runtime, cb) {
+var lineno = null;
+var colno = null;
+var output = "";
+try {
+var parentTemplate = null;
+output += "\n \n \n File without changes\n
\n \n \n";
+if(parentTemplate) {
+parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);
+} else {
+cb(null, output);
+}
+;
+} catch (e) {
+ cb(runtime.handleError(e, lineno, colno));
+}
+}
+return {
+root: root
+};
+
+})();
+})();
+(function() {(window.nunjucksPrecompiled = window.nunjucksPrecompiled || {})["line-by-line/file-diff.html"] = (function() {
+function root(env, context, frame, runtime, cb) {
+var lineno = null;
+var colno = null;
+var output = "";
+try {
+var parentTemplate = null;
+output += "\n \n
\n
\n
\n \n ";
+output += runtime.suppressValue(env.getFilter("safe").call(context, runtime.contextOrFrameLookup(context, frame, "diffs")), env.opts.autoescape);
+output += "\n \n
\n
\n
\n
\n";
+if(parentTemplate) {
+parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);
+} else {
+cb(null, output);
+}
+;
+} catch (e) {
+ cb(runtime.handleError(e, lineno, colno));
+}
+}
+return {
+root: root
+};
+
+})();
+})();
+(function() {(window.nunjucksPrecompiled = window.nunjucksPrecompiled || {})["line-by-line/line.html"] = (function() {
+function root(env, context, frame, runtime, cb) {
+var lineno = null;
+var colno = null;
+var output = "";
+try {
+var parentTemplate = null;
+output += "\n \n ";
+output += runtime.suppressValue(env.getFilter("safe").call(context, (lineno = 2, colno = 46, runtime.callWrap(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "utils")),"valueOrEmpty"), "utils[\"valueOrEmp\"]", context, [runtime.contextOrFrameLookup(context, frame, "oldNumber")]))), env.opts.autoescape);
+output += "
\n ";
+output += runtime.suppressValue(env.getFilter("safe").call(context, (lineno = 3, colno = 46, runtime.callWrap(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "utils")),"valueOrEmpty"), "utils[\"valueOrEmp\"]", context, [runtime.contextOrFrameLookup(context, frame, "newNumber")]))), env.opts.autoescape);
+output += "
\n \n \n \n";
+if(runtime.contextOrFrameLookup(context, frame, "prefix")) {
+output += "\n ";
+output += runtime.suppressValue(env.getFilter("safe").call(context, (lineno = 8, colno = 83, runtime.callWrap(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "utils")),"convertWhiteSpaceToNonBreakingSpace"), "utils[\"convertWhi\"]", context, [runtime.contextOrFrameLookup(context, frame, "prefix")]))), env.opts.autoescape);
+output += " \n";
+;
+}
+output += "\n";
+if(runtime.contextOrFrameLookup(context, frame, "content")) {
+output += "\n ";
+output += runtime.suppressValue(env.getFilter("safe").call(context, (lineno = 11, colno = 80, runtime.callWrap(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "utils")),"convertWhiteSpaceToNonBreakingSpace"), "utils[\"convertWhi\"]", context, [runtime.contextOrFrameLookup(context, frame, "content")]))), env.opts.autoescape);
+output += " \n";
+;
+}
+output += "\n
\n \n \n";
+if(parentTemplate) {
+parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);
+} else {
+cb(null, output);
+}
+;
+} catch (e) {
+ cb(runtime.handleError(e, lineno, colno));
+}
+}
+return {
+root: root
+};
+
+})();
+})();
+(function() {(window.nunjucksPrecompiled = window.nunjucksPrecompiled || {})["line-by-line/wrapper.html"] = (function() {
+function root(env, context, frame, runtime, cb) {
+var lineno = null;
+var colno = null;
+var output = "";
+try {
+var parentTemplate = null;
+output += "\n ";
+output += runtime.suppressValue(runtime.contextOrFrameLookup(context, frame, "content"), env.opts.autoescape);
+output += "\n
\n";
+if(parentTemplate) {
+parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);
+} else {
+cb(null, output);
+}
+;
+} catch (e) {
+ cb(runtime.handleError(e, lineno, colno));
+}
+}
+return {
+root: root
+};
+
+})();
+})();
+
diff --git a/dist/diff2html-templates.min.js b/dist/diff2html-templates.min.js
new file mode 100644
index 0000000..7a14a31
--- /dev/null
+++ b/dist/diff2html-templates.min.js
@@ -0,0 +1 @@
+!function(){(window.nunjucksPrecompiled=window.nunjucksPrecompiled||{})["line-by-line/column-line-number.html"]=function(){function root(env,context,frame,runtime,cb){var lineno=null,colno=null,output="";try{var parentTemplate=null;output+='\n \n \n ',output+=runtime.suppressValue((lineno=3,colno=73,runtime.callWrap(runtime.memberLookup(runtime.contextOrFrameLookup(context,frame,"utils"),"escape"),'utils["escape"]',context,[runtime.memberLookup(runtime.contextOrFrameLookup(context,frame,"block"),"header")])),env.opts.autoescape),output+="
\n \n \n",parentTemplate?parentTemplate.rootRenderFunc(env,context,frame,runtime,cb):cb(null,output)}catch(e){cb(runtime.handleError(e,lineno,colno))}}return{root:root}}()}(),function(){(window.nunjucksPrecompiled=window.nunjucksPrecompiled||{})["line-by-line/empty-diff.html"]=function(){function root(env,context,frame,runtime,cb){var lineno=null,colno=null,output="";try{var parentTemplate=null;output+='\n \n \n File without changes\n
\n \n \n',parentTemplate?parentTemplate.rootRenderFunc(env,context,frame,runtime,cb):cb(null,output)}catch(e){cb(runtime.handleError(e,lineno,colno))}}return{root:root}}()}(),function(){(window.nunjucksPrecompiled=window.nunjucksPrecompiled||{})["line-by-line/file-diff.html"]=function(){function root(env,context,frame,runtime,cb){var lineno=null,colno=null,output="";try{var parentTemplate=null;output+='\n \n
\n
\n
\n \n ',output+=runtime.suppressValue(env.getFilter("safe").call(context,runtime.contextOrFrameLookup(context,frame,"diffs")),env.opts.autoescape),output+="\n \n
\n
\n
\n
\n",parentTemplate?parentTemplate.rootRenderFunc(env,context,frame,runtime,cb):cb(null,output)}catch(e){cb(runtime.handleError(e,lineno,colno))}}return{root:root}}()}(),function(){(window.nunjucksPrecompiled=window.nunjucksPrecompiled||{})["line-by-line/line.html"]=function(){function root(env,context,frame,runtime,cb){var lineno=null,colno=null,output="";try{var parentTemplate=null;output+='\n \n ',output+=runtime.suppressValue(env.getFilter("safe").call(context,(lineno=2,colno=46,runtime.callWrap(runtime.memberLookup(runtime.contextOrFrameLookup(context,frame,"utils"),"valueOrEmpty"),'utils["valueOrEmp"]',context,[runtime.contextOrFrameLookup(context,frame,"oldNumber")]))),env.opts.autoescape),output+='
\n ',output+=runtime.suppressValue(env.getFilter("safe").call(context,(lineno=3,colno=46,runtime.callWrap(runtime.memberLookup(runtime.contextOrFrameLookup(context,frame,"utils"),"valueOrEmpty"),'utils["valueOrEmp"]',context,[runtime.contextOrFrameLookup(context,frame,"newNumber")]))),env.opts.autoescape),output+='
\n \n \n \n',runtime.contextOrFrameLookup(context,frame,"prefix")&&(output+='\n ',output+=runtime.suppressValue(env.getFilter("safe").call(context,(lineno=8,colno=83,runtime.callWrap(runtime.memberLookup(runtime.contextOrFrameLookup(context,frame,"utils"),"convertWhiteSpaceToNonBreakingSpace"),'utils["convertWhi"]',context,[runtime.contextOrFrameLookup(context,frame,"prefix")]))),env.opts.autoescape),output+=" \n"),output+="\n",runtime.contextOrFrameLookup(context,frame,"content")&&(output+='\n ',output+=runtime.suppressValue(env.getFilter("safe").call(context,(lineno=11,colno=80,runtime.callWrap(runtime.memberLookup(runtime.contextOrFrameLookup(context,frame,"utils"),"convertWhiteSpaceToNonBreakingSpace"),'utils["convertWhi"]',context,[runtime.contextOrFrameLookup(context,frame,"content")]))),env.opts.autoescape),output+=" \n"),output+="\n
\n \n \n",parentTemplate?parentTemplate.rootRenderFunc(env,context,frame,runtime,cb):cb(null,output)}catch(e){cb(runtime.handleError(e,lineno,colno))}}return{root:root}}()}(),function(){(window.nunjucksPrecompiled=window.nunjucksPrecompiled||{})["line-by-line/wrapper.html"]=function(){function root(env,context,frame,runtime,cb){var lineno=null,colno=null,output="";try{var parentTemplate=null;output+='\n ',output+=runtime.suppressValue(runtime.contextOrFrameLookup(context,frame,"content"),env.opts.autoescape),output+="\n
\n",parentTemplate?parentTemplate.rootRenderFunc(env,context,frame,runtime,cb):cb(null,output)}catch(e){cb(runtime.handleError(e,lineno,colno))}}return{root:root}}()}();
\ No newline at end of file
diff --git a/dist/diff2html-ui.js b/dist/diff2html-ui.js
index 607d445..a3bfb7b 100644
--- a/dist/diff2html-ui.js
+++ b/dist/diff2html-ui.js
@@ -114,8 +114,6 @@
var languages = that._getLanguages($target);
- console.log(languages);
-
// pass the languages to the highlightjs plugin
hljs.configure({languages: languages});
@@ -146,18 +144,13 @@
return line.language;
});
} else {
- console.log($target.find(".d2h-file-wrapper"));
$target.find(".d2h-file-wrapper").map(function(i, file) {
allFileLanguages.push($(file).data("lang"));
});
}
- // remove duplicated languages
- var distinctLanguages = allFileLanguages.filter(function(v, i) {
- return allFileLanguages.indexOf(v) === i;
- });
-
- return distinctLanguages;
+ // return only distinct languages
+ return this._distinct(allFileLanguages);
};
Diff2HtmlUI.prototype._getHashTag = function() {
@@ -165,13 +158,19 @@
var hashTagIndex = docUrl.indexOf('#');
var hashTag = null;
- if (hashTagIndex != -1) {
+ if (hashTagIndex !== -1) {
hashTag = docUrl.substr(hashTagIndex + 1);
}
return hashTag;
};
+ Diff2HtmlUI.prototype._distinct = function(collection) {
+ return collection.filter(function(v, i) {
+ return collection.indexOf(v) === i;
+ });
+ };
+
module.exports.Diff2HtmlUI = Diff2HtmlUI;
// Expose diff2html in the browser
diff --git a/dist/diff2html-ui.min.js b/dist/diff2html-ui.min.js
index 2b66d2e..4bdadda 100644
--- a/dist/diff2html-ui.min.js
+++ b/dist/diff2html-ui.min.js
@@ -1 +1 @@
-!function(modules){function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={exports:{},id:moduleId,loaded:!1};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.loaded=!0,module.exports}var installedModules={};return __webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.p="",__webpack_require__(0)}([function(module,exports){(function(global){!function(){function Diff2HtmlUI(config){var cfg=config||{};cfg.diff?diffJson=Diff2Html.getJsonFromDiff(cfg.diff):cfg.json&&(diffJson=cfg.json)}var diffJson=null,defaultTarget="body";Diff2HtmlUI.prototype.draw=function(targetId,config){var cfg=config||{},$target=this._getTarget(targetId);$target.html(Diff2Html.getPrettyHtml(diffJson,cfg))},Diff2HtmlUI.prototype.fileListCloseable=function(targetId,startVisible){function show(){$showBtn.hide(),$hideBtn.show(),$fileList.show()}function hide(){$hideBtn.hide(),$showBtn.show(),$fileList.hide()}var $target=this._getTarget(targetId),hashTag=this._getHashTag(),$showBtn=$target.find(".d2h-show"),$hideBtn=$target.find(".d2h-hide"),$fileList=$target.find(".d2h-file-list");"files-summary-show"===hashTag?show():"files-summary-hide"===hashTag?hide():startVisible?show():hide(),$showBtn.click(show),$hideBtn.click(hide)},Diff2HtmlUI.prototype.highlightCode=function(targetId){var that=this,$target=that._getTarget(targetId),languages=that._getLanguages($target);console.log(languages),hljs.configure({languages:languages});var $codeLines=$target.find(".d2h-code-line-ctn");$codeLines.map(function(i,line){hljs.highlightBlock(line)})},Diff2HtmlUI.prototype._getTarget=function(targetId){var $target;return $target=$(targetId?targetId:defaultTarget)},Diff2HtmlUI.prototype._getLanguages=function($target){var allFileLanguages=[];diffJson?allFileLanguages=diffJson.map(function(line){return line.language}):(console.log($target.find(".d2h-file-wrapper")),$target.find(".d2h-file-wrapper").map(function(i,file){allFileLanguages.push($(file).data("lang"))}));var distinctLanguages=allFileLanguages.filter(function(v,i){return allFileLanguages.indexOf(v)===i});return distinctLanguages},Diff2HtmlUI.prototype._getHashTag=function(){var docUrl=document.URL,hashTagIndex=docUrl.indexOf("#"),hashTag=null;return-1!=hashTagIndex&&(hashTag=docUrl.substr(hashTagIndex+1)),hashTag},module.exports.Diff2HtmlUI=Diff2HtmlUI,global.Diff2HtmlUI=Diff2HtmlUI}()}).call(exports,function(){return this}())}]);
\ No newline at end of file
+!function(modules){function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={exports:{},id:moduleId,loaded:!1};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.loaded=!0,module.exports}var installedModules={};return __webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.p="",__webpack_require__(0)}([function(module,exports){(function(global){!function(){function Diff2HtmlUI(config){var cfg=config||{};cfg.diff?diffJson=Diff2Html.getJsonFromDiff(cfg.diff):cfg.json&&(diffJson=cfg.json)}var diffJson=null,defaultTarget="body";Diff2HtmlUI.prototype.draw=function(targetId,config){var cfg=config||{},$target=this._getTarget(targetId);$target.html(Diff2Html.getPrettyHtml(diffJson,cfg))},Diff2HtmlUI.prototype.fileListCloseable=function(targetId,startVisible){function show(){$showBtn.hide(),$hideBtn.show(),$fileList.show()}function hide(){$hideBtn.hide(),$showBtn.show(),$fileList.hide()}var $target=this._getTarget(targetId),hashTag=this._getHashTag(),$showBtn=$target.find(".d2h-show"),$hideBtn=$target.find(".d2h-hide"),$fileList=$target.find(".d2h-file-list");"files-summary-show"===hashTag?show():"files-summary-hide"===hashTag?hide():startVisible?show():hide(),$showBtn.click(show),$hideBtn.click(hide)},Diff2HtmlUI.prototype.highlightCode=function(targetId){var that=this,$target=that._getTarget(targetId),languages=that._getLanguages($target);hljs.configure({languages:languages});var $codeLines=$target.find(".d2h-code-line-ctn");$codeLines.map(function(i,line){hljs.highlightBlock(line)})},Diff2HtmlUI.prototype._getTarget=function(targetId){var $target;return $target=$(targetId?targetId:defaultTarget)},Diff2HtmlUI.prototype._getLanguages=function($target){var allFileLanguages=[];return diffJson?allFileLanguages=diffJson.map(function(line){return line.language}):$target.find(".d2h-file-wrapper").map(function(i,file){allFileLanguages.push($(file).data("lang"))}),this._distinct(allFileLanguages)},Diff2HtmlUI.prototype._getHashTag=function(){var docUrl=document.URL,hashTagIndex=docUrl.indexOf("#"),hashTag=null;return-1!==hashTagIndex&&(hashTag=docUrl.substr(hashTagIndex+1)),hashTag},Diff2HtmlUI.prototype._distinct=function(collection){return collection.filter(function(v,i){return collection.indexOf(v)===i})},module.exports.Diff2HtmlUI=Diff2HtmlUI,global.Diff2HtmlUI=Diff2HtmlUI}()}).call(exports,function(){return this}())}]);
\ No newline at end of file
diff --git a/dist/diff2html.css b/dist/diff2html.css
index 58e0b56..0e8d10b 100644
--- a/dist/diff2html.css
+++ b/dist/diff2html.css
@@ -69,11 +69,14 @@
border-collapse: collapse;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 12px;
- height: 18px;
- line-height: 18px;
width: 100%;
}
+.d2h-diff-tbody > tr > td > div {
+ height: 16px;
+ line-height: 16px;
+}
+
.d2h-files-diff {
width: 100%;
}
@@ -93,9 +96,9 @@
.d2h-code-line {
display: block;
- white-space: pre;
padding: 0 10px;
height: 18px;
+ white-space: nowrap;
line-height: 18px;
margin-left: 80px;
/* Override HighlightJS */
diff --git a/dist/diff2html.js b/dist/diff2html.js
index 4d6f695..bf38508 100644
--- a/dist/diff2html.js
+++ b/dist/diff2html.js
@@ -410,6 +410,10 @@
function Utils() {
}
+ Utils.prototype.convertWhiteSpaceToNonBreakingSpace = function(str) {
+ return str.slice(0).replace(/ /g, ' ');
+ };
+
Utils.prototype.escape = function(str) {
return str.slice(0)
.replace(/&/g, '&')
@@ -2064,7 +2068,7 @@
(function() {
var LineByLinePrinter = __webpack_require__(22).LineByLinePrinter;
- var SideBySidePrinter = __webpack_require__(23).SideBySidePrinter;
+ var SideBySidePrinter = __webpack_require__(39).SideBySidePrinter;
function HtmlPrinter() {
}
@@ -2102,48 +2106,34 @@
var utils = __webpack_require__(2).Utils;
var Rematch = __webpack_require__(20).Rematch;
+ var nunjucksUtils = __webpack_require__(23).NunjucksUtils;
+ var baseTemplatesPath = 'line-by-line';
+
function LineByLinePrinter(config) {
this.config = config;
}
LineByLinePrinter.prototype.makeFileDiffHtml = function(file, diffs) {
- return '\n' +
- ' \n' +
- '
\n' +
- '
\n' +
- '
\n' +
- ' \n' +
- ' ' + diffs +
- ' \n' +
- '
\n' +
- '
\n' +
- '
\n' +
- '
\n';
+ return nunjucksUtils.render(baseTemplatesPath, 'file-diff.html', {'file': file, 'diffs': diffs});
+ };
+
+ LineByLinePrinter.prototype.makeLineByLineHtmlWrapper = function(content) {
+ return nunjucksUtils.render(baseTemplatesPath, 'wrapper.html', {'content': content});
};
LineByLinePrinter.prototype.generateLineByLineJsonHtml = function(diffFiles) {
var that = this;
var htmlDiffs = diffFiles.map(function(file) {
- var diffs;
- if (file.blocks.length) {
- diffs = that._generateFileHtml(file);
- } else {
- diffs = that._generateEmptyDiff();
- }
- return that.makeFileDiffHtml(file, diffs);
- });
+ var diffs;
+ if (file.blocks.length) {
+ diffs = that._generateFileHtml(file);
+ } else {
+ diffs = that._generateEmptyDiff();
+ }
+ return that.makeFileDiffHtml(file, diffs);
+ });
- return '\n' + htmlDiffs.join('\n') + '
\n';
+ return this.makeLineByLineHtmlWrapper(htmlDiffs.join('\n'));
};
var matcher = Rematch.rematch(function(a, b) {
@@ -2154,12 +2144,7 @@
});
LineByLinePrinter.prototype.makeColumnLineNumberHtml = function(block) {
- return '\n' +
- ' \n' +
- ' ' +
- ' ' + utils.escape(block.header) + '
' +
- ' \n' +
- ' \n';
+ return nunjucksUtils.render(baseTemplatesPath, 'column-line-number.html', {block: block});
};
LineByLinePrinter.prototype._generateFileHtml = function(file) {
@@ -2205,10 +2190,10 @@
var diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config);
processedOldLines +=
- that._generateLineHtml(deleteType, oldLine.oldNumber, oldLine.newNumber,
+ that.makeLineHtml(deleteType, oldLine.oldNumber, oldLine.newNumber,
diff.first.line, diff.first.prefix);
processedNewLines +=
- that._generateLineHtml(insertType, newLine.oldNumber, newLine.newNumber,
+ that.makeLineHtml(insertType, newLine.oldNumber, newLine.newNumber,
diff.second.line, diff.second.prefix);
}
@@ -2230,9 +2215,9 @@
}
if (line.type === diffParser.LINE_TYPE.CONTEXT) {
- lines += that._generateLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine);
+ lines += that.makeLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine);
} else if (line.type === diffParser.LINE_TYPE.INSERTS && !oldLines.length) {
- lines += that._generateLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine);
+ lines += that.makeLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine);
} else if (line.type === diffParser.LINE_TYPE.DELETES) {
oldLines.push(line);
} else if (line.type === diffParser.LINE_TYPE.INSERTS && Boolean(oldLines.length)) {
@@ -2255,52 +2240,31 @@
for (var i = 0; i < oldLines.length; i++) {
var oldLine = oldLines[i];
var oldEscapedLine = utils.escape(oldLine.content);
- lines += this._generateLineHtml(oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine);
+ lines += this.makeLineHtml(oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine);
}
for (var j = 0; j < newLines.length; j++) {
var newLine = newLines[j];
var newEscapedLine = utils.escape(newLine.content);
- lines += this._generateLineHtml(newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine);
+ lines += this.makeLineHtml(newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine);
}
return lines;
};
- LineByLinePrinter.prototype.makeLineHtml = function(type, oldNumber, newNumber, htmlPrefix, htmlContent) {
- return '\n' +
- ' ' +
- ' ' + utils.valueOrEmpty(oldNumber) + '
' +
- ' ' + utils.valueOrEmpty(newNumber) + '
' +
- ' \n' +
- ' ' +
- ' ' + htmlPrefix + htmlContent + '
' +
- ' \n' +
- ' \n';
- };
-
- LineByLinePrinter.prototype._generateLineHtml = function(type, oldNumber, newNumber, content, prefix) {
- var htmlPrefix = '';
- if (prefix) {
- htmlPrefix = '' + prefix + ' ';
- }
-
- var htmlContent = '';
- if (content) {
- htmlContent = '' + content + ' ';
- }
-
- return this.makeLineHtml(type, oldNumber, newNumber, htmlPrefix, htmlContent);
+ LineByLinePrinter.prototype.makeLineHtml = function(type, oldNumber, newNumber, content, prefix) {
+ return nunjucksUtils.render(baseTemplatesPath, 'line.html',
+ {
+ type: type,
+ oldNumber: oldNumber,
+ newNumber: newNumber,
+ prefix: prefix,
+ content: content
+ });
};
LineByLinePrinter.prototype._generateEmptyDiff = function() {
- return '\n' +
- ' ' +
- ' ' +
- 'File without changes' +
- '
' +
- ' \n' +
- ' \n';
+ return nunjucksUtils.render(baseTemplatesPath, 'empty-diff.html', {});
};
module.exports.LineByLinePrinter = LineByLinePrinter;
@@ -2310,6 +2274,2962 @@
/***/ },
/* 23 */
+/***/ function(module, exports, __webpack_require__) {
+
+ /* WEBPACK VAR INJECTION */(function(__dirname) {/*
+ *
+ * Utils (utils.js)
+ * Author: rtfpessoa
+ *
+ */
+
+ (function() {
+
+ var path = __webpack_require__(24);
+
+ var nunjucks = __webpack_require__(26);
+ var templatesPath = path.resolve(__dirname, 'templates');
+
+ var diffParser = __webpack_require__(1).DiffParser;
+ var printerUtils = __webpack_require__(4).PrinterUtils;
+ var utils = __webpack_require__(2).Utils;
+
+ var nunjucksEnv = nunjucks.configure(templatesPath, {"autoescape": false})
+ .addGlobal('printerUtils', printerUtils)
+ .addGlobal('utils', utils)
+ .addGlobal('diffParser', diffParser);
+
+ function NunjucksUtils() {
+ }
+
+ NunjucksUtils.prototype.render = function(namespace, view, params) {
+ var viewPath = path.join(namespace, view);
+ return nunjucksEnv.render(viewPath, params);
+ };
+
+ module.exports.NunjucksUtils = new NunjucksUtils();
+
+ })();
+
+ /* WEBPACK VAR INJECTION */}.call(exports, "/"))
+
+/***/ },
+/* 24 */
+/***/ function(module, exports, __webpack_require__) {
+
+ /* WEBPACK VAR INJECTION */(function(process) {// Copyright Joyent, Inc. and other Node contributors.
+ //
+ // Permission is hereby granted, free of charge, to any person obtaining a
+ // copy of this software and associated documentation files (the
+ // "Software"), to deal in the Software without restriction, including
+ // without limitation the rights to use, copy, modify, merge, publish,
+ // distribute, sublicense, and/or sell copies of the Software, and to permit
+ // persons to whom the Software is furnished to do so, subject to the
+ // following conditions:
+ //
+ // The above copyright notice and this permission notice shall be included
+ // in all copies or substantial portions of the Software.
+ //
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ // USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ // resolves . and .. elements in a path array with directory names there
+ // must be no slashes, empty elements, or device names (c:\) in the array
+ // (so also no leading and trailing slashes - it does not distinguish
+ // relative and absolute paths)
+ function normalizeArray(parts, allowAboveRoot) {
+ // if the path tries to go above the root, `up` ends up > 0
+ var up = 0;
+ for (var i = parts.length - 1; i >= 0; i--) {
+ var last = parts[i];
+ if (last === '.') {
+ parts.splice(i, 1);
+ } else if (last === '..') {
+ parts.splice(i, 1);
+ up++;
+ } else if (up) {
+ parts.splice(i, 1);
+ up--;
+ }
+ }
+
+ // if the path is allowed to go above the root, restore leading ..s
+ if (allowAboveRoot) {
+ for (; up--; up) {
+ parts.unshift('..');
+ }
+ }
+
+ return parts;
+ }
+
+ // Split a filename into [root, dir, basename, ext], unix version
+ // 'root' is just a slash, or nothing.
+ var splitPathRe =
+ /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
+ var splitPath = function(filename) {
+ return splitPathRe.exec(filename).slice(1);
+ };
+
+ // path.resolve([from ...], to)
+ // posix version
+ exports.resolve = function() {
+ var resolvedPath = '',
+ resolvedAbsolute = false;
+
+ for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+ var path = (i >= 0) ? arguments[i] : process.cwd();
+
+ // Skip empty and invalid entries
+ if (typeof path !== 'string') {
+ throw new TypeError('Arguments to path.resolve must be strings');
+ } else if (!path) {
+ continue;
+ }
+
+ resolvedPath = path + '/' + resolvedPath;
+ resolvedAbsolute = path.charAt(0) === '/';
+ }
+
+ // At this point the path should be resolved to a full absolute path, but
+ // handle relative paths to be safe (might happen when process.cwd() fails)
+
+ // Normalize the path
+ resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
+ return !!p;
+ }), !resolvedAbsolute).join('/');
+
+ return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
+ };
+
+ // path.normalize(path)
+ // posix version
+ exports.normalize = function(path) {
+ var isAbsolute = exports.isAbsolute(path),
+ trailingSlash = substr(path, -1) === '/';
+
+ // Normalize the path
+ path = normalizeArray(filter(path.split('/'), function(p) {
+ return !!p;
+ }), !isAbsolute).join('/');
+
+ if (!path && !isAbsolute) {
+ path = '.';
+ }
+ if (path && trailingSlash) {
+ path += '/';
+ }
+
+ return (isAbsolute ? '/' : '') + path;
+ };
+
+ // posix version
+ exports.isAbsolute = function(path) {
+ return path.charAt(0) === '/';
+ };
+
+ // posix version
+ exports.join = function() {
+ var paths = Array.prototype.slice.call(arguments, 0);
+ return exports.normalize(filter(paths, function(p, index) {
+ if (typeof p !== 'string') {
+ throw new TypeError('Arguments to path.join must be strings');
+ }
+ return p;
+ }).join('/'));
+ };
+
+
+ // path.relative(from, to)
+ // posix version
+ exports.relative = function(from, to) {
+ from = exports.resolve(from).substr(1);
+ to = exports.resolve(to).substr(1);
+
+ function trim(arr) {
+ var start = 0;
+ for (; start < arr.length; start++) {
+ if (arr[start] !== '') break;
+ }
+
+ var end = arr.length - 1;
+ for (; end >= 0; end--) {
+ if (arr[end] !== '') break;
+ }
+
+ if (start > end) return [];
+ return arr.slice(start, end - start + 1);
+ }
+
+ var fromParts = trim(from.split('/'));
+ var toParts = trim(to.split('/'));
+
+ var length = Math.min(fromParts.length, toParts.length);
+ var samePartsLength = length;
+ for (var i = 0; i < length; i++) {
+ if (fromParts[i] !== toParts[i]) {
+ samePartsLength = i;
+ break;
+ }
+ }
+
+ var outputParts = [];
+ for (var i = samePartsLength; i < fromParts.length; i++) {
+ outputParts.push('..');
+ }
+
+ outputParts = outputParts.concat(toParts.slice(samePartsLength));
+
+ return outputParts.join('/');
+ };
+
+ exports.sep = '/';
+ exports.delimiter = ':';
+
+ exports.dirname = function(path) {
+ var result = splitPath(path),
+ root = result[0],
+ dir = result[1];
+
+ if (!root && !dir) {
+ // No dirname whatsoever
+ return '.';
+ }
+
+ if (dir) {
+ // It has a dirname, strip trailing slash
+ dir = dir.substr(0, dir.length - 1);
+ }
+
+ return root + dir;
+ };
+
+
+ exports.basename = function(path, ext) {
+ var f = splitPath(path)[2];
+ // TODO: make this comparison case-insensitive on windows?
+ if (ext && f.substr(-1 * ext.length) === ext) {
+ f = f.substr(0, f.length - ext.length);
+ }
+ return f;
+ };
+
+
+ exports.extname = function(path) {
+ return splitPath(path)[3];
+ };
+
+ function filter (xs, f) {
+ if (xs.filter) return xs.filter(f);
+ var res = [];
+ for (var i = 0; i < xs.length; i++) {
+ if (f(xs[i], i, xs)) res.push(xs[i]);
+ }
+ return res;
+ }
+
+ // String.prototype.substr - negative index don't work in IE8
+ var substr = 'ab'.substr(-1) === 'b'
+ ? function (str, start, len) { return str.substr(start, len) }
+ : function (str, start, len) {
+ if (start < 0) start = str.length + start;
+ return str.substr(start, len);
+ }
+ ;
+
+ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(25)))
+
+/***/ },
+/* 25 */
+/***/ function(module, exports) {
+
+ // shim for using process in browser
+
+ var process = module.exports = {};
+ var queue = [];
+ var draining = false;
+ var currentQueue;
+ var queueIndex = -1;
+
+ function cleanUpNextTick() {
+ draining = false;
+ if (currentQueue.length) {
+ queue = currentQueue.concat(queue);
+ } else {
+ queueIndex = -1;
+ }
+ if (queue.length) {
+ drainQueue();
+ }
+ }
+
+ function drainQueue() {
+ if (draining) {
+ return;
+ }
+ var timeout = setTimeout(cleanUpNextTick);
+ draining = true;
+
+ var len = queue.length;
+ while(len) {
+ currentQueue = queue;
+ queue = [];
+ while (++queueIndex < len) {
+ if (currentQueue) {
+ currentQueue[queueIndex].run();
+ }
+ }
+ queueIndex = -1;
+ len = queue.length;
+ }
+ currentQueue = null;
+ draining = false;
+ clearTimeout(timeout);
+ }
+
+ process.nextTick = function (fun) {
+ var args = new Array(arguments.length - 1);
+ if (arguments.length > 1) {
+ for (var i = 1; i < arguments.length; i++) {
+ args[i - 1] = arguments[i];
+ }
+ }
+ queue.push(new Item(fun, args));
+ if (queue.length === 1 && !draining) {
+ setTimeout(drainQueue, 0);
+ }
+ };
+
+ // v8 likes predictible objects
+ function Item(fun, array) {
+ this.fun = fun;
+ this.array = array;
+ }
+ Item.prototype.run = function () {
+ this.fun.apply(null, this.array);
+ };
+ process.title = 'browser';
+ process.browser = true;
+ process.env = {};
+ process.argv = [];
+ process.version = ''; // empty string to avoid regexp issues
+ process.versions = {};
+
+ function noop() {}
+
+ process.on = noop;
+ process.addListener = noop;
+ process.once = noop;
+ process.off = noop;
+ process.removeListener = noop;
+ process.removeAllListeners = noop;
+ process.emit = noop;
+
+ process.binding = function (name) {
+ throw new Error('process.binding is not supported');
+ };
+
+ process.cwd = function () { return '/' };
+ process.chdir = function (dir) {
+ throw new Error('process.chdir is not supported');
+ };
+ process.umask = function() { return 0; };
+
+
+/***/ },
+/* 26 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var lib = __webpack_require__(27);
+ var env = __webpack_require__(28);
+ var Loader = __webpack_require__(37);
+ var loaders = __webpack_require__(32);
+ var precompile = __webpack_require__(32);
+
+ module.exports = {};
+ module.exports.Environment = env.Environment;
+ module.exports.Template = env.Template;
+
+ module.exports.Loader = Loader;
+ module.exports.FileSystemLoader = loaders.FileSystemLoader;
+ module.exports.PrecompiledLoader = loaders.PrecompiledLoader;
+ module.exports.WebLoader = loaders.WebLoader;
+
+ module.exports.compiler = __webpack_require__(32);
+ module.exports.parser = __webpack_require__(32);
+ module.exports.lexer = __webpack_require__(32);
+ module.exports.runtime = __webpack_require__(34);
+ module.exports.lib = lib;
+ module.exports.nodes = __webpack_require__(32);
+
+ module.exports.installJinjaCompat = __webpack_require__(38);
+
+ // A single instance of an environment, since this is so commonly used
+
+ var e;
+ module.exports.configure = function(templatesPath, opts) {
+ opts = opts || {};
+ if(lib.isObject(templatesPath)) {
+ opts = templatesPath;
+ templatesPath = null;
+ }
+
+ var TemplateLoader;
+ if(loaders.FileSystemLoader) {
+ TemplateLoader = new loaders.FileSystemLoader(templatesPath, {
+ watch: opts.watch,
+ noCache: opts.noCache
+ });
+ }
+ else if(loaders.WebLoader) {
+ TemplateLoader = new loaders.WebLoader(templatesPath, {
+ useCache: opts.web && opts.web.useCache,
+ async: opts.web && opts.web.async
+ });
+ }
+
+ e = new env.Environment(TemplateLoader, opts);
+
+ if(opts && opts.express) {
+ e.express(opts.express);
+ }
+
+ return e;
+ };
+
+ module.exports.compile = function(src, env, path, eagerCompile) {
+ if(!e) {
+ module.exports.configure();
+ }
+ return new module.exports.Template(src, env, path, eagerCompile);
+ };
+
+ module.exports.render = function(name, ctx, cb) {
+ if(!e) {
+ module.exports.configure();
+ }
+
+ return e.render(name, ctx, cb);
+ };
+
+ module.exports.renderString = function(src, ctx, cb) {
+ if(!e) {
+ module.exports.configure();
+ }
+
+ return e.renderString(src, ctx, cb);
+ };
+
+ if(precompile) {
+ module.exports.precompile = precompile.precompile;
+ module.exports.precompileString = precompile.precompileString;
+ }
+
+
+/***/ },
+/* 27 */
+/***/ function(module, exports) {
+
+ 'use strict';
+
+ var ArrayProto = Array.prototype;
+ var ObjProto = Object.prototype;
+
+ var escapeMap = {
+ '&': '&',
+ '"': '"',
+ '\'': ''',
+ '<': '<',
+ '>': '>'
+ };
+
+ var escapeRegex = /[&"'<>]/g;
+
+ var lookupEscape = function(ch) {
+ return escapeMap[ch];
+ };
+
+ var exports = module.exports = {};
+
+ exports.prettifyError = function(path, withInternals, err) {
+ // jshint -W022
+ // http://jslinterrors.com/do-not-assign-to-the-exception-parameter
+ if (!err.Update) {
+ // not one of ours, cast it
+ err = new exports.TemplateError(err);
+ }
+ err.Update(path);
+
+ // Unless they marked the dev flag, show them a trace from here
+ if (!withInternals) {
+ var old = err;
+ err = new Error(old.message);
+ err.name = old.name;
+ }
+
+ return err;
+ };
+
+ exports.TemplateError = function(message, lineno, colno) {
+ var err = this;
+
+ if (message instanceof Error) { // for casting regular js errors
+ err = message;
+ message = message.name + ': ' + message.message;
+
+ try {
+ if(err.name = '') {}
+ }
+ catch(e) {
+ // If we can't set the name of the error object in this
+ // environment, don't use it
+ err = this;
+ }
+ } else {
+ if(Error.captureStackTrace) {
+ Error.captureStackTrace(err);
+ }
+ }
+
+ err.name = 'Template render error';
+ err.message = message;
+ err.lineno = lineno;
+ err.colno = colno;
+ err.firstUpdate = true;
+
+ err.Update = function(path) {
+ var message = '(' + (path || 'unknown path') + ')';
+
+ // only show lineno + colno next to path of template
+ // where error occurred
+ if (this.firstUpdate) {
+ if(this.lineno && this.colno) {
+ message += ' [Line ' + this.lineno + ', Column ' + this.colno + ']';
+ }
+ else if(this.lineno) {
+ message += ' [Line ' + this.lineno + ']';
+ }
+ }
+
+ message += '\n ';
+ if (this.firstUpdate) {
+ message += ' ';
+ }
+
+ this.message = message + (this.message || '');
+ this.firstUpdate = false;
+ return this;
+ };
+
+ return err;
+ };
+
+ exports.TemplateError.prototype = Error.prototype;
+
+ exports.escape = function(val) {
+ return val.replace(escapeRegex, lookupEscape);
+ };
+
+ exports.isFunction = function(obj) {
+ return ObjProto.toString.call(obj) === '[object Function]';
+ };
+
+ exports.isArray = Array.isArray || function(obj) {
+ return ObjProto.toString.call(obj) === '[object Array]';
+ };
+
+ exports.isString = function(obj) {
+ return ObjProto.toString.call(obj) === '[object String]';
+ };
+
+ exports.isObject = function(obj) {
+ return ObjProto.toString.call(obj) === '[object Object]';
+ };
+
+ exports.groupBy = function(obj, val) {
+ var result = {};
+ var iterator = exports.isFunction(val) ? val : function(obj) { return obj[val]; };
+ for(var i=0; i>> 0; // Hack to convert object.length to a UInt32
+
+ fromIndex = +fromIndex || 0;
+
+ if(Math.abs(fromIndex) === Infinity) {
+ fromIndex = 0;
+ }
+
+ if(fromIndex < 0) {
+ fromIndex += length;
+ if (fromIndex < 0) {
+ fromIndex = 0;
+ }
+ }
+
+ for(;fromIndex < length; fromIndex++) {
+ if (arr[fromIndex] === searchElement) {
+ return fromIndex;
+ }
+ }
+
+ return -1;
+ };
+
+ if(!Array.prototype.map) {
+ Array.prototype.map = function() {
+ throw new Error('map is unimplemented for this js engine');
+ };
+ }
+
+ exports.keys = function(obj) {
+ if(Object.prototype.keys) {
+ return obj.keys();
+ }
+ else {
+ var keys = [];
+ for(var k in obj) {
+ if(obj.hasOwnProperty(k)) {
+ keys.push(k);
+ }
+ }
+ return keys;
+ }
+ };
+
+
+/***/ },
+/* 28 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var path = __webpack_require__(24);
+ var asap = __webpack_require__(29);
+ var lib = __webpack_require__(27);
+ var Obj = __webpack_require__(31);
+ var compiler = __webpack_require__(32);
+ var builtin_filters = __webpack_require__(33);
+ var builtin_loaders = __webpack_require__(32);
+ var runtime = __webpack_require__(34);
+ var globals = __webpack_require__(35);
+ var Frame = runtime.Frame;
+ var Template;
+
+ // Unconditionally load in this loader, even if no other ones are
+ // included (possible in the slim browser build)
+ builtin_loaders.PrecompiledLoader = __webpack_require__(36);
+
+ // If the user is using the async API, *always* call it
+ // asynchronously even if the template was synchronous.
+ function callbackAsap(cb, err, res) {
+ asap(function() { cb(err, res); });
+ }
+
+ var Environment = Obj.extend({
+ init: function(loaders, opts) {
+ // The dev flag determines the trace that'll be shown on errors.
+ // If set to true, returns the full trace from the error point,
+ // otherwise will return trace starting from Template.render
+ // (the full trace from within nunjucks may confuse developers using
+ // the library)
+ // defaults to false
+ opts = this.opts = opts || {};
+ this.opts.dev = !!opts.dev;
+
+ // The autoescape flag sets global autoescaping. If true,
+ // every string variable will be escaped by default.
+ // If false, strings can be manually escaped using the `escape` filter.
+ // defaults to true
+ this.opts.autoescape = opts.autoescape != null ? opts.autoescape : true;
+
+ // If true, this will make the system throw errors if trying
+ // to output a null or undefined value
+ this.opts.throwOnUndefined = !!opts.throwOnUndefined;
+ this.opts.trimBlocks = !!opts.trimBlocks;
+ this.opts.lstripBlocks = !!opts.lstripBlocks;
+
+ this.loaders = [];
+
+ if(!loaders) {
+ // The filesystem loader is only available server-side
+ if(builtin_loaders.FileSystemLoader) {
+ this.loaders = [new builtin_loaders.FileSystemLoader('views')];
+ }
+ else if(builtin_loaders.WebLoader) {
+ this.loaders = [new builtin_loaders.WebLoader('/views')];
+ }
+ }
+ else {
+ this.loaders = lib.isArray(loaders) ? loaders : [loaders];
+ }
+
+ // It's easy to use precompiled templates: just include them
+ // before you configure nunjucks and this will automatically
+ // pick it up and use it
+ if((true) && window.nunjucksPrecompiled) {
+ this.loaders.unshift(
+ new builtin_loaders.PrecompiledLoader(window.nunjucksPrecompiled)
+ );
+ }
+
+ this.initCache();
+
+ this.globals = globals();
+ this.filters = {};
+ this.asyncFilters = [];
+ this.extensions = {};
+ this.extensionsList = [];
+
+ for(var name in builtin_filters) {
+ this.addFilter(name, builtin_filters[name]);
+ }
+ },
+
+ initCache: function() {
+ // Caching and cache busting
+ lib.each(this.loaders, function(loader) {
+ loader.cache = {};
+
+ if(typeof loader.on === 'function') {
+ loader.on('update', function(template) {
+ loader.cache[template] = null;
+ });
+ }
+ });
+ },
+
+ addExtension: function(name, extension) {
+ extension._name = name;
+ this.extensions[name] = extension;
+ this.extensionsList.push(extension);
+ return this;
+ },
+
+ removeExtension: function(name) {
+ var extension = this.getExtension(name);
+ if (!extension) return;
+
+ this.extensionsList = lib.without(this.extensionsList, extension);
+ delete this.extensions[name];
+ },
+
+ getExtension: function(name) {
+ return this.extensions[name];
+ },
+
+ hasExtension: function(name) {
+ return !!this.extensions[name];
+ },
+
+ addGlobal: function(name, value) {
+ this.globals[name] = value;
+ return this;
+ },
+
+ getGlobal: function(name) {
+ if(!this.globals[name]) {
+ throw new Error('global not found: ' + name);
+ }
+ return this.globals[name];
+ },
+
+ addFilter: function(name, func, async) {
+ var wrapped = func;
+
+ if(async) {
+ this.asyncFilters.push(name);
+ }
+ this.filters[name] = wrapped;
+ return this;
+ },
+
+ getFilter: function(name) {
+ if(!this.filters[name]) {
+ throw new Error('filter not found: ' + name);
+ }
+ return this.filters[name];
+ },
+
+ resolveTemplate: function(loader, parentName, filename) {
+ var isRelative = (loader.isRelative && parentName)? loader.isRelative(filename) : false;
+ return (isRelative && loader.resolve)? loader.resolve(parentName, filename) : filename;
+ },
+
+ getTemplate: function(name, eagerCompile, parentName, ignoreMissing, cb) {
+ var that = this;
+ var tmpl = null;
+ if(name && name.raw) {
+ // this fixes autoescape for templates referenced in symbols
+ name = name.raw;
+ }
+
+ if(lib.isFunction(parentName)) {
+ cb = parentName;
+ parentName = null;
+ eagerCompile = eagerCompile || false;
+ }
+
+ if(lib.isFunction(eagerCompile)) {
+ cb = eagerCompile;
+ eagerCompile = false;
+ }
+
+ if (name instanceof Template) {
+ tmpl = name;
+ }
+ else if(typeof name !== 'string') {
+ throw new Error('template names must be a string: ' + name);
+ }
+ else {
+ for (var i = 0; i < this.loaders.length; i++) {
+ var _name = this.resolveTemplate(this.loaders[i], parentName, name);
+ tmpl = this.loaders[i].cache[_name];
+ if (tmpl) break;
+ }
+ }
+
+ if(tmpl) {
+ if(eagerCompile) {
+ tmpl.compile();
+ }
+
+ if(cb) {
+ cb(null, tmpl);
+ }
+ else {
+ return tmpl;
+ }
+ } else {
+ var syncResult;
+ var _this = this;
+
+ var createTemplate = function(err, info) {
+ if(!info && !err) {
+ if(!ignoreMissing) {
+ err = new Error('template not found: ' + name);
+ }
+ }
+
+ if (err) {
+ if(cb) {
+ cb(err);
+ }
+ else {
+ throw err;
+ }
+ }
+ else {
+ var tmpl;
+ if(info) {
+ tmpl = new Template(info.src, _this,
+ info.path, eagerCompile);
+
+ if(!info.noCache) {
+ info.loader.cache[name] = tmpl;
+ }
+ }
+ else {
+ tmpl = new Template('', _this,
+ '', eagerCompile);
+ }
+
+ if(cb) {
+ cb(null, tmpl);
+ }
+ else {
+ syncResult = tmpl;
+ }
+ }
+ };
+
+ lib.asyncIter(this.loaders, function(loader, i, next, done) {
+ function handle(err, src) {
+ if(err) {
+ done(err);
+ }
+ else if(src) {
+ src.loader = loader;
+ done(null, src);
+ }
+ else {
+ next();
+ }
+ }
+
+ // Resolve name relative to parentName
+ name = that.resolveTemplate(loader, parentName, name);
+
+ if(loader.async) {
+ loader.getSource(name, handle);
+ }
+ else {
+ handle(null, loader.getSource(name));
+ }
+ }, createTemplate);
+
+ return syncResult;
+ }
+ },
+
+ express: function(app) {
+ var env = this;
+
+ function NunjucksView(name, opts) {
+ this.name = name;
+ this.path = name;
+ this.defaultEngine = opts.defaultEngine;
+ this.ext = path.extname(name);
+ if (!this.ext && !this.defaultEngine) throw new Error('No default engine was specified and no extension was provided.');
+ if (!this.ext) this.name += (this.ext = ('.' !== this.defaultEngine[0] ? '.' : '') + this.defaultEngine);
+ }
+
+ NunjucksView.prototype.render = function(opts, cb) {
+ env.render(this.name, opts, cb);
+ };
+
+ app.set('view', NunjucksView);
+ return this;
+ },
+
+ render: function(name, ctx, cb) {
+ if(lib.isFunction(ctx)) {
+ cb = ctx;
+ ctx = null;
+ }
+
+ // We support a synchronous API to make it easier to migrate
+ // existing code to async. This works because if you don't do
+ // anything async work, the whole thing is actually run
+ // synchronously.
+ var syncResult = null;
+
+ this.getTemplate(name, function(err, tmpl) {
+ if(err && cb) {
+ callbackAsap(cb, err);
+ }
+ else if(err) {
+ throw err;
+ }
+ else {
+ syncResult = tmpl.render(ctx, cb);
+ }
+ });
+
+ return syncResult;
+ },
+
+ renderString: function(src, ctx, opts, cb) {
+ if(lib.isFunction(opts)) {
+ cb = opts;
+ opts = {};
+ }
+ opts = opts || {};
+
+ var tmpl = new Template(src, this, opts.path);
+ return tmpl.render(ctx, cb);
+ }
+ });
+
+ var Context = Obj.extend({
+ init: function(ctx, blocks, env) {
+ // Has to be tied to an environment so we can tap into its globals.
+ this.env = env || new Environment();
+
+ // Make a duplicate of ctx
+ this.ctx = {};
+ for(var k in ctx) {
+ if(ctx.hasOwnProperty(k)) {
+ this.ctx[k] = ctx[k];
+ }
+ }
+
+ this.blocks = {};
+ this.exported = [];
+
+ for(var name in blocks) {
+ this.addBlock(name, blocks[name]);
+ }
+ },
+
+ lookup: function(name) {
+ // This is one of the most called functions, so optimize for
+ // the typical case where the name isn't in the globals
+ if(name in this.env.globals && !(name in this.ctx)) {
+ return this.env.globals[name];
+ }
+ else {
+ return this.ctx[name];
+ }
+ },
+
+ setVariable: function(name, val) {
+ this.ctx[name] = val;
+ },
+
+ getVariables: function() {
+ return this.ctx;
+ },
+
+ addBlock: function(name, block) {
+ this.blocks[name] = this.blocks[name] || [];
+ this.blocks[name].push(block);
+ return this;
+ },
+
+ getBlock: function(name) {
+ if(!this.blocks[name]) {
+ throw new Error('unknown block "' + name + '"');
+ }
+
+ return this.blocks[name][0];
+ },
+
+ getSuper: function(env, name, block, frame, runtime, cb) {
+ var idx = lib.indexOf(this.blocks[name] || [], block);
+ var blk = this.blocks[name][idx + 1];
+ var context = this;
+
+ if(idx === -1 || !blk) {
+ throw new Error('no super block available for "' + name + '"');
+ }
+
+ blk(env, context, frame, runtime, cb);
+ },
+
+ addExport: function(name) {
+ this.exported.push(name);
+ },
+
+ getExported: function() {
+ var exported = {};
+ for(var i=0; i capacity) {
+ // Manually shift all values starting at the index back to the
+ // beginning of the queue.
+ for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) {
+ queue[scan] = queue[scan + index];
+ }
+ queue.length -= index;
+ index = 0;
+ }
+ }
+ queue.length = 0;
+ index = 0;
+ flushing = false;
+ }
+
+ // `requestFlush` is implemented using a strategy based on data collected from
+ // every available SauceLabs Selenium web driver worker at time of writing.
+ // https://docs.google.com/spreadsheets/d/1mG-5UYGup5qxGdEMWkhP6BWCz053NUb2E1QoUTU16uA/edit#gid=783724593
+
+ // Safari 6 and 6.1 for desktop, iPad, and iPhone are the only browsers that
+ // have WebKitMutationObserver but not un-prefixed MutationObserver.
+ // Must use `global` instead of `window` to work in both frames and web
+ // workers. `global` is a provision of Browserify, Mr, Mrs, or Mop.
+ var BrowserMutationObserver = global.MutationObserver || global.WebKitMutationObserver;
+
+ // MutationObservers are desirable because they have high priority and work
+ // reliably everywhere they are implemented.
+ // They are implemented in all modern browsers.
+ //
+ // - Android 4-4.3
+ // - Chrome 26-34
+ // - Firefox 14-29
+ // - Internet Explorer 11
+ // - iPad Safari 6-7.1
+ // - iPhone Safari 7-7.1
+ // - Safari 6-7
+ if (typeof BrowserMutationObserver === "function") {
+ requestFlush = makeRequestCallFromMutationObserver(flush);
+
+ // MessageChannels are desirable because they give direct access to the HTML
+ // task queue, are implemented in Internet Explorer 10, Safari 5.0-1, and Opera
+ // 11-12, and in web workers in many engines.
+ // Although message channels yield to any queued rendering and IO tasks, they
+ // would be better than imposing the 4ms delay of timers.
+ // However, they do not work reliably in Internet Explorer or Safari.
+
+ // Internet Explorer 10 is the only browser that has setImmediate but does
+ // not have MutationObservers.
+ // Although setImmediate yields to the browser's renderer, it would be
+ // preferrable to falling back to setTimeout since it does not have
+ // the minimum 4ms penalty.
+ // Unfortunately there appears to be a bug in Internet Explorer 10 Mobile (and
+ // Desktop to a lesser extent) that renders both setImmediate and
+ // MessageChannel useless for the purposes of ASAP.
+ // https://github.com/kriskowal/q/issues/396
+
+ // Timers are implemented universally.
+ // We fall back to timers in workers in most engines, and in foreground
+ // contexts in the following browsers.
+ // However, note that even this simple case requires nuances to operate in a
+ // broad spectrum of browsers.
+ //
+ // - Firefox 3-13
+ // - Internet Explorer 6-9
+ // - iPad Safari 4.3
+ // - Lynx 2.8.7
+ } else {
+ requestFlush = makeRequestCallFromTimer(flush);
+ }
+
+ // `requestFlush` requests that the high priority event queue be flushed as
+ // soon as possible.
+ // This is useful to prevent an error thrown in a task from stalling the event
+ // queue if the exception handled by Node.js’s
+ // `process.on("uncaughtException")` or by a domain.
+ rawAsap.requestFlush = requestFlush;
+
+ // To request a high priority event, we induce a mutation observer by toggling
+ // the text of a text node between "1" and "-1".
+ function makeRequestCallFromMutationObserver(callback) {
+ var toggle = 1;
+ var observer = new BrowserMutationObserver(callback);
+ var node = document.createTextNode("");
+ observer.observe(node, {characterData: true});
+ return function requestCall() {
+ toggle = -toggle;
+ node.data = toggle;
+ };
+ }
+
+ // The message channel technique was discovered by Malte Ubl and was the
+ // original foundation for this library.
+ // http://www.nonblocking.io/2011/06/windownexttick.html
+
+ // Safari 6.0.5 (at least) intermittently fails to create message ports on a
+ // page's first load. Thankfully, this version of Safari supports
+ // MutationObservers, so we don't need to fall back in that case.
+
+ // function makeRequestCallFromMessageChannel(callback) {
+ // var channel = new MessageChannel();
+ // channel.port1.onmessage = callback;
+ // return function requestCall() {
+ // channel.port2.postMessage(0);
+ // };
+ // }
+
+ // For reasons explained above, we are also unable to use `setImmediate`
+ // under any circumstances.
+ // Even if we were, there is another bug in Internet Explorer 10.
+ // It is not sufficient to assign `setImmediate` to `requestFlush` because
+ // `setImmediate` must be called *by name* and therefore must be wrapped in a
+ // closure.
+ // Never forget.
+
+ // function makeRequestCallFromSetImmediate(callback) {
+ // return function requestCall() {
+ // setImmediate(callback);
+ // };
+ // }
+
+ // Safari 6.0 has a problem where timers will get lost while the user is
+ // scrolling. This problem does not impact ASAP because Safari 6.0 supports
+ // mutation observers, so that implementation is used instead.
+ // However, if we ever elect to use timers in Safari, the prevalent work-around
+ // is to add a scroll event listener that calls for a flush.
+
+ // `setTimeout` does not call the passed callback if the delay is less than
+ // approximately 7 in web workers in Firefox 8 through 18, and sometimes not
+ // even then.
+
+ function makeRequestCallFromTimer(callback) {
+ return function requestCall() {
+ // We dispatch a timeout with a specified delay of 0 for engines that
+ // can reliably accommodate that request. This will usually be snapped
+ // to a 4 milisecond delay, but once we're flushing, there's no delay
+ // between events.
+ var timeoutHandle = setTimeout(handleTimer, 0);
+ // However, since this timer gets frequently dropped in Firefox
+ // workers, we enlist an interval handle that will try to fire
+ // an event 20 times per second until it succeeds.
+ var intervalHandle = setInterval(handleTimer, 50);
+
+ function handleTimer() {
+ // Whichever timer succeeds will cancel both timers and
+ // execute the callback.
+ clearTimeout(timeoutHandle);
+ clearInterval(intervalHandle);
+ callback();
+ }
+ };
+ }
+
+ // This is for `asap.js` only.
+ // Its name will be periodically randomized to break any code that depends on
+ // its existence.
+ rawAsap.makeRequestCallFromTimer = makeRequestCallFromTimer;
+
+ // ASAP was originally a nextTick shim included in Q. This was factored out
+ // into this ASAP package. It was later adapted to RSVP which made further
+ // amendments. These decisions, particularly to marginalize MessageChannel and
+ // to capture the MutationObserver implementation in a closure, were integrated
+ // back into ASAP proper.
+ // https://github.com/tildeio/rsvp.js/blob/cddf7232546a9cf858524b75cde6f9edf72620a7/lib/rsvp/asap.js
+
+ /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
+
+/***/ },
+/* 31 */
+/***/ function(module, exports) {
+
+ 'use strict';
+
+ // A simple class system, more documentation to come
+
+ function extend(cls, name, props) {
+ // This does that same thing as Object.create, but with support for IE8
+ var F = function() {};
+ F.prototype = cls.prototype;
+ var prototype = new F();
+
+ // jshint undef: false
+ var fnTest = /xyz/.test(function(){ xyz; }) ? /\bparent\b/ : /.*/;
+ props = props || {};
+
+ for(var k in props) {
+ var src = props[k];
+ var parent = prototype[k];
+
+ if(typeof parent === 'function' &&
+ typeof src === 'function' &&
+ fnTest.test(src)) {
+ /*jshint -W083 */
+ prototype[k] = (function (src, parent) {
+ return function() {
+ // Save the current parent method
+ var tmp = this.parent;
+
+ // Set parent to the previous method, call, and restore
+ this.parent = parent;
+ var res = src.apply(this, arguments);
+ this.parent = tmp;
+
+ return res;
+ };
+ })(src, parent);
+ }
+ else {
+ prototype[k] = src;
+ }
+ }
+
+ prototype.typename = name;
+
+ var new_cls = function() {
+ if(prototype.init) {
+ prototype.init.apply(this, arguments);
+ }
+ };
+
+ new_cls.prototype = prototype;
+ new_cls.prototype.constructor = new_cls;
+
+ new_cls.extend = function(name, props) {
+ if(typeof name === 'object') {
+ props = name;
+ name = 'anonymous';
+ }
+ return extend(new_cls, name, props);
+ };
+
+ return new_cls;
+ }
+
+ module.exports = extend(Object, 'Object', {});
+
+
+/***/ },
+/* 32 */
+/***/ function(module, exports) {
+
+
+
+/***/ },
+/* 33 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var lib = __webpack_require__(27);
+ var r = __webpack_require__(34);
+
+ function normalize(value, defaultValue) {
+ if(value === null || value === undefined || value === false) {
+ return defaultValue;
+ }
+ return value;
+ }
+
+ var filters = {
+ abs: function(n) {
+ return Math.abs(n);
+ },
+
+ batch: function(arr, linecount, fill_with) {
+ var i;
+ var res = [];
+ var tmp = [];
+
+ for(i = 0; i < arr.length; i++) {
+ if(i % linecount === 0 && tmp.length) {
+ res.push(tmp);
+ tmp = [];
+ }
+
+ tmp.push(arr[i]);
+ }
+
+ if(tmp.length) {
+ if(fill_with) {
+ for(i = tmp.length; i < linecount; i++) {
+ tmp.push(fill_with);
+ }
+ }
+
+ res.push(tmp);
+ }
+
+ return res;
+ },
+
+ capitalize: function(str) {
+ str = normalize(str, '');
+ var ret = str.toLowerCase();
+ return r.copySafeness(str, ret.charAt(0).toUpperCase() + ret.slice(1));
+ },
+
+ center: function(str, width) {
+ str = normalize(str, '');
+ width = width || 80;
+
+ if(str.length >= width) {
+ return str;
+ }
+
+ var spaces = width - str.length;
+ var pre = lib.repeat(' ', spaces/2 - spaces % 2);
+ var post = lib.repeat(' ', spaces/2);
+ return r.copySafeness(str, pre + str + post);
+ },
+
+ 'default': function(val, def, bool) {
+ if(bool) {
+ return val ? val : def;
+ }
+ else {
+ return (val !== undefined) ? val : def;
+ }
+ },
+
+ dictsort: function(val, case_sensitive, by) {
+ if (!lib.isObject(val)) {
+ throw new lib.TemplateError('dictsort filter: val must be an object');
+ }
+
+ var array = [];
+ for (var k in val) {
+ // deliberately include properties from the object's prototype
+ array.push([k,val[k]]);
+ }
+
+ var si;
+ if (by === undefined || by === 'key') {
+ si = 0;
+ } else if (by === 'value') {
+ si = 1;
+ } else {
+ throw new lib.TemplateError(
+ 'dictsort filter: You can only sort by either key or value');
+ }
+
+ array.sort(function(t1, t2) {
+ var a = t1[si];
+ var b = t2[si];
+
+ if (!case_sensitive) {
+ if (lib.isString(a)) {
+ a = a.toUpperCase();
+ }
+ if (lib.isString(b)) {
+ b = b.toUpperCase();
+ }
+ }
+
+ return a > b ? 1 : (a === b ? 0 : -1);
+ });
+
+ return array;
+ },
+
+ dump: function(obj) {
+ return JSON.stringify(obj);
+ },
+
+ escape: function(str) {
+ if(typeof str === 'string' ||
+ str instanceof r.SafeString) {
+ return lib.escape(str);
+ }
+ return str;
+ },
+
+ safe: function(str) {
+ return r.markSafe(str);
+ },
+
+ first: function(arr) {
+ return arr[0];
+ },
+
+ groupby: function(arr, attr) {
+ return lib.groupBy(arr, attr);
+ },
+
+ indent: function(str, width, indentfirst) {
+ str = normalize(str, '');
+
+ if (str === '') return '';
+
+ width = width || 4;
+ var res = '';
+ var lines = str.split('\n');
+ var sp = lib.repeat(' ', width);
+
+ for(var i=0; i .a.b.c.
+ res = new_ + str.split('').join(new_) + new_;
+ return r.copySafeness(str, res);
+ }
+
+ var nextIndex = str.indexOf(old);
+ // if # of replacements to perform is 0, or the string to does
+ // not contain the old value, return the string
+ if(maxCount === 0 || nextIndex === -1){
+ return str;
+ }
+
+ var pos = 0;
+ var count = 0; // # of replacements made
+
+ while(nextIndex > -1 && (maxCount === -1 || count < maxCount)){
+ // Grab the next chunk of src string and add it with the
+ // replacement, to the result
+ res += str.substring(pos, nextIndex) + new_;
+ // Increment our pointer in the src string
+ pos = nextIndex + old.length;
+ count++;
+ // See if there are any more replacements to be made
+ nextIndex = str.indexOf(old, pos);
+ }
+
+ // We've either reached the end, or done the max # of
+ // replacements, tack on any remaining string
+ if(pos < str.length) {
+ res += str.substring(pos);
+ }
+
+ return r.copySafeness(originalStr, res);
+ },
+
+ reverse: function(val) {
+ var arr;
+ if(lib.isString(val)) {
+ arr = filters.list(val);
+ }
+ else {
+ // Copy it
+ arr = lib.map(val, function(v) { return v; });
+ }
+
+ arr.reverse();
+
+ if(lib.isString(val)) {
+ return r.copySafeness(val, arr.join(''));
+ }
+ return arr;
+ },
+
+ round: function(val, precision, method) {
+ precision = precision || 0;
+ var factor = Math.pow(10, precision);
+ var rounder;
+
+ if(method === 'ceil') {
+ rounder = Math.ceil;
+ }
+ else if(method === 'floor') {
+ rounder = Math.floor;
+ }
+ else {
+ rounder = Math.round;
+ }
+
+ return rounder(val * factor) / factor;
+ },
+
+ slice: function(arr, slices, fillWith) {
+ var sliceLength = Math.floor(arr.length / slices);
+ var extra = arr.length % slices;
+ var offset = 0;
+ var res = [];
+
+ for(var i=0; i= extra) {
+ slice.push(fillWith);
+ }
+ res.push(slice);
+ }
+
+ return res;
+ },
+
+ sort: r.makeMacro(['value', 'reverse', 'case_sensitive', 'attribute'], [], function(arr, reverse, caseSens, attr) {
+ // Copy it
+ arr = lib.map(arr, function(v) { return v; });
+
+ arr.sort(function(a, b) {
+ var x, y;
+
+ if(attr) {
+ x = a[attr];
+ y = b[attr];
+ }
+ else {
+ x = a;
+ y = b;
+ }
+
+ if(!caseSens && lib.isString(x) && lib.isString(y)) {
+ x = x.toLowerCase();
+ y = y.toLowerCase();
+ }
+
+ if(x < y) {
+ return reverse ? 1 : -1;
+ }
+ else if(x > y) {
+ return reverse ? -1: 1;
+ }
+ else {
+ return 0;
+ }
+ });
+
+ return arr;
+ }),
+
+ string: function(obj) {
+ return r.copySafeness(obj, obj);
+ },
+
+ striptags: function(input, preserve_linebreaks) {
+ input = normalize(input, '');
+ preserve_linebreaks = preserve_linebreaks || false;
+ var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>|/gi;
+ var trimmedInput = filters.trim(input.replace(tags, ''));
+ var res = '';
+ if (preserve_linebreaks) {
+ res = trimmedInput
+ .replace(/^ +| +$/gm, '') // remove leading and trailing spaces
+ .replace(/ +/g, ' ') // squash adjacent spaces
+ .replace(/(\r\n)/g, '\n') // normalize linebreaks (CRLF -> LF)
+ .replace(/\n\n\n+/g, '\n\n'); // squash abnormal adjacent linebreaks
+ } else {
+ res = trimmedInput.replace(/\s+/gi, ' ');
+ }
+ return r.copySafeness(input, res);
+ },
+
+ title: function(str) {
+ str = normalize(str, '');
+ var words = str.split(' ');
+ for(var i = 0; i < words.length; i++) {
+ words[i] = filters.capitalize(words[i]);
+ }
+ return r.copySafeness(str, words.join(' '));
+ },
+
+ trim: function(str) {
+ return r.copySafeness(str, str.replace(/^\s*|\s*$/g, ''));
+ },
+
+ truncate: function(input, length, killwords, end) {
+ var orig = input;
+ input = normalize(input, '');
+ length = length || 255;
+
+ if (input.length <= length)
+ return input;
+
+ if (killwords) {
+ input = input.substring(0, length);
+ } else {
+ var idx = input.lastIndexOf(' ', length);
+ if(idx === -1) {
+ idx = length;
+ }
+
+ input = input.substring(0, idx);
+ }
+
+ input += (end !== undefined && end !== null) ? end : '...';
+ return r.copySafeness(orig, input);
+ },
+
+ upper: function(str) {
+ str = normalize(str, '');
+ return str.toUpperCase();
+ },
+
+ urlencode: function(obj) {
+ var enc = encodeURIComponent;
+ if (lib.isString(obj)) {
+ return enc(obj);
+ } else {
+ var parts;
+ if (lib.isArray(obj)) {
+ parts = obj.map(function(item) {
+ return enc(item[0]) + '=' + enc(item[1]);
+ });
+ } else {
+ parts = [];
+ for (var k in obj) {
+ if (obj.hasOwnProperty(k)) {
+ parts.push(enc(k) + '=' + enc(obj[k]));
+ }
+ }
+ }
+ return parts.join('&');
+ }
+ },
+
+ urlize: function(str, length, nofollow) {
+ if (isNaN(length)) length = Infinity;
+
+ var noFollowAttr = (nofollow === true ? ' rel="nofollow"' : '');
+
+ // For the jinja regexp, see
+ // https://github.com/mitsuhiko/jinja2/blob/f15b814dcba6aa12bc74d1f7d0c881d55f7126be/jinja2/utils.py#L20-L23
+ var puncRE = /^(?:\(|<|<)?(.*?)(?:\.|,|\)|\n|>)?$/;
+ // from http://blog.gerv.net/2011/05/html5_email_address_regexp/
+ var emailRE = /^[\w.!#$%&'*+\-\/=?\^`{|}~]+@[a-z\d\-]+(\.[a-z\d\-]+)+$/i;
+ var httpHttpsRE = /^https?:\/\/.*$/;
+ var wwwRE = /^www\./;
+ var tldRE = /\.(?:org|net|com)(?:\:|\/|$)/;
+
+ var words = str.split(/\s+/).filter(function(word) {
+ // If the word has no length, bail. This can happen for str with
+ // trailing whitespace.
+ return word && word.length;
+ }).map(function(word) {
+ var matches = word.match(puncRE);
+ var possibleUrl = matches && matches[1] || word;
+
+ // url that starts with http or https
+ if (httpHttpsRE.test(possibleUrl))
+ return '' + possibleUrl.substr(0, length) + ' ';
+
+ // url that starts with www.
+ if (wwwRE.test(possibleUrl))
+ return '' + possibleUrl.substr(0, length) + ' ';
+
+ // an email address of the form username@domain.tld
+ if (emailRE.test(possibleUrl))
+ return '' + possibleUrl + ' ';
+
+ // url that ends in .com, .org or .net that is not an email address
+ if (tldRE.test(possibleUrl))
+ return '' + possibleUrl.substr(0, length) + ' ';
+
+ return word;
+
+ });
+
+ return words.join(' ');
+ },
+
+ wordcount: function(str) {
+ str = normalize(str, '');
+ var words = (str) ? str.match(/\w+/g) : null;
+ return (words) ? words.length : null;
+ },
+
+ 'float': function(val, def) {
+ var res = parseFloat(val);
+ return isNaN(res) ? def : res;
+ },
+
+ 'int': function(val, def) {
+ var res = parseInt(val, 10);
+ return isNaN(res) ? def : res;
+ }
+ };
+
+ // Aliases
+ filters.d = filters['default'];
+ filters.e = filters.escape;
+
+ module.exports = filters;
+
+
+/***/ },
+/* 34 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var lib = __webpack_require__(27);
+ var Obj = __webpack_require__(31);
+
+ // Frames keep track of scoping both at compile-time and run-time so
+ // we know how to access variables. Block tags can introduce special
+ // variables, for example.
+ var Frame = Obj.extend({
+ init: function(parent) {
+ this.variables = {};
+ this.parent = parent;
+ this.topLevel = false;
+ },
+
+ set: function(name, val, resolveUp) {
+ // Allow variables with dots by automatically creating the
+ // nested structure
+ var parts = name.split('.');
+ var obj = this.variables;
+ var frame = this;
+
+ if(resolveUp) {
+ if((frame = this.resolve(parts[0]))) {
+ frame.set(name, val);
+ return;
+ }
+ frame = this;
+ }
+
+ for(var i=0; i argNames.length) {
+ args = Array.prototype.slice.call(arguments, 0, argNames.length);
+
+ // Positional arguments that should be passed in as
+ // keyword arguments (essentially default values)
+ var vals = Array.prototype.slice.call(arguments, args.length, argCount);
+ for(i = 0; i < vals.length; i++) {
+ if(i < kwargNames.length) {
+ kwargs[kwargNames[i]] = vals[i];
+ }
+ }
+
+ args.push(kwargs);
+ }
+ else if(argCount < argNames.length) {
+ args = Array.prototype.slice.call(arguments, 0, argCount);
+
+ for(i = argCount; i < argNames.length; i++) {
+ var arg = argNames[i];
+
+ // Keyword arguments that should be passed as
+ // positional arguments, i.e. the caller explicitly
+ // used the name of a positional arg
+ args.push(kwargs[arg]);
+ delete kwargs[arg];
+ }
+
+ args.push(kwargs);
+ }
+ else {
+ args = arguments;
+ }
+
+ return func.apply(this, args);
+ };
+ }
+
+ function makeKeywordArgs(obj) {
+ obj.__keywords = true;
+ return obj;
+ }
+
+ function getKeywordArgs(args) {
+ var len = args.length;
+ if(len) {
+ var lastArg = args[len - 1];
+ if(lastArg && lastArg.hasOwnProperty('__keywords')) {
+ return lastArg;
+ }
+ }
+ return {};
+ }
+
+ function numArgs(args) {
+ var len = args.length;
+ if(len === 0) {
+ return 0;
+ }
+
+ var lastArg = args[len - 1];
+ if(lastArg && lastArg.hasOwnProperty('__keywords')) {
+ return len - 1;
+ }
+ else {
+ return len;
+ }
+ }
+
+ // A SafeString object indicates that the string should not be
+ // autoescaped. This happens magically because autoescaping only
+ // occurs on primitive string objects.
+ function SafeString(val) {
+ if(typeof val !== 'string') {
+ return val;
+ }
+
+ this.val = val;
+ this.length = val.length;
+ }
+
+ SafeString.prototype = Object.create(String.prototype, {
+ length: { writable: true, configurable: true, value: 0 }
+ });
+ SafeString.prototype.valueOf = function() {
+ return this.val;
+ };
+ SafeString.prototype.toString = function() {
+ return this.val;
+ };
+
+ function copySafeness(dest, target) {
+ if(dest instanceof SafeString) {
+ return new SafeString(target);
+ }
+ return target.toString();
+ }
+
+ function markSafe(val) {
+ var type = typeof val;
+
+ if(type === 'string') {
+ return new SafeString(val);
+ }
+ else if(type !== 'function') {
+ return val;
+ }
+ else {
+ return function() {
+ var ret = val.apply(this, arguments);
+
+ if(typeof ret === 'string') {
+ return new SafeString(ret);
+ }
+
+ return ret;
+ };
+ }
+ }
+
+ function suppressValue(val, autoescape) {
+ val = (val !== undefined && val !== null) ? val : '';
+
+ if(autoescape && typeof val === 'string') {
+ val = lib.escape(val);
+ }
+
+ return val;
+ }
+
+ function ensureDefined(val, lineno, colno) {
+ if(val === null || val === undefined) {
+ throw new lib.TemplateError(
+ 'attempted to output null or undefined value',
+ lineno + 1,
+ colno + 1
+ );
+ }
+ return val;
+ }
+
+ function memberLookup(obj, val) {
+ obj = obj || {};
+
+ if(typeof obj[val] === 'function') {
+ return function() {
+ return obj[val].apply(obj, arguments);
+ };
+ }
+
+ return obj[val];
+ }
+
+ function callWrap(obj, name, context, args) {
+ if(!obj) {
+ throw new Error('Unable to call `' + name + '`, which is undefined or falsey');
+ }
+ else if(typeof obj !== 'function') {
+ throw new Error('Unable to call `' + name + '`, which is not a function');
+ }
+
+ // jshint validthis: true
+ return obj.apply(context, args);
+ }
+
+ function contextOrFrameLookup(context, frame, name) {
+ var val = frame.lookup(name);
+ return (val !== undefined && val !== null) ?
+ val :
+ context.lookup(name);
+ }
+
+ function handleError(error, lineno, colno) {
+ if(error.lineno) {
+ return error;
+ }
+ else {
+ return new lib.TemplateError(error, lineno, colno);
+ }
+ }
+
+ function asyncEach(arr, dimen, iter, cb) {
+ if(lib.isArray(arr)) {
+ var len = arr.length;
+
+ lib.asyncIter(arr, function(item, i, next) {
+ switch(dimen) {
+ case 1: iter(item, i, len, next); break;
+ case 2: iter(item[0], item[1], i, len, next); break;
+ case 3: iter(item[0], item[1], item[2], i, len, next); break;
+ default:
+ item.push(i, next);
+ iter.apply(this, item);
+ }
+ }, cb);
+ }
+ else {
+ lib.asyncFor(arr, function(key, val, i, len, next) {
+ iter(key, val, i, len, next);
+ }, cb);
+ }
+ }
+
+ function asyncAll(arr, dimen, func, cb) {
+ var finished = 0;
+ var len, i;
+ var outputArr;
+
+ function done(i, output) {
+ finished++;
+ outputArr[i] = output;
+
+ if(finished === len) {
+ cb(null, outputArr.join(''));
+ }
+ }
+
+ if(lib.isArray(arr)) {
+ len = arr.length;
+ outputArr = new Array(len);
+
+ if(len === 0) {
+ cb(null, '');
+ }
+ else {
+ for(i = 0; i < arr.length; i++) {
+ var item = arr[i];
+
+ switch(dimen) {
+ case 1: func(item, i, len, done); break;
+ case 2: func(item[0], item[1], i, len, done); break;
+ case 3: func(item[0], item[1], item[2], i, len, done); break;
+ default:
+ item.push(i, done);
+ // jshint validthis: true
+ func.apply(this, item);
+ }
+ }
+ }
+ }
+ else {
+ var keys = lib.keys(arr);
+ len = keys.length;
+ outputArr = new Array(len);
+
+ if(len === 0) {
+ cb(null, '');
+ }
+ else {
+ for(i = 0; i < keys.length; i++) {
+ var k = keys[i];
+ func(k, arr[k], i, len, done);
+ }
+ }
+ }
+ }
+
+ module.exports = {
+ Frame: Frame,
+ makeMacro: makeMacro,
+ makeKeywordArgs: makeKeywordArgs,
+ numArgs: numArgs,
+ suppressValue: suppressValue,
+ ensureDefined: ensureDefined,
+ memberLookup: memberLookup,
+ contextOrFrameLookup: contextOrFrameLookup,
+ callWrap: callWrap,
+ handleError: handleError,
+ isArray: lib.isArray,
+ keys: lib.keys,
+ SafeString: SafeString,
+ copySafeness: copySafeness,
+ markSafe: markSafe,
+ asyncEach: asyncEach,
+ asyncAll: asyncAll
+ };
+
+
+/***/ },
+/* 35 */
+/***/ function(module, exports) {
+
+ 'use strict';
+
+ function cycler(items) {
+ var index = -1;
+
+ return {
+ current: null,
+ reset: function() {
+ index = -1;
+ this.current = null;
+ },
+
+ next: function() {
+ index++;
+ if(index >= items.length) {
+ index = 0;
+ }
+
+ this.current = items[index];
+ return this.current;
+ },
+ };
+
+ }
+
+ function joiner(sep) {
+ sep = sep || ',';
+ var first = true;
+
+ return function() {
+ var val = first ? '' : sep;
+ first = false;
+ return val;
+ };
+ }
+
+ // Making this a function instead so it returns a new object
+ // each time it's called. That way, if something like an environment
+ // uses it, they will each have their own copy.
+ function globals() {
+ return {
+ range: function(start, stop, step) {
+ if(!stop) {
+ stop = start;
+ start = 0;
+ step = 1;
+ }
+ else if(!step) {
+ step = 1;
+ }
+
+ var arr = [];
+ var i;
+ if (step > 0) {
+ for (i=start; istop; i+=step) {
+ arr.push(i);
+ }
+ }
+ return arr;
+ },
+
+ // lipsum: function(n, html, min, max) {
+ // },
+
+ cycler: function() {
+ return cycler(Array.prototype.slice.call(arguments));
+ },
+
+ joiner: function(sep) {
+ return joiner(sep);
+ }
+ };
+ }
+
+ module.exports = globals;
+
+
+/***/ },
+/* 36 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var Loader = __webpack_require__(37);
+
+ var PrecompiledLoader = Loader.extend({
+ init: function(compiledTemplates) {
+ this.precompiled = compiledTemplates || {};
+ },
+
+ getSource: function(name) {
+ if (this.precompiled[name]) {
+ return {
+ src: { type: 'code',
+ obj: this.precompiled[name] },
+ path: name
+ };
+ }
+ return null;
+ }
+ });
+
+ module.exports = PrecompiledLoader;
+
+
+/***/ },
+/* 37 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var path = __webpack_require__(24);
+ var Obj = __webpack_require__(31);
+ var lib = __webpack_require__(27);
+
+ var Loader = Obj.extend({
+ on: function(name, func) {
+ this.listeners = this.listeners || {};
+ this.listeners[name] = this.listeners[name] || [];
+ this.listeners[name].push(func);
+ },
+
+ emit: function(name /*, arg1, arg2, ...*/) {
+ var args = Array.prototype.slice.call(arguments, 1);
+
+ if(this.listeners && this.listeners[name]) {
+ lib.each(this.listeners[name], function(listener) {
+ listener.apply(null, args);
+ });
+ }
+ },
+
+ resolve: function(from, to) {
+ return path.resolve(path.dirname(from), to);
+ },
+
+ isRelative: function(filename) {
+ return (filename.indexOf('./') === 0 || filename.indexOf('../') === 0);
+ }
+ });
+
+ module.exports = Loader;
+
+
+/***/ },
+/* 38 */
+/***/ function(module, exports) {
+
+ function installCompat() {
+ 'use strict';
+
+ // This must be called like `nunjucks.installCompat` so that `this`
+ // references the nunjucks instance
+ var runtime = this.runtime; // jshint ignore:line
+ var lib = this.lib; // jshint ignore:line
+
+ var orig_contextOrFrameLookup = runtime.contextOrFrameLookup;
+ runtime.contextOrFrameLookup = function(context, frame, key) {
+ var val = orig_contextOrFrameLookup.apply(this, arguments);
+ if (val === undefined) {
+ switch (key) {
+ case 'True':
+ return true;
+ case 'False':
+ return false;
+ case 'None':
+ return null;
+ }
+ }
+
+ return val;
+ };
+
+ var orig_memberLookup = runtime.memberLookup;
+ var ARRAY_MEMBERS = {
+ pop: function(index) {
+ if (index === undefined) {
+ return this.pop();
+ }
+ if (index >= this.length || index < 0) {
+ throw new Error('KeyError');
+ }
+ return this.splice(index, 1);
+ },
+ remove: function(element) {
+ for (var i = 0; i < this.length; i++) {
+ if (this[i] === element) {
+ return this.splice(i, 1);
+ }
+ }
+ throw new Error('ValueError');
+ },
+ count: function(element) {
+ var count = 0;
+ for (var i = 0; i < this.length; i++) {
+ if (this[i] === element) {
+ count++;
+ }
+ }
+ return count;
+ },
+ index: function(element) {
+ var i;
+ if ((i = this.indexOf(element)) === -1) {
+ throw new Error('ValueError');
+ }
+ return i;
+ },
+ find: function(element) {
+ return this.indexOf(element);
+ },
+ insert: function(index, elem) {
+ return this.splice(index, 0, elem);
+ }
+ };
+ var OBJECT_MEMBERS = {
+ items: function() {
+ var ret = [];
+ for(var k in this) {
+ ret.push([k, this[k]]);
+ }
+ return ret;
+ },
+ values: function() {
+ var ret = [];
+ for(var k in this) {
+ ret.push(this[k]);
+ }
+ return ret;
+ },
+ keys: function() {
+ var ret = [];
+ for(var k in this) {
+ ret.push(k);
+ }
+ return ret;
+ },
+ get: function(key, def) {
+ var output = this[key];
+ if (output === undefined) {
+ output = def;
+ }
+ return output;
+ },
+ has_key: function(key) {
+ return this.hasOwnProperty(key);
+ },
+ pop: function(key, def) {
+ var output = this[key];
+ if (output === undefined && def !== undefined) {
+ output = def;
+ } else if (output === undefined) {
+ throw new Error('KeyError');
+ } else {
+ delete this[key];
+ }
+ return output;
+ },
+ popitem: function() {
+ for (var k in this) {
+ // Return the first object pair.
+ var val = this[k];
+ delete this[k];
+ return [k, val];
+ }
+ throw new Error('KeyError');
+ },
+ setdefault: function(key, def) {
+ if (key in this) {
+ return this[key];
+ }
+ if (def === undefined) {
+ def = null;
+ }
+ return this[key] = def;
+ },
+ update: function(kwargs) {
+ for (var k in kwargs) {
+ this[k] = kwargs[k];
+ }
+ return null; // Always returns None
+ }
+ };
+ OBJECT_MEMBERS.iteritems = OBJECT_MEMBERS.items;
+ OBJECT_MEMBERS.itervalues = OBJECT_MEMBERS.values;
+ OBJECT_MEMBERS.iterkeys = OBJECT_MEMBERS.keys;
+ runtime.memberLookup = function(obj, val, autoescape) { // jshint ignore:line
+ obj = obj || {};
+
+ // If the object is an object, return any of the methods that Python would
+ // otherwise provide.
+ if (lib.isArray(obj) && ARRAY_MEMBERS.hasOwnProperty(val)) {
+ return function() {return ARRAY_MEMBERS[val].apply(obj, arguments);};
+ }
+
+ if (lib.isObject(obj) && OBJECT_MEMBERS.hasOwnProperty(val)) {
+ return function() {return OBJECT_MEMBERS[val].apply(obj, arguments);};
+ }
+
+ return orig_memberLookup.apply(this, arguments);
+ };
+ }
+
+ module.exports = installCompat;
+
+
+/***/ },
+/* 39 */
/***/ function(module, exports, __webpack_require__) {
/*
diff --git a/dist/diff2html.min.css b/dist/diff2html.min.css
index 7679838..ead0e59 100644
--- a/dist/diff2html.min.css
+++ b/dist/diff2html.min.css
@@ -1 +1 @@
-.d2h-code-line-prefix,.line-num1{float:left}.d2h-wrapper{display:block;margin:0 auto;text-align:left;width:100%}.d2h-file-wrapper{border:1px solid #ddd;border-radius:3px;margin-bottom:1em}.d2h-file-header{padding:5px 10px;border-bottom:1px solid #d8d8d8;background-color:#f7f7f7;font:13px Helvetica,arial,freesans,clean,sans-serif,"Segoe UI Emoji","Segoe UI Symbol"}.d2h-file-stats{display:inline;font-size:12px;text-align:center;max-width:15%}.d2h-lines-added{text-align:right}.d2h-lines-added>*{background-color:#ceffce;border:1px solid #b4e2b4;color:#399839;border-radius:5px 0 0 5px;padding:2px}.d2h-lines-deleted{text-align:left}.d2h-lines-deleted>*{background-color:#f7c8c8;border:1px solid #e9aeae;color:#c33;border-radius:0 5px 5px 0;padding:2px}.d2h-file-name{display:inline;line-height:33px;max-width:80%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.d2h-file-diff,.d2h-file-side-diff{overflow-x:scroll;overflow-y:hidden}.d2h-diff-table{border-collapse:collapse;font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px;height:18px;line-height:18px;width:100%}.d2h-files-diff{width:100%}.d2h-file-side-diff{display:inline-block;width:50%;margin-right:-4px}.d2h-code-line,.d2h-code-side-line{white-space:pre;padding:0 10px;height:18px;line-height:18px;color:inherit;overflow-x:inherit;background:0 0;display:block}.d2h-code-line{margin-left:80px}.d2h-code-side-line{margin-left:50px}.d2h-code-line del,.d2h-code-side-line del{display:inline-block;margin-top:-1px;text-decoration:none;background-color:#ffb6ba;border-radius:.2em}.d2h-code-line ins,.d2h-code-side-line ins{display:inline-block;margin-top:-1px;text-decoration:none;background-color:#97f295;border-radius:.2em}.d2h-code-line-ctn,.d2h-code-line-prefix{background:0 0;padding:0}.d2h-code-linenumber,.d2h-code-side-linenumber{position:absolute;height:18px;line-height:18px;background-color:#fff;text-align:right;color:rgba(0,0,0,.3);cursor:pointer}.line-num1,.line-num2{width:32px;padding-left:3px;box-sizing:border-box;overflow:hidden;text-overflow:ellipsis}.line-num2{float:right}.d2h-code-linenumber{box-sizing:border-box;width:82px;padding-left:2px;padding-right:2px;border:solid #eee;border-width:0 1px}.d2h-code-side-linenumber{box-sizing:border-box;width:52px;padding-left:10px;padding-right:10px;border:solid #eee;border-width:0 1px;overflow:hidden;text-overflow:ellipsis}.d2h-del{background-color:#fee8e9;border-color:#e9aeae}.d2h-ins{background-color:#dfd;border-color:#b4e2b4}.d2h-info{background-color:#f8fafd;color:rgba(0,0,0,.3);border-color:#d5e4f2}.d2h-file-list-wrapper{margin-bottom:10px;padding:0 10px}.d2h-file-list-wrapper a{text-decoration:none;color:#3572b0}.d2h-file-list-wrapper a:visited{color:#3572b0}.d2h-file-list-header{font-weight:700;float:left}.d2h-file-list-line{text-align:left;font:13px Helvetica,arial,freesans,clean,sans-serif,"Segoe UI Emoji","Segoe UI Symbol"}.d2h-file-list-line .d2h-file-name{line-height:21px}.d2h-file-list{display:block}.d2h-clear{display:block;clear:both}.d2h-del.d2h-change,.d2h-ins.d2h-change{background-color:#ffc}del.d2h-change,ins.d2h-change{background-color:#fad771}.d2h-file-diff .d2h-del.d2h-change{background-color:#fae1af}.d2h-file-diff .d2h-ins.d2h-change{background-color:#ded}.d2h-file-switch{display:none;float:left;font-size:10px;cursor:pointer;margin-top:3px}
\ No newline at end of file
+.d2h-code-line-prefix,.line-num1{float:left}.d2h-wrapper{display:block;margin:0 auto;text-align:left;width:100%}.d2h-file-wrapper{border:1px solid #ddd;border-radius:3px;margin-bottom:1em}.d2h-file-header{padding:5px 10px;border-bottom:1px solid #d8d8d8;background-color:#f7f7f7;font:13px Helvetica,arial,freesans,clean,sans-serif,"Segoe UI Emoji","Segoe UI Symbol"}.d2h-file-stats{display:inline;font-size:12px;text-align:center;max-width:15%}.d2h-lines-added{text-align:right}.d2h-lines-added>*{background-color:#ceffce;border:1px solid #b4e2b4;color:#399839;border-radius:5px 0 0 5px;padding:2px}.d2h-lines-deleted{text-align:left}.d2h-lines-deleted>*{background-color:#f7c8c8;border:1px solid #e9aeae;color:#c33;border-radius:0 5px 5px 0;padding:2px}.d2h-file-name{display:inline;line-height:33px;max-width:80%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.d2h-file-diff,.d2h-file-side-diff{overflow-x:scroll;overflow-y:hidden}.d2h-diff-table{border-collapse:collapse;font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px;width:100%}.d2h-diff-tbody>tr>td>div{height:16px;line-height:16px}.d2h-files-diff{width:100%}.d2h-file-side-diff{display:inline-block;width:50%;margin-right:-4px}.d2h-code-line,.d2h-code-side-line{padding:0 10px;height:18px;line-height:18px;color:inherit;overflow-x:inherit;background:0 0;display:block}.d2h-code-line{white-space:nowrap;margin-left:80px}.d2h-code-side-line{white-space:pre;margin-left:50px}.d2h-code-line del,.d2h-code-side-line del{display:inline-block;margin-top:-1px;text-decoration:none;background-color:#ffb6ba;border-radius:.2em}.d2h-code-line ins,.d2h-code-side-line ins{display:inline-block;margin-top:-1px;text-decoration:none;background-color:#97f295;border-radius:.2em}.d2h-code-line-ctn,.d2h-code-line-prefix{background:0 0;padding:0}.d2h-code-linenumber,.d2h-code-side-linenumber{position:absolute;height:18px;line-height:18px;background-color:#fff;text-align:right;color:rgba(0,0,0,.3);cursor:pointer}.line-num1,.line-num2{width:32px;padding-left:3px;box-sizing:border-box;overflow:hidden;text-overflow:ellipsis}.line-num2{float:right}.d2h-code-linenumber{box-sizing:border-box;width:82px;padding-left:2px;padding-right:2px;border:solid #eee;border-width:0 1px}.d2h-code-side-linenumber{box-sizing:border-box;width:52px;padding-left:10px;padding-right:10px;border:solid #eee;border-width:0 1px;overflow:hidden;text-overflow:ellipsis}.d2h-del{background-color:#fee8e9;border-color:#e9aeae}.d2h-ins{background-color:#dfd;border-color:#b4e2b4}.d2h-info{background-color:#f8fafd;color:rgba(0,0,0,.3);border-color:#d5e4f2}.d2h-file-list-wrapper{margin-bottom:10px;padding:0 10px}.d2h-file-list-wrapper a{text-decoration:none;color:#3572b0}.d2h-file-list-wrapper a:visited{color:#3572b0}.d2h-file-list-header{font-weight:700;float:left}.d2h-file-list-line{text-align:left;font:13px Helvetica,arial,freesans,clean,sans-serif,"Segoe UI Emoji","Segoe UI Symbol"}.d2h-file-list-line .d2h-file-name{line-height:21px}.d2h-file-list{display:block}.d2h-clear{display:block;clear:both}.d2h-del.d2h-change,.d2h-ins.d2h-change{background-color:#ffc}del.d2h-change,ins.d2h-change{background-color:#fad771}.d2h-file-diff .d2h-del.d2h-change{background-color:#fae1af}.d2h-file-diff .d2h-ins.d2h-change{background-color:#ded}.d2h-file-switch{display:none;float:left;font-size:10px;cursor:pointer;margin-top:3px}
\ No newline at end of file
diff --git a/dist/diff2html.min.js b/dist/diff2html.min.js
index 9759ee1..e0d8033 100644
--- a/dist/diff2html.min.js
+++ b/dist/diff2html.min.js
@@ -1,3 +1,5 @@
-!function(modules){function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={exports:{},id:moduleId,loaded:!1};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.loaded=!0,module.exports}var installedModules={};return __webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.p="",__webpack_require__(0)}([function(module,exports,__webpack_require__){(function(global){!function(){function Diff2Html(){}var diffParser=__webpack_require__(1).DiffParser,fileLister=__webpack_require__(3).FileListPrinter,htmlPrinter=__webpack_require__(21).HtmlPrinter;Diff2Html.prototype.getJsonFromDiff=function(diffInput){return diffParser.generateDiffJson(diffInput)},Diff2Html.prototype.getPrettyHtml=function(diffInput,config){var configOrEmpty=config||{},diffJson=diffInput;configOrEmpty.inputFormat&&"diff"!==configOrEmpty.inputFormat||(diffJson=diffParser.generateDiffJson(diffInput));var fileList="";configOrEmpty.showFiles===!0&&(fileList=fileLister.generateFileList(diffJson,configOrEmpty));var diffOutput="";return diffOutput="side-by-side"===configOrEmpty.outputFormat?htmlPrinter.generateSideBySideJsonHtml(diffJson,configOrEmpty):htmlPrinter.generateLineByLineJsonHtml(diffJson,configOrEmpty),fileList+diffOutput},Diff2Html.prototype.getPrettyHtmlFromDiff=function(diffInput,config){var configOrEmpty=config||{};return configOrEmpty.inputFormat="diff",configOrEmpty.outputFormat="line-by-line",this.getPrettyHtml(diffInput,configOrEmpty)},Diff2Html.prototype.getPrettyHtmlFromJson=function(diffJson,config){var configOrEmpty=config||{};return configOrEmpty.inputFormat="json",configOrEmpty.outputFormat="line-by-line",this.getPrettyHtml(diffJson,configOrEmpty)},Diff2Html.prototype.getPrettySideBySideHtmlFromDiff=function(diffInput,config){var configOrEmpty=config||{};return configOrEmpty.inputFormat="diff",configOrEmpty.outputFormat="side-by-side",this.getPrettyHtml(diffInput,configOrEmpty)},Diff2Html.prototype.getPrettySideBySideHtmlFromJson=function(diffJson,config){var configOrEmpty=config||{};return configOrEmpty.inputFormat="json",configOrEmpty.outputFormat="side-by-side",this.getPrettyHtml(diffJson,configOrEmpty)};var diffObject=new Diff2Html;module.exports.Diff2Html=diffObject,global.Diff2Html=diffObject}()}).call(exports,function(){return this}())},function(module,exports,__webpack_require__){!function(){function DiffParser(){}function getExtension(filename,language){var nameSplit=filename.split(".");return nameSplit.length>1?nameSplit[nameSplit.length-1]:language}var utils=__webpack_require__(2).Utils,LINE_TYPE={INSERTS:"d2h-ins",DELETES:"d2h-del",INSERT_CHANGES:"d2h-ins d2h-change",DELETE_CHANGES:"d2h-del d2h-change",CONTEXT:"d2h-cntx",INFO:"d2h-info"};DiffParser.prototype.LINE_TYPE=LINE_TYPE,DiffParser.prototype.generateDiffJson=function(diffInput){var files=[],currentFile=null,currentBlock=null,oldLine=null,newLine=null,saveBlock=function(){currentBlock&&(currentFile.blocks.push(currentBlock),currentBlock=null)},saveFile=function(){currentFile&¤tFile.newName&&(files.push(currentFile),currentFile=null)},startFile=function(){saveBlock(),saveFile(),currentFile={},currentFile.blocks=[],currentFile.deletedLines=0,currentFile.addedLines=0},startBlock=function(line){saveBlock();var values;(values=/^@@ -(\d+),\d+ \+(\d+),\d+ @@.*/.exec(line))?currentFile.isCombined=!1:(values=/^@@@ -(\d+),\d+ -\d+,\d+ \+(\d+),\d+ @@@.*/.exec(line))?currentFile.isCombined=!0:(values=[0,0],currentFile.isCombined=!1),oldLine=values[1],newLine=values[2],currentBlock={},currentBlock.lines=[],currentBlock.oldStartLine=oldLine,currentBlock.newStartLine=newLine,currentBlock.header=line},createLine=function(line){var currentLine={};currentLine.content=line;var newLinePrefixes=currentFile.isCombined?["+"," +"]:["+"],delLinePrefixes=currentFile.isCombined?["-"," -"]:["-"];utils.startsWith(line,newLinePrefixes)?(currentFile.addedLines++,currentLine.type=LINE_TYPE.INSERTS,currentLine.oldNumber=null,currentLine.newNumber=newLine++,currentBlock.lines.push(currentLine)):utils.startsWith(line,delLinePrefixes)?(currentFile.deletedLines++,currentLine.type=LINE_TYPE.DELETES,currentLine.oldNumber=oldLine++,currentLine.newNumber=null,currentBlock.lines.push(currentLine)):(currentLine.type=LINE_TYPE.CONTEXT,currentLine.oldNumber=oldLine++,currentLine.newNumber=newLine++,currentBlock.lines.push(currentLine))},diffLines=diffInput.replace(/\\ No newline at end of file/g,"").replace(/\r\n?/g,"\n").split("\n"),oldMode=/^old mode (\d{6})/,newMode=/^new mode (\d{6})/,deletedFileMode=/^deleted file mode (\d{6})/,newFileMode=/^new file mode (\d{6})/,copyFrom=/^copy from (.+)/,copyTo=/^copy to (.+)/,renameFrom=/^rename from (.+)/,renameTo=/^rename to (.+)/,similarityIndex=/^similarity index (\d+)%/,dissimilarityIndex=/^dissimilarity index (\d+)%/,index=/^index ([0-9a-z]+)..([0-9a-z]+) (\d{6})?/,combinedIndex=/^index ([0-9a-z]+),([0-9a-z]+)..([0-9a-z]+)/,combinedMode=/^mode (\d{6}),(\d{6})..(\d{6})/,combinedNewFile=/^new file mode (\d{6})/,combinedDeletedFile=/^deleted file mode (\d{6}),(\d{6})/;return diffLines.forEach(function(line){if(line&&!utils.startsWith(line,"*")){var values=[];utils.startsWith(line,"diff")?startFile():currentFile&&!currentFile.oldName&&(values=/^--- [aiwco]\/(.+)$/.exec(line))?(currentFile.oldName=values[1],currentFile.language=getExtension(currentFile.oldName,currentFile.language)):currentFile&&!currentFile.newName&&(values=/^\+\+\+ [biwco]?\/(.+)$/.exec(line))?(currentFile.newName=values[1],currentFile.language=getExtension(currentFile.newName,currentFile.language)):currentFile&&utils.startsWith(line,"@@")?startBlock(line):(values=oldMode.exec(line))?currentFile.oldMode=values[1]:(values=newMode.exec(line))?currentFile.newMode=values[1]:(values=deletedFileMode.exec(line))?currentFile.deletedFileMode=values[1]:(values=newFileMode.exec(line))?currentFile.newFileMode=values[1]:(values=copyFrom.exec(line))?(currentFile.oldName=values[1],currentFile.isCopy=!0):(values=copyTo.exec(line))?(currentFile.newName=values[1],currentFile.isCopy=!0):(values=renameFrom.exec(line))?(currentFile.oldName=values[1],currentFile.isRename=!0):(values=renameTo.exec(line))?(currentFile.newName=values[1],currentFile.isRename=!0):(values=similarityIndex.exec(line))?currentFile.unchangedPercentage=values[1]:(values=dissimilarityIndex.exec(line))?currentFile.changedPercentage=values[1]:(values=index.exec(line))?(currentFile.checksumBefore=values[1],currentFile.checksumAfter=values[2],values[2]&&(currentFile.mode=values[3])):(values=combinedIndex.exec(line))?(currentFile.checksumBefore=[values[2],values[3]],currentFile.checksumAfter=values[1]):(values=combinedMode.exec(line))?(currentFile.oldMode=[values[2],values[3]],currentFile.newMode=values[1]):(values=combinedNewFile.exec(line))?currentFile.newFileMode=values[1]:(values=combinedDeletedFile.exec(line))?currentFile.deletedFileMode=values[1]:currentBlock&&createLine(line)}}),saveBlock(),saveFile(),files},module.exports.DiffParser=new DiffParser}()},function(module){!function(){function Utils(){}Utils.prototype.escape=function(str){return str.slice(0).replace(/&/g,"&").replace(//g,">").replace(/\t/g," ")},Utils.prototype.startsWith=function(str,start){if("object"==typeof start){var result=!1;return start.forEach(function(s){0===str.indexOf(s)&&(result=!0)}),result}return 0===str.indexOf(start)},Utils.prototype.valueOrEmpty=function(value){return value?value:""},module.exports.Utils=new Utils}()},function(module,exports,__webpack_require__){!function(){function FileListPrinter(){}var printerUtils=__webpack_require__(4).PrinterUtils;FileListPrinter.prototype.generateFileList=function(diffFiles){return'\n"},module.exports.FileListPrinter=new FileListPrinter}()},function(module,exports,__webpack_require__){!function(){function PrinterUtils(){}function isDeletedName(name){return"dev/null"===name}function removeIns(line){return line.replace(/(]*>((.|\n)*?)<\/ins>)/g,"")}function removeDel(line){return line.replace(/(]*>((.|\n)*?)<\/del>)/g,"")}var jsDiff=__webpack_require__(5),utils=__webpack_require__(2).Utils,Rematch=__webpack_require__(20).Rematch;PrinterUtils.prototype.getHtmlId=function(file){var hashCode=function(text){var i,chr,len,hash=0;if(0===text.length)return hash;for(i=0,len=text.length;len>i;i++)chr=text.charCodeAt(i),hash=(hash<<5)-hash+chr,hash|=0;return hash};return"d2h-"+hashCode(this.getDiffName(file)).toString().slice(-6)},PrinterUtils.prototype.getDiffName=function(file){var oldFilename=file.oldName,newFilename=file.newName;return oldFilename&&newFilename&&oldFilename!==newFilename&&!isDeletedName(newFilename)?oldFilename+" -> "+newFilename:newFilename&&!isDeletedName(newFilename)?newFilename:oldFilename?oldFilename:"Unknown filename"},PrinterUtils.prototype.diffHighlight=function(diffLine1,diffLine2,config){var linePrefix1,linePrefix2,unprefixedLine1,unprefixedLine2,prefixSize=1;config.isCombined&&(prefixSize=2),linePrefix1=diffLine1.substr(0,prefixSize),linePrefix2=diffLine2.substr(0,prefixSize),unprefixedLine1=diffLine1.substr(prefixSize),unprefixedLine2=diffLine2.substr(prefixSize);var diff;diff=config.charByChar?jsDiff.diffChars(unprefixedLine1,unprefixedLine2):jsDiff.diffWordsWithSpace(unprefixedLine1,unprefixedLine2);var highlightedLine="",changedWords=[];if(!config.charByChar&&"words"===config.matching){var treshold=.25;"undefined"!=typeof config.matchWordsThreshold&&(treshold=config.matchWordsThreshold);var matcher=Rematch.rematch(function(a,b){var amod=a.value,bmod=b.value;return Rematch.distance(amod,bmod)}),removed=diff.filter(function(element){return element.removed}),added=diff.filter(function(element){return element.added}),chunks=matcher(added,removed);chunks.forEach(function(chunk){if(1===chunk[0].length&&1===chunk[1].length){var dist=Rematch.distance(chunk[0][0].value,chunk[1][0].value);treshold>dist&&(changedWords.push(chunk[0][0]),changedWords.push(chunk[1][0]))}})}return diff.forEach(function(part){var addClass=changedWords.indexOf(part)>-1?' class="d2h-change"':"",elemType=part.added?"ins":part.removed?"del":null,escapedValue=utils.escape(part.value);highlightedLine+=null!==elemType?"<"+elemType+addClass+">"+escapedValue+""+elemType+">":escapedValue}),{first:{prefix:linePrefix1,line:removeIns(highlightedLine)},second:{prefix:linePrefix2,line:removeDel(highlightedLine)}}},module.exports.PrinterUtils=new PrinterUtils}()},function(module,exports,__webpack_require__){"use strict";function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{"default":obj}}exports.__esModule=!0;var _diffBase=__webpack_require__(6),_diffBase2=_interopRequireDefault(_diffBase),_diffCharacter=__webpack_require__(7),_diffWord=__webpack_require__(8),_diffLine=__webpack_require__(10),_diffSentence=__webpack_require__(11),_diffCss=__webpack_require__(12),_diffJson=__webpack_require__(13),_patchApply=__webpack_require__(14),_patchParse=__webpack_require__(15),_patchCreate=__webpack_require__(17),_convertDmp=__webpack_require__(18),_convertXml=__webpack_require__(19);exports.Diff=_diffBase2["default"],exports.diffChars=_diffCharacter.diffChars,exports.diffWords=_diffWord.diffWords,exports.diffWordsWithSpace=_diffWord.diffWordsWithSpace,exports.diffLines=_diffLine.diffLines,exports.diffTrimmedLines=_diffLine.diffTrimmedLines,exports.diffSentences=_diffSentence.diffSentences,exports.diffCss=_diffCss.diffCss,exports.diffJson=_diffJson.diffJson,exports.structuredPatch=_patchCreate.structuredPatch,exports.createTwoFilesPatch=_patchCreate.createTwoFilesPatch,exports.createPatch=_patchCreate.createPatch,exports.applyPatch=_patchApply.applyPatch,exports.applyPatches=_patchApply.applyPatches,exports.parsePatch=_patchParse.parsePatch,exports.convertChangesToDMP=_convertDmp.convertChangesToDMP,exports.convertChangesToXML=_convertXml.convertChangesToXML,exports.canonicalize=_diffJson.canonicalize},function(module,exports){"use strict";function Diff(){}function buildValues(diff,components,newString,oldString,useLongestToken){for(var componentPos=0,componentLen=components.length,newPos=0,oldPos=0;componentLen>componentPos;componentPos++){var component=components[componentPos];if(component.removed){if(component.value=oldString.slice(oldPos,oldPos+component.count).join(""),oldPos+=component.count,componentPos&&components[componentPos-1].added){var tmp=components[componentPos-1];components[componentPos-1]=components[componentPos],components[componentPos]=tmp}}else{if(!component.added&&useLongestToken){var value=newString.slice(newPos,newPos+component.count);value=value.map(function(value,i){var oldValue=oldString[oldPos+i];return oldValue.length>value.length?oldValue:value}),component.value=value.join("")}else component.value=newString.slice(newPos,newPos+component.count).join("");newPos+=component.count,component.added||(oldPos+=component.count)}}var lastComponent=components[componentLen-1];return(lastComponent.added||lastComponent.removed)&&diff.equals("",lastComponent.value)&&(components[componentLen-2].value+=lastComponent.value,components.pop()),components}function clonePath(path){return{newPos:path.newPos,components:path.components.slice(0)}}exports.__esModule=!0,exports["default"]=Diff,Diff.prototype={diff:function(oldString,newString){function done(value){return callback?(setTimeout(function(){callback(void 0,value)},0),!0):value}function execEditLength(){for(var diagonalPath=-1*editLength;editLength>=diagonalPath;diagonalPath+=2){var basePath=void 0,addPath=bestPath[diagonalPath-1],removePath=bestPath[diagonalPath+1],_oldPos=(removePath?removePath.newPos:0)-diagonalPath;addPath&&(bestPath[diagonalPath-1]=void 0);var canAdd=addPath&&addPath.newPos+1=0&&oldLen>_oldPos;if(canAdd||canRemove){if(!canAdd||canRemove&&addPath.newPos=newLen&&_oldPos+1>=oldLen)return done(buildValues(self,basePath.components,newString,oldString,self.useLongestToken));bestPath[diagonalPath]=basePath}else bestPath[diagonalPath]=void 0}editLength++}var options=arguments.length<=2||void 0===arguments[2]?{}:arguments[2],callback=options.callback;"function"==typeof options&&(callback=options,options={}),this.options=options;var self=this;oldString=this.castInput(oldString),newString=this.castInput(newString),oldString=this.removeEmpty(this.tokenize(oldString)),newString=this.removeEmpty(this.tokenize(newString));var newLen=newString.length,oldLen=oldString.length,editLength=1,maxEditLength=newLen+oldLen,bestPath=[{newPos:-1,components:[]}],oldPos=this.extractCommon(bestPath[0],newString,oldString,0);if(bestPath[0].newPos+1>=newLen&&oldPos+1>=oldLen)return done([{value:newString.join(""),count:newString.length}]);if(callback)!function exec(){setTimeout(function(){return editLength>maxEditLength?callback():void(execEditLength()||exec())},0)}();else for(;maxEditLength>=editLength;){var ret=execEditLength();if(ret)return ret}},pushComponent:function(components,added,removed){var last=components[components.length-1];last&&last.added===added&&last.removed===removed?components[components.length-1]={count:last.count+1,added:added,removed:removed}:components.push({count:1,added:added,removed:removed})},extractCommon:function(basePath,newString,oldString,diagonalPath){for(var newLen=newString.length,oldLen=oldString.length,newPos=basePath.newPos,oldPos=newPos-diagonalPath,commonCount=0;newLen>newPos+1&&oldLen>oldPos+1&&this.equals(newString[newPos+1],oldString[oldPos+1]);)newPos++,oldPos++,commonCount++;return commonCount&&basePath.components.push({count:commonCount}),basePath.newPos=newPos,oldPos},equals:function(left,right){return left===right},removeEmpty:function(array){for(var ret=[],i=0;ifuzzFactor))return!1;toPos++}}return!0}var options=arguments.length<=2||void 0===arguments[2]?{}:arguments[2];if("string"==typeof uniDiff&&(uniDiff=_parse.parsePatch(uniDiff)),Array.isArray(uniDiff)){if(uniDiff.length>1)throw new Error("applyPatch only works with a single input.");uniDiff=uniDiff[0]}for(var lines=source.split("\n"),hunks=uniDiff.hunks,compareLine=options.compareLine||function(lineNumber,line,operation,patchContent){return line===patchContent},errorCount=0,fuzzFactor=options.fuzzFactor||0,minLine=0,offset=0,removeEOFNL=void 0,addEOFNL=void 0,i=0;i=start+localOffset)return localOffset;forwardExhausted=!0}if(backwardExhausted);else{if(forwardExhausted||(wantForward=!0),start-localOffset>=minLine)return-localOffset++;backwardExhausted=!0,_again=!0}}}},module.exports=exports["default"]},function(module,exports,__webpack_require__){"use strict";function _toConsumableArray(arr){if(Array.isArray(arr)){for(var i=0,arr2=Array(arr.length);i0?contextLines(prev.lines.slice(-options.context)):[],oldRangeStart-=curRange.length,newRangeStart-=curRange.length)}(_curRange=curRange).push.apply(_curRange,_toConsumableArray(lines.map(function(entry){return(current.added?"+":"-")+entry}))),current.added?newLine+=lines.length:oldLine+=lines.length}else{if(oldRangeStart)if(lines.length<=2*options.context&&i=diff.length-2&&lines.length<=options.context){var oldEOFNewline=/\n$/.test(oldStr),newEOFNewline=/\n$/.test(newStr);0!=lines.length||oldEOFNewline?oldEOFNewline&&newEOFNewline||curRange.push("\\ No newline at end of file"):curRange.splice(hunk.oldLines,0,"\\ No newline at end of file")}hunks.push(hunk),oldRangeStart=0,newRangeStart=0,curRange=[]}oldLine+=lines.length,newLine+=lines.length}},i=0;i"):change.removed&&ret.push(""),ret.push(escapeHTML(change.value)),change.added?ret.push(" "):change.removed&&ret.push("")}return ret.join("")}function escapeHTML(s){var n=s;return n=n.replace(/&/g,"&"),n=n.replace(//g,">"),n=n.replace(/"/g,""");
+!function(modules){function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={exports:{},id:moduleId,loaded:!1};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.loaded=!0,module.exports}var installedModules={};return __webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.p="",__webpack_require__(0)}([function(module,exports,__webpack_require__){(function(global){!function(){function Diff2Html(){}var diffParser=__webpack_require__(1).DiffParser,fileLister=__webpack_require__(3).FileListPrinter,htmlPrinter=__webpack_require__(21).HtmlPrinter;Diff2Html.prototype.getJsonFromDiff=function(diffInput){return diffParser.generateDiffJson(diffInput)},Diff2Html.prototype.getPrettyHtml=function(diffInput,config){var configOrEmpty=config||{},diffJson=diffInput;configOrEmpty.inputFormat&&"diff"!==configOrEmpty.inputFormat||(diffJson=diffParser.generateDiffJson(diffInput));var fileList="";configOrEmpty.showFiles===!0&&(fileList=fileLister.generateFileList(diffJson,configOrEmpty));var diffOutput="";return diffOutput="side-by-side"===configOrEmpty.outputFormat?htmlPrinter.generateSideBySideJsonHtml(diffJson,configOrEmpty):htmlPrinter.generateLineByLineJsonHtml(diffJson,configOrEmpty),fileList+diffOutput},Diff2Html.prototype.getPrettyHtmlFromDiff=function(diffInput,config){var configOrEmpty=config||{};return configOrEmpty.inputFormat="diff",configOrEmpty.outputFormat="line-by-line",this.getPrettyHtml(diffInput,configOrEmpty)},Diff2Html.prototype.getPrettyHtmlFromJson=function(diffJson,config){var configOrEmpty=config||{};return configOrEmpty.inputFormat="json",configOrEmpty.outputFormat="line-by-line",this.getPrettyHtml(diffJson,configOrEmpty)},Diff2Html.prototype.getPrettySideBySideHtmlFromDiff=function(diffInput,config){var configOrEmpty=config||{};return configOrEmpty.inputFormat="diff",configOrEmpty.outputFormat="side-by-side",this.getPrettyHtml(diffInput,configOrEmpty)},Diff2Html.prototype.getPrettySideBySideHtmlFromJson=function(diffJson,config){var configOrEmpty=config||{};return configOrEmpty.inputFormat="json",configOrEmpty.outputFormat="side-by-side",this.getPrettyHtml(diffJson,configOrEmpty)};var diffObject=new Diff2Html;module.exports.Diff2Html=diffObject,global.Diff2Html=diffObject}()}).call(exports,function(){return this}())},function(module,exports,__webpack_require__){!function(){function DiffParser(){}function getExtension(filename,language){var nameSplit=filename.split(".");return nameSplit.length>1?nameSplit[nameSplit.length-1]:language}var utils=__webpack_require__(2).Utils,LINE_TYPE={INSERTS:"d2h-ins",DELETES:"d2h-del",INSERT_CHANGES:"d2h-ins d2h-change",DELETE_CHANGES:"d2h-del d2h-change",CONTEXT:"d2h-cntx",INFO:"d2h-info"};DiffParser.prototype.LINE_TYPE=LINE_TYPE,DiffParser.prototype.generateDiffJson=function(diffInput){var files=[],currentFile=null,currentBlock=null,oldLine=null,newLine=null,saveBlock=function(){currentBlock&&(currentFile.blocks.push(currentBlock),currentBlock=null)},saveFile=function(){currentFile&¤tFile.newName&&(files.push(currentFile),currentFile=null)},startFile=function(){saveBlock(),saveFile(),currentFile={},currentFile.blocks=[],currentFile.deletedLines=0,currentFile.addedLines=0},startBlock=function(line){saveBlock();var values;(values=/^@@ -(\d+),\d+ \+(\d+),\d+ @@.*/.exec(line))?currentFile.isCombined=!1:(values=/^@@@ -(\d+),\d+ -\d+,\d+ \+(\d+),\d+ @@@.*/.exec(line))?currentFile.isCombined=!0:(values=[0,0],currentFile.isCombined=!1),oldLine=values[1],newLine=values[2],currentBlock={},currentBlock.lines=[],currentBlock.oldStartLine=oldLine,currentBlock.newStartLine=newLine,currentBlock.header=line},createLine=function(line){var currentLine={};currentLine.content=line;var newLinePrefixes=currentFile.isCombined?["+"," +"]:["+"],delLinePrefixes=currentFile.isCombined?["-"," -"]:["-"];utils.startsWith(line,newLinePrefixes)?(currentFile.addedLines++,currentLine.type=LINE_TYPE.INSERTS,currentLine.oldNumber=null,currentLine.newNumber=newLine++,currentBlock.lines.push(currentLine)):utils.startsWith(line,delLinePrefixes)?(currentFile.deletedLines++,currentLine.type=LINE_TYPE.DELETES,currentLine.oldNumber=oldLine++,currentLine.newNumber=null,currentBlock.lines.push(currentLine)):(currentLine.type=LINE_TYPE.CONTEXT,currentLine.oldNumber=oldLine++,currentLine.newNumber=newLine++,currentBlock.lines.push(currentLine))},diffLines=diffInput.replace(/\\ No newline at end of file/g,"").replace(/\r\n?/g,"\n").split("\n"),oldMode=/^old mode (\d{6})/,newMode=/^new mode (\d{6})/,deletedFileMode=/^deleted file mode (\d{6})/,newFileMode=/^new file mode (\d{6})/,copyFrom=/^copy from (.+)/,copyTo=/^copy to (.+)/,renameFrom=/^rename from (.+)/,renameTo=/^rename to (.+)/,similarityIndex=/^similarity index (\d+)%/,dissimilarityIndex=/^dissimilarity index (\d+)%/,index=/^index ([0-9a-z]+)..([0-9a-z]+) (\d{6})?/,combinedIndex=/^index ([0-9a-z]+),([0-9a-z]+)..([0-9a-z]+)/,combinedMode=/^mode (\d{6}),(\d{6})..(\d{6})/,combinedNewFile=/^new file mode (\d{6})/,combinedDeletedFile=/^deleted file mode (\d{6}),(\d{6})/;return diffLines.forEach(function(line){if(line&&!utils.startsWith(line,"*")){var values=[];utils.startsWith(line,"diff")?startFile():currentFile&&!currentFile.oldName&&(values=/^--- [aiwco]\/(.+)$/.exec(line))?(currentFile.oldName=values[1],currentFile.language=getExtension(currentFile.oldName,currentFile.language)):currentFile&&!currentFile.newName&&(values=/^\+\+\+ [biwco]?\/(.+)$/.exec(line))?(currentFile.newName=values[1],currentFile.language=getExtension(currentFile.newName,currentFile.language)):currentFile&&utils.startsWith(line,"@@")?startBlock(line):(values=oldMode.exec(line))?currentFile.oldMode=values[1]:(values=newMode.exec(line))?currentFile.newMode=values[1]:(values=deletedFileMode.exec(line))?currentFile.deletedFileMode=values[1]:(values=newFileMode.exec(line))?currentFile.newFileMode=values[1]:(values=copyFrom.exec(line))?(currentFile.oldName=values[1],currentFile.isCopy=!0):(values=copyTo.exec(line))?(currentFile.newName=values[1],currentFile.isCopy=!0):(values=renameFrom.exec(line))?(currentFile.oldName=values[1],currentFile.isRename=!0):(values=renameTo.exec(line))?(currentFile.newName=values[1],currentFile.isRename=!0):(values=similarityIndex.exec(line))?currentFile.unchangedPercentage=values[1]:(values=dissimilarityIndex.exec(line))?currentFile.changedPercentage=values[1]:(values=index.exec(line))?(currentFile.checksumBefore=values[1],currentFile.checksumAfter=values[2],values[2]&&(currentFile.mode=values[3])):(values=combinedIndex.exec(line))?(currentFile.checksumBefore=[values[2],values[3]],currentFile.checksumAfter=values[1]):(values=combinedMode.exec(line))?(currentFile.oldMode=[values[2],values[3]],currentFile.newMode=values[1]):(values=combinedNewFile.exec(line))?currentFile.newFileMode=values[1]:(values=combinedDeletedFile.exec(line))?currentFile.deletedFileMode=values[1]:currentBlock&&createLine(line)}}),saveBlock(),saveFile(),files},module.exports.DiffParser=new DiffParser}()},function(module){!function(){function Utils(){}Utils.prototype.convertWhiteSpaceToNonBreakingSpace=function(str){return str.slice(0).replace(/ /g," ")},Utils.prototype.escape=function(str){return str.slice(0).replace(/&/g,"&").replace(//g,">").replace(/\t/g," ")},Utils.prototype.startsWith=function(str,start){if("object"==typeof start){var result=!1;return start.forEach(function(s){0===str.indexOf(s)&&(result=!0)}),result}return 0===str.indexOf(start)},Utils.prototype.valueOrEmpty=function(value){return value?value:""},module.exports.Utils=new Utils}()},function(module,exports,__webpack_require__){!function(){function FileListPrinter(){}var printerUtils=__webpack_require__(4).PrinterUtils;FileListPrinter.prototype.generateFileList=function(diffFiles){return'\n"},module.exports.FileListPrinter=new FileListPrinter}()},function(module,exports,__webpack_require__){!function(){function PrinterUtils(){}function isDeletedName(name){return"dev/null"===name}function removeIns(line){return line.replace(/(]*>((.|\n)*?)<\/ins>)/g,"")}function removeDel(line){return line.replace(/(]*>((.|\n)*?)<\/del>)/g,"")}var jsDiff=__webpack_require__(5),utils=__webpack_require__(2).Utils,Rematch=__webpack_require__(20).Rematch;PrinterUtils.prototype.getHtmlId=function(file){var hashCode=function(text){var i,chr,len,hash=0;if(0===text.length)return hash;for(i=0,len=text.length;len>i;i++)chr=text.charCodeAt(i),hash=(hash<<5)-hash+chr,hash|=0;return hash};return"d2h-"+hashCode(this.getDiffName(file)).toString().slice(-6)},PrinterUtils.prototype.getDiffName=function(file){var oldFilename=file.oldName,newFilename=file.newName;return oldFilename&&newFilename&&oldFilename!==newFilename&&!isDeletedName(newFilename)?oldFilename+" -> "+newFilename:newFilename&&!isDeletedName(newFilename)?newFilename:oldFilename?oldFilename:"Unknown filename"},PrinterUtils.prototype.diffHighlight=function(diffLine1,diffLine2,config){var linePrefix1,linePrefix2,unprefixedLine1,unprefixedLine2,prefixSize=1;config.isCombined&&(prefixSize=2),linePrefix1=diffLine1.substr(0,prefixSize),linePrefix2=diffLine2.substr(0,prefixSize),unprefixedLine1=diffLine1.substr(prefixSize),unprefixedLine2=diffLine2.substr(prefixSize);var diff;diff=config.charByChar?jsDiff.diffChars(unprefixedLine1,unprefixedLine2):jsDiff.diffWordsWithSpace(unprefixedLine1,unprefixedLine2);var highlightedLine="",changedWords=[];if(!config.charByChar&&"words"===config.matching){var treshold=.25;"undefined"!=typeof config.matchWordsThreshold&&(treshold=config.matchWordsThreshold);var matcher=Rematch.rematch(function(a,b){var amod=a.value,bmod=b.value;return Rematch.distance(amod,bmod)}),removed=diff.filter(function(element){return element.removed}),added=diff.filter(function(element){return element.added}),chunks=matcher(added,removed);chunks.forEach(function(chunk){if(1===chunk[0].length&&1===chunk[1].length){var dist=Rematch.distance(chunk[0][0].value,chunk[1][0].value);treshold>dist&&(changedWords.push(chunk[0][0]),changedWords.push(chunk[1][0]))}})}return diff.forEach(function(part){var addClass=changedWords.indexOf(part)>-1?' class="d2h-change"':"",elemType=part.added?"ins":part.removed?"del":null,escapedValue=utils.escape(part.value);highlightedLine+=null!==elemType?"<"+elemType+addClass+">"+escapedValue+""+elemType+">":escapedValue}),{first:{prefix:linePrefix1,line:removeIns(highlightedLine)},second:{prefix:linePrefix2,line:removeDel(highlightedLine)}}},module.exports.PrinterUtils=new PrinterUtils}()},function(module,exports,__webpack_require__){"use strict";function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{"default":obj}}exports.__esModule=!0;var _diffBase=__webpack_require__(6),_diffBase2=_interopRequireDefault(_diffBase),_diffCharacter=__webpack_require__(7),_diffWord=__webpack_require__(8),_diffLine=__webpack_require__(10),_diffSentence=__webpack_require__(11),_diffCss=__webpack_require__(12),_diffJson=__webpack_require__(13),_patchApply=__webpack_require__(14),_patchParse=__webpack_require__(15),_patchCreate=__webpack_require__(17),_convertDmp=__webpack_require__(18),_convertXml=__webpack_require__(19);exports.Diff=_diffBase2["default"],exports.diffChars=_diffCharacter.diffChars,exports.diffWords=_diffWord.diffWords,exports.diffWordsWithSpace=_diffWord.diffWordsWithSpace,exports.diffLines=_diffLine.diffLines,exports.diffTrimmedLines=_diffLine.diffTrimmedLines,exports.diffSentences=_diffSentence.diffSentences,exports.diffCss=_diffCss.diffCss,exports.diffJson=_diffJson.diffJson,exports.structuredPatch=_patchCreate.structuredPatch,exports.createTwoFilesPatch=_patchCreate.createTwoFilesPatch,exports.createPatch=_patchCreate.createPatch,exports.applyPatch=_patchApply.applyPatch,exports.applyPatches=_patchApply.applyPatches,exports.parsePatch=_patchParse.parsePatch,exports.convertChangesToDMP=_convertDmp.convertChangesToDMP,exports.convertChangesToXML=_convertXml.convertChangesToXML,exports.canonicalize=_diffJson.canonicalize},function(module,exports){"use strict";function Diff(){}function buildValues(diff,components,newString,oldString,useLongestToken){for(var componentPos=0,componentLen=components.length,newPos=0,oldPos=0;componentLen>componentPos;componentPos++){var component=components[componentPos];if(component.removed){if(component.value=oldString.slice(oldPos,oldPos+component.count).join(""),oldPos+=component.count,componentPos&&components[componentPos-1].added){var tmp=components[componentPos-1];components[componentPos-1]=components[componentPos],components[componentPos]=tmp}}else{if(!component.added&&useLongestToken){var value=newString.slice(newPos,newPos+component.count);value=value.map(function(value,i){var oldValue=oldString[oldPos+i];return oldValue.length>value.length?oldValue:value}),component.value=value.join("")}else component.value=newString.slice(newPos,newPos+component.count).join("");newPos+=component.count,component.added||(oldPos+=component.count)}}var lastComponent=components[componentLen-1];return(lastComponent.added||lastComponent.removed)&&diff.equals("",lastComponent.value)&&(components[componentLen-2].value+=lastComponent.value,components.pop()),components}function clonePath(path){return{newPos:path.newPos,components:path.components.slice(0)}}exports.__esModule=!0,exports["default"]=Diff,Diff.prototype={diff:function(oldString,newString){function done(value){return callback?(setTimeout(function(){callback(void 0,value)},0),!0):value}function execEditLength(){for(var diagonalPath=-1*editLength;editLength>=diagonalPath;diagonalPath+=2){var basePath=void 0,addPath=bestPath[diagonalPath-1],removePath=bestPath[diagonalPath+1],_oldPos=(removePath?removePath.newPos:0)-diagonalPath;addPath&&(bestPath[diagonalPath-1]=void 0);var canAdd=addPath&&addPath.newPos+1=0&&oldLen>_oldPos;if(canAdd||canRemove){if(!canAdd||canRemove&&addPath.newPos=newLen&&_oldPos+1>=oldLen)return done(buildValues(self,basePath.components,newString,oldString,self.useLongestToken));bestPath[diagonalPath]=basePath}else bestPath[diagonalPath]=void 0}editLength++}var options=arguments.length<=2||void 0===arguments[2]?{}:arguments[2],callback=options.callback;"function"==typeof options&&(callback=options,options={}),this.options=options;var self=this;oldString=this.castInput(oldString),newString=this.castInput(newString),oldString=this.removeEmpty(this.tokenize(oldString)),newString=this.removeEmpty(this.tokenize(newString));var newLen=newString.length,oldLen=oldString.length,editLength=1,maxEditLength=newLen+oldLen,bestPath=[{newPos:-1,components:[]}],oldPos=this.extractCommon(bestPath[0],newString,oldString,0);if(bestPath[0].newPos+1>=newLen&&oldPos+1>=oldLen)return done([{value:newString.join(""),count:newString.length}]);if(callback)!function exec(){setTimeout(function(){return editLength>maxEditLength?callback():void(execEditLength()||exec())},0)}();else for(;maxEditLength>=editLength;){var ret=execEditLength();if(ret)return ret}},pushComponent:function(components,added,removed){var last=components[components.length-1];last&&last.added===added&&last.removed===removed?components[components.length-1]={count:last.count+1,added:added,removed:removed}:components.push({count:1,added:added,removed:removed})},extractCommon:function(basePath,newString,oldString,diagonalPath){for(var newLen=newString.length,oldLen=oldString.length,newPos=basePath.newPos,oldPos=newPos-diagonalPath,commonCount=0;newLen>newPos+1&&oldLen>oldPos+1&&this.equals(newString[newPos+1],oldString[oldPos+1]);)newPos++,oldPos++,commonCount++;return commonCount&&basePath.components.push({count:commonCount}),basePath.newPos=newPos,oldPos},equals:function(left,right){return left===right},removeEmpty:function(array){for(var ret=[],i=0;ifuzzFactor))return!1;toPos++}}return!0}var options=arguments.length<=2||void 0===arguments[2]?{}:arguments[2];if("string"==typeof uniDiff&&(uniDiff=_parse.parsePatch(uniDiff)),Array.isArray(uniDiff)){if(uniDiff.length>1)throw new Error("applyPatch only works with a single input.");uniDiff=uniDiff[0]}for(var lines=source.split("\n"),hunks=uniDiff.hunks,compareLine=options.compareLine||function(lineNumber,line,operation,patchContent){return line===patchContent},errorCount=0,fuzzFactor=options.fuzzFactor||0,minLine=0,offset=0,removeEOFNL=void 0,addEOFNL=void 0,i=0;i=start+localOffset)return localOffset;forwardExhausted=!0}if(backwardExhausted);else{if(forwardExhausted||(wantForward=!0),start-localOffset>=minLine)return-localOffset++;backwardExhausted=!0,_again=!0}}}},module.exports=exports["default"]},function(module,exports,__webpack_require__){"use strict";function _toConsumableArray(arr){if(Array.isArray(arr)){for(var i=0,arr2=Array(arr.length);i0?contextLines(prev.lines.slice(-options.context)):[],oldRangeStart-=curRange.length,newRangeStart-=curRange.length)}(_curRange=curRange).push.apply(_curRange,_toConsumableArray(lines.map(function(entry){return(current.added?"+":"-")+entry}))),current.added?newLine+=lines.length:oldLine+=lines.length}else{if(oldRangeStart)if(lines.length<=2*options.context&&i=diff.length-2&&lines.length<=options.context){var oldEOFNewline=/\n$/.test(oldStr),newEOFNewline=/\n$/.test(newStr);0!=lines.length||oldEOFNewline?oldEOFNewline&&newEOFNewline||curRange.push("\\ No newline at end of file"):curRange.splice(hunk.oldLines,0,"\\ No newline at end of file")}hunks.push(hunk),oldRangeStart=0,newRangeStart=0,curRange=[]}oldLine+=lines.length,newLine+=lines.length}},i=0;i"):change.removed&&ret.push(""),ret.push(escapeHTML(change.value)),change.added?ret.push(" "):change.removed&&ret.push("")}return ret.join("")}function escapeHTML(s){var n=s;
-}exports.__esModule=!0,exports.convertChangesToXML=convertChangesToXML},function(module){!function(){function levenshtein(a,b){if(0==a.length)return b.length;if(0==b.length)return a.length;var i,matrix=[];for(i=0;i<=b.length;i++)matrix[i]=[i];var j;for(j=0;j<=a.length;j++)matrix[0][j]=j;for(i=1;i<=b.length;i++)for(j=1;j<=a.length;j++)matrix[i][j]=b.charAt(i-1)==a.charAt(j-1)?matrix[i-1][j-1]:Math.min(matrix[i-1][j-1]+1,Math.min(matrix[i][j-1]+1,matrix[i-1][j]+1));return matrix[b.length][a.length]}var Rematch={};Rematch.arrayToString=function arrayToString(a){return"[object Array]"===Object.prototype.toString.apply(a,[])?"["+a.map(arrayToString).join(", ")+"]":a},Rematch.levenshtein=levenshtein,Rematch.distance=function(x,y){x=x.trim(),y=y.trim();var lev=levenshtein(x,y),score=lev/(x.length+y.length);return score},Rematch.rematch=function(distanceFunction){function findBestMatch(a,b,cache){var cachecount=0;for(var key in cache)cachecount++;for(var bestMatch,bestMatchDist=1/0,i=0;imd&&(bestMatchDist=md,bestMatch={indexA:i,indexB:j,score:bestMatchDist})}return bestMatch}function group(a,b,level,cache){"undefined"==typeof cache&&(cache={});var bm=findBestMatch(a,b,cache);if(level||(level=0),!bm||a.length+b.length<3)return[[a,b]];var a1=a.slice(0,bm.indexA),b1=b.slice(0,bm.indexB),aMatch=[a[bm.indexA]],bMatch=[b[bm.indexB]],tailA=bm.indexA+1,tailB=bm.indexB+1,a2=a.slice(tailA),b2=b.slice(tailB),group1=group(a1,b1,level+1,cache),groupMatch=group(aMatch,bMatch,level+1,cache),group2=group(a2,b2,level+1,cache),result=groupMatch;return(bm.indexA>0||bm.indexB>0)&&(result=group1.concat(result)),(a.length>tailA||b.length>tailB)&&(result=result.concat(group2)),result}return group},module.exports.Rematch=Rematch}()},function(module,exports,__webpack_require__){!function(){function HtmlPrinter(){}var LineByLinePrinter=__webpack_require__(22).LineByLinePrinter,SideBySidePrinter=__webpack_require__(23).SideBySidePrinter;HtmlPrinter.prototype.generateLineByLineJsonHtml=function(diffFiles,config){var lineByLinePrinter=new LineByLinePrinter(config);return lineByLinePrinter.generateLineByLineJsonHtml(diffFiles)},HtmlPrinter.prototype.generateSideBySideJsonHtml=function(diffFiles,config){var sideBySidePrinter=new SideBySidePrinter(config);return sideBySidePrinter.generateSideBySideJsonHtml(diffFiles)},module.exports.HtmlPrinter=new HtmlPrinter}()},function(module,exports,__webpack_require__){!function(){function LineByLinePrinter(config){this.config=config}var diffParser=__webpack_require__(1).DiffParser,printerUtils=__webpack_require__(4).PrinterUtils,utils=__webpack_require__(2).Utils,Rematch=__webpack_require__(20).Rematch;LineByLinePrinter.prototype.makeFileDiffHtml=function(file,diffs){return'\n"},LineByLinePrinter.prototype.generateLineByLineJsonHtml=function(diffFiles){var that=this,htmlDiffs=diffFiles.map(function(file){var diffs;return diffs=file.blocks.length?that._generateFileHtml(file):that._generateEmptyDiff(),that.makeFileDiffHtml(file,diffs)});return'\n'+htmlDiffs.join("\n")+"
\n"};var matcher=Rematch.rematch(function(a,b){var amod=a.content.substr(1),bmod=b.content.substr(1);return Rematch.distance(amod,bmod)});LineByLinePrinter.prototype.makeColumnLineNumberHtml=function(block){return'\n \n '+utils.escape(block.header)+"
\n \n"},LineByLinePrinter.prototype._generateFileHtml=function(file){var that=this;return file.blocks.map(function(block){function processChangeBlock(){var matches,insertType,deleteType,doMatching="lines"===that.config.matching||"words"===that.config.matching;doMatching?(matches=matcher(oldLines,newLines),insertType=diffParser.LINE_TYPE.INSERT_CHANGES,deleteType=diffParser.LINE_TYPE.DELETE_CHANGES):(matches=[[oldLines,newLines]],insertType=diffParser.LINE_TYPE.INSERTS,deleteType=diffParser.LINE_TYPE.DELETES),matches.forEach(function(match){oldLines=match[0],newLines=match[1];for(var oldLine,newLine,processedOldLines=[],processedNewLines=[],common=Math.min(oldLines.length,newLines.length),j=0;common>j;j++){oldLine=oldLines[j],newLine=newLines[j],that.config.isCombined=file.isCombined;var diff=printerUtils.diffHighlight(oldLine.content,newLine.content,that.config);processedOldLines+=that._generateLineHtml(deleteType,oldLine.oldNumber,oldLine.newNumber,diff.first.line,diff.first.prefix),processedNewLines+=that._generateLineHtml(insertType,newLine.oldNumber,newLine.newNumber,diff.second.line,diff.second.prefix)}lines+=processedOldLines+processedNewLines,lines+=that._processLines(oldLines.slice(common),newLines.slice(common))}),oldLines=[],newLines=[]}for(var lines=that.makeColumnLineNumberHtml(block),oldLines=[],newLines=[],i=0;i0||line.type!==diffParser.LINE_TYPE.DELETES&&oldLines.length>0)&&processChangeBlock(),line.type===diffParser.LINE_TYPE.CONTEXT?lines+=that._generateLineHtml(line.type,line.oldNumber,line.newNumber,escapedLine):line.type!==diffParser.LINE_TYPE.INSERTS||oldLines.length?line.type===diffParser.LINE_TYPE.DELETES?oldLines.push(line):line.type===diffParser.LINE_TYPE.INSERTS&&Boolean(oldLines.length)?newLines.push(line):(console.error("Unknown state in html line-by-line generator"),processChangeBlock()):lines+=that._generateLineHtml(line.type,line.oldNumber,line.newNumber,escapedLine)}return processChangeBlock(),lines}).join("\n")},LineByLinePrinter.prototype._processLines=function(oldLines,newLines){for(var lines="",i=0;i\n '+utils.valueOrEmpty(oldNumber)+'
'+utils.valueOrEmpty(newNumber)+'
\n '+htmlPrefix+htmlContent+"
\n\n"},LineByLinePrinter.prototype._generateLineHtml=function(type,oldNumber,newNumber,content,prefix){var htmlPrefix="";prefix&&(htmlPrefix=''+prefix+" ");var htmlContent="";return content&&(htmlContent=''+content+" "),this.makeLineHtml(type,oldNumber,newNumber,htmlPrefix,htmlContent)},LineByLinePrinter.prototype._generateEmptyDiff=function(){return'\n File without changes
\n \n'},module.exports.LineByLinePrinter=LineByLinePrinter}()},function(module,exports,__webpack_require__){!function(){function SideBySidePrinter(config){this.config=config}var diffParser=__webpack_require__(1).DiffParser,printerUtils=__webpack_require__(4).PrinterUtils,utils=__webpack_require__(2).Utils,Rematch=__webpack_require__(20).Rematch,matcher=Rematch.rematch(function(a,b){var amod=a.content.substr(1),bmod=b.content.substr(1);return Rematch.distance(amod,bmod)});SideBySidePrinter.prototype.makeDiffHtml=function(file,diffs){return'\n"},SideBySidePrinter.prototype.generateSideBySideJsonHtml=function(diffFiles){var that=this;return'\n'+diffFiles.map(function(file){var diffs;return diffs=file.blocks.length?that.generateSideBySideFileHtml(file):that.generateEmptyDiff(),that.makeDiffHtml(file,diffs)}).join("\n")+"
\n"},SideBySidePrinter.prototype.makeSideHtml=function(blockHeader){return'\n \n \n '+blockHeader+"
\n \n \n"},SideBySidePrinter.prototype.generateSideBySideFileHtml=function(file){var that=this,fileHtml={};return fileHtml.left="",fileHtml.right="",file.blocks.forEach(function(block){function processChangeBlock(){var matches,insertType,deleteType,doMatching="lines"===that.config.matching||"words"===that.config.matching;doMatching?(matches=matcher(oldLines,newLines),insertType=diffParser.LINE_TYPE.INSERT_CHANGES,deleteType=diffParser.LINE_TYPE.DELETE_CHANGES):(matches=[[oldLines,newLines]],insertType=diffParser.LINE_TYPE.INSERTS,deleteType=diffParser.LINE_TYPE.DELETES),matches.forEach(function(match){oldLines=match[0],newLines=match[1];for(var common=Math.min(oldLines.length,newLines.length),max=Math.max(oldLines.length,newLines.length),j=0;common>j;j++){var oldLine=oldLines[j],newLine=newLines[j];that.config.isCombined=file.isCombined;var diff=printerUtils.diffHighlight(oldLine.content,newLine.content,that.config);fileHtml.left+=that.generateSingleLineHtml(deleteType,oldLine.oldNumber,diff.first.line,diff.first.prefix),fileHtml.right+=that.generateSingleLineHtml(insertType,newLine.newNumber,diff.second.line,diff.second.prefix)}if(max>common){var oldSlice=oldLines.slice(common),newSlice=newLines.slice(common),tmpHtml=that.processLines(oldSlice,newSlice);fileHtml.left+=tmpHtml.left,fileHtml.right+=tmpHtml.right}}),oldLines=[],newLines=[]}fileHtml.left+=that.makeSideHtml(utils.escape(block.header)),fileHtml.right+=that.makeSideHtml("");for(var oldLines=[],newLines=[],i=0;i0||line.type!==diffParser.LINE_TYPE.DELETES&&oldLines.length>0)&&processChangeBlock(),line.type===diffParser.LINE_TYPE.CONTEXT?(fileHtml.left+=that.generateSingleLineHtml(line.type,line.oldNumber,escapedLine,prefix),fileHtml.right+=that.generateSingleLineHtml(line.type,line.newNumber,escapedLine,prefix)):line.type!==diffParser.LINE_TYPE.INSERTS||oldLines.length?line.type===diffParser.LINE_TYPE.DELETES?oldLines.push(line):line.type===diffParser.LINE_TYPE.INSERTS&&Boolean(oldLines.length)?newLines.push(line):(console.error("unknown state in html side-by-side generator"),processChangeBlock()):(fileHtml.left+=that.generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT,"","",""),fileHtml.right+=that.generateSingleLineHtml(line.type,line.newNumber,escapedLine,prefix))}processChangeBlock()}),fileHtml},SideBySidePrinter.prototype.processLines=function(oldLines,newLines){var that=this,fileHtml={};fileHtml.left="",fileHtml.right="";for(var maxLinesNumber=Math.max(oldLines.length,newLines.length),i=0;maxLinesNumber>i;i++){var oldContent,newContent,oldPrefix,newPrefix,oldLine=oldLines[i],newLine=newLines[i];oldLine&&(oldContent=utils.escape(oldLine.content.substr(1)),oldPrefix=oldLine.content[0]),newLine&&(newContent=utils.escape(newLine.content.substr(1)),newPrefix=newLine.content[0]),oldLine&&newLine?(fileHtml.left+=that.generateSingleLineHtml(oldLine.type,oldLine.oldNumber,oldContent,oldPrefix),fileHtml.right+=that.generateSingleLineHtml(newLine.type,newLine.newNumber,newContent,newPrefix)):oldLine?(fileHtml.left+=that.generateSingleLineHtml(oldLine.type,oldLine.oldNumber,oldContent,oldPrefix),fileHtml.right+=that.generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT,"","","")):newLine?(fileHtml.left+=that.generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT,"","",""),fileHtml.right+=that.generateSingleLineHtml(newLine.type,newLine.newNumber,newContent,newPrefix)):console.error("How did it get here?")}return fileHtml},SideBySidePrinter.prototype.makeSingleLineHtml=function(type,number,htmlContent,htmlPrefix){return'\n '+number+' \n '+htmlPrefix+htmlContent+"
\n \n"},SideBySidePrinter.prototype.generateSingleLineHtml=function(type,number,content,prefix){var htmlPrefix="";prefix&&(htmlPrefix=''+prefix+" ");var htmlContent="";return content&&(htmlContent=''+content+" "),this.makeSingleLineHtml(type,number,htmlContent,htmlPrefix)},SideBySidePrinter.prototype.generateEmptyDiff=function(){var fileHtml={};return fileHtml.right="",fileHtml.left='\n File without changes
\n \n',fileHtml},module.exports.SideBySidePrinter=SideBySidePrinter}()}]);
\ No newline at end of file
+return n=n.replace(/&/g,"&"),n=n.replace(//g,">"),n=n.replace(/"/g,""")}exports.__esModule=!0,exports.convertChangesToXML=convertChangesToXML},function(module){!function(){function levenshtein(a,b){if(0==a.length)return b.length;if(0==b.length)return a.length;var i,matrix=[];for(i=0;i<=b.length;i++)matrix[i]=[i];var j;for(j=0;j<=a.length;j++)matrix[0][j]=j;for(i=1;i<=b.length;i++)for(j=1;j<=a.length;j++)matrix[i][j]=b.charAt(i-1)==a.charAt(j-1)?matrix[i-1][j-1]:Math.min(matrix[i-1][j-1]+1,Math.min(matrix[i][j-1]+1,matrix[i-1][j]+1));return matrix[b.length][a.length]}var Rematch={};Rematch.arrayToString=function arrayToString(a){return"[object Array]"===Object.prototype.toString.apply(a,[])?"["+a.map(arrayToString).join(", ")+"]":a},Rematch.levenshtein=levenshtein,Rematch.distance=function(x,y){x=x.trim(),y=y.trim();var lev=levenshtein(x,y),score=lev/(x.length+y.length);return score},Rematch.rematch=function(distanceFunction){function findBestMatch(a,b,cache){var cachecount=0;for(var key in cache)cachecount++;for(var bestMatch,bestMatchDist=1/0,i=0;imd&&(bestMatchDist=md,bestMatch={indexA:i,indexB:j,score:bestMatchDist})}return bestMatch}function group(a,b,level,cache){"undefined"==typeof cache&&(cache={});var bm=findBestMatch(a,b,cache);if(level||(level=0),!bm||a.length+b.length<3)return[[a,b]];var a1=a.slice(0,bm.indexA),b1=b.slice(0,bm.indexB),aMatch=[a[bm.indexA]],bMatch=[b[bm.indexB]],tailA=bm.indexA+1,tailB=bm.indexB+1,a2=a.slice(tailA),b2=b.slice(tailB),group1=group(a1,b1,level+1,cache),groupMatch=group(aMatch,bMatch,level+1,cache),group2=group(a2,b2,level+1,cache),result=groupMatch;return(bm.indexA>0||bm.indexB>0)&&(result=group1.concat(result)),(a.length>tailA||b.length>tailB)&&(result=result.concat(group2)),result}return group},module.exports.Rematch=Rematch}()},function(module,exports,__webpack_require__){!function(){function HtmlPrinter(){}var LineByLinePrinter=__webpack_require__(22).LineByLinePrinter,SideBySidePrinter=__webpack_require__(39).SideBySidePrinter;HtmlPrinter.prototype.generateLineByLineJsonHtml=function(diffFiles,config){var lineByLinePrinter=new LineByLinePrinter(config);return lineByLinePrinter.generateLineByLineJsonHtml(diffFiles)},HtmlPrinter.prototype.generateSideBySideJsonHtml=function(diffFiles,config){var sideBySidePrinter=new SideBySidePrinter(config);return sideBySidePrinter.generateSideBySideJsonHtml(diffFiles)},module.exports.HtmlPrinter=new HtmlPrinter}()},function(module,exports,__webpack_require__){!function(){function LineByLinePrinter(config){this.config=config}var diffParser=__webpack_require__(1).DiffParser,printerUtils=__webpack_require__(4).PrinterUtils,utils=__webpack_require__(2).Utils,Rematch=__webpack_require__(20).Rematch,nunjucksUtils=__webpack_require__(23).NunjucksUtils,baseTemplatesPath="line-by-line";LineByLinePrinter.prototype.makeFileDiffHtml=function(file,diffs){return nunjucksUtils.render(baseTemplatesPath,"file-diff.html",{file:file,diffs:diffs})},LineByLinePrinter.prototype.makeLineByLineHtmlWrapper=function(content){return nunjucksUtils.render(baseTemplatesPath,"wrapper.html",{content:content})},LineByLinePrinter.prototype.generateLineByLineJsonHtml=function(diffFiles){var that=this,htmlDiffs=diffFiles.map(function(file){var diffs;return diffs=file.blocks.length?that._generateFileHtml(file):that._generateEmptyDiff(),that.makeFileDiffHtml(file,diffs)});return this.makeLineByLineHtmlWrapper(htmlDiffs.join("\n"))};var matcher=Rematch.rematch(function(a,b){var amod=a.content.substr(1),bmod=b.content.substr(1);return Rematch.distance(amod,bmod)});LineByLinePrinter.prototype.makeColumnLineNumberHtml=function(block){return nunjucksUtils.render(baseTemplatesPath,"column-line-number.html",{block:block})},LineByLinePrinter.prototype._generateFileHtml=function(file){var that=this;return file.blocks.map(function(block){function processChangeBlock(){var matches,insertType,deleteType,doMatching="lines"===that.config.matching||"words"===that.config.matching;doMatching?(matches=matcher(oldLines,newLines),insertType=diffParser.LINE_TYPE.INSERT_CHANGES,deleteType=diffParser.LINE_TYPE.DELETE_CHANGES):(matches=[[oldLines,newLines]],insertType=diffParser.LINE_TYPE.INSERTS,deleteType=diffParser.LINE_TYPE.DELETES),matches.forEach(function(match){oldLines=match[0],newLines=match[1];for(var oldLine,newLine,processedOldLines=[],processedNewLines=[],common=Math.min(oldLines.length,newLines.length),j=0;common>j;j++){oldLine=oldLines[j],newLine=newLines[j],that.config.isCombined=file.isCombined;var diff=printerUtils.diffHighlight(oldLine.content,newLine.content,that.config);processedOldLines+=that.makeLineHtml(deleteType,oldLine.oldNumber,oldLine.newNumber,diff.first.line,diff.first.prefix),processedNewLines+=that.makeLineHtml(insertType,newLine.oldNumber,newLine.newNumber,diff.second.line,diff.second.prefix)}lines+=processedOldLines+processedNewLines,lines+=that._processLines(oldLines.slice(common),newLines.slice(common))}),oldLines=[],newLines=[]}for(var lines=that.makeColumnLineNumberHtml(block),oldLines=[],newLines=[],i=0;i0||line.type!==diffParser.LINE_TYPE.DELETES&&oldLines.length>0)&&processChangeBlock(),line.type===diffParser.LINE_TYPE.CONTEXT?lines+=that.makeLineHtml(line.type,line.oldNumber,line.newNumber,escapedLine):line.type!==diffParser.LINE_TYPE.INSERTS||oldLines.length?line.type===diffParser.LINE_TYPE.DELETES?oldLines.push(line):line.type===diffParser.LINE_TYPE.INSERTS&&Boolean(oldLines.length)?newLines.push(line):(console.error("Unknown state in html line-by-line generator"),processChangeBlock()):lines+=that.makeLineHtml(line.type,line.oldNumber,line.newNumber,escapedLine)}return processChangeBlock(),lines}).join("\n")},LineByLinePrinter.prototype._processLines=function(oldLines,newLines){for(var lines="",i=0;i=0;i--){var last=parts[i];"."===last?parts.splice(i,1):".."===last?(parts.splice(i,1),up++):up&&(parts.splice(i,1),up--)}if(allowAboveRoot)for(;up--;up)parts.unshift("..");return parts}function filter(xs,f){if(xs.filter)return xs.filter(f);for(var res=[],i=0;i=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:process.cwd();if("string"!=typeof path)throw new TypeError("Arguments to path.resolve must be strings");path&&(resolvedPath=path+"/"+resolvedPath,resolvedAbsolute="/"===path.charAt(0))}return resolvedPath=normalizeArray(filter(resolvedPath.split("/"),function(p){return!!p}),!resolvedAbsolute).join("/"),(resolvedAbsolute?"/":"")+resolvedPath||"."},exports.normalize=function(path){var isAbsolute=exports.isAbsolute(path),trailingSlash="/"===substr(path,-1);return path=normalizeArray(filter(path.split("/"),function(p){return!!p}),!isAbsolute).join("/"),path||isAbsolute||(path="."),path&&trailingSlash&&(path+="/"),(isAbsolute?"/":"")+path},exports.isAbsolute=function(path){return"/"===path.charAt(0)},exports.join=function(){var paths=Array.prototype.slice.call(arguments,0);return exports.normalize(filter(paths,function(p){if("string"!=typeof p)throw new TypeError("Arguments to path.join must be strings");return p}).join("/"))},exports.relative=function(from,to){function trim(arr){for(var start=0;start=0&&""===arr[end];end--);return start>end?[]:arr.slice(start,end-start+1)}from=exports.resolve(from).substr(1),to=exports.resolve(to).substr(1);for(var fromParts=trim(from.split("/")),toParts=trim(to.split("/")),length=Math.min(fromParts.length,toParts.length),samePartsLength=length,i=0;length>i;i++)if(fromParts[i]!==toParts[i]){samePartsLength=i;break}for(var outputParts=[],i=samePartsLength;istart&&(start=str.length+start),str.substr(start,len)}}).call(exports,__webpack_require__(25))},function(module){function cleanUpNextTick(){draining=!1,currentQueue.length?queue=currentQueue.concat(queue):queueIndex=-1,queue.length&&drainQueue()}function drainQueue(){if(!draining){var timeout=setTimeout(cleanUpNextTick);draining=!0;for(var len=queue.length;len;){for(currentQueue=queue,queue=[];++queueIndex1)for(var i=1;i":">"},escapeRegex=/[&"'<>]/g,lookupEscape=function(ch){return escapeMap[ch]},exports=module.exports={};exports.prettifyError=function(path,withInternals,err){if(err.Update||(err=new exports.TemplateError(err)),err.Update(path),!withInternals){var old=err;err=new Error(old.message),err.name=old.name}return err},exports.TemplateError=function(message,lineno,colno){var err=this;if(message instanceof Error){err=message,message=message.name+": "+message.message;try{err.name=""}catch(e){err=this}}else Error.captureStackTrace&&Error.captureStackTrace(err);return err.name="Template render error",err.message=message,err.lineno=lineno,err.colno=colno,err.firstUpdate=!0,err.Update=function(path){var message="("+(path||"unknown path")+")";return this.firstUpdate&&(this.lineno&&this.colno?message+=" [Line "+this.lineno+", Column "+this.colno+"]":this.lineno&&(message+=" [Line "+this.lineno+"]")),message+="\n ",this.firstUpdate&&(message+=" "),this.message=message+(this.message||""),this.firstUpdate=!1,this},err},exports.TemplateError.prototype=Error.prototype,exports.escape=function(val){return val.replace(escapeRegex,lookupEscape)},exports.isFunction=function(obj){return"[object Function]"===ObjProto.toString.call(obj)},exports.isArray=Array.isArray||function(obj){return"[object Array]"===ObjProto.toString.call(obj)},exports.isString=function(obj){return"[object String]"===ObjProto.toString.call(obj)},exports.isObject=function(obj){return"[object Object]"===ObjProto.toString.call(obj)},exports.groupBy=function(obj,val){for(var result={},iterator=exports.isFunction(val)?val:function(obj){return obj[val]},i=0;ii;i++)str+=char_;return str},exports.each=function(obj,func,context){if(null!=obj)if(ArrayProto.each&&obj.each===ArrayProto.each)obj.forEach(func,context);else if(obj.length===+obj.length)for(var i=0,l=obj.length;l>i;i++)func.call(context,obj[i],i,obj)},exports.map=function(obj,func){var results=[];if(null==obj)return results;if(ArrayProto.map&&obj.map===ArrayProto.map)return obj.map(func);for(var i=0;ii?iter(k,obj[k],i,len,next):cb()}var keys=exports.keys(obj),len=keys.length,i=-1;next()},exports.indexOf=Array.prototype.indexOf?function(arr,searchElement,fromIndex){return Array.prototype.indexOf.call(arr,searchElement,fromIndex)}:function(arr,searchElement,fromIndex){var length=this.length>>>0;for(fromIndex=+fromIndex||0,Math.abs(fromIndex)===1/0&&(fromIndex=0),0>fromIndex&&(fromIndex+=length,0>fromIndex&&(fromIndex=0));length>fromIndex;fromIndex++)if(arr[fromIndex]===searchElement)return fromIndex;return-1},Array.prototype.map||(Array.prototype.map=function(){throw new Error("map is unimplemented for this js engine")}),exports.keys=function(obj){if(Object.prototype.keys)return obj.keys();var keys=[];for(var k in obj)obj.hasOwnProperty(k)&&keys.push(k);return keys}},function(module,exports,__webpack_require__){"use strict";function callbackAsap(cb,err,res){asap(function(){cb(err,res)})}var Template,path=__webpack_require__(24),asap=__webpack_require__(29),lib=__webpack_require__(27),Obj=__webpack_require__(31),compiler=__webpack_require__(32),builtin_filters=__webpack_require__(33),builtin_loaders=__webpack_require__(32),runtime=__webpack_require__(34),globals=__webpack_require__(35),Frame=runtime.Frame;builtin_loaders.PrecompiledLoader=__webpack_require__(36);var Environment=Obj.extend({init:function(loaders,opts){opts=this.opts=opts||{},this.opts.dev=!!opts.dev,this.opts.autoescape=null!=opts.autoescape?opts.autoescape:!0,this.opts.throwOnUndefined=!!opts.throwOnUndefined,this.opts.trimBlocks=!!opts.trimBlocks,this.opts.lstripBlocks=!!opts.lstripBlocks,this.loaders=[],loaders?this.loaders=lib.isArray(loaders)?loaders:[loaders]:builtin_loaders.FileSystemLoader?this.loaders=[new builtin_loaders.FileSystemLoader("views")]:builtin_loaders.WebLoader&&(this.loaders=[new builtin_loaders.WebLoader("/views")]),window.nunjucksPrecompiled&&this.loaders.unshift(new builtin_loaders.PrecompiledLoader(window.nunjucksPrecompiled)),this.initCache(),this.globals=globals(),this.filters={},this.asyncFilters=[],this.extensions={},this.extensionsList=[];for(var name in builtin_filters)this.addFilter(name,builtin_filters[name])},initCache:function(){lib.each(this.loaders,function(loader){loader.cache={},"function"==typeof loader.on&&loader.on("update",function(template){loader.cache[template]=null})})},addExtension:function(name,extension){return extension._name=name,this.extensions[name]=extension,this.extensionsList.push(extension),this},removeExtension:function(name){var extension=this.getExtension(name);extension&&(this.extensionsList=lib.without(this.extensionsList,extension),delete this.extensions[name])},getExtension:function(name){return this.extensions[name]},hasExtension:function(name){return!!this.extensions[name]},addGlobal:function(name,value){return this.globals[name]=value,this},getGlobal:function(name){if(!this.globals[name])throw new Error("global not found: "+name);return this.globals[name]},addFilter:function(name,func,async){var wrapped=func;return async&&this.asyncFilters.push(name),this.filters[name]=wrapped,this},getFilter:function(name){if(!this.filters[name])throw new Error("filter not found: "+name);return this.filters[name]},resolveTemplate:function(loader,parentName,filename){var isRelative=loader.isRelative&&parentName?loader.isRelative(filename):!1;return isRelative&&loader.resolve?loader.resolve(parentName,filename):filename},getTemplate:function(name,eagerCompile,parentName,ignoreMissing,cb){var that=this,tmpl=null;if(name&&name.raw&&(name=name.raw),lib.isFunction(parentName)&&(cb=parentName,parentName=null,eagerCompile=eagerCompile||!1),lib.isFunction(eagerCompile)&&(cb=eagerCompile,eagerCompile=!1),name instanceof Template)tmpl=name;else{if("string"!=typeof name)throw new Error("template names must be a string: "+name);for(var i=0;icapacity){for(var scan=0,newLength=queue.length-index;newLength>scan;scan++)queue[scan]=queue[scan+index];queue.length-=index,index=0}}queue.length=0,index=0,flushing=!1}function makeRequestCallFromMutationObserver(callback){var toggle=1,observer=new BrowserMutationObserver(callback),node=document.createTextNode("");return observer.observe(node,{characterData:!0}),function(){toggle=-toggle,node.data=toggle}}function makeRequestCallFromTimer(callback){return function(){function handleTimer(){clearTimeout(timeoutHandle),clearInterval(intervalHandle),callback()}var timeoutHandle=setTimeout(handleTimer,0),intervalHandle=setInterval(handleTimer,50)}}module.exports=rawAsap;var requestFlush,queue=[],flushing=!1,index=0,capacity=1024,BrowserMutationObserver=global.MutationObserver||global.WebKitMutationObserver;requestFlush="function"==typeof BrowserMutationObserver?makeRequestCallFromMutationObserver(flush):makeRequestCallFromTimer(flush),rawAsap.requestFlush=requestFlush,rawAsap.makeRequestCallFromTimer=makeRequestCallFromTimer}).call(exports,function(){return this}())},function(module){"use strict";function extend(cls,name,props){var F=function(){};F.prototype=cls.prototype;var prototype=new F,fnTest=/xyz/.test(function(){xyz})?/\bparent\b/:/.*/;props=props||{};for(var k in props){var src=props[k],parent=prototype[k];prototype[k]="function"==typeof parent&&"function"==typeof src&&fnTest.test(src)?function(src,parent){return function(){var tmp=this.parent;this.parent=parent;var res=src.apply(this,arguments);return this.parent=tmp,res}}(src,parent):src}prototype.typename=name;var new_cls=function(){prototype.init&&prototype.init.apply(this,arguments)};return new_cls.prototype=prototype,new_cls.prototype.constructor=new_cls,new_cls.extend=function(name,props){return"object"==typeof name&&(props=name,name="anonymous"),extend(new_cls,name,props)},new_cls}module.exports=extend(Object,"Object",{})},function(){},function(module,exports,__webpack_require__){"use strict";function normalize(value,defaultValue){return null===value||void 0===value||value===!1?defaultValue:value}var lib=__webpack_require__(27),r=__webpack_require__(34),filters={abs:function(n){return Math.abs(n)},batch:function(arr,linecount,fill_with){var i,res=[],tmp=[];for(i=0;ii;i++)tmp.push(fill_with);res.push(tmp)}return res},capitalize:function(str){str=normalize(str,"");var ret=str.toLowerCase();return r.copySafeness(str,ret.charAt(0).toUpperCase()+ret.slice(1))},center:function(str,width){if(str=normalize(str,""),width=width||80,str.length>=width)return str;var spaces=width-str.length,pre=lib.repeat(" ",spaces/2-spaces%2),post=lib.repeat(" ",spaces/2);return r.copySafeness(str,pre+str+post)},"default":function(val,def,bool){return bool?val?val:def:void 0!==val?val:def},dictsort:function(val,case_sensitive,by){if(!lib.isObject(val))throw new lib.TemplateError("dictsort filter: val must be an object");var array=[];for(var k in val)array.push([k,val[k]]);var si;if(void 0===by||"key"===by)si=0;else{if("value"!==by)throw new lib.TemplateError("dictsort filter: You can only sort by either key or value");si=1}return array.sort(function(t1,t2){var a=t1[si],b=t2[si];return case_sensitive||(lib.isString(a)&&(a=a.toUpperCase()),lib.isString(b)&&(b=b.toUpperCase())),a>b?1:a===b?0:-1}),array},dump:function(obj){return JSON.stringify(obj)},escape:function(str){return"string"==typeof str||str instanceof r.SafeString?lib.escape(str):str},safe:function(str){return r.markSafe(str)},first:function(arr){return arr[0]},groupby:function(arr,attr){return lib.groupBy(arr,attr)},indent:function(str,width,indentfirst){if(str=normalize(str,""),""===str)return"";width=width||4;for(var res="",lines=str.split("\n"),sp=lib.repeat(" ",width),i=0;i-1&&(-1===maxCount||maxCount>count);)res+=str.substring(pos,nextIndex)+new_,pos=nextIndex+old.length,count++,nextIndex=str.indexOf(old,pos);return posi;i++){var start=offset+i*sliceLength;extra>i&&offset++;var end=offset+(i+1)*sliceLength,slice=arr.slice(start,end);fillWith&&i>=extra&&slice.push(fillWith),res.push(slice)}return res},sort:r.makeMacro(["value","reverse","case_sensitive","attribute"],[],function(arr,reverse,caseSens,attr){return arr=lib.map(arr,function(v){return v}),arr.sort(function(a,b){var x,y;return attr?(x=a[attr],y=b[attr]):(x=a,y=b),!caseSens&&lib.isString(x)&&lib.isString(y)&&(x=x.toLowerCase(),y=y.toLowerCase()),y>x?reverse?1:-1:x>y?reverse?-1:1:0}),arr}),string:function(obj){return r.copySafeness(obj,obj)},striptags:function(input,preserve_linebreaks){input=normalize(input,""),preserve_linebreaks=preserve_linebreaks||!1;var tags=/<\/?([a-z][a-z0-9]*)\b[^>]*>|/gi,trimmedInput=filters.trim(input.replace(tags,"")),res="";return res=preserve_linebreaks?trimmedInput.replace(/^ +| +$/gm,"").replace(/ +/g," ").replace(/(\r\n)/g,"\n").replace(/\n\n\n+/g,"\n\n"):trimmedInput.replace(/\s+/gi," "),r.copySafeness(input,res)},title:function(str){str=normalize(str,"");for(var words=str.split(" "),i=0;i"+possibleUrl.substr(0,length)+"":wwwRE.test(possibleUrl)?'"+possibleUrl.substr(0,length)+" ":emailRE.test(possibleUrl)?''+possibleUrl+" ":tldRE.test(possibleUrl)?'"+possibleUrl.substr(0,length)+" ":word});return words.join(" ")},wordcount:function(str){str=normalize(str,"");var words=str?str.match(/\w+/g):null;return words?words.length:null},"float":function(val,def){var res=parseFloat(val);return isNaN(res)?def:res},"int":function(val,def){var res=parseInt(val,10);return isNaN(res)?def:res}};filters.d=filters["default"],filters.e=filters.escape,module.exports=filters},function(module,exports,__webpack_require__){"use strict";function makeMacro(argNames,kwargNames,func){return function(){var args,i,argCount=numArgs(arguments),kwargs=getKeywordArgs(arguments);if(argCount>argNames.length){args=Array.prototype.slice.call(arguments,0,argNames.length);var vals=Array.prototype.slice.call(arguments,args.length,argCount);for(i=0;i=items.length&&(index=0),this.current=items[index],this.current}}}function joiner(sep){sep=sep||",";var first=!0;return function(){var val=first?"":sep;return first=!1,val}}function globals(){return{range:function(start,stop,step){stop?step||(step=1):(stop=start,start=0,step=1);var i,arr=[];if(step>0)for(i=start;stop>i;i+=step)arr.push(i);else for(i=start;i>stop;i+=step)arr.push(i);return arr},cycler:function(){return cycler(Array.prototype.slice.call(arguments))},joiner:function(sep){return joiner(sep)}}}module.exports=globals},function(module,exports,__webpack_require__){"use strict";var Loader=__webpack_require__(37),PrecompiledLoader=Loader.extend({init:function(compiledTemplates){this.precompiled=compiledTemplates||{}},getSource:function(name){return this.precompiled[name]?{src:{type:"code",obj:this.precompiled[name]},path:name}:null}});module.exports=PrecompiledLoader},function(module,exports,__webpack_require__){"use strict";var path=__webpack_require__(24),Obj=__webpack_require__(31),lib=__webpack_require__(27),Loader=Obj.extend({on:function(name,func){this.listeners=this.listeners||{},this.listeners[name]=this.listeners[name]||[],this.listeners[name].push(func)},emit:function(name){var args=Array.prototype.slice.call(arguments,1);this.listeners&&this.listeners[name]&&lib.each(this.listeners[name],function(listener){listener.apply(null,args)})},resolve:function(from,to){return path.resolve(path.dirname(from),to)},isRelative:function(filename){return 0===filename.indexOf("./")||0===filename.indexOf("../")}});module.exports=Loader},function(module){function installCompat(){"use strict";var runtime=this.runtime,lib=this.lib,orig_contextOrFrameLookup=runtime.contextOrFrameLookup;runtime.contextOrFrameLookup=function(context,frame,key){var val=orig_contextOrFrameLookup.apply(this,arguments);if(void 0===val)switch(key){case"True":return!0;case"False":return!1;case"None":return null}return val};var orig_memberLookup=runtime.memberLookup,ARRAY_MEMBERS={pop:function(index){if(void 0===index)return this.pop();if(index>=this.length||0>index)throw new Error("KeyError");return this.splice(index,1)},remove:function(element){for(var i=0;i\n \n \n \n"},SideBySidePrinter.prototype.generateSideBySideJsonHtml=function(diffFiles){var that=this;return'\n'+diffFiles.map(function(file){var diffs;return diffs=file.blocks.length?that.generateSideBySideFileHtml(file):that.generateEmptyDiff(),that.makeDiffHtml(file,diffs)}).join("\n")+"
\n"},SideBySidePrinter.prototype.makeSideHtml=function(blockHeader){return'\n \n \n '+blockHeader+"
\n \n \n"},SideBySidePrinter.prototype.generateSideBySideFileHtml=function(file){var that=this,fileHtml={};return fileHtml.left="",fileHtml.right="",file.blocks.forEach(function(block){function processChangeBlock(){var matches,insertType,deleteType,doMatching="lines"===that.config.matching||"words"===that.config.matching;doMatching?(matches=matcher(oldLines,newLines),insertType=diffParser.LINE_TYPE.INSERT_CHANGES,deleteType=diffParser.LINE_TYPE.DELETE_CHANGES):(matches=[[oldLines,newLines]],insertType=diffParser.LINE_TYPE.INSERTS,deleteType=diffParser.LINE_TYPE.DELETES),matches.forEach(function(match){oldLines=match[0],newLines=match[1];for(var common=Math.min(oldLines.length,newLines.length),max=Math.max(oldLines.length,newLines.length),j=0;common>j;j++){var oldLine=oldLines[j],newLine=newLines[j];that.config.isCombined=file.isCombined;var diff=printerUtils.diffHighlight(oldLine.content,newLine.content,that.config);fileHtml.left+=that.generateSingleLineHtml(deleteType,oldLine.oldNumber,diff.first.line,diff.first.prefix),fileHtml.right+=that.generateSingleLineHtml(insertType,newLine.newNumber,diff.second.line,diff.second.prefix)}if(max>common){var oldSlice=oldLines.slice(common),newSlice=newLines.slice(common),tmpHtml=that.processLines(oldSlice,newSlice);fileHtml.left+=tmpHtml.left,fileHtml.right+=tmpHtml.right}}),oldLines=[],newLines=[]}fileHtml.left+=that.makeSideHtml(utils.escape(block.header)),fileHtml.right+=that.makeSideHtml("");for(var oldLines=[],newLines=[],i=0;i0||line.type!==diffParser.LINE_TYPE.DELETES&&oldLines.length>0)&&processChangeBlock(),line.type===diffParser.LINE_TYPE.CONTEXT?(fileHtml.left+=that.generateSingleLineHtml(line.type,line.oldNumber,escapedLine,prefix),fileHtml.right+=that.generateSingleLineHtml(line.type,line.newNumber,escapedLine,prefix)):line.type!==diffParser.LINE_TYPE.INSERTS||oldLines.length?line.type===diffParser.LINE_TYPE.DELETES?oldLines.push(line):line.type===diffParser.LINE_TYPE.INSERTS&&Boolean(oldLines.length)?newLines.push(line):(console.error("unknown state in html side-by-side generator"),processChangeBlock()):(fileHtml.left+=that.generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT,"","",""),fileHtml.right+=that.generateSingleLineHtml(line.type,line.newNumber,escapedLine,prefix))}processChangeBlock()}),fileHtml},SideBySidePrinter.prototype.processLines=function(oldLines,newLines){var that=this,fileHtml={};fileHtml.left="",fileHtml.right="";for(var maxLinesNumber=Math.max(oldLines.length,newLines.length),i=0;maxLinesNumber>i;i++){var oldContent,newContent,oldPrefix,newPrefix,oldLine=oldLines[i],newLine=newLines[i];oldLine&&(oldContent=utils.escape(oldLine.content.substr(1)),oldPrefix=oldLine.content[0]),newLine&&(newContent=utils.escape(newLine.content.substr(1)),newPrefix=newLine.content[0]),oldLine&&newLine?(fileHtml.left+=that.generateSingleLineHtml(oldLine.type,oldLine.oldNumber,oldContent,oldPrefix),fileHtml.right+=that.generateSingleLineHtml(newLine.type,newLine.newNumber,newContent,newPrefix)):oldLine?(fileHtml.left+=that.generateSingleLineHtml(oldLine.type,oldLine.oldNumber,oldContent,oldPrefix),fileHtml.right+=that.generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT,"","","")):newLine?(fileHtml.left+=that.generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT,"","",""),fileHtml.right+=that.generateSingleLineHtml(newLine.type,newLine.newNumber,newContent,newPrefix)):console.error("How did it get here?")}return fileHtml},SideBySidePrinter.prototype.makeSingleLineHtml=function(type,number,htmlContent,htmlPrefix){return'\n '+number+' \n '+htmlPrefix+htmlContent+"
\n \n"},SideBySidePrinter.prototype.generateSingleLineHtml=function(type,number,content,prefix){var htmlPrefix="";prefix&&(htmlPrefix=''+prefix+" ");var htmlContent="";return content&&(htmlContent=''+content+" "),this.makeSingleLineHtml(type,number,htmlContent,htmlPrefix)},SideBySidePrinter.prototype.generateEmptyDiff=function(){var fileHtml={};return fileHtml.right="",fileHtml.left='\n File without changes
\n \n',fileHtml},module.exports.SideBySidePrinter=SideBySidePrinter}()}]);
\ No newline at end of file
diff --git a/package.json b/package.json
index 116b4fb..8b51e25 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "diff2html",
- "version": "1.3.2",
+ "version": "2.0.0-beta1",
"homepage": "http://rtfpessoa.github.io/diff2html/",
"description": "Fast Diff to colorized HTML",
"keywords": [
@@ -43,14 +43,15 @@
},
"main": "./src/diff2html.js",
"dependencies": {
- "diff": "^2.2.1"
+ "diff": "^2.2.1",
+ "nunjucks": "^2.3.0"
},
"devDependencies": {
- "codacy-coverage": "^1.1.3",
"clean-css": "^3.4.9",
+ "codacy-coverage": "^1.1.3",
"fast-html-parser": "^1.0.1",
- "istanbul": "^0.4.1",
- "jscs": "^2.9.0",
+ "istanbul": "^0.4.2",
+ "jscs": "^2.10.1",
"mocha": "^2.4.5",
"uglifyjs": "^2.4.10",
"webpack": "^1.12.13"
diff --git a/release.sh b/release.sh
index 585dcc5..66ccf24 100755
--- a/release.sh
+++ b/release.sh
@@ -8,6 +8,7 @@
set -e
INPUT_DIR=src
+INTPUT_TEMPLATES_DIR=${INPUT_DIR}/templates
INPUT_UI_DIR=${INPUT_DIR}/ui
INPUT_JS_FILE=${INPUT_DIR}/diff2html.js
INPUT_JS_UI_FILE=${INPUT_UI_DIR}/js/diff2html-ui.js
@@ -20,6 +21,8 @@ OUTPUT_JS_UI_FILE=${OUTPUT_DIR}/diff2html-ui.js
OUTPUT_MIN_JS_UI_FILE=${OUTPUT_DIR}/diff2html-ui.min.js
OUTPUT_CSS_FILE=${OUTPUT_DIR}/diff2html.css
OUTPUT_MIN_CSS_FILE=${OUTPUT_DIR}/diff2html.min.css
+OUTPUT_TEMPLATES_FILE=${OUTPUT_DIR}/diff2html-templates.js
+OUTPUT_MIN_TEMPLATES_FILE=${OUTPUT_DIR}/diff2html-templates.min.js
echo "Creating diff2html release ..."
@@ -28,27 +31,27 @@ rm -rf ${OUTPUT_DIR}
mkdir -p ${OUTPUT_DIR}
echo "Generating js aggregation file in ${OUTPUT_JS_FILE}"
-
webpack ${INPUT_JS_FILE} ${OUTPUT_JS_FILE}
echo "Minifying ${OUTPUT_JS_FILE} to ${OUTPUT_MIN_JS_FILE}"
-
uglifyjs ${OUTPUT_JS_FILE} -c -o ${OUTPUT_MIN_JS_FILE}
echo "Generating js ui aggregation file in ${OUTPUT_JS_UI_FILE}"
-
webpack ${INPUT_JS_UI_FILE} ${OUTPUT_JS_UI_FILE}
echo "Minifying ${OUTPUT_JS_UI_FILE} to ${OUTPUT_MIN_JS_UI_FILE}"
-
uglifyjs ${OUTPUT_JS_UI_FILE} -c -o ${OUTPUT_MIN_JS_UI_FILE}
-echo "Copying css file to ${OUTPUT_CSS_FILE}"
+echo "Pre-compile nunjucks templates in ${INTPUT_TEMPLATES_DIR}"
+nunjucks-precompile ${INTPUT_TEMPLATES_DIR} > ${OUTPUT_TEMPLATES_FILE}
+echo "Minifying ${OUTPUT_TEMPLATES_FILE} to ${OUTPUT_MIN_TEMPLATES_FILE}"
+uglifyjs ${OUTPUT_TEMPLATES_FILE} -c -o ${OUTPUT_MIN_TEMPLATES_FILE}
+
+echo "Copying css file to ${OUTPUT_CSS_FILE}"
cp -f ${INPUT_CSS_FILE} ${OUTPUT_CSS_FILE}
echo "Minifying ${OUTPUT_CSS_FILE} to ${OUTPUT_MIN_CSS_FILE}"
-
cleancss --advanced --compatibility=ie8 -o ${OUTPUT_MIN_CSS_FILE} ${OUTPUT_CSS_FILE}
echo "diff2html release created successfully!"
diff --git a/sample/index.html b/sample/index.html
index 41c2fc2..18f7c6a 100644
--- a/sample/index.html
+++ b/sample/index.html
@@ -9,15 +9,16 @@
Author: rtfpessoa
-->
-
+
-
-
+
+
-
+
+
diff --git a/src/line-by-line-printer.js b/src/line-by-line-printer.js
index e464bb4..01059c4 100644
--- a/src/line-by-line-printer.js
+++ b/src/line-by-line-printer.js
@@ -12,48 +12,34 @@
var utils = require('./utils.js').Utils;
var Rematch = require('./rematch.js').Rematch;
+ var nunjucksUtils = require('./nunjucks-utils.js').NunjucksUtils;
+ var baseTemplatesPath = 'line-by-line';
+
function LineByLinePrinter(config) {
this.config = config;
}
LineByLinePrinter.prototype.makeFileDiffHtml = function(file, diffs) {
- return '\n' +
- ' \n' +
- '
\n' +
- '
\n' +
- '
\n' +
- ' \n' +
- ' ' + diffs +
- ' \n' +
- '
\n' +
- '
\n' +
- '
\n' +
- '
\n';
+ return nunjucksUtils.render(baseTemplatesPath, 'file-diff.html', {'file': file, 'diffs': diffs});
+ };
+
+ LineByLinePrinter.prototype.makeLineByLineHtmlWrapper = function(content) {
+ return nunjucksUtils.render(baseTemplatesPath, 'wrapper.html', {'content': content});
};
LineByLinePrinter.prototype.generateLineByLineJsonHtml = function(diffFiles) {
var that = this;
var htmlDiffs = diffFiles.map(function(file) {
- var diffs;
- if (file.blocks.length) {
- diffs = that._generateFileHtml(file);
- } else {
- diffs = that._generateEmptyDiff();
- }
- return that.makeFileDiffHtml(file, diffs);
- });
+ var diffs;
+ if (file.blocks.length) {
+ diffs = that._generateFileHtml(file);
+ } else {
+ diffs = that._generateEmptyDiff();
+ }
+ return that.makeFileDiffHtml(file, diffs);
+ });
- return '\n' + htmlDiffs.join('\n') + '
\n';
+ return this.makeLineByLineHtmlWrapper(htmlDiffs.join('\n'));
};
var matcher = Rematch.rematch(function(a, b) {
@@ -64,12 +50,7 @@
});
LineByLinePrinter.prototype.makeColumnLineNumberHtml = function(block) {
- return '\n' +
- ' \n' +
- ' ' +
- ' ' + utils.escape(block.header) + '
' +
- ' \n' +
- ' \n';
+ return nunjucksUtils.render(baseTemplatesPath, 'column-line-number.html', {block: block});
};
LineByLinePrinter.prototype._generateFileHtml = function(file) {
@@ -115,10 +96,10 @@
var diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config);
processedOldLines +=
- that._generateLineHtml(deleteType, oldLine.oldNumber, oldLine.newNumber,
+ that.makeLineHtml(deleteType, oldLine.oldNumber, oldLine.newNumber,
diff.first.line, diff.first.prefix);
processedNewLines +=
- that._generateLineHtml(insertType, newLine.oldNumber, newLine.newNumber,
+ that.makeLineHtml(insertType, newLine.oldNumber, newLine.newNumber,
diff.second.line, diff.second.prefix);
}
@@ -140,9 +121,9 @@
}
if (line.type === diffParser.LINE_TYPE.CONTEXT) {
- lines += that._generateLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine);
+ lines += that.makeLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine);
} else if (line.type === diffParser.LINE_TYPE.INSERTS && !oldLines.length) {
- lines += that._generateLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine);
+ lines += that.makeLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine);
} else if (line.type === diffParser.LINE_TYPE.DELETES) {
oldLines.push(line);
} else if (line.type === diffParser.LINE_TYPE.INSERTS && Boolean(oldLines.length)) {
@@ -165,52 +146,31 @@
for (var i = 0; i < oldLines.length; i++) {
var oldLine = oldLines[i];
var oldEscapedLine = utils.escape(oldLine.content);
- lines += this._generateLineHtml(oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine);
+ lines += this.makeLineHtml(oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine);
}
for (var j = 0; j < newLines.length; j++) {
var newLine = newLines[j];
var newEscapedLine = utils.escape(newLine.content);
- lines += this._generateLineHtml(newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine);
+ lines += this.makeLineHtml(newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine);
}
return lines;
};
- LineByLinePrinter.prototype.makeLineHtml = function(type, oldNumber, newNumber, htmlPrefix, htmlContent) {
- return '\n' +
- ' ' +
- ' ' + utils.valueOrEmpty(oldNumber) + '
' +
- ' ' + utils.valueOrEmpty(newNumber) + '
' +
- ' \n' +
- ' ' +
- ' ' + htmlPrefix + htmlContent + '
' +
- ' \n' +
- ' \n';
- };
-
- LineByLinePrinter.prototype._generateLineHtml = function(type, oldNumber, newNumber, content, prefix) {
- var htmlPrefix = '';
- if (prefix) {
- htmlPrefix = '' + prefix + ' ';
- }
-
- var htmlContent = '';
- if (content) {
- htmlContent = '' + content + ' ';
- }
-
- return this.makeLineHtml(type, oldNumber, newNumber, htmlPrefix, htmlContent);
+ LineByLinePrinter.prototype.makeLineHtml = function(type, oldNumber, newNumber, content, prefix) {
+ return nunjucksUtils.render(baseTemplatesPath, 'line.html',
+ {
+ type: type,
+ oldNumber: oldNumber,
+ newNumber: newNumber,
+ prefix: prefix,
+ content: content
+ });
};
LineByLinePrinter.prototype._generateEmptyDiff = function() {
- return '\n' +
- ' ' +
- ' ' +
- 'File without changes' +
- '
' +
- ' \n' +
- ' \n';
+ return nunjucksUtils.render(baseTemplatesPath, 'empty-diff.html', {});
};
module.exports.LineByLinePrinter = LineByLinePrinter;
diff --git a/src/nunjucks-utils.js b/src/nunjucks-utils.js
new file mode 100644
index 0000000..1fb4bdd
--- /dev/null
+++ b/src/nunjucks-utils.js
@@ -0,0 +1,34 @@
+/*
+ *
+ * Utils (utils.js)
+ * Author: rtfpessoa
+ *
+ */
+
+(function() {
+
+ var path = require('path');
+
+ var nunjucks = require('nunjucks');
+ var templatesPath = path.resolve(__dirname, 'templates');
+
+ var diffParser = require('./diff-parser.js').DiffParser;
+ var printerUtils = require('./printer-utils.js').PrinterUtils;
+ var utils = require('./utils.js').Utils;
+
+ var nunjucksEnv = nunjucks.configure(templatesPath, {"autoescape": false})
+ .addGlobal('printerUtils', printerUtils)
+ .addGlobal('utils', utils)
+ .addGlobal('diffParser', diffParser);
+
+ function NunjucksUtils() {
+ }
+
+ NunjucksUtils.prototype.render = function(namespace, view, params) {
+ var viewPath = path.join(namespace, view);
+ return nunjucksEnv.render(viewPath, params);
+ };
+
+ module.exports.NunjucksUtils = new NunjucksUtils();
+
+})();
diff --git a/src/templates/line-by-line/column-line-number.html b/src/templates/line-by-line/column-line-number.html
new file mode 100644
index 0000000..cd80c40
--- /dev/null
+++ b/src/templates/line-by-line/column-line-number.html
@@ -0,0 +1,6 @@
+
+
+
+ {{ utils.escape(block.header) }}
+
+
diff --git a/src/templates/line-by-line/empty-diff.html b/src/templates/line-by-line/empty-diff.html
new file mode 100644
index 0000000..737bef5
--- /dev/null
+++ b/src/templates/line-by-line/empty-diff.html
@@ -0,0 +1,7 @@
+
+
+
+ File without changes
+
+
+
diff --git a/src/templates/line-by-line/file-diff.html b/src/templates/line-by-line/file-diff.html
new file mode 100644
index 0000000..d0d2d8f
--- /dev/null
+++ b/src/templates/line-by-line/file-diff.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+ {{ diffs | safe}}
+
+
+
+
+
diff --git a/src/templates/line-by-line/line.html b/src/templates/line-by-line/line.html
new file mode 100644
index 0000000..cd67adc
--- /dev/null
+++ b/src/templates/line-by-line/line.html
@@ -0,0 +1,16 @@
+
+
+ {{ utils.valueOrEmpty(oldNumber) | safe }}
+ {{ utils.valueOrEmpty(newNumber) | safe }}
+
+
+
+{% if prefix %}
+ {{ utils.convertWhiteSpaceToNonBreakingSpace(prefix) | safe }}
+{% endif %}
+{% if content %}
+ {{ utils.convertWhiteSpaceToNonBreakingSpace(content) | safe }}
+{% endif %}
+
+
+
diff --git a/src/templates/line-by-line/wrapper.html b/src/templates/line-by-line/wrapper.html
new file mode 100644
index 0000000..977d2bc
--- /dev/null
+++ b/src/templates/line-by-line/wrapper.html
@@ -0,0 +1,3 @@
+
+ {{ content }}
+
diff --git a/src/ui/css/diff2html.css b/src/ui/css/diff2html.css
index 58e0b56..0e8d10b 100644
--- a/src/ui/css/diff2html.css
+++ b/src/ui/css/diff2html.css
@@ -69,11 +69,14 @@
border-collapse: collapse;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 12px;
- height: 18px;
- line-height: 18px;
width: 100%;
}
+.d2h-diff-tbody > tr > td > div {
+ height: 16px;
+ line-height: 16px;
+}
+
.d2h-files-diff {
width: 100%;
}
@@ -93,9 +96,9 @@
.d2h-code-line {
display: block;
- white-space: pre;
padding: 0 10px;
height: 18px;
+ white-space: nowrap;
line-height: 18px;
margin-left: 80px;
/* Override HighlightJS */
diff --git a/src/ui/js/diff2html-ui.js b/src/ui/js/diff2html-ui.js
index f7fd75f..ad2b090 100644
--- a/src/ui/js/diff2html-ui.js
+++ b/src/ui/js/diff2html-ui.js
@@ -68,8 +68,6 @@
var languages = that._getLanguages($target);
- console.log(languages);
-
// pass the languages to the highlightjs plugin
hljs.configure({languages: languages});
@@ -100,18 +98,13 @@
return line.language;
});
} else {
- console.log($target.find(".d2h-file-wrapper"));
$target.find(".d2h-file-wrapper").map(function(i, file) {
allFileLanguages.push($(file).data("lang"));
});
}
- // remove duplicated languages
- var distinctLanguages = allFileLanguages.filter(function(v, i) {
- return allFileLanguages.indexOf(v) === i;
- });
-
- return distinctLanguages;
+ // return only distinct languages
+ return this._distinct(allFileLanguages);
};
Diff2HtmlUI.prototype._getHashTag = function() {
@@ -119,13 +112,19 @@
var hashTagIndex = docUrl.indexOf('#');
var hashTag = null;
- if (hashTagIndex != -1) {
+ if (hashTagIndex !== -1) {
hashTag = docUrl.substr(hashTagIndex + 1);
}
return hashTag;
};
+ Diff2HtmlUI.prototype._distinct = function(collection) {
+ return collection.filter(function(v, i) {
+ return collection.indexOf(v) === i;
+ });
+ };
+
module.exports.Diff2HtmlUI = Diff2HtmlUI;
// Expose diff2html in the browser
diff --git a/src/utils.js b/src/utils.js
index a1f0009..18728ce 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -10,6 +10,10 @@
function Utils() {
}
+ Utils.prototype.convertWhiteSpaceToNonBreakingSpace = function(str) {
+ return str.slice(0).replace(/ /g, ' ');
+ };
+
Utils.prototype.escape = function(str) {
return str.slice(0)
.replace(/&/g, '&')
diff --git a/test/line-by-line-tests.js b/test/line-by-line-tests.js
index f30defa..52feef3 100644
--- a/test/line-by-line-tests.js
+++ b/test/line-by-line-tests.js
@@ -1,4 +1,5 @@
var assert = require('assert');
+var Utils = require('../src/utils.js').Utils;
var LineByLinePrinter = require('../src/line-by-line-printer.js').LineByLinePrinter;
@@ -9,32 +10,34 @@ describe('LineByLinePrinter', function() {
var lineByLinePrinter = new LineByLinePrinter({});
var fileHtml = lineByLinePrinter._generateEmptyDiff();
var expected = '\n' +
- ' ' +
- ' ' +
- 'File without changes' +
- '
' +
+ ' \n' +
+ ' \n' +
+ ' File without changes\n' +
+ '
\n' +
' \n' +
' \n';
assert.equal(expected, fileHtml);
});
});
- describe('_generateLineHtml', function() {
+ describe('makeLineHtml', function() {
it('should work for insertions', function() {
var diffParser = require('../src/diff-parser.js').DiffParser;
var lineByLinePrinter = new LineByLinePrinter({});
- var fileHtml = lineByLinePrinter._generateLineHtml(
+ var fileHtml = lineByLinePrinter.makeLineHtml(
diffParser.LINE_TYPE.INSERTS, '', 30, '+', 'test');
+ fileHtml = fileHtml.replace(/\n\n+/g, '\n');
var expected = '\n' +
- ' ' +
- '
' +
- ' 30
' +
+ ' \n' +
+ '
\n' +
+ ' 30
\n' +
' \n' +
- ' ' +
- ' ' +
- 'test ' +
- '+
' +
+ ' \n' +
+ ' \n' +
+ ' test \n' +
+ ' + \n' +
+ '
\n' +
' \n' +
' \n';
@@ -44,17 +47,85 @@ describe('LineByLinePrinter', function() {
var diffParser = require('../src/diff-parser.js').DiffParser;
var lineByLinePrinter = new LineByLinePrinter({});
- var fileHtml = lineByLinePrinter._generateLineHtml(
+ var fileHtml = lineByLinePrinter.makeLineHtml(
diffParser.LINE_TYPE.DELETES, 30, '', '-', 'test');
+ fileHtml = fileHtml.replace(/\n\n+/g, '\n');
var expected = '\n' +
- ' ' +
- ' 30
' +
- '
' +
+ ' \n' +
+ ' 30
\n' +
+ '
\n' +
' \n' +
- ' ' +
- ' ' +
- 'test ' +
- '-
' +
+ ' \n' +
+ ' \n' +
+ ' test \n' +
+ ' - \n' +
+ '
\n' +
+ ' \n' +
+ ' \n';
+
+ assert.equal(expected, fileHtml);
+ });
+ it('should convert indents into non breakin spaces (2 white spaces)', function() {
+
+ var diffParser = require('../src/diff-parser.js').DiffParser;
+ var lineByLinePrinter = new LineByLinePrinter({});
+ var fileHtml = lineByLinePrinter.makeLineHtml(
+ diffParser.LINE_TYPE.INSERTS, '', 30, '+', ' test');
+ fileHtml = fileHtml.replace(/\n\n+/g, '\n');
+ var expected = '\n' +
+ ' \n' +
+ '
\n' +
+ ' 30
\n' +
+ ' \n' +
+ ' \n' +
+ ' \n' +
+ ' test \n' +
+ ' + \n' +
+ '
\n' +
+ ' \n' +
+ ' \n';
+
+ assert.equal(expected, fileHtml);
+ });
+ it('should convert indents into non breakin spaces (4 white spaces)', function() {
+
+ var diffParser = require('../src/diff-parser.js').DiffParser;
+ var lineByLinePrinter = new LineByLinePrinter({});
+ var fileHtml = lineByLinePrinter.makeLineHtml(
+ diffParser.LINE_TYPE.INSERTS, '', 30, '+', ' test');
+ fileHtml = fileHtml.replace(/\n\n+/g, '\n');
+ var expected = '\n' +
+ ' \n' +
+ '
\n' +
+ ' 30
\n' +
+ ' \n' +
+ ' \n' +
+ ' \n' +
+ ' test \n' +
+ ' + \n' +
+ '
\n' +
+ ' \n' +
+ ' \n';
+
+ assert.equal(expected, fileHtml);
+ });
+ it('should convert indents into non breakin spaces (one tab)', function() {
+
+ var diffParser = require('../src/diff-parser.js').DiffParser;
+ var lineByLinePrinter = new LineByLinePrinter({});
+ var fileHtml = lineByLinePrinter.makeLineHtml(
+ diffParser.LINE_TYPE.INSERTS, '', 30, '+', Utils.escape('\ttest'));
+ fileHtml = fileHtml.replace(/\n\n+/g, '\n');
+ var expected = '\n' +
+ ' \n' +
+ '
\n' +
+ ' 30
\n' +
+ ' \n' +
+ ' \n' +
+ ' \n' +
+ ' test \n' +
+ ' + \n' +
+ '
\n' +
' \n' +
' \n';
diff --git a/test/utils-tests.js b/test/utils-tests.js
index 69f9ab5..aa2d944 100644
--- a/test/utils-tests.js
+++ b/test/utils-tests.js
@@ -22,4 +22,18 @@ describe('Utils', function() {
assert.equal(expected, result);
});
});
+ describe('convertWhiteSpaceToNonBreakingSpace', function() {
+ it('should escape 1 whitespaces with ', function() {
+ var result = Utils.convertWhiteSpaceToNonBreakingSpace(' ');
+ assert.equal(' ', result);
+ });
+ it('should escape 2 whitespaces with ', function() {
+ var result = Utils.convertWhiteSpaceToNonBreakingSpace(' ');
+ assert.equal(' ', result);
+ });
+ it('should escape 4 whitespaces with ', function() {
+ var result = Utils.convertWhiteSpaceToNonBreakingSpace(' ');
+ assert.equal(' ', result);
+ });
+ });
});
diff --git a/webpack.config.js b/webpack.config.js
index 98c367c..fba230d 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -5,6 +5,16 @@ module.exports = {
plugins: [
+ new webpack.NormalModuleReplacementPlugin(
+ /(nunjucks)$/,
+ 'nunjucks/index'
+ ),
+
+ new webpack.NormalModuleReplacementPlugin(
+ /(precompile|nodes|lexer|parser|transformer|compiler|loaders)$/,
+ 'node-libs-browser/mock/empty'
+ ),
+
new webpack.DefinePlugin({
'process.env': {
IS_BROWSER: true