");return t.fl(); },partials: {}, subs: { }});
module.exports = global.browserTemplates;
})();
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"hogan.js":4}],114:[function(require,module,exports){
+},{"hogan.js":3}],111:[function(require,module,exports){
/*
*
* Utils (utils.js)
@@ -7348,4 +7186,498 @@ module.exports = global.browserTemplates;
module.exports.Utils = new Utils();
})();
-},{"lodash/merge":99}]},{},[105]);
+},{"lodash/merge":98}],112:[function(require,module,exports){
+
+},{}],113:[function(require,module,exports){
+(function (process){
+// .dirname, .basename, and .extname methods are extracted from Node.js v8.11.1,
+// backported and transplited with Babel, with backwards-compat fixes
+
+// 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;
+}
+
+// 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) {
+ if (typeof path !== 'string') path = path + '';
+ if (path.length === 0) return '.';
+ var code = path.charCodeAt(0);
+ var hasRoot = code === 47 /*/*/;
+ var end = -1;
+ var matchedSlash = true;
+ for (var i = path.length - 1; i >= 1; --i) {
+ code = path.charCodeAt(i);
+ if (code === 47 /*/*/) {
+ if (!matchedSlash) {
+ end = i;
+ break;
+ }
+ } else {
+ // We saw the first non-path separator
+ matchedSlash = false;
+ }
+ }
+
+ if (end === -1) return hasRoot ? '/' : '.';
+ if (hasRoot && end === 1) {
+ // return '//';
+ // Backwards-compat fix:
+ return '/';
+ }
+ return path.slice(0, end);
+};
+
+function basename(path) {
+ if (typeof path !== 'string') path = path + '';
+
+ var start = 0;
+ var end = -1;
+ var matchedSlash = true;
+ var i;
+
+ for (i = path.length - 1; i >= 0; --i) {
+ if (path.charCodeAt(i) === 47 /*/*/) {
+ // If we reached a path separator that was not part of a set of path
+ // separators at the end of the string, stop now
+ if (!matchedSlash) {
+ start = i + 1;
+ break;
+ }
+ } else if (end === -1) {
+ // We saw the first non-path separator, mark this as the end of our
+ // path component
+ matchedSlash = false;
+ end = i + 1;
+ }
+ }
+
+ if (end === -1) return '';
+ return path.slice(start, end);
+}
+
+// Uses a mixed approach for backwards-compatibility, as ext behavior changed
+// in new Node.js versions, so only basename() above is backported here
+exports.basename = function (path, ext) {
+ var f = basename(path);
+ if (ext && f.substr(-1 * ext.length) === ext) {
+ f = f.substr(0, f.length - ext.length);
+ }
+ return f;
+};
+
+exports.extname = function (path) {
+ if (typeof path !== 'string') path = path + '';
+ var startDot = -1;
+ var startPart = 0;
+ var end = -1;
+ var matchedSlash = true;
+ // Track the state of characters (if any) we see before our first dot and
+ // after any path separator we find
+ var preDotState = 0;
+ for (var i = path.length - 1; i >= 0; --i) {
+ var code = path.charCodeAt(i);
+ if (code === 47 /*/*/) {
+ // If we reached a path separator that was not part of a set of path
+ // separators at the end of the string, stop now
+ if (!matchedSlash) {
+ startPart = i + 1;
+ break;
+ }
+ continue;
+ }
+ if (end === -1) {
+ // We saw the first non-path separator, mark this as the end of our
+ // extension
+ matchedSlash = false;
+ end = i + 1;
+ }
+ if (code === 46 /*.*/) {
+ // If this is our first dot, mark it as the start of our extension
+ if (startDot === -1)
+ startDot = i;
+ else if (preDotState !== 1)
+ preDotState = 1;
+ } else if (startDot !== -1) {
+ // We saw a non-dot and non-path separator before our dot, so we should
+ // have a good chance at having a non-empty extension
+ preDotState = -1;
+ }
+ }
+
+ if (startDot === -1 || end === -1 ||
+ // We saw a non-dot character immediately before the dot
+ preDotState === 0 ||
+ // The (right-most) trimmed path component is exactly '..'
+ preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
+ return '';
+ }
+ return path.slice(startDot, end);
+};
+
+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);
+ }
+;
+
+}).call(this,require('_process'))
+},{"_process":114}],114:[function(require,module,exports){
+// shim for using process in browser
+var process = module.exports = {};
+
+// cached from whatever global is present so that test runners that stub it
+// don't break things. But we need to wrap it in a try catch in case it is
+// wrapped in strict mode code which doesn't define any globals. It's inside a
+// function because try/catches deoptimize in certain engines.
+
+var cachedSetTimeout;
+var cachedClearTimeout;
+
+function defaultSetTimout() {
+ throw new Error('setTimeout has not been defined');
+}
+function defaultClearTimeout () {
+ throw new Error('clearTimeout has not been defined');
+}
+(function () {
+ try {
+ if (typeof setTimeout === 'function') {
+ cachedSetTimeout = setTimeout;
+ } else {
+ cachedSetTimeout = defaultSetTimout;
+ }
+ } catch (e) {
+ cachedSetTimeout = defaultSetTimout;
+ }
+ try {
+ if (typeof clearTimeout === 'function') {
+ cachedClearTimeout = clearTimeout;
+ } else {
+ cachedClearTimeout = defaultClearTimeout;
+ }
+ } catch (e) {
+ cachedClearTimeout = defaultClearTimeout;
+ }
+} ())
+function runTimeout(fun) {
+ if (cachedSetTimeout === setTimeout) {
+ //normal enviroments in sane situations
+ return setTimeout(fun, 0);
+ }
+ // if setTimeout wasn't available but was latter defined
+ if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
+ cachedSetTimeout = setTimeout;
+ return setTimeout(fun, 0);
+ }
+ try {
+ // when when somebody has screwed with setTimeout but no I.E. maddness
+ return cachedSetTimeout(fun, 0);
+ } catch(e){
+ try {
+ // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
+ return cachedSetTimeout.call(null, fun, 0);
+ } catch(e){
+ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
+ return cachedSetTimeout.call(this, fun, 0);
+ }
+ }
+
+
+}
+function runClearTimeout(marker) {
+ if (cachedClearTimeout === clearTimeout) {
+ //normal enviroments in sane situations
+ return clearTimeout(marker);
+ }
+ // if clearTimeout wasn't available but was latter defined
+ if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
+ cachedClearTimeout = clearTimeout;
+ return clearTimeout(marker);
+ }
+ try {
+ // when when somebody has screwed with setTimeout but no I.E. maddness
+ return cachedClearTimeout(marker);
+ } catch (e){
+ try {
+ // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
+ return cachedClearTimeout.call(null, marker);
+ } catch (e){
+ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
+ // Some versions of I.E. have different rules for clearTimeout vs setTimeout
+ return cachedClearTimeout.call(this, marker);
+ }
+ }
+
+
+
+}
+var queue = [];
+var draining = false;
+var currentQueue;
+var queueIndex = -1;
+
+function cleanUpNextTick() {
+ if (!draining || !currentQueue) {
+ return;
+ }
+ draining = false;
+ if (currentQueue.length) {
+ queue = currentQueue.concat(queue);
+ } else {
+ queueIndex = -1;
+ }
+ if (queue.length) {
+ drainQueue();
+ }
+}
+
+function drainQueue() {
+ if (draining) {
+ return;
+ }
+ var timeout = runTimeout(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;
+ runClearTimeout(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) {
+ runTimeout(drainQueue);
+ }
+};
+
+// 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.prependListener = noop;
+process.prependOnceListener = noop;
+
+process.listeners = function (name) { return [] }
+
+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; };
+
+},{}]},{},[102]);
diff --git a/dist/diff2html.min.js b/dist/diff2html.min.js
index acf2da4..45c4558 100644
--- a/dist/diff2html.min.js
+++ b/dist/diff2html.min.js
@@ -1 +1 @@
-!function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n||e)},l,l.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;ovalue.length?oldValue:value}),component.value=diff.join(value)}else component.value=diff.join(newString.slice(newPos,newPos+component.count));newPos+=component.count,component.added||(oldPos+=component.count)}}var lastComponent=components[componentLen-1];return 1=newLen&&oldLen<=oldPos+1)return done([{value:this.join(newString),count:newString.length}]);function execEditLength(){for(var diagonalPath=-1*editLength;diagonalPath<=editLength;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=newLen&&oldLen<=_oldPos+1)return done(buildValues(self,basePath.components,newString,oldString,self.useLongestToken));bestPath[diagonalPath]=basePath}else bestPath[diagonalPath]=void 0}var path;editLength++}if(callback)!function exec(){setTimeout(function(){if(maxEditLength=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),newRangeStart=oldRangeStart=0,curRange=[]}oldLine+=lines.length,newLine+=lines.length}},i=0;iarray.length)return!1;for(var i=0;i/g,">")).replace(/"/g,""")}exports.__esModule=!0,exports.convertChangesToXML=function(changes){for(var ret=[],i=0;i"):change.removed&&ret.push(""),ret.push(escapeHTML(change.value)),change.added?ret.push(""):change.removed&&ret.push("")}return ret.join("")}}])},"object"==typeof exports&&"object"==typeof module?module.exports=factory():"function"==typeof define&&define.amd?define([],factory):"object"==typeof exports?exports.JsDiff=factory():root.JsDiff=factory()},{}],3:[function(require,module,exports){!function(Hogan){var rIsWhitespace=/\S/,rQuot=/\"/g,rNewline=/\n/g,rCr=/\r/g,rSlash=/\\/g,rLineSep=/\u2028/,rParagraphSep=/\u2029/;function cleanTripleStache(token){"}"===token.n.substr(token.n.length-1)&&(token.n=token.n.substring(0,token.n.length-1))}function trim(s){return s.trim?s.trim():s.replace(/^\s*|\s*$/g,"")}function tagChange(tag,text,index){if(text.charAt(index)!=tag.charAt(0))return!1;for(var i=1,l=tag.length;i":7,"=":8,_v:9,"{":10,"&":11,_t:12},Hogan.scan=function(text,delimiters){var len=text.length,state=0,tagType=null,tag=null,buf="",tokens=[],seenTag=!1,i=0,lineStart=0,otag="{{",ctag="}}";function addBuf(){0"==next.tag&&(next.indent=tokens[j].text.toString()),tokens.splice(j,1));else noNewLine||tokens.push({tag:"\n"});seenTag=!1,lineStart=tokens.length}function changeDelimiters(text,index){var close="="+ctag,closeIndex=text.indexOf(close,index),delimiters=trim(text.substring(text.indexOf("=",index)+1,closeIndex)).split(" ");return otag=delimiters[0],ctag=delimiters[delimiters.length-1],closeIndex+close.length-1}for(delimiters&&(delimiters=delimiters.split(" "),otag=delimiters[0],ctag=delimiters[1]),i=0;i":createPartial,"<":function(node,context){var ctx={partials:{},code:"",subs:{},inPartial:!0};Hogan.walk(node.nodes,ctx);var template=context.partials[createPartial(node,context)];template.subs=ctx.subs,template.partials=ctx.partials},$:function(node,context){var ctx={subs:{},code:"",partials:context.partials,prefix:node.n};Hogan.walk(node.nodes,ctx),context.subs[node.n]=ctx.code,context.inPartial||(context.code+='t.sub("'+esc(node.n)+'",c,p,i);')},"\n":function(node,context){context.code+=write('"\\n"'+(node.last?"":" + i"))},_v:function(node,context){context.code+="t.b(t.v(t."+chooseMethod(node.n)+'("'+esc(node.n)+'",c,p,0)));'},_t:function(node,context){context.code+=write('"'+esc(node.text)+'"')},"{":tripleStache,"&":tripleStache},Hogan.walk=function(nodelist,context){for(var func,i=0,l=nodelist.length;i/g,rApos=/\'/g,rQuot=/\"/g,hChars=/[&<>\"\']/;function coerceToString(val){return String(null==val?"":val)}var isArray=Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)}}(void 0!==exports?exports:{})},{}],6:[function(require,module,exports){var hashClear=require("./_hashClear"),hashDelete=require("./_hashDelete"),hashGet=require("./_hashGet"),hashHas=require("./_hashHas"),hashSet=require("./_hashSet");function Hash(entries){var index=-1,length=null==entries?0:entries.length;for(this.clear();++indexconfig.maxLineLengthHighlight||unprefixedLine2.length>config.maxLineLengthHighlight)return{first:{prefix:linePrefix1,line:utils.escape(unprefixedLine1)},second:{prefix:linePrefix2,line:utils.escape(unprefixedLine2)}};diff=config.charByChar?jsDiff.diffChars(unprefixedLine1,unprefixedLine2):jsDiff.diffWordsWithSpace(unprefixedLine1,unprefixedLine2);var line,highlightedLine="",changedWords=[];if(!config.charByChar&&"words"===config.matching){var treshold=.25;void 0!==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});matcher(diff.filter(function(element){return element.added}),removed).forEach(function(chunk){1===chunk[0].length&&1===chunk[1].length&&(Rematch.distance(chunk[0][0].value,chunk[1][0].value)"+escapedValue+""+elemType+">":escapedValue}),{first:{prefix:linePrefix1,line:(line=highlightedLine,line.replace(/(]*>((.|\n)*?)<\/ins>)/g,""))},second:{prefix:linePrefix2,line:function(line){return line.replace(/(]*>((.|\n)*?)<\/del>)/g,"")}(highlightedLine)}}},module.exports.PrinterUtils=new PrinterUtils}()},{"./rematch.js":111,"./utils.js":114,diff:2}],111:[function(require,module,exports){!function(){var Rematch={};function levenshtein(a,b){if(0===a.length)return b.length;if(0===b.length)return a.length;var i,j,matrix=[];for(i=0;i<=b.length;i++)matrix[i]=[i];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++)b.charAt(i-1)===a.charAt(j-1)?matrix[i][j]=matrix[i-1][j-1]:matrix[i][j]=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]}Rematch.levenshtein=levenshtein,Rematch.distance=function(x,y){return levenshtein(x=x.trim(),y=y.trim())/(x.length+y.length)},Rematch.rematch=function(distanceFunction){return function group(a,b,level,cache){void 0===cache&&(cache={});var bm=function(a,b,cache){for(var bestMatch,bestMatchDist=1/0,i=0;itailA||b.length>tailB)&&(result=result.concat(group2)),result}},module.exports.Rematch=Rematch}()},{}],112:[function(require,module,exports){!function(){var hoganUtils,diffParser=require("./diff-parser.js").DiffParser,printerUtils=require("./printer-utils.js").PrinterUtils,utils=require("./utils.js").Utils,Rematch=require("./rematch.js").Rematch,matcher=Rematch.rematch(function(a,b){var amod=a.content.substr(1),bmod=b.content.substr(1);return Rematch.distance(amod,bmod)});function SideBySidePrinter(config){this.config=config;var HoganJsUtils=require("./hoganjs-utils.js").HoganJsUtils;hoganUtils=new HoganJsUtils(config)}SideBySidePrinter.prototype.makeDiffHtml=function(file,diffs){var fileDiffTemplate=hoganUtils.template("side-by-side","file-diff"),filePathTemplate=hoganUtils.template("generic","file-path"),fileIconTemplate=hoganUtils.template("icon","file"),fileTagTemplate=hoganUtils.template("tag",printerUtils.getFileTypeIcon(file));return fileDiffTemplate.render({file:file,fileHtmlId:printerUtils.getHtmlId(file),diffs:diffs,filePath:filePathTemplate.render({fileDiffName:printerUtils.getDiffName(file)},{fileIcon:fileIconTemplate,fileTag:fileTagTemplate})})},SideBySidePrinter.prototype.generateSideBySideJsonHtml=function(diffFiles){var that=this,content=diffFiles.map(function(file){var diffs;return diffs=file.blocks.length?that.generateSideBySideFileHtml(file):that.generateEmptyDiff(),that.makeDiffHtml(file,diffs)}).join("\n");return hoganUtils.render("generic","wrapper",{content:content})},SideBySidePrinter.prototype.makeSideHtml=function(blockHeader){return hoganUtils.render("generic","column-line-number",{diffParser:diffParser,blockHeader:utils.escape(blockHeader),lineClass:"d2h-code-side-linenumber",contentClass:"d2h-code-side-line"})},SideBySidePrinter.prototype.generateSideBySideFileHtml=function(file){var that=this,fileHtml={left:"",right:""};return file.blocks.forEach(function(block){fileHtml.left+=that.makeSideHtml(block.header),fileHtml.right+=that.makeSideHtml("");var oldLines=[],newLines=[];function processChangeBlock(){var matches,insertType,deleteType;oldLines.length*newLines.length<(that.config.matchingMaxComparisons||2500)&&("lines"===that.config.matching||"words"===that.config.matching)?(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;j'),t.b("\n"+i),t.b(' '),t.b("\n"+i),t.b(" "),t.b(t.rp(""),t.b("\n"+i),t.b(' '),t.b(t.v(t.f("fileName",c,p,0))),t.b(""),t.b("\n"+i),t.b(' '),t.b("\n"+i),t.b(' '),t.b(t.v(t.f("addedLines",c,p,0))),t.b(""),t.b("\n"+i),t.b(' '),t.b(t.v(t.f("deletedLines",c,p,0))),t.b(""),t.b("\n"+i),t.b(" "),t.b("\n"+i),t.b(" "),t.b("\n"+i),t.b(""),t.fl()},partials:{"'),t.b("\n"+i),t.b('
\ No newline at end of file
diff --git a/src/templates/wrapped-column-line-number.mustache b/src/templates/wrapped-column-line-number.mustache
new file mode 100644
index 0000000..2dc941c
--- /dev/null
+++ b/src/templates/wrapped-column-line-number.mustache
@@ -0,0 +1,10 @@
+
+
+
+
{{{left.blockHeader}}}
+
+
+
+
{{{right.blockHeader}}}
+
+
\ No newline at end of file
diff --git a/src/templates/wrapped-line.mustache b/src/templates/wrapped-line.mustache
new file mode 100644
index 0000000..0af4a1c
--- /dev/null
+++ b/src/templates/wrapped-line.mustache
@@ -0,0 +1,15 @@
+