DNA.Restrict = {};
(function(){ var enzymes = [ "GAATTC", // EcoRI "CTGCAG", // PstI "TCTAGA", // XbaI "ACTAGT", // SpeI "GCGGCCGC", // NotI "GTCGAC", // SalI "AAGCTT", // HindIII "AGATCT" // BglII ];
function findAll(str, sub){ var ret = [], idx = -1; while((idx = str.indexOf(sub, idx + 1)) !== -1){ ret.push(idx); } return ret; }
function detect(dna){ return enzymes.map(function(elm){ return {enz: elm, idxs: findAll(dna, elm)}; }).filter(function(elm){ return elm.idxs.length > 0; }); }
function shortestAbsent(dna, base){ var b = base + base + base;
while(dna.indexOf(b) !== -1){ b += base; }
return b; }
function insertionPoint(enz, base){ for(var i = 1; i < enz.length; i++){ if(enz[i - 1] !== base && enz[i] !== base){ return i; } }
return undefined; }
function splice(str, pos, substr){ return str.substr(0, pos) + substr + str.substr(pos); }
function unsplice(str, pos, len){ return str.substr(0, pos) + str.substr(pos + len); }
function substitute(dna, base, subst){ var enzs = enzymes.map(function(enz){ var point = insertionPoint(enz, base), rep = enz.substr(0, point) + subst + enz.substr(point); return {enz: enz, point: point, rep: rep, reg: new RegExp(enz, 'g')}; });
var ret = dna, prev; do{ prev = ret; enzs.forEach(function(elm){ ret = ret.replace(elm.reg, elm.rep); }); }while(ret !== prev);
return ret; }
function restore(dna, subst){ var offset = 0; findAll(dna, subst).forEach(function(pos){ dna = unsplice(dna, pos - offset, subst.length); offset += subst.length; });
return dna; }
DNA.Restrict = { detect: detect, shortestAbsent: shortestAbsent, substitute: substitute, restore: restore }; })();