Team:EPF-Lausanne/PrimerDesignHelper.js

From 2012.igem.org

(Difference between revisions)
(Small interface improvements)
Line 1: Line 1:
-
/*
+
var DNA,__indexOf=Array.prototype.indexOf||function(a){for(var b=0,c=this.length;b<c;b++){if(b in this&&this[b]===a)return b}return-1};DNA=function(){function a(a){this.data=a}a.allowed=["A","C","G","T"];a.extendedAllowed=["A","C","G","T","R","Y","K","M","S","W","B","D","H","V","N"];a.RS={AatI:"AGGCCT",AatII:"GACGTC",AccI:"GTMKAC",AccIII:"TCCGGA",Acc65I:"GGTACC",AcsI:"RAATTY",AcyI:"GRCGYC",AflI:"GGWCC",AflII:"CTTAAG",AflIII:"ACRYGT",AgeI:"ACCGGT",AhaII:"GRCGYC",AhaIII:"TTTAAA",AluI:"AGCT",Alw44I:"GTGCAC",AlwNI:"CAGNNNCTG",AocI:"CCTNAGG",AosI:"TGCGCA",ApaI:"GGGCCC",ApaLI:"GTGCAC",ApoI:"RAATTY",ApyI:"CCWGG",AscI:"GGCGCGCC",AseI:"ATTAAT",AsnI:"ATTAAT",AspI:"GACNNNGTC",Asp700:"GAANNNNTTC",Asp718:"GGTACC",AspEI:"GACNNNNNGTC",AspHI:"GWGCWC",AsuII:"TTCGAA",AvaI:"CYCGRG",AvaII:"GGWCC",AviII:"TGCGCA",AvrII:"CCTAGG",BalI:"TGGCCA",BamHI:"GGATCC",BanI:"GGYRCC",BanII:"GRGCYC",BbrPI:"CACGTG",BclI:"TGATCA",BfaI:"CTAG",BfrI:"CTTAAG",BglI:"GCCNNNNNGGC",BglII:"AGATCT",BinI:"CCTAGG",BmyI:"GDGCHC",Bpu1102I:"GCTNAGC",BsaAI:"YACGTR",BsaBI:"GATNNNNATC",BsaHI:"GRCGYC",BsaJI:"CCNNGG",BseAI:"TCCGGA",BsePI:"GCGCGC",BsiEI:"CGRYCG",BsiWI:"CGTACG",BsiYI:"CCNNNNNNNGG",BslI:"CCNNNNNNNGG",Bsp1286I:"GDGCHC",Bsp1407I:"TGTACA",BspDI:"ATCGAT",BspEI:"TCCGGA",BspHI:"TCATGA",BspLU11I:"ACATGT",BsrFI:"RCCGGY",BssGI:"CCANNNNNNTGG",BssHII:"GCGCGC",Bst1107I:"GTATAC",BstBI:"TTCGAA",BstEII:"GGTNACC",BstNI:"CCWGG",BstUI:"CGCG",BstXI:"CCANNNNNNTGG",BstYI:"RGATCY",Bsu36I:"CCTNAGG",CelII:"GCTNAGC",CfoI:"GCGC",CfrI:"YGGCCR",Cfr10I:"RCCGGY",ClaI:"ATCGAT",DdeI:"CTNAG",DpnII:"GATC",DraI:"TTTAAA",DraII:"RGGNCCY",DraIII:"CACNNNGTG",DrdI:"GACNNNNNNGTC",DsaI:"CCRYGG",EaeI:"YGGCCR",EagI:"CGGCCG",Eam1105I:"GACNNNNNGTC",Ecl136II:"GAGCTC",EclXI:"CGGCCG",Eco47III:"AGCGCT",EcoNI:"CCTNNNNNAGG",EcoO109I:"RGGNCCY",EcoRI:"GAATTC",EcoRII:"CCWGG",EcoRV:"GATATC",EspI:"GCTNAGC",FnuDII:"CGCG",Fnu4HI:"GCNGC",FseI:"GGCCGGCC",FspI:"TGCGCA",HaeII:"RGCGCY",HaeIII:"GGCC",HgiAI:"GWGCWC",HhaI:"GCGC",HincII:"GTYRAC",HindII:"GTYRAC",HindIII:"AAGCTT",HinfI:"GANTC",HinPI:"GCGC",HpaI:"GTTAAC",HpaII:"CCGG",ItaI:"GCNGC",KasI:"GGCGCC",KpnI:"GGTACC",KspI:"CCGCGG",MaeI:"CTAG",MaeII:"ACGT",MaeIII:"GTNAC",MamI:"GATNNNNATC",MboI:"GATC",MfeI:"CAATTG",MluI:"ACGCGT",MluNI:"TGGCCA",MroI:"TCCGGA",MscI:"TGGCCA",MseI:"TTAA",MspI:"CCGG",MstI:"TGCGCA",MstII:"CCTNAGG",MunI:"CAATTG",MvaI:"CCWGG",MvnI:"CGCG",NaeI:"GCCGGC",NarI:"GGCGCC",NciI:"CCSGG",NcoI:"CCATGG",NdeI:"CATATG",NdeII:"GATC",NgoMI:"GCCGGC",NheI:"GCTAGC",NlaIII:"CATG",NlaIV:"GGNNCC",NotI:"GCGGCCGC",NruI:"TCGCGA",NsiI:"ATGCAT",NspBII:"CMGCKG",NspI:"RCATGY",NspII:"GDGCHC",NspV:"TTCGAA",PacI:"TTAATTAA",PaeR7I:"CTCGAG",PflMI:"CCANNNNNTGG",PinAI:"ACCGGT",PsiI:"TTATAA",PmaCI:"CACGTG",PmeI:"GTTTAAAC",PmlI:"CACGTG",PpuMI:"RGGWCCY",Psp1406I:"AACGTT",PstI:"CTGCAG",PvuI:"CGATCG",PvuII:"CAGCTG",RcaI:"TCATGA",RmaI:"CTAG",RsaI:"GTAC",RsrII:"CGGWCCG",SacI:"GAGCTC",SacII:"CCGCGG",SalI:"GTCGAC",SauI:"CCTNAGG",Sau3AI:"GATC",Sau96I:"GGNCC",ScaI:"AGTACT",ScrFI:"CCNGG",SexAI:"ACCWGGT",SfcI:"CTRYAG",SfiI:"GGCCNNNNNGGCC",SfuI:"TTCGAA",SgrAI:"CRCCGGYG",SmaI:"CCCGGG",SnaBI:"TACGTA",SnoI:"GTGCAC",SpeI:"ACTAGT",SphI:"GCATGC",SrfI:"GCCCGGGC",Sse8387I:"CCTGCAGG",SspI:"AATATT",SspBI:"TGTACA",SstI:"GAGCTC",SstII:"CCGCGG",StuI:"AGGCCT",StyI:"CCWWGG",SwaI:"ATTTAAAT",TaqI:"TCGA",TfiI:"GAWTC",ThaI:"CGCG",Tru9I:"TTAA",Tth111I:"GACNNNGTC",Van91I:"CCANNNNNTGG",XbaI:"TCTAGA",XcmI:"CCANNNNNNNNNTGG",XhoI:"CTCGAG",XhoII:"RGATCY",XmaI:"CCCGGG",XmaIII:"CGGCCG",XmnI:"GAANNNNTTC"};a.cutPositions={AatI:3,AatII:5,AccI:2,AccIII:1,Acc65I:1,AcsI:1,AcyI:2,AflI:1,AflII:1,AflIII:1,AgeI:1,AhaII:2,AhaIII:3,AluI:2,Alw44I:1,AlwNI:6,AocI:2,AosI:3,ApaI:5,ApaLI:1,ApoI:1,ApyI:0,AscI:2,AseI:2,AsnI:2,AspI:4,Asp700:5,Asp718:1,AspEI:6,AspHI:5,AsuII:2,AvaI:1,AvaII:1,AviII:3,AvrII:1,BalI:3,BamHI:1,BanI:1,BanII:5,BbrPI:3,BclI:1,BfaI:1,BfrI:1,BglI:7,BglII:1,BinI:1,BmyI:5,Bpu1102I:2,BsaAI:3,BsaBI:5,BsaHI:2,BsaJI:1,BseAI:1,BsePI:1,BsiEI:4,BsiWI:1,BsiYI:7,BslI:7,Bsp1286I:5,Bsp1407I:1,BspDI:2,BspEI:1,BspHI:1,BspLU11I:1,BsrFI:1,BssGI:8,BssHII:1,Bst1107I:3,BstBI:2,BstEII:1,BstNI:2,BstUI:2,BstXI:8,BstYI:1,Bsu36I:2,CelII:2,CfoI:3,CfrI:1,Cfr10I:1,ClaI:2,DdeI:1,DpnII:0,DraI:3,DraII:2,DraIII:6,DrdI:7,DsaI:1,EaeI:1,EagI:1,Eam1105I:6,Ecl136II:3,EclXI:1,Eco47III:3,EcoNI:5,EcoO109I:2,EcoRI:1,EcoRII:0,EcoRV:3,EspI:2,FnuDII:2,Fnu4HI:2,FseI:6,FspI:3,HaeII:5,HaeIII:2,HgiAI:5,HhaI:3,HincII:3,HindII:3,HindIII:1,HinfI:1,HinPI:1,HpaI:3,HpaII:1,ItaI:2,KasI:1,KpnI:5,KspI:4,MaeI:1,MaeII:1,MaeIII:0,MamI:5,MboI:0,MfeI:1,MluI:1,MluNI:3,MroI:1,MscI:3,MseI:1,MspI:1,MstI:3,MstII:2,MunI:1,MvaI:2,MvnI:2,NaeI:3,NarI:2,NciI:2,NcoI:1,NdeI:2,NdeII:0,NgoMI:1,NheI:1,NlaIII:4,NlaIV:3,NotI:2,NruI:3,NsiI:5,NspBII:3,NspI:5,NspII:5,NspV:2,PacI:5,PaeR7I:1,PflMI:7,PinAI:1,PsiI:3,PmaCI:3,PmeI:4,PmlI:3,PpuMI:2,Psp1406I:2,PstI:5,PvuI:4,PvuII:3,RcaI:1,RmaI:1,RsaI:2,RsrII:2,SacI:5,SacII:4,SalI:1,SauI:2,Sau3AI:0,Sau96I:1,ScaI:3,ScrFI:2,SexAI:1,SfcI:1,SfiI:8,SfuI:2,SgrAI:2,SmaI:3,SnaBI:3,SnoI:1,SpeI:1,SphI:5,SrfI:4,Sse8387I:6,SspI:3,SspBI:1,SstI:5,SstII:4,StuI:3,StyI:1,SwaI:4,TaqI:1,TfiI:1,ThaI:2,Tru9I:1,Tth111I:4,Van91I:7,XbaI:1,XcmI:8,XhoI:1,XhoII:1,XmaI:1,XmaIII:1,XmaCI:1,XmnI:5};a.RSFlipped=void 0;a.getRSFlipped=function(){var a,b,c,d,e,f;if(this.RSFlipped===void 0){this.RSFlipped={};e=this.RS;for(b in e){c=e[b];if(this.RSFlipped[c]){this.RSFlipped[c].push(b)}else{this.RSFlipped[c]=[b]}}f=this.RSFlipped;for(a in f){d=f[a];if(d.length<=2){this.RSFlipped[a]=d.join(" or ")}else{this.RSFlipped[a]=d.slice(0,d.length-1).join(", ")+" or "+d[d.length-1]}}}return this.RSFlipped};a.getCutPosition=function(b){var c,d,e;if(a.cutPositions[b]){return a.cutPositions[b]}else{e=a.cutPositions;for(c in e){d=e[c];if(c.toLowerCase()===b.toLowerCase())return d}return-1}};a.nucleotideMatches={A:["A","R","M","W","D","H","V","N"],C:["C","Y","M","S","B","H","V","N"],G:["G","R","K","S","B","D","V","N"],T:["T","Y","K","W","B","D","H","N"],R:["A","G"],Y:["C","T"],K:["G","T"],M:["A","C"],S:["C","G"],W:["A","T"],B:["C","G","T"],D:["A","G","T"],H:["A","C","T"],V:["A","C","G"],N:["A","C","G","T"]};a.fromString=function(b){var c,d,e,f,g;c=false;if(b!=null){g=this.RS;for(d in g){f=g[d];if(d.toLowerCase()===b.toLowerCase()){e=new a(f.split(""));c=true}}}else{b=""}if(!c)e=new a(b.toUpperCase().replace(/\s/ig,"").split(""));e.validateData();return e};a.fromRandom=function(b){var c,d;if(b===0||b==="0"||!b||b===void 0){return new a([])}else{c=function(){var c;c=[];for(d=1;1<=b?d<=b:d>=b;1<=b?d++:d--){c.push(a.allowed[Math.floor(Math.random()*a.allowed.length)])}return c}();return new a(c)}};a.prototype.validateData=function(b){if(b){if(this.data.some(function(b){return __indexOf.call(a.allowed,b)<0})){throw new Error("Invalid character encountered")}}else{if(this.data.some(function(b){return __indexOf.call(a.extendedAllowed,b)<0})){throw new Error("Invalid character encountered")}}};a.prototype.matches=function(b){var c;if(this.length()!==b.length())return false;c=_.zip(this.data,b.data);return _.all(c,function(b){var c,d,e,f,g,h,i,j;e=b[0],g=b[1];if(e===g){return true}else{if(__indexOf.call(a.allowed,e)>=0){return __indexOf.call(a.nucleotideMatches[e],g)>=0}if(__indexOf.call(a.allowed,g)>=0){return __indexOf.call(a.nucleotideMatches[g],e)>=0}f=a.nucleotideMatches[e];h=a.nucleotideMatches[g];for(c=0,i=f.length-1;0<=i?c<=i:c>=i;0<=i?c++:c--){for(d=0,j=h.length-1;0<=j?d<=j:d>=j;0<=j?d++:d--){if(f[c]===h[d])return true}}return false}})};a.prototype.findRS=function(b){var c,d,e,f,g,h;if(b==null)b=false;if(this.length()>15)return"";c=this.data.join("");e=a.getRSFlipped();if(e[c]){if(b){return e[c]}else{return e[c]+" (5' → 3': "+c+")"}}else{h=a.RS;for(g in h){d=h[g];f=a.fromString(g);if(this.matches(f)){if(b){d}else{d+" (5' → 3': "+c+")"}}}return""}};a.prototype.getCutPosition=function(){return a.getCutPosition(this.findRS(true))};a.prototype.containsRS=function(b){var c,d,e,f,g,h,i,j,k,l,m,n,o;d=[];for(k=0,m=b.length;k<m;k++){g=b[k];d.push(g.toLowerCase())}f=function(){var a;a=[];for(e=0;e<=10;e++){a.push("")}return a}();j=a.getRSFlipped();i=0;o=this.data;for(l=0,n=o.length;l<n;l++){c=o[l];for(e=4;e<=10;e++){f[e]+=c;if(e<=i)f[e]=f[e].substr(1);if(j[f[e]]){h=j[f[e]].toLowerCase().split(" ");if(_.some(d,function(a){return __indexOf.call(h,a)>=0})){return true}}}i++}return false};a.prototype.length=function(){return this.data.length};a.prototype.snip=function(b){if(b>=0&&b<=this.data.length){return new a(this.data.slice(0,b))}else{throw new Error("Invalid snip length (tried to snip a piece of length "+b+" in a sequence of "+this.length()+"bp)")}};a.prototype.reverseComplement=function(){var b,c,d,e,f,g,h;e=[];b=function(a){switch(a){case"A":return"T";case"T":return"A";case"C":return"G";case"G":return"C";default:throw new Error("Invalid character encountered ("+a+")")}};d=this.data.length-1;h=this.data;for(c=0,g=h.length;c<g;c++){f=h[c];e[d-c]=b(f)}return new a(e)};a.prototype.append=function(b){return new a(this.data.concat(b.data))};a.prototype.tm=function(){return TmCalc.calc(this.data)};a.prototype.toString=function(){return this.data.join("")};a.prototype.toJSON=function(){return this.toString()};a.prototype.clone=function(){return new a(this.data.slice(0))};return a}();var DNAInput,DNARSInput,DNASmallInput,Input,InputForm,NumberInput,RadioInput,SelectInput,Separator,Submit,TemperatureInput,__hasProp=Object.prototype.hasOwnProperty,__extends=function(a,b){function d(){this.constructor=a}for(var c in b){if(__hasProp.call(b,c))a[c]=b[c]}d.prototype=b.prototype;a.prototype=new d;a.__super__=b.prototype;return a};InputForm=function(){function a(b){this.update=b.update,this.submit=b.submit,this.name=b.name;this.id="inputform-"+a.i++;this.inputs=[];this.inputDict={};this.lastValue={}}a.i=0;a.create=function(b,c){var d;d=new a(b);c.forEach(function(a){return d.addInput(a)});return d};a.prototype.save=function(a){var b,c,d;try{if(JSON&&localStorage){c={};for(b in a){d=a[b];if(b==="leftRS"||b==="rightRS")d=d.rs;c[b]=d}return localStorage.setItem("values",JSON.stringify(c))}}catch(e){}};a.prototype.restore=function(){var a,b,c,d;try{if(JSON&&localStorage){b=localStorage.getItem("values");if(b!=null){b=JSON.parse(b);d=[];for(a in b){c=b[a];d.push(this.inputDict[a].value(c))}return d}}}catch(e){}};a.prototype.attach=function(a){$(a).append(this.generateDOM());$(".help-block").hide();this.restore();return this.updateCallback()};a.prototype.submitCallback=function(){var a,b,c,d,e;e=this.getFormData(),b=e.data,d=e.messages,c=e.error,a=e.changed;return typeof this.submit==="function"?this.submit(b,d,c):void 0};a.prototype.updateCallback=function(){var a,b,c,d,e;if(this.disableAuto)return;e=this.getFormData(),b=e.data,d=e.messages,c=e.error,a=e.changed;if(a){return typeof this.update==="function"?this.update(b,d,c):void 0}};a.prototype.getFormData=function(){var a,b,c,d;b={};d=[];c=false;this.inputs.forEach(function(a){var e;e=void 0;try{e=a.value()}catch(f){d.push("Error: "+f.message)}if(!a.validate(e)){c=true;d.push("The value of "+a.get("label")+" is invalid")}if(a.get("name")!=null)return b[a.get("name")]=e});a=false;if(!_.isEqual(this.lastValue,b)){a=true;this.inputs.forEach(function(a){if(a.visible(b)){return a.show()}else{return a.hide()}});this.lastValue=b;this.save(b)}return{data:b,messages:d,error:c,changed:a}};a.prototype.addInput=function(a){var b,c,d=this;if(a==="Separator"){this.inputs.push(new Separator);return}if(!window[a.type]instanceof Function){throw new Error("Passed input can't be instantiated")}b=function(){return d.updateCallback.apply(d,arguments)};if(a.type==="Submit"){b=function(){return d.submitCallback.apply(d,arguments)}}c=new window[a.type](b,a);if(!c instanceof Input)throw new Error("Object isn't an input");this.inputDict[a.name]=c;this.inputs.push(c);return this};a.prototype.get=function(a){return this.inputDict[a]};a.prototype.generateDOM=function(){var a,b,c=this;b=$("<form>").attr("id",this.id).attr("class","form-horizontal");if(this.name!=null){a=$("<fieldset>").append($("<legend>").text(this.name));b.append(a)}else{a=b}this.inputs.forEach(function(b){return a.append(b.generateDOM())});a.prepend($("<hr>")).prepend($("<div>").attr("class","control-group "+this.rowClass).append($("<label>").attr("class","control-label").attr("for","help-checkbox").html("Show help blocks")).append($("<div>").attr("class","controls").append($("<input>").attr("class","input-medium").attr("type","checkbox").attr("checked",false).attr("id","help-checkbox").on("change",function(){if($("#help-checkbox").attr("checked")){return $(".help-block").show()}else{return $(".help-block").hide()}})))).prepend($("<div>").attr("class","control-group "+this.rowClass).append($("<label>").attr("class","control-label").attr("for","autoUpdate-checkbox").html("Automatically update results (CPU-heavy, but way more useable)")).append($("<div>").attr("class","controls").append($("<input>").attr("class","input-medium").attr("type","checkbox").attr("checked","checked").attr("id","autoUpdate-checkbox").on("change",function(){if($("#autoUpdate-checkbox").attr("checked")){return c.disableAuto=false}else{return c.disableAuto=true}}))));return b};return a}();Input=function(){function a(b,c,d){this.callback=b;this.data=c;this.rowClass=d!=null?d:"";this.id="input-"+a.i++;this.type="text"}a.i=0;a.prototype.generateDOM=function(){return $("<div>").attr("id","row-"+this.id).attr("class","control-group "+this.rowClass).append(this.generateLabelDOM()).append($("<div>").attr("class","controls").append(this.generateElementDOM()).append(this.generateHelpDOM()))};a.prototype.generateLabelDOM=function(){return $("<label>").attr("class","control-label").attr("for",this.id).html(this.data.label)};a.prototype.generateInputElementDOM=function(a,b,c,d){var e;e=$("<input>").attr("class","input-medium").attr("type",b).attr("id",a).on("change",d).on("keyup",d);e.val(c);return e};a.prototype.generateElementDOM=function(){return this.generateInputElementDOM(this.id,this.type,this.data.value,this.callback)};a.prototype.generateHelpDOM=function(a){if(a==null)a=this.data.help;if(a!=null&&a.length>0){return $("<p>").attr("class","help-block").html(a)}else{return $("<p>").attr("class","help-block").attr("style","display: none")}};a.prototype.get=function(a){return this.data[a]};a.prototype.visible=function(a){if(this.data.visible!=null){return this.data.visible(a)}else{return true}};a.prototype.hide=function(){return $("#row-"+this.id).hide()};a.prototype.show=function(){return $("#row-"+this.id).show()};a.prototype.value=function(a){if(a===void 0){return $("#"+this.id).val()}else{return $("#"+this.id).val(a)}};a.prototype.validate=function(a){return true};return a}();Separator=function(a){function b(){b.__super__.constructor.apply(this,arguments)}__extends(b,a);b.prototype.generateDOM=function(){return $("<hr>").attr("id","row-"+this.id)};b.prototype.value=function(){};b.prototype.validate=function(){return true};return b}(Input);Submit=function(a){function b(){b.__super__.constructor.apply(this,arguments)}__extends(b,a);b.prototype.generateElementDOM=function(){return $("<input>").attr("type","submit").attr("value",this.data.value).attr("class","btn").click(this.callback,function(a){a.preventDefault();a.data(a);return false})};b.prototype.value=function(){};b.prototype.validate=function(){return true};return b}(Input);NumberInput=function(a){function b(){b.__super__.constructor.apply(this,arguments);this.type="number"}__extends(b,a);b.prototype.value=function(a){if(a===void 0){return parseInt(b.__super__.value.call(this),10)}else{return b.__super__.value.call(this,parseInt(a,10))}};b.prototype.validate=function(a){return!isNaN(a)};return b}(Input);TemperatureInput=function(a){function b(){b.__super__.constructor.apply(this,arguments)}__extends(b,a);b.prototype.generateElementDOM=function(){var a;a=b.__super__.generateElementDOM.call(this);return $("<div>").attr("class","input-append").append(a).append($("<span>").attr("class","add-on").text("°C"))};return b}(NumberInput);DNAInput=function(a){function b(){b.__super__.constructor.apply(this,arguments)}__extends(b,a);b.prototype.generateElementDOM=function(){var a;a=$("<textarea>").attr("class","input-xlarge").attr("id",this.id).on("change",this.callback).on("keyup",this.callback);a.val(this.data.value);return a};b.prototype.value=function(a){if(a===void 0){return DNA.fromString(b.__super__.value.call(this))}else{return b.__super__.value.call(this,a.toString())}};b.prototype.validate=function(a){return a!==void 0};return b}(Input);DNASmallInput=function(a){function b(){b.__super__.constructor.apply(this,arguments)}__extends(b,a);b.prototype.generateElementDOM=function(){var a;a=b.__super__.generateElementDOM.call(this);return $("<div>").attr("class","input-prepend input-append").append($("<span>").attr("class","add-on").text("5'")).append(this.generateInputElementDOM(this.id,"text",this.data.value,this.callback)).append($("<span>").attr("class","add-on").text("3'"))};return b}(DNAInput);DNARSInput=function(a){function b(){b.__super__.constructor.apply(this,arguments)}__extends(b,a);b.prototype.generateElementDOM=function(){var a;a=b.__super__.generateElementDOM.call(this);return $("<div>").attr("class","input-prepend input-append").append($("<span>").attr("class","add-on").text("5'")).append(this.generateInputElementDOM(this.id,"text",this.data.value,this.callback)).append($("<span>").attr("class","add-on").text("3'")).append($("<span>").attr("id",this.id+"-rs").attr("class","add-on").text("append 2"))};b.prototype.value=function(a){var c;c=b.__super__.value.call(this,a);if(c!=null&&c instanceof DNA){$("#"+this.id+"-rs").html(c.toString())}if(c===void 0)c=DNA.fromString("");return{dna:c,rs:$("#"+this.id).val()}};return b}(DNAInput);SelectInput=function(a){function b(a,c){b.__super__.constructor.apply(this,arguments);this.choices=c.choices}__extends(b,a);b.prototype.generateElementDOM=function(){var a,c,d=this;c=b.__super__.generateElementDOM.call(this);a=$("<select>").attr("class","input-medium").attr("id",this.id).on("change",this.callback).on("click",this.callback);this.choices.forEach(function(b){var c,d;c=b.name,d=b.value;return a.append($("<option>").attr("value",c).text(d))});return a};return b}(Input);RadioInput=function(a){function b(a,c){b.__super__.constructor.apply(this,arguments);this.choices=c.choices}__extends(b,a);b.prototype.generateElementDOM=function(){var a,c,d,e=this;d=b.__super__.generateElementDOM.call(this);a=$("<div>");c=0;this.choices.forEach(function(b){var c,d,f,g;g=b.name,f=b.label,d=b.help;c=$("<label>").attr("class","radio").text(f).prepend($("<input>").attr("checked",e.data.value===g).attr("type","radio").attr("id",e.id+"-"+g).attr("name",e.id).on("change",e.callback).on("click",e.callback)).append(e.generateHelpDOM(d));return a.append(c)});return a};b.prototype.value=function(a){var b,c=this;if(a===void 0){b={};this.choices.forEach(function(a){var d;d=a.name;return b[d]=$("#"+c.id+"-"+d).attr("checked")==="checked"});return b}else{if(a instanceof String){this.choices.forEach(function(b){var d;d=b.name;return $("#"+c.id+"-"+d).attr("checked",d===a)})}else{this.choices.forEach(function(b){var d;d=b.name;return $("#"+c.id+"-"+d).attr("checked",a[d])})}return a}};return b}(Input);$(function(){window.output=new Output("Primer 1 (<b>{{primer1Tm}}°C</b>, {{primer1TailLength}} + {{primer1Length}}bp): 5' → 3'<br />\n<pre class='primer'>{{primer1}}</pre>\nPrimer 2 (<b>{{primer2Tm}}°C</b>, {{primer2TailLength}} + {{primer2Length}}bp): 5' → 3'<br />\n<pre class='primer'>{{primer2}}</pre>\n<b>Annealing temperature:</b> {{annealingTm}}°C\n\n<br /><br />\n<h3>Messages</h3>\n{{_messages}}\n\n<br />\n<h3>Digestion result</h3>\n{{RSDisplay:}}\n<br />\n<h3>PCR Product</h3>\n{{DNADisplay:full}}\n<!-- <br />\n<h3>Self Dimer</h3>\n{{SelfDimerDisplay:primers}} -->");window.output.attach("#outputAttach");window.primerFinder=new PrimerFinder({output:function(a,b){window.output.setMessages(b);return window.output.set(a)}});window.form=InputForm.create({name:"Primer design helper",submit:function(a,b,c){return window.primerFinder.calc(a,b,c)},update:function(a,b,c){return window.primerFinder.calc(a,b,c)}},[{name:"dna",label:"DNA Sequence of interest",type:"DNAInput",value:"",help:"Most of the time you should just paste the DNA sequence (in the 5' → 3' direction) you want to extract/edit in this field"},{type:"Separator"},{name:"type",label:"Primer type",type:"RadioInput",choices:[{name:"normal",label:"Primers that extract the whole sequence",help:"Running a PCR using these primers will extract the entire sequence"},{name:"rs",label:"Add restriction sites",help:"Running a PCR using these primers will result in the sequence with added standardized restriction sites on both sides."},{name:"known",label:"Add a standard prefix/suffix to the sequence",help:"Running a PCR using these primers will result in the sequence with added standardized tails on both sides (for example for biobricking)."},{name:"custom",label:"Add custom tails to the sequence",help:"Running a PCR using these primers will result in the sequence with added tails on both sides."}],value:"normal"},{type:"Separator"},{name:"standardTail",label:"Standardized tails",type:"SelectInput",value:"biobrickGene",choices:[{name:"biobrickGene",value:"Biobrick (gene)"},{name:"biobrickOther",value:"Biobrick (other)"}],visible:function(a){var b;b=a.type;return b.known}},{name:"randomBases",label:"Random Bases",type:"NumberInput",value:"4",help:"This is the number of random bases will be added on both ends.",visible:function(a){var b;b=a.type;return b.rs}},{name:"leftRS",label:"Left restriction site",type:"DNARSInput",value:"",help:"You can also enter the name of the restriction enzyme (i.e. EcoRI).",visible:function(a){var b;b=a.type;return b.rs}},{name:"rightRS",label:"Right restriction site",type:"DNARSInput",value:"",help:"You can also enter the name of the restriction enzyme (i.e. EcoRI).",visible:function(a){var b;b=a.type;return b.rs}},{name:"leftTail",label:"Left tail",type:"DNASmallInput",value:"",visible:function(a){var b;b=a.type;return b.custom}},{name:"rightTail",label:"Right tail",type:"DNASmallInput",value:"",visible:function(a){var b;b=a.type;return b.custom}},{type:"Separator",visible:function(a){var b;b=a.type;return!b.normal}},{name:"tm",label:"Target Tm",type:"TemperatureInput",value:"50",help:"The program will try to create primers that have an annealing temperature close to this one."},{value:"Generate",type:"Submit"}]);return window.form.attach($("#formAttach"))});window.tails=[{name:"Biobrick (gene)",value:"biobrickGene",primer1Tail:"GTT TCT TCG AAT TCG CGG CCG CTT CTA G",primer2Tail:"GTT TCT TCC TGC AGC GGC CGC TAC TAG TA TTA TTA",messages:["Don't forget to include the first ATG and to exclude the stop codon!","The recommended minimum length of a BioBrick primer is 20bp","The recommended Tm of a BioBrick primer is between 55 and 65°C","Check that the following restriction sites are absent: EcoRI, SpeI, XbaI, PstI, NotI","Check out <a href='http://openwetware.org/wiki/Synthetic_Biology:BioBricks/Part_fabrication'>OpenWetWare's reference page</a>"],validate:function(a,b,c){var d,e;e=a.substr(0,3).toUpperCase();if(e!=="ATG")return"<b>The starting ATG seems to be absent.</b>";d=b.substr(0,3).toUpperCase();if(d==="TTA"||d==="TCA"||d==="CTA"){return"<b>Remove the stop codons from the sequence!</b>"}if(c.containsRS(["EcoRI","SpeI","XbaI","PstI","NotI"])){return"<b>One of the following restriction sites is present (and shouldn't be): EcoRI, SpeI, XbaI, PstI, NotI</b>"}return}},{name:"Biobrick (other)",value:"biobrickOther",primer1Tail:"GTT TCT TCG AAT TCG CGG CCG CTT CTA GAG",primer2Tail:"GTT TCT TCC TGC AGC GGC CGC TAC TAG TA",messages:["The recommended minimum length of a BioBrick primer is 20bp","The recommended Tm of a BioBrick primer is between 55 and 65°C","Check that the following restriction sites are absent: EcoRI, SpeI, XbaI, PstI, NotI","Check out <a href='http://openwetware.org/wiki/Synthetic_Biology:BioBricks/Part_fabrication'>OpenWetWare's reference page</a>"],validate:function(a,b,c){if(c.containsRS(["EcoRI","SpeI","XbaI","PstI","NotI"])){return"<b>One of the following restriction sites is present (and shouldn't be): EcoRI, SpeI, XbaI, PstI, NotI</b>"}return}}];var DNADisplay,Display,Output,RSDisplay,SelfDimerDisplay,__hasProp=Object.prototype.hasOwnProperty,__extends=function(a,b){function d(){this.constructor=a}for(var c in b){if(__hasProp.call(b,c))a[c]=b[c]}d.prototype=b.prototype;a.prototype=new d;a.__super__=b.prototype;return a};Output=function(){function a(b){this.template=b;this.id="output-"+a.i++;this.fields={};this.matches={};this.displays={};this.parsedTemplate=this.parseTemplate(this.template)}a.i=0;a.j=0;a.prototype.attach=function(a){var b,c,d,e,f,g;this.matches={};$(a).html(this.parsedTemplate);f=this.displays;g=[];for(d in f){e=f[d];g.push(function(){var a,d,f,g;g=[];for(a=0,d=e.length;a<d;a++){f=e[a],b=f.displayClass,c=f.displayObj;g.push(c.attach("."+b))}return g}())}return g};a.prototype.setMessages=function(a){var b;b=a;if(a.length===0)b=["No messages"];return this.getFields("_messages").html("<ul><li>"+b.join("</li><li>")+"</li></ul>")};a.prototype.wipe=function(){var a,b,c;c=this.fields;for(a in c){b=c[a];this.updateValue(a,void 0)}return this.fields={}};a.prototype.set=function(a){var b,c;for(b in a){c=a[b];this.updateValue(b,c)}this.updateValue("__all__",this.fields);return this.fields};a.prototype.updateValue=function(a,b){var c,d,e,f,g;if(this.fields[a]!==b){this.fields[a]=b;if(b!=null){this.getFields(a).html(b.toString())}else{this.getFields(a).html("")}}if(this.displays[a]!=null){f=this.displays[a];g=[];for(d=0,e=f.length;d<e;d++){c=f[d].displayObj;g.push(c.set(b))}return g}};a.prototype.getFields=function(a){if(!this.matches[a]){this.matches[a]=$("."+this.id+"-match-"+a)}return this.matches[a]};a.prototype.parseTemplate=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o;b=a[0];c=a[1];l=a+"";m=false;i=false;n=-1;k="";for(h=1,o=a.length-1;1<=o?h<=o:h>=o;1<=o?h++:h--){c=a[h];if(!m){if(b==="{"&&c==="{"){if(i){throw new Error("Invalid template, opened brackets in an already opened context")}k="";n=h;m=true;i=true}else if(b==="}"&&c==="}"){if(!i){throw new Error("Invalid template, closed unopened brackets")}g=k.indexOf(":");if(g>=0){d=k.substr(0,g);j=k.substr(g+1);if(j==="")j="__all__";e=this.id+"-display-"+d+"-"+j;l=l.replace("{{"+k+"}}","<span class='"+e+"'></span>");f=new window[d](j);if(!(this.displays[j]!=null))this.displays[j]=[];this.displays[j].push({displayClass:e,displayObj:f})}else{l=l.replace("{{"+k+"}}","<span class='"+this.id+"-match-"+k+"'></span>")}m=true;i=false}else{if(i)k+=b}}else{m=false}b=c}return l};return a}();Display=function(){function a(a){this.key=a;this.value=void 0}a.prototype.attach=function(a){throw new Error("Not implemented")};a.prototype.set=function(a){return this.value=a[this.key]};a.prototype.pad=function(a,b,c){var d;if(a==null)a="";if(b==null)b=5;if(c==null)c=false;a=a.toString();d=a.length;while(d<b){if(c){a=" "+a}else{a+=" "}d++}return a};a.prototype.wrap=function(a,b){var c,d,e;if(a==null)a="";if(b==null)b=40;a=a.toString();d=a.length;e=[];c=0;while(d>=b){e.push(a.substr(c,b));d-=b;c+=b}if(d>0)e.push(a.substr(c));return e};return a}();DNADisplay=function(a){function b(a){var c,d=this;b.__super__.constructor.apply(this,arguments);this["class"]="dnadisplay-"+b.i++;this.objects=[];c=this;this.dom=$("<div>").attr("class",this["class"]).append($("<label>").append($("<input>").attr("class",this["class"]+"-toggleLines").attr("type","checkbox").attr("checked","on").on("change",function(){if($("."+d["class"]+"-toggleLines").attr("checked")){$("."+d["class"]+"-lines").hide();$("."+d["class"]+"-numberedLines").show()}else{$("."+d["class"]+"-lines").show();$("."+d["class"]+"-numberedLines").hide()}return})).append(" Line Numbers")).append($("<pre>").attr("class",this["class"]+"-lines product").hide()).append($("<pre>").attr("class",this["class"]+"-numberedLines product"))}__extends(b,a);b.i=0;b.prototype.attach=function(a){$(a).append(this.dom);return this.objects=$("."+this["class"])};b.prototype.set=function(a){var b,c,d,e,f,g,h,i,j;h=60;e=6;i=40;d=this.wrap(a,h);f=this.wrap(a,i);g=[];for(b=0,j=f.length;b<j;b++){c=f[b];if(c.length>0){g[b]=this.pad(b*i+1,e,true)+" - "+this.pad((b+1)*i,e)+"  "+c}}this.full=d.join("\n");this.fullNumbered=g.join("\n");$("."+this["class"]+"-lines").text(this.full);return $("."+this["class"]+"-numberedLines").text(this.fullNumbered)};return b}(Display);RSDisplay=function(a){function b(a){var c;b.__super__.constructor.apply(this,arguments);this["class"]="rsdisplay-"+b.i++;this.objects=[];c=this;this.dom=$("<div>").attr("class",this["class"]).append($("<pre>").attr("class",this["class"]+"-pre"))}__extends(b,a);b.i=0;b.prototype.attach=function(a){$(a).append(this.dom);return this.objects=$("."+this["class"])};b.prototype.set=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A;s=a.rs,u=a.type,h=a.leftRS,p=a.rightRS;if(!u.rs){$("."+this["class"]+"-pre").html("Not applicable");return}i=h.rs;q=p.rs;e=s.left,m=s.right,d=s.full,l=s.randomBases;g=DNA.getCutPosition(i);if(g<0){h=DNA.fromString(e).findRS(true);g=DNA.getCutPosition(h)}else{h=i}if(h.length===0)h="?";o=DNA.getCutPosition(q);if(o<0){p=DNA.fromString(m).findRS(true);o=DNA.getCutPosition(p)}else{p=q}if(p.length===0)p="?";j=d.substr(0,l+e.length+10);r=d.substr(d.length-(l+m.length+10));if(l>6){j="..."+j.substr(l-3);r=r.substr(0,r.length-(l-3))+"...";l=6}f="";n="";c=function(a){switch(a){case"A":return"T";case"T":return"A";case"C":return"G";case"G":return"C";default:return a}};z=j.split("");for(v=0,x=z.length;v<x;v++){b=z[v];f+=c(b)}A=r.split("");for(w=0,y=A.length;w<y;w++){b=A[w];n+=c(b)}if(g>=0){k=Math.ceil(Math.abs(e.length/2-g))+1;j=j.substr(0,l+g)+this.pad("",k+1)+j.substr(l+g);f=f.substr(0,l+e.length-g)+this.pad("",k+1)+f.substr(l+e.length-g)}else{j=j.substr(0,l)+"  "+j.substr(l,e.length)+"  "+j.substr(l+e.length);f=f.substr(0,l)+"  "+f.substr(l,e.length)+"  "+f.substr(l+e.length)}if(o>=0){k=Math.ceil(Math.abs(m.length/2-o))+1;r=r.substr(0,r.length-(l+m.length-o))+this.pad("",k+1)+r.substr(r.length-(l+m.length-o));n=n.substr(0,n.length-(l+o))+this.pad("",k+1)+n.substr(n.length-(l+o))}else{r=r.substr(0,r.length-(l+m.length))+"  "+r.substr(r.length-(l+m.length),m.length)+"  "+r.substr(r.length-l);n=n.substr(0,n.length-(l+m.length))+"  "+n.substr(n.length-(l+m.length),m.length)+"  "+n.substr(n.length-l)}t=[];t.push("Left restriction site: "+h+(g<0?" (cutting site unknown)":""));t.push("Right restriction site: "+p+(o<0?" (cutting site unknown)":""));t.push("");t.push("5'"+this.pad("3'",j.length+r.length+1,true));t.push(j+"..."+r);t.push(f+"..."+n);t.push("3'"+this.pad("5'",j.length+r.length+1,true));return $("."+this["class"]+"-pre").text(t.join("\n"))};return b}(Display);SelfDimerDisplay=function(a){function b(a){var c,d=this;b.__super__.constructor.apply(this,arguments);this["class"]="selfdimerdisplay-"+RSDisplay.i++;this.objects=[];c=this;this.dom=$("<div>").attr("class",this["class"]).append($("<span>").text("This calculation is quite heavy and is done on demand. Press on the button to start the calculations:")).append("<br>").append($("<input>").attr("type","button").attr("value","Calculate").attr("class","btn").click(function(){return d.click()})).append("<br>").append("<br>").append($("<pre>").attr("class",this["class"]+"-pre").html("Press the calculate button to update this data"))}__extends(b,a);b.i=0;b.prototype.attach=function(a){$(a).append(this.dom);return this.objects=$("."+this["class"]+"-pre")};b.prototype.set=function(a){var b,c;b=a.primer1,c=a.primer2;if(b!==this.primer1||c!==this.primer2){this.primer1=b;this.primer2=c;return this.objects.html("Press the calculate button to update this data")}};b.prototype.click=function(){var a;a=this.generateReport("Primer 1",this.primer1)+"\n\n"+this.generateReport("Primer 2",this.primer2);return this.objects.html(a)};b.prototype.generateReport=function(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;g=[];g.push(a+":");l=RNA.fromString(b);p=l.findKnots(),h=p.matches,d=p.folds;g.push("Amount of matches: "+h);k=_.zip(function(){r=[];for(var a=1,c=b.length;1<=c?a<=c:a>=c;1<=c?a++:a--){r.push(a)}return r}.apply(this),b.split(""));e="";f="";for(n=0,o=k.length;n<o;n++){j=k[n];i=j[0]+" ";c=this.pad(j[1],i.length-1,true)+" ";if(e.length+i.length>60){g.push(e);g.push(f);g.push("");e="";f=""}e+=c;f+=i}if(e.length>0){g.push(e);g.push(f);g.push("")}return g.join("\n")};return b}(Display);var Primer;Primer=function(){function a(a){if(a instanceof DNA){this.seq=a.clone()}else{this.seq=DNA.fromString(a)}this.tail1=new DNA([]);this.tail2=new DNA([]);this.randEdgeSize=0}a.minLength=8;a.maxLength=50;a.maxDiff=8;a.lastData="";a.lastTail1="";a.lastTail2="";a.lastTm=0;a.lastRandEdgeSize=-1;a.reset=function(){this.lastData="";this.lastTm=0;this.lastTail1="";this.lastTail2="";return this.lastRandEdgeSize=-1};a.prototype.setTails=function(a,b){this.tail1=a;this.tail2=b};a.prototype.addRandomEdges=function(a){this.randEdgeSize=a};a.prototype.isSameAsLast=function(b,c){return a.lastTail1.toString()===this.tail1.toString()&&a.lastTail2.toString()===this.tail2.toString()&&a.lastData===DNA.fromString(b).toString()&&a.lastTm===c&&a.lastRandEdgeSize===this.randEdgeSize};a.prototype.generate=function(b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p;if(2*a.minLength>this.seq.length()){throw new Error("The given sequence is too short")}a.lastData=this.seq.toString();a.lastTm=b;a.lastTail1=this.tail1;a.lastTail2=this.tail2;a.lastRandEdgeSize=this.randEdgeSize;f=Math.min(Math.floor(this.seq.length()/2),a.maxLength);m=this.seq.reverseComplement();g=-1;h=0;i=-1;j=0;for(d=o=a.minLength;o<=f?d<=f:d>=f;o<=f?d++:d--){n=this.seq.snip(d).tm();c=Math.abs(n-b);if(c<=a.maxDiff&&(g===-1||Math.abs(h-b)>c)){g=d;h=n}if(n>=b)break}for(e=p=a.minLength;p<=f?e<=f:e>=f;p<=f?e++:e--){n=m.snip(e).tm();c=Math.abs(n-b);if(c<=a.maxDiff&&(i===-1||Math.abs(j-b)>c)){i=e;j=n}if(n>=b)break}if(g<0||i<0){throw new Error("Couldn't find a primer of correct length that satisfies the conditions")}k=DNA.fromRandom(this.randEdgeSize);l=DNA.fromRandom(this.randEdgeSize);return{rs:{left:this.tail1.toString(),right:this.tail2.toString(),randomBases:this.randEdgeSize,full:k.toString()+this.tail1.toString()+this.seq.toString()+this.tail2.reverseComplement().toString()+l.reverseComplement().toString()},primer1:k.toString()+" "+this.tail1.toString()+" "+this.seq.snip(g).toString(),primers:{primer1:k.toString()+this.tail1.toString()+this.seq.snip(g).toString(),primer2:l.toString()+this.tail2.toString()+m.snip(i).toString()},primer1NoTail:this.seq.snip(g).toString(),primer1Tm:h,primer1Length:g,primer1TailLength:k.length()+this.tail1.length(),primer2:l.toString()+" "+this.tail2.toString()+" "+m.snip(i).toString(),primer2NoTail:m.snip(i).toString(),primer2Tm:j,primer2Length:i,primer2TailLength:l.length()+this.tail2.length(),full:k.toString()+this.tail1.toString()+this.seq.toString()+this.tail2.reverseComplement().toString()+l.reverseComplement().toString()}};return a}();var PrimerFinder;PrimerFinder=function(){function a(a){this.output=a.output;this.defaults={primer1:"No data",primer1Tm:"?",primer1Length:0,primer2:"No data",primer2Tm:"?",primer2Length:0,annealingTm:"?"}}a.prototype.calc=function(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;if(c){b=["A fatal error occured:"].concat(b);this.output(a,b);return}q=this.defaults;for(d in q){m=q[d];if(!(a[d]!=null))a[d]=m}try{g=new Primer(a.dna);n=function(a,b,c){};if(a.type.custom)g.setTails(a.leftTail,a.rightTail);if(a.type.rs){e=a.leftRS.dna.findRS();f=a.rightRS.dna.findRS();if(e!=null&&e.length>0){b.push("The left restriction site is "+e)}else{b.push("The left restriction site wasn't recognized")}if(f!=null&&f.length>0){b.push("The right restriction site is "+f)}else{b.push("The right restriction site wasn't recognized")}g.setTails(a.leftRS.dna,a.rightRS.dna.reverseComplement());g.addRandomEdges(a.randomBases);b.push("Click the 'Generate' button to regenerate the random bases added on the end of the primers.");b.push("In the case of a plasmid where the piece between A and B is cut out, and A is used for the primer 1 RS (and B for the second).\nThe generated primers will put the RS such that the given DNA starts at the A side and ends at the B side (in short,\nit will probably work as you expected, but still check what happens with some other tool).")}if(a.type.known){k="";l="";r=window.tails;for(o=0,p=r.length;o<p;o++){j=r[o];if(j.value===a.standardTail){k=j.primer1Tail;l=j.primer2Tail;if(j.messages!=null)b=[].concat(j.messages);if(j.validate!=null)n=j.validate}}g.setTails(DNA.fromString(k),DNA.fromString(l))}h=g.generate(a.tm);i=n(h.primer1NoTail,h.primer2NoTail,a.dna);if(i!=null)b.push(i);for(d in h){m=h[d];a[d]=m}b=b}catch(s){b=[s.message]}a.annealingTm=Math.min(a.primer1Tm,a.primer2Tm);if(Math.abs(a.primer1Tm-a.primer2Tm)>5){b.push("The difference between the primer's Tm is more than 5°C")}if(a.annealingTm>70){b.push("Consider using the two-step PCR protocol")}if(a.annealingTm>72){b.push("Annealing temperature shouldn't exceed 72°C");a.annealingTm=72}if(a.annealingTm<45){b.push("The annealing temperature should be more than 45°C")}return this.output(a,b)};return a}();var RNA;RNA=function(){function a(a){this.data=a;this.n=this.data.length;this.knots=void 0}a.fromDNA=function(b){return new a(b.data.map(function(a){switch(a){case"T":return"U";default:return a}}))};a.fromString=function(b){return a.fromDNA(DNA.fromString(b))};a.prototype.P=function(a,b){if(this.data[a]==="A"&&this.data[b]==="U"||this.data[a]==="U"&&this.data[b]==="C"){return 1}else if(this.data[a]==="G"&&this.data[b]==="C"||this.data[a]==="C"&&this.data[b]==="G"){return 1}else{return 0}};a.prototype.isTooSelfComplementary=function(){var a,b,c,d,e,f,g,h,i;h=this.findKnots(),d=h.matches,b=h.folds;for(f=0,g=b.length;f<g;f++){a=b[f];e=[];console.log(a);for(c=0,i=a.length-1;0<=i?c<=i:c>=i;0<=i?c++:c--){if(a[c]==="("){if(c>0&&a[c-1]==="("){e[e.length-1]+=this.data[c]}else{e[e.length]=this.data[c]}}}console.log(e)}return false};a.prototype.findKnots=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N=this;if(a==null)a=2;if(this.knots!==void 0)return this.knots;g=function(){var a,b,c;c=[];for(a=1,b=N.n;1<=b?a<=b:a>=b;1<=b?a++:a--){c.push(".")}return c};b=[];for(n=0,D=this.n-1;0<=D?n<=D:n>=D;0<=D?n++:n--){i=[];for(o=0,F=this.n-1;0<=F?o<=F:o>=F;0<=F?o++:o--){i[o]=[g()]}b[n]=i}c=function(){var a,b;b=[];for(k=1,a=this.n;1<=a?k<=a:k>=a;1<=a?k++:k--){b.push(function(){var a,b;b=[];for(l=1,a=this.n;1<=a?l<=a:l>=a;1<=a?l++:l--){b.push(0)}return b}.call(this))}return b}.call(this);for(k=G=this.n-1;G<=0?k<=0:k>=0;G<=0?k++:k--){for(l=k,H=this.n-1;k<=H?l<=H:l>=H;k<=H?l++:l--){p=0;if(k<l-a){p=c[k+1][l-1]+this.P(k,l);j=[];I=b[k+1][l-1];for(v=0,z=I.length;v<z;v++){s=I[v];if(this.P(k,l)===1){s[k]="(";s[l]=")"}else{s[k]=".";s[l]="."}if(j.length<50)j.push(s)}for(m=k,J=l-1;k<=J?m<=J:m>=J;k<=J?m++:m--){u=c[k][m]+c[m+1][l];if(u>p){p=u;j=[]}if(u>=p){K=b[k][m];for(w=0,A=K.length;w<A;w++){e=K[w];L=b[m+1][l];for(x=0,B=L.length;x<B;x++){f=L[x];d=g(this.n);for(r=0;0<=m?r<=m:r>=m;0<=m?r++:r--){d[r]=e[r]}for(r=M=m+1;M<=l?r<=l:r>=l;M<=l?r++:r--){d[r]=f[r]}if(j.length<50)j.push(d)}}}}c[k][l]=p;b[k][l]=j}}}q=[];h={};E=b[0][this.n-1];for(y=0,C=E.length;y<C;y++){s=E[y];t=s.join("");if(h[t]===void 0){h[t]=true;q.push(t)}}return this.knots={matches:c[0][this.n-1],folds:q}};return a}();var TmCalc;TmCalc=function(){function a(){}a.maxCacheSize=500;a.cache={};a.calc=function(b){var c,d,e;if(!this.cache[b]){e=Math.round(this.calcFull(b)*10)/10;if(this.cache.length>=this.maxCacheSize){d=Object.keys(a.cache);c=d[Math.floor(Math.random()*d.length)];delete a.cache[c]}this.cache[b]=e}return this.cache[b]};a.complement=function(a){switch(a){case"A":return"T";case"T":return"A";case"C":return"G";case"G":return"C";default:throw new Error("Invalid character encountered ("+a+")")}};a.neighborH={AA:9.1,AT:8.6,TA:6,CA:5.8,GT:6.5,CT:7.8,GA:5.6,CG:11.9,GC:11.1,GG:11};a.getH=function(a,b){return this.get(this.neighborH,a,b)};a.neighborG={AA:1.9,AT:1.5,TA:.9,CA:1.9,GT:1.3,CT:1.6,GA:1.6,CG:3.6,GC:3.1,GG:3.1};a.getG=function(a,b){return this.get(this.neighborG,a,b)};a.neighborS={AA:24,AT:23.9,TA:16.9,CA:12.9,GT:17.3,CT:20.8,GA:13.5,CG:27.8,GC:26.7,GG:26.6};a.getS=function(a,b){return this.get(this.neighborS,a,b)};a.get=function(a,b,c){switch(b+c){case"AA":return a["AA"];case"TT":return a["AA"];case"AT":return a["AT"];case"TA":return a["TA"];case"TT":return a["TA"];case"CA":return a["CA"];case"TG":return a["CA"];case"GT":return a["GT"];case"AC":return a["GT"];case"CT":return a["CT"];case"AG":return a["CT"];case"GA":return a["GA"];case"TC":return a["GA"];case"CG":return a["CG"];case"TC":return a["CG"];case"GC":return a["GC"];case"TC":return a["GC"];case"GG":return a["GG"];case"CC":return a["GG"];default:throw new Error("No idea what happened... (tried getting "+b+c+")")}};a.calcFull=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o;k=0;j=-(5+.4);l=0;m=500*.01;i=50*.01;b=1.987;g=a[0];for(f=1,o=a.length-1;1<=o?f<=o:f>=o;1<=o?f++:f--){h=a[f];k-=this.getH(g,h);j-=this.getG(g,h);l-=this.getS(g,h);g=h}c=1e3*k;d=l;e=-10.8;n=m/4*1e-6;return c/(e+d+b*Math.log(n/10))-273.15+16.6*Math.log(i/10)/Math.LN10};return a}();(function(){function a(b,c,d){if(b===c)return 0!==b||1/b==1/c;if(null==b||null==c)return b===c;b._chain&&(b=b._wrapped);c._chain&&(c=c._wrapped);if(b.isEqual&&v.isFunction(b.isEqual))return b.isEqual(c);if(c.isEqual&&v.isFunction(c.isEqual))return c.isEqual(b);var e=i.call(b);if(e!=i.call(c))return!1;switch(e){case"[object String]":return b==""+c;case"[object Number]":return b!=+b?c!=+c:0==b?1/b==1/c:b==+c;case"[object Date]":case"[object Boolean]":return+b==+c;case"[object RegExp]":return b.source==c.source&&b.global==c.global&&b.multiline==c.multiline&&b.ignoreCase==c.ignoreCase}if("object"!=typeof b||"object"!=typeof c)return!1;for(var f=d.length;f--;)if(d[f]==b)return!0;d.push(b);var f=0,g=!0;if("[object Array]"==e){if(f=b.length,g=f==c.length)for(;f--&&(g=f in b==f in c&&a(b[f],c[f],d)););}else{if("constructor"in b!="constructor"in c||b.constructor!=c.constructor)return!1;for(var h in b)if(v.has(b,h)&&(f++,!(g=v.has(c,h)&&a(b[h],c[h],d))))break;if(g){for(h in c)if(v.has(c,h)&&!(f--))break;g=!f}}d.pop();return g}var b=this,c=b._,d={},e=Array.prototype,f=Object.prototype,g=e.slice,h=e.unshift,i=f.toString,j=f.hasOwnProperty,k=e.forEach,l=e.map,m=e.reduce,n=e.reduceRight,o=e.filter,p=e.every,q=e.some,r=e.indexOf,s=e.lastIndexOf,f=Array.isArray,t=Object.keys,u=Function.prototype.bind,v=function(a){return new G(a)};"undefined"!==typeof exports?("undefined"!==typeof module&&module.exports&&(exports=module.exports=v),exports._=v):b._=v;v.VERSION="1.3.3";var w=v.each=v.forEach=function(a,b,c){if(a!=null)if(k&&a.forEach===k)a.forEach(b,c);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&b.call(c,a[e],e,a)===d)break}else for(e in a)if(v.has(a,e)&&b.call(c,a[e],e,a)===d)break};v.map=v.collect=function(a,b,c){var d=[];if(a==null)return d;if(l&&a.map===l)return a.map(b,c);w(a,function(a,e,f){d[d.length]=b.call(c,a,e,f)});if(a.length===+a.length)d.length=a.length;return d};v.reduce=v.foldl=v.inject=function(a,b,c,d){var e=arguments.length>2;a==null&&(a=[]);if(m&&a.reduce===m){d&&(b=v.bind(b,d));return e?a.reduce(b,c):a.reduce(b)}w(a,function(a,f,g){if(e)c=b.call(d,c,a,f,g);else{c=a;e=true}});if(!e)throw new TypeError("Reduce of empty array with no initial value");return c};v.reduceRight=v.foldr=function(a,b,c,d){var e=arguments.length>2;a==null&&(a=[]);if(n&&a.reduceRight===n){d&&(b=v.bind(b,d));return e?a.reduceRight(b,c):a.reduceRight(b)}var f=v.toArray(a).reverse();d&&!e&&(b=v.bind(b,d));return e?v.reduce(f,b,c,d):v.reduce(f,b)};v.find=v.detect=function(a,b,c){var d;x(a,function(a,e,f){if(b.call(c,a,e,f)){d=a;return true}});return d};v.filter=v.select=function(a,b,c){var d=[];if(a==null)return d;if(o&&a.filter===o)return a.filter(b,c);w(a,function(a,e,f){b.call(c,a,e,f)&&(d[d.length]=a)});return d};v.reject=function(a,b,c){var d=[];if(a==null)return d;w(a,function(a,e,f){b.call(c,a,e,f)||(d[d.length]=a)});return d};v.every=v.all=function(a,b,c){var e=true;if(a==null)return e;if(p&&a.every===p)return a.every(b,c);w(a,function(a,f,g){if(!(e=e&&b.call(c,a,f,g)))return d});return!!e};var x=v.some=v.any=function(a,b,c){b||(b=v.identity);var e=false;if(a==null)return e;if(q&&a.some===q)return a.some(b,c);w(a,function(a,f,g){if(e||(e=b.call(c,a,f,g)))return d});return!!e};v.include=v.contains=function(a,b){var c=false;if(a==null)return c;if(r&&a.indexOf===r)return a.indexOf(b)!=-1;return c=x(a,function(a){return a===b})};v.invoke=function(a,b){var c=g.call(arguments,2);return v.map(a,function(a){return(v.isFunction(b)?b||a:a[b]).apply(a,c)})};v.pluck=function(a,b){return v.map(a,function(a){return a[b]})};v.max=function(a,b,c){if(!b&&v.isArray(a)&&a[0]===+a[0])return Math.max.apply(Math,a);if(!b&&v.isEmpty(a))return-Infinity;var d={computed:-Infinity};w(a,function(a,e,f){e=b?b.call(c,a,e,f):a;e>=d.computed&&(d={value:a,computed:e})});return d.value};v.min=function(a,b,c){if(!b&&v.isArray(a)&&a[0]===+a[0])return Math.min.apply(Math,a);if(!b&&v.isEmpty(a))return Infinity;var d={computed:Infinity};w(a,function(a,e,f){e=b?b.call(c,a,e,f):a;e<d.computed&&(d={value:a,computed:e})});return d.value};v.shuffle=function(a){var b=[],c;w(a,function(a,d){c=Math.floor(Math.random()*(d+1));b[d]=b[c];b[c]=a});return b};v.sortBy=function(a,b,c){var d=v.isFunction(b)?b:function(a){return a[b]};return v.pluck(v.map(a,function(a,b,e){return{value:a,criteria:d.call(c,a,b,e)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c===void 0?1:d===void 0?-1:c<d?-1:c>d?1:0}),"value")};v.groupBy=function(a,b){var c={},d=v.isFunction(b)?b:function(a){return a[b]};w(a,function(a,b){var e=d(a,b);(c[e]||(c[e]=[])).push(a)});return c};v.sortedIndex=function(a,b,c){c||(c=v.identity);for(var d=0,e=a.length;d<e;){var f=d+e>>1;c(a[f])<c(b)?d=f+1:e=f}return d};v.toArray=function(a){return!a?[]:v.isArray(a)||v.isArguments(a)?g.call(a):a.toArray&&v.isFunction(a.toArray)?a.toArray():v.values(a)};v.size=function(a){return v.isArray(a)?a.length:v.keys(a).length};v.first=v.head=v.take=function(a,b,c){return b!=null&&!c?g.call(a,0,b):a[0]};v.initial=function(a,b,c){return g.call(a,0,a.length-(b==null||c?1:b))};v.last=function(a,b,c){return b!=null&&!c?g.call(a,Math.max(a.length-b,0)):a[a.length-1]};v.rest=v.tail=function(a,b,c){return g.call(a,b==null||c?1:b)};v.compact=function(a){return v.filter(a,function(a){return!!a})};v.flatten=function(a,b){return v.reduce(a,function(a,c){if(v.isArray(c))return a.concat(b?c:v.flatten(c));a[a.length]=c;return a},[])};v.without=function(a){return v.difference(a,g.call(arguments,1))};v.uniq=v.unique=function(a,b,c){var c=c?v.map(a,c):a,d=[];a.length<3&&(b=true);v.reduce(c,function(c,e,f){if(b?v.last(c)!==e||!c.length:!v.include(c,e)){c.push(e);d.push(a[f])}return c},[]);return d};v.union=function(){return v.uniq(v.flatten(arguments,true))};v.intersection=v.intersect=function(a){var b=g.call(arguments,1);return v.filter(v.uniq(a),function(a){return v.every(b,function(b){return v.indexOf(b,a)>=0})})};v.difference=function(a){var b=v.flatten(g.call(arguments,1),true);return v.filter(a,function(a){return!v.include(b,a)})};v.zip=function(){for(var a=g.call(arguments),b=v.max(v.pluck(a,"length")),c=Array(b),d=0;d<b;d++)c[d]=v.pluck(a,""+d);return c};v.indexOf=function(a,b,c){if(a==null)return-1;var d;if(c){c=v.sortedIndex(a,b);return a[c]===b?c:-1}if(r&&a.indexOf===r)return a.indexOf(b);c=0;for(d=a.length;c<d;c++)if(c in a&&a[c]===b)return c;return-1};v.lastIndexOf=function(a,b){if(a==null)return-1;if(s&&a.lastIndexOf===s)return a.lastIndexOf(b);for(var c=a.length;c--;)if(c in a&&a[c]===b)return c;return-1};v.range=function(a,b,c){if(arguments.length<=1){b=a||0;a=0}for(var c=arguments[2]||1,d=Math.max(Math.ceil((b-a)/c),0),e=0,f=Array(d);e<d;){f[e++]=a;a=a+c}return f};var y=function(){};v.bind=function(a,b){var c,d;if(a.bind===u&&u)return u.apply(a,g.call(arguments,1));if(!v.isFunction(a))throw new TypeError;d=g.call(arguments,2);return c=function(){if(!(this instanceof c))return a.apply(b,d.concat(g.call(arguments)));y.prototype=a.prototype;var e=new y,f=a.apply(e,d.concat(g.call(arguments)));return Object(f)===f?f:e}};v.bindAll=function(a){var b=g.call(arguments,1);b.length==0&&(b=v.functions(a));w(b,function(b){a[b]=v.bind(a[b],a)});return a};v.memoize=function(a,b){var c={};b||(b=v.identity);return function(){var d=b.apply(this,arguments);return v.has(c,d)?c[d]:c[d]=a.apply(this,arguments)}};v.delay=function(a,b){var c=g.call(arguments,2);return setTimeout(function(){return a.apply(null,c)},b)};v.defer=function(a){return v.delay.apply(v,[a,1].concat(g.call(arguments,1)))};v.throttle=function(a,b){var c,d,e,f,g,h,i=v.debounce(function(){g=f=false},b);return function(){c=this;d=arguments;e||(e=setTimeout(function(){e=null;g&&a.apply(c,d);i()},b));f?g=true:h=a.apply(c,d);i();f=true;return h}};v.debounce=function(a,b,c){var d;return function(){var e=this,f=arguments;c&&!d&&a.apply(e,f);clearTimeout(d);d=setTimeout(function(){d=null;c||a.apply(e,f)},b)}};v.once=function(a){var b=false,c;return function(){if(b)return c;b=true;return c=a.apply(this,arguments)}};v.wrap=function(a,b){return function(){var c=[a].concat(g.call(arguments,0));return b.apply(this,c)}};v.compose=function(){var a=arguments;return function(){for(var b=arguments,c=a.length-1;c>=0;c--)b=[a[c].apply(this,b)];return b[0]}};v.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};v.keys=t||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var b=[],c;for(c in a)v.has(a,c)&&(b[b.length]=c);return b};v.values=function(a){return v.map(a,v.identity)};v.functions=v.methods=function(a){var b=[],c;for(c in a)v.isFunction(a[c])&&b.push(c);return b.sort()};v.extend=function(a){w(g.call(arguments,1),function(b){for(var c in b)a[c]=b[c]});return a};v.pick=function(a){var b={};w(v.flatten(g.call(arguments,1)),function(c){c in a&&(b[c]=a[c])});return b};v.defaults=function(a){w(g.call(arguments,1),function(b){for(var c in b)a[c]==null&&(a[c]=b[c])});return a};v.clone=function(a){return!v.isObject(a)?a:v.isArray(a)?a.slice():v.extend({},a)};v.tap=function(a,b){b(a);return a};v.isEqual=function(b,c){return a(b,c,[])};v.isEmpty=function(a){if(a==null)return true;if(v.isArray(a)||v.isString(a))return a.length===0;for(var b in a)if(v.has(a,b))return false;return true};v.isElement=function(a){return!!(a&&a.nodeType==1)};v.isArray=f||function(a){return i.call(a)=="[object Array]"};v.isObject=function(a){return a===Object(a)};v.isArguments=function(a){return i.call(a)=="[object Arguments]"};v.isArguments(arguments)||(v.isArguments=function(a){return!(!a||!v.has(a,"callee"))});v.isFunction=function(a){return i.call(a)=="[object Function]"};v.isString=function(a){return i.call(a)=="[object String]"};v.isNumber=function(a){return i.call(a)=="[object Number]"};v.isFinite=function(a){return v.isNumber(a)&&isFinite(a)};v.isNaN=function(a){return a!==a};v.isBoolean=function(a){return a===true||a===false||i.call(a)=="[object Boolean]"};v.isDate=function(a){return i.call(a)=="[object Date]"};v.isRegExp=function(a){return i.call(a)=="[object RegExp]"};v.isNull=function(a){return a===null};v.isUndefined=function(a){return a===void 0};v.has=function(a,b){return j.call(a,b)};v.noConflict=function(){b._=c;return this};v.identity=function(a){return a};v.times=function(a,b,c){for(var d=0;d<a;d++)b.call(c,d)};v.escape=function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;")};v.result=function(a,b){if(a==null)return null;var c=a[b];return v.isFunction(c)?c.call(a):c};v.mixin=function(a){w(v.functions(a),function(b){I(b,v[b]=a[b])})};var z=0;v.uniqueId=function(a){var b=z++;return a?a+b:b};v.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var A=/.^/,B={"\\":"\\","'":"'",r:"\r",n:"\n",t:" ",u2028:"\u2028",u2029:"\u2029"},C;for(C in B)B[B[C]]=C;var D=/\\|'|\r|\n|\t|\u2028|\u2029/g,E=/\\(\\|'|r|n|t|u2028|u2029)/g,F=function(a){return a.replace(E,function(a,b){return B[b]})};v.template=function(a,b,c){c=v.defaults(c||{},v.templateSettings);a="__p+='"+a.replace(D,function(a){return"\\"+B[a]}).replace(c.escape||A,function(a,b){return"'+\n_.escape("+F(b)+")+\n'"}).replace(c.interpolate||A,function(a,b){return"'+\n("+F(b)+")+\n'"}).replace(c.evaluate||A,function(a,b){return"';\n"+F(b)+"\n;__p+='"})+"';\n";c.variable||(a="with(obj||{}){\n"+a+"}\n");var a="var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n"+a+"return __p;\n",d=new Function(c.variable||"obj","_",a);if(b)return d(b,v);b=function(a){return d.call(this,a,v)};b.source="function("+(c.variable||"obj")+"){\n"+a+"}";return b};v.chain=function(a){return v(a).chain()};var G=function(a){this._wrapped=a};v.prototype=G.prototype;var H=function(a,b){return b?v(a).chain():a},I=function(a,b){G.prototype[a]=function(){var a=g.call(arguments);h.call(a,this._wrapped);return H(b.apply(v,a),this._chain)}};v.mixin(v);w("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=e[a];G.prototype[a]=function(){var c=this._wrapped;b.apply(c,arguments);var d=c.length;(a=="shift"||a=="splice")&&d===0&&delete c[0];return H(c,this._chain)}});w(["concat","join","slice"],function(a){var b=e[a];G.prototype[a]=function(){return H(b.apply(this._wrapped,arguments),this._chain)}});G.prototype.chain=function(){this._chain=true;return this};G.prototype.value=function(){return this._wrapped}}).call(this)
-
Immutable class that makes it possible to work with (very simplified) DNA sequences
+
-
*/
+
-
 
