text: ComponentJS.plugin("testdrive",function(a,b,c){b.suite=function(){var e=c.jQuery||c.$;if("function"!=typeof e)throw new Error("testdrive#suite() requires jQuery");var f="ComponentJS-testdrive-suite",g=e("body > ."+f);0===g.length&&(g=e('<div class="'+f+'"><div class="'+f+'-head"><b>ComponentJS</b> Test-Drive Use-Cases Suite<div class="'+f+'-head-close">close</div></div><div class="'+f+'-list"></div></div>'),g.hide(),e("body").append(g));var h=function(a){e(g).show().animate({top:0},300,"swing",a)},i=function(a){e(g).animate({top:-l},300,"swing",function(){e(g).hide(),e(g).remove(),"function"==typeof a&&a()})};if(e("body > ."+f).filter(":visible").length>0)return void i();var j=e(c).width(),k=j/10*8,l=400;g.width(k).height(l).css("top",-l).css("left",j/2-k/2).css("position","absolute").css("z-index",1e4).css("background-color","#f8f8f8").css("-webkit-box-shadow","0 4px 16px 0 #909090").css("box-shadow","0 4px 16px 0 #909090").css("-webkit-border-radius","0 0 8px 8px").css("border-radius","0 0 8px 8px").css("color","#000000").css("font-family","sans-serif").css("font-size","11pt"),e("."+f+"-head",g).width(k-20).height(20).css("position","relative").css("background","#666666").css("background","-moz-linear-gradient(top, #666666 0%, #333333 49%, #222222 51%, #000000 100%)").css("background","-webkit-linear-gradient(top, #666666 0% ,#333333 49% ,#222222 51%, #000000 100%)").css("background","linear-gradient(to bottom, #666666 0%, #333333 49%, #222222 51%, #000000 100%)").css("color","#ffffff").css("padding","7px 10px 7px 10px").css("font-size","16px"),e("."+f+"-head-close",g).css("position","absolute").css("right","10px").css("top","6px").css("padding","4px 10px 4px 10px").css("font-size","12px").css("color","#c0c0c0").css("border","1px solid #606060").css("cursor","pointer"),e("."+f+"-list",g).width(k).height(l-30).css("overflow","scroll").css("overflow-x","hidden");var m=e("<table></table>");m.append('<tr class="'+f+'-list-row-first"><td class="'+f+'-list-name">Identifier</td><td class="'+f+'-list-desc">Description</td></tr>');var n=0;a.foreach(a.keysof(d).sort(),function(a){m.append('<tr data-id="'+a+'" class="'+f+"-list-row "+f+"-list-row-"+n++%2+'"><td class="'+f+'-list-name">'+a+'</td><td class="'+f+'-list-desc">'+d[a].desc+"</td></tr>")}),e("."+f+"-list",g).html(m),e("."+f+"-list table",g).width(k).css("border-collapse","collapse"),e("."+f+"-list-row",g).css("cursor","pointer"),e("."+f+"-list-row-first",g).width(k).css("background-color","#909090").css("color","#f0f0f0"),e("."+f+"-list-row-1",g).width(k).css("background-color","#f0f0f0"),e("."+f+"-list-name",g).css("padding","2px 10px 2px 10px").css("font-family","monospace"),e("."+f+"-list-desc",g).width("100%").css("padding","2px 10px 2px 10px"),e("."+f+"-list-row",g).on("click",function(a){var c=a.target;"tr"!==e(c).prop("tagName")&&(c=e(c).parent());var d=e(c).data("id");"string"==typeof d&&""!==d&&i(function(){b.drive(d).then(null,function(a){alert('ComponentJS: testdrive: use case "" failed: '+a)})})}),e("."+f+"-head-close",g).on("click",i),h()},b.promise=function(){var a={exports:{}};return function(b,c,d){"function"==typeof define&&"undefined"!=typeof define.amd?define(c,function(){return d(b)}):"object"==typeof a&&"object"==typeof a.exports?a.exports=d(b):b[c]=function(){var a=b[c],e=d(b);return e.noConflict=function(){return b[c]=a,e},e}()}(this,"Thenable",function(){var a=0,b=1,c=2,d=function(b){return this instanceof d?(this.id="Thenable/1.0.7",this.state=a,this.fulfillValue=void 0,this.rejectReason=void 0,this.onFulfilled=[],this.onRejected=[],this.proxy={then:this.then.bind(this)},void("function"==typeof b&&b.call(this,this.fulfill.bind(this),this.reject.bind(this)))):new d(b)};d.prototype={fulfill:function(a){return e(this,b,"fulfillValue",a)},reject:function(a){return e(this,c,"rejectReason",a)},then:function(a,b){var c=this,e=new d;return c.onFulfilled.push(h(a,e,"fulfill")),c.onRejected.push(h(b,e,"reject")),f(c),e.proxy}};var e=function(b,c,d,e){return b.state===a&&(b.state=c,b[d]=e,f(b)),b},f=function(a){a.state===b?g(a,"onFulfilled",a.fulfillValue):a.state===c&&g(a,"onRejected",a.rejectReason)},g=function(a,b,c){if(0!==a[b].length){var d=a[b];a[b]=[];var e=function(){for(var a=0;a<d.length;a++)d[a](c)};"object"==typeof process&&"function"==typeof process.nextTick?process.nextTick(e):"function"==typeof setImmediate?setImmediate(e):setTimeout(e,0)}},h=function(a,b,c){return function(d){if("function"!=typeof a)b[c].call(b,d);else{var e;try{e=a(d)}catch(f){return void b.reject(f)}i(b,e)}}},i=function(a,b){if(a===b||a.proxy===b)return void a.reject(new TypeError("cannot resolve promise with itself"));var c;if("object"==typeof b&&null!==b||"function"==typeof b)try{c=b.then}catch(d){return void a.reject(d)}if("function"!=typeof c)a.fulfill(b);else{var e=!1;try{c.call(b,function(c){e||(e=!0,c===b?a.reject(new TypeError("circular thenable chain")):i(a,c))},function(b){e||(e=!0,a.reject(b))})}catch(d){e||a.reject(d)}}};return d}),a.exports}();var d={};b.usecase=function(){var c=b.params("usecase",arguments,{name:{pos:0,req:!0,valid:"string"},desc:{pos:1,req:!0,valid:"string"},conf:{def:{},valid:"object"},func:{pos:2,req:!0,valid:"(function|null)"}});if(null===c.func)delete d[c.name];else{if(a.isdefined(d[c.name]))throw a.exception("usecase",'usecase of name "'+c.name+'" already defined');d[c.name]={desc:c.desc,conf:c.conf,func:c.func}}},b.drive=function(){var c=b.params("drive",arguments,{name:{pos:0,req:!0,valid:"string"},conf:{pos:1,def:{},valid:"object"},timeout:{pos:2,def:1e4,valid:"number"}}),e=d[c.name];if(!a.isdefined(e))throw a.exception("drive",'invalid usecase name "'+c.name+'"');var f=new b.promise,g=f.proxy,h=!1,i=null;c.timeout>0&&(i=setTimeout(function(){i=null,h||(h=!0,b.debug(1,'drive: usecase "'+c.name+'", TIMEOUT after '+c.timeout+" ms"),f.reject(new Error('usecase "'+c.name+'": timeout')))},c.timeout));var j={};a.extend(j,e.conf),a.extend(j,c.conf),b.debug(1,'drive: usecase "'+c.name+'" ('+d[c.name].desc+"), EXECUTING"+(a.keysof(c.conf).length>0?" with configuration "+a.json(c.conf):"")+(c.timeout>0?" and timeout of "+c.timeout+" ms":""));var k;try{k=e.func.apply(j,[j])}catch(l){h||(h=!0,b.debug(1,'drive: usecase "'+c.name+'", EXCEPTION: '+l.message),f.reject(new Error('usecase "'+c.name+'": '+l.message)))}return null!==i&&(clearTimeout(i),i=null),h||("object"!=typeof k&&"function"!=typeof k||"function"!=typeof k.then?f.fulfill(!0):g=k),g=g.then(null,function(a){return b.debug(1,'drive: usecase "'+c.name+'" failed: '+a),a})},b.ensure=function(){var a=b.params("ensure",arguments,{path:{pos:0,req:!0,valid:"string"},state:{pos:1,req:!0,valid:"string"},min:{def:!0,valid:"boolean"},max:{def:!1,valid:"boolean"},sync:{def:!1,valid:"boolean"}}),c=new b.promise,d=b(a.path);return d.state({state:a.state,min:a.min,max:a.max,sync:a.sync,func:function(){c.fulfill(d)}}),c.proxy};var e=[];b.await=function(){var c=b.params("await",arguments,{path:{pos:0,req:!0,valid:"string"},state:{pos:1,req:!0,valid:"string"},direction:{pos:2,def:"enter",valid:"string"}});if(a.states.length<=1)throw a.exception("await","no user-defined component states");var d=a.state_name2idx(c.state);if(-1===d)throw a.exception("await",'invalid state name "'+c.state+'": no such state defined');if(!c.direction.match(/^(?:enter|leave)$/))throw a.exception("await",'invalid direction "'+c.direction+'"');var g,h=new b.promise;for(g=0;g<e.length&&(e[g].path!==c.path||e[g].state!==c.state||e[g].direction!==c.direction);g++);g===e.length&&(e[g]={path:c.path,comp:b(c.path),state:c.state,direction:c.direction,promises:[]}),e[g].promises.push(h);var i=e[g].comp;return i!==a.none&&f(i,i.state(),"enter"),h.proxy};var f=function(c,d,f){var g;if(a.states.length<=1)throw a.exception("await(internal)","no user-defined component states");if(d===a.states[1].state&&"enter"===f)for(g=0;g<e.length;g++)e[g].comp===a.none&&(e[g].comp=b(e[g].path));for(g=0;"undefined"!=typeof e[g];)if(e[g].comp===c&&e[g].state===d&&e[g].direction===f){for(var h=0;h<e[g].promises.length;h++)!function(b,c){setTimeout(a.hook("ComponentJS:settimeout:func","pass",function(){b.fulfill(c)}),0)}(e[g].promises[h],c);e.splice(g,1)}else g++;if(d===a.states[1].state&&"leave"===f)for(g=0;g<e.length;g++)e[g].comp===c&&(e[g].comp=a.none)};a.latch("ComponentJS:bootstrap",function(){a.latch("ComponentJS:comp-created",function(b){if(a.states.length<=1)throw a.exception("await(internal)","no user-defined component states");f(b,a.states[1].state,"enter")}),a.latch("ComponentJS:comp-destroyed",function(b){if(a.states.length<=1)throw a.exception("await(internal)","no user-defined component states");f(b,a.states[1].state,"leave")}),a.latch("ComponentJS:state-enter",function(a,b){f(a,b,"enter")}),a.latch("ComponentJS:state-leave",function(a,b){f(a,b,"leave")})}),b.poll=function(){var a=b.params("poll",arguments,{check:{pos:0,req:!0,valid:"function"},wait:{pos:1,def:100,valid:"(function|number)"},max:{pos:2,def:600,valid:"number"}});"number"==typeof a.wait&&(a.wait=function(a){return function(){return b.sleep(a)}}(a.wait));var c=a.check,d=a.wait,e=a.max;return new b.promise(function(a,b){var f=function(){e--<=0?b():c()?a():d().then(f)};f()})},b.sleep=function(){var a=b.params("sleep",arguments,{ms:{pos:0,req:!0,valid:"number"}});return new b.promise(function(b){setTimeout(function(){b()},a.ms)})},b.once=function(){var a=b.params("once",arguments,{selector:{pos:0,req:!0,valid:"any"},events:{pos:1,req:!0,valid:"string"},subselector:{pos:2,def:null,valid:"(string|null)"}}),d=c.jQuery||c.$;if("function"!=typeof d)throw new Error("testdrive#once() requires jQuery");var e=new b.promise;if("mutation"===a.events){if("function"!=typeof c.MutationObserver)throw new Error("once: MutationObserver not available");if(null!==a.subselector)throw new Error("once: mutation event does not support sub-selector");var f=d(a.selector);if(0===f.length)throw new Error("once: no nodes found");if(1!==f.length)throw new Error("once: more than exactly one node found");var g=new c.MutationObserver(function(a){g.disconnect(),e.fulfill(a)});g.observe(f.get(0),{attributes:!0,characterData:!0,childList:!0,subtree:!1})}else d(a.selector).one(a.events,a.subselector,function(a){e.fulfill(a)});return e.proxy}});