/*
	This file assembled, compressed and cache-managed by
	File Packer, v1.1 (c) 2005 bivia
	
	Each file contained herein is copyright its respective owner.
	By assembling these files, bivia has optimized for delivery
	but has not otherwise edited or changed the files, and bivia
	makes no claims as to their suitability or compatibility
	
	Files included in this package may be accessed directly in this
	directory with the following names:
		_bv_config.js
		_bv_utilities.js
		bvIE_activateFlash.js
		bvDimForm.js
		bvCountForm.js
		bvFormOther.js
		bvFormActive.js
		ffwTopNav.js
		bvPrintables.js
		bvAddABlock.js
		bvSlideShow.js
		ffwMediaplex.js
		ffwComments.js
		ffwCallFestival.js
		bvTabber.js
		bvCollapse.js
		ffwFloatNav.js
		bvStickyWicket.js
		bvMiniPage.js
		bvAttachValidWindows.js
		ffwListGenreFilter.js
		ffwTableScroller.js
		ffwListScroller.js
		bvScrollBars.js
		ffwFlagScroller.js
		ffwVoter.js
		ffwMiniMap.js
		ffwMiniCal.js
		ffwPredict.js
		ffwProfileEdit.js
		~site_init.js
*/

/* (1) packer:START(_bv_config.js) ... */


var Conf = {
	debug : false,
	js_path : '/fileadmin/js/',
	src_img_clear : '/fileadmin/js/bv/clear.gif',
	src_js_domready : '/fileadmin/js/bv/domready.js',
	src_htc_domready : '/fileadmin/js/bv/domready.htc',
	ajax_request_timeout : 20,
	ajax_response_timeout : 45,
	de_activate__attach_valid_windows : {
		prefix : 'bv',
		allowedTypes : 'newwin',
		viewerLocation : ''
	}
};

/* ... /packer:END(_bv_config.js) */
/* (2) packer:START(_bv_utilities.js) ... */

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
 * Bivia Utilities, v2.1.1
 * (c) 2005 bivia.com
 * created by Ben Curtis of bivia.com, February 22 2005
 * objectified, December 22, 2005
 *   - event object largely inspired/ported from Dean Edwards's events
 *     http://dean.edwards.name/my/events.js
 * enhanced domready event handling, September 20, 2006
 *   - ref: http://dean.edwards.name/weblog/2006/06/again/
 *
 * $Id$
 *~~~~*/


// set defaults for this file, which may have already been configured
if (!Conf) var Conf = {};
Conf.debug = Conf.debug || false; // note: setting to "true" here cannot be overridden by a "false" somewhere else
Conf.js_path = Conf.js_path || '/js/';
Conf.src_img_clear = Conf.src_img_clear || '/js/bv/clear.gif';
Conf.ajax_request_timeout = Conf.ajax_request_timeout || 30;
Conf.ajax_response_timeout = Conf.ajax_response_timeout || 30;



var bv = {
	tickBase : new Date(),
	initialized : false,
	init : function () {
		bv.initialized = new Date();
		bv.debug.init();
		bv.css.init();
		bv.dom.init();
		bv.ajax.init();
	}, // END init

	bv_guid : 1,
	guid_counter : 2, // 0 is reserved, bv.bv_guid == 1
	getNewGuid : function() { return bv.guid_counter++; },
	getId : function (el,base) {
		if (!el.id) {
			var b = (base) ? base : "bv";
			el.id = b + bv.getNewGuid();
		}
		return el.id;
	},
	
	debug : {
		initialized : false,
		init : function () {
			bv.debug.initialized = new Date();
			if (Conf['debug']) {
				bv.event.add(window, 'domready', function () { bv.debug.msg('domready','debug'); });
				bv.event.add(window, 'domready', function () { bv.debug.msg('domready (prioritized)','debug'); }, "priority");
				bv.event.add(window, 'load', function () { bv.debug.msg('page loaded','debug'); });
				bv.event.add(window, 'load', bv.debug.make);
				bv.debug.win = window.open('', '_blank');
				bv.debug.msg('init','debug');
			} else {
				bv.debug.msg = function () { };
			}
			if (!window.d) window.d = bv.debug.msg;
		},
		cnt : 1,
		msgList : { debug : ['script-parse [event #0 :: msg @ 0s]'] },
		msgWait : null,
		msg : function(Msg,Cat) {
			if (bv.debug.msgWait) clearTimeout(bv.debug.msgWait);
			if (!Cat) Cat = 'unspecified';
			if (!bv.debug.msgList[Cat])
				bv.debug.msgList[Cat] = new Array();
			var Now = new Date();
			bv.debug.msgList[Cat].push(Msg +' [event #'+ bv.debug.cnt++ +' :: msg @ '+ ((Now.getTime() - bv.tickBase.getTime()) /1000) +'s]');
			bv.debug.msgWait = setTimeout('bv.debug.make();', 1000);
		}, // END debug.msg
		make : function() {
			if (!bv.dom.initialized) return;
			var Alert = '<ul>';
			for (var Cat in bv.debug.msgList) {
				if (typeof Cat != "string" || (typeof bv.debug.msgList[Cat] != "object" || !bv.debug.msgList[Cat].length)) continue;
				Alert += '<li>'+ Cat +'<ol>';
				for (var xx=0; xx<bv.debug.msgList[Cat].length; xx++)
					Alert += '<li>'+ bv.debug.msgList[Cat][xx] +'</li>';
				Alert += '</ol></li>';
			}
			var Now = new Date();
			Alert += '</ul><br />-- end tick count: '+ ((Now.getTime() - bv.tickBase.getTime()) /1000) +'s --';
			if (bv.debug.win) {
				bv.debug.win.document.open();
				bv.debug.win.document.write(Alert);
				bv.debug.win.document.close();
			}
		} // END debug.make
	},

	event : {
		add : function(el, evt, fn, prioritize) {
			if (evt == 'domready') el = window;
			if (typeof el == "string") el = document.getElementById(el);
			if (!el) return;
			if (evt == 'domready') {
				if (prioritize) bv.dom.readyList.unshift(fn);
				else bv.dom.readyList.push(fn);
				if (bv.dom.initialized)
					bv.dom.ready('event.add'); // do not call function directly, because you want it executed in order
			} else { // start Dean Edwards-port code
				if (!fn.bv_guid) fn.bv_guid = bv.getNewGuid();
				if (!el.bv_events) el.bv_events = {};
				if (!el.bv_events[evt]) {
					el.bv_events[evt] = {};
					if (el["on" + evt]) { // store any previously-assigned handlers
						el.bv_events[evt][0] = el["on" + evt];
					}
				}
				el.bv_events[evt][fn.bv_guid] = fn;
				el["on" + evt] = bv.event.handle;
			}
		}, // END event.add
		remove : function(el, evt, fn) {
			if (el.events && el.bv_events[evt] && fn.bv_guid)
				delete el.bv_events[evt][fn.bv_guid];
		}, // END event.remove
		handle : function(e) {
			var Rtn = true;
			e = e || bv.event.fixEvent(window.event);
			for (var ii in this.bv_events[e.type]) {
				this.bv_handleEvent = this.bv_events[e.type][ii];
				if (this.bv_handleEvent(e) === false)
					Rtn = false;
			}
			return Rtn;
		}, // END event.handle
		fixEvent : function (event) {
			if (!event) { // error thrown on unload?
				event = { type : 'unknown' };
			}
			// add W3C standard event methods
			event.preventDefault = bv.event.fixEvent_preventDefault;
			event.stopPropagation = bv.event.fixEvent_stopPropagation;
			return event;
		},
		fixEvent_preventDefault : function() {
			this.returnValue = false;
		},
		fixEvent_stopPropagation : function() {
			this.cancelBubble = true;
		}

	}, // END event

	dom : {
		initialized : false,
		init : function () {
			bv.dom.initialized = false; // not initialized until dom.ready is run
			if (document.addEventListener) {
				document.addEventListener('DOMContentLoaded', bv.dom.ready, false); // Gecko-based browsers, Opera 9+
			} else {
				/*@cc_on @*/
				/*@if (@_win32)
				document.write('<scr'+'ipt id="__ie_onload" defer="defer" src="javascript:false;"><\/script>');
				var script = document.getElementById("__ie_onload");
				script.onreadystatechange = function() {
					if (this.readyState == "complete") {
						bv.dom.ready(); // call the domready handler
					}
				};
				/*@end @*/
			}

			if (/WebKit/i.test(navigator.userAgent)) { // Safari
				var _timer = setInterval(function() {
					if (/loaded|complete/.test(document.readyState)) {
						bv.dom.ready(); // call the onload handler
					}
				}, 10);
				bv.event.add(window, 'domready', function () { clearInterval(_timer); });
			}

			bv.event.add(window, 'load', bv.dom.ready); // fail-safe fire onload, in case the above hangs
			bv.event.add(window, 'unload', function(){ window.bv = null; } ); // clean up after yourself
			if (!document.documentElement) document.documentElement = document.getElementsByTagName('html')[0];
			bv.css.addClass(document.documentElement, 'domCapable domLoading');
		}, // END dom.init

		readyList : [
			function () {
				bv.dom.initialized = new Date();
				if (bv.css && bv.css.addClass)
					bv.css.addClass(document.documentElement, 'domReady');
				if (bv.css && bv.css.removeClass)
					bv.css.removeClass(document.documentElement, 'domLoading');
			}
		],
//		readyDeferList : [],
		ready : function() {
			while (this.E = bv.dom.readyList.shift()) // deletes as it goes
				this.E(); // note: may safely support multiple, simultaneous firings
//			while (this.E = bv.dom.readyDeferList.shift()) this.E(); 
		}, // END dom.ready

		getElementsByClassName : function (el,TagsIn,Class) {
			var rtn = [];
			if (! el || ! el.getElementsByTagName) return rtn;
			var It = "\\b"+Class+"\\b";
			var Tags = TagsIn.split(",");
			for (var xx=0; xx<Tags.length; xx++) {
				var Els = (el.getElementsByTagName) ? el.getElementsByTagName(Tags[xx]) : el.all;
				for (var ii=0; ii<Els.length; ii++) {
					if (Els[ii].className.match(It))
						rtn[rtn.length] = Els[ii];
				}
			}
			return rtn;
		},
		getChildNodesOfType : function (el,TagsIn) {
			var rtn = [];
			TagsIn = TagsIn.toUpperCase();
			for (var xx=0; xx<el.childNodes.length; xx++)
				if ((","+TagsIn+",").indexOf(","+ el.childNodes[xx].nodeName +",") != -1)
					rtn[rtn.length] = el.childNodes[xx];
			return rtn;
		}
	}, // END dom
	
	css : {
		initialized : false,
		init : function () {
			bv.css.initialized = new Date();
			bv.css.makeRuleSheet();
		},
		
		ruleSheet : null,
		makeRuleSheet : function () {
// deactivate until Safari bug is squashed
return;
/*
			var ruleSheet = document.createElement('style');
			ruleSheet.type = 'text/css';
			document.getElementsByTagName('head')[0].appendChild(ruleSheet);
			bv.css.ruleSheet = document.styleSheets[document.styleSheets.length -1] || ruleSheet;
*/
			bv.css.ruleSheet = document.styleSheets[document.styleSheets.length -1];
			if (!bv.css.ruleSheet.rules) // make Mozilla conform to IE and Safari
				bv.css.ruleSheet.rules = bv.css.ruleSheet.cssRules;
		},
		insertRule : function (selector, declaration) {
// deactivate until Safari bug is squashed
return;
			var index = bv.css.ruleSheet.rules.length;
			if (bv.css.ruleSheet.insertRule)
				bv.css.ruleSheet.insertRule(selector +'{'+ declaration +'}', index);
			else bv.css.ruleSheet.addRule(selector, declaration,index);
/* 
	annoying Safari bug; seems it won't render a new style rule to the page 
	unless you change one of its properties first
*/
			bv.css.ruleSheet.rules[index].style.orphans = 'inherit';
			return index;
		}, // END css.insertRule
		deleteRule : function (selector) {
// deactivate until Safari bug is squashed
return;
			for (var xx=0; xx<bv.css.ruleSheet.rules.length; xx++)
				if (bv.css.ruleSheet.bv_rules[xx].selectorText.toLowerCase() == selector)
					bv.css.deleteRuleByIndex(xx);
		}, // END css.deleteRule
		deleteRuleByIndex : function (index) {
// deactivate until Safari bug is squashed
return;
			if (bv.css.ruleSheet.deleteRule)
				bv.css.ruleSheet.deleteRule(index);
			else bv.css.ruleSheet.removeRule(index);
		}, // END css.deleteRuleByIndex

		addClass : function (el,nm) {
			var regex = new RegExp("\\b"+nm+"\\b");
			if (!el.className.match(regex))
				el.className = bv.string.trim(el.className +" "+ nm, true);
		}, // END style.addClass
		removeClass : function (el,nm) {
			var regex = new RegExp("\\b"+nm+"\\b", "g");
			el.className = bv.string.trim(el.className.replace(regex, ''), true);
		}, // END css.removeClass

		getValue : function (el,prop) {
			if (document.defaultView && document.defaultView.getComputedStyle) {
				return document.defaultView.getComputedStyle(el,'').getPropertyValue(prop);
			} else {
				var propCased = bv.string.camelCase(prop);
				if (el.currentStyle) {
					return el.currentStyle[propCased];
				} else return el.style[propCased];
			}
		},
		getOffset : function (el,base) { // no base = offset from parent
			// IE will treat the offset as to the parentNode; Moz refers all to the body element
			// so if we're not finding an offset relative to a base, take a shortcut for IE:
			if (!base && el.offsetParent == el.parentNode) {
				return { top : el.offsetTop, left : el.offsetLeft };
			} else if (!base) base = el.parentNode;
//			var elOffset   = bv.css.getOffsetFromRoot(el);
//			var baseOffset = bv.css.getOffsetFromRoot(base);
			return {
				top  : el.offsetTop  - base.offsetTop,
				left : el.offsetLeft - base.offsetLeft
			};
		},
		getOffsetFromRoot : function (el) {
			var offset = { top : 0, left : 0};
			while (el) {
				offset.top  += el.offsetTop;
				offset.left += el.offsetLeft;
				el = el.offsetParent;
			}
			return offset;
		},
		getWindowSize : function () {
			if (typeof(window.innerWidth) == 'number') {
				return {
					w : window.innerWidth,
					h : window.innerHeight
				};
			} else {
				if (window.document.documentElement && window.document.documentElement.clientWidth) {
					return {
						w : window.document.documentElement.clientWidth,
						h : window.document.documentElement.clientHeight
					};
				} else {
					if (window.document.body && window.document.body.clientWidth) {
						return {
							w : window.document.body.clientWidth,
							h : window.document.body.clientHeight
						};
//							w : window.document.document.body.clientWidth,
//							h : window.document.document.body.clientHeight
					}
				}
			}
			return false;
		},
		opacity : {
			get : function (el) {
				var Style = null;
				var Alpha = 1;
				if (typeof el.bv_opacity == 'number')
					Alpha = el.bv_opacity;
				else if (Style = bv.css.getValue(el, 'opacity'))
					Alpha = parseFloat(Style);
				else if (Style = bv.css.getValue(el, '-moz-opacity'))
					Alpha = parseFloat(Style);
				else if (el.filters && el.filters.length && el.filters.alpha)
					Alpha = parseFloat(el.filters.alpha.opacity) /100;
				if (Alpha >= 0.99999) Alpha = 1; // unmask masked values
				if (Alpha <= 0.00001) Alpha = 0; // unmask masked values
				return Alpha;
			},
			set : function (el,Alpha) {
				if (Alpha > 0.99) Alpha = 0.99999; // mask incoming 1 to prevent fully-visible flickering transitions
				if (Alpha < 0.01) Alpha = 0.00001; // mask incoming 0 to prevent fully-invisible flickering transitions
				el.bv_opacity = parseInt(Alpha *100000) /100000; // helps speed getter; needed for Safari in some cases
				el.style.opacity = el.bv_opacity;
				el.style.MozOpacity = el.bv_opacity;
				el.style.KHTMLOpacity = el.bv_opacity;
				if (el.filters && !el.filters.alpha) // if this hasn't been declared yet as a style, it's not a filter object
					el.style.filter += ' alpha(opacity='+ (el.bv_opacity *100) +')'; // append to prevent overwriting previous filters
				if (el.filters && el.filters.length && el.filters.alpha)
					el.filters.alpha.opacity = el.bv_opacity *100;
				if (el.bv_opacity >= 0.99999) el.bv_opacity = 1; // unmask masked values
				if (el.bv_opacity <= 0.00001) el.bv_opacity = 0; // unmask masked values
				return el.bv_opacity;
			},
			adjustBy : function (el,AlphaDelta) {
				if ((""+AlphaDelta).charAt((""+AlphaDelta).length -1) == "%") {
					var Pct = parseFloat(AlphaDelta) /100;
					AlphaDelta = (Pct >= 0) ? // round up/down away from zero
						Math.ceil((1 - bv.css.opacity.get(el)) * Pct) :
						Math.floor(bv.css.opacity.get(el) * Pct);
				}
				return bv.css.opacity.set(el, bv.css.opacity.get(el) + parseFloat(AlphaDelta));
			}
		}
	}, // END css
	
	ajax : {
		isAvailable : false,
		index : 1,
		calls : [],
		groundState : [],
		historian : null,
		historicRecord : {},
		hashWas : self.location.hash,
		lastToGo : { id:null, at:new Date() },
		
		init : function () {
			if (bv.ajax.initIo()) {
				bv.ajax.isAvailable = true;
//				bv.event.add(window, 'domready', bv.ajax.history.init, 'priority');
			}
		},
		
		addHistory : function () {},
		history : {
			init : function () {
				if (!bv.ajax.historian) {
					if (document.all) {
						var bb = document.createElement('iframe');
						bb.id = 'bvAjaxHistorian';
						bb.height = 1;
						bb.width = 1;
						bb.style.visibility = 'hidden';
						bb.style.position = 'absolute';
						document.getElementsByTagName('body')[0].appendChild(bb);
						bv.ajax.historian = bb.contentWindow;
						bv.ajax.addHistory = function (id) {
							bv.ajax.historian.document.open();
							bv.ajax.historian.document.write('<script type="text/javascript">');
							bv.ajax.historian.document.write('parent.location.hash = "'+ id +'";');
							bv.ajax.historian.document.write('\<\/\scr\ipt>');
							bv.ajax.historian.document.close();
						}
					// start a history for Win IE, which ignores the first document
						bv.ajax.addHistory(self.location.hash);
					} else {
						bv.ajax.historian = {};
						bv.ajax.addHistory = function (id) {
							self.location.hash = id;
						};
					}
					bv.ajax.history.pollTimer = setInterval('bv.ajax.history.poll();', 221);
					bv.ajax.history.poll();
				}
			}, // END ajax.history.init
		
			addToGround : function (fn) {
				bv.ajax.history.init();
				if (typeof fn == 'function')
					bv.ajax.groundState.push(fn);
			},
			goToGround : function () {
				for (var xx=0; xx<bv.ajax.groundState.length; xx++)
					bv.ajax.groundState[xx]();
			},
			pollTimer : null,
			poll : function () {
				if (self.location.hash != bv.ajax.hashWas) {
					bv.ajax.hashWas = self.location.hash;
					var id = (bv.ajax.hashWas.indexOf('#') == 0) ? bv.ajax.hashWas.substring(1) : bv.ajax.hashWas;
					bv.ajax.history.go(id);
				}
			}, // END ajax.history.poll
			make : function (id, call) {
				bv.ajax.history.init();
				if (bv.ajax.historian) {
					while (bv.ajax.historicRecord[id]) id = id + bv.getNewGuid();
					bv.ajax.historicRecord[id] = call;
					bv.ajax.addHistory(id);
				}
			}, // END ajax.history.make
			go : function (id) {
			// make sure we didn't just go here
				if (bv.ajax.lastToGo.id == id) {
					var Now = new Date();
					if (Now.getTime() - bv.ajax.lastToGo.at.getTime() < 1000)
						return false;
				}
				bv.ajax.lastToGo = { id:id, at:new Date() };
				if (bv.ajax.historicRecord[id] && typeof bv.ajax.historicRecord[id] == 'function')
					bv.ajax.historicRecord[id]();
				else bv.ajax.history.goToGround();
			}
		}, // END ajax.history
		
		initIo : function () {
			var Rtn = false;
			if (window.XMLHttpRequest) {
				Rtn = new XMLHttpRequest();
			} else if (window.ActiveXObject) {
				try {
					Rtn = new ActiveXObject("Msxml2.XMLHTTP");
				} catch (e) {
					try {
						Rtn = new ActiveXObject("Microsoft.XMLHTTP");
					} catch (e) {
						Rtn = false;
					}
				}
			}
			return Rtn;
		}, // END ajax.initIo

		makeCallback : function (callback) {
			var Rtn = {
				success : bv.ajax.respSuccess,
				loading : bv.ajax.respLoading,
				error   : bv.ajax.respError,
				timeout : bv.ajax.respTimeout
			};
			if (typeof callback == 'function')
				Rtn.success = callback;
			else if (typeof callback == 'object') {
				for (var Prop in callback)
					Rtn[Prop] = callback[Prop];
			}
			return Rtn;
		}, // END ajax.makeCallback

		setup : function (callback, expectXML, avoidCache, addHeaders, followOnRedirect, requestTimeout, responseTimeout) {
			var cb = bv.ajax.makeCallback(callback);

			var http = {
				index : bv.ajax.index++,
				callback : cb,
				expectXML : (expectXML !== false) ? true : false,
				avoidCache : avoidCache || false,
				addHeaders : (typeof addHeaders != 'object') ? {} : addHeaders,
				followOnRedirect : (followOnRedirect !== false) ? true : false,
				requestTimeout : (typeof requestTimeout != 'number') ? parseFloat(Conf.ajax_request_timeout) : parseFloat(requestTimeout),
				requestTimer : null,
				responseTimeout : (typeof responseTimeout != 'number') ? parseFloat(Conf.ajax_response_timeout) : parseFloat(responseTimeout),
				responseTimer : null,
				hasBegunLoading : false,
				checkState : bv.ajax.checkState,
				redirect : bv.ajax.redirect,
				go : bv.ajax.go
			}
			http.io = bv.ajax.initIo();

			bv.ajax.calls[http.index] = http;
			return http;
		}, // END ajax.setup
		
		respSuccess : function () {},
		respLoading : function () {},
		respError : function () {},
		respTimeout : function () { this.io.abort(); this.callback.error(); },
		
		redirect : function () {
			/*
				use the properties of the object and the Location header
				to redirect the request to the new location
				(need a new io object)
			*/
		},
		
		checkState : function () {
			if (this.requestTimer) clearTimeout(this.requestTimer);
			if (this.io.readyState == 1) {
				if (!this.hasBegunLoading)
					this.callback.loading();
				this.hasBegunLoading = true;
				this.responseTimer = setTimeout("bv.ajax.calls["+ this.index +"].callback.timeout();", 1000* this.responseTimeout);
			} else if (this.io.readyState == 4) {
				if (this.responseTimer) clearTimeout(this.responseTimer);
				this.hasBegunLoading = true;
				if (this.io.status == 200) {
					this.callback.success();
				} else if (this.io.status > 299 && this.io.status < 400) {
					this.redirect();
				} else if (this.io.callback[this.io.status]) {
					this.io.callback[this.io.status](this.io.statusText);
				} else {
					this.io.callback.error(this.io.status, this.io.statusText);
				}
			}
		}, // END ajax.checkState
		
		go : function (url, content) {
			this.io.abort();
			this.hasBegunLoading = false;
			this.requestTimer = setTimeout("bv.ajax.calls["+ this.index +"].callback.timeout();", 1000* this.requestTimeout);
			this.io.onreadystatechange = this.checkState;
			if (content) {
				this.io.open("POST", url, true);
				this.io.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
				this.io.send(bv.string.makeKeyValueString(content));
			} else {
				if (this.avoidCache)
					url = bv.string.appendQueryString(url, "ord="+ Math.random());
				this.io.open("GET", url, true);
				this.io.send(null);
			}
		}, // END ajax.go
	
		pronto : function (url, callback) {
			var http = { url : url };
			http.io = bv.ajax.initIo();
			if (!http.io) return false;
			http.callback = bv.ajax.makeCallback(callback);
			http.hasBegunLoading = false;
	
			http.io.onreadystatechange = function () {
				if (http.io.readyState == 1) {
					if (!http.hasBegunLoading)
						http.callback.loading(http);
					http.hasBegunLoading = true;
				} else if (http.io.readyState == 4) {
					http.hasBegunLoading = true;
					if (http.io.status == 200) {
						http.callback.success(http.io.responseText, http.io.responseXML, http);
					} else if (http.callback[http.status]) {
						http.callback[http.io.status](http.io.statusText, http);
					} else {
						http.callback.error(http.io.status, http.io.statusText, http);
					}
				}
			}
	
	// gotta remember to check for memory leaks...
	
			http.io.open("GET", url, true);
			http.io.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"); // avoid the cache
			http.io.send(null);
			return http;
		} // END prontoAjax
	}, // END ajax
	
	string : {
		trim : function (s,dedupe) {
			// Mac IE chokes on the '?'; you can break this into two replaces for Mac IE compatibility
			s = s.replace(/^[\t\r\n\s]*(.*?)[\t\r\n\s]*$/, '$1');
			if (dedupe) // reduce internal runs of whitespace
				s = s.replace(/[\t\r\n\s]+/g, ' ');
			return s;
		},
		camelCase : function (s) {
			var bits = s.split("[- ]+");
			for (var xx=1; xx<bits.length; xx++)
				if (bits[xx].length)
					bits[xx] = bits[xx].charAt(0).toUpperCase() + bits[xx].substring(1);
			return bits.join('');
		},
		stripHTML : function (s) {
			return s.replace(/<\/?\w+.*?>/g,'');
		},
		parseKeyValueString : function (s,d) {
			if (!d) d = "|"; // delimiter for multiple values with the same key
			while (s.charAt(0) == "?") s = s.substring(1);
			var Pairs = s.split(/\&(amp;)?/);
			var Rtn = {};
			for (var xx=0; xx<Pairs.length; xx++) {
				var NameValue = Pairs[xx].split("=");
				if (Rtn[unescape(NameValue[0])])
					Rtn[unescape(NameValue[0])] += d;
				else
					Rtn[unescape(NameValue[0])] = '';
				Rtn[unescape(NameValue[0])] += Rtn[unescape(NameValue[1])]
			}
			return Rtn;
		},
		makeKeyValueString : function (obj, escapeAmp, delimiter, separater) {
			var amp = (escapeAmp) ? "&amp;" : "&";
			var d = delimiter || amp;
			var s = separater || "=";
			var Arr = [];
			for (var Prop in obj)
				Arr.push(escape(Prop) + s + escape(obj[Prop]));
			return Arr.join(d);
		},
		appendQueryString : function (url, string, escapeAmp) {
			var amp = (escapeAmp) ? "&amp;" : "&";
			var pre = (url.indexOf("?") != -1) ? amp : "?";
			return url + pre + string;
		}
	}, // END string
	
	data : {
		isEmailFormat : function (str) {
			return /^[^\s]@[^\s]\.\w{2,}$/.test(str);
		}
	}, // END form
	
	cookie : {
		get : function (name) {
		
		},
		set : function (name, value, path, expires, domain) {
		
		},
		verifyAccepted : function () {}
	},
	
	array : {
		shuffle : function (a) {
			if (a.length < 2) return a;
			var Last = a[a.length -1]; // store the current last element
			do a = a.sort(bv.utility.sortRandom);
			while (Last == a[0]); // repeat until the new first is not the old last
			return a;
		}
	}, // END array

	utility : {
		sortRandom : function (a,b) {
			if (Math.random() > 0.5) return 1;
			else return -1;
		}
	},

	complete : true
}; // END bv declaration
bv.init();

