var TYPING_OK=1;var TYPING_SWAP_ERROR=2;var TYPING_SKIP_ERROR=3;var TYPING_LOWER_ERROR=4;var TYPING_UPPER_ERROR=5;var TYPING_WRONG_CHAR_ERROR=6;var g_debug="";function debug(A){g_debug+=A}function debugln(A){debug(A+"<br/>")}function debugclear(){g_debug=""}function debugshow(A){$(A).innerHTML=g_debug}var TypingError=function(E,C,D,B,A){this.type=E;this.index=C;this.size=D;this.exToken=B;this.inToken=A};var HashSet=function(){this.m_set={};this.m_size=0;this.insert=function(A){if(typeof(this.m_set[A])=="undefined"){this.m_set[A]=0;this.m_size++}return(++this.m_set[A])};this.get=function(A){return this.count(A)};this.count=function(A){if(typeof(this.m_set[A])!="undefined"){return this.m_set[A]}return 0};this.erase=function(A){var B=0;if(typeof(this.m_set[A])!="undefined"){B=(--this.m_set[A]);if(B==0){delete this.m_set[A];this.m_size--}}return B};this.size=function(){return this.m_size};this.equals=function(A){_equal=(this.m_size==A.m_size);if(_equal){for(var B in A.m_set){if(typeof(this.m_set[B])=="undefined"){_equal=false}}}return _equal}};var StatisticStatus=function(A,C,D,B){this.token=A;this.time=C;this.errors=D;this.numberOfChars=B};var Statistics=function(A){this.errors=0;this.numberOfCharacters=0;this.numberOfBackspace=0;this.startTime=0;this.finishTime=0;this.maxTime=A;this.statusHistory=new Array();this.ispaused=false;this.start=function(){this.startTime=this._getCurrentTime()};this.time=function(){return(this._getCurrentTime()-this.startTime)};this.finish=function(){this.finishTime=this._getCurrentTime()};this.paused=function(){return this.ispaused};this.getTime=function(){if(this.startTime==0){return 0}return parseInt(this._getTimeDifference())};this.getTimeInMS=function(){if(this.startTime==0){return 0}return parseInt(this._getTimeDifference()*1000)};this.getRemainingTime=function(){var B=this.getTime();if(B>this.maxTime){return 0}return this.maxTime-B};this.pauseTimer=function(){this.finishTime=this._getCurrentTime();this.ispaused=true};this.continueTimer=function(){this.startTime=this._getCurrentTime()-(this.finishTime-this.startTime);this.finishTime=0;this.ispaused=false};this.isFinished=function(){return(!this.ispaused&&this.finishTime!=0)};this.setNumberOfCharacters=function(B){this.numberOfCharacters=B};this.getNumberOfCharacters=function(){return this.numberOfCharacters};this.setNumberOfLines=function(B){};this.getNumberOfLines=function(){return 1};this.getNumberOfErrors=function(){return this.errors};this.setNumberOfErrors=function(B){this.errors=B};this.backspacePressed=function(){this.numberOfBackspace++};this.getScore=function(){var B=0;if(this.startTime==0){return 0}B+=parseInt(this.getCPM());B+=5*parseInt(this.getAccuracy());B+=this.getBonus();if(this.getNumberOfErrors()>2){B-=(this.getNumberOfErrors()-2)*50}if(B<0){B=0}return B};this.isPerfect=function(){return(this.isFinished()&&(this.errors==0)&&(this.numberOfBackspace==0))};this.getBonus=function(){var B=0;if(this.isFinished()){B=250-((100*this.errors)+(200*this.numberOfBackspace));if(B<0){B=0}}return B};this.saveStatus=function(C){var B=new StatisticStatus(C,this.time(),this.errors,this.numberOfCharacters);this.statusHistory[this.statusHistory.length]=B};this.getCPM=function(){var C=this._getTimeDifference();var B=(C<0.25)?0:(60*(this.numberOfCharacters/C));return parseInt(B)};this.getAccuracy=function(){var B=(this.numberOfCharacters==0)?100:(100*(1-(this.errors/this.numberOfCharacters)));return parseInt(B)};this._findswaps=function(F,D){var G=new HashSet(),H=new HashSet();var E=1;var B=new Array();for(var C=0;C<F.length;C++){if(F[C].exToken==F[C].inToken){H=new HashSet();G=new HashSet();E=0}else{if((C>=D)&&(E>=D)){H.erase(F[C-D].exToken);G.erase(F[C-D].inToken)}}H.insert(F[C].exToken);G.insert(F[C].inToken);if((E>=D)&&(G.equals(H))){exstr=instr="";for(i=C-D+1;i<=C;i++){exstr+=F[i].exToken;instr+=F[i].inToken;F[i]=new ExerciseTiming(F[i].time,null,null)}B[B.length]=new TypingError(TYPING_SWAP_ERROR,C-D+1,D,exstr,instr);H=new HashSet();G=new HashSet();E=0}E++}return B};this.update=function(G){var E;var B=G.concat([]);var D=new Array();D=D.concat(this._findswaps(B,3));D=D.concat(this._findswaps(B,2));for(E=0;E<B.length;E++){var J,I;J=B[E].exToken;I=B[E].inToken;var H=TYPING_OK;if(J==I){if(I==null){continue}}else{if(J==I.toLowerCase()){H=TYPING_LOWER_ERROR}else{if(J==I.toUpperCase()){H=TYPING_UPPER_ERROR}else{H=TYPING_WRONG_CHAR_ERROR}}}D[D.length]=new TypingError(H,E,1,J,I)}var F=new Array(B.length);for(var C=0;C<B.length;C++){F[C]=null}for(var C=0;C<D.length;C++){F[D[C].index]=D[C]}this.errors=0;for(var C=0;C<F.length;C++){if(F[C]!=null){if(F[C].type!=TYPING_OK){this.errors++}}}return F};this._getTimeDifference=function(){var B=(this.finishTime==0)?this._getCurrentTime():this.finishTime;return(B-this.startTime)};this._getCurrentTime=function(){return((new Date()).getTime()/1000)}};