+
-
var DNA,
+
-
  __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
+
-
 
+
-
DNA = (function() {
+
-
 
+
-
  DNA.allowed = ["A", "C", "G", "T"];
+
-
 
+
-
  DNA.extendedAllowed = ["A", "C", "G", "T", "R", "Y", "K", "M", "S", "W", "B", "D", "H", "V", "N"];
+
-
 
+
-
  DNA.RS = {
+
-
    AatI: "AGGCCT",
+
-
    AatII: "GACGTC",
+
-
    AccI: "GTMKAC",
+
-
    AccIII: "TCCGGA",
+
-
    Acc65I: "GGTACC",
+
-
    AcsI: "RAATTY",
+
-
    AcyI: "GRCGYC",
+
-
    AflI: "GGWCC",
+
-
    AflII: "CTTAAG",
+
-
    AflIII: "ACRYGT",
+
-
    AgeI: "ACCGGT",
+
-
    AhaII: "GRCGYC",
+
-
    AhaIII: "TTTAAA",
+
-
    AluI: "AGCT",
+
-
    Alw44I: "GTGCAC",
+
-
    AlwNI: "CAGNNNCTG",
+
-
    AocI: "CCTNAGG",
+
-
    AosI: "TGCGCA",
+
-
    ApaI: "GGGCCC",
+
-
    ApaLI: "GTGCAC",
+
-
    ApoI: "RAATTY",
+
-
    ApyI: "CCWGG",
+
-
    AscI: "GGCGCGCC",
+
-
    AseI: "ATTAAT",
+
-
    AsnI: "ATTAAT",
+
-
    AspI: "GACNNNGTC",
+
-
    Asp700: "GAANNNNTTC",
+
-
    Asp718: "GGTACC",
+
-
    AspEI: "GACNNNNNGTC",
+
-
    AspHI: "GWGCWC",
+
-
    AsuII: "TTCGAA",
+
-
    AvaI: "CYCGRG",
+
-
    AvaII: "GGWCC",
+
-
    AviII: "TGCGCA",
+
-
    AvrII: "CCTAGG",
+
-
    BalI: "TGGCCA",
+
-
    BamHI: "GGATCC",
+
-
    BanI: "GGYRCC",
+
-
    BanII: "GRGCYC",
+
-
    BbrPI: "CACGTG",
+
-
    BclI: "TGATCA",
+
-
    BfaI: "CTAG",
+
-
    BfrI: "CTTAAG",
+
-
    BglI: "GCCNNNNNGGC",
+
-
    BglII: "AGATCT",
+
-
    BinI: "CCTAGG",
+
-
    BmyI: "GDGCHC",
+
-
    Bpu1102I: "GCTNAGC",
+
-
    BsaAI: "YACGTR",
+
-
    BsaBI: "GATNNNNATC",
+
-
    BsaHI: "GRCGYC",
+
-
    BsaJI: "CCNNGG",
+
-
    BseAI: "TCCGGA",
+
-
    BsePI: "GCGCGC",
+
-
    BsiEI: "CGRYCG",
+
-
    BsiWI: "CGTACG",
+
-
    BsiYI: "CCNNNNNNNGG",
+
-
    BslI: "CCNNNNNNNGG",
+
-
    Bsp1286I: "GDGCHC",
+
-
    Bsp1407I: "TGTACA",
+
-
    BspDI: "ATCGAT",
+
-
    BspEI: "TCCGGA",
+
-
    BspHI: "TCATGA",
+
-
    BspLU11I: "ACATGT",
+
-
    BsrFI: "RCCGGY",
+
-
    BssGI: "CCANNNNNNTGG",
+
-
    BssHII: "GCGCGC",
+
-
    Bst1107I: "GTATAC",
+
-
    BstBI: "TTCGAA",
+
-
    BstEII: "GGTNACC",
+
-
    BstNI: "CCWGG",
+
-
    BstUI: "CGCG",
+
-
    BstXI: "CCANNNNNNTGG",
+
-
    BstYI: "RGATCY",
+
-
    Bsu36I: "CCTNAGG",
+
-
    CelII: "GCTNAGC",
+
-
    CfoI: "GCGC",
+
-
    CfrI: "YGGCCR",
+
-
    Cfr10I: "RCCGGY",
+
-
    ClaI: "ATCGAT",
+
-
    DdeI: "CTNAG",
+
-
    DpnII: "GATC",
+
-
    DraI: "TTTAAA",
+
-
    DraII: "RGGNCCY",
+
-
    DraIII: "CACNNNGTG",
+
-
    DrdI: "GACNNNNNNGTC",
+
-
    DsaI: "CCRYGG",
+
-
    EaeI: "YGGCCR",
+
-
    EagI: "CGGCCG",
+
-
    Eam1105I: "GACNNNNNGTC",
+
-
    Ecl136II: "GAGCTC",
+
-
    EclXI: "CGGCCG",
+
-
    Eco47III: "AGCGCT",
+
-
    EcoNI: "CCTNNNNNAGG",
+
-
    EcoO109I: "RGGNCCY",
+
-
    EcoRI: "GAATTC",
+
-
    EcoRII: "CCWGG",
+
-
    EcoRV: "GATATC",
+
-
    EspI: "GCTNAGC",
+
-
    FnuDII: "CGCG",
+
-
    Fnu4HI: "GCNGC",
+
-
    FseI: "GGCCGGCC",
+
-
    FspI: "TGCGCA",
+
-
    HaeII: "RGCGCY",
+
-
    HaeIII: "GGCC",
+
-
    HgiAI: "GWGCWC",
+
-
    HhaI: "GCGC",
+
-
    HincII: "GTYRAC",
+
-
    HindII: "GTYRAC",
+
-
    HindIII: "AAGCTT",
+
-
    HinfI: "GANTC",
+
-
    HinPI: "GCGC",
+
-
    HpaI: "GTTAAC",
+
-
    HpaII: "CCGG",
+
-
    ItaI: "GCNGC",
+
-
    KasI: "GGCGCC",
+
-
    KpnI: "GGTACC",
+
-
    KspI: "CCGCGG",
+
-
    MaeI: "CTAG",
+
-
    MaeII: "ACGT",
+
-
    MaeIII: "GTNAC",
+
-
    MamI: "GATNNNNATC",
+
-
    MboI: "GATC",
+
-
    MfeI: "CAATTG",
+
-
    MluI: "ACGCGT",
+
-
    MluNI: "TGGCCA",
+
-
    MroI: "TCCGGA",
+
-
    MscI: "TGGCCA",
+
-
    MseI: "TTAA",
+
-
    MspI: "CCGG",
+
-
    MstI: "TGCGCA",
+
-
    MstII: "CCTNAGG",
+
-
    MunI: "CAATTG",
+
-
    MvaI: "CCWGG",
+
-
    MvnI: "CGCG",
+
-
    NaeI: "GCCGGC",
+
-
    NarI: "GGCGCC",
+
-
    NciI: "CCSGG",
+
-
    NcoI: "CCATGG",
+
-
    NdeI: "CATATG",
+
-
    NdeII: "GATC",
+
-
    NgoMI: "GCCGGC",
+
-
    NheI: "GCTAGC",
+
-
    NlaIII: "CATG",
+
-
    NlaIV: "GGNNCC",
+
-
    NotI: "GCGGCCGC",
+
-
    NruI: "TCGCGA",
+
-
    NsiI: "ATGCAT",
+
-
    NspBII: "CMGCKG",
+
-
    NspI: "RCATGY",
+
-
    NspII: "GDGCHC",
+
-
    NspV: "TTCGAA",
+
-
    PacI: "TTAATTAA",
+
-
    PaeR7I: "CTCGAG",
+
-
    PflMI: "CCANNNNNTGG",
+
-
    PinAI: "ACCGGT",
+
-
    PsiI: "TTATAA",
+
-
    PmaCI: "CACGTG",
+
-
    PmeI: "GTTTAAAC",
+
-
    PmlI: "CACGTG",
+
-
    PpuMI: "RGGWCCY",
+
-
    Psp1406I: "AACGTT",
+
-
    PstI: "CTGCAG",
+
-
    PvuI: "CGATCG",
+
-
    PvuII: "CAGCTG",
+
-
    RcaI: "TCATGA",
+
-
    RmaI: "CTAG",
+
-
    RsaI: "GTAC",
+
-
    RsrII: "CGGWCCG",
+
-
    SacI: "GAGCTC",
+
-
    SacII: "CCGCGG",
+
-
    SalI: "GTCGAC",
+
-
    SauI: "CCTNAGG",
+
-
    Sau3AI: "GATC",
+
-
    Sau96I: "GGNCC",
+
-
    ScaI: "AGTACT",
+
-
    ScrFI: "CCNGG",
+
-
    SexAI: "ACCWGGT",
+
-
    SfcI: "CTRYAG",
+
-
    SfiI: "GGCCNNNNNGGCC",
+
-
    SfuI: "TTCGAA",
+
-
    SgrAI: "CRCCGGYG",
+
-
    SmaI: "CCCGGG",
+
-
    SnaBI: "TACGTA",
+
-
    SnoI: "GTGCAC",
+
-
    SpeI: "ACTAGT",
+
-
    SphI: "GCATGC",
+
-
    SrfI: "GCCCGGGC",
+
-
    Sse8387I: "CCTGCAGG",
+
-
    SspI: "AATATT",
+
-
    SspBI: "TGTACA",
+
-
    SstI: "GAGCTC",
+
-
    SstII: "CCGCGG",
+
-
    StuI: "AGGCCT",
+
-
    StyI: "CCWWGG",
+
-
    SwaI: "ATTTAAAT",
+
-
    TaqI: "TCGA",
+
-
    TfiI: "GAWTC",
+
-
    ThaI: "CGCG",
+
-
    Tru9I: "TTAA",
+
-
    Tth111I: "GACNNNGTC",
+
-
    Van91I: "CCANNNNNTGG",
+
-
    XbaI: "TCTAGA",
+
-
    XcmI: "CCANNNNNNNNNTGG",
+
-
    XhoI: "CTCGAG",
+
-
    XhoII: "RGATCY",
+
-
    XmaI: "CCCGGG",
+
-
    XmaIII: "CGGCCG",
+
-
    XmaCI: "CCCGGG",
+
-
    XmnI: "GAANNNNTTC"
+
-
  };
+
-
 
+
-
  DNA.RSFlipped = void 0;
+
-
 
+
-
  DNA.getRSFlipped = function() {
+
-
    var name, seq, _ref;
+
-
    if (this.RSFlipped === void 0) {
+
-
      this.RSFlipped = {};
+
-
      _ref = this.RS;
+
-
      for (name in _ref) {
+
-
        seq = _ref[name];
+
-
        if (this.RSFlipped[seq]) {
+
-
          this.RSFlipped[seq] += " / " + name;
+
-
        } else {
+
-
          this.RSFlipped[seq] = name;
+
-
        }
+
-
      }
+
-
    }
+
-
    return this.RSFlipped;
+
-
  };
+
-
 
+
-
  DNA.nucleotideMatches = {
+
-
    A: ["A", "R", "M", "W", "D", "H", "V", "N"],
+
-
    C: ["C", "Y", "M", "S", "B", "H", "V", "N"],
+
-
    G: ["G", "R", "K", "S", "B", "D", "V", "N"],
+
-
    T: ["T", "Y", "K", "W", "B", "D", "H", "N"],
+
-
    R: ["A", "G"],
+
-
    Y: ["C", "T"],
+
-
    K: ["G", "T"],
+
-
    M: ["A", "C"],
+
-
    S: ["C", "G"],
+
-
    W: ["A", "T"],
+
-
    B: ["C", "G", "T"],
+
-
    D: ["A", "G", "T"],
+
-
    H: ["A", "C", "T"],
+
-
    V: ["A", "C", "G"],
+
-
    N: ["A", "C", "G", "T"]
+
-
  };
+
-
 
+
-
  DNA.fromString = function(data) {
+
-
    var found, name, seq, sequence, _ref;
+
-
    found = false;
+
-
    _ref = this.RS;
+
-
    for (name in _ref) {
+
-
      sequence = _ref[name];
+
-
      if (name.toLowerCase() === data.toLowerCase()) {
+
-
        seq = new DNA(sequence.split(''));
+
-
        found = true;
+
-
      }
+
-
    }
+
-
    if (!found) {
+
-
      seq = new DNA(data.toUpperCase().replace(/\s/ig, "").split(''));
+
-
    }
+
-
    seq.validateData();
+
-
    return seq;
+
-
  };
+
-
 
+
-
  DNA.fromRandom = function(length) {
+
-
    var data, i;
+
-
    if (length === 0 || length === "0" || !length || length === void 0) {
+
-
      return new DNA([]);
+
-
    } else {
+
-
      data = (function() {
+
-
        var _i, _results;
+
-
        _results = [];
+
-
        for (i = _i = 1; 1 <= length ? _i <= length : _i >= length; i = 1 <= length ? ++_i : --_i) {
+
-
          _results.push(DNA.allowed[Math.floor(Math.random() * DNA.allowed.length)]);
+
-
        }
+
-
        return _results;
+
-
      })();
+
-
      return new DNA(data);
+
-
    }
+
-
  };
+
-
 
+
-
  /*
+
-
    The constructor assumes the data has been validated (for performance reasons -> premature and non-consequent
+
-
    optimization ^^). Anyway, the DNA.fromString function is probably what you were looking for!
+
-
  */
+
-
 
+
-
 
+
-
  function DNA(data) {
+
-
    this.data = data;
+
-
  }
+
-
 
+
-
  DNA.prototype.validateData = function(strict) {
+
-
    if (strict) {
+
-
      if (this.data.some(function(x) {
+
-
        return __indexOf.call(DNA.allowed, x) < 0;
+
-
      })) {
+
-
        throw new Error("Invalid character encountered");
+
-
      }
+
-
    } else {
+
-
      if (this.data.some(function(x) {
+
-
        return __indexOf.call(DNA.extendedAllowed, x) < 0;
+
-
      })) {
+
-
        throw new Error("Invalid character encountered");
+
-
      }
+
-
    }
+
-
  };
+
-
 
+
-
  DNA.prototype.matches = function(seq2) {
+
-
    var combined;
+
-
    if (this.length() !== seq2.length()) {
+
-
      return false;
+
-
    }
+
-
    combined = _.zip(this.data, seq2.data);
+
-
    return _.all(combined, function(_arg) {
+
-
      var i, j, n1, n1Matches, n2, n2Matches, _i, _j, _ref, _ref1;
+
-
      n1 = _arg[0], n2 = _arg[1];
+
-
      if (n1 === n2) {
+
-
        return true;
+
-
      } else {
+
-
        if (__indexOf.call(DNA.allowed, n1) >= 0) {
+
-
          return __indexOf.call(DNA.nucleotideMatches[n1], n2) >= 0;
+
-
        }
+
-
        if (__indexOf.call(DNA.allowed, n2) >= 0) {
+
-
          return __indexOf.call(DNA.nucleotideMatches[n2], n1) >= 0;
+
-
        }
+
-
        n1Matches = DNA.nucleotideMatches[n1];
+
-
        n2Matches = DNA.nucleotideMatches[n2];
+
-
        for (i = _i = 0, _ref = n1Matches.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
+
-
          for (j = _j = 0, _ref1 = n2Matches.length - 1; 0 <= _ref1 ? _j <= _ref1 : _j >= _ref1; j = 0 <= _ref1 ? ++_j : --_j) {
+
-
            if (n1Matches[i] === n2Matches[j]) {
+
-
              return true;
+
-
            }
+
-
          }
+
-
        }
+
-
        return false;
+
-
      }
+
-
    });
+
-
  };
+
-
 
+
-
  DNA.prototype.findRS = function() {
+
-
    var key, name, rs, seq, _ref;
+
-
    key = this.data.join("");
+
-
    rs = DNA.getRSFlipped();
+
-
    if (rs[key]) {
+
-
      return rs[key] + " (" + key + ")";
+
-
    } else {
+
-
      _ref = DNA.RS;
+
-
      for (seq in _ref) {
+
-
        name = _ref[seq];
+
-
        if (this.matches(DNA.fromString(seq))) {
+
-
          return name + " (" + seq + ")";
+
-
        }
+
-
      }
+
-
      return "";
+
-
    }
+
-
  };
+
-
 
+
-
  DNA.prototype.length = function() {
+
-
    return this.data.length;
+
-
  };
+
-
 
+
-
  DNA.prototype.snip = function(length) {
+
-
    if (length >= 0 && length <= this.data.length) {
+
-
      return new DNA(this.data.slice(0, length));
+
-
    } else {
+
-
      throw new Error("Invalid snip length (tried to snip a piece of length " + length + " in a sequence of " + this.length() + "bp)");
+
-
    }
+
-
  };
+
-
 
+
-
  DNA.prototype.reverseComplement = function() {
+
-
    var complement, k, l, revCompl, v, _i, _len, _ref;
+
-
    revCompl = [];
+
-
    complement = function(x) {
+
-
      switch (x) {
+
-
        case "A":
+
-
          return "T";
+
-
        case "T":
+
-
          return "A";
+
-
        case "C":
+
-
          return "G";
+
-
        case "G":
+
-
          return "C";
+
-
        default:
+
-
          throw new Error("Invalid character encountered (" + x + ")");
+
-
      }
+
-
    };
+
-
    l = this.data.length - 1;
+
-
    _ref = this.data;
+
-
    for (k = _i = 0, _len = _ref.length; _i < _len; k = ++_i) {
+
-
      v = _ref[k];
+
-
      revCompl[l - k] = complement(v);
+
-
    }
+
-
    return new DNA(revCompl);
+
-
  };
+
-
 
+
-
  DNA.prototype.append = function(seqToAdd) {
+
-
    return new DNA(this.data.concat(seqToAdd.data));
+
-
  };
+
-
 
+
-
  DNA.prototype.tm = function() {
+
-
    return TmCalc.calc(this.data);
+
-
  };
+
-
 
+
-
  DNA.prototype.toString = function() {
+
-
    return this.data.join("");
+
-
  };
+
-
 
+
-
  return DNA;
+
-
 
+
-
})();
+
-
 