/* add to debug:

function loopThrough(el,depth) {
	var D = depth || 0;
	var Indent = "";
	for (var xx=0; xx<D; xx++) Indent += "-";
	var Items = el.childNodes;
	for (var xx=0; xx<Items.length; xx++) {
		d(Indent +' '+ Items[xx].nodeName +' offsetWidth:'+ Items[xx].offsetWidth, 'map menus');
		if (Items[xx].hasChildNodes())
			loopThrough(Items[xx], D +1);
	}
}
*/

/* ... /packer:END(_bv_utilities.js) */
/* (3) packer:START(bvIE_activateFlash.js) ... */


var bvIE_activateFlash = {
	init : function () {
		var objs = document.getElementsByTagName('object');
		for (
				var xx=objs.length -1, obj=null;
				obj=objs[xx];
				xx-- // backwards, to avoid references to objects changing as you replace them
			) {
			var Emb = document.createElement('embed');
			for (
					var ii=0, attr=null, grab=['classid','type','id','name','style','height','width'];
					attr=grab[ii];
					ii++
				) {
				Emb.setAttribute(attr, obj.getAttribute(attr));
			}
			Emb.setAttribute('src', obj.getAttribute('data'));
			Emb.className = obj.className;
			for (
					var ii=0, param=null, params=obj.getElementsByTagName('param');
					param=params[ii];
					ii++
				) {
				Emb.setAttribute(param.name, param.value);
				if (param.name.toLowerCase() == 'movie')
					Emb.setAttribute('src', param.value);
			}
			obj.parentNode.replaceChild(Emb, obj);
		}
	},
	
	zap : function () {
		var objs = document.getElementsByTagName("embed");
		for (
				var ii=objs.length -1, obj=null;
				obj=objs[ii];
				ii-- // backwards to prevent the count from changing as we go
			) {
			obj.parentNode.removeChild(obj); // self-destruct
		}
	},
	
	complete : true
}


if (document.all) {
	window.attachEvent('onunload', bvIE_activateFlash.zap);
	bv.event.add(window, 'domready', bvIE_activateFlash.init);
}

/* ... /packer:END(bvIE_activateFlash.js) */
/* (4) packer:START(bvDimForm.js) ... */


var bvDimForm = {

	init : function (el) { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		var Trg = (el) ? el : document;
		var Els = bv.dom.getElementsByClassName(Trg, 'input,textarea', 'bvDimmable');
		for (var xx=0; xx<Els.length; xx++) {
			Els[xx].bvDimForm_txt = Els[xx].getAttribute('title');
			Els[xx].title = '';
			Els[xx].bvDimForm_dim = bvDimForm.dim;
			Els[xx].bvDimForm_nodim = bvDimForm.nodim;
			bv.event.add(Els[xx], 'blur', Els[xx].bvDimForm_dim);
			bv.event.add(Els[xx], 'focus', Els[xx].bvDimForm_nodim);
			if (!Els[xx].form.bvDimForm_index) {
				Els[xx].form.bvDimForm_index = [];
				Els[xx].form.bvDimForm_nodimAll = bvDimForm.nodimAll;
				bv.event.add(Els[xx].form, 'submit', Els[xx].form.bvDimForm_nodimAll);
			}
			Els[xx].form.bvDimForm_index.push(Els[xx]);
			Els[xx].bvDimForm_dim();
		}
	},
	
	nodimAll : function () {
		for (var xx=0; xx<this.bvDimForm_index.length; xx++) {
			this.bvDimForm_index[xx].bvDimForm_nodim();
		}
	},
	
	dim : function () {
		if (this.value == '' || this.value == this.bvDimForm_txt) {
			try {
				if (this.type == 'password') {
					this.bvDimForm_origType = 'password';
					this.type = 'text';
				}
				bv.css.addClass(this, 'bvDim');
				this.value = this.bvDimForm_txt;
			} catch (e) {}
		}
	},
	
	nodim : function () {
		try {
			if (this.bvDimForm_origType) {
				this.type = 'password';
			}
			bv.css.removeClass(this, 'bvDim');
			if (this.value == this.bvDimForm_txt) {
				this.value = '';
			}
		} catch (e) {}
	}

}

if (bv && bv.event) bv.event.add(window, "domready", bvDimForm.init);

/* ... /packer:END(bvDimForm.js) */
/* (5) packer:START(bvCountForm.js) ... */


var bvCountForm = {

	init : function (el) { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		var Trg = (el) ? el : document;
		var Els = bv.dom.getElementsByClassName(Trg, 'label', 'bvCountable');
		for (var xx=0; xx<Els.length; xx++) {
			var Base = Els[xx].innerHTML;
		// correct for IE misbehavior
			var ForId = (Els[xx].htmlFor) ? Els[xx].htmlFor : Els[xx].getAttribute('for');
			var For = null;
			if (For = document.getElementById(ForId)) {
				var Max = 0;
				if (/\bbvCountMax-\d+\b/.test(Els[xx].className))
					Max = parseInt(Els[xx].className.replace(/.*bvCountMax-(\d+).*/, "$1"));
			// for now, all counting is Char counting
				For.bvCountForm = {
					type : 'Char',
					max  : Max,
					trg  : Els[xx],
					base : Base
				};

				bv.event.add(For, 'keyup', bvCountForm.countChar);
				if (For.bvCountForm.max) bv.event.add(For, 'keydown', bvCountForm.checkMax);
			}
		}
	},
	
	countChar : function () {
		if (this.value.length) {
			if (this.bvCountForm.max) {
				this.bvCountForm.trg.innerHTML = this.value.length +" of max. "+ this.bvCountForm.max;
			} else {
				this.bvCountForm.trg.innerHTML = this.value.length +" characters";
			}
		} else {
			if (this.bvCountForm.base) this.bvCountForm.trg.innerHTML = this.bvCountForm.base;
			else this.bvCountForm.trg.innerHTML = "0 characters";
		}
	},
	
	checkMax : function () {
		if (this.bvCountForm.max && this.bvCountForm.max <= this.value.length) {
			this.value = this.value.substring(0,300);
			return false;
		}
	},
	
	complete : true
}

if (bv && bv.event) bv.event.add(window, "domready", bvCountForm.init);

/* ... /packer:END(bvCountForm.js) */
/* (6) packer:START(bvFormOther.js) ... */


var bvFormOther = {

	init : function (el) { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		var Trg = (el) ? el : document;
		var Els = bv.dom.getElementsByClassName(Trg, 'fieldset', 'bvFormOther');
		for (var xx=0; xx<Els.length; xx++) {
			var Out = bv.dom.getElementsByClassName(Els[xx], 'select,input', 'bvFormOtherOut')[0];
			var In  = bv.dom.getElementsByClassName(Els[xx], 'select,input,textarea,button', 'bvFormOtherIn')[0];
			Out.bvFormOther = Els[xx];
			In.bvFormOther  = Els[xx];
			Els[xx].bvFormOther = {
				chooser : Out,
				other : In
			};
			bv.event.add(Out, 'change', bvFormOther.choose);
			bv.event.add(In, 'blur', bvFormOther.offer);
			bv.event.add(In, 'keypress', bvFormOther.checkAcceptance);
			bv.css.addClass(Els[xx], 'bvFormOtherHide');
			
		// when people return to the page with the back button
		// the 'other' field is populated, but the js-written text is not
			if (In.value.length) {
				for (var xx=Out.options.length -1; xx>=0; xx--) { // backwards, cuz 'other' is usually last
					if (Out.options[xx].value == 'other') {
						Out.options[xx].text = In.value;
						break;
					}
				}
			}
		}
	},
	
	choose : function () {
		var O = this.bvFormOther.bvFormOther.other;
		if (this.options[this.selectedIndex].value == 'other') {
			this.bvFormOther.style.height = 'auto';
			bv.css.removeClass(this.bvFormOther, 'bvFormOtherHide');
			bv.css.addClass(this.bvFormOther, 'bvFormOtherShow');
			this.bvFormOther.style.height = '';
			O.value = this.options[this.selectedIndex].text;
			setTimeout(function (el) { var trg = el; return function () { trg.focus(); trg.select(); }}(O), 10);
		} else {
			O.value = '';
		}
	}, // END: choose
	
	offer : function () {
		bvFormOther.accept(this);
	}, // END: offer
	
	checkAcceptance : function (e) {
		switch (e.keyCode) {
			case 38 : // cursor up
			case 40 : // cursor down
			case 27 : // escape key
			case 13 : // enter or return
				bvFormOther.accept(this);
				e.preventDefault();
				return false;
				break;
		}
	
		
	}, // END: checkAcceptance
	
	accept : function (el) {
		el.bvFormOther.style.height = 'auto';
		bv.css.removeClass(el.bvFormOther, 'bvFormOtherShow');
		bv.css.addClass(el.bvFormOther, 'bvFormOtherHide');
		el.bvFormOther.style.height = '';
		var C = el.bvFormOther.bvFormOther.chooser;
		C.options[C.selectedIndex].text = el.value;
	}, // END: accept
	
	complete : true
}

if (bv && bv.event) bv.event.add(window, "domready", bvFormOther.init);

/* ... /packer:END(bvFormOther.js) */
/* (7) packer:START(bvFormActive.js) ... */


var bvFormActive = {

	forms : {},

	init : function (el) { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		var Trg = (el) ? el : document;
		var Els = bv.dom.getElementsByClassName(Trg, 'input', 'bvFormActive');
		for (var xx=0; xx<Els.length; xx++) {
			var TrgId = Els[xx].className.match(/\bbvFormActiveTrg-(\w+)\b/);
			var Trg = (TrgId) ? document.getElementById(TrgId[1]) : null;
			Els[xx].bvFormActive = function (target) {
				var Trg = target;
				return function () {
					if (this.checked) {
						if (Trg) bv.css.addClass(Trg, 'bvFormActivated');
						if (bvFormActive.forms[this.name])
							bvFormActive.forms[this.name].bvFormActive();
						bvFormActive.forms[this.name] = this;
					} else {
						if (Trg) bv.css.removeClass(Trg, 'bvFormActivated');
					}
				};
			}(Trg);
			bv.event.add(Els[xx], 'click', Els[xx].bvFormActive);
			Els[xx].bvFormActive();
		}
	},
	
	complete : true
}

if (bv && bv.event) bv.event.add(window, "domready", bvFormActive.init);

/* ... /packer:END(bvFormActive.js) */
/* (8) packer:START(ffwTopNav.js) ... */


var ffwTopNav = {
	trg : 'navSite',
	
	init : function (trgId) {
		var id = (trgId) ? trgId : ffwTopNav.trg;
		var Trg = document.getElementById(id);
		if (!Trg) return;
		var Menus = Trg.getElementsByTagName('dl');
		for (var xx=0; xx<Menus.length; xx++) {
			var M = Menus[xx].getElementsByTagName('select')[0];
			bv.event.add(M, 'change', ffwTopNav.go);
			var Items = Menus[xx].getElementsByTagName('dd');
			for (var ii=0; ii<Items.length; ii++) {
				var opt = document.createElement('option');
				if (Items[ii].childNodes[0].href) { // if there is a link, create an option pointing to it
					opt.setAttribute('value', Items[ii].childNodes[0].href);
					opt.appendChild(document.createTextNode(Items[ii].childNodes[0].childNodes[0].nodeValue));
				} else { // assume this is the "current page"
					opt.setAttribute('value', '');
					opt.setAttribute('selected', 'selected');
					opt.appendChild(document.createTextNode(Items[ii].childNodes[0].nodeValue));
				}
				opt.className = "destination";
				M.appendChild(opt);
//				Menus[xx].removeChild(Items[ii]);
				Items[ii].style.display = 'none';
			}
		}
	},
	
	go : function () {
		if (this.options[this.selectedIndex].value != '')
			top.location.href = this.options[this.selectedIndex].value;
	},
	
	complete : true
}

bv.event.add(window, 'domready', ffwTopNav.init, 'priority');

// creates a submit-on-return action even without a submit button in the form
bv.event.add(window, 'domready', function () {
		bv.event.add(document.getElementById('topsigninPassword'), 'keyup', function (e) {
			if (e.keyCode == 13) this.form.submit();
		} );
	} );


/* ... /packer:END(ffwTopNav.js) */
/* (9) packer:START(bvPrintables.js) ... */


var bvPrintables = {

	batch : [],

	configure : function (name, value) {
		if (typeof bvPrintables[name] == typeof value)
			bvPrintables[name] = value;
		else if (bv) bv.debug.msg('type mismatch in call to configure(): '+ name +'::'+ value, 'bvPrintables');
	},

	init : function (el) { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		var B = document.getElementsByTagName('body');
		if (B[0]) {
			var UL = document.createElement('ul');
			UL.className = 'bvPrintables';
			var LI = document.createElement('li');
			for (var xx=0; xx<bvPrintables.batch.length; xx++) {
				LI.innerHTML = bvPrintables.batch[xx];
				UL.appendChild(LI.cloneNode(true));
			}
			B[0].appendChild(UL);
		}
	},
	
	complete : true	
}

if (bv && bv.event) bv.event.add(window, "domready", bvPrintables.init);

