/*///////////////////////////////////////////////////////////////////////////////////////////
// /javascript/http/au/en/front.combined.v1.203.js                                         //
// created: Tue, 24 Jan 2012 12:53:52 +1100                                                //
// files included:                                                                         //
//  /javascript/jquery_plugins/livequery/livequery-1.1.1/jquery.livequery.min.js           //
//  /javascript/jquery_plugins/jquery_ui/jquery-ui-1.8.7.custom.min.js                     //
//  /javascript/jquery_plugins/jquery_tools/jquery.tools-1.2.2.min.js                      //
//  /javascript/jquery_plugins/scroll_to/jquery.scrollTo-1.4.2-min.js                      //
//  /javascript/jquery_plugins/pretty_photo/jquery.prettyPhoto.js                          //
//  /javascript/jquery_plugins/core/ajax_forms/ajax_forms-0.0.1.js                         //
//  /javascript/jquery_plugins/core/ajax_suggest/ajax_suggest-0.0.1.js                     //
//  /javascript/jquery_plugins/core/ajax_response/ajax_response-0.0.1.js                   //
//  /javascript/jquery_plugins/core/auto_align/auto_align-0.0.1.js                         //
//  /javascript/jquery_plugins/core/checkbox_all/checkbox_all-0.0.1.js                     //
//  /javascript/jquery_plugins/core/date_time/date_time-0.0.1.js                           //
//  /javascript/jquery_plugins/core/general_tools/general_tools-0.0.1.js                   //
//  /javascript/jquery_plugins/core/google_address_suggest/google_address_suggest-0.0.1.js //
//  /javascript/jquery_plugins/core/fixed_pos/fixed_pos-0.0.1.js                           //
//  /javascript/jquery_plugins/core/in_field_labels/in_field_label-0.0.1.js                //
//  /javascript/jquery_plugins/core/mouse/mouse-0.0.1.js                                   //
//  /javascript/jquery_plugins/core/popovers/popovers-0.0.1.js                             //
//  /javascript/jquery_plugins/core/popovers/popovers_mini-0.0.1.js                        //
//  /javascript/jquery_plugins/core/text_shortener/text_shortener-0.0.1.js                 //
//  /javascript/jquery_plugins/core/transform_input/transform_input-0.0.2.js               //
//  /javascript/front/custom.js                                                            //
//  /javascript/front/venue_page.js                                                        //
//  /javascript/front/search_results.js                                                    //
//  /javascript/front/takeaway_schedule.js                                                 //
//  /javascript/front/takeaway_shopping_cart.js                                            //
//  /javascript/front/voucher_shopping_cart.js                                             //
//  /javascript/front/google_analytics.js                                                  //
//  /javascript/front/yahoo.js                                                             //
//  /javascript/front/jquery.mCustomScrollbar.js                                           //
//  /javascript/front/jquery.mousewheel.min.js                                             //
//  /javascript/front/jquery.cluetip.js                                                    //
///////////////////////////////////////////////////////////////////////////////////////////*/

/*//////////////////////////////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/livequery/livequery-1.1.1/jquery.livequery.min.js //
// created: Mon, 26 Sep 2011 14:01:58 +1000                                           //
// modified: Fri, 12 Feb 2010 19:24:26 +1100                                          //
// size: 3007 bytes                                                                   //
//////////////////////////////////////////////////////////////////////////////////////*/

/* Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net)
 * Dual licensed under the MIT (MIT_LICENSE.txt)
 * and GPL Version 2 (GPL_LICENSE.txt) licenses.
 *
 * Version: 1.1.1
 * Requires jQuery 1.3+
 * Docs: http://docs.jquery.com/Plugins/livequery
 */
(function(a){a.extend(a.fn,{livequery:function(e,d,c){var b=this,f;if(a.isFunction(e)){c=d,d=e,e=undefined}a.each(a.livequery.queries,function(g,h){if(b.selector==h.selector&&b.context==h.context&&e==h.type&&(!d||d.$lqguid==h.fn.$lqguid)&&(!c||c.$lqguid==h.fn2.$lqguid)){return(f=h)&&false}});f=f||new a.livequery(this.selector,this.context,e,d,c);f.stopped=false;f.run();return this},expire:function(e,d,c){var b=this;if(a.isFunction(e)){c=d,d=e,e=undefined}a.each(a.livequery.queries,function(f,g){if(b.selector==g.selector&&b.context==g.context&&(!e||e==g.type)&&(!d||d.$lqguid==g.fn.$lqguid)&&(!c||c.$lqguid==g.fn2.$lqguid)&&!this.stopped){a.livequery.stop(g.id)}});return this}});a.livequery=function(b,d,f,e,c){this.selector=b;this.context=d;this.type=f;this.fn=e;this.fn2=c;this.elements=[];this.stopped=false;this.id=a.livequery.queries.push(this)-1;e.$lqguid=e.$lqguid||a.livequery.guid++;if(c){c.$lqguid=c.$lqguid||a.livequery.guid++}return this};a.livequery.prototype={stop:function(){var b=this;if(this.type){this.elements.unbind(this.type,this.fn)}else{if(this.fn2){this.elements.each(function(c,d){b.fn2.apply(d)})}}this.elements=[];this.stopped=true},run:function(){if(this.stopped){return}var d=this;var e=this.elements,c=a(this.selector,this.context),b=c.not(e);this.elements=c;if(this.type){b.bind(this.type,this.fn);if(e.length>0){a.each(e,function(f,g){if(a.inArray(g,c)<0){a.event.remove(g,d.type,d.fn)}})}}else{b.each(function(){d.fn.apply(this)});if(this.fn2&&e.length>0){a.each(e,function(f,g){if(a.inArray(g,c)<0){d.fn2.apply(g)}})}}}};a.extend(a.livequery,{guid:0,queries:[],queue:[],running:false,timeout:null,checkQueue:function(){if(a.livequery.running&&a.livequery.queue.length){var b=a.livequery.queue.length;while(b--){a.livequery.queries[a.livequery.queue.shift()].run()}}},pause:function(){a.livequery.running=false},play:function(){a.livequery.running=true;a.livequery.run()},registerPlugin:function(){a.each(arguments,function(c,d){if(!a.fn[d]){return}var b=a.fn[d];a.fn[d]=function(){var e=b.apply(this,arguments);a.livequery.run();return e}})},run:function(b){if(b!=undefined){if(a.inArray(b,a.livequery.queue)<0){a.livequery.queue.push(b)}}else{a.each(a.livequery.queries,function(c){if(a.inArray(c,a.livequery.queue)<0){a.livequery.queue.push(c)}})}if(a.livequery.timeout){clearTimeout(a.livequery.timeout)}a.livequery.timeout=setTimeout(a.livequery.checkQueue,20)},stop:function(b){if(b!=undefined){a.livequery.queries[b].stop()}else{a.each(a.livequery.queries,function(c){a.livequery.queries[c].stop()})}}});a.livequery.registerPlugin("append","prepend","after","before","wrap","attr","removeAttr","addClass","removeClass","toggleClass","empty","remove","html");a(function(){a.livequery.play()})})(jQuery);









/*////////////////////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/jquery_ui/jquery-ui-1.8.7.custom.min.js //
// created: Mon, 26 Sep 2011 14:01:58 +1000                                 //
// modified: Fri, 07 Jan 2011 15:24:04 +1100                                //
// size: 206617 bytes                                                       //
////////////////////////////////////////////////////////////////////////////*/

/*!
 * jQuery UI 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI
 */
(function(c,j){function k(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.7",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,
NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,
"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");
if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,l,m){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(l)g-=parseFloat(c.curCSS(f,
"border"+this+"Width",true))||0;if(m)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h,
d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){var b=a.nodeName.toLowerCase(),d=c.attr(a,"tabindex");if("area"===b){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&k(a)}return(/input|select|textarea|button|object/.test(b)?!a.disabled:"a"==b?a.href||!isNaN(d):!isNaN(d))&&k(a)},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}});
c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e<b.length;e++)a.options[b[e][0]]&&
b[e][1].apply(a.element,d)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&&c.ui.isOverAxis(b,e,i)}})}})(jQuery);
;/*!
 * jQuery UI Widget 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Widget
 */
(function(b,j){if(b.cleanData){var k=b.cleanData;b.cleanData=function(a){for(var c=0,d;(d=a[c])!=null;c++)b(d).triggerHandler("remove");k(a)}}else{var l=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add([this]).each(function(){b(this).triggerHandler("remove")});return l.call(b(this),a,c)})}}b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]=function(h){return!!b.data(h,
a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend(true,{},c.options);b[e][a].prototype=b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)):d;if(e&&d.charAt(0)==="_")return h;
e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==j){h=i;return false}}):this.each(function(){var g=b.data(this,a);g?g.option(d||{})._init():b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){b.data(c,this.widgetName,this);this.element=b(c);this.options=b.extend(true,{},this.options,
this._getCreateOptions(),a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},
widget:function(){return this.element},option:function(a,c){var d=a;if(arguments.length===0)return b.extend({},this.options);if(typeof a==="string"){if(c===j)return this.options[a];d={};d[a]=c}this._setOptions(d);return this},_setOptions:function(a){var c=this;b.each(a,function(d,e){c._setOption(d,e)});return this},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this},
enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery);
;/*!
 * jQuery UI Mouse 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Mouse
 *
 * Depends:
 *	jquery.ui.widget.js
 */
(function(c){c.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(b){return a._mouseDown(b)}).bind("click."+this.widgetName,function(b){if(true===c.data(b.target,a.widgetName+".preventClickEvent")){c.removeData(b.target,a.widgetName+".preventClickEvent");b.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(a){a.originalEvent=
a.originalEvent||{};if(!a.originalEvent.mouseHandled){this._mouseStarted&&this._mouseUp(a);this._mouseDownEvent=a;var b=this,e=a.which==1,f=typeof this.options.cancel=="string"?c(a.target).parents().add(a.target).filter(this.options.cancel).length:false;if(!e||f||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){b.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted=
this._mouseStart(a)!==false;if(!this._mouseStarted){a.preventDefault();return true}}this._mouseMoveDelegate=function(d){return b._mouseMove(d)};this._mouseUpDelegate=function(d){return b._mouseUp(d)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);a.preventDefault();return a.originalEvent.mouseHandled=true}},_mouseMove:function(a){if(c.browser.msie&&!(document.documentMode>=9)&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);
return a.preventDefault()}if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;a.target==this._mouseDownEvent.target&&c.data(a.target,this.widgetName+".preventClickEvent",
true);this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery);
;/*
 * jQuery UI Position 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Position
 */
(function(c){c.ui=c.ui||{};var n=/left|center|right/,o=/top|center|bottom/,t=c.fn.position,u=c.fn.offset;c.fn.position=function(b){if(!b||!b.of)return t.apply(this,arguments);b=c.extend({},b);var a=c(b.of),d=a[0],g=(b.collision||"flip").split(" "),e=b.offset?b.offset.split(" "):[0,0],h,k,j;if(d.nodeType===9){h=a.width();k=a.height();j={top:0,left:0}}else if(d.setTimeout){h=a.width();k=a.height();j={top:a.scrollTop(),left:a.scrollLeft()}}else if(d.preventDefault){b.at="left top";h=k=0;j={top:b.of.pageY,
left:b.of.pageX}}else{h=a.outerWidth();k=a.outerHeight();j=a.offset()}c.each(["my","at"],function(){var f=(b[this]||"").split(" ");if(f.length===1)f=n.test(f[0])?f.concat(["center"]):o.test(f[0])?["center"].concat(f):["center","center"];f[0]=n.test(f[0])?f[0]:"center";f[1]=o.test(f[1])?f[1]:"center";b[this]=f});if(g.length===1)g[1]=g[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(b.at[0]==="right")j.left+=h;else if(b.at[0]==="center")j.left+=h/2;if(b.at[1]==="bottom")j.top+=
k;else if(b.at[1]==="center")j.top+=k/2;j.left+=e[0];j.top+=e[1];return this.each(function(){var f=c(this),l=f.outerWidth(),m=f.outerHeight(),p=parseInt(c.curCSS(this,"marginLeft",true))||0,q=parseInt(c.curCSS(this,"marginTop",true))||0,v=l+p+parseInt(c.curCSS(this,"marginRight",true))||0,w=m+q+parseInt(c.curCSS(this,"marginBottom",true))||0,i=c.extend({},j),r;if(b.my[0]==="right")i.left-=l;else if(b.my[0]==="center")i.left-=l/2;if(b.my[1]==="bottom")i.top-=m;else if(b.my[1]==="center")i.top-=m/2;
i.left=Math.round(i.left);i.top=Math.round(i.top);r={left:i.left-p,top:i.top-q};c.each(["left","top"],function(s,x){c.ui.position[g[s]]&&c.ui.position[g[s]][x](i,{targetWidth:h,targetHeight:k,elemWidth:l,elemHeight:m,collisionPosition:r,collisionWidth:v,collisionHeight:w,offset:e,my:b.my,at:b.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(i,{using:b.using}))})};c.ui.position={fit:{left:function(b,a){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();b.left=
d>0?b.left-d:Math.max(b.left-a.collisionPosition.left,b.left)},top:function(b,a){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();b.top=d>0?b.top-d:Math.max(b.top-a.collisionPosition.top,b.top)}},flip:{left:function(b,a){if(a.at[0]!=="center"){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();var g=a.my[0]==="left"?-a.elemWidth:a.my[0]==="right"?a.elemWidth:0,e=a.at[0]==="left"?a.targetWidth:-a.targetWidth,h=-2*a.offset[0];b.left+=
a.collisionPosition.left<0?g+e+h:d>0?g+e+h:0}},top:function(b,a){if(a.at[1]!=="center"){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();var g=a.my[1]==="top"?-a.elemHeight:a.my[1]==="bottom"?a.elemHeight:0,e=a.at[1]==="top"?a.targetHeight:-a.targetHeight,h=-2*a.offset[1];b.top+=a.collisionPosition.top<0?g+e+h:d>0?g+e+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(b,a){if(/static/.test(c.curCSS(b,"position")))b.style.position="relative";var d=c(b),
g=d.offset(),e=parseInt(c.curCSS(b,"top",true),10)||0,h=parseInt(c.curCSS(b,"left",true),10)||0;g={top:a.top-g.top+e,left:a.left-g.left+h};"using"in a?a.using.call(b,g):d.css(g)};c.fn.offset=function(b){var a=this[0];if(!a||!a.ownerDocument)return null;if(b)return this.each(function(){c.offset.setOffset(this,b)});return u.call(this)}}})(jQuery);
;/*
 * jQuery UI Draggable 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Draggables
 *
 * Depends:
 *	jquery.ui.core.js
 *	jquery.ui.mouse.js
 *	jquery.ui.widget.js
 */
(function(d){d.widget("ui.draggable",d.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper==
"original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(a){var b=
this.options;if(this.helper||b.disabled||d(a.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(a);if(!this.handle)return false;return true},_mouseStart:function(a){var b=this.options;this.helper=this._createHelper(a);this._cacheHelperProportions();if(d.ui.ddmanager)d.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-
this.margins.top,left:this.offset.left-this.margins.left};d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this.position=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);b.containment&&this._setContainment();if(this._trigger("start",a)===false){this._clear();return false}this._cacheHelperProportions();
d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(a,true);return true},_mouseDrag:function(a,b){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!b){b=this._uiHash();if(this._trigger("drag",a,b)===false){this._mouseUp({});return false}this.position=b.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||
this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);return false},_mouseStop:function(a){var b=false;if(d.ui.ddmanager&&!this.options.dropBehaviour)b=d.ui.ddmanager.drop(this,a);if(this.dropped){b=this.dropped;this.dropped=false}if(!this.element[0]||!this.element[0].parentNode)return false;if(this.options.revert=="invalid"&&!b||this.options.revert=="valid"&&b||this.options.revert===true||d.isFunction(this.options.revert)&&this.options.revert.call(this.element,
b)){var c=this;d(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){c._trigger("stop",a)!==false&&c._clear()})}else this._trigger("stop",a)!==false&&this._clear();return false},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(a){var b=!this.options.handle||!d(this.options.handle,this.element).length?true:false;d(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==
a.target)b=true});return b},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a])):b.helper=="clone"?this.element.clone():this.element;a.parents("body").length||a.appendTo(b.appendTo=="parent"?this.element[0].parentNode:b.appendTo);a[0]!=this.element[0]&&!/(fixed|absolute)/.test(a.css("position"))&&a.css("position","absolute");return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||
0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],
this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-
(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment==
"parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[(a.containment=="document"?0:d(window).scrollLeft())-this.offset.relative.left-this.offset.parent.left,(a.containment=="document"?0:d(window).scrollTop())-this.offset.relative.top-this.offset.parent.top,(a.containment=="document"?0:d(window).scrollLeft())+d(a.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a.containment=="document"?
0:d(window).scrollTop())+(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)&&a.containment.constructor!=Array){var b=d(a.containment)[0];if(b){a=d(a.containment).offset();var c=d(b).css("overflow")!="hidden";this.containment=[a.left+(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0)-this.margins.left,a.top+(parseInt(d(b).css("borderTopWidth"),
10)||0)+(parseInt(d(b).css("paddingTop"),10)||0)-this.margins.top,a.left+(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,a.top+(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}}else if(a.containment.constructor==
Array)this.containment=a.containment},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName);return{top:b.top+this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():
f?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName),e=a.pageX,g=a.pageY;
if(this.originalPosition){if(this.containment){if(a.pageX-this.offset.click.left<this.containment[0])e=this.containment[0]+this.offset.click.left;if(a.pageY-this.offset.click.top<this.containment[1])g=this.containment[1]+this.offset.click.top;if(a.pageX-this.offset.click.left>this.containment[2])e=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g-this.originalPageY)/
b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:!(g-this.offset.click.top<this.containment[1])?g-b.grid[1]:g+b.grid[1]:g;e=this.originalPageX+Math.round((e-this.originalPageX)/b.grid[0])*b.grid[0];e=this.containment?!(e-this.offset.click.left<this.containment[0]||e-this.offset.click.left>this.containment[2])?e:!(e-this.offset.click.left<this.containment[0])?e-b.grid[0]:e+b.grid[0]:e}}return{top:g-this.offset.click.top-
this.offset.relative.top-this.offset.parent.top+(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop()),left:e-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging");this.helper[0]!=
this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove();this.helper=null;this.cancelHelperRemoval=false},_trigger:function(a,b,c){c=c||this._uiHash();d.ui.plugin.call(this,a,[b,c]);if(a=="drag")this.positionAbs=this._convertPositionTo("absolute");return d.Widget.prototype._trigger.call(this,a,b,c)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}});d.extend(d.ui.draggable,{version:"1.8.7"});
d.ui.plugin.add("draggable","connectToSortable",{start:function(a,b){var c=d(this).data("draggable"),f=c.options,e=d.extend({},b,{item:c.element});c.sortables=[];d(f.connectToSortable).each(function(){var g=d.data(this,"sortable");if(g&&!g.options.disabled){c.sortables.push({instance:g,shouldRevert:g.options.revert});g._refreshItems();g._trigger("activate",a,e)}})},stop:function(a,b){var c=d(this).data("draggable"),f=d.extend({},b,{item:c.element});d.each(c.sortables,function(){if(this.instance.isOver){this.instance.isOver=
0;c.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert)this.instance.options.revert=true;this.instance._mouseStop(a);this.instance.options.helper=this.instance.options._helper;c.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})}else{this.instance.cancelHelperRemoval=false;this.instance._trigger("deactivate",a,f)}})},drag:function(a,b){var c=d(this).data("draggable"),f=this;d.each(c.sortables,function(){this.instance.positionAbs=
c.positionAbs;this.instance.helperProportions=c.helperProportions;this.instance.offset.click=c.offset.click;if(this.instance._intersectsWith(this.instance.containerCache)){if(!this.instance.isOver){this.instance.isOver=1;this.instance.currentItem=d(f).clone().appendTo(this.instance.element).data("sortable-item",true);this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return b.helper[0]};a.target=this.instance.currentItem[0];this.instance._mouseCapture(a,
true);this.instance._mouseStart(a,true,true);this.instance.offset.click.top=c.offset.click.top;this.instance.offset.click.left=c.offset.click.left;this.instance.offset.parent.left-=c.offset.parent.left-this.instance.offset.parent.left;this.instance.offset.parent.top-=c.offset.parent.top-this.instance.offset.parent.top;c._trigger("toSortable",a);c.dropped=this.instance.element;c.currentItem=c.element;this.instance.fromOutside=c}this.instance.currentItem&&this.instance._mouseDrag(a)}else if(this.instance.isOver){this.instance.isOver=
0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._trigger("out",a,this.instance._uiHash(this.instance));this.instance._mouseStop(a,true);this.instance.options.helper=this.instance.options._helper;this.instance.currentItem.remove();this.instance.placeholder&&this.instance.placeholder.remove();c._trigger("fromSortable",a);c.dropped=false}})}});d.ui.plugin.add("draggable","cursor",{start:function(){var a=d("body"),b=d(this).data("draggable").options;if(a.css("cursor"))b._cursor=
a.css("cursor");a.css("cursor",b.cursor)},stop:function(){var a=d(this).data("draggable").options;a._cursor&&d("body").css("cursor",a._cursor)}});d.ui.plugin.add("draggable","iframeFix",{start:function(){var a=d(this).data("draggable").options;d(a.iframeFix===true?"iframe":a.iframeFix).each(function(){d('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(d(this).offset()).appendTo("body")})},
stop:function(){d("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)})}});d.ui.plugin.add("draggable","opacity",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;if(a.css("opacity"))b._opacity=a.css("opacity");a.css("opacity",b.opacity)},stop:function(a,b){a=d(this).data("draggable").options;a._opacity&&d(b.helper).css("opacity",a._opacity)}});d.ui.plugin.add("draggable","scroll",{start:function(){var a=d(this).data("draggable");if(a.scrollParent[0]!=
document&&a.scrollParent[0].tagName!="HTML")a.overflowOffset=a.scrollParent.offset()},drag:function(a){var b=d(this).data("draggable"),c=b.options,f=false;if(b.scrollParent[0]!=document&&b.scrollParent[0].tagName!="HTML"){if(!c.axis||c.axis!="x")if(b.overflowOffset.top+b.scrollParent[0].offsetHeight-a.pageY<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop+c.scrollSpeed;else if(a.pageY-b.overflowOffset.top<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop-
c.scrollSpeed;if(!c.axis||c.axis!="y")if(b.overflowOffset.left+b.scrollParent[0].offsetWidth-a.pageX<c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft+c.scrollSpeed;else if(a.pageX-b.overflowOffset.left<c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft-c.scrollSpeed}else{if(!c.axis||c.axis!="x")if(a.pageY-d(document).scrollTop()<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()-c.scrollSpeed);else if(d(window).height()-
(a.pageY-d(document).scrollTop())<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()+c.scrollSpeed);if(!c.axis||c.axis!="y")if(a.pageX-d(document).scrollLeft()<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()-c.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()+c.scrollSpeed)}f!==false&&d.ui.ddmanager&&!c.dropBehaviour&&d.ui.ddmanager.prepareOffsets(b,a)}});d.ui.plugin.add("draggable",
"snap",{start:function(){var a=d(this).data("draggable"),b=a.options;a.snapElements=[];d(b.snap.constructor!=String?b.snap.items||":data(draggable)":b.snap).each(function(){var c=d(this),f=c.offset();this!=a.element[0]&&a.snapElements.push({item:this,width:c.outerWidth(),height:c.outerHeight(),top:f.top,left:f.left})})},drag:function(a,b){for(var c=d(this).data("draggable"),f=c.options,e=f.snapTolerance,g=b.offset.left,n=g+c.helperProportions.width,m=b.offset.top,o=m+c.helperProportions.height,h=
c.snapElements.length-1;h>=0;h--){var i=c.snapElements[h].left,k=i+c.snapElements[h].width,j=c.snapElements[h].top,l=j+c.snapElements[h].height;if(i-e<g&&g<k+e&&j-e<m&&m<l+e||i-e<g&&g<k+e&&j-e<o&&o<l+e||i-e<n&&n<k+e&&j-e<m&&m<l+e||i-e<n&&n<k+e&&j-e<o&&o<l+e){if(f.snapMode!="inner"){var p=Math.abs(j-o)<=e,q=Math.abs(l-m)<=e,r=Math.abs(i-n)<=e,s=Math.abs(k-g)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:j-c.helperProportions.height,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",
{top:l,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:i-c.helperProportions.width}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:k}).left-c.margins.left}var t=p||q||r||s;if(f.snapMode!="outer"){p=Math.abs(j-m)<=e;q=Math.abs(l-o)<=e;r=Math.abs(i-g)<=e;s=Math.abs(k-n)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:j,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:l-c.helperProportions.height,
left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:i}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:k-c.helperProportions.width}).left-c.margins.left}if(!c.snapElements[h].snapping&&(p||q||r||s||t))c.options.snap.snap&&c.options.snap.snap.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[h].item}));c.snapElements[h].snapping=p||q||r||s||t}else{c.snapElements[h].snapping&&c.options.snap.release&&c.options.snap.release.call(c.element,
a,d.extend(c._uiHash(),{snapItem:c.snapElements[h].item}));c.snapElements[h].snapping=false}}}});d.ui.plugin.add("draggable","stack",{start:function(){var a=d(this).data("draggable").options;a=d.makeArray(d(a.stack)).sort(function(c,f){return(parseInt(d(c).css("zIndex"),10)||0)-(parseInt(d(f).css("zIndex"),10)||0)});if(a.length){var b=parseInt(a[0].style.zIndex)||0;d(a).each(function(c){this.style.zIndex=b+c});this[0].style.zIndex=b+a.length}}});d.ui.plugin.add("draggable","zIndex",{start:function(a,
b){a=d(b.helper);b=d(this).data("draggable").options;if(a.css("zIndex"))b._zIndex=a.css("zIndex");a.css("zIndex",b.zIndex)},stop:function(a,b){a=d(this).data("draggable").options;a._zIndex&&d(b.helper).css("zIndex",a._zIndex)}})})(jQuery);
;/*
 * jQuery UI Droppable 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Droppables
 *
 * Depends:
 *	jquery.ui.core.js
 *	jquery.ui.widget.js
 *	jquery.ui.mouse.js
 *	jquery.ui.draggable.js
 */
(function(d){d.widget("ui.droppable",{widgetEventPrefix:"drop",options:{accept:"*",activeClass:false,addClasses:true,greedy:false,hoverClass:false,scope:"default",tolerance:"intersect"},_create:function(){var a=this.options,b=a.accept;this.isover=0;this.isout=1;this.accept=d.isFunction(b)?b:function(c){return c.is(b)};this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight};d.ui.ddmanager.droppables[a.scope]=d.ui.ddmanager.droppables[a.scope]||[];d.ui.ddmanager.droppables[a.scope].push(this);
a.addClasses&&this.element.addClass("ui-droppable")},destroy:function(){for(var a=d.ui.ddmanager.droppables[this.options.scope],b=0;b<a.length;b++)a[b]==this&&a.splice(b,1);this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable");return this},_setOption:function(a,b){if(a=="accept")this.accept=d.isFunction(b)?b:function(c){return c.is(b)};d.Widget.prototype._setOption.apply(this,arguments)},_activate:function(a){var b=d.ui.ddmanager.current;this.options.activeClass&&
this.element.addClass(this.options.activeClass);b&&this._trigger("activate",a,this.ui(b))},_deactivate:function(a){var b=d.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass);b&&this._trigger("deactivate",a,this.ui(b))},_over:function(a){var b=d.ui.ddmanager.current;if(!(!b||(b.currentItem||b.element)[0]==this.element[0]))if(this.accept.call(this.element[0],b.currentItem||b.element)){this.options.hoverClass&&this.element.addClass(this.options.hoverClass);
this._trigger("over",a,this.ui(b))}},_out:function(a){var b=d.ui.ddmanager.current;if(!(!b||(b.currentItem||b.element)[0]==this.element[0]))if(this.accept.call(this.element[0],b.currentItem||b.element)){this.options.hoverClass&&this.element.removeClass(this.options.hoverClass);this._trigger("out",a,this.ui(b))}},_drop:function(a,b){var c=b||d.ui.ddmanager.current;if(!c||(c.currentItem||c.element)[0]==this.element[0])return false;var e=false;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var g=
d.data(this,"droppable");if(g.options.greedy&&!g.options.disabled&&g.options.scope==c.options.scope&&g.accept.call(g.element[0],c.currentItem||c.element)&&d.ui.intersect(c,d.extend(g,{offset:g.element.offset()}),g.options.tolerance)){e=true;return false}});if(e)return false;if(this.accept.call(this.element[0],c.currentItem||c.element)){this.options.activeClass&&this.element.removeClass(this.options.activeClass);this.options.hoverClass&&this.element.removeClass(this.options.hoverClass);this._trigger("drop",
a,this.ui(c));return this.element}return false},ui:function(a){return{draggable:a.currentItem||a.element,helper:a.helper,position:a.position,offset:a.positionAbs}}});d.extend(d.ui.droppable,{version:"1.8.7"});d.ui.intersect=function(a,b,c){if(!b.offset)return false;var e=(a.positionAbs||a.position.absolute).left,g=e+a.helperProportions.width,f=(a.positionAbs||a.position.absolute).top,h=f+a.helperProportions.height,i=b.offset.left,k=i+b.proportions.width,j=b.offset.top,l=j+b.proportions.height;
switch(c){case "fit":return i<=e&&g<=k&&j<=f&&h<=l;case "intersect":return i<e+a.helperProportions.width/2&&g-a.helperProportions.width/2<k&&j<f+a.helperProportions.height/2&&h-a.helperProportions.height/2<l;case "pointer":return d.ui.isOver((a.positionAbs||a.position.absolute).top+(a.clickOffset||a.offset.click).top,(a.positionAbs||a.position.absolute).left+(a.clickOffset||a.offset.click).left,j,i,b.proportions.height,b.proportions.width);case "touch":return(f>=j&&f<=l||h>=j&&h<=l||f<j&&h>l)&&(e>=
i&&e<=k||g>=i&&g<=k||e<i&&g>k);default:return false}};d.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(a,b){var c=d.ui.ddmanager.droppables[a.options.scope]||[],e=b?b.type:null,g=(a.currentItem||a.element).find(":data(droppable)").andSelf(),f=0;a:for(;f<c.length;f++)if(!(c[f].options.disabled||a&&!c[f].accept.call(c[f].element[0],a.currentItem||a.element))){for(var h=0;h<g.length;h++)if(g[h]==c[f].element[0]){c[f].proportions.height=0;continue a}c[f].visible=c[f].element.css("display")!=
"none";if(c[f].visible){c[f].offset=c[f].element.offset();c[f].proportions={width:c[f].element[0].offsetWidth,height:c[f].element[0].offsetHeight};e=="mousedown"&&c[f]._activate.call(c[f],b)}}},drop:function(a,b){var c=false;d.each(d.ui.ddmanager.droppables[a.options.scope]||[],function(){if(this.options){if(!this.options.disabled&&this.visible&&d.ui.intersect(a,this,this.options.tolerance))c=c||this._drop.call(this,b);if(!this.options.disabled&&this.visible&&this.accept.call(this.element[0],a.currentItem||
a.element)){this.isout=1;this.isover=0;this._deactivate.call(this,b)}}});return c},drag:function(a,b){a.options.refreshPositions&&d.ui.ddmanager.prepareOffsets(a,b);d.each(d.ui.ddmanager.droppables[a.options.scope]||[],function(){if(!(this.options.disabled||this.greedyChild||!this.visible)){var c=d.ui.intersect(a,this,this.options.tolerance);if(c=!c&&this.isover==1?"isout":c&&this.isover==0?"isover":null){var e;if(this.options.greedy){var g=this.element.parents(":data(droppable):eq(0)");if(g.length){e=
d.data(g[0],"droppable");e.greedyChild=c=="isover"?1:0}}if(e&&c=="isover"){e.isover=0;e.isout=1;e._out.call(e,b)}this[c]=1;this[c=="isout"?"isover":"isout"]=0;this[c=="isover"?"_over":"_out"].call(this,b);if(e&&c=="isout"){e.isout=0;e.isover=1;e._over.call(e,b)}}}})}}})(jQuery);
;/*
 * jQuery UI Resizable 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Resizables
 *
 * Depends:
 *	jquery.ui.core.js
 *	jquery.ui.mouse.js
 *	jquery.ui.widget.js
 */
(function(e){e.widget("ui.resizable",e.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1E3},_create:function(){var b=this,a=this.options;this.element.addClass("ui-resizable");e.extend(this,{_aspectRatio:!!a.aspectRatio,aspectRatio:a.aspectRatio,originalElement:this.element,
_proportionallyResizeElements:[],_helper:a.helper||a.ghost||a.animate?a.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){/relative/.test(this.element.css("position"))&&e.browser.opera&&this.element.css({position:"relative",top:"auto",left:"auto"});this.element.wrap(e('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),
top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=
this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=a.handles||(!e(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",
nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var c=this.handles.split(",");this.handles={};for(var d=0;d<c.length;d++){var f=e.trim(c[d]),g=e('<div class="ui-resizable-handle '+("ui-resizable-"+f)+'"></div>');/sw|se|ne|nw/.test(f)&&g.css({zIndex:++a.zIndex});"se"==f&&g.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[f]=".ui-resizable-"+f;this.element.append(g)}}this._renderAxis=function(h){h=h||this.element;for(var i in this.handles){if(this.handles[i].constructor==
String)this.handles[i]=e(this.handles[i],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var j=e(this.handles[i],this.element),k=0;k=/sw|ne|nw|se|n|s/.test(i)?j.outerHeight():j.outerWidth();j=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join("");h.css(j,k);this._proportionallyResize()}e(this.handles[i])}};this._renderAxis(this.element);this._handles=e(".ui-resizable-handle",this.element).disableSelection();
this._handles.mouseover(function(){if(!b.resizing){if(this.className)var h=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=h&&h[1]?h[1]:"se"}});if(a.autoHide){this._handles.hide();e(this.element).addClass("ui-resizable-autohide").hover(function(){e(this).removeClass("ui-resizable-autohide");b._handles.show()},function(){if(!b.resizing){e(this).addClass("ui-resizable-autohide");b._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(c){e(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};
if(this.elementIsWrapper){b(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(),height:a.outerHeight(),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);b(this.originalElement);return this},_mouseCapture:function(b){var a=false;for(var c in this.handles)if(e(this.handles[c])[0]==b.target)a=true;return!this.options.disabled&&a},_mouseStart:function(b){var a=this.options,c=this.element.position(),
d=this.element;this.resizing=true;this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()};if(d.is(".ui-draggable")||/absolute/.test(d.css("position")))d.css({position:"absolute",top:c.top,left:c.left});e.browser.opera&&/relative/.test(d.css("position"))&&d.css({position:"relative",top:"auto",left:"auto"});this._renderProxy();c=m(this.helper.css("left"));var f=m(this.helper.css("top"));if(a.containment){c+=e(a.containment).scrollLeft()||0;f+=e(a.containment).scrollTop()||0}this.offset=
this.helper.offset();this.position={left:c,top:f};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:c,top:f};this.sizeDiff={width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:b.pageX,top:b.pageY};this.aspectRatio=typeof a.aspectRatio=="number"?a.aspectRatio:
this.originalSize.width/this.originalSize.height||1;a=e(".ui-resizable-"+this.axis).css("cursor");e("body").css("cursor",a=="auto"?this.axis+"-resize":a);d.addClass("ui-resizable-resizing");this._propagate("start",b);return true},_mouseDrag:function(b){var a=this.helper,c=this.originalMousePosition,d=this._change[this.axis];if(!d)return false;c=d.apply(this,[b,b.pageX-c.left||0,b.pageY-c.top||0]);if(this._aspectRatio||b.shiftKey)c=this._updateRatio(c,b);c=this._respectSize(c,b);this._propagate("resize",
b);a.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(c);this._trigger("resize",b,this.ui());return false},_mouseStop:function(b){this.resizing=false;var a=this.options,c=this;if(this._helper){var d=this._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName);d=f&&e.ui.hasScroll(d[0],"left")?0:c.sizeDiff.height;
f={width:c.size.width-(f?0:c.sizeDiff.width),height:c.size.height-d};d=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null;var g=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null;a.animate||this.element.css(e.extend(f,{top:g,left:d}));c.helper.height(c.size.height);c.helper.width(c.size.width);this._helper&&!a.animate&&this._proportionallyResize()}e("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",
b);this._helper&&this.helper.remove();return false},_updateCache:function(b){this.offset=this.helper.offset();if(l(b.left))this.position.left=b.left;if(l(b.top))this.position.top=b.top;if(l(b.height))this.size.height=b.height;if(l(b.width))this.size.width=b.width},_updateRatio:function(b){var a=this.position,c=this.size,d=this.axis;if(b.height)b.width=c.height*this.aspectRatio;else if(b.width)b.height=c.width/this.aspectRatio;if(d=="sw"){b.left=a.left+(c.width-b.width);b.top=null}if(d=="nw"){b.top=
a.top+(c.height-b.height);b.left=a.left+(c.width-b.width)}return b},_respectSize:function(b){var a=this.options,c=this.axis,d=l(b.width)&&a.maxWidth&&a.maxWidth<b.width,f=l(b.height)&&a.maxHeight&&a.maxHeight<b.height,g=l(b.width)&&a.minWidth&&a.minWidth>b.width,h=l(b.height)&&a.minHeight&&a.minHeight>b.height;if(g)b.width=a.minWidth;if(h)b.height=a.minHeight;if(d)b.width=a.maxWidth;if(f)b.height=a.maxHeight;var i=this.originalPosition.left+this.originalSize.width,j=this.position.top+this.size.height,
k=/sw|nw|w/.test(c);c=/nw|ne|n/.test(c);if(g&&k)b.left=i-a.minWidth;if(d&&k)b.left=i-a.maxWidth;if(h&&c)b.top=j-a.minHeight;if(f&&c)b.top=j-a.maxHeight;if((a=!b.width&&!b.height)&&!b.left&&b.top)b.top=null;else if(a&&!b.top&&b.left)b.left=null;return b},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var b=this.helper||this.element,a=0;a<this._proportionallyResizeElements.length;a++){var c=this._proportionallyResizeElements[a];if(!this.borderDif){var d=[c.css("borderTopWidth"),
c.css("borderRightWidth"),c.css("borderBottomWidth"),c.css("borderLeftWidth")],f=[c.css("paddingTop"),c.css("paddingRight"),c.css("paddingBottom"),c.css("paddingLeft")];this.borderDif=e.map(d,function(g,h){g=parseInt(g,10)||0;h=parseInt(f[h],10)||0;return g+h})}e.browser.msie&&(e(b).is(":hidden")||e(b).parents(":hidden").length)||c.css({height:b.height()-this.borderDif[0]-this.borderDif[2]||0,width:b.width()-this.borderDif[1]-this.borderDif[3]||0})}},_renderProxy:function(){var b=this.options;this.elementOffset=
this.element.offset();if(this._helper){this.helper=this.helper||e('<div style="overflow:hidden;"></div>');var a=e.browser.msie&&e.browser.version<7,c=a?1:0;a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+a,height:this.element.outerHeight()+a,position:"absolute",left:this.elementOffset.left-c+"px",top:this.elementOffset.top-c+"px",zIndex:++b.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(b,a){return{width:this.originalSize.width+
a}},w:function(b,a){return{left:this.originalPosition.left+a,width:this.originalSize.width-a}},n:function(b,a,c){return{top:this.originalPosition.top+c,height:this.originalSize.height-c}},s:function(b,a,c){return{height:this.originalSize.height+c}},se:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},sw:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,a,c]))},ne:function(b,a,c){return e.extend(this._change.n.apply(this,
arguments),this._change.e.apply(this,[b,a,c]))},nw:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,a,c]))}},_propagate:function(b,a){e.ui.plugin.call(this,b,[a,this.ui()]);b!="resize"&&this._trigger(b,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});e.extend(e.ui.resizable,
{version:"1.8.7"});e.ui.plugin.add("resizable","alsoResize",{start:function(){var b=e(this).data("resizable").options,a=function(c){e(c).each(function(){var d=e(this);d.data("resizable-alsoresize",{width:parseInt(d.width(),10),height:parseInt(d.height(),10),left:parseInt(d.css("left"),10),top:parseInt(d.css("top"),10),position:d.css("position")})})};if(typeof b.alsoResize=="object"&&!b.alsoResize.parentNode)if(b.alsoResize.length){b.alsoResize=b.alsoResize[0];a(b.alsoResize)}else e.each(b.alsoResize,
function(c){a(c)});else a(b.alsoResize)},resize:function(b,a){var c=e(this).data("resizable");b=c.options;var d=c.originalSize,f=c.originalPosition,g={height:c.size.height-d.height||0,width:c.size.width-d.width||0,top:c.position.top-f.top||0,left:c.position.left-f.left||0},h=function(i,j){e(i).each(function(){var k=e(this),q=e(this).data("resizable-alsoresize"),p={},r=j&&j.length?j:k.parents(a.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(r,function(n,o){if((n=
(q[o]||0)+(g[o]||0))&&n>=0)p[o]=n||null});if(e.browser.opera&&/relative/.test(k.css("position"))){c._revertToRelativePosition=true;k.css({position:"absolute",top:"auto",left:"auto"})}k.css(p)})};typeof b.alsoResize=="object"&&!b.alsoResize.nodeType?e.each(b.alsoResize,function(i,j){h(i,j)}):h(b.alsoResize)},stop:function(){var b=e(this).data("resizable"),a=b.options,c=function(d){e(d).each(function(){var f=e(this);f.css({position:f.data("resizable-alsoresize").position})})};if(b._revertToRelativePosition){b._revertToRelativePosition=
false;typeof a.alsoResize=="object"&&!a.alsoResize.nodeType?e.each(a.alsoResize,function(d){c(d)}):c(a.alsoResize)}e(this).removeData("resizable-alsoresize")}});e.ui.plugin.add("resizable","animate",{stop:function(b){var a=e(this).data("resizable"),c=a.options,d=a._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName),g=f&&e.ui.hasScroll(d[0],"left")?0:a.sizeDiff.height;f={width:a.size.width-(f?0:a.sizeDiff.width),height:a.size.height-g};g=parseInt(a.element.css("left"),10)+(a.position.left-
a.originalPosition.left)||null;var h=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(e.extend(f,h&&g?{top:h,left:g}:{}),{duration:c.animateDuration,easing:c.animateEasing,step:function(){var i={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10),top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};d&&d.length&&e(d[0]).css({width:i.width,height:i.height});a._updateCache(i);a._propagate("resize",
b)}})}});e.ui.plugin.add("resizable","containment",{start:function(){var b=e(this).data("resizable"),a=b.element,c=b.options.containment;if(a=c instanceof e?c.get(0):/parent/.test(c)?a.parent().get(0):c){b.containerElement=e(a);if(/document/.test(c)||c==document){b.containerOffset={left:0,top:0};b.containerPosition={left:0,top:0};b.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}}else{var d=e(a),f=[];e(["Top",
"Right","Left","Bottom"]).each(function(i,j){f[i]=m(d.css("padding"+j))});b.containerOffset=d.offset();b.containerPosition=d.position();b.containerSize={height:d.innerHeight()-f[3],width:d.innerWidth()-f[1]};c=b.containerOffset;var g=b.containerSize.height,h=b.containerSize.width;h=e.ui.hasScroll(a,"left")?a.scrollWidth:h;g=e.ui.hasScroll(a)?a.scrollHeight:g;b.parentData={element:a,left:c.left,top:c.top,width:h,height:g}}}},resize:function(b){var a=e(this).data("resizable"),c=a.options,d=a.containerOffset,
f=a.position;b=a._aspectRatio||b.shiftKey;var g={top:0,left:0},h=a.containerElement;if(h[0]!=document&&/static/.test(h.css("position")))g=d;if(f.left<(a._helper?d.left:0)){a.size.width+=a._helper?a.position.left-d.left:a.position.left-g.left;if(b)a.size.height=a.size.width/c.aspectRatio;a.position.left=c.helper?d.left:0}if(f.top<(a._helper?d.top:0)){a.size.height+=a._helper?a.position.top-d.top:a.position.top;if(b)a.size.width=a.size.height*c.aspectRatio;a.position.top=a._helper?d.top:0}a.offset.left=
a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;c=Math.abs((a._helper?a.offset.left-g.left:a.offset.left-g.left)+a.sizeDiff.width);d=Math.abs((a._helper?a.offset.top-g.top:a.offset.top-d.top)+a.sizeDiff.height);f=a.containerElement.get(0)==a.element.parent().get(0);g=/relative|absolute/.test(a.containerElement.css("position"));if(f&&g)c-=a.parentData.left;if(c+a.size.width>=a.parentData.width){a.size.width=a.parentData.width-c;if(b)a.size.height=a.size.width/a.aspectRatio}if(d+
a.size.height>=a.parentData.height){a.size.height=a.parentData.height-d;if(b)a.size.width=a.size.height*a.aspectRatio}},stop:function(){var b=e(this).data("resizable"),a=b.options,c=b.containerOffset,d=b.containerPosition,f=b.containerElement,g=e(b.helper),h=g.offset(),i=g.outerWidth()-b.sizeDiff.width;g=g.outerHeight()-b.sizeDiff.height;b._helper&&!a.animate&&/relative/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g});b._helper&&!a.animate&&/static/.test(f.css("position"))&&
e(this).css({left:h.left-d.left-c.left,width:i,height:g})}});e.ui.plugin.add("resizable","ghost",{start:function(){var b=e(this).data("resizable"),a=b.options,c=b.size;b.ghost=b.originalElement.clone();b.ghost.css({opacity:0.25,display:"block",position:"relative",height:c.height,width:c.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof a.ghost=="string"?a.ghost:"");b.ghost.appendTo(b.helper)},resize:function(){var b=e(this).data("resizable");b.ghost&&b.ghost.css({position:"relative",
height:b.size.height,width:b.size.width})},stop:function(){var b=e(this).data("resizable");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}});e.ui.plugin.add("resizable","grid",{resize:function(){var b=e(this).data("resizable"),a=b.options,c=b.size,d=b.originalSize,f=b.originalPosition,g=b.axis;a.grid=typeof a.grid=="number"?[a.grid,a.grid]:a.grid;var h=Math.round((c.width-d.width)/(a.grid[0]||1))*(a.grid[0]||1);a=Math.round((c.height-d.height)/(a.grid[1]||1))*(a.grid[1]||1);if(/^(se|s|e)$/.test(g)){b.size.width=
d.width+h;b.size.height=d.height+a}else if(/^(ne)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}else{if(/^(sw)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a}else{b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}b.position.left=f.left-h}}});var m=function(b){return parseInt(b,10)||0},l=function(b){return!isNaN(parseInt(b,10))}})(jQuery);
;/*
 * jQuery UI Selectable 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Selectables
 *
 * Depends:
 *	jquery.ui.core.js
 *	jquery.ui.mouse.js
 *	jquery.ui.widget.js
 */
(function(e){e.widget("ui.selectable",e.ui.mouse,{options:{appendTo:"body",autoRefresh:true,distance:0,filter:"*",tolerance:"touch"},_create:function(){var c=this;this.element.addClass("ui-selectable");this.dragged=false;var f;this.refresh=function(){f=e(c.options.filter,c.element[0]);f.each(function(){var d=e(this),b=d.offset();e.data(this,"selectable-item",{element:this,$element:d,left:b.left,top:b.top,right:b.left+d.outerWidth(),bottom:b.top+d.outerHeight(),startselected:false,selected:d.hasClass("ui-selected"),
selecting:d.hasClass("ui-selecting"),unselecting:d.hasClass("ui-unselecting")})})};this.refresh();this.selectees=f.addClass("ui-selectee");this._mouseInit();this.helper=e("<div class='ui-selectable-helper'></div>")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(c){var f=this;this.opos=[c.pageX,
c.pageY];if(!this.options.disabled){var d=this.options;this.selectees=e(d.filter,this.element[0]);this._trigger("start",c);e(d.appendTo).append(this.helper);this.helper.css({left:c.clientX,top:c.clientY,width:0,height:0});d.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var b=e.data(this,"selectable-item");b.startselected=true;if(!c.metaKey){b.$element.removeClass("ui-selected");b.selected=false;b.$element.addClass("ui-unselecting");b.unselecting=true;f._trigger("unselecting",
c,{unselecting:b.element})}});e(c.target).parents().andSelf().each(function(){var b=e.data(this,"selectable-item");if(b){var g=!c.metaKey||!b.$element.hasClass("ui-selected");b.$element.removeClass(g?"ui-unselecting":"ui-selected").addClass(g?"ui-selecting":"ui-unselecting");b.unselecting=!g;b.selecting=g;(b.selected=g)?f._trigger("selecting",c,{selecting:b.element}):f._trigger("unselecting",c,{unselecting:b.element});return false}})}},_mouseDrag:function(c){var f=this;this.dragged=true;if(!this.options.disabled){var d=
this.options,b=this.opos[0],g=this.opos[1],h=c.pageX,i=c.pageY;if(b>h){var j=h;h=b;b=j}if(g>i){j=i;i=g;g=j}this.helper.css({left:b,top:g,width:h-b,height:i-g});this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!(!a||a.element==f.element[0])){var k=false;if(d.tolerance=="touch")k=!(a.left>h||a.right<b||a.top>i||a.bottom<g);else if(d.tolerance=="fit")k=a.left>b&&a.right<h&&a.top>g&&a.bottom<i;if(k){if(a.selected){a.$element.removeClass("ui-selected");a.selected=false}if(a.unselecting){a.$element.removeClass("ui-unselecting");
a.unselecting=false}if(!a.selecting){a.$element.addClass("ui-selecting");a.selecting=true;f._trigger("selecting",c,{selecting:a.element})}}else{if(a.selecting)if(c.metaKey&&a.startselected){a.$element.removeClass("ui-selecting");a.selecting=false;a.$element.addClass("ui-selected");a.selected=true}else{a.$element.removeClass("ui-selecting");a.selecting=false;if(a.startselected){a.$element.addClass("ui-unselecting");a.unselecting=true}f._trigger("unselecting",c,{unselecting:a.element})}if(a.selected)if(!c.metaKey&&
!a.startselected){a.$element.removeClass("ui-selected");a.selected=false;a.$element.addClass("ui-unselecting");a.unselecting=true;f._trigger("unselecting",c,{unselecting:a.element})}}}});return false}},_mouseStop:function(c){var f=this;this.dragged=false;e(".ui-unselecting",this.element[0]).each(function(){var d=e.data(this,"selectable-item");d.$element.removeClass("ui-unselecting");d.unselecting=false;d.startselected=false;f._trigger("unselected",c,{unselected:d.element})});e(".ui-selecting",this.element[0]).each(function(){var d=
e.data(this,"selectable-item");d.$element.removeClass("ui-selecting").addClass("ui-selected");d.selecting=false;d.selected=true;d.startselected=true;f._trigger("selected",c,{selected:d.element})});this._trigger("stop",c);this.helper.remove();return false}});e.extend(e.ui.selectable,{version:"1.8.7"})})(jQuery);
;/*
 * jQuery UI Sortable 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Sortables
 *
 * Depends:
 *	jquery.ui.core.js
 *	jquery.ui.mouse.js
 *	jquery.ui.widget.js
 */
(function(d){d.widget("ui.sortable",d.ui.mouse,{widgetEventPrefix:"sort",options:{appendTo:"parent",axis:false,connectWith:false,containment:false,cursor:"auto",cursorAt:false,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,grid:false,handle:false,helper:"original",items:"> *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){this.containerCache={};this.element.addClass("ui-sortable");
this.refresh();this.floating=this.items.length?/left|right/.test(this.items[0].item.css("float")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData("sortable-item");return this},_setOption:function(a,b){if(a==="disabled"){this.options[a]=b;this.widget()[b?"addClass":"removeClass"]("ui-sortable-disabled")}else d.Widget.prototype._setOption.apply(this,
arguments)},_mouseCapture:function(a,b){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(a);var c=null,e=this;d(a.target).parents().each(function(){if(d.data(this,"sortable-item")==e){c=d(this);return false}});if(d.data(a.target,"sortable-item")==e)c=d(a.target);if(!c)return false;if(this.options.handle&&!b){var f=false;d(this.options.handle,c).find("*").andSelf().each(function(){if(this==a.target)f=true});if(!f)return false}this.currentItem=
c;this._removeCurrentsFromItems();return true},_mouseStart:function(a,b,c){b=this.options;var e=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(a);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");d.extend(this.offset,
{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();b.containment&&this._setContainment();
if(b.cursor){if(d("body").css("cursor"))this._storedCursor=d("body").css("cursor");d("body").css("cursor",b.cursor)}if(b.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",b.opacity)}if(b.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",b.zIndex)}if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start",
a,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!c)for(c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("activate",a,e._uiHash(this));if(d.ui.ddmanager)d.ui.ddmanager.current=this;d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(a);return true},_mouseDrag:function(a){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");
if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var b=this.options,c=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-a.pageY<b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop+b.scrollSpeed;else if(a.pageY-this.overflowOffset.top<b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop-b.scrollSpeed;if(this.overflowOffset.left+
this.scrollParent[0].offsetWidth-a.pageX<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft+b.scrollSpeed;else if(a.pageX-this.overflowOffset.left<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft-b.scrollSpeed}else{if(a.pageY-d(document).scrollTop()<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()-b.scrollSpeed);else if(d(window).height()-(a.pageY-d(document).scrollTop())<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()+
b.scrollSpeed);if(a.pageX-d(document).scrollLeft()<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()-b.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()+b.scrollSpeed)}c!==false&&d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+
"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(b=this.items.length-1;b>=0;b--){c=this.items[b];var e=c.item[0],f=this._intersectsWithPointer(c);if(f)if(e!=this.currentItem[0]&&this.placeholder[f==1?"next":"prev"]()[0]!=e&&!d.ui.contains(this.placeholder[0],e)&&(this.options.type=="semi-dynamic"?!d.ui.contains(this.element[0],e):true)){this.direction=f==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(c))this._rearrange(a,
c);else break;this._trigger("change",a,this._uiHash());break}}this._contactContainers(a);d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);this._trigger("sort",a,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(a,b){if(a){d.ui.ddmanager&&!this.options.dropBehaviour&&d.ui.ddmanager.drop(this,a);if(this.options.revert){var c=this;b=c.placeholder.offset();c.reverting=true;d(this.helper).animate({left:b.left-this.offset.parent.left-c.margins.left+(this.offsetParent[0]==
document.body?0:this.offsetParent[0].scrollLeft),top:b.top-this.offset.parent.top-c.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){c._clear(a)})}else this._clear(a,b);return false}},cancel:function(){var a=this;if(this.dragging){this._mouseUp();this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var b=this.containers.length-1;b>=0;b--){this.containers[b]._trigger("deactivate",
null,a._uiHash(this));if(this.containers[b].containerCache.over){this.containers[b]._trigger("out",null,a._uiHash(this));this.containers[b].containerCache.over=0}}}this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove();d.extend(this,{helper:null,dragging:false,reverting:false,_noFinalSort:null});this.domPosition.prev?d(this.domPosition.prev).after(this.currentItem):
d(this.domPosition.parent).prepend(this.currentItem);return this},serialize:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};d(b).each(function(){var e=(d(a.item||this).attr(a.attribute||"id")||"").match(a.expression||/(.+)[-=_](.+)/);if(e)c.push((a.key||e[1]+"[]")+"="+(a.key&&a.expression?e[1]:e[2]))});!c.length&&a.key&&c.push(a.key+"=");return c.join("&")},toArray:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};b.each(function(){c.push(d(a.item||this).attr(a.attribute||
"id")||"")});return c},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,e=this.positionAbs.top,f=e+this.helperProportions.height,g=a.left,h=g+a.width,i=a.top,k=i+a.height,j=this.offset.click.top,l=this.offset.click.left;j=e+j>i&&e+j<k&&b+l>g&&b+l<h;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers||this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>a[this.floating?"width":"height"]?j:g<b+
this.helperProportions.width/2&&c-this.helperProportions.width/2<h&&i<e+this.helperProportions.height/2&&f-this.helperProportions.height/2<k},_intersectsWithPointer:function(a){var b=d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left,a.width);b=b&&a;a=this._getDragVerticalDirection();var c=this._getDragHorizontalDirection();if(!b)return false;return this.floating?c&&c=="right"||a=="down"?2:1:a&&(a=="down"?
2:1)},_intersectsWithSides:function(a){var b=d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top+a.height/2,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left+a.width/2,a.width);var c=this._getDragVerticalDirection(),e=this._getDragHorizontalDirection();return this.floating&&e?e=="right"&&a||e=="left"&&!a:c&&(c=="down"&&b||c=="up"&&!b)},_getDragVerticalDirection:function(){var a=this.positionAbs.top-this.lastPositionAbs.top;return a!=0&&(a>0?"down":"up")},
_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a);this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(a){var b=[],c=[],e=this._connectWith();if(e&&a)for(a=e.length-1;a>=0;a--)for(var f=d(e[a]),g=f.length-1;g>=0;g--){var h=d.data(f[g],"sortable");if(h&&h!=
this&&!h.options.disabled)c.push([d.isFunction(h.options.items)?h.options.items.call(h.element):d(h.options.items,h.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),h])}c.push([d.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):d(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(a=c.length-1;a>=0;a--)c[a][0].each(function(){b.push(this)});return d(b)},_removeCurrentsFromItems:function(){for(var a=
this.currentItem.find(":data(sortable-item)"),b=0;b<this.items.length;b++)for(var c=0;c<a.length;c++)a[c]==this.items[b].item[0]&&this.items.splice(b,1)},_refreshItems:function(a){this.items=[];this.containers=[this];var b=this.items,c=[[d.isFunction(this.options.items)?this.options.items.call(this.element[0],a,{item:this.currentItem}):d(this.options.items,this.element),this]],e=this._connectWith();if(e)for(var f=e.length-1;f>=0;f--)for(var g=d(e[f]),h=g.length-1;h>=0;h--){var i=d.data(g[h],"sortable");
if(i&&i!=this&&!i.options.disabled){c.push([d.isFunction(i.options.items)?i.options.items.call(i.element[0],a,{item:this.currentItem}):d(i.options.items,i.element),i]);this.containers.push(i)}}for(f=c.length-1;f>=0;f--){a=c[f][1];e=c[f][0];h=0;for(g=e.length;h<g;h++){i=d(e[h]);i.data("sortable-item",a);b.push({item:i,instance:a,width:0,height:0,left:0,top:0})}}},refreshPositions:function(a){if(this.offsetParent&&this.helper)this.offset.parent=this._getParentOffset();for(var b=this.items.length-1;b>=
0;b--){var c=this.items[b],e=this.options.toleranceElement?d(this.options.toleranceElement,c.item):c.item;if(!a){c.width=e.outerWidth();c.height=e.outerHeight()}e=e.offset();c.left=e.left;c.top=e.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(b=this.containers.length-1;b>=0;b--){e=this.containers[b].element.offset();this.containers[b].containerCache.left=e.left;this.containers[b].containerCache.top=e.top;this.containers[b].containerCache.width=
this.containers[b].element.outerWidth();this.containers[b].containerCache.height=this.containers[b].element.outerHeight()}return this},_createPlaceholder:function(a){var b=a||this,c=b.options;if(!c.placeholder||c.placeholder.constructor==String){var e=c.placeholder;c.placeholder={element:function(){var f=d(document.createElement(b.currentItem[0].nodeName)).addClass(e||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!e)f.style.visibility="hidden";return f},
update:function(f,g){if(!(e&&!c.forcePlaceholderSize)){g.height()||g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10));g.width()||g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")||0,10))}}}}b.placeholder=d(c.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);c.placeholder.update(b,b.placeholder)},_contactContainers:function(a){for(var b=
null,c=null,e=this.containers.length-1;e>=0;e--)if(!d.ui.contains(this.currentItem[0],this.containers[e].element[0]))if(this._intersectsWith(this.containers[e].containerCache)){if(!(b&&d.ui.contains(this.containers[e].element[0],b.element[0]))){b=this.containers[e];c=e}}else if(this.containers[e].containerCache.over){this.containers[e]._trigger("out",a,this._uiHash(this));this.containers[e].containerCache.over=0}if(b)if(this.containers.length===1){this.containers[c]._trigger("over",a,this._uiHash(this));
this.containers[c].containerCache.over=1}else if(this.currentContainer!=this.containers[c]){b=1E4;e=null;for(var f=this.positionAbs[this.containers[c].floating?"left":"top"],g=this.items.length-1;g>=0;g--)if(d.ui.contains(this.containers[c].element[0],this.items[g].item[0])){var h=this.items[g][this.containers[c].floating?"left":"top"];if(Math.abs(h-f)<b){b=Math.abs(h-f);e=this.items[g]}}if(e||this.options.dropOnEmpty){this.currentContainer=this.containers[c];e?this._rearrange(a,e,null,true):this._rearrange(a,
null,this.containers[c].element,true);this._trigger("change",a,this._uiHash());this.containers[c]._trigger("change",a,this._uiHash(this));this.options.placeholder.update(this.currentContainer,this.placeholder);this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}}},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a,this.currentItem])):b.helper=="clone"?this.currentItem.clone():this.currentItem;a.parents("body").length||
d(b.appendTo!="parent"?b.appendTo:this.currentItem[0].parentNode)[0].appendChild(a[0]);if(a[0]==this.currentItem[0])this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")};if(a[0].style.width==""||b.forceHelperSize)a.width(this.currentItem.width());if(a[0].style.height==""||b.forceHelperSize)a.height(this.currentItem.height());return a},_adjustOffsetFromHelper:function(a){if(typeof a==
"string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition==
"absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition==
"relative"){var a=this.currentItem.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},
_setContainment:function(){var a=this.options;if(a.containment=="parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,d(a.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-
this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)){var b=d(a.containment)[0];a=d(a.containment).offset();var c=d(b).css("overflow")!="hidden";this.containment=[a.left+(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0)-this.margins.left,a.top+(parseInt(d(b).css("borderTopWidth"),10)||0)+(parseInt(d(b).css("paddingTop"),10)||0)-this.margins.top,a.left+(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),
10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,a.top+(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?
this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);return{top:b.top+this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=
this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0]))this.offset.relative=this._getRelativeOffset();var f=a.pageX,g=a.pageY;if(this.originalPosition){if(this.containment){if(a.pageX-this.offset.click.left<this.containment[0])f=this.containment[0]+
this.offset.click.left;if(a.pageY-this.offset.click.top<this.containment[1])g=this.containment[1]+this.offset.click.top;if(a.pageX-this.offset.click.left>this.containment[2])f=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g-this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?
g:!(g-this.offset.click.top<this.containment[1])?g-b.grid[1]:g+b.grid[1]:g;f=this.originalPageX+Math.round((f-this.originalPageX)/b.grid[0])*b.grid[0];f=this.containment?!(f-this.offset.click.left<this.containment[0]||f-this.offset.click.left>this.containment[2])?f:!(f-this.offset.click.left<this.containment[0])?f-b.grid[0]:f+b.grid[0]:f}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(d.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():
e?0:c.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(d.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:c.scrollLeft())}},_rearrange:function(a,b,c,e){c?c[0].appendChild(this.placeholder[0]):b.item[0].parentNode.insertBefore(this.placeholder[0],this.direction=="down"?b.item[0]:b.item[0].nextSibling);this.counter=this.counter?++this.counter:1;var f=this,g=this.counter;window.setTimeout(function(){g==
f.counter&&f.refreshPositions(!e)},0)},_clear:function(a,b){this.reverting=false;var c=[];!this._noFinalSort&&this.currentItem[0].parentNode&&this.placeholder.before(this.currentItem);this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var e in this._storedCSS)if(this._storedCSS[e]=="auto"||this._storedCSS[e]=="static")this._storedCSS[e]="";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!b&&c.push(function(f){this._trigger("receive",
f,this._uiHash(this.fromOutside))});if((this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!b)c.push(function(f){this._trigger("update",f,this._uiHash())});if(!d.ui.contains(this.element[0],this.currentItem[0])){b||c.push(function(f){this._trigger("remove",f,this._uiHash())});for(e=this.containers.length-1;e>=0;e--)if(d.ui.contains(this.containers[e].element[0],this.currentItem[0])&&!b){c.push(function(f){return function(g){f._trigger("receive",
g,this._uiHash(this))}}.call(this,this.containers[e]));c.push(function(f){return function(g){f._trigger("update",g,this._uiHash(this))}}.call(this,this.containers[e]))}}for(e=this.containers.length-1;e>=0;e--){b||c.push(function(f){return function(g){f._trigger("deactivate",g,this._uiHash(this))}}.call(this,this.containers[e]));if(this.containers[e].containerCache.over){c.push(function(f){return function(g){f._trigger("out",g,this._uiHash(this))}}.call(this,this.containers[e]));this.containers[e].containerCache.over=
0}}this._storedCursor&&d("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!b){this._trigger("beforeStop",a,this._uiHash());for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}return false}b||this._trigger("beforeStop",a,this._uiHash());this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
this.helper[0]!=this.currentItem[0]&&this.helper.remove();this.helper=null;if(!b){for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}this.fromOutside=false;return true},_trigger:function(){d.Widget.prototype._trigger.apply(this,arguments)===false&&this.cancel()},_uiHash:function(a){var b=a||this;return{helper:b.helper,placeholder:b.placeholder||d([]),position:b.position,originalPosition:b.originalPosition,offset:b.positionAbs,item:b.currentItem,sender:a?a.element:null}}});
d.extend(d.ui.sortable,{version:"1.8.7"})})(jQuery);
;/*
 * jQuery UI Accordion 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Accordion
 *
 * Depends:
 *	jquery.ui.core.js
 *	jquery.ui.widget.js
 */
(function(c){c.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:true,clearStyle:false,collapsible:false,event:"click",fillSpace:false,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var a=this,b=a.options;a.running=0;a.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix");
a.headers=a.element.find(b.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){b.disabled||c(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){b.disabled||c(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){b.disabled||c(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){b.disabled||c(this).removeClass("ui-state-focus")});a.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");
if(b.navigation){var d=a.element.find("a").filter(b.navigationFilter).eq(0);if(d.length){var f=d.closest(".ui-accordion-header");a.active=f.length?f:d.closest(".ui-accordion-content").prev()}}a.active=a._findActive(a.active||b.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");a.active.next().addClass("ui-accordion-content-active");a._createIcons();a.resize();a.element.attr("role","tablist");a.headers.attr("role","tab").bind("keydown.accordion",
function(g){return a._keydown(g)}).next().attr("role","tabpanel");a.headers.not(a.active||"").attr({"aria-expanded":"false",tabIndex:-1}).next().hide();a.active.length?a.active.attr({"aria-expanded":"true",tabIndex:0}):a.headers.eq(0).attr("tabIndex",0);c.browser.safari||a.headers.find("a").attr("tabIndex",-1);b.event&&a.headers.bind(b.event.split(" ").join(".accordion ")+".accordion",function(g){a._clickHandler.call(a,g,this);g.preventDefault()})},_createIcons:function(){var a=this.options;if(a.icons){c("<span></span>").addClass("ui-icon "+
a.icons.header).prependTo(this.headers);this.active.children(".ui-icon").toggleClass(a.icons.header).toggleClass(a.icons.headerSelected);this.element.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var a=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("tabIndex");
this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var b=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");if(a.autoHeight||a.fillHeight)b.css("height","");return c.Widget.prototype.destroy.call(this)},_setOption:function(a,b){c.Widget.prototype._setOption.apply(this,arguments);a=="active"&&this.activate(b);if(a=="icons"){this._destroyIcons();
b&&this._createIcons()}if(a=="disabled")this.headers.add(this.headers.next())[b?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(a){if(!(this.options.disabled||a.altKey||a.ctrlKey)){var b=c.ui.keyCode,d=this.headers.length,f=this.headers.index(a.target),g=false;switch(a.keyCode){case b.RIGHT:case b.DOWN:g=this.headers[(f+1)%d];break;case b.LEFT:case b.UP:g=this.headers[(f-1+d)%d];break;case b.SPACE:case b.ENTER:this._clickHandler({target:a.target},a.target);
a.preventDefault()}if(g){c(a.target).attr("tabIndex",-1);c(g).attr("tabIndex",0);g.focus();return false}return true}},resize:function(){var a=this.options,b;if(a.fillSpace){if(c.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}b=this.element.parent().height();c.browser.msie&&this.element.parent().css("overflow",d);this.headers.each(function(){b-=c(this).outerHeight(true)});this.headers.next().each(function(){c(this).height(Math.max(0,b-c(this).innerHeight()+
c(this).height()))}).css("overflow","auto")}else if(a.autoHeight){b=0;this.headers.next().each(function(){b=Math.max(b,c(this).height("").height())}).height(b)}return this},activate:function(a){this.options.active=a;a=this._findActive(a)[0];this._clickHandler({target:a},a);return this},_findActive:function(a){return a?typeof a==="number"?this.headers.filter(":eq("+a+")"):this.headers.not(this.headers.not(a)):a===false?c([]):this.headers.filter(":eq(0)")},_clickHandler:function(a,b){var d=this.options;
if(!d.disabled)if(a.target){a=c(a.currentTarget||b);b=a[0]===this.active[0];d.active=d.collapsible&&b?false:this.headers.index(a);if(!(this.running||!d.collapsible&&b)){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);if(!b){a.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected);
a.next().addClass("ui-accordion-content-active")}h=a.next();f=this.active.next();g={options:d,newHeader:b&&d.collapsible?c([]):a,oldHeader:this.active,newContent:b&&d.collapsible?c([]):h,oldContent:f};d=this.headers.index(this.active[0])>this.headers.index(a[0]);this.active=b?c([]):a;this._toggle(h,f,g,b,d)}}else if(d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);
this.active.next().addClass("ui-accordion-content-active");var f=this.active.next(),g={options:d,newHeader:c([]),oldHeader:d.active,newContent:c([]),oldContent:f},h=this.active=c([]);this._toggle(h,f,g)}},_toggle:function(a,b,d,f,g){var h=this,e=h.options;h.toShow=a;h.toHide=b;h.data=d;var j=function(){if(h)return h._completed.apply(h,arguments)};h._trigger("changestart",null,h.data);h.running=b.size()===0?a.size():b.size();if(e.animated){d={};d=e.collapsible&&f?{toShow:c([]),toHide:b,complete:j,
down:g,autoHeight:e.autoHeight||e.fillSpace}:{toShow:a,toHide:b,complete:j,down:g,autoHeight:e.autoHeight||e.fillSpace};if(!e.proxied)e.proxied=e.animated;if(!e.proxiedDuration)e.proxiedDuration=e.duration;e.animated=c.isFunction(e.proxied)?e.proxied(d):e.proxied;e.duration=c.isFunction(e.proxiedDuration)?e.proxiedDuration(d):e.proxiedDuration;f=c.ui.accordion.animations;var i=e.duration,k=e.animated;if(k&&!f[k]&&!c.easing[k])k="slide";f[k]||(f[k]=function(l){this.slide(l,{easing:k,duration:i||700})});
f[k](d)}else{if(e.collapsible&&f)a.toggle();else{b.hide();a.show()}j(true)}b.prev().attr({"aria-expanded":"false",tabIndex:-1}).blur();a.prev().attr({"aria-expanded":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;if(!this.running){this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""});this.toHide.removeClass("ui-accordion-content-active");this._trigger("change",null,this.data)}}});c.extend(c.ui.accordion,{version:"1.8.7",animations:{slide:function(a,
b){a=c.extend({easing:"swing",duration:300},a,b);if(a.toHide.size())if(a.toShow.size()){var d=a.toShow.css("overflow"),f=0,g={},h={},e;b=a.toShow;e=b[0].style.width;b.width(parseInt(b.parent().width(),10)-parseInt(b.css("paddingLeft"),10)-parseInt(b.css("paddingRight"),10)-(parseInt(b.css("borderLeftWidth"),10)||0)-(parseInt(b.css("borderRightWidth"),10)||0));c.each(["height","paddingTop","paddingBottom"],function(j,i){h[i]="hide";j=(""+c.css(a.toShow[0],i)).match(/^([\d+-.]+)(.*)$/);g[i]={value:j[1],
unit:j[2]||"px"}});a.toShow.css({height:0,overflow:"hidden"}).show();a.toHide.filter(":hidden").each(a.complete).end().filter(":visible").animate(h,{step:function(j,i){if(i.prop=="height")f=i.end-i.start===0?0:(i.now-i.start)/(i.end-i.start);a.toShow[0].style[i.prop]=f*g[i.prop].value+g[i.prop].unit},duration:a.duration,easing:a.easing,complete:function(){a.autoHeight||a.toShow.css("height","");a.toShow.css({width:e,overflow:d});a.complete()}})}else a.toHide.animate({height:"hide",paddingTop:"hide",
paddingBottom:"hide"},a);else a.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},a)},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1E3:200})}}})})(jQuery);
;/*
 * jQuery UI Autocomplete 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Autocomplete
 *
 * Depends:
 *	jquery.ui.core.js
 *	jquery.ui.widget.js
 *	jquery.ui.position.js
 */
(function(d){d.widget("ui.autocomplete",{options:{appendTo:"body",delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},_create:function(){var a=this,b=this.element[0].ownerDocument,f;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!(a.options.disabled||a.element.attr("readonly"))){f=false;var e=d.ui.keyCode;switch(c.keyCode){case e.PAGE_UP:a._move("previousPage",
c);break;case e.PAGE_DOWN:a._move("nextPage",c);break;case e.UP:a._move("previous",c);c.preventDefault();break;case e.DOWN:a._move("next",c);c.preventDefault();break;case e.ENTER:case e.NUMPAD_ENTER:if(a.menu.active){f=true;c.preventDefault()}case e.TAB:if(!a.menu.active)return;a.menu.select(c);break;case e.ESCAPE:a.element.val(a.term);a.close(c);break;default:clearTimeout(a.searching);a.searching=setTimeout(function(){if(a.term!=a.element.val()){a.selectedItem=null;a.search(null,c)}},a.options.delay);
break}}}).bind("keypress.autocomplete",function(c){if(f){f=false;c.preventDefault()}}).bind("focus.autocomplete",function(){if(!a.options.disabled){a.selectedItem=null;a.previous=a.element.val()}}).bind("blur.autocomplete",function(c){if(!a.options.disabled){clearTimeout(a.searching);a.closing=setTimeout(function(){a.close(c);a._change(c)},150)}});this._initSource();this.response=function(){return a._response.apply(a,arguments)};this.menu=d("<ul></ul>").addClass("ui-autocomplete").appendTo(d(this.options.appendTo||
"body",b)[0]).mousedown(function(c){var e=a.menu.element[0];d(c.target).closest(".ui-menu-item").length||setTimeout(function(){d(document).one("mousedown",function(g){g.target!==a.element[0]&&g.target!==e&&!d.ui.contains(e,g.target)&&a.close()})},1);setTimeout(function(){clearTimeout(a.closing)},13)}).menu({focus:function(c,e){e=e.item.data("item.autocomplete");false!==a._trigger("focus",c,{item:e})&&/^key/.test(c.originalEvent.type)&&a.element.val(e.value)},selected:function(c,e){var g=e.item.data("item.autocomplete"),
h=a.previous;if(a.element[0]!==b.activeElement){a.element.focus();a.previous=h;setTimeout(function(){a.previous=h;a.selectedItem=g},1)}false!==a._trigger("select",c,{item:g})&&a.element.val(g.value);a.term=a.element.val();a.close(c);a.selectedItem=g},blur:function(){a.menu.element.is(":visible")&&a.element.val()!==a.term&&a.element.val(a.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu");d.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");
this.menu.element.remove();d.Widget.prototype.destroy.call(this)},_setOption:function(a,b){d.Widget.prototype._setOption.apply(this,arguments);a==="source"&&this._initSource();if(a==="appendTo")this.menu.element.appendTo(d(b||"body",this.element[0].ownerDocument)[0])},_initSource:function(){var a=this,b,f;if(d.isArray(this.options.source)){b=this.options.source;this.source=function(c,e){e(d.ui.autocomplete.filter(b,c.term))}}else if(typeof this.options.source==="string"){f=this.options.source;this.source=
function(c,e){a.xhr&&a.xhr.abort();a.xhr=d.ajax({url:f,data:c,dataType:"json",success:function(g,h,i){i===a.xhr&&e(g);a.xhr=null},error:function(g){g===a.xhr&&e([]);a.xhr=null}})}}else this.source=this.options.source},search:function(a,b){a=a!=null?a:this.element.val();this.term=this.element.val();if(a.length<this.options.minLength)return this.close(b);clearTimeout(this.closing);if(this._trigger("search",b)!==false)return this._search(a)},_search:function(a){this.element.addClass("ui-autocomplete-loading");
this.source({term:a},this.response)},_response:function(a){if(a&&a.length){a=this._normalize(a);this._suggest(a);this._trigger("open")}else this.close();this.element.removeClass("ui-autocomplete-loading")},close:function(a){clearTimeout(this.closing);if(this.menu.element.is(":visible")){this.menu.element.hide();this.menu.deactivate();this._trigger("close",a)}},_change:function(a){this.previous!==this.element.val()&&this._trigger("change",a,{item:this.selectedItem})},_normalize:function(a){if(a.length&&
a[0].label&&a[0].value)return a;return d.map(a,function(b){if(typeof b==="string")return{label:b,value:b};return d.extend({label:b.label||b.value,value:b.value||b.label},b)})},_suggest:function(a){var b=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(b,a);this.menu.deactivate();this.menu.refresh();b.show();this._resizeMenu();b.position(d.extend({of:this.element},this.options.position))},_resizeMenu:function(){var a=this.menu.element;a.outerWidth(Math.max(a.width("").outerWidth(),
this.element.outerWidth()))},_renderMenu:function(a,b){var f=this;d.each(b,function(c,e){f._renderItem(a,e)})},_renderItem:function(a,b){return d("<li></li>").data("item.autocomplete",b).append(d("<a></a>").text(b.label)).appendTo(a)},_move:function(a,b){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term);this.menu.deactivate()}else this.menu[a](b);else this.search(null,b)},widget:function(){return this.menu.element}});
d.extend(d.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")},filter:function(a,b){var f=new RegExp(d.ui.autocomplete.escapeRegex(b),"i");return d.grep(a,function(c){return f.test(c.label||c.value||c)})}})})(jQuery);
(function(d){d.widget("ui.menu",{_create:function(){var a=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(b){if(d(b.target).closest(".ui-menu-item a").length){b.preventDefault();a.select(b)}});this.refresh()},refresh:function(){var a=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex",
-1).mouseenter(function(b){a.activate(b,d(this).parent())}).mouseleave(function(){a.deactivate()})},activate:function(a,b){this.deactivate();if(this.hasScroll()){var f=b.offset().top-this.element.offset().top,c=this.element.attr("scrollTop"),e=this.element.height();if(f<0)this.element.attr("scrollTop",c+f);else f>=e&&this.element.attr("scrollTop",c+f-e+b.height())}this.active=b.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",a,{item:b})},
deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id");this._trigger("blur");this.active=null}},next:function(a){this.move("next",".ui-menu-item:first",a)},previous:function(a){this.move("prev",".ui-menu-item:last",a)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(a,b,f){if(this.active){a=this.active[a+"All"](".ui-menu-item").eq(0);
a.length?this.activate(f,a):this.activate(f,this.element.children(b))}else this.activate(f,this.element.children(b))},nextPage:function(a){if(this.hasScroll())if(!this.active||this.last())this.activate(a,this.element.children(".ui-menu-item:first"));else{var b=this.active.offset().top,f=this.element.height(),c=this.element.children(".ui-menu-item").filter(function(){var e=d(this).offset().top-b-f+d(this).height();return e<10&&e>-10});c.length||(c=this.element.children(".ui-menu-item:last"));this.activate(a,
c)}else this.activate(a,this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(a){if(this.hasScroll())if(!this.active||this.first())this.activate(a,this.element.children(".ui-menu-item:last"));else{var b=this.active.offset().top,f=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var c=d(this).offset().top-b+f-d(this).height();return c<10&&c>-10});result.length||(result=this.element.children(".ui-menu-item:first"));
this.activate(a,result)}else this.activate(a,this.element.children(".ui-menu-item").filter(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()<this.element.attr("scrollHeight")},select:function(a){this._trigger("selected",a,{item:this.active})}})})(jQuery);
;/*
 * jQuery UI Button 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Button
 *
 * Depends:
 *	jquery.ui.core.js
 *	jquery.ui.widget.js
 */
(function(a){var g,i=function(b){a(":ui-button",b.target.form).each(function(){var c=a(this).data("button");setTimeout(function(){c.refresh()},1)})},h=function(b){var c=b.name,d=b.form,e=a([]);if(c)e=d?a(d).find("[name='"+c+"']"):a("[name='"+c+"']",b.ownerDocument).filter(function(){return!this.form});return e};a.widget("ui.button",{options:{disabled:null,text:true,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset.button").bind("reset.button",
i);if(typeof this.options.disabled!=="boolean")this.options.disabled=this.element.attr("disabled");this._determineButtonType();this.hasTitle=!!this.buttonElement.attr("title");var b=this,c=this.options,d=this.type==="checkbox"||this.type==="radio",e="ui-state-hover"+(!d?" ui-state-active":"");if(c.label===null)c.label=this.buttonElement.html();if(this.element.is(":disabled"))c.disabled=true;this.buttonElement.addClass("ui-button ui-widget ui-state-default ui-corner-all").attr("role","button").bind("mouseenter.button",
function(){if(!c.disabled){a(this).addClass("ui-state-hover");this===g&&a(this).addClass("ui-state-active")}}).bind("mouseleave.button",function(){c.disabled||a(this).removeClass(e)}).bind("focus.button",function(){a(this).addClass("ui-state-focus")}).bind("blur.button",function(){a(this).removeClass("ui-state-focus")});d&&this.element.bind("change.button",function(){b.refresh()});if(this.type==="checkbox")this.buttonElement.bind("click.button",function(){if(c.disabled)return false;a(this).toggleClass("ui-state-active");
b.buttonElement.attr("aria-pressed",b.element[0].checked)});else if(this.type==="radio")this.buttonElement.bind("click.button",function(){if(c.disabled)return false;a(this).addClass("ui-state-active");b.buttonElement.attr("aria-pressed",true);var f=b.element[0];h(f).not(f).map(function(){return a(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed",false)});else{this.buttonElement.bind("mousedown.button",function(){if(c.disabled)return false;a(this).addClass("ui-state-active");
g=this;a(document).one("mouseup",function(){g=null})}).bind("mouseup.button",function(){if(c.disabled)return false;a(this).removeClass("ui-state-active")}).bind("keydown.button",function(f){if(c.disabled)return false;if(f.keyCode==a.ui.keyCode.SPACE||f.keyCode==a.ui.keyCode.ENTER)a(this).addClass("ui-state-active")}).bind("keyup.button",function(){a(this).removeClass("ui-state-active")});this.buttonElement.is("a")&&this.buttonElement.keyup(function(f){f.keyCode===a.ui.keyCode.SPACE&&a(this).click()})}this._setOption("disabled",
c.disabled)},_determineButtonType:function(){this.type=this.element.is(":checkbox")?"checkbox":this.element.is(":radio")?"radio":this.element.is("input")?"input":"button";if(this.type==="checkbox"||this.type==="radio"){this.buttonElement=this.element.parents().last().find("label[for="+this.element.attr("id")+"]");this.element.addClass("ui-helper-hidden-accessible");var b=this.element.is(":checked");b&&this.buttonElement.addClass("ui-state-active");this.buttonElement.attr("aria-pressed",b)}else this.buttonElement=
this.element},widget:function(){return this.buttonElement},destroy:function(){this.element.removeClass("ui-helper-hidden-accessible");this.buttonElement.removeClass("ui-button ui-widget ui-state-default ui-corner-all ui-state-hover ui-state-active  ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only").removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html());this.hasTitle||
this.buttonElement.removeAttr("title");a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments);if(b==="disabled")c?this.element.attr("disabled",true):this.element.removeAttr("disabled");this._resetButton()},refresh:function(){var b=this.element.is(":disabled");b!==this.options.disabled&&this._setOption("disabled",b);if(this.type==="radio")h(this.element[0]).each(function(){a(this).is(":checked")?a(this).button("widget").addClass("ui-state-active").attr("aria-pressed",
true):a(this).button("widget").removeClass("ui-state-active").attr("aria-pressed",false)});else if(this.type==="checkbox")this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed",true):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed",false)},_resetButton:function(){if(this.type==="input")this.options.label&&this.element.val(this.options.label);else{var b=this.buttonElement.removeClass("ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only"),
c=a("<span></span>").addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),d=this.options.icons,e=d.primary&&d.secondary;if(d.primary||d.secondary){b.addClass("ui-button-text-icon"+(e?"s":d.primary?"-primary":"-secondary"));d.primary&&b.prepend("<span class='ui-button-icon-primary ui-icon "+d.primary+"'></span>");d.secondary&&b.append("<span class='ui-button-icon-secondary ui-icon "+d.secondary+"'></span>");if(!this.options.text){b.addClass(e?"ui-button-icons-only":"ui-button-icon-only").removeClass("ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary");
this.hasTitle||b.attr("title",c)}}else b.addClass("ui-button-text-only")}}});a.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(b,c){b==="disabled"&&this.buttons.button("option",b,c);a.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass("ui-corner-left").end().filter(":last").addClass("ui-corner-right").end().end()},
destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy");a.Widget.prototype.destroy.call(this)}})})(jQuery);
;/*
 * jQuery UI Dialog 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Dialog
 *
 * Depends:
 *	jquery.ui.core.js
 *	jquery.ui.widget.js
 *  jquery.ui.button.js
 *	jquery.ui.draggable.js
 *	jquery.ui.mouse.js
 *	jquery.ui.position.js
 *	jquery.ui.resizable.js
 */
(function(c,j){var k={buttons:true,height:true,maxHeight:true,maxWidth:true,minHeight:true,minWidth:true,width:true},l={maxHeight:true,maxWidth:true,minHeight:true,minWidth:true};c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,position:{my:"center",at:"center",collision:"fit",using:function(a){var b=c(this).css(a).offset().top;b<0&&
c(this).css("top",a.top-b)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");if(typeof this.originalTitle!=="string")this.originalTitle="";this.options.title=this.options.title||this.originalTitle;var a=this,b=a.options,d=b.title||"&#160;",e=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("<div></div>")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",
-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(i){a.moveToTop(false,i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var f=(a.uiDialogTitlebar=c("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),h=c('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role",
"button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);return false}).appendTo(f);(a.uiDialogTitlebarCloseText=c("<span></span>")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("<span></span>").addClass("ui-dialog-title").attr("id",e).html(d).prependTo(f);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose=
b.beforeclose;f.find("*").add(f).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");a.uiDialog.remove();a.originalTitle&&
a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d,e;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();b.uiDialog.unbind("keypress.ui-dialog");b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!==b.uiDialog[0]){e=c(this).css("z-index");
isNaN(e)||(d=Math.max(d,e))}});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,e=d.options;if(e.modal&&!a||!e.stack&&!e.modal)return d._trigger("focus",b);if(e.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=e.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.attr("scrollTop"),scrollLeft:d.element.attr("scrollLeft")};c.ui.dialog.maxZ+=1;d.uiDialog.css("z-index",c.ui.dialog.maxZ);
d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;a._size();a._position(b.position);d.show(b.show);a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(e){if(e.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),f=g.filter(":first");g=g.filter(":last");if(e.target===g[0]&&!e.shiftKey){f.focus(1);return false}else if(e.target===f[0]&&e.shiftKey){g.focus(1);return false}}});
c(a.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus();a._isOpen=true;a._trigger("open");return a}},_createButtons:function(a){var b=this,d=false,e=c("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=c("<div></div>").addClass("ui-dialog-buttonset").appendTo(e);b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a,function(){return!(d=true)});if(d){c.each(a,function(f,
h){h=c.isFunction(h)?{click:h,text:f}:h;f=c('<button type="button"></button>').attr(h,true).unbind("click").click(function(){h.click.apply(b.element[0],arguments)}).appendTo(g);c.fn.button&&f.button()});e.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(f){return{position:f.position,offset:f.offset}}var b=this,d=b.options,e=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(f,h){g=
d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging");b._trigger("dragStart",f,a(h))},drag:function(f,h){b._trigger("drag",f,a(h))},stop:function(f,h){d.position=[h.position.left-e.scrollLeft(),h.position.top-e.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);b._trigger("dragStop",f,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(f){return{originalPosition:f.originalPosition,originalSize:f.originalSize,
position:f.position,size:f.size}}a=a===j?this.options.resizable:a;var d=this,e=d.options,g=d.uiDialog.css("position");a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:a,start:function(f,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",f,b(h))},resize:function(f,h){d._trigger("resize",f,b(h))},stop:function(f,
h){c(this).removeClass("ui-dialog-resizing");e.height=c(this).height();e.width=c(this).width();d._trigger("resizeStop",f,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(a){var b=[],d=[0,0],e;if(a){if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "):[a[0],a[1]];if(b.length===
1)b[1]=b[0];c.each(["left","top"],function(g,f){if(+b[g]===b[g]){d[g]=b[g];b[g]=f}});a={my:b.join(" "),at:b.join(" "),offset:d.join(" ")}}a=c.extend({},c.ui.dialog.prototype.options.position,a)}else a=c.ui.dialog.prototype.options.position;(e=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(c.extend({of:window},a));e||this.uiDialog.hide()},_setOptions:function(a){var b=this,d={},e=false;c.each(a,function(g,f){b._setOption(g,f);if(g in k)e=true;if(g in
l)d[g]=f});e&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",d)},_setOption:function(a,b){var d=this,e=d.uiDialog;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":e.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?e.addClass("ui-dialog-disabled"):e.removeClass("ui-dialog-disabled");
break;case "draggable":var g=e.is(":data(draggable)");g&&!b&&e.draggable("destroy");!g&&b&&d._makeDraggable();break;case "position":d._position(b);break;case "resizable":(g=e.is(":data(resizable)"))&&!b&&e.resizable("destroy");g&&typeof b==="string"&&e.resizable("option","handles",b);!g&&b!==false&&d._makeResizable(b);break;case "title":c(".ui-dialog-title",d.uiDialogTitlebar).html(""+(b||"&#160;"));break}c.Widget.prototype._setOption.apply(d,arguments)},_size:function(){var a=this.options,b,d,e=
this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});if(a.minWidth>a.width)a.width=a.minWidth;b=this.uiDialog.css({height:"auto",width:a.width}).height();d=Math.max(0,a.minHeight-b);if(a.height==="auto")if(c.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();a=this.element.css("height","auto").height();e||this.uiDialog.hide();this.element.height(Math.max(a,d))}else this.element.height(Math.max(a.height-b,0));this.uiDialog.is(":data(resizable)")&&
this.uiDialog.resizable("option","minHeight",this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.7",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),create:function(a){if(this.instances.length===
0){setTimeout(function(){c.ui.dialog.overlay.instances.length&&c(document).bind(c.ui.dialog.overlay.events,function(d){if(c(d.target).zIndex()<c.ui.dialog.overlay.maxZ)return false})},1);c(document).bind("keydown.dialog-overlay",function(d){if(a.options.closeOnEscape&&d.keyCode&&d.keyCode===c.ui.keyCode.ESCAPE){a.close(d);d.preventDefault()}});c(window).bind("resize.dialog-overlay",c.ui.dialog.overlay.resize)}var b=(this.oldInstances.pop()||c("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),
height:this.height()});c.fn.bgiframe&&b.bgiframe();this.instances.push(b);return b},destroy:function(a){var b=c.inArray(a,this.instances);b!=-1&&this.oldInstances.push(this.instances.splice(b,1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var d=0;c.each(this.instances,function(){d=Math.max(d,this.css("z-index"))});this.maxZ=d},height:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);
b=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return a<b?c(window).height()+"px":a+"px"}else return c(document).height()+"px"},width:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);b=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);return a<b?c(window).width()+"px":a+"px"}else return c(document).width()+"px"},resize:function(){var a=c([]);c.each(c.ui.dialog.overlay.instances,
function(){a=a.add(this)});a.css({width:0,height:0}).css({width:c.ui.dialog.overlay.width(),height:c.ui.dialog.overlay.height()})}});c.extend(c.ui.dialog.overlay.prototype,{destroy:function(){c.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);
;/*
 * jQuery UI Slider 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Slider
 *
 * Depends:
 *	jquery.ui.core.js
 *	jquery.ui.mouse.js
 *	jquery.ui.widget.js
 */
(function(d){d.widget("ui.slider",d.ui.mouse,{widgetEventPrefix:"slide",options:{animate:false,distance:0,max:100,min:0,orientation:"horizontal",range:false,step:1,value:0,values:null},_create:function(){var b=this,a=this.options;this._mouseSliding=this._keySliding=false;this._animateOff=true;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget ui-widget-content ui-corner-all");a.disabled&&this.element.addClass("ui-slider-disabled ui-disabled");
this.range=d([]);if(a.range){if(a.range===true){this.range=d("<div></div>");if(!a.values)a.values=[this._valueMin(),this._valueMin()];if(a.values.length&&a.values.length!==2)a.values=[a.values[0],a.values[0]]}else this.range=d("<div></div>");this.range.appendTo(this.element).addClass("ui-slider-range");if(a.range==="min"||a.range==="max")this.range.addClass("ui-slider-range-"+a.range);this.range.addClass("ui-widget-header")}d(".ui-slider-handle",this.element).length===0&&d("<a href='#'></a>").appendTo(this.element).addClass("ui-slider-handle");
if(a.values&&a.values.length)for(;d(".ui-slider-handle",this.element).length<a.values.length;)d("<a href='#'></a>").appendTo(this.element).addClass("ui-slider-handle");this.handles=d(".ui-slider-handle",this.element).addClass("ui-state-default ui-corner-all");this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(c){c.preventDefault()}).hover(function(){a.disabled||d(this).addClass("ui-state-hover")},function(){d(this).removeClass("ui-state-hover")}).focus(function(){if(a.disabled)d(this).blur();
else{d(".ui-slider .ui-state-focus").removeClass("ui-state-focus");d(this).addClass("ui-state-focus")}}).blur(function(){d(this).removeClass("ui-state-focus")});this.handles.each(function(c){d(this).data("index.ui-slider-handle",c)});this.handles.keydown(function(c){var e=true,f=d(this).data("index.ui-slider-handle"),h,g,i;if(!b.options.disabled){switch(c.keyCode){case d.ui.keyCode.HOME:case d.ui.keyCode.END:case d.ui.keyCode.PAGE_UP:case d.ui.keyCode.PAGE_DOWN:case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:e=
false;if(!b._keySliding){b._keySliding=true;d(this).addClass("ui-state-active");h=b._start(c,f);if(h===false)return}break}i=b.options.step;h=b.options.values&&b.options.values.length?(g=b.values(f)):(g=b.value());switch(c.keyCode){case d.ui.keyCode.HOME:g=b._valueMin();break;case d.ui.keyCode.END:g=b._valueMax();break;case d.ui.keyCode.PAGE_UP:g=b._trimAlignValue(h+(b._valueMax()-b._valueMin())/5);break;case d.ui.keyCode.PAGE_DOWN:g=b._trimAlignValue(h-(b._valueMax()-b._valueMin())/5);break;case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:if(h===
b._valueMax())return;g=b._trimAlignValue(h+i);break;case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:if(h===b._valueMin())return;g=b._trimAlignValue(h-i);break}b._slide(c,f,g);return e}}).keyup(function(c){var e=d(this).data("index.ui-slider-handle");if(b._keySliding){b._keySliding=false;b._stop(c,e);b._change(c,e);d(this).removeClass("ui-state-active")}});this._refreshValue();this._animateOff=false},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");
this._mouseDestroy();return this},_mouseCapture:function(b){var a=this.options,c,e,f,h,g;if(a.disabled)return false;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();c=this._normValueFromMouse({x:b.pageX,y:b.pageY});e=this._valueMax()-this._valueMin()+1;h=this;this.handles.each(function(i){var j=Math.abs(c-h.values(i));if(e>j){e=j;f=d(this);g=i}});if(a.range===true&&this.values(1)===a.min){g+=1;f=d(this.handles[g])}if(this._start(b,
g)===false)return false;this._mouseSliding=true;h._handleIndex=g;f.addClass("ui-state-active").focus();a=f.offset();this._clickOffset=!d(b.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:b.pageX-a.left-f.width()/2,top:b.pageY-a.top-f.height()/2-(parseInt(f.css("borderTopWidth"),10)||0)-(parseInt(f.css("borderBottomWidth"),10)||0)+(parseInt(f.css("marginTop"),10)||0)};this.handles.hasClass("ui-state-hover")||this._slide(b,g,c);return this._animateOff=true},_mouseStart:function(){return true},
_mouseDrag:function(b){var a=this._normValueFromMouse({x:b.pageX,y:b.pageY});this._slide(b,this._handleIndex,a);return false},_mouseStop:function(b){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(b,this._handleIndex);this._change(b,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=false},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(b){var a;
if(this.orientation==="horizontal"){a=this.elementSize.width;b=b.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{a=this.elementSize.height;b=b.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}a=b/a;if(a>1)a=1;if(a<0)a=0;if(this.orientation==="vertical")a=1-a;b=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+a*b)},_start:function(b,a){var c={handle:this.handles[a],value:this.value()};if(this.options.values&&this.options.values.length){c.value=
this.values(a);c.values=this.values()}return this._trigger("start",b,c)},_slide:function(b,a,c){var e;if(this.options.values&&this.options.values.length){e=this.values(a?0:1);if(this.options.values.length===2&&this.options.range===true&&(a===0&&c>e||a===1&&c<e))c=e;if(c!==this.values(a)){e=this.values();e[a]=c;b=this._trigger("slide",b,{handle:this.handles[a],value:c,values:e});this.values(a?0:1);b!==false&&this.values(a,c,true)}}else if(c!==this.value()){b=this._trigger("slide",b,{handle:this.handles[a],
value:c});b!==false&&this.value(c)}},_stop:function(b,a){var c={handle:this.handles[a],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(a);c.values=this.values()}this._trigger("stop",b,c)},_change:function(b,a){if(!this._keySliding&&!this._mouseSliding){var c={handle:this.handles[a],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(a);c.values=this.values()}this._trigger("change",b,c)}},value:function(b){if(arguments.length){this.options.value=
this._trimAlignValue(b);this._refreshValue();this._change(null,0)}return this._value()},values:function(b,a){var c,e,f;if(arguments.length>1){this.options.values[b]=this._trimAlignValue(a);this._refreshValue();this._change(null,b)}if(arguments.length)if(d.isArray(arguments[0])){c=this.options.values;e=arguments[0];for(f=0;f<c.length;f+=1){c[f]=this._trimAlignValue(e[f]);this._change(null,f)}this._refreshValue()}else return this.options.values&&this.options.values.length?this._values(b):this.value();
else return this._values()},_setOption:function(b,a){var c,e=0;if(d.isArray(this.options.values))e=this.options.values.length;d.Widget.prototype._setOption.apply(this,arguments);switch(b){case "disabled":if(a){this.handles.filter(".ui-state-focus").blur();this.handles.removeClass("ui-state-hover");this.handles.attr("disabled","disabled");this.element.addClass("ui-disabled")}else{this.handles.removeAttr("disabled");this.element.removeClass("ui-disabled")}break;case "orientation":this._detectOrientation();
this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation);this._refreshValue();break;case "value":this._animateOff=true;this._refreshValue();this._change(null,0);this._animateOff=false;break;case "values":this._animateOff=true;this._refreshValue();for(c=0;c<e;c+=1)this._change(null,c);this._animateOff=false;break}},_value:function(){var b=this.options.value;return b=this._trimAlignValue(b)},_values:function(b){var a,c;if(arguments.length){a=this.options.values[b];
return a=this._trimAlignValue(a)}else{a=this.options.values.slice();for(c=0;c<a.length;c+=1)a[c]=this._trimAlignValue(a[c]);return a}},_trimAlignValue:function(b){if(b<=this._valueMin())return this._valueMin();if(b>=this._valueMax())return this._valueMax();var a=this.options.step>0?this.options.step:1,c=(b-this._valueMin())%a;alignValue=b-c;if(Math.abs(c)*2>=a)alignValue+=c>0?a:-a;return parseFloat(alignValue.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},
_refreshValue:function(){var b=this.options.range,a=this.options,c=this,e=!this._animateOff?a.animate:false,f,h={},g,i,j,l;if(this.options.values&&this.options.values.length)this.handles.each(function(k){f=(c.values(k)-c._valueMin())/(c._valueMax()-c._valueMin())*100;h[c.orientation==="horizontal"?"left":"bottom"]=f+"%";d(this).stop(1,1)[e?"animate":"css"](h,a.animate);if(c.options.range===true)if(c.orientation==="horizontal"){if(k===0)c.range.stop(1,1)[e?"animate":"css"]({left:f+"%"},a.animate);
if(k===1)c.range[e?"animate":"css"]({width:f-g+"%"},{queue:false,duration:a.animate})}else{if(k===0)c.range.stop(1,1)[e?"animate":"css"]({bottom:f+"%"},a.animate);if(k===1)c.range[e?"animate":"css"]({height:f-g+"%"},{queue:false,duration:a.animate})}g=f});else{i=this.value();j=this._valueMin();l=this._valueMax();f=l!==j?(i-j)/(l-j)*100:0;h[c.orientation==="horizontal"?"left":"bottom"]=f+"%";this.handle.stop(1,1)[e?"animate":"css"](h,a.animate);if(b==="min"&&this.orientation==="horizontal")this.range.stop(1,
1)[e?"animate":"css"]({width:f+"%"},a.animate);if(b==="max"&&this.orientation==="horizontal")this.range[e?"animate":"css"]({width:100-f+"%"},{queue:false,duration:a.animate});if(b==="min"&&this.orientation==="vertical")this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},a.animate);if(b==="max"&&this.orientation==="vertical")this.range[e?"animate":"css"]({height:100-f+"%"},{queue:false,duration:a.animate})}}});d.extend(d.ui.slider,{version:"1.8.7"})})(jQuery);
;/*
 * jQuery UI Tabs 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Tabs
 *
 * Depends:
 *	jquery.ui.core.js
 *	jquery.ui.widget.js
 */
(function(d,p){function u(){return++v}function w(){return++x}var v=0,x=0;d.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:false,cookie:null,collapsible:false,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"<div></div>",remove:null,select:null,show:null,spinner:"<em>Loading&#8230;</em>",tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},_create:function(){this._tabify(true)},_setOption:function(b,e){if(b=="selected")this.options.collapsible&&
e==this.options.selected||this.select(e);else{this.options[b]=e;this._tabify()}},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+u()},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+w());return d.cookie.apply(null,[b].concat(d.makeArray(arguments)))},_ui:function(b,e){return{tab:b,panel:e,index:this.anchors.index(b)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=
d(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(b){function e(g,f){g.css("display","");!d.support.opacity&&f.opacity&&g[0].style.removeAttribute("filter")}var a=this,c=this.options,h=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=d(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return d("a",this)[0]});this.panels=d([]);this.anchors.each(function(g,f){var i=d(f).attr("href"),l=i.split("#")[0],q;if(l&&(l===location.toString().split("#")[0]||
(q=d("base")[0])&&l===q.href)){i=f.hash;f.href=i}if(h.test(i))a.panels=a.panels.add(a.element.find(a._sanitizeSelector(i)));else if(i&&i!=="#"){d.data(f,"href.tabs",i);d.data(f,"load.tabs",i.replace(/#.*$/,""));i=a._tabId(f);f.href="#"+i;f=a.element.find("#"+i);if(!f.length){f=d(c.panelTemplate).attr("id",i).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(a.panels[g-1]||a.list);f.data("destroy.tabs",true)}a.panels=a.panels.add(f)}else c.disabled.push(g)});if(b){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all");
this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(c.selected===p){location.hash&&this.anchors.each(function(g,f){if(f.hash==location.hash){c.selected=g;return false}});if(typeof c.selected!=="number"&&c.cookie)c.selected=parseInt(a._cookie(),10);if(typeof c.selected!=="number"&&this.lis.filter(".ui-tabs-selected").length)c.selected=
this.lis.index(this.lis.filter(".ui-tabs-selected"));c.selected=c.selected||(this.lis.length?0:-1)}else if(c.selected===null)c.selected=-1;c.selected=c.selected>=0&&this.anchors[c.selected]||c.selected<0?c.selected:0;c.disabled=d.unique(c.disabled.concat(d.map(this.lis.filter(".ui-state-disabled"),function(g){return a.lis.index(g)}))).sort();d.inArray(c.selected,c.disabled)!=-1&&c.disabled.splice(d.inArray(c.selected,c.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active");
if(c.selected>=0&&this.anchors.length){a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash)).removeClass("ui-tabs-hide");this.lis.eq(c.selected).addClass("ui-tabs-selected ui-state-active");a.element.queue("tabs",function(){a._trigger("show",null,a._ui(a.anchors[c.selected],a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash))))});this.load(c.selected)}d(window).bind("unload",function(){a.lis.add(a.anchors).unbind(".tabs");a.lis=a.anchors=a.panels=null})}else c.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"));
this.element[c.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");c.cookie&&this._cookie(c.selected,c.cookie);b=0;for(var j;j=this.lis[b];b++)d(j)[d.inArray(b,c.disabled)!=-1&&!d(j).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");c.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(c.event!=="mouseover"){var k=function(g,f){f.is(":not(.ui-state-disabled)")&&f.addClass("ui-state-"+g)},n=function(g,f){f.removeClass("ui-state-"+
g)};this.lis.bind("mouseover.tabs",function(){k("hover",d(this))});this.lis.bind("mouseout.tabs",function(){n("hover",d(this))});this.anchors.bind("focus.tabs",function(){k("focus",d(this).closest("li"))});this.anchors.bind("blur.tabs",function(){n("focus",d(this).closest("li"))})}var m,o;if(c.fx)if(d.isArray(c.fx)){m=c.fx[0];o=c.fx[1]}else m=o=c.fx;var r=o?function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(o,o.duration||"normal",
function(){e(f,o);a._trigger("show",null,a._ui(g,f[0]))})}:function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");a._trigger("show",null,a._ui(g,f[0]))},s=m?function(g,f){f.animate(m,m.duration||"normal",function(){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");e(f,m);a.element.dequeue("tabs")})}:function(g,f){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");a.element.dequeue("tabs")};
this.anchors.bind(c.event+".tabs",function(){var g=this,f=d(g).closest("li"),i=a.panels.filter(":not(.ui-tabs-hide)"),l=a.element.find(a._sanitizeSelector(g.hash));if(f.hasClass("ui-tabs-selected")&&!c.collapsible||f.hasClass("ui-state-disabled")||f.hasClass("ui-state-processing")||a.panels.filter(":animated").length||a._trigger("select",null,a._ui(this,l[0]))===false){this.blur();return false}c.selected=a.anchors.index(this);a.abort();if(c.collapsible)if(f.hasClass("ui-tabs-selected")){c.selected=
-1;c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){s(g,i)}).dequeue("tabs");this.blur();return false}else if(!i.length){c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this));this.blur();return false}c.cookie&&a._cookie(c.selected,c.cookie);if(l.length){i.length&&a.element.queue("tabs",function(){s(g,i)});a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier.";
d.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},_getIndex:function(b){if(typeof b=="string")b=this.anchors.index(this.anchors.filter("[href$="+b+"]"));return b},destroy:function(){var b=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var e=
d.data(this,"href.tabs");if(e)this.href=e;var a=d(this).unbind(".tabs");d.each(["href","load","cache"],function(c,h){a.removeData(h+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){d.data(this,"destroy.tabs")?d(this).remove():d(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});b.cookie&&this._cookie(null,b.cookie);return this},add:function(b,
e,a){if(a===p)a=this.anchors.length;var c=this,h=this.options;e=d(h.tabTemplate.replace(/#\{href\}/g,b).replace(/#\{label\}/g,e));b=!b.indexOf("#")?b.replace("#",""):this._tabId(d("a",e)[0]);e.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var j=c.element.find("#"+b);j.length||(j=d(h.panelTemplate).attr("id",b).data("destroy.tabs",true));j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(a>=this.lis.length){e.appendTo(this.list);j.appendTo(this.list[0].parentNode)}else{e.insertBefore(this.lis[a]);
j.insertBefore(this.panels[a])}h.disabled=d.map(h.disabled,function(k){return k>=a?++k:k});this._tabify();if(this.anchors.length==1){h.selected=0;e.addClass("ui-tabs-selected ui-state-active");j.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){c._trigger("show",null,c._ui(c.anchors[0],c.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[a],this.panels[a]));return this},remove:function(b){b=this._getIndex(b);var e=this.options,a=this.lis.eq(b).remove(),c=this.panels.eq(b).remove();
if(a.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(b+(b+1<this.anchors.length?1:-1));e.disabled=d.map(d.grep(e.disabled,function(h){return h!=b}),function(h){return h>=b?--h:h});this._tabify();this._trigger("remove",null,this._ui(a.find("a")[0],c[0]));return this},enable:function(b){b=this._getIndex(b);var e=this.options;if(d.inArray(b,e.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled");e.disabled=d.grep(e.disabled,function(a){return a!=b});this._trigger("enable",null,
this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(b){b=this._getIndex(b);var e=this.options;if(b!=e.selected){this.lis.eq(b).addClass("ui-state-disabled");e.disabled.push(b);e.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[b],this.panels[b]))}return this},select:function(b){b=this._getIndex(b);if(b==-1)if(this.options.collapsible&&this.options.selected!=-1)b=this.options.selected;else return this;this.anchors.eq(b).trigger(this.options.event+".tabs");return this},
load:function(b){b=this._getIndex(b);var e=this,a=this.options,c=this.anchors.eq(b)[0],h=d.data(c,"load.tabs");this.abort();if(!h||this.element.queue("tabs").length!==0&&d.data(c,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(a.spinner){var j=d("span",c);j.data("label.tabs",j.html()).html(a.spinner)}this.xhr=d.ajax(d.extend({},a.ajaxOptions,{url:h,success:function(k,n){e.element.find(e._sanitizeSelector(c.hash)).html(k);e._cleanup();a.cache&&d.data(c,
"cache.tabs",true);e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.success(k,n)}catch(m){}},error:function(k,n){e._cleanup();e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.error(k,n,b,c)}catch(m){}}}));e.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this},
url:function(b,e){this.anchors.eq(b).removeData("cache.tabs").data("load.tabs",e);return this},length:function(){return this.anchors.length}});d.extend(d.ui.tabs,{version:"1.8.7"});d.extend(d.ui.tabs.prototype,{rotation:null,rotate:function(b,e){var a=this,c=this.options,h=a._rotate||(a._rotate=function(j){clearTimeout(a.rotation);a.rotation=setTimeout(function(){var k=c.selected;a.select(++k<a.anchors.length?k:0)},b);j&&j.stopPropagation()});e=a._unrotate||(a._unrotate=!e?function(j){j.clientX&&
a.rotate(null)}:function(){t=c.selected;h()});if(b){this.element.bind("tabsshow",h);this.anchors.bind(c.event+".tabs",e);h()}else{clearTimeout(a.rotation);this.element.unbind("tabsshow",h);this.anchors.unbind(c.event+".tabs",e);delete this._rotate;delete this._unrotate}return this}})})(jQuery);
;/*
 * jQuery UI Datepicker 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Datepicker
 *
 * Depends:
 *	jquery.ui.core.js
 */
(function(d,G){function K(){this.debug=false;this._curInst=null;this._keyEvent=false;this._disabledInputs=[];this._inDialog=this._datepickerShowing=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this._dayOverClass=
"ui-datepicker-days-cell-over";this.regional=[];this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su",
"Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:false,showMonthAfterYear:false,yearSuffix:""};this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,gotoCurrent:false,changeMonth:false,changeYear:false,yearRange:"c-10:c+10",showOtherMonths:false,selectOtherMonths:false,showWeek:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",
minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:true,showButtonPanel:false,autoSize:false};d.extend(this._defaults,this.regional[""]);this.dpDiv=d('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')}function E(a,b){d.extend(a,b);for(var c in b)if(b[c]==
null||b[c]==G)a[c]=b[c];return a}d.extend(d.ui,{datepicker:{version:"1.8.7"}});var y=(new Date).getTime();d.extend(K.prototype,{markerClassName:"hasDatepicker",log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){E(this._defaults,a||{});return this},_attachDatepicker:function(a,b){var c=null;for(var e in this._defaults){var f=a.getAttribute("date:"+e);if(f){c=c||{};try{c[e]=eval(f)}catch(h){c[e]=f}}}e=a.nodeName.toLowerCase();
f=e=="div"||e=="span";if(!a.id){this.uuid+=1;a.id="dp"+this.uuid}var i=this._newInst(d(a),f);i.settings=d.extend({},b||{},c||{});if(e=="input")this._connectDatepicker(a,i);else f&&this._inlineDatepicker(a,i)},_newInst:function(a,b){return{id:a[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1"),input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:!b?this.dpDiv:d('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')}},
_connectDatepicker:function(a,b){var c=d(a);b.append=d([]);b.trigger=d([]);if(!c.hasClass(this.markerClassName)){this._attachments(c,b);c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});this._autoSize(b);d.data(a,"datepicker",b)}},_attachments:function(a,b){var c=this._get(b,"appendText"),e=this._get(b,"isRTL");b.append&&
b.append.remove();if(c){b.append=d('<span class="'+this._appendClass+'">'+c+"</span>");a[e?"before":"after"](b.append)}a.unbind("focus",this._showDatepicker);b.trigger&&b.trigger.remove();c=this._get(b,"showOn");if(c=="focus"||c=="both")a.focus(this._showDatepicker);if(c=="button"||c=="both"){c=this._get(b,"buttonText");var f=this._get(b,"buttonImage");b.trigger=d(this._get(b,"buttonImageOnly")?d("<img/>").addClass(this._triggerClass).attr({src:f,alt:c,title:c}):d('<button type="button"></button>').addClass(this._triggerClass).html(f==
""?c:d("<img/>").attr({src:f,alt:c,title:c})));a[e?"before":"after"](b.trigger);b.trigger.click(function(){d.datepicker._datepickerShowing&&d.datepicker._lastInput==a[0]?d.datepicker._hideDatepicker():d.datepicker._showDatepicker(a[0]);return false})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var e=function(f){for(var h=0,i=0,g=0;g<f.length;g++)if(f[g].length>h){h=f[g].length;i=g}return i};b.setMonth(e(this._get(a,
c.match(/MM/)?"monthNames":"monthNamesShort")));b.setDate(e(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,b){var c=d(a);if(!c.hasClass(this.markerClassName)){c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});d.data(a,"datepicker",b);this._setDate(b,this._getDefaultDate(b),
true);this._updateDatepicker(b);this._updateAlternate(b);b.dpDiv.show()}},_dialogDatepicker:function(a,b,c,e,f){a=this._dialogInst;if(!a){this.uuid+=1;this._dialogInput=d('<input type="text" id="'+("dp"+this.uuid)+'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');this._dialogInput.keydown(this._doKeyDown);d("body").append(this._dialogInput);a=this._dialogInst=this._newInst(this._dialogInput,false);a.settings={};d.data(this._dialogInput[0],"datepicker",a)}E(a.settings,e||{});
b=b&&b.constructor==Date?this._formatDate(a,b):b;this._dialogInput.val(b);this._pos=f?f.length?f:[f.pageX,f.pageY]:null;if(!this._pos)this._pos=[document.documentElement.clientWidth/2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)];this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px");a.settings.onSelect=c;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);
this._showDatepicker(this._dialogInput[0]);d.blockUI&&d.blockUI(this.dpDiv);d.data(this._dialogInput[0],"datepicker",a);return this},_destroyDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();d.removeData(a,"datepicker");if(e=="input"){c.append.remove();c.trigger.remove();b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",
this._doKeyUp)}else if(e=="div"||e=="span")b.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=false;c.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else if(e=="div"||e=="span")b.children("."+this._inlineClass).children().removeClass("ui-state-disabled");this._disabledInputs=d.map(this._disabledInputs,
function(f){return f==a?null:f})}},_disableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=true;c.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else if(e=="div"||e=="span")b.children("."+this._inlineClass).children().addClass("ui-state-disabled");this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:
f});this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return false;for(var b=0;b<this._disabledInputs.length;b++)if(this._disabledInputs[b]==a)return true;return false},_getInst:function(a){try{return d.data(a,"datepicker")}catch(b){throw"Missing instance data for this datepicker";}},_optionDatepicker:function(a,b,c){var e=this._getInst(a);if(arguments.length==2&&typeof b=="string")return b=="defaults"?d.extend({},d.datepicker._defaults):e?b=="all"?d.extend({},
e.settings):this._get(e,b):null;var f=b||{};if(typeof b=="string"){f={};f[b]=c}if(e){this._curInst==e&&this._hideDatepicker();var h=this._getDateDatepicker(a,true);E(e.settings,f);this._attachments(d(a),e);this._autoSize(e);this._setDateDatepicker(a,h);this._updateDatepicker(e)}},_changeDatepicker:function(a,b,c){this._optionDatepicker(a,b,c)},_refreshDatepicker:function(a){(a=this._getInst(a))&&this._updateDatepicker(a)},_setDateDatepicker:function(a,b){if(a=this._getInst(a)){this._setDate(a,b);
this._updateDatepicker(a);this._updateAlternate(a)}},_getDateDatepicker:function(a,b){(a=this._getInst(a))&&!a.inline&&this._setDateFromField(a,b);return a?this._getDate(a):null},_doKeyDown:function(a){var b=d.datepicker._getInst(a.target),c=true,e=b.dpDiv.is(".ui-datepicker-rtl");b._keyEvent=true;if(d.datepicker._datepickerShowing)switch(a.keyCode){case 9:d.datepicker._hideDatepicker();c=false;break;case 13:c=d("td."+d.datepicker._dayOverClass+":not(."+d.datepicker._currentClass+")",b.dpDiv);c[0]?
d.datepicker._selectDay(a.target,b.selectedMonth,b.selectedYear,c[0]):d.datepicker._hideDatepicker();return false;case 27:d.datepicker._hideDatepicker();break;case 33:d.datepicker._adjustDate(a.target,a.ctrlKey?-d.datepicker._get(b,"stepBigMonths"):-d.datepicker._get(b,"stepMonths"),"M");break;case 34:d.datepicker._adjustDate(a.target,a.ctrlKey?+d.datepicker._get(b,"stepBigMonths"):+d.datepicker._get(b,"stepMonths"),"M");break;case 35:if(a.ctrlKey||a.metaKey)d.datepicker._clearDate(a.target);c=a.ctrlKey||
a.metaKey;break;case 36:if(a.ctrlKey||a.metaKey)d.datepicker._gotoToday(a.target);c=a.ctrlKey||a.metaKey;break;case 37:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,e?+1:-1,"D");c=a.ctrlKey||a.metaKey;if(a.originalEvent.altKey)d.datepicker._adjustDate(a.target,a.ctrlKey?-d.datepicker._get(b,"stepBigMonths"):-d.datepicker._get(b,"stepMonths"),"M");break;case 38:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,-7,"D");c=a.ctrlKey||a.metaKey;break;case 39:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,
e?-1:+1,"D");c=a.ctrlKey||a.metaKey;if(a.originalEvent.altKey)d.datepicker._adjustDate(a.target,a.ctrlKey?+d.datepicker._get(b,"stepBigMonths"):+d.datepicker._get(b,"stepMonths"),"M");break;case 40:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,+7,"D");c=a.ctrlKey||a.metaKey;break;default:c=false}else if(a.keyCode==36&&a.ctrlKey)d.datepicker._showDatepicker(this);else c=false;if(c){a.preventDefault();a.stopPropagation()}},_doKeyPress:function(a){var b=d.datepicker._getInst(a.target);if(d.datepicker._get(b,
"constrainInput")){b=d.datepicker._possibleChars(d.datepicker._get(b,"dateFormat"));var c=String.fromCharCode(a.charCode==G?a.keyCode:a.charCode);return a.ctrlKey||a.metaKey||c<" "||!b||b.indexOf(c)>-1}},_doKeyUp:function(a){a=d.datepicker._getInst(a.target);if(a.input.val()!=a.lastVal)try{if(d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),a.input?a.input.val():null,d.datepicker._getFormatConfig(a))){d.datepicker._setDateFromField(a);d.datepicker._updateAlternate(a);d.datepicker._updateDatepicker(a)}}catch(b){d.datepicker.log(b)}return true},
_showDatepicker:function(a){a=a.target||a;if(a.nodeName.toLowerCase()!="input")a=d("input",a.parentNode)[0];if(!(d.datepicker._isDisabledDatepicker(a)||d.datepicker._lastInput==a)){var b=d.datepicker._getInst(a);d.datepicker._curInst&&d.datepicker._curInst!=b&&d.datepicker._curInst.dpDiv.stop(true,true);var c=d.datepicker._get(b,"beforeShow");E(b.settings,c?c.apply(a,[a,b]):{});b.lastVal=null;d.datepicker._lastInput=a;d.datepicker._setDateFromField(b);if(d.datepicker._inDialog)a.value="";if(!d.datepicker._pos){d.datepicker._pos=
d.datepicker._findPos(a);d.datepicker._pos[1]+=a.offsetHeight}var e=false;d(a).parents().each(function(){e|=d(this).css("position")=="fixed";return!e});if(e&&d.browser.opera){d.datepicker._pos[0]-=document.documentElement.scrollLeft;d.datepicker._pos[1]-=document.documentElement.scrollTop}c={left:d.datepicker._pos[0],top:d.datepicker._pos[1]};d.datepicker._pos=null;b.dpDiv.empty();b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});d.datepicker._updateDatepicker(b);c=d.datepicker._checkOffset(b,
c,e);b.dpDiv.css({position:d.datepicker._inDialog&&d.blockUI?"static":e?"fixed":"absolute",display:"none",left:c.left+"px",top:c.top+"px"});if(!b.inline){c=d.datepicker._get(b,"showAnim");var f=d.datepicker._get(b,"duration"),h=function(){d.datepicker._datepickerShowing=true;var i=b.dpDiv.find("iframe.ui-datepicker-cover");if(i.length){var g=d.datepicker._getBorders(b.dpDiv);i.css({left:-g[0],top:-g[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex(d(a).zIndex()+1);d.effects&&
d.effects[c]?b.dpDiv.show(c,d.datepicker._get(b,"showOptions"),f,h):b.dpDiv[c||"show"](c?f:null,h);if(!c||!f)h();b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus();d.datepicker._curInst=b}}},_updateDatepicker:function(a){var b=this,c=d.datepicker._getBorders(a.dpDiv);a.dpDiv.empty().append(this._generateHTML(a));var e=a.dpDiv.find("iframe.ui-datepicker-cover");e.length&&e.css({left:-c[0],top:-c[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()});a.dpDiv.find("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a").bind("mouseout",
function(){d(this).removeClass("ui-state-hover");this.className.indexOf("ui-datepicker-prev")!=-1&&d(this).removeClass("ui-datepicker-prev-hover");this.className.indexOf("ui-datepicker-next")!=-1&&d(this).removeClass("ui-datepicker-next-hover")}).bind("mouseover",function(){if(!b._isDisabledDatepicker(a.inline?a.dpDiv.parent()[0]:a.input[0])){d(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");d(this).addClass("ui-state-hover");this.className.indexOf("ui-datepicker-prev")!=
-1&&d(this).addClass("ui-datepicker-prev-hover");this.className.indexOf("ui-datepicker-next")!=-1&&d(this).addClass("ui-datepicker-next-hover")}}).end().find("."+this._dayOverClass+" a").trigger("mouseover").end();c=this._getNumberOfMonths(a);e=c[1];e>1?a.dpDiv.addClass("ui-datepicker-multi-"+e).css("width",17*e+"em"):a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");a.dpDiv[(c[0]!=1||c[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");a.dpDiv[(this._get(a,
"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");a==d.datepicker._curInst&&d.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&a.input.focus();if(a.yearshtml){var f=a.yearshtml;setTimeout(function(){f===a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml);f=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(c){return{thin:1,medium:2,thick:3}[c]||c};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},
_checkOffset:function(a,b,c){var e=a.dpDiv.outerWidth(),f=a.dpDiv.outerHeight(),h=a.input?a.input.outerWidth():0,i=a.input?a.input.outerHeight():0,g=document.documentElement.clientWidth+d(document).scrollLeft(),j=document.documentElement.clientHeight+d(document).scrollTop();b.left-=this._get(a,"isRTL")?e-h:0;b.left-=c&&b.left==a.input.offset().left?d(document).scrollLeft():0;b.top-=c&&b.top==a.input.offset().top+i?d(document).scrollTop():0;b.left-=Math.min(b.left,b.left+e>g&&g>e?Math.abs(b.left+e-
g):0);b.top-=Math.min(b.top,b.top+f>j&&j>f?Math.abs(f+i):0);return b},_findPos:function(a){for(var b=this._get(this._getInst(a),"isRTL");a&&(a.type=="hidden"||a.nodeType!=1);)a=a[b?"previousSibling":"nextSibling"];a=d(a).offset();return[a.left,a.top]},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=d.data(a,"datepicker")))if(this._datepickerShowing){a=this._get(b,"showAnim");var c=this._get(b,"duration"),e=function(){d.datepicker._tidyDialog(b);this._curInst=null};d.effects&&d.effects[a]?
b.dpDiv.hide(a,d.datepicker._get(b,"showOptions"),c,e):b.dpDiv[a=="slideDown"?"slideUp":a=="fadeIn"?"fadeOut":"hide"](a?c:null,e);a||e();if(a=this._get(b,"onClose"))a.apply(b.input?b.input[0]:null,[b.input?b.input.val():"",b]);this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if(d.blockUI){d.unblockUI();d("body").append(this.dpDiv)}}this._inDialog=false}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},
_checkExternalClick:function(a){if(d.datepicker._curInst){a=d(a.target);a[0].id!=d.datepicker._mainDivId&&a.parents("#"+d.datepicker._mainDivId).length==0&&!a.hasClass(d.datepicker.markerClassName)&&!a.hasClass(d.datepicker._triggerClass)&&d.datepicker._datepickerShowing&&!(d.datepicker._inDialog&&d.blockUI)&&d.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){a=d(a);var e=this._getInst(a[0]);if(!this._isDisabledDatepicker(a[0])){this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):
0),c);this._updateDatepicker(e)}},_gotoToday:function(a){a=d(a);var b=this._getInst(a[0]);if(this._get(b,"gotoCurrent")&&b.currentDay){b.selectedDay=b.currentDay;b.drawMonth=b.selectedMonth=b.currentMonth;b.drawYear=b.selectedYear=b.currentYear}else{var c=new Date;b.selectedDay=c.getDate();b.drawMonth=b.selectedMonth=c.getMonth();b.drawYear=b.selectedYear=c.getFullYear()}this._notifyChange(b);this._adjustDate(a)},_selectMonthYear:function(a,b,c){a=d(a);var e=this._getInst(a[0]);e._selectingMonthYear=
false;e["selected"+(c=="M"?"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10);this._notifyChange(e);this._adjustDate(a)},_clickMonthYear:function(a){var b=this._getInst(d(a)[0]);b.input&&b._selectingMonthYear&&setTimeout(function(){b.input.focus()},0);b._selectingMonthYear=!b._selectingMonthYear},_selectDay:function(a,b,c,e){var f=d(a);if(!(d(e).hasClass(this._unselectableClass)||this._isDisabledDatepicker(f[0]))){f=this._getInst(f[0]);f.selectedDay=f.currentDay=
d("a",e).html();f.selectedMonth=f.currentMonth=b;f.selectedYear=f.currentYear=c;this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){a=d(a);this._getInst(a[0]);this._selectDate(a,"")},_selectDate:function(a,b){a=this._getInst(d(a)[0]);b=b!=null?b:this._formatDate(a);a.input&&a.input.val(b);this._updateAlternate(a);var c=this._get(a,"onSelect");if(c)c.apply(a.input?a.input[0]:null,[b,a]);else a.input&&a.input.trigger("change");if(a.inline)this._updateDatepicker(a);
else{this._hideDatepicker();this._lastInput=a.input[0];typeof a.input[0]!="object"&&a.input.focus();this._lastInput=null}},_updateAlternate:function(a){var b=this._get(a,"altField");if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),e=this._getDate(a),f=this.formatDate(c,e,this._getFormatConfig(a));d(b).each(function(){d(this).val(f)})}},noWeekends:function(a){a=a.getDay();return[a>0&&a<6,""]},iso8601Week:function(a){a=new Date(a.getTime());a.setDate(a.getDate()+4-(a.getDay()||7));var b=
a.getTime();a.setMonth(0);a.setDate(1);return Math.floor(Math.round((b-a)/864E5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"?b.toString():b+"";if(b=="")return null;for(var e=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff,f=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,h=(c?c.dayNames:null)||this._defaults.dayNames,i=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,
j=c=-1,l=-1,u=-1,k=false,o=function(p){(p=z+1<a.length&&a.charAt(z+1)==p)&&z++;return p},m=function(p){var v=o(p);p=new RegExp("^\\d{1,"+(p=="@"?14:p=="!"?20:p=="y"&&v?4:p=="o"?3:2)+"}");p=b.substring(s).match(p);if(!p)throw"Missing number at position "+s;s+=p[0].length;return parseInt(p[0],10)},n=function(p,v,H){p=o(p)?H:v;for(v=0;v<p.length;v++)if(b.substr(s,p[v].length).toLowerCase()==p[v].toLowerCase()){s+=p[v].length;return v+1}throw"Unknown name at position "+s;},r=function(){if(b.charAt(s)!=
a.charAt(z))throw"Unexpected literal at position "+s;s++},s=0,z=0;z<a.length;z++)if(k)if(a.charAt(z)=="'"&&!o("'"))k=false;else r();else switch(a.charAt(z)){case "d":l=m("d");break;case "D":n("D",f,h);break;case "o":u=m("o");break;case "m":j=m("m");break;case "M":j=n("M",i,g);break;case "y":c=m("y");break;case "@":var w=new Date(m("@"));c=w.getFullYear();j=w.getMonth()+1;l=w.getDate();break;case "!":w=new Date((m("!")-this._ticksTo1970)/1E4);c=w.getFullYear();j=w.getMonth()+1;l=w.getDate();break;
case "'":if(o("'"))r();else k=true;break;default:r()}if(c==-1)c=(new Date).getFullYear();else if(c<100)c+=(new Date).getFullYear()-(new Date).getFullYear()%100+(c<=e?0:-100);if(u>-1){j=1;l=u;do{e=this._getDaysInMonth(c,j-1);if(l<=e)break;j++;l-=e}while(1)}w=this._daylightSavingAdjust(new Date(c,j-1,l));if(w.getFullYear()!=c||w.getMonth()+1!=j||w.getDate()!=l)throw"Invalid date";return w},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",
RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1E7,formatDate:function(a,b,c){if(!b)return"";var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,h=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort;c=(c?c.monthNames:null)||this._defaults.monthNames;var i=function(o){(o=k+1<a.length&&a.charAt(k+1)==o)&&k++;
return o},g=function(o,m,n){m=""+m;if(i(o))for(;m.length<n;)m="0"+m;return m},j=function(o,m,n,r){return i(o)?r[m]:n[m]},l="",u=false;if(b)for(var k=0;k<a.length;k++)if(u)if(a.charAt(k)=="'"&&!i("'"))u=false;else l+=a.charAt(k);else switch(a.charAt(k)){case "d":l+=g("d",b.getDate(),2);break;case "D":l+=j("D",b.getDay(),e,f);break;case "o":l+=g("o",(b.getTime()-(new Date(b.getFullYear(),0,0)).getTime())/864E5,3);break;case "m":l+=g("m",b.getMonth()+1,2);break;case "M":l+=j("M",b.getMonth(),h,c);break;
case "y":l+=i("y")?b.getFullYear():(b.getYear()%100<10?"0":"")+b.getYear()%100;break;case "@":l+=b.getTime();break;case "!":l+=b.getTime()*1E4+this._ticksTo1970;break;case "'":if(i("'"))l+="'";else u=true;break;default:l+=a.charAt(k)}return l},_possibleChars:function(a){for(var b="",c=false,e=function(h){(h=f+1<a.length&&a.charAt(f+1)==h)&&f++;return h},f=0;f<a.length;f++)if(c)if(a.charAt(f)=="'"&&!e("'"))c=false;else b+=a.charAt(f);else switch(a.charAt(f)){case "d":case "m":case "y":case "@":b+=
"0123456789";break;case "D":case "M":return null;case "'":if(e("'"))b+="'";else c=true;break;default:b+=a.charAt(f)}return b},_get:function(a,b){return a.settings[b]!==G?a.settings[b]:this._defaults[b]},_setDateFromField:function(a,b){if(a.input.val()!=a.lastVal){var c=this._get(a,"dateFormat"),e=a.lastVal=a.input?a.input.val():null,f,h;f=h=this._getDefaultDate(a);var i=this._getFormatConfig(a);try{f=this.parseDate(c,e,i)||h}catch(g){this.log(g);e=b?"":e}a.selectedDay=f.getDate();a.drawMonth=a.selectedMonth=
f.getMonth();a.drawYear=a.selectedYear=f.getFullYear();a.currentDay=e?f.getDate():0;a.currentMonth=e?f.getMonth():0;a.currentYear=e?f.getFullYear():0;this._adjustInstDate(a)}},_getDefaultDate:function(a){return this._restrictMinMax(a,this._determineDate(a,this._get(a,"defaultDate"),new Date))},_determineDate:function(a,b,c){var e=function(h){var i=new Date;i.setDate(i.getDate()+h);return i},f=function(h){try{return d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),h,d.datepicker._getFormatConfig(a))}catch(i){}var g=
(h.toLowerCase().match(/^c/)?d.datepicker._getDate(a):null)||new Date,j=g.getFullYear(),l=g.getMonth();g=g.getDate();for(var u=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,k=u.exec(h);k;){switch(k[2]||"d"){case "d":case "D":g+=parseInt(k[1],10);break;case "w":case "W":g+=parseInt(k[1],10)*7;break;case "m":case "M":l+=parseInt(k[1],10);g=Math.min(g,d.datepicker._getDaysInMonth(j,l));break;case "y":case "Y":j+=parseInt(k[1],10);g=Math.min(g,d.datepicker._getDaysInMonth(j,l));break}k=u.exec(h)}return new Date(j,
l,g)};if(b=(b=b==null||b===""?c:typeof b=="string"?f(b):typeof b=="number"?isNaN(b)?c:e(b):new Date(b.getTime()))&&b.toString()=="Invalid Date"?c:b){b.setHours(0);b.setMinutes(0);b.setSeconds(0);b.setMilliseconds(0)}return this._daylightSavingAdjust(b)},_daylightSavingAdjust:function(a){if(!a)return null;a.setHours(a.getHours()>12?a.getHours()+2:0);return a},_setDate:function(a,b,c){var e=!b,f=a.selectedMonth,h=a.selectedYear;b=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=
a.currentDay=b.getDate();a.drawMonth=a.selectedMonth=a.currentMonth=b.getMonth();a.drawYear=a.selectedYear=a.currentYear=b.getFullYear();if((f!=a.selectedMonth||h!=a.selectedYear)&&!c)this._notifyChange(a);this._adjustInstDate(a);if(a.input)a.input.val(e?"":this._formatDate(a))},_getDate:function(a){return!a.currentYear||a.input&&a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay))},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),
b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),e=this._get(a,"showButtonPanel"),f=this._get(a,"hideIfNoPrevNext"),h=this._get(a,"navigationAsDateFormat"),i=this._getNumberOfMonths(a),g=this._get(a,"showCurrentAtPos"),j=this._get(a,"stepMonths"),l=i[0]!=1||i[1]!=1,u=this._daylightSavingAdjust(!a.currentDay?new Date(9999,9,9):new Date(a.currentYear,a.currentMonth,a.currentDay)),k=this._getMinMaxDate(a,"min"),o=this._getMinMaxDate(a,"max");g=a.drawMonth-g;var m=a.drawYear;if(g<0){g+=12;m--}if(o){var n=
this._daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth()-i[0]*i[1]+1,o.getDate()));for(n=k&&n<k?k:n;this._daylightSavingAdjust(new Date(m,g,1))>n;){g--;if(g<0){g=11;m--}}}a.drawMonth=g;a.drawYear=m;n=this._get(a,"prevText");n=!h?n:this.formatDate(n,this._daylightSavingAdjust(new Date(m,g-j,1)),this._getFormatConfig(a));n=this._canAdjustMonth(a,-1,m,g)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_'+y+".datepicker._adjustDate('#"+a.id+"', -"+j+", 'M');\" title=\""+n+'"><span class="ui-icon ui-icon-circle-triangle-'+
(c?"e":"w")+'">'+n+"</span></a>":f?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+n+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+n+"</span></a>";var r=this._get(a,"nextText");r=!h?r:this.formatDate(r,this._daylightSavingAdjust(new Date(m,g+j,1)),this._getFormatConfig(a));f=this._canAdjustMonth(a,+1,m,g)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_'+y+".datepicker._adjustDate('#"+a.id+"', +"+j+", 'M');\" title=\""+r+'"><span class="ui-icon ui-icon-circle-triangle-'+
(c?"w":"e")+'">'+r+"</span></a>":f?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+r+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+r+"</span></a>";j=this._get(a,"currentText");r=this._get(a,"gotoCurrent")&&a.currentDay?u:b;j=!h?j:this.formatDate(j,r,this._getFormatConfig(a));h=!a.inline?'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_'+y+'.datepicker._hideDatepicker();">'+this._get(a,
"closeText")+"</button>":"";e=e?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(c?h:"")+(this._isInRange(a,r)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_'+y+".datepicker._gotoToday('#"+a.id+"');\">"+j+"</button>":"")+(c?"":h)+"</div>":"";h=parseInt(this._get(a,"firstDay"),10);h=isNaN(h)?0:h;j=this._get(a,"showWeek");r=this._get(a,"dayNames");this._get(a,"dayNamesShort");var s=this._get(a,"dayNamesMin"),z=
this._get(a,"monthNames"),w=this._get(a,"monthNamesShort"),p=this._get(a,"beforeShowDay"),v=this._get(a,"showOtherMonths"),H=this._get(a,"selectOtherMonths");this._get(a,"calculateWeek");for(var L=this._getDefaultDate(a),I="",C=0;C<i[0];C++){for(var M="",D=0;D<i[1];D++){var N=this._daylightSavingAdjust(new Date(m,g,a.selectedDay)),t=" ui-corner-all",x="";if(l){x+='<div class="ui-datepicker-group';if(i[1]>1)switch(D){case 0:x+=" ui-datepicker-group-first";t=" ui-corner-"+(c?"right":"left");break;case i[1]-
1:x+=" ui-datepicker-group-last";t=" ui-corner-"+(c?"left":"right");break;default:x+=" ui-datepicker-group-middle";t="";break}x+='">'}x+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+t+'">'+(/all|left/.test(t)&&C==0?c?f:n:"")+(/all|right/.test(t)&&C==0?c?n:f:"")+this._generateMonthYearHeader(a,g,m,k,o,C>0||D>0,z,w)+'</div><table class="ui-datepicker-calendar"><thead><tr>';var A=j?'<th class="ui-datepicker-week-col">'+this._get(a,"weekHeader")+"</th>":"";for(t=0;t<7;t++){var q=
(t+h)%7;A+="<th"+((t+h+6)%7>=5?' class="ui-datepicker-week-end"':"")+'><span title="'+r[q]+'">'+s[q]+"</span></th>"}x+=A+"</tr></thead><tbody>";A=this._getDaysInMonth(m,g);if(m==a.selectedYear&&g==a.selectedMonth)a.selectedDay=Math.min(a.selectedDay,A);t=(this._getFirstDayOfMonth(m,g)-h+7)%7;A=l?6:Math.ceil((t+A)/7);q=this._daylightSavingAdjust(new Date(m,g,1-t));for(var O=0;O<A;O++){x+="<tr>";var P=!j?"":'<td class="ui-datepicker-week-col">'+this._get(a,"calculateWeek")(q)+"</td>";for(t=0;t<7;t++){var F=
p?p.apply(a.input?a.input[0]:null,[q]):[true,""],B=q.getMonth()!=g,J=B&&!H||!F[0]||k&&q<k||o&&q>o;P+='<td class="'+((t+h+6)%7>=5?" ui-datepicker-week-end":"")+(B?" ui-datepicker-other-month":"")+(q.getTime()==N.getTime()&&g==a.selectedMonth&&a._keyEvent||L.getTime()==q.getTime()&&L.getTime()==N.getTime()?" "+this._dayOverClass:"")+(J?" "+this._unselectableClass+" ui-state-disabled":"")+(B&&!v?"":" "+F[1]+(q.getTime()==u.getTime()?" "+this._currentClass:"")+(q.getTime()==b.getTime()?" ui-datepicker-today":
""))+'"'+((!B||v)&&F[2]?' title="'+F[2]+'"':"")+(J?"":' onclick="DP_jQuery_'+y+".datepicker._selectDay('#"+a.id+"',"+q.getMonth()+","+q.getFullYear()+', this);return false;"')+">"+(B&&!v?"&#xa0;":J?'<span class="ui-state-default">'+q.getDate()+"</span>":'<a class="ui-state-default'+(q.getTime()==b.getTime()?" ui-state-highlight":"")+(q.getTime()==u.getTime()?" ui-state-active":"")+(B?" ui-priority-secondary":"")+'" href="#">'+q.getDate()+"</a>")+"</td>";q.setDate(q.getDate()+1);q=this._daylightSavingAdjust(q)}x+=
P+"</tr>"}g++;if(g>11){g=0;m++}x+="</tbody></table>"+(l?"</div>"+(i[0]>0&&D==i[1]-1?'<div class="ui-datepicker-row-break"></div>':""):"");M+=x}I+=M}I+=e+(d.browser.msie&&parseInt(d.browser.version,10)<7&&!a.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':"");a._keyEvent=false;return I},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var j=this._get(a,"changeMonth"),l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),k='<div class="ui-datepicker-title">',
o="";if(h||!j)o+='<span class="ui-datepicker-month">'+i[b]+"</span>";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='<select class="ui-datepicker-month" onchange="DP_jQuery_'+y+".datepicker._selectMonthYear('#"+a.id+"', this, 'M');\" onclick=\"DP_jQuery_"+y+".datepicker._clickMonthYear('#"+a.id+"');\">";for(var n=0;n<12;n++)if((!i||n>=e.getMonth())&&(!m||n<=f.getMonth()))o+='<option value="'+n+'"'+(n==b?' selected="selected"':"")+">"+g[n]+"</option>";o+="</select>"}u||(k+=o+(h||!(j&&
l)?"&#xa0;":""));a.yearshtml="";if(h||!l)k+='<span class="ui-datepicker-year">'+c+"</span>";else{g=this._get(a,"yearRange").split(":");var r=(new Date).getFullYear();i=function(s){s=s.match(/c[+-].*/)?c+parseInt(s.substring(1),10):s.match(/[+-].*/)?r+parseInt(s,10):parseInt(s,10);return isNaN(s)?r:s};b=i(g[0]);g=Math.max(b,i(g[1]||""));b=e?Math.max(b,e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()):g;for(a.yearshtml+='<select class="ui-datepicker-year" onchange="DP_jQuery_'+y+".datepicker._selectMonthYear('#"+
a.id+"', this, 'Y');\" onclick=\"DP_jQuery_"+y+".datepicker._clickMonthYear('#"+a.id+"');\">";b<=g;b++)a.yearshtml+='<option value="'+b+'"'+(b==c?' selected="selected"':"")+">"+b+"</option>";a.yearshtml+="</select>";if(d.browser.mozilla)k+='<select class="ui-datepicker-year"><option value="'+c+'" selected="selected">'+c+"</option></select>";else{k+=a.yearshtml;a.yearshtml=null}}k+=this._get(a,"yearSuffix");if(u)k+=(h||!(j&&l)?"&#xa0;":"")+o;k+="</div>";return k},_adjustInstDate:function(a,b,c){var e=
a.drawYear+(c=="Y"?b:0),f=a.drawMonth+(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&b<c?c:b;return b=a&&b>a?a:b},_notifyChange:function(a){var b=this._get(a,
"onChangeMonthYear");if(b)b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a);
c=this._daylightSavingAdjust(new Date(c,e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,
"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker=
function(a){if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));
return this.each(function(){typeof a=="string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new K;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.7";window["DP_jQuery_"+y]=d})(jQuery);
;/*
 * jQuery UI Progressbar 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Progressbar
 *
 * Depends:
 *   jquery.ui.core.js
 *   jquery.ui.widget.js
 */
(function(b,d){b.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=b("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow");
this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===d)return this._value();this._setOption("value",a);return this},_setOption:function(a,c){if(a==="value"){this.options.value=c;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;if(typeof a!=="number")a=0;return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100*
this._value()/this.options.max},_refreshValue:function(){var a=this.value(),c=this._percentage();if(this.oldValue!==a){this.oldValue=a;this._trigger("change")}this.valueDiv.toggleClass("ui-corner-right",a===this.options.max).width(c.toFixed(0)+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.7"})})(jQuery);
;/*
 * jQuery UI Effects 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/
 */
jQuery.effects||function(f,j){function n(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1],
16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return o.transparent;return o[f.trim(c).toLowerCase()]}function s(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return n(b)}function p(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,
a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function q(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in t||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function u(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function k(c,a,b,d){if(typeof c=="object"){d=
a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:b in f.fx.speeds?f.fx.speeds[b]:f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}function m(c){if(!c||typeof c==="number"||f.fx.speeds[c])return true;if(typeof c==="string"&&!f.effects[c])return true;return false}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor",
"borderTopColor","borderColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=s(b.elem,a);b.end=n(b.end);b.colorInit=true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var o={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,
0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,
211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},r=["add","remove","toggle"],t={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b,
d){if(f.isFunction(b)){d=b;b=null}return this.each(function(){f.queue(this,"fx",function(){var e=f(this),g=e.attr("style")||" ",h=q(p.call(this)),l,v=e.attr("className");f.each(r,function(w,i){c[i]&&e[i+"Class"](c[i])});l=q(p.call(this));e.attr("className",v);e.animate(u(h,l),a,b,function(){f.each(r,function(w,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments)});h=f.queue(this);l=
h.splice(h.length-1,1)[0];h.splice(1,0,l);f.dequeue(this)})})};f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===j?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},
b,d,e]):this._toggleClass(c,a):f.effects.animateClass.apply(this,[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.7",save:function(c,a){for(var b=0;b<a.length;b++)a[b]!==null&&c.data("ec.storage."+a[b],c[0].style[a[b]])},restore:function(c,a){for(var b=0;b<a.length;b++)a[b]!==null&&c.css(a[b],c.data("ec.storage."+a[b]))},setMode:function(c,a){if(a=="toggle")a=c.is(":hidden")?"show":"hide";
return a},getBaseline:function(c,a){var b;switch(c[0]){case "top":b=0;break;case "middle":b=0.5;break;case "bottom":b=1;break;default:b=c[0]/a.height}switch(c[1]){case "left":c=0;break;case "center":c=0.5;break;case "right":c=1;break;default:c=c[1]/a.width}return{x:c,y:b}},createWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent();var a={width:c.outerWidth(true),height:c.outerHeight(true),"float":c.css("float")},b=f("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",
background:"transparent",border:"none",margin:0,padding:0});c.wrap(b);b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(d,e){a[e]=c.css(e);if(isNaN(parseInt(a[e],10)))a[e]="auto"});c.css({position:"relative",top:0,left:0})}return b.css(a).show()},removeWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent().replaceWith(c);
return c},setTransition:function(c,a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=k.apply(this,arguments),b={options:a[1],duration:a[2],callback:a[3]};a=b.options.mode;var d=f.effects[c];if(f.fx.off||!d)return a?this[a](b.duration,b.callback):this.each(function(){b.callback&&b.callback.call(this)});return d.call(this,b)},_show:f.fn.show,show:function(c){if(m(c))return this._show.apply(this,arguments);
else{var a=k.apply(this,arguments);a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(m(c))return this._hide.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(m(c)||typeof c==="boolean"||f.isFunction(c))return this.__toggle.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c),
b=[];f.each(["em","px","%","pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c,
a,b,d,e){return d*((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+b},easeInQuint:function(c,a,b,d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c,
a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,10*(a/e-1))+b},easeOutExpo:function(c,a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a==
e)return b+d;if((a/=e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*a)+1)+b},easeInElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=
g/(2*Math.PI)*Math.asin(d/h);return-(h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g))+b},easeOutElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);return h*Math.pow(2,-10*a)*Math.sin((a*e-c)*2*Math.PI/g)+d+b},easeInOutElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e/2)==2)return b+d;g||(g=e*0.3*1.5);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/
h);if(a<1)return-0.5*h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)+b;return h*Math.pow(2,-10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)*0.5+d+b},easeInBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;return d*(a/=e)*a*((g+1)*a-g)+b},easeOutBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;return d*((a=a/e-1)*a*((g+1)*a+g)+1)+b},easeInOutBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;if((a/=e/2)<1)return d/2*a*a*(((g*=1.525)+1)*a-g)+b;return d/2*((a-=2)*a*(((g*=1.525)+1)*a+g)+2)+b},easeInBounce:function(c,
a,b,d,e){return d-f.easing.easeOutBounce(c,e-a,0,d,e)+b},easeOutBounce:function(c,a,b,d,e){return(a/=e)<1/2.75?d*7.5625*a*a+b:a<2/2.75?d*(7.5625*(a-=1.5/2.75)*a+0.75)+b:a<2.5/2.75?d*(7.5625*(a-=2.25/2.75)*a+0.9375)+b:d*(7.5625*(a-=2.625/2.75)*a+0.984375)+b},easeInOutBounce:function(c,a,b,d,e){if(a<e/2)return f.easing.easeInBounce(c,a*2,0,d,e)*0.5+b;return f.easing.easeOutBounce(c,a*2-e,0,d,e)*0.5+d*0.5+b}})}(jQuery);
;/*
 * jQuery UI Effects Blind 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Blind
 *
 * Depends:
 *	jquery.effects.core.js
 */
(function(b){b.effects.blind=function(c){return this.queue(function(){var a=b(this),g=["position","top","left"],f=b.effects.setMode(a,c.options.mode||"hide"),d=c.options.direction||"vertical";b.effects.save(a,g);a.show();var e=b.effects.createWrapper(a).css({overflow:"hidden"}),h=d=="vertical"?"height":"width";d=d=="vertical"?e.height():e.width();f=="show"&&e.css(h,0);var i={};i[h]=f=="show"?d:0;e.animate(i,c.duration,c.options.easing,function(){f=="hide"&&a.hide();b.effects.restore(a,g);b.effects.removeWrapper(a);
c.callback&&c.callback.apply(a[0],arguments);a.dequeue()})})}})(jQuery);
;/*
 * jQuery UI Effects Bounce 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Bounce
 *
 * Depends:
 *	jquery.effects.core.js
 */
(function(e){e.effects.bounce=function(b){return this.queue(function(){var a=e(this),l=["position","top","left"],h=e.effects.setMode(a,b.options.mode||"effect"),d=b.options.direction||"up",c=b.options.distance||20,m=b.options.times||5,i=b.duration||250;/show|hide/.test(h)&&l.push("opacity");e.effects.save(a,l);a.show();e.effects.createWrapper(a);var f=d=="up"||d=="down"?"top":"left";d=d=="up"||d=="left"?"pos":"neg";c=b.options.distance||(f=="top"?a.outerHeight({margin:true})/3:a.outerWidth({margin:true})/
3);if(h=="show")a.css("opacity",0).css(f,d=="pos"?-c:c);if(h=="hide")c/=m*2;h!="hide"&&m--;if(h=="show"){var g={opacity:1};g[f]=(d=="pos"?"+=":"-=")+c;a.animate(g,i/2,b.options.easing);c/=2;m--}for(g=0;g<m;g++){var j={},k={};j[f]=(d=="pos"?"-=":"+=")+c;k[f]=(d=="pos"?"+=":"-=")+c;a.animate(j,i/2,b.options.easing).animate(k,i/2,b.options.easing);c=h=="hide"?c*2:c/2}if(h=="hide"){g={opacity:0};g[f]=(d=="pos"?"-=":"+=")+c;a.animate(g,i/2,b.options.easing,function(){a.hide();e.effects.restore(a,l);e.effects.removeWrapper(a);
b.callback&&b.callback.apply(this,arguments)})}else{j={};k={};j[f]=(d=="pos"?"-=":"+=")+c;k[f]=(d=="pos"?"+=":"-=")+c;a.animate(j,i/2,b.options.easing).animate(k,i/2,b.options.easing,function(){e.effects.restore(a,l);e.effects.removeWrapper(a);b.callback&&b.callback.apply(this,arguments)})}a.queue("fx",function(){a.dequeue()});a.dequeue()})}})(jQuery);
;/*
 * jQuery UI Effects Clip 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Clip
 *
 * Depends:
 *	jquery.effects.core.js
 */
(function(b){b.effects.clip=function(e){return this.queue(function(){var a=b(this),i=["position","top","left","height","width"],f=b.effects.setMode(a,e.options.mode||"hide"),c=e.options.direction||"vertical";b.effects.save(a,i);a.show();var d=b.effects.createWrapper(a).css({overflow:"hidden"});d=a[0].tagName=="IMG"?d:a;var g={size:c=="vertical"?"height":"width",position:c=="vertical"?"top":"left"};c=c=="vertical"?d.height():d.width();if(f=="show"){d.css(g.size,0);d.css(g.position,c/2)}var h={};h[g.size]=
f=="show"?c:0;h[g.position]=f=="show"?0:c/2;d.animate(h,{queue:false,duration:e.duration,easing:e.options.easing,complete:function(){f=="hide"&&a.hide();b.effects.restore(a,i);b.effects.removeWrapper(a);e.callback&&e.callback.apply(a[0],arguments);a.dequeue()}})})}})(jQuery);
;/*
 * jQuery UI Effects Drop 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Drop
 *
 * Depends:
 *	jquery.effects.core.js
 */
(function(c){c.effects.drop=function(d){return this.queue(function(){var a=c(this),h=["position","top","left","opacity"],e=c.effects.setMode(a,d.options.mode||"hide"),b=d.options.direction||"left";c.effects.save(a,h);a.show();c.effects.createWrapper(a);var f=b=="up"||b=="down"?"top":"left";b=b=="up"||b=="left"?"pos":"neg";var g=d.options.distance||(f=="top"?a.outerHeight({margin:true})/2:a.outerWidth({margin:true})/2);if(e=="show")a.css("opacity",0).css(f,b=="pos"?-g:g);var i={opacity:e=="show"?1:
0};i[f]=(e=="show"?b=="pos"?"+=":"-=":b=="pos"?"-=":"+=")+g;a.animate(i,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){e=="hide"&&a.hide();c.effects.restore(a,h);c.effects.removeWrapper(a);d.callback&&d.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
;/*
 * jQuery UI Effects Explode 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Explode
 *
 * Depends:
 *	jquery.effects.core.js
 */
(function(j){j.effects.explode=function(a){return this.queue(function(){var c=a.options.pieces?Math.round(Math.sqrt(a.options.pieces)):3,d=a.options.pieces?Math.round(Math.sqrt(a.options.pieces)):3;a.options.mode=a.options.mode=="toggle"?j(this).is(":visible")?"hide":"show":a.options.mode;var b=j(this).show().css("visibility","hidden"),g=b.offset();g.top-=parseInt(b.css("marginTop"),10)||0;g.left-=parseInt(b.css("marginLeft"),10)||0;for(var h=b.outerWidth(true),i=b.outerHeight(true),e=0;e<c;e++)for(var f=
0;f<d;f++)b.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-f*(h/d),top:-e*(i/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:h/d,height:i/c,left:g.left+f*(h/d)+(a.options.mode=="show"?(f-Math.floor(d/2))*(h/d):0),top:g.top+e*(i/c)+(a.options.mode=="show"?(e-Math.floor(c/2))*(i/c):0),opacity:a.options.mode=="show"?0:1}).animate({left:g.left+f*(h/d)+(a.options.mode=="show"?0:(f-Math.floor(d/2))*(h/d)),top:g.top+
e*(i/c)+(a.options.mode=="show"?0:(e-Math.floor(c/2))*(i/c)),opacity:a.options.mode=="show"?1:0},a.duration||500);setTimeout(function(){a.options.mode=="show"?b.css({visibility:"visible"}):b.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(b[0]);b.dequeue();j("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery);
;/*
 * jQuery UI Effects Fade 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Fade
 *
 * Depends:
 *	jquery.effects.core.js
 */
(function(b){b.effects.fade=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide");c.animate({opacity:d},{queue:false,duration:a.duration,easing:a.options.easing,complete:function(){a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
;/*
 * jQuery UI Effects Fold 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Fold
 *
 * Depends:
 *	jquery.effects.core.js
 */
(function(c){c.effects.fold=function(a){return this.queue(function(){var b=c(this),j=["position","top","left"],d=c.effects.setMode(b,a.options.mode||"hide"),g=a.options.size||15,h=!!a.options.horizFirst,k=a.duration?a.duration/2:c.fx.speeds._default/2;c.effects.save(b,j);b.show();var e=c.effects.createWrapper(b).css({overflow:"hidden"}),f=d=="show"!=h,l=f?["width","height"]:["height","width"];f=f?[e.width(),e.height()]:[e.height(),e.width()];var i=/([0-9]+)%/.exec(g);if(i)g=parseInt(i[1],10)/100*
f[d=="hide"?0:1];if(d=="show")e.css(h?{height:0,width:g}:{height:g,width:0});h={};i={};h[l[0]]=d=="show"?f[0]:g;i[l[1]]=d=="show"?f[1]:0;e.animate(h,k,a.options.easing).animate(i,k,a.options.easing,function(){d=="hide"&&b.hide();c.effects.restore(b,j);c.effects.removeWrapper(b);a.callback&&a.callback.apply(b[0],arguments);b.dequeue()})})}})(jQuery);
;/*
 * jQuery UI Effects Highlight 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Highlight
 *
 * Depends:
 *	jquery.effects.core.js
 */
(function(b){b.effects.highlight=function(c){return this.queue(function(){var a=b(this),e=["backgroundImage","backgroundColor","opacity"],d=b.effects.setMode(a,c.options.mode||"show"),f={backgroundColor:a.css("backgroundColor")};if(d=="hide")f.opacity=0;b.effects.save(a,e);a.show().css({backgroundImage:"none",backgroundColor:c.options.color||"#ffff99"}).animate(f,{queue:false,duration:c.duration,easing:c.options.easing,complete:function(){d=="hide"&&a.hide();b.effects.restore(a,e);d=="show"&&!b.support.opacity&&
this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
;/*
 * jQuery UI Effects Pulsate 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Pulsate
 *
 * Depends:
 *	jquery.effects.core.js
 */
(function(d){d.effects.pulsate=function(a){return this.queue(function(){var b=d(this),c=d.effects.setMode(b,a.options.mode||"show");times=(a.options.times||5)*2-1;duration=a.duration?a.duration/2:d.fx.speeds._default/2;isVisible=b.is(":visible");animateTo=0;if(!isVisible){b.css("opacity",0).show();animateTo=1}if(c=="hide"&&isVisible||c=="show"&&!isVisible)times--;for(c=0;c<times;c++){b.animate({opacity:animateTo},duration,a.options.easing);animateTo=(animateTo+1)%2}b.animate({opacity:animateTo},duration,
a.options.easing,function(){animateTo==0&&b.hide();a.callback&&a.callback.apply(this,arguments)});b.queue("fx",function(){b.dequeue()}).dequeue()})}})(jQuery);
;/*
 * jQuery UI Effects Scale 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Scale
 *
 * Depends:
 *	jquery.effects.core.js
 */
(function(c){c.effects.puff=function(b){return this.queue(function(){var a=c(this),e=c.effects.setMode(a,b.options.mode||"hide"),g=parseInt(b.options.percent,10)||150,h=g/100,i={height:a.height(),width:a.width()};c.extend(b.options,{fade:true,mode:e,percent:e=="hide"?g:100,from:e=="hide"?i:{height:i.height*h,width:i.width*h}});a.effect("scale",b.options,b.duration,b.callback);a.dequeue()})};c.effects.scale=function(b){return this.queue(function(){var a=c(this),e=c.extend(true,{},b.options),g=c.effects.setMode(a,
b.options.mode||"effect"),h=parseInt(b.options.percent,10)||(parseInt(b.options.percent,10)==0?0:g=="hide"?0:100),i=b.options.direction||"both",f=b.options.origin;if(g!="effect"){e.origin=f||["middle","center"];e.restore=true}f={height:a.height(),width:a.width()};a.from=b.options.from||(g=="show"?{height:0,width:0}:f);h={y:i!="horizontal"?h/100:1,x:i!="vertical"?h/100:1};a.to={height:f.height*h.y,width:f.width*h.x};if(b.options.fade){if(g=="show"){a.from.opacity=0;a.to.opacity=1}if(g=="hide"){a.from.opacity=
1;a.to.opacity=0}}e.from=a.from;e.to=a.to;e.mode=g;a.effect("size",e,b.duration,b.callback);a.dequeue()})};c.effects.size=function(b){return this.queue(function(){var a=c(this),e=["position","top","left","width","height","overflow","opacity"],g=["position","top","left","overflow","opacity"],h=["width","height","overflow"],i=["fontSize"],f=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],k=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=c.effects.setMode(a,
b.options.mode||"effect"),n=b.options.restore||false,m=b.options.scale||"both",l=b.options.origin,j={height:a.height(),width:a.width()};a.from=b.options.from||j;a.to=b.options.to||j;if(l){l=c.effects.getBaseline(l,j);a.from.top=(j.height-a.from.height)*l.y;a.from.left=(j.width-a.from.width)*l.x;a.to.top=(j.height-a.to.height)*l.y;a.to.left=(j.width-a.to.width)*l.x}var d={from:{y:a.from.height/j.height,x:a.from.width/j.width},to:{y:a.to.height/j.height,x:a.to.width/j.width}};if(m=="box"||m=="both"){if(d.from.y!=
d.to.y){e=e.concat(f);a.from=c.effects.setTransition(a,f,d.from.y,a.from);a.to=c.effects.setTransition(a,f,d.to.y,a.to)}if(d.from.x!=d.to.x){e=e.concat(k);a.from=c.effects.setTransition(a,k,d.from.x,a.from);a.to=c.effects.setTransition(a,k,d.to.x,a.to)}}if(m=="content"||m=="both")if(d.from.y!=d.to.y){e=e.concat(i);a.from=c.effects.setTransition(a,i,d.from.y,a.from);a.to=c.effects.setTransition(a,i,d.to.y,a.to)}c.effects.save(a,n?e:g);a.show();c.effects.createWrapper(a);a.css("overflow","hidden").css(a.from);
if(m=="content"||m=="both"){f=f.concat(["marginTop","marginBottom"]).concat(i);k=k.concat(["marginLeft","marginRight"]);h=e.concat(f).concat(k);a.find("*[width]").each(function(){child=c(this);n&&c.effects.save(child,h);var o={height:child.height(),width:child.width()};child.from={height:o.height*d.from.y,width:o.width*d.from.x};child.to={height:o.height*d.to.y,width:o.width*d.to.x};if(d.from.y!=d.to.y){child.from=c.effects.setTransition(child,f,d.from.y,child.from);child.to=c.effects.setTransition(child,
f,d.to.y,child.to)}if(d.from.x!=d.to.x){child.from=c.effects.setTransition(child,k,d.from.x,child.from);child.to=c.effects.setTransition(child,k,d.to.x,child.to)}child.css(child.from);child.animate(child.to,b.duration,b.options.easing,function(){n&&c.effects.restore(child,h)})})}a.animate(a.to,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){a.to.opacity===0&&a.css("opacity",a.from.opacity);p=="hide"&&a.hide();c.effects.restore(a,n?e:g);c.effects.removeWrapper(a);b.callback&&
b.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
;/*
 * jQuery UI Effects Shake 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Shake
 *
 * Depends:
 *	jquery.effects.core.js
 */
(function(d){d.effects.shake=function(a){return this.queue(function(){var b=d(this),j=["position","top","left"];d.effects.setMode(b,a.options.mode||"effect");var c=a.options.direction||"left",e=a.options.distance||20,l=a.options.times||3,f=a.duration||a.options.duration||140;d.effects.save(b,j);b.show();d.effects.createWrapper(b);var g=c=="up"||c=="down"?"top":"left",h=c=="up"||c=="left"?"pos":"neg";c={};var i={},k={};c[g]=(h=="pos"?"-=":"+=")+e;i[g]=(h=="pos"?"+=":"-=")+e*2;k[g]=(h=="pos"?"-=":"+=")+
e*2;b.animate(c,f,a.options.easing);for(e=1;e<l;e++)b.animate(i,f,a.options.easing).animate(k,f,a.options.easing);b.animate(i,f,a.options.easing).animate(c,f/2,a.options.easing,function(){d.effects.restore(b,j);d.effects.removeWrapper(b);a.callback&&a.callback.apply(this,arguments)});b.queue("fx",function(){b.dequeue()});b.dequeue()})}})(jQuery);
;/*
 * jQuery UI Effects Slide 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Slide
 *
 * Depends:
 *	jquery.effects.core.js
 */
(function(c){c.effects.slide=function(d){return this.queue(function(){var a=c(this),h=["position","top","left"],f=c.effects.setMode(a,d.options.mode||"show"),b=d.options.direction||"left";c.effects.save(a,h);a.show();c.effects.createWrapper(a).css({overflow:"hidden"});var g=b=="up"||b=="down"?"top":"left";b=b=="up"||b=="left"?"pos":"neg";var e=d.options.distance||(g=="top"?a.outerHeight({margin:true}):a.outerWidth({margin:true}));if(f=="show")a.css(g,b=="pos"?isNaN(e)?"-"+e:-e:e);var i={};i[g]=(f==
"show"?b=="pos"?"+=":"-=":b=="pos"?"-=":"+=")+e;a.animate(i,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){f=="hide"&&a.hide();c.effects.restore(a,h);c.effects.removeWrapper(a);d.callback&&d.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
;/*
 * jQuery UI Effects Transfer 1.8.7
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Transfer
 *
 * Depends:
 *	jquery.effects.core.js
 */
(function(e){e.effects.transfer=function(a){return this.queue(function(){var b=e(this),c=e(a.options.to),d=c.offset();c={top:d.top,left:d.left,height:c.innerHeight(),width:c.innerWidth()};d=b.offset();var f=e('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(a.options.className).css({top:d.top,left:d.left,height:b.innerHeight(),width:b.innerWidth(),position:"absolute"}).animate(c,a.duration,a.options.easing,function(){f.remove();a.callback&&a.callback.apply(b[0],arguments);
b.dequeue()})})}})(jQuery);
;









/*///////////////////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/jquery_tools/jquery.tools-1.2.2.min.js //
// created: Mon, 26 Sep 2011 14:01:58 +1000                                //
// modified: Sun, 30 Jan 2011 23:58:12 +1100                               //
// size: 44778 bytes                                                       //
///////////////////////////////////////////////////////////////////////////*/

/*
 * jQuery Tools 1.2.2 - The missing UI library for the Web
 * 
 * [tabs, tabs.slideshow, tooltip, tooltip.slide, tooltip.dynamic, scrollable, scrollable.autoscroll, scrollable.navigator, overlay, overlay.apple, dateinput, rangeinput, validator, toolbox.flashembed, toolbox.history, toolbox.expose, toolbox.mousewheel]
 * 
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 * 
 * http://flowplayer.org/tools/
 * 
 * jquery.event.wheel.js - rev 1 
 * Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)
 * Liscensed under the MIT License (MIT-LICENSE.txt)
 * http://www.opensource.org/licenses/mit-license.php
 * Created: 2008-07-01 | Updated: 2008-07-14
 * 
 * -----
 * 
 * File generated: Tue May 25 07:23:03 GMT 2010
 */
(function(c){function p(d,a,b){var e=this,l=d.add(this),h=d.find(b.tabs),j=a.jquery?a:d.children(a),i;h.length||(h=d.children());j.length||(j=d.parent().find(a));j.length||(j=c(a));c.extend(this,{click:function(f,g){var k=h.eq(f);if(typeof f=="string"&&f.replace("#","")){k=h.filter("[href*="+f.replace("#","")+"]");f=Math.max(h.index(k),0)}if(b.rotate){var n=h.length-1;if(f<0)return e.click(n,g);if(f>n)return e.click(0,g)}if(!k.length){if(i>=0)return e;f=b.initialIndex;k=h.eq(f)}if(f===i)return e;
g=g||c.Event();g.type="onBeforeClick";l.trigger(g,[f]);if(!g.isDefaultPrevented()){o[b.effect].call(e,f,function(){g.type="onClick";l.trigger(g,[f])});i=f;h.removeClass(b.current);k.addClass(b.current);return e}},getConf:function(){return b},getTabs:function(){return h},getPanes:function(){return j},getCurrentPane:function(){return j.eq(i)},getCurrentTab:function(){return h.eq(i)},getIndex:function(){return i},next:function(){return e.click(i+1)},prev:function(){return e.click(i-1)}});c.each("onBeforeClick,onClick".split(","),
function(f,g){c.isFunction(b[g])&&c(e).bind(g,b[g]);e[g]=function(k){c(e).bind(g,k);return e}});if(b.history&&c.fn.history){c.tools.history.init(h);b.event="history"}h.each(function(f){c(this).bind(b.event,function(g){e.click(f,g);return g.preventDefault()})});j.find("a[href^=#]").click(function(f){e.click(c(this).attr("href"),f)});if(location.hash)e.click(location.hash);else if(b.initialIndex===0||b.initialIndex>0)e.click(b.initialIndex)}c.tools=c.tools||{version:"1.2.2"};c.tools.tabs={conf:{tabs:"a",
current:"current",onBeforeClick:null,onClick:null,effect:"default",initialIndex:0,event:"click",rotate:false,history:false},addEffect:function(d,a){o[d]=a}};var o={"default":function(d,a){this.getPanes().hide().eq(d).show();a.call()},fade:function(d,a){var b=this.getConf(),e=b.fadeOutSpeed,l=this.getPanes();e?l.fadeOut(e):l.hide();l.eq(d).fadeIn(b.fadeInSpeed,a)},slide:function(d,a){this.getPanes().slideUp(200);this.getPanes().eq(d).slideDown(400,a)},ajax:function(d,a){this.getPanes().eq(0).load(this.getTabs().eq(d).attr("href"),
a)}},m;c.tools.tabs.addEffect("horizontal",function(d,a){m||(m=this.getPanes().eq(0).width());this.getCurrentPane().animate({width:0},function(){c(this).hide()});this.getPanes().eq(d).animate({width:m},function(){c(this).show();a.call()})});c.fn.tabs=function(d,a){var b=this.data("tabs");if(b)return b;if(c.isFunction(a))a={onBeforeClick:a};a=c.extend({},c.tools.tabs.conf,a);this.each(function(){b=new p(c(this),d,a);c(this).data("tabs",b)});return a.api?b:this}})(jQuery);
(function(d){function r(g,a){function p(f){var e=d(f);return e.length<2?e:g.parent().find(f)}var c=this,j=g.add(this),b=g.data("tabs"),h,l,m,n=false,o=p(a.next).click(function(){b.next()}),k=p(a.prev).click(function(){b.prev()});d.extend(c,{getTabs:function(){return b},getConf:function(){return a},play:function(){if(!h){var f=d.Event("onBeforePlay");j.trigger(f);if(f.isDefaultPrevented())return c;n=false;h=setInterval(b.next,a.interval);j.trigger("onPlay");b.next()}},pause:function(){if(!h)return c;
var f=d.Event("onBeforePause");j.trigger(f);if(f.isDefaultPrevented())return c;h=clearInterval(h);m=clearInterval(m);j.trigger("onPause")},stop:function(){c.pause();n=true}});d.each("onBeforePlay,onPlay,onBeforePause,onPause".split(","),function(f,e){d.isFunction(a[e])&&c.bind(e,a[e]);c[e]=function(s){return c.bind(e,s)}});if(a.autopause){var t=b.getTabs().add(o).add(k).add(b.getPanes());t.hover(function(){c.pause();l=clearInterval(l)},function(){n||(l=setTimeout(c.play,a.interval))})}if(a.autoplay)m=
setTimeout(c.play,a.interval);else c.stop();a.clickable&&b.getPanes().click(function(){b.next()});if(!b.getConf().rotate){var i=a.disabledClass;b.getIndex()||k.addClass(i);b.onBeforeClick(function(f,e){if(e){k.removeClass(i);e==b.getTabs().length-1?o.addClass(i):o.removeClass(i)}else k.addClass(i)})}}var q;q=d.tools.tabs.slideshow={conf:{next:".forward",prev:".backward",disabledClass:"disabled",autoplay:false,autopause:true,interval:3E3,clickable:true,api:false}};d.fn.slideshow=function(g){var a=
this.data("slideshow");if(a)return a;g=d.extend({},q.conf,g);this.each(function(){a=new r(d(this),g);d(this).data("slideshow",a)});return g.api?a:this}})(jQuery);
(function(f){function p(a,b,c){var h=c.relative?a.position().top:a.offset().top,e=c.relative?a.position().left:a.offset().left,i=c.position[0];h-=b.outerHeight()-c.offset[0];e+=a.outerWidth()+c.offset[1];var j=b.outerHeight()+a.outerHeight();if(i=="center")h+=j/2;if(i=="bottom")h+=j;i=c.position[1];a=b.outerWidth()+a.outerWidth();if(i=="center")e-=a/2;if(i=="left")e-=a;return{top:h,left:e}}function t(a,b){var c=this,h=a.add(c),e,i=0,j=0,m=a.attr("title"),q=n[b.effect],k,r=a.is(":input"),u=r&&a.is(":checkbox, :radio, select, :button"),
s=a.attr("type"),l=b.events[s]||b.events[r?u?"widget":"input":"def"];if(!q)throw'Nonexistent effect "'+b.effect+'"';l=l.split(/,\s*/);if(l.length!=2)throw"Tooltip: bad events configuration for "+s;a.bind(l[0],function(d){if(b.predelay){clearTimeout(i);j=setTimeout(function(){c.show(d)},b.predelay)}else c.show(d)}).bind(l[1],function(d){if(b.delay){clearTimeout(j);i=setTimeout(function(){c.hide(d)},b.delay)}else c.hide(d)});if(m&&b.cancelDefault){a.removeAttr("title");a.data("title",m)}f.extend(c,
{show:function(d){if(!e){if(m)e=f(b.layout).addClass(b.tipClass).appendTo(document.body).hide().append(m);else if(b.tip)e=f(b.tip).eq(0);else{e=a.next();e.length||(e=a.parent().next())}if(!e.length)throw"Cannot find tooltip for "+a;}if(c.isShown())return c;e.stop(true,true);var g=p(a,e,b);d=d||f.Event();d.type="onBeforeShow";h.trigger(d,[g]);if(d.isDefaultPrevented())return c;g=p(a,e,b);e.css({position:"absolute",top:g.top,left:g.left});k=true;q[0].call(c,function(){d.type="onShow";k="full";h.trigger(d)});
g=b.events.tooltip.split(/,\s*/);e.bind(g[0],function(){clearTimeout(i);clearTimeout(j)});g[1]&&!a.is("input:not(:checkbox, :radio), textarea")&&e.bind(g[1],function(o){o.relatedTarget!=a[0]&&a.trigger(l[1].split(" ")[0])});return c},hide:function(d){if(!e||!c.isShown())return c;d=d||f.Event();d.type="onBeforeHide";h.trigger(d);if(!d.isDefaultPrevented()){k=false;n[b.effect][1].call(c,function(){d.type="onHide";k=false;h.trigger(d)});return c}},isShown:function(d){return d?k=="full":k},getConf:function(){return b},
getTip:function(){return e},getTrigger:function(){return a}});f.each("onHide,onBeforeShow,onShow,onBeforeHide".split(","),function(d,g){f.isFunction(b[g])&&f(c).bind(g,b[g]);c[g]=function(o){f(c).bind(g,o);return c}})}f.tools=f.tools||{version:"1.2.2"};f.tools.tooltip={conf:{effect:"toggle",fadeOutSpeed:"fast",predelay:0,delay:30,opacity:1,tip:0,position:["top","center"],offset:[0,0],relative:false,cancelDefault:true,events:{def:"mouseenter,mouseleave",input:"focus,blur",widget:"focus mouseenter,blur mouseleave",
tooltip:"mouseenter,mouseleave"},layout:"<div/>",tipClass:"tooltip"},addEffect:function(a,b,c){n[a]=[b,c]}};var n={toggle:[function(a){var b=this.getConf(),c=this.getTip();b=b.opacity;b<1&&c.css({opacity:b});c.show();a.call()},function(a){this.getTip().hide();a.call()}],fade:[function(a){var b=this.getConf();this.getTip().fadeTo(b.fadeInSpeed,b.opacity,a)},function(a){this.getTip().fadeOut(this.getConf().fadeOutSpeed,a)}]};f.fn.tooltip=function(a){var b=this.data("tooltip");if(b)return b;a=f.extend(true,
{},f.tools.tooltip.conf,a);if(typeof a.position=="string")a.position=a.position.split(/,?\s/);this.each(function(){b=new t(f(this),a);f(this).data("tooltip",b)});return a.api?b:this}})(jQuery);
(function(d){var i=d.tools.tooltip;d.extend(i.conf,{direction:"up",bounce:false,slideOffset:10,slideInSpeed:200,slideOutSpeed:200,slideFade:!d.browser.msie});var e={up:["-","top"],down:["+","top"],left:["-","left"],right:["+","left"]};i.addEffect("slide",function(g){var a=this.getConf(),f=this.getTip(),b=a.slideFade?{opacity:a.opacity}:{},c=e[a.direction]||e.up;b[c[1]]=c[0]+"="+a.slideOffset;a.slideFade&&f.css({opacity:0});f.show().animate(b,a.slideInSpeed,g)},function(g){var a=this.getConf(),f=a.slideOffset,
b=a.slideFade?{opacity:0}:{},c=e[a.direction]||e.up,h=""+c[0];if(a.bounce)h=h=="+"?"-":"+";b[c[1]]=h+"="+f;this.getTip().animate(b,a.slideOutSpeed,function(){d(this).hide();g.call()})})})(jQuery);
(function(g){function j(a){var c=g(window),d=c.width()+c.scrollLeft(),h=c.height()+c.scrollTop();return[a.offset().top<=c.scrollTop(),d<=a.offset().left+a.width(),h<=a.offset().top+a.height(),c.scrollLeft()>=a.offset().left]}function k(a){for(var c=a.length;c--;)if(a[c])return false;return true}var i=g.tools.tooltip;i.dynamic={conf:{classNames:"top right bottom left"}};g.fn.dynamic=function(a){if(typeof a=="number")a={speed:a};a=g.extend({},i.dynamic.conf,a);var c=a.classNames.split(/\s/),d;this.each(function(){var h=
g(this).tooltip().onBeforeShow(function(e,f){e=this.getTip();var b=this.getConf();d||(d=[b.position[0],b.position[1],b.offset[0],b.offset[1],g.extend({},b)]);g.extend(b,d[4]);b.position=[d[0],d[1]];b.offset=[d[2],d[3]];e.css({visibility:"hidden",position:"absolute",top:f.top,left:f.left}).show();f=j(e);if(!k(f)){if(f[2]){g.extend(b,a.top);b.position[0]="top";e.addClass(c[0])}if(f[3]){g.extend(b,a.right);b.position[1]="right";e.addClass(c[1])}if(f[0]){g.extend(b,a.bottom);b.position[0]="bottom";e.addClass(c[2])}if(f[1]){g.extend(b,
a.left);b.position[1]="left";e.addClass(c[3])}if(f[0]||f[2])b.offset[0]*=-1;if(f[1]||f[3])b.offset[1]*=-1}e.css({visibility:"visible"}).hide()});h.onBeforeShow(function(){var e=this.getConf();this.getTip();setTimeout(function(){e.position=[d[0],d[1]];e.offset=[d[2],d[3]]},0)});h.onHide(function(){var e=this.getTip();e.removeClass(a.classNames)});ret=h});return a.api?ret:this}})(jQuery);
(function(e){function n(f,c){var a=e(c);return a.length<2?a:f.parent().find(c)}function t(f,c){var a=this,l=f.add(a),g=f.children(),k=0,m=c.vertical;j||(j=a);if(g.length>1)g=e(c.items,f);e.extend(a,{getConf:function(){return c},getIndex:function(){return k},getSize:function(){return a.getItems().size()},getNaviButtons:function(){return o.add(p)},getRoot:function(){return f},getItemWrap:function(){return g},getItems:function(){return g.children(c.item).not("."+c.clonedClass)},move:function(b,d){return a.seekTo(k+
b,d)},next:function(b){return a.move(1,b)},prev:function(b){return a.move(-1,b)},begin:function(b){return a.seekTo(0,b)},end:function(b){return a.seekTo(a.getSize()-1,b)},focus:function(){return j=a},addItem:function(b){b=e(b);if(c.circular){e(".cloned:last").before(b);e(".cloned:first").replaceWith(b.clone().addClass(c.clonedClass))}else g.append(b);l.trigger("onAddItem",[b]);return a},seekTo:function(b,d,h){if(c.circular&&b===0&&k==-1&&d!==0)return a;if(!c.circular&&b<0||b>a.getSize()||b<-1)return a;
var i=b;if(b.jquery)b=a.getItems().index(b);else i=a.getItems().eq(b);var q=e.Event("onBeforeSeek");if(!h){l.trigger(q,[b,d]);if(q.isDefaultPrevented()||!i.length)return a}i=m?{top:-i.position().top}:{left:-i.position().left};k=b;j=a;if(d===undefined)d=c.speed;g.animate(i,d,c.easing,h||function(){l.trigger("onSeek",[b])});return a}});e.each(["onBeforeSeek","onSeek","onAddItem"],function(b,d){e.isFunction(c[d])&&e(a).bind(d,c[d]);a[d]=function(h){e(a).bind(d,h);return a}});if(c.circular){var r=a.getItems().slice(-1).clone().prependTo(g),
s=a.getItems().eq(1).clone().appendTo(g);r.add(s).addClass(c.clonedClass);a.onBeforeSeek(function(b,d,h){if(!b.isDefaultPrevented())if(d==-1){a.seekTo(r,h,function(){a.end(0)});return b.preventDefault()}else d==a.getSize()&&a.seekTo(s,h,function(){a.begin(0)})});a.seekTo(0,0)}var o=n(f,c.prev).click(function(){a.prev()}),p=n(f,c.next).click(function(){a.next()});!c.circular&&a.getSize()>1&&a.onBeforeSeek(function(b,d){o.toggleClass(c.disabledClass,d<=0);p.toggleClass(c.disabledClass,d>=a.getSize()-
1)});c.mousewheel&&e.fn.mousewheel&&f.mousewheel(function(b,d){if(c.mousewheel){a.move(d<0?1:-1,c.wheelSpeed||50);return false}});c.keyboard&&e(document).bind("keydown.scrollable",function(b){if(!(!c.keyboard||b.altKey||b.ctrlKey||e(b.target).is(":input")))if(!(c.keyboard!="static"&&j!=a)){var d=b.keyCode;if(m&&(d==38||d==40)){a.move(d==38?-1:1);return b.preventDefault()}if(!m&&(d==37||d==39)){a.move(d==37?-1:1);return b.preventDefault()}}});e(a).trigger("onBeforeSeek",[c.initialIndex])}e.tools=e.tools||
{version:"1.2.2"};e.tools.scrollable={conf:{activeClass:"active",circular:false,clonedClass:"cloned",disabledClass:"disabled",easing:"swing",initialIndex:0,item:null,items:".items",keyboard:true,mousewheel:false,next:".next",prev:".prev",speed:400,vertical:false,wheelSpeed:0}};var j;e.fn.scrollable=function(f){var c=this.data("scrollable");if(c)return c;f=e.extend({},e.tools.scrollable.conf,f);this.each(function(){c=new t(e(this),f);e(this).data("scrollable",c)});return f.api?c:this}})(jQuery);
(function(c){var g=c.tools.scrollable;g.autoscroll={conf:{autoplay:true,interval:3E3,autopause:true}};c.fn.autoscroll=function(d){if(typeof d=="number")d={interval:d};var b=c.extend({},g.autoscroll.conf,d),h;this.each(function(){var a=c(this).data("scrollable");if(a)h=a;var e,i,f=true;a.play=function(){if(!e){f=false;e=setInterval(function(){a.next()},b.interval);a.next()}};a.pause=function(){e=clearInterval(e)};a.stop=function(){a.pause();f=true};b.autopause&&a.getRoot().add(a.getNaviButtons()).hover(function(){a.pause();
clearInterval(i)},function(){f||(i=setTimeout(a.play,b.interval))});b.autoplay&&setTimeout(a.play,b.interval)});return b.api?h:this}})(jQuery);
(function(d){function p(c,g){var h=d(g);return h.length<2?h:c.parent().find(g)}var m=d.tools.scrollable;m.navigator={conf:{navi:".navi",naviItem:null,activeClass:"active",indexed:false,idPrefix:null,history:false}};d.fn.navigator=function(c){if(typeof c=="string")c={navi:c};c=d.extend({},m.navigator.conf,c);var g;this.each(function(){function h(a,b,i){e.seekTo(b);if(j){if(location.hash)location.hash=a.attr("href").replace("#","")}else return i.preventDefault()}function f(){return k.find(c.naviItem||
"> *")}function n(a){var b=d("<"+(c.naviItem||"a")+"/>").click(function(i){h(d(this),a,i)}).attr("href","#"+a);a===0&&b.addClass(l);c.indexed&&b.text(a+1);c.idPrefix&&b.attr("id",c.idPrefix+a);return b.appendTo(k)}function o(a,b){a=f().eq(b.replace("#",""));a.length||(a=f().filter("[href="+b+"]"));a.click()}var e=d(this).data("scrollable"),k=p(e.getRoot(),c.navi),q=e.getNaviButtons(),l=c.activeClass,j=c.history&&d.fn.history;if(e)g=e;e.getNaviButtons=function(){return q.add(k)};f().length?f().each(function(a){d(this).click(function(b){h(d(this),
a,b)})}):d.each(e.getItems(),function(a){n(a)});e.onBeforeSeek(function(a,b){var i=f().eq(b);!a.isDefaultPrevented()&&i.length&&f().removeClass(l).eq(b).addClass(l)});e.onAddItem(function(a,b){b=n(e.getItems().index(b));j&&b.history(o)});j&&f().history(o)});return c.api?g:this}})(jQuery);
(function(a){function t(d,b){var c=this,i=d.add(c),o=a(window),k,f,m,g=a.tools.expose&&(b.mask||b.expose),n=Math.random().toString().slice(10);if(g){if(typeof g=="string")g={color:g};g.closeOnClick=g.closeOnEsc=false}var p=b.target||d.attr("rel");f=p?a(p):d;if(!f.length)throw"Could not find Overlay: "+p;d&&d.index(f)==-1&&d.click(function(e){c.load(e);return e.preventDefault()});a.extend(c,{load:function(e){if(c.isOpened())return c;var h=q[b.effect];if(!h)throw'Overlay: cannot find effect : "'+b.effect+
'"';b.oneInstance&&a.each(s,function(){this.close(e)});e=e||a.Event();e.type="onBeforeLoad";i.trigger(e);if(e.isDefaultPrevented())return c;m=true;g&&a(f).expose(g);var j=b.top,r=b.left,u=f.outerWidth({margin:true}),v=f.outerHeight({margin:true});if(typeof j=="string")j=j=="center"?Math.max((o.height()-v)/2,0):parseInt(j,10)/100*o.height();if(r=="center")r=Math.max((o.width()-u)/2,0);h[0].call(c,{top:j,left:r},function(){if(m){e.type="onLoad";i.trigger(e)}});g&&b.closeOnClick&&a.mask.getMask().one("click",
c.close);b.closeOnClick&&a(document).bind("click."+n,function(l){a(l.target).parents(f).length||c.close(l)});b.closeOnEsc&&a(document).bind("keydown."+n,function(l){l.keyCode==27&&c.close(l)});return c},close:function(e){if(!c.isOpened())return c;e=e||a.Event();e.type="onBeforeClose";i.trigger(e);if(!e.isDefaultPrevented()){m=false;q[b.effect][1].call(c,function(){e.type="onClose";i.trigger(e)});a(document).unbind("click."+n).unbind("keydown."+n);g&&a.mask.close();return c}},getOverlay:function(){return f},
getTrigger:function(){return d},getClosers:function(){return k},isOpened:function(){return m},getConf:function(){return b}});a.each("onBeforeLoad,onStart,onLoad,onBeforeClose,onClose".split(","),function(e,h){a.isFunction(b[h])&&a(c).bind(h,b[h]);c[h]=function(j){a(c).bind(h,j);return c}});k=f.find(b.close||".close");if(!k.length&&!b.close){k=a('<div class="close"></div>');f.prepend(k)}k.click(function(e){c.close(e)});b.load&&c.load()}a.tools=a.tools||{version:"1.2.2"};a.tools.overlay={addEffect:function(d,
b,c){q[d]=[b,c]},conf:{close:null,closeOnClick:true,closeOnEsc:true,closeSpeed:"fast",effect:"default",fixed:!a.browser.msie||a.browser.version>6,left:"center",load:false,mask:null,oneInstance:true,speed:"normal",target:null,top:"10%"}};var s=[],q={};a.tools.overlay.addEffect("default",function(d,b){var c=this.getConf(),i=a(window);if(!c.fixed){d.top+=i.scrollTop();d.left+=i.scrollLeft()}d.position=c.fixed?"fixed":"absolute";this.getOverlay().css(d).fadeIn(c.speed,b)},function(d){this.getOverlay().fadeOut(this.getConf().closeSpeed,
d)});a.fn.overlay=function(d){var b=this.data("overlay");if(b)return b;if(a.isFunction(d))d={onBeforeLoad:d};d=a.extend(true,{},a.tools.overlay.conf,d);this.each(function(){b=new t(a(this),d);s.push(b);a(this).data("overlay",b)});return d.api?b:this}})(jQuery);
(function(i){function j(b){var d=b.offset();return{top:d.top+b.height()/2,left:d.left+b.width()/2}}var k=i.tools.overlay,f=i(window);i.extend(k.conf,{start:{top:null,left:null},fadeInSpeed:"fast",zIndex:9999});function n(b,d){var a=this.getOverlay(),c=this.getConf(),g=this.getTrigger(),o=this,l=a.outerWidth({margin:true}),h=a.data("img");if(!h){var e=a.css("backgroundImage");if(!e)throw"background-image CSS property not set for overlay";e=e.slice(e.indexOf("(")+1,e.indexOf(")")).replace(/\"/g,"");
a.css("backgroundImage","none");h=i('<img src="'+e+'"/>');h.css({border:0,display:"none"}).width(l);i("body").append(h);a.data("img",h)}e=c.start.top||Math.round(f.height()/2);var m=c.start.left||Math.round(f.width()/2);if(g){g=j(g);e=g.top;m=g.left}h.css({position:"absolute",top:e,left:m,width:0,zIndex:c.zIndex}).show();b.top+=f.scrollTop();b.left+=f.scrollLeft();b.position="absolute";a.css(b);h.animate({top:a.css("top"),left:a.css("left"),width:l},c.speed,function(){if(c.fixed){b.top-=f.scrollTop();
b.left-=f.scrollLeft();b.position="fixed";h.add(a).css(b)}a.css("zIndex",c.zIndex+1).fadeIn(c.fadeInSpeed,function(){o.isOpened()&&!i(this).index(a)?d.call():a.hide()})})}function p(b){var d=this.getOverlay().hide(),a=this.getConf(),c=this.getTrigger();d=d.data("img");var g={top:a.start.top,left:a.start.left,width:0};c&&i.extend(g,j(c));a.fixed&&d.css({position:"absolute"}).animate({top:"+="+f.scrollTop(),left:"+="+f.scrollLeft()},0);d.animate(g,a.closeSpeed,b)}k.addEffect("apple",n,p)})(jQuery);
(function(d){function R(b,c){return 32-(new Date(b,c,32)).getDate()}function S(b,c){b=""+b;for(c=c||2;b.length<c;)b="0"+b;return b}function T(b,c,j){var m=b.getDate(),h=b.getDay(),t=b.getMonth();b=b.getFullYear();var f={d:m,dd:S(m),ddd:B[j].shortDays[h],dddd:B[j].days[h],m:t+1,mm:S(t+1),mmm:B[j].shortMonths[t],mmmm:B[j].months[t],yy:String(b).slice(2),yyyy:b};c=c.replace(X,function(o){return o in f?f[o]:o.slice(1,o.length-1)});return Y.html(c).html()}function y(b){return parseInt(b,10)}function U(b,
c){return b.getYear()===c.getYear()&&b.getMonth()==c.getMonth()&&b.getDate()==c.getDate()}function C(b){if(b){if(b.constructor==Date)return b;if(typeof b=="string"){var c=b.split("-");if(c.length==3)return new Date(y(c[0]),y(c[1])-1,y(c[2]));if(!/^-?\d+$/.test(b))return;b=y(b)}c=new Date;c.setDate(c.getDate()+b);return c}}function Z(b,c){function j(a,e,g){l=a;D=a.getFullYear();E=a.getMonth();G=a.getDate();g=g||d.Event("api");g.type="change";H.trigger(g,[a]);if(!g.isDefaultPrevented()){b.val(T(a,e.format,
e.lang));b.data("date",a);h.hide(g)}}function m(a){a.type="onShow";H.trigger(a);d(document).bind("keydown.d",function(e){var g=e.keyCode;if(g==8){b.val("");return h.hide(e)}if(g==27)return h.hide(e);if(d(V).index(g)>=0){if(!u){h.show(e);return e.preventDefault()}var i=d("#"+f.weeks+" a"),p=d("."+f.focus),q=i.index(p);p.removeClass(f.focus);if(g==74||g==40)q+=7;else if(g==75||g==38)q-=7;else if(g==76||g==39)q+=1;else if(g==72||g==37)q-=1;if(q==-1){h.addMonth(-1);p=d("#"+f.weeks+" a:last")}else if(q==
35){h.addMonth();p=d("#"+f.weeks+" a:first")}else p=i.eq(q);p.addClass(f.focus);return e.preventDefault()}if(g==34)return h.addMonth();if(g==33)return h.addMonth(-1);if(g==36)return h.today();if(g==13)d(e.target).is("select")||d("."+f.focus).click();return d([16,17,18,9]).index(g)>=0});d(document).bind("click.d",function(e){var g=e.target;if(!d(g).parents("#"+f.root).length&&g!=b[0]&&(!K||g!=K[0]))h.hide(e)})}var h=this,t=new Date,f=c.css,o=B[c.lang],k=d("#"+f.root),L=k.find("#"+f.title),K,I,J,D,
E,G,l=b.attr("data-value")||c.value||b.val(),r=b.attr("min")||c.min,s=b.attr("max")||c.max,u;l=C(l)||t;r=C(r||c.yearRange[0]*365);s=C(s||c.yearRange[1]*365);if(!o)throw"Dateinput: invalid language: "+c.lang;if(b.attr("type")=="date"){var M=d("<input/>");d.each("name,readonly,disabled,value,required".split(","),function(a,e){M.attr(e,b.attr(e))});b.replaceWith(M);b=M}b.addClass(f.input);var H=b.add(h);if(!k.length){k=d("<div><div><a/><div/><a/></div><div><div/><div/></div></div>").hide().css({position:"absolute"}).attr("id",
f.root);k.children().eq(0).attr("id",f.head).end().eq(1).attr("id",f.body).children().eq(0).attr("id",f.days).end().eq(1).attr("id",f.weeks).end().end().end().find("a").eq(0).attr("id",f.prev).end().eq(1).attr("id",f.next);L=k.find("#"+f.head).find("div").attr("id",f.title);if(c.selectors){var z=d("<select/>").attr("id",f.month),A=d("<select/>").attr("id",f.year);L.append(z.add(A))}for(var $=k.find("#"+f.days),N=0;N<7;N++)$.append(d("<span/>").text(o.shortDays[(N+c.firstDay)%7]));b.after(k)}if(c.trigger)K=
d("<a/>").attr("href","#").addClass(f.trigger).click(function(a){h.show();return a.preventDefault()}).insertAfter(b);var O=k.find("#"+f.weeks);A=k.find("#"+f.year);z=k.find("#"+f.month);d.extend(h,{show:function(a){if(!(b.is("[readonly]")||u)){a=a||d.Event();a.type="onBeforeShow";H.trigger(a);if(!a.isDefaultPrevented()){d.each(W,function(){this.hide()});u=true;z.unbind("change").change(function(){h.setValue(A.val(),d(this).val())});A.unbind("change").change(function(){h.setValue(d(this).val(),z.val())});
I=k.find("#"+f.prev).unbind("click").click(function(){I.hasClass(f.disabled)||h.addMonth(-1);return false});J=k.find("#"+f.next).unbind("click").click(function(){J.hasClass(f.disabled)||h.addMonth();return false});h.setValue(l);var e=b.position();k.css({top:e.top+b.outerHeight({margins:true})+c.offset[0],left:e.left+c.offset[1]});if(c.speed)k.show(c.speed,function(){m(a)});else{k.show();m(a)}return h}}},setValue:function(a,e,g){var i;if(parseInt(e,10)>=-1){a=y(a);e=y(e);g=y(g);i=new Date(a,e,g)}else{i=
a||l;a=i.getYear()+1900;e=i.getMonth();g=i.getDate()}if(e==-1){e=11;a--}else if(e==12){e=0;a++}if(!u){j(i,c);return h}E=e;D=a;i=new Date(a,e,1-c.firstDay);g=i.getDay();var p=R(a,e),q=R(a,e-1),P;if(c.selectors){z.empty();d.each(o.months,function(v,F){r<new Date(a,v+1,-1)&&s>new Date(a,v,0)&&z.append(d("<option/>").html(F).attr("value",v))});A.empty();for(i=a+c.yearRange[0];i<a+c.yearRange[1];i++)r<new Date(i+1,-1,0)&&s>new Date(i,0,0)&&A.append(d("<option/>").text(i));z.val(e);A.val(a)}else L.html(o.months[e]+
" "+a);O.empty();I.add(J).removeClass(f.disabled);for(var w=0,n,x;w<42;w++){n=d("<a/>");if(w%7===0){P=d("<div/>").addClass(f.week);O.append(P)}if(w<g){n.addClass(f.off);x=q-g+w+1;i=new Date(a,e-1,x)}else if(w>=g+p){n.addClass(f.off);x=w-p-g+1;i=new Date(a,e+1,x)}else{x=w-g+1;i=new Date(a,e,x);if(U(l,i))n.attr("id",f.current).addClass(f.focus);else U(t,i)&&n.attr("id",f.today)}r&&i<r&&n.add(I).addClass(f.disabled);s&&i>s&&n.add(J).addClass(f.disabled);n.attr("href","#"+x).text(x).data("date",i);P.append(n);
n.click(function(v){var F=d(this);if(!F.hasClass(f.disabled)){d("#"+f.current).removeAttr("id");F.attr("id",f.current);j(F.data("date"),c,v)}return false})}f.sunday&&O.find(f.week).each(function(){var v=c.firstDay?7-c.firstDay:0;d(this).children().slice(v,v+1).addClass(f.sunday)});return h},setMin:function(a,e){r=C(a);e&&l<r&&h.setValue(r);return h},setMax:function(a,e){s=C(a);e&&l>s&&h.setValue(s);return h},today:function(){return h.setValue(t)},addDay:function(a){return this.setValue(D,E,G+(a||
1))},addMonth:function(a){return this.setValue(D,E+(a||1),G)},addYear:function(a){return this.setValue(D+(a||1),E,G)},hide:function(a){if(u){a=a||d.Event();a.type="onHide";H.trigger(a);d(document).unbind("click.d").unbind("keydown.d");if(a.isDefaultPrevented())return;k.hide();u=false}return h},getConf:function(){return c},getInput:function(){return b},getCalendar:function(){return k},getValue:function(a){return a?T(l,a,c.lang):l},isOpen:function(){return u}});d.each(["onBeforeShow","onShow","change",
"onHide"],function(a,e){d.isFunction(c[e])&&d(h).bind(e,c[e]);h[e]=function(g){d(h).bind(e,g);return h}});b.bind("focus click",h.show).keydown(function(a){var e=a.keyCode;if(!u&&d(V).index(e)>=0){h.show(a);return a.preventDefault()}return a.shiftKey||a.ctrlKey||a.altKey||e==9?true:a.preventDefault()});C(b.val())&&j(l,c)}d.tools=d.tools||{version:"1.2.2"};var W=[],Q,V=[75,76,38,39,74,72,40,37],B={};Q=d.tools.dateinput={conf:{format:"mm/dd/yy",selectors:false,yearRange:[-5,5],lang:"en",offset:[0,0],
speed:0,firstDay:0,min:0,max:0,trigger:false,css:{prefix:"cal",input:"date",root:0,head:0,title:0,prev:0,next:0,month:0,year:0,days:0,body:0,weeks:0,today:0,current:0,week:0,off:0,sunday:0,focus:0,disabled:0,trigger:0}},localize:function(b,c){d.each(c,function(j,m){c[j]=m.split(",")});B[b]=c}};Q.localize("en",{months:"January,February,March,April,May,June,July,August,September,October,November,December",shortMonths:"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec",days:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday",
shortDays:"Sun,Mon,Tue,Wed,Thu,Fri,Sat"});var X=/d{1,4}|m{1,4}|yy(?:yy)?|"[^"]*"|'[^']*'/g,Y=d("<a/>");d.expr[":"].date=function(b){var c=b.getAttribute("type");return c&&c=="date"||!!d(b).data("dateinput")};d.fn.dateinput=function(b){if(this.data("dateinput"))return this;b=d.extend({},Q.conf,b);d.each(b.css,function(j,m){if(!m&&j!="prefix")b.css[j]=(b.css.prefix||"")+(m||j)});var c;this.each(function(){var j=new Z(d(this),b);W.push(j);j=j.getInput().data("dateinput",j);c=c?c.add(j):j});return c?
c:this}})(jQuery);
(function(e){function F(d,a){a=Math.pow(10,a);return Math.round(d*a)/a}function p(d,a){if(a=parseInt(d.css(a),10))return a;return(d=d[0].currentStyle)&&d.width&&parseInt(d.width,10)}function C(d){return(d=d.data("events"))&&d.onSlide}function G(d,a){function h(c,b,f,j){if(f===undefined)f=b/k*z;else if(j)f-=a.min;if(r)f=Math.round(f/r)*r;if(b===undefined||r)b=f*k/z;if(isNaN(f))return g;b=Math.max(0,Math.min(b,k));f=b/k*z;if(j||!n)f+=a.min;if(n)if(j)b=k-b;else f=a.max-f;f=F(f,t);var q=c.type=="click";
if(D&&l!==undefined&&!q){c.type="onSlide";A.trigger(c,[f,b]);if(c.isDefaultPrevented())return g}j=q?a.speed:0;q=q?function(){c.type="change";A.trigger(c,[f])}:null;if(n){m.animate({top:b},j,q);a.progress&&B.animate({height:k-b+m.width()/2},j)}else{m.animate({left:b},j,q);a.progress&&B.animate({width:b+m.width()/2},j)}l=f;H=b;d.val(f);return g}function s(){if(n=a.vertical||p(i,"height")>p(i,"width")){k=p(i,"height")-p(m,"height");u=i.offset().top+k}else{k=p(i,"width")-p(m,"width");u=i.offset().left}}
function v(){s();g.setValue(a.value||a.min)}var g=this,o=a.css,i=e("<div><div/><a href='#'/></div>").data("rangeinput",g),n,l,u,k,H;d.before(i);var m=i.addClass(o.slider).find("a").addClass(o.handle),B=i.find("div").addClass(o.progress);e.each("min,max,step,value".split(","),function(c,b){c=d.attr(b);if(parseFloat(c))a[b]=parseFloat(c,10)});var z=a.max-a.min,r=a.step=="any"?0:a.step,t=a.precision;if(t===undefined)try{t=r.toString().split(".")[1].length}catch(I){t=0}if(d.attr("type")=="range"){var w=
e("<input/>");e.each("name,readonly,disabled,required".split(","),function(c,b){w.attr(b,d.attr(b))});w.val(a.value);d.replaceWith(w);d=w}d.addClass(o.input);var A=e(g).add(d),D=true;e.extend(g,{getValue:function(){return l},setValue:function(c,b){return h(b||e.Event("api"),undefined,c,true)},getConf:function(){return a},getProgress:function(){return B},getHandle:function(){return m},getInput:function(){return d},step:function(c,b){b=b||e.Event();var f=a.step=="any"?1:a.step;g.setValue(l+f*(c||1),
b)},stepUp:function(c){return g.step(c||1)},stepDown:function(c){return g.step(-c||-1)}});e.each("onSlide,change".split(","),function(c,b){e.isFunction(a[b])&&e(g).bind(b,a[b]);g[b]=function(f){e(g).bind(b,f);return g}});m.drag({drag:false}).bind("dragStart",function(){D=C(e(g))||C(d)}).bind("drag",function(c,b,f){if(d.is(":disabled"))return false;h(c,n?b:f)}).bind("dragEnd",function(c){if(!c.isDefaultPrevented()){c.type="change";A.trigger(c,[l])}}).click(function(c){return c.preventDefault()});i.click(function(c){if(d.is(":disabled")||
c.target==m[0])return c.preventDefault();s();var b=m.width()/2;h(c,n?k-u-b+c.pageY:c.pageX-u-b)});a.keyboard&&d.keydown(function(c){if(!d.attr("readonly")){var b=c.keyCode,f=e([75,76,38,33,39]).index(b)!=-1,j=e([74,72,40,34,37]).index(b)!=-1;if((f||j)&&!(c.shiftKey||c.altKey||c.ctrlKey)){if(f)g.step(b==33?10:1,c);else if(j)g.step(b==34?-10:-1,c);return c.preventDefault()}}});d.blur(function(c){var b=e(this).val();b!==l&&g.setValue(b,c)});e.extend(d[0],{stepUp:g.stepUp,stepDown:g.stepDown});v();k||
e(window).load(v)}e.tools=e.tools||{version:"1.2.2"};var E;E=e.tools.rangeinput={conf:{min:0,max:100,step:"any",steps:0,value:0,precision:undefined,vertical:0,keyboard:true,progress:false,speed:100,css:{input:"range",slider:"slider",progress:"progress",handle:"handle"}}};var x,y;e.fn.drag=function(d){document.ondragstart=function(){return false};d=e.extend({x:true,y:true,drag:true},d);x=x||e(document).bind("mousedown mouseup",function(a){var h=e(a.target);if(a.type=="mousedown"&&h.data("drag")){var s=
h.position(),v=a.pageX-s.left,g=a.pageY-s.top,o=true;x.bind("mousemove.drag",function(i){var n=i.pageX-v;i=i.pageY-g;var l={};if(d.x)l.left=n;if(d.y)l.top=i;if(o){h.trigger("dragStart");o=false}d.drag&&h.css(l);h.trigger("drag",[i,n]);y=h});a.preventDefault()}else try{y&&y.trigger("dragEnd")}finally{x.unbind("mousemove.drag");y=null}});return this.data("drag",true)};e.expr[":"].range=function(d){var a=d.getAttribute("type");return a&&a=="range"||!!e(d).filter("input").data("rangeinput")};e.fn.rangeinput=
function(d){if(this.data("rangeinput"))return this;d=e.extend(true,{},E.conf,d);var a;this.each(function(){var h=new G(e(this),e.extend(true,{},d));h=h.getInput().data("rangeinput",h);a=a?a.add(h):h});return a?a:this}})(jQuery);
(function(e){function v(a,b,c){var j=a.offset().top,g=a.offset().left,l=c.position.split(/,?\s+/),f=l[0];l=l[1];j-=b.outerHeight()-c.offset[0];g+=a.outerWidth()+c.offset[1];c=b.outerHeight()+a.outerHeight();if(f=="center")j+=c/2;if(f=="bottom")j+=c;a=a.outerWidth();if(l=="center")g-=(a+b.outerWidth())/2;if(l=="left")g-=a;return{top:j,left:g}}function w(a){function b(){return this.getAttribute("type")==a}b.key="[type="+a+"]";return b}function s(a,b,c){function j(f,d,k){if(!(!c.grouped&&f.length)){var h;
if(k===false||e.isArray(k)){h=i.messages[d.key||d]||i.messages["*"];h=h[c.lang]||i.messages["*"].en;(d=h.match(/\$\d/g))&&e.isArray(k)&&e.each(d,function(n){h=h.replace(this,k[n])})}else h=k[c.lang]||k;f.push(h)}}var g=this,l=b.add(g);a=a.not(":button, :image, :reset, :submit");e.extend(g,{getConf:function(){return c},getForm:function(){return b},getInputs:function(){return a},invalidate:function(f,d){if(!d){var k=[];e.each(f,function(h,n){h=a.filter("[name="+h+"]");if(h.length){h.trigger("OI",[n]);
k.push({input:h,messages:[n]})}});f=k;d=e.Event()}d.type="onFail";l.trigger(d,[f]);d.isDefaultPrevented()||q[c.effect][0].call(g,f,d);return g},reset:function(f){f=f||a;f.removeClass(c.errorClass).each(function(){var d=e(this).data("msg.el");if(d){d.remove();e(this).data("msg.el",null)}})},checkValidity:function(f,d){f=f||a;f=f.not(":disabled");if(!f.length)return true;d=d||e.Event();d.type="onBeforeValidate";l.trigger(d,[f]);if(d.isDefaultPrevented())return d.result;var k=[],h=c.errorInputEvent+
".v";f.each(function(){var p=[],m=e(this).unbind(h).data("messages",p);e.each(t,function(){var o=this,r=o[0];if(m.filter(r).length){o=o[1].call(g,m,m.val());if(o!==true){d.type="onBeforeFail";l.trigger(d,[m,r]);if(d.isDefaultPrevented())return false;var u=m.attr(c.messageAttr);if(u){p=[u];return false}else j(p,r,o)}}});if(p.length){k.push({input:m,messages:p});m.trigger("OI",[p]);c.errorInputEvent&&m.bind(h,function(o){g.checkValidity(m,o)})}if(c.singleError&&k.length)return false});var n=q[c.effect];
if(!n)throw'Validator: cannot find effect "'+c.effect+'"';if(k.length){g.invalidate(k,d);return false}else{n[1].call(g,f,d);d.type="onSuccess";l.trigger(d,[f]);f.unbind(h)}return true}});e.each("onBeforeValidate,onBeforeFail,onFail,onSuccess".split(","),function(f,d){e.isFunction(c[d])&&e(g).bind(d,c[d]);g[d]=function(k){e(g).bind(d,k);return g}});c.formEvent&&b.bind(c.formEvent,function(f){if(!g.checkValidity(null,f))return f.preventDefault()});b.bind("reset",function(){g.reset()});a[0]&&a[0].validity&&
a.each(function(){this.oninvalid=function(){return false}});if(b[0])b[0].checkValidity=g.checkValidity;c.inputEvent&&a.bind(c.inputEvent,function(f){g.checkValidity(e(this),f)});a.filter(":checkbox, select").filter("[required]").change(function(f){var d=e(this);if(this.checked||d.is("select")&&e(this).val())q[c.effect][1].call(g,d,f)})}e.tools=e.tools||{version:"1.2.2"};var x=/\[type=([a-z]+)\]/,y=/^-?[0-9]*(\.[0-9]+)?$/,z=/^([a-z0-9_\.\-\+]+)@([\da-z\.\-]+)\.([a-z\.]{2,6})$/i,A=/^(https?:\/\/)?([\da-z\.\-]+)\.([a-z\.]{2,6})([\/\w \.\-]*)*\/?$/i,
i;i=e.tools.validator={conf:{grouped:false,effect:"default",errorClass:"invalid",inputEvent:null,errorInputEvent:"keyup",formEvent:"submit",lang:"en",message:"<div/>",messageAttr:"data-message",messageClass:"error",offset:[0,0],position:"center right",singleError:false,speed:"normal"},messages:{"*":{en:"Please correct this value"}},localize:function(a,b){e.each(b,function(c,j){i.messages[c]=i.messages[c]||{};i.messages[c][a]=j})},localizeFn:function(a,b){i.messages[a]=i.messages[a]||{};e.extend(i.messages[a],
b)},fn:function(a,b,c){if(e.isFunction(b))c=b;else{if(typeof b=="string")b={en:b};this.messages[a.key||a]=b}if(b=x.exec(a))a=w(b[1]);t.push([a,c])},addEffect:function(a,b,c){q[a]=[b,c]}};var t=[],q={"default":[function(a){var b=this.getConf();e.each(a,function(c,j){c=j.input;c.addClass(b.errorClass);var g=c.data("msg.el");if(!g){g=e(b.message).addClass(b.messageClass).appendTo(document.body);c.data("msg.el",g)}g.css({visibility:"hidden"}).find("span").remove();e.each(j.messages,function(l,f){e("<span/>").html(f).appendTo(g)});
g.outerWidth()==g.parent().width()&&g.add(g.find("p")).css({display:"inline"});j=v(c,g,b);g.css({visibility:"visible",position:"absolute",top:j.top,left:j.left}).fadeIn(b.speed)})},function(a){var b=this.getConf();a.removeClass(b.errorClass).each(function(){var c=e(this).data("msg.el");c&&c.css({visibility:"hidden"})})}]};e.each("email,url,number".split(","),function(a,b){e.expr[":"][b]=function(c){return c.getAttribute("type")===b}});e.fn.oninvalid=function(a){return this[a?"bind":"trigger"]("OI",
a)};i.fn(":email","Please enter a valid email address",function(a,b){return!b||z.test(b)});i.fn(":url","Please enter a valid URL",function(a,b){return!b||A.test(b)});i.fn(":number","Please enter a numeric value.",function(a,b){return y.test(b)});i.fn("[max]","Please enter a value smaller than $1",function(a,b){a=a.attr("max");return parseFloat(b)<=parseFloat(a)?true:[a]});i.fn("[min]","Please enter a value larger than $1",function(a,b){a=a.attr("min");return parseFloat(b)>=parseFloat(a)?true:[a]});
i.fn("[required]","Please complete this mandatory field.",function(a,b){if(a.is(":checkbox"))return a.is(":checked");return!!b});i.fn("[pattern]",function(a){var b=new RegExp("^"+a.attr("pattern")+"$");return b.test(a.val())});e.fn.validator=function(a){if(this.data("validator"))return this;a=e.extend(true,{},i.conf,a);if(this.is("form"))return this.each(function(){var c=e(this),j=new s(c.find(":input"),c,a);c.data("validator",j)});else{var b=new s(this,this.eq(0).closest("form"),a);return this.data("validator",
b)}}})(jQuery);
(function(){function f(a,b){if(b)for(key in b)if(b.hasOwnProperty(key))a[key]=b[key];return a}function l(a,b){var c=[];for(var d in a)if(a.hasOwnProperty(d))c[d]=b(a[d]);return c}function m(a,b,c){if(e.isSupported(b.version))a.innerHTML=e.getHTML(b,c);else if(b.expressInstall&&e.isSupported([6,65]))a.innerHTML=e.getHTML(f(b,{src:b.expressInstall}),{MMredirectURL:location.href,MMplayerType:"PlugIn",MMdoctitle:document.title});else{if(!a.innerHTML.replace(/\s/g,"")){a.innerHTML="<h2>Flash version "+
b.version+" or greater is required</h2><h3>"+(g[0]>0?"Your version is "+g:"You have no flash plugin installed")+"</h3>"+(a.tagName=="A"?"<p>Click here to download latest version</p>":"<p>Download latest version from <a href='"+k+"'>here</a></p>");if(a.tagName=="A")a.onclick=function(){location.href=k}}if(b.onFail){var d=b.onFail.call(this);if(typeof d=="string")a.innerHTML=d}}if(h)window[b.id]=document.getElementById(b.id);f(this,{getRoot:function(){return a},getOptions:function(){return b},getConf:function(){return c},
getApi:function(){return a.firstChild}})}var h=document.all,k="http://www.adobe.com/go/getflashplayer",n=typeof jQuery=="function",o=/(\d+)[^\d]+(\d+)[^\d]*(\d*)/,i={width:"100%",height:"100%",id:"_"+(""+Math.random()).slice(9),allowfullscreen:true,allowscriptaccess:"always",quality:"high",version:[3,0],onFail:null,expressInstall:null,w3c:false,cachebusting:false};window.attachEvent&&window.attachEvent("onbeforeunload",function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){}});
window.flashembed=function(a,b,c){if(typeof a=="string")a=document.getElementById(a.replace("#",""));if(a){if(typeof b=="string")b={src:b};return new m(a,f(f({},i),b),c)}};var e=f(window.flashembed,{conf:i,getVersion:function(){var a;try{a=navigator.plugins["Shockwave Flash"].description.slice(16)}catch(b){try{var c=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");a=c&&c.GetVariable("$version")}catch(d){}}return(a=o.exec(a))?[a[1],a[3]]:[0,0]},asString:function(a){if(a===null||a===undefined)return null;
var b=typeof a;if(b=="object"&&a.push)b="array";switch(b){case "string":a=a.replace(new RegExp('(["\\\\])',"g"),"\\$1");a=a.replace(/^\s?(\d+\.?\d+)%/,"$1pct");return'"'+a+'"';case "array":return"["+l(a,function(d){return e.asString(d)}).join(",")+"]";case "function":return'"function()"';case "object":b=[];for(var c in a)a.hasOwnProperty(c)&&b.push('"'+c+'":'+e.asString(a[c]));return"{"+b.join(",")+"}"}return String(a).replace(/\s/g," ").replace(/\'/g,'"')},getHTML:function(a,b){a=f({},a);var c='<object width="'+
a.width+'" height="'+a.height+'" id="'+a.id+'" name="'+a.id+'"';if(a.cachebusting)a.src+=(a.src.indexOf("?")!=-1?"&":"?")+Math.random();c+=a.w3c||!h?' data="'+a.src+'" type="application/x-shockwave-flash"':' classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"';c+=">";if(a.w3c||h)c+='<param name="movie" value="'+a.src+'" />';a.width=a.height=a.id=a.w3c=a.src=null;a.onFail=a.version=a.expressInstall=null;for(var d in a)if(a[d])c+='<param name="'+d+'" value="'+a[d]+'" />';a="";if(b){for(var j in b)if(b[j]){d=
b[j];a+=j+"="+(/function|object/.test(typeof d)?e.asString(d):d)+"&"}a=a.slice(0,-1);c+='<param name="flashvars" value=\''+a+"' />"}c+="</object>";return c},isSupported:function(a){return g[0]>a[0]||g[0]==a[0]&&g[1]>=a[1]}}),g=e.getVersion();if(n){jQuery.tools=jQuery.tools||{version:"1.2.2"};jQuery.tools.flashembed={conf:i};jQuery.fn.flashembed=function(a,b){return this.each(function(){$(this).data("flashembed",flashembed(this,a,b))})}}})();
(function(b){function h(c){if(c){var a=d.contentWindow.document;a.open().close();a.location.hash=c}}var g,d,f,i;b.tools=b.tools||{version:"1.2.2"};b.tools.history={init:function(c){if(!i){if(b.browser.msie&&b.browser.version<"8"){if(!d){d=b("<iframe/>").attr("src","javascript:false;").hide().get(0);b("body").append(d);setInterval(function(){var a=d.contentWindow.document;a=a.location.hash;g!==a&&b.event.trigger("hash",a)},100);h(location.hash||"#")}}else setInterval(function(){var a=location.hash;
a!==g&&b.event.trigger("hash",a)},100);f=!f?c:f.add(c);c.click(function(a){var e=b(this).attr("href");d&&h(e);if(e.slice(0,1)!="#"){location.href="#"+e;return a.preventDefault()}});i=true}}};b(window).bind("hash",function(c,a){a?f.filter(function(){var e=b(this).attr("href");return e==a||e==a.replace("#","")}).trigger("history",[a]):f.eq(0).trigger("history",[a]);g=a;window.location.hash=g});b.fn.history=function(c){b.tools.history.init(this);return this.bind("history",c)}})(jQuery);
(function(b){function k(){if(b.browser.msie){var a=b(document).height(),d=b(window).height();return[window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth,a-d<20?d:a]}return[b(window).width(),b(document).height()]}function h(a){if(a)return a.call(b.mask)}b.tools=b.tools||{version:"1.2.2"};var l;l=b.tools.expose={conf:{maskId:"exposeMask",loadSpeed:"slow",closeSpeed:"fast",closeOnClick:true,closeOnEsc:true,zIndex:9998,opacity:0.8,startOpacity:0,color:"#fff",onLoad:null,
onClose:null}};var c,i,f,g,j;b.mask={load:function(a,d){if(f)return this;if(typeof a=="string")a={color:a};a=a||g;g=a=b.extend(b.extend({},l.conf),a);c=b("#"+a.maskId);if(!c.length){c=b("<div/>").attr("id",a.maskId);b("body").append(c)}var m=k();c.css({position:"absolute",top:0,left:0,width:m[0],height:m[1],display:"none",opacity:a.startOpacity,zIndex:a.zIndex});a.color&&c.css("backgroundColor",a.color);if(h(a.onBeforeLoad)===false)return this;a.closeOnEsc&&b(document).bind("keydown.mask",function(e){e.keyCode==
27&&b.mask.close(e)});a.closeOnClick&&c.bind("click.mask",function(e){b.mask.close(e)});b(window).bind("resize.mask",function(){b.mask.fit()});if(d&&d.length){j=d.eq(0).css("zIndex");/**/d.find(".jsInFieldLabel").css('zIndex',1);/**/ b.each(d,function(){var e=b(this);/relative|absolute|fixed/i.test(e.css("position"))||e.css("position","relative")});i=d.css({zIndex:Math.max(a.zIndex+1,j=="auto"?0:j)})}c.css({display:"block"}).fadeTo(a.loadSpeed,a.opacity,function(){b.mask.fit();h(a.onLoad)});f=true;return this},close:function(){if(f){if(h(g.onBeforeClose)===
false)return this;c.fadeOut(g.closeSpeed,function(){h(g.onClose);i&&i.css({zIndex:j})});b(document).unbind("keydown.mask");c.unbind("click.mask");b(window).unbind("resize.mask");f=false}return this},fit:function(){if(f){var a=k();c.css({width:a[0],height:a[1]})}},getMask:function(){return c},isLoaded:function(){return f},getConf:function(){return g},getExposed:function(){return i}};b.fn.mask=function(a){b.mask.load(a);return this};b.fn.expose=function(a){b.mask.load(a,this);return this}})(jQuery);
(function(b){function c(a){switch(a.type){case "mousemove":return b.extend(a.data,{clientX:a.clientX,clientY:a.clientY,pageX:a.pageX,pageY:a.pageY});case "DOMMouseScroll":b.extend(a,a.data);a.delta=-a.detail/3;break;case "mousewheel":a.delta=a.wheelDelta/120;break}a.type="wheel";return b.event.handle.call(this,a,a.delta)}b.fn.mousewheel=function(a){return this[a?"bind":"trigger"]("wheel",a)};b.event.special.wheel={setup:function(){b.event.add(this,d,c,{})},teardown:function(){b.event.remove(this,
d,c)}};var d=!b.browser.mozilla?"mousewheel":"DOMMouseScroll"+(b.browser.version<"1.9"?" mousemove":"")})(jQuery);










/*///////////////////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/scroll_to/jquery.scrollTo-1.4.2-min.js //
// created: Mon, 26 Sep 2011 14:01:58 +1000                                //
// modified: Wed, 31 Aug 2011 11:54:40 +1000                               //
// size: 2252 bytes                                                        //
///////////////////////////////////////////////////////////////////////////*/

/**
 * jQuery.ScrollTo - Easy element scrolling using jQuery.
 * Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
 * Dual licensed under MIT and GPL.
 * Date: 5/25/2009
 * @author Ariel Flesler
 * @version 1.4.2
 *
 * http://flesler.blogspot.com/2007/10/jqueryscrollto.html
 */
;(function(d){var k=d.scrollTo=function(a,i,e){d(window).scrollTo(a,i,e)};k.defaults={axis:'xy',duration:parseFloat(d.fn.jquery)>=1.3?0:1};k.window=function(a){return d(window)._scrollable()};d.fn._scrollable=function(){return this.map(function(){var a=this,i=!a.nodeName||d.inArray(a.nodeName.toLowerCase(),['iframe','#document','html','body'])!=-1;if(!i)return a;var e=(a.contentWindow||a).document||a.ownerDocument||a;return d.browser.safari||e.compatMode=='BackCompat'?e.body:e.documentElement})};d.fn.scrollTo=function(n,j,b){if(typeof j=='object'){b=j;j=0}if(typeof b=='function')b={onAfter:b};if(n=='max')n=9e9;b=d.extend({},k.defaults,b);j=j||b.speed||b.duration;b.queue=b.queue&&b.axis.length>1;if(b.queue)j/=2;b.offset=p(b.offset);b.over=p(b.over);return this._scrollable().each(function(){var q=this,r=d(q),f=n,s,g={},u=r.is('html,body');switch(typeof f){case'number':case'string':if(/^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(f)){f=p(f);break}f=d(f,this);case'object':if(f.is||f.style)s=(f=d(f)).offset()}d.each(b.axis.split(''),function(a,i){var e=i=='x'?'Left':'Top',h=e.toLowerCase(),c='scroll'+e,l=q[c],m=k.max(q,i);if(s){g[c]=s[h]+(u?0:l-r.offset()[h]);if(b.margin){g[c]-=parseInt(f.css('margin'+e))||0;g[c]-=parseInt(f.css('border'+e+'Width'))||0}g[c]+=b.offset[h]||0;if(b.over[h])g[c]+=f[i=='x'?'width':'height']()*b.over[h]}else{var o=f[h];g[c]=o.slice&&o.slice(-1)=='%'?parseFloat(o)/100*m:o}if(/^\d+$/.test(g[c]))g[c]=g[c]<=0?0:Math.min(g[c],m);if(!a&&b.queue){if(l!=g[c])t(b.onAfterFirst);delete g[c]}});t(b.onAfter);function t(a){r.animate(g,j,b.easing,a&&function(){a.call(this,n,b)})}}).end()};k.max=function(a,i){var e=i=='x'?'Width':'Height',h='scroll'+e;if(!d(a).is('html,body'))return a[h]-d(a)[e.toLowerCase()]();var c='client'+e,l=a.ownerDocument.documentElement,m=a.ownerDocument.body;return Math.max(l[h],m[h])-Math.min(l[c],m[c])};function p(a){return typeof a=='object'?a:{top:a,left:a}}})(jQuery);









/*///////////////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/pretty_photo/jquery.prettyPhoto.js //
// created: Mon, 26 Sep 2011 14:01:58 +1000                            //
// modified: Tue, 21 Dec 2010 17:29:26 +1100                           //
// size: 22746 bytes                                                   //
///////////////////////////////////////////////////////////////////////*/

// note: updated for core by adding ".prettyPhoto" to all the bind/unbind event calls
//		 changed the .click, .keydown, .resize, .scroll bind function calls to bind ('x.prettyPhoto', ...)

/* ------------------------------------------------------------------------
 * Class: prettyPhoto
 * Use: Lightbox clone for jQuery
 * Author: Stephane Caron (http://www.no-margin-for-errors.com)
 * Version: 3.0.1
 * ------------------------------------------------------------------------- */

(function($){$.prettyPhoto={version:'3.0'};$.fn.prettyPhoto=function(pp_settings){pp_settings=jQuery.extend({animation_speed:'fast',slideshow:false,autoplay_slideshow:false,opacity:0.80,show_title:true,allow_resize:true,default_width:500,default_height:344,counter_separator_label:'/',theme:'facebook',hideflash:false,wmode:'opaque',autoplay:true,modal:false,overlay_gallery:true,keyboard_shortcuts:true,changepicturecallback:function(){},callback:function(){},markup:'<div class="pp_pic_holder"> \
      <div class="ppt">&nbsp;</div> \
      <div class="pp_top"> \
       <div class="pp_left"></div> \
       <div class="pp_middle"></div> \
       <div class="pp_right"></div> \
      </div> \
      <div class="pp_content_container"> \
       <div class="pp_left"> \
       <div class="pp_right"> \
        <div class="pp_content"> \
         <div class="pp_loaderIcon"></div> \
         <div class="pp_fade"> \
          <a href="#" class="pp_expand" title="Expand the image">Expand</a> \
          <div class="pp_hoverContainer"> \
           <a class="pp_next" href="#">next</a> \
           <a class="pp_previous" href="#">previous</a> \
          </div> \
          <div id="pp_full_res"></div> \
          <div class="pp_details clearfix"> \
           <p class="pp_description"></p> \
           <a class="pp_close" href="#">Close</a> \
           <div class="pp_nav"> \
            <a href="#" class="pp_arrow_previous">Previous</a> \
            <p class="currentTextHolder">0/0</p> \
            <a href="#" class="pp_arrow_next">Next</a> \
           </div> \
          </div> \
         </div> \
        </div> \
       </div> \
       </div> \
      </div> \
      <div class="pp_bottom"> \
       <div class="pp_left"></div> \
       <div class="pp_middle"></div> \
       <div class="pp_right"></div> \
      </div> \
     </div> \
     <div class="pp_overlay"></div>',gallery_markup:'<div class="pp_gallery"> \
        <a href="#" class="pp_arrow_previous">Previous</a> \
        <ul> \
         {gallery} \
        </ul> \
        <a href="#" class="pp_arrow_next">Next</a> \
       </div>',image_markup:'<img id="fullResImage" src="" />',flash_markup:'<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="{width}" height="{height}"><param name="wmode" value="{wmode}" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="{path}" /><embed src="{path}" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="{width}" height="{height}" wmode="{wmode}"></embed></object>',quicktime_markup:'<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab" height="{height}" width="{width}"><param name="src" value="{path}"><param name="autoplay" value="{autoplay}"><param name="type" value="video/quicktime"><embed src="{path}" height="{height}" width="{width}" autoplay="{autoplay}" type="video/quicktime" pluginspage="http://www.apple.com/quicktime/download/"></embed></object>',iframe_markup:'<iframe src ="{path}" width="{width}" height="{height}" frameborder="no"></iframe>',inline_markup:'<div class="pp_inline clearfix">{content}</div>',custom_markup:''},pp_settings);var matchedObjects=this,percentBased=false,correctSizes,pp_open,pp_contentHeight,pp_contentWidth,pp_containerHeight,pp_containerWidth,windowHeight=$(window).height(),windowWidth=$(window).width(),pp_slideshow;doresize=true,scroll_pos=_get_scroll();$(window).unbind('resize.prettyPhoto').bind ('resize.prettyPhoto', function(){_center_overlay();_resize_overlay();});if(pp_settings.keyboard_shortcuts){$(document).unbind('keydown.prettyPhoto').bind ('keydown.prettyPhoto', function(e){if(typeof $pp_pic_holder!='undefined'){if($pp_pic_holder.is(':visible')){switch(e.keyCode){case 37:$.prettyPhoto.changePage('previous');break;case 39:$.prettyPhoto.changePage('next');break;case 27:if(!settings.modal)
$.prettyPhoto.close();break;};return false;};};});}
$.prettyPhoto.initialize=function(){settings=pp_settings;if($.browser.msie&&parseInt($.browser.version)==6)settings.theme="light_square";_buildOverlay(this);if(settings.allow_resize)
$(window).bind ('scroll.prettyPhoto', function(){_center_overlay();});_center_overlay();set_position=jQuery.inArray($(this).attr('href'),pp_images);$.prettyPhoto.open();return false;}
$.prettyPhoto.open=function(event){if(typeof settings=="undefined"){settings=pp_settings;if($.browser.msie&&$.browser.version==6)settings.theme="light_square";_buildOverlay(event.target);pp_images=$.makeArray(arguments[0]);pp_titles=(arguments[1])?$.makeArray(arguments[1]):$.makeArray("");pp_descriptions=(arguments[2])?$.makeArray(arguments[2]):$.makeArray("");isSet=(pp_images.length>1)?true:false;set_position=0;}
if($.browser.msie&&$.browser.version==6)$('select').css('visibility','hidden');if(settings.hideflash)$('object,embed').css('visibility','hidden');_checkPosition($(pp_images).size());$('.pp_loaderIcon').show();if($ppt.is(':hidden'))$ppt.css('opacity',0).show();$pp_overlay.show().fadeTo(settings.animation_speed,settings.opacity);$pp_pic_holder.find('.currentTextHolder').text((set_position+1)+settings.counter_separator_label+$(pp_images).size());$pp_pic_holder.find('.pp_description').show().html(unescape(pp_descriptions[set_position]));(settings.show_title&&pp_titles[set_position]!=""&&typeof pp_titles[set_position]!="undefined")?$ppt.html(unescape(pp_titles[set_position])):$ppt.html('&nbsp;');movie_width=(parseFloat(grab_param('width',pp_images[set_position])))?grab_param('width',pp_images[set_position]):settings.default_width.toString();movie_height=(parseFloat(grab_param('height',pp_images[set_position])))?grab_param('height',pp_images[set_position]):settings.default_height.toString();if(movie_width.indexOf('%')!=-1||movie_height.indexOf('%')!=-1){movie_height=parseFloat(($(window).height()*parseFloat(movie_height)/100)-150);movie_width=parseFloat(($(window).width()*parseFloat(movie_width)/100)-150);percentBased=true;}else{percentBased=false;}
$pp_pic_holder.fadeIn(function(){imgPreloader="";switch(_getFileType(pp_images[set_position])){case'image':imgPreloader=new Image();nextImage=new Image();if(isSet&&set_position>$(pp_images).size())nextImage.src=pp_images[set_position+1];prevImage=new Image();if(isSet&&pp_images[set_position-1])prevImage.src=pp_images[set_position-1];$pp_pic_holder.find('#pp_full_res')[0].innerHTML=settings.image_markup;$pp_pic_holder.find('#fullResImage').attr('src',pp_images[set_position]);imgPreloader.onload=function(){correctSizes=_fitToViewport(imgPreloader.width,imgPreloader.height);_showContent();};imgPreloader.onerror=function(){alert('Image cannot be loaded. Make sure the path is correct and image exist.');$.prettyPhoto.close();};imgPreloader.src=pp_images[set_position];break;case'youtube':correctSizes=_fitToViewport(movie_width,movie_height);movie='http://www.youtube.com/v/'+grab_param('v',pp_images[set_position]);if(settings.autoplay)movie+="&autoplay=1";toInject=settings.flash_markup.replace(/{width}/g,correctSizes['width']).replace(/{height}/g,correctSizes['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,movie);break;case'vimeo':correctSizes=_fitToViewport(movie_width,movie_height);movie_id=pp_images[set_position];var regExp=/http:\/\/(www\.)?vimeo.com\/(\d+)/;var match=movie_id.match(regExp);movie='http://player.vimeo.com/video/'+match[2]+'?title=0&amp;byline=0&amp;portrait=0';if(settings.autoplay)movie+="&autoplay=1;";vimeo_width=correctSizes['width']+'/embed/?moog_width='+correctSizes['width'];toInject=settings.iframe_markup.replace(/{width}/g,vimeo_width).replace(/{height}/g,correctSizes['height']).replace(/{path}/g,movie);break;case'quicktime':correctSizes=_fitToViewport(movie_width,movie_height);correctSizes['height']+=15;correctSizes['contentHeight']+=15;correctSizes['containerHeight']+=15;toInject=settings.quicktime_markup.replace(/{width}/g,correctSizes['width']).replace(/{height}/g,correctSizes['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,pp_images[set_position]).replace(/{autoplay}/g,settings.autoplay);break;case'flash':correctSizes=_fitToViewport(movie_width,movie_height);flash_vars=pp_images[set_position];flash_vars=flash_vars.substring(pp_images[set_position].indexOf('flashvars')+10,pp_images[set_position].length);filename=pp_images[set_position];filename=filename.substring(0,filename.indexOf('?'));toInject=settings.flash_markup.replace(/{width}/g,correctSizes['width']).replace(/{height}/g,correctSizes['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,filename+'?'+flash_vars);break;case'iframe':correctSizes=_fitToViewport(movie_width,movie_height);frame_url=pp_images[set_position];frame_url=frame_url.substr(0,frame_url.indexOf('iframe')-1);toInject=settings.iframe_markup.replace(/{width}/g,correctSizes['width']).replace(/{height}/g,correctSizes['height']).replace(/{path}/g,frame_url);break;case'custom':correctSizes=_fitToViewport(movie_width,movie_height);toInject=settings.custom_markup;break;case'inline':myClone=$(pp_images[set_position]).clone().css({'width':settings.default_width}).wrapInner('<div id="pp_full_res"><div class="pp_inline clearfix"></div></div>').appendTo($('body'));correctSizes=_fitToViewport($(myClone).width(),$(myClone).height());$(myClone).remove();toInject=settings.inline_markup.replace(/{content}/g,$(pp_images[set_position]).html());break;};if(!imgPreloader){$pp_pic_holder.find('#pp_full_res')[0].innerHTML=toInject;_showContent();};});return false;};$.prettyPhoto.changePage=function(direction){currentGalleryPage=0;if(direction=='previous'){set_position--;if(set_position<0){set_position=0;return;};}else if(direction=='next'){set_position++;if(set_position>$(pp_images).size()-1){set_position=0;}}else{set_position=direction;};if(!doresize)doresize=true;$('.pp_contract').removeClass('pp_contract').addClass('pp_expand');_hideContent(function(){$.prettyPhoto.open();});};$.prettyPhoto.changeGalleryPage=function(direction){if(direction=='next'){currentGalleryPage++;if(currentGalleryPage>totalPage){currentGalleryPage=0;};}else if(direction=='previous'){currentGalleryPage--;if(currentGalleryPage<0){currentGalleryPage=totalPage;};}else{currentGalleryPage=direction;};itemsToSlide=(currentGalleryPage==totalPage)?pp_images.length-((totalPage)*itemsPerPage):itemsPerPage;$pp_pic_holder.find('.pp_gallery li').each(function(i){$(this).animate({'left':(i*itemWidth)-((itemsToSlide*itemWidth)*currentGalleryPage)});});};$.prettyPhoto.startSlideshow=function(){if(typeof pp_slideshow=='undefined'){$pp_pic_holder.find('.pp_play').unbind('click.prettyPhoto').removeClass('pp_play').addClass('pp_pause').bind ('click.prettyPhoto', function(){$.prettyPhoto.stopSlideshow();return false;});pp_slideshow=setInterval($.prettyPhoto.startSlideshow,settings.slideshow);}else{$.prettyPhoto.changePage('next');};}
$.prettyPhoto.stopSlideshow=function(){$pp_pic_holder.find('.pp_pause').unbind('click.prettyPhoto').removeClass('pp_pause').addClass('pp_play').bind ('click.prettyPhoto', function(){$.prettyPhoto.startSlideshow();return false;});clearInterval(pp_slideshow);pp_slideshow=undefined;}
$.prettyPhoto.close=function(){clearInterval(pp_slideshow);$pp_pic_holder.stop().find('object,embed').css('visibility','hidden');$('div.pp_pic_holder,div.ppt,.pp_fade').fadeOut(settings.animation_speed,function(){$(this).remove();});$pp_overlay.fadeOut(settings.animation_speed,function(){if($.browser.msie&&$.browser.version==6)$('select').css('visibility','visible');if(settings.hideflash)$('object,embed').css('visibility','visible');$(this).remove();$(window).unbind('scroll.prettyPhoto');settings.callback();doresize=true;pp_open=false;delete settings;});};_showContent=function(){$('.pp_loaderIcon').hide();$ppt.fadeTo(settings.animation_speed,1);projectedTop=scroll_pos['scrollTop']+((windowHeight/2)-(correctSizes['containerHeight']/2));if(projectedTop<0)projectedTop=0;$pp_pic_holder.find('.pp_content').animate({'height':correctSizes['contentHeight']},settings.animation_speed);$pp_pic_holder.animate({'top':projectedTop,'left':(windowWidth/2)-(correctSizes['containerWidth']/2),'width':correctSizes['containerWidth']},settings.animation_speed,function(){$pp_pic_holder.find('.pp_hoverContainer,#fullResImage').height(correctSizes['height']).width(correctSizes['width']);$pp_pic_holder.find('.pp_fade').fadeIn(settings.animation_speed);if(isSet&&_getFileType(pp_images[set_position])=="image"){$pp_pic_holder.find('.pp_hoverContainer').show();}else{$pp_pic_holder.find('.pp_hoverContainer').hide();}
if(correctSizes['resized'])$('a.pp_expand,a.pp_contract').fadeIn(settings.animation_speed);
if(settings.autoplay_slideshow&&!pp_slideshow&&!pp_open)$.prettyPhoto.startSlideshow();
settings.changepicturecallback();pp_open=true;});_insert_gallery();};
function _hideContent(callback){$pp_pic_holder.find('#pp_full_res object,#pp_full_res embed').css('visibility','hidden');$pp_pic_holder.find('.pp_fade').fadeOut(settings.animation_speed,function(){$('.pp_loaderIcon').show();callback();});};function _checkPosition(setCount){if(set_position==setCount-1){$pp_pic_holder.find('a.pp_next').css('visibility','hidden');$pp_pic_holder.find('a.pp_next').addClass('disabled').unbind('click.prettyPhoto');}else{$pp_pic_holder.find('a.pp_next').css('visibility','visible');$pp_pic_holder.find('a.pp_next.disabled').removeClass('disabled').bind('click.prettyPhoto',function(){$.prettyPhoto.changePage('next');return false;});};if(set_position==0){$pp_pic_holder.find('a.pp_previous').css('visibility','hidden').addClass('disabled').unbind('click.prettyPhoto');}else{$pp_pic_holder.find('a.pp_previous.disabled').css('visibility','visible').removeClass('disabled').bind('click.prettyPhoto',function(){$.prettyPhoto.changePage('previous');return false;});};(setCount>1)?$('.pp_nav').show():$('.pp_nav').hide();};function _fitToViewport(width,height){resized=false;_getDimensions(width,height);imageWidth=width,imageHeight=height;if(((pp_containerWidth>windowWidth)||(pp_containerHeight>windowHeight))&&doresize&&settings.allow_resize&&!percentBased){resized=true,fitting=false;while(!fitting){if((pp_containerWidth>windowWidth)){imageWidth=(windowWidth-200);imageHeight=(height/width)*imageWidth;}else if((pp_containerHeight>windowHeight)){imageHeight=(windowHeight-200);imageWidth=(width/height)*imageHeight;}else{fitting=true;};pp_containerHeight=imageHeight,pp_containerWidth=imageWidth;};_getDimensions(imageWidth,imageHeight);};return{width:Math.floor(imageWidth),height:Math.floor(imageHeight),containerHeight:Math.floor(pp_containerHeight),containerWidth:Math.floor(pp_containerWidth)+40,contentHeight:Math.floor(pp_contentHeight),contentWidth:Math.floor(pp_contentWidth),resized:resized};};function _getDimensions(width,height){width=parseFloat(width);height=parseFloat(height);$pp_details=$pp_pic_holder.find('.pp_details');$pp_details.width(width);detailsHeight=parseFloat($pp_details.css('marginTop'))+parseFloat($pp_details.css('marginBottom'));$pp_details=$pp_details.clone().appendTo($('body')).css({'position':'absolute','top':-10000});detailsHeight+=$pp_details.height();detailsHeight=(detailsHeight<=34)?36:detailsHeight;if($.browser.msie&&$.browser.version==7)detailsHeight+=8;$pp_details.remove();pp_contentHeight=height+detailsHeight;pp_contentWidth=width;pp_containerHeight=pp_contentHeight+$ppt.height()+$pp_pic_holder.find('.pp_top').height()+$pp_pic_holder.find('.pp_bottom').height();pp_containerWidth=width;}
function _getFileType(itemSrc){if(itemSrc.match(/youtube\.com\/watch/i)){return'youtube';
}else if(itemSrc.match(/vimeo\.com/i)){
	return'vimeo';
}else if(itemSrc.indexOf('.mov')!=-1){return'quicktime';}else if(itemSrc.indexOf('.swf')!=-1){return'flash';
}else if(itemSrc.indexOf('iframe')!=-1){return'iframe';
}else if(itemSrc.indexOf('custom')!=-1){return'custom';
}else if(itemSrc.substr(0,1)=='#'){return'inline';
}else{return'image';};};
function _center_overlay(){
	if(doresize&&typeof $pp_pic_holder!='undefined'){
		scroll_pos=_get_scroll();
		titleHeight=$ppt.height(),contentHeight=$pp_pic_holder.height(),contentwidth=$pp_pic_holder.width();
		projectedTop=(windowHeight/2)+scroll_pos['scrollTop']-(contentHeight/2);
		$pp_pic_holder.css({'top':projectedTop,'left':(windowWidth/2)+scroll_pos['scrollLeft']-(contentwidth/2)});
	};};
function _get_scroll(){if(self.pageYOffset){return{scrollTop:self.pageYOffset,scrollLeft:self.pageXOffset};}else if(document.documentElement&&document.documentElement.scrollTop){return{scrollTop:document.documentElement.scrollTop,scrollLeft:document.documentElement.scrollLeft};}else if(document.body){return{scrollTop:document.body.scrollTop,scrollLeft:document.body.scrollLeft};};};
function _resize_overlay(){windowHeight=$(window).height(),windowWidth=$(window).width();if(typeof $pp_overlay!="undefined")$pp_overlay.height($(document).height());};
function _insert_gallery(){
	if(isSet&&settings.overlay_gallery&&_getFileType(pp_images[set_position])=="image"){
		itemWidth=52+5;
		navWidth=(settings.theme=="facebook")?58:38;
/*
		itemsPerPage=Math.floor((correctSizes['containerWidth']-100-navWidth)/itemWidth);
*/
		itemsPerPage=Math.floor((correctSizes['containerWidth']-navWidth)/itemWidth);
		
		itemsPerPage=(itemsPerPage<pp_images.length)?itemsPerPage:pp_images.length;
		totalPage=Math.ceil(pp_images.length/itemsPerPage)-1;
		if(totalPage==0){
			navWidth=0;
			$pp_pic_holder.find('.pp_gallery .pp_arrow_next,.pp_gallery .pp_arrow_previous').hide();
		}else{
			$pp_pic_holder.find('.pp_gallery .pp_arrow_next,.pp_gallery .pp_arrow_previous').show();
		};
		galleryWidth=itemsPerPage*itemWidth+navWidth;
		$pp_pic_holder.find('.pp_gallery').width(galleryWidth).css('margin-left',-(galleryWidth/2));
		$pp_pic_holder.find('.pp_gallery ul').width(itemsPerPage*itemWidth).find('li.selected').removeClass('selected');
		goToPage=(Math.floor(set_position/itemsPerPage)<=totalPage)?Math.floor(set_position/itemsPerPage):totalPage;
		if(itemsPerPage){
			/*	
			$pp_pic_holder.find('.pp_gallery').hide().show().removeClass('disabled');
			*/
			$pp_pic_holder.find('.pp_gallery').show().removeClass('disabled');
	
		}else{
			/*	
			$pp_pic_holder.find('.pp_gallery').hide().addClass('disabled');
			*/
		}
		$.prettyPhoto.changeGalleryPage(goToPage);
		$pp_pic_holder.find('.pp_gallery ul li:eq('+set_position+')').addClass('selected');
	}else{
		$pp_pic_holder.find('.pp_content').unbind('mouseenter.prettyPhoto mouseleave.prettyPhoto');
		/*
		$pp_pic_holder.find('.pp_gallery').hide();
		*/
	}
}
function _buildOverlay(caller){theRel=$(caller).attr('rel');galleryRegExp=/\[(?:.*)\]/;isSet=(galleryRegExp.exec(theRel))?true:false;pp_images=(isSet)?jQuery.map(matchedObjects,function(n,i){if($(n).attr('rel').indexOf(theRel)!=-1)return $(n).attr('href');}):$.makeArray($(caller).attr('href'));pp_titles=(isSet)?jQuery.map(matchedObjects,function(n,i){if($(n).attr('rel').indexOf(theRel)!=-1)return($(n).find('img').attr('alt'))?$(n).find('img').attr('alt'):"";}):$.makeArray($(caller).find('img').attr('alt'));pp_descriptions=(isSet)?jQuery.map(matchedObjects,function(n,i){if($(n).attr('rel').indexOf(theRel)!=-1)return($(n).attr('title'))?$(n).attr('title'):"";}):$.makeArray($(caller).attr('title'));$('body').append(settings.markup);$pp_pic_holder=$('.pp_pic_holder'),$ppt=$('.ppt'),$pp_overlay=$('div.pp_overlay');if(isSet&&settings.overlay_gallery){currentGalleryPage=0;toInject="";for(var i=0;i<pp_images.length;i++){var regex=new RegExp("(.*?)\.(jpg|jpeg|png|gif)$");var results=regex.exec(pp_images[i]);if(!results){classname='default';}else{classname='';}
toInject+="<li class='"+classname+"'><a href='#'><img src='"+pp_images[i]+"' width='50' alt='' /></a></li>";};toInject=settings.gallery_markup.replace(/{gallery}/g,toInject);$pp_pic_holder.find('#pp_full_res').after(toInject);$pp_pic_holder.find('.pp_gallery .pp_arrow_next').bind ('click.prettyPhoto', function(){$.prettyPhoto.changeGalleryPage('next');$.prettyPhoto.stopSlideshow();return false;});$pp_pic_holder.find('.pp_gallery .pp_arrow_previous').bind ('click.prettyPhoto', function(){$.prettyPhoto.changeGalleryPage('previous');$.prettyPhoto.stopSlideshow();return false;});$pp_pic_holder.find('.pp_content').hover(function(){$pp_pic_holder.find('.pp_gallery:not(.disabled)').fadeIn();},function(){
/*
	$pp_pic_holder.find('.pp_gallery:not(.disabled)').fadeOut();
*/
});itemWidth=52+5;$pp_pic_holder.find('.pp_gallery ul li').each(function(i){$(this).css({'position':'absolute','left':i*itemWidth});$(this).find('a').unbind('click.prettyPhoto').bind ('click.prettyPhoto', function(){$.prettyPhoto.changePage(i);$.prettyPhoto.stopSlideshow();return false;});});};if(settings.slideshow){$pp_pic_holder.find('.pp_nav').prepend('<a href="#" class="pp_play">Play</a>')
$pp_pic_holder.find('.pp_nav .pp_play').bind ('click.prettyPhoto', function(){$.prettyPhoto.startSlideshow();return false;});}
$pp_pic_holder.attr('class','pp_pic_holder '+settings.theme);$pp_overlay.css({'opacity':0,'height':$(document).height(),'width':$(document).width()}).bind('click.prettyPhoto',function(){if(!settings.modal)$.prettyPhoto.close();});$('a.pp_close').bind('click.prettyPhoto',function(){$.prettyPhoto.close();return false;});$('a.pp_expand').bind('click.prettyPhoto',function(e){if($(this).hasClass('pp_expand')){$(this).removeClass('pp_expand').addClass('pp_contract');doresize=false;}else{$(this).removeClass('pp_contract').addClass('pp_expand');doresize=true;};_hideContent(function(){$.prettyPhoto.open();});return false;});$pp_pic_holder.find('.pp_previous, .pp_nav .pp_arrow_previous').bind('click.prettyPhoto',function(){$.prettyPhoto.changePage('previous');$.prettyPhoto.stopSlideshow();return false;});$pp_pic_holder.find('.pp_next, .pp_nav .pp_arrow_next').bind('click.prettyPhoto',function(){$.prettyPhoto.changePage('next');$.prettyPhoto.stopSlideshow();return false;});_center_overlay();};return this.unbind('click.prettyPhoto').bind ('click.prettyPhoto', $.prettyPhoto.initialize);};function grab_param(name,url){name=name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");var regexS="[\\?&]"+name+"=([^&#]*)";var regex=new RegExp(regexS);var results=regex.exec(url);return(results==null)?"":results[1];}})(jQuery);










/*////////////////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/core/ajax_forms/ajax_forms-0.0.1.js //
// created: Mon, 26 Sep 2011 14:01:58 +1000                             //
// modified: Wed, 31 Aug 2011 11:54:39 +1000                            //
// size: 31449 bytes                                                    //
////////////////////////////////////////////////////////////////////////*/

(function($) {

	// static constructs
	$.core = $.core || { version: '0.0.1' };

	$.core.ajaxForm = {

		// update the default conf values below in $.core.ajaxForm.settings
		updateSettings: function (settings) {
			this.settings = $.extend (true, {}, this.settings, settings);
		},
		// settings that control the way this plugin operates (different to the conf values below that are used when the plugin is being applied to an element)
		settings: {
			messageAnimations: true,						// should the messages be animated when hiding/showing?
			ajaxFormClass: 'core-ajaxForm',					// the selector used to identify ajaxForm elements (used by other core plugins,  eg. the popover plugin when it needs to identify and create new ajaxForms inside itself)
			ifhBlockClass: 'core-ifhBlock',					// 
			messageClass: 'core-message',					// the selector used to identify message elements
			messageGroupingClass: 'core-messageGroup',		// the selector used to identify message element groupings (an alternative to using placing a message inside a .core-inFieldLabel element)
			dialogueButtonsClass: 'core-dialogueButtons',	// css class added to the popover which will cause the dialogue buttons to be aligned in a certain way)
			pleaseWaitClass: 'core-pleaseWait',				// the selector used to identify "please wait" elements 
			iframeDomIdPrefix: 'coreAjaxFormFrame'			// used to create the ids of iframes when creating an iframe to submit a form to
		},

		// update the default conf values below in $.core.popover.conf
		updateDefaultConf: function (conf) {
			this.conf = $.extend (true, {}, this.conf, conf);
		},
		// the default conf values used when this plugin is applied to an element
		conf: {
		},

		// keep a reference to the ajax forms that have been created,  referenceb by internal uid
		existingAjaxFormApis: {}
	};

	function ajaxForm (ajaxForm, conf) {

		// private variables
		var api = this;
		var $ajaxForm = $(ajaxForm);
//		var $w = $(window);
		var uid = Math.random ().toString ().slice (10);
		var popoverUid = null;
		var popoverUidForConvertId = null;	// used when converting dom element ids
		var lastIframeId = null;
		var existingMessageElementIds = [];
		var visibleMessageElementIds = [];
		var submittedBy = null;
		var lastFocusId = null;
		var lastFocusName = null;
		var fieldBlurTimeout = null;
		var ifhKey = null;
		var ifhPage = null;

		// API methods
		$.extend (api, {

			// initialise the ajaxForm element
			init: function () {

				// observe any input fields inside the form and record which one currently has focus when it changes
				$ajaxForm.find ('input[type!=submit], select, textarea').live ('focus.core-ajaxForm', function (event) {
					lastFocusId = unconvert_id ($(this).attr ('id'), popoverUidForConvertId);
					lastFocusName = $(this).attr ('name');
				})
				// observe the blur so that the focused element can be forgotten
				.live ('blur.core-ajaxForm, select, textarea', function (event) {
					// don't blur straight away,  that way when the user clicks on a submit button this last focused field isn't forgotten
					var $this = $(this);
					clearTimeout (fieldBlurTimeout);
					fieldBlurTimeout = setTimeout (function () {
						if (lastFocusId == unconvert_id ($this.attr ('id'), popoverUidForConvertId))
							lastFocusId = null;
						if (lastFocusName == $this.attr ('name'))
							lastFocusName = null;
					}, 100);
				});

				// find any message elements within the form,  and prepare them ready
				$ajaxForm.find ('.' + $.core.ajaxForm.settings.messageClass).css ('display', 'none').addClass ('message').html ('').map (function () {
					existingMessageElementIds.push ($(this).attr ('id'));	// record the element for later
				});

				// hide any "please wait" elements to begin with
				$ajaxForm.find ('.' + $.core.ajaxForm.settings.pleaseWaitClass).hide ();

//alert (var_dump (existingMessageElementIds));

				// find the submit buttons and observe their clicks,  so that we can add which element "submitted" the form to the ajax request
//				$ajaxForm.find (':submit,input[type=image]').testDataFail ('ajaxForm_submitInit', true, true).bind ('click.core-ajaxForm', function (event) {
				$ajaxForm.find (':submit,input[type=image]').bind ('click.core-ajaxForm', function (event) {
					submittedBy = unconvert_id ($(this).attr ('id'), popoverUidForConvertId);
				});

				// add a "hidden" input button that is activated (pressed) when the user submits the form by pressing enter (instead of the normal first input[type=submit]/button[type=submit])
				$ajaxForm.prepend ('<input type="submit" value="" class="core-hiddenSubmit" />');

				// observe the form submissions so that they can be handled via ajax instead of submitting normally
//				$ajaxForm.testDataFail ('ajaxForm_init', true, true).bind ('submit.core-ajaxForm', (function () {
				$ajaxForm.bind ('submit.core-ajaxForm', function (e, forceDefaultSubmit) {

					// when the form is submitted to an iframe,  the normal submit event must occur,  so don't override it in this case
					if (forceDefaultSubmit == true)
						return true;

					// override the default form submit event
					e.preventDefault ();	// prevent the normal form submission
					api.submit ();	// submit the form via ajax
				});

				return api;
			},

			// set the form's popover uid
			setPopoverUid: function (uid, forConvert) {
				popoverUid = uid;
				popoverUidForConvertId = (forConvert !== false ? uid : null);	// used when converting dom element ids
				return api;
			},

			// set the ajaxForm's ifhKey
			setIfhKey: function (tempIfhKey) {
				ifhKey = tempIfhKey;
				return api;
			},

			// set the ajaxForm's ifhPage
			setIfhPage: function (tempIfhPage) {
				ifhPage = tempIfhPage;
				return api;
			},

			// submit the ajax form
			submit: function () {

				// if the submitter hasn't been set then find the first submit element in the form and use that
				if (submittedBy === null)
					submittedBy = unconvert_id ($ajaxForm.find (':submit:first,input[type=image]:first').first ().attr ('id'), popoverUidForConvertId);
				var lastSubmitter = unconvert_id ($ajaxForm.find (':submit:last,input[type=image]:last').first ().attr ('id'), popoverUidForConvertId);

//				var lastFocusId = $ajaxForm.find (':focus').attr ('id');
//				var lastFocusName = $ajaxForm.find (':focus').attr ('name');

				// show this form's "please wait" blocks
				$ajaxForm.find ('.' + $.core.ajaxForm.settings.pleaseWaitClass).fadeIn (500);



				// work out which method to use
				var method = $ajaxForm.attr ('method');
				if (method == '')
					method = 'get';

				// generate the paramaters
				var params = $ajaxForm.serializeArray ();
/**
				params.push ({ name: 'submittedBy', value: submittedBy });	// tell the server which element submitted the form
				params.push ({ name: 'formAction', value: 'submit' });		// tell the server that the form is being submitted (as opposed to eg. going forward/back pages in the form)
				params.push ({ name: 'ifhKey', value: ifhKey });			// tell the server the ajaxForm's ifhKey
				params.push ({ name: 'ifhPage', value: ifhPage });			// tell the server the ajaxForm's ifhPage
/**/
				var extraParams = [];
				extraParams.push ({ name: 'submittedBy', value: submittedBy });			// tell the server which element submitted the form
				extraParams.push ({ name: 'lastSubmitter', value: lastSubmitter });		// tell the server what the last submit button is
				if (lastFocusId)
					extraParams.push ({ name: 'lastFocusId', value: lastFocusId });		// tell the server which element was last focused (useful to work out if the user was focused on a particular field and pressed enter instead of clicking the submit button)
				if (lastFocusName)
					extraParams.push ({ name: 'lastFocusName', value: lastFocusName });	// tell the server which element was last focused (useful to work out if the user was focused on a particular field and pressed enter instead of clicking the submit button)
				extraParams.push ({ name: 'formAction', value: 'submit' });				// tell the server that the form is being submitted (as opposed to eg. going forward/back pages in the form)
				if (ifhKey)
					extraParams.push ({ name: 'ifhKey', value: ifhKey });				// tell the server the ajaxForm's ifhKey
				if (ifhPage)
					extraParams.push ({ name: 'ifhPage', value: ifhPage });				// tell the server the ajaxForm's ifhPage
				if (popoverUid)
					extraParams.push ({ name: 'popoverUid', value: popoverUid });		// tell the server the ajaxForm's popover's uid

				for (var count = 0; count < extraParams.length; count++)
					params.push (extraParams[count]);

				submittedBy = null;	// reset the submitter for next time




				// if the form contains a file input,  submit the form to a hidden iframe
				if (($ajaxForm.find ('input[type=file]').length > 0)) {

					// if the iframe already exists,  remove it and start again
					if (lastIframeId !== null)
						$('#' + $.core.ajaxForm.settings.iframeDomIdPrefix + lastIframeId).remove ();

					// create the new iframe and attach it to the dom
					var iframeId = lastIframeId = Math.random ().toString ().slice (10);
//					$('body').append ('<iframe id="' + $.core.ajaxForm.settings.iframeDomIdPrefix + iframeId + '" name="' + $.core.ajaxForm.settings.iframeDomIdPrefix + iframeId + '" src="about:blank" onLoad="$.getAjaxFormApi (' + uid + ').processIframeResponse (' + iframeId + ');" style="display: none;"></iframe>');
					var $iframe = $('<iframe id="' + $.core.ajaxForm.settings.iframeDomIdPrefix + iframeId + '" name="' + $.core.ajaxForm.settings.iframeDomIdPrefix + iframeId + '" src="about:blank" onLoad="$(this).data (\'ajaxFormApi\').processIframeResponse ($(this));" style="display: none;"></iframe>');
					$iframe.data ('ajaxFormApi', api);
					$('body').append ($iframe);




					// update the form that is going to be submitted,  so that it submits to the iframe
//					$ajaxForm.attr ('action', );
					$ajaxForm.attr ('target', $.core.ajaxForm.settings.iframeDomIdPrefix + iframeId);
					$ajaxForm.attr ('method', method);
					$ajaxForm.attr ('enctype', 'multipart/form-data');	// firefox
					$ajaxForm.attr ('encoding', 'multipart/form-data');	// internet explorer




					// add hidden fields to the form
					$.each (
					$.merge ($.merge ([], extraParams), [{ name: 'httpSource', value: 'iframe' }]),	// all the extraParams plus add the 'httpSource' input
					function (index, value) {
						var $input = $ajaxForm.find ('input[name=' + value.name + ']');

						// if the input exists
						if ($input.length) {
							// set the input's value
							if (value !== null)
								$input.val (value.value);
							// or remove it if required
							else
								$input.remove ();
						}
						// or create the new input
						else
							$ajaxForm.prepend ('<input type="hidden" name="' + htmlentities (value.name) + '" value="' + htmlentities (value.value) + '" />');
					});



					// trigger the submit event,  and force it to run the real submit event without it being prevented
					$ajaxForm.trigger ('submit', [true]);

				}

				// submit the form via ajax
				else {

					// perform the ajax call
					$.ajax ({
						url: $ajaxForm.attr ('action'),
						type: method,
						data: params,
						complete: submissionComplete,
						success: api.processJsonResponse
					});
				}

				return true;
			},

			processIframeResponse: function ($iframe) {
//			processIframeResponse: function (iframeId) {

				// find the iframe
//				var $iframe = $('#' + $.core.ajaxForm.settings.iframeDomIdPrefix + iframeId);
//				if (!$iframe.length)
//					return false;

				$iframe = $($iframe);

				// get access to the content of the iframe
				if ($iframe.contentDocument)
					var d = $iframe.contentDocument;
				else if ($iframe.contentWindow)
					var d = $iframe.contentWindow.document;
				else
					var d = window.frames[$iframe.attr ('id')].document;
//					var d = window.frames[$.core.ajaxForm.settings.iframeDomIdPrefix + iframeId].document;

				// the "onLoad" event may be triggered when the iframe is created (eg. in chrome),  as well as when the iframe's content is loaded upon submitting the form to it
				// so make sure the iframe content has been loaded before trying to process it's response
				if ((!d) || (d.location.href == 'about:blank'))
					return false;

				submissionComplete ();

//				alert ('processing iframe response: ' + d.location.href);

				var $input = $('#jsonResponse', d);
				if ($input.length > 0) {
					api.processJsonResponse ($.parseJSON ($input.text ()));
					return true;
				}
				return false;
			},

			// replace the contents of the contentBox in this popover
			replaceIfhBlock: function (html, ifhKey, ifhPage) {

				$ifhBlock = $ajaxForm.closest ('.' + $.core.ajaxForm.settings.ifhBlockClass);
				if (!$ifhBlock.length)
					$ifhBlock = $ajaxForm;
				if ($ifhBlock.length) {

					// replace the ifh block with the new content (if new content was specified)
					if (html !== null) {

						var $newIfhBlock = $('<div class="' + $.core.ajaxForm.settings.ifhBlockClass + '">' + html + '</div>');

						// find elements with an id and convert them
						$newIfhBlock.find ('[id^=]').attr ('id', function (index, orig) { return convert_id (orig, popoverUidForConvertId); });
						// find the elements with a "for" and convert them
						$newIfhBlock.find ('[for^=]').attr ('for', function (index, orig) { return convert_id (orig, popoverUidForConvertId); });

						// replace the ifh block
						$ifhBlock.replaceWith ($newIfhBlock);

					}
					else
						var $newIfhBlock = $ifhBlock;

					// initialise any ajaxForms within the new block
					$newIfhBlock.find ('.' + $.core.ajaxForm.settings.ajaxFormClass).map (function () {
						$(this).ajaxForm ();	// now initialised via livequery but run anyway so that the ifhKey and ifhPage can be set below
						var api = $(this).data ('ajaxForm');
						if (api)
							api.setPopoverUid (popoverUid, popoverUidForConvertId == popoverUid).setIfhKey (ifhKey).setIfhPage (ifhPage);
					});
					return true;
				}
				return false;
			},

			// reverse the dialogue buttons if necessary
			applyDialogueButtonReverse: function () {

				if ($.core.reverseChildren)
					$ajaxForm.find ('.' + $.core.ajaxForm.settings.dialogueButtonsClass + '>div').reverseChildren ('dialogueButtons');

				return api;
			},

			// process the given json response,  carry out it's instructions
			processJsonResponse: function (response) {

				// if the response came back as an json object then process it
				if (typeof (response) == 'object') {

					var $popover = $();
					popoverApi = null;
					if (popoverUid) {
						$popover = $ajaxForm.closest ('.core-popover');
						popoverApi = $popover.data ('popover');
						if (!popoverApi)
							popoverApi = $popover.data ('popoverMini');
					}

					var popoverIsClosing = false;
					var redirectingUser = false;

					var messageIdsToAppearThisTime = [];	// record which messages are shown,  any others left over can be hidden
					var newMessages = [];					// record the actual messages to show,  used when working out if each message is the same or if it has changed (it will either pulsate,  or hide+change+show respectively)

					

					// loop through each instruction
					$(response).each (function (index, value) {
						switch (value[0]) {

							// eXecute (eval) "at start"
							case 'x1':
								api.eval (value[1]);
								break;
						}
					});

					// initial loop through each instruction
					$(response).each (function (index, value) {
						switch (value[0]) {

							// close popover (if applicable)
							case 'c':
								if ($popover.length) {
									// close with a delay
									if (value[1] !== undefined)
										popoverApi.closeDelayed (value[1]);
									// or close straight away
									else
										popoverApi.close ();
									popoverIsClosing = true;
								}
								break;

							// redirect user
							case 'r':
								document.location.href = value[1];
								redirectingUser = true;
								break;

							// reload the page
							case 'rl':
								window.location.reload ();
								redirectingUser = true;
								break;

							// display an nice error message to the user
							case 'error':

								// format the message nicely,  it may have been plain text or html
								var $message = $('<div/>').html (value[1]);
								if (!$message.find ('p').length)
									$message = $('<p/>').html (value[1]).wrap ($('<div></div>')).parent ();
								$message.find ('p:first').addClass ('core-spaceForCloseX core-first');
								$message.find ('p:last').addClass ('core-last');

								// show the message
								$.createPopover (
								{	content: $message.html (),
									customClass: 'core-popoverLargeFont' },
								{	template: 'generalNoTitle',
									baseAttachDirectionX: 0.5,
									popoverAttachDirectionX: 0.5,
									baseAttachDirectionY: 0.5,
									popoverAttachDirectionY: 0.5,
									applyMask: true,
									addCloseX: true,
									easyClose: true,
									fixed: true,
									group: 'error'
								});
								break;
						}
					});





					if ((!redirectingUser)) {

						// loop through each instruction
						$(response).each (function (index, value) {
							switch (value[0]) {

								// update ifh block
								case 'i':
									api.replaceIfhBlock (value[1], value[2], value[3]);
									break;

								// update content block
								case 'co':
									api.replaceIfhBlock (value[1], null, null);
									break;

								// update ifh key
								case 'k':
									api.setIfhKey (value[1]);
									break;

								// update ifh page
								case 'g':
									api.setIfhPage (value[1]);
									break;

								// update element inside the popover (update element/s found with the given selector with the new html)
								case 'p':
									if ($popover.length)
										$popover.find (value[1]).html (value[2]);
									break;
							}
						});

						// loop through each instruction
						$(response).each (function (index, value) {
							switch (value[0]) {

								// message
								case 'm':

									// check to see if the message element exists first.  if so then change the message
									if ($.inArray ('message_' + value[1], existingMessageElementIds) >= 0) {

										// update the message
										newMessages['message_' + value[1]] = value[2];

										messageIdsToAppearThisTime.push ('message_' + value[1]);
									}

									// or create a new message element
									else {
//alert ('#' + convert_id ('message_' + value[1], popoverUidForConvertId));
										// search for the message element directly via #message_fieldname
										var $messageElement = ($('#' + convert_id ('message_' + value[1], popoverUidForConvertId)));
										if ($messageElement.length)
											$messageElement.addClass ('message');
										// or try to create one somewhere
										else {

											// otherwise search for the surrounding .core-inFieldLabel element and insert the new message div before that
											var $insertBeforeElement = $('#' + convert_id (value[1], popoverUidForConvertId)).closest ('.' + $.core.inFieldLabel.settings.inFieldLabelClass);

											if (!$insertBeforeElement.length) {

												// otherwise search for the surrounding .core-messageGroup element and insert the new message div before that
												var $insertBeforeElement = $('#' + convert_id (value[1], popoverUidForConvertId)).closest ('.' + $.core.ajaxForm.settings.messageGroupingClass);
												if (!$insertBeforeElement.length) {

													// otherwise search for the relevant label and insert the new message div before that
													var $insertBeforeElement = $('label[for="' + convert_id (value[1], popoverUidForConvertId) + '"]');
													if (!$insertBeforeElement.length) {

														// otherwise use the input element and insert the new message div before that
														var $insertBeforeElement = $('#' + convert_id (value[1], popoverUidForConvertId));
													}
												}
											}

											// insert the message div
											if ($insertBeforeElement.length)
												$insertBeforeElement.before ('<div id="message_' + convert_id (value[1], popoverUidForConvertId) + '" class="message" style="display: none;"></div>');
										}


										if (($messageElement.length) || ($insertBeforeElement.length)) {
											newMessages['message_' + value[1]] = value[2];
											existingMessageElementIds.push ('message_' + value[1]);
											messageIdsToAppearThisTime.push ('message_' + value[1]);
										}
									}
									break;
							}
						});

						// loop through each instruction
						$(response).each (function (index, value) {
							switch (value[0]) {

								// focus field
								case 'f':
									$('#' + convert_id (value[1], popoverUidForConvertId)).focus ();
									break;

								// close popover selector
								case 'cps':
									if ($popover.length) {
										$popover.find (value[1]).bind ('click.core-popover-close', function () {
											popoverApi.close ();
										});
									}
									break;

								// update element
								case 'u':
									$(value[1]).html (value[2]);
									break;

								// replace element
								case 'rp':
									$(value[1]).replaceWith (value[2]);
									break;
							}
						});

						// loop through each instruction
						$(response).each (function (index, value) {
							switch (value[0]) {

								// eXecute (eval) "at end"
								case 'x2':
									api.eval (value[1]);
									break;
							}
						});
					}













					// only display/hide messages if..
					if ((!popoverIsClosing) && (!redirectingUser)) {

						// show / pulsate / hide messages

						// find out which messages to hide
						var messageIdsToHide = [];
						for (var count = 0; count < existingMessageElementIds.length; count++) {

							// if the message wasn't supposed to appear this time
							// and it was already visible..
							if (($.inArray (existingMessageElementIds[count], messageIdsToAppearThisTime) < 0) && ($.inArray (existingMessageElementIds[count], visibleMessageElementIds) >= 0)) {

								// then record that we have to hide it
								messageIdsToHide.push (existingMessageElementIds[count]);
							}
						}

						// work out if there are too many message elements that need showing/hiding,  if not then they can be animated
						var threshold = ($.browser.msie ? 25 : 50);	// lower threshold of 25 for ie,  50 for other browsers
						if (($.core.ajaxForm.settings.messageAnimations) && (messageIdsToAppearThisTime.length + messageIdsToHide.length <= threshold)) {

							// show/pulsate the messages that are supposed to appear
							for (var count = 0; count < messageIdsToAppearThisTime.length; count++) {

								if (newMessages[messageIdsToAppearThisTime[count]] !== undefined) {

									// if it's already visible,  pulsate it
									if ($.inArray (messageIdsToAppearThisTime[count], visibleMessageElementIds) >= 0) {

										// if the message is the same then pulsate it
										// or if the browser is ie (because the html gets changed when applied to the dom so it can't be directly compared to the original html)
										if ((!$.browser.msie) && (newMessages[messageIdsToAppearThisTime[count]] == $('#' + convert_id (messageIdsToAppearThisTime[count], popoverUidForConvertId)).html ()))
											$('#' + convert_id (messageIdsToAppearThisTime[count], popoverUidForConvertId)).html (newMessages[messageIdsToAppearThisTime[count]]).effect ('pulsate', { times: 2 }, 800);

										// otherwise hide it,  and show the new message
										else {
											// hide the existing message
											$('#' + convert_id (messageIdsToAppearThisTime[count], popoverUidForConvertId)).hide ('blind').map (

												// change the message and then show it again
												function () { 
													setTimeout (
														(function (messageElement, messageHtml) {
															return function () { ($(messageElement).html (messageHtml).show ('blind')) }
														})
													(this, newMessages[messageIdsToAppearThisTime[count]]), 300);
												}
											);
										}

										// record that this message is visible
//										visibleMessageElementIds.push (messageIdsToAppearThisTime[count]);

									}
									// otherwise simply make it appear
									else {

										$('#' + convert_id (messageIdsToAppearThisTime[count], popoverUidForConvertId)).html (newMessages[messageIdsToAppearThisTime[count]]).show ('blind');
										// record that this message is visible
										if ($.inArray (messageIdsToAppearThisTime[count], visibleMessageElementIds) < 0)
											visibleMessageElementIds.push (messageIdsToAppearThisTime[count]);
									}
								}
							}

							// hide the messages that are supposed to disappear
							for (var count = 0; count < messageIdsToHide.length; count++) {
								$('#' + convert_id (messageIdsToHide[count], popoverUidForConvertId)).hide ('blind');

								// remove this message from the list of visible messages
								visibleMessageElementIds.remove (messageIdsToHide[count]);
	//							visibleMessageElementIds = remove_from_array (messageIdsToHide[count], visibleMessageElementIds);
							}
						}

						// otherwise make them appear/disappear quickly
						else {

							// show the messages that are supposed to appear
							for (var count = 0; count < messageIdsToAppearThisTime.length; count++) {

								// if it's already visible,  (don't) pulsate it
								if ($.inArray (messageIdsToAppearThisTime[count], visibleMessageElementIds) >= 0)
									$('#' + convert_id (messageIdsToAppearThisTime[count], popoverUidForConvertId)).html (newMessages[messageIdsToAppearThisTime[count]]);
								// otherwise make it appear
								else
									$('#' + convert_id (messageIdsToAppearThisTime[count], popoverUidForConvertId)).html (newMessages[messageIdsToAppearThisTime[count]]).show ();
								// record that this message is visible
								if ($.inArray (messageIdsToAppearThisTime[count], visibleMessageElementIds) < 0)
									visibleMessageElementIds.push (messageIdsToAppearThisTime[count]);
							}

							// hide the messages that are supposed to disappear
							for (var count = 0; count < messageIdsToHide.length; count++) {
								$('#' + convert_id (messageIdsToHide[count], popoverUidForConvertId)).hide ();

								// remove this message from the list of visible messages
								visibleMessageElementIds.remove (messageIdsToHide[count]);
	//										visibleMessageElementIds = remove_from_array (messageIdsToHide[count], visibleMessageElementIds);
							}
						}

						// scroll to the first message if it's off the screen
						// make sure there's a message to scroll to and that $.scrollTo exists first
						if ((messageIdsToAppearThisTime.length) && ($.isFunction ($.fn.scrollTo))) {
							var $message = $('#' + messageIdsToAppearThisTime[0]);
							if ($message.length) {

								var extraWhiteSpace = 30;	// add a extra pixels around the message

								// determine the element's position
								var offset = $message.offset ();	// the offset to the top/left of the element

								// determine the element's dimensions
								var messageHeight = $message.outerHeight ();

								// find the bottom of the screen
								var pageBottom = $(window).scrollTop () + $(window).height ();

								// not too far down
								var need2Scroll = false;
								if (offset.top + messageHeight + extraWhiteSpace > pageBottom)
									need2Scroll = true;
								// not too far up
								if ((offset.top - extraWhiteSpace < $(window).scrollTop ()) && (offset.top - extraWhiteSpace > 0))
									need2Scroll = true;

								if (need2Scroll) {
									// scroll to the right point
									$.scrollTo ($message, 500, {
										easing: 'easeOutQuart',
										offset:
										{	left: 0,
											top: -extraWhiteSpace
										}
									});

								}
							}
						}
					}

					// reverse the dialogue buttons if necessary
					api.applyDialogueButtonReverse ();
				}
			},

			// eval the given code
			// has access to $ajaxForm and api
			eval: function (code) {
				(function (api) {
					eval (code);
				}) (api);
				return api;
			},

			// return the ajaxForm element
			getAjaxForm: function () {
				return $ajaxForm;
			},

			// manipulate start, finish and speeds
			getConf: function () {
				return conf;
			},

			// convert the given id (based on this popover's uid if applicable)
			convertId: function (orig) {
				return convert_id (orig, popoverUidForConvertId);
			}
		});

		// assign the callbacks
		$.each (['onBeforeLoad', 'onLoad', 'onBeforeSubmit', 'onAfterSubmit'], function (i, name) {

			// configuration
			if ($.isFunction (conf[name]))
				$ajaxForm.bind (name, conf[name]);

			// API
			$ajaxForm[name] = function (fn) {
				$ajaxForm.bind (name, fn);
				return $ajaxForm;
			};
		});
//$ajaxForm.css ('background-color', 'blue');




		// private functions

		// perform things that need to happen when the form submission is complete (whether it succeeded or not)
		var submissionComplete = function (response) {
			$ajaxForm.find ('.' + $.core.ajaxForm.settings.pleaseWaitClass).stop (true, true).hide ();	// hide the "please wait" elements
			return true;
		}






		// 
		api.init ();

		// record a reference to this ajax form internally
		$.core.ajaxForm.existingAjaxFormApis['id' + uid] = api;
	}
	
	// jQuery plugin initialisation
	$.fn.ajaxForm = function (conf) {

		if ($.isFunction (conf))
			conf = { onBeforeLoad: conf };

		// merge the caller's conf with the default conf
		conf = $.extend (true, {}, $.core.ajaxForm.conf, conf);

		// turn each selected element into an ajaxForm
		this.each (function () {

			var $this = $(this);

			// make sure this element is a form
			if ($this.is ('form')) {

				// only apply the ajaxForm to this element if it hasn't already been applied
				if (!$this.data ('ajaxForm')) {
					var api = new ajaxForm ($this, conf);	// turn this element into an ajaxForm
					$this.data ('ajaxForm', api);			// record the api within this element for later
				}
			}
		});

		return conf.api ? api: this;
	};
/**
	// get an ajax form based on it's internal uid
	$.getAjaxFormApi = function (uid) {

		if ($.core.ajaxForm.existingAjaxFormApis['id' + uid] != undefined)
			return $.core.ajaxForm.existingAjaxFormApis['id' + uid];
		return null;
	}
/**/
}) (jQuery);









/*////////////////////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/core/ajax_suggest/ajax_suggest-0.0.1.js //
// created: Mon, 26 Sep 2011 14:01:58 +1000                                 //
// modified: Wed, 31 Aug 2011 11:54:39 +1000                                //
// size: 14464 bytes                                                        //
////////////////////////////////////////////////////////////////////////////*/

(function($) {

	// if the current element is an input,
	// fetch suggestions when the user starts typing
	$.fn.coreAjaxSuggest = function (custConf) {

		var cachedSuggestions = {};	// cache for suggestions (shared between inputs initialised within this same request)

		var defaultConf = {
			url: null,
			type: 'get',
			extraParams: {},
			minChars: 1,				// the number of chars required before sending the request
			useCache: true,
			submitOnSelection: false,	// submit the form when enter is pressed or an option is clicked?
			onBeforeSend: null,			// callback to alter the ajax query string
			forceWidth: true			// force the width of the popover to be the same as the input field
		}

		var $this = $(this);
		$this.each (function () {
			var $input = $(this);
			var justChangedFromCursorNavigation = false;

			// make sure this is a text input field
			if (!$input.is ('input[type=text]'))
				return true;

			var conf = $.extend (true, {}, defaultConf, custConf);

			(function () {

				var myTimeout = null;
				var showingSuggestions = false;
				var requestingSuggestions = false;
				var lastValueSent = null;
				var popoverApi = null;

				// load suggestions from the server
				var getSuggestions = function () {

					if (justChangedFromCursorNavigation) {
						justChangedFromCursorNavigation = false;
						return;
					}

					// provided the input is different to the last set of suggestions
					// requestingSuggestions is used because multiple events can be triggered at once to send the request,  this will stop a second one from happening straight away
					var newValue = $input.val ();
					if (((newValue != lastValueSent) || (!showingSuggestions)) && (!requestingSuggestions)) {
						lastValueSent = newValue;	// remember the latest string that suggestions were fetched for

						// send the request for some suggestions
						if (newValue.length >= conf.minChars) {

							// use a cached version
							if (cachedSuggestions[newValue] !== undefined)
								applySuggestions (cachedSuggestions[newValue]);

							// or send the request to the server
							else {

								// call the callback
								var extraParams = conf.extraParams;
								if ($.isFunction (conf.onBeforeSend))
									extraParams = conf.onBeforeSend.apply (this, [ extraParams ]);

								requestingSuggestions = true;

								var parameters = [];
								$.each (extraParams, function (name, value) {
									parameters.push ({ name: name, value: value });
								});
								parameters.push ({ name: 'term', value: newValue });

								$.ajax ({
									url: conf.url,
									type: conf.type,
									data: parameters,
									dataType: 'json',
									complete: function () { setTimeout (function () { requestingSuggestions = false; }, 100); },
									success: function (response) {
										// show the suggestions
										if ((response[0][0] == 'suggestions') || (response[0][0] == 'suggestionsMulti')) {
											if (conf.useCache)
												cachedSuggestions[newValue] = response;
											applySuggestions (response);
										}
									}
								});
							}
						}
						// hide the popover if there are 0 suggestions
						else {
							if ((popoverApi != null) && (popoverApi.isOpened ()))
								popoverApi.close ();
						}
					}
				};

				// take the given suggestions and show/hide the popover
				var applySuggestions = function (response) {

					var suggestionListsHtml = [];
					if (response[0][0] == 'suggestionsMulti') {
						$.each (response[0][1], function (index, value) {
							var html = buildSuggestionListHtml (value.title, value.list);
							if (html.length)
								suggestionListsHtml.push (html);
						});
					}
					else if (response[0][0] == 'suggestions') {
						var html = buildSuggestionListHtml (null, response[0][1]);
						if (html.length)
							suggestionListsHtml.push (html);
					}

					// show the popover if there are some suggestions
					if (suggestionListsHtml.length) {

						var html = suggestionListsHtml.join ('') + '<div class="contentEnd"></div>';

						// show the popover
						if ((popoverApi != null) && (showingSuggestions)) {
							popoverApi.replaceContentBoxHtml (html);	// show the new suggestions

							var $popover = popoverApi.getPopover ();
							applyWidthLogic ($popover);
							applySelectionLogic ($popover);
						}
						else {
							// close any other suggestion popovers before making this one appear
							var otherPopoverApis = $('.core-ajaxSuggestPopover');
							if (otherPopoverApis.length > 0)
								otherPopoverApis.data ('popover').close ();

							// show the new popover
							showingSuggestions = true;
							var width = null;
							if (conf.forceWidth)
								var width = $input.outerWidth ();
							popoverApi = $.createPopover (
							{	content: html,
								customClass: 'core-ajaxSuggestPopover'
							},
							{	template: 'basicNoTitle',
								effect: 'blind',
								attachTo: $input,
								baseAttachDirectionX: 'left',
								popoverAttachDirectionX: 'left',
								baseAttachDirectionY: 'bottom',
								popoverAttachDirectionY: 'top',
								attachOffsetX: 0,
								attachOffsetY: -1,
								width: width,
								applyMask: false,
								easyClose: true,
								closeSpeed: 'fast',
								startOnScreen: false,
								onBeforeClose: function () {
									showingSuggestions = false;
									removeSelectionLogic ();	// let the up/down/enter keys act normally again
								},
								onBeforePosition: function () {
									applyWidthLogic ($(this));
									applySelectionLogic ($(this));
								}
							}).data ('popover');
						}
					}
					// hide the popover if there are 0 suggestions
					else {
						if ((popoverApi != null) && (popoverApi.isOpened ()))
							popoverApi.close ();
					}
				};

				// build the content for the popover
				var buildSuggestionListHtml = function (title, suggestions) {
					var html = '';
					// only create this list if it has values
					if (suggestions.length) {
						var titleHtml = '';
						if (title)
							titleHtml = '<h3>' + ($('<div/>').text (title).html ()) + '</h3>';

						var listHtml = '';
						$.each (suggestions, function (index, value) {
							listHtml += '<li>' + value + '</li>'
						});

						html += '<div class="core-ajaxSuggest">' + titleHtml + '<ul>' + listHtml + '</ul></div>';
					}
					return html;
				};

				// set the width of each div containing a suggestion list
				var applyWidthLogic = function ($popover) {
					if (!conf.forceWidth) {
						var $body = $('body');
						var $divs = $popover.find ('div.core-ajaxSuggest');
						$.each ($divs, function (index, value) {

							var $div = $(value).css ('float', 'left');
							var $temp = $div.clone ();
							$body.append ($temp);

							// check to see if the div is bigger than the space being shown (ie. it can scroll)
							var currentHeight = $temp.height ();
							$temp.css ('max-height', (currentHeight + 1) + 'px');
							if (currentHeight != $temp.height ())
								$div.width ($temp.width () + 20);	// add in some space for the vertical scroll bar

							$temp.remove ();
						});
					}
					return true;
				};

				// add logic to the element so that items are highlighted when hovered over, up/down/enter works etc
				var applySelectionLogic = function ($popover) {

					// update the input value upon click
					var $ul = $popover.find ('ul');
					var $allLi = $ul.find ('>li');

					$allLi.bind ('click.core-ajaxSuggest', function () {
						$input.val ($(this).text ());
						popoverApi.close ();
						if (conf.submitOnSelection)
							$input.closest ('form').submit ();
					})
					// make the li's highlight when hovered
					.bind ('mouseenter.core-ajaxSuggest', function () {
						var $li = $(this);
						$ul.find ('li').removeClass ('active');
						$li.addClass ('active');
					});

					// bind the up/down arrows to change the selected suggestion
					$(document).unbind ('keydown.core-ajaxSuggest')
					.bind ('keydown.core-ajaxSuggest', function (e) {

						// up/down
//						if ((e.keyCode == 38) || (e.keyCode == 40)) {
						if ($.inArray (e.keyCode, [38, 40]) >= 0) {
							e.preventDefault ();	// stop the form from being submitted
							var $li = $ul.find ('li.active');
							if (e.keyCode == 38) {	// up

								var $newLi = $li.prev ();	// find the (previous li) to the (currently active li)
								if (!$newLi.length) {

									// try to find the next ul in the list
									$li.parent ('ul').addClass ('core-temp');
									var $prevUl = null;
									$.each ($ul, function () {
										if ($(this).hasClass ('core-temp'))
											return false;
										$prevUl = $(this);
									});
									$ul.removeClass ('core-temp');
									if ($prevUl !== null)
										$newLi = $prevUl.find ('li').last ();	// find the (last li) on the prev ul
								}

								var $initialLi = $ul.last ().find ('li').last ();	// find the (last li)
							}
							else if (e.keyCode == 40) {	// down

								var $newLi = $li.next ();	// find the (next li) to the (currently active li)
								if (!$newLi.length) {

									// try to find the previous ul in the list
									$li.parent ('ul').addClass ('core-temp');
									var found = false;
									var $nextUl = null;
									$.each ($ul, function () {
										if (found) {
											$nextUl = $(this);
											return false;
										}
										if ($(this).hasClass ('core-temp'))
											found = true;
									});
									$ul.removeClass ('core-temp');
									if ($nextUl !== null)
										$newLi = $nextUl.find ('li').first ();	// find the (first li) on the next ul
								}

								var $initialLi = $ul.first ().find ('li').first ();	// find the (first li)
							}

							$ul.find ('li').removeClass ('active');

							var $scrollTo = null;
							if ($newLi.length) {
								$scrollTo = $newLi.addClass ('active');
								$input.val ($newLi.text ());	// change the text in the input field
								justChangedFromCursorNavigation = true;
							}
							else if (!$li.length) {
								$scrollTo = $initialLi.addClass ('active');
								$input.val ($initialLi.text ());	// change the text in the input field
								justChangedFromCursorNavigation = true;
							}

							if ($scrollTo !== null) {
								var $currentDiv = $scrollTo.closest ('div.core-ajaxSuggest');
								var divHeight = $currentDiv.height ();
								var liHeight = $scrollTo.height ();
								var topOfDiv = $currentDiv.offset ().top;
								var topOfLi = $scrollTo.offset ().top;
								var bottomOfDiv = topOfDiv + divHeight;
								var bottomOfLi = topOfLi + liHeight;

								// if the (active li) is above the viewing area
								if (topOfLi < topOfDiv) {
									$currentDiv.scrollTo (0);
									topOfLi = $scrollTo.offset ().top;
									$currentDiv.scrollTo (topOfLi - topOfDiv);
								}
								// if the (active li) is below the viewing area
								else if (bottomOfLi >= bottomOfDiv) {
//									alert (topOfLi + ' < ' + topOfDiv + ', ' + bottomOfLi + ' >= ' + bottomOfDiv);
									$currentDiv.scrollTo (0);
									topOfLi = $scrollTo.offset ().top;
									$currentDiv.scrollTo (topOfLi - topOfDiv - divHeight + liHeight);
								}
							}
						}
						// enter
						else if (e.keyCode == 13) {
							// use this suggestion
							var $li = $ul.find ('li.active').first ();
							if ($li.length) {
								if (!conf.submitOnSelection)
									e.preventDefault ();	// stop the form from being submitted
								$input.val ($li.text ());
								popoverApi.close ();
							}
						}
						// esc
//						else if (e.keyCode == 27)
//							popoverApi.close ();
						// any other key - un-highlight the selected one so that when you press enter,  it doesn't choose the selected item
						else if ($.inArray (e.keyCode, [37, 38, 39, 40]) == -1)	// not: left, up, right, down
							$ul.find ('li').removeClass ('active');
					});
				};

				// let the up/down/enter keys act normally again
				var removeSelectionLogic = function () {

					// bind the up/down arrows to change the selected suggestion
					$(document).unbind ('keydown.core-ajaxSuggest');
				};





				// trigger the request for suggestions when things happen to the input field
				$input.bind ('keyup.core-ajaxSuggest', function (e) {
					if ($.inArray (e.keyCode, [37, 38, 39, 40]) == -1) {	// not: left, up, right, down
						clearTimeout (myTimeout);
						if (cachedSuggestions[$input.val ()] !== undefined)	// if the value has been cached then show it straight away
							getSuggestions ();
						else	// otherwise wait a moment before sending an ajax request (so the server doesn't get flooded upon every key press)
							myTimeout = setTimeout (getSuggestions, 300);
					}
				});
				$input.bind ('focus.core-ajaxSuggest click.core-ajaxSuggest', function () {
					clearTimeout (myTimeout);
					getSuggestions ();
					return false;	// stop this event from bubbling
				});
/**
				// hide the suggestions
				$input.bind ('blur.core-ajaxSuggest', function () {
					// get this to run after (so that if the user is really clicking on a suggestion,  that will register first before this blur event,  needs to be greater than 1 for IE)
					setTimeout (function () {
						clearTimeout (myTimeout);
						if ((popoverApi != null) && (popoverApi.isOpened ()))
							popoverApi.close ();
					}, 50);
				});
/**/
				// try to make sure the browser doesn't show it's own suggestions
				$input.attr ({ 'spellcheck': 'false', 'autocomplete': 'off' });
			}) ();
		});

		return $this;
	};

}) (jQuery);









/*//////////////////////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/core/ajax_response/ajax_response-0.0.1.js //
// created: Mon, 26 Sep 2011 14:01:58 +1000                                   //
// modified: Wed, 31 Aug 2011 11:54:39 +1000                                  //
// size: 2463 bytes                                                           //
//////////////////////////////////////////////////////////////////////////////*/

(function($) {

	// static constructs
	$.core = $.core || { version: '0.0.1' };

	$.core.processAjaxResponse = function (response) {

		// if the response came back as an json object then process it
		if (typeof (response) == 'object') {

			var redirectingUser = false;

			// loop through each instruction
			$(response).each (function (index, value) {
				switch (value[0]) {

					// eXecute (eval) "at start"
					case 'x1':
						(function () {
							eval (value[1]);
						}) ();
						break;
				}
			});

			// initial loop through each instruction
			$(response).each (function (index, value) {
				switch (value[0]) {

					// redirect user
					case 'r':
						document.location.href = value[1];
						redirectingUser = true;
						break;

					// reload the page
					case 'rl':
						window.location.reload ();
						redirectingUser = true;
						break;
				}
			});





			if ((!redirectingUser)) {

				// loop through each instruction
				$(response).each (function (index, value) {
					switch (value[0]) {

						// focus field
						case 'f':
							$('#' + value[1]).focus ();
							break;

						// update element
						case 'u':
							$(value[1]).html (value[2]);
							break;

						// replace element
						case 'rp':
							$(value[1]).replaceWith (value[2]);
							break;
					}
				});

				// loop through each instruction
				$(response).each (function (index, value) {
					switch (value[0]) {

						// eXecute (eval) "at end"
						case 'x2':
							(function () {
								eval (value[1]);
							}) ();
							break;
					}
				});
			}
		}
	}

}) (jQuery);










/*////////////////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/core/auto_align/auto_align-0.0.1.js //
// created: Mon, 26 Sep 2011 14:01:58 +1000                             //
// modified: Wed, 31 Aug 2011 11:54:39 +1000                            //
// size: 6564 bytes                                                     //
////////////////////////////////////////////////////////////////////////*/

jQuery.fn.autoAlign = function (conf) {
	var $this = $(this);

	// default values
	defaultConf = {
//		beforeMatch: null,
//		afterMatch: null
	};
	var myConf = $.extend (true, {}, defaultConf, conf);

	// loop through each of the current elements
	$this.each (function () {

		(function ($element, myConf) {
			$element = $($element);

			if ($element.is ('dl')) {
				var $dt = $element.find ('dt');
				var $dd = $element.find ('dd');

				// the dt elements
				var maxWidth = null;
				$dt.each (function () {
					$(this).css ({ width: 'auto' });
					if ((maxWidth === null) || ($(this).width () > maxWidth))
						maxWidth = $(this).width ();
				});
				$dt.width (maxWidth);

				// the dd elements
				var maxWidth = null;
				$dd.each (function () {
					$(this).css ({ width: 'auto' });
					if ((maxWidth === null) || ($(this).width () > maxWidth))
						maxWidth = $(this).width ();
				});
				$dd.width (maxWidth);
			}

		}) ($(this), myConf);
	});

	return $(this);
};

// match the given element's heights,  use the max height
jQuery.fn.autoMatchHeight = function (conf) {

	// default 
	defaultConf = {
//		beforeMatch: null,
//		afterMatch: null
	};
	var myConf = $.extend (true, {}, defaultConf, conf);

	(function ($elements, myConf) {
		var $elements = $($elements);

		// a function to match the elements
		var match = function () {

			// callback before matching
//			if ($.isFunction (myConf.beforeMatch))
//				myConf.beforeMatch ();

			// match the elements
			var max = null;
			$elements.each (function () {
				$(this).css ({ height: 'auto' });
				var currentHeight = $(this).outerHeight ();
				if ((max === null) || (currentHeight > max))
					max = currentHeight;
			});
			$elements.outerHeight (max);

			// callback after matching
//			if ($.isFunction (myConf.afterMatch))
//				myConf.afterMatch ();
		}

		match ();
//		$().ready (match);
		$elements.find ('img').load (match);

	}) ($(this), myConf);

	return $(this);
};

// align the given elements into columns
jQuery.fn.columnAlign = function (conf) {

	// default 
	defaultConf = {
		maxColumns: 20
//		beforeMatch: null,
//		afterMatch: null
	};
	var myConf = $.extend (true, {}, defaultConf, conf);

	var $elements = $(this);

	// a function to match the elements
	var tryColumns = function ($myElements, columns) {

		// if there aren't enough cels to fill the desired columns then return here
		if ($myElements.length < columns)
			return false;

		$myElements.css ({ width: 'auto', clear: 'both', display: 'block', float: 'left' });

		// find the widest cell in each column
		var maxWidths = [];
		var count = 0;
		$myElements.each (function () {
//			alert ($(this).width () + $(this).html ());
			if ((maxWidths[count % columns] == undefined) || ($(this).width () > maxWidths[count % columns]))
				maxWidths[count % columns] = $(this).width ();
			count++;
		});

		// set each cell to the width of the widest one in it's column
		count = 0;
		$myElements.each (function () {
			$(this).css ('clear', (count % columns == 0 ? 'left' : 'none'));
			$(this).width (maxWidths[count % columns]);
//$(this).attr ('title', 'width: ' + maxWidths[count % columns]);
			count++;
		});

		// work out if any cells wrapped
		var overflowed = false;
		if (columns > 1) {	// can only overflow if there's more than one column
			var topOffsets = [];
			count = 0;
			$myElements.each (function () {
				// if any cells on the current row are actually further down than the others,  then it has wrapped
				var rowNumber = Math.floor (count / columns);
				var offsetTop = $(this).offset ().top;
//$(this).attr ('title', 'offset top: ' + offsetTop);
				if (topOffsets[rowNumber] == undefined)
					topOffsets[rowNumber] = offsetTop;
				else if (offsetTop != topOffsets[rowNumber]) {
					overflowed = true;
					return false;
				}
				count++;
			});
		}

//		alert (columns + ' ' + overflowed);
//if (columns == 4)
//	alert (aaa);

		return !overflowed;
	}

	// a function to match the elements
	var alignColumns = function () {

		// callback before matching
//		if ($.isFunction (myConf.beforeMatch))
//			myConf.beforeMatch ();


		// loop through each element and align it's children into columns
		$elements.each (function () {

			var $myElement = $(this);

			// show any hidden parents (that are actually hidden with display=none) so that the button is visible when taking measurements.  they are re-hidden below
			var $hiddenParents = $myElement.parents (':hidden').filter (function () {
				return $(this).css ('display') == 'none';
			});
			$hiddenParents.show ();

			// keep on trying columns (1 col, 2 cols, 3 cols etc) until we find that they start wrapping
			var columns = 1;	// start with 2 columns
			do {
				columns++;
			}
			while ((tryColumns ($myElement.children (), columns)) && (columns < myConf.maxColumns));

			// align the cells into the number of columns before they started wrapping
			tryColumns ($myElement.children (), Math.max (1, columns - 1));

			$hiddenParents.hide ();
		});


		// callback after matching
//		if ($.isFunction (myConf.afterMatch))
//			myConf.afterMatch ();
	}




	// make sure inputs have been transformed because this adjusts the width of the respective elements
/**
	if ($.core.transformInput != undefined) {
		$elements.find ('input[type=checkbox]:not(.core-ignoreTransformInput)').map (function () {
			$(this).coreTransformCheckbox ();
		});
		$elements.find ('input[type=radio]:not(.core-ignoreTransformInput)').map (function () {
			$(this).coreTransformRadio ();
		});
	}
/**/



//alert ('ya');
//return $(this);
	alignColumns ();
//	$().ready (alignColumns);
	$elements.find ('img').load (alignColumns);
/**/
	return $(this);
};









/*////////////////////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/core/checkbox_all/checkbox_all-0.0.1.js //
// created: Mon, 26 Sep 2011 14:01:58 +1000                                 //
// modified: Wed, 31 Aug 2011 11:54:39 +1000                                //
// size: 3812 bytes                                                         //
////////////////////////////////////////////////////////////////////////////*/

(function($) {

	// for the given element,  apply the 'all' logic to checkboxes inside it.
	// if the 'all' checkbox is clicked,  the others are un-ticked and vice versa
	$.fn.coreCheckboxAll = function (custConf) {

		var defaultConf = {
			allOptions: ['all', '0', '']	// these are the checkbox input values that are considered to be 'all' options
		};

		$(this).each (function () {
			var $this = $(this);

			var conf = $.extend (true, {}, defaultConf, custConf);

			// divide the 'all' / 'normal' checboxes
			var $checkboxes = $this.find ('input[type=checkbox]');
			var $allCheckboxes = [];
			var $normalCheckboxes = [];
			$checkboxes.each (function () {
				var $checkbox = $(this);
				if ($.inArray ($checkbox.val (), conf.allOptions) >= 0)
					$allCheckboxes.push ($checkbox);
				else
					$normalCheckboxes.push ($checkbox);
			});

			// do something when things change
			var foundAnyChecked = false;
			$checkboxes.each (function () {
				var $checkbox = $(this);

				if ($checkbox.attr ('checked'))
					foundAnyChecked = true;

				$checkbox.bind ('change.core-checkboxAll', function () {

					// an 'all' checkbox
					if ($.inArray ($checkbox.val (), conf.allOptions) >= 0) {
						// keep the 'all' checkboxes checked
						$.each ($allCheckboxes, function (index, $checkbox) {
							$checkbox.attr ('checked', true).trigger ('customChange');
//							((!$checkbox.attr ('checked')) && ($checkbox.trigger ('click')));
						});
						// uncheck every 'normal' checkbox
						$.each ($normalCheckboxes, function (index, $checkbox) {
							$checkbox.attr ('checked', false).trigger ('customChange');
//							(($checkbox.attr ('checked')) && ($checkbox.trigger ('click')));
						});
					}
					else {
						// work out if none of the 'normal' checkboxes are checked
						var foundNormalChecked = false;
						$.each ($normalCheckboxes, function (index, $checkbox) {
							if ($checkbox.attr ('checked')) {
								foundNormalChecked = true;
								return false;
							}
						});
						if (foundNormalChecked) {
							// uncheck every 'all' checkbox
							$.each ($allCheckboxes, function (index, $checkbox) {
								$checkbox.attr ('checked', false).trigger ('customChange');
//								(($checkbox.attr ('checked')) && ($checkbox.trigger ('click')));
							});
						}
						else {
							// check every 'all' checkbox
							$.each ($allCheckboxes, function (index, $checkbox) {
								$checkbox.attr ('checked', true).trigger ('customChange');
//								((!$checkbox.attr ('checked')) && ($checkbox.trigger ('click')));
							});
						}
					}
				});
			});

			// initialise the checkboxes
			if (!foundAnyChecked) {
				// check every 'all' checkbox
				$.each ($allCheckboxes, function (index, $checkbox) {
					$checkbox.attr ('checked', true).trigger ('customChange');
//					((!$checkbox.attr ('checked')) && ($checkbox.trigger ('click')));
				});
			}
		});

		return $(this);
	};

}) (jQuery);









/*//////////////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/core/date_time/date_time-0.0.1.js //
// created: Mon, 26 Sep 2011 14:01:58 +1000                           //
// modified: Wed, 31 Aug 2011 11:54:39 +1000                          //
// size: 1540 bytes                                                   //
//////////////////////////////////////////////////////////////////////*/

(function(jQuery){

	// useful when applying available/not-available dates to a jquery.ui datepicker
	datePickerApplyDateList = function (dateList, includeThisList) {

		// return a function that will check if the given date is in/not in the date list
		return function (date) {
			var m = date.getMonth () + 1, d = date.getDate (), Y = date.getFullYear ();
			var currentDate = Y + '-' + m + '-' + d;
			if (((includeThisList) && ($.inArray (currentDate, dateList) >= 0))	// include the days from the list
			|| ((!includeThisList) && ($.inArray (currentDate, dateList) < 0)))	// or exclude the days from the list
				return [true];
			return [false];
		};
	};

}) (jQuery);









/*//////////////////////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/core/general_tools/general_tools-0.0.1.js //
// created: Mon, 26 Sep 2011 14:01:58 +1000                                   //
// modified: Wed, 31 Aug 2011 11:54:39 +1000                                  //
// size: 10233 bytes                                                          //
//////////////////////////////////////////////////////////////////////////////*/

// work out if the given element is an object
(function ($) {

	var toString = Object.prototype.toString,
	hasOwnProp = Object.prototype.hasOwnProperty;

	$.isObject = function (obj) {
		if (toString.call (obj) !== '[object Object]')
			return false;

		//own properties are iterated firstly,
		//so to speed up, we can test last one if it is not own

		var key;
		for (key in obj) {}

		return !key || hasOwnProp.call (obj, key);
	}

}) (jQuery);

// check to see if the given value is an integer
function is_int (value) { 
	if ((value === undefined) || (value === null))
		return false;
	return ((typeof (value) == 'number') || ((!isNaN (parseInt (value * 1))) && (value.length > 0)));
}

// check to see if the given value is a float
function is_float (value) {
	if ((value === undefined) || (value === null))
		return false;
//	value == parseFloat (value)
	return ((typeof (value) == 'number') || ((!isNaN (parseFloat (value * 1))) && (value.length > 0)));
}


























Array.prototype.remove = function (needle, removeAllInstances) {
	if (removeAllInstances === undefined)
		removeAllInstances = true;
	do {
		var arrayPos = $.inArray (needle, this);
		if (arrayPos >= 0)
			this.splice (arrayPos, 1);
	}
	while ((arrayPos >= 0) && (removeAllInstances));
	return this;
};


/**
// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

// Array Remove - By John Resig (MIT Licensed)
Array.remove = function(array, from, to) {
  var rest = array.slice((to || from) + 1 || array.length);
  array.length = from < 0 ? array.length + from : from;
  return array.push.apply(array, rest);
};
/**/










// repeat the string x number of times
String.prototype.repeat = function (repetitions) {
	return new Array (repetitions + 1).join (this);
}

// check to see if the string ends with the given string
String.prototype.endsWith = function (string) {
	return (this.substr (Math.max (0, this.length - string.length)) == string);
}

function htmlentities (value) {
	if ((value !== undefined) && (value !== null)) {
		if ($.browser.msie)	// do some extra work for ie to maintain the \n characters (msie loses them)
			return jQuery ('<div/>').text (value.replace ('\\', '\\\\').replace ('\n', '\\n')).html ().replace ('\\n', '\n').replace ('\\\\', '\\').replace ('"', '&quot;');
		return jQuery ('<div/>').text (value).html ().replace ('"', '&quot;');
	}
	return '';
}

function html_entity_decode (value) {
	if (value !== undefined)
		return jQuery ('<div/>').html (value).text ();
	return '';
}

function addslashes (str) {  
	// Escapes single quote, double quotes and backslash characters in a string with backslashes    
	//   
	// version: 810.114  
	// discuss at: http://phpjs.org/functions/addslashes  
	// +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)  
	// +   improved by: Ates Goral (http://magnetiq.com)  
	// +   improved by: marrtins  
	// +   improved by: Nate  
	// +   improved by: Onno Marsman  
	// *     example 1: addslashes("kevin's birthday");  
	// *     returns 1: 'kevin\'s birthday'  
	return (str+'').replace(/([\\"'])/g, "\\$1").replace(/\0/g, "\\0");  
}

// chop the given string to the given length and add .. to it
str_chop = function (string, length, position, textToAppend, trimResult) {

	// default values
	if (position === undefined)
		position = 'end';
	if (textToAppend === undefined)
		textToAppend = '..';
	if (trimResult === undefined)
		trimResult = true;

	// not too big
	if (string.length <= length)
		return string

	// return with result trimmed
	if (trimResult) {
		if (position == 'start')
			return textToAppend + jQuery.trim (string.substr (0, length));

		else if ((position == 'middle') || (position == 'center')) {
			var lengthStart = length / 2;
			var lengthEnd = length - lengthStart;
			return jQuery.trim (string.substr (0, lengthStart)) + textToAppend + jQuery.trim (string.substr ((string.length - lengthEnd), lengthEnd));
		}

		// end (default)
		return jQuery.trim (string.substr (0, length)) + textToAppend;
	}

	// no trim
	if (position == 'start')
		return textToAppend + string.substr (0, length);

	else if ((position == 'middle') || (position == 'center')) {
		var lengthStart = length / 2;
		var lengthEnd = length - lengthStart;
		return string.substr (0, lengthStart) + textToAppend + string.substr ((string.length - lengthEnd), lengthEnd);
	}

	// end (default)
	return string.substr (0, length) + textToAppend;
}

function nl2br (str, is_xhtml) {
	// Converts newlines to HTML line breaks  
	// 
	// version: 1008.1718
	// discuss at: http://phpjs.org/functions/nl2br
	// +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	// +   improved by: Philip Peterson
	// +   improved by: Onno Marsman
	// +   improved by: Atli Þór
	// +   bugfixed by: Onno Marsman
	// +      input by: Brett Zamir (http://brett-zamir.me)
	// +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	// +   improved by: Brett Zamir (http://brett-zamir.me)
	// +   improved by: Maximusya
	// *     example 1: nl2br('Kevin\nvan\nZonneveld');
	// *     returns 1: 'Kevin\nvan\nZonneveld'
	// *     example 2: nl2br("\nOne\nTwo\n\nThree\n", false);
	// *     returns 2: '<br>\nOne<br>\nTwo<br>\n<br>\nThree<br>\n'
	// *     example 3: nl2br("\nOne\nTwo\n\nThree\n", true);
	// *     returns 3: '\nOne\nTwo\n\nThree\n'
	var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '' : '<br>';

	return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1'+ breakTag +'$2');
}

// convert new lines to paragraphs
function nl2p (str) {
	if ((str !== undefined) && (str !== null))
		return ('<p>' + ((jQuery.trim (str + '')).replace (/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1</p><p>$2')) + '</p>').replace (/<p>(\r\n|\n\r|\r|\n|\t| )*/g, '<p>').replace (/(\r\n|\n\r|\r|\n|\t| )*<\/p>/g, '</p>').replace (/<p><\/p>/g, '');
	return '';
}

// add the given suffix to the element id (provided it hasn't been added already)
convert_id = function (elementId, suffix) {
	if ((suffix != undefined) && (suffix != '')) {
		suffix = suffix.toString ();
		if (suffix) {
			// check to see if the suffix has already been added to this string
			if (elementId.substr (elementId.length - suffix.length, suffix.length) != suffix)
				return elementId + suffix;
		}
	}
	return elementId;
};

// remove the given suffix from the given element id
unconvert_id = function (elementId, suffix) {
	if ((suffix !== undefined) && (suffix !== null)) {
		suffix = suffix.toString ();
		if (suffix) {
//			if (elementId.indexOf (suffix, elementId.length - (suffix).length) >= 0)
			if (elementId.substr (elementId.length - suffix.length, suffix.length) == suffix) {
				return elementId.substr (0, elementId.length - suffix.length);
			}
		}
	}
	return elementId;
};

















// focus the current element after a delay
jQuery.fn.focusDelayed = function (delay) {
	var $this = $(this);
	if (!delay)	// default value
		delay = 450;

	setTimeout (function () {
		if ($.browser.msie)	// focus twice for ie.   it seems to not always focus with the first one but the second does the trick
			$this.focus ().focus ();
		else
			$this.focus ();
	}, delay);
}
/**
// return the contents of an object as a visual string
jQuery.fn.extend({
	serializeForm: function () {

		values = jQuery(this).serializeArray ();

		var temp = {};
		for (var index in values) {
			var name = values[index]['name'];
			if (name.endsWith ('[]')) {
				if (temp[name] === undefined)
					temp[name] = [];
				temp[name].push (values[index]['value']);
			}
			else
				temp[name] = values[index]['value'];
		}
		return temp;
	}
});
/**/

/**
// get jQuery to turn the cursor into a pointer when it hovers over an element with a click event
jQuery.event.special.mouseover = {
	setup: function() {
		$(this).css ('cursor','pointer');
		return false;
	},
	teardown: function() {
		$(this).css ('cursor','');
		return false;
	}
};
/**/


jQuery.extend(jQuery.expr[':'], {
    focus: function(e){
        try{ return e == document.activeElement; }
        catch(err){ return false; }
    }
});




















// eval the given code in this function for encapsulation
function encapsulated_eval (code) {
	eval (code);
	return true;
}
/**
// return the contents of an object as a visual string
var var_dump = function (object, depth) {

	if (!is_int (depth))
		depth = 0;

	var temp = [];

	// handle the top-level case of the value being an object or array
	if (!depth) {
		if ($.isArray (object)) {
			temp.push ('(Array)');
			depth += 1;
		}
		else if ($.isObject (object)) {
			temp.push ('(Object)');
			depth += 1;
		}
	}

	if (($.isArray (object)) || ($.isObject (object))) {
		for (var index in object) {
			if ($.isArray (object[index]))
				temp.push ('  '.repeat (depth) + index + ': (Array)' + "\n" + var_dump (object[index], depth + 1));
			else if ($.isObject (object[index]))
				temp.push ('  '.repeat (depth) + index + ': (Object)' + "\n" + var_dump (object[index], depth + 1));
			else
				temp.push ('  '.repeat (depth) + index + ': "' + object[index] + '"');
		}
	}
	else if (object === undefined)
		temp.push ('<undefined>');
	else
		temp.push (object);
	return temp.join ("\n");
}
/**/









/*////////////////////////////////////////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/core/google_address_suggest/google_address_suggest-0.0.1.js //
// created: Tue, 22 Nov 2011 11:23:02 +1100                                                     //
// modified: Tue, 22 Nov 2011 11:23:02 +1100                                                    //
// size: 11721 bytes                                                                            //
////////////////////////////////////////////////////////////////////////////////////////////////*/

// note: the following js file needs to be included in the webpage before the google address suggest will work
//		 http://maps.google.com/maps/api/js?sensor=false
//		 can be added to header via: $config['temp']['jsIncludes'][] = 'http://maps.google.com/maps/api/js?sensor=false';
// google geocode example at: http://code.google.com/apis/maps/documentation/javascript/services.html#Geocoding
// google geocode documentation at: http://code.google.com/apis/maps/documentation/javascript/reference.html#Geocoder
(function($) {

	// static constructs
	$.core = $.core || { version: '0.0.1' };

	$.core.googleAddressSuggest = {
		// update the default conf values below in $.core.googleAddressSuggest.conf
		updateDefaultConf: function (conf) {
			this.conf = $.extend (true, {}, this.conf, conf);
		},
		setDefaultGoogleBounds: function (swLat, swLong, neLat, neLong) {
			this.conf.googleBounds = { swLat: swLat, swLong: swLong, neLat: neLat, neLong: neLong };
		},
		setDefaultGoogleLanguage: function (language) {
			this.conf.googleLanguage = language;
		},
		setDefaultGoogleRegion: function (region) {
			this.conf.googleRegion = region;
		},
		// the default conf values used when this plugin is applied to an element
		conf: {
			maxSuggestions: 10,				// the maximum number of suggestions to be shown
			sendDelay: 500,					// the number of ms to wait after the field changes,  before sending the request
			suggestionMessage: 'Did you mean?',	// the sentence to show at the top of the popover

			googleBounds: null,
			googleLanguage: null,
			googleRegion: null,

			popoverConf:
			{	template: 'helperNoTitle',
//				attachTo: $element,			// set later
				baseAttachDirectionX: 'left',
				popoverAttachDirectionX: 'left',
				baseAttachDirectionY: 'bottom',
				popoverAttachDirectionY: 'top',
				attachOffsetX: 10,
				attachOffsetY: 2,
				startOnScreenY: false,
				applyMask: false,
				easyClose: true,
				applyArrows: true,
//				pointTo: $element,			// set later
				maxWidth: 600,
				onBeforeShow: null,			// callback that is overridden below
				onClose: null				// callback that is overridden below
			},



			// events
			onBeforeGetSuggestList: null,	// called before the request is sent to google
			onGetSuggestList: null,			// called when the suggestion list is retrieved from google
			onBeforeUseSuggestion: null,	// called as the user chooses suggestion
			onAfterUseSuggestion: null		// called after the user chooses suggestion
		}
	};





	function googleAddressSuggest ($element, conf) {

		var api = this;
		var $element = $($element);
		var $popover = null;
		var lastValue = null;
		var getSuggestionTimeout = null;
		var isPopoverShowing = false;



		// API methods
		$.extend (api, {

			init: function () {

				var tempOnBeforeShow = conf.popoverConf.onBeforeShow;
				conf.popoverConf.onBeforeShow = function (e) {

					// call the original onBeforeShow ()
					if ($.isFunction (tempOnBeforeShow)) {
						tempOnBeforeShow (e);
						if (e.isDefaultPrevented ())
							return api;
					}

					// make the links populate the field's value
					var $popover = $(this);
					$popover.find ('ul.core-suggestionList a').bind ('click.googleAddressSuggest', function (e) {
						e.preventDefault ();
						// update the field with the new value
						$element.val ($(this).text ());
						// store the latest value for comparison later on
						lastValue = $(this).text ();
						// close the popover
						$popover.data ('popover').close ();
						//TODO:FIXME:i inject this line for the takeaway search requirement:
						// "when user select/click the suggested address, submit the search request"
						// i can't find out a better way to capture/reponse to the user's click event to the google suggest box. 
						// i simply bind a selectSuggestion event to $element on takeaway search page,
						// and trigger this event $element.trigger('selectSuggestion');
						// If $element doesn't have this 'selectSuggestion' event, it won't cause any error though.
						// but we should find a better way to do this.
						$element.trigger('selectSuggestion');
					});
				};

				var tempOnClose = conf.popoverConf.onClose;
				conf.popoverConf.onClose = function (e) {
					// record that the popover is not showing
					isPopoverShowing = false;

					// call the original onClose ()
					if ($.isFunction (tempOnClose)) {

						// onBeforeShow
						tempOnClose (e);
						if (e.isDefaultPrevented ())
							return api;
					}
				}









				// 
				observeFieldChanges ();
				assignCallbacks ();
			},

			// send the request to google to get suggestions
			sendSuggestionRequest: function () {

				// store the latest value for comparison later on
				lastValue = $element.val ();

				// send the request to google
				if ((typeof (google) == 'undefined') || (typeof (google.maps) == 'undefined') || (typeof (google.maps.Geocoder) == 'undefined'))
					alert ('The google api has not been included in the page');

				if ($element.val () != '') {

					var request = { address: $element.val () };
					if (conf.googleBounds !== null)
						request.bounds = new google.maps.LatLngBounds (new google.maps.LatLng (conf.googleBounds.swLat, conf.googleBounds.swLong), new google.maps.LatLng (conf.googleBounds.neLat, conf.googleBounds.neLong));
					if (conf.googleLanguage !== null)
						request.language = conf.googleLanguage;
					if (conf.googleRegion !== null)
						request.region = conf.googleRegion;

					var geocoder = new google.maps.Geocoder ();
					geocoder.geocode (request, function (geocoderResults, geocoderStatus) {

						// process the response
						if (geocoderStatus == google.maps.GeocoderStatus.OK) {

							// generate the list of addresses
							var addresses = [];
//							var coords = [];
							// show the suggestions if there's more than 1 address
							var showSuggestions = geocoderResults.length > 1;
							$.each (geocoderResults, function (index, value) {
								addresses.push (value.formatted_address);
//								coords.push ({ lat: value.geometry.location.lat (), lng: value.geometry.location.lng () });
								// show the suggestions if any address returned isn't the same as the original string
								if (value.formatted_address != $element.val ());
									showSuggestions = true;
								// don't add too many suggestions
								if (addresses.length >= conf.maxSuggestions)
									return false;
							});

							// show the suggestions if necessary
							if (showSuggestions) {

								// render the new suggestion html
								var newHtml = '<p>' + conf.suggestionMessage + '</p><ul class="core-suggestionList"><li><a href="#">' + addresses.join ('</a></li><li><a href="#">') + '</a></li></ul>';
								// replace the html if the popover is already showing
								if (isPopoverShowing) {
									$popover.data ('popover').replaceContentBoxHtml (newHtml)

									// make the links populate the field's value
									$popover.find ('a').bind ('click.googleAddressSuggest', function (e) {
										e.preventDefault ();
										// update the field with the new value
										$element.val ($(this).text ());
										// store the latest value for comparison later on
										lastValue = $(this).text ();
										// close the popover
										$popover.data ('popover').close ();
										//TODO:FIXME:i inject this line for the takeaway search requirement:
										// "when user select/click the suggested address, submit the search request"
										// i can't find out a better way to capture/reponse to the user's click event to the google suggest box. 
										// i simply bind a selectSuggestion event to $element on takeaway search page,
										// and trigger this event $element.trigger('selectSuggestion');
										// If $element doesn't have this 'selectSuggestion' event, it won't cause any error though.
										// but we should find a better way to do this.
										$element.trigger('selectSuggestion');
									});
								}
								// or open a new popover
								else {
									$popover = $.createPopover (
									{	content: newHtml
									},
									conf.popoverConf );
									isPopoverShowing = true;
								};
							}
							// if there are no suggestions to show but the popover is open,  close it
							else if (isPopoverShowing)
								$popover.data ('popover').close ();
						}
						// if no response could be obtained from google,  close the popover
						else if (isPopoverShowing)
							$popover.data ('popover').close ();
					});
				}
				// if no input was specified then close the popover
				else if (isPopoverShowing)
					$popover.data ('popover').close ();
			}

		});

		// observe the field for changes so that when something changes,  the request to google can be triggered
		var observeFieldChanges = function () {

			// observe changes to the field
			$element.unbind ('.googleAddressSuggest').bind ('change.googleAddressSuggest keyup.googleAddressSuggest', function () {
				// if no change then don't do anything
				if ($element.val () == lastValue) {
					return;
				} 

				// set the timeout to send the request to google
				clearTimeout (getSuggestionTimeout);
				getSuggestionTimeout = setTimeout (api.sendSuggestionRequest, conf.sendDelay);
			});
			
			// if the user blurs the input field AFTER the popover has shown,  then hide the popover
//			$element.bind ('blur.googleAddressSuggest', function () {
//				if (isPopoverShowing)
//					$popover.data ('popover').close ();
//			});
		}

		// assign the callbacks
		var assignCallbacks = function () {
			$.each (['onBeforeGetSuggestList', 'onGetSuggestList', 'onBeforeUseSuggestion', 'onAfterUseSuggestion'], function (i, name) {

				// configuration
				if ($.isFunction (conf[name]))
					$element.bind (name, conf[name]);

				// API
				$element[name] = function (fn) {
					$element.bind (name, fn);
					return $element;
				};
			});
			return true;
		}








		// initialise the form
		api.init ();
	}

	// jQuery plugin initialisation
	$.fn.coreGoogleAddressSuggest = function (conf) {

		conf = $.extend (true, {}, $.core.googleAddressSuggest.conf, conf);

		this.each (function () {

			var $this = $(this);
			if ($this.is ('input[type=text]')) {

				var tempConf = $.extend (true, {}, conf);	// clone the conf

				// attach it to,  and make it point to the right place
				tempConf.popoverConf = $.extend (true, {}, { attachTo: $this, pointTo: $this }, tempConf.popoverConf);

				// only apply the googleAddressSuggest to this element if it hasn't already been applied
				if (!$this.data ('coreGoogleAddressSuggest')) {
					var api = new googleAddressSuggest ($this, tempConf);
					$this.data ('coreGoogleAddressSuggest', api);
				}
			}
		});

		return $(this);
	};
}) (jQuery);









/*//////////////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/core/fixed_pos/fixed_pos-0.0.1.js //
// created: Mon, 26 Sep 2011 14:01:58 +1000                           //
// modified: Wed, 31 Aug 2011 11:54:39 +1000                          //
// size: 6995 bytes                                                   //
//////////////////////////////////////////////////////////////////////*/

(function($) {

	// static constructs
	$.core = $.core || { version: '0.0.1' };

	$.core.fixedPos = {
		// update the default conf values below in $.core.fixedPos.conf
		updateDefaultConf: function (conf) {
			this.conf = $.extend (true, {}, this.conf, conf);
		},
		// the default conf values used when this plugin is applied to an element
		conf: {
			offsetY: 0,				// how many pixels should left above the floating element?
			zIndex: null,			// what z-index should the elements have when fixed? (null for no change)

			// events
			onBeforeFix: null,		// called before the element is "fixed" on the screen
			onFix: null,			// called after the element is "fixed" on the screen
			onBeforeUnfix: null,	// called before the element is put back into the page
			onUnfix: null			// called after the element is put back into the page
		}
	};





	function fixedPos (fixedPos, conf) {

		var api = this;
		var $fixedPos = $(fixedPos);
		var $placeHolder;
		var $window = $(window);
		var $body = $('body');
		var isFixed = false;
		var originalWidthAttribute = null;
		var origZIndex = null;
		var paused = false;






		// API methods
		$.extend (api, {

			init: function () {

				// initialise the element
				$fixedPos.css (
				{	position: 'static',
					left: '',
					top: ''
				});

				// put this element into a placeholder element
				$fixedPos.wrap ($('<div/>'));
				$placeHolder = $fixedPos.parent ();

				$placeHolder.css ('float', $fixedPos.css ('float'));





				// observe the window scroll
				$window.bind ('scroll.core-fixedPos, resize.core-fixedPos', function (e) {

					if (paused)
						return;

					// check to see if it's height needs to be fixed
					if (!isFixed) {
						if ($window.scrollTop () > $fixedPos.offset ().top - conf.offsetY) {

							// call the onBeforeFix javascript (before the element is "fixed" on the screen)
							e2 = $.Event ();
							e2.type = 'onBeforeFix';
							$fixedPos.trigger (e2);
							if (e2.isDefaultPrevented ()) {
								e.preventDefault ();
								return api;
							}



							originalWidthAttribute = $fixedPos.css ('width');
							var tempWidth = $fixedPos.width ();

							$placeHolder.css (
							{	width: $fixedPos.outerWidth (),
								height: $fixedPos.outerHeight (),
								margin: $fixedPos.css ('margin'),
								'margin-top': $fixedPos.css ('margin-top'),
								'margin-right': $fixedPos.css ('margin-right'),
								'margin-bottom': $fixedPos.css ('margin-bottom'),
								'margin-left': $fixedPos.css ('margin-left')
							});

							// ie calculates the below to NaN where the others calculate it to 0,  so test for the NaN possibility
							var marginTop = parseInt ($placeHolder.css ('margin-top'));
							if (isNaN (marginTop))
								marginTop = 0;

							$fixedPos.css (
							{	position: 'fixed',
								width: tempWidth + 'px',
								left: ($placeHolder.offset ().left - parseInt ($placeHolder.css ('margin-left'))) + 'px',
								top: (conf.offsetY - marginTop) + 'px'
							});
							if (conf.zIndex !== null) {
								origZIndex = $fixedPos.css ('z-index');
								$fixedPos.css ('z-index', conf.zIndex);
							}

							isFixed = true;



							// call the onFix javascript (after the element is "fixed" on the screen)
							e2 = $.Event ();
							e2.type = 'onFix';
							$fixedPos.trigger (e2);
							if (e2.isDefaultPrevented ()) {
								e.preventDefault ();
								return api;
							}
						}
					}
					// or..
					else {
//alert ('rah');
//alert ($window.unbind ('scroll.core-fixedPos'));
						// check to see if it's height needs to be un-fixed
						if ($window.scrollTop () < $placeHolder.offset ().top - conf.offsetY) {

							// call the onBeforeUnfix javascript (before the element is put back into the page)
							e2 = $.Event ();
							e2.type = 'onBeforeUnfix';
							$fixedPos.trigger (e2);
							if (e2.isDefaultPrevented ()) {
								e.preventDefault ();
								return api;
							}



							$fixedPos.css (
							{	position: 'static',
								width: originalWidthAttribute,
								left: '',
								top: ''
							});
							if (conf.zIndex !== null)
								$fixedPos.css ('z-index', origZIndex);

							$placeHolder.css (
							{	width: '',
								height: '',
								margin: '',
								'margin-top': '',
								'margin-right': '',
								'margin-bottom': '',
								'margin-left': ''
							});

							isFixed = false;



							// call the onUnfix javascript (after the element is put back into the page)
							e2 = $.Event ();
							e2.type = 'onUnfix';
							$fixedPos.trigger (e2);
							if (e2.isDefaultPrevented ()) {
								e.preventDefault ();
								return api;
							}
						}
						// or if it needs to be re-positioned (in case the placeholder has moved on the screen,  eg upon re-size)
						else {
							$fixedPos.css (
							{	left: ($placeHolder.offset ().left - parseInt ($placeHolder.css ('margin-left'))) + 'px',
								top: (conf.offsetY - marginTop) + 'px'
							});
						}
					}
				});

				assignCallbacks ();
			},
			// stop the element from being adjusted
			pause: function () {
				paused = true;
				return api;
			},
			// start the element being adjusted again
			unpause: function () {
				paused = false;
				return api;
			}
		});

		// assign the callbacks
		var assignCallbacks = function () {
			$.each (['onBeforeFix', 'onFix', 'onBeforeUnfix', 'onUnfix'], function (i, name) {

				// configuration
				if ($.isFunction (conf[name]))
					$fixedPos.bind (name, conf[name]);

				// API
				$fixedPos[name] = function (fn) {
					$fixedPos.bind (name, fn);
					return $fixedPos;
				};
			});
			return true;
		};










		// initialise the form
		api.init ();
	}

	// jQuery plugin initialisation
	$.fn.coreFixedPos = function (conf) {

		conf = $.extend (true, {}, $.core.fixedPos.conf, conf);

		this.each (function () {

			var $this = $(this);

			// only apply the fixedPos to this element if it hasn't already been applied
			if (!$this.data ('fixedPos')) {
				var api = new fixedPos ($this, conf);
				$this.data ('fixedPos', api);
			}
		});

		return $(this);
	};
}) (jQuery);









/*/////////////////////////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/core/in_field_labels/in_field_label-0.0.1.js //
// created: Mon, 26 Sep 2011 14:01:58 +1000                                      //
// modified: Mon, 21 Feb 2011 11:17:41 +1100                                     //
// size: 6461 bytes                                                              //
/////////////////////////////////////////////////////////////////////////////////*/

(function($) {

	// static constructs
	$.core = $.core || { version: '0.0.1' };

	$.core.inFieldLabel = {

		// update the default conf values below in $.core.inFieldLabel.settings
		updateSettings: function (settings) {
			this.settings = $.extend (true, {}, this.settings, settings);
		},
		// settings that control the way this plugin operates (different to the conf values below that are used when the plugin is being applied to an element)
		settings: {
			inFieldLabelClass: 'core-inFieldLabel',				// 
			inFieldLabelSelector: '.core-inFieldLabel label'	// the selector used to identify inFieldLabel elements (used by other core plugins,  eg. the popover plugin when it needs to identify and create new inFieldLabels inside itself)
		},

		// update the default conf values below in $.core.inFieldLabel.conf
		updateDefaultConf: function (conf) {
			this.conf = $.extend (true, {}, this.conf, conf);
		},
		// the default conf values used when this plugin is applied to an element
		conf: {
//			fadeOpacity: 0.45	// the default fade opacity used
		}
	};



/*
 * In-Field Label jQuery Plugin
 * http://fuelyourcoding.com/scripts/infield.html
 *
 * Copyright (c) 2009 Doug Neiner
 * Dual licensed under the MIT and GPL licenses.
 * Uses the same license as jQuery, see:
 * http://docs.jquery.com/License
 *
 * @version 0.1
 */
	
    $.inFieldLabel = function(label,field, options){
        // To avoid scope issues, use 'base' instead of 'this'
        // to reference this class from internal events and functions.
        var base = this;
        
        // Access to jQuery and DOM versions of each element
        base.$label = $(label);
        base.label = label;

 		base.$field = $(field);
		base.field = field;
        
		base.$label.data('inFieldLabel', base);
		base.showing = true;
        
        base.init = function(){
			// Merge supplied options with default options
            base.options = $.extend({},$.inFieldLabel.defaultOptions, options);

			// Check if the field is already filled in
			if(base.$field.val() != ""){
				base.$label.hide();
				base.showing = false;
			};
			
			base.$field.focus(function(){
				base.fadeOnFocus();
			}).blur(function(){
				base.checkForEmpty(true);
			}).bind('keydown.core-infieldlabel',function(e){
				// Use of a namespace (.infieldlabel) allows us to
				// unbind just this method later
				base.hideOnChange(e);
			}).change(function(e){
				base.checkForEmpty();
			}).bind('onPropertyChange', function(){	// 'onPropertyChange' => 'propertychange' ?
				base.checkForEmpty();
			});
        };

		// If the label is currently showing
		// then fade it down to the amount
		// specified in the settings
		base.fadeOnFocus = function(){
			if(base.showing){
				base.setOpacity(base.options.fadeOpacity);
			};
		};
		
		base.setOpacity = function(opacity){
			base.$label.stop().animate({ opacity: opacity }, base.options.fadeDuration);
			base.showing = (opacity > 0.0);
		};
		
		// Checks for empty as a fail safe
		// set blur to true when passing from
		// the blur event
		base.checkForEmpty = function(blur){
			if(base.$field.val() == ""){
				base.prepForShow();
				base.setOpacity( blur ? 1.0 : base.options.fadeOpacity );
			} else {
				base.setOpacity(0.0);
			};
		};
		
		base.prepForShow = function(e){
			if(!base.showing) {
				// Prepare for a animate in...
				base.$label.css({opacity: 0.0}).show();
				
				// Reattach the keydown event
				base.$field.bind('keydown.core-infieldlabel',function(e){
					base.hideOnChange(e);
				});
			};
		};

		base.hideOnChange = function(e){
			if(
				(e.keyCode == 16) || // Skip Shift
				(e.keyCode == 9) // Skip Tab
			  ) return; 
			
			if(base.showing){
				base.$label.hide();
				base.showing = false;
			};
			
			// Remove keydown event to save on CPU processing
			base.$field.unbind('keydown.core-infieldlabel');
		};
      
		// Run the initialization method
        base.init();
    };
	
    $.inFieldLabel.defaultOptions = {
        fadeOpacity: 0.5, // Once a field has focus, how transparent should the label be
		fadeDuration: 300 // How long should it take to animate from 1.0 opacity to the fadeOpacity
    };
	

    $.fn.inFieldLabel = function (options){
        return this.each(function(){
			if ($(this).data ('inFieldLabel_init'))
				return;
			$(this).data ('inFieldLabel_init', true);

			// Find input or textarea based on for= attribute
			// The for attribute on the label must contain the ID
			// of the input or textarea element
			var for_attr = $(this).attr('for');
			if( !for_attr ) return; // Nothing to attach, since the for field wasn't used

			
			// Find the referenced input or textarea element
			var $field = $(
				"input#" + for_attr + "[type='text']," + 
				"input#" + for_attr + "[type='password']," + 
				"textarea#" + for_attr
				);
				
			if( $field.length == 0) return; // Again, nothing to attach
			
			// Only create object for input[text], input[password], or textarea
            (new $.inFieldLabel(this, $field[0], options));
        });
    };

	// apply inFieldLabels to the page for existing and future elements
	$.applyInFieldLabels = function () {

		$('.' + $.core.inFieldLabel.settings.inFieldLabelClass + ' input, .' + $.core.inFieldLabel.settings.inFieldLabelClass + ' textarea').livequery (function () {
			if (!$(this).data ('core_inFieldLabel_init')) {
				$(this).closest ('.' + $.core.inFieldLabel.settings.inFieldLabelClass).find ('label[for=' + $(this).attr ('id') + ']').inFieldLabel ();
				$(this).data ('core_inFieldLabel_init', true);
			}
		});
	}
	
}) (jQuery);









/*//////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/core/mouse/mouse-0.0.1.js //
// created: Mon, 26 Sep 2011 14:01:58 +1000                   //
// modified: Wed, 31 Aug 2011 11:54:39 +1000                  //
// size: 5029 bytes                                           //
//////////////////////////////////////////////////////////////*/

(function($) {

	var pleaseWaitWeightings = {};		// each "name" has a counter and the "please wait" element will show until every "name"'s counter is reduced back to 0
	var pleaseWaitWeightingsCount = 0;	// this value will increase as more things want the "please wait" to appear.  when they request it to disappear this value will decrease until it gets to 0,  and it will then disappear
	var $pleaseWait = $();
	var pleaseWaitAdded = false;
	$.core.mouseX = 0;
	$.core.mouseY = 0;

	$.core.mouse = {

		// update the default conf values below in $.core.popover.conf
		updateDefaultConf: function (conf) {
			this.conf = $.extend (true, {}, this.conf, conf);
		},
		// the default conf values used when this plugin is applied to an element
		conf: {
			xOffset: 16,	// x-offset given to the "please wait" element
			yOffset: 18		// y-offset given to the "please wait" element
		},

		// turn mouse observations on/off
		// observe the mouse's x/y position as it moves
		observeMousePosition: function (observe) {
			if ((observe === undefined) || (observe))
				$('body:first').bind ('mousemove.core-mouse', observeMousePos);
			else
				$('body:first').unbind ('mousemove.core-mouse');
		},




		// show "please wait" if it isn't already being shown
		startPleaseWait: function (name) {
			// show the "please wait" if it's not showing already
			if (pleaseWaitWeightings[name] === undefined) {
				pleaseWaitWeightings[name] = 1;
				pleaseWaitWeightingsCount++;

				renderPleaseWait ();	// add the element to the dom
				$pleaseWait.css ({ left: ($.core.mouseX + $.core.mouse.conf.xOffset) + 'px', top: ($.core.mouseY + $.core.mouse.conf.yOffset) + 'px' } );	// position the element initially
				$('body:first').unbind ('mousemove.core-mouse', observeMousePos).bind ('mousemove.core-mouse', observeMousePosWithPleaseWait);				// move the element when the mouse moves

				$pleaseWait.show (); // show it visually to the screen
			}
			else
				pleaseWaitWeightings[name]++;
			return true;
		},

		// request that "please wait" is hidden
		stopPleaseWait: function (name, forceStopName, forceStop) {
			if (pleaseWaitWeightings[name] !== undefined) {

				// force-stop for this name?
				if ((forceStopName !== undefined) && (forceStopName))
					pleaseWaitWeightings[name] = 0;
				else
					pleaseWaitWeightings[name]--;

				// hide the element if necessary
				if (pleaseWaitWeightings[name] <= 0) {
					delete pleaseWaitWeightings[name];
					pleaseWaitWeightingsCount--;
				}
			}

			// forec-stop,  regardless of name?
			if ((forceStop !== undefined) && (forceStop)) {
				pleaseWaitWeightings = {};
				pleaseWaitWeightingsCount = 0;
			}

			// check if the element needs to be hidden
			if (pleaseWaitWeightingsCount <= 0) {
				$pleaseWait.hide (); // hide it visually from to the screen
				$('body:first').unbind ('mousemove.core-mouse', observeMousePosWithPleaseWait).bind ('mousemove.core-mouse', observeMousePos);	// stop the element from moving
			}
			return true;
		},

		// add the "please wait" element to the dom so any images are loaded
		primePleaseWaitElement: function () {
			renderPleaseWait ();
			return true;
		}
	};




	// private methods

	// add the "please wait" element to the dom
	var renderPleaseWait = function () {
		if (!pleaseWaitAdded) {
			$pleaseWait = $('<div class="core-pleaseWaitSpinner">Please wait</div>').css ('display', 'none');
			$('body:first').append ($pleaseWait);
			pleaseWaitAdded = true;
		}
	};

	// record the mouse's position
	var observeMousePos = function (e) {
		$.core.mouseX = e.pageX;
		$.core.mouseY = e.pageY;
	};

	// record the mouse's position and move the "please wait" element
	var observeMousePosWithPleaseWait = function (e) {
		$.core.mouseX = e.pageX;
		$.core.mouseY = e.pageY;
		$pleaseWait.css ({ left: ($.core.mouseX + $.core.mouse.conf.xOffset) + 'px', top: ($.core.mouseY + $.core.mouse.conf.yOffset) + 'px' } );
	};





	// start observing the mouse position when the page loads
	$().ready (function () {
		$.core.mouse.observeMousePosition ();
	});

}) (jQuery);









/*////////////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/core/popovers/popovers-0.0.1.js //
// created: Mon, 26 Sep 2011 14:01:58 +1000                         //
// modified: Thu, 22 Sep 2011 14:05:59 +1000                        //
// size: 85539 bytes                                                //
////////////////////////////////////////////////////////////////////*/

(function($) {

	// static constructs
	$.core = $.core || { version: '0.0.1' };

	$.core.popover = {

		// update the default conf values below in $.core.popover.settings
		updateSettings: function (settings) {
			this.settings = $.extend (true, {}, this.settings, settings);
		},
		// settings that control the way this plugin operates (different to the conf values below that are used when the plugin is being applied to an element)
		settings: {
			popoverAnimations: true,									// should the popovers use animations to fade in and out etc?
			allowMask: true,											// is the mask allowed?
			maskAnimation: true,										// should the mask use animations to fade in and out?
			zIndex: 10000,												// the start z-index of the popovers
			templateTriggerCssParams: ['width', 'minWidth', 'maxWidth']	// the list of parameters that should be looked for in template popover triggers' css classes,  in the format of core-param-<paramName>-<value>
		},

		// update the default conf values below in $.core.popover.conf
		updateDefaultConf: function (conf) {
			this.conf = $.extend (true, {}, this.conf, conf);
		},
		// the default conf values used when this plugin is applied to an element
		conf: {
			id: null,									// the id to give the popover
			template: 'general',						// the popover template to use
			group: null,
			removeOnClose: true,						// delete the element from the dom after closing

			ajax: null,									// the url or urls to request which can update the content of the popover
			ajaxData: null,								// the data used in the ajax request
			recalculateStartPositionAfterAjax: false,	// after receiving an ajax response,  the changed dimensions of the popover may change the ideal starting point of the popover.  this will get it to re-calculate the start position upon ajax completion
			buttons: [],								// 
			buttonAlignment: 'right',					// the alignment of the buttons at the bottom of the popover. 'left', 'center', 'right' (default)

			easyClose: true,							// close the popover by clicking outside or pressing escape
			closeOnClick: null,							// set to false to manually override
			closeOnEsc: null,							// set to false to manually override 
			addCloseX: true,							// add the "closeX" element to the popover (ie. add the "X" button
			closeOtherPopovers: false,
			closeAfter: null,							// close this popover after x milliseconds
			closeXHtml: '<a class="core-closeX"></a>',	// the html used for the closeX button

			attachTo: null,								// 'mouse', an $element or null (for viewable window)
			followMouse: false,							// should the position of the popover follow the mouse (if true,  attach to is also set to 'mouse')
			baseAttachDirectionX: 'center',				// 'left', 'center', 'right', or a percentage
			popoverAttachDirectionX: 'center',			// 'left', 'center', 'right'
			baseAttachDirectionY: null,					// 'top', 'center', 'bottom', or a percentage (null will become 20% or center depending on whether it's being attached to anything)
			popoverAttachDirectionY: 'center',			// 'top', 'center', 'bottom'
			attachOffsetX: 0,							// offset in pixels to adjust the starting point
			attachOffsetY: 0,							// offset in pixels to adjust the starting point
			startOnScreen: true,						// make sure the popover appears in the viewable area of the page to begin with
			startOnScreenX: null,						// position the popover back into the viewable area of the page if it appears initially offscreen (if not null then this overrides startOnScreen)
			startOnScreenY: null,						// position the popover back into the viewable area of the page if it appears initially offscreen (if not null then this overrides startOnScreen)
			fixed: false,								// fix the popover into one position on the screen (fixed positioning not supported by ie6)

			applyArrows: false,							// add an arrow pointing towards the attached element
			pointTo: [],
			arrowEdgeBuffer: 5,							// the number of pixels that the arrow stops at before it gets to the corner of the popover
			arrowHtml: '<div class="core-popoverArrow"><div class="core-outer"><div class="core-inner"></div></div></div>',	// the html used for the arrow

			width: null,								// the width of the popover
			minWidth: null,								// the max-width of the popover
			maxWidth: null,								// the min-width of the popover

			effect: 'default',
			showSpeed: 'normal',						// take x milliseconds to open
			closeSpeed: 'normal',						// take x milliseconds to close

			applyMaskToSelf: false,						// use the mask on this popover
			applyMask: true,							// use the mask on this popover's group
			maskOptions: {								// options controlling the mask
				color: null,
				speed: 800,
				opacity: 0.7
			},

			applyDraggable: true,						// turns the dragability on/off (uses jQueryUI)
			dragOptions: {								// the options passed to the jQueryUI draggable call.  ALL OTHER DRAGGABLE OPTIONS CAN BE SET they will be passed to jQueryUI
				handle: false,							// default selector to use when finding elements to drag by
				opacity: 0.85,							// default opacity when dragging
				containment: 'document'					// restrict movement of the popover to the document's boundaries
			},

			// events
			onBeforePosition: null,						// called after the element has been created but before it has been positioned (good for manipulating the content before it is positioned on the screen)
			onBeforeShow: null,
			onShow: null,
			onBeforeClose: null,
			onClose: null
		},




		// the default conf values for a confirm-action popover (bubbled up into the general conf above)
		dialoguePopoverConf: {
			template: 'noticeNoTitle',

			// things specific to dialogue popovers
			message: 'Are you sure?',
			messageHtml: null,
			confirmButtonText: 'Yes',
			confirmButtonHtml: null,
			onConfirm: function (popoverApi) {},
			cancelButtonText: 'No - Cancel',
			cancelButtonHtml: null,
			onCancel: function (popoverApi) {},
			buttons: [],
			buttonAlignment: 'center',
			url: null
		},
		// confs specific to jquery element functions
		// the default conf values for a confirm-action popover (bubbled up into the dialoguePopoverConf conf above)
		confirmActionPopoverConf: {
			attachTo: 'mouse',
			baseAttachDirectionX: 'left',
			popoverAttachDirectionX: 'left',
			baseAttachDirectionY: 'top',
			popoverAttachDirectionY: 'center',
			attachOffsetX: 5,	// 65
			attachOffsetY: 0,	// -50
			width: 266,

			// things specific to confirmAction popovers
			url: null,
			useAjax: false
		},
		// the default conf values for a confirm-delete popover (bubbled up into the confirmActionPopoverConf conf above)
		confirmDeletePopoverConf: {
			message: 'Are you sure you want to delete this?',
			confirmButtonText: 'Yes - Delete'
		},




		// the default popoverTrigger conf
		defaultTriggerConf: {
			popoverFunction: null,
			openTriggers: 'click',
			closeTriggers: '',
			ignoreTriggerHiding: false,
			showDelay: 0,
			closeDelay: 0,
			title: null,
			titleHtml: null,
			message: null,
			messageHtml: null,
			useTitle: false,
			stopDefaultToolTip: false,	// don't show the original title
			reApplyNamespace: null,		// when re-running the triggerPopover function on the element,  should it check to see if a popoverTrigger has already been created for it?  and if so what name should it go under?
			popoverConf:
			{	template: 'helperNoTitle',
				easyClose: true,
				attachTo: 'mouse',
				followMouse: false,
				baseAttachDirectionX: 'right',
				popoverAttachDirectionX: 'left',
				baseAttachDirectionY: 'top',
				popoverAttachDirectionY: 'top',
				attachOffsetX: 0,
				attachOffsetY: 2,	// push it down a bit because when the toolTip is on the far rhs it will stop moving when it gets to the end of the screen,  covering up the mouse clicks.  this moves it away from under the mouse
				effect: 'default',
				showSpeed: 400,
				closeSpeed: 250
			}
		},
		// the default toolTip conf
		toolTipTriggerConf: {
//			popoverFunction: null,
			openTriggers: 'mouseenter',
			closeTriggers: 'mouseleave',
			showDelay: 400,
//			closeDelay: 0,
//			message: null,
//			messageHtml: null,
			useTitle: true,
			stopDefaultToolTip: true,
			reApplyNamespace: 'toolTip',
			popoverConf:
			{	template: 'toolTip',
				easyClose: false,
				attachTo: 'mouse',
				followMouse: true,
				effect: 'fade'
			}
		},




		// the default helper conf
		helperTriggerConf: {
//			popoverFunction: null,
//			openTriggers: 'focus',
//			closeTriggers: 'blur',
			openTriggers: 'mouseenter,focus',
			closeTriggers: 'mouseleave,blur',
//			showDelay: 0,
//			closeDelay: 0,
//			message: null,
//			messageHtml: null,
			useTitle: true,
			stopDefaultToolTip: true,
			reApplyNamespace: 'helperNoTitle',
			popoverConf:
			{	template: 'helperNoTitle',
				easyClose: true,
				attachTo: 'self',
				followMouse: false,
				baseAttachDirectionX: 0.6,
				popoverAttachDirectionX: 0.25,
				baseAttachDirectionY: 'bottom',
				popoverAttachDirectionY: 'top',
				attachOffsetX: 0,
				attachOffsetY: 7,
				applyArrows: true,
				pointTo: 'self',
				maxWidth: 600,
				effect: 'fade',
				showSpeed: 500,
				closeSpeed: 150
			}
		},




		// the default template trigger conf
		templateTriggerConf: {
			popoverConf:
			{	baseAttachDirectionX: 'left',
				popoverAttachDirectionX: 'right',
				baseAttachDirectionY: 'top',
				popoverAttachDirectionY: 'top',
				attachOffsetX: 18,
				attachOffsetY: -17,
				addCloseX: true,
				applyDraggable: true,
				maxWidth: 400
			}
		},




		// the default conf values for a dialogue popover button
		buttonConf: {
			text: 'button',
			html: null,
			onClick: function (popoverApi) { alert ('default'); },
			isCancel: false,
			followUrl: false
		},




		// add a display/hide effect that the popovers can use
		// allowMouseFollowWhenClosing: if the popover is following the mouse,  when closing this can cause a problem if the close effect changes its position.  setting this to false will stop the popover from following the mouse when it is closing
		addEffect: function (name, loadFn, closeFn, allowMouseFollowWhenClosing) {
			if (allowMouseFollowWhenClosing === undefined)
				allowMouseFollowWhenClosing = false;
			effects[name] = [loadFn, closeFn, allowMouseFollowWhenClosing];
		}
	};







	var effects = {};
	var instances = {};
	var order = { topLevel: [] };
	var focusedUid = null;
	var setClickCloseTimeout = null;

	// make popovers opaque when dragging in IE so we don't have problems with some things becoming see-through
	if ($.browser.msie)
		$.core.popover.updateDefaultConf ({ dragOptions: { opacity: false } });
/**
	// the default effect. nice and easy!
	$.core.popover.addEffect('default',

		/* 
			onShow/onClose functions must be called otherwise none of the 
			user supplied callback methods won't be called
		* /
		function(pos, onShow) {

			var conf = this.getConf(),
				 w = $(window);

			if (!conf.fixed) {
				pos.top += w.scrollTop();
				pos.left += w.scrollLeft();
			}

			pos.position = conf.fixed ? 'fixed' : 'absolute';
			this.getPopover().css(pos).fadeIn(conf.speed, onShow);

		}, function(onClose) {
			this.getPopover().fadeOut(this.getConf().closeSpeed, onClose);
		}
	);
/**/
	// add an effect called "default" to the popover
	$.core.popover.addEffect ('default',

		// show function
		function (pos, onShow) {
			// fade the popover in
			var conf = this.getConf ();
			this.getPopover ().css (pos).fadeIn (conf.showSpeed, onShow);
//			pos.top += 1;
//			this.getPopover ().css ('display', 'block').css (pos).animate ({ top: '-=1', opacity: 1}, conf.showSpeed, 'linear', onShow);
			return true;
		},

		// close function
		function (onHide) {

			// fade the overlay out
			var conf = this.getConf ();
			if ((!is_int (conf.closeSpeed)) || (conf.closeSpeed > 0)) {
				this.getPopover ().stop (true).animate ({ top: '+=55', opacity: 0}, conf.closeSpeed, 'linear', function () {
					$(this).hide ();	// hide the element properly when finished fading out
					onHide.call ();		// call the caller's callback function
				});
			}
			else {
				this.getPopover ().stop (true).hide ();	// hide the popover
				onHide.call ();							// call the caller's callback function
			}
			return true;
		},
		false
	);

	// add an effect called "fade" to the popover
	$.core.popover.addEffect ('fade',

		// show function
		function (pos, onShow) {
			// fade the popover in
			var conf = this.getConf ();
			this.getPopover ().css (pos).fadeIn (conf.showSpeed, onShow);
			return true;
		},

		// close function
		function (onHide) {

			// fade the overlay out
			var conf = this.getConf ();
			if ((!is_int (conf.closeSpeed)) || (conf.closeSpeed > 0)) {
				this.getPopover ().stop (true).fadeOut (conf.closeSpeed, function () {
					$(this).hide ();	// hide the element properly when finished fading out
					onHide.call ();		// call the caller's callback function
				});
			}
			else {
				this.getPopover ().stop (true).hide ();	// hide the popover
				onHide.call ();							// call the caller's callback function
			}
			return true;
		},
		true
	);

	// add an effect called "blind" to the popover
	$.core.popover.addEffect ('blind',

		// show function
		function (pos, onShow) {
			// fade the popover in
			var conf = this.getConf ();
			this.getPopover ().css (pos).show ('blind', {}, conf.showSpeed, onShow);
			return true;
		},

		// close function
		function (onHide) {

			// fade the overlay out
			var conf = this.getConf ();
			if ((!is_int (conf.closeSpeed)) || (conf.closeSpeed > 0))
				this.getPopover ().stop (true).hide ('blind', {}, conf.closeSpeed, onHide);
			else {
				this.getPopover ().stop (true).hide ();	// hide the popover
				onHide.call ();							// call the caller's callback function
			}
			return true;
		},
		false
	);

	// add an effect called "noAnimate" to the popover
	$.core.popover.addEffect ('noAnimate',

		// show function
		function (pos, onShow) {
			this.getPopover ().css (pos).show ();	// make the popover appear
			onShow.call ();							// call the caller's callback function
			return true;
		},

		// close function
		function (onHide) {
			this.getPopover ().stop (true).hide ();	// hide the popover
			onHide.call ();							// call the caller's callback function
			return true;
		},
		false
	);













	function popover (popover, conf) {

		// private variables
		var api = this;
		var $popover = $(popover);
		var $w = $(window);
//		var closers;
		var opened = false;
		var uid = Math.random ().toString ().slice (10);
		var closeTimeout = null;
		var popoverApisToCloseWhenClosing = [];
		var needToShowNewContentBlock = false;

		var arrows = [];

		// if no group was specified then create it's own unique random group
		if (conf.group === null) {
			if (conf.applyMaskToSelf) {
				conf.applyMaskToSelf = false;
				conf.applyMask = true;
			}
			conf.group = Math.random ().toString ().slice (10);
		}

		// API methods
		$.extend (api, {

			open: function (e) {

				e = e || $.Event ();

				// can be opened only once
				if (api.isOpened ())
					return api;



				// find the effect
				var effect = conf.effect;
				if (!$.core.popover.settings.popoverAnimations)
					effect = 'noAnimate';
				var eff = effects[effect];
				if (!eff)
					throw 'popover: cannot find effect : "' + effect + '\"';



				// onBeforeShow
				e2 = $.Event ();
				e2.type = 'onBeforeShow';
				$popover.trigger (e2);
				if (e2.isDefaultPrevented ()) {
					e.preventDefault ();
					return api;
				}



				// close other instances?
				if (conf.closeOtherPopovers) {
					$.each (instances, function () {
						this.close (e);
					});
				}







				// record that this popover is open
				opened = true;



				// mark this element as being a popover
				$popover.addClass ('core-popover');

				// find elements with an id and convert them
				$popover.find ('[id]').attr ('id', function (index, orig) { return convert_id (orig, uid); });
				// find the elements with a "for" and convert them
				$popover.find ('[for]').attr ('for', function (index, orig) { return convert_id (orig, uid); });

				// if required,  give it the desired id
				if (conf.id)
					$popover.attr ('id', conf.id);




				if ($.core.ajaxForm) {

					// set the uid inside any ajax forms within the popover
					// and then activate them
// CHECK THIS
//					$popover.find ('.' + $.core.ajaxForm.settings.ajaxFormClass).ajaxForm ().data ('ajaxForm').set_popover_uid (uid);
					$popover.find ('.' + $.core.ajaxForm.settings.ajaxFormClass).map (function () {
						$(this).ajaxForm ();
						var api = $(this).data ('ajaxForm');
						if (api)
							api.setPopoverUid (uid);
					});

					// adjust the alignment of the dialogue buttons that appear at the bottom of the popover (via css by adding a class to the whole popover)
					switch (conf.buttonAlignment) {
						case 'right' :
							$popover.find ('.core-dialogueButtons>div:not(.core-left)').addClass ('core-right');
							break;
						case 'left' :
							$popover.find ('.core-dialogueButtons>div:not(.core-right)').addClass ('core-left');
							break;
					}
				}

				// make it draggable if required
				if (conf.applyDraggable) {
					$popover.draggable (conf.dragOptions);

					// apply the draggable class to only the handles
					if (conf.dragOptions.handle !== false)
						$popover.find (conf.dragOptions.handle).addClass ('core-popoverDraggable');
					// or apply the draggable class to the whole popover
					else
						$popover.addClass ('core-popoverDraggable');
				}

				// add the closeX if necessary
				if (conf.addCloseX) {
					var $close = $(conf.closeXHtml).bind ('click.core-popover-close', function () { api.close (); });
					$popover.prepend ($close);
				}







				// set the popover's min/max/widths
				// handle ie6's min/max-widths differently
				if (($.browser.msie) && ($.browser.version < 7)) {
					if (conf.maxWidth)
						$popover.width (parseInt (conf.maxWidth));
					if (conf.minWidth)
						$popover.width (parseInt (conf.minWidth));
				}
				else {
					if (conf.maxWidth)
						$popover.css ('max-width', parseInt (conf.maxWidth) + 'px');
					if (conf.minWidth)
						$popover.css ('min-width', parseInt (conf.minWidth) + 'px');
				}
				if (conf.width)
					$popover.width (conf.width);


/**
				//
				$popover.css ('position', 'absolute');
				$popover.show ();
				var maxWidth = 0;
				$popover.children ().map (function () { if ($(this).width () > maxWidth) maxWidth = $(this).width (); });
				$popover.hide ();
/**/
				// fix the width of the titlebox in <= ie7
				if (($.browser.msie) && ($.browser.version < 8))
					$popover.show ().find ('.core-titleBox').outerWidth ($popover.width ()).end ().hide ();

				// call the onBeforePosition javascript (before the overlay is applied to the popover)
				e2 = $.Event ();
				e2.type = 'onBeforePosition';
				$popover.trigger (e2);
				if (e2.isDefaultPrevented ()) {
					e.preventDefault ();
					return api;
				}

				// if needed, determine the default for baseAttachDirectionY
				if (conf.baseAttachDirectionY === null)
					conf.baseAttachDirectionY = ($(conf.attachTo).length != 0 || $(conf.attachTo).length == 'mouse') ? 'center' : 20;	// the center of the element to attach to,  or 20% of the screen if no element is given

				// position the popover neatly on the screen
				var pos = api.getStartCoordinates ();

				// make sure the popover appears on the page's viewable area if necessary
				pos = api.getOnScreenCoordinates ($popover.width (), $popover.height (), pos.left, pos.top);







				// fixed or absolute positioning? (fixed will keep it stuck in the same spot regardless of scrolling)
				if (((!$.browser.msie) || ($.browser.version >= 7)) && (conf.fixed)) {	// (fixed positioning not supported by ie6)
					pos.top -= $w.scrollTop ();
					pos.left -= $w.scrollLeft ();
					$popover.css ('position', 'fixed');
				}
				else
					$popover.css ('position', 'absolute');

				// load effect
				eff[0].call (api, { top: pos.top, left: pos.left }, function () {
					if (opened) {

						// onShow
						e2 = $.Event ();
						e2.type = 'onShow';
						$popover.trigger (e2);

						if (conf.closeAfter > 0)
							api.closeDelayed (conf.closeAfter);
					}
				});

				// add the mask effect if necessary
				if (((conf.applyMaskToSelf) || (conf.applyMask)) && ($.core.popover.settings.allowMask)) {
//					maskConf = $.extend (true, { closeOnClick: conf.easyClose, closeOnEsc: conf.easyClose, loadSpeed: conf.maskOptions.speed }, conf.maskOptions);	// should the mask hide on click / esc-keypress?
					maskConf = $.extend (true, { closeOnClick: false, closeOnEsc: false, loadSpeed: conf.maskOptions.speed }, conf.maskOptions);	// should the mask hide on click / esc-keypress?
					if (!$.core.popover.settings.maskAnimation)
						maskConf.loadSpeed = maskConf.closeSpeed = 0;
					$popover.mask (maskConf);
				}

				// add the arrow if necessary
				if (conf.applyArrows)
					api.addArrow (conf.pointTo);

				// reverse the dialogue buttons if necessary
				api.applyDialogueButtonReverse ();







				// keep the popover attached to the mouse
				if (conf.followMouse) {
					$('body').bind ('mousemove.core-popover' + uid, function (e) {
						var pos = api.getStartCoordinates ();
						pos = api.getOnScreenCoordinates ($popover.width (), $popover.height (), pos.left, pos.top);
						$popover.css ({ left: pos.left + 'px', top: pos.top + 'px' } );
						api.positionArrows ();	// re-position the arrows if necessary
					});
				}







				// collate a list of the urls to request
				var urls = [];
				var data = [];
				if ($.isArray (conf.ajax)) {
					for (var count = 0; count < conf.ajax.length; count++) {
						urls.push (conf.ajax[count]);
						data.push (conf.ajaxData[count]);
					}
				}
				else {
					if (typeof (conf.ajax) == 'string') {
						urls.push (conf.ajax);
						data.push (conf.ajaxData);
					}
				}

				// submit any ajax requests
				for (var count = 0; count < urls.length; count++) {

					var ajaxSettings = {};
					if ($.isObject (urls[count]))
						ajaxSettings = urls[count];
					else
						ajaxSettings.url = urls[count];

					var datum = data[count];
					if ((datum === null) || (!$.isObject (datum)))
						var datum = {};
					datum.popoverUid = uid;

					// default values
					ajaxSettings = $.extend (true, {
						url: null,
						type: (conf.ajaxData === null ? 'get' : 'post'),
						data: datum,
						complete: function () {},
						success: function () {}
					}, ajaxSettings);

					// define the complete function
//					ajaxSettings.complete = function (XMLHttpRequest, textStatus) {
//					}

					// define the success function
					ajaxSettings.success = api.processJsonResponse;

					// submit the request
					if (ajaxSettings.url)
						$.ajax (ajaxSettings);
				}

				return api;
			},

			// close the popover
			close: function (e) {

				if (!api.isOpened ())
					return $popover;

				e = e || $.Event ();
				e.type = 'onBeforeClose';
				$popover.trigger (e);
				if (e.isDefaultPrevented ())
					return;

				// check again just in case something withing the onBeforeClose callback called .close () again
				if (!api.isOpened ())
					return $popover;

				opened = false;



				// find the effect
				var effect = conf.effect;
				if (!$.core.popover.settings.popoverAnimations)
					effect = 'noAnimate';
				var eff = effects[effect];
				if (!eff)
					throw 'popover: cannot find effect : "' + effect + '\"';

				// stop the mouse from moving the popover
				if (!eff[2]) // if it's not allowed to follow the mouse
					$('body').unbind ('mousemove.core-popover' + uid);



				// remove the popover api if necessary
				if (conf.removeOnClose) {
					delete instances[uid];	// remove the popover from the internal list of popovers
					order.topLevel.remove (uid);	// remove the popover from the order list

					// and from it's group if necessary
					if (conf.group) {
						var groupAlias = 'g' + conf.group;	// alter the group's name internally so it doesn't interfere with the popover namespace (ie. the uids)
						order[groupAlias].remove (uid);
						if (order[groupAlias].length <= 0) {	// remove the group if it's empty
							delete order[groupAlias];
							order.topLevel.remove (groupAlias);
						}
					}
				}

				// re-apply the popover order and close the mask if necessary
				applyFocusOrder ();

				// close effect
				var effect = conf.effect;
				if (!$.core.popover.settings.popoverAnimations)
					effect = 'noAnimate';
				effects[effect][1].call (api, function () {

					e.type = 'onClose';
					$popover.trigger (e);

					// remove the popover from the dom if necessary
					if (conf.removeOnClose)
						$popover.remove ();

					// stop observing mouse movements if the popover is left in the dom
//					if (eff[2]) // if it was allowed to follow the mouse when closing
						$('body').unbind ('mousemove.core-popover' + uid);
				});

				// unbind the keyboard / click actions
//				$(document).unbind ('click.popover' + uid).unbind ('keydown.core-popover' + uid);

				// close any other associated popovers that need closing
				$.each (popoverApisToCloseWhenClosing, function () { this.close (); });

				return $popover;
			},

			// close the popover after the given amount of time (in ms)
			closeDelayed: function (delayMS) {
				if (opened) {

					// cancel any existing closeDelayed timeout
					api.cancelCloseDelayed ();

					// start the close delayed process
					if (delayMS <= 0)
						api.close ();
					closeTimeout = setTimeout (function () { api.close (); }, delayMS);
				}
				return api;
			},

			// cancel the popover's delayed closure
			cancelCloseDelayed: function () {
				clearTimeout (closeTimeout);
				return api;
			},

			// focus the popover,  bringing it to the foreground
			focus: function () {

				// if this popover already has focus,  don't do any more calculations to re-focus it
				if (focusedUid == uid)
					return api;

				// if this popover is a part of a group then bring that group to the foreground
				if (conf.group) {

					var groupAlias = 'g' + conf.group;	// alter the group's name internally so it doesn't interfere with the popover namespace (ie. the uids)

					// bring the group to the top of the list
					if ($.inArray (groupAlias, order.topLevel) >= 0) {
						order.topLevel.remove (groupAlias);
						order.topLevel.push (groupAlias);

						// bring the popover to the top of the list within the group
						if (order[groupAlias] !== undefined) {
							if ($.inArray (uid, order[groupAlias]) >= 0) {
								order[groupAlias].remove (uid);
								order[groupAlias].push (uid);
							}
						}
					}
				}
/**
				// or just bring this individual popover to the top of the list
				else {
					if ($.inArray (uid, order.topLevel) >= 0) {
						order.topLevel.remove (uid);
						order.topLevel.push (uid);
					}
				}
/**/

				applyFocusOrder ();
				return api;
			},

			processJsonResponse: function (response) {

				// if the response came back as an json object then process it
				if (typeof (response) == 'object') {


					var popoverIsClosing = false;
					var redirectingUser = false;

					// loop through each instruction
					$(response).each (function (index, value) {
						switch (value[0]) {

							// eXecute (eval) "at start"
							case 'x1':
								api.eval (value[1]);
								break;
						}
					});

					// loop through each instruction
					$(response).each (function (index, value) {
						switch (value[0]) {

							// close popover
							case 'c':
								// close with a delay
								if (value[1] !== undefined)
									api.closeDelayed (value[1]);
								// or close straight away
								else
									api.close ();
								popoverIsClosing = true;
								break;

							// redirect user
							case 'r':
								document.location.href = value[1];
								redirectingUser = true;
								break;

							// reload the page
							case 'rl':
								window.location.reload ();
								redirectingUser = true;
								break;
						}
					});

					if (!redirectingUser) {

						// loop through each instruction
						$(response).each (function (index, value) {
							switch (value[0]) {

								// update ifh block
								case 'i':
									api.replaceContentBoxHtml ('<div class="' + $.core.ajaxForm.settings.ifhBlockClass + '">' + value[1] + '</div>', value[2], value[3]);
									break;

								// update content block
								case 'co':
									api.replaceContentBoxHtml (value[1], null, null);
									break;

								// update element inside the popover (update element/s found with the given selector with the new html)
								case 'p':
									$popover.find (value[1]).html (api.convertElementIds (value[2]));
									break;
							}
						});

						// loop through each instruction
						$(response).each (function (index, value) {
							switch (value[0]) {

//								// message
//								case 'm':
//									// no messages for popover ajax responses
//									break;

								// focus field
								case 'f':
									$('#' + convert_id (value[1], uid)).focusDelayed ();
									break;

								// update element
								case 'u':
									$(value[1]).html (value[2]);
									break;

								// replace element
								case 'rp':
									$(value[1]).replaceWith (value[2]);
									break;

								// close popover selector
								case 'cps':
									$popover.find (value[1]).bind ('click.core-popover-close', function () {
										api.close ();
									});
									break;
							}
						});

						// loop through each instruction
						$(response).each (function (index, value) {
							switch (value[0]) {

								// eXecute (eval) "at end"
								case 'x2':
									api.eval (value[1]);
									break;
							}
						});
					}

					if (needToShowNewContentBlock)
						api.showNewContentBox ();

					// reverse the dialogue buttons if necessary
					api.applyDialogueButtonReverse ();
				}
			},

			// replace the contents of the contentBox in this popover
			replaceContentBoxHtml: function (html, ifhKey, ifhPage) {
				var $contentBlock = $popover.find ('.core-contentBox');
				if ($contentBlock.length) {

					// replace the ifh block with the new content (if new content was specified)
					// convert the ids of the elements in the new html
					var $newContentBlock = api.convertElementIds ('<div class="' + $.core.ajaxForm.settings.ifhBlockClass + '">' + html + '</div>');

//					existingMessageElementIds = [];
//					visibleMessageElementIds = [];
//					messageIdsToAppearThisTime = [];
//					newMessages = [];

					// set the uid inside any ajax forms within the popover
					// and then activate them
					if ($.fn.ajaxForm !== undefined) {
						$newContentBlock.find ('.' + $.core.ajaxForm.settings.ajaxFormClass).map (function () {
							$(this).ajaxForm ();
							var ajaxFormApi = $(this).data ('ajaxForm');
							if (ajaxFormApi)
								ajaxFormApi.setPopoverUid (uid).setIfhKey (ifhKey).setIfhPage (ifhPage);
						});
					}
// CHECK THIS
// move this jsMessage initialisation into the ajaxForm api
//						$newContentBlock.find ('.' + $.core.ajaxForm.settings.ajaxFormClass).ajaxForm ().data ('ajaxForm').set_popover_uid (uid).end ().find ('.jsMessage').css ('display', 'none').addClass ('message').html ('').map (function () { existingMessageElementIds.push ($(this).attr ('id')); });
//					$popover.find ('.' + $.core.ajaxForm.settings.ajaxFormClass).ajaxForm ();

					// replace the content
					$contentBlock.html ($newContentBlock);

					// set the flag so that the block can be shown nicely and the popover repositioned when the whole ajax response has been processed
					needToShowNewContentBlock = true;

					api.positionArrows ();
				}
				return api;
			},

			showNewContentBox: function () {

				var $newContentBox = $popover.find ('.core-contentBox').find ('div').eq (0);
//				var $newContentBox = $popover.find ('.core_ifhBlock');

				// reposition the popover if necessary
				var originalOffset = $popover.offset ();
				var newOffset = originalOffset;

				// make the popover appear in the best starting spot (the dimension change of the popover may have changed this)
				if (conf.recalculateStartPositionAfterAjax)
					newOffset = api.getStartCoordinates ($popover.width (), $popover.height ());

				// make sure the popover appears on the page's viewable area if necessary
				newOffset = api.getOnScreenCoordinates ($popover.width (), $popover.height (), newOffset.left, newOffset.top);

				// the 'show' and the 'position animation' happen as two separate concurrent things,  can this happen as one action to smoothe the animation?
				$newContentBox.hide ();
				if ((originalOffset.left != newOffset.left) || (originalOffset.top != newOffset.top))
					$popover.animate ({ left: '-=' + (originalOffset.left - newOffset.left), top: '-=' + (originalOffset.top - newOffset.top) });

				$newContentBox.show (($.core.popover.settings.popoverAnimations) ? 'blind' : null);

				setTimeout (api.positionArrows, 400);	// re-position the arrows if necessary

				needToShowNewContentBlock = false;
				return api;
			},

			// reverse the dialogue buttons if necessary
			applyDialogueButtonReverse: function () {

				if ($.core.reverseChildren)
					$popover.find ('.core-dialogueButtons>div').reverseChildren ('dialogueButtons');

				return api;
			},

			// determine the best onscreen position for this popover
			// use the given popover width/height,  or if empty then use the popover's actual width/height
			getStartCoordinates: function (popoverWidth, popoverHeight) {
				var left = 0;
				var top = 0;

				// position the overlay in relation to the given element
				// if more than one is found it'll use the first one
				var baseOffset = null;
				if (conf.attachTo != null) {
					if (conf.attachTo == 'mouse') {
						baseOffset = { left: $.core.mouseX ? $.core.mouseX : 0, top: $.core.mouseY ? $.core.mouseY : 0 };	// the offset to the top/left of the mouse position
						var baseWidth = 16;	// assume a 16 x 16 pixel mouse cursor
						var baseHeight = 16;
					}
					else if ($(conf.attachTo).length) {
						var attachToElement = $(conf.attachTo);
						baseOffset = attachToElement.offset ();	// the offset to the top/left of the attachTo element
						var baseWidth = attachToElement.outerWidth ();
						var baseHeight = attachToElement.outerHeight ();
					}
				}
				// position the overlay in relation to the screen
				if (baseOffset === null) {
					var baseOffset = { top: $w.scrollTop (), left: $w.scrollLeft () };	// the offset to the top/left of the document's viewable area
//					var baseOffset = { top: 0, left: 0 };	// the offset to the top/left of the document
					var baseWidth = $w.width ();
					var baseHeight = $w.height ();
				}
//alert (var_dump (baseOffset));
				// determine the popover's dimensions
				if (popoverWidth === undefined)
					popoverWidth = $popover.outerWidth ();
				if (popoverHeight === undefined)
					popoverHeight = $popover.outerHeight ();




				// adjust x
				// percentage
				if (is_float (conf.baseAttachDirectionX))
					left = baseOffset.left + (baseWidth * conf.baseAttachDirectionX);
				// or position
				else {
					switch (conf.baseAttachDirectionX) {
						case 'left': left = baseOffset.left;	break;
						case 'right': left = baseOffset.left + baseWidth;	break;
						default: left = baseOffset.left + (baseWidth / 2);	break;	// 'center'
					}
				}
				// percentage
				if (is_float (conf.popoverAttachDirectionX))
					left -= popoverWidth * conf.popoverAttachDirectionX;
				// or position
				else {
					switch (conf.popoverAttachDirectionX) {
						case 'left': left -= 0;	break;
						case 'right': left -= popoverWidth;	break;
						default: left -= (popoverWidth / 2);	break;	// 'center'
					}
				}
				left += conf.attachOffsetX;
//				left -= $w.scrollLeft ();




				// adjust y
				// percentage
				if (is_float (conf.baseAttachDirectionY))
					top = baseOffset.top + (baseHeight * conf.baseAttachDirectionY);
				// or position
				else {
					switch (conf.baseAttachDirectionY) {
						case 'top': top = baseOffset.top;	break;
						case 'center': top = baseOffset.top + baseHeight / 2;	break;
						case 'bottom': top = baseOffset.top + baseHeight;	break;
					}
				}
				// percentage
				if (is_float (conf.popoverAttachDirectionY))
					top -= popoverHeight * conf.popoverAttachDirectionY;
				// or position
				else {
					switch (conf.popoverAttachDirectionY) {
						case 'top': top -= 0;	break;
						case 'center': top -= popoverHeight / 2;	break;
						case 'bottom': top -= popoverHeight;	break;
					}
				}
				top += conf.attachOffsetY;
//				top -= $w.scrollTop ();

//				return api.getOnScreenCoordinates (popoverWidth, popoverHeight, left, top);
				return { top: parseInt (top), left: parseInt (left) };
			},

			// determine the best onscreen position for this popover
			// use the given popover width/height,  or if empty then use the popover's actual width/height
			// use the given top/left offsets,  or if empty then use the popover's actual top/left
			getOnScreenCoordinates: function (popoverWidth, popoverHeight, left, top) {

				// determine the popover's position
				var offset = $popover.offset ();	// the offset to the top/left of the popover
				if (left === undefined)
					left = offset.left;
				if (top === undefined)
					top = offset.top;

				// determine the popover's dimensions
				if (popoverWidth === undefined)
					popoverWidth = $popover.outerWidth ();
				if (popoverHeight === undefined)
					popoverHeight = $popover.outerHeight ();

				// adjust x
				// make sure the overlay won't appear off the screen
				if (((conf.startOnScreenX !== null) && (conf.startOnScreenX))
				|| ((conf.startOnScreenX === null) && (conf.startOnScreen))) {
					var pageRight = $w.scrollLeft () + $w.width ();
					// not too far right
					if (left + popoverWidth > pageRight)
						left = pageRight - popoverWidth;
					// not too far left
					if (left < $w.scrollLeft ())
						left = $w.scrollLeft ();
				}

				// adjust y
				// make sure the overlay won't appear off the screen
				if (((conf.startOnScreenY !== null) && (conf.startOnScreenY))
				|| ((conf.startOnScreenY === null) && (conf.startOnScreen))) {
					var pageBottom = $w.scrollTop () + $w.height ();

					// not too far down
					if (top + popoverHeight > pageBottom)
						top = pageBottom - popoverHeight;
					// not too far up
					if (top < $w.scrollTop ())
						top = $w.scrollTop ();
				}

				return { top: top, left: left };
			},

			// reposition the popover if necessary
			positionNeatlyOnScreen: function () {

				var originalOffset = $popover.offset ();
				var newOffset = api.getOnScreenCoordinates ();
				if ((originalOffset.left != newOffset.left) || (originalOffset.top != newOffset.top))
					$popover.animate ({ left: '-=' + (originalOffset.left - newOffset.left), top: '-=' + (originalOffset.top - newOffset.top) });

				setTimeout (api.positionArrows, 400);	// re-position the arrows if necessary

				return api;
			},

			// add the arrow html to the popover and position it
			addArrow: function (pointTo) {

				// loop through the array of pointTo elements specified
				var addedArrow = false;
				$.each ($(pointTo), function (index, pointTo) {

					// if it's pointing to something then use it
					if ((pointTo != null) && (pointTo != 'mouse')) {

						// account for the fact that the element may be a jQuery object of multiple elements (eg. $('.className'))
						$.each ($(pointTo), function (index, pointTo) {

							// create the arrow
							var $arrow = $($.core.popover.conf.arrowHtml);

							// add the arrow html to the popover
							var $outer = $popover.prepend ($arrow).find ('.core-outer');

							// find out the desired dimensions from the css class
							var arrowBorderWidth = parseInt ($outer.css ('borderBottomWidth').replace(/[^0-9]/g, '')) + 1;
							var arrowDepth = parseInt ($outer.css ('height').replace(/[^0-9]/g, ''));
							var arrowBreadth = parseInt ($outer.css ('width').replace(/[^0-9]/g, ''));

							if (!arrowBorderWidth)
								arrowBorderWidth = 2;
							if (!arrowDepth)
								arrowDepth = 12;
							if (!arrowBreadth)
								arrowBreadth = 16;

							arrows.push (
							{	$pointTo: $(pointTo),
								$arrow: $arrow,
								arrowBorderWidth: arrowBorderWidth,
								arrowDepth: arrowDepth,
								arrowBreadth: arrowBreadth
							});

							// prepare the arrow's css
							$popover.find ('.core-outer, .core-inner').css ({ width: 0, height: 0 });






							// only observe the popover click + drag the first time an arrow is added
							if (arrows.length == 1) {

								// if the user clicks on the popover and holds the button down (probably to move the popover)
								// then re-calculate the position of the arrow
								$popover.bind ('mousedown.core-popover-arrowPosMove', function () {

									// adjust the arrow position upon mouse move
									$('body').bind ('mousemove.core-popover-arrowPosMove' + uid, function () { api.positionArrows (); });

									// when the mouse button is released,  stop observing the mouse move
									$popover.bind ('mouseup.core-popover-arrowPosMove', function () {
										$('body').unbind ('mousemove.core-popover-arrowPosMove' + uid);
										$popover.unbind ('mouseup.core-popover-arrowPosMove');
									});
								});
							}

							addedArrow = true;
						});
					}
				});

				// position the arrows in the most appropriate place around the popover
				if (addedArrow)
					api.positionArrows ();

				return api;
			},

			// add the arrow html to the popover and position it
			removeArrow: function () {

				// remove the latest arrow
				arrowInfo = arrows.pop ();
				arrowInfo.$arrow.remove ();

				// stop observing the click + drag (to adjust the arrow's position)
				if (!arrows.length) {
					$popover.unbind ('.core-popover-arrowPosMove');
					$('body').unbind ('.core-popover-arrowPosMove' + uid);
				}

				return api;
			},

			// re/position the arrow
			positionArrows: function () {

				$.each (arrows, function (index, arrowInfo) {

					var arrowBreadthLeft = parseInt (arrowInfo.arrowBreadth / 2);
					var arrowBreadthRight = arrowInfo.arrowBreadth - arrowBreadthLeft;




					var baseOffset = arrowInfo.$pointTo.offset ();	// the offset to the top/left of the attachTo element
					var baseWidth = arrowInfo.$pointTo.outerWidth ();
					var baseHeight = arrowInfo.$pointTo.outerHeight ();

					var popoverOffset = $popover.offset ();	// the offset to the top/left of the popover element
					var popoverWidth = $popover.outerWidth ();
					var popoverHeight = $popover.outerHeight ();




					// work out the visual horizontal distance to the attached element (which ever of the left and right distances are closer)
					var origHorizontalDistance = Math.min (
						Math.abs (baseOffset.left - (popoverOffset.left + popoverWidth)),	// popover <---> attach
						Math.abs ((baseOffset.left + baseWidth) - popoverOffset.left)		// attach <----> popover
					);
					var horizontalDistance = origHorizontalDistance;

					// if the popover overlaps horizontally with the attached element,  the horizontal distance is 0
					if ((popoverOffset.left <= baseOffset.left + baseWidth) && (popoverOffset.left + popoverWidth >= baseOffset.left))
						horizontalDistance = 0;

					// work out the visual vertical distance to the attached element (which ever of the top and bottom distances are closer)
					var origVerticalDistance = Math.min (
						Math.abs (baseOffset.top - (popoverOffset.top + popoverHeight)),	// popover <---> attach
						Math.abs ((baseOffset.top + baseHeight) - popoverOffset.top)		// attach <----> popover
					);
					var verticalDistance = origVerticalDistance;

					// if the popover overlaps vertically with the attached element,  the vertical distance is 0
					if ((popoverOffset.top <= baseOffset.top + baseHeight) && (popoverOffset.top + popoverHeight >= baseOffset.top))
						verticalDistance = 0;


					// handle the case when both the horizontal and vertical of the popover overlaps with the attach element
					var invertDirection = false;
					if ((horizontalDistance == 0) && (verticalDistance == 0)) {
						horizontalDistance = origHorizontalDistance;
						verticalDistance = origVerticalDistance;
						invertDirection = true;
					}




					// based on which visual distance is further away from the attached element
					// work out which direction the arrow needs to go
					var rotateCount = 0;
					var xOffset = 0;
					var yOffset = 0;
					var arrowMid = null;
					if (((!invertDirection) && (horizontalDistance > verticalDistance))
					|| ((invertDirection) && (horizontalDistance < verticalDistance))) {

						// work out which direction the popover is in in relation to the attached element
						if ((baseOffset.left + (baseWidth / 2)) - (popoverOffset.left + (popoverWidth / 2)) > 0) {
							rotateCount = 1;	// >
							xOffset = popoverWidth - (arrowInfo.arrowBorderWidth - 1);
						}
						else {
							rotateCount = 3;	// <
							xOffset = -arrowInfo.arrowDepth + (arrowInfo.arrowBorderWidth - 1);
						}

						// slide the arrow up and down based on the relative vertical position
						yOffset = parseInt ((baseOffset.top + (baseHeight / 2)) - (arrowInfo.arrowBreadth / 2) - popoverOffset.top);
						if (yOffset > popoverHeight - arrowInfo.arrowBreadth - conf.arrowEdgeBuffer)
							yOffset = popoverHeight - arrowInfo.arrowBreadth - conf.arrowEdgeBuffer;
						if (yOffset < conf.arrowEdgeBuffer)
							yOffset = conf.arrowEdgeBuffer;
					}
					else {

						// work out which direction the popover is in in relation to the attached element
						if ((baseOffset.top + (baseHeight / 2)) - (popoverOffset.top + (popoverHeight / 2)) > 0) {
							rotateCount = 2;	// \/
							yOffset = popoverHeight - (arrowInfo.arrowBorderWidth - 1);
						}
						else {
							rotateCount = 0;	// /\
							yOffset = -arrowInfo.arrowDepth + (arrowInfo.arrowBorderWidth - 1);
						}

						// slide the arrow left and right based on the relative horizontal position
						xOffset = parseInt ((baseOffset.left + (baseWidth / 2)) - (arrowInfo.arrowBreadth / 2) - popoverOffset.left);
						if (xOffset > popoverWidth - arrowInfo.arrowBreadth - conf.arrowEdgeBuffer)
							xOffset = popoverWidth - arrowInfo.arrowBreadth - conf.arrowEdgeBuffer;
						if (xOffset < conf.arrowEdgeBuffer)
							xOffset = conf.arrowEdgeBuffer;
					}

					// flip the arrow around
					var directions = ['top', 'right', 'bottom', 'left'];
					var directions2 = [1, 0, 0, 0];
					for (var count = 0; count < rotateCount; count++) {
						directions.push (directions.shift ());
						directions2.push (directions2.shift ());
					}



					// generate the latest css values
					var cssOuter = {};
					cssOuter['border-' + directions [0] + '-width'] = 0;
					cssOuter['border-' + directions [1] + '-width'] = arrowBreadthLeft + 'px';
					cssOuter['border-' + directions [2] + '-width'] = arrowInfo.arrowDepth + 'px';
					cssOuter['border-' + directions [3] + '-width'] = arrowBreadthRight + 'px';
					cssOuter['border-' + directions [0] + '-color'] = 'transparent';
					cssOuter['border-' + directions [1] + '-color'] = 'transparent';
					cssOuter['border-' + directions [2] + '-color'] = '';
					cssOuter['border-' + directions [3] + '-color'] = 'transparent';
					cssOuter['left'] = xOffset + 'px';
					cssOuter['top'] = yOffset + 'px';

					var cssInner = {};
					cssInner['border-' + directions [0] + '-width'] = 0;
					cssInner['border-' + directions [1] + '-width'] = (Math.min (arrowBreadthLeft - arrowInfo.arrowBorderWidth, arrowInfo.arrowBreadth)) + 'px';
					cssInner['border-' + directions [2] + '-width'] = (Math.min (arrowInfo.arrowDepth - arrowInfo.arrowBorderWidth, arrowInfo.arrowBreadth)) + 'px';
					cssInner['border-' + directions [3] + '-width'] = (Math.min (arrowBreadthRight - arrowInfo.arrowBorderWidth, arrowInfo.arrowBreadth)) + 'px';
					cssInner['border-' + directions [0] + '-color'] = 'transparent';
					cssInner['border-' + directions [1] + '-color'] = 'transparent';
					cssInner['border-' + directions [2] + '-color'] = '';
					cssInner['border-' + directions [3] + '-color'] = 'transparent';

					cssInner['left'] = ((
						((directions2[0] * -(arrowBreadthRight - arrowInfo.arrowBorderWidth)))
						+ (directions2[3] * -arrowInfo.arrowDepth)
						+ (directions2[2] * -(arrowBreadthLeft - arrowInfo.arrowBorderWidth))
						+ (directions2[1] * arrowInfo.arrowBorderWidth)
						)) + 'px';

					cssInner['top'] = ((
						((directions2[0] * arrowInfo.arrowBorderWidth))
						+ (directions2[3] * -(arrowBreadthRight - arrowInfo.arrowBorderWidth))
						+ (directions2[2] * -arrowInfo.arrowDepth)
						+ (directions2[1] * -(arrowBreadthLeft - arrowInfo.arrowBorderWidth))
						)) + 'px';

					// update the arrow's css with the latest values
					arrowInfo.$arrow.find ('div.core-outer')
					.css (cssOuter)
					.find ('div.core-inner').css (cssInner);
				});

				return api;
			},

			// add a popover to close when this popover closes
			addPopoverToClose: function (tempApi) {
				if ($.inArray (tempApi, popoverApisToCloseWhenClosing) < 0)
					popoverApisToCloseWhenClosing.push (tempApi);
				return api;
			},

			// remove a 'popover to close' when this popover closes
			removePopoverToCloseLink: function (tempApi) {
				popoverApisToCloseWhenClosing.remove (tempApi);
				return api;
			},

			// create a child popover
			// this is the same as the regular $.createPopover () function but it attaches the new popover to this popover by default (ie. the starting position is based upon the position of this popover)
			// and an association is established between the popovers so that when this (the parent) popover closes,  the child will too
			// and the new popover is put into the same group is this popover
			createChildPopover: function (substitutionValues, tempConf) {

				tempConf = $.extend (true, {}, { attachTo: api.getPopover (), group: conf.group, popoverFunction: null }, tempConf);
				if (!$.isFunction (tempConf.popoverFunction))
					tempConf.popoverFunction = $.createPopover;

				var tempApi = tempConf.popoverFunction (substitutionValues, tempConf).data ('popover');
				api.addPopoverToClose (tempApi);

				return tempApi.getPopover ();
			},

			// create a sibling popover
			// this is the same as the regular $.createPopover () function but it attaches the new popover to this popover by default (ie. the starting position is based upon the position of this popover)
			// and the new popover is put into the same group is this popover
			createSiblingPopover: function (substitutionValues, tempConf) {
				tempConf = $.extend (true, {}, { attachTo: api.getPopover (), group: conf.group, popoverFunction: null }, tempConf);
				if (!$.isFunction (tempConf.popoverFunction))
					tempConf.popoverFunction = $.createPopover;

				var $tempPopover = tempConf.popoverFunction (substitutionValues, tempConf);
				return $tempPopover;
			},




			// eval the given code
			// has access to $popover and api
			eval: function (code) {
				eval (code);
				return api;
			},

			// return the popover element
			getPopover: function () {
				return $popover;
			},
/**
			getClosers: function () {
				return closers;
			},
/**/
			// return whether the popover has been opened or not
			isOpened: function () {
				return opened;
			},

			// manipulate start, finish and speeds
			getConf: function () {
				return conf;
			},

			// get the uid
			getUid: function () {
				return uid;
			},

			// convert the given id (based on this popover's uid)
			convertId: function (orig) {
				return convert_id (orig, uid);
			},

			// convert the ids of the elements in the given html (or element)
			// returns a jQuery object
			convertElementIds: function ($html) {

				$html = $($html);
				var $tempHtml = $('<div></div>').append ($html);	// put the html into a dummy <div> so that the .find function below covers the top-most element itself

				// find elements with an id and convert them
				$tempHtml.find ('[id]').attr ('id', function (index, orig) { return convert_id (orig, uid); });
				// find the elements with a "for" and convert them
				$tempHtml.find ('[for]').attr ('for', function (index, orig) { return convert_id (orig, uid); });

				return $html;
			}
		});

		// assign the callbacks
		$.each (['onBeforePosition', 'onBeforeShow', 'onShow', 'onBeforeClose', 'onClose'], function (i, name) {

			// configuration
			if ($.isFunction (conf[name]))
				$popover.bind (name, conf[name]);

			// API
			$popover[name] = function (fn) {
				$popover.bind (name, fn);
				return $popover;
			};
		});
/**		
		// close button
		closers = $popover.find(conf.close || ".close");

		if (!closers.length && !conf.close) {
			closers = $('<a class="close"></a>');
			$popover.prepend(closers);
		}

		closers.click(function(e) {
			api.close(e);
		});
/**/

		// private functions

		// give the popovers according to the current order of popovers in the 'order' object of arrays
		var applyFocusOrder = function () {
//			clearTimeout (setClickCloseTimeout);

			// push the special 'toolTip' and 'helper' group to the top
			$.each (['ghelper','gtoolTip'], function (i, groupAlias) {
				if ($.inArray (groupAlias, order.topLevel) >= 0) {
					order.topLevel.remove (groupAlias);
					order.topLevel.push (groupAlias);
				}
			});


			// generate a flat list of the popovers in increasing desired z-index order
			// loop through the 'topLevel' popover group's order
			var uids = [];
			var groupUidMaskInfo = {};
			for (var count = 0; count < order.topLevel.length; count++) {
/**
				// a single popover
				if (instances[order.topLevel[count]] !== undefined)
					uids.push (order.topLevel[count]);
//					instances[order.topLevel[count]].getPopover ().css ('z-index', zIndex++);

				// a popover group
				else {
/**/
					// loop through this popover group's order
					var group = order.topLevel[count];
					for (var count2 = 0; count2 < order[group].length; count2++) {
						if (instances[order[group][count2]] !== undefined) {
							uids.push (order[group][count2]);

							// if this particular popover wants the mask to be applied to it's group and no other popover in it's group has applied the mask to the group,  record this popover as being the one to look for for this group's mask details
							if ((groupUidMaskInfo[group] === undefined) && (instances[order[group][count2]].getConf ().applyMask))
								groupUidMaskInfo[group] = order[group][count2];
						}
					}
//				}
			}

			// loop through the popovers now that they're in order,  and work out which one (popover or group) is the top-most one that requires a mask
			var topUidWithMask = null;
			var topGroupWithMask = null;
//			var relevantGroupPopoverUid = null;	// the popover uid with the mask details,  that are to be applied to the group
			for (var count = 0; count < uids.length; count++) {

				// if this popover has a mask then record it's uid
				var tempConf = $.extend (true, {}, instances[uids[count]].getConf ());
				if (tempConf.applyMaskToSelf) {
					topUidWithMask = uids[count];
					topGroupWithMask = tempConf.group;
//					relevantGroupPopoverUid = uids[count];
				}

				// otherwise,  if this popover wants to apply the mask to it's group record this popover's group
				else if ((tempConf.group != null) && (tempConf.applyMask)) {
					if (tempConf.group != topGroupWithMask) {
						topUidWithMask = null;
						topGroupWithMask = tempConf.group;
//						relevantGroupPopoverUid = uids[count];
					}
				}
			}
			// if an individual popover is at the top then forget about the top group
			if (topUidWithMask != null) {
				topGroupWithMask = null;
//				relevantGroupPopoverUid = null;
			}

			// if it's a group at the top,  find the back-most popover
			if (topGroupWithMask != null) {
				var groupAlias = 'g' + topGroupWithMask;	// alter the group's name internally so it doesn't interfere with the popover namespace (ie. the uids)
				topUidWithMask = order[groupAlias][0];
//				relevantGroupPopoverUid = order[group][0];
			}




			// apply the z-indexes to the popovers and mask
			var zIndex = $.core.popover.settings.zIndex;	// start at the z-index number stated by the settings
			var topUid = null;
			var focusUid = null;
			for (var count = 0; count < uids.length; count++) {

				if (($.core.popover.settings.allowMask) && (uids[count] == topUidWithMask))
					$('#exposeMask').css ('z-index', zIndex++);
//				else if (uids[count] == relevantGroupPopoverUid)
//					$('#exposeMask').css ('z-index', zIndex++);
				instances[uids[count]].getPopover ().css ('z-index', zIndex++).removeClass ('core-popoverFocused');

				topUid = uids[count];
				if ($.inArray (instances[uids[count]].getConf ().group, ['toolTip', 'helper']) < 0)
					focusUid = uids[count];
			}
			if (focusUid)
				instances[focusUid].getPopover ().addClass ('core-popoverFocused');

			// record that this popover is focused so that the focus calculations don't need to run next time this popover is clicked
			focusedUid = topUid;

			// close the mask if necessary
//			if ((topUidWithMask == null) && (relevantGroupPopoverUid == null) && ($.mask.isLoaded ()))
			if (($.core.popover.settings.allowMask) && (topUidWithMask == null) && ($.mask.isLoaded ()))
				$.mask.close ();

			



			// handle the easyClose events (click outside the popover + esc-keypress)
			$(document).unbind ('click.core-popover');
			$(document).unbind ('keydown.core-popover');
			if (instances[topUid] != null) {

				var tempConf = instances[topUid].getConf ();

				// when window is clicked outside overlay, close the popover
				if ((tempConf.easyClose) && (tempConf.closeOnClick !== false)) {
					var tempApi = instances[topUid];
					setClickCloseTimeout = setTimeout (function () {	// stop the popover from closing straight away if the user clicked something to make this appear
						$(document).unbind ('click.core-popover');
						$(document).bind ('click.core-popover', function (e) {
							if (!$(e.target).parents ('.core-popover').length)	// .core_popover
								tempApi.close (e);
						});
					}, 1);
				}

				// keyboard::escape
				// one callback is enough if multiple instances are loaded simultaneously
				if ((tempConf.easyClose) && (tempConf.closeOnEsc !== false)) {
					var tempApi = instances[topUid];
					$(document).one ('keydown.core-popover', function (e) {
						if (e.keyCode == 27)
							tempApi.close (e);
					});
				}
			}

			return api;
		};

		// add this popover to the popover order list so it can be ordered
		var addThisPopoverToInstances = function () {

			instances[uid] = api;	// add this popover to the list

			// add this popover to the list
			// a popover that's in a group
//			if (conf.group) {
				// create an order array for the group,  and place that group inside the 'topLevel' order array
				var groupAlias = 'g' + conf.group;	// alter the group's name internally so it doesn't interfere with the popover namespace (ie. the uids)
				order[groupAlias] = order[groupAlias] || [];
				order[groupAlias].push (uid);

				if ($.inArray (groupAlias, order.topLevel) < 0)
					order.topLevel.push (groupAlias);

				// bring this group to the front
				order.topLevel.remove (groupAlias);
				order.topLevel.push (groupAlias);
//			}
			// a single popover (not in a group)
//			else
//				order.topLevel.push (uid);

			// give the popovers their respective z-indexes
			applyFocusOrder ();

			return api;
		};

		// initialise the popover
		var init = function () {

			// add this popover to the popover order list so it can be ordered
			addThisPopoverToInstances ();

			// make it so that when this popover is clicked,  it will be brought into focus
			$popover.mousedown (api.focus);
		};



		// show the popover
		init ();
	}

	// jQuery plugin initialisation
	$.fn.popover = function (conf) {

		// merge the caller's conf with the default conf
		conf = $.extend (true, {}, $.core.popover.conf, conf);

		// turn each selected element into a popover
		this.each (function () {

			var $this = $(this);

			// only apply the popover to this element if it hasn't already been applied
			if (!$this.data ('popover')) {

				var tempConf = $.extend (true, {}, conf);	// clone the conf

				// if the popover is to be attached to the mouse
				if (tempConf.followMouse) {
					tempConf.fixed = false;			// make sure it isn't set into a "fixed" position because this causes position problems when scrolling
					tempConf.attachTo = 'mouse';	// make it's start position where the mouse is
				}

				var api = new popover ($this, tempConf);	// turn this element into a popover
				$this.data ('popover', api);				// record the api within this element for later
				api.open ();
			}
		});

		return this;
	};

}) (jQuery);






























// popovers
(function ($) {
	// create a new popover (create a dom element and turn it into an overlay)
	$.createPopover = function (substitutionValues, conf) {

		// apply the default template if not specified
		conf = $.extend (true, {}, { template: $.core.popover.conf.template }, conf);

		// first make sure the template exists
		if ($.popoverTemplates[conf.template] !== undefined) {

			// grab the template
			var template = $.popoverTemplates[conf.template];



			// apply this template's default options
			conf = $.extend (true, {}, template.conf, conf);

			// apply the default dialogue popover options
			conf = $.extend (true, {}, $.core.popover.dialogueConf, conf);

			// make sure each button has default values if they weren't specified
			if (!$.isArray (conf.buttons))
				conf.buttons = [];
			$.each (conf.buttons, function (index, buttonConf) {
				conf.buttons[index] = $.extend (true, {}, $.core.popover.buttonConf, buttonConf);
			});

			// if some buttons were specified then add the 'dialogueButtons' div to the substitution values so it's added into the popover
			substitutionValues.dialogueButtons = (conf.buttons.length ? '<div class="core-dialogueButtons"><div></div></div>' : '');

			// if there are some buttons,  add them to the popover onBeforePosition
			// and link the onClose event to the isCancel buttons
			if (conf.buttons.length) {

				var cancelling = true;	// changed when 'Yes' has been clicked,  so that when closing,  the cancel functions aren't called

				//
				var origOnBeforePosition = conf.onBeforePosition;
				conf.onBeforePosition = function (e) {

					var $popover = $(this);
					var popoverApi = $popover.data ('popover');


					// add the buttons to the popover
					var $dialogueButtonsDiv = $popover.find ('div.core-dialogueButtons>div');
					if ($dialogueButtonsDiv.length) {
						$.each (conf.buttons, function (index, buttonConf) {

							// create the button
							// if html was specified for the button
							if (buttonConf.html !== null) {
								// work out if the content is html for a button (or an anchor) and if so use that as the whole button
								if ($('<div>' + buttonConf.html + '</div>').children ().first ().is ('button,a,input[type=image],input[type=submit]'))
									var $temp = $(buttonConf.html);
								// or put it inside a button
								else
									var $temp = $('<button type="button">' + buttonConf.html + '</button>');
							}
							// or only plain text
							else
								$temp = $('<button type="button">' + htmlentities (buttonConf.text) + '</button>');

							// if it's an anchor,  make sure it won't send the user somewhere else upon click
							if ($temp.is ('a'))
								$temp.click (function (e) { e.preventDefault (); });

							// run the onClick when clicked
							if ($.isFunction (buttonConf.onClick)) {

								// if this is a cancel button then simply trigger the popover's close action
								// this (closing the popover) will cause this button's function to run
								if (buttonConf.isCancel)
									$temp.click (function () { popoverApi.close (); });

								// call the function and if it doesn't return false,  close the popover
								else {
									$temp.click (function () {

										cancelling = false;	// make sure the cancel function/s aren't called when the popover closes
										if (buttonConf.onClick (popoverApi) !== false) {
//											if (popoverApi.isOpened ()) {

												// if a url was specified and this is a button that will invoke that url
												if ((buttonConf.followUrl) && (conf.url)) {

													// load the url via ajax
													if (conf.useAjax) {

														var ajaxSettings = {};
														ajaxSettings.url = conf.url;

														// default values
														ajaxSettings = {
															url: conf.url,
															type: 'get',
															data: {	popoverUid: popoverApi.getUid () },
															complete: function () {},
															success: popoverApi.processJsonResponse
														};
														$.ajax (ajaxSettings);
													}
													// or redirect the user
													else
														document.location.href = conf.url;
												}
													
												// or close the popover
												else
													popoverApi.close ();
//											}
										}
										cancelling = true;
									});
								};
							}

							// add the function to the list
							$dialogueButtonsDiv.append ($temp);
						});
					}

					// call the function that was passed by the original caller
					if ($.isFunction (origOnBeforePosition)) {
						origOnBeforePosition.call (e);
						if (e.isDefaultPrevented ())
							return;
					}
				}

				//
				var origOnBeforeClose = conf.onBeforeClose;
				conf.onBeforeClose = function (e) {

					var $popover = $(this);
					var popoverApi = $popover.data ('popover');

					// provided the user hasn't clicked one of the other buttons
					if (cancelling) {
						cancelling = false;

						// call all the cancel button functions (unless one of them returns false)
						$.each (conf.buttons, function (index, buttonConf) {
							if ((buttonConf.isCancel) && ($.isFunction (buttonConf.onClick))) {
								if (buttonConf.onClick (popoverApi) === false) {
									e.preventDefault ();
									return;
								}
							}
						});
					}

					// check this in case one of the cancel functions also closed the popover
					if (popoverApi.isOpened ()) {

						// call the function that was passed by the original caller
						if ($.isFunction (origOnBeforeClose)) {
							origOnBeforeClose.call (e);
							if (e.isDefaultPrevented ())
								return;
						}
					}
				}
			}




			// generate the html
			// apply the relevant substitutions
			substitutionValues = $.extend ({}, substitutionValues);
			var html = template.html;
			$(template.substitutionNames).each (function (index, value) {
				html = html.replace ('%%' + value + '%%', (substitutionValues[value] || ''));
			});

			// create the popover element based on the html,
			// and attach the popover element to the page
			// make it appear
			// return it
			return $(html).addClass ('core-popover').appendTo ($('body')).popover (conf);
		}
		return null;
	};

	// create a dialogue popover which asks the user to confirm something
	$.createDialoguePopover = function (substitutionValues, conf) {

		// default values specific to the dialogue popover
		conf = $.extend (true, {}, $.core.popover.dialoguePopoverConf, conf);

		if (conf.messageHtml !== null)
			var content = conf.messageHtml;
		else
			var content = $('<div>' + nl2p (htmlentities (conf.message)) + '</div>').children ().first ().addClass ('core-spaceForCloseX').end ().last ().addClass ('core-last').end ().end ().html ();
		substitutionValues = $.extend (true, {}, substitutionValues, { content: content });

		// add two buttons by default
		if ((!$.isArray (conf.buttons)) || (!conf.buttons.length))
			conf.buttons = [
				{	text: conf.confirmButtonText,
					html: conf.confirmButtonHtml,
					onClick: conf.onConfirm,
					followUrl: true
				},
				{	text: conf.cancelButtonText,
					html: conf.cancelButtonHtml,
					onClick: conf.onCancel,
					isCancel: true
				}
			];

		return $.createPopover (
			substitutionValues,
			conf
		);
	};






	// upon clicking the given element/s,  alert the user with a confirmation popover before navigating to the desired url and/or performing the onConfirm event
	$.fn.confirmAction = function (conf) {

		// default values specific to the confirm action popover
		conf = $.extend (true, {}, $.core.popover.confirmActionPopoverConf, conf);

		// observe clicks on each $(this) element
		this.each (function () {

			var $element = $(this);
			var tempConf = $.extend (true, {}, conf);	// clone the conf

			// if 'self',  set attachTo to a reference of $element
			if (tempConf.attachTo == 'self')
				tempConf.attachTo = $element;

			// determine this element's url to go to upon confirm
			if ((tempConf.url === null) && ($element.is ('a')))
				tempConf.url = $element.attr ('href');

			$element.bind ('click.core-confirmAction', function (e) {
				e.preventDefault ();
				$.createDialoguePopover ({}, tempConf);
			});
		});

		return $(this);
	};

	// upon clicking the given element/s,  alert the user with a confirmation popover before navigating to the desired url and/or performing the onConfirm event
	$.fn.confirmDelete = function (conf) {

		// default values specific to the confirm delete popover
		conf = $.extend (true, {}, $.core.popover.confirmDeletePopoverConf, conf);

		// observe clicks on each $(this) element
		return $(this).confirmAction (conf);
	};

}) (jQuery);



































// popover triggers
(function($) {

	var eventMap = {
		mouseenter: 'mouseleave',
		mouseleave: 'mouseenter',

		mouseover: 'mouseout',
		mouseout: 'mouseover',

		mousedown: 'mouseup',
		mouseup: 'mousedown',

		focus: 'blur',
		blur: 'focus'
	};

	function popoverTrigger ($element, conf) {

		var api = this;
		var $element = $($element);
		var popoverApi = null;
		var content = null;
		var showHideTimeout = null;
		var activeEvents = [];

		// API methods
		$.extend (api, {

			// return the current content
			getContent: function () {
				return content;
			},

			// set new content
			// if the popover is open and the content has changed,  close and open it again
			setContent: function (newContent) {
				if (newContent != content) {
					content = newContent;
					if ((popoverApi) && (popoverApi.isOpened ()))
						api.close ().open ();
				}
				return api;
			},

			// open the popoverTrigger popover
			open: function () {
				clearTimeout (showHideTimeout);
				// show with a delay if necessary
				if (conf.showDelay > 0)
					showHideTimeout = setTimeout (reallyOpen, conf.showDelay);
				else
					reallyOpen ();
				return api;
			},

			// close the popoverTrigger popover
			close: function () {
				clearTimeout (showHideTimeout);
				// show with a delay if necessary
				if (conf.closeDelay > 0)
					showHideTimeout = setTimeout (reallyClose, conf.closeDelay);
				else
					reallyClose ();
				return api;
			},

			// observe the element's mouseover/mouseleave events to trigger/hide the popoverTrigger popover
			applyTriggers: function () {

				// only show the popover if there is some content to show
				if (content) {

					// bind the triggers
					// to show the popover
					if (conf.openTriggers.length) {

						$.each (conf.openTriggers.split (','), function (i, name) {

							$element.bind (name + '.core-popoverTrigger', function (e) {

								// if this a link that can be clicked to show the popover,  prevent it's default link-click action
								if ((name == 'click') && ($element.is ('a')))
									e.preventDefault ();

								// record that this event is active
								if ((eventMap[name]) && ($.inArray (name, activeEvents) < 0))
									activeEvents.push (name);

								api.open ();
							});
						});
					}

					// to hide the popover
					if (conf.closeTriggers.length) {
						$.each (conf.closeTriggers.split (','), function (i, name) {
							$element.bind (name + '.core-popoverTrigger', function (e) {

								// de-activate this event
								if ((eventMap[name]) && ($.inArray (eventMap[name], activeEvents) >= 0))
									activeEvents.remove (eventMap[name]);

								// only close the popover if none of the events are active
								if (activeEvents.length <= 0)
									api.close ();
							});
						});
					}
				}

				return api;
			}
		});




		// private functions
		// really open the popover
		var reallyOpen = function () {
			if ((!popoverApi) || (!popoverApi.isOpened ())) {
				popoverApi = conf.popoverFunction (
					{	content: content,
						title: conf.titleHtml },
					conf.popoverConf
				).data ('popover');

			}
			if (!conf.ignoreTriggerHiding)
				checkToSeeIfElementExistsInDom ();
			return api;
		};

		// really close the popover
		var reallyClose = function () {
			if (popoverApi) {
				// close the popover
				if (popoverApi.close ()) {
					popoverApi = null;	// remove the reference to the popoverApi that's just been closed
					activeEvents = [];	// reset the list of active elements
				}
			}
			return api;
		};

		// periodically check to see if the trigger element is still attached to the dom,
		// if not (possibly because the $element was hidden) then hide the popover
		var checkToSeeIfElementExistsInDom = function (started) {
			if (popoverApi) {
				if ((started) && (($element.closest ('body').length == 0) || ($element.is (':hidden')))) {
//					alert ($element.closest ('body').length + ' ' + ($('<div></div>').append ($element.clone ())).html ());
					reallyClose ();
				}
				showHideTimeout = setTimeout (function () { checkToSeeIfElementExistsInDom (true); }, 500);
			}
		}
	}

	// show the (title or) customised message/messageHtml when the mouse moves over the given element/s
	$.fn.popoverTrigger = function (conf) {

		// default values for the popover trigger
		conf = $.extend (true, {}, $.core.popover.defaultTriggerConf, conf);

		var content = '';
		if (conf.messageHtml !== null)
			content = conf.messageHtml;
		else if (conf.message !== null)
			content = $('<div>' + nl2p (htmlentities (conf.message)) + '</div>').children ().first ().addClass ('core-first').end ().last ().addClass ('core-last').end ().html ();

		if (conf.titleHtml !== null);
//			conf.titleHtml = conf.titleHtml;
		else if (conf.title !== null)
			conf.titleHtml = $('<div>' + htmlentities (conf.title) + '</div>').html ();

		// 
		if (!$.isFunction (conf.popoverFunction))
			conf.popoverFunction = $.createPopover;

		this.each (function () {

			var $element = $(this);
			var tempConf = $.extend (true, {}, conf);	// clone the conf
			var tempContent = content;

			// use the element's 'title' attribute unless overridden by message/messageHtml
			if ((tempConf.useTitle) && (tempContent == '')) {
				if ($element.attr ('title') != '')
					tempContent = $('<div>' + nl2p (htmlentities ($element.attr ('title'))) + '</div>').children ().first ().addClass ('core-first').end ().last ().addClass ('core-last').end ().end ().html ();
			}
//			if (tempContent === undefined)
//				tempContent = '';

			// remove the default title so it doesn't show
			if (tempConf.stopDefaultToolTip)
				$element.removeAttr ('title');

			// if toolTip has already been applied to this element...
			var api;
			if (tempConf.reApplyNamespace) {
				var api = $element.data ('popoverTrigger_' + tempConf.reApplyNamespace);
				if (api) {

					// close the popover if the content has changed (it will re-open)
					if ((tempContent.length) && (tempContent != api.getContent ()))
						api.setContent (tempContent);
					return true;
				}
			}

			// if 'self',  set attachTo to a reference of $element
			if (tempConf.popoverConf.attachTo == 'self')
				tempConf.popoverConf.attachTo = $element;

			// if any of the pointTo arrows are 'self',  make them point to this current element
			if (!$.isArray (tempConf.popoverConf.pointTo))
				tempConf.popoverConf.pointTo = [tempConf.popoverConf.pointTo];
			$.each (tempConf.popoverConf.pointTo, function (index, pointTo) {
				if (pointTo == 'self')
					tempConf.popoverConf.pointTo[index] = $element;
			});

			api = new popoverTrigger ($element, tempConf);
			api.setContent (tempContent);
			api.applyTriggers ();
			if (tempConf.reApplyNamespace)
				$element.data ('popoverTrigger_' + tempConf.reApplyNamespace, api);	// record the api within this element for later
			else
				$element.data ('popoverTrigger', api);	// record the api within this element for later
		});

		return $(this);
	};

	// show the title attribute value when the mouse moves over the given element/s
	$.fn.toolTipTrigger = function (conf) {

		// default values specific to the toolTip popover
		conf = $.extend (true, {}, $.core.popover.toolTipTriggerConf, conf);
		conf.popoverConf.group = 'toolTip';	// force the popover to be in the special 'toolTip' group (which is kept above all the rest)

		return $(this).popoverTrigger (conf);
	};
	// apply toolTips to existing and future elements with a title attribute
	$.fn.applyToolTip = function (conf) {

		// apply this functionality via .livequery () so new dynamic elements will also get this tooltip
		$(this).filter ('[title]:not(.core-ignoreToolTip)').livequery (function () {
			$(this).toolTipTrigger (conf);
		});
		return true;
	}
	// apply toolTips to existing and future elements with a title attribute
	$.applyToolTips = function (conf) {

		// apply this functionality via .livequery () so new dynamic elements will also get this tooltip
		$('[title]:not(.core-ignoreToolTip)').livequery (function () {
			$(this).toolTipTrigger (conf);
		});
		return true;
	}

	// show the title attribute value when the mouse moves over the given element/s
	$.fn.helperTrigger = function (conf) {

		// default values specific to the toolTip popover
		conf = $.extend (true, {}, $.core.popover.helperTriggerConf, conf);
		conf.popoverConf.group = 'helper';	// force the popover to be in the special 'helper' group (which is kept above all the rest)

		return $(this).popoverTrigger (conf);
	};
	// apply toolTips to existing and future elements with a title attribute
	$.applyHelpers = function (conf, selector) {

		if (selector === undefined)
			selector = 'input[type=text][title]:not(.core-ignoreToolTip),' + 'select[title]:not(.core-ignoreToolTip),' + 'textarea[title]:not(.core-ignoreToolTip),' + '.jsHelper:not(.core-ignoreToolTip)';

		// apply this functionality via .live () so new dynamic elements will also get this helper
		$(selector).livequery (function () {
			$(this).helperTrigger (conf);
		});
		return true;
	}

	// show the title attribute value when the mouse moves over the given element/s
	$.fn.templatePopoverTrigger = function (conf) {

		// default values specific to the toolTip popover
		conf = $.extend (true, {}, $.core.popover.templateTriggerConf, conf);

		// find the content template
		var parts = $(this).attr ('id').split ('_');
		parts.shift ();
		var $template = $('#template_' + parts.join ('_'));

		// use the template
		if ($template.length)
			conf.messageHtml = $template.html ();

		// work out if a width has been specified
		var classes = $(this).attr('class').split (/\s+/);
		$.each (classes, function (index, className) {
			$.each ($.core.popover.settings.templateTriggerCssParams, function (index2, paramName) {
				if (className.substr (0, ('core-param-' + paramName + '-').length) == 'core-param-' + paramName + '-') {
					var value = className.substr (('core-param-' + paramName + '-').length);
					conf.popoverConf[paramName] = value;
				}
			});
		});

		return $(this).popoverTrigger (conf);
	};
	// apply toolTips to existing and future elements with a title attribute
	$.applyTemplatePopoverTriggers = function (conf, selector) {

		if (selector === undefined)
			selector = '.core-templatePopoverTrigger';

		// apply this functionality via .live () so new dynamic elements will also get this helper
		$(selector).livequery (function () {
			$(this).templatePopoverTrigger (conf);
		});
		return true;
	}
}) (jQuery);























// popover templates
(function($) {

	// define a new popover template
	$.definePopoverTemplate = function (templateName, html, substitutionNames, conf) {

		// check the input
		if (templateName == '')
			return false;

		if (html === undefined)
			html = '';
		substitutionNames = $.extend ([], substitutionNames);
		conf = $.extend (true, {}, conf);

		// initialise the templates object if needed
		if (this.popoverTemplates === undefined)
			this.popoverTemplates = {};

		// store this new template
		this.popoverTemplates[templateName] = { html: html, substitutionNames: substitutionNames, conf: conf };

		return true;
	}
	// define popover templates
	// general
	$.definePopoverTemplate (
		'general',	// for general purpose messages
		'<div class="core-popoverBox core-popoverWithTitle core-popoverGeneral %%customClass%%"><div class="core-titleBox">%%title%%</div><div class="core-contentBox">%%content%%%%dialogueButtons%%</div></div>',
		['title', 'content', 'dialogueButtons', 'customClass'],
		{	dragOptions: {
				handle: '.core-titleBox'
			}
		}
	);
	$.definePopoverTemplate (
		'generalNoTitle',
		'<div class="core-popoverBox core-popoverNoTitle core-popoverGeneral %%customClass%%"><div class="core-contentBox core-contentBoxNoTitle">%%content%%%%dialogueButtons%%</div></div>',
		['content', 'dialogueButtons', 'customClass'],
		{}
	);
	// notice
	$.definePopoverTemplate (
		'notice',	// to alert the user with a message that they should take action upon
		'<div class="core-popoverBox core-popoverWithTitle core-popoverNotice %%customClass%%"><div class="core-titleBox">%%title%%</div><div class="core-contentBox">%%content%%%%dialogueButtons%%</div></div>',
		['title', 'content', 'dialogueButtons', 'customClass'],
		{	dragOptions: {
				handle: '.core-titleBox'
			}
		}
	);
	$.definePopoverTemplate (
		'noticeNoTitle',
		'<div class="core-popoverBox core-popoverNoTitle core-popoverNotice %%customClass%%"><div class="core-contentBox core-contentBoxNoTitle">%%content%%%%dialogueButtons%%</div></div>',
		['content', 'dialogueButtons', 'customClass'],
		{}
	);
	// helper
	$.definePopoverTemplate (
		'helper',	// to display a piece of helpful informaiton
		'<div class="core-popoverBox core-popoverWithTitle core-popoverHelper %%customClass%%"><div class="core-titleBox">%%title%%</div><div class="core-contentBox core-contentBox">%%content%%%%dialogueButtons%%</div></div>',
		['title', 'content', 'dialogueButtons', 'customClass'],
		{	easyClose: false,
			addCloseX: false,
			applyMask: false,
			applyDraggable: false,
			dragOptions: {
				handle: '.core-titleBox'
			}
		}
	);
	$.definePopoverTemplate (
		'helperNoTitle',
		'<div class="core-popoverBox core-popoverNoTitle core-popoverHelper %%customClass%%"><div class="core-contentBox core-contentBoxNoTitle">%%content%%%%dialogueButtons%%</div></div>',
		['content', 'dialogueButtons', 'customClass'],
		{	easyClose: false,
			addCloseX: false,
			applyMask: false,
			applyDraggable: false
		}
	);
	// basic
	$.definePopoverTemplate (
		'basicNoTitle',
		'<div class="core-popoverBox core-popoverNoTitle core-popoverBasic %%customClass%%"><div class="core-contentBox core-contentBoxNoTitle">%%content%%%%dialogueButtons%%</div></div>',
		['content', 'dialogueButtons', 'customClass'],
		{	easyClose: true,
			addCloseX: false,
			applyMask: false,
			applyDraggable: false
		}
	);
	// toolTip
	$.definePopoverTemplate (
		'toolTip',	// to show an element's 'title' text
		'<div class="core-popoverBox core-popoverNoTitle core-popoverToolTip %%customClass%%"><div class="core-contentBox core-contentBoxNoTitle">%%content%%%%dialogueButtons%%</div></div>',
		['content', 'dialogueButtons', 'customClass'],
		{	addCloseX: false,
			applyMask: false,
			applyDraggable: false
		}
	);
	// blank
	$.definePopoverTemplate (
		'blank',	// a blank template to put whatever into
		'<div class="%%customClass%%">%%content%%</div>',
		['content','customClass'],
		{	addCloseX: false,
			applyMask: false,
			applyDraggable: false
		}
	);
}) (jQuery);










/*/////////////////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/core/popovers/popovers_mini-0.0.1.js //
// created: Mon, 26 Sep 2011 14:01:58 +1000                              //
// modified: Wed, 31 Aug 2011 11:54:40 +1000                             //
// size: 32212 bytes                                                     //
/////////////////////////////////////////////////////////////////////////*/

(function($) {

	var $w = $(window);
	var $d = $(document);

	// static constructs
	$.core = $.core || { version: '0.0.1' };

	$.core.popoverMini = {

		// update the default conf values below in $.core.popover.settings
		updateSettings: function (settings) {
			this.settings = $.extend (true, {}, this.settings, settings);
		},
		// settings that control the way this plugin operates (different to the conf values below that are used when the plugin is being applied to an element)
		settings: {
			allowAnimations: false,			// should the mask use animations to fade in and out?
			allowMask: true,				// should the mask use animations to fade in and out?
			zIndex: 10000					// the start z-index of the popovers
		},

		// update the default conf values below in $.core.popover.conf
		updateDefaultConf: function (conf) {
			this.conf = $.extend (true, {}, this.conf, conf);
		},
		// the default conf values used when this plugin is applied to an element
		conf: {
			template: 'general',
			group: null,

			fixed: false,								// fix the popover into one position on the screen (fixed positioning not supported by ie6) (overridden to 'mouse' if attachToMouse is true)
			attachToMouse: false,						// should the popover follow the mouse?
			baseElement: null,							// an element, 'mouse' or ('screen' / null) (overridden to 'mouse' if attachToMouse is true)

			baseDirX: 0.5,								// 'left', 'center', 'right', or a number between 0 and 1 (ie. a percentage)
			popoverDirX: 0.5,							// 'left', 'center', 'right'
			offsetX: 0,									// offset in pixels to adjust the starting point
			startOnScreenX: true,						// position the popover back into the viewable area of the page if it appears initially offscreen X

			baseDirY: 0.5,								// 'top', 'center', 'bottom', or a number between 0 and 1 (ie. a percentage)
			popoverDirY: 0.5,							// 'top', 'center', 'bottom'
			offsetY: 0,									// offset in pixels to adjust the starting point
			startOnScreenY: true,						// position the popover back into the viewable area of the page if it appears initially offscreen Y

			width: null,								// the width of the popover
			minWidth: null,								// the max-width of the popover
			maxWidth: null,								// the min-width of the popover

			applyMaskToSelf: false,						// use the mask on this popover
			applyMask: true,							// use the mask on this popover's group
			maskOptions: {								// options controlling the mask
				color: null,
				loadSpeed: 800,
				closeSpeed: 800,
				opacity: 0.7
			},

			applyDraggable: true,						// turns the dragability on/off (uses jQueryUI)
			dragOptions: {								// the options passed to the jQueryUI draggable call.  ALL OTHER DRAGGABLE OPTIONS CAN BE SET they will be passed to jQueryUI
				handle: false,							// default selector to use when finding elements to drag by
				opacity: 0.85,							// default opacity when dragging
				containment: 'document'					// restrict movement of the popover to the document's boundaries
			},

			easyClose: true,							// close the popover by clicking outside or pressing escape
			closeOnClick: null,							// set to false to manually override
			closeOnEsc: null,							// set to false to manually override 

			closeAfter: null,							// close this popover after x milliseconds
			addCloseX: true,							// add the "closeX" element to the popover (ie. add the "X" button
			closeXHtml: '<a class="core-closeX"></a>',	// the html used for the closeX button

			// events
			onBeforePosition: null,						// called after the element has been created but before it has been positioned (good for manipulating the content before it is positioned on the screen)
			onBeforeShow: null,
			onShow: null,
			onBeforeClose: null,
			onClose: null
		}
	};

	var instances = {};
	var order = { topLevel: [] };
	var focusedUid = null;
	var setClickCloseTimeout = null;

	var popoverMini = function ($popover, tempConf) {

		// private variables
		var api = this;
		var $popover = $($popover);
		var conf = $.extend (true, {}, tempConf);		// clone the conf
		var $b = $('body:first');

		var uid = Math.random ().toString ().slice (10);

		var opened = false;
		var popoverApisToCloseWhenClosing = [];
		var closeTimeout = null;

		// resolve the base element
		$baseElement = conf.baseElement;
		if ($.inArray ($baseElement, ['mouse', 'screen', null]) < 0)
			var $baseElement = $($baseElement).first ();

		// if animations are off,  turn off mask fade-in/out speed
		if (!$.core.popoverMini.settings.allowAnimations) {
			conf.maskOptions.loadSpeed = 0;
			conf.maskOptions.closeSpeed = 0;
		}

		// if no group was specified then create it's own unique random group
		if (conf.group === null) {
			if (conf.applyMaskToSelf) {
				conf.applyMaskToSelf = false;
				conf.applyMask = true;
			}
			conf.group = Math.random ().toString ().slice (10);
		}






		// mark this element as being a popover
		$popover.addClass ('core-popover');






		// API methods
		$.extend (api, {

			// open (show) the popover
			open: function (e) {

				// can be opened only once
				if (opened)
					return api;





				// record that this popover is open
				opened = true;





				// onBeforeShow
				e2 = $.Event ();
				e2.type = 'onBeforeShow';
				$popover.trigger (e2);
				if (e2.isDefaultPrevented ()) {
					e.preventDefault ();
					return api;
				}





				// make it draggable if required
				if (conf.applyDraggable) {
					$popover.draggable (conf.dragOptions);

					// apply the draggable class to only the handles
					if (conf.dragOptions.handle !== false)
						$popover.find (conf.dragOptions.handle).addClass ('core-popoverDraggable');
					// or apply the draggable class to the whole popover
					else
						$popover.addClass ('core-popoverDraggable');
				}

				// apply ajax forms
				if ($.core.ajaxForm) {

					// set the uid inside any ajax forms within the popover
					// and then activate the ajax forms
					$popover.find ('.' + $.core.ajaxForm.settings.ajaxFormClass).map (function () {
						$(this).ajaxForm ();
						var api = $(this).data ('ajaxForm');
						if (api)
							api.setPopoverUid (uid, false);
					});
				}

				// add the closeX if necessary
				if (conf.addCloseX) {
					var $close = $(conf.closeXHtml).bind ('click.core-popoverMini-close', function () { api.close (); });
					$popover.prepend ($close);
				}






				// set the popover's min/max/widths
				// handle ie6's min/max-widths differently
				if (($.browser.msie) && ($.browser.version < 7)) {
					if (conf.maxWidth)
						$popover.width (parseInt (conf.maxWidth));
					if (conf.minWidth)
						$popover.width (parseInt (conf.minWidth));
				}
				// normal browsers
				else {
					if (conf.maxWidth)
						$popover.css ('max-width', parseInt (conf.maxWidth) + 'px');
					if (conf.minWidth)
						$popover.css ('min-width', parseInt (conf.minWidth) + 'px');
				}
				if (conf.width) {
					$popover.width (conf.width);
				}

				// fix the width of the titlebox in <= ie7
				if (($.browser.msie) && ($.browser.version < 8))
					$popover.show ().find ('.core-titleBox').outerWidth ($popover.width ()).end ().hide ();






				// call the onBeforePosition javascript (before the overlay is applied to the popover)
				e2 = $.Event ();
				e2.type = 'onBeforePosition';
				$popover.trigger (e2);
				if (e2.isDefaultPrevented ()) {
					e.preventDefault ();
					return api;
				}






				// position the popover
				var pos = getStartCoordinates ();
				pos = getOnScreenCoordinates (pos.left, pos.top);

				// fixed or absolute positioning? (fixed will keep it stuck in the same spot regardless of scrolling)
				if (((!$.browser.msie) || ($.browser.version >= 7)) && (conf.fixed)) {	// (fixed positioning not supported by ie6)
					pos.top -= $w.scrollTop ();
					pos.left -= $w.scrollLeft ();
					$popover.css ('position', 'fixed');
				}
				else
					$popover.css ('position', 'absolute');

				$popover.css ({ left: pos.left + 'px', top: pos.top + 'px' } );

				// visually show the popover
				var callBack = function () {

					// onShow
					e2 = $.Event ();
					e2.type = 'onShow';
					$popover.trigger (e2);

					// close again after x ms
					if (conf.closeAfter > 0)
						api.closeDelayed (conf.closeAfter);
				}
				if ($.core.popoverMini.settings.allowAnimations)
					$popover.show ('fade', {}, 200, callBack);
				else {
					$popover.show ();
					callBack ();
				}












				// add the mask effect if necessary
				if (((conf.applyMaskToSelf) || (conf.applyMask)) && ($.core.popover.settings.allowMask)) {
					maskConf = $.extend (true, { closeOnClick: false, closeOnEsc: false, loadSpeed: conf.maskOptions.speed }, conf.maskOptions);	// should the mask hide on click / esc-keypress?
					if (!$.core.popover.settings.maskAnimation)
						maskConf.loadSpeed = maskConf.closeSpeed = 0;
					$popover.mask (maskConf);
				}




				// keep the popover attached to the mouse if necessary
				if (conf.attachToMouse) {
					$b.bind ('mousemove.core-popoverMini' + uid, function (e) {
						var pos = getStartCoordinates ();
						pos = getOnScreenCoordinates (pos.left, pos.top);
						$popover.css ({ left: pos.left + 'px', top: pos.top + 'px' } );
					});
				}













				return api;
			},

			// close the popover
			close: function (e) {

				if (!opened)
					return $popover;

				e = e || $.Event ();
				e.type = 'onBeforeClose';
				$popover.trigger (e);
				if (e.isDefaultPrevented ())
					return;

				opened = false;



				// remove the popover api
				delete instances[uid];	// remove the popover from the internal list of popovers
				order.topLevel.remove (uid);	// remove the popover from the order list

				// and from it's group if necessary
				if (conf.group) {
					var groupAlias = 'g' + conf.group;	// alter the group's name internally so it doesn't interfere with the popover namespace (ie. the uids)
					order[groupAlias].remove (uid);
					if (order[groupAlias].length <= 0) {	// remove the group if it's empty
						delete order[groupAlias];
						order.topLevel.remove (groupAlias);
					}
				}

				// re-apply the popover order and close the mask if necessary
				applyFocusOrder ();

				var callback = function () {
					e.type = 'onClose';
					$popover.trigger (e);

					$popover.remove ();

					// stop observing mouse movements
					if (conf.attachToMouse)
						$b.unbind ('mousemove.core-popoverMini' + uid);
				}

				// visually hide the popover
				if ($.core.popoverMini.settings.allowAnimations)
					$popover.hide (($.core.popoverMini.settings.allowAnimations ? 'fade' : null), {}, 100, callback);
				else {
					$popover.hide ().remove ();
					callback ();
				}

				// close any other associated popovers that need closing
				$.each (popoverApisToCloseWhenClosing, function () { this.close (); });

				return api;
			},

			// close the popover after the given amount of time (in ms)
			closeDelayed: function (delayMS) {
				if (opened) {

					// cancel any existing closeDelayed timeout
					api.cancelCloseDelayed ();

					// start the close delayed process
					if (delayMS <= 0)
						api.close ();
					closeTimeout = setTimeout (function () { api.close (); }, delayMS);
				}
				return api;
			},

			// cancel the popover's delayed closure
			cancelCloseDelayed: function () {
				clearTimeout (closeTimeout);
				return api;
			},

			// add a popover to close when this popover closes
			addPopoverToClose: function (tempApi) {
				if ($.inArray (tempApi, popoverApisToCloseWhenClosing) < 0)
					popoverApisToCloseWhenClosing.push (tempApi);
				return api;
			},

			// focus the popover,  bringing it to the foreground
			focus: function () {

				// if this popover already has focus,  don't do any more calculations to re-focus it
				if (focusedUid == uid)
					return api;

				// if this popover is a part of a group then bring that group to the foreground
				if (conf.group) {

					var groupAlias = 'g' + conf.group;	// alter the group's name internally so it doesn't interfere with the popover namespace (ie. the uids)

					// bring the group to the top of the list
					if ($.inArray (groupAlias, order.topLevel) >= 0) {
						order.topLevel.remove (groupAlias);
						order.topLevel.push (groupAlias);

						// bring the popover to the top of the list within the group
						if (order[groupAlias] !== undefined) {
							if ($.inArray (uid, order[groupAlias]) >= 0) {
								order[groupAlias].remove (uid);
								order[groupAlias].push (uid);
							}
						}
					}
				}
/**
				// or just bring this individual popover to the top of the list
				else {
					if ($.inArray (uid, order.topLevel) >= 0) {
						order.topLevel.remove (uid);
						order.topLevel.push (uid);
					}
				}
/**/

				applyFocusOrder ();
				return api;
			},

			// create a child popover
			// this is the same as the regular $.createPopover () function but it attaches the new popover to this popover by default (ie. the starting position is based upon the position of this popover)
			// and an association is established between the popovers so that when this (the parent) popover closes,  the child will too
			// and the new popover is put into the same group is this popover
			createChildPopover: function (substitutionValues, tempConf) {

				tempConf = $.extend (true, {}, { attachTo: api.getPopover (), group: conf.group, popoverFunction: null }, tempConf);
				if (!$.isFunction (tempConf.popoverFunction))
					tempConf.popoverFunction = $.createPopoverMini;

				var $tempPopover = tempConf.popoverFunction (substitutionValues, tempConf);
				api.addPopoverToClose ($tempPopover.data ('popoverMini'));

				return $tempPopover;
			},

			// create a sibling popover
			// this is the same as the regular $.createPopover () function but it attaches the new popover to this popover by default (ie. the starting position is based upon the position of this popover)
			// and the new popover is put into the same group is this popover
			createSiblingPopover: function (substitutionValues, tempConf) {
				tempConf = $.extend (true, {}, { attachTo: api.getPopover (), group: conf.group, popoverFunction: null }, tempConf);
				if (!$.isFunction (tempConf.popoverFunction))
					tempConf.popoverFunction = $.createPopoverMini;

				var $tempPopover = tempConf.popoverFunction (substitutionValues, tempConf);
				return $tempPopover;
			},









			// replace the contents of the contentBox in this popover
			replaceContentBoxHtml: function (html, ifhKey, ifhPage) {
				var $contentBlock = $popover.find ('.core-contentBox');
				if ($contentBlock.length) {

					// replace the ifh block with the new content (if new content was specified)
					// convert the ids of the elements in the new html
//					var $newContentBlock = api.convertElementIds ('<div class="' + $.core.ajaxForm.settings.ifhBlockClass + '">' + html + '</div>');
					var $newContentBlock = $('<div class="' + $.core.ajaxForm.settings.ifhBlockClass + '">' + html + '</div>');

//					existingMessageElementIds = [];
//					visibleMessageElementIds = [];
//					messageIdsToAppearThisTime = [];
//					newMessages = [];

					// set the uid inside any ajax forms within the popover
					// and then activate them
					if ($.fn.ajaxForm !== undefined) {
						$newContentBlock.find ('.' + $.core.ajaxForm.settings.ajaxFormClass).map (function () {
							$(this).ajaxForm ();
							var ajaxFormApi = $(this).data ('ajaxForm');
							if (ajaxFormApi)
								ajaxFormApi.setPopoverUid (uid, false).setIfhKey (ifhKey).setIfhPage (ifhPage);
						});
					}
// CHECK THIS
// move this jsMessage initialisation into the ajaxForm api
//					$newContentBlock.find ('.' + $.core.ajaxForm.settings.ajaxFormClass).ajaxForm ().data ('ajaxForm').set_popover_uid (uid).end ().find ('.jsMessage').css ('display', 'none').addClass ('message').html ('').map (function () { existingMessageElementIds.push ($(this).attr ('id')); });
//					$popover.find ('.' + $.core.ajaxForm.settings.ajaxFormClass).ajaxForm ();
//alert ($('<div/>').html ($newContentBlock.html ()).html ());
					// replace the content
					$contentBlock.html ($newContentBlock);

					// set the flag so that the block can be shown nicely and the popover repositioned when the whole ajax response has been processed
//					needToShowNewContentBlock = true;
				}
				return api;
			},
/**
			showNewContentBox: function () {

				var $newContentBox = $popover.find ('.core-contentBox').find ('div').eq (0);

				// reposition the popover if necessary
				var originalOffset = $popover.offset ();
				var newOffset = originalOffset;

				// make the popover appear in the best starting spot (the dimension change of the popover may have changed this)
				if (conf.recalculateStartPositionAfterAjax)
					newOffset = api.getStartCoordinates ($popover.width (), $popover.height ());

				// make sure the popover appears on the page's viewable area if necessary
				newOffset = api.getOnScreenCoordinates ($popover.width (), $popover.height (), newOffset.left, newOffset.top);

				// the 'show' and the 'position animation' happen as two separate concurrent things,  can this happen as one action to smoothe the animation?
				$newContentBox.hide ();
				if ((originalOffset.left != newOffset.left) || (originalOffset.top != newOffset.top))
					$popover.animate ({ left: '-=' + (originalOffset.left - newOffset.left), top: '-=' + (originalOffset.top - newOffset.top) });

				$newContentBox.show (($.core.popover.settings.popoverAnimations) ? 'blind' : null);

				setTimeout (api.positionArrows, 400);	// re-position the arrows if necessary

				needToShowNewContentBlock = false;
				return api;
			},
/**/







			// return the popover element
			getPopover: function () {
				return $popover;
			},

			// return whether the popover has been opened or not
			isOpened: function () {
				return opened;
			},

			// manipulate start, finish and speeds
			getConf: function () {
				return conf;
			},

			// get the uid
			getUid: function () {
				return uid;
			}
		});







		// private methods


















		// determine the best onscreen position for this popover
		// use the given popover width/height,  or if empty then use the popover's actual width/height
		var getStartCoordinates = function (width, height) {

			// determine the popover's dimensions
			if (width === undefined)
				width = $popover.outerWidth ();
			if (height === undefined)
				height = $popover.outerHeight ();

			// position the overlay in relation to the given element
			// if more than one is found it'll use the first one
			var baseOffset = null;
			if ($baseElement != null) {
				if ($baseElement == 'mouse') {
					baseOffset = { left: $.core.mouseX ? $.core.mouseX : 0, top: $.core.mouseY ? $.core.mouseY : 0 };	// the offset to the top/left of the mouse position
					var baseWidth = 16;	// assume a 16 x 16 pixel mouse cursor
					var baseHeight = 16;
				}
				else if ($baseElement) {
					baseOffset = $baseElement.offset ();	// the offset to the top/left of the baseElement element
					var baseWidth = $baseElement.outerWidth ();
					var baseHeight = $baseElement.outerHeight ();
				}
			}
			// if necessary,  position the overlay in relation to the screen
			if (baseOffset === null) {
				var baseOffset = { top: $w.scrollTop (), left: $w.scrollLeft () };	// the offset to the top/left of the document's viewable area
				var baseWidth = $w.width ();
				var baseHeight = $w.height ();
			}




			// adjust x
			var left = 0;
			// percentage
			if (is_float (conf.baseDirX))
				left = baseOffset.left + (baseWidth * conf.baseDirX);
			// or position
			else {
				switch (conf.baseDirX) {
					case 'left': left = baseOffset.left;	break;
					case 'right': left = baseOffset.left + baseWidth;	break;
					default: left = baseOffset.left + (baseWidth / 2);	break;	// 'center'
				}
			}
			// percentage
			if (is_float (conf.popoverDirX))
				left -= width * conf.popoverDirX;
			// or position
			else {
				switch (conf.popoverDirX) {
					case 'left': left -= 0;	break;
					case 'right': left -= width;	break;
					default: left -= (width / 2);	break;	// 'center'
				}
			}
			left += conf.offsetX;




			// adjust y
			var top = 0;
			// percentage
			if (is_float (conf.baseDirY))
				top = baseOffset.top + (baseHeight * conf.baseDirY);
			// or position
			else {
				switch (conf.baseDirY) {
					case 'top': top = baseOffset.top;	break;
					case 'center': top = baseOffset.top + baseHeight / 2;	break;
					case 'bottom': top = baseOffset.top + baseHeight;	break;
				}
			}
			// percentage
			if (is_float (conf.popoverDirY))
				top -= height * conf.popoverDirY;
			// or position
			else {
				switch (conf.popoverDirY) {
					case 'top': top -= 0;	break;
					case 'center': top -= height / 2;	break;
					case 'bottom': top -= height;	break;
				}
			}
			top += conf.offsetY;

//			return api.getOnScreenCoordinates (width, height, left, top);
			return { top: parseInt (top), left: parseInt (left) };
		};

		// determine the best onscreen position for this popover
		// use the given popover width/height,  or if empty then use the popover's actual width/height
		// use the given top/left offsets,  or if empty then use the popover's actual top/left
		var getOnScreenCoordinates = function (left, top, width, height) {

			// determine the popover's position
			var offset = $popover.offset ();	// the offset to the top/left of the popover
			if (left === undefined)
				left = offset.left;
			if (top === undefined)
				top = offset.top;

			// determine the popover's dimensions
			if (width === undefined)
				width = $popover.outerWidth ();
			if (height === undefined)
				height = $popover.outerHeight ();

			// adjust x
			// make sure the overlay won't appear off the screen
			if (conf.startOnScreenX) {
				var pageRight = $w.scrollLeft () + $w.width ();
				// not too far right
				if (left + width > pageRight)
					left = pageRight - width;
				// not too far left
				if (left < $w.scrollLeft ())
					left = $w.scrollLeft ();
			}

			// adjust y
			// make sure the overlay won't appear off the screen
			if (conf.startOnScreenY) {
				var pageBottom = $w.scrollTop () + $w.height ();

				// not too far down
				if (top + height > pageBottom)
					top = pageBottom - height;
				// not too far up
				if (top < $w.scrollTop ())
					top = $w.scrollTop ();
			}

			return { top: top, left: left };
		};
















		// private functions

		// give the popovers according to the current order of popovers in the 'order' object of arrays
		var applyFocusOrder = function () {
/**
			// push the special 'toolTip' and 'helper' group to the top
			$.each (['ghelper','gtoolTip'], function (i, groupAlias) {
				if ($.inArray (groupAlias, order.topLevel) >= 0) {
					order.topLevel.remove (groupAlias);
					order.topLevel.push (groupAlias);
				}
			});
/**/

			// generate a flat list of the popovers in increasing desired z-index order
			// loop through the 'topLevel' popover group's order
			var uids = [];
			var groupUidMaskInfo = {};
			for (var count = 0; count < order.topLevel.length; count++) {

				// loop through this popover group's order
				var group = order.topLevel[count];
				for (var count2 = 0; count2 < order[group].length; count2++) {
					if (instances[order[group][count2]] !== undefined) {
						uids.push (order[group][count2]);

						// if this particular popover wants the mask to be applied to it's group and no other popover in it's group has applied the mask to the group,  record this popover as being the one to look for for this group's mask details
						if ((groupUidMaskInfo[group] === undefined) && (instances[order[group][count2]].getConf ().applyMask))
							groupUidMaskInfo[group] = order[group][count2];
					}
				}
			}

			// loop through the popovers now that they're in order,  and work out which one (popover or group) is the top-most one that requires a mask
			var topUidWithMask = null;
			var topGroupWithMask = null;
			for (var count = 0; count < uids.length; count++) {

				// if this popover has a mask then record it's uid
				var tempConf = $.extend (true, {}, instances[uids[count]].getConf ());
				if (tempConf.applyMaskToSelf) {
					topUidWithMask = uids[count];
					topGroupWithMask = tempConf.group;
				}

				// otherwise,  if this popover wants to apply the mask to it's group record this popover's group
				else if ((tempConf.group != null) && (tempConf.applyMask)) {
					if (tempConf.group != topGroupWithMask) {
						topUidWithMask = null;
						topGroupWithMask = tempConf.group;
					}
				}
			}
			// if an individual popover is at the top then forget about the top group
			if (topUidWithMask != null)
				topGroupWithMask = null;

			// if it's a group at the top,  find the back-most popover
			if (topGroupWithMask != null) {
				var groupAlias = 'g' + topGroupWithMask;	// alter the group's name internally so it doesn't interfere with the popover namespace (ie. the uids)
				topUidWithMask = order[groupAlias][0];
			}




			// apply the z-indexes to the popovers and mask
			var zIndex = $.core.popover.settings.zIndex;	// start at the z-index number stated by the settings
			var topUid = null;
			var focusUid = null;
			for (var count = 0; count < uids.length; count++) {

				if (($.core.popover.settings.allowMask) && (uids[count] == topUidWithMask))
					$('#exposeMask').css ('z-index', zIndex++);
				instances[uids[count]].getPopover ().css ('z-index', zIndex++).removeClass ('core-popoverFocused');

				topUid = uids[count];
				if ($.inArray (instances[uids[count]].getConf ().group, ['toolTip', 'helper']) < 0)
					focusUid = uids[count];
			}
			if (focusUid)
				instances[focusUid].getPopover ().addClass ('core-popoverFocused');

			// record that this popover is focused so that the focus calculations don't need to run next time this popover is clicked
			focusedUid = topUid;

			// close the mask if necessary
			if (($.core.popover.settings.allowMask) && (topUidWithMask == null) && ($.mask.isLoaded ()))
				$.mask.close ();

			



			// handle the easyClose events (click outside the popover + esc-keypress)
			$d.unbind ('click.core-popoverMini');
			$d.unbind ('keydown.core-popoverMini');
			if (instances[topUid] != null) {

				var tempConf = instances[topUid].getConf ();

				// when window is clicked outside overlay, close the popover
				if ((tempConf.closeOnClick)
				|| ((tempConf.closeOnClick === null) && (tempConf.easyClose))) {
					var tempApi = instances[topUid];
					setClickCloseTimeout = setTimeout (function () {	// stop the popover from closing straight away if the user clicked something to make this appear
						$d.unbind ('click.core-popoverMini');
						$d.bind ('click.core-popoverMini', function (e) {
							if (!$(e.target).parents ('.core-popover').length)	// .core_popover
								tempApi.close (e);
						});
					}, 1);
				}

				// keyboard::escape
				// one callback is enough if multiple instances are loaded simultaneously
				if ((tempConf.closeOnEsc)
				|| ((tempConf.closeOnEsc === null) && (tempConf.easyClose))) {
					var tempApi = instances[topUid];
					$d.one ('keydown.core-popoverMini', function (e) {
						if (e.keyCode == 27)
							tempApi.close (e);
					});
				}
			}

			return api;
		};

		// add this popover to the popover order list so it can be ordered
		var addThisPopoverToInstances = function () {

			instances[uid] = api;	// add this popover to the list

			// add this popover to the list
			// a popover that's in a group
			// create an order array for the group,  and place that group inside the 'topLevel' order array
			var groupAlias = 'g' + conf.group;	// alter the group's name internally so it doesn't interfere with the popover namespace (ie. the uids)
			order[groupAlias] = order[groupAlias] || [];
			order[groupAlias].push (uid);

			if ($.inArray (groupAlias, order.topLevel) < 0)
				order.topLevel.push (groupAlias);

			// bring this group to the front
			order.topLevel.remove (groupAlias);
			order.topLevel.push (groupAlias);

			// give the popovers their respective z-indexes
			applyFocusOrder ();

			return api;
		};

		// assign the callbacks
		$.each (['onBeforePosition', 'onBeforeShow', 'onShow', 'onBeforeClose', 'onClose'], function (i, name) {

			// configuration
			if ($.isFunction (conf[name]))
				$popover.bind (name, conf[name]);

			// API
			$popover[name] = function (fn) {
				$popover.bind (name, fn);
				return $popover;
			};
		});

		// initialise the popover
		var init = function () {

			// add this popover to the popover order list so it can be ordered
			addThisPopoverToInstances ();

			// make it so that when this popover is clicked,  it will be brought into focus
			$popover.mousedown (api.focus);
		};



		// show the popover
		init ();
	};

	// jQuery plugin initialisation
	$.fn.popoverMini = function (conf) {

		// merge the caller's conf with the default conf
		conf = $.extend (true, {}, $.core.popoverMini.conf, conf);

		// if the popover is to be attached to the mouse..
		if (conf.attachToMouse) {
			conf.fixed = false;			// make sure it isn't set into a "fixed" position because this causes position problems when scrolling
			conf.baseElement = 'mouse';	// make it's start position where the mouse is
		}

		// turn each selected element into a popover
		$(this).each (function () {

			var $this = $(this);

			// only apply the popover to this element if it hasn't already been applied
			if (!$this.data ('popoverMini')) {

				var api = new popoverMini ($this, conf);	// turn this element into a popover
				$this.data ('popoverMini', api);			// record the api within this element for later
				api.open ();								// show the popover
			}
		});

		return this;
	};











	// create a new popover (create a dom element and turn it into an overlay)
	$.createPopoverMini = function (substitutionValues, conf) {

		// apply the default template if not specified
		conf = $.extend (true, {}, { template: $.core.popoverMini.conf.template }, conf);

		// first make sure the template exists
		if ($.popoverTemplates[conf.template] !== undefined) {

			// grab the template
			var template = $.popoverTemplates[conf.template];


			// apply this template's default options
			conf = $.extend (true, {}, template.conf, conf);

			// apply the default dialogue popover options
			conf = $.extend (true, {}, $.core.popover.dialogueConf, conf);


			// generate the html
			// apply the relevant substitutions
			substitutionValues = $.extend ({}, substitutionValues);
			var html = template.html;
			$(template.substitutionNames).each (function (index, value) {
				html = html.replace ('%%' + value + '%%', (substitutionValues[value] || ''));
			});

			// create the popover element based on the html,
			// and attach the popover element to the page
			// make it appear
			// return it
			return $(html).appendTo ($('body')).popoverMini (conf);
		}
		return null;
	};

}) (jQuery);




/**
jQuery ().ready ((function ($) {
	return function () {
		setTimeout (function () {
			$.createPopoverMini (
			{ title: 'helo', content: 'there oaehtulrens hnsoeh sch,scrh.usnhc,.snht snoeha ntehaostn uhsaeou oae' },
			{	baseElement: '#locationTerm'
//				attachToMouse: true,
//				minWidth: 700
			});
		}
		, 1000);
	}
}) (jQuery));
/**/










/*////////////////////////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/core/text_shortener/text_shortener-0.0.1.js //
// created: Wed, 19 Oct 2011 15:42:17 +1100                                     //
// modified: Mon, 17 Oct 2011 11:57:28 +1100                                    //
// size: 7957 bytes                                                             //
////////////////////////////////////////////////////////////////////////////////*/

(function($) {

	// 
	$.fn.shortenText = function (custConf) {

		var defaultConf = {
			maxWidth: 200,												// the maximum width of a line before it needs to break
			mode: 'breakLines',											// breakLines/truncate
			dashChar: '-',												// the dash character to add at the end of lines when a word is broken
			addTruncatePopover: true,									// add the "more details" popover if truncated?
			customTruncateClickHandler: null,							// a custom function to run instead of the default popover trigger
			noTruncateHandler: null,									// if the text wasn't truncated then call the custom function
//			moreInfoHtml: '..<a class="map1_question" href="#">?</a>',	// the "more details" link
			moreInfoHtml: ' .. <a href="" class="fakeLink">more</a>',	// the "more details" link
//			moreInfoHtmlWidth: 18,										// width in pixels of the "more details" html
			moreInfoHtmlWidth: 43,										// width in pixels of the "more details" html
			moreInfoPopoverStyle:'',
			popoverConf: {
				baseAttachDirectionX: 'left',
				popoverAttachDirectionX: 'right',
				baseAttachDirectionY: 'top',
				popoverAttachDirectionY: 'top',
				attachOffsetX: 18,
				attachOffsetY: -17,
				addCloseX: true,
				applyDraggable: true,
				maxWidth: 250
			}
		};

		$(this).each (function () {
			var $this = $(this);
			var conf = $.extend (true, {}, defaultConf, custConf);



			// show any hidden parents (that are actually hidden with display=none) so that this element is visible when taking measurements.  they are re-hidden below
			var $hiddenParents = $this.parents (':hidden').filter (function () {
				return $(this).css ('display') == 'none';
			});
			$hiddenParents.show ();




			var origDisplay = $this.css ('display');
			$this.css ('display', 'inline');

			// adjust the parent element's width so that it can be detected properly when $this extends the desired width
			var $parent = $this.parent ();
			var origParentWidth = $parent.css ('width');
			$parent.width (conf.maxWidth + 200);


			// keep the original string
			var origText = $.trim ($this.text ());
			var myText = origText;
			var truncated = false;

			// work out how long the end of line dash '-' is
			var dashChar = '';
			var dashWidth = 0;
			var moreInfoHtml = '';
			var moreInfoHtmlWidth = 0;
			if (conf.mode == 'breakLines') {
				dashChar = conf.dashChar;
				dashWidth = $this.text (conf.dashChar).width ();
				moreInfoHtml = '';
				moreInfoHtmlWidth = 0;
			}
			else if ((conf.mode == 'truncate') && (conf.addTruncatePopover)) {
				var moreInfoHtml = conf.moreInfoHtml;
				var moreInfoHtmlWidth = conf.moreInfoHtmlWidth
			}
			$this.text (origText);

			// if the line is too long...
			var lines = [];
			while (($this.outerWidth () > conf.maxWidth) && (myText.length > 0)) {

				// chop enough off this line to make it shorter than the maximum allowed
				var myTextRest = '';
				var chopOffAtNextSpace = false;
				var fullMyText = null;
				var fullMyTextRest = null;
				do {
					myTextRest = myText.substr (myText.length - 1, 1) + myTextRest;	// grab a character
					myText = myText.substr (0, myText.length - 1);					// remove that character
					$this.text (myText);											// apply this change so it can be measured

					// work out if we've reached the maximum width
					if ($this.outerWidth () <= conf.maxWidth)
						chopOffAtNextSpace = true;
					if ((chopOffAtNextSpace) && (fullMyText === null)) {
						if ($this.outerWidth () + dashWidth + moreInfoHtmlWidth <= conf.maxWidth) {
							fullMyText = myText;	// add a dash to show that the word was chopped
							fullMyTextRest = myTextRest;
						}
					}

					// if we've passed the biggest width and have now found a space then stop shortening this line
					if ((chopOffAtNextSpace) && (myTextRest.substr (0, 1) == ' ') && ($this.outerWidth () + moreInfoHtmlWidth <= conf.maxWidth))
						break;

					// down to 1/3 of the max width
					// if no space was found then use the biggest line possible instead and just cut it
					else if ($this.outerWidth () <= conf.maxWidth / 3) {
						if ((fullMyText !== null) && (fullMyText.length)) {
							myText = fullMyText + dashChar;
							myTextRest = fullMyTextRest;
						}
						break;
					}
				}
				while (myText.length > 0);

				myText = $.trim (myText);
				myTextRest = $.trim (myTextRest);
				

//alert ('A myText = "' + myText + '"');
//alert ('A myTextRest = "' + myTextRest + '"');
				if (myText.length) {
					lines.push (htmlentities (myText));	// store this shortened line
					myText = myTextRest;		// start again with the rest of the line
					$this.text (myText);				// apply this new part so it can be measured
				}
				else if (myTextRest.length) {
					lines.push (htmlentities (myTextRest.substr (0, 1)));	// store the first char
					myText = myTextRest.substr (1, myTextRest.length);		// grab the rest of the line
					$this.text (myText);				// apply this new part so it can be measured
				}

				if (conf.mode == 'truncate') {
					truncated = (myTextRest.length > 0);
					break;
				}
			}

			// if the loop ended then the last piece of the string probably needs to be added
			if (((conf.mode != 'truncate') || (!lines.length))	// if we're not truncating the string,  or we don't have a full line yet
			&& ($.trim (myText).length))						// and there is something to add
				lines.push (htmlentities ($.trim (myText)));	// store this shortened line

			// put the processed lines back in there
			$this.html (lines.join ('<br />'));

			// add 'title' (hover) text if truncated
			if (conf.mode == 'truncate') {
				if (truncated) {
					if (conf.addTruncatePopover) {

						// add the "more info" html
						$this.append (moreInfoHtml);

						// work out what the popover content should be (add space on the RHS for the close "X"
						var $temp = $('<div></div>').html (origText);
						if (!$temp.children ().first ().addClass ('core-spaceForCloseX').length) {
							var tempClass = 'core-spaceForCloseX';
							if (conf.moreInfoPopoverStyle.length>0) {
								tempClass = tempClass + ' ' + conf.moreInfoPopoverStyle;
							}
							$temp = $temp.addClass (tempClass).wrap ('<div/>').parent ();
						}

						if ($.isFunction (conf.customTruncateClickHandler)) {
							$this.children (':last').bind ('click.core-textShortener', function () {
								conf.customTruncateClickHandler.apply (this);
								return false;
							});
						}
						else {

							// get the popover to work when clicked
							$this.children (':last').popoverTrigger (
							{	messageHtml: $temp.html (),
								popoverConf: conf.popoverConf
							});
						}
					}
					else
						$this.attr ('title', origText);
				}
				// if the text wasn't truncated then call the custom function
				else {
					if ($.isFunction (conf.noTruncateHandler))
						conf.noTruncateHandler.apply (this);
				}
			}

			$parent.css ('width', origParentWidth);
			$this.css ('display', origDisplay);
			$hiddenParents.hide ();
		});

		return $(this);
	};

}) (jQuery);









/*//////////////////////////////////////////////////////////////////////////////////
// path: /javascript/jquery_plugins/core/transform_input/transform_input-0.0.2.js //
// created: Mon, 26 Sep 2011 14:01:58 +1000                                       //
// modified: Wed, 31 Aug 2011 11:54:40 +1000                                      //
// size: 31689 bytes                                                              //
//////////////////////////////////////////////////////////////////////////////////*/

(function($) {

	// static constructs
	$.core = $.core || { version: '0.0.1' };

	$.core.transformInput = {

		// update the default conf values below in $.core.transformInput.conf
		updateDefaultFileInputConf: function (conf) {
			this.fileInputConf = $.extend (true, {}, this.conf, conf);
		},

		// the default conf values used when this plugin is applied to a file input
		fileInputConf: {
			fakeFileInputHtml: '<input type="text" readonly="readonly" /><button type="button"></button>',
			fileInputButtonHtml: 'Browse',
			displayFilenameInInputs: true,	// should the file's name be put into any input fields inside the fake file input html?

			buttonCssClass: 'core-button',	// 

			zIndex: 2,						// the z-index that the invisible file input is given,  the input fields behind it are given this z-index - 1

			onBeforeTransform: null,		// called when the element is about to be transformed
			onTransform: null				// called after the element has been transformed
		},

		// update the default conf values below in $.core.transformInput.conf
		updateDefaultButtonConf: function (conf) {
			this.buttonConf = $.extend (true, {}, this.conf, conf);
		},

		// the default conf values used when this plugin is applied to a button
		buttonConf: {
			buttonCssClass: 'core-button',	// 

			zIndex: 2,						// the z-index that the invisible file input is given,  the input fields behind it are given this z-index - 1

			onBeforeTransform: null,		// called when the element is about to be transformed
			onTransform: null				// called after the element has been transformed
		},

		// update the default conf values below in $.core.transformInput.conf
		updateDefaultDropDownConf: function (conf) {
			this.dropDownConf = $.extend (true, {}, this.conf, conf);
		},
		
		// the default conf values used when this plugin is applied to a drop-down
		dropdownLinkConf: {
			dropdownIconLeft: null,
			dropdownIconRight: 'core-iconArrowDown',
			dropdownContent: '<div/>',
			vertAlignDropDown: true,

			zIndex: 2,						// the z-index that the invisible file input is given,  the input fields behind it are given this z-index - 1

			onBeforeTransform: null,		// called when the element is about to be transformed
			onTransform: null				// called after the element has been transformed
		},

		radioConf: {
			onBeforeTransform: null,		// called when the element is about to be transformed
			onTransform: null				// called after the element has been transformed
		},

		checkboxConf: {
			onBeforeTransform: null,		// called when the element is about to be transformed
			onTransform: null				// called after the element has been transformed
		},

		textInputConf: {
			zIndex: 2,						// the z-index that the text input is given,  the input image behind it are given this z-index - 1

			onBeforeTransform: null,		// called when the element is about to be transformed
			onTransform: null				// called after the element has been transformed
		}
	};





	function transformInput (element, conf, type) {

		var api = this;
		var $element = $(element);
		var myConvertedOk = false;






		// API methods
		$.extend (api, {

			init: function () {

				assignCallbacks ();

				// call the onBeforeTransform javascript (when the element is about to be transformed)
				e = $.Event ();
				e.type = 'onBeforeTransform';
				$element.trigger (e);
				if (e.isDefaultPrevented ()) {
					return api;
				}



				switch (type) {
					// transform this if it is a file input
					case 'fileInput' :
						if ((!$element.is ('input[type=file]')) || (!transformFileInput ()))
							return;
						break;
					// transform this if it is a button
					case 'button' :
						if ((!$element.is ('button')) || (!transformButton ()))
							return;
						break;
					// transform this if it is an anchor -> button
					case 'anchorButton' :
						if ((!$element.is ('a')) || (!transformAnchorButton ()))
							return;
						break;
					// transform this if it is an anchor -> dropdown
					case 'dropdownLink' :
						if ((!$element.is ('a')) || (!transformDropdownLink ()))
							return;
						break;
					// transform this if it is an radio input
					case 'radioInput' :
						if ((!$element.is ('input[type=radio]')) || (!transformRadioInput ()))
							return;
						break;
					// transform this if it is a checkbox input
					case 'checkboxInput' :
						if ((!$element.is ('input[type=checkbox]')) || (!transformCheckboxInput ()))
							return;
						break;
					// transform this if it is a text input
					case 'textInput' :
						if ((!$element.is ('input[type=text],input[type=password]')) || (!transformTextInput ()))
							return;
						break;
				}

				$element.addClass ('core-transformed');



				// call the onTransform javascript (after the element has been transformed)
				e = $.Event ();
				e.type = 'onTransform';
				$element.trigger (e);

				myConvertedOk = true;
			},

			convertedOk: function () {
				return myConvertedOk;
			}
		});









		// put this element into a placeholder element
		var transformFileInput = function () {

			// show any hidden parents (that are actually hidden with display=none) so that the button is visible when taking measurements.  they are re-hidden below
			var $hiddenParents = $element.parents (':hidden').filter (function () {
				return $(this).css ('display') == 'none';
			});
			$hiddenParents.show ();

			// create the placeholder
			$element.wrap ($('<div class="core-fileInputPlaceholder"><div class="core-fileInputButtonBox"></div></div>'));
			var $fileInputButtonBox = $element.parent ();
			var $placeHolder = $fileInputButtonBox.parent ();

			// add the fake html to appear below the hidden file input field
			var $fakeInputBlock = ($('<div class="core-fileInputFake">' + conf.fakeFileInputHtml + '<div class="core-transformInputContentEnd"></div></div>'));	// adding the "core-transformInputContentEnd" div causes the height of the core-fileInputFake to be the full height of it's content
			$fakeInputBlock.find ('button').html (conf.fileInputButtonHtml);
			$placeHolder.append ($fakeInputBlock);
			var $fakeInputFields = $fakeInputBlock.find ('input');



			// put the invisilble file input field ABOVE the visible fake input block
			$element.css ('z-index', conf.zIndex);
			$placeHolder.css ('z-index', conf.zIndex - 1);

			// set the height of the invisible file input field so it's tall enough
			$element.height ($fakeInputBlock.outerHeight ());

			// position the hidden file input field so that it's aligned to the right (ie. the button is shown, on firefox & ie)
			$element.css ('left', '-' + ($element.outerWidth () - $fakeInputBlock.outerWidth () - 5) + 'px');

			// set the width and height of the file input button box (that contains the invisible file input field) so that covers the desired area
			$fileInputButtonBox.width ($fakeInputBlock.outerWidth ());
			$fileInputButtonBox.height ($fakeInputBlock.outerHeight ());

			// set the height of the placeholder so that the following html flows below it
			$placeHolder.height ($fakeInputBlock.outerHeight ());



			// add the tooltip trigger to show the file's name as a tooltip
			if ($.core.popover)
				$element.applyToolTip ();

			// when a file is chosen,  show the file's name in the fake input block's input field
			var updateVisibleFileName = function () {
				var val = $element.val ().replace(/^c:\\fakepath\\/i, '');	// remove the "C:\fakepath\" that chrome and others adds to the string
				if (conf.displayFilenameInInputs)
					$fakeInputFields.val (val);
				$element.attr ('title', val);
			};
			$element.bind ('change.core-transformInput mouseleave.core-transformInput', updateVisibleFileName);
			updateVisibleFileName ();

			$hiddenParents.hide ();

			return true;
		};





		// put this element into a placeholder element
		var transformButton = function () {

			$element.show ();

			// show any hidden parents (that are actually hidden with display=none) so that the button is visible when taking measurements.  they are re-hidden below
			var $hiddenParents = $element.parents (':hidden').filter (function () {
				return $(this).css ('display') == 'none';
			});
			$hiddenParents.show ();

			// create the placeholder
			$element.wrap ($('<div class="core-buttonPlaceholder"><div class="core-buttonButtonBox"></div></div>'));
			var $buttonButtonBox = $element.parent ();
			var $placeHolder = $buttonButtonBox.parent ();

			// copy the css properties that may affect how the new placeholder sits on the page
			copyCssAttributes ($element, $placeHolder, true);

			// add the fake html to appear below the hidden file input field
			var $fakeInputBlock = $('<div class="core-buttonFake"><a href=""></a><div class="core-transformInputContentEnd"></div></div>');	// adding the "core-transformInputContentEnd" div causes the height of the core-buttonFake to be the full height of it's content
			$fakeInputBlock.find ('a').html ($element.html ());	// give the new link the same content as the original link
			$placeHolder.append ($fakeInputBlock);

			makeAnchorAButton ($fakeInputBlock.find ('a'));		// turn the a elements into an anchor-button



			// put the invisilble file input field ABOVE the visible fake input block
			$element.css ('z-index', conf.zIndex);
			$placeHolder.css ('z-index', conf.zIndex - 1);

			// set the width/height of the invisible button so it's wide/tall enough
			$element.width ($fakeInputBlock.outerWidth ());
			$element.height ($fakeInputBlock.outerHeight ());
			$element.css ('z-index', 10);


			// position the hidden file input field so that it's aligned to the right (ie. the button is shown, on firefox & ie)
			$element.css ('left', '-' + ($element.outerWidth () - $fakeInputBlock.outerWidth () - 5) + 'px');

			// set the width and height of the file input button box (that contains the invisible file input field) so that covers the desired area
//			$buttonButtonBox.width ($fakeInputBlock.outerWidth ());
//			$buttonButtonBox.height ($fakeInputBlock.outerHeight ());

			// set the height of the placeholder so that the following html flows below it
			$placeHolder.height ($fakeInputBlock.outerHeight ());

			$hiddenParents.hide ();

			return true;
		};





		// update the link,  making it look like a button
		var transformAnchorButton = function () {
			return makeAnchorAButton ($element);
		};





		// put this element into a placeholder element
		var transformDropdownLink = function () {

			// show any hidden parents (that are actually hidden with display=none) so that the button is visible when taking measurements.  they are re-hidden below
			var $hiddenParents = $element.parents (':hidden').filter (function () {
				return $(this).css ('display') == 'none';
			});
			$hiddenParents.show ();

			// put a placeholder into the page to take up the same amount of space as the drop-down
			var $placeHolder = $('<span class="core-dropdownPH">.</span>');
			$placeHolder.css ('z-index', conf.zIndex - 1);

			$element.wrap ('<span class="core-dropdownBlock"/>');
			var $dropdownBlock = $element.parent ();
			$dropdownBlock.css ('z-index', conf.zIndex);
			$dropdownBlock.after ($placeHolder);



			// update the main link to make it look right
			$element.addClass ('core-mainLink');
//			if (conf.dropdownIconLeft)
//				$element.addClass ('core-iconOnLeft').prepend ('<span class="core-icon ' + conf.dropdownIconLeft + '"></span>');
			if (conf.dropdownIconRight)
				$element.addClass ('core-iconOnRight').append ('<span class="core-icon ' + conf.dropdownIconRight + '"></span>');
			// position the icons vertically neatly
			$element.find ('.core-icon').map (function () {
				$(this).css ('margin-top', parseInt (($element.height () - $(this).height ()) / 2) + 'px');
			});



			// create the html that will appear when the drop-down (link) is clicked
			var $dropdownBox = $(conf.dropDownContent);
			$dropdownBox.addClass ('core-box');

			// give the li's a background colour when mouse'ed over
			$dropdownBox.find ('>li>a').bind ('mouseenter.core-transformInput', function () {
				$(this).addClass ('hover');
			})
			$dropdownBox.find ('>li>a').bind ('mouseleave.core-transformInput', function () {
				$(this).removeClass ('hover');
			})
			$dropdownBlock.append ($dropdownBox);



			// functions to open and close the drop-down
			var open = function () {
				if (!$dropdownBox.is (':visible')) {
					$dropdownBox.outerWidth (Math.max ($dropdownBox.outerWidth (), $element.outerWidth ()));
					$placeHolder.width ($dropdownBlock.outerWidth ());
					$dropdownBlock.addClass ('core-dropdownBlockActive');
					$dropdownBox.show ('blind', 'fast');
				}
			}
			var closing = false;
			var close = function () {
				if (($dropdownBox.is (':visible')) && (!closing)) {
					closing = true;
					$dropdownBox.hide ('blind', 'fast', function () { $dropdownBlock.removeClass ('core-dropdownBlockActive'); closing = false; });
				}
			}



			// observe the main-link clicks
			$element.click (function (e) {
				e.preventDefault ();

				// show the drop-down
				if (!$dropdownBox.is (':visible'))
					open ();
				// hide the drop-down
				else
					close ();
			});

			// handle the easyClose events (click outside the popover + esc-keypress)
			$(document).bind ('click.core-transformInput', function (e) {
				// check to make sure the user didn't click -within- this drop-down
				if ($(e.target).parents ().index ($dropdownBlock) < 0)
					close ();
			});

			// keyboard::escape
			// one callback is enough if multiple instances are loaded simultaneously
			$(document).bind ('keydown.core-transformInput', function (e) {
				if (e.keyCode == 27)
					close ();
			});



			// now that the drop-down has been set up,  set the width of the placeholder element that sits behind the drop-down,  so it fills up the space
			$placeHolder.width ($dropdownBlock.outerWidth ());

			// reposition the select vertically if needed (with top-margin)
			if (conf.vertAlignDropDown) {
				var dropdownBlockOffset = $dropdownBlock.offset ();
				var dropdownBlockTop = parseInt (dropdownBlockOffset.top + ($dropdownBlock.outerHeight () / 2));	// get the middle point

				var placeHolderOffset = $placeHolder.offset ();
				var placeHolderTop = parseInt (placeHolderOffset.top + ($placeHolder.outerHeight () / 2));	// get the middle point


				if (dropdownBlockTop != placeHolderTop) {
					var marginTop = parseInt ($dropdownBlock.css ('margin-top'));
					if (isNaN (marginTop))
						marginTop = 0;
					$dropdownBlock.css ('margin-top', (marginTop - (dropdownBlockTop - placeHolderTop)) + 'px');
				}
			}

			$hiddenParents.hide ();

			return true;
		};





		// radio input
		var transformRadioInput = function () {

			// try to find it's enclosing label
			var $label = $element.parent ('label');

			// create the placeholder
			$element.wrap ($('<div class="core-radioPlaceholder"></div>'));
			var $placeHolder = $element.parent ();

			// copy the css classes from the radio button to the placeholder (so that different styles can be applied to the image. eg. a small radio input)
			var classes = $element.attr ('class');
			if (classes.length) {
				$.each ($element.attr ('class').split (' '), function (index, value) {
					$placeHolder.addClass (value);
				});
			}



			// copy the css properties that may affect how the new placeholder sits on the page
//			copyCssAttributes ($element, $placeHolder);
			$element.addClass ('core-originalRadio');	// hide the original



			// add the fake html to appear below the hidden file input field
			var $fakeRadio = $('<a class="core-radioInput"/>');	// adding the "core-transformInputContentEnd" div causes the height of the core-buttonFake to be the full height of it's content
			$placeHolder.prepend ($fakeRadio);

			(($element.attr ('checked')) && ($fakeRadio.addClass('core-radioInputChecked')));	// initially draw the radio button if required

			// if this radio input is inside a label,  give it some padding
			if ($label.length) {
				$label.addClass ('core-radioLabel');
				$fakeRadio.addClass ('core-radioInputWithLabel');
			}





			// re-draw the fake radio button
			var setFakeElementClass = function () {
				(($element.attr ('checked')) && ($fakeRadio.addClass ('core-radioInputChecked')) || ($fakeRadio.removeClass ('core-radioInputChecked')));
			};

			// unselect all sibling radio buttons
			var unselectSiblingRadios = function () {
				var origChecked = $element.attr ('checked');
				var $siblings = $('input[type=radio][name="' + element.attr ('name') + '"]', $element.closest ('form'));	// find radios with the same name in the same form
				if (!$siblings.length)
					$siblings = $('input[type=radio][name="' + element.attr ('name') + '"]');	// or if none found,  use radios with the same name anywhere in the page

				$siblings.each (function () {
					$(this).attr ('checked', false);	// unselect each one
					$(this).trigger ('customRedraw');	// redraw each one
				});

				$element.attr ('checked', origChecked);	// set this one the way it should be
				setFakeElementClass ();	// redraw it
				return true;
			};

			// uncheck all other radio inputs of same name (in the same form)
			$element.bind ('click.core-transformInput', function (e) {
//				e.preventDefault ();
				if ($element.attr ('disabled'))
					return false;
//alert ('click');
//alert ('clickA: ' + $element.attr ('id') + ' ' + $element.attr ('checked'));
				$(this).attr ('checked', true);
				unselectSiblingRadios ();
				setFakeElementClass ();
			});

			// uncheck all other radio inputs of same name (in the same form)
//			$element.bind ('change.core-transformInput', function (e) {
//alert ('change');
//			});

			$fakeRadio.bind ('click.core-transformInput', function (e) {
				e.preventDefault ();
				if ($element.attr ('disabled'))
					return false;
//alert ('fake radio click');
				var origChecked = $element.attr ('checked');

//				$element.attr ('checked', true);
//				unselectSiblingRadios ();
//				setFakeElementClass ();
				if (!origChecked) {
					$element.attr ('checked', true);
					$element.trigger ('customChange');
					$element.trigger ('change');
				}
				return false;
			});

			// uncheck sibling radio buttons and re-draw
			$element.bind ('customChange.core-transformInput', function (e) {
//alert ('custom change');
				if ($element.attr ('disabled'))
					return false;

				unselectSiblingRadios ();
			});

			// redraw this radio button
			$element.bind ('customRedraw.core-transformInput', function (e) {
//alert ('custom redraw');
//				if ($element.attr ('disabled'))
//					return false;
				setFakeElementClass ();
			});

			return true;
		};





		// checkbox input
		var transformCheckboxInput = function () {

			// try to find it's enclosing label
			var $label = $element.parent ('label');

			// create the placeholder
			$element.wrap ($('<div class="core-checkboxPlaceholder"></div>'));
			var $placeHolder = $element.parent ();

			// copy the css classes from the checkbox to the placeholder (so that different styles can be applied to the image. eg. a small checkbox input)
			var classes = $element.attr ('class');
			if (classes.length) {
				$.each ($element.attr ('class').split (' '), function (index, value) {
					$placeHolder.addClass (value);
				});
			}



			// copy the css properties that may affect how the new placeholder sits on the page
//			copyCssAttributes ($element, $placeHolder);
			$element.addClass ('core-originalCheckbox');	// hide the original

			var setFakeElementClass = function () {
				(($element.attr ('checked')) && ($fakeCheckbox.addClass ('core-checkboxInputChecked')) || ($fakeCheckbox.removeClass ('core-checkboxInputChecked')));
			};

			// add the fake html to appear below the hidden file input field
			var $fakeCheckbox = $('<a class="core-checkboxInput"/>');	// adding the "core-transformInputContentEnd" div causes the height of the core-buttonFake to be the full height of it's content
			$placeHolder.prepend ($fakeCheckbox);

			(($element.attr ('checked')) && ($fakeCheckbox.addClass('core-checkboxInputChecked')));	// initially draw the checkbox button if required

			// if this checkbox input is inside a label,  give it some padding
			if ($label.length) {
				$label.addClass ('core-checkboxLabel');
				$fakeCheckbox.addClass ('core-checkboxInputWithLabel');
			}





			// because ie browsers don't seem to trigger the click when the user clicks on the fake element (when it's inside the label)
			// handle this click separately
			$fakeCheckbox.bind ('click.core-transformInput', function (e) {
				e.preventDefault ();
				if ($element.attr ('disabled'))
					return false;

//alert ('click 2: ' + $element.attr ('id') + ' ' + $element.attr ('checked'));
				$element.attr ('checked', $element.attr ('checked') ? false : true);
//				setFakeElementClass ();
				$element.trigger ('customChange');
				$element.trigger ('change');
				return false;
			});

			// change the class of the fake checkbox (to make it look checked/unchecked) based on the real checkbox input's status
			$element.bind ('click.core-transformInput customChange.core-transformInput', function (e) {
//				e.preventDefault ();
				if ($element.attr ('disabled'))
					return false;
//alert ('clickA: ' + $element.attr ('id') + ' ' + $element.attr ('checked'));
				setFakeElementClass ();
			});

			return true;
		};





		// text input
		var transformTextInput = function () {

			// show any hidden parents (that are actually hidden with display=none) so that the button is visible when taking measurements.  they are re-hidden below
			var $hiddenParents = $element.parents (':hidden').filter (function () {
				return $(this).css ('display') == 'none';
			});
			$hiddenParents.show ();

			$element.show ();

			// remove the padding inside the input field for non-msie browsers (chrome and firefox don't need it but ie does)
			if (!$.browser.msie) {
				if ($.browser.webkit)
					$element.css ({ 'padding-top': '1px', 'padding-bottom': 0 });
				else
					$element.css ({ 'padding-top': 0, 'padding-bottom': 0 });
			}

			// create the placeholder
			$element.wrap ($('<div class="core-textInputPlaceholder"></div>'));
			var $placeHolder = $element.parent ();

			// copy the css classes from the radio button to the placeholder (so that different styles can be applied to the image. eg. a small radio input)
			var classes = $element.attr ('class');
			if (classes.length) {
				$.each ($element.attr ('class').split (' '), function (index, value) {
					$placeHolder.addClass (value);
				});
			}

			copyCssAttributes2 ($element, $placeHolder);

			// create the nice fake looking background
			var $fakeTextInput = $('<div class="core-fakeTextInput"><span class="core-a"/><span class="core-c"/><span class="core-b"/></div>');
//			var $fakeTextInput = $('<div class="core-fakeTextInput">hello</div>');
//			var $fakeTextInput = $('<div>hello</div>');
			$placeHolder.append ($fakeTextInput);

			// set the width of the thing
			$placeHolder.width ($element.outerWidth ());

			$hiddenParents.hide ();

			return true;
		};




















		// take an anchor and turn it into a button (make it look like a button)
		var makeAnchorAButton = function ($anchor) {
			var text = $anchor.html ();

			$anchor.addClass (conf.buttonCssClass)

			// work out if the anchor has a fixed with (if so then the html needs to be put together differently
			var origWidthCss = $anchor.css ('width');
			var origWidth = $anchor.outerWidth ();
			$anchor.css ('width', 'auto');

			// no fixed width
			if ($anchor.outerWidth () == origWidth)
				$anchor.css ('width', '').html ('<span class="core-a"/><span class="core-b"/><span class="core-c"/>').find ('.core-b').html (text);
			// fixed width
			else {
				$anchor.css ('width', origWidthCss).html ('<span class="core-a"/><span class="core-b"/><span class="core-c"/>').find ('.core-b').html (text);
				var widthA = $anchor.find ('.core-a').width ();
				var widthC = $anchor.find ('.core-c').width ();
				$anchor.find ('.core-b').width (origWidth - (widthA + widthC));
			}

			return true;
		};




/**
		// take an anchor-button and set it's background colour
		var setAnchorButtonBackgroundColour = function ($anchor) {
			var backgroundColorRGB = $anchor.parent ().getBackgroundColor ();
			$anchor.find ('span').css ('background-color', 'rgb(' + backgroundColorRGB[0] + ',' + backgroundColorRGB[1] + ',' + backgroundColorRGB[2] + ')');
			return true;
		};
/**/
		// take the styles that will affect the positioning of the placeholder from the original button
		var copyCssAttributes = function ($source, $dest) {

			// copy these attributes
			$.each (['margin-left', 'margin-right', 'margin-top', 'margin-bottom', 'float', 'display'], function (index, value) {
				$dest.css (value, $source.css (value));
			});

			// remove these attributes from the orignal
			$.each (['margin', 'margin-left', 'margin-right', 'margin-top', 'margin-bottom', 'padding', 'padding-left', 'padding-right', 'padding-top', 'padding-bottom'], function (index, value) {
				$source.css (value, 0);
			});

			return true;
		};

		// take the styles that will affect the positioning of the placeholder from the original button
		// leave padding and float (for textInputs)
		var copyCssAttributes2 = function ($source, $dest) {

			// copy these attributes
			$.each (['margin-left', 'margin-right', 'margin-top', 'margin-bottom', 'display'], function (index, value) {
				$dest.css (value, $source.css (value));
			});

			// remove these attributes from the orignal
			$.each (['margin', 'margin-left', 'margin-right', 'margin-top', 'margin-bottom'], function (index, value) {
				$source.css (value, 0);
			});
			return true;
		};

		// assign the callbacks
		var assignCallbacks = function () {
			$.each (['onBeforeTransform', 'onTransform'], function (i, name) {

				// configuration
				if ($.isFunction (conf[name]))
					$element.bind (name, conf[name]);

				// API
				$element[name] = function (fn) {
					$element.bind (name, fn);
					return $element;
				};
			});
			return true;
		};

		// initialise the element
		return api.init ();
	}



























	var transform = function ($items, conf, defaultConf, type) {

		$items.each (function () {
			// only apply coreTransformInput to this element if it hasn't already been applied
			if ((!$(this).hasClass ('core-transformed')) && (!$(this).hasClass ('core-ignoreTransformInput'))) {
				conf = $.extend (true, {}, defaultConf, conf);

				// only apply coreTransformInput to this element if it hasn't already been applied
//				if (!$this.data ('transformInput')) {
//				if (!$this.hasClass ('core-transformed')) {
					var api = new transformInput ($(this), conf, type);
					if (api.convertedOk ())
						$(this).data ('transformInput', api);
//				}
			}
		});

		return $items;
	};

	// file inputs
	$.fn.coreTransformFileInput = function (conf) {
		return transform (this, conf, $.core.transformInput.fileInputConf, 'fileInput');
	};
	// apply transform to all file inputs
	$.coreApplyTransformFileInputs = function (conf) {
//		$('input[type=file]:not(.core-ignoreTransformInput)').livequery (function () {
		$('input[type=file]').livequery (function () {
			$(this).coreTransformFileInput (conf);
		});
		return true;
	};

	// buttons
	$.fn.coreTransformButton = function (conf) {
		return transform (this, conf, $.core.transformInput.buttonConf, 'button');
	};
	// apply transform to all buttons
	$.coreApplyTransformButtons = function (conf) {
//		$('button:not(.core-ignoreTransformInput)').livequery (function () {
		$('button').livequery (function () {
			$(this).coreTransformButton (conf);
		});
		return true;
	};

	// anchorButtons (anchors to look like buttons)
	$.fn.coreTransformAnchorButton = function (conf) {
		return transform (this, conf, $.core.transformInput.buttonConf, 'anchorButton');	// 'buttonConf' on purpose
	}
	// apply transform to all anchor-buttons
	$.coreApplyTransformAnchorButtons = function () {
//		$('.core-anchorButton:not(.core-ignoreTransformInput)').livequery (function () {
		$('.core-anchorButton').livequery (function () {
			$(this).coreTransformAnchorButton ();
		});
		return true;
	};

	// drop down link
	$.fn.coreTransformDropdownLink = function (conf) {
		return transform (this, conf, $.core.transformInput.dropdownLinkConf, 'dropdownLink');
	};

	// radio input
	$.fn.coreTransformRadio = function (conf) {
		return transform (this, conf, $.core.transformInput.radioConf, 'radioInput');
	};
	// apply transform to all radio inputs
	$.coreApplyTransformRadios = function () {
//		$('input[type=radio]:not(.core-ignoreTransformInput)').livequery (function () {
		$('input[type=radio]').livequery (function () {
			$(this).coreTransformRadio ();
		});
		return true;
	};

	// checkbox input
	$.fn.coreTransformCheckbox = function (conf) {
		return transform (this, conf, $.core.transformInput.checkboxConf, 'checkboxInput');
	};
	// apply transform to all checkbox inputs
	$.coreApplyTransformCheckboxes = function () {
//		$('input[type=checkbox]:not(.core-ignoreTransformInput)').livequery (function () {
		$('input[type=checkbox]').livequery (function () {
			$(this).coreTransformCheckbox ();
		});
		return true;
	};

	// text input
	$.fn.coreTransformTextInput = function (conf) {
		return transform (this, conf, $.core.transformInput.textInputConf, 'textInput');
	};
	// apply transform to all text inputs
	$.coreApplyTransformTextInputs = function () {
//		$('input[type=text]:not(.core-ignoreTransformInput),input[type=password]:not(.core-ignoreTransformInput)').livequery (function () {
		$('input[type=text],input[type=password]').livequery (function () {
			$(this).coreTransformTextInput ();
		});
		return true;
	};








	// perform any updates to the 'fake' transformed button (that was rendered into the html instead of using transform inputs)
	$.fn.coreFixFakeTransformAnchorButton = function (conf) {

		this.each (function () {

			if ((!$(this).hasClass ('core-transformed')) && (!$(this).hasClass ('core-ignoreTransformInput'))) {

				var $a = $(this).find ('.core-buttonFake a');
				$a.width ($a.find ('span.core-a').outerWidth () + $a.find ('span.core-b').outerWidth () + $a.find ('span.core-c').outerWidth ());
				$(this).find ('.core-buttonButtonBox button').width ($a.outerWidth ());
			}
		});

		return $(this);
	};
	// apply transform fix to all fake transformed buttons
	$.coreApplyFixFakeTransformAnchorButtons = function () {
//		$('.core-fakeButtonPlaceholder:not(.core-ignoreTransformInput)').livequery (function () {
		$('.core-fakeButtonPlaceholder').livequery (function () {
			$(this).coreFixFakeTransformAnchorButton ();
		});
		return true;
	};

}) (jQuery);









/*/////////////////////////////////////////////
// path: /javascript/front/custom.js         //
// created: Wed, 19 Oct 2011 15:42:18 +1100  //
// modified: Wed, 19 Oct 2011 14:02:29 +1100 //
// size: 7028 bytes                          //
/////////////////////////////////////////////*/

// initialisation BEFORE the dom has loaded
(function($) {

    
	// apply inFieldLabels to the page for existing and future elements
	$.applyInFieldLabels ();

	// stop "fake" links from doing anything when clicked
	$('.jsFakeLink').livequery (function () {
		$(this).bind ('click', function (e) {
			e.preventDefault ();
		});
	});





	// google maps
	$.core.googleAddressSuggest.setDefaultGoogleBounds (-43.068888,111.621094,-11.005904,154.819336);	// swLat, swLong, neLat, neLong
	$.core.googleAddressSuggest.setDefaultGoogleRegion ('AU');	// http://www.iana.org/assignments/language-subtag-registry
	$.core.googleAddressSuggest.updateDefaultConf ({ maxSuggestions: 15 });

	// observe the login links - create a login popover when clicked
	$('#link_login,.jsLoginPopover').live ('click.loginPopover', function () {
		$.createPopover (
			{	content: '<h3 class="noSpaceBelow">Login to Menulog</h3>'
			},
			{	template: 'helperNoTitle',
				attachTo: 'mouse',
				baseAttachDirectionX: 'left',
				popoverAttachDirectionX: 'right',
				baseAttachDirectionY: 'top',
				popoverAttachDirectionY: 'top',
				attachOffsetX: 18,
				attachOffsetY: -17,
				addCloseX: true,
				width: 240,
				height: 300,
				applyMask: true,
				applyDraggable: true,
				easyClose: true,
				ajax: 'http://www.basepizza.com.au/accounts/ajax_login.php'
			}
		);
		var pageTracker = _gat._getTracker("UA-698294-1");
		pageTracker._setVar("loggedin");
		return false;
	});


	// observe the my account links - create a popover when clicked
	$('#link_myAccount,.jsMyAccountPopover').live ('click.loginPopover', function () {
		
		var $link = $(this);
		var $template = $('#template_myAccountNavs');
		if ($template.length) {
			$.createPopover (
				{	content: $template.html ()
				},
				{	template: 'blank',
					attachTo: $link,
					baseAttachDirectionX: 'left',
					popoverAttachDirectionX: 'left',
					baseAttachDirectionY: 'bottom',
					popoverAttachDirectionY: 'top',
					attachOffsetX: 5,
					attachOffsetY: 0,
					easyClose: true
				}
			);
		}
		return false;
	});

	showMorePopover = function ($template) {
		$.createPopover (
		{	content: $template.html ()
		},
		{	template: 'helperNoTitle',
			attachTo: 'mouse',
			baseAttachDirectionX: 'left',
			popoverAttachDirectionX: 'right',
			baseAttachDirectionY: 'top',
			popoverAttachDirectionY: 'top',
			attachOffsetX: 18,
			attachOffsetY: -17,
			addCloseX: true,
			maxWidth: 350
		});
	}

	forgottenPasswordLink = function ($element) {
		$($element)
		.unbind ('click.forgottenPassword')
		.bind ('click.forgottenPassword', function () {
			$.createPopover (
				{	title: 'Forgotten Password'
				},
				{	template: 'helper',
					attachTo: 'mouse',
					baseAttachDirectionX: 'left',
					popoverAttachDirectionX: 'right',
					baseAttachDirectionY: 'top',
					popoverAttachDirectionY: 'top',
					attachOffsetX: 18,
					attachOffsetY: -17,
					addCloseX: true,
					width: 283,
//					height: 100,
					applyMask: true,
					applyDraggable: true,
					easyClose: true,
					ajax: 'http://www.basepizza.com.au/accounts/ajax_forgotten_password.php'
				}
			);
			return false;
		});
		return true;
	}

	// add browser specific classes to relevant elements on the page
	if (($.browser.msie) && ($.browser.version < 8)) {
		$('label.radio').livequery (function () {		$(this).addClass ('ie7Radio');		});
		$('label.checkbox').livequery (function () {	$(this).addClass ('ie7Checkbox');	});
		$('.jsBrowserVer').livequery (function () {		$(this).addClass ('ie7');			});
	}
	else if (($.browser.msie) && ($.browser.version < 9)) {
		$('label.radio').livequery (function () {		$(this).addClass ('ie8Radio');		});
		$('label.checkbox').livequery (function () {	$(this).addClass ('ie8Checkbox');	});
		$('.jsBrowserVer').livequery (function () {		$(this).addClass ('ie8');			});
	}
	else if (($.browser.msie) && ($.browser.version >= 9)) {
		$('label.radio').livequery (function () {		$(this).addClass ('ie9Radio');		});
		$('label.checkbox').livequery (function () {	$(this).addClass ('ie9Checkbox');	});
		$('.jsBrowserVer').livequery (function () {		$(this).addClass ('ie9');			});
	}

	// make a request to the server when the following input fields have changed
	$.fn.ajaxOnUpdate = function (conf) {

		// default values specific to the confirm action popover
		conf = $.extend (true, {}, { type: 'POST', disable: null, data: {}, success: $.core.processAjaxResponse }, conf);

		// observe clicks on each $(this) element
		var $allThis = $(this);
		$allThis.each (function () {
			var $input = $(this);
			$input.change (function () {

				// disable the fields if necessary
				if (conf.disable)
					$(conf.disable).attr ('disabled', true);

				// make the ajax request
				var myConf = $.extend (true, {}, {}, conf);
				$allThis.map (function () {
					myConf.data[$(this).attr ('name')] = $(this).val ();
				});

				$.ajax (myConf);
			});
		});
	}
}) (jQuery);

// initialisation WHEN the dom has loaded
jQuery ().ready ((function ($) {

	return function () {

		// render the "please wait" mouse element into the page so any images load
		$.core.mouse.primePleaseWaitElement ();

		// add browser specific classes to relevant elements on the page
		if (($.browser.msie) && ($.browser.version < 8)) {
			$('label.radio').map (function () {		$(this).addClass ('ie7Radio');		});
			$('label.checkbox').map (function () {	$(this).addClass ('ie7Checkbox');	});
			$('.jsBrowserVer').map (function () {	$(this).addClass ('ie7');			});
		}
		else if (($.browser.msie) && ($.browser.version < 9)) {
			$('label.radio').map (function () {			$(this).addClass ('ie8Radio');		});
			$('label.checkbox').map (function () {		$(this).addClass ('ie8Checkbox');	});
			$('.jsBrowserVer').map (function () {		$(this).addClass ('ie8');			});
		}
		else if (($.browser.msie) && ($.browser.version >= 9)) {
			$('label.radio').map (function () {			$(this).addClass ('ie9Radio');		});
			$('label.checkbox').map (function () {		$(this).addClass ('ie9Checkbox');	});
			$('.jsBrowserVer').map (function () {		$(this).addClass ('ie9');			});
		}
	}

}) (jQuery));










/*/////////////////////////////////////////////
// path: /javascript/front/venue_page.js     //
// created: Mon, 16 Jan 2012 11:16:18 +1100  //
// modified: Mon, 16 Jan 2012 11:16:18 +1100 //
// size: 17778 bytes                         //
/////////////////////////////////////////////*/

(function ($) {

	var restaurantId = null;

	// record when things have been initialised (so they aren't twice)
	var takeawayPageInitialised = false;
	var takeawayMenuBlockInitialised = false;
	var diningPageInitialised = false;
	var bookIframeInitialised = false;
	var takeawayRatingPageInitialised = false;
	var diningRatingFormInitialised = false;
	var diningRatingsInitialised = false;

	// extra functions to be called when the takeaway/dining pages are initialised respectively
	var extraTakeawayPageInitFunctions = [];
	var extraTakeawayMenuInitFunctions = [];
	var extraDiningInitFunctions = [];

	var bookIframeUrl = null;

	var ajaxCache = [];

	// the anchors on the page that navigate around
	//					url #hash					page		block selector (required to be on the page for the block to work)	divs to show selector					nav link selector (to highlight)
	var pageContent = [[['#takeaway'],				'takeaway',	'#blockTakeawayMenu',												'#takeawayPage,#blockTakeawayMenu',		''],
						[['#reviews'],				'takeaway',	'#blockTakeawayRatings',											'#takeawayPage,#blockTakeawayRatings',	''],
						[['#dining','#details'],	'dining',	'#blockDiningAbout',												'#diningPage,#blockDiningAbout',		'#link_diningAbout'],
						[['#diningReviews'],		'dining',	'#blockDiningAbout',												'#diningPage,#blockDiningAbout',		'#link_diningAbout'],
						[['#menus'],				'dining',	'#blockDiningMenus',												'#diningPage,#blockDiningMenus',		'#link_diningMenu'],
						[['#invite'],				'dining',	'#blockInvite',														'#diningPage,#blockInvite',				'#link_diningInvite'],
						[['#specials'],				'dining',	'#blockDiningSpecials',												'#diningPage,#blockDiningSpecials',		'#link_diningSpecials'],
						[['#book'],					'dining',	'#blockBook',														'#diningPage,#blockBook',				'']];

	// store the analytics urls here,  ready for when a user views a particular hash
	var analyticsUrls = {};










	// show the content that correlates to the current url's #hash
	venuePage_init = function (tempRestaurantId) {
		restaurantId = tempRestaurantId;
		venuePage_navigate (true);		// show the right page to start with
		venuePage_observeHashChange ();	// check for #hash url changes
		return true;
	};

	// store an analytics url for use when the user browses to the various blocks
	venuePage_registerAnalyticsUrl = function (hash, url) {
		analyticsUrls[hash] = url;
		return true;
	};

	// find out when the url's #hash changes,  which happens when the user navigates within the page,  and when the user navigates forward/backwards via the browser's navigation
	venuePage_observeHashChange = function () {
		var pollPeriod = 200;	// ms
		var currentHash = window.location.hash;
		var checkHash = function () {
			// if the hash location has changed,  show the right content
			if (window.location.hash != currentHash) {
				currentHash = window.location.hash;
				venuePage_navigate (false);
			}
			hashTimeout = setTimeout (checkHash, pollPeriod);
		};
		var hashTimeout = setTimeout (checkHash, pollPeriod);
	};

	venuePage_initTakeawayPage = function () {

		if (!takeawayPageInitialised) {
			takeawayPageInitialised = true;
			$('#takeawayPage').show ();

			venuePage_initVenuePageTakeawayPopovers ();	// info1 box popover links
			venuePage_initVenuePageGallery ('#link_takeawayLogo,#link_viewTakeawayGallery', '#takeawayGallery');
			$('#venueTakeawayInfoBox, #generalDetailsBox').autoMatchHeight ();	// align the heights of the info1 and info2 top boxes
			$('#link_otherTakeawayRestaurants').coreTransformDropdownLink ({ dropDownContent: $('#template_takeawaySearchLinks').html () });
			$('#conditions').shortenText ({ maxWidth: 698, mode: 'truncate', moreInfoPopoverStyle:'venu_conditions', popoverConf: { maxWidth: 500} });	// limit the width of the conditions show above the menu

			// run any extra init functions
			$.each (extraTakeawayPageInitFunctions, function (index, fn) {
				fn.apply (this);
			});
		}
		return true;
	};
	venuePage_addTakeawayPageInitFunction = function (fn) {
		extraTakeawayPageInitFunctions.push (fn);
	};

	// initialise things specific to the takeaway menu page
	venuePage_initTakeawayMenuBlock = function (active) {

		if (active) {
			if (!takeawayMenuBlockInitialised) {

				takeawayMenuBlockInitialised = true;
				$('#takeawayPage,#blockTakeawayMenu').show ();

				// run any extra init functions
				$.each (extraTakeawayMenuInitFunctions, function (index, fn) {
					fn.apply (this);
				});
			}
		}


		// pause or un-pause the fixed pos elements
		var fixedPosApi;
		if (active) {
			$('#takeawayPage,#blockTakeawayMenu').show ();

			// start the fixed pos elements scrolling again
			if (fixedPosApi = $('#cartSummary').data ('fixedPos'))
				fixedPosApi.unpause ();
			if (fixedPosApi = $('#courseNav').data ('fixedPos'))
				fixedPosApi.unpause ();
		}
		else {
			// stop the fixed pos elements from scrolling
			if (fixedPosApi = $('#cartSummary').data ('fixedPos'))
				fixedPosApi.pause ();
			if (fixedPosApi = $('#courseNav').data ('fixedPos'))
				fixedPosApi.pause ();
		}

		return true;
	};
	venuePage_addTakeawayMenuInitFunction = function (fn) {
		extraTakeawayMenuInitFunctions.push (fn);
	};









	venuePage_initDining = function () {

		if (takeawayPageInitialised) {

			// stop the fixed pos elements from scrolling
			var fixedPosApi;
			if (fixedPosApi = $('#cartSummary').data ('fixedPos'))
				fixedPosApi.pause ();
			if (fixedPosApi = $('#courseNav').data ('fixedPos'))
				fixedPosApi.pause ();
		}

		if (!diningPageInitialised) {
			diningPageInitialised = true;

			venuePage_initVenuePageDiningPopovers ();	// info1 box popover links
			venuePage_initVenuePageGallery ('#link_diningLogo,#link_viewDiningGallery', '#diningGallery');
			// make the "map" popover work
			$('#link_viewMap').bind ('click', function () {
				activateMapPopover ('#link_viewMap', restaurantId);
				return false;
			});
			// make the about details' "more" link show the full about details
			$('#link_aboutUsMore').bind ('click', function () {
				$('#aboutUsPreview').hide ('blind');
				$('#aboutUs').show ('blind');
				return false;
			});
			// make the awards "more" link show the full list of awards
			$('#link_awardsMore').bind ('click', function () {
				$(this).hide ('blind');
				$('#awards').show ('blind');
				return false;
			});
			// make the awards "less" link show the preview list of awards
			$('#link_awardsLess').bind ('click', function () {
				$('#link_awardsMore').show ('blind');
				$('#awards').hide ('blind');
				return false;
			});

			// make the "manage your listing" link open the login popover
			$('#link_manageListing').bind ('click', function () {
				$.createPopover (
				{	title: 'Login to Menulog'
				},
				{	attachTo: 'mouse',
					baseAttachDirectionX: 'left',
					popoverAttachDirectionX: 'right',
					baseAttachDirectionY: 'top',
					popoverAttachDirectionY: 'top',
					attachOffsetX: 18,
					attachOffsetY: -17,
					addCloseX: true,
					applyDraggable: true,
					width: 330,
					ajax: $(this).attr ('href')
				});				
				return false;
			});

			// make the "latest specials" box on the RHS link to the specials block when clicked
			$('#latestSpecials').map (function () {
				var $latestSpecials = $(this);
				$latestSpecials.bind ('click', function () {
					document.location.href = $latestSpecials.find ('a').attr ('href');
					return false;
				});
			});

			// run any extra init functions
			$.each (extraDiningInitFunctions, function (index, fn) {
				fn.apply (this);
			});
		}
		return true;
	};
	venuePage_addDiningInitFunction = function (fn) {
		extraDiningInitFunctions.push (fn);
	};

	venuePage_initDiningRatingsBlock = function (active) {
		if (active) {
			if (!diningRatingsInitialised) {
				$('#diningRatingsPreview').hide ('blind');
				$('#existingDiningRatings').show ('blind');
				diningRatingsInitialised = true;
			}
		}
		return true;
	};

	// work out which block to show based on the current url
	venuePage_navigate = function (firstTime) {

		// find the relevant block element to show
		var currentHash = window.location.hash.split ('-').shift ();	// grab whatever is before the first '-' character from the url's hash
		var found = false;
		$.each (pageContent, function (index, contentData) {
			var hashes = contentData[0];
			var blockSelector = contentData[2];
			var $block = $(blockSelector);

			if (($.inArray (currentHash, hashes) != -1)	&& ($block.length)) {

				venuePage_showContent (contentData);
				found = true;
				return false;
			}
		});
		// if no other was found,  show the default content element
		// go in order (ie. try takeaway first,  then dining about...)
		if ((!found) && (firstTime)) {
			$.each (pageContent, function (index, contentData) {
				var blockSelector = contentData[2];
				var $block = $(blockSelector);

				if ($block.length) {
					venuePage_showContent (contentData);
					return false;
				}
			});
		}
		return true;
	};

	// show the specified page
	venuePage_showContent = function (contentData) {
		var hashes = contentData[0];
		var page = contentData[1];
		var $links = $(contentData[4]);

		// "un-select" the selected nav tab
		$('#diningNav').find ('li.selected').removeClass ('selected');
		$('#takeawayNav').find ('li.selected').removeClass ('selected');

		// initialise the relevant page
		if (page == 'dining')
			venuePage_initDining ();
		else	// takeaway
			venuePage_initTakeawayPage ();

		// initialise the takeaway menu page (or tell it to pause things if it's not the current block)
		venuePage_initTakeawayMenuBlock ($.inArray ('#takeaway', hashes) != -1);
		venuePage_initDiningRatingsBlock ($.inArray ('#diningReviews', hashes) != -1);



		// show the right block
		var $toShowElements = null;
		var toHideSelectors = [];
		$.each (pageContent, function (index, contentData2) {
			var hashes2 = contentData2[0];
			var toShowSelector = contentData2[3];
			
			if (hashes2 == hashes) {
				$toShowElements = $(toShowSelector);
				$links.parent ('li').addClass ('selected');	// "select" this block's tab
			}
			else
				toHideSelectors.push (toShowSelector);
		});

		// hide the other pages' content
		if (toHideSelectors.length)
			$(toHideSelectors.join (',')).hide ();
		// show just this page's content
		if ($toShowElements)
			$toShowElements.show ();



		// initialise the booking iframe if the booking page is to be shown
		if ($.inArray ('#book', hashes) != -1)
			venuePage_initVenuePageBookIframe ();

		// if the user has browsed to a page that needs to request something via ajax...
		if (($.inArray ('#reviews', hashes) != -1)
		|| ($.inArray ('#diningReviews', hashes) != -1)
		|| ($.inArray ('#dining', hashes) != -1)
		|| ($.inArray ('#menus', hashes) != -1)
		|| ($.inArray ('#invite', hashes) != -1)
		|| ($.inArray ('#book', hashes) != -1)) {

			var currentHash = window.location.hash.split ('-').shift ();	// grab whatever is before the first '-' character from the url's hash

			// urls for the takeaway ratings page
			var urls = [];
			if ($.inArray ('#reviews', hashes) != -1) {
				var tempUrl = 'http://www.basepizza.com.au/venue/ajax_list_ratings.php?systemType=takeaway&restaurantId=' + restaurantId + '&hash=' + window.location.hash.replace ('#', '');
				if (!takeawayRatingPageInitialised) {
					tempUrl += '&loadRatingForm=1';	// show the new rating from the first time
					takeawayRatingPageInitialised = true;
				}
				urls.push (tempUrl);
			}
			// url for the dining page rating form
			else if ((($.inArray ('#dining', hashes) != -1)
			|| ($.inArray ('#menus', hashes) != -1)
			|| ($.inArray ('#invite', hashes) != -1)
			|| ($.inArray ('#book', hashes) != -1)
			|| (currentHash == '#diningReviews'))
			&& (!diningRatingFormInitialised)) {
				diningRatingFormInitialised = true;
				urls.push ('http://www.basepizza.com.au/venue/ajax_dining_rating_form.php?restaurantId=' + restaurantId);
			}



			// if we're showing the dining reviews and there's more to the hash,  then load the relevant ratings
			if ((currentHash == '#diningReviews') && (currentHash != window.location.hash))
				urls.push ('http://www.basepizza.com.au/venue/ajax_list_ratings.php?systemType=dining&restaurantId=' + restaurantId + '&hash=' + window.location.hash.replace ('#', ''));

			// if we're showing the dining menus there's more to the hash,  then load the relevant menu
			if (currentHash == '#menus')
				urls.push ('http://www.basepizza.com.au/venue/ajax_dining_menu.php?restaurantId=' + restaurantId + '&hash=' + window.location.hash.replace ('#', ''));


			// fetch the ratings from the server
			if (urls.length) {

				$.each (urls, function (index, url) {

					// check to see if the response to this request has already been cached
					var cacheHit = false;
					$.each (ajaxCache, function (index, value) {
						if (value.url == url) {
							$.core.processAjaxResponse (value.response);
							cacheHit = true;
							return false;
						}
					});

					// send the request
					if (!cacheHit) {
						$.ajax ({
							url: url,
							type: 'GET',
							dataType: 'json',
							success: function (json) {
								ajaxCache.push ({ url: url, response: json });
								return $.core.processAjaxResponse (json);
							}
						});
					}
				});
			}
		}

		// send the analytics request to google if the relevant url is available
		$.each (hashes, function (index, hash) {
			if (analyticsUrls[hash.substr (1)] !== undefined) {
				analytics_trackPageview (analyticsUrls[hash.substr (1)]);
				return false;	// break out of the loop
			}
		});

		// track the page view with neilson tagging code
		loadNeilsonTrackingPixel (true);	// true: force reload

		return true;
	};

	// register the iframe book url
	venuePage_registerBookIframeUrl = function (newBookIframeUrl) {
		bookIframeUrl = newBookIframeUrl;
		return true;
	};

	// initialise the venue page dining book iframe
	venuePage_initVenuePageBookIframe = function (siteSection) {
		// initialise the booking iframe if the booking page is to be shown
		if (!bookIframeInitialised) {
			bookIframeInitialised = true;
			$('#blockBook').html ('<iframe src="' + bookIframeUrl + '" marginwidth="0" marginheight="0" hspace="0" vspace="0" frameBorder="0" scrolling="no"></iframe>');
		}
		return true;
	};

	// initialise the venue page popovers
	venuePage_initVenuePageTakeawayPopovers = function () {
		return venuePage_initVenuePagePopovers ([
			'takeawaySchedule,600',
			'takeawayAbout,450',
			'takeawaySpeedRating,450',
			'takeawayVouchers,450',
			'takeawayPaymentConditions,300'
		]);
	};
	venuePage_initVenuePageDiningPopovers = function () {
		return venuePage_initVenuePagePopovers ([
			'diningSchedule,600',
			'diningContactDetails,450'
		]);
	};
	venuePage_initVenuePagePopovers = function (linkDetails) {
		$.each (linkDetails, function (index, value) {

			var parts = value.split (',');
			var name = parts[0];
			var maxWidth = parseInt (parts[1]);

			$('#link_' + name).popoverTrigger (
			{	messageHtml: $('#template_' + name).html (),
				popoverConf:
				{	
					closeOtherPopovers:true,
					baseAttachDirectionX: 'left',
					popoverAttachDirectionX: 'right',
					baseAttachDirectionY: 'top',
					popoverAttachDirectionY: 'top',
					attachOffsetX: 18,
					attachOffsetY: -17,
					addCloseX: true,
					applyDraggable: true,
					onBeforePosition: function () {
						var $popover = $(this);
						$popover.css ({ display: 'block' });
						$popover.find ('dl').autoAlign ();
						$popover.find ('dd').after ($('<dd class="contentEnd"/>'));
						$popover.css ({ display: 'none' });
					},	//	# align the elements inside the popover
					maxWidth: maxWidth
				}
			});
		});
		return true;
	};

	// initialise the venue page photo galleries
	venuePage_initVenuePageGallery = function ($linkSelector, $gallerySelector) {
		// only make the links work if the gallery exists
		$gallerySelector = $($gallerySelector);
		if ($gallerySelector.length) {

			// make the photo gallery work
			$gallerySelector.find ('a[rel^=prettyPhoto]').prettyPhoto (
			{	animationSpeed: 'fast',
				slideshow: 3000,
				opacity: 0.7 }
			);
			// make the logo and "view gallery" links activate the photo gallery
			$($linkSelector)
			.addClass ('clickable')
			.click (function () {
				$gallerySelector.find ('a[rel^=prettyPhoto]').first ().click ();
				return false;
			});
		}
		return true;
	};

	// make the sliders in a rating form work
	venuePage_initRatingSliders = function (formSelector) {

		$form = $(formSelector);
		$form.find ('ul.ratingCriteriaList li').map (function () {
			var $li = $(this);
			var $input = $li.find ('input');
			var $ratingReadable = $li.find ('.ratingReadable');
			var value = (is_float ($input.val ()) ? parseFloat ($input.val ()) : '');

			$ratingReadable.text (value);

			var sliderValue = value;
			if (!is_float (sliderValue))
				sliderValue = 5;


			var $slider = $('<div/>').slider (
			{	
				range: 'min',
				min: 0,
				max: 10,
				value: sliderValue,
				step: 1,
				slide: function (event, ui) {
					$input.val (ui.value);
					$ratingReadable.text (ui.value);
				}
			});
			$input.after ($slider);
		});
	};
}) (jQuery);










/*/////////////////////////////////////////////
// path: /javascript/front/search_results.js //
// created: Tue, 24 Jan 2012 11:35:29 +1100  //
// modified: Tue, 24 Jan 2012 11:35:29 +1100 //
// size: 20433 bytes                         //
/////////////////////////////////////////////*/

(function($) {

	takeawaySearch_bindViewMapOrResultsLinks = function () {
		$('#link_viewMap').bind ('click', function (e) {
			e.preventDefault ();
			analytics_trackEvent({
                'category'  : 'ta_search',
                'action'    : 'link_viewMap'
			});			
			$('#searchResultBlock,#link_viewMap,#topPaginationListings').hide ();
			$('#mapBlock,#link_viewListings,#topPaginationMap').show ();
			$('#viewMode').val ('map');
			var api = $('#searchResultsMap').data ('googleMap').render ();	// render the map if it hasn't already been rendered
		});
		$('#link_viewListings').bind ('click', function (e) {
			e.preventDefault ();
			$('#searchResultBlock,#link_viewMap,#topPaginationListings').show ();
			$('#mapBlock,#link_viewListings,#topPaginationMap').hide ();
			$('#viewMode').val ('');	// 'listings' will be picked up by default
		});
		return true;
	};

	takeawaySearch_bindTakeawaySearchFormLinks = function () {
		$.each ([
		['#link_searchOptionsFood', '#searchOptionsFood', '#useFood'],
		['#link_searchOptionsCuisine', '#searchOptionsCuisine', '#useCuis'],
		['#link_searchOptionsDistance', '#searchOptionsDistance', '#useDist'],
		['#link_searchOptionsName', '#searchOptionsName', '#useRestName'],
		['#link_searchOptionsDiscounts', '#searchOptionsDiscounts', '#useSpec'],
		['#link_searchOptionsPaymentMethods', '#searchOptionsPaymentMethods', '#usePmtMth'],
		['#link_searchOptionsOrderTime', '#searchOptionsOrderTime', '#useTime'],
		['#link_searchOptionsAmbience', '#searchOptionsAmbience', '#useAmb'],
		['#link_searchOptionsAvgPrc', '#searchOptionsAvgPrc', '#useAvgPrc'],
		['#link_searchOptionsFoodFeatures', '#searchOptionsFoodFeatures', '#useFF'],
		['#link_searchOptionsBestFor', '#searchOptionsBestFor', '#useB4'],
		['#link_searchOptionsSpecialsOnly', '#searchOptionsSpecialsOnly', '#useSpecOnly']
		],
		function (index, value) {
			var $source = $(value[0]);
			var $dest = $(value[1]);
			var $useInput = $(value[2]);	// hidden field telling the server whether to use this search criteria or not (ie. if the section is closed then don't use it)
			$source.bind ('click', function () {
				if ($dest.is (':visible')) {
					$source.removeClass ('expanded');
					if ($useInput.length)
						$useInput.val ('');
				}
				else {
					$source.addClass ('expanded');
					if ($useInput.length)
						$useInput.val (1);
				}
				$dest.animate ({opacity: 'toggle', height: 'toggle'}, 300);
			});
		});
		return true;
	};

	takeawaySearch_bindOrderNowLaterOptions = function (nowSelector, laterSelector, dateTimeDivSelector) {
		$(nowSelector + ',' + laterSelector).bind ('change', function () {
			$(dateTimeDivSelector).animate ({opacity: 'toggle', height: 'toggle'}, 300);
		});
		return true;
	};

	takeawaySearch_addSearchCalendar = function (readableSelector, altSelector) {
		var nowDate = new Date ();
		var endDate = new Date (nowDate.getFullYear (), nowDate.getMonth () + 3, 0, 0, 0, 0, 0);	// the last day of the month,  2 full months ahead

		$(function () {
			$(readableSelector).datepicker (
			{	altField: altSelector,
				altFormat: 'yy-mm-dd',
				buttonImage: 'http://www.basepizza.com.au/images/icons/calendar_small.png',
				buttonImageOnly: true,
				buttonText: 'Show calendar',
				dateFormat: 'D, d MM',
				minDate: new Date (nowDate.getFullYear (), nowDate.getMonth (), nowDate.getDate (), 0, 0, 0, 0), 
				maxDate: new Date (endDate.getFullYear (), endDate.getMonth (), endDate.getDate (), 0, 0, 0, 0), 
				showOn: 'both' 
			});
		});

		return true;
	};

	takeawaySearch_bindPromotionPopoverLinks = function (restaurantIds, title) {
		$.each (restaurantIds, function (index, restaurantId) {
			var $link = $('#link_promotionMoreInfo' + restaurantId);
			var $template = $('#template_promotionsMoreInfo' + restaurantId);
			var $title = $('#restaurantRow' + restaurantId).find ('h2:first');
			$link.popoverTrigger (
			{	title: title.replace ('%%restaurant%%', $title.text ()),
				messageHtml: $template.html (),
				popoverConf:
				{	template: 'helper',
					closeOtherPopovers:true,
					easyClose: true,
					baseAttachDirectionX: 'left',
					popoverAttachDirectionX: 'right',
					baseAttachDirectionY: 'top',
					popoverAttachDirectionY: 'top',
					attachOffsetX: 18,
					attachOffsetY: -17,
					addCloseX: true,
					applyDraggable: true,
					maxWidth: 500
				}
			});
			$link.addClass ('clickable');
		});
		return true;
	};
	
	takeawaySearch_bindSpeedRatingPopoverLinks = function (restaurantIds) {
		$.each (restaurantIds, function (index, restaurantId) {
			var speedRatingHref = $('#speedRating_' + restaurantId);
			speedRatingHref.popoverTrigger ({
				title: 'User Speed Rating',
				messageHtml: '<p>Speed ratings are based on user reviews given by customers who have ordered from Menulog before. Ratings are calculated on a scale of 1-10.</p> <p>They are indicative only.</p>',
				popoverConf:
				{
					template: 'helper',
					easyClose: true,
					closeOtherPopovers:true,
					baseAttachDirectionX: 'right',
					popoverAttachDirectionX: 'right',
					baseAttachDirectionY: 'top',
					popoverAttachDirectionY: 'top',
					attachOffsetX: 58,
					attachOffsetY: -17,
					addCloseX: true,
					applyDraggable: true,
					maxWidth: 300
				}
			});
		});
		return true;
	};

	takeawaySearch_initVouchersAcceptedConditionsLink = function (link) {
		$link = $(link);

		var termsHtml = '<ol>\n<li>Available only at restaurants that display \'Vouchers Accepted\',</li>\n<li>Menulog facilitates the discount and pays the full amount directly to the restaurant.</li>\n<li>Vouchers can only be used in conjunction with paying via credit card,</li>\n<li>Available for 1st order per household,</li>\n<li>Must be used before its expiry date,</li>\n<li>Vouchers can only be used in full (ie. no change is given).</li>\n<li>Voucher code to be entered at end of checkout process</li>\n<li>Menulog reserves the right to charge the value of the voucher to your allotted credit card if we determine that the voucher was redeemed contrary to the terms of use.</li>\n</ol>';

		$link.popoverTrigger (
		{	title: 'Menulog Voucher Terms and Conditions',
			messageHtml: termsHtml,
			popoverConf:
			{	template: 'helper',
				baseAttachDirectionX: 'left',
				popoverAttachDirectionX: 'right',
				baseAttachDirectionY: 'top',
				popoverAttachDirectionY: 'top',
				attachOffsetX: 18,
				attachOffsetY: -17,
				addCloseX: true,
				applyDraggable: true,
				maxWidth: 500,
				//we track click voucher here, right before the popover show up
				onBeforeShow : function(){
			        analytics_trackEvent({
                        'category'  : 'ta_search',
                        'action'    : 'click_vouchers_accepted'
			        });					
				}
			}
		});
	};

	// show/hide the extended list of food items (food search)
	takeawaySearch_bindMoreFoodItemLinks = function ($showElement, $hideElement, $foodItemElement) {

		$showElement.bind ('click', function () {
			$showElement.hide ();
			$hideElement.show ();
			$foodItemElement.show ('blind', 400);
			return false;	// stop default action + bubbling
		});

		$hideElement.bind ('click', function () {
			$showElement.show ();
			$hideElement.hide ();
			$foodItemElement.hide ('blind', 400);
			return false;	// stop default action + bubbling
		});

		return true;
	};

	$.fn.center = function () {
	    this.css("position","absolute");
	    this.css("top", (($(window).height() - this.outerHeight()) / 2) + $(window).scrollTop() + "px");
	    this.css("left", (($(window).width() - this.outerWidth()) / 2) + $(window).scrollLeft() + "px");
	    return this;
	}
	
	// http://code.google.com/apis/maps/documentation/javascript/
	$.fn.search_initMap = function (conf) {

		var googleMap = function (element, conf) {

			var api = this;
			var $element = $(element);
			var map = null;
			var mapRendered = false;

			var defaultConf = {
				fetchBubbleContentUrl: null,
				fetchBubbleVarName: null
//				markers: []
			};
			conf = $.extend (true, {}, defaultConf, conf);

			var iconTypes = {
				normal: '',	// normal is handled in a custom way below
				dot: {
					icon: new google.maps.MarkerImage ('http://www.basepizza.com.au/images/bullets/map_marker_dot.png',
						new google.maps.Size (11, 11),	// This marker is 20 pixels wide by 32 pixels tall.
						new google.maps.Point (0, 0),	// The origin for this image is 0, 0.
						new google.maps.Point (5, 5))	// The anchor for this image is the base of the flagpole at 0, 32.
				},
				house: {
					icon: new google.maps.MarkerImage ('http://www.basepizza.com.au/images/bullets/map_marker_house.png',
						new google.maps.Size (26, 24),	// This marker is 20 pixels wide by 32 pixels tall.
						new google.maps.Point (0, 0),	// The origin for this image is 0, 0.
						new google.maps.Point (13, 18)),	// The anchor for this image is the base of the flagpole at 0, 32.
					shadow: new google.maps.MarkerImage ('http://www.basepizza.com.au/images/bullets/map_marker_house_shadow.png',
						new google.maps.Size (44, 24),	// This marker is 20 pixels wide by 32 pixels tall.
						new google.maps.Point (0, 0),	// The origin for this image is 0, 0.
						new google.maps.Point (13, 18))	// The anchor for this image is the base of the flagpole at 0, 32.
				}
			};

			var defaultMarker = {
				id: null,
				lat: null,
				lng: null,
				iconType: 'normal',
				boundsInclude: true,
				labelColour: 'ADCB42',
				label: null,
				title: null,
				infoWindowHtml: null,
				zIndex: 1,
				latLng: null,		// the google latLng object, for internal use
				marker: null		// the google marker object, for internal use
			}
			var markers = [];
			var infoWindow = null;	// the google bubble object
			var infoWindowAjaxCache = {};	// cache the bubble content for bubbles that need loading via ajax






			// API methods
			// init type things
			$.extend (api, {
				init: function () {
					infoWindow = new google.maps.InfoWindow ();
					return api;
				},

				// define a marker for the map
				addMarker: function (markerData) {
					markerData = $.extend (true, {}, defaultMarker, markerData);
					markers.push (markerData);
					return api;
				},

				// specify links on the page that will show a marker's infoWindow when clicked
				addMarkerLink: function (markerId, selector) {
					// show the info window when clicked
					$(selector).bind ('click', function (e) {
						e.preventDefault ();
						api.showMarkerInfoWindow (markerId);
					});
/**
					// stop links within the element from showing the infoWindow,  instead they should carry out their default action
					$(selector).find ('a').bind ('click', function (e) {
						e.stopPropagation ();
					});
/**/
					return api;
				},

				// create the map object and populate it with data
				render: function () {
					if (!mapRendered) {

						// define the map options
						var myOptions = {
							zoom: 4,
							mapTypeId: google.maps.MapTypeId.ROADMAP,
							mapTypeControlOptions: {
//								mapTypeIds: [google.maps.MapTypeId.ROADMAP]
								mapTypeIds: []
							}
						};

						// create the map
						map = new google.maps.Map (document.getElementById ($element.attr ('id')), myOptions);
						var bounds = new google.maps.LatLngBounds ();

						// add the markers to the map
						$.each (markers, function (index, markerData) {

							// create the position and expand/position the view to include it
							markerData.latLng = new google.maps.LatLng (markerData.lat, markerData.lng);
							if (markerData.boundsInclude)
								bounds.extend (markerData.latLng);

							// determine which marker to use
							// custom marker
							if ((markerData.iconType != 'normal') && (iconTypes[markerData.iconType] !== undefined)) {
								icon = iconTypes[markerData.iconType].icon;
								shadow = iconTypes[markerData.iconType].shadow;
							}
							// 'normal' icon
							else {
								icon = new google.maps.MarkerImage ('http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=' + markerData.label + '|' + markerData.labelColour + '|000000',
									new google.maps.Size (21, 34),	// This marker is 20 pixels wide by 32 pixels tall.
									new google.maps.Point (0, 0),	// The origin for this image is 0, 0.
									new google.maps.Point (10, 34)),	// The anchor for this image is the base of the flagpole at 0, 32.
								shadow = new google.maps.MarkerImage ('http://chart.apis.google.com/chart?chst=d_map_pin_shadow',
									new google.maps.Size (40, 37),	// This marker is 20 pixels wide by 32 pixels tall.
									new google.maps.Point (0, 0),	// The origin for this image is 0, 0.
									new google.maps.Point (9, 35))	// The anchor for this image is the base of the flagpole at 0, 32.
							}

							// create a new marker object
							markerData.marker = new google.maps.Marker ({
								position: markerData.latLng,
								map: map,
								icon: icon,
								shadow: shadow,
								title: markerData.title,
								zIndex: markerData.zIndex
							});

							// show the marker's bubble when clicked
							google.maps.event.addListener (markerData.marker, 'click', function () {
								openInfoWindow (markerData);
							});

							// make sure the map doesn't start zoomed in too far
							var startZoomCheck = google.maps.event.addListener (map, 'bounds_changed', function () { 
								if (map.getZoom () > 17)
									map.setZoom (17);
								google.maps.event.removeListener (startZoomCheck);	// remove the event listener so this happens only once
							});

						});

						// expand/position the map to fit these markers
						map.fitBounds (bounds);

						mapRendered = true;
					}
					return api;
				},

				// center the map and show the marker's info window
				showMarkerInfoWindow: function (id) {
					// find the marker
					$.each (markers, function (index, markerData) {
						if (id == markerData.id) {
//							map.setCenter (markerData.latLng);
							openInfoWindow (markerData);
							return false;	// break out of the loop
						}
					});
					return api;
				}

			});

			var openInfoWindow = function (markerData) {

				// if there's some content then use it
				var html = null;
				if (markerData.infoWindowHtml)
					html = formatInfoWindowHtml (markerData.infoWindowHtml);
				// check to see if the content has already been cached
				else if (infoWindowAjaxCache['restaurant' + markerData.id] !== undefined)
					html = infoWindowAjaxCache['restaurant' + markerData.id];

				// position the marker,  set new content and open it
				infoWindow.setPosition (markerData.latLng);
				infoWindow.setContent (html !== null ? html : ' ');	// add a space character if empty
				infoWindow.open (map, markerData.marker);

				// if there's no content then fetch it via ajax
				if ((html === null) && (conf.fetchBubbleContentUrl) && (conf.fetchBubbleVarName)) {

					var parameters = [];
					parameters.push ({ name: conf.fetchBubbleVarName, 'value': markerData.id });	// the id of the thing to fetch

					$.ajax ({
						url: conf.fetchBubbleContentUrl,
						type: 'POST',
						dataType: 'json',
						data: parameters,
						success: function (response) {
							// update the content of the bubble and re-open it (to re-position it)
							$.each (response, function (index, value) {
								if (value[0] == 'html') {
									infoWindowAjaxCache['restaurant' + markerData.id] = formatInfoWindowHtml (value[1]);	// cache the result incase it's needed again
									infoWindow.setContent (infoWindowAjaxCache['restaurant' + markerData.id]);
									infoWindow.open (map, markerData.marker);	// re-open it (to re-position it)
									return false;
								}
							});
						}
					});
				}

				return true;
			};

			var formatInfoWindowHtml = function (infoWindowHtml) {

				// if we specify the width + height of the infoWindow html inline,  google handles the width of the bubble better
				// temporarily put the infoWindowHtml into the page so we can determine it's dimensions
				var $tempPlonkSpot = $('#tempPlonkSpot').html (infoWindowHtml).show ();
				$tempPlonkSpot.find ('.restaurantInfo .core-anchorButton').coreTransformAnchorButton ();	// make sure the button is transformed before the height is measured
				var width = $tempPlonkSpot.find ('.restaurantInfo:first').width ();
				var height = $tempPlonkSpot.find ('.restaurantInfo:first').height ();
				$tempPlonkSpot.find ('.restaurantInfo:first').width (width + 12).height (height);	// add 12 pixels width so that the google's closeX doesn't appear over the content

				var html = $tempPlonkSpot.html ();
				$tempPlonkSpot.html ('').hide ();

				return html;
			};

			api.init ();
		}


		// tur the given element/s into a map
		$(this).each (function () {

			var $this = $(this);

			if (!$this.data ('googleMap')) {
				var api = new googleMap ($this, conf);
				$this.data ('googleMap', api);
			}
		});

		return $(this);
	};
/**
	// initialize the map popover links
	initSearchPageMapPopoverLinks = function (ids) {
		$.each (ids, function (index, value) {
			var parts = value.split (',');
			var restaurantId = parseInt (parts[0]);
			var domId = parts[1];

			$('#' + domId).shortenText (
			{	maxWidth: 180,
				mode: 'truncate',
				moreInfoHtml: ' .. <a href="" class="fakeLink">Map</a>',
				// open the map popover when clicked instead of showing the "more" text
				customTruncateClickHandler: function () { activateMapPopover (domId, restaurantId); },
				// if the text is not truncated then add a map link to the text
				noTruncateHandler: function () {
					$(this)
					.append (' <a href="" class="fakeLink">Map</a>')
					.find ('a:last').bind ('click', function () {
						activateMapPopover (domId, restaurantId);
						return false;
					});
				}
			});
		});
		return true;
	}
/**/
	// show the map popover
	// if restaurantId is not given,  the link element is looked at for the restaurantId
	activateMapPopover = function (domId, restaurantId) {
		var $element = $(domId);
		if (restaurantId === undefined)
			restaurantId = $element.attr ('id').replace (/[^0-9]/g, '');
		if (($element) && (restaurantId)) {
			$.createPopover (
			{	title: 'View map',
				content: '<div class="mapPopoverHeight"></div>'
			},
			{	attachTo: 'mouse',
				baseAttachDirectionX: 'left',
				popoverAttachDirectionX: 'right',
				baseAttachDirectionY: 'top',
				popoverAttachDirectionY: 'top',
				attachOffsetX: 18,
				attachOffsetY: -17,
				width: 550,
				height: 400,
				addCloseX: true,
				ajax: 'http://www.basepizza.com.au/venue/ajax_view_restaurant_map.php?restaurantId='+ restaurantId,
				cancelButtonText: "'.escape_string_for_js ($lm->gv ('js', 'buttonClose', 'Close').'"
			});
            analytics_trackEvent({
                                    'category'  : 'ta_search',
                                    'action'    : 'click_individual_restaurant_map'
            });
			return true;
		}
		return false;
	}

}) (jQuery);










/*////////////////////////////////////////////////
// path: /javascript/front/takeaway_schedule.js //
// created: Mon, 26 Sep 2011 14:02:01 +1000     //
// modified: Mon, 12 Sep 2011 15:10:17 +1000    //
// size: 1802 bytes                             //
////////////////////////////////////////////////*/

(function($) {

	initVenueTakeawayScheduleFields = function ($orderDate, $orderTime, restaurantId, cartType) {
		$orderDate = $($orderDate);
		$orderTime = $($orderTime);
		$orderDate.bind ('change.takeawaySchedule', function () {
			var parameters =
			{	restaurantId: restaurantId,
				cartType: cartType,
				orderDate: $orderDate.val ()
			};
			$.ajax ({
				url: 'http://www.basepizza.com.au/takeaway/ajax_fetch_time_options.php',
				type: 'POST',
				dataType: 'json',
				data: parameters,
				success: function (response) {
					if (response[0][0] == 'updateTimes') {
						var options = '';
						$.each (response[0][1], function (index, value) {
							options += '<option value="' + value[0] + '">' + value[1] + '</option>';
						});
						var originalTime = $orderTime.val ();
						$orderTime.html (options);
						$orderTime.val (originalTime);
					}
				}
			});
		});

		return true;
	}
}) (jQuery);









/*/////////////////////////////////////////////////////
// path: /javascript/front/takeaway_shopping_cart.js //
// created: Wed, 04 Jan 2012 21:56:53 +1100          //
// modified: Mon, 19 Dec 2011 09:20:44 +1100         //
// size: 81661 bytes                                 //
/////////////////////////////////////////////////////*/

(function($) {

	$.menulog = $.menulog || { };

	$.menulog.takeawayShoppingCart = {

		// update the default conf values below in $.core.transformInput.conf
		updateDefaultConf: function (conf) {
			this.conf = $.extend (true, {}, this.conf, conf);
		},

		// the default conf values used when this plugin is applied to a file input
		conf: {
			restaurantId: null,
			cartId: null,
			menuId: null,
			suburbId: null,
			cartType: null,
			quickLink: null,

			currencySymbol: '$',
			currencySymbolIsPrefix: true,
			currencyDecPl: 2,
			currencyDecimalDelimiter: '.',

			showPricesWithTax: true,

			freeDeliveryAvail: false,
			minOrderAmtNoTax: null,
			minOrderAmtWithTax: null,

			subTotalNoTax: 0,
			subTotalWithTax: 0,
			deliveryFeeNoTax: 0,
			deliveryFeeWithTax: 0,
			finalDeliveryFeeNoTax: 0,
			finalDeliveryFeeWithTax: 0,
			totalNoTax: 0,
			totalWithTax: 0,
			freeDeliveryAfterNoTax: null,
			freeDeliveryAfterWithTax: null,

			allowEdit: true,			// turned off when on the checkout page so the user can't edit anything
			onMenuPage: true,			// only do certain things on the menu page

			analyticsAddUrl: null,
			analyticsAddedUrl: null
		},

		emptyCartItemTemplate: {
			cartItemId: null,
			foodItemId: null,
			name: null,
			quantity: 1,
			unitPriceNoTax: 0,
			unitPriceWithTax: 0,
			oldUnitPriceNoTax: 0,
			oldUnitPriceWithTax: 0,
			variety: [],
			bundledCartItems: [],
			$element: null		// for internal use
		},

		ftcDiscountTemplate: {
			available: false,
			percentage: 0,
			selected: false,
			value: 0,
			optionType: null,		// for internal use (null, radio, checkbox)
			$element: null			// for internal use
		},

		takeawayDiscountTemplate: {
			id: null,
			available: false,
			type: 'percent',	// percent / fixed
			title: '',
			descriptionHtml: '',
			minOrderAmount: null,
			maxOrderAmount: null,
			displayDates: false,
			percentage: null,
			fixedAmountNoTax: null,
			fixedAmountWithTax: null,
			askForComment: 0,
			comment: null,
			exclusive: false,
			selected: false,
			optionType: null,	// for internal use (null, radio, checkbox)
			$element: null		// for internal use
		},

		loyaltyDiscountTemplate: {
			available: false,
			ordersRequired: 0,
			progress: 0,
			progressDesc: null,
			couldUseThisTime: false,
			maxValueWithTax: 0,
			allowFTC: false,
			allowTakeawayDiscounts: false,
			allowGroupDealDiscounts: false,			
			selected: false,
			valueCoversCartCost: false,	// for internal use
			optionType: null,			// for internal use (null, radio, checkbox)
			$element: null				// for internal use
		}
	};

	function takeawayShoppingCart ($cartSummary, conf) {

		var api = this;
		$cartSummary = $($cartSummary);
		$courseNavBox = $('#courseNav');
		$courseList = $('#courseList');

		var initialising = true;
		var cartItems = {};
		var totalCartItems = 0;
		var discountDetailsTimeout = null;
		var lastSentDiscountSelection = [];
		var lastSentDiscountCommentHash = null;

		var ftcDiscount = $.extend (true, {}, $.menulog.takeawayShoppingCart.ftcDiscountTemplate);
		var takeawayDiscounts = [];
		var loyaltyDiscount = $.extend (true, {}, $.menulog.takeawayShoppingCart.loyaltyDiscountTemplate);

		var messagePopoverApi = undefined;	// api to the popover that shows this cart's helper messages
		var ifhPopoverApi = undefined;		// api to the popover that shows ifh content
		var errorPopoverApi = undefined;	// api to the popover that shows error content

		// the elements inside the $cartSummary
		var $cartTitle = null;
		var $cartContent = null;
		var $cartEmptyMessage = null;
		var $cartItems = null;
		var $cartItemRowTemplate = null;
		var $namePriceTemplate = null;
		var $nameNoPriceTemplate = null;
		var $freeDeliveryRow = null;
		var $discounts = null;
		var $discountRowTemplate = null;

		var $divider = null;

		var $cartTotals = null;
		var $subTotalRow = null;
		var $deliveryFeeRow = null;
		var $totalRow = null;
		var $checkoutButton = null;

		//
		var messagePopoverDefaultConf =
		{	template: 'helperNoTitle',
			baseDirX: 'right',
			popoverDirX: 'left',
			baseDirY: 'center',
			popoverDirY: 'center',
			offsetX: 10,
			offsetY: 0,
			closeAfter: 3500,
			group: 'cart'
		};

		var $window = $(window);
		var windowHeight = $window.height ();

		var showCartAnimations = ((!$.browser.msie) || ($.browser.version >= 9));	// don't show cart summary animations (on the RHS) for IE7, IE8
		var highlightMenuFoodItems = ((!$.browser.msie) || ($.browser.version >= 8));	// don't highlight menu food items (on the RHS) for IE7

		// record which food item LIs relate to which food items
		// (only needed for highlighting food items in the menu)
		var $foodItemLIs = null;
		var foodItemElementMap = {};

		var findMenuFoodItems = function () {
			if (highlightMenuFoodItems) {
				$foodItemLIs = $('#courseList .foodItem');
				foodItemElementMap = {};
				$.each ($foodItemLIs, function (index, $foodItemLI) {
					$foodItemLI = $($foodItemLI);
					var foodItemId = $foodItemLI.attr ('foodItemId');
					if (foodItemElementMap[foodItemId] === undefined)
						foodItemElementMap[foodItemId] = [$foodItemLI];
					else
						foodItemElementMap[foodItemId].push ($foodItemLI);
				});
			}
		}
		findMenuFoodItems ();

		toldGoogleAboutAddClick = false;
		toldGoogleAboutAddedClick = false;

		// API methods
		// init type things
		$.extend (api, {

			init: function () {

				if (conf.onMenuPage) {

					// fix the course nav to the top of the screen when scrolling down
// disabled temporarily
					$('#courseNav').coreFixedPos ();

					// make the course nav links work
					initCourseNav ();

					// make the food items work (so the user can add items to their cart)
					observeFoodItemForms ();

					// make the specials scroller work
					initSpecialsScroller ();
				}
			},

			setCurrency: function (currencyData) {
				conf.currencySymbol = currencyData.symbol;
				conf.currencySymbolIsPrefix = currencyData.symbolIsPrefix;
				conf.currencyDecPl = currencyData.decPl;
				conf.currencyDecimalDelimiter = currencyData.decimalDelimiter;
				return api;
			},

			// set the suburb and update the delivery costs
			setSuburb: function (suburbId, deliveryFeeNoTax, deliveryFeeWithTax, freeDeliveryAfterNoTax, freeDeliveryAfterWithTax) {
				conf.suburbId = suburbId;
				conf.deliveryFeeNoTax = deliveryFeeNoTax;
				conf.deliveryFeeWithTax = deliveryFeeWithTax;
				conf.freeDeliveryAfterNoTax = freeDeliveryAfterNoTax;
				conf.freeDeliveryAfterWithTax = freeDeliveryAfterWithTax;

				if (!initialising) {
					renderTotals ();
					if (conf.suburbId)
						$('#suburbId').val (conf.suburbId);
				}
				return api;
			},

			// once the cart has finished being initially populated this is called
			finishedInitialising: function () {
				initialising = false;
//				highlightMenuFoodItems ();
				renderCartSummary ();

				// record which discounts are selected
				lastSentDiscountSelection = getDiscountSelection ();
				lastSentDiscountCommentHash = getDiscountCommentHash ();
/**/
				// observe when the window changes height (the cart summary may need resizing)
				$window.bind ('resize', function (e) {
					windowHeight = $window.height ();	// record the new page height (so it's not re-calculated every time something's added to the cart)
					checkCartHeight ();	// check to see if the height of the cart summary needs adjusting
				});
/**/
				return api;
			}
		});

		// API methods
		// page related things
		$.extend (api, {

			// make the food item and course photo links (the camera picture) open a popover
			initPhotoLinks: function (photoLinkIds) {
				$.each (photoLinkIds, function (index, value) {

					var parts = value.split (',');
					var id = parts[0];
					var width = parseInt (parts[1]);
					var height = parseInt (parts[2]);

					var $link = $('#' + id);

					$('#' + id).popoverTrigger (
					{	title: $link.parent ().find ('h3,h4').first ().text (),
						messageHtml: '<img src="' + $link.attr ('href') + '" style="width: ' + width + 'px; height: ' + height + 'px;" />',
						popoverConf:
						{	template: 'helper',
							baseAttachDirectionX: 'center',
							popoverAttachDirectionX: 'center',
							baseAttachDirectionY: 'top',
							popoverAttachDirectionY: 'top',
							attachOffsetX: 0,
							attachOffsetY: -33,
							addCloseX: true,
							applyDraggable: true,
							width: width + 35
						}
					});
				});
			},

			observeCartTypeChange: function () {

				$('#cartTypeOptions').bind ('submit', function () {

					var $form = $(this);
					var cartType = $form.find ('input:radio:checked').val ();
					if (!cartType)
						cartType = $form.find ('input:[name=cartType]').val ();

					var parameters = [];
					parameters.push ({ name: 'action', 'value': 'updateCartType' });	// the action to take
					parameters.push ({ name: 'restaurantId', 'value': conf.restaurantId });
					parameters.push ({ name: 'cartId', 'value': conf.cartId });
					parameters.push ({ name: 'menuId', 'value': conf.menuId });
					parameters.push ({ name: 'cartType', 'value': cartType });
					parameters.push ({ name: 'suburbId', 'value': $('#suburbId').val () });

					$.ajax ({
						url: $(this).attr ('action'),
						type: 'POST',
						dataType: 'json',
						data: parameters,
						success: api.processJsonResponse
					});
					return false;
				});
				$('#cartTypeOptions input:radio').bind ('change', function () {
					$('#cartTypeOptions').submit ();
				});
				$('#cartTypeOptions select').bind ('change', function () {
					$('#delivery').attr ('checked', true);	// because a new suburbId was chosen,  change the cart type to delivery
					$('#cartTypeOptions').submit ();
				});
				return true;
			}
		});

		// API methods
		// cart item related things
		$.extend (api, {

			// add an item to the cart (a cart item)
			// or update it (based on the cartItemId)
			internal_addItemToCart: function (cartItem, newIfhHtml, newIfhJs, submitterId) {

				// render the "added" popover
				if (!initialising) {

					if (!submitterId)
						submitterId = 'mouse';

					// close the message popover if it's already being shown
					if (messagePopoverApi !== undefined)
						messagePopoverApi.close ();

					// show the user a message "added"
					var popoverConf = $.extend (true, {}, messagePopoverDefaultConf, {
						template: 'helperNoTitle',
						baseElement: $('#' + submitterId),
//						applyArrows: true,
//						pointTo: $('#' + submitterId),
						closeAfter: 1500
					});

					// if the ifh popver is being shown: change it's content if necessary,  or close it
					var addingNewContent = ((ifhPopoverApi !== null) && (newIfhHtml !== null));

					// position the message differently if the user is going to be shown another ifh (so they can add more)
					if (addingNewContent) {
						popoverConf.baseElement = ifhPopoverApi.getPopover ();
						popoverConf.baseDirY = 'bottom';
						popoverConf.popoverDirY = 'bottom';
					}

					// show the "added" message
					messagePopoverApi = $.createPopoverMini (
						{	content: 'Added',
							customClass: 'core-popoverLargeFont'
						},
						popoverConf
					).data ('popover');
				}

				// update the cart item (maintain it's $element)
				if (cartItems['cartItem' + cartItem.cartItemId] !== undefined) {
					var $temp = cartItems['cartItem' + cartItem.cartItemId].$element;
					cartItem = $.extend (true, {}, $.menulog.takeawayShoppingCart.emptyCartItemTemplate, cartItem)
					cartItem.$element = $temp;
					cartItems['cartItem' + cartItem.cartItemId] = cartItem;
				}
				// create a new if not updating
				else {
					cartItem = $.extend (true, {}, $.menulog.takeawayShoppingCart.emptyCartItemTemplate, cartItem)
					cartItems['cartItem' + cartItem.cartItemId] = cartItem;
					totalCartItems++;
				}

				// store the cart item's values
				cartItems['cartItem' + cartItem.cartItemId] = cartItem;

				highlightMenuFoodItem (cartItem.foodItemId);
				if (!initialising) {
					renderCartItem (cartItem);
//					highlightMenuFoodItems ();
					showCartEmptyMessageIfNecessary ();

					checkCartHeight ();	// check to see if the height of the cart summary needs adjusting
					scrollCartSummaryToFoodItem (cartItem.$element, function () {	// scroll the cart to the food item if necessary
//						setTimeout (function () { cartItem.$element.effect ('highlight', {}, 1500); }, 500);	// flash it in a moment
						if (showCartAnimations)
							cartItem.$element.effect ('highlight', {}, 1500);	// flash it in a moment
					});
					if (showCartAnimations)
						setTimeout (checkCartHeight, 500);	// and again after things have finished animating

					// if the ifh popver is being shown: change it's content if necessary,  or close it
					if (ifhPopoverApi !== undefined) {
						if (newIfhHtml !== null) {
							ifhPopoverApi.replaceContentBoxHtml (newIfhHtml);
							bindVarietyRadios (newIfhJs, ifhPopoverApi.getPopover (), true);
						}
						else
							ifhPopoverApi.close ();
					}

					$.core.mouse.stopPleaseWait ('cart', true);	// force-stop the please-wait spinny thing


					// tell google analytics that the user "added" an item to their cart - the first time only
					if ((conf.analyticsAddedUrl) && (!toldGoogleAboutAddedClick)) {
						analytics_trackPageview (conf.analyticsAddedUrl);
						toldGoogleAboutAddedClick = true;
					}
				}
				return api;
			},

			// send a request to the server to remove the given cart item
			ajax_removeItemFromCart: function (cartItemId) {

				var parameters = [];
				parameters.push ({ name: 'action', 'value': 'remove' });	// the action to take
				parameters.push ({ name: 'restaurantId', 'value': conf.restaurantId });
				parameters.push ({ name: 'cartId', 'value': conf.cartId });
				parameters.push ({ name: 'menuId', 'value': conf.menuId });
				parameters.push ({ name: 'cartItemId', 'value': cartItemId });

				$.ajax (
				{	url: 'http://www.basepizza.com.au/takeaway/ajax_update_cart.php',
					type: 'POST',
					dataType: 'json',
					data: parameters,
					success: api.processJsonResponse
				});

				return api;
			},

			// update the total values,  and re-render them if not initialising
			internal_updateTotals: function (totalsData) {
				conf.subTotalNoTax = totalsData.subTotalNoTax;
				conf.subTotalWithTax = totalsData.subTotalWithTax;
				conf.deliveryFeeNoTax = totalsData.deliveryFeeNoTax;
				conf.deliveryFeeWithTax = totalsData.deliveryFeeWithTax;
				conf.totalNoTax = totalsData.totalNoTax;
				conf.totalWithTax = totalsData.totalWithTax;
				ftcDiscount.value = totalsData.ftcValue;

				if (!initialising) {
					renderDiscounts ();
					renderTotals ();
				}
				return api;
			}
		});

		// API methods
		// discount related things
		$.extend (api, {

			// set the ftc discount value
			setFtcDiscount: function (newFtcDiscount) {
				// updating
				if (ftcDiscount.$element !== null)
					ftcDiscount = $.extend (true, {}, ftcDiscount, newFtcDiscount);
				// new
				else
					ftcDiscount = $.extend (true, {}, $.menulog.takeawayShoppingCart.ftcDiscountTemplate, { available: true }, newFtcDiscount);
				return true;
			},
			removeFtcDiscount: function () {
				ftcDiscount.available = false;
				ftcDiscount.selected = false;
				return true;
			},

			// update the ftc discount description text that the user sees
			ftcDiscountAmt: function (value) {
				ftcDiscount.value = value;
				if (ftcDiscount.$element !== null)
					ftcDiscount.$element.find ('div.value').text (getReadablePrice (-value, true))
				return api;
			},

			// add a takeaway discount
			addTakeawayDiscount: function (newTakeawayDiscount) {
				// check to see if the discount has already been set
				var updated = false;
				$.each (takeawayDiscounts, function (index, takeawayDiscount) {
					if (newTakeawayDiscount.id == takeawayDiscount.id) {
						takeawayDiscounts[index] = $.extend (true, {}, takeawayDiscounts[index], newTakeawayDiscount);
						updated = true;
						return false;	// break
					}
				});
				if (!updated)
					takeawayDiscounts.push ($.extend (true, {}, $.menulog.takeawayShoppingCart.takeawayDiscountTemplate, newTakeawayDiscount));
				return true;
			},
			removeTakeawayDiscount: function (discountId) {
				$.each (takeawayDiscounts, function (index, takeawayDiscount) {
					if (discountId == takeawayDiscount.id) {
						takeawayDiscount.available = false;
						takeawayDiscount.selected = false;
						return false;	// break
					}
				});
				return true;
			},

			// set the loyalty discount
			setLoyaltyDiscount: function (newLoyaltyDiscount) {
				// updating
				if (loyaltyDiscount.$element !== null)
					loyaltyDiscount = ($.extend (true, {}, loyaltyDiscount, newLoyaltyDiscount));
				// new
				else
					loyaltyDiscount = ($.extend (true, {}, $.menulog.takeawayShoppingCart.loyaltyDiscountTemplate, { available: true }, newLoyaltyDiscount));
				return true;
			},
			removeLoyaltyDiscount: function () {
				loyaltyDiscount.available = false;
				loyaltyDiscount.selected = false;
				return true;
			},

			// update the loyalty discount description text that the user sees
			loyaltyProgressDesc: function (progressDesc) {
				loyaltyDiscount.progressDesc = progressDesc;
				if (loyaltyDiscount.$element !== null)
					loyaltyDiscount.$element.find ('span.loyaltyProgressMsg').text (progressDesc);
				return api;
			},



			// show or hide the discount rows depending on which one is picked (for the checkout page)
			showHideDiscounts: function () {

				// work out which discounts to show
				var showFTCDiscount = ((ftcDiscount.available) && (ftcDiscount.selected) && (ftcDiscount.$element !== null));
				var showTakeawayDiscounts = false;
				$.each (takeawayDiscounts, function (index, takeawayDiscount) {
					if ((isTakeawayDiscountUsable (takeawayDiscount, conf.showPricesWithTax)) && (takeawayDiscount.selected)) {
						showTakeawayDiscounts = true;
						return false;	// break
					}
				});
				var showLoyaltyDiscount = ((loyaltyDiscount.selected) && (loyaltyDiscount.selected) && (loyaltyDiscount.$element !== null));


				var effect = undefined;
				if (showCartAnimations)
					effect = (initialising ? undefined : 'blind');

				// hide/show the discounts if necessary
				if (ftcDiscount.$element !== null) {
					if (showFTCDiscount)
						ftcDiscount.$element.filter (':hidden').show (effect);
					else
						ftcDiscount.$element.filter (':visible').hide (effect);
				}

				$.each (takeawayDiscounts, function (index, takeawayDiscount) {
					if (showTakeawayDiscounts)
						takeawayDiscount.$element.filter (':hidden').show (effect);
					else
						takeawayDiscount.$element.filter (':visible').hide (effect);
				});

				if (loyaltyDiscount.$element !== null) {
					if (showLoyaltyDiscount)
						loyaltyDiscount.$element.filter (':hidden').show (effect);
					else
						loyaltyDiscount.$element.filter (':visible').hide (effect);
				}
			}
		});

		// API methods
		// popover related
		$.extend (api, {

			// let the user choose their options
			openIfhPopover: function (popoverPurpose, title, ifhHtml, ifhJs, submitterId) {

				// close the message popover if it's being shown
				if (messagePopoverApi !== undefined)
					messagePopoverApi.close ();

				// close the ifh popover if it's already being shown
				var closing = false;
				if (ifhPopoverApi !== undefined) {
					closing = true;
					ifhPopoverApi.close ();
				}

				var closeOnClick = null;
				if (popoverPurpose == 'chooseSuburbDateTime')
					closeOnClick = false;

				setTimeout (function () {
					ifhPopoverApi = $.createPopoverMini (
					{	title: title,
						content: ifhHtml
					},
					{	template: (title != '' ? 'general' : 'generalNoTitle'),
						baseElement: $('#' + submitterId),
						baseDirX: 'center',
						popoverDirX: 0.70,
						baseDirY: 'center',
						popoverDirY: 0.35,
						offsetX: 0,
						offsetY: 0,
						maxWidth: 600,
						applyMask: true,
						closeOnClick: closeOnClick,
						group: 'cart',
						dragOptions: {
							handle: '.core-titleBox, .popoverTitle:first'
						},
//						onBeforePosition: function () { $popover = $(this); $popover.find ('.jsAlignColumns').columnAlign (); bindVarietyRadios (ifhJs, $popover, false); }
						onBeforePosition: function () { $popover = $(this); bindVarietyRadios (ifhJs, $popover, false);},
						onShow: function () {
							$.core.mouse.stopPleaseWait ('cart', true);	// force-stop the please wait spinny thing
						}

					}).data ('popoverMini');
				}, (closing ? 300 : 0));	// if the popover is closing from before,  wait a moment so that when this one is shown,  the mask is applied to the screen

				return true;
			},

			// close the ifh popover if it's already being shown
			closeIfhPopover: function () {
				if (ifhPopoverApi !== undefined)
					ifhPopoverApi.close ();
				return true;
			},

			// process the response from the server
			processJsonResponse: function (json) {
				var stoppedPleaseWait = false;

				// if the response came back as an json object then process it
				if (typeof (json) == 'object') {

					// loop through each instruction
					$(json).each (function (index, value) {

						if ($.inArray (value[0], ['add', 'openIfhPopover']) >= 0)
							stoppedPleaseWait = true;

						switch (value[0]) {
							case 'add': // add an item to the cart
								api.internal_updateTotals (value[2]);	// new total values
								api.internal_addItemToCart (value[1], value[3], value[4], value[5]);	// cart item, new ifh html, new ifh js, submitter
								break;
							case 'remove':	// remove an item from the shopping cart
								api.internal_updateTotals (value[2]);	// new total values
								internal_removeItemFromCart (value[1]);
								break;
							case 'reloadPage':	// reload the page (eg. this is done after the cart type changes: delivery <-> pickUp)
								window.location.reload ();
								break;
							// display an nice error message to the user
							case 'error':

								// format the message nicely,  it may have been plain text or html
								var $message = $('<div/>').html (value[1]);
								if (!$message.find ('p').length)
									$message = $('<p/>').html (value[1]).wrap ($('<div></div>')).parent ();
								$message.find ('p:first').addClass ('core-spaceForCloseX core-first');
								$message.find ('p:last').addClass ('core-last');

								// close the ifh popover if it's already being shown
								if (ifhPopoverApi !== undefined)
									ifhPopoverApi.close ();

								// close the error popover if it's already being shown
								if (errorPopoverApi !== undefined)
									errorPopoverApi.close ();

								// show the message
								errorPopoverApi = $.createPopover (
								{	content: $message.html (),
									customClass: 'core-popoverLargeFont' },
								{	template: 'generalNoTitle',
									baseAttachDirectionX: 0.5,
									popoverAttachDirectionX: 0.5,
									baseAttachDirectionY: 0.5,
									popoverAttachDirectionY: 0.5,
									applyMask: true,
									addCloseX: true,
									easyClose: true,
									fixed: true,
									group: 'error'
								}).data ('popover');
								break;
							// run an arbitrary api.method (provided it exists)
							default:
								if ($.isFunction (api[value[0]])) {
									var methodName = value[0];
									value.shift ();
									api[methodName].apply (api[methodName], value);	// call the function specified in value[0] with the given parameters
								}
								break;
						}
					});
				}


				// if the ajax response didn't execute a method that stops the please-wait spinny thing (for some reason),  hide it now
				if (!stoppedPleaseWait)
					$.core.mouse.stopPleaseWait ('cart', true);	// force-stop the please-wait spinny thing
				return true;
			},




			// return the cart element
			getCartSummaryElement: function () {
				return $cartSummary;
			},

			// return the conf object
			getConf: function () {
				return conf;
			}
		});

		// make the course nav bar work when clicked and stick the course nav bar + cart summary to the page when scrolling down
		var initCourseNav = function () {
			var $courseNavLIs = $courseNavBox.find ('li');
			var courseLiIds = [];
			var courseOffsets = [];
			var currentlyJumping = 0;
			var lastRelevantCourseIndex = null;
			var courseNavBoxHeight = $courseNavBox.outerHeight (true);

			var highlightCourses = ((!$.browser.msie));	// don't highlight or track the page position if the UA is IE
			var highlightCourse = function ($courseNavLink) {
				// highlight the current course name in the nav list
				$courseNavBox.find ('li.selected').removeClass ('selected');
				$courseNavLink.parent ('li').addClass ('selected');
				return true;
			}

			// make the course nav links work when clicked (ie. scroll to the course on the page)
			var firstCourse = true;
			$courseNavLIs.each (function () {
				var $courseNavLI = $(this);

				$courseNavLI.find ('a').map (function () {
					var $courseNavLink = $(this);

					// highlight the current course name in the nav list
					if ((highlightCourses) && (firstCourse)) {
						highlightCourse ($courseNavLink);
						firstCourse = false;
					}

					// work out the scroll-to destination
					var temp = $courseNavLink.attr ('id').split ('_');
					temp.shift ();
					var destinationId = '#' + temp.join ('_');
					courseLiIds.push (destinationId);

					// observe the click
					$courseNavLink.click (function () {

						var $destination = $(destinationId);
						if ($destination.length) {

							// keep track of the fact that we're currently jumping down to a course,  so that the courses don't get highlighted based on the page-scroll
							currentlyJumping++;

							// scroll to the right point
							$.scrollTo ($destination, 500, {
								easing: 'easeOutQuart',
								offset:
								{	left: 0,
									top: -(courseNavBoxHeight - 10)
								},
								onAfter: function () {
									setTimeout (function () { currentlyJumping--; }, 200);
								}
							});

							// highlight the current course name in the nav list
							if (highlightCourses)
								highlightCourse ($courseNavLink);
						}
						return false;
					});
				});
			});

			if (highlightCourses) {
				// observe the window scroll
				$(window).bind ('scroll.courseHighlight, resize.courseHighlight', function (e) {

					// if the page isn't currently jumping (because the user clicked on a course nav link)
					if (currentlyJumping <= 0) {

						// work out which course is at the top of the screen
						var windowScrollTop = $(window).scrollTop () +  + 50;

						// check to see if a different course should be selected,  do it quickly based on the recorded positions rather than getting the elements each time and 
						var relevantCourseIndex = -1;
						$.each (courseOffsets, function (index, value) {
							if ((value < windowScrollTop) || (relevantCourseIndex == -1))
								relevantCourseIndex = index;
						});

						// work out which course should be highlighted
						if (relevantCourseIndex != lastRelevantCourseIndex) {

							courseOffsets = []; // re-create the offset values
							var $relevantCourse = null;
							$.each (courseLiIds, function (index, value) {
								var $courseLI = $(value);
								var offsetTop = $courseLI.offset ().top;
								courseOffsets.push (offsetTop); // re-create the offset values
								if ((offsetTop < windowScrollTop) || ($relevantCourse === null))
									$relevantCourse = $courseLI;
							});

							// highlight the relevant course name in the nav list
							if ($relevantCourse !== null) {
								lastRelevantCourseIndex = relevantCourseIndex;
								highlightCourse ($('#link_' + $relevantCourse.attr ('id')));
							}
						}
					}
				});
			}
		};

		// observe the food item forms which get submitted when the user adds an item to their cart
		var observeFoodItemForms = function () {

			// observe the food item forms
			// add an item to the cart
			$('#courseList form')
			.unbind ('submit.takeawayShoppingCartFoodItemForm')
			.bind ('submit.takeawayShoppingCartFoodItemForm', function () {
				ajax_addItemToCart ($(this));
				return false;
			});

			return true;
		};

		// highlight a particular cart item because it's in the cart
		var highlightMenuFoodItem = function (foodItemId) {
			if ((highlightMenuFoodItems) && ($.isArray (foodItemElementMap[foodItemId])))
				$.each (foodItemElementMap[foodItemId], function () { $(this).addClass ('inCart'); });
			return true;
		};
		// unhighlight a particular cart item because it's not in the cart anymore
		var unHighlightMenuFoodItem = function (foodItemId) {
			if ((highlightMenuFoodItems) && ($.isArray (foodItemElementMap[foodItemId])))
				$.each (foodItemElementMap[foodItemId], function () { $(this).removeClass ('inCart'); });
			return true;
		};

		// make the specials box into a scroller if necessary (ie. if the content is too wide for the box
		var initSpecialsScroller = function () {

			var $scroller = $('#specialsScroller');
			var $specials = $scroller.find ('.items>div');

			// calculate the overall width (to see if the scroller is needed)
			var width = 0;
			$specials.map (function () { width += $(this).outerWidth (true); });
			$specials.autoMatchHeight ();

			// if the content is too wide then make the scroller scroll
			if (width > $scroller.width ()) {

				$scroller.find ('.scrollable')
				// add the left scroll button
				.before ('<a class="prev leftArrow"></a>')
				// add the right scroll button
				.after ('<a class="next rightArrow"></a>')
				// shrink the scroller area so the arrows fit
				.width ($scroller.find ('.scrollable').width () - 36);

				// start the scroller
				$scroller.scrollable ().navigator ();

				// make the L+R arrows get brighter when the mouse hovers over them
//				$scroller.find ('.leftArrow, .rightArrow').hoverHighlight ();
			}

			// make the heights of the L+R arrows,  the items and the scroller itself the same
			$scroller.find ('.scrollable, .leftArrow, .rightArrow').outerHeight ($specials.outerHeight ());

			return true;
		};
		
		/**
		 * work out how many takeaway discounts are available
		 */
		var countAvailabeTakeawayDiscount = function() {
			// work out how many discounts are available
			var usableTakeawayDiscounts = 0;
			$.each (takeawayDiscounts, function (index, takeawayDiscount) {
				if (isTakeawayDiscountUsable (takeawayDiscount, conf.showPricesWithTax)) {
					usableTakeawayDiscounts++;
				}
			});
			return usableTakeawayDiscounts;
		};

		/**
		 * if we have multiple availabe discounts,
		 * show 'Select your discount' on shopping cart
		 * 
		 */
		var renderSelectDiscountText = function() {
			if ($("#menulog_page_id").text() != 'venue') {
				return '';
			}
			var availableDiscounts = 0;
			if (loyaltyDiscount.available) {
				availableDiscounts++;
			}
		
			if (ftcDiscount.available) {
				availableDiscounts++;
			}
			availableDiscounts += countAvailabeTakeawayDiscount();
			if (availableDiscounts < 2) {
				return '';
			}
			return $('<div class="selectDiscount"><div class="selectDiscountText">Select Your Discount<div class="contentEnd"/></div>');
		};
		
		// render the cart,  start it a fresh
		var renderCartSummary = function () {
			
			// initialise the elements of the cart summary
			$cartTitle = $('<span class="cartTitle">Your Order</span>');

			$cartContent = $('<div class="cartContent"><div/></div>');	// used to limit the height of the cart (when the cart items get too tall)

			// the message shown when the cart is empty (hide if there are items in the cart)
			$cartEmptyMessage = $('<div class="cartEmpty">There are no items in your cart.</div>');
			if (totalCartItems)
				$cartEmptyMessage.hide ();

			// the cart items - the top section
			$cartItems = $('<div class="cartItems"/>');
			if (conf.allowEdit) {
				$cartItemRowTemplate = $(
					  '<div class="row">'
					+ '	<div class="details"/>'
					+ ' <div class="deleteX"><a href="" class="mapNotMapped_removeFoodItem" title="Remove">Remove</a></div>'
					+ '	<div class="contentEnd"/>'
					+ '</div>');
			}
			else {
				$cartItemRowTemplate = $(
					  '<div class="row">'
					+ '	<div class="details"/>'
					+ '	<div class="contentEnd"/>'
					+ '</div>');
			}
			$namePriceTemplate = $(
				  '<div class="namePrice">'
				+ ' <div class="itemQty"/>'
				+ '	<div class="name"/>'
				+ '	<div class="value"/>'
				+ '	<div class="contentEnd"/>'
				+ '</div>');
			$nameNoPriceTemplate = $('<div class="row nameNoPrice"/>');

			// set up free delivery
			$freeDeliveryRow = $('<div class="row freeDelivery"><div id="freeDeliveryText">Free Delivery<div class="contentEnd"/></div></div>');

			// set up the discounts
			$discounts = $('<div class="discounts"/>');
			$discountRowTemplate = $(
				  '<div class="row">'
				+ '	<div class="name discountName"/>'
				+ '	<div class="value discountValue"/>'
				+ '	<div class="contentEnd"/>'
				+ '</div>');

			// divider between the top and bottom
			$divider = $('<div class="divider"/>');

			// totals section - the lower section
			$cartTotals = $('<div class="cartTotals"/>');

			$subTotalRow = $(
				  '<div class="subTotalSection">'
				+ ' <div class="row">'
				+ '	 <div class="name subTotal">Sub-total:</div>'
				+ '	 <div class="value" id="subTotalValue"></div>'
				+ '  <div class="contentEnd"/>'
				+ ' </div>'
				+ '</div>'
			);
			$deliveryFeeRow = $(
				  '<div class="row" id="deliveryFeeRow">'
				+ '	<div class="name">Delivery fee:</div>'
				+ '	<div class="value"></div>'
				+ '</div>');
			$totalRow = $(
				  '<div class="row total">'
				+ '	<div class="name">Total Inc GST:</div>'
				+ '	<div class="value"></div>'
				+ '</div>');
			
			//we only show delivery information when cartType is 'delivery'
			if (conf.cartType == 'delivery') {
				$cartTotals.append ($deliveryFeeRow);
				$cartTotals.append($freeDeliveryRow);
			}
			$cartTotals.append ($totalRow);

			$checkoutButton = $('<input type="submit" class="orderNow" name="" value=""/>');
			
			// reset the cart content
			$cartSummary.html ('');
			$cartSummary.addClass ('shoppingCart box1');
			if (conf.allowEdit)
				$cartSummary.addClass ('shoppingCartEditable');
			if (conf.onMenuPage)
				$cartSummary.addClass ('shoppingCartMenuPage');

			// put the cart content together (ie. the scrollable area)
			$cartContent.append ($cartEmptyMessage);
			
			
			$cartContent.append ($cartItems);
			$cartContent.append ($subTotalRow);
			
			$discountSection = $('<div id="discountSection"/>');
			$discountSection.append(renderSelectDiscountText());
			$discountSection.append($discounts);
			$cartContent.append($discountSection);

			// put the cart summary together
			$cartSummary.append ($cartTitle);
			$cartSummary.append ($('<div class="contentEnd"/>'));
			$cartSummary.append ($cartContent);
			$cartSummary.append ($divider);
			$cartSummary.append ($cartTotals);
			if (conf.onMenuPage)
				$cartSummary.append ($checkoutButton);

			// make the cart temporarily think that it's initialising so that the cart items aren't animated when added
			var tempInitialising = initialising;
			initialising = true;

			// add the cart items into the cart summary
			$.each (cartItems, function (index, cartItem) {
				renderCartItem (cartItem);
			});

			// discounts
			renderDiscounts ();
			// totals
			renderTotals ();

			// send the user to the checkout page when they click the "checkout" button
			$checkoutButton.bind ('click', sendUserToCheckout);

			// make sure the cart isn't too tall
			checkCartHeight ();

			// fix the cart summary to the top of the screen when scrolling down
// disabled temporarily
			if (conf.onMenuPage)
				$('#cartSummary').coreFixedPos ({ offsetY: 10 });

			initialising = tempInitialising;
			return true;
		};

		// send the user to the checkout page when they click the "checkout" button
		var sendUserToCheckout = function () {
			document.location.href = 'http://www.basepizza.com.au/' + conf.quickLink + '/takeaway/checkout';
			return true;
		};

		// render the discounts into the cart summary
		var renderDiscounts = function () {
			// work out which options to givon the user,  eg. radios, checkboxes, nothing
			var ftcOptionType = null;
			var takeawayDiscountType = null;
			var loyaltyOptionType = null;

			// work out how many discounts are available
			var usableTakeawayDiscounts = countAvailabeTakeawayDiscount();

			// apply logic to work out which type of option to give the user per discount type
			if (loyaltyDiscount.available) {

				ftcOptionType = 'radio';
				takeawayDiscountType = 'radio';
				loyaltyOptionType = 'radio';

				if ((ftcDiscount.available) && (usableTakeawayDiscounts));	// use 'radio',  set above
				else if (ftcDiscount.available) {
					if (loyaltyDiscount.allowFTC) {
						ftcOptionType = 'checkbox';
						loyaltyOptionType = null;
					}
				}
				else if (usableTakeawayDiscounts == 1) {
					if (loyaltyDiscount.allowTakeawayDiscounts) {
						takeawayDiscountType = null;
						loyaltyOptionType = null;
					}
				}
				else if (usableTakeawayDiscounts > 1);	// use 'radio',  set above
				else
					loyaltyOptionType = null;
			}
			else if (ftcDiscount.available) {
				ftcOptionType = 'checkbox';
				if (usableTakeawayDiscounts) {
					ftcOptionType = 'radio';
					takeawayDiscountType = 'radio';
				}
			}
			else if (usableTakeawayDiscounts > 1)
				takeawayDiscountType = 'radio';

			renderFtcDiscount (ftcOptionType, lastSentDiscountSelection);
			renderTakeawayDiscounts (takeawayDiscountType, lastSentDiscountSelection);
			renderLoyaltyDiscount (loyaltyOptionType, lastSentDiscountSelection);


			// if no discounts were chosen,  choose the first one
			if (conf.allowEdit) {

				// if no discounts were chosen,  choose the first one
				if (!$discounts.find ('.available input:checked').length) {
					if (ftcDiscount.selected)
						ftcDiscount.$element.find ('.option input:first').attr ('checked', true);

					$.each (takeawayDiscounts, function (index, takeawayDiscount) {
						if ((isTakeawayDiscountUsable (takeawayDiscount, conf.showPricesWithTax)) && (takeawayDiscount.selected))
							takeawayDiscount.$element.find ('.option input:first').attr ('checked', true);
					});

					if ((loyaltyDiscount.selected) && (loyaltyDiscount.$element !== null))
						loyaltyDiscount.$element.find ('.option input:first').attr ('checked', true);
				}
			}
			else
				api.showHideDiscounts ();

			// show or hide the discount values respective of which radio/checkboxes are selected
			showHideDiscountPrices ();

			return true;
		};

		// render the ftc discount
		var renderFtcDiscount = function (optionType, selectedDiscounts) {
			if (ftcDiscount.available) {
				var $tempDiscountRow = $discountRowTemplate.clone ()
				.find ('.name').html ('%%percent%%% off first order'.replace ('%%percent%%', ftcDiscount.percentage * 100)).end ()
				.find ('.value').text (getReadablePrice (-calcFtcDiscountValue (conf.showPricesWithTax, true), true))
				.end ();

				// add the radio button/checkbox if needed
				var temp = [$tempDiscountRow];
				optionifyDiscount (temp, optionType, 'discountFTC', selectedDiscounts);
				$tempDiscountRow = temp[0];

				showHideDiscountRow (ftcDiscount, $tempDiscountRow);
			}
			return true;
		};

		// render a takeaway discount
		var renderTakeawayDiscounts = function (optionType, selectedDiscounts) {

			// loop through the takeaway discounts
			$.each (takeawayDiscounts, function (index, takeawayDiscount) {

				// provided the cart is actually usable render it
				if (isTakeawayDiscountUsable (takeawayDiscount, conf.showPricesWithTax)) {

					var value = calcTakeawayDiscountValue (takeawayDiscount, conf.showPricesWithTax, true);
					if (value > 0)
						var $tempDiscountRow = $discountRowTemplate.clone ()
						.find ('.name').text (takeawayDiscount.title).end ()
						.find ('.value').text (getReadablePrice (-value, true))
						.end ();
					else
						var $tempDiscountRow = $nameNoPriceTemplate.clone ().text (takeawayDiscount.title).append ($('<div class="contentEnd"/>'));

					// add the option for the user to type a comment for this discount
					if (takeawayDiscount.askForComment) {
						if (conf.allowEdit)
							$tempDiscountRow.find ('.contentEnd').before ($('<div class="commentLayout"><div class="core-inFieldLabel"><label for="discountTA' + takeawayDiscount.id + '_comment">Enter your choice</label><input id="discountTA' + takeawayDiscount.id + '_comment" name="discountTA' + takeawayDiscount.id + '_comment" type="text" class="comment"/></div><a href="#" class="map1_question jsHelper">?</a></div>'));
						else {
							if (takeawayDiscount.comment)
								$tempDiscountRow.find ('.contentEnd').before ($('<span/>').text (' - ' + takeawayDiscount.comment));
						}
					}

					// add the radio button/checkbox if needed
					var temp = [$tempDiscountRow];
					optionifyDiscount (temp, optionType, 'discountTA' + takeawayDiscount.id, selectedDiscounts);
					$tempDiscountRow = temp[0];

					if (takeawayDiscount.askForComment) {

						// add the default value
						$tempDiscountRow.find ('input[type=text]').val (takeawayDiscount.comment);

						// observe the input field for changes
						$tempDiscountRow.find ('input[type=text]')
						.bind ('keyup', function () {
							ajax_updateDiscountDetails (2600);	// send the update in a moment,  to allow for the user to send more keypresses
						})
						.bind ('change', function () {	// observe the input field for changes
							ajax_updateDiscountDetails ();	// send the update straight away because the use has finished editing
						});


						// show the user the discount details in a popover on mouse-over the '?'
						var popoverHtml = $('<div><div class="popoverTitle"></div><div class="jsContent"></div></div>')
						.find ('.popoverTitle').html (takeawayDiscount.title).end ()
						.find ('.jsContent').html (takeawayDiscount.descriptionHtml).end ();

						$tempDiscountRow.find ('a.map1_question')
						.click (function () { return false; })	// stop the anchor tag from being clickable
						.popoverTrigger ({ // show the popover
							messageHtml: popoverHtml.html (),
							openTriggers: 'mouseenter,focus',
							closeTriggers: 'mouseleave,blur',
							popoverConf:
							{	template: 'helperNoTitle',
								easyClose: false,
								attachTo: 'self',
								applyArrows: true,
								pointTo: 'self',
								baseAttachDirectionX: 'center',
								popoverAttachDirectionX: 'right',
								baseAttachDirectionY: 'bottom',
								popoverAttachDirectionY: 'top',
								attachOffsetX: 15,
								attachOffsetY: 10,
								maxWidth: 300
							}
						});
					}
				}
				// or if it's not usable just add a placeholder for in-case it gets shown later
				else
					var $tempDiscountRow = $('<div/>');

				showHideDiscountRow (takeawayDiscount, $tempDiscountRow);
			});
			return true;
		};

		// render the loyalty discount
		var renderLoyaltyDiscount = function (optionType, selectedDiscounts) {
			if (loyaltyDiscount.available) {

				// create the element
				// render the name and show the user the value
				if (loyaltyDiscount.couldUseThisTime) {

					var $tempDiscountRow = $discountRowTemplate.clone ()
					.find ('.name').html ('Loyalty discount').end ()
//					.find ('.value').html (getReadablePrice (-calcLoyaltyDiscountValue (conf.showPricesWithTax, true), true)).end ()
					.append ($('<div class="contentEnd"/>'))
					.append ('<span class="loyaltyLimitedMsg">(limit applied based on past loyalty orders)</span>')
					.append ($('<div class="contentEnd"/>'));
				}
				// or render the name and show the user their progress
				else {
					var $tempDiscountRow = $nameNoPriceTemplate.clone ()
					.html ('Your loyalty credit:<br /><span class="loyaltyProgressMsg">' + loyaltyDiscount.progressDesc + '</span>')
					.append ($('<div class="contentEnd"/>'));
				}

				// add the radio button/checkbox if needed
				var temp = [$tempDiscountRow];
				optionifyDiscount (temp, optionType, 'discountLoyalty', selectedDiscounts);
				$tempDiscountRow = temp[0];

				// show it
				showHideDiscountRow (loyaltyDiscount, $tempDiscountRow);

				// work out if the amount available from this loyalty discount is enough to cover the cart cost
				calcLoyaltyDiscountValue (conf.showPricesWithTax, true);
				if (loyaltyDiscount.valueCoversCartCost)
					$tempDiscountRow.find ('span.loyaltyLimitedMsg').hide ();
			}
			return true;
		};

		// take a discount row,  and turn it into html containing the input radio/checkbox and click observe
		var optionifyDiscount = function (element, optionType, inputValue, selectedDiscounts) {
			if (!conf.allowEdit)
				return false;

			var $origElement = element[0];

			// only change the element if a radio/checkbox needs to be added
			if (optionType) {

				// create the new content
				var $newElement = $('<div><div class="option"></div><div class="optionName"></div></div>').find ('.optionName').html ($origElement.html ()).end ();

				// add a radio button or checkbox
				if (optionType == 'radio')
					var $input = $('<input type="radio" name="discountId" class="smallRadio"/>').val (inputValue);
				else if (optionType == 'checkbox')
					var $input = $('<input type="checkbox" name="discountId[]"/>').val (inputValue);
				$newElement.find ('.option').append ($input);

				// insert the new content into the original element
				$origElement.html ($newElement.html ())
				.find ('.contentEnd').remove ().end ()		// remove any contentEnd elements inside the row
				.append ($('<div class="contentEnd"/>'));	// put a contentEnd element at the bottom of the whole row

				// observe changes to the discounts so that the server can be updated

				// select this discount if it was selected before
				if ($.inArray (inputValue, selectedDiscounts) >= 0)
					$origElement.find ('.option input:first').attr ('checked', true);

				// make the row clickable if required
				if (optionType == 'radio') {
					// toggle the radio button when the whole row is clicked
					$origElement.addClass ('clickable').bind ('click', function () {
						// trigger customChange so that the real radio button is changed,  and whenever customChange occurs the selected discount etc is updated in the trigger below
						$origElement.find ('input:first').attr ('checked', true).trigger ('customChange');
					});
					$origElement.find ('.option input:first').bind ('customChange', function () {
						showHideDiscountPrices ();		// show or hide the discount values respective of which radio/checkboxes are selected
						renderTotals ();
						ajax_updateDiscountDetails ();	// update the server with the selected discount
					});
				}
				else if (optionType == 'checkbox') {
					// toggle the checkbox when the whole row is clicked

					$origElement.find ('.option input:first')
					.bind ('click', function (e) {
						e.stopPropagation ();
						$(this).trigger ('customChange');
					})
					.bind ('customChange', function () {
						showHideDiscountPrices ();		// show or hide the discount values respective of which radio/checkboxes are selected
						renderTotals ();
						ajax_updateDiscountDetails ();	// update the server with the selected discount
						return false;
					});
					$origElement.addClass ('clickable').bind ('click', function () {
						var $input = $origElement.find ('.option input:first');
						$input.attr ('checked', !$input.attr ('checked')).trigger ('customChange');
						return false;
					})
				}
			}
			return true;
		};

		// show or hide a discount row neatly,  depending on whether it's already showing etc
		var showHideDiscountRow = function (originalData, $newElement) {

			// add for the first time
			if (originalData.$element === null) {
				originalData.$element = $('<div/>');
				$discounts.append (originalData.$element);
			}
			var originalElementHadContent = (originalData.$element.text () != '');
			var newElementHasContent = ($newElement.text () != '');

			// show/hide it neatly depending on if content existed before and if it has content now
			if (initialising) {
				originalData.$element.replaceWith ($newElement);
				originalData.$element = $newElement;
				$newElement.show ();
			}
			else {
				// need to show the row
				if (newElementHasContent) {

					originalData.$element.replaceWith ($newElement);
					originalData.$element = $newElement;

					if (!originalElementHadContent)
						originalData.$element.show (showCartAnimations ? 'blind' : undefined);
				}
				// need to hide the row
				else {
					if (originalElementHadContent)
						originalData.$element.hide (showCartAnimations ? 'blind' : undefined, {}, null, function () {
							originalData.$element.replaceWith ($newElement);
							originalData.$element = $newElement;
						});
					else {
						originalData.$element.replaceWith ($newElement);
						originalData.$element = $newElement;
					}
				}
			}
			return true;
		};

		// show or hide the discount prices depending on which one is picked
		var showHideDiscountPrices = function () {
//			if (!initialising) {
				// initially hide the discount amount (ie. it is only shown when selected)
				$discounts.find ('.row').map (function () {
					// if the radio/checkbox is selected then show the value,  otherwise hide the value
					var $row = $(this);
					var $input = $row.find ('.option input:first');
					if ($input.length) {
						if ($input.attr ('checked'))
							$row.find ('.value').show ();
						else
							$row.find ('.value').hide ();
					}
					// if there are no radios/checkboxes,  show the value anyway
					else
						$row.find ('.value').show ();
				});
//			}

			// show/hide the loyalty discount "amount is limited" message
			if ((loyaltyDiscount.available) && (loyaltyDiscount.$element !== null)) {
				var showLimitedMessage = false;

				var $input = loyaltyDiscount.$element.find ('.option input:first');
				if ((!$input.length) || ($input.attr ('checked')))	// if it's checked,  or if there are no radios/checkboxes,  show anyway
					showLimitedMessage = true;

				if ((showLimitedMessage) && (!loyaltyDiscount.valueCoversCartCost))
					loyaltyDiscount.$element.find ('span.loyaltyLimitedMsg:hidden').show (showCartAnimations ? 'blind' : undefined);
				else
					loyaltyDiscount.$element.find ('span.loyaltyLimitedMsg:visible').hide (showCartAnimations ? 'blind' : undefined);
			}

			return true;
		};

		// update the server with details about the chosen discounts
		var ajax_updateDiscountDetails = function (delayMS) {

			if (delayMS > 0) {
				clearTimeout (discountDetailsTimeout);
				discountDetailsTimeout = setTimeout (function () { ajax_updateDiscountDetails (0); }, delayMS);
				return true;
			}

			// only tell the server about the details if it has changed
			if ((getDiscountSelection ().join ('_') == lastSentDiscountSelection.join ('_'))
			&& (getDiscountCommentHash () == lastSentDiscountCommentHash))
				return true;

			// record which discounts are selected + comments entered (so we know not to re-send a selection next time the user clicks the same box)
			lastSentDiscountSelection = getDiscountSelection ();
			lastSentDiscountCommentHash = getDiscountCommentHash ();



			var parameters = [];
			parameters.push ({ name: 'action', 'value': 'updateDiscounts' });	// the action to take
			parameters.push ({ name: 'restaurantId', 'value': conf.restaurantId });
			parameters.push ({ name: 'cartId', 'value': conf.cartId });
			parameters.push ({ name: 'menuId', 'value': conf.menuId });

			// work out which discounts are selected (ie. radio/checkbox checked)
			var selectedDiscounts = [];
			$discounts.find ('input:checked').map (function () {
				selectedDiscounts.push ($(this).val ());
			});
			parameters.push ({ name: 'discountIds', 'value': selectedDiscounts.join (',') });

			// add the discount comments
			var discountComments = [];
			$discounts.find ('input[type=text]').map (function () {
				parameters.push ({ name: $(this).attr ('name'), 'value': $(this).val () });
			});


			$.ajax (
			{	url: 'http://www.basepizza.com.au/takeaway/ajax_update_cart.php',
				type: 'POST',
				dataType: 'json',
				data: parameters,
				success: api.processJsonResponse
			});
			return true;
		};

		// record which discounts are selected
		var getDiscountSelection = function () {
			var discountSelection = [];
			$discounts.find ('input:checked').map (function () {
				discountSelection.push ($(this).val ());
			});
			return discountSelection;
		};

		// record which discounts are selected
		var getDiscountCommentHash = function () {
			var discountComments = [];
			$discounts.find ('input[type=text]').map (function () {
				discountComments.push ($(this).val ());
			});
			return discountComments.join (']_[');
		};

		// show or hide the "free delivery" message depending on the delivery fee and the cost of the cart		
		var switchFreeDeliveryAndDeliveryFee = function () {
			//only do this when cartType is delivery
			if (conf.cartType == 'delivery') {
				if ((conf.suburbId) && (conf.finalDeliveryFeeWithTax == 0)) {
					$freeDeliveryRow.filter (':hidden').show();
					$deliveryFeeRow.filter(':visible').hide();
				} else {
					$deliveryFeeRow.filter(':hidden').show();
					$freeDeliveryRow.filter (':visible').hide();
				}
			}
			return true;
		};
		
		// render the total values into the cart summary
		var renderTotals = function () {

			// calculate the ftc value
			var ftcValue = calcFtcDiscountValue (conf.showPricesWithTax, false);

			// calculate the takeaway discount value
			var takeawayDiscountValue = 0;
			$.each (takeawayDiscounts, function (index, takeawayDiscount) {
				takeawayDiscountValue += calcTakeawayDiscountValue (takeawayDiscount, conf.showPricesWithTax, false);
			});

			// calculate the loyalty value
			var loyaltyDiscountValue = calcLoyaltyDiscountValue (conf.showPricesWithTax, false);

			// render the totals including tax
			if (conf.showPricesWithTax) {

				conf.finalDeliveryFeeWithTax = conf.deliveryFeeWithTax;
				if ((conf.freeDeliveryAfterWithTax > 0) && (conf.subTotalWithTax - (ftcValue + takeawayDiscountValue + loyaltyDiscountValue) > conf.freeDeliveryAfterWithTax)) {
					conf.finalDeliveryFeeWithTax = 0;
				}
				
				//subTotal Price doesn't include any discounts:only sum of item prices.
				$subTotalRow.find ('.value').html (getReadablePrice(conf.subTotalWithTax, true));
				//we must render delivery fee row specially:
				//no delivery fee, we display 'FREE DELIVERY'
				//with delivery fee, we display 'Delivery fee:$x.xx'
				$deliveryFeeRow.find ('.value').html (getReadablePrice (conf.finalDeliveryFeeWithTax, true));
				$totalRow.find ('.value').html (getReadablePrice (conf.subTotalWithTax + conf.deliveryFeeWithTax - (ftcValue + takeawayDiscountValue + loyaltyDiscountValue), true));
			}
			// or render the totals excluding tax
			else {
				conf.finalDeliveryFeeNoTax = conf.deliveryFeeNoTax;
				if ((conf.freeDeliveryAfterNoTax > 0) && (conf.subTotalNoTax - (ftcValue + takeawayDiscountValue + loyaltyDiscountValue) > conf.freeDeliveryAfterNoTax))
					conf.finalDeliveryFeeNoTax = 0;

				$subTotalRow.find ('.value').html (getReadablePrice (conf.subTotalNoTax - (ftcValue + takeawayDiscountValue + loyaltyDiscountValue), true));
				$deliveryFeeRow.find ('.value').html (getReadablePrice (conf.finalDeliveryFeeNoTax, true));
				$totalRow.find ('.value').html (getReadablePrice (conf.subTotalNoTax + conf.deliveryFeeNoTax - (ftcValue + takeawayDiscountValue + loyaltyDiscountValue), true));
			}

			switchFreeDeliveryAndDeliveryFee();
			return true;
		};

		// show the "There are no items in your cart yet." message if it's empty
		var showCartEmptyMessageIfNecessary = function () {
			if (!totalCartItems)
				$cartEmptyMessage.show ();
			else
				$cartEmptyMessage.hide ();
			return true;
		};

		// check to make sure the user's cart isn't too tall,  and if so make it's content scroll
		// for ie7: added setTimeout to get it to work
		// only limit the height of the cart on the menu page
		if (conf.onMenuPage) {
			if (($.browser.msie) && ($.browser.version >= 7) && ($.browser.version < 8)) {
				var checkCartHeight = function () {
					setTimeout (function () {
						checkCartHeight2 ();
					}, 1);
				}
			}
			else {
				var checkCartHeight = function () {
					checkCartHeight2 ();
				}
			}
		}
		// not needed when not on the menu page
		else
			var checkCartHeight = function () {};

		// the function that's actually called
		var checkCartHeight2 = function () {

			var scrollTop = $cartContent.scrollTop ();
			var origMaxHeight = $cartContent.css ('max-height');

			
			$cartContent.css ('max-height', '');	// temporarily un-fix the height of the middle section
			var cartSummaryHeight = $cartSummary.height () + 45;

			// set the maximum height and allow scrolling to occur
			if (cartSummaryHeight >= windowHeight) {
				var cartSummaryNonContentHeight = cartSummaryHeight - $cartContent.height ();
				$cartContent.css ({ 'max-height': (Math.max (windowHeight - cartSummaryNonContentHeight, 100)) + 'px', 'overflow-y': 'auto' });
//				$cartContent.scrollTop (scrollTop);
			}
			// make sure no scrolling occurs
			else
				$cartContent.css ({ 'max-height': origMaxHeight, 'overflow-y': 'hidden' });
		};

		// when a food item is added to the user's cart,  scroll the cart to the food item if necessary
		var scrollCartSummaryToFoodItem = function ($element, onAfter) {
			var cartItemTop = $element.offset ().top;
			var cartItemHeight = $element.outerHeight ();
			var cartContentTop = $cartContent.offset ().top;
			var cartContentHeight = $cartContent.outerHeight ();

			// if any of the cart item is off the top of the $cartContent
			// slide it on to view at the top
			if (cartItemTop < cartContentTop)
				$cartContent.scrollTo ($element, 600, { onAfter: onAfter });
			// or if any of the cart item is off the bottom of the $cartContent
			// slide it on to view at the bottom
			else if (cartItemTop + cartItemHeight > cartContentTop + cartContentHeight) {
				var cartContentScrollTop = $cartContent.scrollTop ();
				$cartContent.scrollTo ((cartContentScrollTop + cartItemTop + cartItemHeight - cartContentHeight) - cartContentTop, 600, { onAfter: onAfter });
			}
			// or just call the onAfter callback now
			else
				onAfter ();
		};

		// calculate the value of the ftc discount
		var calcFtcDiscountValue = function (showPricesWithTax, calculateRegardlessOfBeingSelected) {
			if (ftcDiscount.available) {

				// the ftc value may only be needed if it's radio/checkbox is selected
				var useValue = true;
				if (!calculateRegardlessOfBeingSelected) {
					useValue = false;

					if (conf.allowEdit) {
						$input = ftcDiscount.$element.find ('.option input:first');
						if ((!$input.length) || ($input.attr ('checked')))
							useValue = true;
					}
					else {
						if ((ftcDiscount.available) && (ftcDiscount.selected))
							useValue = true;
					}
				}

				// calculate the value
				if (useValue) {
					return parseFloat (ftcDiscount.value);
				}
			}
			return 0;
		};
		// calculate the value of a takeaway discount
		var calcTakeawayDiscountValue = function (takeawayDiscount, showPricesWithTax, calculateRegardlessOfBeingSelected) {

			// the ftc value may only be needed if it's radio/checkbox is selected
			var useValue = true;
			if (!calculateRegardlessOfBeingSelected) {

				// work out if this takeaway discount is selected
				useValue = false;
				if (isTakeawayDiscountUsable (takeawayDiscount, conf.showPricesWithTax)) {	// only consider it if it's available (ie. showing to the user).  if the discount isn't available because the user doesn't have enough in the cart then it can't be used)

					if (conf.allowEdit) {
						$input = takeawayDiscount.$element.find ('.option input:first');
						if ((!$input.length) || ($input.attr ('checked')))
							useValue = true;
					}
					else if ((takeawayDiscount.available) && (takeawayDiscount.selected))
						useValue = true;
				}
			}

			if (useValue) {
				if (takeawayDiscount.type == 'percent') {
					if (showPricesWithTax)
						return parseFloat ((conf.subTotalWithTax * (takeawayDiscount.percentage)).toFixed (conf.currencyDecPl));
					return parseFloat ((conf.subTotalNoTax * (takeawayDiscount.percentage)).toFixed (conf.currencyDecPl));
				}
				else if (takeawayDiscount.type == 'fixedAmount') {
					if (showPricesWithTax)
						return parseFloat (takeawayDiscount.fixedAmountWithTax.toFixed (conf.currencyDecPl));
					return parseFloat (takeawayDiscount.fixedAmountNoTax.toFixed (conf.currencyDecPl));
				}
			}
			return 0;
		};
		// work out if the given takeaway discount is applicable to this cart
		var isTakeawayDiscountUsable = function (takeawayDiscount, showPricesWithTax) {
			if (!takeawayDiscount.available)
				return false;
			// work out if the user has enough $ in their cart for this discount
			if (showPricesWithTax)
				var cartCost = conf.subTotalWithTax;
			else
				var cartCost = conf.subTotalNoTax;

			if (((takeawayDiscount.minOrderAmount === null) || (cartCost >= takeawayDiscount.minOrderAmount))
			&& ((takeawayDiscount.maxOrderAmount === null) || (cartCost <= takeawayDiscount.maxOrderAmount)))
				return true;
			return false;
		};
		// calculate the value of the loyalty discount
		var calcLoyaltyDiscountValue = function (showPricesWithTax, calculateRegardlessOfBeingSelected) {

			if ((loyaltyDiscount.available) && (loyaltyDiscount.$element !== null)) {
				loyaltyDiscount.valueCoversCartCost = (loyaltyDiscount.maxValueWithTax >= conf.subTotalWithTax);

				if (loyaltyDiscount.couldUseThisTime) {

					// the loyalty value may only be needed if it's radio/checkbox is selected
					var useValue = true;
					if (!calculateRegardlessOfBeingSelected) {
						useValue = false;

						if (conf.allowEdit) {
							$input = loyaltyDiscount.$element.find ('.option input:first');
							if ((!$input.length) || ($input.attr ('checked')))
								useValue = true;
						}
						else {
							if ((loyaltyDiscount.available) && (loyaltyDiscount.selected))
								useValue = true;
						}
					}

					// calculate the value
					if (useValue) {
						if (loyaltyDiscount.valueCoversCartCost)
							return conf.subTotalWithTax;
						return loyaltyDiscount.maxValueWithTax;
//						return (showPricesWithTax ? loyaltyDiscount.amountWithTax : loyaltyDiscount.amountNoTax );
					}
				}
			}
			return 0;
		};

		// send a request to the server to add the given cart item
		var ajax_addItemToCart = function ($form) {

			// if the user needs to,  check to make sure they selected a variety
			var messages = [];
			var $optionRadios = $form.find ('input[type=radio]');
			if (($optionRadios.length) && (!$optionRadios.filter (':checked').length))
				messages.push ('Please select a variety to add');

			// if the user needs to,  check to make sure they entered a quantity
			var $quantityInput = $form.find ('input[name=qty]');

			if (($quantityInput.length) && (parseInt ($quantityInput.val ()) != $quantityInput.val ()))
				messages.push ('Please specify a quantity to add');

			// display a different message if the user hasn't done either
			if (messages.length == 2)
				messages = ['Please select a variety and quantity to add'];

			// work out if this food item has a minimum quantity required
			// and display a message if the user doesn't have enough
			var $minQty = $form.find ('input[name=minQty]');
			if (($minQty.length) && (parseInt ($quantityInput.val ()) < parseInt ($minQty.val ())))
				messages = ['Please add at least %%quantity%% of these to your cart'.replace ('%%quantity%%', $minQty.val ())];

			// display any error messages and finish
			if (messages.length) {

				// close the message popover if it's already being shown
				if (messagePopoverApi !== undefined)
					messagePopoverApi.close ();

				// show the user a message
				messagePopoverApi = $.createPopoverMini (
					{	content: $('<div><p>' + messages.join ('</p><p>') + '</p></div>').find ('p:last').addClass ('noSpaceBelow').end ().html (),
						customClass: 'core-popoverLargeFont'
					},
					$.extend (true, {}, messagePopoverDefaultConf, {
						baseElement: $form.find ('input[type="image"], input[type="submit"]')
					})
				).data ('popoverMini');
				return false;
			}

			$.core.mouse.startPleaseWait ('cart');	// show the please-wait spinny thing

			// send the request to the server to 'add' the food item to the cart
			var parameters = $form.serializeArray ();
			parameters.push ({ name: 'action', 'value': 'add' });	// the action to take
			parameters.push ({ name: 'restaurantId', 'value': conf.restaurantId });
			parameters.push ({ name: 'cartId', 'value': conf.cartId });
			parameters.push ({ name: 'menuId', 'value': conf.menuId });
			parameters.push ({ name: 'submitter', 'value': $form.find ('input[type="submit"], input[type="image"]').attr ('id') });

			$.ajax (
			{	url: 'http://www.basepizza.com.au/takeaway/ajax_update_cart.php',
				type: 'POST',
				dataType: 'json',
				data: parameters,
				success: function (response) {
					api.processJsonResponse (response);
				},
				error: function () {
					$.core.mouse.stopPleaseWait ('cart', true);	// force-stop the please-wait spinny thing
				}
			});

			// tell google analytics that the user tried to "add" an item to their cart - the first time only
			if ((conf.analyticsAddUrl) && (!toldGoogleAboutAddClick)) {
				analytics_trackPageview (conf.analyticsAddUrl);
				toldGoogleAboutAddClick = true;
			}

			return true;
		};

		/**
		 * check if a cart item has options
		 */
		var checkIfCartItemHasOptions = function(bundledCartItem) {
			var optionGroups = bundledCartItem.variety.optionGroups;
			//a food item, for example '2xlarge pastas', 
			//user can select two options:Spaghetti Bolognese, Fettuccine Carbonara
			//so even the food item id is same, they should still be counted as unique
			if (optionGroups.length > 0) {
				return true;
			}
			return false;
		}
		
		/**
		 * process boundled cart items for rendering
		 * 
		 */
		var getUniqueBundledCartItems = function(cartItem) {
			var result = [];
			var uniqueItems = {};
			var cachedItems = {};
			bundledCartItems = cartItem.bundledCartItems;
			var counter = 0;
			$.each (bundledCartItems, function(index, bundledCartItem) {
				//the food item is unique for 2 cases:
				//1. not in cachedItems; 2. the food item's variety's optionGroup has options
				if (cachedItems[bundledCartItem.foodItemId] == undefined) {
					cachedItems[bundledCartItem.foodItemId] = counter;
					uniqueItems[counter] = bundledCartItem;
					counter++;
				} else if (checkIfCartItemHasOptions(bundledCartItem) == true) {
					cachedItems[bundledCartItem.foodItemId] = counter;
					uniqueItems[counter] = bundledCartItem;
					counter++;
				} else {
					var uniqueItemIndex = cachedItems[bundledCartItem.foodItemId];
					uniqueItems[uniqueItemIndex].quantity = parseInt(bundledCartItem.quantity) + parseInt(uniqueItems[uniqueItemIndex].quantity);
				}
				
			});
			return uniqueItems;
		};
		
		// render the given cart item into the $cartSummary
		var renderCartItem = function (cartItem) {
			var $newElement = $cartItemRowTemplate.clone ();

			var $namePrice = createNamePriceRow (cartItem.name, true, cartItem.quantity, true, cartItem.unitPriceNoTax, cartItem.unitPriceWithTax, cartItem.oldUnitPriceNoTax, cartItem.oldUnitPriceWithTax, true);
			$namePrice.addClass ('foodItem');

			// add the food item details
			$newElement.find ('.details').prepend ($namePrice)
			.map (function () {

				var $details = $(this);
	
				// if this is a bundle then render the bundled food items
				if (cartItem.bundledCartItems.length) {
					processedBundledCartItems = getUniqueBundledCartItems(cartItem);
					$.each (processedBundledCartItems, function (index, bundledCartItem) {
						// add the cart item's name
						var foodItemId = bundledCartItem.foodItemId;
						var $namePrice = createNamePriceRow (bundledCartItem.name, (bundledCartItem.quantity > 1), bundledCartItem.quantity, false, 0, 0, 0, 0);
						$namePrice.addClass ('bundleItem');
						$details.append ($namePrice);

						// render the variety if it's got a name
						var variety = bundledCartItem.variety;
						if (variety.name) {
							var $namePrice = createNamePriceRow (variety.name, false, 1, false, 0, 0, 0, 0);
							$details.append ($namePrice);
						}

						// add any options
						$.each (variety.optionGroups, function (index, optionGroup) {
							$.each (optionGroup.options, function (index2, option) {
								var showPrice = (option.unitPriceWithTax > 0);

								var name = [];
								if (optionGroup.name)
									name.push ('- ' + optionGroup.name);
								if (option.name)
									name.push (option.name);

								var $namePrice = createNamePriceRow (name.join (': '), false, cartItem.quantity, showPrice, option.unitPriceNoTax, option.unitPriceWithTax, option.oldUnitPriceNoTax, option.oldUnitPriceWithTax);
								$details.append ($namePrice);
							});
						});
					});
				}
				// otherwise
				else {
					// render the variety if it's got a name
					var variety = cartItem.variety;
					if (variety.name) {
						var $namePrice = createNamePriceRow (variety.name, false, 1, false, 0, 0, 0, 0);
						$details.append ($namePrice);
					}
					// add any options
					$.each (variety.optionGroups, function (index, optionGroup) {
						$.each (optionGroup.options, function (index2, option) {
							var showPrice = (option.unitPriceWithTax > 0);

							var name = [];
							if (optionGroup.name)
								name.push ('- ' + optionGroup.name);
							if (option.name)
								name.push (option.name);

							var $namePrice = createNamePriceRow (name.join (': '), false, cartItem.quantity, showPrice, option.unitPriceNoTax, option.unitPriceWithTax, option.oldUnitPriceNoTax, option.oldUnitPriceWithTax);
							$details.append ($namePrice);
						});
					});
				}
			});

			// scroll to the food item on the page when clicked (only when on the menu page)
			if (conf.onMenuPage) {
				$newElement.find ('.details')
				.unbind ('click.takeawayShoppingCartFoodItemJump')
				.bind ('click.takeawayShoppingCartFoodItemJump', function () {
					// find the food item on the page
					var $foodItemRow = $('.jsFoodItem' + cartItem.foodItemId + ':first');
					// scroll to it and then highlight it
					if ($foodItemRow.length) {
						$.scrollTo ($foodItemRow, 500, {
							easing: 'easeOutQuart',
							offset:
							{	left: 0,
								top: -($courseNavBox.outerHeight (true) + 5)
							},
							onAfter: function () {
								$foodItemRow.effect ('highlight', {}, 1500);
							}
						});
					}
				});
			}

			// let the user remove the item from the cart
			$newElement.find ('.deleteX a').confirmDelete (
			{	message: 'Are you sure you want to remove this item from your order?',
                				confirmButtonHtml: '<input type="submit" class="yesRemoveButton" value="" name="" />',
				cancelButtonHtml: '<input type="submit" class="noCancelButton" value="" name="" />',
                				onConfirm: function (popoverApi) {
					popoverApi.close ();
					api.ajax_removeItemFromCart (cartItem.cartItemId);
				},
				width: ((($.browser.msie) && ($.browser.version < 8)) ? 290 : 280),	// add a bit of extra room for <= ie7 because it renders the buttons a bit wider
				applyMask: ((($.browser.msie) && ($.browser.version < 9)) ? true : true)	// msie < 7, 7 and 8 don't seem to render the mask with transparency
			});



			// initialise the row (update it if it already exists)
			var updating = (cartItem.$element !== null);

			if (updating) {
				$newElement.insertAfter (cartItem.$element);
				cartItem.$element.remove ();
				cartItem.$element = $newElement;
			}
			else {
				cartItem.$element = $newElement;
				$cartItems.append (cartItem.$element);
				// if the cart has finished initialising,  slide it neatly into view
				if (!initialising) {
					cartItem.$element.show ();
					cartItem.$element.hide ();
					cartItem.$element.show (showCartAnimations ? 'blind' : undefined, 'slow');
				}
			}
			return true;
		};

		var createNamePriceRow = function (name, showQuantity, quantity, showPrice, unitPriceNoTax, unitPriceWithTax, oldUnitPriceNoTax, oldUnitPriceWithTax, isFoodItem) {
			var $namePrice = $namePriceTemplate.clone ();
			isFoodItem = isFoodItem || false;
			// set the name
			if (showQuantity && isFoodItem == false)
				$namePrice.find ('.name').text (quantity + ' x ' + name);
			else
				$namePrice.find ('.name').text (name);
			
			if (isFoodItem) {
				$namePrice.find ('.itemQty').text(quantity);
			} else {
				$namePrice.find ('.itemQty').html('&nbsp;');
			}
			// populate it with values
			if (showPrice) {
				// render the cost including tax
				if (conf.showPricesWithTax) {
					if (unitPriceWithTax < oldUnitPriceWithTax)
						$namePrice.find ('.value').html ('<strike>' + getReadablePrice (quantity * oldUnitPriceWithTax, true) + '</strike>' + getReadablePrice (quantity * unitPriceWithTax, true));
					else
						$namePrice.find ('.value').html (getReadablePrice (quantity * unitPriceWithTax, true));
				}
				// render the cost excluding tax
				else {
					if (unitPriceNoTax < oldUnitPriceNoTax)
						$namePrice.find ('.value').html ('<strike>' + getReadablePrice (quantity * oldUnitPriceNoTax, true) + '</strike>' + getReadablePrice (quantity * unitPriceNoTax, true));
					else
						$namePrice.find ('.value').html (getReadablePrice (quantity * unitPriceNoTax, true));
				}
			}
			return $namePrice;
		};

		var internal_removeItemFromCart = function (cartItemId) {

			// remove the cart item from memory
			var cartItem = cartItems['cartItem' + cartItemId];

			// visually remove it from the cart
			visuallyRemoveCartItem (cartItem);
			delete (cartItems['cartItem' + cartItem.cartItemId]);
			totalCartItems--;

			showCartEmptyMessageIfNecessary ();

			checkCartHeight ();	// check to see if the height of the cart summary needs adjusting
			if (showCartAnimations)
				setTimeout (checkCartHeight, 500);	// and again after things have finished animating

			// un-highlight the food item (if the food item isn't in the cart anymore)
			unHighlightMenuFoodItem (cartItem.foodItemId);

			return true;
		};

		// remove the cart item from the $cartSummary
		var visuallyRemoveCartItem = function (cartItem) {

			// initialise the row (remove it if it already exists)
			if (cartItem.$element) {
				// if the cart is still initialising then simply remove the food item from the list
				if (initialising)
					cartItem.$element.remove ();
				// or slide it neatly out of  view
				else {
					cartItem.$element.hide ();
					cartItem.$element.show ().hide (showCartAnimations ? 'blind' : undefined, {}, 'slow', function () { cartItem.$element.remove (); });
				}
			}
			return true;
		};

		// observe the radio option inputs so that clicking on them will show the relevant optionGroups (if they need to be changed)
		var bindVarietyRadios = function (ifhJs, $popover, alreadyOpen) {
			// make sure that the width of all the option groups are the same length
			var $optionGroups = $popover.find ('.optionGroups');
			if ($optionGroups.length) {

				if (!alreadyOpen)
					$popover.show ();	// temporarily show the popover so the widths of the optionGroups inside can be measured
				var $hiddenOptionGroups = $optionGroups.filter (':hidden');
				var $foodItemBlocks = $popover.find ('.foodItem');
				$hiddenOptionGroups.show ();	// show all the optionGroups so their widths can be measured

				// determine the width of the food items
				var maxFoodItemWidth = null;
				$foodItemBlocks.map (function () {
					if ((maxFoodItemWidth === null) || ($(this).width () > maxFoodItemWidth))
						maxFoodItemWidth = $(this).width ();
				});

				// determine the width of the longest 'optionGroups'
				var maxWidth = null;
				$optionGroups.length;
				$optionGroups.map (function () {
					if ((maxWidth === null) || ($(this).width () > maxWidth))
						maxWidth = $(this).width ();
				});

				// set all the optionGroups to this waxWidth
				$optionGroups.width (maxWidth);
				$foodItemBlocks.width (maxWidth);	// set the width of the title so that even if no optionGroups are showing,  something is taking up the width
				$hiddenOptionGroups.hide ();	// hide all the relevant optionGroups again

				// hide the popover again because it is still yet to be "shown"
				if (!alreadyOpen)
					$popover.hide ();
			}

			// run the js to observe the variety radio links
			if (ifhJs.length)
				eval (ifhJs);

			return true;
		};

		// repeat the given string 'times' number of times
		var repeatString = function (string, times) {
			var returnVal = '';
			for (var count = 0; count < times; count ++)
				returnVal += string;
			return returnVal;
		};

		// render the given price in a readable format
		var getReadablePrice = function (amount, forceDecimals) {

			// work out what the price should be (show it to 2 dec.pl if the number isn't whole,  or forceDecimals is true)
			var negative = (amount < 0);
			amount = Math.abs (amount);
			var displayAmount = amount.toFixed (0);
			var tempDisplayAmount1 = displayAmount + '.' + repeatString ('0', conf.currencyDecPl).replace ('.', conf.currencyDecimalDelimiter);
			var tempDisplayAmount2 = amount.toFixed (conf.currencyDecPl).replace ('.', conf.currencyDecimalDelimiter);
			if ((forceDecimals) || (tempDisplayAmount1 != tempDisplayAmount2))
				displayAmount = tempDisplayAmount2;

			// render it with the negative symbol if needed and with the currency symbol on the correct side
			if (conf.currencySymbolIsPrefix)
				return (negative ? '-' : '') + conf.currencySymbol + displayAmount;
			return (negative ? '-' : '') + displayAmount + conf.currencySymbol;
		};

		// initialise
		return api.init ();
	}

	$.fn.takeawayShoppingCart = function (conf) {

		conf = $.extend (true, {}, $.menulog.takeawayShoppingCart.conf, conf);

		this.each (function () {
			var $this = $(this);

			// only apply coreTransformInput to this element if it hasn't already been applied
			if (!$this.data ('takeawayShoppingCart')) {
				var api = new takeawayShoppingCart ($this, conf);
				$this.data ('takeawayShoppingCart', api);
			}
		});

		return $(this);
	};

}) (jQuery);









/*////////////////////////////////////////////////////
// path: /javascript/front/voucher_shopping_cart.js //
// created: Mon, 26 Sep 2011 14:02:01 +1000         //
// modified: Mon, 12 Sep 2011 15:10:17 +1000        //
// size: 30394 bytes                                //
////////////////////////////////////////////////////*/

(function($) {

	$.menulog = $.menulog || { };

	$.menulog.voucherShoppingCart = {

		// update the default conf values below in $.core.transformInput.conf
		updateDefaultConf: function (conf) {
			this.conf = $.extend (true, {}, this.conf, conf);
		},

		// the default conf values used when this plugin is applied to a file input
		conf: {
			currencySymbol: '$',
			currencySymbolIsPrefix: true,
			currencyDecPl: 2,
			currencyDecimalDelimiter: '.',

			showPricesWithTax: true,

			redeemVoucherName: null,

			subTotalNoTax: 0,
			subTotalWithTax: 0,
			redeemVoucherNoTax: 0,
			redeemVoucherWithTax: 0,
			totalNoTax: 0,
			totalWithTax: 0,

			allowEdit: true,			// turned off when on the checkout page so the user can't edit anything
			onBrowsePage: true,			// only do certain things on the browse page
			allowHide: true,			// allow the summary to be shrunk
			startHidden: true			// start shrunk?

//			onBeforeAddCartItem: null,	// callback for when an item is about to be added to the shopping cart
//			onAfterAddCartItem: null	// callback for when an item is about to be added to the shopping cart
		},

		emptyCartItemTemplate: {
			cartItemId: null,
			voucherTypeId: null,
			name: null,
			quantity: 1,
			unitPriceNoTax: 0,
			unitPriceWithTax: 0,
			$element: null		// for internal use
		}
	};





	function voucherShoppingCart ($cartSummary, conf) {

		var api = this;
		$cartSummary = $($cartSummary);

		var initialising = true;
		var showingSummary = !conf.startHidden;
		var cartItems = {};
		var totalCartItems = 0;

		var messagePopoverApi = null;	// api to the popover that shows this cart's helper messages
		var errorPopoverApi = null;		// api to the popover that shows error content

		var $cartTitle = null;
		var $viewSummary = null;
		var $cartHideShowBlock = null;
		var $cartContent = null;
		var $cartEmptyMessage = null;
		var $cartItems = null;
		var $cartItemRowTemplate = null;
		var $namePriceTemplate = null;
		var $nameNoPriceTemplate = null;

		var $divider = null;

		var $cartTotals = null;
		var $subTotalRow = null;
		var $totalRow = null;
		var $checkoutButton = null;
		var $quickSummary = null;

		//
		var messagePopoverDefaultConf =
		{	template: 'helperNoTitle',
			baseAttachDirectionX: 'right',
			popoverAttachDirectionX: 'left',
			baseAttachDirectionY: 'center',
			popoverAttachDirectionY: 'center',
			attachOffsetX: 10,
			attachOffsetY: 0,
			closeAfter: 3500
		};

		var $window = $(window);
		var windowHeight = $window.height ();












		// API methods
		// init type things
		$.extend (api, {

			init: function () {

//				assignCallbacks ();
/**
				// call the onBeforeTransform javascript (when the element is about to be transformed)
				e = $.Event ();
				e.type = 'onBeforeTransform';
				$cartSummary.trigger (e);
				if (e.isDefaultPrevented ()) {
					return api;
				}
/**/

				if (conf.onBrowsePage) {

					// observe the "add voucher to cart" forms on the browse page
					observeVoucherForms ();
				}
			},

			// once the cart has finished being initially populated this is called
			finishedInitialising: function () {
				initialising = false;
				renderCartSummary ();

				// observe when the window changes height (the cart summary may need resizing)
				$window.bind ('resize', function (e) {
					windowHeight = $window.height ();	// record the new page height (so it's not re-calculated every time something's added to the cart)
//					checkCartHeight ();	// check to see if the height of the cart summary needs adjusting
				});

				return api;
			}
		});













		// API methods
		// ..
		$.extend (api, {

			// add an item to the cart (a cart item)
			// or update it (based on the cartItemId)
			internal_addItemToCart: function (cartItem, submitterId) {

				// update the cart item (maintain it's $element)
				if (cartItems['cartItem' + cartItem.cartItemId] !== undefined) {
					var $temp = cartItems['cartItem' + cartItem.cartItemId].$element;
					cartItem = $.extend (true, {}, $.menulog.voucherShoppingCart.emptyCartItemTemplate, cartItem)
					cartItem.$element = $temp;
					cartItems['cartItem' + cartItem.cartItemId] = cartItem;
				}
				// create a new if not updating
				else {
					cartItem = $.extend (true, {}, $.menulog.voucherShoppingCart.emptyCartItemTemplate, cartItem)
					cartItems['cartItem' + cartItem.cartItemId] = cartItem;
					totalCartItems++;
				}

				// store the cart item's values
				cartItems['cartItem' + cartItem.cartItemId] = cartItem;

				if (!initialising) {
					renderCartItem (cartItem);
					showCartEmptyMessageIfNecessary ();
/**
					checkCartHeight ();	// check to see if the height of the cart summary needs adjusting
					scrollCartSummaryToFoodItem (cartItem.$element, function () {	// scroll the cart to the food item if necessary
//						setTimeout (function () { cartItem.$element.effect ('highlight', {}, 1500); }, 500);	// flash it in a moment
						cartItem.$element.effect ('highlight', {}, 1500);	// flash it in a moment
					});
					setTimeout (checkCartHeight, 500);	// and again after things have finished animating
/**/

/**
					if (!submitterId)
						submitterId = 'mouse';

					// close the message popover if it's already being shown
					if (messagePopoverApi !== null)
						messagePopoverApi.close ();

					// show the user a message "added"
					var popoverConf = $.extend (true, {}, messagePopoverDefaultConf, {
						template: 'helperNoTitle',
						attachTo: $('#' + submitterId),
						applyArrows: true,
						pointTo: $('#' + submitterId),
						closeAfter: 1500
					});

					// show the "added" message
					messagePopoverApi = $.createPopover (
						{	content: 'Added',
							customClass: 'core-popoverLargeFont'
						},
						popoverConf
					).data ('popover');
/**/
					sendUserToCheckout ();
				}
				return api;
			},

			// send a request to the server to remove the given cart item
			ajax_removeItemFromCart: function (cartItemId) {

				var parameters = [];
				parameters.push ({ name: 'action', 'value': 'remove' });	// the action to take
				parameters.push ({ name: 'cartItemId', 'value': cartItemId });

				$.ajax (
				{	url: 'http://www.basepizza.com.au/vouchers/ajax_update_cart.php',
					type: 'POST',
					dataType: 'json',
					data: parameters,
					success: api.processJsonResponse
				});

				return api;
			},

			internal_removeItemFromCart: function (cartItemId) {

				// remove the cart item from memory
				var cartItem = cartItems['cartItem' + cartItemId];

				// visually remove it from the cart
				visuallyRemoveCartItem (cartItem);
				delete (cartItems['cartItem' + cartItem.cartItemId]);
				totalCartItems--;

				showCartEmptyMessageIfNecessary ();

//				checkCartHeight ();	// check to see if the height of the cart summary needs adjusting
//				setTimeout (checkCartHeight, 500);	// and again after things have finished animating

				return true;
			},

			// update the total values,  and re-render them if not initialising
			internal_updateTotals: function (totalsData) {
				conf.subTotalNoTax = totalsData.subTotalNoTax;
				conf.subTotalWithTax = totalsData.subTotalWithTax;
				conf.totalNoTax = totalsData.totalNoTax;
				conf.totalWithTax = totalsData.totalWithTax;

				if (!initialising)
					renderTotals ();
				return api;
			}
		});







		// API methods
		// ..
		$.extend (api, {

			// process the response from the server
			processJsonResponse: function (json) {

				// if the response came back as an json object then process it
				if (typeof (json) == 'object') {

					// loop through each instruction
					$(json).each (function (index, value) {

						switch (value[0]) {
/**
							case 'add': // add an item to the cart
								api.internal_updateTotals (value[2]);	// new total values
								api.internal_addItemToCart (value[1], value[3], value[4], value[5]);	// cart item, new ifh html, new ifh js, submitter
								break;
							case 'remove':	// remove an item from the shopping cart
								api.internal_updateTotals (value[2]);	// new total values
								internal_removeItemFromCart (value[1]);
								break;
//							case 'loyaltyProgressDesc':
//								api.loyaltyProgressDesc (value[1]);	// update the loyalty progress description
//								break;
//							case 'openIfhPopover':
//								openIfhPopover (value[1], value[2], value[3], value[4], value[5]);	// popoverPurpose, title, ifh html, ifh js, submitter
//								break;
//							case 'closeIfhPopover':
//								closeIfhPopover ();
//								break;
//							case 'setSuburb':
//								api.setSuburb (value[1], value[2], value[3], value[4], value[5]);	// set the shopping cart's suburbId
//								break;
							case 'reloadPage':	// reload the page (eg. this is done after the cart type changes: delivery <-> pickUp)
								window.location.reload ();
								break;
/**/
							// display an nice error message to the user
							case 'error':

								// format the message nicely,  it may have been plain text or html
								var $message = $('<div/>').html (value[1]);
								if (!$message.find ('p').length)
									$message = $('<p/>').html (value[1]).wrap ($('<div></div>')).parent ();
								$message.find ('p:first').addClass ('core-spaceForCloseX core-first');
								$message.find ('p:last').addClass ('core-last');

								// close the ifh popover if it's already being shown
//								if (ifhPopoverApi !== null)
//									ifhPopoverApi.close ();

								// close the error popover if it's already being shown
								if (errorPopoverApi !== null)
									errorPopoverApi.close ();

								// show the message
								errorPopoverApi = $.createPopover (
								{	content: $message.html (),
									customClass: 'core-popoverLargeFont' },
								{	template: 'generalNoTitle',
									baseAttachDirectionX: 0.5,
									popoverAttachDirectionX: 0.5,
									baseAttachDirectionY: 0.5,
									popoverAttachDirectionY: 0.5,
									applyMask: true,
									addCloseX: true,
									easyClose: true,
									fixed: true,
									group: 'error'
								}).data ('popover');
								break;
							// run an arbitrary api.method (provided it exists)
							default:
								if ($.isFunction (api[value[0]])) {
									var methodName = value[0];
									value.shift ();
									api[methodName].apply (api[methodName], value);	// call the function specified in value[0] with the given parameters
								}
								break;
						}
					});
				}
				return true;
			}
		});




















		// submit the "add voucher to cart" forms via ajax
		var observeVoucherForms = function () {

			$('.voucherForm').bind ('submit', function () {

				var $form = $(this);

				// send the request to the server
				$.ajax ({
					url: 'http://www.basepizza.com.au/vouchers/ajax_update_cart.php',
					type: 'POST',
					dataType: 'json',
					data: $(this).serialize (),
					success: api.processJsonResponse
/**
						function (reply) {
						$.each (reply, function (index, value) {
							switch (value[0]) {
								case 'updated' :
/**
									// close the message popover if it's already being shown
									if (messagePopoverApi !== null)
										messagePopoverApi.close ();

									// show the user a message "added"
									var popoverConf = $.extend (true, {}, messagePopoverDefaultConf, {
										attachTo: $form.find ('button'),
										applyArrows: true,
										pointTo: $form.find ('button'),
										closeAfter: 1500
									});

									// show the "added" message
									messagePopoverApi = $.createPopover (
										{	content: 'Added',
											customClass: 'core-popoverLargeFont'
										},
										popoverConf
									).data ('popover');
/** /
									// forward the user to the checkout page
									document.location.href = 'http://www.basepizza.com.au/vouchers/checkout.php';
								break;
							}
						});
					}
/**/
				});

				return false;
			});
		};















		// render the cart,  start it a fresh
		var renderCartSummary = function () {

			// initialise the elements of the cart summary
			$cartTitle = $('<span class="cartTitle">Your Order</span>');

			// the "view summary" link
			if ((conf.allowHide) && (conf.startHidden))
				$viewSummary = $('<div class="viewSummary"><a href="">View</a></viewSummary>');
			else
				$viewSummary = $('<div class="viewSummary"><a href="">Hide</a></viewSummary>');
			$viewSummary.find ('a').bind ('click', function () {
				showHideSummary ();
				return false;
			});

			// the part of the summary that can get hidden
			$cartHideShowBlock = $('<div></div>');
			if ((conf.allowHide) && (conf.startHidden))
				$cartHideShowBlock.hide ();

			$cartContent = $('<div class="cartContent"><div/></div>');	// used to limit the height of the cart (when the cart items get too tall)

			// the message shown when the cart is empty (hide if there are items in the cart)
			$cartEmptyMessage = $('<div class="cartEmpty">There are no items in your cart.</div>');
			if (totalCartItems)
				$cartEmptyMessage.hide ();

			// the cart items - the top section
			$cartItems = $('<div class="cartItems"/>');
			if (conf.allowEdit) {
				$cartItemRowTemplate = $(
					  '<div class="row">'
					+ '	<div class="deleteX"><a href="" class="mapNotMapped_removeFoodItem" title="Remove">Remove</a></div>'
					+ '	<div class="details"/>'
					+ '	<div class="contentEnd"/>'
					+ '</div>');
			}
			else {
				$cartItemRowTemplate = $(
					  '<div class="row">'
					+ '	<div class="details"/>'
					+ '	<div class="contentEnd"/>'
					+ '</div>');
			}
			$namePriceTemplate = $(
				  '<div class="namePrice">'
				+ '	<div class="name"/>'
				+ '	<div class="value"/>'
				+ '	<div class="contentEnd"/>'
				+ '</div>');
			$nameNoPriceTemplate = $('<div class="row nameNoPrice"/>');

			// divider between the top and bottom
			$divider = $('<div class="divider"/>');

			// totals section - the lower section
			$cartTotals = $('<div class="cartTotals"/>');

			$subTotalRow = $(
				  '<div class="row">'
				+ '	<div class="name">Sub-total:</div>'
				+ '	<div class="value"></div>'
				+ '</div>');
			$redeemVoucherRow = $(
				  '<div class="row">'
				+ '	<div class="name">' + conf.redeemVoucherName + '</div>'
				+ '	<div class="value"></div>'
				+ '</div>');
			$totalRow = $(
				  '<div class="row total">'
				+ '	<div class="name">Total Inc GST:</div>'
				+ '	<div class="value"></div>'
				+ '</div>');

			if (conf.redeemVoucherName !== null) {
				$cartTotals.append ($subTotalRow);
				$cartTotals.append ($redeemVoucherRow);
			}
			$cartTotals.append ($totalRow);
			$cartTotals.append ($('<div class="contentEnd"/>'));

//			$checkoutButton = $('<button>Order Now</button>');
			$checkoutButton = $('<input type="image" src="http://www.basepizza.com.au/generated_content/buttons/green/T3JkZXIgTm93.png" />');

			// the quick summary is shown next to the checkout button when the summary is minimised
			$quickSummary = $('<div class="quickSummary"></div>');
			if ((conf.allowHide) && (!conf.startHidden))
				$quickSummary.hide ();




			// reset the cart content
			$cartSummary.html ('');
			$cartSummary.addClass ('shoppingCart box1');
			if (conf.allowEdit)
				$cartSummary.addClass ('shoppingCartEditable');
			if (conf.onBrowsePage)
				$cartSummary.addClass ('shoppingCartMenuPage');

			// put the cart content together (ie. the scrollable area)
			$cartContent.append ($cartEmptyMessage);
			$cartContent.append ($cartItems);

			// put the cart summary together
			$cartHideShowBlock.append ($cartContent);
			$cartHideShowBlock.append ($divider);
			$cartHideShowBlock.append ($cartTotals);

			
			$cartSummary.append ($cartTitle);
			if (conf.allowHide)
				$cartSummary.append ($viewSummary);
			$cartSummary.append ($('<div class="contentEnd"/>'));
			$cartSummary.append ($cartHideShowBlock);
			if (conf.allowHide)
				$cartSummary.append ($quickSummary);
			if (conf.onBrowsePage)
				$cartSummary.append ($checkoutButton);

			// make the cart temporarily think that it's initialising so that the cart items aren't animated when added
			var tempInitialising = initialising;
			initialising = true;

			// add the cart items into the cart summary
			$.each (cartItems, function (index, cartItem) {
				renderCartItem (cartItem);
			});

			// totals
			renderTotals ();
			fixCartWidths ();

			// send the user to the checkout page when they click the "checkout" button
			$checkoutButton.bind ('click', sendUserToCheckout);

			// make sure the cart isn't too tall
//			checkCartHeight ();

			// fix the cart summary to the top of the screen when scrolling down
			if (conf.onBrowsePage)
				$('#cartSummary').coreFixedPos ({ offsetY: 10 });

			initialising = tempInitialising;
			return true;
		};

		// send the user to the checkout page when they click the "checkout" button
		var sendUserToCheckout = function () {
			document.location.href = 'http://www.basepizza.com.au/vouchers/checkout';
			return true;
		};

		// render the given cart item into the $cartSummary
		var renderCartItem = function (cartItem) {

			var $newElement = $cartItemRowTemplate.clone ();

			var $namePrice = createNamePriceRow (cartItem.name, true, cartItem.quantity, true, cartItem.unitPriceNoTax, cartItem.unitPriceWithTax);
			$namePrice.addClass ('foodItem');

			// add the food item details
			$newElement.find ('.details').prepend ($namePrice);

			// let the user remove the item from the cart
			$newElement.find ('.deleteX a').confirmDelete (
			{	message: 'Are you sure you want to remove this item from your order?',
//				confirmButtonText: 'Yes - Remove',
				confirmButtonHtml: '<input type="image" src="http://www.basepizza.com.au/generated_content/buttons/green/WWVzIC0gUmVtb3Zl.png" />',
				cancelButtonHtml: '<input type="image" src="http://www.basepizza.com.au/generated_content/buttons/green/Tm8gLSBDYW5jZWw=.png" />',
				onConfirm: function (popoverApi) {
					popoverApi.close ();
					api.ajax_removeItemFromCart (cartItem.cartItemId);
				},
				width: ((($.browser.msie) && ($.browser.version < 8)) ? 280 : 250),	// add a bit of extra room for <= ie7 because it renders the buttons a bit wider
				applyMask: ((($.browser.msie) && ($.browser.version < 9)) ? true : true)	// msie < 7, 7 and 8 don't seem to render the mask with transparency
			});



			// initialise the row (update it if it already exists)
			var updating = (cartItem.$element !== null);

			if (updating) {
				$newElement.insertAfter (cartItem.$element);
				cartItem.$element.remove ();
				cartItem.$element = $newElement;

				// if the cart has finished initialising,  highlight the new row
				if (!initialising)
					fixCartWidths ();
			}
			else {
				cartItem.$element = $newElement;
				$cartItems.append (cartItem.$element);
				// if the cart has finished initialising,  slide it neatly into view
				if (!initialising) {
					cartItem.$element.show ();
					fixCartWidths ();
					cartItem.$element.hide ();
					cartItem.$element.show ('blind', 'slow');
				}
			}
			return true;
		};

		var createNamePriceRow = function (name, showQuantity, quantity, showPrice, unitPriceNoTax, unitPriceWithTax) {
			var $namePrice = $namePriceTemplate.clone ();

			// set the name
			if (showQuantity)
				$namePrice.find ('.name').text (quantity + ' x ' + name);
			else
				$namePrice.find ('.name').text (name);

			// populate it with values
			if (showPrice) {
				// render the cost including tax
				if (conf.showPricesWithTax) 
					$namePrice.find ('.value').html (getReadablePrice (quantity * unitPriceWithTax, true));
				// render the cost excluding tax
				else
					$namePrice.find ('.value').html (getReadablePrice (quantity * unitPriceNoTax, true));
			}

			return $namePrice;
		};

		// render the total values into the cart summary
		var renderTotals = function () {

			// render the totals including tax
			if (conf.showPricesWithTax) {
				$subTotalRow.find ('.value').html (getReadablePrice (conf.subTotalWithTax, true));
				$redeemVoucherRow.find ('.value').html (getReadablePrice (-conf.redeemVoucherWithTax, true));
				$totalRow.find ('.value').html (getReadablePrice (Math.max (0, conf.subTotalWithTax - conf.redeemVoucherWithTax), true));
				$quickSummary.html ('Total: ' + getReadablePrice (Math.max (0, conf.subTotalWithTax - conf.redeemVoucherWithTax), true));
			}
			// or render the totals excluding tax
			else {
				$subTotalRow.find ('.value').html (getReadablePrice (conf.subTotalNoTax, true));
				$redeemVoucherRow.find ('.value').html (getReadablePrice (-conf.redeemVoucherNoTax, true));
				$totalRow.find ('.value').html (getReadablePrice (Math.max (0, conf.subTotalNoTax - conf.redeemVoucherNoTax), true));
				$quickSummary.html (getReadablePrice (Math.max (0, conf.subTotalNoTax - conf.redeemVoucherNoTax), true));
			}
			return true;
		};

		// show the "There are no items in your cart yet." message if it's empty
		var showCartEmptyMessageIfNecessary = function () {
			if (!totalCartItems)
				$cartEmptyMessage.filter (':hidden').show ('blind');
			else
				$cartEmptyMessage.filter (':visible').hide ('blind');
			return true;
		};

		// match up the widths of the things in the cart summary
		var fixCartWidths = function () {

			// show any hidden parents (that are actually hidden with display=none) so that the button is visible when taking measurements.  they are re-hidden below
			var $hiddenChildren = $cartSummary.find (':hidden').filter (function () {
				return $(this).css ('display') == 'none';
			});
			$hiddenChildren.show ();

			// find the width of the whole row
			var maxWidth = $cartItems.width () - 20 - 4;	// 20 px for the left+right padding around the thing,  and 2 px leeway so that the width of the .name div's aren't very likely to push the .value div's over the edge

			// find the width of the deleteX's
			var deleteXWidth = parseInt ($cartItems.find ('.deleteX:visible').outerWidth ());
			if (isNaN (deleteXWidth))
				deleteXWidth = 0;

			// set the width of the values
			var valuesWidth = matchPriceWidths ($cartSummary.find ('.value:visible'), 45);

			// make sure the food item names fit within the space that's actually available (when they're newly created they take up too much width)
			var newWidth1 = (maxWidth - deleteXWidth - valuesWidth);

			$cartItems.find ('.name').width (newWidth1);

			// set the width of the cart totals' names
			var newWidth2 = (maxWidth - valuesWidth);
			$cartTotals.find ('.name:visible').width (newWidth2);

			// the height of the div.row elements don't pick up the height of their contents for some reason (in ie7/8) (adding contentEnd class doesn't do it)
			// so find out the height of the tallest child element of each and use that as it's height
			var calculateHeight = function () {
				$cartSummary.find ('div.row:visible').map (function () {
					var max = $(this).height (); // start with the height of the element itself
					$(this).children ().map (function () { if (max < $(this).height ()) max = $(this).height (); }); // and find out if any children are taller (for some reason)
					$(this).height (max);
				});
			}
			calculateHeight ();
			setTimeout (calculateHeight, 400);

			$hiddenChildren.hide ();

			return true;
		};

		// find the largest width of the given elements and slide them to that width
		var matchPriceWidths = function ($elements, minWidth) {

			var $elements = $($elements);
			if (!$elements.length)
				return 0;

			// a function to match the elements
			var newMax = null;
			var match = function () {

				// match the element's widths
				var myMax = null;
				$elements.each (function () {
					var origWidth = $(this).width ();
					$(this).css ({ width: 'auto' });
					if ((myMax === null) || ($(this).outerWidth () > myMax))
						myMax = $(this).outerWidth ();
					$(this).width (origWidth);
				});

				// apply the minimum width
				newMax = myMax;
				if ((minWidth !== undefined) && (newMax < minWidth))
					newMax = minWidth;

				$elements.map (function () {

					var currentWidth = $(this).width ();
					var newWidth = newMax - ($(this).outerWidth () - currentWidth);	// 
					$(this).width (newWidth);
				});
			}

			match ();
//			$().ready (match);
//			$('img').load (match);

			return newMax;
		};





		// remove the cart item from the $cartSummary
		var visuallyRemoveCartItem = function (cartItem) {

			// initialise the row (remove it if it already exists)
			if (cartItem.$element) {
				// if the cart is still initialising then simply remove the food item from the list
				if (initialising)
					cartItem.$element.remove ();
				// or slide it neatly out of  view
				else {
					cartItem.$element.hide ();
					fixCartWidths ();
					cartItem.$element.show ().hide ('blind', {}, 'slow', function () { cartItem.$element.remove (); });
				}
			}
			return true;
		};

		// show or hide the summary ("minimise" or "maximise" it)
		var showHideSummary = function () {
			if (showingSummary) {
				$cartHideShowBlock.stop ().hide ('blind');
				$quickSummary.stop ().show ('blind');
				$viewSummary.find ('a').html ('View');
				showingSummary = false;
			}
			else {
				$cartHideShowBlock.stop ().show ('blind');
				$quickSummary.stop ().hide ('blind');
				$viewSummary.find ('a').html ('Hide');
				showingSummary = true;
			}
			return true;
		};













		// repeat the given string 'times' number of times
		var repeatString = function (string, times) {
			var returnVal = '';
			for (var count = 0; count < times; count ++)
				returnVal += string;
			return returnVal;
		};

		// render the given price in a readable format
		var getReadablePrice = function (amount, forceDecimals) {

			// work out what the price should be (show it to 2 dec.pl if the number isn't whole,  or forceDecimals is true)
			var negative = (amount < 0);
			amount = Math.abs (amount);
			var displayAmount = amount.toFixed (0);
			var tempDisplayAmount1 = displayAmount + '.' + repeatString ('0', conf.currencyDecPl).replace ('.', conf.currencyDecimalDelimiter);
			var tempDisplayAmount2 = amount.toFixed (conf.currencyDecPl).replace ('.', conf.currencyDecimalDelimiter);
			if ((forceDecimals) || (tempDisplayAmount1 != tempDisplayAmount2))
				displayAmount = tempDisplayAmount2;

			// render it with the negative symbol if needed and with the currency symbol on the correct side
			if (conf.currencySymbolIsPrefix)
				return (negative ? '-' : '') + conf.currencySymbol + displayAmount;
			return (negative ? '-' : '') + displayAmount + conf.currencySymbol;
		};









/**
		// assign the callbacks
		var assignCallbacks = function () {

			$.each (['onBeforeAddCartItem', 'onAfterAddCartItem'], function (i, name) {

				// configuration
				if ($.isFunction (conf[name]))
					$cartSummary.bind (name, conf[name]);

				// API
				$cartSummary[name] = function (fn) {
					$cartSummary.bind (name, fn);
					return $cartSummary;
				};
			});

			return true;
		}
/**/
		// initialise
		return api.init ();
	}

	// 
	$.fn.voucherShoppingCart = function (conf) {

		conf = $.extend (true, {}, $.menulog.voucherShoppingCart.conf, conf);

		this.each (function () {
			var $this = $(this);

			// only apply coreTransformInput to this element if it hasn't already been applied
			if (!$this.data ('voucherShoppingCart')) {
				var api = new voucherShoppingCart ($this, conf);
				$this.data ('voucherShoppingCart', api);
			}
		});

		return $(this);
	};

}) (jQuery);









/*///////////////////////////////////////////////
// path: /javascript/front/google_analytics.js //
// created: Thu, 27 Oct 2011 14:10:47 +1100    //
// modified: Tue, 25 Oct 2011 09:52:20 +1100   //
// size: 2271 bytes                            //
///////////////////////////////////////////////*/

// BEFORE the dom has loaded
(function($) {

	// include the google analytics code
	var gaJsHost = (('https:' == document.location.protocol) ? 'https://ssl.' : 'http://www.');
	document.write (unescape ("%3Cscript src=\'" + gaJsHost + "google-analytics.com/ga.js\' type=\'text/javascript\'%3E%3C/script%3E"));

	analytics_trackPageview = function (url) {
		// track this page view
		try {
            var pageTracker = _gat._getTracker ('UA-698294-1');
			pageTracker._trackPageview (url);
		}
		catch (err) {};
		return true;
	};
    analytics_trackEvent = function(options) {
        var acceptedArgs = ['category', 'action', 'opt_label', 'opt_value', 'opt_noninteraction'];
        var argsToBePassed = {opt_label: null, opt_value: null, opt_noninteraction : true};
        for (var i = 0; i < 5; i++) {
            if(typeof options[acceptedArgs[i]] !== "undefined") {
                argsToBePassed[acceptedArgs[i]] = options[acceptedArgs[i]];
            }
        }
        try {
            var pageTracker = _gat._getTracker ('UA-698294-1');
            pageTracker._trackEvent(argsToBePassed['category'], argsToBePassed['action'], argsToBePassed['opt_label'], argsToBePassed['opt_value'], argsToBePassed['opt_noninteraction']);
        } catch(err) {};
        return true;
    };

}) (jQuery);










/*/////////////////////////////////////////////
// path: /javascript/front/yahoo.js          //
// created: Mon, 26 Sep 2011 14:02:01 +1000  //
// modified: Mon, 12 Sep 2011 15:10:17 +1000 //
// size: 4324 bytes                          //
/////////////////////////////////////////////*/

// initialisation BEFORE the dom has loaded
(function($) {

	var renderedYahooDiningHeaderFooterNavs = false;
	var renderedYahooHeaderBanner = false;
	var renderedYahooFooterBanner = false;
	var renderedYahooBoxBanner = false;

	renderYahooElements = function (siteSection, forceReload) {

		if (siteSection == 'dining') {

			// header/footer navs
			if (((!renderedYahooDiningHeaderFooterNavs) || (forceReload)) && ($('#diningPage').length)) {

				// re-render the header each time
				$('#yahooHeaderBarDining').html ('<iframe src=\"http://au.adserver.yahoo.com/a?f=2145049466&p=aulifmenul&l=HEAD&c=sh&bg=ffffff\" marginwidth=\"0\" marginheight=\"0\" width=\"1000\" height=\"33\" hspace=\"0\" vspace=\"0\" frameBorder=\"0\" scrolling=\"no\"></iframe>\n');
				$('#yahooHeaderBarVouchers').html ('<iframe src=\"http://au.adserver.yahoo.com/a?f=2145049467&p=aulifmenul&l=HEAD&c=sh&bg=ffffff\" marginwidth=\"0\" marginheight=\"0\" width=\"1000\" height=\"33\" hspace=\"0\" vspace=\"0\" frameBorder=\"0\" scrolling=\"no\"></iframe>\n');

				// only render the footer the first time
				if (!renderedYahooDiningHeaderFooterNavs) {
					$('#yahooFooterBarDining').html ('<iframe src=\"http://au.adserver.yahoo.com/a?f=2145049466&p=aulifmenul&l=FOOT&c=h&bg=ffffff\" marginwidth=\"0\" marginheight=\"0\" width=\"1000\" height=\"75\" hspace=\"0\" vspace=\"0\" frameBorder=\"0\" scrolling=\"no\"></iframe>\n');
					$('#yahooFooterBarVouchers').html ('<iframe src=\"http://au.adserver.yahoo.com/a?f=2145049467&p=aulifmenul&l=FOOT&c=h&bg=ffffff\" marginwidth=\"0\" marginheight=\"0\" width=\"1000\" height=\"75\" hspace=\"0\" vspace=\"0\" frameBorder=\"0\" scrolling=\"no\"></iframe>\n');
				}
				renderedYahooDiningHeaderFooterNavs = true;
			}

			// header banner
			if ((!renderedYahooHeaderBanner) || (forceReload)) {

				if ($('#yahooHeaderBannerDining').length) {
					renderedYahooHeaderBanner = true;
					$('#yahooHeaderBannerDining').html ('<iframe src=\"http://www.basepizza.com.au/banners/yahoo_banner.php?bannerType=headerBanner&c=sh&yahooSpaceId=2145049466&yahooPropertyName=aulifmenul\" width=\"728\" height=\"90\" marginwidth=\"0\" marginheight=\"0\" hspace=\"0\" vspace=\"0\" frameBorder=\"0\" scrolling=\"no\"></iframe>');
				}
				else if ($('#yahooHeaderBannerVouchers').length) {
					renderedYahooHeaderBanner = true;
					$('#yahooHeaderBannerVouchers').html ('<iframe src=\"http://www.basepizza.com.au/banners/yahoo_banner.php?bannerType=headerBanner&c=sh&yahooSpaceId=2145049467&yahooPropertyName=aulifmenul\" width=\"728\" height=\"90\" marginwidth=\"0\" marginheight=\"0\" hspace=\"0\" vspace=\"0\" frameBorder=\"0\" scrolling=\"no\"></iframe>');
				}
			}

			// footer banner
			if ((!renderedYahooFooterBanner) || (forceReload)) {

				if ($('#yahooFooterBannerDining').length) {
					renderedYahooFooterBanner = true;
					$('#yahooFooterBannerDining').html ('<iframe src=\"http://www.basepizza.com.au/banners/yahoo_banner.php?bannerType=footerBanner&c=sh&yahooSpaceId=2145049466&yahooPropertyName=aulifmenul\" width=\"728\" height=\"90\" marginwidth=\"0\" marginheight=\"0\" hspace=\"0\" vspace=\"0\" frameBorder=\"0\" scrolling=\"no\"></iframe>');
				}
				else if ($('#yahooFooterBannerVouchers').length) {
					renderedYahooFooterBanner = true;
					$('#yahooFooterBannerVouchers').html ('<iframe src=\"http://www.basepizza.com.au/banners/yahoo_banner.php?bannerType=footerBanner&c=sh&yahooSpaceId=2145049467&yahooPropertyName=aulifmenul\" width=\"728\" height=\"90\" marginwidth=\"0\" marginheight=\"0\" hspace=\"0\" vspace=\"0\" frameBorder=\"0\" scrolling=\"no\"></iframe>');
				}
			}

			// box banner
			if ((!renderedYahooBoxBanner) || (forceReload)) {

				if ($('#yahooBoxBannerDining').length) {
					renderedYahooBoxBanner = true;
					$('#yahooBoxBannerDining').html ('<iframe src=\"http://www.basepizza.com.au/banners/yahoo_banner.php?bannerType=boxBanner&c=sh&yahooSpaceId=2145049466&yahooPropertyName=aulifmenul\" width=\"300\" height=\"264\" marginwidth=\"0\" marginheight=\"0\" hspace=\"0\" vspace=\"0\" frameBorder=\"0\" scrolling=\"no\"></iframe>');
				}
				else if ($('#yahooBoxBannerVouchers').length) {
					renderedYahooBoxBanner = true;
					$('#yahooBoxBannerVouchers').html ('<iframe src=\"http://www.basepizza.com.au/banners/yahoo_banner.php?bannerType=boxBanner&c=sh&yahooSpaceId=2145049467&yahooPropertyName=aulifmenul\" width=\"300\" height=\"264\" marginwidth=\"0\" marginheight=\"0\" hspace=\"0\" vspace=\"0\" frameBorder=\"0\" scrolling=\"no\"></iframe>');
				}
			}
		}
		return true;
	};

	// load the neilson tracking pixel (yahoo)
	var loadedNeilsonTrackingPixel = false;
	loadNeilsonTrackingPixel = function (forceReload) {
		if ((!loadedNeilsonTrackingPixel) || (forceReload)) {
			var _rsCI = 'yahoo-au';
			var _rsCG = '0';
			var _rsIMG = new Image (1,1);
			_rsIMG.src = '//secure-au.imrworldwide.com/cgi-bin/m?rnd=' + (new Date()).getTime() + '&ci=' + _rsCI + '&cg=' + _rsCG + '&si=' + escape(window.location.href) + '&rp=' + escape(document.referrer) + '&cc=1';
			loadedNeilsonTrackingPixel = true;
		}
	};

}) (jQuery);









/*//////////////////////////////////////////////////////
// path: /javascript/front/jquery.mCustomScrollbar.js //
// created: Mon, 26 Sep 2011 14:02:01 +1000           //
// modified: Mon, 12 Sep 2011 15:10:17 +1000          //
// size: 12566 bytes                                  //
//////////////////////////////////////////////////////*/

/* malihu custom scrollbar plugin - http://manos.malihu.gr */
(function ($) {
$.fn.mCustomScrollbar = function (scrollType,animSpeed,easeType,bottomSpace,draggerDimType,mouseWheelSupport,scrollBtnsSupport,scrollBtnsSpeed){

	var $this = $(this);
	$this.addClass ('mcs');
	var $customScrollBox= $this.find (".customScrollBox");
	var $customScrollBox_container=$this.find (".customScrollBox .container");
	var $customScrollBox_content=$this.find (".customScrollBox .content");
	var $dragger_container=$this.find(".dragger_container");
	$dragger_container.height ($(this).outerHeight ());
	var $dragger=$this.find(".dragger");
	var $scrollUpBtn=$this.find(".scrollUpBtn");
	var $scrollDownBtn=$this.find(".scrollDownBtn");
	var $customScrollBox_horWrapper=$this.find(".customScrollBox .horWrapper");
	
	//get & store minimum dragger height & width (defined in css)
	if(!$customScrollBox.data("minDraggerHeight")){
		$customScrollBox.data("minDraggerHeight",$dragger.height());
	}
	if(!$customScrollBox.data("minDraggerWidth")){
		$customScrollBox.data("minDraggerWidth",$dragger.width());
	}
	
	//get & store original content height & width
	if(!$customScrollBox.data("contentHeight")){
		$customScrollBox.data("contentHeight",$customScrollBox_container.height());
	}
	if(!$customScrollBox.data("contentWidth")){
		$customScrollBox.data("contentWidth",$customScrollBox_container.width());
	}
	
	CustomScroller();
	
	function CustomScroller(reloadType){
		//horizontal scrolling ------------------------------
		if(scrollType=="horizontal"){
			var visibleWidth=$customScrollBox.width();
			//set content width automatically
			$customScrollBox_horWrapper.css("width",999999); //set a rediculously high width value ;)
			$customScrollBox.data("totalContent",$customScrollBox_container.width()); //get inline div width
			$customScrollBox_horWrapper.css("width",$customScrollBox.data("totalContent")); //set back the proper content width value
			
			if($customScrollBox_container.width()>visibleWidth){ //enable scrollbar if content is long
				$dragger.css("display","block");
				if(reloadType!="resize" && $customScrollBox_container.width()!=$customScrollBox.data("contentWidth")){
					$dragger.css("left",0);
					$customScrollBox_container.css("left",0);
					$customScrollBox.data("contentWidth",$customScrollBox_container.width());
				}
				$dragger_container.css("display","block");
				$scrollDownBtn.css("display","inline-block");
				$scrollUpBtn.css("display","inline-block");
				var totalContent=$customScrollBox_content.width();
				var minDraggerWidth=$customScrollBox.data("minDraggerWidth");
				var draggerContainerWidth=$dragger_container.width();
		
				function AdjustDraggerWidth(){
					if(draggerDimType=="auto"){
						var adjDraggerWidth=Math.round(totalContent-((totalContent-visibleWidth)*1.3)); //adjust dragger width analogous to content
						if(adjDraggerWidth<=minDraggerWidth){ //minimum dragger width
							$dragger.css("width",minDraggerWidth+"px");
						} else if(adjDraggerWidth>=draggerContainerWidth){
							$dragger.css("width",draggerContainerWidth-10+"px");
						} else {
							$dragger.css("width",adjDraggerWidth+"px");
						}
					}
				}
				AdjustDraggerWidth();
		
				var targX=0;
				var draggerWidth=$dragger.width();
				$dragger.draggable({ 
					axis: "x", 
					containment: "parent", 
					drag: function(event, ui) {
						ScrollX();
					}, 
					stop: function(event, ui) {
						DraggerRelease();
					}
				});
			
				$dragger_container.click(function(e) {
					var $this=$(this);
					var mouseCoord=(e.pageX - $this.offset().left);
					if(mouseCoord<$dragger.position().left || mouseCoord>($dragger.position().left+$dragger.width())){
						var targetPos=mouseCoord+$dragger.width();
						if(targetPos<$dragger_container.width()){
							$dragger.css("left",mouseCoord);
							ScrollX();
						} else {
							$dragger.css("left",$dragger_container.width()-$dragger.width());
							ScrollX();
						}
					}
				});

				//mousewheel
				$(function($) {
					if(mouseWheelSupport=="yes"){
						$customScrollBox.unbind("mousewheel");
						$customScrollBox.bind("mousewheel", function(event, delta) {
							var vel = Math.abs(delta*10);
							$dragger.css("left", $dragger.position().left-(delta*vel));
							ScrollX();
							if($dragger.position().left<0){
								$dragger.css("left", 0);
								$customScrollBox_container.stop();
								ScrollX();
							}
							if($dragger.position().left>$dragger_container.width()-$dragger.width()){
								$dragger.css("left", $dragger_container.width()-$dragger.width());
								$customScrollBox_container.stop();
								ScrollX();
							}
							return false;
						});
					}
				});
				
				//scroll buttons
				if(scrollBtnsSupport=="yes"){
					$scrollDownBtn.mouseup(function(){
						BtnsScrollXStop();
					}).mousedown(function(){
						BtnsScrollX("down");
					}).mouseout(function(){
						BtnsScrollXStop();
					});
				
					$scrollUpBtn.mouseup(function(){
						BtnsScrollXStop();
					}).mousedown(function(){
						BtnsScrollX("up");
					}).mouseout(function(){
						BtnsScrollXStop();
					});
				
					$scrollDownBtn.click(function(e) {
						e.preventDefault();
					});
					$scrollUpBtn.click(function(e) {
						e.preventDefault();
					});
				
					btnsScrollTimerX=0;
				
					function BtnsScrollX(dir){
						if(dir=="down"){
							var btnsScrollTo=$dragger_container.width()-$dragger.width();
							var scrollSpeed=Math.abs($dragger.position().left-btnsScrollTo)*(100/scrollBtnsSpeed);
							$dragger.stop().animate({left: btnsScrollTo}, scrollSpeed,"linear");
						} else {
							var btnsScrollTo=0;
							var scrollSpeed=Math.abs($dragger.position().left-btnsScrollTo)*(100/scrollBtnsSpeed);
							$dragger.stop().animate({left: -btnsScrollTo}, scrollSpeed,"linear");
						}
						clearInterval(btnsScrollTimerX);
						btnsScrollTimerX = setInterval( ScrollX, 20);
					}
				
					function BtnsScrollXStop(){
						clearInterval(btnsScrollTimerX);
						$dragger.stop();
					}
				}

				//scroll
				var scrollAmount=(totalContent-visibleWidth)/(draggerContainerWidth-draggerWidth);
				function ScrollX(){
					var draggerX=$dragger.position().left;
					var targX=-draggerX*scrollAmount;
					var thePos=$customScrollBox_container.position().left-targX;
					$customScrollBox_container.stop().animate({left: "-="+thePos}, animSpeed, easeType);
				}
			} else { //disable scrollbar if content is short
				$dragger.css("left",0).css("display","none"); //reset content scroll
				$customScrollBox_container.css("left",0);
				$dragger_container.css("display","none");
				$scrollDownBtn.css("display","none");
				$scrollUpBtn.css("display","none");
			}
		//vertical scrolling ------------------------------
		} else {
			var visibleHeight=$customScrollBox.height();
			if($customScrollBox_container.height()>visibleHeight){ //enable scrollbar if content is long
				$dragger.css("display","block");
				if(reloadType!="resize" && $customScrollBox_container.height()!=$customScrollBox.data("contentHeight")){
					$dragger.css("top",0);
					$customScrollBox_container.css("top",0);
					$customScrollBox.data("contentHeight",$customScrollBox_container.height());
				}
				$dragger_container.css("display","block");
				$scrollDownBtn.css("display","inline-block");
				$scrollUpBtn.css("display","inline-block");
				var totalContent=$customScrollBox_content.height();
				var minDraggerHeight=$customScrollBox.data("minDraggerHeight");
				var draggerContainerHeight=$dragger_container.height();
		
				function AdjustDraggerHeight(){
					if(draggerDimType=="auto"){
						var adjDraggerHeight=Math.round(totalContent-((totalContent-visibleHeight)*1.3)); //adjust dragger height analogous to content
						if(adjDraggerHeight<=minDraggerHeight){ //minimum dragger height
							$dragger.css("height",minDraggerHeight+"px").css("line-height",minDraggerHeight+"px");
						} else if(adjDraggerHeight>=draggerContainerHeight){
							$dragger.css("height",draggerContainerHeight-10+"px").css("line-height",draggerContainerHeight-10+"px");
						} else {
							$dragger.css("height",adjDraggerHeight+"px").css("line-height",adjDraggerHeight+"px");
						}
					}
				}
				AdjustDraggerHeight();
		
				var targY=0;
				var draggerHeight=$dragger.height();
				$dragger.draggable({ 
					axis: "y", 
					containment: "parent", 
					drag: function(event, ui) {
						Scroll();
					}, 
					stop: function(event, ui) {
						DraggerRelease();
					}
				});
				
				$dragger_container.click(function(e) {
					var $this=$(this);
					var mouseCoord=(e.pageY - $this.offset().top);
					if(mouseCoord<$dragger.position().top || mouseCoord>($dragger.position().top+$dragger.height())){
						var targetPos=mouseCoord+$dragger.height();
						if(targetPos<$dragger_container.height()){
							$dragger.css("top",mouseCoord);
							Scroll();
						} else {
							$dragger.css("top",$dragger_container.height()-$dragger.height());
							Scroll();
						}
					}
				});

				//mousewheel
				$(function($) {
					if(mouseWheelSupport=="yes"){
						$customScrollBox.unbind("mousewheel");
						$customScrollBox.bind("mousewheel", function(event, delta) {
							var vel = Math.abs(delta*10);
							$dragger.css("top", $dragger.position().top-(delta*vel));
							Scroll();
							if($dragger.position().top<0){
								$dragger.css("top", 0);
								$customScrollBox_container.stop();
								Scroll();
							}
							if($dragger.position().top>$dragger_container.height()-$dragger.height()){
								$dragger.css("top", $dragger_container.height()-$dragger.height());
								$customScrollBox_container.stop();
								Scroll();
							}
							return false;
						});
					}
				});

				//scroll buttons
				if(scrollBtnsSupport=="yes"){
					$scrollDownBtn.mouseup(function(){
						BtnsScrollStop();
					}).mousedown(function(){
						BtnsScroll("down");
					}).mouseout(function(){
						BtnsScrollStop();
					});
				
					$scrollUpBtn.mouseup(function(){
						BtnsScrollStop();
					}).mousedown(function(){
						BtnsScroll("up");
					}).mouseout(function(){
						BtnsScrollStop();
					});
				
					$scrollDownBtn.click(function(e) {
						e.preventDefault();
					});
					$scrollUpBtn.click(function(e) {
						e.preventDefault();
					});
				
					btnsScrollTimer=0;
				
					function BtnsScroll(dir){
						if(dir=="down"){
							var btnsScrollTo=$dragger_container.height()-$dragger.height();
							var scrollSpeed=Math.abs($dragger.position().top-btnsScrollTo)*(100/scrollBtnsSpeed);
							$dragger.stop().animate({top: btnsScrollTo}, scrollSpeed,"linear");
						} else {
							var btnsScrollTo=0;
							var scrollSpeed=Math.abs($dragger.position().top-btnsScrollTo)*(100/scrollBtnsSpeed);
							$dragger.stop().animate({top: -btnsScrollTo}, scrollSpeed,"linear");
						}
						clearInterval(btnsScrollTimer);
						btnsScrollTimer = setInterval( Scroll, 20);
					}
				
					function BtnsScrollStop(){
						clearInterval(btnsScrollTimer);
						$dragger.stop();
					}
				}
				
				//scroll
				if(bottomSpace<1){
					bottomSpace=1; //minimum bottomSpace value is 1
				}
				var scrollAmount=(totalContent-(visibleHeight/bottomSpace))/(draggerContainerHeight-draggerHeight);
				function Scroll(){
					var draggerY=$dragger.position().top;
					var targY=-draggerY*scrollAmount;
					var thePos=$customScrollBox_container.position().top-targY;
					$customScrollBox_container.stop().animate({top: "-="+thePos}, animSpeed, easeType);
				}
			} else { //disable scrollbar if content is short
				$dragger.css("top",0).css("display","none"); //reset content scroll
				$customScrollBox_container.css("top",0);
				$dragger_container.css("display","none");
				$scrollDownBtn.css("display","none");
				$scrollUpBtn.css("display","none");
			}
		}
		
		$dragger.mouseup(function(){
			DraggerRelease();
		}).mousedown(function(){
			DraggerPress();
		});

		function DraggerPress(){
			$dragger.addClass("dragger_pressed");
		}

		function DraggerRelease(){
			$dragger.removeClass("dragger_pressed");
		}
	}
	
	$(window).resize(function() {
		if(scrollType=="horizontal"){
			if($dragger.position().left>$dragger_container.width()-$dragger.width()){
				$dragger.css("left", $dragger_container.width()-$dragger.width());
			}
		} else {
			if($dragger.position().top>$dragger_container.height()-$dragger.height()){
				$dragger.css("top", $dragger_container.height()-$dragger.height());
			}
		}
		CustomScroller("resize");
	});
};  
})(jQuery);









/*////////////////////////////////////////////////////
// path: /javascript/front/jquery.mousewheel.min.js //
// created: Mon, 26 Sep 2011 14:02:01 +1000         //
// modified: Mon, 12 Sep 2011 15:10:17 +1000        //
// size: 1172 bytes                                 //
////////////////////////////////////////////////////*/

/* Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
 *
 * Version: 3.0.2
 * 
 * Requires: 1.2.2+
 */
(function(c){var a=["DOMMouseScroll","mousewheel"];c.event.special.mousewheel={setup:function(){if(this.addEventListener){for(var d=a.length;d;){this.addEventListener(a[--d],b,false)}}else{this.onmousewheel=b}},teardown:function(){if(this.removeEventListener){for(var d=a.length;d;){this.removeEventListener(a[--d],b,false)}}else{this.onmousewheel=null}}};c.fn.extend({mousewheel:function(d){return d?this.bind("mousewheel",d):this.trigger("mousewheel")},unmousewheel:function(d){return this.unbind("mousewheel",d)}});function b(f){var d=[].slice.call(arguments,1),g=0,e=true;f=c.event.fix(f||window.event);f.type="mousewheel";if(f.wheelDelta){g=f.wheelDelta/120}if(f.detail){g=-f.detail/3}d.unshift(f,g);return c.event.handle.apply(this,d)}})(jQuery);









/*/////////////////////////////////////////////
// path: /javascript/front/jquery.cluetip.js //
// created: Wed, 05 Oct 2011 10:53:05 +1100  //
// modified: Tue, 04 Oct 2011 10:05:11 +1100 //
// size: 23949 bytes                         //
/////////////////////////////////////////////*/

/*
 * jQuery clueTip plugin
 * Version 1.0.7  (January 28, 2010)
 * @requires jQuery v1.3+
 *
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */
 
/*
 *
 * Full list of options/settings can be found at the bottom of this file and at http://plugins.learningjquery.com/cluetip/
 *
 * Examples can be found at http://plugins.learningjquery.com/cluetip/demo/
 *
*/

;(function($) { 
  $.cluetip = {version: '1.0.6'};
  var $cluetip, $cluetipInner, $cluetipOuter, $cluetipTitle, $cluetipArrows, $cluetipWait, $dropShadow, imgCount;
  
  $.fn.cluetip = function(js, options) {
    if (typeof js == 'object') {
      options = js;
      js = null;
    }
    if (js == 'destroy') {
      return this.removeData('thisInfo').unbind('.cluetip');
    }
    return this.each(function(index) {
      var link = this, $this = $(this);
      
      // support metadata plugin (v1.0 and 2.0)
      var opts = $.extend(true, {}, $.fn.cluetip.defaults, options || {}, $.metadata ? $this.metadata() : $.meta ? $this.data() : {});

      // start out with no contents (for ajax activation)
      var cluetipContents = false;
      var cluezIndex = +opts.cluezIndex;
      $this.data('thisInfo', {title: link.title, zIndex: cluezIndex});
      var isActive = false, closeOnDelay = 0;

      // create the cluetip divs
      if (!$('#cluetip').length) {
        $(['<div id="cluetip">',
          '<div id="cluetip-outer">',
            '<h3 id="cluetip-title"></h3>',
            '<div id="cluetip-inner"></div>',
          '</div>',
          '<div id="cluetip-extra"></div>',
          '<div id="cluetip-arrows" class="cluetip-arrows"></div>',
        '</div>'].join(''))
        [insertionType](insertionElement).hide();
        
        $cluetip = $('#cluetip').css({position: 'absolute'});
        $cluetipOuter = $('#cluetip-outer').css({position: 'relative', zIndex: cluezIndex});
        $cluetipInner = $('#cluetip-inner');
        $cluetipTitle = $('#cluetip-title');        
        $cluetipArrows = $('#cluetip-arrows');
        $cluetipWait = $('<div id="cluetip-waitimage"></div>')
          .css({position: 'absolute'}).insertBefore($cluetip).hide();
      }
      var dropShadowSteps = (opts.dropShadow) ? +opts.dropShadowSteps : 0;
      if (!$dropShadow) {
        $dropShadow = $([]);
        for (var i=0; i < dropShadowSteps; i++) {
          $dropShadow = $dropShadow.add($('<div></div>').css({zIndex: cluezIndex-1, opacity:.1, top: 1+i, left: 1+i}));
        }
        $dropShadow.css({position: 'absolute', backgroundColor: '#000'})
        .prependTo($cluetip);
      }
      var tipAttribute = $this.attr(opts.attribute), ctClass = opts.cluetipClass;
      if (!tipAttribute && !opts.splitTitle && !js) {
        return true;
      }
      // if hideLocal is set to true, on DOM ready hide the local content that will be displayed in the clueTip
      if (opts.local && opts.localPrefix) {tipAttribute = opts.localPrefix + tipAttribute;}
      if (opts.local && opts.hideLocal) { $(tipAttribute + ':first').hide(); }
      var tOffset = parseInt(opts.topOffset, 10), lOffset = parseInt(opts.leftOffset, 10);
      // vertical measurement variables
      var tipHeight, wHeight,
          defHeight = isNaN(parseInt(opts.height, 10)) ? 'auto' : (/\D/g).test(opts.height) ? opts.height : opts.height + 'px';
      var sTop, linkTop, posY, tipY, mouseY, baseline;
      // horizontal measurement variables
      var tipInnerWidth = parseInt(opts.width, 10) || 275,
          tipWidth = tipInnerWidth + (parseInt($cluetip.css('paddingLeft'),10)||0) + (parseInt($cluetip.css('paddingRight'),10)||0) + dropShadowSteps,
          linkWidth = this.offsetWidth,
          linkLeft, posX, tipX, mouseX, winWidth;
            
      // parse the title
      var tipParts;
      var tipTitle = (opts.attribute != 'title') ? $this.attr(opts.titleAttribute) : '';
      if (opts.splitTitle) {
        if (tipTitle == undefined) {tipTitle = '';}
        tipParts = tipTitle.split(opts.splitTitle);
        tipTitle = tipParts.shift();
      }
      if (opts.escapeTitle) {
        tipTitle = tipTitle.replace(/&/g,'&amp;').replace(/>/g,'&gt;').replace(/</g,'&lt;');
      }
      
      var localContent;
      function returnFalse() { return false; }

/***************************************      
* ACTIVATION
****************************************/
    
//activate clueTip
    var activate = function(event) {
      if (!opts.onActivate($this)) {
        return false;
      }
      isActive = true;
      $cluetip.removeClass().css({width: tipInnerWidth});
      if (tipAttribute == $this.attr('href')) {
        $this.css('cursor', opts.cursor);
      }
      if (opts.hoverClass) {
        $this.addClass(opts.hoverClass);
      }
      linkTop = posY = $this.offset().top;
      linkLeft = $this.offset().left;
      mouseX = event.pageX;
      mouseY = event.pageY;
      if (link.tagName.toLowerCase() != 'area') {
        sTop = $(document).scrollTop();
        winWidth = $(window).width();
      }
// position clueTip horizontally
      if (opts.positionBy == 'fixed') {
        posX = linkWidth + linkLeft + lOffset;
        $cluetip.css({left: posX});
      } else {
        posX = (linkWidth > linkLeft && linkLeft > tipWidth)
          || linkLeft + linkWidth + tipWidth + lOffset > winWidth 
          ? linkLeft - tipWidth - lOffset 
          : linkWidth + linkLeft + lOffset;
        if (link.tagName.toLowerCase() == 'area' || opts.positionBy == 'mouse' || linkWidth + tipWidth > winWidth) { // position by mouse
          if (mouseX + 20 + tipWidth > winWidth) {  
            $cluetip.addClass(' cluetip-' + ctClass);
            posX = (mouseX - tipWidth - lOffset) >= 0 ? mouseX - tipWidth - lOffset - parseInt($cluetip.css('marginLeft'),10) + parseInt($cluetipInner.css('marginRight'),10) :  mouseX - (tipWidth/2);
          } else {
            posX = mouseX + lOffset;
          }
        }
        var pY = posX < 0 ? event.pageY + tOffset : event.pageY;
        $cluetip.css({
          left: (posX > 0 && opts.positionBy != 'bottomTop') ? posX : (mouseX + (tipWidth/2) > winWidth) ? winWidth/2 - tipWidth/2 : Math.max(mouseX - (tipWidth/2),0),
          zIndex: $this.data('thisInfo').zIndex
        });
        $cluetipArrows.css({zIndex: $this.data('thisInfo').zIndex+1});
      }
        wHeight = $(window).height();

/***************************************
* load a string from cluetip method's first argument
***************************************/
      if (js) {
        if (typeof js == 'function') {
          js = js.call(link);
        }
        $cluetipInner.html(js);
        cluetipShow(pY);
      }
/***************************************
* load the title attribute only (or user-selected attribute). 
* clueTip title is the string before the first delimiter
* subsequent delimiters place clueTip body text on separate lines
***************************************/

      else if (tipParts) {
        var tpl = tipParts.length;
        $cluetipInner.html(tpl ? tipParts[0] : '');
        if (tpl > 1) {
          for (var i=1; i < tpl; i++){
            $cluetipInner.append('<div class="split-body">' + tipParts[i] + '</div>');
          }          
        }
        cluetipShow(pY);
      }
/***************************************
* load external file via ajax          
***************************************/

      else if (!opts.local && tipAttribute.indexOf('#') !== 0) {
        if (/\.(jpe?g|tiff?|gif|png)$/i.test(tipAttribute)) {
          $cluetipInner.html('<img src="' + tipAttribute + '" alt="' + tipTitle + '" />');
          cluetipShow(pY);
        } else if (cluetipContents && opts.ajaxCache) {
          $cluetipInner.html(cluetipContents);
          cluetipShow(pY);
        } else {
          var optionBeforeSend = opts.ajaxSettings.beforeSend,
              optionError = opts.ajaxSettings.error,
              optionSuccess = opts.ajaxSettings.success,
              optionComplete = opts.ajaxSettings.complete;
          var ajaxSettings = {
            cache: false, // force requested page not to be cached by browser
            url: tipAttribute,
            beforeSend: function(xhr) {
              if (optionBeforeSend) {optionBeforeSend.call(link, xhr, $cluetip, $cluetipInner);}
              $cluetipOuter.children().empty();
              if (opts.waitImage) {
                $cluetipWait
                .css({top: mouseY+20, left: mouseX+20, zIndex: $this.data('thisInfo').zIndex-1})
                .show();
              }
            },
            error: function(xhr, textStatus) {
              if (isActive) {
                if (optionError) {
                  optionError.call(link, xhr, textStatus, $cluetip, $cluetipInner);
                } else {
                  $cluetipInner.html('<i>sorry, the contents could not be loaded</i>');  
                }
              }
            },
            success: function(data, textStatus) {       
              cluetipContents = opts.ajaxProcess.call(link, data);
              if (isActive) {
                if (optionSuccess) {optionSuccess.call(link, data, textStatus, $cluetip, $cluetipInner);}
                $cluetipInner.html(cluetipContents);
              }
            },
            complete: function(xhr, textStatus) {
              if (optionComplete) {optionComplete.call(link, xhr, textStatus, $cluetip, $cluetipInner);}
              var imgs = $cluetipInner[0].getElementsByTagName('img');
              imgCount = imgs.length;
              for (var i=0, l = imgs.length; i < l; i++) {
                if (imgs[i].complete) {
                  imgCount--;
                }
              }
              if (imgCount && !$.browser.opera) {
                $(imgs).bind('load error', function() {
                  imgCount--;
                  if (imgCount<1) {
                    $cluetipWait.hide();
                    if (isActive) { cluetipShow(pY); }
                  }
                }); 
              } else {
                $cluetipWait.hide();
                if (isActive) { cluetipShow(pY); }
              } 
            }
          };
          var ajaxMergedSettings = $.extend(true, {}, opts.ajaxSettings, ajaxSettings);
          
          $.ajax(ajaxMergedSettings);
        }

/***************************************
* load an element from the same page
***************************************/
      } else if (opts.local) {
        
        var $localContent = $(tipAttribute + (/#\S+$/.test(tipAttribute) ? '' : ':eq(' + index + ')')).clone(true).show();
        $cluetipInner.html($localContent);
        cluetipShow(pY);
      }
    };

// get dimensions and options for cluetip and prepare it to be shown
    var cluetipShow = function(bpY) {
      $cluetip.addClass('cluetip-' + ctClass);
      if (opts.truncate) { 
        var $truncloaded = $cluetipInner.text().slice(0,opts.truncate) + '...';
        $cluetipInner.html($truncloaded);
      }
      function doNothing() {}; //empty function
      tipTitle ? $cluetipTitle.show().html(tipTitle) : (opts.showTitle) ? $cluetipTitle.show().html('&nbsp;') : $cluetipTitle.hide();
      if (opts.sticky) {
        var $closeLink = $('<div id="cluetip-close"><a href="#">' + opts.closeText + '</a></div>');
        (opts.closePosition == 'bottom') ? $closeLink.appendTo($cluetipInner) : (opts.closePosition == 'title') ? $closeLink.prependTo($cluetipTitle) : $closeLink.prependTo($cluetipInner);
        $closeLink.bind('click.cluetip', function() {
          cluetipClose();
          return false;
        });
        if (opts.mouseOutClose) {
          $cluetip.bind('mouseleave.cluetip', function() {
            cluetipClose();
          });
        } else {
          $cluetip.unbind('mouseleave.cluetip');
        }
      }
// now that content is loaded, finish the positioning 
      var direction = '';
      $cluetipOuter.css({zIndex: $this.data('thisInfo').zIndex, overflow: defHeight == 'auto' ? 'visible' : 'auto', height: defHeight});
      tipHeight = defHeight == 'auto' ? Math.max($cluetip.outerHeight(),$cluetip.height()) : parseInt(defHeight,10);   
      tipY = posY;
      baseline = sTop + wHeight;
      if (opts.positionBy == 'fixed') {
        tipY = posY - opts.dropShadowSteps + tOffset;
      } else if ( (posX < mouseX && Math.max(posX, 0) + tipWidth > mouseX) || opts.positionBy == 'bottomTop') {
        if (posY + tipHeight + tOffset > baseline && mouseY - sTop > tipHeight + tOffset) { 
          tipY = mouseY - tipHeight - tOffset;
          direction = 'top';
        } else { 
          tipY = mouseY + tOffset;
          direction = 'bottom';
        }
      } else if ( posY + tipHeight + tOffset > baseline ) {
        tipY = (tipHeight >= wHeight) ? sTop : baseline - tipHeight - tOffset;
      } else if ($this.css('display') == 'block' || link.tagName.toLowerCase() == 'area' || opts.positionBy == "mouse") {
        tipY = bpY - tOffset;
      } else {
        tipY = posY - opts.dropShadowSteps;
      }
      if (direction == '') {
        posX < linkLeft ? direction = 'left' : direction = 'right';
      }
      $cluetip.css({top: tipY + 'px'}).removeClass().addClass('clue-' + direction + '-' + ctClass).addClass(' cluetip-' + ctClass);
      if (opts.arrows) { // set up arrow positioning to align with element
        var bgY = (posY - tipY - opts.dropShadowSteps);
        $cluetipArrows.css({top: (/(left|right)/.test(direction) && posX >=0 && bgY > 0) ? bgY + 'px' : /(left|right)/.test(direction) ? 0 : ''}).show();
      } else {
        $cluetipArrows.hide();
      }

// (first hide, then) ***SHOW THE CLUETIP***
      $dropShadow.hide();
      $cluetip.hide()[opts.fx.open](opts.fx.openSpeed || 0);
      if (opts.dropShadow) { $dropShadow.css({height: tipHeight, width: tipInnerWidth, zIndex: $this.data('thisInfo').zIndex-1}).show(); }
      if ($.fn.bgiframe) { $cluetip.bgiframe(); }
      // delayed close (not fully tested)
      if (opts.delayedClose > 0) {
        closeOnDelay = setTimeout(cluetipClose, opts.delayedClose);
      }
      // trigger the optional onShow function
      opts.onShow.call(link, $cluetip, $cluetipInner);
    };

/***************************************
   =INACTIVATION
-------------------------------------- */
    var inactivate = function(event) {
      isActive = false;
      $cluetipWait.hide();
      if (!opts.sticky || (/click|toggle/).test(opts.activation) ) {
        cluetipClose();
        clearTimeout(closeOnDelay);        
      }
      if (opts.hoverClass) {
        $this.removeClass(opts.hoverClass);
      }
    };
// close cluetip and reset some things
    var cluetipClose = function() {
      $cluetipOuter 
      .parent().hide().removeClass();
      opts.onHide.call(link, $cluetip, $cluetipInner);
      $this.removeClass('cluetip-clicked');
      if (tipTitle) {
        $this.attr(opts.titleAttribute, tipTitle);
      }
      $this.css('cursor','');
      if (opts.arrows) {
        $cluetipArrows.css({top: ''});
      }
    };

    $(document).bind('hideCluetip', function(e) {
      cluetipClose();
    });
/***************************************
   =BIND EVENTS
-------------------------------------- */
  // activate by click
      if ( (/click|toggle/).test(opts.activation) ) {
        $this.bind('click.cluetip', function(event) {
          if ($cluetip.is(':hidden') || !$this.is('.cluetip-clicked')) {
            activate(event);
            $('.cluetip-clicked').removeClass('cluetip-clicked');
            $this.addClass('cluetip-clicked');
          } else {
            inactivate(event);
          }
          this.blur();
          return false;
        });
  // activate by focus; inactivate by blur    
      } else if (opts.activation == 'focus') {
        $this.bind('focus.cluetip', function(event) {
          activate(event);
        });
        $this.bind('blur.cluetip', function(event) {
          inactivate(event);
        });
  // activate by hover
      } else {
        // clicking is returned false if clickThrough option is set to false
        $this[opts.clickThrough ? 'unbind' : 'bind']('click', returnFalse);
        //set up mouse tracking
        var mouseTracks = function(evt) {
          if (opts.tracking == true) {
            var trackX = posX - evt.pageX;
            var trackY = tipY ? tipY - evt.pageY : posY - evt.pageY;
            $this.bind('mousemove.cluetip', function(evt) {
              $cluetip.css({left: evt.pageX + trackX, top: evt.pageY + trackY });
            });
          }
        };
        if ($.fn.hoverIntent && opts.hoverIntent) {
          $this.hoverIntent({
            sensitivity: opts.hoverIntent.sensitivity,
            interval: opts.hoverIntent.interval,  
            over: function(event) {
              activate(event);
              mouseTracks(event);
            }, 
            timeout: opts.hoverIntent.timeout,  
            out: function(event) {inactivate(event); $this.unbind('mousemove.cluetip');}
          });           
        } else {
          $this.bind('mouseenter.cluetip', function(event) {
            activate(event);
            mouseTracks(event);
          })
          .bind('mouseleave.cluetip', function(event) {
            inactivate(event);
            $this.unbind('mousemove.cluetip');
          });
        }
        $this.bind('mouseover.cluetip', function(event) {
          $this.attr('title','');
        }).bind('mouseleave.cluetip', function(event) {
          $this.attr('title', $this.data('thisInfo').title);
        });
      }
    });
  };
  
/*
 * options for clueTip
 *
 * each one can be explicitly overridden by changing its value. 
 * for example: $.fn.cluetip.defaults.width = 200; 
 * would change the default width for all clueTips to 200. 
 *
 * each one can also be overridden by passing an options map to the cluetip method.
 * for example: $('a.example').cluetip({width: 200}); 
 * would change the default width to 200 for clueTips invoked by a link with class of "example"
 *
 */
  
  $.fn.cluetip.defaults = {  // set up default options
    width:            275,      // The width of the clueTip
    height:           'auto',   // The height of the clueTip
    cluezIndex:       97,       // Sets the z-index style property of the clueTip
    positionBy:       'auto',   // Sets the type of positioning: 'auto', 'mouse','bottomTop', 'fixed'
    topOffset:        15,       // Number of px to offset clueTip from top of invoking element
    leftOffset:       15,       // Number of px to offset clueTip from left of invoking element
    local:            false,    // Whether to use content from the same page for the clueTip's body
    localPrefix:      null,       // string to be prepended to the tip attribute if local is true
    hideLocal:        true,     // If local option is set to true, this determines whether local content
                                // to be shown in clueTip should be hidden at its original location
    attribute:        'rel',    // the attribute to be used for fetching the clueTip's body content
    titleAttribute:   'title',  // the attribute to be used for fetching the clueTip's title
    splitTitle:       '',       // A character used to split the title attribute into the clueTip title and divs
                                // within the clueTip body. more info below [6]
    escapeTitle:      false,    // whether to html escape the title attribute
    showTitle:        true,     // show title bar of the clueTip, even if title attribute not set
    cluetipClass:     'default',// class added to outermost clueTip div in the form of 'cluetip-' + clueTipClass.
    hoverClass:       '',       // class applied to the invoking element onmouseover and removed onmouseout
    waitImage:        true,     // whether to show a "loading" img, which is set in jquery.cluetip.css
    cursor:           'help',
    arrows:           false,    // if true, displays arrow on appropriate side of clueTip
    dropShadow:       true,     // set to false if you don't want the drop-shadow effect on the clueTip
    dropShadowSteps:  6,        // adjusts the size of the drop shadow
    sticky:           false,    // keep visible until manually closed
    mouseOutClose:    false,    // close when clueTip is moused out
    activation:       'hover',  // set to 'click' to force user to click to show clueTip
                                // set to 'focus' to show on focus of a form element and hide on blur
    clickThrough:     false,    // if true, and activation is not 'click', then clicking on link will take user to the link's href,
                                // even if href and tipAttribute are equal
    tracking:         false,    // if true, clueTip will track mouse movement (experimental)
    delayedClose:     0,        // close clueTip on a timed delay (experimental)
    closePosition:    'top',    // location of close text for sticky cluetips; can be 'top' or 'bottom' or 'title'
    closeText:        'Close',  // text (or HTML) to to be clicked to close sticky clueTips
    truncate:         0,        // number of characters to truncate clueTip's contents. if 0, no truncation occurs
    
    // effect and speed for opening clueTips
    fx: {             
                      open:       'show', // can be 'show' or 'slideDown' or 'fadeIn'
                      openSpeed:  ''
    },     

    // settings for when hoverIntent plugin is used             
    hoverIntent: {    
                      sensitivity:  3,
              			  interval:     50,
              			  timeout:      0
    },

    // short-circuit function to run just before clueTip is shown. 
    onActivate:       function(e) {return true;},
    // function to run just after clueTip is shown. 
    onShow:           function(ct, ci){},
    // function to run just after clueTip is hidden.
    onHide:           function(ct, ci){},
    // whether to cache results of ajax request to avoid unnecessary hits to server    
    ajaxCache:        true,  

    // process data retrieved via xhr before it's displayed
    ajaxProcess:      function(data) {
                        data = data.replace(/<(script|style|title)[^<]+<\/(script|style|title)>/gm, '').replace(/<(link|meta)[^>]+>/g,'');
                        return data;
    },                

    // can pass in standard $.ajax() parameters. Callback functions, such as beforeSend, 
    // will be queued first within the default callbacks. 
    // The only exception is error, which overrides the default
    ajaxSettings: {
                      // error: function(ct, ci) { /* override default error callback */ }
                      // beforeSend: function(ct, ci) { /* called first within default beforeSend callback }
                      dataType: 'html'
    },
    debug: false
  };


/*
 * Global defaults for clueTips. Apply to all calls to the clueTip plugin.
 *
 * @example $.cluetip.setup({
 *   insertionType: 'prependTo',
 *   insertionElement: '#container'
 * });
 * 
 * @property
 * @name $.cluetip.setup
 * @type Map
 * @cat Plugins/tooltip
 * @option String insertionType: Default is 'appendTo'. Determines the method to be used for inserting the clueTip into the DOM. Permitted values are 'appendTo', 'prependTo', 'insertBefore', and 'insertAfter'
 * @option String insertionElement: Default is 'body'. Determines which element in the DOM the plugin will reference when inserting the clueTip.
 *
 */
   
  var insertionType = 'appendTo', insertionElement = 'body';

  $.cluetip.setup = function(options) {
    if (options && options.insertionType && (options.insertionType).match(/appendTo|prependTo|insertBefore|insertAfter/)) {
      insertionType = options.insertionType;
    }
    if (options && options.insertionElement) {
      insertionElement = options.insertionElement;
    }
  };
  
})(jQuery);