+
-
window.tails = [
+
-
{
+
-
name: "Biobrick (gene)",
+
-
value: "biobrickGene",
+
-
primer1Tail: "GTT TCT TCG AAT TCG CGG CCG CTT CTA G",
+
-
primer2Tail: "GTT TCT TCC TGC AGC GGC CGC TAC TAG TA TTA TTA",
+
-
messages: [
+
-
"Don't forget to include the first ATG and to exclude the stop codon!",
+
-
"The recommended minimum length of a BioBrick primer is 20bp",
+
-
"The recommended Tm of a BioBrick primer is between 55 and 65 °C",
+
-
"Check that the following restriction sites are absent: EcoRI, SpeI, XbaI, PstI, NotI",
+
-
"Check out <a href='http://openwetware.org/wiki/Synthetic_Biology:BioBricks/Part_fabrication'>OpenWetWare's reference page</a>"
+
-
],
+
-
validate: function(primer1, primer2){
+
-
var start = primer1.substr(0, 3).toUpperCase();
+
-
+
-
if(start != "ATG"){
+
-
return "<b>The starting ATG seems to be absent.</b>"
+
-
}
+
-
var end = primer2.substr(0, 3).toUpperCase();
+
-
//        TAA            TGA            TAG
+
-
if(end == "TTA" || end == "TCA" || end == "CTA"){
+
-
return "<b>Remove the stop codons from the sequence!</b>"
+
-
}
+
-
}
+
-
},
+
-
{
+
-
name: "Biobrick (other)",
+
-
value: "biobrickOther",
+
-
primer1Tail: "GTT TCT TCG AAT TCG CGG CCG CTT CTA GAG",
+
-
primer2Tail: "GTT TCT TCC TGC AGC GGC CGC TAC TAG TA",
+
-
messages: [
+
-
"The recommended minimum length of a BioBrick primer is 20bp",
+
-
"The recommended Tm of a BioBrick primer is between 55 and 65 °C",
+
-
"Check that the following restriction sites are absent: EcoRI, SpeI, XbaI, PstI, NotI",
+
-
"Check out <a href='http://openwetware.org/wiki/Synthetic_Biology:BioBricks/Part_fabrication'>OpenWetWare's reference page</a>"
+
-
]
+
-
}
+
-
];
+
-
window.calc = function(){
+
-
var data = document.getElementById("data").value;
+
-
var isNormal = document.getElementById("primerTypeNormal").checked;
+
-
var isCustom = document.getElementById("primerTypeCustom").checked;
+
-
var isRS = document.getElementById("primerTypeRestrictionSites").checked;
+
-
var isKnown = document.getElementById("primerTypeKnownTail").checked;
+
-
var isNumbered = document.getElementById("toggleLines").checked;
+
-
var goalTm = document.getElementById("goalTm").value;
+
-
+
-
try{
+
-
var messages = [];
+
-
var toAdd = {};
+
-
var p = new Primer(data);
+
-
var validate = function(primer1, primer2){};
+
-
+
-
if(isCustom){
+
-
p.setTails(DNA.fromString(document.getElementById("primer1Tail").value), DNA.fromString(document.getElementById("primer2Tail").value));
+
-
}
+
-
+
-
if(isRS){
+
-
var rs1 = DNA.fromString(document.getElementById("primer1RS").value);
+
-
var rs2 = DNA.fromString(document.getElementById("primer2RS").value);
+
-
+
-
var match1 = rs1.findRS();
+
-
var match2 = rs2.findRS();
+
-
toAdd.primer1RSMatch = match1.length > 0 ? "- "+match1 : "";
+
-
toAdd.primer2RSMatch = match2.length > 0 ? "- "+match2 : "";
+
-
+
-
p.setTails(rs1, rs2.reverseComplement());
+
-
p.addRandomEdges(document.getElementById("primerRandBases").value);
+
-
+
-
messages.push("Click the 'Calculate' button to regenerate the random bases added on the end of the primers.");
+
-
messages.push(
+
-
"In the case of a plasmid where the piece between A and B is cut out, and A is used for the primer 1 RS (and B for the second). "
+
-
+ "The generated primers will put the RS such that the given DNA starts at the A side and ends at the B side (in short, "
+
-
+ "it will probably work as you expected, but still check what happens with some other tool)."
+
-
);
+
-
}
+
-
+
-
if(isKnown){
+
-
var selected = $("#knownTailSelect").val();
+
-
+
-
var tail1 = "";
+
-
var tail2 = "";
+
-
+
-
for(var i = 0; i < window.tails.length; i++){
+
-
if(window.tails[i].value == selected){
+
-
tail1 = window.tails[i].primer1Tail;
+
-
tail2 = window.tails[i].primer2Tail;
+
-
if(window.tails[i].messages)
+
-
messages = [].concat(window.tails[i].messages);
+
-
if(window.tails[i].validate)
+
-
validate = window.tails[i].validate;
+
-
}
+
-
}
+
-
+
-
p.setTails(DNA.fromString(tail1), DNA.fromString(tail2));
+
-
}
+
-
+
-
//if(!p.isSameAsLast(data, goalTm) || window.isCurrentlyNumbered != isNumbered){
+
-
window.isCurrentlyNumbered = isNumbered;
+
-
var primers = p.generate(goalTm);
+
-
+
-
for(var key in toAdd){
+
-
primers[key] = toAdd[key];
+
-
}
+
-
+
-
var result = validate(primers.primer1NoTail, primers.primer2NoTail);
+
-
+
-
if(result)
+
-
messages.push(result);
+
-
+
-
if(messages.length > 0){
+
-
window.output({
+
-
primers: primers,
+
-
messages: messages,
+
-
numbered: isNumbered
+
-
});
+
-
}else{
+
-
window.output({
+
-
primers: primers,
+
-
numbered: isNumbered
+
-
});
+
-
}
+
-
//}
+
-
}catch(e){
+
-
window.output({
+
-
error: e.message,
+
-
numbered: isNumbered
+
-
});
+
-
}
+
-
};
+
-
window.isCurrentlyNumbered = -1;
+
-
window.output = function(options){
+
-
var output = {
+
-
message: [],
+
-
primer1: "No data",
+
-
primer1Temp: "NaN",
+
-
primer1bp: "NaN",
+
-
primer1Tailbp: "NaN",
+
-
primer1RSMatch: "",
+
-
primer2: "No data",
+
-
primer2Temp: "NaN",
+
-
primer2bp: "NaN",
+
-
primer2Tailbp: "NaN",
+
-
primer2RSMatch: "",
+
-
full: "",
+
-
numbered: false
+
-
};
+
-
if(options.numbered){
+
-
output.numbered = options.numbered;
+
-
}
+
-
+
-
if(options.error){
+
-
output.message.push(options.error);
+
-
}
+
-
if(options.messages){
+
-
output.message = output.message.concat(options.messages);
+
-
}
+
-
if(options.primers){
+
-
for(var key in options.primers){
+
-
if(key == "message"){
+
-
output[key].push(options.primers[key]);
+
-
}else{
+
-
output[key] = options.primers[key];
+
-
}
+
-
}
+
-
}
+
-
+
-
if(Math.abs(output.primer1Temp - output.primer2Temp) > 5){
+
-
output.message.push("The difference is more than 5 °C");
+
-
}
+
-
+
-
if(Math.min(output.primer1Temp, output.primer2Temp) > 72){
+
-
output.message.push("Consider using the two-step PCR protocol");
+
-
}
+
-
+
-
if(Math.min(output.primer1Temp, output.primer2Temp) > 72){
+
-
output.message.push("Annealing temperature shouldn't exceed 72 °C");
+
-
}
+
-
+
-
if(Math.min(output.primer1Temp, output.primer2Temp) < 45){
+
-
output.message.push("The annealing temperature should be more than 45 °C");
+
-
}
+
-
+
-
document.getElementById("primer1RSMatch").innerHTML = output.primer1RSMatch;
+
-
document.getElementById("primer2RSMatch").innerHTML = output.primer2RSMatch;
+
-
+
-
document.getElementById("messages").innerHTML = output.message.length > 0 ? "<ul><li>"+output.message.join("</li><li>")+"</li></ul>" : "";
+
-
document.getElementById("primer1").innerHTML = output.primer1;
+
-
document.getElementById("primer1Temp").innerHTML = output.primer1Temp;
+
-
document.getElementById("primer1bp").innerHTML = output.primer1Tailbp != 0 && output.primer1Tailbp != "NaN" ? output.primer1Tailbp+" + "+output.primer1bp : output.primer1bp;
+
-
document.getElementById("primer2").innerHTML = output.primer2;
+
-
document.getElementById("primer2Temp").innerHTML = output.primer2Temp;
+
-
document.getElementById("primer2bp").innerHTML = output.primer2Tailbp != 0 && output.primer2Tailbp != "NaN" ? output.primer2Tailbp+" + "+output.primer2bp : output.primer2bp;
+
-
document.getElementById("annealingTemp").innerHTML = Math.min(72, Math.min(output.primer1Temp, output.primer2Temp));
+
-
+
-
var width = 80;
+
-
var lines = window.wrap(output.full, width);
+
-
var outputLines = [];
+
-
if(output.numbered){
+
-
for(var i = 0; i < lines.length; i++){
+
-
outputLines[i] = window.pad(i*width+1, 6, true)+" - "+window.pad((i+1)*width, 6)+"  "+lines[i];
+
-
}
+
-
}else{
+
-
outputLines = lines;
+
-
}
+
-
document.getElementById("finalResult").innerHTML = outputLines.join("\n");
+
-
};
+
-
 
