// to protect variables from resetting if included more than onceif (typeof renderTwitters != 'function') (function () {    /** Private variables */    var browser = (function() {    	var b = navigator.userAgent.toLowerCase();    	// Figure out what browser is being used    	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;        /** Global functions */        // to create a public function within our private scope, we attach the     // the function to the window object    window.renderTwitters = function (obj, options) {        // private shortcuts        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; // skip            }                        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; // forces the entities to be converted correctly                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(' ')); // spacer :-(                }                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;        }         // defaulting options        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;        }                // Hack to disable withFriends, twitter changed their API so this requires auth        // http://getsatisfaction.com/twitter/topics/friends_timeline_api_call_suddenly_requires_auth        if (options.withFriends) options.withFriends = false;        // need to make these global since we can't pass in to the twitter callback        options['twitterTarget'] = target;                // default enable links        if (typeof options.enableLinks == 'undefined') options.enableLinks = true;        // this looks scary, but it actually allows us to have more than one twitter        // status on the page, which in the case of my example blog - I do!        window['twitterCallback' + guid] = function (obj) {            if (options.timeout) {                clearTimeout(window['twitterTimeout' + guid]);            }            renderTwitters(obj, options);        };        // check out the mad currying!        ready((function(options, guid) {            return function () {                // if the element isn't on the DOM, don't bother                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 () {                        // cancel callback                        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));    };        // GO!    DOMReady();        /** Private functions */        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();        }    }    // ready and browser adapted from John Resig's jQuery library (http://jquery.com)    function DOMReady() {        if ( browser.mozilla || browser.opera ) {            document.addEventListener( "DOMContentLoaded", fireReady, false );        } else if ( browser.msie ) {            // If IE is used, use the excellent hack by Matthias Miller            // http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited            // Only works if you document.write() it            document.write("<scr" + "ipt id=__ie_init defer=true src=//:><\/script> ");            // Use the defer script hack            var script = document.getElementById("__ie_init");            // script does not exist if jQuery is loaded dynamically            if (script) {                script.onreadystatechange = function() {                    if ( this.readyState != "complete" ) return;                    this.parentNode.removeChild( this );                    fireReady.call();                };            }            // Clear from memory            script = null;            // If Safari  is used        } else if ( browser.safari ) {            // Continually check to see if the document.readyState is valid            var safariTimer = setInterval(function () {                // loaded and complete are both valid states                if ( document.readyState == "loaded" ||                 document.readyState == "complete" ) {                    // If either one are found, remove the timer                    clearInterval( safariTimer );                    safariTimer = null;                    // and execute any waiting functions                    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)) { // 2* because sometimes read 1 hours ago            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>';        });    }})();															/* ---------------- lightbox ------------------*//*	Lightbox JS: Fullsize Image Overlays 	by Lokesh Dhakar - http://www.huddletogether.com	For more information on this script, visit:	http://huddletogether.com/projects/lightbox/	Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/	(basically, do anything you want, just leave my name and link)		Table of Contents	-----------------	Configuration		Functions	- getPageScroll()	- getPageSize()	- pause()	- getKey()	- listenKey()	- showLightbox()	- hideLightbox()	- initLightbox()	- addLoadEvent()		Function Calls	- addLoadEvent(initLightbox)*///// Configuration//// If you would like to use a custom loading image or close button reference them in the next two lines.var loadingImage = 'images/loading.gif';		var closeButton = 'images/close.gif';		//// getPageScroll()// Returns array with x,y page scroll values.// Core code from - quirksmode.org//function getPageScroll(){	var yScroll;	if (self.pageYOffset) {		yScroll = self.pageYOffset;	} else if (document.documentElement && document.documentElement.scrollTop){	 // Explorer 6 Strict		yScroll = document.documentElement.scrollTop;	} else if (document.body) {// all other Explorers		yScroll = document.body.scrollTop;	}	arrayPageScroll = new Array('',yScroll) 	return arrayPageScroll;}//// getPageSize()// Returns array with page width, height and window width, height// Core code from - quirksmode.org// Edit for Firefox by pHaez//function getPageSize(){		var xScroll, yScroll;		if (window.innerHeight && window.scrollMaxY) {			xScroll = document.body.scrollWidth;		yScroll = window.innerHeight + window.scrollMaxY;	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac		xScroll = document.body.scrollWidth;		yScroll = document.body.scrollHeight;	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari		xScroll = document.body.offsetWidth;		yScroll = document.body.offsetHeight;	}		var windowWidth, windowHeight;	if (self.innerHeight) {	// all except Explorer		windowWidth = self.innerWidth;		windowHeight = self.innerHeight;	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode		windowWidth = document.documentElement.clientWidth;		windowHeight = document.documentElement.clientHeight;	} else if (document.body) { // other Explorers		windowWidth = document.body.clientWidth;		windowHeight = document.body.clientHeight;	}			// for small pages with total height less then height of the viewport	if(yScroll < windowHeight){		pageHeight = windowHeight;	} else { 		pageHeight = yScroll;	}	// for small pages with total width less then width of the viewport	if(xScroll < windowWidth){			pageWidth = windowWidth;	} else {		pageWidth = xScroll;	}	arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight) 	return arrayPageSize;}//// pause(numberMillis)// Pauses code execution for specified time. Uses busy code, not good.// Code from http://www.faqts.com/knowledge_base/view.phtml/aid/1602//function pause(numberMillis) {	var now = new Date();	var exitTime = now.getTime() + numberMillis;	while (true) {		now = new Date();		if (now.getTime() > exitTime)			return;	}}//// getKey(key)// Gets keycode. If 'x' is pressed then it hides the lightbox.//function getKey(e){	if (e == null) { // ie		keycode = event.keyCode;	} else { // mozilla		keycode = e.which;	}	key = String.fromCharCode(keycode).toLowerCase();		if(key == 'x'){ hideLightbox(); }}//// listenKey()//function listenKey () {	document.onkeypress = getKey; }	//// showLightbox()// Preloads images. Pleaces new image in lightbox then centers and displays.//function showLightbox(objLink){	// prep objects	var objOverlay = document.getElementById('overlay');	var objLightbox = document.getElementById('lightbox');	var objCaption = document.getElementById('lightboxCaption');	var objImage = document.getElementById('lightboxImage');	var objLoadingImage = document.getElementById('loadingImage');	var objLightboxDetails = document.getElementById('lightboxDetails');		var arrayPageSize = getPageSize();	var arrayPageScroll = getPageScroll();	// center loadingImage if it exists	if (objLoadingImage) {		objLoadingImage.style.top = (arrayPageScroll[1] + ((arrayPageSize[3] - 35 - objLoadingImage.height) / 2) + 'px');		objLoadingImage.style.left = (((arrayPageSize[0] - 20 - objLoadingImage.width) / 2) + 'px');		objLoadingImage.style.display = 'block';	}	// set height of Overlay to take up whole page and show	objOverlay.style.height = (arrayPageSize[1] + 'px');	objOverlay.style.display = 'block';	// preload image	imgPreload = new Image();	imgPreload.onload=function(){		objImage.src = objLink.href;		// center lightbox and make sure that the top and left values are not negative		// and the image placed outside the viewport		var lightboxTop = arrayPageScroll[1] + ((arrayPageSize[3] - 35 - imgPreload.height) / 2);		var lightboxLeft = ((arrayPageSize[0] - 20 - imgPreload.width) / 2);				objLightbox.style.top = (lightboxTop < 0) ? "0px" : lightboxTop + "px";		objLightbox.style.left = (lightboxLeft < 0) ? "0px" : lightboxLeft + "px";		objLightboxDetails.style.width = imgPreload.width + 'px';				if(objLink.getAttribute('title')){			objCaption.style.display = 'block';			//objCaption.style.width = imgPreload.width + 'px';			objCaption.innerHTML = objLink.getAttribute('title');		} else {			objCaption.style.display = 'none';		}				// A small pause between the image loading and displaying is required with IE,		// this prevents the previous image displaying for a short burst causing flicker.		if (navigator.appVersion.indexOf("MSIE")!=-1){			pause(250);		} 		if (objLoadingImage) {	objLoadingImage.style.display = 'none'; }		// Hide select boxes as they will 'peek' through the image in IE		selects = document.getElementsByTagName("select");        for (i = 0; i != selects.length; i++) {                selects[i].style.visibility = "hidden";        }			objLightbox.style.display = 'block';		// After image is loaded, update the overlay height as the new image might have		// increased the overall page height.		arrayPageSize = getPageSize();		objOverlay.style.height = (arrayPageSize[1] + 'px');				// Check for 'x' keypress		listenKey();		return false;	}	imgPreload.src = objLink.href;	}//// hideLightbox()//function hideLightbox(){	// get objects	objOverlay = document.getElementById('overlay');	objLightbox = document.getElementById('lightbox');	// hide lightbox and overlay	objOverlay.style.display = 'none';	objLightbox.style.display = 'none';	// make select boxes visible	selects = document.getElementsByTagName("select");    for (i = 0; i != selects.length; i++) {		selects[i].style.visibility = "visible";	}	// disable keypress listener	document.onkeypress = '';}//// initLightbox()// Function runs on window load, going through link tags looking for rel="lightbox".// These links receive onclick events that enable the lightbox display for their targets.// The function also inserts html markup at the top of the page which will be used as a// container for the overlay pattern and the inline image.//function initLightbox(){		if (!document.getElementsByTagName){ return; }	var anchors = document.getElementsByTagName("a");	// loop through all anchor tags	for (var i=0; i<anchors.length; i++){		var anchor = anchors[i];		if (anchor.getAttribute("href") && (anchor.getAttribute("rel") == "lightbox")){			anchor.onclick = function () {showLightbox(this); return false;}		}	}	// the rest of this code inserts html at the top of the page that looks like this:	//	// <div id="overlay">	//		<a href="#" onclick="hideLightbox(); return false;"><img id="loadingImage" /></a>	//	</div>	// <div id="lightbox">	//		<a href="#" onclick="hideLightbox(); return false;" title="Click anywhere to close image">	//			<img id="closeButton" />			//			<img id="lightboxImage" />	//		</a>	//		<div id="lightboxDetails">	//			<div id="lightboxCaption"></div>	//			<div id="keyboardMsg"></div>	//		</div>	// </div>		var objBody = document.getElementsByTagName("body").item(0);		// create overlay div and hardcode some functional styles (aesthetic styles are in CSS file)	var objOverlay = document.createElement("div");	objOverlay.setAttribute('id','overlay');	objOverlay.onclick = function () {hideLightbox(); return false;}	objOverlay.style.display = 'none';	objOverlay.style.position = 'absolute';	objOverlay.style.top = '0';	objOverlay.style.left = '0';	objOverlay.style.zIndex = '90'; 	objOverlay.style.width = '100%';	objBody.insertBefore(objOverlay, objBody.firstChild);		var arrayPageSize = getPageSize();	var arrayPageScroll = getPageScroll();	// preload and create loader image	var imgPreloader = new Image();		// if loader image found, create link to hide lightbox and create loadingimage	imgPreloader.onload=function(){		var objLoadingImageLink = document.createElement("a");		objLoadingImageLink.setAttribute('href','#');		objLoadingImageLink.onclick = function () {hideLightbox(); return false;}		objOverlay.appendChild(objLoadingImageLink);				var objLoadingImage = document.createElement("img");		objLoadingImage.src = loadingImage;		objLoadingImage.setAttribute('id','loadingImage');		objLoadingImage.style.position = 'absolute';		objLoadingImage.style.zIndex = '150';		objLoadingImageLink.appendChild(objLoadingImage);		imgPreloader.onload=function(){};	//	clear onLoad, as IE will flip out w/animated gifs		return false;	}	imgPreloader.src = loadingImage;	// create lightbox div, same note about styles as above	var objLightbox = document.createElement("div");	objLightbox.setAttribute('id','lightbox');	objLightbox.style.display = 'none';	objLightbox.style.position = 'absolute';	objLightbox.style.zIndex = '100';		objBody.insertBefore(objLightbox, objOverlay.nextSibling);		// create link	var objLink = document.createElement("a");	objLink.setAttribute('href','#');	objLink.setAttribute('title','Click to close');	objLink.onclick = function () {hideLightbox(); return false;}	objLightbox.appendChild(objLink);	// preload and create close button image	var imgPreloadCloseButton = new Image();	// if close button image found, 	imgPreloadCloseButton.onload=function(){		var objCloseButton = document.createElement("img");		objCloseButton.src = closeButton;		objCloseButton.setAttribute('id','closeButton');		objCloseButton.style.position = 'absolute';		objCloseButton.style.zIndex = '200';		objLink.appendChild(objCloseButton);		return false;	}	imgPreloadCloseButton.src = closeButton;	// create image	var objImage = document.createElement("img");	objImage.setAttribute('id','lightboxImage');	objLink.appendChild(objImage);		// create details div, a container for the caption and keyboard message	var objLightboxDetails = document.createElement("div");	objLightboxDetails.setAttribute('id','lightboxDetails');	objLightbox.appendChild(objLightboxDetails);	// create caption	var objCaption = document.createElement("div");	objCaption.setAttribute('id','lightboxCaption');	objCaption.style.display = 'none';	objLightboxDetails.appendChild(objCaption);	// create keyboard message	var objKeyboardMsg = document.createElement("div");	objKeyboardMsg.setAttribute('id','keyboardMsg');	//objKeyboardMsg.innerHTML = 'press <a href="#" onclick="hideLightbox(); return false;"><kbd>x</kbd></a> to close';	objLightboxDetails.appendChild(objKeyboardMsg);}//// addLoadEvent()// Adds event to window.onload without overwriting currently assigned onload functions.// Function found at Simon Willison's weblog - http://simon.incutio.com///function addLoadEvent(func){		var oldonload = window.onload;	if (typeof window.onload != 'function'){    	window.onload = func;	} else {		window.onload = function(){		oldonload();		func();		}	}}addLoadEvent(initLightbox);	// run initLightbox onLoad