/* jQuery autoResize (textarea auto-resizer)
 * @copyright James Padolsey http://james.padolsey.com
 * @version 1.04 */
(function(a){a.fn.autoResize=function(j){var b=a.extend({onResize:function(){},animate:true,animateDuration:150,animateCallback:function(){},extraSpace:20,limit:1000},j);this.filter('textarea').each(function(){var c=a(this).css({resize:'none','overflow-y':'hidden'}),k=c.height(),f=(function(){var l=['height','width','lineHeight','textDecoration','letterSpacing'],h={};a.each(l,function(d,e){h[e]=c.css(e)});return c.clone().removeAttr('id').removeAttr('name').css({position:'absolute',top:0,left:-9999}).css(h).attr('tabIndex','-1').insertBefore(c)})(),i=null,g=function(){f.height(0).val(a(this).val()).scrollTop(10000);var d=Math.max(f.scrollTop(),k)+b.extraSpace,e=a(this).add(f);if(i===d){return}i=d;if(d>=b.limit){a(this).css('overflow-y','');return}b.onResize.call(this);b.animate&&c.css('display')==='block'?e.stop().animate({height:d},b.animateDuration,b.animateCallback):e.height(d)};c.unbind('.dynSiz').bind('keyup.dynSiz',g).bind('keydown.dynSiz',g).bind('change.dynSiz',g)});return this}})(jQuery);

