
(function($){var TypeChecker={typeOf:function(value){var s=typeof value;if(s!=='object'){return s;}
if(!value){return'null';}
if(typeof value.length==='number'&&!value.propertyIsEnumerable('length')&&typeof value.splice==='function'){return'array';}
return s;},checkArgTypes:function(){var args=[].slice.apply(arguments);var callerArguments=args.shift();checkNumArgs(callerArguments);for(var i=0;i<args.length;i++){this.assertType(callerArguments[i],args[i]);}},checkNumArgs:function(callerArguments){if(callerArguments.callee.length!=callerArguments.length){throw'wrong number of args: got '+callerArguments.length+' but expected '+callerArguments.callee.length;}},assertTypeIs:function(object,type){this.checkNumArgs(arguments);if(this.typeOf(object)!==type){throw'Type Error: got '+this.typeOf(object)+' but expected '+type;}},assertTypeIsOneOf:function(){var args=[].slice.apply(arguments);var object=args.shift();var self=this;if(!Boolean($.grep(args,function(elt){return self.typeOf(object)===elt;}).length)){throw'Type Error: got '+typeOf(object)+' but expected one of: '+args;}}};var ConsoleLogger=function(){this.level=ConsoleLogger.levels.debug;this.logMethodEntries=true;};ConsoleLogger.levels={debug:1,info:2,warn:3,error:4};$.extend(ConsoleLogger.prototype,{enter:function(methodName,args){if(this.logMethodEntries){var suffix="";if(args!==undefined){var args2=[];for(var i=0;i<args.length;i++){args2.push(args[i]===undefined?"undefined":args[i].toString());}
suffix=" with args: ["+args2+"]";}
this.info("Entering method %s%s",methodName,suffix);}},setLevel:function(level){this.level=levels[level];},debug:function(){if(!window.console||!console.debug){return;}
if(this.level<=ConsoleLogger.levels.debug){console.debug.apply(console,arguments);}},info:function(){if(!window.console||!console.info){return;}
if(this.level<=ConsoleLogger.levels.info){console.info.apply(console,arguments);}},warn:function(){if(!window.console||!console.warn){return;}
if(this.level<=ConsoleLogger.levels.warn){console.warn.apply(console,arguments);}},error:function(){if(!window.console||!console.error){return;}
if(this.level<=ConsoleLogger.levels.error){console.error.apply(console,arguments);}}});var log=new ConsoleLogger();if($.fn.shoveler){log.warn("Shoveler already loaded!! Re-loading!!");}
$.fn.shoveler=function(generator,numCellsTotal,options){if(this.size()!==1){throw"must only init one shoveler at a time but you are trying to init "+this.size();}
return new Shoveler(this,generator,numCellsTotal,options);};var Shoveler=function(domElement,generator,numCellsTotal,options){if(this===window){throw new Error("Shoveler must be called with 'new'");}
if(!domElement||typeof domElement!=='object'){throw new Error("Must give a domElement object param to Shoveler");}
this.root=$(domElement);if(!this.root.hasClass('shoveler')){log.warn("jQuery must be initialized with an element with a class of 'shoveler'");}
if(!generator||typeof generator!=='function'){throw new Error("Must give a function generator param to Shoveler");}
var defaultOptions={cellTransformer:function(input){return input;},cellChangeSpeedInMs:50,ajaxTimeout:3000,onPageChangeCompleteHandler:function(){},paginationSelector:'.shoveler-pagination',rootUlSelector:'ul:first',prevButtonSelector:'div.prev-button',nextButtonSelector:'div.next-button',circular:true};$.extend(this,defaultOptions,options||{});this.rootUl=$(this.rootUlSelector,domElement);if(this.rootUl.size()!==1){throw new Error('Shovler must be initialized with an element with a single UL descendant');}
if(!$(this.paginationSelector,this.root).size()){throw new Error("Shoveler div must have a '"+this.paginationSelector+"'");}
this.generator=function(){var ret=generator.apply(this,arguments);if(!ret&&!ret instanceof'string'&&!ret instanceof Array){throw new Error("Generator should return string or array, but instead returned: "+ret.toString());}
return ret;};this.numCellsTotal=numCellsTotal;this.currentCell=0;this.cache=[];var data=this.getAllCells().map(function(){return $(this).html();});for(var i=this.cache.length;i<this.numCellsTotal;i++){this.cache[i]=i;}
this.updateCache(0,true,data,false);if(!$(this.paginationSelector).find('.page-number').size()||!$(this.paginationSelector).find('.num-pages').size())
{$(this.paginationSelector,this.root).prepend($('<span>Page '+'<span class="page-number">???</span> of '+'<span class="num-pages">???</span> '+'<span class="start-over"> (<a href="">Start Over</a>) </span>'+'<span class="debug-info"> '+'cell:<span class="cell-number">0</span>, '+'numVisible=<span class="num-visible">???</span>'+'</span></span>'));}
var self=this;$('span.start-over',this.root).click(function(){self.gotoPage(0);return false;});$(this.prevButtonSelector,this.root).click(function(){if(!self.isFirstPage()){self.gotoPage(Math.ceil(self.getCurrentPage()-1));}
else if(self.circular){self.gotoPage(self.getNumPages()-1,true);}});$(this.nextButtonSelector,this.root).click(function(){if(!self.isLastPage()){self.gotoPage(Math.floor(self.getCurrentPage()+1));}
else if(self.circular){self.gotoPage(0,true);}});$(this.prevButtonSelector,this.root).add($(this.nextButtonSelector,this.root)).mousedown(function(){$(this).addClass('depressed');}).mouseup(function(){$(this).removeClass('depressed');});$(window).resize(function(){self.updateUI();});this.updateUI();};$.extend(Shoveler.prototype,{updateUI:function(){this.adjustNumLisInDom();this.getNewCellsIfNeeded();this.updateStats();var buttons=$('div.next-button,div.prev-button',this.root);buttons[this.shouldShowScrollButtons()?'show':'hide']();},alreadyInitedUI:false,initialUpdateUI:function(){if(!this.alreadyInitedUI){this.alreadyInitedUI=true;this.updateUI();}},shouldShowScrollButtons:function(){return this.getNumPages()>1||this.currentCell!==0;},updateStats:function(){var pagination=$(this.paginationSelector,this.root);pagination[this.shouldShowScrollButtons()?'show':'hide']();$('.page-number',this.root).text(1+Math.floor(this.getCurrentPage()));$('.num-pages',this.root).text(this.getNumPages());$('.cell-number',this.root).text(""+this.currentCell);$('.num-visible',this.root).text(""+this.getNumCellsPerPage());$('span.start-over',this.root).css('display',this.isFirstPage()?'none':'');if(!self.circular){$(this.nextButtonSelector,this.root)[this.isLastPage()?'addClass':'removeClass']('disabled');$(this.prevButtonSelector,this.root)[this.isFirstPage()?'addClass':'removeClass']('disabled');}},getCurrentPage:function(){return this.currentCell/this.getNumCellsPerPage();},isMidPage:function(){return!!(this.currentCell%this.getNumCellsPerPage());},isLastPage:function(){return this.currentCell+this.getNumCellsPerPage()>=this.numCellsTotal;},isFirstPage:function(){return this.getCurrentPage()===0;},getNumCellsPerPage:function(){return this.getAllCells().size();},getNumPages:function(){return Math.ceil(this.numCellsTotal/this.getNumCellsPerPage());},getAllCells:function(){return this.rootUl.find('> li');},adjustNumLisInDom:function(){if(this.getAllCells().size()===0){this.rootUl.append($('<li>'));}
var totalWidth=this.rootUl.width();var cellWidth=this.getAllCells().width();if(cellWidth===0){return;}
var cellsPerPage=Math.floor(totalWidth/cellWidth);var remainingSpace=totalWidth%cellWidth;var actualCellsPerPage=this.getNumCellsPerPage();var difference=cellsPerPage-actualCellsPerPage;if(difference===0){}
while(difference>0){this.rootUl.append($('<li>'));difference--;}
while(difference<0){this.rootUl.find('> li:last').remove();difference++;}
var margin=Math.floor(remainingSpace/cellsPerPage/2);this.getAllCells().css({'margin-left':margin+'px','margin-right':margin+'px'});},isCellEmpty:function(value){return typeof value=='undefined'||typeof value=='number';},isCacheEmpty:function(originalCacheIndex){return $.inArray(originalCacheIndex,this.cache)>=0;},cacheUpdated:function(wasAjax){if(!this.animInProgress()){this.updateVisibleCellsImmediately(this.currentCell);this.onPageChangeCompleteHandler();this.updateUI();}
else if(wasAjax){this.pendingAsyncDataRequiresPageRefresh=true;}},getNewCellsIfNeeded:function(){var slice=this.cache.slice(this.currentCell,this.currentCell+this.getNumCellsPerPage());slice=$.grep(slice,function(item,index){return typeof item==='number';});if(!slice.length){return;}
var originalStartIndex=slice[0];var numCells=slice.pop()-originalStartIndex+1;var data=this.generator(originalStartIndex,numCells);if(typeof data!=="string"){this.updateCache(originalStartIndex,false,data,false);}
else{log.info("making ajax call to %s",data);var self=this;$.ajax({url:data,dataType:"json",timeout:self.ajaxTimeout,error:function(){log.warn("failed ajax request to %s",data);},success:function(jsonObjArray){log.info("Got json data by ajax: %s",jsonObjArray);if(!jsonObjArray||!jsonObjArray instanceof Array){throw"unexpected value returned from ajax call: "+
(jsonObjArray?(typeof jsonObjArray):jsonObjArray);}
if(jsonObjArray.length<numCells){log.error("Got less cells than expected. Got %s but expected %s",jsonObjArray.length,numCells);jsonObjArray.length=numCells;}
self.updateCache(originalStartIndex,false,jsonObjArray,true);}});}},switchVisibleCellsInterval:null,animInProgress:function(){return this.switchVisibleCellsInterval!==null;},switchVisibleCells:function(lastDirection,wrapped){if(this.animInProgress()){log.warn("animation already in progress");clearInterval(this.switchVisibleCellsInterval);this.switchVisibleCellsInterval=null;}
var animateFromRightToLeft=(lastDirection===1);var decrement=lastDirection;if(wrapped){animateFromRightToLeft=!animateFromRightToLeft;decrement*=-1;}
var indexWithinPage=animateFromRightToLeft?this.getNumCellsPerPage()-1:0;var endIndexWithinPage=animateFromRightToLeft?0:this.getNumCellsPerPage()-1;var startCell=this.currentCell;var self=this;this.switchVisibleCellsInterval=setInterval(function(){var currentCacheIndex=startCell+indexWithinPage;self.updateCellIfVisible(currentCacheIndex);if(indexWithinPage===endIndexWithinPage){clearInterval(self.switchVisibleCellsInterval);self.switchVisibleCellsInterval=null;if(self.pendingAsyncDataRequiresPageRefresh){self.updateVisibleCellsImmediately(startCell);}
self.onPageChangeCompleteHandler();self.updateUI();return;}
indexWithinPage-=decrement;},this.cellChangeSpeedInMs);},updateVisibleCellsImmediately:function(startCell){this.pendingAsyncDataRequiresPageRefresh=false;for(var i=0;i<this.getNumCellsPerPage();i++){var cacheIndex=startCell+i;this.updateCellIfVisible(cacheIndex);}},updateCellIfVisible:function(currentCacheIndex){var cellIndex=currentCacheIndex-this.currentCell;var li=this.getAllCells().eq(cellIndex);if(!this.isCellEmpty(this.cache[currentCacheIndex])){var html=this.cache[currentCacheIndex].data;li.html(html).removeClass("shoveler-progress");}
else if(currentCacheIndex>=this.numCellsTotal){li.html('<span class="empty"/>').removeClass("shoveler-progress");}
else{li.html('<span class="empty"/>').addClass("shoveler-progress");}},updateCache:function(originalStartIndex,isHtml,data,wasAjax){if(data.length===0){return;}
var self=this;var didUpdate=false;$.each(data,function(index,value){var originalCacheIndex=originalStartIndex+index;if(self.isCacheEmpty(originalCacheIndex)){var toStore=value;if(!isHtml){toStore=self.cellTransformer(value);}
var index=$.inArray(originalCacheIndex,self.cache);if(index>=0){self.cache[index]={data:$.trim(toStore)};}
didUpdate=true;}
else{log.warn("updating cache[%s], but it was already cached",originalCacheIndex);}});if(!didUpdate){log.warn("Didn't update cache at all in updateCache()");}
else{if(!isHtml){this.cacheUpdated(wasAjax);}}},gotoPage:function(pageNumber,wrapped){TypeChecker.assertTypeIs(pageNumber,'number');TypeChecker.assertTypeIsOneOf(wrapped,'boolean','undefined');if(pageNumber>=this.getNumPages()){log.warn("Can't go to page %s since there are only %s pages",pageNumber,this.getNumPages());pageNumber=this.getNumPages()-1;}
if(pageNumber<0){log.warn("Can't go to page %s, going to 0 instead",pageNumber);pageNumber=0;}
var lastDirection=(this.getCurrentPage()<pageNumber)?1:-1;this.currentCell=pageNumber*this.getNumCellsPerPage();this.updateStats();this.switchVisibleCells(lastDirection,wrapped);this.getNewCellsIfNeeded();},removeItemByCurrentCacheIndex:function(cacheIndex){TypeChecker.assertTypeIs(cacheIndex,'number');var ret=this.cache.splice(cacheIndex,1)[0].data;this.numCellsTotal--;this.gotoPage(this.getCurrentPage());return ret;},removeItemByPageIndex:function(pageIndex){TypeChecker.assertTypeIs(pageIndex,'number');return this.removeItemByCurrentCacheIndex(this.currentCell+pageIndex);},addToLeft:function(html){TypeChecker.assertTypeIs(html,'string');this.cache.unshift({data:html});this.numCellsTotal++;this.gotoPage(this.getCurrentPage());},size:function(){return this.numCellsTotal;}});})(jQuery);
