/* Compressed by the perl version of jsmin. */
/* JavaScript::Minifier 0.02 */

Event.simulateMouse=function(element,eventName){var options=Object.extend({pointerX:0,pointerY:0,buttons:0,ctrlKey:false,altKey:false,shiftKey:false,metaKey:false},arguments[2]||{});var oEvent=document.createEvent("MouseEvents");oEvent.initMouseEvent(eventName,true,true,document.defaultView,options.buttons,options.pointerX,options.pointerY,options.pointerX,options.pointerY,options.ctrlKey,options.altKey,options.shiftKey,options.metaKey,0,$(element));if(this.mark)Element.remove(this.mark);this.mark=document.createElement('div');this.mark.appendChild(document.createTextNode(" "));document.body.appendChild(this.mark);this.mark.style.position='absolute';this.mark.style.top=options.pointerY+"px";this.mark.style.left=options.pointerX+"px";this.mark.style.width="5px";this.mark.style.height="5px;";this.mark.style.borderTop="1px solid red;"
this.mark.style.borderLeft="1px solid red;"
if(this.step)
alert('['+new Date().getTime().toString()+'] '+eventName+'/'+Test.Unit.inspect(options));$(element).dispatchEvent(oEvent);};Event.simulateKey=function(element,eventName){var options=Object.extend({ctrlKey:false,altKey:false,shiftKey:false,metaKey:false,keyCode:0,charCode:0},arguments[2]||{});var oEvent=document.createEvent("KeyEvents");oEvent.initKeyEvent(eventName,true,true,window,options.ctrlKey,options.altKey,options.shiftKey,options.metaKey,options.keyCode,options.charCode);$(element).dispatchEvent(oEvent);};Event.simulateKeys=function(element,command){for(var i=0;i<command.length;i++){Event.simulateKey(element,'keypress',{charCode:command.charCodeAt(i)});}};var Test={}
Test.Unit={};Test.Unit.inspect=Object.inspect;Test.Unit.Logger=Class.create();Test.Unit.Logger.prototype={initialize:function(log){this.log=$(log);if(this.log){this._createLogTable();}},start:function(testName){if(!this.log)return;this.testName=testName;this.lastLogLine=document.createElement('tr');this.statusCell=document.createElement('td');this.nameCell=document.createElement('td');this.nameCell.className="nameCell";this.nameCell.appendChild(document.createTextNode(testName));this.messageCell=document.createElement('td');this.lastLogLine.appendChild(this.statusCell);this.lastLogLine.appendChild(this.nameCell);this.lastLogLine.appendChild(this.messageCell);this.loglines.appendChild(this.lastLogLine);},finish:function(status,summary){if(!this.log)return;this.lastLogLine.className=status;this.statusCell.innerHTML=status;this.messageCell.innerHTML=this._toHTML(summary);this.addLinksToResults();},message:function(message){if(!this.log)return;this.messageCell.innerHTML=this._toHTML(message);},summary:function(summary){if(!this.log)return;this.logsummary.innerHTML=this._toHTML(summary);},_createLogTable:function(){this.log.innerHTML='<div id="logsummary"></div>'+'<table id="logtable">'+'<thead><tr><th>Status</th><th>Test</th><th>Message</th></tr></thead>'+'<tbody id="loglines"></tbody>'+'</table>';this.logsummary=$('logsummary')
this.loglines=$('loglines');},_toHTML:function(txt){return txt.escapeHTML().replace(/\n/g,"<br/>");},addLinksToResults:function(){$$("tr.failed .nameCell").each(function(td){td.title="Run only this test"
Event.observe(td,'click',function(){window.location.search="?tests="+td.innerHTML;});});$$("tr.passed .nameCell").each(function(td){td.title="Run all tests"
Event.observe(td,'click',function(){window.location.search="";});});}}
Test.Unit.Runner=Class.create();Test.Unit.Runner.prototype={initialize:function(testcases){this.options=Object.extend({testLog:'testlog'},arguments[1]||{});this.options.resultsURL=this.parseResultsURLQueryParameter();this.options.tests=this.parseTestsQueryParameter();if(this.options.testLog){this.options.testLog=$(this.options.testLog)||null;}
if(this.options.tests){this.tests=[];for(var i=0;i<this.options.tests.length;i++){if(/^test/.test(this.options.tests[i])){this.tests.push(new Test.Unit.Testcase(this.options.tests[i],testcases[this.options.tests[i]],testcases["setup"],testcases["teardown"]));}}}else{if(this.options.test){this.tests=[new Test.Unit.Testcase(this.options.test,testcases[this.options.test],testcases["setup"],testcases["teardown"])];}else{this.tests=[];for(var testcase in testcases){if(/^test/.test(testcase)){this.tests.push(new Test.Unit.Testcase(this.options.context?' -> '+this.options.titles[testcase]:testcase,testcases[testcase],testcases["setup"],testcases["teardown"]));}}}}
this.currentTest=0;this.logger=new Test.Unit.Logger(this.options.testLog);setTimeout(this.runTests.bind(this),1000);},parseResultsURLQueryParameter:function(){return window.location.search.parseQuery()["resultsURL"];},parseTestsQueryParameter:function(){if(window.location.search.parseQuery()["tests"]){return window.location.search.parseQuery()["tests"].split(',');};},getResult:function(){var hasFailure=false;for(var i=0;i<this.tests.length;i++){if(this.tests[i].errors>0){return"ERROR";}
if(this.tests[i].failures>0){hasFailure=true;}}
if(hasFailure){return"FAILURE";}else{return"SUCCESS";}},postResults:function(){if(this.options.resultsURL){new Ajax.Request(this.options.resultsURL,{method:'get',parameters:'result='+this.getResult(),asynchronous:false});}},runTests:function(){var test=this.tests[this.currentTest];if(!test){this.postResults();this.logger.summary(this.summary());return;}
if(!test.isWaiting){this.logger.start(test.name);}
test.run();if(test.isWaiting){this.logger.message("Waiting for "+test.timeToWait+"ms");setTimeout(this.runTests.bind(this),test.timeToWait||1000);}else{this.logger.finish(test.status(),test.summary());this.currentTest++;this.runTests();}},summary:function(){var assertions=0;var failures=0;var errors=0;var messages=[];for(var i=0;i<this.tests.length;i++){assertions+=this.tests[i].assertions;failures+=this.tests[i].failures;errors+=this.tests[i].errors;}
return((this.options.context?this.options.context+': ':'')+
this.tests.length+" tests, "+
assertions+" assertions, "+
failures+" failures, "+
errors+" errors");}}
Test.Unit.Assertions=Class.create();Test.Unit.Assertions.prototype={initialize:function(){this.assertions=0;this.failures=0;this.errors=0;this.messages=[];},summary:function(){return(this.assertions+" assertions, "+
this.failures+" failures, "+
this.errors+" errors"+"\n"+
this.messages.join("\n"));},pass:function(){this.assertions++;},fail:function(message){this.failures++;this.messages.push("Failure: "+message);},info:function(message){this.messages.push("Info: "+message);},error:function(error){this.errors++;this.messages.push(error.name+": "+error.message+"("+Test.Unit.inspect(error)+")");},status:function(){if(this.failures>0)return'failed';if(this.errors>0)return'error';return'passed';},assert:function(expression){var message=arguments[1]||'assert: got "'+Test.Unit.inspect(expression)+'"';try{expression?this.pass():this.fail(message);}
catch(e){this.error(e);}},assertEqual:function(expected,actual){var message=arguments[2]||"assertEqual";try{(expected==actual)?this.pass():this.fail(message+': expected "'+Test.Unit.inspect(expected)+'", actual "'+Test.Unit.inspect(actual)+'"');}
catch(e){this.error(e);}},assertInspect:function(expected,actual){var message=arguments[2]||"assertInspect";try{(expected==actual.inspect())?this.pass():this.fail(message+': expected "'+Test.Unit.inspect(expected)+'", actual "'+Test.Unit.inspect(actual)+'"');}
catch(e){this.error(e);}},assertEnumEqual:function(expected,actual){var message=arguments[2]||"assertEnumEqual";try{$A(expected).length==$A(actual).length&&expected.zip(actual).all(function(pair){return pair[0]==pair[1]})?this.pass():this.fail(message+': expected '+Test.Unit.inspect(expected)+', actual '+Test.Unit.inspect(actual));}
catch(e){this.error(e);}},assertNotEqual:function(expected,actual){var message=arguments[2]||"assertNotEqual";try{(expected!=actual)?this.pass():this.fail(message+': got "'+Test.Unit.inspect(actual)+'"');}
catch(e){this.error(e);}},assertIdentical:function(expected,actual){var message=arguments[2]||"assertIdentical";try{(expected===actual)?this.pass():this.fail(message+': expected "'+Test.Unit.inspect(expected)+'", actual "'+Test.Unit.inspect(actual)+'"');}
catch(e){this.error(e);}},assertNotIdentical:function(expected,actual){var message=arguments[2]||"assertNotIdentical";try{!(expected===actual)?this.pass():this.fail(message+': expected "'+Test.Unit.inspect(expected)+'", actual "'+Test.Unit.inspect(actual)+'"');}
catch(e){this.error(e);}},assertNull:function(obj){var message=arguments[1]||'assertNull'
try{(obj==null)?this.pass():this.fail(message+': got "'+Test.Unit.inspect(obj)+'"');}
catch(e){this.error(e);}},assertMatch:function(expected,actual){var message=arguments[2]||'assertMatch';var regex=new RegExp(expected);try{(regex.exec(actual))?this.pass():this.fail(message+' : regex: "'+Test.Unit.inspect(expected)+' did not match: '+Test.Unit.inspect(actual)+'"');}
catch(e){this.error(e);}},assertHidden:function(element){var message=arguments[1]||'assertHidden';this.assertEqual("none",element.style.display,message);},assertNotNull:function(object){var message=arguments[1]||'assertNotNull';this.assert(object!=null,message);},assertType:function(expected,actual){var message=arguments[2]||'assertType';try{(actual.constructor==expected)?this.pass():this.fail(message+': expected "'+Test.Unit.inspect(expected)+'", actual "'+(actual.constructor)+'"');}
catch(e){this.error(e);}},assertNotOfType:function(expected,actual){var message=arguments[2]||'assertNotOfType';try{(actual.constructor!=expected)?this.pass():this.fail(message+': expected "'+Test.Unit.inspect(expected)+'", actual "'+(actual.constructor)+'"');}
catch(e){this.error(e);}},assertInstanceOf:function(expected,actual){var message=arguments[2]||'assertInstanceOf';try{(actual instanceof expected)?this.pass():this.fail(message+": object was not an instance of the expected type");}
catch(e){this.error(e);}},assertNotInstanceOf:function(expected,actual){var message=arguments[2]||'assertNotInstanceOf';try{!(actual instanceof expected)?this.pass():this.fail(message+": object was an instance of the not expected type");}
catch(e){this.error(e);}},assertRespondsTo:function(method,obj){var message=arguments[2]||'assertRespondsTo';try{(obj[method]&&typeof obj[method]=='function')?this.pass():this.fail(message+": object doesn't respond to ["+method+"]");}
catch(e){this.error(e);}},assertReturnsTrue:function(method,obj){var message=arguments[2]||'assertReturnsTrue';try{var m=obj[method];if(!m)m=obj['is'+method.charAt(0).toUpperCase()+method.slice(1)];m()?this.pass():this.fail(message+": method returned false");}
catch(e){this.error(e);}},assertReturnsFalse:function(method,obj){var message=arguments[2]||'assertReturnsFalse';try{var m=obj[method];if(!m)m=obj['is'+method.charAt(0).toUpperCase()+method.slice(1)];!m()?this.pass():this.fail(message+": method returned true");}
catch(e){this.error(e);}},assertRaise:function(exceptionName,method){var message=arguments[2]||'assertRaise';try{method();this.fail(message+": exception expected but none was raised");}
catch(e){((exceptionName==null)||(e.name==exceptionName))?this.pass():this.error(e);}},assertElementsMatch:function(){var expressions=$A(arguments),elements=$A(expressions.shift());if(elements.length!=expressions.length){this.fail('assertElementsMatch: size mismatch: '+elements.length+' elements, '+expressions.length+' expressions');return false;}
elements.zip(expressions).all(function(pair,index){var element=$(pair.first()),expression=pair.last();if(element.match(expression))return true;this.fail('assertElementsMatch: (in index '+index+') expected '+expression.inspect()+' but got '+element.inspect());}.bind(this))&&this.pass();},assertElementMatches:function(element,expression){this.assertElementsMatch([element],expression);},benchmark:function(operation,iterations){var startAt=new Date();(iterations||1).times(operation);var timeTaken=((new Date())-startAt);this.info((arguments[2]||'Operation')+' finished '+
iterations+' iterations in '+(timeTaken/1000)+'s');return timeTaken;},_isVisible:function(element){element=$(element);if(!element.parentNode)return true;this.assertNotNull(element);if(element.style&&Element.getStyle(element,'display')=='none')
return false;return this._isVisible(element.parentNode);},assertNotVisible:function(element){this.assert(!this._isVisible(element),Test.Unit.inspect(element)+" was not hidden and didn't have a hidden parent either. "+(""||arguments[1]));},assertVisible:function(element){this.assert(this._isVisible(element),Test.Unit.inspect(element)+" was not visible. "+(""||arguments[1]));},benchmark:function(operation,iterations){var startAt=new Date();(iterations||1).times(operation);var timeTaken=((new Date())-startAt);this.info((arguments[2]||'Operation')+' finished '+
iterations+' iterations in '+(timeTaken/1000)+'s');return timeTaken;}}
Test.Unit.Testcase=Class.create();Object.extend(Object.extend(Test.Unit.Testcase.prototype,Test.Unit.Assertions.prototype),{initialize:function(name,test,setup,teardown){Test.Unit.Assertions.prototype.initialize.bind(this)();this.name=name;if(typeof test=='string'){test=test.gsub(/(\.should[^\(]+\()/,'#{0}this,');test=test.gsub(/(\.should[^\(]+)\(this,\)/,'#{1}(this)');this.test=function(){eval('with(this){'+test+'}');}}else{this.test=test||function(){};}
this.setup=setup||function(){};this.teardown=teardown||function(){};this.isWaiting=false;this.timeToWait=1000;},wait:function(time,nextPart){this.isWaiting=true;this.test=nextPart;this.timeToWait=time;},run:function(){try{try{if(!this.isWaiting)this.setup.bind(this)();this.isWaiting=false;this.test.bind(this)();}finally{if(!this.isWaiting){this.teardown.bind(this)();}}}
catch(e){this.error(e);}}});Test.setupBDDExtensionMethods=function(){var METHODMAP={shouldEqual:'assertEqual',shouldNotEqual:'assertNotEqual',shouldEqualEnum:'assertEnumEqual',shouldBeA:'assertType',shouldNotBeA:'assertNotOfType',shouldBeAn:'assertType',shouldNotBeAn:'assertNotOfType',shouldBeNull:'assertNull',shouldNotBeNull:'assertNotNull',shouldBe:'assertReturnsTrue',shouldNotBe:'assertReturnsFalse',shouldRespondTo:'assertRespondsTo'};Test.BDDMethods={};for(m in METHODMAP){Test.BDDMethods[m]=eval('function(){'+'var args = $A(arguments);'+'var scope = args.shift();'+'scope.'+METHODMAP[m]+'.apply(scope,(args || []).concat([this])); }');}
[Array.prototype,String.prototype,Number.prototype].each(function(p){Object.extend(p,Test.BDDMethods)});}
Test.context=function(name,spec,log){Test.setupBDDExtensionMethods();var compiledSpec={};var titles={};for(specName in spec){switch(specName){case"setup":case"teardown":compiledSpec[specName]=spec[specName];break;default:var testName='test'+specName.gsub(/\s+/,'-').camelize();var body=spec[specName].toString().split('\n').slice(1);if(/^\{/.test(body[0]))body=body.slice(1);body.pop();body=body.map(function(statement){return statement.strip()});compiledSpec[testName]=body.join('\n');titles[testName]=specName;}}
new Test.Unit.Runner(compiledSpec,{titles:titles,testLog:log||'testlog',context:name});};