nowpad
Version:
Realtime Text Collaboration
609 lines (608 loc) • 40.1 kB
JavaScript
(function(scope){var diff_match_patch = scope.diff_match_patch = function(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=0.5;this.Match_Distance=1E3;this.Patch_DeleteThreshold=0.5;this.Patch_Margin=4;this.Match_MaxBits=32}
diff_match_patch.prototype.diff_main=function(a,b,c,d){if(typeof d=="undefined")d=this.Diff_Timeout<=0?Number.MAX_VALUE:(new Date).getTime()+this.Diff_Timeout*1E3;if(a==null||b==null)throw Error("Null input. (diff_main)");if(a==b){if(a)return[[0,a]];return[]}if(typeof c=="undefined")c=true;var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);f=this.diff_commonSuffix(a,b);var g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,b.length-f);a=this.diff_compute_(a,
b,e,d);c&&a.unshift([0,c]);g&&a.push([0,g]);this.diff_cleanupMerge(a);return a};
diff_match_patch.prototype.diff_compute_=function(a,b,c,d){if(!a)return[[1,b]];if(!b)return[[-1,a]];var e=a.length>b.length?a:b,f=a.length>b.length?b:a,g=e.indexOf(f);if(g!=-1){c=[[1,e.substring(0,g)],[0,f],[1,e.substring(g+f.length)]];if(a.length>b.length)c[0][0]=c[2][0]=-1;return c}if(f.length==1)return[[-1,a],[1,b]];if(e=this.diff_halfMatch_(a,b)){f=e[0];a=e[1];g=e[2];b=e[3];e=e[4];f=this.diff_main(f,g,c,d);c=this.diff_main(a,b,c,d);return f.concat([[0,e]],c)}if(c&&a.length>100&&b.length>100)return this.diff_lineMode_(a,
b,d);return this.diff_bisect_(a,b,d)};
diff_match_patch.prototype.diff_lineMode_=function(a,b,c){var d=this.diff_linesToChars_(a,b);a=d[0];b=d[1];d=d[2];a=this.diff_bisect_(a,b,c);this.diff_charsToLines_(a,d);this.diff_cleanupSemantic(a);a.push([0,""]);for(var e=b=0,f=0,g=d="";b<a.length;){switch(a[b][0]){case 1:f++;g+=a[b][1];break;case -1:e++;d+=a[b][1];break;case 0:if(e>=1&&f>=1){d=this.diff_main(d,g,false,c);a.splice(b-e-f,e+f);b=b-e-f;for(e=d.length-1;e>=0;e--)a.splice(b,0,d[e]);b+=d.length}e=f=0;g=d=""}b++}a.pop();return a};
diff_match_patch.prototype.diff_bisect_=function(a,b,c){for(var d=a.length,e=b.length,f=Math.ceil((d+e)/2),g=f,h=2*f,j=Array(h),i=Array(h),k=0;k<h;k++){j[k]=-1;i[k]=-1}j[g+1]=0;i[g+1]=0;k=d-e;for(var l=k%2!=0,s=0,p=0,q=0,t=0,r=0;r<f;r++){if((new Date).getTime()>c)break;for(var n=-r+s;n<=r-p;n+=2){var m=g+n,o;o=n==-r||n!=r&&j[m-1]<j[m+1]?j[m+1]:j[m-1]+1;for(var u=o-n;o<d&&u<e&&a.charAt(o)==b.charAt(u);){o++;u++}j[m]=o;if(o>d)p+=2;else if(u>e)s+=2;else if(l){m=g+k-n;if(m>=0&&m<h&&i[m]!=-1){var v=d-
i[m];if(o>=v)return this.diff_bisectSplit_(a,b,o,u,c)}}}for(n=-r+q;n<=r-t;n+=2){m=g+n;v=n==-r||n!=r&&i[m-1]<i[m+1]?i[m+1]:i[m-1]+1;for(o=v-n;v<d&&o<e&&a.charAt(d-v-1)==b.charAt(e-o-1);){v++;o++}i[m]=v;if(v>d)t+=2;else if(o>e)q+=2;else if(!l){m=g+k-n;if(m>=0&&m<h&&j[m]!=-1){o=j[m];u=g+o-m;v=d-v;if(o>=v)return this.diff_bisectSplit_(a,b,o,u,c)}}}}return[[-1,a],[1,b]]};
diff_match_patch.prototype.diff_bisectSplit_=function(a,b,c,d,e){var f=a.substring(0,c),g=b.substring(0,d);a=a.substring(c);b=b.substring(d);f=this.diff_main(f,g,false,e);e=this.diff_main(a,b,false,e);return f.concat(e)};
diff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(h){for(var j="",i=0,k=-1,l=d.length;k<h.length-1;){k=h.indexOf("\n",i);if(k==-1)k=h.length-1;var s=h.substring(i,k+1);i=k+1;if(e.hasOwnProperty?e.hasOwnProperty(s):e[s]!==undefined)j+=String.fromCharCode(e[s]);else{j+=String.fromCharCode(l);e[s]=l;d[l++]=s}}return j}var d=[],e={};d[0]="";var f=c(a),g=c(b);return[f,g,d]};
diff_match_patch.prototype.diff_charsToLines_=function(a,b){for(var c=0;c<a.length;c++){for(var d=a[c][1],e=[],f=0;f<d.length;f++)e[f]=b[d.charCodeAt(f)];a[c][1]=e.join("")}};diff_match_patch.prototype.diff_commonPrefix=function(a,b){if(!a||!b||a.charAt(0)!=b.charAt(0))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;){if(a.substring(f,e)==b.substring(f,e))f=c=e;else d=e;e=Math.floor((d-c)/2+c)}return e};
diff_match_patch.prototype.diff_commonSuffix=function(a,b){if(!a||!b||a.charAt(a.length-1)!=b.charAt(b.length-1))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;){if(a.substring(a.length-e,a.length-f)==b.substring(b.length-e,b.length-f))f=c=e;else d=e;e=Math.floor((d-c)/2+c)}return e};
diff_match_patch.prototype.diff_commonOverlap_=function(a,b){var c=a.length,d=b.length;if(c==0||d==0)return 0;if(c>d)a=a.substring(c-d);else if(c<d)b=b.substring(0,c);c=Math.min(c,d);if(a==b)return c;d=0;for(var e=1;;){var f=a.substring(c-e);f=b.indexOf(f);if(f==-1)return d;e+=f;if(f==0||a.substring(c-e)==b.substring(0,e)){d=e;e++}}};
diff_match_patch.prototype.diff_halfMatch_=function(a,b){function c(i,k,l){for(var s=i.substring(l,l+Math.floor(i.length/4)),p=-1,q="",t,r,n,m;(p=k.indexOf(s,p+1))!=-1;){var o=f.diff_commonPrefix(i.substring(l),k.substring(p)),u=f.diff_commonSuffix(i.substring(0,l),k.substring(0,p));if(q.length<u+o){q=k.substring(p-u,p)+k.substring(p,p+o);t=i.substring(0,l-u);r=i.substring(l+o);n=k.substring(0,p-u);m=k.substring(p+o)}}return q.length*2>=i.length?[t,r,n,m,q]:null}if(this.Diff_Timeout<=0)return null;
var d=a.length>b.length?a:b,e=a.length>b.length?b:a;if(d.length<4||e.length*2<d.length)return null;var f=this,g=c(d,e,Math.ceil(d.length/4));d=c(d,e,Math.ceil(d.length/2));var h;if(!g&&!d)return null;else h=d?g?g[4].length>d[4].length?g:d:d:g;var j;if(a.length>b.length){g=h[0];d=h[1];e=h[2];j=h[3]}else{e=h[0];j=h[1];g=h[2];d=h[3]}h=h[4];return[g,d,e,j,h]};
diff_match_patch.prototype.diff_cleanupSemantic=function(a){for(var b=false,c=[],d=0,e=null,f=0,g=0,h=0,j=0,i=0;f<a.length;){if(a[f][0]==0){c[d++]=f;g=j;h=i;i=j=0;e=a[f][1]}else{if(a[f][0]==1)j+=a[f][1].length;else i+=a[f][1].length;if(e!==null&&e.length<=Math.max(g,h)&&e.length<=Math.max(j,i)){a.splice(c[d-1],0,[-1,e]);a[c[d-1]+1][0]=1;d--;d--;f=d>0?c[d-1]:-1;i=j=h=g=0;e=null;b=true}}f++}b&&this.diff_cleanupMerge(a);this.diff_cleanupSemanticLossless(a);for(f=1;f<a.length;){if(a[f-1][0]==-1&&a[f][0]==
1){b=a[f-1][1];c=a[f][1];if(d=this.diff_commonOverlap_(b,c)){a.splice(f,0,[0,c.substring(0,d)]);a[f-1][1]=b.substring(0,b.length-d);a[f+1][1]=c.substring(d);f++}f++}f++}};
diff_match_patch.prototype.diff_cleanupSemanticLossless=function(a){function b(r,n){if(!r||!n)return 5;var m=0;if(r.charAt(r.length-1).match(c)||n.charAt(0).match(c)){m++;if(r.charAt(r.length-1).match(d)||n.charAt(0).match(d)){m++;if(r.charAt(r.length-1).match(e)||n.charAt(0).match(e)){m++;if(r.match(f)||n.match(g))m++}}}return m}for(var c=/[^a-zA-Z0-9]/,d=/\s/,e=/[\r\n]/,f=/\n\r?\n$/,g=/^\r?\n\r?\n/,h=1;h<a.length-1;){if(a[h-1][0]==0&&a[h+1][0]==0){var j=a[h-1][1],i=a[h][1],k=a[h+1][1],l=this.diff_commonSuffix(j,
i);if(l){var s=i.substring(i.length-l);j=j.substring(0,j.length-l);i=s+i.substring(0,i.length-l);k=s+k}l=j;s=i;for(var p=k,q=b(j,i)+b(i,k);i.charAt(0)===k.charAt(0);){j+=i.charAt(0);i=i.substring(1)+k.charAt(0);k=k.substring(1);var t=b(j,i)+b(i,k);if(t>=q){q=t;l=j;s=i;p=k}}if(a[h-1][1]!=l){if(l)a[h-1][1]=l;else{a.splice(h-1,1);h--}a[h][1]=s;if(p)a[h+1][1]=p;else{a.splice(h+1,1);h--}}}h++}};
diff_match_patch.prototype.diff_cleanupEfficiency=function(a){for(var b=false,c=[],d=0,e="",f=0,g=false,h=false,j=false,i=false;f<a.length;){if(a[f][0]==0){if(a[f][1].length<this.Diff_EditCost&&(j||i)){c[d++]=f;g=j;h=i;e=a[f][1]}else{d=0;e=""}j=i=false}else{if(a[f][0]==-1)i=true;else j=true;if(e&&(g&&h&&j&&i||e.length<this.Diff_EditCost/2&&g+h+j+i==3)){a.splice(c[d-1],0,[-1,e]);a[c[d-1]+1][0]=1;d--;e="";if(g&&h){j=i=true;d=0}else{d--;f=d>0?c[d-1]:-1;j=i=false}b=true}}f++}b&&this.diff_cleanupMerge(a)};
diff_match_patch.prototype.diff_cleanupMerge=function(a){a.push([0,""]);for(var b=0,c=0,d=0,e="",f="",g;b<a.length;)switch(a[b][0]){case 1:d++;f+=a[b][1];b++;break;case -1:c++;e+=a[b][1];b++;break;case 0:if(c+d>1){if(c!==0&&d!==0){g=this.diff_commonPrefix(f,e);if(g!==0){if(b-c-d>0&&a[b-c-d-1][0]==0)a[b-c-d-1][1]+=f.substring(0,g);else{a.splice(0,0,[0,f.substring(0,g)]);b++}f=f.substring(g);e=e.substring(g)}g=this.diff_commonSuffix(f,e);if(g!==0){a[b][1]=f.substring(f.length-g)+a[b][1];f=f.substring(0,
f.length-g);e=e.substring(0,e.length-g)}}if(c===0)a.splice(b-c-d,c+d,[1,f]);else d===0?a.splice(b-c-d,c+d,[-1,e]):a.splice(b-c-d,c+d,[-1,e],[1,f]);b=b-c-d+(c?1:0)+(d?1:0)+1}else if(b!==0&&a[b-1][0]==0){a[b-1][1]+=a[b][1];a.splice(b,1)}else b++;c=d=0;f=e=""}a[a.length-1][1]===""&&a.pop();c=false;for(b=1;b<a.length-1;){if(a[b-1][0]==0&&a[b+1][0]==0)if(a[b][1].substring(a[b][1].length-a[b-1][1].length)==a[b-1][1]){a[b][1]=a[b-1][1]+a[b][1].substring(0,a[b][1].length-a[b-1][1].length);a[b+1][1]=a[b-1][1]+
a[b+1][1];a.splice(b-1,1);c=true}else if(a[b][1].substring(0,a[b+1][1].length)==a[b+1][1]){a[b-1][1]+=a[b+1][1];a[b][1]=a[b][1].substring(a[b+1][1].length)+a[b+1][1];a.splice(b+1,1);c=true}b++}c&&this.diff_cleanupMerge(a)};diff_match_patch.prototype.diff_xIndex=function(a,b){var c=0,d=0,e=0,f=0,g;for(g=0;g<a.length;g++){if(a[g][0]!==1)c+=a[g][1].length;if(a[g][0]!==-1)d+=a[g][1].length;if(c>b)break;e=c;f=d}if(a.length!=g&&a[g][0]===-1)return f;return f+(b-e)};
diff_match_patch.prototype.diff_prettyHtml=function(a){for(var b=[],c=0,d=/&/g,e=/</g,f=/>/g,g=/\n/g,h=0;h<a.length;h++){var j=a[h][0],i=a[h][1],k=i.replace(d,"&").replace(e,"<").replace(f,">").replace(g,"¶<br>");switch(j){case 1:b[h]='<ins style="background:#e6ffe6;">'+k+"</ins>";break;case -1:b[h]='<del style="background:#ffe6e6;">'+k+"</del>";break;case 0:b[h]="<span>"+k+"</span>"}if(j!==-1)c+=i.length}return b.join("")};
diff_match_patch.prototype.diff_text1=function(a){for(var b=[],c=0;c<a.length;c++)if(a[c][0]!==1)b[c]=a[c][1];return b.join("")};diff_match_patch.prototype.diff_text2=function(a){for(var b=[],c=0;c<a.length;c++)if(a[c][0]!==-1)b[c]=a[c][1];return b.join("")};diff_match_patch.prototype.diff_levenshtein=function(a){for(var b=0,c=0,d=0,e=0;e<a.length;e++){var f=a[e][0],g=a[e][1];switch(f){case 1:c+=g.length;break;case -1:d+=g.length;break;case 0:b+=Math.max(c,d);d=c=0}}b+=Math.max(c,d);return b};
diff_match_patch.prototype.diff_toDelta=function(a){for(var b=[],c=0;c<a.length;c++)switch(a[c][0]){case 1:b[c]="+"+encodeURI(a[c][1]);break;case -1:b[c]="-"+a[c][1].length;break;case 0:b[c]="="+a[c][1].length}return b.join("\t").replace(/%20/g," ")};
diff_match_patch.prototype.diff_fromDelta=function(a,b){for(var c=[],d=0,e=0,f=b.split(/\t/g),g=0;g<f.length;g++){var h=f[g].substring(1);switch(f[g].charAt(0)){case "+":try{c[d++]=[1,decodeURI(h)]}catch(j){throw Error("Illegal escape in diff_fromDelta: "+h);}break;case "-":case "=":var i=parseInt(h,10);if(isNaN(i)||i<0)throw Error("Invalid number in diff_fromDelta: "+h);h=a.substring(e,e+=i);if(f[g].charAt(0)=="=")c[d++]=[0,h];else c[d++]=[-1,h];break;default:if(f[g])throw Error("Invalid diff operation in diff_fromDelta: "+
f[g]);}}if(e!=a.length)throw Error("Delta length ("+e+") does not equal source text length ("+a.length+").");return c};diff_match_patch.prototype.match_main=function(a,b,c){if(a==null||b==null||c==null)throw Error("Null input. (match_main)");c=Math.max(0,Math.min(c,a.length));return a==b?0:a.length?a.substring(c,c+b.length)==b?c:this.match_bitap_(a,b,c):-1};
diff_match_patch.prototype.match_bitap_=function(a,b,c){function d(r,n){var m=r/b.length,o=Math.abs(c-n);if(!f.Match_Distance)return o?1:m;return m+o/f.Match_Distance}if(b.length>this.Match_MaxBits)throw Error("Pattern too long for this browser.");var e=this.match_alphabet_(b),f=this,g=this.Match_Threshold,h=a.indexOf(b,c);if(h!=-1){g=Math.min(d(0,h),g);h=a.lastIndexOf(b,c+b.length);if(h!=-1)g=Math.min(d(0,h),g)}var j=1<<b.length-1;h=-1;for(var i,k,l=b.length+a.length,s,p=0;p<b.length;p++){i=0;for(k=
l;i<k;){if(d(p,c+k)<=g)i=k;else l=k;k=Math.floor((l-i)/2+i)}l=k;i=Math.max(1,c-k+1);var q=Math.min(c+k,a.length)+b.length;k=Array(q+2);for(k[q+1]=(1<<p)-1;q>=i;q--){var t=e[a.charAt(q-1)];k[q]=p===0?(k[q+1]<<1|1)&t:(k[q+1]<<1|1)&t|(s[q+1]|s[q])<<1|1|s[q+1];if(k[q]&j){t=d(p,q-1);if(t<=g){g=t;h=q-1;if(h>c)i=Math.max(1,2*c-h);else break}}}if(d(p+1,c)>g)break;s=k}return h};
diff_match_patch.prototype.match_alphabet_=function(a){for(var b={},c=0;c<a.length;c++)b[a.charAt(c)]=0;for(c=0;c<a.length;c++)b[a.charAt(c)]|=1<<a.length-c-1;return b};
diff_match_patch.prototype.patch_addContext_=function(a,b){if(b.length!=0){for(var c=b.substring(a.start2,a.start2+a.length1),d=0;b.indexOf(c)!=b.lastIndexOf(c)&&c.length<this.Match_MaxBits-this.Patch_Margin-this.Patch_Margin;){d+=this.Patch_Margin;c=b.substring(a.start2-d,a.start2+a.length1+d)}d+=this.Patch_Margin;(c=b.substring(a.start2-d,a.start2))&&a.diffs.unshift([0,c]);(d=b.substring(a.start2+a.length1,a.start2+a.length1+d))&&a.diffs.push([0,d]);a.start1-=c.length;a.start2-=c.length;a.length1+=
c.length+d.length;a.length2+=c.length+d.length}};
diff_match_patch.prototype.patch_make=function(a,b,c){var d;if(typeof a=="string"&&typeof b=="string"&&typeof c=="undefined"){d=a;b=this.diff_main(d,b,true);if(b.length>2){this.diff_cleanupSemantic(b);this.diff_cleanupEfficiency(b)}}else if(a&&typeof a=="object"&&typeof b=="undefined"&&typeof c=="undefined"){b=a;d=this.diff_text1(b)}else if(typeof a=="string"&&b&&typeof b=="object"&&typeof c=="undefined")d=a;else if(typeof a=="string"&&typeof b=="string"&&c&&typeof c=="object"){d=a;b=c}else throw Error("Unknown call format to patch_make.");
if(b.length===0)return[];c=[];a=new patch_obj;for(var e=0,f=0,g=0,h=d,j=0;j<b.length;j++){var i=b[j][0],k=b[j][1];if(!e&&i!==0){a.start1=f;a.start2=g}switch(i){case 1:a.diffs[e++]=b[j];a.length2+=k.length;d=d.substring(0,g)+k+d.substring(g);break;case -1:a.length1+=k.length;a.diffs[e++]=b[j];d=d.substring(0,g)+d.substring(g+k.length);break;case 0:if(k.length<=2*this.Patch_Margin&&e&&b.length!=j+1){a.diffs[e++]=b[j];a.length1+=k.length;a.length2+=k.length}else if(k.length>=2*this.Patch_Margin)if(e){this.patch_addContext_(a,
h);c.push(a);a=new patch_obj;e=0;h=d;f=g}}if(i!==1)f+=k.length;if(i!==-1)g+=k.length}if(e){this.patch_addContext_(a,h);c.push(a)}return c};diff_match_patch.prototype.patch_deepCopy=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c],e=new patch_obj;e.diffs=[];for(var f=0;f<d.diffs.length;f++)e.diffs[f]=d.diffs[f].slice();e.start1=d.start1;e.start2=d.start2;e.length1=d.length1;e.length2=d.length2;b[c]=e}return b};
diff_match_patch.prototype.patch_apply=function(a,b){if(a.length==0)return[b,[]];a=this.patch_deepCopy(a);var c=this.patch_addPadding(a);b=c+b+c;this.patch_splitMax(a);for(var d=0,e=[],f=0;f<a.length;f++){var g=a[f].start2+d,h=this.diff_text1(a[f].diffs),j,i=-1;if(h.length>this.Match_MaxBits){j=this.match_main(b,h.substring(0,this.Match_MaxBits),g);if(j!=-1){i=this.match_main(b,h.substring(h.length-this.Match_MaxBits),g+h.length-this.Match_MaxBits);if(i==-1||j>=i)j=-1}}else j=this.match_main(b,h,
g);if(j==-1){e[f]=false;d-=a[f].length2-a[f].length1}else{e[f]=true;d=j-g;g=i==-1?b.substring(j,j+h.length):b.substring(j,i+this.Match_MaxBits);if(h==g)b=b.substring(0,j)+this.diff_text2(a[f].diffs)+b.substring(j+h.length);else{g=this.diff_main(h,g,false);if(h.length>this.Match_MaxBits&&this.diff_levenshtein(g)/h.length>this.Patch_DeleteThreshold)e[f]=false;else{this.diff_cleanupSemanticLossless(g);h=0;var k;for(i=0;i<a[f].diffs.length;i++){var l=a[f].diffs[i];if(l[0]!==0)k=this.diff_xIndex(g,h);
if(l[0]===1)b=b.substring(0,j+k)+l[1]+b.substring(j+k);else if(l[0]===-1)b=b.substring(0,j+k)+b.substring(j+this.diff_xIndex(g,h+l[1].length));if(l[0]!==-1)h+=l[1].length}}}}}b=b.substring(c.length,b.length-c.length);return[b,e]};
diff_match_patch.prototype.patch_addPadding=function(a){for(var b=this.Patch_Margin,c="",d=1;d<=b;d++)c+=String.fromCharCode(d);for(d=0;d<a.length;d++){a[d].start1+=b;a[d].start2+=b}d=a[0];var e=d.diffs;if(e.length==0||e[0][0]!=0){e.unshift([0,c]);d.start1-=b;d.start2-=b;d.length1+=b;d.length2+=b}else if(b>e[0][1].length){var f=b-e[0][1].length;e[0][1]=c.substring(e[0][1].length)+e[0][1];d.start1-=f;d.start2-=f;d.length1+=f;d.length2+=f}d=a[a.length-1];e=d.diffs;if(e.length==0||e[e.length-1][0]!=
0){e.push([0,c]);d.length1+=b;d.length2+=b}else if(b>e[e.length-1][1].length){f=b-e[e.length-1][1].length;e[e.length-1][1]+=c.substring(0,f);d.length1+=f;d.length2+=f}return c};
diff_match_patch.prototype.patch_splitMax=function(a){for(var b=this.Match_MaxBits,c=0;c<a.length;c++)if(a[c].length1>b){var d=a[c];a.splice(c--,1);for(var e=d.start1,f=d.start2,g="";d.diffs.length!==0;){var h=new patch_obj,j=true;h.start1=e-g.length;h.start2=f-g.length;if(g!==""){h.length1=h.length2=g.length;h.diffs.push([0,g])}for(;d.diffs.length!==0&&h.length1<b-this.Patch_Margin;){g=d.diffs[0][0];var i=d.diffs[0][1];if(g===1){h.length2+=i.length;f+=i.length;h.diffs.push(d.diffs.shift());j=false}else if(g===
-1&&h.diffs.length==1&&h.diffs[0][0]==0&&i.length>2*b){h.length1+=i.length;e+=i.length;j=false;h.diffs.push([g,i]);d.diffs.shift()}else{i=i.substring(0,b-h.length1-this.Patch_Margin);h.length1+=i.length;e+=i.length;if(g===0){h.length2+=i.length;f+=i.length}else j=false;h.diffs.push([g,i]);if(i==d.diffs[0][1])d.diffs.shift();else d.diffs[0][1]=d.diffs[0][1].substring(i.length)}}g=this.diff_text2(h.diffs);g=g.substring(g.length-this.Patch_Margin);i=this.diff_text1(d.diffs).substring(0,this.Patch_Margin);
if(i!==""){h.length1+=i.length;h.length2+=i.length;if(h.diffs.length!==0&&h.diffs[h.diffs.length-1][0]===0)h.diffs[h.diffs.length-1][1]+=i;else h.diffs.push([0,i])}j||a.splice(++c,0,h)}}};diff_match_patch.prototype.patch_toText=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=a[c];return b.join("")};
diff_match_patch.prototype.patch_fromText=function(a){var b=[];if(!a)return b;a=a.split("\n");for(var c=0,d=/^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/;c<a.length;){var e=a[c].match(d);if(!e)throw Error("Invalid patch string: "+a[c]);var f=new patch_obj;b.push(f);f.start1=parseInt(e[1],10);if(e[2]===""){f.start1--;f.length1=1}else if(e[2]=="0")f.length1=0;else{f.start1--;f.length1=parseInt(e[2],10)}f.start2=parseInt(e[3],10);if(e[4]===""){f.start2--;f.length2=1}else if(e[4]=="0")f.length2=0;else{f.start2--;
f.length2=parseInt(e[4],10)}for(c++;c<a.length;){e=a[c].charAt(0);try{var g=decodeURI(a[c].substring(1))}catch(h){throw Error("Illegal escape in patch_fromText: "+g);}if(e=="-")f.diffs.push([-1,g]);else if(e=="+")f.diffs.push([1,g]);else if(e==" ")f.diffs.push([0,g]);else if(e=="@")break;else if(e!=="")throw Error('Invalid patch mode "'+e+'" in: '+g);c++}}return b};function patch_obj(){this.diffs=[];this.start2=this.start1=null;this.length2=this.length1=0}
patch_obj.prototype.toString=function(){var a,b;a=this.length1===0?this.start1+",0":this.length1==1?this.start1+1:this.start1+1+","+this.length1;b=this.length2===0?this.start2+",0":this.length2==1?this.start2+1:this.start2+1+","+this.length2;a=["@@ -"+a+" +"+b+" @@\n"];var c;for(b=0;b<this.diffs.length;b++){switch(this.diffs[b][0]){case 1:c="+";break;case -1:c="-";break;case 0:c=" "}a[b+1]=c+encodeURI(this.diffs[b][1])+"\n"}return a.join("").replace(/%20/g," ")};this.diff_match_patch=diff_match_patch;
this.patch_obj=patch_obj;this.DIFF_DELETE=-1;this.DIFF_INSERT=1;this.DIFF_EQUAL=0;})(typeof window !== 'undefined' ? window : exports);
(function() {
(function() {
var diff_match_patch, dmp, scope;
scope = typeof window !== "undefined" && window !== null ? window : exports;
diff_match_patch = typeof window !== "undefined" && window !== null ? window.diff_match_patch : require(__dirname + '/diff_match_patch.js').diff_match_patch;
dmp = new diff_match_patch();
return scope.nowpadCommon = {
List: (function() {
_Class.prototype.items = {};
_Class.prototype.length = 0;
function _Class() {
this.items = {};
}
_Class.prototype.forEach = function(callback) {
var key, value, _ref, _results;
_ref = this.items;
_results = [];
for (key in _ref) {
value = _ref[key];
_results.push(callback(value));
}
return _results;
};
_Class.prototype.generateId = function() {
var id;
while (true) {
id = String(Math.floor(Math.random() * 1000));
if (typeof this.items[id] === 'undefined') {
break;
}
}
return id;
};
_Class.prototype.add = function(item) {
this.items[item.id] = item;
return this.length++;
};
_Class.prototype.get = function(id) {
return this.items[id] || false;
};
_Class.prototype.has = function(id) {
return this.items[id] != null;
};
_Class.prototype.set = function(id, item) {
if (typeof this.items[id] === 'undefined') {
throw new Error('an item with the id of [' + id + '] does not exist');
}
return this.items[id] = item;
};
_Class.prototype.remove = function(id) {
var item;
if (this.has(id)) {
item = this.get(id);
delete this.items[id];
this.length--;
return item;
} else {
return false;
}
};
_Class.prototype.destroy = function(id) {
var item;
if (this.has(id)) {
item = this.get(id);
this.remove(id);
return item.destroy();
} else {
return false;
}
};
return _Class;
})(),
createPatch: function(before, after) {
var patches, patchesStr;
patches = dmp.patch_make(before, after);
patchesStr = dmp.patch_toText(patches);
return patchesStr;
},
applyPatch: function(_patchesStr, _value, _selectionRange) {
var diff, mod, pass, patch, patches, result, selectionRange, start, value, _i, _j, _len, _len2, _ref;
patches = dmp.patch_fromText(_patchesStr);
pass = false;
selectionRange = {};
_selectionRange || (_selectionRange = {});
selectionRange.selectionStart = _selectionRange.selectionStart || 0;
selectionRange.selectionEnd = _selectionRange.selectionEnd || _selectionRange.selectionStart;
result = dmp.patch_apply(patches, _value);
value = result[0];
pass = result[1][0] || false;
if (selectionRange.selectionStart || selectionRange.selectionEnd) {
for (_i = 0, _len = patches.length; _i < _len; _i++) {
patch = patches[_i];
start = 0;
mod = 0;
_ref = patch.diffs;
for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) {
diff = _ref[_j];
switch (diff[0]) {
case -1:
mod -= diff[1].length;
break;
case 1:
mod += diff[1].length;
}
}
if (patch.diffs[0][0] === 0) {
start = patch.diffs[0][1].length;
}
start += patch.start1;
if (start < selectionRange.selectionStart) {
selectionRange.selectionStart += mod;
}
if (start < selectionRange.selectionStart || start < selectionRange.selectionEnd) {
selectionRange.selectionEnd += mod;
}
console.log('selectionRange:', [_selectionRange.selectionStart, _selectionRange.selectionEnd], [selectionRange.selectionStart, selectionRange.selectionEnd], [patch.start1, start, mod]);
}
}
return {
pass: pass,
value: value,
selectionRange: selectionRange
};
}
};
})();
}).call(this);
(function() {
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
(function() {
var $, Element, List, Pad, console, jQuery, nowpad, nowpadCommon;
$ = jQuery = window.jQuery;
console = window.console;
nowpadCommon = window.nowpadCommon;
List = nowpadCommon.List;
if ($.browser.msie || typeof console === 'undefined' || typeof console.log === 'undefined') {
throw Error('Your browser is not supported yet');
}
Element = (function() {
Element.prototype.element = null;
Element.prototype.elementType = null;
function Element(element) {
this.element = element;
this.elementType = (function() {
if (this.element.getSession != null) {
return 'ace';
} else if (this.element instanceof jQuery) {
return 'jquery';
} else if (this.element instanceof window.Element) {
return 'native';
} else {
throw new Error('Unknown element type');
}
}).call(this);
}
Element.prototype.active = function(value) {
var result;
result = false;
if ((value != null) && value === true) {
switch (this.elementType) {
case 'ace':
this.element.textInput.getElement().focus();
break;
case 'jquery':
this.element.get(0).focus();
break;
case 'native':
this.element.focus();
}
result = true;
} else {
switch (this.elementType) {
case 'ace':
result = this.element.textInput.getElement() === document.activeElement;
break;
case 'jquery':
result = this.element.find(document.activeElement).add(this.element.filter(document.activeElement)).length !== 0;
break;
case 'native':
result = this.element === document.activeElement;
}
}
return result;
};
Element.prototype.value = function(value) {
if (value != null) {
switch (this.elementType) {
case 'ace':
return this.element.getSession().setValue(value);
case 'jquery':
return this.element.val(value);
case 'native':
return this.element.value = value;
}
} else {
switch (this.elementType) {
case 'ace':
return this.element.getSession().getValue();
case 'jquery':
return this.element.val();
case 'native':
return this.element.value;
}
}
};
Element.prototype.selectionRange = function(selectionRange, content) {
var element, endColumn, endRow, endSplit, endString, i, lines, range, result, selectionEnd, selectionStart, session, startColumn, startRow, startSplit, startString;
if (selectionRange != null) {
switch (this.elementType) {
case 'ace':
session = this.element.getSession();
content = content || session.getValue();
startString = content.substring(0, selectionRange.selectionStart);
endString = content.substring(0, selectionRange.selectionEnd);
startSplit = startString.split('\n');
endSplit = endString.split('\n');
startRow = startSplit.length ? startSplit.length - 1 : 0;
endRow = endSplit.length ? endSplit.length - 1 : 0;
startColumn = startSplit[startRow].length;
endColumn = endSplit[endRow].length;
return session.selection.setSelectionRange({
start: {
row: startRow,
column: startColumn
},
end: {
row: endRow,
column: endColumn
}
});
case 'jquery':
element = this.element.get(0);
element.selectionStart = selectionRange.selectionStart;
return element.selectionEnd = selectionRange.selectionEnd;
case 'native':
this.element.selectionStart = selectionRange.selectionStart;
return this.element.selectionEnd = selectionRange.selectionEnd;
}
} else {
switch (this.elementType) {
case 'ace':
lines = this.element.getSession().doc.getAllLines();
range = this.element.getSelectionRange();
selectionStart = 0;
selectionEnd = 0;
i = 0;
while (i < lines.length && i <= range.end.row) {
if (i === range.start.row) {
selectionStart += range.start.column;
} else if (i < range.start.row) {
selectionStart += lines[i].length + 1;
}
if (i === range.end.row) {
selectionEnd += range.end.column;
} else if (i <= range.end.row) {
selectionEnd += lines[i].length + 1;
}
++i;
}
return result = {
selectionStart: selectionStart,
selectionEnd: selectionEnd
};
case 'jquery':
element = this.element.get(0);
return result = {
selectionStart: el.selectionStart,
selectionEnd: el.selectionEnd
};
case 'native':
return result = {
selectionStart: this.element.selectionStart,
selectionEnd: this.element.selectionEnd
};
}
}
};
Element.prototype.line = function(line) {
if (line) {
switch (this.elementType) {
case 'ace':
return this.element.gotoLine(line);
}
}
};
Element.prototype.addClass = function(name) {
switch (this.elementType) {
case 'jquery':
return this.element.addClass(name);
}
};
Element.prototype.removeClass = function(name) {
switch (this.elementType) {
case 'jquery':
return this.element.removeClass(name);
}
};
Element.prototype.change = function(callback) {
switch (this.elementType) {
case 'ace':
return this.element.getSession().on('change', callback);
case 'jquery':
return this.element.keyup(callback);
case 'native':
return this.element.addEventListener('keyup', callback, false);
}
};
return Element;
})();
Pad = (function() {
Pad.prototype.id = null;
Pad.prototype.element = null;
Pad.prototype.documentId = null;
Pad.prototype.lastSyncedValue = '';
Pad.prototype.lastCurrentValue = '';
Pad.prototype.lastSyncedState = false;
Pad.prototype.newSyncedState = false;
Pad.prototype.newSyncedStates = [];
Pad.prototype.selectionRange = {
selectionStart: 0,
selectionEnd: 0
};
Pad.prototype.timer = false;
Pad.prototype.timerDelay = 200;
Pad.prototype.isTyping = false;
Pad.prototype.inRequest = false;
Pad.prototype.timeoutDelay = 1500;
function Pad(_arg) {
var element;
this.id = _arg.id, element = _arg.element, this.documentId = _arg.documentId;
this.element = new Element(element);
window.now.nowpad_valueSyncDocument(this.documentId, __bind(function(state, value, delay) {
this.lastCurrentValue = this.lastSyncedValue = value;
this.lastSyncedState = state;
this.timerDelay = delay;
this.element.value(value);
return window.setTimeout(__bind(function() {
return this.element.line(1);
}, this), 500);
}, this));
this.element.change(__bind(function() {
return this.resetTimer();
}, this));
}
Pad.prototype.syncNotify = function(state) {
if (state !== this.lastSyncedState) {
return this.resetTimer();
}
};
Pad.prototype.delayNotify = function(delay) {
if (delay !== this.timerDelay) {
return this.timerDelay = delay;
}
};
Pad.prototype.resetTimer = function() {
this.clearTimer();
this.isTyping = true;
return this.timer = window.setTimeout(__bind(function() {
this.isTyping = false;
return this.request();
}, this), this.timerDelay);
};
Pad.prototype.clearTimer = function() {
if (this.timer) {
window.clearTimeout(this.timer);
return this.timer = false;
}
};
Pad.prototype.request = function() {
var timeoutCallback, timeoutInterval;
if (!nowpad.ready) {
return false;
}
if (this.inRequest) {
return false;
}
this.inRequest = true;
this.sync();
this.element.addClass('sync');
timeoutCallback = __bind(function() {
window.now.nowpad_unlockDocument(this.documentId);
this.element.removeClass('sync');
return this.inRequest = false;
}, this);
timeoutInterval = window.setTimeout(timeoutCallback, this.timeoutDelay);
return window.now.nowpad_lockDocument(this.documentId, __bind(function(lockSuccess) {
var patch;
window.clearTimeout(timeoutInterval);
if (lockSuccess) {
this.lastCurrentValue = this.element.value();
this.selectionRange = this.element.selectionRange();
patch = nowpadCommon.createPatch(this.lastSyncedValue, this.lastCurrentValue);
timeoutInterval = window.setTimeout(timeoutCallback, this.timeoutDelay);
return window.now.nowpad_patchSyncDocument(this.documentId, this.lastSyncedState, patch, __bind(function(_states, _state) {
clearTimeout(timeoutInterval);
console.log('Sync response: ', {
_state: _state,
_states: _states
});
if (_states.length !== 0) {
this.newSyncedStates = _states;
this.newSyncedState = _state;
if (this.isTyping) {
this.resetTimer();
} else {
this.sync();
}
}
window.now.nowpad_unlockDocument(this.documentId);
this.element.removeClass('sync');
return this.inRequest = false;
}, this));
} else {
this.element.removeClass('sync');
this.inRequest = false;
return this.resetTimer();
}
}, this));
};
Pad.prototype.sync = function() {
var lastCurrentValue, lastSyncedState, newCurrentValue, newSelectionRange, newSyncedState, newSyncedStates, newSyncedValue, oldSelectionRange, selectionEndDifference, selectionStartDifference, state, _i, _len;
if (this.newSyncedStates.length === 0) {
return false;
}
lastCurrentValue = this.lastCurrentValue;
newCurrentValue = this.element.value();
lastSyncedState = this.lastSyncedState;
newSyncedStates = this.newSyncedStates;
newSyncedState = this.newSyncedState;
newSyncedValue = this.lastSyncedValue;
oldSelectionRange = {
selectionStart: this.selectionRange.selectionStart,
selectionEnd: this.selectionRange.selectionEnd
};
for (_i = 0, _len = newSyncedStates.length; _i < _len; _i++) {
state = newSyncedStates[_i];
console.log('remote:', state);
newSyncedValue = this.applyPatch(state, newSyncedValue);
}
if (lastCurrentValue && (lastCurrentValue !== newCurrentValue)) {
state = {
patch: nowpadCommon.createPatch(lastCurrentValue || '', newCurrentValue),
clientId: nowpad.clientId
};
console.log('local:', state);
newCurrentValue = this.applyPatch(state, newSyncedValue);
} else {
newCurrentValue = newSyncedValue;
}
if (this.element.value() !== newCurrentValue) {
newSelectionRange = this.element.selectionRange();
this.element.value(newCurrentValue);
selectionStartDifference = newSelectionRange.selectionStart - oldSelectionRange.selectionStart;
selectionEndDifference = newSelectionRange.selectionEnd - oldSelectionRange.selectionEnd;
this.selectionRange.selectionStart += selectionStartDifference;
this.selectionRange.selectionEnd += selectionEndDifference;
console.log([newSelectionRange.selectionStart, oldSelectionRange.selectionStart], [newSelectionRange.selectionEnd, oldSelectionRange.selectionEnd], [selectionStartDifference, selectionEndDifference], [this.selectionRange.selectionStart, this.selectionRange.selectionEnd]);
if (this.element.active()) {
console.log('applying cursor:', this.selectionRange);
this.element.selectionRange(this.selectionRange, newCurrentValue);
} else {
console.log('skipping cursor for element:', this.element);
}
}
this.newSyncedStates = [];
this.newSyncedState = false;
this.lastSyncedState = newSyncedState;
this.lastSyncedValue = newSyncedValue;
return this.lastCurrentValue = newSyncedValue;
};
Pad.prototype.applyPatch = function(_state, _value) {
var patchResult, patchValue;
patchResult = nowpadCommon.applyPatch(_state.patch, _value, this.selectionRange);
patchValue = patchResult.value;
if (_value !== patchValue && _state.clientId !== nowpad.clientId) {
console.log('updating cursor:', {
range: this.selectionRange,
valuesDifferent: _value !== patchValue,
clientDifferent: _state.clientId !== nowpad.clientId
});
this.selectionRange = patchResult.selectionRange;
} else {
console.log('ignored cursor:', {
range: this.selectionRange,
valuesDifferent: _value !== patchValue,
clientDifferent: _state.clientId !== nowpad.clientId
});
}
return patchValue;
};
return Pad;
})();
nowpad = window.nowpad = {
ready: false,
clientId: null,
client: {
id: null,
info: {}
},
pads: new List(),
pendingInstances: [],
init: function() {
return window.now.ready(function() {
return window.now.nowpad_handshake(function(documentId, state) {
console.log('Sync notify called: ', documentId, state);
return nowpad.pads.forEach(function(pad) {
if (pad.documentId === documentId) {
return pad.syncNotify(state);
}
});
}, function(documentId, delay) {
return nowpad.pads.forEach(function(pad) {
if (pad.documentId === documentId) {
return pad.delayNotify(delay);
}
});
}, function(clientId) {
var instance, _i, _len, _ref, _results;
nowpad.clientId = clientId;
nowpad.ready = true;
_ref = nowpad.pendingInstances;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
instance = _ref[_i];
_results.push(nowpad.createInstance(instance.config, instance.callback));
}
return _results;
});
});
},
createInstance: function(config, callback) {
var pad, padId;
if (this.ready) {
padId = nowpad.pads.generateId();
config.id = padId;
pad = new Pad(config);
this.pads.add(pad);
if (callback) {
return callback(pad);
}
} else {
return this.pendingInstances.push({
config: config,
callback: callback
});
}
}
};
nowpad.init();
return jQuery.fn.nowpad = function(documentId) {
var $this;
$this = $(this);
nowpad.createInstance({
element: $this,
documentId: documentId || $this.data('documentId') || 'empty'
});
return $this;
};
})();
}).call(this);