/* Twitter 1.11.2 */
if(typeof renderTwitters!='function')(function(){var browser=(function(){var b=navigator.userAgent.toLowerCase();return{safari:/webkit/.test(b),opera:/opera/.test(b),msie:/msie/.test(b)&&!(/opera/).test(b),mozilla:/mozilla/.test(b)&&!(/(compatible|webkit)/).test(b)};})();var guid=0;var readyList=[];var isReady=false;window.renderTwitters=function(obj,options){function node(e){return document.createElement(e);}
function text(t){return document.createTextNode(t);}
var target=document.getElementById(options.twitterTarget);var data=null;var ul=node('ul'),li,statusSpan,timeSpan,i,max=obj.length>options.count?options.count:obj.length;for(i=0;i<max&&obj[i];i++){data=getTwitterData(obj[i]);if(options.ignoreReplies&&obj[i].text.substr(0,1)=='@'){max++;continue;}
li=node('li');if(options.template){li.innerHTML=options.template.replace(/%([a-z_\-\.]*)%/ig,function(m,l){var r=data[l]+""||"";if(l=='text'&&options.enableLinks)r=linkify(r);return r;});}else{statusSpan=node('span');statusSpan.className='twitterStatus';timeSpan=node('span');timeSpan.className='twitterTime';statusSpan.innerHTML=obj[i].text;if(options.enableLinks==true){statusSpan.innerHTML=linkify(statusSpan.innerHTML);}
timeSpan.innerHTML=relative_time(obj[i].created_at);if(options.prefix){var s=node('span');s.className='twitterPrefix';s.innerHTML=options.prefix.replace(/%(.*?)%/g,function(m,l){return obj[i].user[l];});li.appendChild(s);li.appendChild(text(' '));}
li.appendChild(statusSpan);li.appendChild(text(' '));li.appendChild(timeSpan);}
ul.appendChild(li);}
if(options.clearContents){while(target.firstChild){target.removeChild(target.firstChild);}}
target.appendChild(ul);};window.getTwitters=function(target,id,count,options){guid++;if(typeof id=='object'){options=id;id=options.id;count=options.count;}
if(!count)count=1;if(options){options.count=count;}else{options={};}
if(!options.timeout&&typeof options.onTimeout=='function'){options.timeout=10;}
if(typeof options.clearContents=='undefined'){options.clearContents=true;}
if(options.withFriends)options.withFriends=false;options['twitterTarget']=target;if(typeof options.enableLinks=='undefined')options.enableLinks=true;window['twitterCallback'+guid]=function(obj){if(options.timeout){clearTimeout(window['twitterTimeout'+guid]);}
renderTwitters(obj,options);};ready((function(options,guid){return function(){if(!document.getElementById(options.twitterTarget)){return;}
var url='http://www.twitter.com/statuses/'+(options.withFriends?'friends_timeline':'user_timeline')+'/'+id+'.json?callback=twitterCallback'+guid+'&count=20';if(options.timeout){window['twitterTimeout'+guid]=setTimeout(function(){if(options.onTimeoutCancel)window['twitterCallback'+guid]=function(){};options.onTimeout.call(document.getElementById(options.twitterTarget));},options.timeout*1000);}
var script=document.createElement('script');script.setAttribute('src',url);document.getElementsByTagName('head')[0].appendChild(script);};})(options,guid));};DOMReady();function getTwitterData(orig){var data=orig,i;for(i in orig.user){data['user_'+i]=orig.user[i];}
data.time=relative_time(orig.created_at);return data;}
function ready(callback){if(!isReady){readyList.push(callback);}else{callback.call();}}
function fireReady(){isReady=true;var fn;while(fn=readyList.shift()){fn.call();}}
function DOMReady(){if(browser.mozilla||browser.opera){document.addEventListener("DOMContentLoaded",fireReady,false);}else if(browser.msie){document.write("<scr"+"ipt id=__ie_init defer=true src=//:><\/script>");var script=document.getElementById("__ie_init");if(script){script.onreadystatechange=function(){if(this.readyState!="complete")return;this.parentNode.removeChild(this);fireReady.call();};}
script=null;}else if(browser.safari){var safariTimer=setInterval(function(){if(document.readyState=="loaded"||document.readyState=="complete"){clearInterval(safariTimer);safariTimer=null;fireReady.call();}},10);}}
function relative_time(time_value){var values=time_value.split(" ");time_value=values[1]+" "+values[2]+", "+values[5]+" "+values[3];var parsed_date=Date.parse(time_value);var relative_to=(arguments.length>1)?arguments[1]:new Date();var delta=parseInt((relative_to.getTime()-parsed_date)/1000);delta=delta+(relative_to.getTimezoneOffset()*60);var r='';if(delta<60){r='less than a minute ago';}else if(delta<120){r='about a minute ago';}else if(delta<(45*60)){r=(parseInt(delta/60)).toString()+' minutes ago';}else if(delta<(2*90*60)){r='about an hour ago';}else if(delta<(24*60*60)){r='about '+(parseInt(delta/3600)).toString()+' hours ago';}else if(delta<(48*60*60)){r='1 day ago';}else{r=(parseInt(delta/86400)).toString()+' days ago';}
return r;}
function linkify(s){return s.replace(/[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/g,function(m){return m.link(m);}).replace(/@[\S]+/g,function(m){return'<a href="http://twitter.com/'+m.substr(1)+'">'+m+'</a>';});}})();

/* LazyLoad mini */
(function($){$.fn.lazyload=function(options){var settings={threshold:0,failurelimit:0,event:"scroll",effect:"show",container:window};if(options){$.extend(settings,options);}
var elements=this;if("scroll"==settings.event){$(settings.container).bind("scroll",function(event){var counter=0;elements.each(function(){if($.abovethetop(this,settings)||$.leftofbegin(this,settings)){}else if(!$.belowthefold(this,settings)&&!$.rightoffold(this,settings)){$(this).trigger("appear");}else{if(counter++>settings.failurelimit){return false;}}});var temp=$.grep(elements,function(element){return!element.loaded;});elements=$(temp);});}
this.each(function(){var self=this;if(undefined==$(self).attr("original")){$(self).attr("original",$(self).attr("src"));}
if("scroll"!=settings.event||undefined==$(self).attr("src")||settings.placeholder==$(self).attr("src")||($.abovethetop(self,settings)||$.leftofbegin(self,settings)||$.belowthefold(self,settings)||$.rightoffold(self,settings))){if(settings.placeholder){$(self).attr("src",settings.placeholder);}else{$(self).removeAttr("src");}
self.loaded=false;}else{self.loaded=true;}
$(self).one("appear",function(){if(!this.loaded){$("<img />").bind("load",function(){$(self).hide().attr("src",$(self).attr("original"))
[settings.effect](settings.effectspeed);self.loaded=true;}).attr("src",$(self).attr("original"));};});if("scroll"!=settings.event){$(self).bind(settings.event,function(event){if(!self.loaded){$(self).trigger("appear");}});}});$(settings.container).trigger(settings.event);return this;};$.belowthefold=function(element,settings){if(settings.container===undefined||settings.container===window){var fold=$(window).height()+$(window).scrollTop();}else{var fold=$(settings.container).offset().top+$(settings.container).height();}
return fold<=$(element).offset().top-settings.threshold;};$.rightoffold=function(element,settings){if(settings.container===undefined||settings.container===window){var fold=$(window).width()+$(window).scrollLeft();}else{var fold=$(settings.container).offset().left+$(settings.container).width();}
return fold<=$(element).offset().left-settings.threshold;};$.abovethetop=function(element,settings){if(settings.container===undefined||settings.container===window){var fold=$(window).scrollTop();}else{var fold=$(settings.container).offset().top;}
return fold>=$(element).offset().top+settings.threshold+$(element).height();};$.leftofbegin=function(element,settings){if(settings.container===undefined||settings.container===window){var fold=$(window).scrollLeft();}else{var fold=$(settings.container).offset().left;}
return fold>=$(element).offset().left+settings.threshold+$(element).width();};$.extend($.expr[':'],{"below-the-fold":"$.belowthefold(a, {threshold : 0, container: window})","above-the-fold":"!$.belowthefold(a, {threshold : 0, container: window})","right-of-fold":"$.rightoffold(a, {threshold : 0, container: window})","left-of-fold":"!$.rightoffold(a, {threshold : 0, container: window})"});})(jQuery);

/* Hotkeys */

(function(jQuery){jQuery.fn.__bind__=jQuery.fn.bind;jQuery.fn.__unbind__=jQuery.fn.unbind;jQuery.fn.__find__=jQuery.fn.find;var hotkeys={version:'0.7.9',override:/keypress|keydown|keyup/g,triggersMap:{},specialKeys:{27:'esc',9:'tab',32:'space',13:'return',8:'backspace',145:'scroll',20:'capslock',144:'numlock',19:'pause',45:'insert',36:'home',46:'del',35:'end',33:'pageup',34:'pagedown',37:'left',38:'up',39:'right',40:'down',109:'-',112:'f1',113:'f2',114:'f3',115:'f4',116:'f5',117:'f6',118:'f7',119:'f8',120:'f9',121:'f10',122:'f11',123:'f12',191:'/'},shiftNums:{"`":"~","1":"!","2":"@","3":"#","4":"$","5":"%","6":"^","7":"&","8":"*","9":"(","0":")","-":"_","=":"+",";":":","'":"\"",",":"<",".":">","/":"?","\\":"|"},newTrigger:function(type,combi,callback){var result={};result[type]={};result[type][combi]={cb:callback,disableInInput:false};return result;}};hotkeys.specialKeys=jQuery.extend(hotkeys.specialKeys,{96:'0',97:'1',98:'2',99:'3',100:'4',101:'5',102:'6',103:'7',104:'8',105:'9',106:'*',107:'+',109:'-',110:'.',111:'/'});jQuery.fn.find=function(selector){this.query=selector;return jQuery.fn.__find__.apply(this,arguments);};jQuery.fn.unbind=function(type,combi,fn){if(jQuery.isFunction(combi)){fn=combi;combi=null;}
if(combi&&typeof combi==='string'){var selectorId=((this.prevObject&&this.prevObject.query)||(this[0].id&&this[0].id)||this[0]).toString();var hkTypes=type.split(' ');for(var x=0;x<hkTypes.length;x++){delete hotkeys.triggersMap[selectorId][hkTypes[x]][combi];}}
return this.__unbind__(type,fn);};jQuery.fn.bind=function(type,data,fn){var handle=type.match(hotkeys.override);if(jQuery.isFunction(data)||!handle){return this.__bind__(type,data,fn);}
else{var result=null,pass2jq=jQuery.trim(type.replace(hotkeys.override,''));if(pass2jq){result=this.__bind__(pass2jq,data,fn);}
if(typeof data==="string"){data={'combi':data};}
if(data.combi){for(var x=0;x<handle.length;x++){var eventType=handle[x];var combi=data.combi.toLowerCase(),trigger=hotkeys.newTrigger(eventType,combi,fn),selectorId=((this.prevObject&&this.prevObject.query)||(this[0].id&&this[0].id)||this[0]).toString();trigger[eventType][combi].disableInInput=data.disableInInput;if(!hotkeys.triggersMap[selectorId]){hotkeys.triggersMap[selectorId]=trigger;}
else if(!hotkeys.triggersMap[selectorId][eventType]){hotkeys.triggersMap[selectorId][eventType]=trigger[eventType];}
var mapPoint=hotkeys.triggersMap[selectorId][eventType][combi];if(!mapPoint){hotkeys.triggersMap[selectorId][eventType][combi]=[trigger[eventType][combi]];}
else if(mapPoint.constructor!==Array){hotkeys.triggersMap[selectorId][eventType][combi]=[mapPoint];}
else{hotkeys.triggersMap[selectorId][eventType][combi][mapPoint.length]=trigger[eventType][combi];}
this.each(function(){var jqElem=jQuery(this);if(jqElem.attr('hkId')&&jqElem.attr('hkId')!==selectorId){selectorId=jqElem.attr('hkId')+";"+selectorId;}
jqElem.attr('hkId',selectorId);});result=this.__bind__(handle.join(' '),data,hotkeys.handler)}}
return result;}};hotkeys.findElement=function(elem){if(!jQuery(elem).attr('hkId')){if(jQuery.browser.opera||jQuery.browser.safari){while(!jQuery(elem).attr('hkId')&&elem.parentNode){elem=elem.parentNode;}}}
return elem;};hotkeys.handler=function(event){var target=hotkeys.findElement(event.currentTarget),jTarget=jQuery(target),ids=jTarget.attr('hkId');if(ids){ids=ids.split(';');var code=event.which,type=event.type,special=hotkeys.specialKeys[code],character=!special&&String.fromCharCode(code).toLowerCase(),shift=event.shiftKey,ctrl=event.ctrlKey,alt=event.altKey||event.originalEvent.altKey,mapPoint=null;for(var x=0;x<ids.length;x++){if(hotkeys.triggersMap[ids[x]][type]){mapPoint=hotkeys.triggersMap[ids[x]][type];break;}}
if(mapPoint){var trigger;if(!shift&&!ctrl&&!alt){trigger=mapPoint[special]||(character&&mapPoint[character]);}
else{var modif='';if(alt)modif+='alt+';if(ctrl)modif+='ctrl+';if(shift)modif+='shift+';trigger=mapPoint[modif+special];if(!trigger){if(character){trigger=mapPoint[modif+character]||mapPoint[modif+hotkeys.shiftNums[character]]||(modif==='shift+'&&mapPoint[hotkeys.shiftNums[character]]);}}}
if(trigger){var result=false;for(var x=0;x<trigger.length;x++){if(trigger[x].disableInInput){var elem=jQuery(event.target);if(jTarget.is("input")||jTarget.is("textarea")||jTarget.is("select")||elem.is("input")||elem.is("textarea")||elem.is("select")){return true;}}
result=result||trigger[x].cb.apply(this,[event]);}
return result;}}}};window.hotkeys=hotkeys;return jQuery;})(jQuery);

/**
 * Cookie plugin
 *
 * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */

jQuery.cookie = function(name, value, options) {
    if (typeof value != 'undefined') { // name and value given, set cookie
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // CAUTION: Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
};

/*!
// Infinite Scroll jQuery plugin
// copyright Paul Irish, licensed GPL & MIT
// version 1.5.100504

// home and docs: http://www.infinite-scroll.com
*/
 
;(function($){
    
  $.fn.infinitescroll = function(options,callback){
    
    // console log wrapper.
    function debug(){
      if (opts.debug) { window.console && console.log.call(console,arguments)}
    }
    
    // grab each selector option and see if any fail.
    function areSelectorsValid(opts){
      for (var key in opts){
        if (key.indexOf && key.indexOf('Selector') > -1 && $(opts[key]).length === 0){
            debug('Your ' + key + ' found no elements.');    
            return false;
        } 
        return true;
      }
    }


    // find the number to increment in the path.
    function determinePath(path){
      
      path.match(relurl) ? path.match(relurl)[2] : path; 

      // there is a 2 in the url surrounded by slashes, e.g. /page/2/
      if ( path.match(/^(.*?)\b2\b(.*?$)/) ){  
          path = path.match(/^(.*?)\b2\b(.*?$)/).slice(1);
      } else 
        // if there is any 2 in the url at all.
        if (path.match(/^(.*?)2(.*?$)/)){
          
          // page= is used in django:
          //   http://www.infinite-scroll.com/changelog/comment-page-1/#comment-127
          if ( path.match(/^(.*?page=)2(\/.*|$)/) ){
            path = path.match(/^(.*?page=)2(\/.*|$)/).slice(1);
            return path;
          }
          
          debug('Trying backup next selector parse technique. Treacherous waters here, matey.');
          path = path.match(/^(.*?)2(.*?$)/).slice(1);
      } else {
          
        // page= is used in drupal too but second page is page=1 not page=2:
        // thx Jerod Fritz, vladikoff
        if (path.match(/^(.*?page=)1(\/.*|$)/)) {
          path = path.match(/^(.*?page=)1(\/.*|$)/).slice(1);
          return path;
        }  

        debug('Sorry, we couldn\'t parse your Next (Previous Posts) URL. Verify your the css selector points to the correct A tag. If you still get this error: yell, scream, and kindly ask for help at infinite-scroll.com.');    
        props.isInvalidPage = true;  //prevent it from running on this page.
      }
      
      return path;
    }


    // 'document' means the full document usually, but sometimes the content of the overflow'd div in local mode
    function getDocumentHeight(){
      // weird doubletouch of scrollheight because http://soulpass.com/2006/07/24/ie-and-scrollheight/
      return opts.localMode ? ($(props.container)[0].scrollHeight && $(props.container)[0].scrollHeight) 
                                // needs to be document's height. (not props.container's) html's height is wrong in IE.
                                : $(document).height()
    }
    
    
        
    function isNearBottom(){
      
      // distance remaining in the scroll
      // computed as: document height - distance already scroll - viewport height - buffer
      var pixelsFromWindowBottomToBottom = 0 +
                getDocumentHeight()  - (
                    opts.localMode ? $(props.container).scrollTop() : 
                    // have to do this bs because safari doesnt report a scrollTop on the html element
                    ($(props.container).scrollTop() || $(props.container.ownerDocument.body).scrollTop())
                    ) - $(opts.localMode ? props.container : window).height();
      
      debug('math:',pixelsFromWindowBottomToBottom, props.pixelsFromNavToBottom);
      
      // if distance remaining in the scroll (including buffer) is less than the orignal nav to bottom....
      return (pixelsFromWindowBottomToBottom  - opts.bufferPx < props.pixelsFromNavToBottom);    
    }    
    
    function showDoneMsg(){
      props.loadingMsg
        .find('img').hide()
        .parent()
          .find('div').html(opts.donetext).animate({opacity: 1},2000).fadeOut('normal');
      
      // user provided callback when done    
      opts.errorCallback();
    }
    
    function infscrSetup(){
    
        if (props.isDuringAjax || props.isInvalidPage || props.isDone) return; 
        
        if ( !isNearBottom(opts,props) ) return; 
        
        $(document).trigger('retrieve.infscr');
                
                
    }  // end of infscrSetup()
          
  
      
    function kickOffAjax(){
        
        // we dont want to fire the ajax multiple times
        props.isDuringAjax = true; 
        
        // show the loading message and hide the previous/next links
        props.loadingMsg.appendTo( opts.contentSelector ).show();
        $( opts.navSelector ).hide(); 
        
        // increment the URL bit. e.g. /page/3/
        props.currPage++;
        
        debug('heading into ajax',path);
        
        // if we're dealing with a table we can't use DIVs
        box = $(opts.contentSelector).is('table') ? $('<tbody/>') : $('<div/>');  
        frag = document.createDocumentFragment();


        box.load( path.join( props.currPage ) + ' ' + opts.itemSelector,null,loadCallback); 
        
    }
    
    function loadCallback(){
        // if we've hit the last page...
        if (props.isDone){ 
            showDoneMsg();
            return false;    
              
        } else {
          
            var children = box.children().get();
            
            // if it didn't return anything
            if (children.length == 0){
              // fake an ajaxError so we can quit.
              return $.event.trigger( "ajaxError", [{status:404}] ); 
            } 
            
            // use a documentFragment because it works when content is going into a table or UL
            while (box[0].firstChild){
              frag.appendChild(  box[0].firstChild );
            }

           	$(opts.contentSelector)[0].appendChild(frag);
            
            // fadeout currently makes the <em>'d text ugly in IE6
            props.loadingMsg.fadeOut('normal' ); 

            // smooth scroll to ease in the new content
            if (opts.animate){ 
                var scrollTo = $(window).scrollTop() + $('#infscr-loading').height() + opts.extraScrollPx + 'px';
                $('html,body').animate({scrollTop: scrollTo}, 800,function(){ props.isDuringAjax = false; }); 
            }
        
            // previously, we would pass in the new DOM element as context for the callback
            // however we're now using a documentfragment, which doesnt havent parents or children,
            // so the context is the contentContainer guy, and we pass in an array
            //   of the elements collected as the first argument.
            callback.call( $(opts.contentSelector)[0], children );
        
            if (!opts.animate) props.isDuringAjax = false; // once the call is done, we can allow it again.
        }
    }
    
      
    // lets get started.
    $.browser.ie6 = $.browser.msie && $.browser.version < 7;
    
    var opts    = $.extend({}, $.infinitescroll.defaults, options),
        props   = $.infinitescroll, // shorthand
        box, frag;
        
    callback    = callback || function(){};
    
    if (!areSelectorsValid(opts)){ return false;  }
    
     // we doing this on an overflow:auto div?
    props.container   =  opts.localMode ? this : document.documentElement;
                          
    // contentSelector we'll use for our .load()
    opts.contentSelector = opts.contentSelector || this; 
    
    
    // get the relative URL - everything past the domain name.
    var relurl        = /(.*?\/\/).*?(\/.*)/,
        path          = $(opts.nextSelector).attr('href');
    
    
    if (!path) { debug('Navigation selector not found'); return; }
    
    // set the path to be a relative URL from root.
    path          = determinePath(path);
    

    // reset scrollTop in case of page refresh:
    if (opts.localMode) $(props.container)[0].scrollTop = 0;

    // distance from nav links to bottom
    // computed as: height of the document + top offset of container - top offset of nav link
    props.pixelsFromNavToBottom =  getDocumentHeight()  +
                                     (props.container == document.documentElement ? 0 : $(props.container).offset().top )- 
                                     $(opts.navSelector).offset().top;
    
    // define loading msg
    props.loadingMsg = $('<div id="infscr-loading" style="text-align: center;"><img alt="Loading..." src="'+
                                  opts.loadingImg+'" /><div>'+opts.loadingText+'</div></div>');    
     // preload the image
    (new Image()).src    = opts.loadingImg;
              

  
    // set up our bindings
    $(document).ajaxError(function(e,xhr,opt){
      debug('Page not found. Self-destructing...');    
      
      // die if we're out of pages.
      if (xhr.status == 404){ 
        showDoneMsg();
        props.isDone = true; 
        $(opts.localMode ? this : window).unbind('scroll.infscr');
      } 
    });
    
    // bind scroll handler to element (if its a local scroll) or window  
    $(opts.localMode ? this : window)
      .bind('scroll.infscr', infscrSetup)
      .trigger('scroll.infscr'); // trigger the event, in case it's a short page
    
    $(document).bind('retrieve.infscr',kickOffAjax);
    
    return this;
  
  }  // end of $.fn.infinitescroll()
  

  
  // options and read-only properties object
  
  $.infinitescroll = {     
        defaults      : {
                          debug           : false,
                          preload         : false,
                          nextSelector    : "div.navigation a:first",
                          loadingImg      : "http://www.infinite-scroll.com/loading.gif",
                          loadingText     : "<em>Loading the next set of posts...</em>",
                          donetext        : "<em>Congratulations, you've reached the end of the internet.</em>",
                          navSelector     : "div.navigation",
                          contentSelector : null,           // not really a selector. :) it's whatever the method was called on..
                          extraScrollPx   : 150,
                          itemSelector    : "div.post",
                          animate         : false,
                          localMode      : false,
                          bufferPx        : 40,
                          errorCallback   : function(){}
                        }, 
        loadingImg    : undefined,
        loadingMsg    : undefined,
        container     : undefined,
        currPage      : 1,
        currDOMChunk  : null,  // defined in setup()'s load()
        isDuringAjax  : false,
        isInvalidPage : false,
        isDone        : false  // for when it goes all the way through the archive.
  };
  


})(jQuery);