/* ... /packer:END(bvPrintables.js) */
/* (10) packer:START(bvAddABlock.js) ... */


var addABlock = {

	configure : function (name, value) {
		if (typeof addABlock[name] == typeof value)
			addABlock[name] = value;
		else if (bv) bv.debug.msg('type mismatch in call to configure(): '+ name +'::'+ value, 'addABlock');
	},

	init : function (el) { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		var Trg = (el) ? el : document;
		var Els = bv.dom.getElementsByClassName(Trg, 'table', 'addABlock');
		if (Els && Els.length) {
			for (var xx=0; xx<Els.length; xx++)
				addABlock.makeTable(Els[xx]);
		}
	},
	
	makeTable : function (el) {
		el.addABlock = {
			trg : null,
			rows : null,
			src : null,
			max : 0,
			trigger : null
		};
		el.addABlock.trg = el.getElementsByTagName('tbody')[0];
		el.addABlock.rows = bv.dom.getChildNodesOfType(el.addABlock.trg, 'tr');
		el.addABlock.src = el.addABlock.rows[el.addABlock.rows.length -1].cloneNode(true);
		var Header = el.addABlock.src.getElementsByTagName('th');
		el.addABlock.src.header = (Header && Header.length) ? Header[0] : null;
		
		el.addABlock.max = (parts = el.className.match(/\baddABlockMax-(\d+)\b/)) ? parseInt(parts[1]) : 0;
		if (el.addABlock.max == 0 || el.addABlock.rows.length < el.addABlock.max) {
			var Text = (parts = el.className.match(/\baddABlockTitle-(\w+)\b/)) ? parts[1] : 'row';
			el.addABlock.trigger = document.createElement('a');
			el.addABlock.trigger.className = 'addABlockTrigger';
			el.addABlock.trigger.href = 'javascript:// add a '+ escape(Text);
			el.addABlock.trigger.innerHTML = 'add a '+ Text;
			el.addABlock.trigger.addABlock = { trg : el };
			bv.event.add(el.addABlock.trigger, 'click', addABlock.add);
			el.parentNode.insertBefore(el.addABlock.trigger, el.nextSibling);
			
			var Inputs = el.addABlock.src.getElementsByTagName('input');
			for (var xx=0; xx<Inputs.length; xx++) {
				switch (Inputs[xx].type) {
					case 'text' :
					case 'textarea' :
					case 'password' :
						Inputs[xx].setAttribute('value', '');
						break;
					case 'radio' :
					case 'checkbox' :
						Inputs[xx].removeAttribute('checked');
						break;
					default :
						break;
				}
			}
			var Selects = el.addABlock.src.getElementsByTagName('select');
			for (var xx=0; xx<Selects.length; xx++) {
				Selects[xx].selectedIndex = 0;
				var Opts = Selects[xx].getElementsByTagName('option');
				for (var ii=0; ii<Opts.length; ii++)
					Opts[ii].removeAttribute('selected');
			}
		}
	},
	
	add : function () {
		if (!this.addABlock.trg) return true;
		var Trg = this.addABlock.trg;
		if (Trg.addABlock.rows.length < Trg.addABlock.max || Trg.addABlock.max == 0) {
			if (Trg.addABlock.src.header)
				Trg.addABlock.src.header.innerHTML = (Trg.addABlock.rows.length +1) +'.';
			var NewRow = Trg.addABlock.src.cloneNode(true);
			Trg.addABlock.trg.appendChild(NewRow);
			Trg.addABlock.rows.push(NewRow);
			if (Trg.addABlock.rows.length == Trg.addABlock.max)
				Trg.parentNode.removeChild(Trg.addABlock.trigger);
		} else {
			Trg.removeChild(Trg.addABlock.trigger);
		}
		return false;
	},

	complete : true
}

if (bv && bv.event) bv.event.add(window, "domready", addABlock.init);



/* ... /packer:END(bvAddABlock.js) */
/* (11) packer:START(bvSlideShow.js) ... */


var bvSlideShow = {

	autoSlideWait : 5,
	slideDuration : 2,
	frameRate : 60,
	frameJump : 0.95,
	target : document,
	shows : [],
	configure : function (name, value) {
		if (typeof bvSlideShow[name] == typeof value)
			bvSlideShow[name] = value;
		else if (bv) bv.debug.msg('type mismatch in call to configure(): '+ name +'::'+ value, 'bvSlideShow');
	},

	init : function (el) { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		var Trg = el || bvSlideShow.target;
		if (Trg && Trg.nodeType) {
			var Shows = bv.dom.getElementsByClassName(Trg, 'ul,ol', 'slideshow');
			for (var xx=0; xx<Shows.length; xx++) {
				bvSlideShow.shows[xx] = bvSlideShow.makeShow(Shows[xx]);
				bvSlideShow.shows[bv.getId(bvSlideShow.shows[xx])] = bvSlideShow.shows[xx];
			}
		}
		bvSlideShow.startup();
	},

	makeShow : function (el) {
		el.bv_slideWait      = bvSlideShow.autoSlideWait;
		el.bv_slideDuration  = bvSlideShow.slideDuration;
		el.bv_frameRate      = bvSlideShow.frameRate;
		el.bv_frameJump      = bvSlideShow.frameJump;
		el.bv_slideCurrent   = 1;
		el.bv_slideCurrentId = null;
		el.bv_slidePrevious  = null;
		if (SrcId = el.className.match(/\bslideSrc-([^\s]+)/)) { // gather rollover slides from alternate list
			var Src = document.getElementById(SrcId[1]);
			el.bv_slides = [];
			if (!Src) return el;
			var List = Src.getElementsByTagName('li');
			for (var xx=0; xx<List.length; xx++) {
				var A = List[xx].getElementsByTagName('a');
				for (var ii=0; ii<A.length; ii++) {
					if (rel = A[ii].getAttribute('rel')) {
						if (imgsrc = rel.match(/\bimg-([^\s]+)/)) {
							A[ii].bv_slideTarget = bvSlideShow.makeSlideElement({img : {src : imgsrc[1]}, a : {href : A[ii].href,title : bv.string.stripHTML(A[ii].innerHTML)}}, el);
							bv.event.add(A[ii], 'mouseover', bvSlideShow.rollTrigger);
							el.appendChild(A[ii].bv_slideTarget);
							el.bv_slides.push(A[ii].bv_slideTarget);
							A[ii].bv_slideTarget.bv_slideTrigger = A[ii];
						}
					}
				}
			}
			el.bv_slideCurrentId = bv.getId(el.bv_slides[0].bv_slideTrigger);
			el.bv_slides[0].slideIn("0%");
			el.bv_slidePrevious = el.bv_slides[0].bv_slideTrigger;
			bv.css.addClass(el.bv_slides[0].bv_slideTrigger, 'slideshowActiveTrigger');
		} else { // automatically loop over this list
			el.bv_slides = el.getElementsByTagName('li');
			for (var xx=0; xx<el.bv_slides.length; xx++) {
				bvSlideShow.makeSlide(el.bv_slides[xx], el);
			}
			el.bv_slideCount   = el.bv_slides.length;
			el.bv_slideAdvance = bvSlideShow.advanceSlide;
		}
		return el;
	},
	
	makeSlideElement : function (elData, parent) {
		var El = { li : null, a : null, img : null};
		for (var elementType in El) {
			El[elementType] = document.createElement(elementType);
			if (elData[elementType]) {
				for (var attr in elData[elementType]) {
					El[elementType][attr] = elData[elementType][attr];
				}
			}
		}
		El.a.appendChild(El.img);
		El.li.appendChild(El.a);
		bvSlideShow.makeSlide(El.li, parent);
		return El.li;
	},
	makeSlide : function (el, parent) {
		el.id = bv.getId(el)
		el.currFrame = -1;
		el.inFrame = false;
		el.slideIn = bvSlideShow.slideIn;
		el.slideStep = bvSlideShow.slideStep;
		el.bv_slideParentShow = parent;
	},
	
	
	startup : function () {
		for (var xx=0; xx<bvSlideShow.shows.length; xx++) {
			if (bvSlideShow.shows[xx].bv_slideAdvance) {
				bvSlideShow.shows[xx].bv_slideTimer = setTimeout('bvSlideShow.shows['+ xx +'].bv_slideAdvance()', bvSlideShow.shows[xx].bv_slideWait *1000);
			}
		}
	},
	shutdown : function () {
		for (var xx=0; xx<bvSlideShow.shows.length; xx++) {
			if (bvSlideShow.shows[xx].bv_slideTimer) {
				clearInterval(bvSlideShow.shows[xx].bv_slideTimer);
			}
		}
	},
	
	
	rollTrigger : function () {
		if (this.bv_slideTarget.bv_slideParentShow.bv_slideCurrentId != bv.getId(this)) {
			this.bv_slideTarget.bv_slideParentShow.bv_slideCurrentId = bv.getId(this);
			this.bv_slideTarget.bv_slideParentShow.bv_slideCurrent++;
			if (this.bv_slideTarget.bv_slideParentShow.bv_slidePrevious)
				bv.css.removeClass(this.bv_slideTarget.bv_slideParentShow.bv_slidePrevious, 'slideshowActiveTrigger');
			this.bv_slideTarget.bv_slideParentShow.bv_slidePrevious = this;
			bv.css.addClass(this, 'slideshowActiveTrigger');
			this.bv_slideTarget.slideIn();
		}
	},
	
	
	advanceSlide : function () {
		if (this.bv_slideTimer) clearTimeout(this.bv_slideTimer);
		this.bv_slideCurrent++;
		this.bv_slides[this.bv_slideCurrent % this.bv_slideCount].slideIn();
		this.bv_slideTimer = setTimeout('document.getElementById("'+ bv.getId(this) +'").bv_slideAdvance()', this.bv_slideWait *1000);
	},
	
	slideIn : function (From) {
		var Start = From || "-120%";
		this.style.left = Start;
		this.style.zIndex = this.bv_slideParentShow.bv_slideCurrent;
		this.bv_slideLeft = bv.css.getOffset(this).left;
		var xx = this.bv_slideLeft;
		var Jumps = [xx];
		while (xx<0) {
			xx = Math.ceil(xx * this.bv_slideParentShow.bv_frameJump);
			Jumps.push(xx);
		}
		Jumps[Jumps.length -1] = 0;
		for (var xx=0; xx<Jumps.length; xx++) {
			setTimeout('document.getElementById("'+ bv.getId(this) +'").bv_slideLeft = '+ Jumps[xx], ((xx+1)*1000* this.bv_slideParentShow.bv_slideDuration)/Jumps.length);
		}
		this.bv_slideTimer = setInterval('bvSlideShow.slideStep(document.getElementById("'+ bv.getId(this) +'"))', 1000/this.bv_slideParentShow.bv_frameRate);
	},
		
	slideStep : function (el) {
		if (el.bv_slideLeft == 0) clearInterval(el.bv_slideTimer);
		el.style.left = el.bv_slideLeft +'px';
	}

}

if (bv && bv.event) bv.event.add(window, "domready", bvSlideShow.init);

/* ... /packer:END(bvSlideShow.js) */
/* (12) packer:START(ffwMediaplex.js) ... */


var ffwMediaplex = {

	target : document,
	lobby : null,
	stage : null,
	requestScreen : null,
	loadScreen : null,
	errorScreen : null,
	fade : null,
	children : [],
	childrenOpacity : 1,
	startWith : null,
	nowShowing : null,
	castOfPages : [],
	castOfHTML : [],
	jumpToTrg : false,
	configure : function (name, value) {
		if (typeof ffwMediaplex[name] == typeof value)
			ffwMediaplex[name] = value;
		else if (bv) bv.debug.msg('type mismatch in call to configure(): '+ name +'::'+ value, 'ffwMediaplex');
	},

	init : function (el) { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		var Trg = el || ffwMediaplex.target;
		if (Trg && Trg.nodeType) {
			ffwMediaplex.lobby = Trg.getElementById('mediaplex');
			if (!ffwMediaplex.lobby) return;
			
			if (bv && bv.ajax.history)
				bv.ajax.history.addToGround(ffwMediaplex.curtainCall);

			var Curtain = document.createElement('div');
			Curtain.id = "theaterCurtain";
			Curtain.onclick = ffwMediaplex.removeCurtain;
			document.getElementsByTagName('body')[0].appendChild(Curtain);
			// fix Win Firefox's complaint about position:absolute Flash over position:fixed
			if (/Gecko/.test(navigator.userAgent) && /Win/.test(navigator.userAgent)) {
				Curtain.style.position = "absolute";
				// resize, after all the crops and collapses
				bv.event.add(window,'domready', function () { Curtain.style.height = (document.getElementById('wrap').offsetHeight +10) +'px'; } );
			}

			var Stage = document.createElement('div');
			Stage.id = "theaterStage";
			Stage.className = "stage";
			Stage.style.height = ffwMediaplex.lobby.offsetHeight +'px';
			document.getElementsByTagName('body')[0].appendChild(Stage);
			ffwMediaplex.stage = Stage;

			var RequestingScreen = document.createElement('div');
			RequestingScreen.className = "screen";
			RequestingScreen.style.paddingTop = (ffwMediaplex.lobby.offsetHeight /3) +'px';
			LoadingScreen = RequestingScreen.cloneNode(false);
			ErrorScreen = RequestingScreen.cloneNode(false);
			RequestingScreen.id = "theaterRequestingScreen";
			LoadingScreen.id = "theaterLoadingScreen";
			ErrorScreen.id = "theaterErrorScreen";
			RequestingScreen.innerHTML = 'Requesting<br /><img src="/fileadmin/img/icons/ajax_loading_apple_spinner.gif" width="32" height="32" alt="" />';
			LoadingScreen.innerHTML = 'Loading<br /><img src="/fileadmin/img/icons/ajax_loading_apple_spinner.gif" width="32" height="32" alt="" />';
			ErrorScreen.innerHTML = 'Error<br /><small style="font-size:14px;">An error occured while loading data from the server.</small>';
			Stage.appendChild(RequestingScreen);
			Stage.appendChild(LoadingScreen);
			Stage.appendChild(ErrorScreen);
			ffwMediaplex.requestScreen = RequestingScreen;
			ffwMediaplex.loadScreen = LoadingScreen;
			ffwMediaplex.errorScreen = ErrorScreen;

			for (var xx=0; xx<ffwMediaplex.lobby.childNodes.length; xx++) {
				if (ffwMediaplex.lobby.childNodes[xx].nodeName.toLowerCase() == 'div') {
					ffwMediaplex.children.push(ffwMediaplex.lobby.childNodes[xx]);
					bv.css.opacity.set(ffwMediaplex.lobby.childNodes[xx], 1);
				}
			}
			
			var A = ffwMediaplex.lobby.getElementsByTagName('a');
			for (var xx=0; xx<A.length; xx++) {
				if (rel = A[xx].getAttribute('rel')) {
					if (pgsrc = rel.match(/\bpg-([^\s]+)/)) {
						A[xx].ffw_ajax_src = pgsrc[1] +"?cachebuster="+ Date.parse(new Date());
						A[xx].ffw_ajax_id  = pgsrc[1].replace(/[^\w]/g, '__');
						A[xx].ffw_ajax_trg = false;
						if (trg = rel.match(/\btrg-([^\s]+)/)) {
							A[xx].ffw_ajax_trg = trg[1];
						}
						bv.event.add(A[xx], "click", ffwMediaplex.aCue);
						if (Math.floor(bv.ajax.hashWas.indexOf(A[xx].ffw_ajax_id) /2) == 0) { // it's the first or second character
							ffwMediaplex.startWith = A[xx];
							bv.ajax.hashWas = 'gonna start with startWith';
						}
					}
				}
			}
			if (ffwMediaplex.startWith) {
				bv.event.add(window, 'domready', ffwMediaplex.removeCurtain);
				bv.event.add(window, 'domready', ffwMediaplex.aCue);
			}
		}
	},
	
	aCue : function () {
		var A = (this && this.ffw_ajax_id) ? this : ffwMediaplex.startWith;
		if (!A) return true;
		if (bv.ajax && bv.ajax.isAvailable) {
			var id  = A.ffw_ajax_id;
			var src = A.ffw_ajax_src;
			var trg = A.ffw_ajax_trg;
			var lightsUp = /\blightsUp\b/.test(A.className);
			bv.ajax.history.make(id, function () { ffwMediaplex.callHandler(id, src, trg, lightsUp); });
			return false;
		} else return true;
	},
	callHandler : function (id, src, trg, lightsUp) {
		if (ffwMediaplex.castOfPages[id]) {
			ffwMediaplex.drawCurtain(lightsUp);
			ffwMediaplex.showPage(id);
			if (trg && ffwMediaplex.castOfPages[id].mediaplexScrollList) {//alert('success:\n'+ ffwMediaplex.castOfPages[id].mediaplexScrollList+'\n'+trg);
//				setTimeout(function () { ffwListScroller.jumpTo(ffwMediaplex.castOfPages[id].mediaplexScrollList, trg); }, 100);
				ffwListScroller.jumpTo(ffwMediaplex.castOfPages[id].mediaplexScrollList, trg);
			}// else alert('failed:\n'+ ffwMediaplex.castOfPages[id].mediaplexScrollList+'\n'+trg);
		} else {//alert(id);
			bv.ajax.pronto(
				src,
				{
					success : ffwMediaplex.pageLoaded,
					loading : ffwMediaplex.pageLoading,
					error   : ffwMediaplex.pageLoadError
				}
			);
			ffwMediaplex.drawCurtain(lightsUp);
			if (trg) ffwMediaplex.jumpToTrg = trg;
		}
	},
	
	showPage : function (castId) {
		if (ffwMediaplex.nowShowing && ffwMediaplex.nowShowing.style)
			bv.css.removeClass(ffwMediaplex.nowShowing, 'cameraAction');
		ffwMediaplex.nowShowing = ffwMediaplex.castOfPages[castId];
		if (ffwMediaplex.castOfHTML[castId]) {
			ffwMediaplex.nowShowing.innerHTML = ffwMediaplex.castOfHTML[castId];
			ffwMediaplex.pagePrep(ffwMediaplex.nowShowing);
		}
		bv.css.addClass(ffwMediaplex.nowShowing, 'cameraAction');
		ffwMediaplex.stage.id = "onStagePage";
	},
	pageLoaded : function (txt, xml, obj) {
		var newPage = document.createElement('div');
		newPage.id = obj.url.replace(/\?cachebuster=\d+/,'').replace(/[^\w]/g, '__');
		newPage.className = "theater";
		newPage.innerHTML = txt;
		
	// IE needs to zap the objects, but the HTML needs to be fully replace to prevent activation
		if (document.all) {
			ffwMediaplex.castOfHTML[newPage.id] = txt;
		}
		ffwMediaplex.castOfPages[newPage.id] = newPage;
		ffwMediaplex.stage.appendChild(newPage);

		ffwMediaplex.showPage(newPage.id);
		ffwMediaplex.pagePrep(newPage);
	},
	pagePrep : function (pg) {
	// add abilities that are normally added on dom load
		if (bvStickyWicket) {
			var galleries = bv.dom.getElementsByClassName(pg, 'ol', 'photoGallery');
			for (var xx=0; xx<galleries.length; xx++) {
				bvStickyWicket.init(bv.getId(galleries[xx]),'li');
			}
		}
		if (bvCollapse) {
			bvCollapse.init(pg, 'li');
		}
		if (bvAttachValidWindows) {
			bvAttachValidWindows.init();
		}
		if (ffwVoter) {
			ffwVoter.init(pg);
		}

	// this needs the content to render first
		if (ffwListScroller) {
			var L = ffwListScroller.init(pg);
			pg.mediaplexScrollList = L[0];
			var Jumpers = bv.dom.getElementsByClassName(pg, 'ul', 'filmmakerAnchors');
			if (Jumpers && Jumpers[0]) {
				var A = Jumpers[0].getElementsByTagName('a');
				for (var xx=0; xx<A.length; xx++) {
					A[xx].jump_trg = L[0];
					bv.event.add(A[xx], 'click', ffwListScroller.jumpLink);
				}
			}
			if (ffwMediaplex.jumpToTrg) {// alert('scrolling '+ newPage.mediaplexScrollList +'\nto '+ ffwMediaplex.jumpToTrg);
				ffwListScroller.jumpTo(pg.mediaplexScrollList, ffwMediaplex.jumpToTrg);
				ffwMediaplex.jumpToTrg = false;
			}
		}
	},
	pageLoading : function (obj) {
		ffwMediaplex.stage.id = "onStageLoading";
	},
	pageLoadError : function (code, text, obj) {
		ffwMediaplex.stage.id = "onStageError";
	},

	drawCurtain : function (lightsUp) {
		if (window.bvSlideShow) bvSlideShow.shutdown();
		bv.css.addClass(document.getElementsByTagName('body')[0], 'contentMediaTheaterCurtain');
		if(lightsUp) bv.css.addClass(document.getElementsByTagName('body')[0], 'contentMediaTheaterLightsUp');
		ffwMediaplex.stage.id = "onStageRequesting";
	},

	removeCurtain : function () {
		bv.ajax.history.make('lobby', ffwMediaplex.curtainCall);
	},
	curtainCall : function () {
		if (window.bvSlideShow) bvSlideShow.startup();
		ffwMediaplex.stage.id = "onStageNone";
		bv.css.removeClass(document.getElementsByTagName('body')[0], 'contentMediaTheaterCurtain');
		bv.css.removeClass(document.getElementsByTagName('body')[0], 'contentMediaTheaterLightsUp');
	
	// IE keeps playing the Flash even if it's display:none;, and even if its parent is removed (or innerHTML='')
	// this sorta works, but then you get activation issues later: object.parentNode.replaceChild(object.cloneNode(true), object);
	// moreover, if you just remove it/replace it, the DOM gets wonky even when replaced by innerHTML later
	// so, first remove them all, then remove the parent stuff; when the page is called from cache, remake the HTML
		if (document.all) {
			var objects = ffwMediaplex.nowShowing.getElementsByTagName('object'); // not embeds, because the "activator" runs on page load, before these show up
			for (var xx=0, object=null; object=objects[xx]; xx++) {
				object.parentNode.removeChild(object); // self-destruct (it'll come back from a replaced innerHTML)
			}
			ffwMediaplex.nowShowing.innerHTML = '';
		}
	}
	
}