+
-
window.pad = function(str, width, right){
+
-
str += "";
+
-
while(str.length < width){
+
-
if(right){
+
-
str = " "+str;
+
-
}else{
+
-
str += " ";
+
-
}
+
-
}
+
-
return str;
+
-
}
+
-
 
+
-
window.wrap = function(str, width){
+
-
var chunks = [];
+
-
var i = 0, l = str.length;
+
-
while(i < l){
+
-
if(i + width >= l){
+
-
chunks.push(str.substr(i, l-i));
+
-
}else{
+
-
chunks.push(str.substr(i, width));
+
-
}
+
-
i += width;
+
-
}
+
-
return chunks;
+
-
};
+
-
 
+
-
window.updateRadioElements = function(){
+
-
if(document.getElementById('primerTypeRestrictionSites').checked){
+
-
$('#restrictionSiteRow').show();
+
-
}else{
+
-
$('#restrictionSiteRow').hide();
+
-
}
+
-
if(document.getElementById('primerTypeCustom').checked){
+
-
$('#customRow').show();
+
-
}else{
+
-
$('#customRow').hide();
+
-
}
+
-
if(document.getElementById('primerTypeKnownTail').checked){
+
-
$('#knownTailRow').show();
+
-
}else{
+
-
$('#knownTailRow').hide();
+
-
}
+
-
};var Primer;
+
-
 
+
-
Primer = (function() {
+
-
 
+
-
  Primer.minLength = 8;
+
-
 
+
-
  Primer.maxLength = 50;
+
-
 
+
-
  Primer.maxDiff = 8;
+
-
 
+
-
  Primer.lastData = "";
+
-
 
+
-
  Primer.lastTail1 = "";
+
-
 
+
-
  Primer.lastTail2 = "";
+
-
 
+
-
  Primer.lastTm = 0;
+
-
 
+
-
  Primer.lastRandEdgeSize = -1;
+
-
 
+
-
  Primer.reset = function() {
+
-
    this.lastData = "";
+
-
    this.lastTm = 0;
+
-
    this.lastTail1 = "";
+
-
    this.lastTail2 = "";
+
-
    return this.lastRandEdgeSize = -1;
+
-
  };
+
-
 
+
-
  function Primer(data) {
+
-
    this.seq = DNA.fromString(data);
+
-
    this.tail1 = new DNA([]);
+
-
    this.tail2 = new DNA([]);
+
-
    this.randEdgeSize = 0;
+
-
  }
+
-
 
+
-
  Primer.prototype.setTails = function(tail1, tail2) {
+
-
    this.tail1 = tail1;
+
-
    this.tail2 = tail2;
+
-
  };
+
-
 
+
-
  Primer.prototype.addRandomEdges = function(randEdgeSize) {
+
-
    this.randEdgeSize = randEdgeSize;
+
-
  };
+
-
 
+
-
  Primer.prototype.isSameAsLast = function(data, tm) {
+
-
    return Primer.lastTail1.toString() === this.tail1.toString() && Primer.lastTail2.toString() === this.tail2.toString() && Primer.lastData === DNA.fromString(data).toString() && Primer.lastTm === tm && Primer.lastRandEdgeSize === this.randEdgeSize;
+
-
  };
+
-
 
+
-
  Primer.prototype.generate = function(goal) {
+
-
    var diff, l1, l2, maxLength, primer1Length, primer1Temp, primer2Length, primer2Temp, rand1, rand2, revCompl, temp, _i, _j, _ref, _ref1;
+
-
    if (2 * Primer.minLength > this.seq.length()) {
+
-
      throw new Error("The given sequence is too short");
+
-
    }
+
-
    Primer.lastData = this.seq.toString();
+
-
    Primer.lastTm = goal;
+
-
    Primer.lastTail1 = this.tail1;
+
-
    Primer.lastTail2 = this.tail2;
+
-
    Primer.lastRandEdgeSize = this.randEdgeSize;
+
-
    maxLength = Math.min(Math.floor(this.seq.length() / 2), Primer.maxLength);
+
-
    revCompl = this.seq.reverseComplement();
+
-
    primer1Length = -1;
+
-
    primer1Temp = 0;
+
-
    primer2Length = -1;
+
-
    primer2Temp = 0;
+
-
    for (l1 = _i = _ref = Primer.minLength; _ref <= maxLength ? _i <= maxLength : _i >= maxLength; l1 = _ref <= maxLength ? ++_i : --_i) {
+
-
      temp = this.seq.snip(l1).tm();
+
-
      diff = Math.abs(temp - goal);
+
-
      if (diff <= Primer.maxDiff && (primer1Length === -1 || Math.abs(primer1Temp - goal) > diff)) {
+
-
        primer1Length = l1;
+
-
        primer1Temp = temp;
+
-
      }
+
-
      if (temp >= goal) {
+
-
        break;
+
-
      }
+
-
    }
+
-
    for (l2 = _j = _ref1 = Primer.minLength; _ref1 <= maxLength ? _j <= maxLength : _j >= maxLength; l2 = _ref1 <= maxLength ? ++_j : --_j) {
+
-
      temp = revCompl.snip(l2).tm();
+
-
      diff = Math.abs(temp - goal);
+
-
      if (diff <= Primer.maxDiff && (primer2Length === -1 || Math.abs(primer2Temp - goal) > diff)) {
+
-
        primer2Length = l2;
+
-
        primer2Temp = temp;
+
-
      }
+
-
      if (temp >= goal) {
+
-
        break;
+
-
      }
+
-
    }
+
-
    if (primer1Length < 0 || primer2Length < 0) {
+
-
      throw new Error("Couldn't find a primer of correct length that satisfies the conditions");
+
-
    }
+
-
    rand1 = DNA.fromRandom(this.randEdgeSize);
+
-
    rand2 = DNA.fromRandom(this.randEdgeSize);
+
-
    return {
+
-
      primer1: rand1.toString() + " " + this.tail1.toString() + " " + this.seq.snip(primer1Length).toString(),
+
-
      primer1NoTail: this.seq.snip(primer1Length).toString(),
+
-
      primer1Temp: primer1Temp,
+
-
      primer1bp: primer1Length,
+
-
      primer1Tailbp: rand1.length() + this.tail1.length(),
+
-
      primer2: rand2.toString() + " " + this.tail2.toString() + " " + revCompl.snip(primer2Length).toString(),
+
-
      primer2NoTail: revCompl.snip(primer2Length).toString(),
+
-
      primer2Temp: primer2Temp,
+
-
      primer2bp: primer2Length,
+
-
      primer2Tailbp: rand2.length() + this.tail2.length(),
+
-
      full: rand1.toString() + this.tail1.toString() + this.seq.toString() + this.tail2.reverseComplement().toString() + rand2.reverseComplement().toString()
+
-
    };
+
-
  };
+
-
 
+
-
  return Primer;
+
-
 
+
-
})();
+
-
var RNA;
+
-
 
+
-
RNA = (function() {
+
-
 
+
-
  RNA.fromDNA = function(dna) {
+
-
    return new RNA(dna.data.map(function(x) {
+
-
      switch (x) {
+
-
        case "T":
+
-
          return "U";
+
-
        default:
+
-
          return x;
+
-
      }
+
-
    }));
+
-
  };
+
-
 
+
-
  RNA.fromString = function(data) {
+
-
    return RNA.fromDNA(DNA.fromString(data));
+
-
  };
+
-
 
+
-
  /*
+
-
    Note: Just like for the DNA class, you probably didn't want to use the constructor. Use fromDNA or fromString instead!
+
-
  */
+
-
 
+
-
 
+
-
  function RNA(data) {
+
-
    this.data = data;
+
-
    this.n = this.data.length;
+
-
    this.knots = void 0;
+
-
  }
+
-
 
+
-
  RNA.prototype.P = function(i, j) {
+
-
    if ((this.data[i] === "A" && this.data[j] === "U") || (this.data[i] === "U" && this.data[j] === "C")) {
+
-
      return 1;
+
-
    } else if ((this.data[i] === "G" && this.data[j] === "C") || (this.data[i] === "C" && this.data[j] === "G")) {
+
-
      return 1;
+
-
    } else {
+
-
      return 0;
+
-
    }
+
-
  };
+
-
 
+
-
  RNA.prototype.isTooSelfComplementary = function() {
+
-
    var matches;
+
-
    matches = this.findKnots().matches;
+
-
    return (matches / (this.n / 2)) > 0.5;
+
-
  };
+
-
 
+
-
  RNA.prototype.findKnots = function(minSize) {
+
-
    var HM, M, a, a1, a2, createSolution, hashSet, hm, hs, i, j, k, l, m, max, output, p, sol, str, tmp, _i, _j, _k, _l, _len, _len1, _len2, _len3, _m, _n, _o, _p, _q, _r, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9, _s,
+
-
      _this = this;
+
-
    if (minSize == null) {
+
-
      minSize = 2;
+
-
    }
+
-
    if (this.knots !== void 0) {
+
-
      return this.knots;
+
-
    }
+
-
    createSolution = function() {
+
-
      var i, _i, _ref, _results;
+
-
      _results = [];
+
-
      for (i = _i = 1, _ref = _this.n; 1 <= _ref ? _i <= _ref : _i >= _ref; i = 1 <= _ref ? ++_i : --_i) {
+
-
        _results.push(".");
+
-
      }
+
-
      return _results;
+
-
    };
+
-
    HM = [];
+
-
    for (l = _i = 0, _ref = this.n - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; l = 0 <= _ref ? ++_i : --_i) {
+
-
      hm = [];
+
-
      for (m = _j = 0, _ref1 = this.n - 1; 0 <= _ref1 ? _j <= _ref1 : _j >= _ref1; m = 0 <= _ref1 ? ++_j : --_j) {
+
-
        hm[m] = [createSolution()];
+
-
      }
+
-
      HM[l] = hm;
+
-
    }
+
-
    M = (function() {
+
-
      var _k, _ref2, _results;
+
-
      _results = [];
+
-
      for (i = _k = 1, _ref2 = this.n; 1 <= _ref2 ? _k <= _ref2 : _k >= _ref2; i = 1 <= _ref2 ? ++_k : --_k) {
+
-
        _results.push((function() {
+
-
          var _l, _ref3, _results1;
+
-
          _results1 = [];
+
-
          for (j = _l = 1, _ref3 = this.n; 1 <= _ref3 ? _l <= _ref3 : _l >= _ref3; j = 1 <= _ref3 ? ++_l : --_l) {
+
-
            _results1.push(0);
+
-
          }
+
-
          return _results1;
+
-
        }).call(this));
+
-
      }
+
-
      return _results;
+
-
    }).call(this);
+
-
    for (i = _k = _ref2 = this.n - 1; _ref2 <= 0 ? _k <= 0 : _k >= 0; i = _ref2 <= 0 ? ++_k : --_k) {
+
-
      for (j = _l = i, _ref3 = this.n - 1; i <= _ref3 ? _l <= _ref3 : _l >= _ref3; j = i <= _ref3 ? ++_l : --_l) {
+
-
        max = 0;
+
-
        if (i < j - minSize) {
+
-
          max = M[i + 1][j - 1] + this.P(i, j);
+
-
          hs = [];
+
-
          _ref4 = HM[i + 1][j - 1];
+
-
          for (_m = 0, _len = _ref4.length; _m < _len; _m++) {
+
-
            sol = _ref4[_m];
+
-
            if (this.P(i, j) === 1) {
+
-
              sol[i] = "(";
+
-
              sol[j] = ")";
+
-
            } else {
+
-
              sol[i] = ".";
+
-
              sol[j] = ".";
+
-
            }
+
-
            if (hs.length < 50) {
+
-
              hs.push(sol);
+
-
            }
+
-
          }
+
-
          for (k = _n = i, _ref5 = j - 1; i <= _ref5 ? _n <= _ref5 : _n >= _ref5; k = i <= _ref5 ? ++_n : --_n) {
+
-
            tmp = M[i][k] + M[k + 1][j];
+
-
            if (tmp > max) {
+
-
              max = tmp;
+
-
              hs = [];
+
-
            }
+
-
            if (tmp >= max) {
+
-
              _ref6 = HM[i][k];
+
-
              for (_o = 0, _len1 = _ref6.length; _o < _len1; _o++) {
+
-
                a1 = _ref6[_o];
+
-
                _ref7 = HM[k + 1][j];
+
-
                for (_p = 0, _len2 = _ref7.length; _p < _len2; _p++) {
+
-
                  a2 = _ref7[_p];
+
-
                  a = createSolution(this.n);
+
-
                  for (p = _q = 0; 0 <= k ? _q <= k : _q >= k; p = 0 <= k ? ++_q : --_q) {
+
-
                    a[p] = a1[p];
+
-
                  }
+
-
                  for (p = _r = _ref8 = k + 1; _ref8 <= j ? _r <= j : _r >= j; p = _ref8 <= j ? ++_r : --_r) {
+
-
                    a[p] = a2[p];
+
-
                  }
+
-
                  if (hs.length < 50) {
+
-
                    hs.push(a);
+
-
                  }
+
-
                }
+
-
              }
+
-
            }
+
-
          }
+
-
          M[i][j] = max;
+
-
          HM[i][j] = hs;
+
-
        }
+
-
      }
+
-
    }
+
-
    output = [];
+
-
    hashSet = {};
+
-
    _ref9 = HM[0][this.n - 1];
+
-
    for (_s = 0, _len3 = _ref9.length; _s < _len3; _s++) {
+
-
      sol = _ref9[_s];
+
-
      str = sol.join("");
+
-
      if (hashSet[str] === void 0) {
+
-
        hashSet[str] = true;
+
-
        output.push(str);
+
-
      }
+
-
    }
+
-
    return this.knots = {
+
-
      matches: M[0][this.n - 1],
+
-
      folds: output
+
-
    };
+
-
  };
+
-
 
+
-
  return RNA;
+
-
 
+
-
})();
+
-
/*
+
-
Container class that helps with Tm calculations. It has been seperated to enable easy improvements to the
+
-
algorithm.
+
-
*/
+
-
 
+
-
var TmCalc;
+
-
 
+
-
TmCalc = (function() {
+
-
 
+
-
  function TmCalc() {}
+
-
 
+
-
  TmCalc.maxCacheSize = 500;
+
-
 
+
-
  TmCalc.cache = {};
+
-
 
+
-
  TmCalc.calc = function(data) {
+
-
    var key, keys, result;
+
-
    if (!this.cache[data]) {
+
-
      result = Math.round(this.calcFull(data) * 10) / 10;
+
-
      if (this.cache.length >= this.maxCacheSize) {
+
-
        keys = Object.keys(TmCalc.cache);
+
-
        key = keys[Math.floor(Math.random() * keys.length)];
+
-
        delete TmCalc.cache[key];
+
-
      }
+
-
      this.cache[data] = result;
+
-
    }
+
-
    return this.cache[data];
+
-
  };
+
-
 
+
-
  TmCalc.complement = function(n) {
+
-
    switch (n) {
+
-
      case "A":
+
-
        return "T";
+
-
      case "T":
+
-
        return "A";
+
-
      case "C":
+
-
        return "G";
+
-
      case "G":
+
-
        return "C";
+
-
      default:
+
-
        throw new Error("Invalid character encountered (" + n + ")");
+
-
    }
+
-
  };
+
-
 
+
-
  TmCalc.neighborH = {
+
-
    AA: 9.1,
+
-
    AT: 8.6,
+
-
    TA: 6.0,
+
-
    CA: 5.8,
+
-
    GT: 6.5,
+
-
    CT: 7.8,
+
-
    GA: 5.6,
+
-
    CG: 11.9,
+
-
    GC: 11.1,
+
-
    GG: 11.0
+
-
  };
+
-
 
+
-
  TmCalc.getH = function(n1, n2) {
+
-
    return this.get(this.neighborH, n1, n2);
+
-
  };
+
-
 
+
-
  TmCalc.neighborG = {
+
-
    AA: 1.9,
+
-
    AT: 1.5,
+
-
    TA: 0.9,
+
-
    CA: 1.9,
+
-
    GT: 1.3,
+
-
    CT: 1.6,
+
-
    GA: 1.6,
+
-
    CG: 3.6,
+
-
    GC: 3.1,
+
-
    GG: 3.1
+
-
  };
+
-
 
+
-
  TmCalc.getG = function(n1, n2) {
+
-
    return this.get(this.neighborG, n1, n2);
+
-
  };
+
-
 
+
-
  TmCalc.neighborS = {
+
-
    AA: 24.0,
+
-
    AT: 23.9,
+
-
    TA: 16.9,
+
-
    CA: 12.9,
+
-
    GT: 17.3,
+
-
    CT: 20.8,
+
-
    GA: 13.5,
+
-
    CG: 27.8,
+
-
    GC: 26.7,
+
-
    GG: 26.6
+
-
  };
+
-
 
+
-
  TmCalc.getS = function(n1, n2) {
+
-
    return this.get(this.neighborS, n1, n2);
+
-
  };
+
-
 
+
-
  TmCalc.get = function(searchVar, n1, n2) {
+
-
    switch (n1 + n2) {
+
-
      case "AA":
+
-
        return searchVar["AA"];
+
-
      case "TT":
+
-
        return searchVar["AA"];
+
-
      case "AT":
+
-
        return searchVar["AT"];
+
-
      case "TA":
+
-
        return searchVar["TA"];
+
-
      case "TT":
+
-
        return searchVar["TA"];
+
-
      case "CA":
+
-
        return searchVar["CA"];
+
-
      case "TG":
+
-
        return searchVar["CA"];
+
-
      case "GT":
+
-
        return searchVar["GT"];
+
-
      case "AC":
+
-
        return searchVar["GT"];
+
-
      case "CT":
+
-
        return searchVar["CT"];
+
-
      case "AG":
+
-
        return searchVar["CT"];
+
-
      case "GA":
+
-
        return searchVar["GA"];
+
-
      case "TC":
+
-
        return searchVar["GA"];
+
-
      case "CG":
+
-
        return searchVar["CG"];
+
-
      case "TC":
+
-
        return searchVar["CG"];
+
-
      case "GC":
+
-
        return searchVar["GC"];
+
-
      case "TC":
+
-
        return searchVar["GC"];
+
-
      case "GG":
+
-
        return searchVar["GG"];
+
-
      case "CC":
+
-
        return searchVar["GG"];
+
-
      default:
+
-
        throw new Error("No idea what happened... (tried getting " + n1 + n2 + ")");
+
-
    }
+
-
  };
+
-
 
+
-
  TmCalc.calcFull = function(data) {
+
-
    /* See (Breslauer et al. 1986): http://www.pnas.org/content/83/11/3746.full.pdf
+
-
    */
+
-
 
+
-
    var R, dh, ds, dsinit, i, n1, n2, naConc, predG, predH, predS, primerConc, primerc_local, _i, _ref;
+
-
    predH = 0;
+
-
    predG = -(5 + 0.4);
+
-
    predS = 0;
+
-
    primerConc = 500 * 10e-3;
+
-
    naConc = 50 * 10e-3;
+
-
    R = 1.987;
+
-
    n1 = data[0];
+
-
    for (i = _i = 1, _ref = data.length - 1; 1 <= _ref ? _i <= _ref : _i >= _ref; i = 1 <= _ref ? ++_i : --_i) {
+
-
      n2 = data[i];
+
-
      predH -= this.getH(n1, n2);
+
-
      predG -= this.getG(n1, n2);
+
-
      predS -= this.getS(n1, n2);
+
-
      n1 = n2;
+
-
    }
+
-
    dh = 1000 * predH;
+
-
    ds = predS;
+
-
    dsinit = -10.8;
+
-
    primerc_local = primerConc / 4 * 1e-6;
+
-
    return dh / (dsinit + ds + R * Math.log(primerc_local / 10)) - 273.15 + 16.6 * Math.log(naConc / 10) / Math.LN10;
+
-
  };
+
-
 
+
-
  /* Again, old
+
-
  @calcFull: (data, options) ->
+
-
    ##
+
-
    For more details see: http://www.basic.northwestern.edu/biotools/oligocalc.html
+
-
    ##
+
-
    freq = @calcFrequencies(data)
+
-
   
+
-
    if not options
+
-
      options = {}
+
-
   
+
-
    if not options.Na
+
-
      options.Na = 0.05
+
-
   
+
-
    GC = freq["G"] + freq["C"]
+
-
    AT = freq["A"] + freq["T"]
+
-
    N = data.length
+
-
   
+
-
    if N < 14
+
-
      AT*2 + GC*4 - 16.6*Math.log(0.050)/Math.log(10) + 16.6*Math.log(options.Na)/Math.log(10)
+
-
    else if N < 50 #18
+
-
      100.5 + (41 * GC/N) - (820/N) + 16.6*Math.log(options.Na)/Math.log(10)
+
-
    #else if N < 50
+
-
    #  81.5 + (41 * GC/N) - (500/N) + 16.6*Math.log(options.Na) - 0.62*options.F
+
-
    else
+
-
      79.8 + 18.5*Math.log(options.Na)/Math.log(10) + (58.4 * GC/N) + (11.8 * (GC/N) * (GC/N)) - (820/N)
+
-
   
+
-
   
+
-
 
+
-
  @calcFrequencies: (data) ->
+
-
    freq = {A: 0, C: 0, G: 0, T: 0}
+
-
    data.forEach (x) ->
+
-
      freq[x]++
+
-
    freq
+
-
  */
+
-
 
+
-
 
+
-
  return TmCalc;
+
-
 
+
-
})();
+
-
 
+
-
/* Old version (not very accurate):
+
-
  @calc: (data) ->
+
-
    Math.round(@calcFull(data)*100)/100
+
-
 
+
-
  @calcFull: (data) ->
+
-
    freq = @calcFrequencies(data)
+
-
    if data.length < 14
+
-
      4 * (freq["G"] + freq["C"]) + 2 * (freq["A"] + freq["T"])
+
-
    else
+
-
      64.9 + 41 * (freq["G"] + freq["C"] - 16.4)/data.length
+
-
 
+
-
  @calcFrequencies: (data) ->
+
-
    freq = {A: 0, C: 0, G: 0, T: 0}
+
-
    data.forEach (x) ->
+
-
      freq[x]++
+
-
    freq
+
-
*/
+
-
 