if (bv && bv.event) bv.event.add(window, "domready", ffwMediaplex.init);

/* ... /packer:END(ffwMediaplex.js) */
/* (13) packer:START(ffwComments.js) ... */


var ffwComments = {

	maxTags : 2,

	init : function (el) { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		var Cmt = document.getElementById('postList');
		if (!Cmt) return;
		else {
			var Root = document.getElementById('comments');
			Root.ffwComments = { trg : Root, collapsed : false };
			Root.toggle = ffwComments.toggleAll;
			var Els = Cmt.getElementsByTagName('li');
			for (var xx=0; xx<Els.length; xx++) {
				var SubjLink = bv.dom.getElementsByClassName(Els[xx], 'div', 'postSubject')[0].getElementsByTagName('a')[0];
				var Parts = SubjLink.href.match(/\/([^\/]+)\/([^\/]+)\/(\d+)\/\#/);
				if (!Parts || Parts.length != 4 || typeof parseInt(Parts[3]) != 'number') continue;
				Els[xx].ffwComments = { trg : Els[xx], collapsed : false, type : (Parts[2] == "Post") ? 'p':'c', id : parseInt(Parts[3]) };
				Els[xx].toggle = ffwComments.toggle;
				SubjLink.ffwComments = { trg : Els[xx] };
				if (Els[xx].className.match(/\bpostThread\b/)) {
					bv.event.add(SubjLink, 'click', ffwComments.toggleAll);
					var Div = document.createElement('div');
					Div.className = 'postThreadToggle';
					Div.ffwComments = { trg : Els[xx] };
					var Ln = Els[xx].getElementsByTagName('a');
					Ln[Ln.length -1].appendChild(Div);
					bv.event.add(Div, 'click', ffwComments.toggleAll);
				} else {
					bv.event.add(SubjLink, 'click', ffwComments.toggle);
				}
			}
/* toggles the whole list
			var UberToggles = bv.dom.getElementsByClassName(Root.getElementsByTagName('h4')[0], 'img', 'cmtControl');
			for (var xx=0; xx<UberToggles.length; xx++) {
				UberToggles[xx].ffwComments = { trg : Root };
				bv.event.add(UberToggles[xx], 'click', ffwComments.toggleAll);
			}
*/
			if (Root.className.match(/\bcmtDefaultCollapsed\b/)) Root.toggle();
		}
		
		var PostForm = document.getElementById('postForm');
		if (PostForm) bv.event.add(PostForm, 'submit', ffwComments.checkValidPost);
		var TagGroup = document.getElementById('postTagGroup');
		if (TagGroup) {
			TagGroup.ffwComments = {
				max : ffwComments.maxTags,
				tags : TagGroup.getElementsByTagName('input')
			};
			for (var xx=0; xx<TagGroup.ffwComments.tags.length; xx++) {
				TagGroup.ffwComments.tags[xx].ffwComments = { trg : TagGroup };
				bv.event.add(TagGroup.ffwComments.tags[xx], 'click', ffwComments.checkMaxTags);
			}
		}
	},
	
	checkValidPost : function () {
		if (this.postSubject.value == '') {
			alert('You must enter a subject for your post.')
			this.postSubject.focus();
			return false;
		}
	}, // END: checkValidPost
	
	checkMaxTags : function () {
		if (!this.checked) return true; // always allow uncheck
		var Cnt = 0;
		var Trg = this.ffwComments.trg;
		for (var xx=0; xx<Trg.ffwComments.tags.length; xx++) {
			if (Trg.ffwComments.tags[xx].checked) Cnt++;
		}
		if (Cnt > Trg.ffwComments.max) {
			alert('You may only select a maximum of '+ Trg.ffwComments.max +' tags for your post. Before selecting this tag, you must uncheck one of the currently selected tags.');
			return false;
		} else return true;
	}, // END: checkMaxTags
	
	toggleAll : function (ExpandCollapse) {
		var Trg = this.ffwComments.trg;
		if (typeof ExpandCollapse != 'string' || !ExpandCollapse.match(/^(expand|collapse)$/)) {
			ExpandCollapse = (Trg.ffwComments.collapsed) ? 'expand' : 'collapse';
		}
		if (ExpandCollapse == "collapse") {
			bv.css.addClass(Trg, "collapse");
			Trg.ffwComments.collapsed = true;
		} else {
			bv.css.removeClass(Trg, "collapse");
			Trg.ffwComments.collapsed = false;
			if (Trg.ffwComments.type == 'p' && !Trg.ffwComments.ping) {
				Trg.ffwComments.ping = new Image();
				Trg.ffwComments.ping.src = '/index.php?eID=ffw&id='+Trg.ffwComments.id+'&action=pRead';
			}
		}
		var Els = Trg.getElementsByTagName('li');
		for (var xx=0; xx<Els.length; xx++)
			if (Els[xx].ffwComments) Els[xx].toggle(ExpandCollapse);
		return false;
	}, // END: toggleAll

	toggle : function (ExpandCollapse) {
		var Trg = this.ffwComments.trg;
		var DirectCall = typeof ExpandCollapse != 'string';
		if (typeof ExpandCollapse != 'string' || !ExpandCollapse.match(/^(expand|collapse)$/)) {
			ExpandCollapse = (Trg.ffwComments.collapsed) ? 'expand' : 'collapse';
		}
		if (ExpandCollapse == "collapse") {
			bv.css.addClass(Trg, "collapse");
			Trg.ffwComments.collapsed = true;
		} else {
			bv.css.removeClass(Trg, "collapse");
			Trg.ffwComments.collapsed = false;
			if (!Trg.ffwComments.ping && (Trg.ffwComments.type == 'p' || DirectCall)) {
				Trg.ffwComments.ping = new Image();
				Trg.ffwComments.ping.src = '/index.php?eID=ffw&id='+Trg.ffwComments.id+'&action='+Trg.ffwComments.type+'Read';
			}
		}
		return false;
	} // END: toggle

}

if (bv && bv.event) bv.event.add(window, "domready", ffwComments.init, "priority");

/* ... /packer:END(ffwComments.js) */
/* (14) packer:START(ffwCallFestival.js) ... */


var ffwCallFestival = {

	View : null,
	Viewtop : 0,
	ViewAt : 0,
	PrevViews : {},

	configure : function (name, value) {
		if (typeof ffwCallFestival[name] == typeof value)
			ffwCallFestival[name] = value;
		else if (bv) bv.debug.msg('type mismatch in call to configure(): '+ name +'::'+ value, 'ffwCallFestival');
	},

	init : function (el) { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		var Src = document.getElementById('festListByCountry') || document.getElementById('calTrg');
		if (Src) {
			if (location.hash.length < 3 || /\bpreset\b/.test(location.hash))
				location.hash = 'start'; // prevent a jump to the top if scrolled down w/o existing hash
			ffwCallFestival.View = document.createElement('div');
			document.getElementById('contentGroup').appendChild(ffwCallFestival.View);
			ffwCallFestival.View.id = 'festTrg';
			ffwCallFestival.LoadView = document.createElement('div');
			document.getElementById('contentGroup').appendChild(ffwCallFestival.LoadView);
			ffwCallFestival.LoadView.style.clear = 'both';
			ffwCallFestival.LoadView.style.display = 'none';
			ffwCallFestival.LoadView.style.textAlign = 'center';
			ffwCallFestival.LoadView.style.padding = '100px';
			ffwCallFestival.LoadView.style.height = '800px';
			ffwCallFestival.LoadView.style.background = '#fff url(/fileadmin/img/icons/ajax_loading_apple_spinner.gif) 50% 15% no-repeat';
			var A = Src.getElementsByTagName('a');
			var StartWith = null;
			for (var xx=0; xx<A.length; xx++) {
				var Fest = A[xx].href.match(/\/festival\/([\w_-]+)\/?/i);
				if (Fest && Fest[1]) {
					A[xx].ffwCallFestival = { trg : Fest[1] };
					bv.event.add(A[xx], 'click', ffwCallFestival.call);
					if (location.href.substring(location.href.indexOf('#') +1) == Fest[1])
						StartWith = A[xx];
				}
			}
		}
	},
	
	call : function () {
		if (bv.ajax && bv.ajax.isAvailable && this.ffwCallFestival) {
			var id  = this.ffwCallFestival.trg.toLowerCase();
			var src = "/core/Festival/"+ this.ffwCallFestival.trg +"/c.html?cachebuster="+ Date.parse(new Date());
			bv.ajax.history.make(id, function () { ffwCallFestival.callHandler(id, src); });
			this.blur(); // prevent scroll-wheel from scrolling the bvScroll div after clicking gives it focus
			return false;
		}
	},
	callPreset : function (src) {
		bv.event.add(window, 'load', function () {
			if (bv.ajax && bv.ajax.isAvailable) {
				bv.ajax.history.make('preset', function () {
					ffwCallFestival.callHandler('preset', '/core/Festival/'+ src +'/c.html?cachebuster='+ Date.parse(new Date()) );
				} );
			}
		} );
	},
	callHandler : function (id, src) {
		ffwCallFestival.Viewtop = bv.css.getOffset(ffwCallFestival.View).top;
		if (ffwCallFestival.PrevViews[id]) {
			ffwCallFestival.pageLoaded(ffwCallFestival.PrevViews[id], '', {url:src});
		} else {
			bv.ajax.pronto(
				src,
				{
					success : ffwCallFestival.pageLoaded,
					loading : ffwCallFestival.pageLoading,
					error   : ffwCallFestival.pageLoadError
				}
			);
		}
	},
	
	pageLoaded : function (txt, xml, obj) {
//		var id = obj.url.substring(obj.url.lastIndexOf('=') +1);
		var PathInfo = obj.url.match(/\/Festival\/([^\/]+)\/c.html/i);
		if (!PathInfo || !PathInfo[1]) return;
		var id = PathInfo[1].toLowerCase();
		ffwCallFestival.View.innerHTML = txt;
		ffwCallFestival.PrevViews[id]  = txt;
		
		ffwCallFestival.View.style.display = 'block';
		ffwCallFestival.LoadView.style.display = 'none';
		
		// if the window hasn't scrolled to the goal, but is where we left it, try again
		if (
				ffwCallFestival.ViewAt != ffwCallFestival.Viewtop
				&&
				ffwCallFestival.ViewAt == ffwCallFestival.getScroll()
			) ffwCallFestival.slowScroll();

	// add abilities that are normally added on dom load
		if (bvStickyWicket)       { bvStickyWicket.init('photoGallery','li'); }
		if (bvCollapse)           { bvCollapse.init(ffwCallFestival.View, 'div,p,dl'); }
		if (ffwComments)          { ffwComments.init(); }
		if (bvDimForm)            { bvDimForm.init(ffwCallFestival.View); }
		if (bvAttachValidWindows) { bvAttachValidWindows.init(ffwCallFestival.View); }
	},
	pageLoading : function (obj) {
		ffwCallFestival.LoadView.style.display = 'block';
		ffwCallFestival.View.style.display = 'none';
		ffwCallFestival.slowScroll();
	},
	pageLoadError : function (code, text, obj) {
	},
	
	slowScroll : function () {
		var Off = (ffwCallFestival.Viewtop - ffwCallFestival.getScroll())/10;
		Off = (Off < 0) ? Math.ceil(Off) : Math.floor(Off);
		ffwCallFestival.ViewAt = ffwCallFestival.getScroll();
		window.scrollTo(0, Off + ffwCallFestival.getScroll());
	// if you have moved, try to move again
		if (ffwCallFestival.ViewAt != ffwCallFestival.getScroll())
			setTimeout('ffwCallFestival.slowScroll();', 5);
	},
	
	getScroll : function () { // ffwCallFestival.getScroll();
		var Top = 0;
		if (typeof window.scrollY == 'number' && window.scrollY > 0)
			Top = window.scrollY;
		else if (typeof document.documentElement.scrollTop == 'number' && document.documentElement.scrollTop > 0)
			Top = document.documentElement.scrollTop;
		else if (typeof document.body.scrollTop == 'number' && document.body.scrollTop > 0)
			Top = document.body.scrollTop;
		return Top;
	},
	
	complete : true
}

if (bv && bv.event) bv.event.add(window, "domready", ffwCallFestival.init);


/* ... /packer:END(ffwCallFestival.js) */
/* (15) packer:START(bvTabber.js) ... */

var bvTabber = {
	
	init : function () {
		var dl = document.getElementsByTagName('dl');
		for (var xx=0; xx<dl.length; xx++) {
			if (/\bbvTabber\b/.test(dl[xx].className)) {
				dl[xx].bvTabber_last = '';
				var dt = dl[xx].getElementsByTagName('dt');
				for (var ii=0; ii<dt.length; ii++) {
					dt[ii].bvTabber_tab = dl[xx];
					dt[ii].bvTabber_grp = dt[ii].className.substring(3);
					if (dl[xx].className.indexOf('tabberShow' + dt[ii].bvTabber_grp) != -1) {
						bv.css.removeClass(dl[xx], dl[xx].bvTabber_last);
						dl[xx].bvTabber_last = dt[ii].bvTabber_grp;
					}
					bv.event.add(dt[ii], 'mousedown', bvTabber.cancel);
					bv.event.add(dt[ii], 'click', bvTabber.toggle);
				}
			}
		}
	}, // END: init
	
	toggle : function (e) {
		if (e.target.nodeName.toLowerCase() == 'a') return;
		bv.css.removeClass(this.bvTabber_tab, 'tabberShow'+ this.bvTabber_tab.bvTabber_last);
		this.bvTabber_tab.bvTabber_last = this.bvTabber_grp;
		bv.css.addClass(this.bvTabber_tab, 'tabberShow'+ this.bvTabber_tab.bvTabber_last);
	}, // END: toggle
	
	cancel : function () { return false; },

	complete : true
};

if (bv && bv.event) bv.event.add(window, 'domready', bvTabber.init);






/* ... /packer:END(bvTabber.js) */
/* (16) packer:START(bvCollapse.js) ... */


var bvCollapse = {

	TrgEls  : 'div',

	configure : function (name, value) {
		if (typeof bvCollapse[name] == typeof value)
			bvCollapse[name] = value;
		else if (bv) bv.debug.msg('type mismatch in call to configure(): '+ name +'::'+ value, 'bvCollapse');
	},

	init : function (el,TagsIn) { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		var Trg = (el) ? el : document;
		var Tags= (TagsIn) ? TagsIn : bvCollapse.TrgEls;
		var Els = bv.dom.getElementsByClassName(Trg, Tags, 'bvCollapse');
		for (var xx=0; xx<Els.length; xx++) {
			Els[xx].bvCollapse = /\bbvCollapseShow\b/.test(Els[xx].className);
			Els[xx].bvCollapseOnce = /\bbvCollapseOnce\b/.test(Els[xx].className);
			Els[xx].bvCollapseToggle = bvCollapse.toggle;
			bv.event.add(Els[xx], 'click', function () { this.bvCollapseToggle(); } );
		}
	},
		
	toggle : function () {
		if (!this.bvCollapse) {
			this.bvCollapse = true;
			bv.css.addClass(this, 'bvCollapseShow');
		} else {
			this.bvCollapse = false;
			bv.css.removeClass(this, 'bvCollapseShow');
		}
		if (this.bvCollapseOnce) this.bvCollapseToggle = function () {};
	}

}

if (bv && bv.event) bv.event.add(window, "domready", bvCollapse.init);

/* ... /packer:END(bvCollapse.js) */
/* (17) packer:START(ffwFloatNav.js) ... */


var ffwFloatNav = {
	
	timer : null,
	trg : null,
	getScrollOffset : function () {},
	getDocumentHeight : function () {},
	was : 0,
	top : 223,
	bottom : 0,
	floor : 0,
	at : 223,
	height : null,

	init : function () {
		ffwFloatNav.trg = document.getElementById('navFloater');
		if (ffwFloatNav.trg) {
			ffwFloatNav.getScrollOffset = null;
			if (typeof window.pageYOffset == 'number') {
				ffwFloatNav.getScrollOffset = ffwFloatNav.readOldNetscapeScroll;
				ffwFloatNav.getDocumentHeight = ffwFloatNav.readECMADocumentHeight;
			} else if (document.all && typeof document.body.scrollTop == 'number') {
				ffwFloatNav.getScrollOffset = ffwFloatNav.readIEScroll;
				ffwFloatNav.getDocumentHeight = ffwFloatNav.readIEDocumentHeight;
			} else if (document.documentElement && typeof document.documentElement.scrollTop == 'number') {
				ffwFloatNav.getScrollOffset = ffwFloatNav.readECMAScroll;
				ffwFloatNav.getDocumentHeight = ffwFloatNav.readECMADocumentHeight;
			}
			if (! ffwFloatNav.getScrollOffset) {
				ffwFloatNav.getScrollOffset = function () {};
				return;
			}

			bv.css.addClass(document.getElementsByTagName('body')[0], 'navFloating');
			bv.event.add(window, 'resize', ffwFloatNav.readBaseline);
			bv.event.add(window, 'scroll', ffwFloatNav.checkScroll);
			bv.event.add(window, 'load', ffwFloatNav.checkScroll); // in case we entered the page already scrolled
		}
	}, // END: init
	
	readECMAScroll : function () {
		return document.documentElement.scrollTop;
	},
	readIEScroll : function () {
		return document.body.scrollTop || document.documentElement.scrollTop;
	},
	readOldNetscapeScroll : function () {
		return window.pageYOffset;
	},
	
	readECMADocumentHeight : function () {
		return document.body.offsetHeight;
	},
	readIEDocumentHeight : function () {
		return document.body.scrollHeight;
	},
	

	readBaseline : function () {
		ffwFloatNav.height = bv.css.getWindowSize().h;
		ffwFloatNav.bottom = Math.min(0, ffwFloatNav.height - ffwFloatNav.trg.offsetHeight -20);
		ffwFloatNav.floor = (ffwFloatNav.bottom && null != (g = document.getElementById('contentGroup'))) ? 10 + ffwFloatNav.getDocumentHeight() - (bv.css.getOffsetFromRoot(g).top + g.offsetHeight) : 0;
		ffwFloatNav.checkScroll();
	}, // END: readBaseline


	checkScroll : function () {
		if (ffwFloatNav.height === null) {
			ffwFloatNav.readBaseline();
			return;
		}
		var ScrollDiff = ffwFloatNav.getScrollOffset() - ffwFloatNav.was;

		if (ffwFloatNav.getScrollOffset() < ffwFloatNav.top) { // near the top
			ffwFloatNav.at = Math.min(ffwFloatNav.top - ffwFloatNav.getScrollOffset(), ffwFloatNav.at - ScrollDiff);
		} else if (ffwFloatNav.getScrollOffset() > ffwFloatNav.getDocumentHeight() - ffwFloatNav.height - ffwFloatNav.floor) { // near the bottom
			ffwFloatNav.at = Math.max(ffwFloatNav.bottom - ffwFloatNav.floor, ffwFloatNav.at - ScrollDiff);
		} else {
			if (ScrollDiff < 0) { // scrolling up
				if (ffwFloatNav.at < ffwFloatNav.top) {
					ffwFloatNav.at = Math.min(0, ffwFloatNav.at - ScrollDiff);
				}
			} else { // scrolling down
				if (ffwFloatNav.at > ffwFloatNav.bottom) {
					ffwFloatNav.at = Math.max(ffwFloatNav.bottom, ffwFloatNav.at - ScrollDiff);
				}
			}
		}
		
		ffwFloatNav.trg.style.marginTop = ffwFloatNav.at +'px';
		ffwFloatNav.was = ffwFloatNav.getScrollOffset();
	}, // END: checkScroll


	complete : true
}

bv.event.add(window, 'domready', ffwFloatNav.init);
bv.event.add(window, 'load', function () { if (ffwFloatNav.trg) ffwFloatNav.checkScroll() } );

bv.event.add(window, 'domready', function () {
		if (document.getElementById('navFloater')) {
			ffwTopNav.init('navSearchBy');
		}
	}, 'priority' ); // this needs to come before the regular init, so that it resizes before it gets measured

/* ... /packer:END(ffwFloatNav.js) */
/* (18) packer:START(bvStickyWicket.js) ... */


var bvStickyWicket = {

	wickets : {},
	addWicket : function (id, trgEl) {
		bvStickyWicket.wickets[id] = trgEl;
	},

	init : function (TrgOverride,TagsIn) { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		var Trg = bvStickyWicket.wickets;
		if (TrgOverride) {
			Trg = {};
			Trg[TrgOverride] = TagsIn;
		}
		for (Id in Trg) {
			var Field = document.getElementById(Id);
			if (!Field) continue;
			Field.bvStickyWicket_prev = false;
			var Players = Field.getElementsByTagName(Trg[Id]);
			for (var xx=0; xx<Players.length; xx++) {
				if (Players[xx].bvStickyWicket_field) continue;
				Players[xx].bvStickyWicket_field = Field;
				bv.event.add(Players[xx], 'mouseover', bvStickyWicket.take);
				if ((/\bbvStickyWicketStuck\b/).test(Players[xx].className)) {
					if (Field.bvStickyWicket_prev)
						bv.css.removeClass(Field.bvStickyWicket_prev, 'bvStickyWicketStuck');
					bv.css.addClass(Players[xx], 'bvStickyWicketStuck');
					Field.bvStickyWicket_prev = Players[xx];
				}
			}
		}
	},

	take : function () {
		if (this.bvStickyWicket_field.bvStickyWicket_prev)
			bv.css.removeClass(this.bvStickyWicket_field.bvStickyWicket_prev, 'bvStickyWicketStuck');
		bv.css.addClass(this, 'bvStickyWicketStuck');
		this.bvStickyWicket_field.bvStickyWicket_prev = this;
	}
	
}

if (bv && bv.event) bv.event.add(window, "domready", bvStickyWicket.init);

/* ... /packer:END(bvStickyWicket.js) */
/* (19) packer:START(bvMiniPage.js) ... */


var bvMiniPage = {

	Trg : null,
	goalSize : { w:800, h:100 },
	step : 10,
	timer : null,

	init : function () {
		if (!bv) return; // require bv_utilities.js
		try {
			var Body = document.getElementsByTagName('body')[0];
			bvMiniPage.Trg = document.getElementById('wrap');
		} catch (e) {
			return false;
		}
		
		if (bvMiniPage.Trg && Body && /\bbvMinimize\b/.test(Body.className)) {
			bvMiniPage.resize();
			setTimeout(bvMiniPage.check, 15); // some time for the page to layout
			bv.event.add(window, 'load', bvMiniPage.check); // in case the layout changes
			if (window.opener && ! window.opener.name) {
				window.opener.name = 'base'+ parseInt(Math.random() *10000);
			}
			var A = document.getElementsByTagName('a');
			for (var xx=0, el; el = A[xx]; xx++) {
				if (el.href && /^(http|\/)/.test(el.href.toLowerCase()) && ! el.getAttribute('rel') && ! el.getAttribute('target')) {
					el.target = (window.opener) ? window.opener.name : '_blank';
					bv.event.add(el, 'click', function () { top.blur(); setTimeout('top.close();', 5000); } );
				}
			}
		}
	},
	
	check : function () {
		var oldSize = bvMiniPage.goalSize;
		bvMiniPage.Trg.style.width = 'auto';
		var trgSize = { w:bvMiniPage.Trg.offsetWidth +45, h:bvMiniPage.Trg.offsetHeight +55 }
		bvMiniPage.Trg.style.width = '';
		bvMiniPage.goalSize = {
			w:parseInt(Math.max(300,Math.min(Math.max(800,screen.availWidth *0.8),trgSize.w)))  +35,
			h:parseInt(Math.max(150,Math.min(Math.max(500,screen.availHeight *0.8),trgSize.h))) +20
		}
	// only resize if the content actually changed size
		if (oldSize.w != bvMiniPage.goalSize.w || oldSize.h != bvMiniPage.goalSize.h)
			bvMiniPage.resize();
	}, // END: check
	
	resize : function () {
		window.resizeTo(bvMiniPage.goalSize.w,bvMiniPage.goalSize.h);
		if (location.hash) {
			var Trg = document.getElementById(location.hash.replace(/[^\w\d\-_]/, ''));
			if (Trg) {
				setTimeout('self.scrollTo(0, '+ bv.css.getOffset(Trg).top +');', 10);
			}
		}
	}, // END: resize


	complete : true
}

if (bv && bv.event) bv.event.add(window, "domready", bvMiniPage.init);

/* ... /packer:END(bvMiniPage.js) */
/* (20) packer:START(bvAttachValidWindows.js) ... */


var bvAttachValidWindows = {
	type : {
		newwin : {
			win : 'bvwin',
			viewerLocation : '',
			queryAppend : '',
			params : '',
			rtn : false
		}
	},
	
	addType : function (Obj) {
		for (var Key in Obj) {
			bvAttachValidWindows.type[Key] = {
				win : 'bv',
				viewerLocation : '',
				queryAppend : '',
				params : '',
				rtn : true
			};
			for (var Param in Obj[Key]) {
				bvAttachValidWindows.type[Key][Param] = Obj[Key][Param];
			}
		}
	}, 
	
	init : function (el) {
		var Trg = (el) ? el : document;
		var As = Trg.getElementsByTagName('a');
		for (var xx=0; xx<As.length; xx++) {
			var rel = As[xx].getAttribute('rel');
			if (!rel) continue;
			var rels = rel.split(" ");
			for (var ii=0; ii<rels.length; ii++) {
				var Key = rels[ii];
				if (bvAttachValidWindows.type[Key]) {
					As[xx].bvAttachedWindow = bvAttachValidWindows.type[Key];
					bv.event.add(As[xx], 'click', function () {
						if (! this.bvAttachedWindow.queryAppend || this.bvAttachedWindow.queryAppend == '') {
							var href = this.bvAttachedWindow.viewerLocation + this.href;
						} else {
							var sep = (this.href.indexOf('?') > -1) ? '&' : '?';
							var href = this.bvAttachedWindow.viewerLocation + this.href;
							if (href.indexOf('#') > -1) {
								var pre  = href.substring(0, href.indexOf('#'));
								var post = href.substring(href.indexOf('#'));
							} else {
								var pre  = href;
								var post = '';
							}
							href = pre + sep + this.bvAttachedWindow.queryAppend + post;
						}
						window.open(href, this.bvAttachedWindow.win, this.bvAttachedWindow.params).focus();
						return this.bvAttachedWindow.rtn;
					} );
				}
			}
		}
	}

}

if (window.bv && bv.event) bv.event.add(window, 'domready', bvAttachValidWindows.init );

/* ... /packer:END(bvAttachValidWindows.js) */
/* (21) packer:START(ffwListGenreFilter.js) ... */


var ffwListGenreFilter = {

	genres : [ 'Label', 'All', 'Ani', 'Chi', 'Com', 'Doc', 'Dra', 'Exp', 'GLBT', 'Sci-Fi', 'TV' ],
	selectBox : null,

	configure : function (name, value) {
		if (typeof ffwListGenreFilter[name] == typeof value)
			ffwListGenreFilter[name] = value;
		else if (bv) bv.debug.msg('type mismatch in call to configure(): '+ name +'::'+ value, 'ffwListGenreFilter');
	},

	init : function () { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		var OLs = document.getElementsByTagName('ol');
		for (var xx=0; xx<OLs.length; xx++) {
			if (/\bGenreFilterList\b/.test(OLs[xx].className)) {
				if (!ffwListGenreFilter.selectBox) ffwListGenreFilter.makeSelectBoxTmpl();
	
				bv.css.addClass(OLs[xx], 'GenreFilterListActive showAll');
				var Box = ffwListGenreFilter.selectBox.cloneNode(true);
				OLs[xx].appendChild(Box);
				var Lead = document.createElement('li');
				Lead.className = 'genreListLead';
				OLs[xx].insertBefore(Lead,OLs[xx].firstChild);
				var Last = document.createElement('li');
				Last.className = 'genreListLast';
				OLs[xx].appendChild(Last);
				var Li = Box.childNodes;
				for (var ii=0; ii<Li.length; ii++) {
					Li[ii].genreFilter = { host:OLs[xx] };
					bv.event.add(Li[ii], 'click', ffwListGenreFilter.box.filter);
					bv.event.add(Li[ii], 'mouseover', ffwListGenreFilter.box.preview);
					bv.event.add(Li[ii], 'mouseout', ffwListGenreFilter.box.unPreview);
				}
				OLs[xx].genreFilter = {
					state:0,
					setHeight:null,
					lead:Lead,
					last:Last,
					current:'showAll',
					baseFilter:'showAll',
					origClass:OLs[xx].className,
					interval:null
				};
			}
		}
	},
	
	makeSelectBoxTmpl : function () {
		var Box = document.createElement('li');
		Box.className = 'controller controlTop controlGenreFilter';
		var item = document.createElement('div');
		for (var xx=0; xx<ffwListGenreFilter.genres.length; xx++) {
			var G = item.cloneNode(true);
			G.className = 'filter'+ ffwListGenreFilter.genres[xx];
			Box.appendChild(G);
		}
		ffwListGenreFilter.selectBox = Box;
	},
	
	box : {
		filter : function () {
			// a div was clicked; figure out which
			if (/Label/.test(this.className)) return;
			if (/\bfilter[\w-]+\b/.test(this.className))
				var newFilter = 'show'+ this.className.substring(6);
			else var newFilter = 'showAll';
			var List = this.genreFilter.host;
			if (typeof List.genreFilter.setHeight != 'number') {
				List.genreFilter.setHeight = List.offsetHeight -1;
				List.style.height = List.genreFilter.setHeight +'px';
			}
			bv.css.removeClass(List, List.genreFilter.current);
			bv.css.addClass(List, newFilter);
			List.genreFilter.current = newFilter;
			if (List.ScrollList && List.ScrollList.active) {
				List.ScrollList.homeTrg = List.ScrollList.homePos = 0;
				List.ScrollList.lead.style.marginTop = '-1px'; // Safari fix, which doesn't like 0px'
				List.ScrollList.height = bv.css.getOffset(List.genreFilter.last).top + List.ScrollList.controlBottom.offsetHeight;
			}
		}, //END: box.filter

		preview : function () {
			bv.css.addClass(this, 'genreFilterPreview');
		}, //END: box.preview
		unPreview : function () {
			bv.css.removeClass(this, 'genreFilterPreview');
		} //END: box.unPreview
	}, //END: box
	
	complete : true
}

if (bv && bv.event) bv.event.add(window, "domready", ffwListGenreFilter.init);



/* ... /packer:END(ffwListGenreFilter.js) */
/* (22) packer:START(ffwTableScroller.js) ... */


var ffwTableScroller = {

	tables : { all : []},
	rate   : 1,
	smooth : 1,

	configure : function (name, value) {
		if (typeof ffwTableScroller[name] == typeof value)
			ffwTableScroller[name] = value;
		else if (bv) bv.debug.msg('type mismatch in call to configure(): '+ name +'::'+ value, 'ffwTableScroller');
	},

	init : function (elOverride) { // verify ability, find targetted tables
		if (!bv) return; // require bv_utilities.js
		var el = (elOverride) ? elOverride : document;
		var Ts = el.getElementsByTagName('table');
		var Found = [];
		for (var xx=0; xx<Ts.length; xx++) {
			if (/\bScrollTable\b/.test(Ts[xx].className)) {
				Found.push(Ts[xx]);
			}
		}
	// separate the finding from the making, since making *doubles* the number of tables
		for (var xx=0; xx<Found.length; xx++) {
			var rtn = ffwTableScroller.make(Found[xx]);
			if (rtn) {
				ffwTableScroller.tables[rtn.id] = rtn;
				ffwTableScroller.tables.all.push(rtn);
			}
		}
		return Found;
	},


	make : function (T) {
		T.ScrollTable = { foo:'bar'};
	
		var THead = T.getElementsByTagName('thead');
		T.THead = (THead && THead[0]) ? THead[0] : null;
		var TBody = T.getElementsByTagName('tbody');
		T.TBody = (TBody && TBody[0]) ? TBody[0] : null;

		var CropSize = ffwTableScroller.measure(T);
		if (CropSize == 0) return undefined;

		var Master = ffwTableScroller.breakTable(T);
		Master.ScrollTable = T.ScrollTable;
		Master.ScrollTable.rows = Master.getElementsByTagName('tr');
		Master.ScrollTable.lead = Master.ScrollTable.rows[0];
		Master.ScrollTable.last = Master.ScrollTable.rows[Master.ScrollTable.rows.length -2]; // "2", because the last one is the column-sizer; not true if there are nested tables in the last row of Master...
		bv.css.addClass(Master.ScrollTable.lead, 'firstInLine');
		bv.css.addClass(Master.ScrollTable.last, 'lastInLine');

	// create a div, add it before the body table, size it, then stick the body table in it
		var D = document.createElement('div');
		D.className = "ScrollTableContainer";
		D.style.height = (CropSize +1) +'px';
		D.ScrollTable = T.ScrollTable;
		Master.parentNode.insertBefore(D,Master).appendChild(Master);

		ffwTableScroller.addControllerArrows(D);
	
		T.ScrollTable.id      = 'tbl'+ bv.getNewGuid();
		T.ScrollTable.master  = Master;
		T.ScrollTable.height  = bv.css.getOffset(T.ScrollTable.last.childNodes[0], T.ScrollTable.lead.childNodes[0]).top + T.ScrollTable.last.childNodes[0].offsetHeight;
		T.ScrollTable.window  = CropSize;
		T.ScrollTable.homePos = 0;
		T.ScrollTable.homeTrg = 0;
		T.ScrollTable.rate    = ffwTableScroller.rate;
		T.ScrollTable.goHome  = ffwTableScroller.generalHome;
		return T.ScrollTable;
	}, // END: make
	
	measure : function (T) {
		var Height = 0;
		var Parent = (T.TBody && T.TBody[0]) ? TBody[0] : T;
		bv.css.addClass(T, 'ScrollTableActive');
		var Trg = T.className.match(/\bScrollTableTrg-([^ ]+)/);
		if (Trg && Trg.length && /^\d+px$/.test(Trg[1])) {
			if (Parent.offsetHeight > parseInt(Trg[1]))
				Height = parseInt(Trg[1]);
		} else if (Trg && Trg.length && /^\d+$/.test(Trg[1])) {
			var TRs = Parent.getElementsByTagName('tr');
			if (TRs && TRs.length > parseInt(Trg[1]))
				Height = bv.css.getOffset(TRs[parseInt(Trg[1])].childNodes[0],TRs[0].childNodes[0]).top;
		}
		if (Height == 0) bv.css.removeClass(T, 'ScrollTableActive');
		return Height;
	}, // END: measure
	
	breakTable : function (T) {
		if (!T.THead) return T;

	// create a row to hold 0-height tds that fix the width of columns across two tables
		var tr = document.createElement('tr');
		T.THead.appendChild(tr);
	
	// TODO: compensate for colspans
		var child = T.THead.childNodes[0].firstChild;
		while (child) {
			if (child.nodeType == 1 && (/^t(h|d)$/i).test(child.nodeName)) { // an element node of type th ot td
				var td = document.createElement('td');
				td.style.width      = child.offsetWidth +'px';
				td.style.height     = '1px';
				td.style.overflow   = 'hidden';
				td.style.padding    = '0';
				td.style.margin     = '0';
				td.style.visibility = 'hidden';
				td.innerHTML = '<!-- empty -->';
				tr.appendChild(td);
			}
			child = child.nextSibling;
		}
		T.TBody.appendChild(tr.cloneNode(true));
	
	// move the body to the new table, since the old may have things like captions
		Tmp = T.cloneNode(false);
		T.parentNode.insertBefore(Tmp,T.nextSibling);
		T.style.marginBottom = '0px';
		Tmp.style.marginTop  = '0px';
		Tmp.appendChild(T.TBody);

		return Tmp;
	}, // END: breakTable
	
	addControllerArrows : function (D) {
		var control = document.createElement('div');
		control.className = 'controller controlBottom';
		var up = document.createElement('div');
		up.className = 'arrow arrowUp';
		var down = document.createElement('div');
		down.className = 'arrow arrowDown';

		control.appendChild(up);
		control.appendChild(down);
		D.appendChild(control);
		
		up.ScrollTable   = D.ScrollTable;
		down.ScrollTable = D.ScrollTable;
		
		bv.event.add(up,   'mousedown', ffwTableScroller.scrollArrow.press);
		bv.event.add(up,   'mouseup',   ffwTableScroller.scrollArrow.release);
		bv.event.add(down, 'mousedown', ffwTableScroller.scrollArrow.press);
		bv.event.add(down, 'mouseup',   ffwTableScroller.scrollArrow.release);
	}, // END: addControllerArrows


	scrollArrow : {
		press : function () {
			if (this.ScrollTable.interval) clearTimeout(this.ScrollTable.interval);
			this.ScrollTable.height = bv.css.getOffset(this.ScrollTable.last.childNodes[0], this.ScrollTable.lead.childNodes[0]).top + this.ScrollTable.last.childNodes[0].offsetHeight;
			var Mod = (this.className.indexOf('arrowUp') == -1) ? 1 : -1;
			ffwTableScroller.scrollArrow.set(this.ScrollTable, this.ScrollTable.homeTrg + (this.ScrollTable.rate * Mod), this.ScrollTable.rate * Mod);
			return false;
		}, // END: scrollArrow.press
		release : function () {
			if (this.ScrollTable.interval) clearTimeout(this.ScrollTable.interval);
			return false;
		}, // END: scrollArrow.release
		set : function (S, Val, recurBy) {
			if (Val + recurBy > S.height - S.window && Val < S.height - S.window)
				recurBy = S.height - S.window - Val;
			if (Val > S.height - S.window) {
				Val = Math.min(Val, S.homeTrg);
			}
			if (Val < 0) Val = 0;
			S.homeTrg = Val;
			S.goHome();
			if (typeof recurBy == 'number') {
				var Adj = (recurBy > 0) ? 1 : -1;
				S.interval = setTimeout('ffwTableScroller.scrollArrow.set(ffwTableScroller.tables["'+ S.id +'"], '+ (Val+recurBy) +', '+ (recurBy+Adj) +');', ffwTableScroller.rate);
			}
		} // END: scrollArrow.set
	}, // END: scrollArrow

	
	generalHome : function () {
		if (this.interval) clearTimeout(this.interval);
		if (ffwTableScroller.smooth == 1)
			this.homePos = this.homeTrg;
		else if (this.homeTrg != this.homePos) {
			this.interval = setTimeout('ffwTableScroller.tables["'+ this.list.id +'"].ScrollTable.goHome();',ffwTableScroller.rate);
			var Adjust = (this.homeTrg - this.homePos) / ffwTableScroller.smooth;
			if (Adjust > 0)
				this.homePos += Math.ceil(Adjust);
			else
				this.homePos += Math.floor(Adjust);
		}
		var Goto = (this.homePos == 0) ? 1 : this.homePos; // Safari fix, which seems to forget things if it's 0
		this.master.style.marginTop = (-1 * Goto) +'px';
	}, // END: generalHome
	
	complete : true
}

if (bv && bv.event) bv.event.add(window, "domready", ffwTableScroller.init);



/* ... /packer:END(ffwTableScroller.js) */
/* (23) packer:START(ffwListScroller.js) ... */


var ffwListScroller = {

	lists : {},
	rate : 40,
	smooth : 1,
	alphabet : 'abcdefghijklmnopqrstuvwxyz',
	alphaSize : { // to properly size the mouse-sensing divs so that they line up with the bg image
		'a':[9,15],
		'b':[6,15],
		'c':[6,15],
		'd':[6,15],
		'e':[6,15],
		'f':[5,15],
		'g':[6,15],
		'h':[6,15],
		'i':[4,15],
		'j':[6,15],
		'k':[6,15],
		'l':[7,15],
		'm':[8,15],
		'n':[7,15],
		'o':[6,15],
		'p':[6,15],
		'q':[6,15],
		'r':[7,15],
		's':[6,15],
		't':[6,15],
		'u':[6,15],
		'v':[8,15],
		'w':[8,15],
		'x':[7,15],
		'y':[7,15],
		'z':[11,15]
	},

	configure : function (name, value) {
		if (typeof ffwListScroller[name] == typeof value)
			ffwListScroller[name] = value;
		else if (bv) bv.debug.msg('type mismatch in call to configure(): '+ name +'::'+ value, 'ffwListScroller');
	},

	init : function (elOverride) { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		var el = (elOverride) ? elOverride : document;
		var OLs = el.getElementsByTagName('ol');
		var Lists = [];
		for (var xx=0; xx<OLs.length; xx++) {
			if (/\bScrollList\b/.test(OLs[xx].className)) {
				Lists.push(OLs[xx]);
				ffwListScroller.clear(OLs[xx]);
			}
		}
		return Lists;
	},
	
	clear : function (L, newClass) {
		var Type = 'AZ';
		if (/\bScrollListType-AZList\b/.test(L.className)) {
			Type = 'AZ';
		} else if (/\bScrollListType-Arrow\b/.test(L.className)) {
			Type = 'arrow';
		}
		if (L.ScrollList && L.ScrollList.origClass)
			L.className = L.ScrollList.origClass;
		L.ScrollList = {
				'list'      : L,
				'active'    : false,
				'type'      : Type,
				'origClass' : L.className,
				'setClass'  : L.className,
				'height'    : L.offsetHeight,
				'heightdiff': 0,
				'padding'   : 0,
				'last'      : L.lastChild,
				'items'     : [],
				'homeTrg'   : 0.5,
				'homePos'   : 0,
				'maxrange'  : 0,
				'base'      : null,
				'interval'  : null
			};
		for (var xx=0; xx<L.childNodes.length; xx++) {
			if (L.childNodes[xx].nodeType == 1 && L.childNodes[xx].nodeName.toLowerCase() == 'li') {
				L.ScrollList.items.push(L.childNodes[xx]);
				if (!/\bcontroller\b/.test(L.childNodes[xx].className)) {
					L.ScrollList.last = L.childNodes[xx];
					if (!L.ScrollList.lead) L.ScrollList.lead =  L.childNodes[xx];
				}
			}
		}
		if ((L.ScrollList.window = ffwListScroller.make.crop(L)) > 0) {
			ffwListScroller.lists[bv.getId(L)] = L;
			switch (L.ScrollList.type) {
				case "AZ" :
					L.ScrollList.lead = ffwListScroller.make.scanAZ(L);
					ffwListScroller.make.addAZControllers(L);
					L.ScrollList.goHome = ffwListScroller.generalHome;
					ffwListScroller.scrollAZ.set(L, true);
					break;
				case "arrow" :
					ffwListScroller.make.addArrowControllers(L);
					L.ScrollList.goHome = ffwListScroller.generalHome;
					ffwListScroller.scrollArrow.set(L, 0);
					break;
				default :
					break;
			}
		}
	},
	
	reset : function (L) {
		ffwListScroller.make.crop(L);
	}, //END:reset
	
	make : {
		crop : function (L) {
			bv.css.addClass(L, 'ScrollListActive');
			var Trg = L.className.match(/\bScrollListTrg-([^ ]+)/);
			if (Trg && Trg.length && /^\d+px$/.test(Trg[1])) {
				var BottomShouldBe = bv.css.getOffsetFromRoot(L).top + parseInt(Trg[1]);
			} else if (Trg && Trg.length && /^\d+$/.test(Trg[1])) {
				var Lis = L.getElementsByTagName('li');
				var BottomShouldBe = (Lis.length) ? bv.css.getOffsetFromRoot(Lis[Math.min(Lis.length -1, parseInt(Trg[1]) +1)]).top : 0;
			} else {
				var Match;
				if (
						( Trg && Trg.length && (Match = document.getElementById(Trg[1])) )
					||
						( Match = document.getElementById('contentGroup') )
				) {
					var BottomShouldBe = Match.offsetHeight + bv.css.getOffsetFromRoot(Match).top;
				} else {
					var BottomShouldBe = 0;
				}
			}
			if (BottomShouldBe == 0) return 0;

			var TopIs = bv.css.getOffsetFromRoot(L).top;
			var StyleHeight = parseInt(bv.css.getValue(L, 'height'));
			L.ScrollList.padding = L.offsetHeight - (isNaN(StyleHeight) ? L.offsetHeight : StyleHeight); // should properly handle this, regardless of box model corrections...
			L.ScrollList.heightdiff = Math.round(
				L.offsetHeight - 
				bv.css.getOffset(L.ScrollList.last,L.ScrollList.lead).top -
				L.ScrollList.last.offsetHeight
			);
	
			var GoalHeight = Math.max(BottomShouldBe - TopIs - L.ScrollList.padding, 25);
			if (L.offsetHeight > GoalHeight +30) {
				L.style.height = GoalHeight +'px';
				L.ScrollList.active = true;
				return GoalHeight;
			} else {
				L.ScrollList.active = false;
				bv.css.removeClass(L, 'ScrollListActive');
			}
			return 0;
		}, // END: make.crop
		
		scanAZ : function (L) {
			var LIs = L.getElementsByTagName('li');
			var prevEl = null;
			var prevAlpha = null;
			for (var Idx=0; Idx<LIs.length; Idx++) {
				var X = LIs[Idx].firstChild.innerHTML.charAt(0).toLowerCase();
				if (X != prevAlpha) {
					L.ScrollList[X] = {
						'first' : {
							'el'  : LIs[Idx],
							'top' : bv.css.getOffset(LIs[Idx]).top
						}
					};
					if (prevAlpha && prevEl) {
						L.ScrollList[prevAlpha].last = {
							'el'  : prevEl,
							'top' : bv.css.getOffset(prevEl).top
						};
						L.ScrollList[prevAlpha].range = L.ScrollList[prevAlpha].last.top - L.ScrollList[prevAlpha].first.top;
						L.ScrollList.maxrange = Math.max(L.ScrollList.maxrange, L.ScrollList[prevAlpha].range);
					}
				}
				if(L.ScrollList.base == null)
					L.ScrollList.base = bv.css.getOffset(LIs[Idx]).top;
				prevAlpha = X;
				prevEl = LIs[Idx];
			}
			L.ScrollList[prevAlpha].last = { // use prev values, because you can't be sure what the last one is
				'el'  : prevEl,
				'top' : bv.css.getOffset(prevEl).top
			}
			L.ScrollList['a'].first = { // reset the first one, to include all the non-alpha characters which might come before 'a'
				'el'  : LIs[0],
				'top' : 0
			}
			LIs[0].style.marginTop = '0px';
			if (L.ScrollList.maxrange > L.ScrollList.window) {
				L.ScrollList.window = L.ScrollList.maxrange + L.ScrollList.padding;
				L.style.height = L.ScrollList.window +'px';
			}
			return LIs[0];
		}, // END: make.scan
		
		addAZControllers : function (L) {
			var LI = document.createElement('li');
			var LIBot = LI.cloneNode(false);
			LI.ScrollList = L.ScrollList;
			LIBot.ScrollList = L.ScrollList;
			bv.event.add(LI, 'mouseout', ffwListScroller.displayAZ.reset);
			bv.event.add(LIBot, 'mouseout', ffwListScroller.displayAZ.reset);
			var BGOffset = 0;
			for (var xx=0; xx<ffwListScroller.alphabet.length; xx++) {
				var X = ffwListScroller.alphabet.charAt(xx);
				var DIV = document.createElement('div');
				DIV.className = X;
				DIV.style.width  = (ffwListScroller.alphaSize[X][0] +1) +'px';
				DIV.style.height = ffwListScroller.alphaSize[X][1] +'px';
				DIV.style.left   = (-1 * BGOffset) +'px';
				DIV.style.backgroundPosition = BGOffset +'px 0px';
				var DIVBot = DIV.cloneNode(false);
				DIV.ScrollList = L.ScrollList;
				DIVBot.ScrollList = L.ScrollList;
				LI.appendChild(DIV);
				LIBot.appendChild(DIVBot);
				bv.event.add(DIV, 'mouseover', ffwListScroller.scrollAZ.preview);
				bv.event.add(DIV, 'click', ffwListScroller.scrollAZ.call);
				bv.event.add(DIVBot, 'mouseover', ffwListScroller.scrollAZ.preview);
				bv.event.add(DIVBot, 'click', ffwListScroller.scrollAZ.call);
				BGOffset -= ffwListScroller.alphaSize[X][0];
			}
			bv.css.addClass(LI,'controller controlTop');
			bv.css.addClass(LIBot,'controller controlBottom');
			L.appendChild(LI);
			L.ScrollList.controlTop = LI;
			L.appendChild(LIBot);
			L.ScrollList.controlBottom = LIBot;
		}, // END: make.addAZControllers
		
		addArrowControllers : function (L) {
			var Set = L.className.match(/\bScrollListRate-([^ ]+)/);
			if (Set && Set.length && /^\d+$/.test(Set[1])) {
				L.ScrollList.rate = (Set.length) ? parseInt(Set[1]) : 5;
			} else {
				L.ScrollList.rate = 5;
			}
		
			var LI = document.createElement('li');
			LI.ScrollList = L.ScrollList;

			var DIVup   = document.createElement('div');
			var DIVdown = document.createElement('div');
			DIVup.className    = "arrowUp";
			DIVdown.className  = "arrowDown";
			DIVup.ScrollList   = L.ScrollList;
			DIVdown.ScrollList = L.ScrollList;

			LI.appendChild(DIVup);
			LI.appendChild(DIVdown);
			bv.event.add(DIVup,   'mousedown', ffwListScroller.scrollArrow.press);
			bv.event.add(DIVup,   'mouseup',   ffwListScroller.scrollArrow.release);
			bv.event.add(DIVdown, 'mousedown', ffwListScroller.scrollArrow.press);
			bv.event.add(DIVdown, 'mouseup',   ffwListScroller.scrollArrow.release);

			bv.css.addClass(LI,'controller controlBottom');
			L.appendChild(LI);
			L.ScrollList.controlBottom = LI;
		} // END: make.addArrowControllers
	}, // END: make

	displayAZ : {
		block : function (L,Top,Bot,FirstLast) {
			for (var xx=0; xx<ffwListScroller.alphabet.length; xx++) {
				var X = ffwListScroller.alphabet.charAt(xx);
				if (L.ScrollList[X] && L.ScrollList[X][FirstLast].top >= Top && L.ScrollList[X][FirstLast].top <= Bot)
					bv.css.addClass(L, 'AZListShow-'+X);
				else bv.css.removeClass(L, 'AZListShow-'+X);
			}
		}, // END: displayAZ.block
		reset : function () {
			this.ScrollList.list.className = this.ScrollList.setClass;
		}
	}, // END: displayAZ

	scrollAZ : {
		preview : function () {
			ffwListScroller.scrollAZ.set(this, false);
		}, // END: scrollAZ.preview
	
		call : function () {
			ffwListScroller.scrollAZ.set(this, true);
		}, // END: scrollAZ.call

		set : function (el,isSet) {
			var L = el.ScrollList.list;
			var CalledFrom = (/\bcontrolBottom\b/.test(el.parentNode.className)) ? 'last' : 'first';
			var CallTarget = (/^[a-z]$/.test(el.className)) ? el.className : 'a';
			if (L.ScrollList[CallTarget] && L.ScrollList[CallTarget][CalledFrom]) {
				if (CalledFrom == 'first')
					var Top = L.ScrollList[CallTarget][CalledFrom].top - L.ScrollList.base;
				else
					var Top = L.ScrollList[CallTarget][CalledFrom].top - L.ScrollList.window;
	
				if(L.ScrollList.homeTrg != Top) {
					if (Top > L.ScrollList.height - L.ScrollList.window) Top = L.ScrollList.height - L.ScrollList.window;
					if (Top < 0) Top = 0;
					var Bot = Top + L.ScrollList.window;
					ffwListScroller.displayAZ.block(L,Top,Bot,CalledFrom);
					if (isSet) {
						L.ScrollList.homeTrg = Top;
						L.ScrollList.setClass = L.className;
						L.ScrollList.goHome();
					}
				}
			}
		} // END: scrollAZ.set
	}, // END: scrollAZ
	
	scrollArrow : {
		press : function () {
			if (this.ScrollList.interval) clearTimeout(this.ScrollList.interval);

		// in case something has changed the height since the last scrolling
			this.ScrollList.height = 
				bv.css.getOffset(this.ScrollList.last,this.ScrollList.lead).top +
				this.ScrollList.last.offsetHeight +
				this.ScrollList.controlBottom.offsetHeight;
// alert(this.ScrollList.height+' = '+bv.css.getOffset(this.ScrollList.last).top+' - '+bv.css.getOffset(this.ScrollList.lead).top+' + '+this.ScrollList.last.offsetHeight+' + '+this.ScrollList.controlBottom.offsetHeight);
// alert(this.ScrollList.last.className+':'+this.ScrollList.lead.className);

			var Mod = (this.className.indexOf('arrowUp') == -1) ? 1 : -1;
			ffwListScroller.scrollArrow.set(this.ScrollList.list, this.ScrollList.homeTrg + (this.ScrollList.rate * Mod), this.ScrollList.rate * Mod);
			return false;
		}, // END: scrollArrow.press
		release : function () {
			if (this.ScrollList.interval) clearTimeout(this.ScrollList.interval);
			return false;
		}, // END: scrollArrow.release
		set : function (el, Val, recurBy) {
			if (Val + recurBy > el.ScrollList.height - el.ScrollList.window && Val < el.ScrollList.height - el.ScrollList.window)
				recurBy = el.ScrollList.height - el.ScrollList.window - Val;
			if (Val > el.ScrollList.height - el.ScrollList.window) {
				Val = Math.min(Val, el.ScrollList.homeTrg);
			}
			if (Val < 0) Val = 0;
			el.ScrollList.homeTrg = Val;
			el.ScrollList.goHome();
			if (typeof recurBy == 'number') {
				var Adj = (recurBy > 0) ? 1 : -1;
				el.ScrollList.interval = setTimeout('ffwListScroller.scrollArrow.set(ffwListScroller.lists["'+ el.id +'"], '+ (Val+recurBy) +', '+ (recurBy+Adj) +');', ffwListScroller.rate);
			}
		} // END: scrollArrow.set
	}, // END: scrollArrow
	
	jumpLink : function () {
		if (!(Id = this.href.match(/\#([\w\d_-]+)/)) || ! this.jump_trg || ! this.jump_trg.ScrollList) {
			return true;
		} else {
			return ffwListScroller.jumpTo(this.jump_trg, Id[1]);
		}
	},
	jumpTo : function (List, TrgId) {
		var Trg = document.getElementById(TrgId);
		if (List && List.ScrollList && Trg) {
			List.ScrollList.homeTrg = bv.css.getOffset(Trg, List.ScrollList.lead).top;
			List.ScrollList.goHome();
		}// else alert('failed:\n'+List+'\n'+List.ScrollList+'\n'+TrgId);
		return false;
	}, // END: jumpLink
	
	generalHome : function () {
		if (this.interval) clearTimeout(this.interval);
		if (ffwListScroller.smooth == 1)
			this.homePos = this.homeTrg;
		else if (this.homeTrg != this.homePos) {
			this.interval = setTimeout('ffwListScroller.lists["'+ this.list.id +'"].ScrollList.goHome();',ffwListScroller.rate);
			var Adjust = (this.homeTrg - this.homePos) / ffwListScroller.smooth;
			if (Adjust > 0)
				this.homePos += Math.ceil(Adjust);
			else
				this.homePos += Math.floor(Adjust);
		}
		var Goto = (this.homePos == 0) ? 1 : this.homePos; // Safari fix, which seems to forget things if it's 0
		this.lead.style.marginTop = (-1 * Goto) +'px';
	}, // END: generalHome
	
	complete : true
}

if (bv && bv.event) bv.event.add(window, "domready", ffwListScroller.init);



/* ... /packer:END(ffwListScroller.js) */
/* (24) packer:START(bvScrollBars.js) ... */

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
 * bvScrollBars, v1.1
 * (c) 2005 bivia.com
 * created by Ben Curtis of bivia.com, February 27 2005
 *   - revised for _bv_utilities, March 25, 2006
 *
 * Creates CSS-defined custom scrollbars for divs, 
 * for when overflow:auto|scroll is bad looking.
 *~~~~*/

var bvScrollBars = {

	model : document.createElement('div'),

	init : function () {
		if (navigator.appName == "Microsoft Internet Explorer" && navigator.platform == "MacPPC") return;
	// Safari issues with overflow:hidden not hiding scrollbars;
		if (navigator.userAgent.indexOf('Safari') != -1)
			document.write('<style type="text/css">div.bvScrollBars, dd.bvScrollBars { overflow:hidden !important; }</style>');
		bv.event.add(window, 'domready', bvScrollBars.find);
	}, // END: init
	
	find : function () {
		var Sc = bv.dom.getElementsByClassName(document, "div,ol,ul,dd", "bvScrollBars");
		if (Sc.length) { // since there are scrollbars needed, create the model node
			bvScrollBars.model.className = "bvScrollGui";
			var ThumbTrack       = document.createElement('div');
			ThumbTrack.className = "bvScrollTrack";
			bvScrollBars.model.appendChild(ThumbTrack);
			var ThumbSlide       = document.createElement('div');
			ThumbSlide.className = "bvScrollThumb";
			var ThumbDetails       = document.createElement('div');
			ThumbDetails.className = "bvScrollThumbDetails";
			ThumbSlide.appendChild(ThumbDetails);
			bvScrollBars.model.appendChild(ThumbSlide);
			var ArrowUp       = document.createElement('div');
			ArrowUp.className = "bvScrollUp";
			bvScrollBars.model.appendChild(ArrowUp);
			var ArrowDown       = document.createElement('div');
			ArrowDown.className = "bvScrollDown";
			bvScrollBars.model.appendChild(ArrowDown);
	
			bv.event.add(document, "mousemove", bvScrollBars.act.slide.Move);
			bv.event.add(document, "mousedown", bvScrollBars.act.check);
			bv.event.add(document, "mouseup", bvScrollBars.act.slide.ClickUp);
		}
		for (var xx=0; xx<Sc.length; xx++) bvScrollBars.make(Sc[xx]);
	}, // END: find
	
	make : function (Div) {
		Div.bv_scrollContent = bv.dom.getElementsByClassName(Div,'div','bvScrollContainer')[0];
		Div.bv_scrollContent.style.top = "0px";
		Div.bv_scrollMax = Div.bv_scrollContent.offsetHeight - Div.offsetHeight;
		Div.bv_scrollUnit = Div.offsetHeight *0.9;
		bv.css.addClass(Div,"hideOverflow");

		var Gui = bvScrollBars.model.cloneNode(true);
			Div.appendChild(Gui);
			Div.bv_scrollContent.style.marginRight = (Gui.offsetWidth +5) +"px";
			Div.bv_scrollGui = Gui;
		
	// the addition of scrollbars can cause the content to squash and grow taller
		Div.bv_scrollMax = Div.bv_scrollContent.offsetHeight - Div.offsetHeight;

		if (Div.bv_scrollMax <= 0) bv.css.addClass(Div, "bvScrollDisabled");
		else {
			
		// Track
			Div.bv_scrollTrack = bv.dom.getElementsByClassName(Div,'div','bvScrollTrack')[0];
			Div.bv_scrollTrack.bv_scroller   = Div;
			bv.event.add(Div.bv_scrollTrack, 'mousedown', bvScrollBars.act.track.ClickDown);
			bv.event.add(Div.bv_scrollTrack, 'mouseup', bvScrollBars.act.track.ClickUp);
			Div.bv_scrollTrack.bv_waitTimer  = null;
			Div.bv_scrollTrack.bv_cycleTimer = null;
		
		// Thumb
			Div.bv_scrollThumb = bv.dom.getElementsByClassName(Div,'div','bvScrollThumb')[0];
			Div.bv_scrollThumb.bv_scroller = Div;
			bv.event.add(Div.bv_scrollThumb, 'mousedown', bvScrollBars.act.slide.ClickDown);
			bv.event.add(Div.bv_scrollThumb, 'mouseup',   bvScrollBars.act.slide.ClickUp);
		
		// ArrowUp
			Div.bv_scrollArrowUp = bv.dom.getElementsByClassName(Div,'div','bvScrollUp')[0];
			Div.bv_scrollArrowUp.bv_scroller   = Div;
			bv.event.add(Div.bv_scrollArrowUp, 'click',     bvScrollBars.act.arrow.UpClick);
			bv.event.add(Div.bv_scrollArrowUp, 'mousedown', bvScrollBars.act.arrow.UpClickDown);
			bv.event.add(Div.bv_scrollArrowUp, 'mouseup',   bvScrollBars.act.arrow.UpClickUp);
			bv.event.add(Div.bv_scrollArrowUp, 'mouseout',  bvScrollBars.act.arrow.UpClickUp);
			Div.bv_scrollArrowUp.bv_waitTimer  = null;
			Div.bv_scrollArrowUp.bv_cycleTimer = null;
		
		// ArrowDown
			Div.bv_scrollArrowDown = bv.dom.getElementsByClassName(Div,'div','bvScrollDown')[0];
			Div.bv_scrollArrowDown.bv_scroller   = Div;
			bv.event.add(Div.bv_scrollArrowDown, 'click',     bvScrollBars.act.arrow.DownClick);
			bv.event.add(Div.bv_scrollArrowDown, 'mousedown', bvScrollBars.act.arrow.DownClickDown);
			bv.event.add(Div.bv_scrollArrowDown, 'mouseup',   bvScrollBars.act.arrow.DownClickUp);
			bv.event.add(Div.bv_scrollArrowDown, 'mouseout',  bvScrollBars.act.arrow.DownClickUp);
			Div.bv_scrollArrowDown.bv_waitTimer  = null;
			Div.bv_scrollArrowDown.bv_cycleTimer = null;
	
			var TrackLength = Gui.offsetHeight - Div.bv_scrollArrowUp.offsetHeight - Div.bv_scrollArrowDown.offsetHeight;
			Div.bv_scrollThumb.style.height = Math.max(
						parseInt(Div.bv_scrollThumb.offsetWidth) /1.5, 
						Div.offsetHeight *(TrackLength / Div.bv_scrollContent.offsetHeight)
					) +"px";
			Div.bv_scrollThumb.getElementsByTagName('div')[0].style.height = "100%";
			Div.bv_scrollThumb.bv_top = Div.bv_scrollArrowUp.offsetHeight;
			Div.bv_scrollThumb.style.top = Div.bv_scrollThumb.bv_top +"px";
			Div.bv_scrollThumb.bv_excursion = TrackLength - Div.bv_scrollThumb.offsetHeight;
			
		} // end disabled check
	}, // END: make
	
	scroll : {
		to : function (Which, Pos) {
			if (Which.bv_scrollMax <= 0) return;
			if (Pos < 0) Pos = 0;
			if (Pos > Which.bv_scrollMax) Pos = Which.bv_scrollMax;
			Which.bv_scrollContent.style.top = (-1* Pos) +"px";
			bvScrollBars.scroll.thumb(Which);
		}, // END: scroll.to
		by : function (Which, Amt) {
			bvScrollBars.scroll.to(Which, -1* (parseInt(Which.bv_scrollContent.style.top) - Amt));
		}, // END: scroll.by
		thumb : function (Which) {
			var T = Which.bv_scrollThumb;
			T.style.top = (Math.round(T.bv_excursion *(-1* parseInt(Which.bv_scrollContent.style.top)/Which.bv_scrollMax)) + T.bv_top) +"px";
		} // END: scroll.thumb
	}, // END: scroll
	
	act : {
		check : function (evt) {
			if (evt.target && evt.target.className.indexOf('Scroll') != -1) {
				evt.stopPropagation();
				return false;
			}
		}, //END: act.check

		track : {
			ClickDown : function (evt) {
				var ClickAt = evt.offsetY || evt.layerY;
				var Mod = (ClickAt > parseInt(this.bv_scroller.bv_scrollThumb.style.top)) ? 1 : -1;
				if (this.bv_cycleTimer) clearInterval(this.bv_cycleTimer);
				this.bv_waitTimer  = setTimeout("",350);
				this.bv_cycleTimer = setInterval("bvScrollBars.act.track.Budge(document.getElementById('"+ bv.getId(this.bv_scroller) +"'),"+ Mod +");",350);
			}, // END: act.track.ClickDown
			ClickUp : function (evt) {
				if (this.bv_cycleTimer) clearInterval(this.bv_cycleTimer);
				if (this.bv_waitTimer) {
					clearTimeout(this.bv_waitTimer);
					var ClickAt = evt.offsetY || evt.layerY;
					var Mod = (ClickAt > parseInt(this.bv_scroller.bv_scrollThumb.style.top)) ? 1 : -1;
					bvScrollBars.act.track.Budge(this.bv_scroller, Mod);
				}
			}, // END: act.track.ClickUp
			Budge : function (Which, Mod) {
				if (Which.bv_scrollTrack.bv_waitTimer) clearTimeout(Which.bv_scrollTrack.bv_waitTimer);
				Which.bv_scrollTrack.bv_waitTimer = null;
				bvScrollBars.scroll.by(Which, Mod * Which.bv_scrollUnit);
			} // END: act.track.Budge
		}, // END: act.track

		slide : {
			Move : function (evt) {
				if (!window.bvScrollBarGrabbed) return true;
				else {
					bvScrollBars.scroll.to(
							window.bvScrollBarGrabbed.bv_scroller,
							window.bvScrollBarGrabbed.bv_scroller.bv_scrollMax *(
								(evt.clientY - window.bvScrollBarGrabbed.bv_scrollZeroPoint) / 
								window.bvScrollBarGrabbed.bv_excursion
							)
						);
					return true;
				}
			}, // END: act.slide.Move
			ClickDown : function (evt) {
				window.bvScrollBarGrabbed = this;
				this.bv_scrollZeroPoint = evt.clientY - parseInt(this.style.top) + this.bv_top;
			}, // END: act.slide.ClickDown
			ClickUp : function () {
				window.bvScrollBarGrabbed = null;
			} // END: act.slide.ClickUp
		}, // END: act.slide

		arrow : {
			UpClick : function () {
				if (this.bv_waitTimer) clearTimeout(this.bv_waitTimer);
				if (this.bv_cycleTimer) clearInterval(this.bv_cycleTimer);
				else bvScrollBars.scroll.by(this.bv_scroller, -15);
			}, // END: act.arrow.UpClick
			UpClickDown : function () {
				if (this.bv_waitTimer) clearTimeout(this.bv_waitTimer);
				if (this.bv_cycleTimer) clearInterval(this.bv_cycleTimer);
				this.bv_waitTimer = setTimeout("bvScrollBars.act.arrow.UpClickDownCycle('"+ bv.getId(this.bv_scroller) +"');",500);
			}, // END: act.arrow.UpClickDown
			UpClickDownCycle : function (Id) {
				document.getElementById(Id).bv_scrollArrowUp.bv_cycleTimer = setInterval("bvScrollBars.scroll.by(document.getElementById('"+ Id +"'), -5);",25);
			}, // END: act.arrow.UpClickDownCycle
			UpClickUp : function () {
				if (this.bv_waitTimer) clearTimeout(this.bv_waitTimer);
				if (this.bv_cycleTimer) clearInterval(this.bv_cycleTimer);
			}, // END: act.arrow.UpClickUp
			DownClick : function () {
				if (this.bv_waitTimer) clearTimeout(this.bv_waitTimer);
				if (this.bv_cycleTimer) clearInterval(this.bv_cycleTimer);
				else bvScrollBars.scroll.by(this.bv_scroller, +15);
			}, // END: act.arrow.DownClick
			DownClickDown : function () {
				if (this.bv_waitTimer) clearTimeout(this.bv_waitTimer);
				if (this.bv_cycleTimer) clearInterval(this.bv_cycleTimer);
				this.bv_waitTimer = setTimeout("bvScrollBars.act.arrow.DownClickDownCycle('"+ bv.getId(this.bv_scroller) +"');",500);
			}, // END: act.arrow.DownClickDown
			DownClickDownCycle : function (Id) {
				document.getElementById(Id).bv_scrollArrowDown.bv_cycleTimer = setInterval("bvScrollBars.scroll.by(document.getElementById('"+ Id +"'), +5);",25);
			}, // END: act.arrow.DownClickDownCycle
			DownClickUp : function () {
				if (this.bv_waitTimer) clearTimeout(this.bv_waitTimer);
				if (this.bv_cycleTimer) clearInterval(this.bv_cycleTimer);
			} // END: act.arrow.DownClickUp
		} // END: act.arrow
	}, // END: act
	
	complete : true
};
bvScrollBars.init();


/* ... /packer:END(bvScrollBars.js) */
/* (25) packer:START(ffwFlagScroller.js) ... */


var ffwFlagScroller = {

	delay : 200,

	init : function (el) { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		var D, S, Els;
		if (!(D = document.getElementById('festListByCountry'))) return;
		if ((S = bv.dom.getElementsByClassName(D, 'div', 'bvScrollBars')).length == 0) return;
		Els = S[0].getElementsByTagName('th');
		var Y = {};
		for (var xx=Els.length -1; xx>=0; xx--) {
			Y[Els[xx].innerHTML] = Els[xx];
		}
//for (var Prop in Y) d(Prop+' at '+ bv.css.getOffset(Y[Prop],S[0]).top, 'scroll maker');
		if (!(L = document.getElementById('navNameList'))) return;
		if (!(Lis = L.getElementsByTagName('li'))) return;
		for (var xx=0; xx<Lis.length; xx++) {
			var Trg = Lis[xx].title;
			if (Y[Trg]) {
				Lis[xx].ffwFlagScrollerWait = null;
				Lis[xx].ffwFlagScrollerBox  = S[0];
				Lis[xx].ffwFlagScrollerTrg  = Y[Trg];
				Lis[xx].ffwFlagScrollerBase = Y[Trg].parentNode.parentNode
				bv.event.add(Lis[xx], 'mouseover', ffwFlagScroller.scroll);
				bv.event.add(Lis[xx], 'mouseout',  ffwFlagScroller.clear);
			}
		}
	},
	
	scroll : function () {
		this.ffwFlagScrollerWait = setTimeout(ffwFlagScroller.setScroll(this), ffwFlagScroller.delay);
	},
	
	setScroll : function (F) {
		return function () {
			bvScrollBars.scroll.to(F.ffwFlagScrollerBox, bv.css.getOffset(F.ffwFlagScrollerTrg,F.ffwFlagScrollerBase).top +1);
		}
//d('scrolling to "'+ this.title +'" at '+ bv.css.getOffset(this.ffwFlagScrollerTrg,this.ffwFlagScrollerBase).top, 'scroller');
	},
	
	clear : function () {
		if (this.ffwFlagScrollerWait) clearTimeout(this.ffwFlagScrollerWait);
	},
	
	complete : true
}

if (bv && bv.event) bv.event.add(window, "domready", ffwFlagScroller.init);

/* ... /packer:END(ffwFlagScroller.js) */
/* (26) packer:START(ffwVoter.js) ... */

// ?cachebuster="+ Date.parse(new Date());


var ffwVoter = {

	polls : [],

	configure : function (name, value) {
		if (typeof ffwVoter[name] == typeof value)
			ffwVoter[name] = value;
		else if (bv) bv.debug.msg('type mismatch in call to configure(): '+ name +'::'+ value, 'ffwVoter');
	},

	init : function (el) { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		var Trg = (el) ? el : document;
		var Els = bv.dom.getElementsByClassName(Trg, 'table', 'ffwVote');
		for (var xx=0; xx<Els.length; xx++) {
			var TDs = Els[xx].getElementsByTagName('td');
			for (var ii=0; ii<TDs.length; ii++) {
				if ((/\bffwVoteHere\b/).test(TDs[ii].className)) {
					ffwVoter.setPips(TDs[ii]);
					bv.event.add(TDs[ii], 'mouseout', ffwVoter.show);
				}
			}
		}
	},
	
	setPips : function (El) { // assesses previous votes, if any, and preload options
		var Imgs = El.getElementsByTagName('img');
		var IdMatch = El.className.match(/\bffwVoteTrg-(\d+)\b/);
		var Id = (IdMatch) ? parseInt(IdMatch[1]) : 0;
		var Label = (document.getElementById('videoRatingMember')) ? document.getElementById('videoRatingMember').childNodes[0] : null;
		El.ffwVoter = {
			id   : Id,
			label: Label,
			vote : 0,
			pips : Imgs
		}
		ffwVoter.polls[El.ffwVoter.id] = El;
		El.show = ffwVoter.show;
		for (var xx=0; xx<Imgs.length; xx++) {
			if ((/_mark\b/).test(Imgs[xx].src)) El.ffwVoter.vote = xx+1;
			Imgs[xx].ffwVoter = {
				iam : xx+1,
				chad : new Image(),
				mark : new Image(),
				empty : new Image(),
				host : El
			}
			Imgs[xx].ffwVoter.chad.src  = Imgs[xx].src.replace(/_(chad|mark|empty)\b/, '_chad');
			Imgs[xx].ffwVoter.mark.src  = Imgs[xx].src.replace(/_(chad|mark|empty)\b/, '_mark');
			Imgs[xx].ffwVoter.empty.src = Imgs[xx].src.replace(/_(chad|mark|empty)\b/, '_empty');
			bv.event.add(Imgs[xx],'mouseover',ffwVoter.hover);
			bv.event.add(Imgs[xx],'click',ffwVoter.vote);
		}
		ffwVoter.syncVote(El);
	},

//	ffwVoter.setVote({ id:5, vote:3, member:199 });
	setVote : function (Rslt) {
		if (Rslt.vote) { // vote != 0; means a vote has just been cast or had previously been cast
			if (typeof Rslt.member != 'number' || Rslt.member == 0) { // not logged in
				if (confirm('You must be signed in to rate a movie clip. Would you like to sign in now?')) {
					top.location.href = '/login/';
				} else {
					ffwVoter.polls[Rslt.id].ffwVoter.vote = 0;
					ffwVoter.polls[Rslt.id].show();
				}
			} else if (ffwVoter.polls[Rslt.id]) {
				if (ffwVoter.polls[Rslt.id].ffwVoter.label)
					ffwVoter.polls[Rslt.id].ffwVoter.label.innerHTML = 'Your rating:';
				ffwVoter.polls[Rslt.id].ffwVoter.vote = Rslt.vote;
				ffwVoter.polls[Rslt.id].show();
			}
		} else { // no vote passed; not logged in, or hasn't voted
		}
	},
	
// /index.php?eID=ffw&action=rate&id=5&vote=3
	syncVote : function (El) {
		var Src = '/index.php?eID=ffw&action=rate&id='+ El.ffwVoter.id;
		if (El.ffwVoter.vote) Src += '&vote='+ El.ffwVoter.vote
		Src += '&cachebuster='+ Date.parse(new Date());
		var JSON = document.createElement('script');
		JSON.setAttribute('type', 'text/javascript');
		JSON.setAttribute('src', Src);
		document.getElementsByTagName('head')[0].appendChild(JSON);
	},

	vote : function () {
		this.ffwVoter.host.ffwVoter.vote = this.ffwVoter.iam;
		this.ffwVoter.host.show(this.ffwVoter.iam);
		ffwVoter.syncVote(this.ffwVoter.host);
	},
	
	hover : function () {
		this.ffwVoter.host.show(this.ffwVoter.iam);
	},
	
	show : function (V) {
		var setTo = (typeof V == 'number') ? V : this.ffwVoter.vote;
		var I = this.ffwVoter.pips;
		if (setTo) {
			for (var xx=0; xx<I.length; xx++) {
				var Show = (xx<setTo) ? 'mark' : 'empty';
				I[xx].src = I[xx].ffwVoter[Show].src;
			}
		} else { // hasn't voted yet; set to neutral
			for (var xx=0; xx<I.length; xx++) {
				I[xx].src = I[xx].ffwVoter.chad.src;
			}
		}
	}
	
}

if (bv && bv.event) bv.event.add(window, "domready", ffwVoter.init);

/* ... /packer:END(ffwVoter.js) */
/* (27) packer:START(ffwMiniMap.js) ... */


var ffwMiniMap = {

	configure : function (name, value) {
		if (typeof ffwMiniMap[name] == typeof value)
			ffwMiniMap[name] = value;
		else if (bv) bv.debug.msg('type mismatch in call to configure(): '+ name +'::'+ value, 'ffwMiniMap');
	},

	init : function () { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		var Trg = document.getElementById('navMiniMap');
		var List = document.getElementById('navMiniMapList');
		var Map = document.getElementById('miniMapCoords');
		if (Trg && List && Map) {
			var Li = List.getElementsByTagName('li');
			for (var xx=0; xx<Li.length; xx++) {
				Li[xx].ffwMiniMap = {
					wait : null,
					trg : Trg,
					val : Li[xx].className.substring(3)
				}
				bv.event.add(Li[xx], 'mouseover', ffwMiniMap.addHilite);
				bv.event.add(Li[xx], 'mouseout', ffwMiniMap.removeHilite);
			}
			var Area = Map.getElementsByTagName('area');
			for (var xx=0; xx<Area.length; xx++) {
				Area[xx].ffwMiniMap = {
					trg : Trg,
					val : Area[xx].title.replace(/\s+/g, '_')
				}
				bv.event.add(Area[xx], 'mouseover', ffwMiniMap.addHilite);
				bv.event.add(Area[xx], 'mouseout', ffwMiniMap.removeHilite);
			}
		}
	},

	addHilite : function () {
	// cancel the switch off, if it is going to be switched on right away
		if (this.ffwMiniMap.wait) clearTimeout(this.ffwMiniMap.wait);
		if (this.ffwMiniMap.trg && this.ffwMiniMap.val)
			bv.css.addClass(this.ffwMiniMap.trg, 'sec'+ this.ffwMiniMap.val);
	},
	removeHilite : function () {
	// delay switch off, in case the mouseoff is triggered by passing into a nested element
		if (this.ffwMiniMap.trg && this.ffwMiniMap.val)
			this.ffwMiniMap.wait = setTimeout('bv.css.removeClass(document.getElementById("'+bv.getId(this.ffwMiniMap.trg)+'"), "sec'+ this.ffwMiniMap.val +'")', 10);
	},

	complete : true
}

if (bv && bv.event) bv.event.add(window, "domready", ffwMiniMap.init);



/* ... /packer:END(ffwMiniMap.js) */
/* (28) packer:START(ffwMiniCal.js) ... */


var ffwMiniCal = {

	calTypes : ['Entry','Run'],
	cal : {
		'Entry_currentCal' : null,
		'Run_currentCal' : null
	},
	staging : null,
	cachebuster : Date.parse(new Date()),

	configure : function (name, value) {
		if (typeof ffwMiniCal[name] == typeof value)
			ffwMiniCal[name] = value;
		else if (bv) bv.debug.msg('type mismatch in call to configure(): '+ name +'::'+ value, 'ffwMiniCal');
	},

	init : function () { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		if (!bv.ajax || !bv.ajax.isAvailable) return;
		if ((Holder = document.getElementById('navMiniCal')) == null) return;
		
		ffwMiniCal.staging = document.createElement('div');
		ffwMiniCal.staging.style.display  = "none";
		ffwMiniCal.staging.style.position = "absolute";
		
		for (var xx=0, Type; Type = ffwMiniCal.calTypes[xx]; xx++) {
			if ((CalPage = document.getElementById('cal'+ Type)) != null) {
				try {
					var T = CalPage.getElementsByTagName('table')[0];
					ffwMiniCal.prep(T);
					ffwMiniCal.get(T);
					ffwMiniCal.cal[Type +'_currentCal'] = T;
					ffwMiniCal.cal[Type +'_page'] = CalPage;
				} catch (err) { return; }
			}
			if (T) bv.css.addClass(Holder, 'ajaxActive');
		}
		
	}, // END: init


	stage : function (Str) { // take a string and turn it into a calendar
		ffwMiniCal.staging.innerHTML = Str;
		var Cal = ffwMiniCal.staging.getElementsByTagName('table');
		if ((C = Cal[0]) != undefined) {
			bv.css.addClass(C, 'waiting');
			var Linkies = C.getElementsByTagName('a');
			if (Linkies && Linkies[0] && (M = Linkies[0].href.match(/\b(run|entry)(cal)?\b/i)) != null) {
				ffwMiniCal.cal[M[1].substring(0,1).toUpperCase() + M[1].substring(1) +'_page'].appendChild(C);
				ffwMiniCal.prep(C);
			}
		}
	}, // END: stage
	stageRemote : function (txt, xml, obj) { // prep Ajax response for staging
		ffwMiniCal.stage(txt);
	},
	
	
	prep : function (Cal) { // take a calendar table, and parse its links, add its shortcuts
		if ((Cap = Cal.getElementsByTagName('caption')) == null) return null;
		var Linkies = Cap[0].getElementsByTagName('a');
		for (var xx=0; Ln = Linkies[xx]; xx++) {
			if ((M = Ln.href.match(/.*\/(Entry|Run)Cal\/(\d\d\d\d)\/(\w+)\//)) != null) {
				Ln.calTrg = {Type:M[1], Year:M[2], Month:M[3]};
				if (!Cal.linkedTo) Cal.linkedTo = [];
				Cal.linkedTo.push(Ln.calTrg);
				bv.event.add(Ln, 'click', ffwMiniCal.clickCall);
			} else if ((M = Ln.href.match(/.*calendar\/+(\w+)\/+(\d\d\d\d)\/+(entry|run)\//)) != null) {
				Cal.month = M[1];
				Cal.year  = parseInt(M[2]);
				Cal.type  = (M[3] == 'entry') ? "Entry" : "Run";
				Cal.go    = Ln.href;
			}
		}
		if (! Cal.month || ! Cal.year || ! Cal.type ) return null;

	// add unique id; add as key to cal obj
		ffwMiniCal.cal[Cal.type + Cal.year + Cal.month] = Cal;
		bv.event.add(Cal, 'click', ffwMiniCal.clickGo);
	}, // END: prep


	get : function (Cal) { // make sure the linked calendars are available
		if (Cal.linkedTo) {
			for (var xx=0, Trg; Trg = Cal.linkedTo[xx]; xx++) {
				if (! ffwMiniCal.cal[Trg.Type+Trg.Year+Trg.Month]) {
					bv.ajax.pronto('/core/'+ Trg.Type +'Cal/'+ Trg.Year +'/'+ Trg.Month +'/c.html?cachebuster='+ ffwMiniCal.cachebuster, ffwMiniCal.stageRemote);
				}
			}
		}
	}, // END: get


	place : function (Type, Year, Month, Attempts) { // place the new calendar in position
		if (typeof Attempts != 'number' || Attempts < 0) Attempts = 0;
		if (ffwMiniCal.cal[Type +'_page'] && ffwMiniCal.cal[Type+Year+Month]) {
			if (ffwMiniCal.cal[Type +'_currentCal']) {
				bv.css.addClass(ffwMiniCal.cal[Type +'_currentCal'], 'waiting');
			}
			bv.css.removeClass(ffwMiniCal.cal[Type+Year+Month], 'waiting');
			ffwMiniCal.cal[Type +'_currentCal'] = ffwMiniCal.cal[Type+Year+Month];
			ffwMiniCal.get(ffwMiniCal.cal[Type+Year+Month]);

			var Ping = new Image(); // let Typo3 know what one is showing
			Ping.src = '/core/'+ Type +'Cal/'+ Year +'/'+ Month +'/c.html?tx_ffw_pi5[setSess]=1&cachebuster='+ ffwMiniCal.cachebuster++;
		}
	}, // END: place


	clickCall : function (e) { // arrow is clicked; call a new calendar
		if (this.calTrg) {
			ffwMiniCal.place(this.calTrg.Type, this.calTrg.Year, this.calTrg.Month, 0);
			e.stopPropagation();
			return false;
		}
	}, // END: clickCall
	clickGo : function (e) { // calendar is clicked, but not a link; go to calendar page
//		if (this.go) top.location.href = this.go;
//		if (this.go && e.target.nodeType && e.target.nodeName == 'TD') top.location.href = this.go;
	}, // END: clickGo


	complete : true
}

if (bv && bv.event) bv.event.add(window, "domready", ffwMiniCal.init);



/* ... /packer:END(ffwMiniCal.js) */
/* (29) packer:START(ffwPredict.js) ... */



var ffwPredict = {

	db : {},
	retryTimeout : 8, // seconds before the second try to retrieve data is made
	box : null,

	configure : function (name, value) {
		if (typeof ffwPredict[name] == typeof value)
			ffwPredict[name] = value;
		else if (bv) bv.debug.msg('type mismatch in call to configure(): '+ name +'::'+ value, 'ffwPredict');
	},

	init : function (el) { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		
		if (!ffwPredict.box) { // first time run
			var Box = document.createElement('div');
			Box.id = 'ffwPredictBox';
			Box.className = 'prep';
			Box.appendChild(document.createElement('ul'));
			document.getElementsByTagName('body')[0].appendChild(Box);
			ffwPredict.box = Box;

		// festival addablock needs to get parsed
			var AddABlocks = bv.dom.getElementsByClassName(document, 'a', 'addABlockTrigger');
			while ((el = AddABlocks.shift()) != undefined)
				bv.event.add(el, 'click', function () { ffwPredict.init(this.addABlock.trg); } );
			
		// preload background images
			var ListBG = new Image(); ListBG.src = '/fileadmin/img/bg/fff_92pct.png';
			var ItemBG = new Image(); ItemBG.src = '/fileadmin/img/bg/bright_rounded_top.png';
		}
		
		var Trg = (typeof el == 'object' && el.nodeType) ? el : document;
		var Inputs = bv.dom.getElementsByClassName(Trg, 'input', 'ffwPredict');
		while ((I = Inputs.shift()) != undefined) {
			if (I.ffwPredict && I.ffwPredict.init) continue;
			if ((Src = I.className.match(/\bffwPredictSrc-(\w+)\b/)) != null) {
				if (! ffwPredict.db[Src[1]]) {
					ffwPredict.db[Src[1]] = { retry : setTimeout(ffwPredict.makeRetry(Src[1]), ffwPredict.retryTimeout *1000) };
					ffwPredict.data.get(Src[1]);
				}
				if (! I.form.corrected ) {
					I.form.setAttribute('autocomplete', 'off');
					bv.event.add(I.form, 'submit', ffwPredict.formCheck);
					I.form.corrected = true;
				}
				I.ffwPredict = {
					init : true,
					type : Src[1],
					enteredValue : I.value,
					displayValue : I.value
				};
				I.ffwPredictRemove = ffwPredict.ui.removeDisplay;
				bv.event.add(I, 'keydown', ffwPredict.ui.controlThis);
				bv.event.add(I, 'keyup', ffwPredict.ui.searchThis);
				bv.event.add(I, 'focus', ffwPredict.ui.prepDisplay);
			} else { I.ffwPredict = { init : true }; }
		}
	},
	makeRetry : function (Trg) {
		return function () {
			if (ffwPredict.db[Trg] && ffwPredict.db[Trg].retry)
				clearTimeout(ffwPredict.db[Trg].retry);
			delete ffwPredict.db[Trg];
			ffwPredict.data.get(Trg); // if this fails, stop
		}
	}, // END: makeRetry
	response : function (Obj) {
		ffwPredict.data.process(Obj);
	}, // END: response
	
	
	formCheck : function (e) {// alert('checking');
//		if (e.keyCode && e.keyCode == 13) {
//			for (var Prop in e) if (/(target|key|which)/i.test(Prop) && ! confirm(Prop+': '+e[Prop])) break;

		if (this.preventSubmit) return false;
//		}
	}, // END: formCheck
	formPreventSubmit : function (form) {
		return function () { form.preventSubmit = false; };
	},
	
	
	data : {
	// index.php?eID=ffw&action=predict&type=fest
		get : function (T) {
			var Type = (/^(\w+)$/i.test(T)) ? T.toLowerCase() : "festival";
			var Src = '/index.php?eID=ffw&action=predict&type='+ Type;
			Src += '&cachebuster='+ Date.parse(new Date());
			var JSON = document.createElement('script');
			JSON.setAttribute('type', 'text/javascript');
			JSON.setAttribute('src', Src);
			document.documentElement.appendChild(JSON);
		}, // END: data.get
		
		process : function (Obj, force) {
			bv.css.removeClass(ffwPredict.box, 'prep');
			if (ffwPredict.db[Obj.type] && ffwPredict.db[Obj.type].retry)
				clearTimeout(ffwPredict.db[Obj.type].retry);
			if (
					! ffwPredict.db[Obj.type] ||
					! ffwPredict.db[Obj.type].src ||
					ffwPredict.db[Obj.type].expired ||
					force
				) { // prevent a retry or other delay from overwriting existing data
				ffwPredict.db[Obj.type] = {
					src : Obj,
					nullFilter : ffwPredict.data.makeNullFilter(Obj),
					filter : {},
					list : {},
					expired : false
				};
				setTimeout('ffwPredict.db["'+ Obj.type +'"].expired = true; ffwPredict.data.get("'+ Obj.type +'");', Obj.expires);
			}
		}, // END: data.process
		
		makeNullFilter : function (Src) {
			var rtn = '\r';
			for (var idx in Src.data) {
				rtn += Src.data[idx].text +'\t'+ Src.data[idx].code +'\r';
			}
			return rtn;
		}, // END: data.makeNullFilter
		
		getFiltered : function (Src, Pattern) {
			if (Pattern == '') return '';
			Pattern = Pattern.toLowerCase();
			if (Src.filter[Pattern]) return Src.filter[Pattern];
			var Base = Src.nullFilter;
//			var P = Pattern.replace(/\\/g, '\\\\');
// gotta escape the magic regexp chars
			var P = Pattern.replace(/(\(|\)|\[|\]|\{|\}|\*|\+|\.|\?|\\)/g, '\\\1');
		// not sure why, but ^ and $ are not matching the start/end of lines
			var Anywhere = new RegExp("[\\r\\n\\f][^\\r\\n\\f\\t]*"+ P +"[^\\r\\n\\f]*", "ig");
			var AtStart  = new RegExp("[\\r\\n\\f]"+ P +"[^\\r\\n\\f]*", "ig");
	
		// check if any super-sets already exist, and start with them if so
			var Chop = Pattern;
			while (Chop = Chop.substring(1)) {
				if (Src.filter[Chop]) Base = Src.filter[Chop];
			}
			Chop = Pattern;
			while (Chop = Chop.substring(0, Chop.length -1)) {
				if (Src.filter[Chop]) Base = Src.filter[Chop];
			}
	
		// retrieve all of the lines with matching text, and return a string with one match per line
			var Matches = Base.match(Anywhere);
			if (Matches) {
				Matches = Matches.sort().join("");
			// pull out the matches that match at the start of the textline
				var BetterMatches = Matches.match(AtStart);
				var LeadMatches = (BetterMatches) ? BetterMatches.join("") : '';
				var LessorMatches = Matches.replace(AtStart, '');
				Src.filter[Pattern] = (LeadMatches + LessorMatches).replace(/[\n\f\r]+/, "\r");
			} else { // no matches
				Src.filter[Pattern] = '';
			}
			
			return Src.filter[Pattern];
		}, // END: data.getFiltered
		
		getList : function (Src, Pattern) {
			if (Pattern == '' || !Src || !Src.list) return document.createElement('ul');
			Pattern = Pattern.toLowerCase();
			if (Src.list[Pattern]) return Src.list[Pattern];
			
			var Filter = ffwPredict.data.getFiltered(Src, Pattern);
			var Items = Filter.split(/[\r\f\n]+/);
			var UL = document.createElement('ul');
			UL.selectedIndex = null;
			UL.items = [];
			while ((Item = Items.shift()) != undefined) {
				if (! /^[^\t]*\w[^\t]*\t/.test(Item)) continue;
				var Parts = Item.split(/\t/);
				var LI = document.createElement('li');
				LI.index = UL.items.length;
				UL.items.push(LI);
				LI.itemID = Parts[1];
				LI.appendChild(document.createTextNode(Parts[0]));
				UL.appendChild(LI);
				bv.event.add(LI, 'mouseover', ffwPredict.ui.controlSelectThis);
				bv.event.add(LI, 'click', ffwPredict.ui.selectThis);
				bv.event.add(LI, 'keydown', ffwPredict.ui.controlHost);
				bv.event.add(LI, 'keyup', ffwPredict.ui.searchHost);
			}
			Src.list[Pattern] = UL;
			return Src.list[Pattern];
		}
	}, // END: data
	
	ui : {
		
		control : function (e) {
			if (! ffwPredict.box.list || ! ffwPredict.box.list.items || ffwPredict.box.list.items.length == 0) return;

		// Safari will double the keypress; not sure why. Prevent more than 200 keypresses per second:
			if (ffwPredict.box.repeatKeyOff) return;
			ffwPredict.box.repeatKeyOff = true;
			setTimeout('ffwPredict.box.repeatKeyOff = false;', 50);

			switch (e.keyCode) {
				case 38 : // cursor up
					ffwPredict.ui.controlSelect(ffwPredict.box.list, ffwPredict.box.list.selectedIndex -1);
					break;
				case 40 : // cursor down
					if (ffwPredict.box.host.value == '') break;
					if (typeof ffwPredict.box.list.selectedIndex == 'number') {
						ffwPredict.ui.controlSelect(ffwPredict.box.list, ffwPredict.box.list.selectedIndex +1);
					} else {
						ffwPredict.ui.controlSelect(ffwPredict.box.list, 0);
					}
					break;
				case 27 : // escape key
					ffwPredict.ui.controlSelect(ffwPredict.box.list, -1);
					break;
				case  9 : // tab
				case 13 : // enter or return
					if (typeof ffwPredict.box.list.selectedIndex == 'number') {
						ffwPredict.box.host.form.preventSubmit = true;
						setTimeout(ffwPredict.formPreventSubmit(ffwPredict.box.host.form), 500);
						ffwPredict.ui.select(ffwPredict.box.list.items[ffwPredict.box.list.selectedIndex].childNodes[0].nodeValue);
					} else {
						ffwPredict.ui.controlSelect(ffwPredict.box.list, -1);
					}
					break;
			}
		},
		controlThis : function (e) { ffwPredict.ui.control(e); },
		controlHost : function (e) { ffwPredict.ui.control(e); },

		controlSelectThis : function () {
			ffwPredict.ui.controlSelect(this.parentNode, this.index);
		},
		controlSelect : function (List, Idx) {
			if (typeof List.selectedIndex == 'number') {
				bv.css.removeClass(List.items[List.selectedIndex], 'selected');
			}
			if (Idx >= List.items.length) Idx = 0;
			if (Idx >= 0) {
				List.selectedIndex = Idx;
				bv.css.addClass(List.items[Idx], 'selected');
				bv.css.addClass(ffwPredict.box, 'active');
			} else {
				List.selectedIndex = null;
				bv.css.removeClass(ffwPredict.box, 'active');
			}
		},

		selectThis : function () {
			ffwPredict.ui.select(this.childNodes[0].nodeValue);
		},
		select : function (Text) {
			if (typeof ffwPredict.box.list.selectedIndex == 'number') {
				bv.css.removeClass(ffwPredict.box.list.items[ffwPredict.box.list.selectedIndex], 'selected');
				ffwPredict.box.list.selectedIndex = null;
			}
			ffwPredict.box.host.value = Text;
			setTimeout('ffwPredict.box.host.focus();', 50); // Win IE 6 does not focus the element
			ffwPredict.ui.removeDisplay();
		},
		
		search : function (e, Host) {
			switch (e.keyCode) {
				case  9 : // tab
				case 13 : // enter or return
				case 27 : // escape
				case 38 : // cursor up
				case 40 : // cursor down
					return;
			}
			Host.focus();
			for (var xx=0; xx<ffwPredict.box.childNodes.length; xx++) {
				if (typeof ffwPredict.box.childNodes[xx].selectedIndex == 'number') {
					bv.css.removeClass(ffwPredict.box.childNodes[xx].items[ffwPredict.box.childNodes[xx].selectedIndex], 'selected');
				}
				ffwPredict.box.childNodes[xx].selectedIndex = null;
				ffwPredict.box.removeChild(ffwPredict.box.childNodes[xx]);
			}
			var List = ffwPredict.data.getList(ffwPredict.db[Host.ffwPredict.type], Host.value);
			if (List.items && List.items.length) {
				ffwPredict.box.appendChild(List);
				ffwPredict.box.list = List;
				bv.css.addClass(ffwPredict.box, 'active');
			} else {
				ffwPredict.box.list = null;
				bv.css.removeClass(ffwPredict.box, 'active');
			}
		},
		searchThis : function (e) { ffwPredict.ui.search(e, this); },
		searchHost : function (e) { ffwPredict.ui.search(e, ffwPredict.box.host); },
		
		prepDisplay : function () {
			bv.css.removeClass(ffwPredict.box, 'active');
			var Pos = bv.css.getOffsetFromRoot(this);
			ffwPredict.box.style.left  = Pos.left +'px';
			ffwPredict.box.style.top   = (Pos.top + this.offsetHeight) +'px';
			ffwPredict.box.style.width = (this.offsetWidth -3) +'px';
			ffwPredict.box.host = this;
		},
		
		removeDisplay : function () {
			ffwPredict.box.host.focus();
			bv.css.removeClass(ffwPredict.box, 'active');
		},
		
		
		display : function () {
			if (ffwPredict.db[this.ffwPredict.type]) {
//				document.getElementById('debug').innerHTML = ffwPredict.db[this.ffwPredict.type].nullFilter;
//				document.getElementById('debug').value = ffwPredict.getFiltered(ffwPredict.db[this.ffwPredict.type], this.value);
			}
		} // END: ui.display
	}, // END: ui

	complete : true
}

if (bv && bv.event) bv.event.add(window, "load", ffwPredict.init);

/* ... /packer:END(ffwPredict.js) */
/* (30) packer:START(ffwProfileEdit.js) ... */


var ffwProfileEdit = {

	init : function (el) { // verify ability, find targetted lists
		if (!bv) return; // require bv_utilities.js
		var In = document.getElementById('editModeEnter');
		var Out = document.getElementById('editModeExit');
		if (In && Out) {
			bv.event.add(In, 'click', ffwProfileEdit.enterEdit);
			bv.event.add(Out, 'click', ffwProfileEdit.exitEdit);
		}
	},
	
	enterEdit : function () {
		bv.css.addClass(document.getElementsByTagName('body')[0], 'editMode');
		return false;
	},

	exitEdit : function () {
		bv.css.removeClass(document.getElementsByTagName('body')[0], 'editMode');
		return false;
	},

	complete : true
}

if (bv && bv.event) bv.event.add(window, "domready", ffwProfileEdit.init);



/* ... /packer:END(ffwProfileEdit.js) */
/* (31) packer:START(~site_init.js) ... */


bvSlideShow.configure("autoSlideWait", 5);
bvSlideShow.configure("slideDuration", 0.75);
bvSlideShow.configure("frameRate", 100);
bvSlideShow.configure("frameJump", 0.85);
bv.event.add(window, 'domready', function(){ bvSlideShow.configure("target", document.getElementById('mediaplex')); }, "priority");

bvStickyWicket.addWicket('photoGallery','li');

bvCollapse.configure('TrgEls','div,p,dl,td');

bvAttachValidWindows.addType({
		popview : {
			win : 'bvpop',
			viewerLocation : '/popviewer.php?i=',
			queryAppend : '',
			params : 'resizable, height=10, width=10',
			rtn : false
		},
		minwin : {
			win : 'bvminwin',
			viewerLocation : '',
			queryAppend : 'layout=minimize',
			params : 'resizable, scrollbars, height=10, width=10',
			rtn : false
		},
		helpwin : {
			win : 'ffwhelp',
			viewerLocation : '',
			queryAppend : '',
			params : 'resizable, scrollbars, height=450, width=500',
			rtn : false
		},
		preview : {
			win : 'ffwpreview',
			viewerLocation : '',
			queryAppend : '',
			params : '',
			rtn : false
		}
	});


bvPrintables.configure('batch', [
			'Printed from: '+ self.location.href,
			'...as of '+ bv.tickBase.toString(),
			'<p>Film Festival World is a website dedicated to independent films, film festivals around the world, and the people that make both happen.</p>'
		]
	);

/* ... /packer:END(~site_init.js) */
/* /File Packer, v1.1 */