+
-
// Underscore.js 1.3.3
+
-
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
+
-
// Underscore is freely distributable under the MIT license.
+
-
// Portions of Underscore are inspired or borrowed from Prototype,
+
-
// Oliver Steele's Functional, and John Resig's Micro-Templating.
+
-
// For all details and documentation:
+
-
// http://documentcloud.github.com/underscore
+
-
(function(){function r(a,c,d){if(a===c)return 0!==a||1/a==1/c;if(null==a||null==c)return a===c;a._chain&&(a=a._wrapped);c._chain&&(c=c._wrapped);if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return!1;switch(e){case "[object String]":return a==""+c;case "[object Number]":return a!=+a?c!=+c:0==a?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
+
-
c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if("object"!=typeof a||"object"!=typeof c)return!1;for(var f=d.length;f--;)if(d[f]==a)return!0;d.push(a);var f=0,g=!0;if("[object Array]"==e){if(f=a.length,g=f==c.length)for(;f--&&(g=f in a==f in c&&r(a[f],c[f],d)););}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return!1;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,h)&&!f--)break;
+
-
g=!f}}d.pop();return g}var s=this,I=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,J=k.unshift,l=p.toString,K=p.hasOwnProperty,y=k.forEach,z=k.map,A=k.reduce,B=k.reduceRight,C=k.filter,D=k.every,E=k.some,q=k.indexOf,F=k.lastIndexOf,p=Array.isArray,L=Object.keys,t=Function.prototype.bind,b=function(a){return new m(a)};"undefined"!==typeof exports?("undefined"!==typeof module&&module.exports&&(exports=module.exports=b),exports._=b):s._=b;b.VERSION="1.3.3";var j=b.each=b.forEach=function(a,
+
-
c,d){if(a!=null)if(y&&a.forEach===y)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===o)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===o)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(z&&a.map===z)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(A&&
+
-
a.reduce===A){e&&(c=b.bind(c,e));return f?a.reduce(c,d):a.reduce(c)}j(a,function(a,b,i){if(f)d=c.call(e,d,a,b,i);else{d=a;f=true}});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(B&&a.reduceRight===B){e&&(c=b.bind(c,e));return f?a.reduceRight(c,d):a.reduceRight(c)}var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=function(a,
+
-
c,b){var e;G(a,function(a,g,h){if(c.call(b,a,g,h)){e=a;return true}});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(C&&a.filter===C)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(D&&a.every===D)return a.every(c,b);j(a,function(a,g,h){if(!(e=e&&c.call(b,
+
-
a,g,h)))return o});return!!e};var G=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(E&&a.some===E)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;if(q&&a.indexOf===q)return a.indexOf(c)!=-1;return b=G(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
+
-
function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&
+
-
(e={value:a,computed:b})});return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){d=Math.floor(Math.random()*(f+1));b[f]=b[d];b[d]=a});return b};b.sortBy=function(a,c,d){var e=b.isFunction(c)?c:function(a){return a[c]};return b.pluck(b.map(a,function(a,b,c){return{value:a,criteria:e.call(d,a,b,c)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c===void 0?1:d===void 0?-1:c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};
+
-
j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:b.isArray(a)||b.isArguments(a)?i.call(a):a.toArray&&b.isFunction(a.toArray)?a.toArray():b.values(a)};b.size=function(a){return b.isArray(a)?a.length:b.keys(a).length};b.first=b.head=b.take=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,
+
-
0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,
+
-
e=[];a.length<3&&(c=true);b.reduce(d,function(d,g,h){if(c?b.last(d)!==g||!d.length:!b.include(d,g)){d.push(g);e.push(a[h])}return d},[]);return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1),true);return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=
+
-
i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,d){if(a==null)return-1;var e;if(d){d=b.sortedIndex(a,c);return a[d]===c?d:-1}if(q&&a.indexOf===q)return a.indexOf(c);d=0;for(e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(F&&a.lastIndexOf===F)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){if(arguments.length<=
+
-
1){b=a||0;a=0}for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;){g[f++]=a;a=a+d}return g};var H=function(){};b.bind=function(a,c){var d,e;if(a.bind===t&&t)return t.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));H.prototype=a.prototype;var b=new H,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=
+
-
i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(null,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i,j=b.debounce(function(){h=
+
-
g=false},c);return function(){d=this;e=arguments;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);j()},c));g?h=true:i=a.apply(d,e);j();g=true;return i}};b.debounce=function(a,b,d){var e;return function(){var f=this,g=arguments;d&&!e&&a.apply(f,g);clearTimeout(e);e=setTimeout(function(){e=null;d||a.apply(f,g)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));
+
-
return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=L||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&
+
-
c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.pick=function(a){var c={};j(b.flatten(i.call(arguments,1)),function(b){b in a&&(c[b]=a[b])});return c};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty=
+
-
function(a){if(a==null)return true;if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=function(a){return l.call(a)=="[object Arguments]"};b.isArguments(arguments)||(b.isArguments=function(a){return!(!a||!b.has(a,"callee"))});b.isFunction=function(a){return l.call(a)=="[object Function]"};
+
-
b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isFinite=function(a){return b.isNumber(a)&&isFinite(a)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,
+
-
b){return K.call(a,b)};b.noConflict=function(){s._=I;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;")};b.result=function(a,c){if(a==null)return null;var d=a[c];return b.isFunction(d)?d.call(a):d};b.mixin=function(a){j(b.functions(a),function(c){M(c,b[c]=a[c])})};var N=0;b.uniqueId=
+
-
function(a){var b=N++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var u=/.^/,n={"\\":"\\","'":"'",r:"\r",n:"\n",t:"\t",u2028:"\u2028",u2029:"\u2029"},v;for(v in n)n[n[v]]=v;var O=/\\|'|\r|\n|\t|\u2028|\u2029/g,P=/\\(\\|'|r|n|t|u2028|u2029)/g,w=function(a){return a.replace(P,function(a,b){return n[b]})};b.template=function(a,c,d){d=b.defaults(d||{},b.templateSettings);a="__p+='"+a.replace(O,function(a){return"\\"+n[a]}).replace(d.escape||
+
-
u,function(a,b){return"'+\n_.escape("+w(b)+")+\n'"}).replace(d.interpolate||u,function(a,b){return"'+\n("+w(b)+")+\n'"}).replace(d.evaluate||u,function(a,b){return"';\n"+w(b)+"\n;__p+='"})+"';\n";d.variable||(a="with(obj||{}){\n"+a+"}\n");var a="var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n"+a+"return __p;\n",e=new Function(d.variable||"obj","_",a);if(c)return e(c,b);c=function(a){return e.call(this,a,b)};c.source="function("+(d.variable||"obj")+"){\n"+a+"}";return c};
+
-
b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var x=function(a,c){return c?b(a).chain():a},M=function(a,c){m.prototype[a]=function(){var a=i.call(arguments);J.call(a,this._wrapped);return x(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return x(d,
+
-
this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return x(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);
+

Revision as of 11:13, 28 July 2012

var DNA,__indexOf=Array.prototype.indexOf||function(a){for(var b=0,c=this.length;b<c;b++){if(b in this&&this[b]===a)return b}return-1};DNA=function(){function a(a){this.data=a}a.allowed=["A","C","G","T"];a.extendedAllowed=["A","C","G","T","R","Y","K","M","S","W","B","D","H","V","N"];a.RS={AatI:"AGGCCT",AatII:"GACGTC",AccI:"GTMKAC",AccIII:"TCCGGA",Acc65I:"GGTACC",AcsI:"RAATTY",AcyI:"GRCGYC",AflI:"GGWCC",AflII:"CTTAAG",AflIII:"ACRYGT",AgeI:"ACCGGT",AhaII:"GRCGYC",AhaIII:"TTTAAA",AluI:"AGCT",Alw44I:"GTGCAC",AlwNI:"CAGNNNCTG",AocI:"CCTNAGG",AosI:"TGCGCA",ApaI:"GGGCCC",ApaLI:"GTGCAC",ApoI:"RAATTY",ApyI:"CCWGG",AscI:"GGCGCGCC",AseI:"ATTAAT",AsnI:"ATTAAT",AspI:"GACNNNGTC",Asp700:"GAANNNNTTC",Asp718:"GGTACC",AspEI:"GACNNNNNGTC",AspHI:"GWGCWC",AsuII:"TTCGAA",AvaI:"CYCGRG",AvaII:"GGWCC",AviII:"TGCGCA",AvrII:"CCTAGG",BalI:"TGGCCA",BamHI:"GGATCC",BanI:"GGYRCC",BanII:"GRGCYC",BbrPI:"CACGTG",BclI:"TGATCA",BfaI:"CTAG",BfrI:"CTTAAG",BglI:"GCCNNNNNGGC",BglII:"AGATCT",BinI:"CCTAGG",BmyI:"GDGCHC",Bpu1102I:"GCTNAGC",BsaAI:"YACGTR",BsaBI:"GATNNNNATC",BsaHI:"GRCGYC",BsaJI:"CCNNGG",BseAI:"TCCGGA",BsePI:"GCGCGC",BsiEI:"CGRYCG",BsiWI:"CGTACG",BsiYI:"CCNNNNNNNGG",BslI:"CCNNNNNNNGG",Bsp1286I:"GDGCHC",Bsp1407I:"TGTACA",BspDI:"ATCGAT",BspEI:"TCCGGA",BspHI:"TCATGA",BspLU11I:"ACATGT",BsrFI:"RCCGGY",BssGI:"CCANNNNNNTGG",BssHII:"GCGCGC",Bst1107I:"GTATAC",BstBI:"TTCGAA",BstEII:"GGTNACC",BstNI:"CCWGG",BstUI:"CGCG",BstXI:"CCANNNNNNTGG",BstYI:"RGATCY",Bsu36I:"CCTNAGG",CelII:"GCTNAGC",CfoI:"GCGC",CfrI:"YGGCCR",Cfr10I:"RCCGGY",ClaI:"ATCGAT",DdeI:"CTNAG",DpnII:"GATC",DraI:"TTTAAA",DraII:"RGGNCCY",DraIII:"CACNNNGTG",DrdI:"GACNNNNNNGTC",DsaI:"CCRYGG",EaeI:"YGGCCR",EagI:"CGGCCG",Eam1105I:"GACNNNNNGTC",Ecl136II:"GAGCTC",EclXI:"CGGCCG",Eco47III:"AGCGCT",EcoNI:"CCTNNNNNAGG",EcoO109I:"RGGNCCY",EcoRI:"GAATTC",EcoRII:"CCWGG",EcoRV:"GATATC",EspI:"GCTNAGC",FnuDII:"CGCG",Fnu4HI:"GCNGC",FseI:"GGCCGGCC",FspI:"TGCGCA",HaeII:"RGCGCY",HaeIII:"GGCC",HgiAI:"GWGCWC",HhaI:"GCGC",HincII:"GTYRAC",HindII:"GTYRAC",HindIII:"AAGCTT",HinfI:"GANTC",HinPI:"GCGC",HpaI:"GTTAAC",HpaII:"CCGG",ItaI:"GCNGC",KasI:"GGCGCC",KpnI:"GGTACC",KspI:"CCGCGG",MaeI:"CTAG",MaeII:"ACGT",MaeIII:"GTNAC",MamI:"GATNNNNATC",MboI:"GATC",MfeI:"CAATTG",MluI:"ACGCGT",MluNI:"TGGCCA",MroI:"TCCGGA",MscI:"TGGCCA",MseI:"TTAA",MspI:"CCGG",MstI:"TGCGCA",MstII:"CCTNAGG",MunI:"CAATTG",MvaI:"CCWGG",MvnI:"CGCG",NaeI:"GCCGGC",NarI:"GGCGCC",NciI:"CCSGG",NcoI:"CCATGG",NdeI:"CATATG",NdeII:"GATC",NgoMI:"GCCGGC",NheI:"GCTAGC",NlaIII:"CATG",NlaIV:"GGNNCC",NotI:"GCGGCCGC",NruI:"TCGCGA",NsiI:"ATGCAT",NspBII:"CMGCKG",NspI:"RCATGY",NspII:"GDGCHC",NspV:"TTCGAA",PacI:"TTAATTAA",PaeR7I:"CTCGAG",PflMI:"CCANNNNNTGG",PinAI:"ACCGGT",PsiI:"TTATAA",PmaCI:"CACGTG",PmeI:"GTTTAAAC",PmlI:"CACGTG",PpuMI:"RGGWCCY",Psp1406I:"AACGTT",PstI:"CTGCAG",PvuI:"CGATCG",PvuII:"CAGCTG",RcaI:"TCATGA",RmaI:"CTAG",RsaI:"GTAC",RsrII:"CGGWCCG",SacI:"GAGCTC",SacII:"CCGCGG",SalI:"GTCGAC",SauI:"CCTNAGG",Sau3AI:"GATC",Sau96I:"GGNCC",ScaI:"AGTACT",ScrFI:"CCNGG",SexAI:"ACCWGGT",SfcI:"CTRYAG",SfiI:"GGCCNNNNNGGCC",SfuI:"TTCGAA",SgrAI:"CRCCGGYG",SmaI:"CCCGGG",SnaBI:"TACGTA",SnoI:"GTGCAC",SpeI:"ACTAGT",SphI:"GCATGC",SrfI:"GCCCGGGC",Sse8387I:"CCTGCAGG",SspI:"AATATT",SspBI:"TGTACA",SstI:"GAGCTC",SstII:"CCGCGG",StuI:"AGGCCT",StyI:"CCWWGG",SwaI:"ATTTAAAT",TaqI:"TCGA",TfiI:"GAWTC",ThaI:"CGCG",Tru9I:"TTAA",Tth111I:"GACNNNGTC",Van91I:"CCANNNNNTGG",XbaI:"TCTAGA",XcmI:"CCANNNNNNNNNTGG",XhoI:"CTCGAG",XhoII:"RGATCY",XmaI:"CCCGGG",XmaIII:"CGGCCG",XmnI:"GAANNNNTTC"};a.cutPositions={AatI:3,AatII:5,AccI:2,AccIII:1,Acc65I:1,AcsI:1,AcyI:2,AflI:1,AflII:1,AflIII:1,AgeI:1,AhaII:2,AhaIII:3,AluI:2,Alw44I:1,AlwNI:6,AocI:2,AosI:3,ApaI:5,ApaLI:1,ApoI:1,ApyI:0,AscI:2,AseI:2,AsnI:2,AspI:4,Asp700:5,Asp718:1,AspEI:6,AspHI:5,AsuII:2,AvaI:1,AvaII:1,AviII:3,AvrII:1,BalI:3,BamHI:1,BanI:1,BanII:5,BbrPI:3,BclI:1,BfaI:1,BfrI:1,BglI:7,BglII:1,BinI:1,BmyI:5,Bpu1102I:2,BsaAI:3,BsaBI:5,BsaHI:2,BsaJI:1,BseAI:1,BsePI:1,BsiEI:4,BsiWI:1,BsiYI:7,BslI:7,Bsp1286I:5,Bsp1407I:1,BspDI:2,BspEI:1,BspHI:1,BspLU11I:1,BsrFI:1,BssGI:8,BssHII:1,Bst1107I:3,BstBI:2,BstEII:1,BstNI:2,BstUI:2,BstXI:8,BstYI:1,Bsu36I:2,CelII:2,CfoI:3,CfrI:1,Cfr10I:1,ClaI:2,DdeI:1,DpnII:0,DraI:3,DraII:2,DraIII:6,DrdI:7,DsaI:1,EaeI:1,EagI:1,Eam1105I:6,Ecl136II:3,EclXI:1,Eco47III:3,EcoNI:5,EcoO109I:2,EcoRI:1,EcoRII:0,EcoRV:3,EspI:2,FnuDII:2,Fnu4HI:2,FseI:6,FspI:3,HaeII:5,HaeIII:2,HgiAI:5,HhaI:3,HincII:3,HindII:3,HindIII:1,HinfI:1,HinPI:1,HpaI:3,HpaII:1,ItaI:2,KasI:1,KpnI:5,KspI:4,MaeI:1,MaeII:1,MaeIII:0,MamI:5,MboI:0,MfeI:1,MluI:1,MluNI:3,MroI:1,MscI:3,MseI:1,MspI:1,MstI:3,MstII:2,MunI:1,MvaI:2,MvnI:2,NaeI:3,NarI:2,NciI:2,NcoI:1,NdeI:2,NdeII:0,NgoMI:1,NheI:1,NlaIII:4,NlaIV:3,NotI:2,NruI:3,NsiI:5,NspBII:3,NspI:5,NspII:5,NspV:2,PacI:5,PaeR7I:1,PflMI:7,PinAI:1,PsiI:3,PmaCI:3,PmeI:4,PmlI:3,PpuMI:2,Psp1406I:2,PstI:5,PvuI:4,PvuII:3,RcaI:1,RmaI:1,RsaI:2,RsrII:2,SacI:5,SacII:4,SalI:1,SauI:2,Sau3AI:0,Sau96I:1,ScaI:3,ScrFI:2,SexAI:1,SfcI:1,SfiI:8,SfuI:2,SgrAI:2,SmaI:3,SnaBI:3,SnoI:1,SpeI:1,SphI:5,SrfI:4,Sse8387I:6,SspI:3,SspBI:1,SstI:5,SstII:4,StuI:3,StyI:1,SwaI:4,TaqI:1,TfiI:1,ThaI:2,Tru9I:1,Tth111I:4,Van91I:7,XbaI:1,XcmI:8,XhoI:1,XhoII:1,XmaI:1,XmaIII:1,XmaCI:1,XmnI:5};a.RSFlipped=void 0;a.getRSFlipped=function(){var a,b,c,d,e,f;if(this.RSFlipped===void 0){this.RSFlipped={};e=this.RS;for(b in e){c=e[b];if(this.RSFlipped[c]){this.RSFlipped[c].push(b)}else{this.RSFlipped[c]=[b]}}f=this.RSFlipped;for(a in f){d=f[a];if(d.length<=2){this.RSFlipped[a]=d.join(" or ")}else{this.RSFlipped[a]=d.slice(0,d.length-1).join(", ")+" or "+d[d.length-1]}}}return this.RSFlipped};a.getCutPosition=function(b){var c,d,e;if(a.cutPositions[b]){return a.cutPositions[b]}else{e=a.cutPositions;for(c in e){d=e[c];if(c.toLowerCase()===b.toLowerCase())return d}return-1}};a.nucleotideMatches={A:["A","R","M","W","D","H","V","N"],C:["C","Y","M","S","B","H","V","N"],G:["G","R","K","S","B","D","V","N"],T:["T","Y","K","W","B","D","H","N"],R:["A","G"],Y:["C","T"],K:["G","T"],M:["A","C"],S:["C","G"],W:["A","T"],B:["C","G","T"],D:["A","G","T"],H:["A","C","T"],V:["A","C","G"],N:["A","C","G","T"]};a.fromString=function(b){var c,d,e,f,g;c=false;if(b!=null){g=this.RS;for(d in g){f=g[d];if(d.toLowerCase()===b.toLowerCase()){e=new a(f.split(""));c=true}}}else{b=""}if(!c)e=new a(b.toUpperCase().replace(/\s/ig,"").split(""));e.validateData();return e};a.fromRandom=function(b){var c,d;if(b===0||b==="0"||!b||b===void 0){return new a([])}else{c=function(){var c;c=[];for(d=1;1<=b?d<=b:d>=b;1<=b?d++:d--){c.push(a.allowed[Math.floor(Math.random()*a.allowed.length)])}return c}();return new a(c)}};a.prototype.validateData=function(b){if(b){if(this.data.some(function(b){return __indexOf.call(a.allowed,b)<0})){throw new Error("Invalid character encountered")}}else{if(this.data.some(function(b){return __indexOf.call(a.extendedAllowed,b)<0})){throw new Error("Invalid character encountered")}}};a.prototype.matches=function(b){var c;if(this.length()!==b.length())return false;c=_.zip(this.data,b.data);return _.all(c,function(b){var c,d,e,f,g,h,i,j;e=b[0],g=b[1];if(e===g){return true}else{if(__indexOf.call(a.allowed,e)>=0){return __indexOf.call(a.nucleotideMatches[e],g)>=0}if(__indexOf.call(a.allowed,g)>=0){return __indexOf.call(a.nucleotideMatches[g],e)>=0}f=a.nucleotideMatches[e];h=a.nucleotideMatches[g];for(c=0,i=f.length-1;0<=i?c<=i:c>=i;0<=i?c++:c--){for(d=0,j=h.length-1;0<=j?d<=j:d>=j;0<=j?d++:d--){if(f[c]===h[d])return true}}return false}})};a.prototype.findRS=function(b){var c,d,e,f,g,h;if(b==null)b=false;if(this.length()>15)return"";c=this.data.join("");e=a.getRSFlipped();if(e[c]){if(b){return e[c]}else{return e[c]+" (5' → 3': "+c+")"}}else{h=a.RS;for(g in h){d=h[g];f=a.fromString(g);if(this.matches(f)){if(b){d}else{d+" (5' → 3': "+c+")"}}}return""}};a.prototype.getCutPosition=function(){return a.getCutPosition(this.findRS(true))};a.prototype.containsRS=function(b){var c,d,e,f,g,h,i,j,k,l,m,n,o;d=[];for(k=0,m=b.length;k<m;k++){g=b[k];d.push(g.toLowerCase())}f=function(){var a;a=[];for(e=0;e<=10;e++){a.push("")}return a}();j=a.getRSFlipped();i=0;o=this.data;for(l=0,n=o.length;l<n;l++){c=o[l];for(e=4;e<=10;e++){f[e]+=c;if(e<=i)f[e]=f[e].substr(1);if(j[f[e]]){h=j[f[e]].toLowerCase().split(" ");if(_.some(d,function(a){return __indexOf.call(h,a)>=0})){return true}}}i++}return false};a.prototype.length=function(){return this.data.length};a.prototype.snip=function(b){if(b>=0&&b<=this.data.length){return new a(this.data.slice(0,b))}else{throw new Error("Invalid snip length (tried to snip a piece of length "+b+" in a sequence of "+this.length()+"bp)")}};a.prototype.reverseComplement=function(){var b,c,d,e,f,g,h;e=[];b=function(a){switch(a){case"A":return"T";case"T":return"A";case"C":return"G";case"G":return"C";default:throw new Error("Invalid character encountered ("+a+")")}};d=this.data.length-1;h=this.data;for(c=0,g=h.length;c<g;c++){f=h[c];e[d-c]=b(f)}return new a(e)};a.prototype.append=function(b){return new a(this.data.concat(b.data))};a.prototype.tm=function(){return TmCalc.calc(this.data)};a.prototype.toString=function(){return this.data.join("")};a.prototype.toJSON=function(){return this.toString()};a.prototype.clone=function(){return new a(this.data.slice(0))};return a}();var DNAInput,DNARSInput,DNASmallInput,Input,InputForm,NumberInput,RadioInput,SelectInput,Separator,Submit,TemperatureInput,__hasProp=Object.prototype.hasOwnProperty,__extends=function(a,b){function d(){this.constructor=a}for(var c in b){if(__hasProp.call(b,c))a[c]=b[c]}d.prototype=b.prototype;a.prototype=new d;a.__super__=b.prototype;return a};InputForm=function(){function a(b){this.update=b.update,this.submit=b.submit,this.name=b.name;this.id="inputform-"+a.i++;this.inputs=[];this.inputDict={};this.lastValue={}}a.i=0;a.create=function(b,c){var d;d=new a(b);c.forEach(function(a){return d.addInput(a)});return d};a.prototype.save=function(a){var b,c,d;try{if(JSON&&localStorage){c={};for(b in a){d=a[b];if(b==="leftRS"||b==="rightRS")d=d.rs;c[b]=d}return localStorage.setItem("values",JSON.stringify(c))}}catch(e){}};a.prototype.restore=function(){var a,b,c,d;try{if(JSON&&localStorage){b=localStorage.getItem("values");if(b!=null){b=JSON.parse(b);d=[];for(a in b){c=b[a];d.push(this.inputDict[a].value(c))}return d}}}catch(e){}};a.prototype.attach=function(a){$(a).append(this.generateDOM());$(".help-block").hide();this.restore();return this.updateCallback()};a.prototype.submitCallback=function(){var a,b,c,d,e;e=this.getFormData(),b=e.data,d=e.messages,c=e.error,a=e.changed;return typeof this.submit==="function"?this.submit(b,d,c):void 0};a.prototype.updateCallback=function(){var a,b,c,d,e;if(this.disableAuto)return;e=this.getFormData(),b=e.data,d=e.messages,c=e.error,a=e.changed;if(a){return typeof this.update==="function"?this.update(b,d,c):void 0}};a.prototype.getFormData=function(){var a,b,c,d;b={};d=[];c=false;this.inputs.forEach(function(a){var e;e=void 0;try{e=a.value()}catch(f){d.push("Error: "+f.message)}if(!a.validate(e)){c=true;d.push("The value of "+a.get("label")+" is invalid")}if(a.get("name")!=null)return b[a.get("name")]=e});a=false;if(!_.isEqual(this.lastValue,b)){a=true;this.inputs.forEach(function(a){if(a.visible(b)){return a.show()}else{return a.hide()}});this.lastValue=b;this.save(b)}return{data:b,messages:d,error:c,changed:a}};a.prototype.addInput=function(a){var b,c,d=this;if(a==="Separator"){this.inputs.push(new Separator);return}if(!window[a.type]instanceof Function){throw new Error("Passed input can't be instantiated")}b=function(){return d.updateCallback.apply(d,arguments)};if(a.type==="Submit"){b=function(){return d.submitCallback.apply(d,arguments)}}c=new window[a.type](b,a);if(!c instanceof Input)throw new Error("Object isn't an input");this.inputDict[a.name]=c;this.inputs.push(c);return this};a.prototype.get=function(a){return this.inputDict[a]};a.prototype.generateDOM=function(){var a,b,c=this;b=$("<form>").attr("id",this.id).attr("class","form-horizontal");if(this.name!=null){a=$("<fieldset>").append($("<legend>").text(this.name));b.append(a)}else{a=b}this.inputs.forEach(function(b){return a.append(b.generateDOM())});a.prepend($("
")).prepend($("
").attr("class","control-group "+this.rowClass).append($("<label>").attr("class","control-label").attr("for","help-checkbox").html("Show help blocks")).append($("
").attr("class","controls").append($("<input>").attr("class","input-medium").attr("type","checkbox").attr("checked",false).attr("id","help-checkbox").on("change",function(){if($("#help-checkbox").attr("checked")){return $(".help-block").show()}else{return $(".help-block").hide()}})))).prepend($("
").attr("class","control-group "+this.rowClass).append($("<label>").attr("class","control-label").attr("for","autoUpdate-checkbox").html("Automatically update results (CPU-heavy, but way more useable)")).append($("
").attr("class","controls").append($("<input>").attr("class","input-medium").attr("type","checkbox").attr("checked","checked").attr("id","autoUpdate-checkbox").on("change",function(){if($("#autoUpdate-checkbox").attr("checked")){return c.disableAuto=false}else{return c.disableAuto=true}}))));return b};return a}();Input=function(){function a(b,c,d){this.callback=b;this.data=c;this.rowClass=d!=null?d:"";this.id="input-"+a.i++;this.type="text"}a.i=0;a.prototype.generateDOM=function(){return $("
").attr("id","row-"+this.id).attr("class","control-group "+this.rowClass).append(this.generateLabelDOM()).append($("
").attr("class","controls").append(this.generateElementDOM()).append(this.generateHelpDOM()))};a.prototype.generateLabelDOM=function(){return $("<label>").attr("class","control-label").attr("for",this.id).html(this.data.label)};a.prototype.generateInputElementDOM=function(a,b,c,d){var e;e=$("<input>").attr("class","input-medium").attr("type",b).attr("id",a).on("change",d).on("keyup",d);e.val(c);return e};a.prototype.generateElementDOM=function(){return this.generateInputElementDOM(this.id,this.type,this.data.value,this.callback)};a.prototype.generateHelpDOM=function(a){if(a==null)a=this.data.help;if(a!=null&&a.length>0){return $("

").attr("class","help-block").html(a)}else{return $("<p>").attr("class","help-block").attr("style","display: none")}};a.prototype.get=function(a){return this.data[a]};a.prototype.visible=function(a){if(this.data.visible!=null){return this.data.visible(a)}else{return true}};a.prototype.hide=function(){return $("#row-"+this.id).hide()};a.prototype.show=function(){return $("#row-"+this.id).show()};a.prototype.value=function(a){if(a===void 0){return $("#"+this.id).val()}else{return $("#"+this.id).val(a)}};a.prototype.validate=function(a){return true};return a}();Separator=function(a){function b(){b.__super__.constructor.apply(this,arguments)}__extends(b,a);b.prototype.generateDOM=function(){return $("


").attr("id","row-"+this.id)};b.prototype.value=function(){};b.prototype.validate=function(){return true};return b}(Input);Submit=function(a){function b(){b.__super__.constructor.apply(this,arguments)}__extends(b,a);b.prototype.generateElementDOM=function(){return $("<input>").attr("type","submit").attr("value",this.data.value).attr("class","btn").click(this.callback,function(a){a.preventDefault();a.data(a);return false})};b.prototype.value=function(){};b.prototype.validate=function(){return true};return b}(Input);NumberInput=function(a){function b(){b.__super__.constructor.apply(this,arguments);this.type="number"}__extends(b,a);b.prototype.value=function(a){if(a===void 0){return parseInt(b.__super__.value.call(this),10)}else{return b.__super__.value.call(this,parseInt(a,10))}};b.prototype.validate=function(a){return!isNaN(a)};return b}(Input);TemperatureInput=function(a){function b(){b.__super__.constructor.apply(this,arguments)}__extends(b,a);b.prototype.generateElementDOM=function(){var a;a=b.__super__.generateElementDOM.call(this);return $("
").attr("class","input-append").append(a).append($("").attr("class","add-on").text("°C"))};return b}(NumberInput);DNAInput=function(a){function b(){b.__super__.constructor.apply(this,arguments)}__extends(b,a);b.prototype.generateElementDOM=function(){var a;a=$("<textarea>").attr("class","input-xlarge").attr("id",this.id).on("change",this.callback).on("keyup",this.callback);a.val(this.data.value);return a};b.prototype.value=function(a){if(a===void 0){return DNA.fromString(b.__super__.value.call(this))}else{return b.__super__.value.call(this,a.toString())}};b.prototype.validate=function(a){return a!==void 0};return b}(Input);DNASmallInput=function(a){function b(){b.__super__.constructor.apply(this,arguments)}__extends(b,a);b.prototype.generateElementDOM=function(){var a;a=b.__super__.generateElementDOM.call(this);return $("
").attr("class","input-prepend input-append").append($("").attr("class","add-on").text("5'")).append(this.generateInputElementDOM(this.id,"text",this.data.value,this.callback)).append($("").attr("class","add-on").text("3'"))};return b}(DNAInput);DNARSInput=function(a){function b(){b.__super__.constructor.apply(this,arguments)}__extends(b,a);b.prototype.generateElementDOM=function(){var a;a=b.__super__.generateElementDOM.call(this);return $("
").attr("class","input-prepend input-append").append($("").attr("class","add-on").text("5'")).append(this.generateInputElementDOM(this.id,"text",this.data.value,this.callback)).append($("").attr("class","add-on").text("3'")).append($("").attr("id",this.id+"-rs").attr("class","add-on").text("append 2"))};b.prototype.value=function(a){var c;c=b.__super__.value.call(this,a);if(c!=null&&c instanceof DNA){$("#"+this.id+"-rs").html(c.toString())}if(c===void 0)c=DNA.fromString("");return{dna:c,rs:$("#"+this.id).val()}};return b}(DNAInput);SelectInput=function(a){function b(a,c){b.__super__.constructor.apply(this,arguments);this.choices=c.choices}__extends(b,a);b.prototype.generateElementDOM=function(){var a,c,d=this;c=b.__super__.generateElementDOM.call(this);a=$("<select>").attr("class","input-medium").attr("id",this.id).on("change",this.callback).on("click",this.callback);this.choices.forEach(function(b){var c,d;c=b.name,d=b.value;return a.append($("<option>").attr("value",c).text(d))});return a};return b}(Input);RadioInput=function(a){function b(a,c){b.__super__.constructor.apply(this,arguments);this.choices=c.choices}__extends(b,a);b.prototype.generateElementDOM=function(){var a,c,d,e=this;d=b.__super__.generateElementDOM.call(this);a=$("
");c=0;this.choices.forEach(function(b){var c,d,f,g;g=b.name,f=b.label,d=b.help;c=$("<label>").attr("class","radio").text(f).prepend($("<input>").attr("checked",e.data.value===g).attr("type","radio").attr("id",e.id+"-"+g).attr("name",e.id).on("change",e.callback).on("click",e.callback)).append(e.generateHelpDOM(d));return a.append(c)});return a};b.prototype.value=function(a){var b,c=this;if(a===void 0){b={};this.choices.forEach(function(a){var d;d=a.name;return b[d]=$("#"+c.id+"-"+d).attr("checked")==="checked"});return b}else{if(a instanceof String){this.choices.forEach(function(b){var d;d=b.name;return $("#"+c.id+"-"+d).attr("checked",d===a)})}else{this.choices.forEach(function(b){var d;d=b.name;return $("#"+c.id+"-"+d).attr("checked",a[d])})}return a}};return b}(Input);$(function(){window.output=new Output("Primer 1 (Template:Primer1Tm°C, Template:Primer1TailLength + Template:Primer1Lengthbp): 5' → 3'
\n
{{primer1}}
\nPrimer 2 (Template:Primer2Tm°C, Template:Primer2TailLength + Template:Primer2Lengthbp): 5' → 3'
\n
{{primer2}}
\nAnnealing temperature: Template:AnnealingTm°C\n\n

\n

Messages

\nTemplate:Messages\n\n
\n

Digestion result

\nTemplate:RSDisplay:\n
\n

PCR Product

\nTemplate:DNADisplay:full\n");window.output.attach("#outputAttach");window.primerFinder=new PrimerFinder({output:function(a,b){window.output.setMessages(b);return window.output.set(a)}});window.form=InputForm.create({name:"Primer design helper",submit:function(a,b,c){return window.primerFinder.calc(a,b,c)},update:function(a,b,c){return window.primerFinder.calc(a,b,c)}},[{name:"dna",label:"DNA Sequence of interest",type:"DNAInput",value:"",help:"Most of the time you should just paste the DNA sequence (in the 5' → 3' direction) you want to extract/edit in this field"},{type:"Separator"},{name:"type",label:"Primer type",type:"RadioInput",choices:[{name:"normal",label:"Primers that extract the whole sequence",help:"Running a PCR using these primers will extract the entire sequence"},{name:"rs",label:"Add restriction sites",help:"Running a PCR using these primers will result in the sequence with added standardized restriction sites on both sides."},{name:"known",label:"Add a standard prefix/suffix to the sequence",help:"Running a PCR using these primers will result in the sequence with added standardized tails on both sides (for example for biobricking)."},{name:"custom",label:"Add custom tails to the sequence",help:"Running a PCR using these primers will result in the sequence with added tails on both sides."}],value:"normal"},{type:"Separator"},{name:"standardTail",label:"Standardized tails",type:"SelectInput",value:"biobrickGene",choices:[{name:"biobrickGene",value:"Biobrick (gene)"},{name:"biobrickOther",value:"Biobrick (other)"}],visible:function(a){var b;b=a.type;return b.known}},{name:"randomBases",label:"Random Bases",type:"NumberInput",value:"4",help:"This is the number of random bases will be added on both ends.",visible:function(a){var b;b=a.type;return b.rs}},{name:"leftRS",label:"Left restriction site",type:"DNARSInput",value:"",help:"You can also enter the name of the restriction enzyme (i.e. EcoRI).",visible:function(a){var b;b=a.type;return b.rs}},{name:"rightRS",label:"Right restriction site",type:"DNARSInput",value:"",help:"You can also enter the name of the restriction enzyme (i.e. EcoRI).",visible:function(a){var b;b=a.type;return b.rs}},{name:"leftTail",label:"Left tail",type:"DNASmallInput",value:"",visible:function(a){var b;b=a.type;return b.custom}},{name:"rightTail",label:"Right tail",type:"DNASmallInput",value:"",visible:function(a){var b;b=a.type;return b.custom}},{type:"Separator",visible:function(a){var b;b=a.type;return!b.normal}},{name:"tm",label:"Target Tm",type:"TemperatureInput",value:"50",help:"The program will try to create primers that have an annealing temperature close to this one."},{value:"Generate",type:"Submit"}]);return window.form.attach($("#formAttach"))});window.tails=[{name:"Biobrick (gene)",value:"biobrickGene",primer1Tail:"GTT TCT TCG AAT TCG CGG CCG CTT CTA G",primer2Tail:"GTT TCT TCC TGC AGC GGC CGC TAC TAG TA TTA TTA",messages:["Don't forget to include the first ATG and to exclude the stop codon!","The recommended minimum length of a BioBrick primer is 20bp","The recommended Tm of a BioBrick primer is between 55 and 65°C","Check that the following restriction sites are absent: EcoRI, SpeI, XbaI, PstI, NotI","Check out <a href='http://openwetware.org/wiki/Synthetic_Biology:BioBricks/Part_fabrication'>OpenWetWare's reference page</a>"],validate:function(a,b,c){var d,e;e=a.substr(0,3).toUpperCase();if(e!=="ATG")return"The starting ATG seems to be absent.";d=b.substr(0,3).toUpperCase();if(d==="TTA"||d==="TCA"||d==="CTA"){return"Remove the stop codons from the sequence!"}if(c.containsRS(["EcoRI","SpeI","XbaI","PstI","NotI"])){return"One of the following restriction sites is present (and shouldn't be): EcoRI, SpeI, XbaI, PstI, NotI"}return}},{name:"Biobrick (other)",value:"biobrickOther",primer1Tail:"GTT TCT TCG AAT TCG CGG CCG CTT CTA GAG",primer2Tail:"GTT TCT TCC TGC AGC GGC CGC TAC TAG TA",messages:["The recommended minimum length of a BioBrick primer is 20bp","The recommended Tm of a BioBrick primer is between 55 and 65°C","Check that the following restriction sites are absent: EcoRI, SpeI, XbaI, PstI, NotI","Check out <a href='http://openwetware.org/wiki/Synthetic_Biology:BioBricks/Part_fabrication'>OpenWetWare's reference page</a>"],validate:function(a,b,c){if(c.containsRS(["EcoRI","SpeI","XbaI","PstI","NotI"])){return"One of the following restriction sites is present (and shouldn't be): EcoRI, SpeI, XbaI, PstI, NotI"}return}}];var DNADisplay,Display,Output,RSDisplay,SelfDimerDisplay,__hasProp=Object.prototype.hasOwnProperty,__extends=function(a,b){function d(){this.constructor=a}for(var c in b){if(__hasProp.call(b,c))a[c]=b[c]}d.prototype=b.prototype;a.prototype=new d;a.__super__=b.prototype;return a};Output=function(){function a(b){this.template=b;this.id="output-"+a.i++;this.fields={};this.matches={};this.displays={};this.parsedTemplate=this.parseTemplate(this.template)}a.i=0;a.j=0;a.prototype.attach=function(a){var b,c,d,e,f,g;this.matches={};$(a).html(this.parsedTemplate);f=this.displays;g=[];for(d in f){e=f[d];g.push(function(){var a,d,f,g;g=[];for(a=0,d=e.length;a<d;a++){f=e[a],b=f.displayClass,c=f.displayObj;g.push(c.attach("."+b))}return g}())}return g};a.prototype.setMessages=function(a){var b;b=a;if(a.length===0)b=["No messages"];return this.getFields("_messages").html("
  • "+b.join("
  • ")+"
")};a.prototype.wipe=function(){var a,b,c;c=this.fields;for(a in c){b=c[a];this.updateValue(a,void 0)}return this.fields={}};a.prototype.set=function(a){var b,c;for(b in a){c=a[b];this.updateValue(b,c)}this.updateValue("__all__",this.fields);return this.fields};a.prototype.updateValue=function(a,b){var c,d,e,f,g;if(this.fields[a]!==b){this.fields[a]=b;if(b!=null){this.getFields(a).html(b.toString())}else{this.getFields(a).html("")}}if(this.displays[a]!=null){f=this.displays[a];g=[];for(d=0,e=f.length;d<e;d++){c=f[d].displayObj;g.push(c.set(b))}return g}};a.prototype.getFields=function(a){if(!this.matches[a]){this.matches[a]=$("."+this.id+"-match-"+a)}return this.matches[a]};a.prototype.parseTemplate=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o;b=a[0];c=a[1];l=a+"";m=false;i=false;n=-1;k="";for(h=1,o=a.length-1;1<=o?h<=o:h>=o;1<=o?h++:h--){c=a[h];if(!m){if(b==="{"&&c==="{"){if(i){throw new Error("Invalid template, opened brackets in an already opened context")}k="";n=h;m=true;i=true}else if(b==="}"&&c==="}"){if(!i){throw new Error("Invalid template, closed unopened brackets")}g=k.indexOf(":");if(g>=0){d=k.substr(0,g);j=k.substr(g+1);if(j==="")j="__all__";e=this.id+"-display-"+d+"-"+j;l=l.replace("Template:"+k+"","");f=new window[d](j);if(!(this.displays[j]!=null))this.displays[j]=[];this.displays[j].push({displayClass:e,displayObj:f})}else{l=l.replace("Template:"+k+"","")}m=true;i=false}else{if(i)k+=b}}else{m=false}b=c}return l};return a}();Display=function(){function a(a){this.key=a;this.value=void 0}a.prototype.attach=function(a){throw new Error("Not implemented")};a.prototype.set=function(a){return this.value=a[this.key]};a.prototype.pad=function(a,b,c){var d;if(a==null)a="";if(b==null)b=5;if(c==null)c=false;a=a.toString();d=a.length;while(d=b){e.push(a.substr(c,b));d-=b;c+=b}if(d>0)e.push(a.substr(c));return e};return a}();DNADisplay=function(a){function b(a){var c,d=this;b.__super__.constructor.apply(this,arguments);this["class"]="dnadisplay-"+b.i++;this.objects=[];c=this;this.dom=$("
").attr("class",this["class"]).append($("<label>").append($("<input>").attr("class",this["class"]+"-toggleLines").attr("type","checkbox").attr("checked","on").on("change",function(){if($("."+d["class"]+"-toggleLines").attr("checked")){$("."+d["class"]+"-lines").hide();$("."+d["class"]+"-numberedLines").show()}else{$("."+d["class"]+"-lines").show();$("."+d["class"]+"-numberedLines").hide()}return})).append(" Line Numbers")).append($("
").attr("class",this["class"]+"-lines product").hide()).append($("<pre>").attr("class",this["class"]+"-numberedLines product"))}__extends(b,a);b.i=0;b.prototype.attach=function(a){$(a).append(this.dom);return this.objects=$("."+this["class"])};b.prototype.set=function(a){var b,c,d,e,f,g,h,i,j;h=60;e=6;i=40;d=this.wrap(a,h);f=this.wrap(a,i);g=[];for(b=0,j=f.length;b<j;b++){c=f[b];if(c.length>0){g[b]=this.pad(b*i+1,e,true)+" - "+this.pad((b+1)*i,e)+"  "+c}}this.full=d.join("\n");this.fullNumbered=g.join("\n");$("."+this["class"]+"-lines").text(this.full);return $("."+this["class"]+"-numberedLines").text(this.fullNumbered)};return b}(Display);RSDisplay=function(a){function b(a){var c;b.__super__.constructor.apply(this,arguments);this["class"]="rsdisplay-"+b.i++;this.objects=[];c=this;this.dom=$("<div>").attr("class",this["class"]).append($("<pre>").attr("class",this["class"]+"-pre"))}__extends(b,a);b.i=0;b.prototype.attach=function(a){$(a).append(this.dom);return this.objects=$("."+this["class"])};b.prototype.set=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A;s=a.rs,u=a.type,h=a.leftRS,p=a.rightRS;if(!u.rs){$("."+this["class"]+"-pre").html("Not applicable");return}i=h.rs;q=p.rs;e=s.left,m=s.right,d=s.full,l=s.randomBases;g=DNA.getCutPosition(i);if(g<0){h=DNA.fromString(e).findRS(true);g=DNA.getCutPosition(h)}else{h=i}if(h.length===0)h="?";o=DNA.getCutPosition(q);if(o<0){p=DNA.fromString(m).findRS(true);o=DNA.getCutPosition(p)}else{p=q}if(p.length===0)p="?";j=d.substr(0,l+e.length+10);r=d.substr(d.length-(l+m.length+10));if(l>6){j="..."+j.substr(l-3);r=r.substr(0,r.length-(l-3))+"...";l=6}f="";n="";c=function(a){switch(a){case"A":return"T";case"T":return"A";case"C":return"G";case"G":return"C";default:return a}};z=j.split("");for(v=0,x=z.length;v<x;v++){b=z[v];f+=c(b)}A=r.split("");for(w=0,y=A.length;w<y;w++){b=A[w];n+=c(b)}if(g>=0){k=Math.ceil(Math.abs(e.length/2-g))+1;j=j.substr(0,l+g)+this.pad("",k+1)+j.substr(l+g);f=f.substr(0,l+e.length-g)+this.pad("",k+1)+f.substr(l+e.length-g)}else{j=j.substr(0,l)+"  "+j.substr(l,e.length)+"  "+j.substr(l+e.length);f=f.substr(0,l)+"  "+f.substr(l,e.length)+"  "+f.substr(l+e.length)}if(o>=0){k=Math.ceil(Math.abs(m.length/2-o))+1;r=r.substr(0,r.length-(l+m.length-o))+this.pad("",k+1)+r.substr(r.length-(l+m.length-o));n=n.substr(0,n.length-(l+o))+this.pad("",k+1)+n.substr(n.length-(l+o))}else{r=r.substr(0,r.length-(l+m.length))+"  "+r.substr(r.length-(l+m.length),m.length)+"  "+r.substr(r.length-l);n=n.substr(0,n.length-(l+m.length))+"  "+n.substr(n.length-(l+m.length),m.length)+"  "+n.substr(n.length-l)}t=[];t.push("Left restriction site: "+h+(g<0?" (cutting site unknown)":""));t.push("Right restriction site: "+p+(o<0?" (cutting site unknown)":""));t.push("");t.push("5'"+this.pad("3'",j.length+r.length+1,true));t.push(j+"..."+r);t.push(f+"..."+n);t.push("3'"+this.pad("5'",j.length+r.length+1,true));return $("."+this["class"]+"-pre").text(t.join("\n"))};return b}(Display);SelfDimerDisplay=function(a){function b(a){var c,d=this;b.__super__.constructor.apply(this,arguments);this["class"]="selfdimerdisplay-"+RSDisplay.i++;this.objects=[];c=this;this.dom=$("<div>").attr("class",this["class"]).append($("<span>").text("This calculation is quite heavy and is done on demand. Press on the button to start the calculations:")).append("<br>").append($("<input>").attr("type","button").attr("value","Calculate").attr("class","btn").click(function(){return d.click()})).append("<br>").append("<br>").append($("<pre>").attr("class",this["class"]+"-pre").html("Press the calculate button to update this data"))}__extends(b,a);b.i=0;b.prototype.attach=function(a){$(a).append(this.dom);return this.objects=$("."+this["class"]+"-pre")};b.prototype.set=function(a){var b,c;b=a.primer1,c=a.primer2;if(b!==this.primer1||c!==this.primer2){this.primer1=b;this.primer2=c;return this.objects.html("Press the calculate button to update this data")}};b.prototype.click=function(){var a;a=this.generateReport("Primer 1",this.primer1)+"\n\n"+this.generateReport("Primer 2",this.primer2);return this.objects.html(a)};b.prototype.generateReport=function(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;g=[];g.push(a+":");l=RNA.fromString(b);p=l.findKnots(),h=p.matches,d=p.folds;g.push("Amount of matches: "+h);k=_.zip(function(){r=[];for(var a=1,c=b.length;1<=c?a<=c:a>=c;1<=c?a++:a--){r.push(a)}return r}.apply(this),b.split(""));e="";f="";for(n=0,o=k.length;n<o;n++){j=k[n];i=j[0]+" ";c=this.pad(j[1],i.length-1,true)+" ";if(e.length+i.length>60){g.push(e);g.push(f);g.push("");e="";f=""}e+=c;f+=i}if(e.length>0){g.push(e);g.push(f);g.push("")}return g.join("\n")};return b}(Display);var Primer;Primer=function(){function a(a){if(a instanceof DNA){this.seq=a.clone()}else{this.seq=DNA.fromString(a)}this.tail1=new DNA([]);this.tail2=new DNA([]);this.randEdgeSize=0}a.minLength=8;a.maxLength=50;a.maxDiff=8;a.lastData="";a.lastTail1="";a.lastTail2="";a.lastTm=0;a.lastRandEdgeSize=-1;a.reset=function(){this.lastData="";this.lastTm=0;this.lastTail1="";this.lastTail2="";return this.lastRandEdgeSize=-1};a.prototype.setTails=function(a,b){this.tail1=a;this.tail2=b};a.prototype.addRandomEdges=function(a){this.randEdgeSize=a};a.prototype.isSameAsLast=function(b,c){return a.lastTail1.toString()===this.tail1.toString()&&a.lastTail2.toString()===this.tail2.toString()&&a.lastData===DNA.fromString(b).toString()&&a.lastTm===c&&a.lastRandEdgeSize===this.randEdgeSize};a.prototype.generate=function(b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p;if(2*a.minLength>this.seq.length()){throw new Error("The given sequence is too short")}a.lastData=this.seq.toString();a.lastTm=b;a.lastTail1=this.tail1;a.lastTail2=this.tail2;a.lastRandEdgeSize=this.randEdgeSize;f=Math.min(Math.floor(this.seq.length()/2),a.maxLength);m=this.seq.reverseComplement();g=-1;h=0;i=-1;j=0;for(d=o=a.minLength;o<=f?d<=f:d>=f;o<=f?d++:d--){n=this.seq.snip(d).tm();c=Math.abs(n-b);if(c<=a.maxDiff&&(g===-1||Math.abs(h-b)>c)){g=d;h=n}if(n>=b)break}for(e=p=a.minLength;p<=f?e<=f:e>=f;p<=f?e++:e--){n=m.snip(e).tm();c=Math.abs(n-b);if(c<=a.maxDiff&&(i===-1||Math.abs(j-b)>c)){i=e;j=n}if(n>=b)break}if(g<0||i<0){throw new Error("Couldn't find a primer of correct length that satisfies the conditions")}k=DNA.fromRandom(this.randEdgeSize);l=DNA.fromRandom(this.randEdgeSize);return{rs:{left:this.tail1.toString(),right:this.tail2.toString(),randomBases:this.randEdgeSize,full:k.toString()+this.tail1.toString()+this.seq.toString()+this.tail2.reverseComplement().toString()+l.reverseComplement().toString()},primer1:k.toString()+" "+this.tail1.toString()+" "+this.seq.snip(g).toString(),primers:{primer1:k.toString()+this.tail1.toString()+this.seq.snip(g).toString(),primer2:l.toString()+this.tail2.toString()+m.snip(i).toString()},primer1NoTail:this.seq.snip(g).toString(),primer1Tm:h,primer1Length:g,primer1TailLength:k.length()+this.tail1.length(),primer2:l.toString()+" "+this.tail2.toString()+" "+m.snip(i).toString(),primer2NoTail:m.snip(i).toString(),primer2Tm:j,primer2Length:i,primer2TailLength:l.length()+this.tail2.length(),full:k.toString()+this.tail1.toString()+this.seq.toString()+this.tail2.reverseComplement().toString()+l.reverseComplement().toString()}};return a}();var PrimerFinder;PrimerFinder=function(){function a(a){this.output=a.output;this.defaults={primer1:"No data",primer1Tm:"?",primer1Length:0,primer2:"No data",primer2Tm:"?",primer2Length:0,annealingTm:"?"}}a.prototype.calc=function(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;if(c){b=["A fatal error occured:"].concat(b);this.output(a,b);return}q=this.defaults;for(d in q){m=q[d];if(!(a[d]!=null))a[d]=m}try{g=new Primer(a.dna);n=function(a,b,c){};if(a.type.custom)g.setTails(a.leftTail,a.rightTail);if(a.type.rs){e=a.leftRS.dna.findRS();f=a.rightRS.dna.findRS();if(e!=null&&e.length>0){b.push("The left restriction site is "+e)}else{b.push("The left restriction site wasn't recognized")}if(f!=null&&f.length>0){b.push("The right restriction site is "+f)}else{b.push("The right restriction site wasn't recognized")}g.setTails(a.leftRS.dna,a.rightRS.dna.reverseComplement());g.addRandomEdges(a.randomBases);b.push("Click the 'Generate' button to regenerate the random bases added on the end of the primers.");b.push("In the case of a plasmid where the piece between A and B is cut out, and A is used for the primer 1 RS (and B for the second).\nThe generated primers will put the RS such that the given DNA starts at the A side and ends at the B side (in short,\nit will probably work as you expected, but still check what happens with some other tool).")}if(a.type.known){k="";l="";r=window.tails;for(o=0,p=r.length;o<p;o++){j=r[o];if(j.value===a.standardTail){k=j.primer1Tail;l=j.primer2Tail;if(j.messages!=null)b=[].concat(j.messages);if(j.validate!=null)n=j.validate}}g.setTails(DNA.fromString(k),DNA.fromString(l))}h=g.generate(a.tm);i=n(h.primer1NoTail,h.primer2NoTail,a.dna);if(i!=null)b.push(i);for(d in h){m=h[d];a[d]=m}b=b}catch(s){b=[s.message]}a.annealingTm=Math.min(a.primer1Tm,a.primer2Tm);if(Math.abs(a.primer1Tm-a.primer2Tm)>5){b.push("The difference between the primer's Tm is more than 5°C")}if(a.annealingTm>70){b.push("Consider using the two-step PCR protocol")}if(a.annealingTm>72){b.push("Annealing temperature shouldn't exceed 72°C");a.annealingTm=72}if(a.annealingTm<45){b.push("The annealing temperature should be more than 45°C")}return this.output(a,b)};return a}();var RNA;RNA=function(){function a(a){this.data=a;this.n=this.data.length;this.knots=void 0}a.fromDNA=function(b){return new a(b.data.map(function(a){switch(a){case"T":return"U";default:return a}}))};a.fromString=function(b){return a.fromDNA(DNA.fromString(b))};a.prototype.P=function(a,b){if(this.data[a]==="A"&&this.data[b]==="U"||this.data[a]==="U"&&this.data[b]==="C"){return 1}else if(this.data[a]==="G"&&this.data[b]==="C"||this.data[a]==="C"&&this.data[b]==="G"){return 1}else{return 0}};a.prototype.isTooSelfComplementary=function(){var a,b,c,d,e,f,g,h,i;h=this.findKnots(),d=h.matches,b=h.folds;for(f=0,g=b.length;f<g;f++){a=b[f];e=[];console.log(a);for(c=0,i=a.length-1;0<=i?c<=i:c>=i;0<=i?c++:c--){if(a[c]==="("){if(c>0&&a[c-1]==="("){e[e.length-1]+=this.data[c]}else{e[e.length]=this.data[c]}}}console.log(e)}return false};a.prototype.findKnots=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N=this;if(a==null)a=2;if(this.knots!==void 0)return this.knots;g=function(){var a,b,c;c=[];for(a=1,b=N.n;1<=b?a<=b:a>=b;1<=b?a++:a--){c.push(".")}return c};b=[];for(n=0,D=this.n-1;0<=D?n<=D:n>=D;0<=D?n++:n--){i=[];for(o=0,F=this.n-1;0<=F?o<=F:o>=F;0<=F?o++:o--){i[o]=[g()]}b[n]=i}c=function(){var a,b;b=[];for(k=1,a=this.n;1<=a?k<=a:k>=a;1<=a?k++:k--){b.push(function(){var a,b;b=[];for(l=1,a=this.n;1<=a?l<=a:l>=a;1<=a?l++:l--){b.push(0)}return b}.call(this))}return b}.call(this);for(k=G=this.n-1;G<=0?k<=0:k>=0;G<=0?k++:k--){for(l=k,H=this.n-1;k<=H?l<=H:l>=H;k<=H?l++:l--){p=0;if(k<l-a){p=c[k+1][l-1]+this.P(k,l);j=[];I=b[k+1][l-1];for(v=0,z=I.length;v<z;v++){s=I[v];if(this.P(k,l)===1){s[k]="(";s[l]=")"}else{s[k]=".";s[l]="."}if(j.length<50)j.push(s)}for(m=k,J=l-1;k<=J?m<=J:m>=J;k<=J?m++:m--){u=c[k][m]+c[m+1][l];if(u>p){p=u;j=[]}if(u>=p){K=b[k][m];for(w=0,A=K.length;w<A;w++){e=K[w];L=b[m+1][l];for(x=0,B=L.length;x<B;x++){f=L[x];d=g(this.n);for(r=0;0<=m?r<=m:r>=m;0<=m?r++:r--){d[r]=e[r]}for(r=M=m+1;M<=l?r<=l:r>=l;M<=l?r++:r--){d[r]=f[r]}if(j.length<50)j.push(d)}}}}c[k][l]=p;b[k][l]=j}}}q=[];h={};E=b[0][this.n-1];for(y=0,C=E.length;y<C;y++){s=E[y];t=s.join("");if(h[t]===void 0){h[t]=true;q.push(t)}}return this.knots={matches:c[0][this.n-1],folds:q}};return a}();var TmCalc;TmCalc=function(){function a(){}a.maxCacheSize=500;a.cache={};a.calc=function(b){var c,d,e;if(!this.cache[b]){e=Math.round(this.calcFull(b)*10)/10;if(this.cache.length>=this.maxCacheSize){d=Object.keys(a.cache);c=d[Math.floor(Math.random()*d.length)];delete a.cache[c]}this.cache[b]=e}return this.cache[b]};a.complement=function(a){switch(a){case"A":return"T";case"T":return"A";case"C":return"G";case"G":return"C";default:throw new Error("Invalid character encountered ("+a+")")}};a.neighborH={AA:9.1,AT:8.6,TA:6,CA:5.8,GT:6.5,CT:7.8,GA:5.6,CG:11.9,GC:11.1,GG:11};a.getH=function(a,b){return this.get(this.neighborH,a,b)};a.neighborG={AA:1.9,AT:1.5,TA:.9,CA:1.9,GT:1.3,CT:1.6,GA:1.6,CG:3.6,GC:3.1,GG:3.1};a.getG=function(a,b){return this.get(this.neighborG,a,b)};a.neighborS={AA:24,AT:23.9,TA:16.9,CA:12.9,GT:17.3,CT:20.8,GA:13.5,CG:27.8,GC:26.7,GG:26.6};a.getS=function(a,b){return this.get(this.neighborS,a,b)};a.get=function(a,b,c){switch(b+c){case"AA":return a["AA"];case"TT":return a["AA"];case"AT":return a["AT"];case"TA":return a["TA"];case"TT":return a["TA"];case"CA":return a["CA"];case"TG":return a["CA"];case"GT":return a["GT"];case"AC":return a["GT"];case"CT":return a["CT"];case"AG":return a["CT"];case"GA":return a["GA"];case"TC":return a["GA"];case"CG":return a["CG"];case"TC":return a["CG"];case"GC":return a["GC"];case"TC":return a["GC"];case"GG":return a["GG"];case"CC":return a["GG"];default:throw new Error("No idea what happened... (tried getting "+b+c+")")}};a.calcFull=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o;k=0;j=-(5+.4);l=0;m=500*.01;i=50*.01;b=1.987;g=a[0];for(f=1,o=a.length-1;1<=o?f<=o:f>=o;1<=o?f++:f--){h=a[f];k-=this.getH(g,h);j-=this.getG(g,h);l-=this.getS(g,h);g=h}c=1e3*k;d=l;e=-10.8;n=m/4*1e-6;return c/(e+d+b*Math.log(n/10))-273.15+16.6*Math.log(i/10)/Math.LN10};return a}();(function(){function a(b,c,d){if(b===c)return 0!==b||1/b==1/c;if(null==b||null==c)return b===c;b._chain&&(b=b._wrapped);c._chain&&(c=c._wrapped);if(b.isEqual&&v.isFunction(b.isEqual))return b.isEqual(c);if(c.isEqual&&v.isFunction(c.isEqual))return c.isEqual(b);var e=i.call(b);if(e!=i.call(c))return!1;switch(e){case"[object String]":return b==""+c;case"[object Number]":return b!=+b?c!=+c:0==b?1/b==1/c:b==+c;case"[object Date]":case"[object Boolean]":return+b==+c;case"[object RegExp]":return b.source==c.source&&b.global==c.global&&b.multiline==c.multiline&&b.ignoreCase==c.ignoreCase}if("object"!=typeof b||"object"!=typeof c)return!1;for(var f=d.length;f--;)if(d[f]==b)return!0;d.push(b);var f=0,g=!0;if("[object Array]"==e){if(f=b.length,g=f==c.length)for(;f--&&(g=f in b==f in c&&a(b[f],c[f],d)););}else{if("constructor"in b!="constructor"in c||b.constructor!=c.constructor)return!1;for(var h in b)if(v.has(b,h)&&(f++,!(g=v.has(c,h)&&a(b[h],c[h],d))))break;if(g){for(h in c)if(v.has(c,h)&&!(f--))break;g=!f}}d.pop();return g}var b=this,c=b._,d={},e=Array.prototype,f=Object.prototype,g=e.slice,h=e.unshift,i=f.toString,j=f.hasOwnProperty,k=e.forEach,l=e.map,m=e.reduce,n=e.reduceRight,o=e.filter,p=e.every,q=e.some,r=e.indexOf,s=e.lastIndexOf,f=Array.isArray,t=Object.keys,u=Function.prototype.bind,v=function(a){return new G(a)};"undefined"!==typeof exports?("undefined"!==typeof module&&module.exports&&(exports=module.exports=v),exports._=v):b._=v;v.VERSION="1.3.3";var w=v.each=v.forEach=function(a,b,c){if(a!=null)if(k&&a.forEach===k)a.forEach(b,c);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&b.call(c,a[e],e,a)===d)break}else for(e in a)if(v.has(a,e)&&b.call(c,a[e],e,a)===d)break};v.map=v.collect=function(a,b,c){var d=[];if(a==null)return d;if(l&&a.map===l)return a.map(b,c);w(a,function(a,e,f){d[d.length]=b.call(c,a,e,f)});if(a.length===+a.length)d.length=a.length;return d};v.reduce=v.foldl=v.inject=function(a,b,c,d){var e=arguments.length>2;a==null&&(a=[]);if(m&&a.reduce===m){d&&(b=v.bind(b,d));return e?a.reduce(b,c):a.reduce(b)}w(a,function(a,f,g){if(e)c=b.call(d,c,a,f,g);else{c=a;e=true}});if(!e)throw new TypeError("Reduce of empty array with no initial value");return c};v.reduceRight=v.foldr=function(a,b,c,d){var e=arguments.length>2;a==null&&(a=[]);if(n&&a.reduceRight===n){d&&(b=v.bind(b,d));return e?a.reduceRight(b,c):a.reduceRight(b)}var f=v.toArray(a).reverse();d&&!e&&(b=v.bind(b,d));return e?v.reduce(f,b,c,d):v.reduce(f,b)};v.find=v.detect=function(a,b,c){var d;x(a,function(a,e,f){if(b.call(c,a,e,f)){d=a;return true}});return d};v.filter=v.select=function(a,b,c){var d=[];if(a==null)return d;if(o&&a.filter===o)return a.filter(b,c);w(a,function(a,e,f){b.call(c,a,e,f)&&(d[d.length]=a)});return d};v.reject=function(a,b,c){var d=[];if(a==null)return d;w(a,function(a,e,f){b.call(c,a,e,f)||(d[d.length]=a)});return d};v.every=v.all=function(a,b,c){var e=true;if(a==null)return e;if(p&&a.every===p)return a.every(b,c);w(a,function(a,f,g){if(!(e=e&&b.call(c,a,f,g)))return d});return!!e};var x=v.some=v.any=function(a,b,c){b||(b=v.identity);var e=false;if(a==null)return e;if(q&&a.some===q)return a.some(b,c);w(a,function(a,f,g){if(e||(e=b.call(c,a,f,g)))return d});return!!e};v.include=v.contains=function(a,b){var c=false;if(a==null)return c;if(r&&a.indexOf===r)return a.indexOf(b)!=-1;return c=x(a,function(a){return a===b})};v.invoke=function(a,b){var c=g.call(arguments,2);return v.map(a,function(a){return(v.isFunction(b)?b||a:a[b]).apply(a,c)})};v.pluck=function(a,b){return v.map(a,function(a){return a[b]})};v.max=function(a,b,c){if(!b&&v.isArray(a)&&a[0]===+a[0])return Math.max.apply(Math,a);if(!b&&v.isEmpty(a))return-Infinity;var d={computed:-Infinity};w(a,function(a,e,f){e=b?b.call(c,a,e,f):a;e>=d.computed&&(d={value:a,computed:e})});return d.value};v.min=function(a,b,c){if(!b&&v.isArray(a)&&a[0]===+a[0])return Math.min.apply(Math,a);if(!b&&v.isEmpty(a))return Infinity;var d={computed:Infinity};w(a,function(a,e,f){e=b?b.call(c,a,e,f):a;e<d.computed&&(d={value:a,computed:e})});return d.value};v.shuffle=function(a){var b=[],c;w(a,function(a,d){c=Math.floor(Math.random()*(d+1));b[d]=b[c];b[c]=a});return b};v.sortBy=function(a,b,c){var d=v.isFunction(b)?b:function(a){return a[b]};return v.pluck(v.map(a,function(a,b,e){return{value:a,criteria:d.call(c,a,b,e)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c===void 0?1:d===void 0?-1:c<d?-1:c>d?1:0}),"value")};v.groupBy=function(a,b){var c={},d=v.isFunction(b)?b:function(a){return a[b]};w(a,function(a,b){var e=d(a,b);(c[e]||(c[e]=[])).push(a)});return c};v.sortedIndex=function(a,b,c){c||(c=v.identity);for(var d=0,e=a.length;d<e;){var f=d+e>>1;c(a[f])<c(b)?d=f+1:e=f}return d};v.toArray=function(a){return!a?[]:v.isArray(a)||v.isArguments(a)?g.call(a):a.toArray&&v.isFunction(a.toArray)?a.toArray():v.values(a)};v.size=function(a){return v.isArray(a)?a.length:v.keys(a).length};v.first=v.head=v.take=function(a,b,c){return b!=null&&!c?g.call(a,0,b):a[0]};v.initial=function(a,b,c){return g.call(a,0,a.length-(b==null||c?1:b))};v.last=function(a,b,c){return b!=null&&!c?g.call(a,Math.max(a.length-b,0)):a[a.length-1]};v.rest=v.tail=function(a,b,c){return g.call(a,b==null||c?1:b)};v.compact=function(a){return v.filter(a,function(a){return!!a})};v.flatten=function(a,b){return v.reduce(a,function(a,c){if(v.isArray(c))return a.concat(b?c:v.flatten(c));a[a.length]=c;return a},[])};v.without=function(a){return v.difference(a,g.call(arguments,1))};v.uniq=v.unique=function(a,b,c){var c=c?v.map(a,c):a,d=[];a.length<3&&(b=true);v.reduce(c,function(c,e,f){if(b?v.last(c)!==e||!c.length:!v.include(c,e)){c.push(e);d.push(a[f])}return c},[]);return d};v.union=function(){return v.uniq(v.flatten(arguments,true))};v.intersection=v.intersect=function(a){var b=g.call(arguments,1);return v.filter(v.uniq(a),function(a){return v.every(b,function(b){return v.indexOf(b,a)>=0})})};v.difference=function(a){var b=v.flatten(g.call(arguments,1),true);return v.filter(a,function(a){return!v.include(b,a)})};v.zip=function(){for(var a=g.call(arguments),b=v.max(v.pluck(a,"length")),c=Array(b),d=0;d<b;d++)c[d]=v.pluck(a,""+d);return c};v.indexOf=function(a,b,c){if(a==null)return-1;var d;if(c){c=v.sortedIndex(a,b);return a[c]===b?c:-1}if(r&&a.indexOf===r)return a.indexOf(b);c=0;for(d=a.length;c<d;c++)if(c in a&&a[c]===b)return c;return-1};v.lastIndexOf=function(a,b){if(a==null)return-1;if(s&&a.lastIndexOf===s)return a.lastIndexOf(b);for(var c=a.length;c--;)if(c in a&&a[c]===b)return c;return-1};v.range=function(a,b,c){if(arguments.length<=1){b=a||0;a=0}for(var c=arguments[2]||1,d=Math.max(Math.ceil((b-a)/c),0),e=0,f=Array(d);e<d;){f[e++]=a;a=a+c}return f};var y=function(){};v.bind=function(a,b){var c,d;if(a.bind===u&&u)return u.apply(a,g.call(arguments,1));if(!v.isFunction(a))throw new TypeError;d=g.call(arguments,2);return c=function(){if(!(this instanceof c))return a.apply(b,d.concat(g.call(arguments)));y.prototype=a.prototype;var e=new y,f=a.apply(e,d.concat(g.call(arguments)));return Object(f)===f?f:e}};v.bindAll=function(a){var b=g.call(arguments,1);b.length==0&&(b=v.functions(a));w(b,function(b){a[b]=v.bind(a[b],a)});return a};v.memoize=function(a,b){var c={};b||(b=v.identity);return function(){var d=b.apply(this,arguments);return v.has(c,d)?c[d]:c[d]=a.apply(this,arguments)}};v.delay=function(a,b){var c=g.call(arguments,2);return setTimeout(function(){return a.apply(null,c)},b)};v.defer=function(a){return v.delay.apply(v,[a,1].concat(g.call(arguments,1)))};v.throttle=function(a,b){var c,d,e,f,g,h,i=v.debounce(function(){g=f=false},b);return function(){c=this;d=arguments;e||(e=setTimeout(function(){e=null;g&&a.apply(c,d);i()},b));f?g=true:h=a.apply(c,d);i();f=true;return h}};v.debounce=function(a,b,c){var d;return function(){var e=this,f=arguments;c&&!d&&a.apply(e,f);clearTimeout(d);d=setTimeout(function(){d=null;c||a.apply(e,f)},b)}};v.once=function(a){var b=false,c;return function(){if(b)return c;b=true;return c=a.apply(this,arguments)}};v.wrap=function(a,b){return function(){var c=[a].concat(g.call(arguments,0));return b.apply(this,c)}};v.compose=function(){var a=arguments;return function(){for(var b=arguments,c=a.length-1;c>=0;c--)b=[a[c].apply(this,b)];return b[0]}};v.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};v.keys=t||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var b=[],c;for(c in a)v.has(a,c)&&(b[b.length]=c);return b};v.values=function(a){return v.map(a,v.identity)};v.functions=v.methods=function(a){var b=[],c;for(c in a)v.isFunction(a[c])&&b.push(c);return b.sort()};v.extend=function(a){w(g.call(arguments,1),function(b){for(var c in b)a[c]=b[c]});return a};v.pick=function(a){var b={};w(v.flatten(g.call(arguments,1)),function(c){c in a&&(b[c]=a[c])});return b};v.defaults=function(a){w(g.call(arguments,1),function(b){for(var c in b)a[c]==null&&(a[c]=b[c])});return a};v.clone=function(a){return!v.isObject(a)?a:v.isArray(a)?a.slice():v.extend({},a)};v.tap=function(a,b){b(a);return a};v.isEqual=function(b,c){return a(b,c,[])};v.isEmpty=function(a){if(a==null)return true;if(v.isArray(a)||v.isString(a))return a.length===0;for(var b in a)if(v.has(a,b))return false;return true};v.isElement=function(a){return!!(a&&a.nodeType==1)};v.isArray=f||function(a){return i.call(a)=="[object Array]"};v.isObject=function(a){return a===Object(a)};v.isArguments=function(a){return i.call(a)=="[object Arguments]"};v.isArguments(arguments)||(v.isArguments=function(a){return!(!a||!v.has(a,"callee"))});v.isFunction=function(a){return i.call(a)=="[object Function]"};v.isString=function(a){return i.call(a)=="[object String]"};v.isNumber=function(a){return i.call(a)=="[object Number]"};v.isFinite=function(a){return v.isNumber(a)&&isFinite(a)};v.isNaN=function(a){return a!==a};v.isBoolean=function(a){return a===true||a===false||i.call(a)=="[object Boolean]"};v.isDate=function(a){return i.call(a)=="[object Date]"};v.isRegExp=function(a){return i.call(a)=="[object RegExp]"};v.isNull=function(a){return a===null};v.isUndefined=function(a){return a===void 0};v.has=function(a,b){return j.call(a,b)};v.noConflict=function(){b._=c;return this};v.identity=function(a){return a};v.times=function(a,b,c){for(var d=0;d<a;d++)b.call(c,d)};v.escape=function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};v.result=function(a,b){if(a==null)return null;var c=a[b];return v.isFunction(c)?c.call(a):c};v.mixin=function(a){w(v.functions(a),function(b){I(b,v[b]=a[b])})};var z=0;v.uniqueId=function(a){var b=z++;return a?a+b:b};v.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var A=/.^/,B={"\\":"\\","'":"'",r:"\r",n:"\n",t:"	",u2028:"\u2028",u2029:"\u2029"},C;for(C in B)B[B[C]]=C;var D=/\\|'|\r|\n|\t|\u2028|\u2029/g,E=/\\(\\|'|r|n|t|u2028|u2029)/g,F=function(a){return a.replace(E,function(a,b){return B[b]})};v.template=function(a,b,c){c=v.defaults(c||{},v.templateSettings);a="__p+='"+a.replace(D,function(a){return"\\"+B[a]}).replace(c.escape||A,function(a,b){return"'+\n_.escape("+F(b)+")+\n'"}).replace(c.interpolate||A,function(a,b){return"'+\n("+F(b)+")+\n'"}).replace(c.evaluate||A,function(a,b){return"';\n"+F(b)+"\n;__p+='"})+"';\n";c.variable||(a="with(obj||{}){\n"+a+"}\n");var a="var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n"+a+"return __p;\n",d=new Function(c.variable||"obj","_",a);if(b)return d(b,v);b=function(a){return d.call(this,a,v)};b.source="function("+(c.variable||"obj")+"){\n"+a+"}";return b};v.chain=function(a){return v(a).chain()};var G=function(a){this._wrapped=a};v.prototype=G.prototype;var H=function(a,b){return b?v(a).chain():a},I=function(a,b){G.prototype[a]=function(){var a=g.call(arguments);h.call(a,this._wrapped);return H(b.apply(v,a),this._chain)}};v.mixin(v);w("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=e[a];G.prototype[a]=function(){var c=this._wrapped;b.apply(c,arguments);var d=c.length;(a=="shift"||a=="splice")&&d===0&&delete c[0];return H(c,this._chain)}});w(["concat","join","slice"],function(a){var b=e[a];G.prototype[a]=function(){return H(b.apply(this._wrapped,arguments),this._chain)}});G.prototype.chain=function(){this._chain=true;return this};G.prototype.value=function(){return this._wrapped}}).call(this)